[alsa-devel] reading 1 second of audio at a time
Hi,
Am trying to achieve something trivial: reading 1 second of audio at a time, but something goes wrong:
Sound 1277148008.835094 Sound 1277148008.838224 Sound 1277148010.834839 Sound 1277148010.838001 Sound 1277148012.834523 Sound 1277148012.837580 Sound 1277148014.835240 Sound 1277148014.838333
As you can see; audio is returned for 2 seconds, then it sleeps 2 secondsn, then 2 seconds of audio, etc.
What I do is:
if (snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) { }
if (snd_pcm_hw_params_set_format(pcm_handle, hwparams, SND_PCM_FORMAT_S16_LE) < 0) { }
exact_rate = 44100; if (snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &exact_rate, 0) < 0) { error_exit("Error setting rate.\n"); } if (*rate != exact_rate) { fprintf(stderr, "The rate %d Hz is not supported by your hardware.\n ==> Using %d Hz instead.\n", *rate, exact_rate); *rate = exact_rate; }
if (snd_pcm_hw_params_set_channels(pcm_handle, hwparams, 2) < 0) { }
int periods = 2; if (snd_pcm_hw_params_set_periods(pcm_handle, hwparams, periods, 0) < 0) { }
if (snd_pcm_hw_params_set_buffer_size(pcm_handle, hwparams, exact_rate * 2 * n_channels) < 0) { }
if (snd_pcm_hw_params(pcm_handle, hwparams) < 0) { }
return pcm_handle; }
void get_audio_1s(snd_pcm_t *pcm_handle, short *buffer, int rate, int channels) { int samples = channels * rate, index = 0;
while(samples > 0) { int cur = samples, pcmreturn;
while ((pcmreturn = snd_pcm_readi(pcm_handle, &buffer[index], cur)) < 0) { snd_pcm_prepare(pcm_handle); printf(" underrun\n"); }
index += pcmreturn; samples -= pcmreturn; } }
So I call this get_audio_1s() with the samplerate (44100) and the number of channels (2). Then it seems to return the first second at once, then the second second of audio too, then sleeps for 2 seconds(!) and then repeats.
Folkert van Heusden
2010/6/22 folkert folkert@vanheusden.com
Hi,
Am trying to achieve something trivial: reading 1 second of audio at a time, but something goes wrong:
Sound 1277148008.835094 Sound 1277148008.838224 Sound 1277148010.834839 Sound 1277148010.838001 Sound 1277148012.834523 Sound 1277148012.837580 Sound 1277148014.835240 Sound 1277148014.838333
As you can see; audio is returned for 2 seconds, then it sleeps 2 secondsn, then 2 seconds of audio, etc.
What I do is:
if (snd_pcm_hw_params_set_access(pcm_handle, hwparams,
SND_PCM_ACCESS_RW_INTERLEAVED) < 0) { }
if (snd_pcm_hw_params_set_format(pcm_handle, hwparams,
SND_PCM_FORMAT_S16_LE) < 0) { }
exact_rate = 44100; if (snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams,
&exact_rate, 0) < 0) { error_exit("Error setting rate.\n"); } if (*rate != exact_rate) { fprintf(stderr, "The rate %d Hz is not supported by your hardware.\n ==> Using %d Hz instead.\n", *rate, exact_rate); *rate = exact_rate; }
if (snd_pcm_hw_params_set_channels(pcm_handle, hwparams, 2) < 0) { } int periods = 2; if (snd_pcm_hw_params_set_periods(pcm_handle, hwparams, periods, 0)
< 0) { }
if (snd_pcm_hw_params_set_buffer_size(pcm_handle, hwparams,
exact_rate * 2 * n_channels) < 0) { }
buffer_size is actually no of samples , exact_rate*2*n_channels seem to be buffer_bytes
Have you checked whether hardware driver support exactly 1 second buffer ?
since the most common HDA , you cannot get exactlyy 1 second buffer because period_size is multiple of 128 bytes
if (snd_pcm_hw_params(pcm_handle, hwparams) < 0) { } return pcm_handle;
}
void get_audio_1s(snd_pcm_t *pcm_handle, short *buffer, int rate, int channels) { int samples = channels * rate, index = 0;
while(samples > 0) { int cur = samples, pcmreturn; while ((pcmreturn = snd_pcm_readi(pcm_handle,
&buffer[index], cur)) < 0) { snd_pcm_prepare(pcm_handle); printf(" underrun\n"); }
index += pcmreturn; samples -= pcmreturn; }
}
So I call this get_audio_1s() with the samplerate (44100) and the number of channels (2). Then it seems to return the first second at once, then the second second of audio too, then sleeps for 2 seconds(!) and then repeats.
Folkert van Heusden
-- Ever wonder what is out there? Any alien races? Then please support the seti@home project: setiathome.ssl.berkeley.edu
Phone: +31-6-41278122, PGP-key: 1F28D8AE, www.vanheusden.com _______________________________________________ Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
On Tue, Jun 22, 2010 at 4:26 AM, folkert folkert@vanheusden.com wrote:
Hi,
Am trying to achieve something trivial: reading 1 second of audio at a time, but something goes wrong:
Sound 1277148008.835094 Sound 1277148008.838224 Sound 1277148010.834839 Sound 1277148010.838001 Sound 1277148012.834523 Sound 1277148012.837580 Sound 1277148014.835240 Sound 1277148014.838333
As you can see; audio is returned for 2 seconds, then it sleeps 2 secondsn, then 2 seconds of audio, etc.
That is 'normal' behavior, even though a bit odd (described in the changelog of the attempted patches)
I submitted patches to make such blocking read/write calls return as expected, but since they change the semantics of read/write they were not accepted http://mailman.alsa-project.org/pipermail/alsa-devel/2009-December/023986.ht... http://mailman.alsa-project.org/pipermail/alsa-devel/2009-December/023985.ht...
So, you have to write your application around this behavior.
participants (3)
-
folkert
-
Jassi Brar
-
Raymond Yau