[alsa-devel] Fwd: [Alsa-devel] Read the input of a soundcard with ALSA
Takashi Iwai
tiwai at suse.de
Tue Apr 24 15:08:23 CEST 2007
At Mon, 23 Apr 2007 16:18:30 +0200,
Nyx wrote:
>
> Hi,
>
> I have some problems to read the input of my soundcard using Alsa and I
> don't really understand how to have access to the input of my soundcard.
> I follow :
> http://www.alsa-project.org/alsa-doc/alsa-lib/_2test_2pcm_8c-example.html
> http://www.alsa-project.org/alsa-doc/alsa-lib/_2test_2latency_8c-example.html
>
>
> # So, in my program, I have created two handles for capture and playback :
> char *device = "hw:0,0";
> snd_output_t *output;
> snd_input_t *input;
> snd_pcm_t *phandle, *chandle;
>
> # then I connect the phandle to the out
> err = snd_output_stdio_attach(&output, stdout, 0);
> if (..)
>
> # Do I have to connect the chandle with the input ?
> # err = snd_input_stdio_attach(&input, stdin, 0);
>
> # I open the access to PCM
> err = snd_pcm_open(&phandle, pdevice, SND_PCM_STREAM_PLAYBACK, 0)
> if (..)
> err = snd_pcm_open(&chandle, pdevice, SND_PCM_STREAM_CAPTURE, 0)
> if(..)
>
> # Hardware and software Parameters
> ## Hardware Parameters
> snd_pcm_hw_params;
> int err;
>
> err = snd_pcm_hw_params_any(phandle, params); if(..);
> err = snd_pcm_hw_params_set_access(phandle,
> params,SND_PCM_ACCESS_RW_INTERLEAVED); if(..);
> err = snd_pcm_hw_params_set_format(phandle, params,SND_PCM_FORMAT_S16);
> if(..);
> err = snd_pcm_hw_params_set_channels(phandle, params, 1); if(..);
> err = snd_pcm_hw_params_set_rate_near(phandle, params, 44100, 0); if(..);
> err = snd_pcm_hw_params_set_buffer_time_near(phandle, params, 500000, &dir);
> if(..);
> err = snd_pcm_hw_params_set_time_near(phandle, params, 100000, &dir),
> if(..);
> err = snd_pcm_hw_params(phandle, params);
>
> ##Software parameters
> err = snd_pcm_sw_params(phandle, params); if(..);
> err = snd_pcm_sw_params_set_start_threshold(phandle, swparams, 0x7fffffff);
> if(..);
> err = snd_pcm_sw_params_set_avail_min(phandle, swparams, 4);
>
> # same configuration for phandle
>
> # Link output to input and start
> err = snd_pcm_link(chandle, phandle); if(..);
> err = snd_pcm_start(chandle); if(..);
>
> #Then I want to read my input
> frames_in = 0;
> in_max = 0;
> latency = 28;
> buffer = malloc((latency_max * snd_pcm_format_width(format) / 8) * 2);
> while (1) {
> r = readbuf(chandle, buffer, latency, &frames_in, &in_max)); if(..);
>
> }
>
> # description of the function
> long readbuf(snd_pcm_t *handle, char *buf, long len, size_t *frames, size_t
> *max)
> {
> long r;
> do {
> r = snd_pcm_readi(handle, buf, len);
> } while (r == -EAGAIN);
>
> if (r > 0) {
> *frames += r;
> if ((long)*max < r)
> *max = r;
> }
> printf ("r = %s, len %li and buf[%d] %f \r", snd_strerror(r), len,i,
> buf[i]);
> return r;
> }
>
> So I compile it and I run it, and I have
> $ read = Broken Pipe, len = 28 and buf[..] = 0.000
>
> Anyone can help me to read the input of my sound card ?
When you link both playback and capture streams and start them at the
same time, then it results in buffer underrun for the playback --
unless you fill the data beforehand. snd_pcm_start() triggers _both_
streams linked together. Hence, a common technique for such
full-duplex streams is to fill empty data to the playback stream
beforehand, then starts.
Takashi
More information about the Alsa-devel
mailing list