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