[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