Hello, Stephen, thank you; people on HydrogenAudio already helped me to 
properly convert 16 bits FLAC sound data to 32 bits float data; the right way 
is as follows :

FloatFLACDecodingData.LOut[FloatFLACDecodingData.WriteAddress + i] = float ( 
buffer[0][i] ) / 32768.0f;

08.03.2014, 22:47, "Stephen F. Booth" <m...@sbooth.org>:
> On Sat, Mar 8, 2014 at 7:49 AM, Каримов Родион <rodionkari...@yandex.ru> 
> wrote:
>> I create FLAC file decoding, processing and playing program and have the 
>> following question : how to convert FLAC 16 bit file data to 32 bit float 
>> buffer for CPU processing? I've already inplemented sound playing and tested 
>> it with sine wave - it works without problems; I even made writing into 
>> decoding buffer values of sine wave, instead of decoded FLAC file data, and 
>> it also works without problems; now I try different approaches to convert 
>> FLAC 16 bits sound data to 32 bits float CPU buffer, but they give noise or 
>> sound with artefacts. I use Stream Decoder from FLAC C API and my 
>> write_callback is as follows :
>
> I've used code like the following to convert decoded FLAC to normalized 
> floating point audio in the interval [-1,1):
>
> float scaleFactor = (1L << ((((frame->header.bits_per_sample + 7) / 8) * 8) - 
> 1));
>
> for(unsigned channel = 0; channel < frame->header.channels; ++channel) {
>
> float *floatBuffer = /* target output channel buffer from somewhere */
> for(unsigned sample = 0; sample < frame->header.blocksize; ++sample)
> *floatBuffer++ = buffer[channel][sample] / scaleFactor;
> }
>
> If you don't want to normalize the audio you can just remove the division.  
> You're obviously on Windows but on Mac OS X this can be done efficiently 
> using the Accelerate framework's vDSP_vflt16() and vDSP_vsdiv().  I'm sure 
> there are comparable routines you could use if the above method is too slow.
>
> Stephen
>
>> FLAC__StreamDecoderWriteStatus write_callback ( const FLAC__StreamDecoder 
>> *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void 
>> * client_data ) {
>>   size_t                                i;
>>
>>   BYTE *                                ChannelDataBuffer;
>>   WORD *                                WORDChannelDataBuffer;
>>   DWORD *                               DWORDChannelDataBuffer;
>>   int *                                 IntChannelDataBuffer;
>>
>>   if ( bps == 16 ) {
>>     ChannelDataBuffer                   = ( BYTE * ) buffer [ 0 ];
>>     WORDChannelDataBuffer               = ( WORD * ) buffer [ 0 ];
>>     DWORDChannelDataBuffer              = ( DWORD * ) buffer [ 0 ];
>>     IntChannelDataBuffer                = ( int * ) buffer [ 0 ];
>>
>>     for ( i = 0; i < frame -> header.blocksize; i++ ) {
>>       //FloatFLACDecodingData.LOut [ FloatFLACDecodingData.WriteAddress + i 
>> ]                         = ( 1.0f + ( float ) sin ( ( ( double ) ( 
>> FloatFLACDecodingData.WriteAddress + i ) / ( double ) TABLE_SIZE ) * M_PI * 
>> 2.0 * 1.0 ) ) * 0.4f;
>>       //FloatFLACDecodingData.LOut [ FloatFLACDecodingData.WriteAddress + i 
>> ]                         = float ( ( FLAC__int16 ) buffer [ 0 ] [ i ] ) * 
>> 65535.0f;
>>       //FloatFLACDecodingData.LOut [ FloatFLACDecodingData.WriteAddress + i 
>> ]                         = ( float ( ( FLAC__int16 ) buffer [ 0 ] [ i ] ) / 
>> 65535.0f - 0.5f ) * 2.0f;
>>       //FloatFLACDecodingData.LOut [ FloatFLACDecodingData.WriteAddress + i 
>> ]                         = ( float ( _byteswap_ushort ( ( FLAC__int16 ) 
>> buffer [ 0 ] [ i ] ) ) / 65535.0f - 0.5f ) * 2.0f;
>>
>>       //FloatFLACDecodingData.LOut [ FloatFLACDecodingData.WriteAddress + i 
>> ]                         = ( float ( WORDChannelDataBuffer [ i ] ) / 
>> 65535.0f - 0.5f ) * 2.0f;
>>       //FloatFLACDecodingData.LOut [ FloatFLACDecodingData.WriteAddress + i 
>> ]                         = ( float ( _byteswap_ushort ( 
>> WORDChannelDataBuffer [ i ] ) ) / 65535.0f - 0.5f ) * 2.0f;
>>       FloatFLACDecodingData.LOut [ FloatFLACDecodingData.WriteAddress + i ]  
>>                        = ( float ( DWORDChannelDataBuffer [ i ] ) / 65535.0f 
>> - 0.5f ) * 2.0f;
>>       //FloatFLACDecodingData.LOut [ FloatFLACDecodingData.WriteAddress + i 
>> ]                         = ( float ( _byteswap_ulong ( 
>> DWORDChannelDataBuffer [ i ] ) ) / 65535.0f - 0.5f ) * 2.0f;
>>
>>       //FloatFLACDecodingData.LOut [ FloatFLACDecodingData.WriteAddress + i 
>> ]                         = ( float ( IntChannelDataBuffer [ i ] ) / 
>> 65535.0f - 0.5f ) * 2.0f;
>>
>>     } //-for
>>
>>     FloatFLACDecodingData.WriteAddress  = FloatFLACDecodingData.WriteAddress 
>> + frame -> header.blocksize;
>>
>>   }
>>
>>   return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
>>
>> }
>>
>> The closes results are with looking on buffer variable as 
>> DWORDChannelDataBuffer ( IntChannelDataBuffer and ( FLAC__int16 ) buffer [ 0 
>> ] [ i ] give the same results ), but this approach anyway gives wrong sound 
>> - it is somehow to sharp and bright with some "hard edges"; other approaches 
>> give very strong noise and some of them give total mess. So, how to convert 
>> FLAC 16 bit data into 32 bits float data for CPU buffer, so that it will 
>> work in C ++ ?
>> _______________________________________________
>> flac-dev mailing list
>> flac-dev@xiph.org
>> http://lists.xiph.org/mailman/listinfo/flac-dev
_______________________________________________
flac-dev mailing list
flac-dev@xiph.org
http://lists.xiph.org/mailman/listinfo/flac-dev

Reply via email to