LCOV - code coverage report
Current view: top level - pulsecore - sample-util.c (source / functions) Hit Total Coverage
Test: lcov.out Lines: 287 462 62.1 %
Date: 2012-07-17 Functions: 7 23 30.4 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 180 364 49.5 %

           Branch data     Line data    Source code
       1                 :            : /***
       2                 :            :   This file is part of PulseAudio.
       3                 :            : 
       4                 :            :   Copyright 2004-2006 Lennart Poettering
       5                 :            :   Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
       6                 :            : 
       7                 :            :   PulseAudio is free software; you can redistribute it and/or modify
       8                 :            :   it under the terms of the GNU Lesser General Public License as published
       9                 :            :   by the Free Software Foundation; either version 2.1 of the License,
      10                 :            :   or (at your option) any later version.
      11                 :            : 
      12                 :            :   PulseAudio is distributed in the hope that it will be useful, but
      13                 :            :   WITHOUT ANY WARRANTY; without even the implied warranty of
      14                 :            :   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
      15                 :            :   General Public License for more details.
      16                 :            : 
      17                 :            :   You should have received a copy of the GNU Lesser General Public License
      18                 :            :   along with PulseAudio; if not, write to the Free Software
      19                 :            :   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
      20                 :            :   USA.
      21                 :            : ***/
      22                 :            : 
      23                 :            : #ifdef HAVE_CONFIG_H
      24                 :            : #include <config.h>
      25                 :            : #endif
      26                 :            : 
      27                 :            : #include <stdio.h>
      28                 :            : #include <string.h>
      29                 :            : #include <stdlib.h>
      30                 :            : #include <stdio.h>
      31                 :            : #include <errno.h>
      32                 :            : #include <math.h>
      33                 :            : 
      34                 :            : #include <pulse/timeval.h>
      35                 :            : 
      36                 :            : #include <pulsecore/log.h>
      37                 :            : #include <pulsecore/core-error.h>
      38                 :            : #include <pulsecore/macro.h>
      39                 :            : #include <pulsecore/g711.h>
      40                 :            : #include <pulsecore/core-util.h>
      41                 :            : #include <pulsecore/endianmacros.h>
      42                 :            : 
      43                 :            : #include "sample-util.h"
      44                 :            : 
      45                 :            : #define PA_SILENCE_MAX (PA_PAGE_SIZE*16)
      46                 :            : 
      47                 :          0 : pa_memblock *pa_silence_memblock(pa_memblock* b, const pa_sample_spec *spec) {
      48                 :            :     void *data;
      49                 :            : 
      50         [ #  # ]:          0 :     pa_assert(b);
      51         [ #  # ]:          0 :     pa_assert(spec);
      52                 :            : 
      53                 :          0 :     data = pa_memblock_acquire(b);
      54                 :          0 :     pa_silence_memory(data, pa_memblock_get_length(b), spec);
      55                 :          0 :     pa_memblock_release(b);
      56                 :            : 
      57                 :          0 :     return b;
      58                 :            : }
      59                 :            : 
      60                 :          0 : pa_memchunk* pa_silence_memchunk(pa_memchunk *c, const pa_sample_spec *spec) {
      61                 :            :     void *data;
      62                 :            : 
      63         [ #  # ]:          0 :     pa_assert(c);
      64         [ #  # ]:          0 :     pa_assert(c->memblock);
      65         [ #  # ]:          0 :     pa_assert(spec);
      66                 :            : 
      67                 :          0 :     data = pa_memblock_acquire(c->memblock);
      68                 :          0 :     pa_silence_memory((uint8_t*) data+c->index, c->length, spec);
      69                 :          0 :     pa_memblock_release(c->memblock);
      70                 :            : 
      71                 :          0 :     return c;
      72                 :            : }
      73                 :            : 
      74                 :            : static uint8_t silence_byte(pa_sample_format_t format) {
      75   [ #  #  #  #  :          0 :     switch (format) {
                      # ]
      76                 :            :         case PA_SAMPLE_U8:
      77                 :            :             return 0x80;
      78                 :            :         case PA_SAMPLE_S16LE:
      79                 :            :         case PA_SAMPLE_S16BE:
      80                 :            :         case PA_SAMPLE_S32LE:
      81                 :            :         case PA_SAMPLE_S32BE:
      82                 :            :         case PA_SAMPLE_FLOAT32LE:
      83                 :            :         case PA_SAMPLE_FLOAT32BE:
      84                 :            :         case PA_SAMPLE_S24LE:
      85                 :            :         case PA_SAMPLE_S24BE:
      86                 :            :         case PA_SAMPLE_S24_32LE:
      87                 :            :         case PA_SAMPLE_S24_32BE:
      88                 :            :             return 0;
      89                 :            :         case PA_SAMPLE_ALAW:
      90                 :            :             return 0xd5;
      91                 :            :         case PA_SAMPLE_ULAW:
      92                 :            :             return 0xff;
      93                 :            :         default:
      94                 :          0 :             pa_assert_not_reached();
      95                 :            :     }
      96                 :            : }
      97                 :            : 
      98                 :          0 : void* pa_silence_memory(void *p, size_t length, const pa_sample_spec *spec) {
      99         [ #  # ]:          0 :     pa_assert(p);
     100         [ #  # ]:          0 :     pa_assert(length > 0);
     101         [ #  # ]:          0 :     pa_assert(spec);
     102                 :            : 
     103                 :          0 :     memset(p, silence_byte(spec->format), length);
     104                 :          0 :     return p;
     105                 :            : }
     106                 :            : 
     107                 :            : #define VOLUME_PADDING 32
     108                 :            : 
     109                 :         11 : static void calc_linear_integer_volume(int32_t linear[], const pa_cvolume *volume) {
     110                 :            :     unsigned channel, nchannels, padding;
     111                 :            : 
     112         [ -  + ]:         11 :     pa_assert(linear);
     113         [ -  + ]:         11 :     pa_assert(volume);
     114                 :            : 
     115                 :         11 :     nchannels = volume->channels;
     116                 :            : 
     117         [ +  + ]:         22 :     for (channel = 0; channel < nchannels; channel++)
     118                 :         11 :         linear[channel] = (int32_t) lrint(pa_sw_volume_to_linear(volume->values[channel]) * 0x10000);
     119                 :            : 
     120         [ +  + ]:        363 :     for (padding = 0; padding < VOLUME_PADDING; padding++, channel++)
     121                 :        352 :         linear[channel] = linear[padding];
     122                 :         11 : }
     123                 :            : 
     124                 :         15 : static void calc_linear_float_volume(float linear[], const pa_cvolume *volume) {
     125                 :            :     unsigned channel, nchannels, padding;
     126                 :            : 
     127         [ -  + ]:         15 :     pa_assert(linear);
     128         [ -  + ]:         15 :     pa_assert(volume);
     129                 :            : 
     130                 :         15 :     nchannels = volume->channels;
     131                 :            : 
     132         [ +  + ]:         30 :     for (channel = 0; channel < nchannels; channel++)
     133                 :         15 :         linear[channel] = (float) pa_sw_volume_to_linear(volume->values[channel]);
     134                 :            : 
     135         [ +  + ]:        495 :     for (padding = 0; padding < VOLUME_PADDING; padding++, channel++)
     136                 :        480 :         linear[channel] = linear[padding];
     137                 :         15 : }
     138                 :            : 
     139                 :         11 : static void calc_linear_integer_stream_volumes(pa_mix_info streams[], unsigned nstreams, const pa_cvolume *volume, const pa_sample_spec *spec) {
     140                 :            :     unsigned k, channel;
     141                 :            :     float linear[PA_CHANNELS_MAX + VOLUME_PADDING];
     142                 :            : 
     143         [ -  + ]:         11 :     pa_assert(streams);
     144         [ -  + ]:         11 :     pa_assert(spec);
     145         [ -  + ]:         11 :     pa_assert(volume);
     146                 :            : 
     147                 :         11 :     calc_linear_float_volume(linear, volume);
     148                 :            : 
     149         [ +  + ]:         33 :     for (k = 0; k < nstreams; k++) {
     150                 :            : 
     151         [ +  + ]:         44 :         for (channel = 0; channel < spec->channels; channel++) {
     152                 :         22 :             pa_mix_info *m = streams + k;
     153                 :         22 :             m->linear[channel].i = (int32_t) lrint(pa_sw_volume_to_linear(m->volume.values[channel]) * linear[channel] * 0x10000);
     154                 :            :         }
     155                 :            :     }
     156                 :         11 : }
     157                 :            : 
     158                 :          2 : static void calc_linear_float_stream_volumes(pa_mix_info streams[], unsigned nstreams, const pa_cvolume *volume, const pa_sample_spec *spec) {
     159                 :            :     unsigned k, channel;
     160                 :            :     float linear[PA_CHANNELS_MAX + VOLUME_PADDING];
     161                 :            : 
     162         [ -  + ]:          2 :     pa_assert(streams);
     163         [ -  + ]:          2 :     pa_assert(spec);
     164         [ -  + ]:          2 :     pa_assert(volume);
     165                 :            : 
     166                 :          2 :     calc_linear_float_volume(linear, volume);
     167                 :            : 
     168         [ +  + ]:          6 :     for (k = 0; k < nstreams; k++) {
     169                 :            : 
     170         [ +  + ]:          8 :         for (channel = 0; channel < spec->channels; channel++) {
     171                 :          4 :             pa_mix_info *m = streams + k;
     172                 :          4 :             m->linear[channel].f = (float) (pa_sw_volume_to_linear(m->volume.values[channel]) * linear[channel]);
     173                 :            :         }
     174                 :            :     }
     175                 :          2 : }
     176                 :            : 
     177                 :         13 : size_t pa_mix(
     178                 :            :         pa_mix_info streams[],
     179                 :            :         unsigned nstreams,
     180                 :            :         void *data,
     181                 :            :         size_t length,
     182                 :            :         const pa_sample_spec *spec,
     183                 :            :         const pa_cvolume *volume,
     184                 :            :         pa_bool_t mute) {
     185                 :            : 
     186                 :            :     pa_cvolume full_volume;
     187                 :            :     unsigned k;
     188                 :            :     unsigned z;
     189                 :            :     void *end;
     190                 :            : 
     191         [ -  + ]:         13 :     pa_assert(streams);
     192         [ -  + ]:         13 :     pa_assert(data);
     193         [ -  + ]:         13 :     pa_assert(length);
     194         [ -  + ]:         13 :     pa_assert(spec);
     195                 :            : 
     196         [ +  - ]:         13 :     if (!volume)
     197                 :         13 :         volume = pa_cvolume_reset(&full_volume, spec->channels);
     198                 :            : 
     199 [ +  - ][ +  - ]:         13 :     if (mute || pa_cvolume_is_muted(volume) || nstreams <= 0) {
     200                 :          0 :         pa_silence_memory(data, length, spec);
     201                 :          0 :         return length;
     202                 :            :     }
     203                 :            : 
     204         [ +  + ]:         39 :     for (k = 0; k < nstreams; k++)
     205                 :         26 :         streams[k].ptr = (uint8_t*) pa_memblock_acquire(streams[k].chunk.memblock) + streams[k].chunk.index;
     206                 :            : 
     207         [ +  + ]:         39 :     for (z = 0; z < nstreams; z++)
     208         [ -  + ]:         26 :         if (length > streams[z].chunk.length)
     209                 :          0 :             length = streams[z].chunk.length;
     210                 :            : 
     211                 :         13 :     end = (uint8_t*) data + length;
     212                 :            : 
     213   [ +  +  +  +  :         13 :     switch (spec->format) {
          +  +  +  +  +  
             +  +  +  +  
                      - ]
     214                 :            : 
     215                 :            :         case PA_SAMPLE_S16NE:{
     216                 :          1 :             unsigned channel = 0;
     217                 :            : 
     218                 :          1 :             calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
     219                 :            : 
     220         [ +  + ]:         11 :             while (data < end) {
     221                 :            :                 int32_t sum = 0;
     222                 :            :                 unsigned i;
     223                 :            : 
     224         [ +  + ]:         30 :                 for (i = 0; i < nstreams; i++) {
     225                 :         20 :                     pa_mix_info *m = streams + i;
     226                 :         20 :                     int32_t v, lo, hi, cv = m->linear[channel].i;
     227                 :            : 
     228         [ +  - ]:         20 :                     if (PA_LIKELY(cv > 0)) {
     229                 :            : 
     230                 :            :                         /* Multiplying the 32bit volume factor with the
     231                 :            :                          * 16bit sample might result in an 48bit value. We
     232                 :            :                          * want to do without 64 bit integers and hence do
     233                 :            :                          * the multiplication independently for the HI and
     234                 :            :                          * LO part of the volume. */
     235                 :            : 
     236                 :         20 :                         hi = cv >> 16;
     237                 :         20 :                         lo = cv & 0xFFFF;
     238                 :            : 
     239                 :         20 :                         v = *((int16_t*) m->ptr);
     240                 :         20 :                         v = ((v * lo) >> 16) + (v * hi);
     241                 :         20 :                         sum += v;
     242                 :            :                     }
     243                 :         20 :                     m->ptr = (uint8_t*) m->ptr + sizeof(int16_t);
     244                 :            :                 }
     245                 :            : 
     246 [ +  + ][ +  + ]:         10 :                 sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);
     247                 :         10 :                 *((int16_t*) data) = (int16_t) sum;
     248                 :            : 
     249                 :         10 :                 data = (uint8_t*) data + sizeof(int16_t);
     250                 :            : 
     251         [ +  - ]:         10 :                 if (PA_UNLIKELY(++channel >= spec->channels))
     252                 :         10 :                     channel = 0;
     253                 :            :             }
     254                 :            : 
     255                 :            :             break;
     256                 :            :         }
     257                 :            : 
     258                 :            :         case PA_SAMPLE_S16RE:{
     259                 :          1 :             unsigned channel = 0;
     260                 :            : 
     261                 :          1 :             calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
     262                 :            : 
     263         [ +  + ]:         23 :             while (data < end) {
     264                 :            :                 int32_t sum = 0;
     265                 :            :                 unsigned i;
     266                 :            : 
     267         [ +  + ]:         30 :                 for (i = 0; i < nstreams; i++) {
     268                 :         20 :                     pa_mix_info *m = streams + i;
     269                 :         20 :                     int32_t v, lo, hi, cv = m->linear[channel].i;
     270                 :            : 
     271         [ +  - ]:         20 :                     if (PA_LIKELY(cv > 0)) {
     272                 :            : 
     273                 :         20 :                         hi = cv >> 16;
     274                 :         20 :                         lo = cv & 0xFFFF;
     275                 :            : 
     276         [ -  + ]:         20 :                         v = PA_INT16_SWAP(*((int16_t*) m->ptr));
     277                 :         20 :                         v = ((v * lo) >> 16) + (v * hi);
     278                 :         20 :                         sum += v;
     279                 :            :                     }
     280                 :         20 :                     m->ptr = (uint8_t*) m->ptr + sizeof(int16_t);
     281                 :            :                 }
     282                 :            : 
     283 [ +  - ][ +  - ]:         10 :                 sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);
     284         [ -  + ]:         10 :                 *((int16_t*) data) = PA_INT16_SWAP((int16_t) sum);
     285                 :            : 
     286                 :         10 :                 data = (uint8_t*) data + sizeof(int16_t);
     287                 :            : 
     288         [ +  - ]:         10 :                 if (PA_UNLIKELY(++channel >= spec->channels))
     289                 :         10 :                     channel = 0;
     290                 :            :             }
     291                 :            : 
     292                 :            :             break;
     293                 :            :         }
     294                 :            : 
     295                 :            :         case PA_SAMPLE_S32NE:{
     296                 :          1 :             unsigned channel = 0;
     297                 :            : 
     298                 :          1 :             calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
     299                 :            : 
     300         [ +  + ]:         11 :             while (data < end) {
     301                 :            :                 int64_t sum = 0;
     302                 :            :                 unsigned i;
     303                 :            : 
     304         [ +  + ]:         30 :                 for (i = 0; i < nstreams; i++) {
     305                 :         20 :                     pa_mix_info *m = streams + i;
     306                 :         20 :                     int32_t cv = m->linear[channel].i;
     307                 :            :                     int64_t v;
     308                 :            : 
     309         [ +  - ]:         20 :                     if (PA_LIKELY(cv > 0)) {
     310                 :            : 
     311                 :         20 :                         v = *((int32_t*) m->ptr);
     312                 :         20 :                         v = (v * cv) >> 16;
     313                 :         20 :                         sum += v;
     314                 :            :                     }
     315                 :         20 :                     m->ptr = (uint8_t*) m->ptr + sizeof(int32_t);
     316                 :            :                 }
     317                 :            : 
     318 [ +  + ][ +  + ]:         10 :                 sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL);
     319                 :         10 :                 *((int32_t*) data) = (int32_t) sum;
     320                 :            : 
     321                 :         10 :                 data = (uint8_t*) data + sizeof(int32_t);
     322                 :            : 
     323         [ +  - ]:         10 :                 if (PA_UNLIKELY(++channel >= spec->channels))
     324                 :         10 :                     channel = 0;
     325                 :            :             }
     326                 :            : 
     327                 :            :             break;
     328                 :            :         }
     329                 :            : 
     330                 :            :         case PA_SAMPLE_S32RE:{
     331                 :          1 :             unsigned channel = 0;
     332                 :            : 
     333                 :          1 :             calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
     334                 :            : 
     335         [ +  + ]:         11 :             while (data < end) {
     336                 :            :                 int64_t sum = 0;
     337                 :            :                 unsigned i;
     338                 :            : 
     339         [ +  + ]:         30 :                 for (i = 0; i < nstreams; i++) {
     340                 :         20 :                     pa_mix_info *m = streams + i;
     341                 :         20 :                     int32_t cv = m->linear[channel].i;
     342                 :            :                     int64_t v;
     343                 :            : 
     344         [ +  - ]:         20 :                     if (PA_LIKELY(cv > 0)) {
     345                 :            : 
     346         [ -  + ]:         20 :                         v = PA_INT32_SWAP(*((int32_t*) m->ptr));
     347                 :         20 :                         v = (v * cv) >> 16;
     348                 :         20 :                         sum += v;
     349                 :            :                     }
     350                 :         20 :                     m->ptr = (uint8_t*) m->ptr + sizeof(int32_t);
     351                 :            :                 }
     352                 :            : 
     353 [ +  - ][ +  - ]:         10 :                 sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL);
     354         [ -  + ]:         10 :                 *((int32_t*) data) = PA_INT32_SWAP((int32_t) sum);
     355                 :            : 
     356                 :         10 :                 data = (uint8_t*) data + sizeof(int32_t);
     357                 :            : 
     358         [ +  - ]:         10 :                 if (PA_UNLIKELY(++channel >= spec->channels))
     359                 :         10 :                     channel = 0;
     360                 :            :             }
     361                 :            : 
     362                 :            :             break;
     363                 :            :         }
     364                 :            : 
     365                 :            :         case PA_SAMPLE_S24NE: {
     366                 :          1 :             unsigned channel = 0;
     367                 :            : 
     368                 :          1 :             calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
     369                 :            : 
     370         [ +  + ]:         11 :             while (data < end) {
     371                 :            :                 int64_t sum = 0;
     372                 :            :                 unsigned i;
     373                 :            : 
     374         [ +  + ]:         30 :                 for (i = 0; i < nstreams; i++) {
     375                 :         20 :                     pa_mix_info *m = streams + i;
     376                 :         20 :                     int32_t cv = m->linear[channel].i;
     377                 :            :                     int64_t v;
     378                 :            : 
     379         [ +  - ]:         20 :                     if (PA_LIKELY(cv > 0)) {
     380                 :            : 
     381                 :         40 :                         v = (int32_t) (PA_READ24NE(m->ptr) << 8);
     382                 :         20 :                         v = (v * cv) >> 16;
     383                 :         20 :                         sum += v;
     384                 :            :                     }
     385                 :         20 :                     m->ptr = (uint8_t*) m->ptr + 3;
     386                 :            :                 }
     387                 :            : 
     388 [ +  - ][ +  - ]:         10 :                 sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL);
     389                 :         10 :                 PA_WRITE24NE(data, ((uint32_t) sum) >> 8);
     390                 :            : 
     391                 :         10 :                 data = (uint8_t*) data + 3;
     392                 :            : 
     393         [ +  - ]:         10 :                 if (PA_UNLIKELY(++channel >= spec->channels))
     394                 :         10 :                     channel = 0;
     395                 :            :             }
     396                 :            : 
     397                 :            :             break;
     398                 :            :         }
     399                 :            : 
     400                 :            :         case PA_SAMPLE_S24RE: {
     401                 :          1 :             unsigned channel = 0;
     402                 :            : 
     403                 :          1 :             calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
     404                 :            : 
     405         [ +  + ]:         11 :             while (data < end) {
     406                 :            :                 int64_t sum = 0;
     407                 :            :                 unsigned i;
     408                 :            : 
     409         [ +  + ]:         30 :                 for (i = 0; i < nstreams; i++) {
     410                 :         20 :                     pa_mix_info *m = streams + i;
     411                 :         20 :                     int32_t cv = m->linear[channel].i;
     412                 :            :                     int64_t v;
     413                 :            : 
     414         [ +  - ]:         20 :                     if (PA_LIKELY(cv > 0)) {
     415                 :            : 
     416                 :         40 :                         v = (int32_t) (PA_READ24RE(m->ptr) << 8);
     417                 :         20 :                         v = (v * cv) >> 16;
     418                 :         20 :                         sum += v;
     419                 :            :                     }
     420                 :         20 :                     m->ptr = (uint8_t*) m->ptr + 3;
     421                 :            :                 }
     422                 :            : 
     423 [ +  + ][ +  + ]:         10 :                 sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL);
     424                 :         10 :                 PA_WRITE24RE(data, ((uint32_t) sum) >> 8);
     425                 :            : 
     426                 :         10 :                 data = (uint8_t*) data + 3;
     427                 :            : 
     428         [ +  - ]:         10 :                 if (PA_UNLIKELY(++channel >= spec->channels))
     429                 :         10 :                     channel = 0;
     430                 :            :             }
     431                 :            : 
     432                 :            :             break;
     433                 :            :         }
     434                 :            : 
     435                 :            :         case PA_SAMPLE_S24_32NE: {
     436                 :          1 :             unsigned channel = 0;
     437                 :            : 
     438                 :          1 :             calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
     439                 :            : 
     440         [ +  + ]:         11 :             while (data < end) {
     441                 :            :                 int64_t sum = 0;
     442                 :            :                 unsigned i;
     443                 :            : 
     444         [ +  + ]:         30 :                 for (i = 0; i < nstreams; i++) {
     445                 :         20 :                     pa_mix_info *m = streams + i;
     446                 :         20 :                     int32_t cv = m->linear[channel].i;
     447                 :            :                     int64_t v;
     448                 :            : 
     449         [ +  - ]:         20 :                     if (PA_LIKELY(cv > 0)) {
     450                 :            : 
     451                 :         20 :                         v = (int32_t) (*((uint32_t*)m->ptr) << 8);
     452                 :         20 :                         v = (v * cv) >> 16;
     453                 :         20 :                         sum += v;
     454                 :            :                     }
     455                 :         20 :                     m->ptr = (uint8_t*) m->ptr + sizeof(int32_t);
     456                 :            :                 }
     457                 :            : 
     458 [ +  - ][ +  - ]:         10 :                 sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL);
     459                 :         10 :                 *((uint32_t*) data) = ((uint32_t) (int32_t) sum) >> 8;
     460                 :            : 
     461                 :         10 :                 data = (uint8_t*) data + sizeof(uint32_t);
     462                 :            : 
     463         [ +  - ]:         10 :                 if (PA_UNLIKELY(++channel >= spec->channels))
     464                 :         10 :                     channel = 0;
     465                 :            :             }
     466                 :            : 
     467                 :            :             break;
     468                 :            :         }
     469                 :            : 
     470                 :            :         case PA_SAMPLE_S24_32RE: {
     471                 :          1 :             unsigned channel = 0;
     472                 :            : 
     473                 :          1 :             calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
     474                 :            : 
     475         [ +  + ]:         11 :             while (data < end) {
     476                 :            :                 int64_t sum = 0;
     477                 :            :                 unsigned i;
     478                 :            : 
     479         [ +  + ]:         30 :                 for (i = 0; i < nstreams; i++) {
     480                 :         20 :                     pa_mix_info *m = streams + i;
     481                 :         20 :                     int32_t cv = m->linear[channel].i;
     482                 :            :                     int64_t v;
     483                 :            : 
     484         [ +  - ]:         20 :                     if (PA_LIKELY(cv > 0)) {
     485                 :            : 
     486         [ -  + ]:         20 :                         v = (int32_t) (PA_UINT32_SWAP(*((uint32_t*) m->ptr)) << 8);
     487                 :         20 :                         v = (v * cv) >> 16;
     488                 :         20 :                         sum += v;
     489                 :            :                     }
     490                 :         20 :                     m->ptr = (uint8_t*) m->ptr + 3;
     491                 :            :                 }
     492                 :            : 
     493 [ +  - ][ +  - ]:         10 :                 sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL);
     494         [ -  + ]:         10 :                 *((uint32_t*) data) = PA_INT32_SWAP(((uint32_t) (int32_t) sum) >> 8);
     495                 :            : 
     496                 :         10 :                 data = (uint8_t*) data + sizeof(uint32_t);
     497                 :            : 
     498         [ +  - ]:         10 :                 if (PA_UNLIKELY(++channel >= spec->channels))
     499                 :         10 :                     channel = 0;
     500                 :            :             }
     501                 :            : 
     502                 :            :             break;
     503                 :            :         }
     504                 :            : 
     505                 :            :         case PA_SAMPLE_U8: {
     506                 :          1 :             unsigned channel = 0;
     507                 :            : 
     508                 :          1 :             calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
     509                 :            : 
     510         [ +  + ]:         11 :             while (data < end) {
     511                 :            :                 int32_t sum = 0;
     512                 :            :                 unsigned i;
     513                 :            : 
     514         [ +  + ]:         30 :                 for (i = 0; i < nstreams; i++) {
     515                 :         20 :                     pa_mix_info *m = streams + i;
     516                 :         20 :                     int32_t v, cv = m->linear[channel].i;
     517                 :            : 
     518         [ +  - ]:         20 :                     if (PA_LIKELY(cv > 0)) {
     519                 :            : 
     520                 :         20 :                         v = (int32_t) *((uint8_t*) m->ptr) - 0x80;
     521                 :         20 :                         v = (v * cv) >> 16;
     522                 :         20 :                         sum += v;
     523                 :            :                     }
     524                 :         20 :                     m->ptr = (uint8_t*) m->ptr + 1;
     525                 :            :                 }
     526                 :            : 
     527 [ +  + ][ +  + ]:         10 :                 sum = PA_CLAMP_UNLIKELY(sum, -0x80, 0x7F);
     528                 :         10 :                 *((uint8_t*) data) = (uint8_t) (sum + 0x80);
     529                 :            : 
     530                 :         10 :                 data = (uint8_t*) data + 1;
     531                 :            : 
     532         [ +  - ]:         10 :                 if (PA_UNLIKELY(++channel >= spec->channels))
     533                 :         10 :                     channel = 0;
     534                 :            :             }
     535                 :            : 
     536                 :            :             break;
     537                 :            :         }
     538                 :            : 
     539                 :            :         case PA_SAMPLE_ULAW: {
     540                 :          1 :             unsigned channel = 0;
     541                 :            : 
     542                 :          1 :             calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
     543                 :            : 
     544         [ +  + ]:         11 :             while (data < end) {
     545                 :            :                 int32_t sum = 0;
     546                 :            :                 unsigned i;
     547                 :            : 
     548         [ +  + ]:         30 :                 for (i = 0; i < nstreams; i++) {
     549                 :         20 :                     pa_mix_info *m = streams + i;
     550                 :         20 :                     int32_t v, hi, lo, cv = m->linear[channel].i;
     551                 :            : 
     552         [ +  - ]:         20 :                     if (PA_LIKELY(cv > 0)) {
     553                 :            : 
     554                 :         20 :                         hi = cv >> 16;
     555                 :         20 :                         lo = cv & 0xFFFF;
     556                 :            : 
     557                 :         20 :                         v = (int32_t) st_ulaw2linear16(*((uint8_t*) m->ptr));
     558                 :         20 :                         v = ((v * lo) >> 16) + (v * hi);
     559                 :         20 :                         sum += v;
     560                 :            :                     }
     561                 :         20 :                     m->ptr = (uint8_t*) m->ptr + 1;
     562                 :            :                 }
     563                 :            : 
     564 [ +  + ][ +  + ]:         10 :                 sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);
     565                 :         10 :                 *((uint8_t*) data) = (uint8_t) st_14linear2ulaw((int16_t) sum >> 2);
     566                 :            : 
     567                 :         10 :                 data = (uint8_t*) data + 1;
     568                 :            : 
     569         [ +  - ]:         10 :                 if (PA_UNLIKELY(++channel >= spec->channels))
     570                 :         10 :                     channel = 0;
     571                 :            :             }
     572                 :            : 
     573                 :            :             break;
     574                 :            :         }
     575                 :            : 
     576                 :            :         case PA_SAMPLE_ALAW: {
     577                 :          1 :             unsigned channel = 0;
     578                 :            : 
     579                 :          1 :             calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
     580                 :            : 
     581         [ +  + ]:         11 :             while (data < end) {
     582                 :            :                 int32_t sum = 0;
     583                 :            :                 unsigned i;
     584                 :            : 
     585         [ +  + ]:         30 :                 for (i = 0; i < nstreams; i++) {
     586                 :         20 :                     pa_mix_info *m = streams + i;
     587                 :         20 :                     int32_t v, hi, lo, cv = m->linear[channel].i;
     588                 :            : 
     589         [ +  - ]:         20 :                     if (PA_LIKELY(cv > 0)) {
     590                 :            : 
     591                 :         20 :                         hi = cv >> 16;
     592                 :         20 :                         lo = cv & 0xFFFF;
     593                 :            : 
     594                 :         20 :                         v = (int32_t) st_alaw2linear16(*((uint8_t*) m->ptr));
     595                 :         20 :                         v = ((v * lo) >> 16) + (v * hi);
     596                 :         20 :                         sum += v;
     597                 :            :                     }
     598                 :         20 :                     m->ptr = (uint8_t*) m->ptr + 1;
     599                 :            :                 }
     600                 :            : 
     601 [ +  - ][ +  + ]:         10 :                 sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);
     602                 :         10 :                 *((uint8_t*) data) = (uint8_t) st_13linear2alaw((int16_t) sum >> 3);
     603                 :            : 
     604                 :         10 :                 data = (uint8_t*) data + 1;
     605                 :            : 
     606         [ +  - ]:         10 :                 if (PA_UNLIKELY(++channel >= spec->channels))
     607                 :         10 :                     channel = 0;
     608                 :            :             }
     609                 :            : 
     610                 :            :             break;
     611                 :            :         }
     612                 :            : 
     613                 :            :         case PA_SAMPLE_FLOAT32NE: {
     614                 :          1 :             unsigned channel = 0;
     615                 :            : 
     616                 :          1 :             calc_linear_float_stream_volumes(streams, nstreams, volume, spec);
     617                 :            : 
     618         [ +  + ]:         11 :             while (data < end) {
     619                 :            :                 float sum = 0;
     620                 :            :                 unsigned i;
     621                 :            : 
     622         [ +  + ]:         30 :                 for (i = 0; i < nstreams; i++) {
     623                 :         20 :                     pa_mix_info *m = streams + i;
     624                 :         20 :                     float v, cv = m->linear[channel].f;
     625                 :            : 
     626         [ +  - ]:         20 :                     if (PA_LIKELY(cv > 0)) {
     627                 :            : 
     628                 :         20 :                         v = *((float*) m->ptr);
     629                 :         20 :                         v *= cv;
     630                 :         20 :                         sum += v;
     631                 :            :                     }
     632                 :         20 :                     m->ptr = (uint8_t*) m->ptr + sizeof(float);
     633                 :            :                 }
     634                 :            : 
     635                 :         10 :                 *((float*) data) = sum;
     636                 :            : 
     637                 :         10 :                 data = (uint8_t*) data + sizeof(float);
     638                 :            : 
     639         [ +  - ]:         10 :                 if (PA_UNLIKELY(++channel >= spec->channels))
     640                 :         10 :                     channel = 0;
     641                 :            :             }
     642                 :            : 
     643                 :            :             break;
     644                 :            :         }
     645                 :            : 
     646                 :            :         case PA_SAMPLE_FLOAT32RE: {
     647                 :          1 :             unsigned channel = 0;
     648                 :            : 
     649                 :          1 :             calc_linear_float_stream_volumes(streams, nstreams, volume, spec);
     650                 :            : 
     651         [ +  + ]:         11 :             while (data < end) {
     652                 :            :                 float sum = 0;
     653                 :            :                 unsigned i;
     654                 :            : 
     655         [ +  + ]:         30 :                 for (i = 0; i < nstreams; i++) {
     656                 :         20 :                     pa_mix_info *m = streams + i;
     657                 :         20 :                     float v, cv = m->linear[channel].f;
     658                 :            : 
     659         [ +  - ]:         20 :                     if (PA_LIKELY(cv > 0)) {
     660                 :            : 
     661                 :         40 :                         v = PA_FLOAT32_SWAP(*(float*) m->ptr);
     662                 :         20 :                         v *= cv;
     663                 :         20 :                         sum += v;
     664                 :            :                     }
     665                 :         20 :                     m->ptr = (uint8_t*) m->ptr + sizeof(float);
     666                 :            :                 }
     667                 :            : 
     668                 :         10 :                 *((float*) data) = PA_FLOAT32_SWAP(sum);
     669                 :            : 
     670                 :         10 :                 data = (uint8_t*) data + sizeof(float);
     671                 :            : 
     672         [ +  - ]:         10 :                 if (PA_UNLIKELY(++channel >= spec->channels))
     673                 :         10 :                     channel = 0;
     674                 :            :             }
     675                 :            : 
     676                 :            :             break;
     677                 :            :         }
     678                 :            : 
     679                 :            :         default:
     680                 :          0 :             pa_log_error("Unable to mix audio data of format %s.", pa_sample_format_to_string(spec->format));
     681                 :          0 :             pa_assert_not_reached();
     682                 :            :     }
     683                 :            : 
     684         [ +  + ]:         39 :     for (k = 0; k < nstreams; k++)
     685                 :         26 :         pa_memblock_release(streams[k].chunk.memblock);
     686                 :            : 
     687                 :            :     return length;
     688                 :            : }
     689                 :            : 
     690                 :            : typedef union {
     691                 :            :   float f;
     692                 :            :   uint32_t i;
     693                 :            : } volume_val;
     694                 :            : 
     695                 :            : typedef void (*pa_calc_volume_func_t) (void *volumes, const pa_cvolume *volume);
     696                 :            : 
     697                 :            : static const pa_calc_volume_func_t calc_volume_table[] = {
     698                 :            :   [PA_SAMPLE_U8]        = (pa_calc_volume_func_t) calc_linear_integer_volume,
     699                 :            :   [PA_SAMPLE_ALAW]      = (pa_calc_volume_func_t) calc_linear_integer_volume,
     700                 :            :   [PA_SAMPLE_ULAW]      = (pa_calc_volume_func_t) calc_linear_integer_volume,
     701                 :            :   [PA_SAMPLE_S16LE]     = (pa_calc_volume_func_t) calc_linear_integer_volume,
     702                 :            :   [PA_SAMPLE_S16BE]     = (pa_calc_volume_func_t) calc_linear_integer_volume,
     703                 :            :   [PA_SAMPLE_FLOAT32LE] = (pa_calc_volume_func_t) calc_linear_float_volume,
     704                 :            :   [PA_SAMPLE_FLOAT32BE] = (pa_calc_volume_func_t) calc_linear_float_volume,
     705                 :            :   [PA_SAMPLE_S32LE]     = (pa_calc_volume_func_t) calc_linear_integer_volume,
     706                 :            :   [PA_SAMPLE_S32BE]     = (pa_calc_volume_func_t) calc_linear_integer_volume,
     707                 :            :   [PA_SAMPLE_S24LE]     = (pa_calc_volume_func_t) calc_linear_integer_volume,
     708                 :            :   [PA_SAMPLE_S24BE]     = (pa_calc_volume_func_t) calc_linear_integer_volume,
     709                 :            :   [PA_SAMPLE_S24_32LE]  = (pa_calc_volume_func_t) calc_linear_integer_volume,
     710                 :            :   [PA_SAMPLE_S24_32BE]  = (pa_calc_volume_func_t) calc_linear_integer_volume
     711                 :            : };
     712                 :            : 
     713                 :         13 : void pa_volume_memchunk(
     714                 :            :         pa_memchunk*c,
     715                 :            :         const pa_sample_spec *spec,
     716                 :            :         const pa_cvolume *volume) {
     717                 :            : 
     718                 :            :     void *ptr;
     719                 :            :     volume_val linear[PA_CHANNELS_MAX + VOLUME_PADDING];
     720                 :            :     pa_do_volume_func_t do_volume;
     721                 :            : 
     722         [ -  + ]:         13 :     pa_assert(c);
     723         [ -  + ]:         13 :     pa_assert(spec);
     724         [ -  + ]:         13 :     pa_assert(pa_sample_spec_valid(spec));
     725         [ -  + ]:         13 :     pa_assert(pa_frame_aligned(c->length, spec));
     726         [ -  + ]:         13 :     pa_assert(volume);
     727                 :            : 
     728         [ +  - ]:         13 :     if (pa_memblock_is_silence(c->memblock))
     729                 :            :         return;
     730                 :            : 
     731         [ +  - ]:         13 :     if (pa_cvolume_channels_equal_to(volume, PA_VOLUME_NORM))
     732                 :            :         return;
     733                 :            : 
     734         [ -  + ]:         13 :     if (pa_cvolume_channels_equal_to(volume, PA_VOLUME_MUTED)) {
     735                 :          0 :         pa_silence_memchunk(c, spec);
     736                 :          0 :         return;
     737                 :            :     }
     738                 :            : 
     739                 :         13 :     do_volume = pa_get_volume_func(spec->format);
     740         [ -  + ]:         13 :     pa_assert(do_volume);
     741                 :            : 
     742                 :         13 :     calc_volume_table[spec->format] ((void *)linear, volume);
     743                 :            : 
     744                 :         13 :     ptr = (uint8_t*) pa_memblock_acquire(c->memblock) + c->index;
     745                 :            : 
     746                 :         13 :     do_volume (ptr, (void *)linear, spec->channels, c->length);
     747                 :            : 
     748                 :         13 :     pa_memblock_release(c->memblock);
     749                 :            : }
     750                 :            : 
     751                 :          0 : size_t pa_frame_align(size_t l, const pa_sample_spec *ss) {
     752                 :            :     size_t fs;
     753                 :            : 
     754         [ #  # ]:          0 :     pa_assert(ss);
     755                 :            : 
     756                 :          0 :     fs = pa_frame_size(ss);
     757                 :            : 
     758                 :          0 :     return (l/fs) * fs;
     759                 :            : }
     760                 :            : 
     761                 :         13 : pa_bool_t pa_frame_aligned(size_t l, const pa_sample_spec *ss) {
     762                 :            :     size_t fs;
     763                 :            : 
     764         [ -  + ]:         13 :     pa_assert(ss);
     765                 :            : 
     766                 :         13 :     fs = pa_frame_size(ss);
     767                 :            : 
     768                 :         13 :     return l % fs == 0;
     769                 :            : }
     770                 :            : 
     771                 :          0 : void pa_interleave(const void *src[], unsigned channels, void *dst, size_t ss, unsigned n) {
     772                 :            :     unsigned c;
     773                 :            :     size_t fs;
     774                 :            : 
     775         [ #  # ]:          0 :     pa_assert(src);
     776         [ #  # ]:          0 :     pa_assert(channels > 0);
     777         [ #  # ]:          0 :     pa_assert(dst);
     778         [ #  # ]:          0 :     pa_assert(ss > 0);
     779         [ #  # ]:          0 :     pa_assert(n > 0);
     780                 :            : 
     781                 :          0 :     fs = ss * channels;
     782                 :            : 
     783         [ #  # ]:          0 :     for (c = 0; c < channels; c++) {
     784                 :            :         unsigned j;
     785                 :            :         void *d;
     786                 :            :         const void *s;
     787                 :            : 
     788                 :          0 :         s = src[c];
     789                 :          0 :         d = (uint8_t*) dst + c * ss;
     790                 :            : 
     791         [ #  # ]:          0 :         for (j = 0; j < n; j ++) {
     792                 :          0 :             memcpy(d, s, (int) ss);
     793                 :          0 :             s = (uint8_t*) s + ss;
     794                 :          0 :             d = (uint8_t*) d + fs;
     795                 :            :         }
     796                 :            :     }
     797                 :          0 : }
     798                 :            : 
     799                 :          0 : void pa_deinterleave(const void *src, void *dst[], unsigned channels, size_t ss, unsigned n) {
     800                 :            :     size_t fs;
     801                 :            :     unsigned c;
     802                 :            : 
     803         [ #  # ]:          0 :     pa_assert(src);
     804         [ #  # ]:          0 :     pa_assert(dst);
     805         [ #  # ]:          0 :     pa_assert(channels > 0);
     806         [ #  # ]:          0 :     pa_assert(ss > 0);
     807         [ #  # ]:          0 :     pa_assert(n > 0);
     808                 :            : 
     809                 :          0 :     fs = ss * channels;
     810                 :            : 
     811         [ #  # ]:          0 :     for (c = 0; c < channels; c++) {
     812                 :            :         unsigned j;
     813                 :            :         const void *s;
     814                 :            :         void *d;
     815                 :            : 
     816                 :          0 :         s = (uint8_t*) src + c * ss;
     817                 :          0 :         d = dst[c];
     818                 :            : 
     819         [ #  # ]:          0 :         for (j = 0; j < n; j ++) {
     820                 :          0 :             memcpy(d, s, (int) ss);
     821                 :          0 :             s = (uint8_t*) s + fs;
     822                 :          0 :             d = (uint8_t*) d + ss;
     823                 :            :         }
     824                 :            :     }
     825                 :          0 : }
     826                 :            : 
     827                 :          0 : static pa_memblock *silence_memblock_new(pa_mempool *pool, uint8_t c) {
     828                 :            :     pa_memblock *b;
     829                 :            :     size_t length;
     830                 :            :     void *data;
     831                 :            : 
     832         [ #  # ]:          0 :     pa_assert(pool);
     833                 :            : 
     834                 :          0 :     length = PA_MIN(pa_mempool_block_size_max(pool), PA_SILENCE_MAX);
     835                 :            : 
     836                 :          0 :     b = pa_memblock_new(pool, length);
     837                 :            : 
     838                 :          0 :     data = pa_memblock_acquire(b);
     839                 :          0 :     memset(data, c, length);
     840                 :          0 :     pa_memblock_release(b);
     841                 :            : 
     842                 :          0 :     pa_memblock_set_is_silence(b, TRUE);
     843                 :            : 
     844                 :          0 :     return b;
     845                 :            : }
     846                 :            : 
     847                 :          0 : void pa_silence_cache_init(pa_silence_cache *cache) {
     848         [ #  # ]:          0 :     pa_assert(cache);
     849                 :            : 
     850                 :            :     memset(cache, 0, sizeof(pa_silence_cache));
     851                 :          0 : }
     852                 :            : 
     853                 :          0 : void pa_silence_cache_done(pa_silence_cache *cache) {
     854                 :            :     pa_sample_format_t f;
     855         [ #  # ]:          0 :     pa_assert(cache);
     856                 :            : 
     857         [ #  # ]:          0 :     for (f = 0; f < PA_SAMPLE_MAX; f++)
     858         [ #  # ]:          0 :         if (cache->blocks[f])
     859                 :          0 :             pa_memblock_unref(cache->blocks[f]);
     860                 :            : 
     861                 :            :     memset(cache, 0, sizeof(pa_silence_cache));
     862                 :          0 : }
     863                 :            : 
     864                 :          0 : pa_memchunk* pa_silence_memchunk_get(pa_silence_cache *cache, pa_mempool *pool, pa_memchunk* ret, const pa_sample_spec *spec, size_t length) {
     865                 :            :     pa_memblock *b;
     866                 :            :     size_t l;
     867                 :            : 
     868         [ #  # ]:          0 :     pa_assert(cache);
     869         [ #  # ]:          0 :     pa_assert(pa_sample_spec_valid(spec));
     870                 :            : 
     871         [ #  # ]:          0 :     if (!(b = cache->blocks[spec->format]))
     872                 :            : 
     873   [ #  #  #  #  :          0 :         switch (spec->format) {
                      # ]
     874                 :            :             case PA_SAMPLE_U8:
     875                 :          0 :                 cache->blocks[PA_SAMPLE_U8] = b = silence_memblock_new(pool, 0x80);
     876                 :          0 :                 break;
     877                 :            :             case PA_SAMPLE_S16LE:
     878                 :            :             case PA_SAMPLE_S16BE:
     879                 :            :             case PA_SAMPLE_S32LE:
     880                 :            :             case PA_SAMPLE_S32BE:
     881                 :            :             case PA_SAMPLE_S24LE:
     882                 :            :             case PA_SAMPLE_S24BE:
     883                 :            :             case PA_SAMPLE_S24_32LE:
     884                 :            :             case PA_SAMPLE_S24_32BE:
     885                 :            :             case PA_SAMPLE_FLOAT32LE:
     886                 :            :             case PA_SAMPLE_FLOAT32BE:
     887                 :          0 :                 cache->blocks[PA_SAMPLE_S16LE] = b = silence_memblock_new(pool, 0);
     888                 :          0 :                 cache->blocks[PA_SAMPLE_S16BE] = pa_memblock_ref(b);
     889                 :          0 :                 cache->blocks[PA_SAMPLE_S32LE] = pa_memblock_ref(b);
     890                 :          0 :                 cache->blocks[PA_SAMPLE_S32BE] = pa_memblock_ref(b);
     891                 :          0 :                 cache->blocks[PA_SAMPLE_S24LE] = pa_memblock_ref(b);
     892                 :          0 :                 cache->blocks[PA_SAMPLE_S24BE] = pa_memblock_ref(b);
     893                 :          0 :                 cache->blocks[PA_SAMPLE_S24_32LE] = pa_memblock_ref(b);
     894                 :          0 :                 cache->blocks[PA_SAMPLE_S24_32BE] = pa_memblock_ref(b);
     895                 :          0 :                 cache->blocks[PA_SAMPLE_FLOAT32LE] = pa_memblock_ref(b);
     896                 :          0 :                 cache->blocks[PA_SAMPLE_FLOAT32BE] = pa_memblock_ref(b);
     897                 :          0 :                 break;
     898                 :            :             case PA_SAMPLE_ALAW:
     899                 :          0 :                 cache->blocks[PA_SAMPLE_ALAW] = b = silence_memblock_new(pool, 0xd5);
     900                 :          0 :                 break;
     901                 :            :             case PA_SAMPLE_ULAW:
     902                 :          0 :                 cache->blocks[PA_SAMPLE_ULAW] = b = silence_memblock_new(pool, 0xff);
     903                 :          0 :                 break;
     904                 :            :             default:
     905                 :          0 :                 pa_assert_not_reached();
     906                 :            :     }
     907                 :            : 
     908         [ #  # ]:          0 :     pa_assert(b);
     909                 :            : 
     910                 :          0 :     ret->memblock = pa_memblock_ref(b);
     911                 :            : 
     912                 :          0 :     l = pa_memblock_get_length(b);
     913         [ #  # ]:          0 :     if (length > l || length == 0)
     914                 :          0 :         length = l;
     915                 :            : 
     916                 :          0 :     ret->length = pa_frame_align(length, spec);
     917                 :          0 :     ret->index = 0;
     918                 :            : 
     919                 :          0 :     return ret;
     920                 :            : }
     921                 :            : 
     922                 :          0 : void pa_sample_clamp(pa_sample_format_t format, void *dst, size_t dstr, const void *src, size_t sstr, unsigned n) {
     923                 :            :     const float *s;
     924                 :            :     float *d;
     925                 :            : 
     926                 :          0 :     s = src; d = dst;
     927                 :            : 
     928         [ #  # ]:          0 :     if (format == PA_SAMPLE_FLOAT32NE) {
     929         [ #  # ]:          0 :         for (; n > 0; n--) {
     930                 :            :             float f;
     931                 :            : 
     932                 :          0 :             f = *s;
     933 [ #  # ][ #  # ]:          0 :             *d = PA_CLAMP_UNLIKELY(f, -1.0f, 1.0f);
     934                 :            : 
     935                 :          0 :             s = (const float*) ((const uint8_t*) s + sstr);
     936                 :          0 :             d = (float*) ((uint8_t*) d + dstr);
     937                 :            :         }
     938                 :            :     } else {
     939         [ #  # ]:          0 :         pa_assert(format == PA_SAMPLE_FLOAT32RE);
     940                 :            : 
     941         [ #  # ]:          0 :         for (; n > 0; n--) {
     942                 :            :             float f;
     943                 :            : 
     944                 :          0 :             f = PA_FLOAT32_SWAP(*s);
     945 [ #  # ][ #  # ]:          0 :             f = PA_CLAMP_UNLIKELY(f, -1.0f, 1.0f);
     946                 :          0 :             *d = PA_FLOAT32_SWAP(f);
     947                 :            : 
     948                 :          0 :             s = (const float*) ((const uint8_t*) s + sstr);
     949                 :          0 :             d = (float*) ((uint8_t*) d + dstr);
     950                 :            :         }
     951                 :            :     }
     952                 :          0 : }
     953                 :            : 
     954                 :            : /* Similar to pa_bytes_to_usec() but rounds up, not down */
     955                 :            : 
     956                 :          0 : pa_usec_t pa_bytes_to_usec_round_up(uint64_t length, const pa_sample_spec *spec) {
     957                 :            :     size_t fs;
     958                 :            :     pa_usec_t usec;
     959                 :            : 
     960         [ #  # ]:          0 :     pa_assert(spec);
     961                 :            : 
     962                 :          0 :     fs = pa_frame_size(spec);
     963                 :          0 :     length = (length + fs - 1) / fs;
     964                 :            : 
     965                 :          0 :     usec = (pa_usec_t) length * PA_USEC_PER_SEC;
     966                 :            : 
     967                 :          0 :     return (usec + spec->rate - 1) / spec->rate;
     968                 :            : }
     969                 :            : 
     970                 :            : /* Similar to pa_usec_to_bytes() but rounds up, not down */
     971                 :            : 
     972                 :          0 : size_t pa_usec_to_bytes_round_up(pa_usec_t t, const pa_sample_spec *spec) {
     973                 :            :     uint64_t u;
     974         [ #  # ]:          0 :     pa_assert(spec);
     975                 :            : 
     976                 :          0 :     u = (uint64_t) t * (uint64_t) spec->rate;
     977                 :            : 
     978                 :          0 :     u = (u + PA_USEC_PER_SEC - 1) / PA_USEC_PER_SEC;
     979                 :            : 
     980                 :          0 :     u *= pa_frame_size(spec);
     981                 :            : 
     982                 :          0 :     return (size_t) u;
     983                 :            : }
     984                 :            : 
     985                 :          0 : void pa_memchunk_dump_to_file(pa_memchunk *c, const char *fn) {
     986                 :            :     FILE *f;
     987                 :            :     void *p;
     988                 :            : 
     989         [ #  # ]:          0 :     pa_assert(c);
     990         [ #  # ]:          0 :     pa_assert(fn);
     991                 :            : 
     992                 :            :     /* Only for debugging purposes */
     993                 :            : 
     994                 :          0 :     f = pa_fopen_cloexec(fn, "a");
     995                 :            : 
     996         [ #  # ]:          0 :     if (!f) {
     997                 :          0 :         pa_log_warn("Failed to open '%s': %s", fn, pa_cstrerror(errno));
     998                 :          0 :         return;
     999                 :            :     }
    1000                 :            : 
    1001                 :          0 :     p = pa_memblock_acquire(c->memblock);
    1002                 :            : 
    1003         [ #  # ]:          0 :     if (fwrite((uint8_t*) p + c->index, 1, c->length, f) != c->length)
    1004                 :          0 :         pa_log_warn("Failed to write to '%s': %s", fn, pa_cstrerror(errno));
    1005                 :            : 
    1006                 :          0 :     pa_memblock_release(c->memblock);
    1007                 :            : 
    1008                 :          0 :     fclose(f);
    1009                 :            : }
    1010                 :            : 
    1011                 :            : static void calc_sine(float *f, size_t l, double freq) {
    1012                 :            :     size_t i;
    1013                 :            : 
    1014                 :          0 :     l /= sizeof(float);
    1015                 :            : 
    1016         [ #  # ]:          0 :     for (i = 0; i < l; i++)
    1017                 :          0 :         *(f++) = (float) 0.5f * sin((double) i*M_PI*2*freq / (double) l);
    1018                 :            : }
    1019                 :            : 
    1020                 :          0 : void pa_memchunk_sine(pa_memchunk *c, pa_mempool *pool, unsigned rate, unsigned freq) {
    1021                 :            :     size_t l;
    1022                 :            :     unsigned gcd, n;
    1023                 :            :     void *p;
    1024                 :            : 
    1025                 :          0 :     pa_memchunk_reset(c);
    1026                 :            : 
    1027                 :          0 :     gcd = pa_gcd(rate, freq);
    1028                 :          0 :     n = rate / gcd;
    1029                 :            : 
    1030                 :          0 :     l = pa_mempool_block_size_max(pool) / sizeof(float);
    1031                 :            : 
    1032                 :          0 :     l /= n;
    1033         [ #  # ]:          0 :     if (l <= 0) l = 1;
    1034                 :          0 :     l *= n;
    1035                 :            : 
    1036                 :          0 :     c->length = l * sizeof(float);
    1037                 :          0 :     c->memblock = pa_memblock_new(pool, c->length);
    1038                 :            : 
    1039                 :          0 :     p = pa_memblock_acquire(c->memblock);
    1040                 :          0 :     calc_sine(p, c->length, freq * l / rate);
    1041                 :          0 :     pa_memblock_release(c->memblock);
    1042                 :          0 : }
    1043                 :            : 
    1044                 :          0 : size_t pa_convert_size(size_t size, const pa_sample_spec *from, const pa_sample_spec *to) {
    1045                 :            :     pa_usec_t usec;
    1046                 :            : 
    1047         [ #  # ]:          0 :     pa_assert(from);
    1048         [ #  # ]:          0 :     pa_assert(to);
    1049                 :            : 
    1050                 :          0 :     usec = pa_bytes_to_usec_round_up(size, from);
    1051                 :          0 :     return pa_usec_to_bytes_round_up(usec, to);
    1052                 :            : }

Generated by: LCOV version 1.9