Re: [alsa-devel] pcm_rate API question
From: Rob Sykes aquegg@yahoo.co.uk To: "alsa-devel@alsa-project.org" alsa-devel@alsa-project.org Sent: Friday, 27 September 2013, 16:28 Subject: Re: [alsa-devel] pcm_rate API question
From: Clemens Ladisch clemens@ladisch.de To: Rob Sykes aquegg@yahoo.co.uk; "alsa-devel@alsa-project.org" alsa-devel@alsa-project.org Cc: Sent: Friday, 27 September 2013, 13:38 Subject: Re: [alsa-devel] pcm_rate API question
Rob Sykes wrote:
void
(*convert_s16)(void *obj, int16_t *dst, unsigned int
dst_frames,
const int16_t *src, unsigned int src_frames);
is the plugin obliged always to consume src_frames and generate dst_frames
samples?
Yes. src_frames and dst_frames are the period sizes of the respective devices; their values will never change, and they define the actual conversion ratio.
Thanks, Clemens. Typically there is some buffering/delay within a resampler -- how does the pcm_rate API allow for this? E.g. from the libsamplerate FAQ:
Q6 : I'm use the SRC_SINC_* converters and up-sampling by a ratio of 2. I reset the converter and put in 1000 samples and I expect to get 2000 samples out, but I'm getting less than that. Why? The short answer is that there is a transport delay inside the converter itself. Long answer follows. By way of example, the first time you call src_process() you might only get 1900 samples out. However, after that first call all subsequent calls will probably get you about 2000 samples out for every 1000 samples you put in.
Also, just noticed that when performing a rate conversion from 44100 -> 48000, the buffer sizes used by alsa are 5512 and 6000, however the actual ratio for the required conversion is 5512.5 to 6000.
If, as you say above, the buffer sizes define the conversion ratio, then this seems to imply that alsa is unable to perform accurate rate conversion for one of the most common uses! — am I missing something here? A pointer to the API documentation, or perhaps some relevant threads, would be very useful.
Cheers, Rob
Rob Sykes wrote:
Typically there is some buffering/delay within a resampler -- how does the pcm_rate API allow for this?
The API itself does not allow for this. Your code must generate dst_frames samples.
At startup, prefix the output with zero samples. For example, rate_samplerate.c in the alsa-plugins package does this:
src_short_to_float_array(src, rate->src_buf, src_frames * rate->channels); src_process(rate->state, &rate->data); if (rate->data.output_frames_gen < dst_frames) ofs = dst_frames - rate->data.output_frames_gen; else ofs = 0; src_float_to_short_array(rate->dst_buf, dst + ofs * rate->channels, rate->data.output_frames_gen * rate->channels);
If, as you say above, the buffer sizes
the period sizes
define the conversion ratio, then this seems to imply that alsa is unable to perform accurate rate conversion for one of the most common uses!
The conversion indeed is not accurate, unless you are using a period size of an integer multiple of 441 frames. In your example, the application probably used a buffer of 0.5 s and four periods per buffer; it should either double the buffer size or halve the number of periods.
Regards, Clemens
----- Original Message -----
From: Clemens Ladisch clemens@ladisch.de To: alsa-devel@alsa-project.org Cc: Sent: Monday, 30 September 2013, 9:59 Subject: Re: [alsa-devel] pcm_rate API question
Typically there is some buffering/delay within a resampler -- how does the pcm_rate API allow for this?
The API itself does not allow for this. Your code must generate dst_frames samples.
At startup, prefix the output with zero samples. For example,
Thanks Clemens. Having to prefix the output with a signal that is unrelated to the input signal doesn't seem great, though I guess this just manifests itself as a delay (variable, dependent on resampler, etc.) and may go unnoticed. Of more concern is that this situation can apparently occur at any time: "after that first call all subsequent calls will probably get you about 2000 samples out for every 1000 samples you put in" — only "probably", not "always"; occurring after the start, this will likely cause audible distortion.
The conversion indeed is not accurate, unless you are using a period size of an integer multiple of 441 frames. In your example, the application probably used a buffer of 0.5 s and four periods per buffer; it should either double the buffer size or halve the number of periods.
Oh okay, the application in question was aplay 1.0.25; maybe it's since been fixed, but no matter, it seems that the above buffering issue is the main problem.
Cheers, Rob
Rob Sykes wrote:
Typically there is some buffering/delay within a resampler -- how does the pcm_rate API allow for this?
The API itself does not allow for this. Your code must generate dst_frames samples.
At startup, prefix the output with zero samples.
this situation can apparently occur at any time: "after that first call all subsequent calls will probably get you about 2000 samples out for every 1000 samples you put in" — only "probably", not "always"; occurring after the start, this will likely cause audible distortion.
You must know your resampling algorithm. If it introduces delays, you need to buffer more samples.
Regards, Clemens
participants (2)
-
Clemens Ladisch
-
Rob Sykes