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.htm...
# 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