From: Pavel H. <pav...@iv...> - 2012-03-14 13:38:36
|
Dne 14.3.2012 11:03, Johannes Freyberger napsal(a): > Hi Pavel, > > I'm using the effect the way you'd like to do and it seems to work correct, > however I was already told this is not the recommended way. Nevertheless > I'll try to put my idea into a few lines (just to give an idea not for > copy/past ;-)): > > // first find, create and init the effect > > sox_init(); > pSoxEffectHandler = sox_find_effect( Name ); // find handler, Name is "rate" > for a SRC > > // check, whether it's a multichannel effect > > if ( ( m_pSoxEffectHandler->flags & SOX_EFF_MCHAN ) == SOX_EFF_MCHAN ) > pSoxEffect[0] = sox_create_effect( pSoxEffectHandler ); // > instantiate on effect for all channels > else // effect needs one instance per channel > { > for each channel > pSoxEffect[c] = sox_create_effect( pSoxEffectHandler ); // > instantiate one effect per channel > } > > // for each instance set options > > for each channel > { > int NbOptions = 3; > Options[ 0 ] = "-b 90"; > Options[ 1 ] = "-a"; > Options[ 2 ] = "48000"; // destination samplerate > sox_effect_options( pSoxEffect[c], NbOptions, Options ); // pass options > to effect > > pSoxEffect[c]->in_signal.rate = SampleRateIn; > pSoxEffect[c]->in_signal.channels = NbChannelsIn; // or 1 if it's one > instance per channel > } > > // start effect > for each channel > pSoxEffectHandler->start( pSoxEffect[c] ); > > // then during processing > for each channel > pSoxEffectHandler->flow( pSoxEffect[c], pInputBuffer[c], pOutputBuffer[c], > &InputSamplesRead[c], &OutputSamples[c] ) > > // at the end of processing > for each channel > pSoxEffectHandler->drain( pSoxEffect[c], pOutputBuffer[c], > &DrainSamples[c] ) > > // stop effect > for each channel > pSoxEffectHandler->stop( pSoxEffect[c] ); > > So if you have a stereo data on a non multichannel effect you'll need two > effect instances and each instance receives only the samples for one > channel. As far as I could see the channels should not go out of sync, which > means if they're using equal settings they will/should return the same > number of samples. > > If you provide float samples to the effect you'll need to call the macros > SOX_FLOAT_32BIT_TO_SAMPLE() and SOX_SAMPLE_TO_FLOAT_32BIT() before sending > and after receiving samples. There are also macros like this for other > formats (16 bit etc.). > > Hope this helps, > Johannes Johannes, thanks a lot, I very appreciate the details of your solution. How do you handle interleaved inputs/outputs? Do you split the input buffers into arrays of single-channel ones for non-MCHAN effects? Do you think I could chain multiple effects, such as rate + dither? Rate is an effect which combines many historical input samples (convolution). Will your implementation preserve the "status information" within the effect between subsequent calls of the flow method followed by draining to avoid splitting the stream into many small "independent chunks" which would lead to low-quality resampling (i.e. starting the resampling algorithm over and over again from zero)? I thought that by using the input/output effects with proper input encodings/signals I could avoid the format conversion since it would be handled by the input/output effects themselves. But actually the conversion is simple, using the macros you mentioned. Thanks a lot for your help. Pavel. |