[pulseaudio-discuss] [PATCH 04/10] remap: Add stereo to mono special case remapping

Tanu Kaskinen tanuk at iki.fi
Mon Apr 1 08:11:52 PDT 2013


On 04/01/2013 03:28 PM, Thomas Martitz wrote:
> Am 01.04.2013 13:13, schrieb Peter Meerwald:
>> Hello Tanu,
>>
>> thanks for reviewing!
>>
>>>>> + case PA_SAMPLE_S16NE:
>>>>> + {
>>>>> + int16_t *d = (int16_t *) dst, *s = (int16_t *) src;
>>>>> +
>>>>> + for (i = n>> 2; i> 0; i--) {
>>>>> + d[0] += (s[0] + s[1])/2;
>>>>> + d[1] += (s[2] + s[3])/2;
>>>>> + d[2] += (s[4] + s[5])/2;
>>>>> + d[3] += (s[6] + s[7])/2;
>>>> You probably meant '=', not '+='?
>>>>
>>>> Also, s[0] + s[1] can overflow, so the inputs should be divided
>>>> individually before summing.
>>> Or the inputs could be cast to uint32_t, which I guess would be better
>>> than dividing multiple times.
>>
>> I think (s[0] + s[1])/2 is correct; at least as long as sizeof(int) >
>> sizeof(short); short gets promoted to int -- see 'integer promotion in
>> C99'; also my compiler thinks above is correct :)
>>
>
>
> Why should int16+int16 be promoted to int32? Pretty sure this code is
> prone to overflow.

I was pretty sure too, until I tried compiling a test program. I think 
this text in the C99 standard[1] (section 6.3.1.1) means that shorts are 
always promoted to ints, even if both operands of a calculation are shorts:

"The following may be used in an expression wherever an int or unsigned 
int may be used:

  - An object or expression with an integer type whose integer 
conversion rank is less than or equal to the rank of int and unsigned int.

  - A bit-field of type _Bool, int, signed int, or unsigned int.

If an int can represent all values of the original type, the value is 
converted to an int; otherwise, it is converted to an unsigned int. 
These are called the integer promotions. All other types are unchanged 
by the integer promotions."

I have trouble understanding that text, but that's the closest thing 
that I found that would explain the observed behavior.

There's also this example in section 5.1.2.3:

"EXAMPLE 2

In executing the fragment

         char c1, c2;
         /* ... */
         c1 = c1 + c2;

the "integer promotions" require that the abstract machine promote the 
value of each variable to int size and then add the two ints and 
truncate the sum. Provided the addition of two chars can be done without 
overflow, or with overflow wrapping silently to produce the correct 
result, the actual execution need only produce the same result, possibly 
omitting the promotions."

[1] http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf

-- 
Tanu


More information about the pulseaudio-discuss mailing list