[alsa-devel] capturing data from the microphone
[the same message is waiting in moderator queue, sorry if you receive it two times]
Hello,
i'm trying to capture audio data from the microphone, but i'm not able to read any frames. The frames are always 0 and delay is fixed to 2730. I've tried calling snd_pcm_avail_delay, snd_pcm_avail_update but does not make a difference. The soundcard is driven by snd_hda_intel. The code is more or less the same as Paul Davis' tutorial on using the alsa api.
This is the code for init and the loop that tries to read the data:
#define MIC_BUFSIZE 4096
static gpointer snd_pcm_read(gpointer data) { int error; snd_pcm_sframes_t frames = MIC_BUFSIZE;
while (TRUE) {
if ((error = snd_pcm_wait (pcm_handle, 1000)) < 0) { g_printerr("Failed to poll: %s\n", snd_strerror(error)); continue; }
if ((error = snd_pcm_avail(pcm_handle)) < 0) { if (error == -EPIPE) { g_printerr("xrun! %s\n", snd_strerror(error)); continue; //return GINT_TO_POINTER(FALSE); } else { g_printerr("alsa_pcm_avail_update error %s\n", snd_strerror(error)); continue; //return GINT_TO_POINTER(FALSE); } }
frames = error; if (frames == 0) continue;
frames = frames > MIC_BUFSIZE ? MIC_BUFSIZE : frames; g_printerr ("frames: %ld\n", frames); g_static_mutex_lock(&mutex); error = snd_pcm_readi(pcm_handle, Mic_Buffer[Mic_WriteBuf], frames); g_static_mutex_unlock(&mutex); if (error < 0) error = snd_pcm_recover(pcm_handle, error, 0); if (error < 0) { LOG("snd_pcm_readi FAIL!: %s\n", snd_strerror(error)); } }
return GINT_TO_POINTER(TRUE); }
BOOL Mic_Init() { snd_pcm_hw_params_t *hwparams; snd_pcm_sw_params_t *swparams; int err;
if (Mic_Inited) return TRUE;
// Open the default sound card in capture if ((err = snd_pcm_open(&pcm_handle, "default", SND_PCM_STREAM_CAPTURE, /*SND_PCM_NONBLOCK*/ 0)) < 0) { g_printerr("Failed to open device: %s\n", snd_strerror(err)); return FALSE; }
// Allocate the snd_pcm_hw_params_t structure and fill it. snd_pcm_hw_params_alloca(&hwparams); if ((err = snd_pcm_hw_params_any(pcm_handle, hwparams)) < 0) { g_printerr("Failed to setup hw parameters: %s\n", snd_strerror(err)); return FALSE; }
//Set the access if ((err = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { g_printerr("Failed to set access: %s\n", snd_strerror(err)); return FALSE; }
//dir 0 == exacte (Rate = 16K exacte) if ((err = snd_pcm_hw_params_set_rate(pcm_handle, hwparams, 16000, 0)) < 0) { g_printerr("Failed to set rate: %s\n", snd_strerror(err)); return FALSE; }
/* Set sample format */ if ((err = snd_pcm_hw_params_set_format(pcm_handle, hwparams, SND_PCM_FORMAT_S8)) < 0) { g_printerr("Failed to set format: %s\n", snd_strerror(err)); return FALSE; }
// Set one channel (mono) if ((err = snd_pcm_hw_params_set_channels(pcm_handle, hwparams, 1)) < 0) { g_printerr("Failed to set channels: %s\n", snd_strerror(err)); return FALSE; }
//Set the params if ((err = snd_pcm_hw_params(pcm_handle, hwparams)) < 0) { g_printerr("Failed to set hw parameters: %s\n", snd_strerror(err)); return FALSE; }
snd_pcm_sw_params_alloca(&swparams); if ((err = snd_pcm_sw_params_current (pcm_handle, swparams)) < 0) { g_printerr("Failed to set current sw parameters: %s\n", snd_strerror(err)); return FALSE; }
if ((err = snd_pcm_sw_params_set_avail_min (pcm_handle, swparams, MIC_BUFSIZE)) < 0) { g_printerr("Failed to set minimum available count: %s\n", snd_strerror(err)); return FALSE; }
if ((err = snd_pcm_sw_params_set_start_threshold (pcm_handle, swparams, 0U)) < 0) { g_printerr("Failed to set start mode: %s\n", snd_strerror(err)); return FALSE; }
if ((err = snd_pcm_sw_params (pcm_handle, swparams)) < 0) { g_printerr("Failed to set sw parameters: %s\n", snd_strerror(err)); return FALSE; }
if ((err = snd_pcm_prepare (pcm_handle)) < 0) { g_printerr("Failed to prepare audio interface to use: %s\n", snd_strerror(err)); return FALSE; }
Mic_Inited = TRUE; Mic_Reset();
mic_reader = g_thread_create(snd_pcm_read, NULL, TRUE, NULL);
return TRUE; }
thanks, Riccardo
Hi,
I have the same kind of problem. I try to capture PCM stream thanks to areacord : # arecord -c 1 -t wav -f S16_LE -r 8000 -d 10 input.wav
30 seconds later I have the folowing message : # arecord: pcm_read:1629: read error: Input/output error
I can observe the PCM stream on an oscilloscope but no interrupt are catched by the system (AIC ss0 counter remains at zero ) : # cat /proc/interrupts CPU0 1: 275059 AIC at91_tick, rtc0, ttyS0 7: 179 AIC ttyS2 9: 11 AIC mmc0 13: 0 AIC atmel_spi.1 14: 0 AIC ssc0 82: 1 GPIO alerte 107: 9464 GPIO eth0
Any idea?
Riccardo Magliocchetti wrote:
[the same message is waiting in moderator queue, sorry if you receive it two times]
Hello,
i'm trying to capture audio data from the microphone, but i'm not able to read any frames. The frames are always 0 and delay is fixed to 2730. I've tried calling snd_pcm_avail_delay, snd_pcm_avail_update but does not make a difference. The soundcard is driven by snd_hda_intel. The code is more or less the same as Paul Davis' tutorial on using the alsa api.
This is the code for init and the loop that tries to read the data:
#define MIC_BUFSIZE 4096
static gpointer snd_pcm_read(gpointer data) { int error; snd_pcm_sframes_t frames = MIC_BUFSIZE;
while (TRUE) {
if ((error = snd_pcm_wait (pcm_handle, 1000)) < 0) { g_printerr("Failed to poll: %s\n", snd_strerror(error)); continue; } if ((error = snd_pcm_avail(pcm_handle)) < 0) { if (error == -EPIPE) { g_printerr("xrun! %s\n", snd_strerror(error)); continue; //return GINT_TO_POINTER(FALSE); } else { g_printerr("alsa_pcm_avail_update error %s\n", snd_strerror(error)); continue; //return GINT_TO_POINTER(FALSE); } } frames = error; if (frames == 0) continue; frames = frames > MIC_BUFSIZE ? MIC_BUFSIZE : frames; g_printerr ("frames: %ld\n", frames); g_static_mutex_lock(&mutex); error = snd_pcm_readi(pcm_handle, Mic_Buffer[Mic_WriteBuf], frames); g_static_mutex_unlock(&mutex); if (error < 0) error = snd_pcm_recover(pcm_handle, error, 0); if (error < 0) { LOG("snd_pcm_readi FAIL!: %s\n", snd_strerror(error)); }
}
return GINT_TO_POINTER(TRUE); }
BOOL Mic_Init() { snd_pcm_hw_params_t *hwparams; snd_pcm_sw_params_t *swparams; int err;
if (Mic_Inited) return TRUE; // Open the default sound card in capture if ((err = snd_pcm_open(&pcm_handle, "default", SND_PCM_STREAM_CAPTURE,
/*SND_PCM_NONBLOCK*/ 0)) < 0) { g_printerr("Failed to open device: %s\n", snd_strerror(err)); return FALSE; }
// Allocate the snd_pcm_hw_params_t structure and fill it. snd_pcm_hw_params_alloca(&hwparams); if ((err = snd_pcm_hw_params_any(pcm_handle, hwparams)) < 0) { g_printerr("Failed to setup hw parameters: %s\n", snd_strerror(err)); return FALSE; } //Set the access if ((err = snd_pcm_hw_params_set_access(pcm_handle, hwparams,
SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { g_printerr("Failed to set access: %s\n", snd_strerror(err)); return FALSE; }
//dir 0 == exacte (Rate = 16K exacte) if ((err = snd_pcm_hw_params_set_rate(pcm_handle, hwparams, 16000, 0)) < 0) { g_printerr("Failed to set rate: %s\n", snd_strerror(err)); return FALSE; } /* Set sample format */ if ((err = snd_pcm_hw_params_set_format(pcm_handle, hwparams, SND_PCM_FORMAT_S8)) < 0) { g_printerr("Failed to set format: %s\n", snd_strerror(err)); return FALSE; } // Set one channel (mono) if ((err = snd_pcm_hw_params_set_channels(pcm_handle, hwparams, 1)) < 0) { g_printerr("Failed to set channels: %s\n", snd_strerror(err)); return FALSE; } //Set the params if ((err = snd_pcm_hw_params(pcm_handle, hwparams)) < 0) { g_printerr("Failed to set hw parameters: %s\n", snd_strerror(err)); return FALSE; } snd_pcm_sw_params_alloca(&swparams); if ((err = snd_pcm_sw_params_current (pcm_handle, swparams)) < 0) { g_printerr("Failed to set current sw parameters: %s\n", snd_strerror(err)); return FALSE; } if ((err = snd_pcm_sw_params_set_avail_min (pcm_handle, swparams, MIC_BUFSIZE)) < 0) { g_printerr("Failed to set minimum available count: %s\n", snd_strerror(err)); return FALSE; } if ((err = snd_pcm_sw_params_set_start_threshold (pcm_handle, swparams, 0U)) < 0) { g_printerr("Failed to set start mode: %s\n", snd_strerror(err)); return FALSE; } if ((err = snd_pcm_sw_params (pcm_handle, swparams)) < 0) { g_printerr("Failed to set sw parameters: %s\n", snd_strerror(err)); return FALSE; } if ((err = snd_pcm_prepare (pcm_handle)) < 0) { g_printerr("Failed to prepare audio interface to use: %s\n", snd_strerror(err)); return FALSE; } Mic_Inited = TRUE; Mic_Reset(); mic_reader = g_thread_create(snd_pcm_read, NULL, TRUE, NULL); return TRUE;
}
thanks, Riccardo
Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
which device are you using ? ( pulseaudio , dmix or default device defined in /usr/share/alsa/cards/*.conf )
post output of
arecord -v -c 1 -t wav -f S16_LE -r 8000 -d 10 input.wav
2010/1/5 Marc Garnier marc.garnier@heig-vd.ch
Hi,
I have the same kind of problem. I try to capture PCM stream thanks to areacord : # arecord -c 1 -t wav -f S16_LE -r 8000 -d 10 input.wav
30 seconds later I have the folowing message : # arecord: pcm_read:1629: read error: Input/output error
I can observe the PCM stream on an oscilloscope but no interrupt are catched by the system (AIC ss0 counter remains at zero ) : # cat /proc/interrupts CPU0 1: 275059 AIC at91_tick, rtc0, ttyS0 7: 179 AIC ttyS2 9: 11 AIC mmc0 13: 0 AIC atmel_spi.1 14: 0 AIC ssc0 82: 1 GPIO alerte 107: 9464 GPIO eth0
Any idea?
Ok, let me go into details. I work on a custom device platform based on an Atmel at91sam9261. I wrote an alsa driver composed of 2 files (sound/soc/atmel/myplateform_q2686.c and sound/soc/codecs/q2686.c) and I also add this line into arch/arm/mach-at91/board-myplateform.c :
at91_add_device_ssc(AT91SAM9261_ID_SSC0, ATMEL_SSC_TX | ATMEL_SSC_RX);
When I boot my device I can see that : Q2686 SoC Audio Codec 0.2 asoc: Q2686 <-> atmel-ssc0 mapping ok ALSA device list: #0: MYPLATFORM (Q2686)
And everything ok with playback : # aplay -c 1 tone.wav
But when I want to record a pcm stream I have this error: # arecord -v -c 1 -t wav -f S16_LE -r 8000 -d 10 input.wav arecord: pcm_read:1629: read error: Input/output error
Any more idea?
Raymond Yau wrote:
which device are you using ? ( pulseaudio , dmix or default device defined in /usr/share/alsa/cards/*.conf )
post output of
arecord -v -c 1 -t wav -f S16_LE -r 8000 -d 10 input.wav
2010/1/5 Marc Garnier marc.garnier@heig-vd.ch
Hi,
I have the same kind of problem. I try to capture PCM stream thanks to areacord : # arecord -c 1 -t wav -f S16_LE -r 8000 -d 10 input.wav
30 seconds later I have the folowing message : # arecord: pcm_read:1629: read error: Input/output error
I can observe the PCM stream on an oscilloscope but no interrupt are catched by the system (AIC ss0 counter remains at zero ) : # cat /proc/interrupts CPU0 1: 275059 AIC at91_tick, rtc0, ttyS0 7: 179 AIC ttyS2 9: 11 AIC mmc0 13: 0 AIC atmel_spi.1 14: 0 AIC ssc0 82: 1 GPIO alerte 107: 9464 GPIO eth0
Any idea?
Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
arecord: pcm_read:1629: read error: Input/output error
This usually mean hardware interrupt did not not occur ( driver bug )
2010/1/6 Marc Garnier marc.garnier@heig-vd.ch
Ok, let me go into details. I work on a custom device platform based on an Atmel at91sam9261. I wrote an alsa driver composed of 2 files (sound/soc/atmel/myplateform_q2686.c and sound/soc/codecs/q2686.c) and I also add this line into arch/arm/mach-at91/board-myplateform.c :
at91_add_device_ssc(AT91SAM9261_ID_SSC0, ATMEL_SSC_TX | ATMEL_SSC_RX);
When I boot my device I can see that : Q2686 SoC Audio Codec 0.2 asoc: Q2686 <-> atmel-ssc0 mapping ok ALSA device list: #0: MYPLATFORM (Q2686)
And everything ok with playback : # aplay -c 1 tone.wav
But when I want to record a pcm stream I have this error: # arecord -v -c 1 -t wav -f S16_LE -r 8000 -d 10 input.wav arecord: pcm_read:1629: read error: Input/output error
Any more idea?
Raymond Yau wrote:
which device are you using ? ( pulseaudio , dmix or default device
defined
in /usr/share/alsa/cards/*.conf )
post output of
arecord -v -c 1 -t wav -f S16_LE -r 8000 -d 10 input.wav
2010/1/5 Marc Garnier marc.garnier@heig-vd.ch
Yep, as I said in previous post, actually no interrupt occur and I wonder why... "AIC ss0" counter remains at zero : # cat /proc/interrupts CPU0 1: 275059 AIC at91_tick, rtc0, ttyS0 7: 179 AIC ttyS2 9: 11 AIC mmc0 13: 0 AIC atmel_spi.1 14: 0 AIC ssc0 82: 1 GPIO alerte 107: 9464 GPIO eth0
My sound divice is very simple, there isn't I2C ou SPI control bus, only PCM. Clock is always provided by this device (SND_SOC_DAIFMT_CBM_CFM). There are my driver files :
sound/soc/atmel/myplateform_q2686.c :
#include ... [....]
#include "../codecs/q2686.h" #include "atmel-pcm.h" #include "atmel_ssc_dai.h"
#define CODEC_CLOCK 12000000
static int provabox_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
int ret;
/* set codec DAI configuration */ ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); if (ret < 0) return ret;
/* set cpu DAI configuration */ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); if (ret < 0) return ret;
return 0; }
static struct snd_soc_ops provabox_ops = { .hw_params = provabox_hw_params, };
/* * Logic for a q2686 as connected on a provabox board. */ static int provabox_q2686_init(struct snd_soc_codec *codec) { printk(KERN_DEBUG "provabox_q2686 " ": provabox_q2686_init() called\n");
return 0; }
static struct snd_soc_dai_link provabox_dai = { .name = "Q2686", .stream_name = "Q2686 PCM", .cpu_dai = &atmel_ssc_dai[0], .codec_dai = &q2686_dai, .init = provabox_q2686_init, .ops = &provabox_ops, };
static struct snd_soc_card snd_soc_provabox = { .name = "PROVABOX", .platform = &atmel_soc_platform, .dai_link = &provabox_dai, .num_links = 1, };
static struct snd_soc_device provabox_snd_devdata = { .card = &snd_soc_provabox, .codec_dev = &soc_codec_dev_q2686, };
static struct platform_device *provabox_snd_device;
static int __init provabox_init(void) { struct atmel_ssc_info *ssc_p = provabox_dai.cpu_dai->private_data; struct ssc_device *ssc = NULL; int ret;
/* * Request SSC device */ ssc = ssc_request(0); if (IS_ERR(ssc)) { printk(KERN_ERR "ASoC: Failed to request SSC 0\n"); ret = PTR_ERR(ssc); ssc = NULL; goto err_ssc; } ssc_p->ssc = ssc;
provabox_snd_device = platform_device_alloc("soc-audio", -1); if (!provabox_snd_device) { printk(KERN_ERR "ASoC: Platform device allocation failed\n"); ret = -ENOMEM; }
platform_set_drvdata(provabox_snd_device, &provabox_snd_devdata); provabox_snd_devdata.dev = &provabox_snd_device->dev;
ret = platform_device_add(provabox_snd_device); if (ret) { printk(KERN_ERR "ASoC: Platform device allocation failed\n"); platform_device_put(provabox_snd_device); }
return ret;
err_ssc: ssc_free(ssc); ssc_p->ssc = NULL; return ret; }
static void __exit provabox_exit(void) { struct atmel_ssc_info *ssc_p = provabox_dai.cpu_dai->private_data; struct ssc_device *ssc;
if (ssc_p != NULL) { ssc = ssc_p->ssc; if (ssc != NULL) ssc_free(ssc); ssc_p->ssc = NULL; }
platform_device_unregister(provabox_snd_device); provabox_snd_device = NULL; }
module_init(provabox_init); module_exit(provabox_exit);
/* Module information */ MODULE_AUTHOR("Marc Garnier"); MODULE_DESCRIPTION("ALSA SoC PROVABOX_Q2686"); MODULE_LICENSE("GPL");
----------------- codec file -----------------
sound/soc/codecs/q2686.c
#include ... [...]
#include "q2686.h"
#define Q2686_VERSION "0.2" #define Q2686_RATES (SNDRV_PCM_RATE_8000_192000) #define Q2686_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
static int q2686_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; int ret = 0; //ret = snd_soc_dai_set_tdm_slot(cpu_dai, ); if (ret < 0) return ret;
return 0; }
static int q2686_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { return 0; }
static int q2686_pcm_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { return 0; }
static int q2686_mute(struct snd_soc_dai *dai, int mute) { return 0; }
static void q2686_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { }
static int q2686_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id, unsigned int freq, int dir) { return 0; }
static struct snd_soc_dai_ops q2686_dai_ops = { .prepare = q2686_pcm_prepare, .hw_params = q2686_hw_params, .shutdown = q2686_shutdown, .digital_mute = q2686_mute, .set_sysclk = q2686_set_dai_sysclk, .set_fmt = q2686_set_dai_fmt, };
static int q2686_soc_probe(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); struct snd_soc_codec *codec; int ret = 0;
printk(KERN_INFO "Q2686 SoC Audio Codec %s\n", Q2686_VERSION);
socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); if (!socdev->card->codec) return -ENOMEM;
codec = socdev->card->codec; mutex_init(&codec->mutex);
codec->name = "Q2686"; codec->owner = THIS_MODULE; codec->dai = &q2686_dai; codec->num_dai = 1; codec->write = NULL; codec->read = NULL; INIT_LIST_HEAD(&codec->dapm_widgets); INIT_LIST_HEAD(&codec->dapm_paths);
/* Register PCMs. */ ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); if (ret < 0) { printk(KERN_ERR "Q2686: failed to create pcms\n"); goto pcm_err; }
/* Register Card. */ ret = snd_soc_init_card(socdev); if (ret < 0) { printk(KERN_ERR "Q2686: failed to register card\n"); goto card_err; }
return ret;
card_err: snd_soc_free_pcms(socdev); pcm_err: kfree(socdev->card->codec);
return ret; }
static int q2686_soc_remove(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); struct snd_soc_codec *codec = socdev->card->codec;
if (!codec) return 0;
snd_soc_free_pcms(socdev); kfree(socdev->card->codec);
return 0; }
struct snd_soc_dai q2686_dai = { .name = "Q2686", .playback = { .stream_name = "Playback", .channels_min = 1, .channels_max = 2, .rates = Q2686_RATES, .formats = Q2686_FORMATS, }, .capture = { .stream_name = "Capture", .channels_min = 1, .channels_max = 2, .rates = Q2686_RATES, .formats = Q2686_FORMATS,}, .ops = &q2686_dai_ops, .symmetric_rates = 1, }; EXPORT_SYMBOL_GPL(q2686_dai);
static int q2686_soc_suspend(struct platform_device *pdev, pm_message_t state) { return 0; }
static int q2686_soc_resume(struct platform_device *pdev) { return 0; }
struct snd_soc_codec_device soc_codec_dev_q2686 = { .probe = q2686_soc_probe, .remove = q2686_soc_remove, .suspend = q2686_soc_suspend, .resume = q2686_soc_resume, }; EXPORT_SYMBOL_GPL(soc_codec_dev_q2686);
static int __init q2686_modinit(void) { return snd_soc_register_dai(&q2686_dai); } module_init(q2686_modinit);
static void __exit q2686_exit(void) { snd_soc_unregister_dai(&q2686_dai); } module_exit(q2686_exit);
MODULE_DESCRIPTION("ASoC Q2686 driver"); MODULE_AUTHOR("Marc Garnier"); MODULE_LICENSE("GPL");
Raymond Yau wrote:
arecord: pcm_read:1629: read error: Input/output error
This usually mean hardware interrupt did not not occur ( driver bug )
2010/1/6 Marc Garnier marc.garnier@heig-vd.ch
Ok, let me go into details. I work on a custom device platform based on an Atmel at91sam9261. I wrote an alsa driver composed of 2 files (sound/soc/atmel/myplateform_q2686.c and sound/soc/codecs/q2686.c) and I also add this line into arch/arm/mach-at91/board-myplateform.c :
at91_add_device_ssc(AT91SAM9261_ID_SSC0, ATMEL_SSC_TX | ATMEL_SSC_RX);
When I boot my device I can see that : Q2686 SoC Audio Codec 0.2 asoc: Q2686 <-> atmel-ssc0 mapping ok ALSA device list: #0: MYPLATFORM (Q2686)
And everything ok with playback : # aplay -c 1 tone.wav
But when I want to record a pcm stream I have this error: # arecord -v -c 1 -t wav -f S16_LE -r 8000 -d 10 input.wav arecord: pcm_read:1629: read error: Input/output error
Any more idea?
Raymond Yau wrote:
which device are you using ? ( pulseaudio , dmix or default device
defined
in /usr/share/alsa/cards/*.conf )
post output of
arecord -v -c 1 -t wav -f S16_LE -r 8000 -d 10 input.wav
2010/1/5 Marc Garnier marc.garnier@heig-vd.ch
Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
You haven't specified the buffer/period size in the hw params. See alsa-lib/test/pcm.c - Pierre
On Mon, Jan 4, 2010 at 11:39 AM, Riccardo Magliocchetti riccardo.magliocchetti@gmail.com wrote:
[the same message is waiting in moderator queue, sorry if you receive it two times]
Hello,
i'm trying to capture audio data from the microphone, but i'm not able to read any frames. The frames are always 0 and delay is fixed to 2730. I've tried calling snd_pcm_avail_delay, snd_pcm_avail_update but does not make a difference. The soundcard is driven by snd_hda_intel. The code is more or less the same as Paul Davis' tutorial on using the alsa api.
This is the code for init and the loop that tries to read the data:
#define MIC_BUFSIZE 4096
static gpointer snd_pcm_read(gpointer data) { int error; snd_pcm_sframes_t frames = MIC_BUFSIZE;
while (TRUE) {
if ((error = snd_pcm_wait (pcm_handle, 1000)) < 0) { g_printerr("Failed to poll: %s\n", snd_strerror(error)); continue; }
if ((error = snd_pcm_avail(pcm_handle)) < 0) { if (error == -EPIPE) { g_printerr("xrun! %s\n", snd_strerror(error)); continue; //return GINT_TO_POINTER(FALSE); } else { g_printerr("alsa_pcm_avail_update error %s\n", snd_strerror(error)); continue; //return GINT_TO_POINTER(FALSE); } }
frames = error; if (frames == 0) continue;
frames = frames > MIC_BUFSIZE ? MIC_BUFSIZE : frames; g_printerr ("frames: %ld\n", frames); g_static_mutex_lock(&mutex); error = snd_pcm_readi(pcm_handle, Mic_Buffer[Mic_WriteBuf], frames); g_static_mutex_unlock(&mutex); if (error < 0) error = snd_pcm_recover(pcm_handle, error, 0); if (error < 0) { LOG("snd_pcm_readi FAIL!: %s\n", snd_strerror(error)); } }
return GINT_TO_POINTER(TRUE); }
BOOL Mic_Init() { snd_pcm_hw_params_t *hwparams; snd_pcm_sw_params_t *swparams; int err;
if (Mic_Inited) return TRUE;
// Open the default sound card in capture if ((err = snd_pcm_open(&pcm_handle, "default", SND_PCM_STREAM_CAPTURE, /*SND_PCM_NONBLOCK*/ 0)) < 0) { g_printerr("Failed to open device: %s\n", snd_strerror(err)); return FALSE; }
// Allocate the snd_pcm_hw_params_t structure and fill it. snd_pcm_hw_params_alloca(&hwparams); if ((err = snd_pcm_hw_params_any(pcm_handle, hwparams)) < 0) { g_printerr("Failed to setup hw parameters: %s\n", snd_strerror(err)); return FALSE; }
//Set the access if ((err = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { g_printerr("Failed to set access: %s\n", snd_strerror(err)); return FALSE; }
//dir 0 == exacte (Rate = 16K exacte) if ((err = snd_pcm_hw_params_set_rate(pcm_handle, hwparams, 16000, 0)) < 0) { g_printerr("Failed to set rate: %s\n", snd_strerror(err)); return FALSE; }
/* Set sample format */ if ((err = snd_pcm_hw_params_set_format(pcm_handle, hwparams, SND_PCM_FORMAT_S8)) < 0) { g_printerr("Failed to set format: %s\n", snd_strerror(err)); return FALSE; }
// Set one channel (mono) if ((err = snd_pcm_hw_params_set_channels(pcm_handle, hwparams, 1)) < 0) { g_printerr("Failed to set channels: %s\n", snd_strerror(err)); return FALSE; }
//Set the params if ((err = snd_pcm_hw_params(pcm_handle, hwparams)) < 0) { g_printerr("Failed to set hw parameters: %s\n", snd_strerror(err)); return FALSE; }
snd_pcm_sw_params_alloca(&swparams); if ((err = snd_pcm_sw_params_current (pcm_handle, swparams)) < 0) { g_printerr("Failed to set current sw parameters: %s\n", snd_strerror(err)); return FALSE; }
if ((err = snd_pcm_sw_params_set_avail_min (pcm_handle, swparams, MIC_BUFSIZE)) < 0) { g_printerr("Failed to set minimum available count: %s\n", snd_strerror(err)); return FALSE; }
if ((err = snd_pcm_sw_params_set_start_threshold (pcm_handle, swparams, 0U)) < 0) { g_printerr("Failed to set start mode: %s\n", snd_strerror(err)); return FALSE; }
if ((err = snd_pcm_sw_params (pcm_handle, swparams)) < 0) { g_printerr("Failed to set sw parameters: %s\n", snd_strerror(err)); return FALSE; }
if ((err = snd_pcm_prepare (pcm_handle)) < 0) { g_printerr("Failed to prepare audio interface to use: %s\n", snd_strerror(err)); return FALSE; }
Mic_Inited = TRUE; Mic_Reset();
mic_reader = g_thread_create(snd_pcm_read, NULL, TRUE, NULL);
return TRUE; }
thanks, Riccardo
Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
Hi Pierre,
pl bossart ha scritto:
You haven't specified the buffer/period size in the hw params. See alsa-lib/test/pcm.c
- Pierre
They fail when opening default device so I had to remove them, work fine when opening plughw:0,0 though.
On Mon, Jan 4, 2010 at 11:39 AM, Riccardo Magliocchetti riccardo.magliocchetti@gmail.com wrote:
[the same message is waiting in moderator queue, sorry if you receive it two times]
Hello,
i'm trying to capture audio data from the microphone, but i'm not able to read any frames. The frames are always 0 and delay is fixed to 2730. I've tried calling snd_pcm_avail_delay, snd_pcm_avail_update but does not make a difference. The soundcard is driven by snd_hda_intel. The code is more or less the same as Paul Davis' tutorial on using the alsa api.
This is the code for init and the loop that tries to read the data:
#define MIC_BUFSIZE 4096
static gpointer snd_pcm_read(gpointer data) { int error; snd_pcm_sframes_t frames = MIC_BUFSIZE;
while (TRUE) {
if ((error = snd_pcm_wait (pcm_handle, 1000)) < 0) { g_printerr("Failed to poll: %s\n", snd_strerror(error)); continue; } if ((error = snd_pcm_avail(pcm_handle)) < 0) { if (error == -EPIPE) { g_printerr("xrun! %s\n", snd_strerror(error)); continue; //return GINT_TO_POINTER(FALSE); } else { g_printerr("alsa_pcm_avail_update error %s\n", snd_strerror(error)); continue; //return GINT_TO_POINTER(FALSE); } } frames = error; if (frames == 0) continue; frames = frames > MIC_BUFSIZE ? MIC_BUFSIZE : frames; g_printerr ("frames: %ld\n", frames); g_static_mutex_lock(&mutex); error = snd_pcm_readi(pcm_handle, Mic_Buffer[Mic_WriteBuf], frames); g_static_mutex_unlock(&mutex); if (error < 0) error = snd_pcm_recover(pcm_handle, error, 0); if (error < 0) { LOG("snd_pcm_readi FAIL!: %s\n", snd_strerror(error)); }
}
return GINT_TO_POINTER(TRUE); }
BOOL Mic_Init() { snd_pcm_hw_params_t *hwparams; snd_pcm_sw_params_t *swparams; int err;
if (Mic_Inited) return TRUE; // Open the default sound card in capture if ((err = snd_pcm_open(&pcm_handle, "default", SND_PCM_STREAM_CAPTURE,
/*SND_PCM_NONBLOCK*/ 0)) < 0) { g_printerr("Failed to open device: %s\n", snd_strerror(err)); return FALSE; }
// Allocate the snd_pcm_hw_params_t structure and fill it. snd_pcm_hw_params_alloca(&hwparams); if ((err = snd_pcm_hw_params_any(pcm_handle, hwparams)) < 0) { g_printerr("Failed to setup hw parameters: %s\n", snd_strerror(err)); return FALSE; } //Set the access if ((err = snd_pcm_hw_params_set_access(pcm_handle, hwparams,
SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { g_printerr("Failed to set access: %s\n", snd_strerror(err)); return FALSE; }
//dir 0 == exacte (Rate = 16K exacte) if ((err = snd_pcm_hw_params_set_rate(pcm_handle, hwparams, 16000, 0)) < 0) { g_printerr("Failed to set rate: %s\n", snd_strerror(err)); return FALSE; } /* Set sample format */ if ((err = snd_pcm_hw_params_set_format(pcm_handle, hwparams, SND_PCM_FORMAT_S8)) < 0) { g_printerr("Failed to set format: %s\n", snd_strerror(err)); return FALSE; } // Set one channel (mono) if ((err = snd_pcm_hw_params_set_channels(pcm_handle, hwparams, 1)) < 0) { g_printerr("Failed to set channels: %s\n", snd_strerror(err)); return FALSE; } //Set the params if ((err = snd_pcm_hw_params(pcm_handle, hwparams)) < 0) { g_printerr("Failed to set hw parameters: %s\n", snd_strerror(err)); return FALSE; } snd_pcm_sw_params_alloca(&swparams); if ((err = snd_pcm_sw_params_current (pcm_handle, swparams)) < 0) { g_printerr("Failed to set current sw parameters: %s\n", snd_strerror(err)); return FALSE; } if ((err = snd_pcm_sw_params_set_avail_min (pcm_handle, swparams, MIC_BUFSIZE)) < 0) { g_printerr("Failed to set minimum available count: %s\n", snd_strerror(err)); return FALSE; } if ((err = snd_pcm_sw_params_set_start_threshold (pcm_handle, swparams, 0U)) < 0) { g_printerr("Failed to set start mode: %s\n", snd_strerror(err)); return FALSE; } if ((err = snd_pcm_sw_params (pcm_handle, swparams)) < 0) { g_printerr("Failed to set sw parameters: %s\n", snd_strerror(err)); return FALSE; } if ((err = snd_pcm_prepare (pcm_handle)) < 0) { g_printerr("Failed to prepare audio interface to use: %s\n", snd_strerror(err)); return FALSE; } Mic_Inited = TRUE; Mic_Reset(); mic_reader = g_thread_create(snd_pcm_read, NULL, TRUE, NULL); return TRUE;
}
thanks, Riccardo
Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
2010/1/6 Riccardo Magliocchetti riccardo.magliocchetti@gmail.com
Hi Pierre,
pl bossart ha scritto:
You haven't specified the buffer/period size in the hw params. See alsa-lib/test/pcm.c
- Pierre
They fail when opening default device so I had to remove them, work fine when opening plughw:0,0 though.
On Mon, Jan 4, 2010 at 11:39 AM, Riccardo Magliocchetti riccardo.magliocchetti@gmail.com wrote:
[the same message is waiting in moderator queue, sorry if you receive it
two times]
Hello,
i'm trying to capture audio data from the microphone, but i'm not able
to
read any frames. The frames are always 0 and delay is fixed to 2730. I've tried calling snd_pcm_avail_delay, snd_pcm_avail_update but does not make a
difference.
The soundcard is driven by snd_hda_intel. The code is more or less the same as Paul Davis' tutorial on using the alsa api.
This is the code for init and the loop that tries to read the data:
#define MIC_BUFSIZE 4096
static gpointer snd_pcm_read(gpointer data) { int error; snd_pcm_sframes_t frames = MIC_BUFSIZE;
while (TRUE) {
if ((error = snd_pcm_wait (pcm_handle, 1000)) < 0) { g_printerr("Failed to poll: %s\n", snd_strerror(error)); continue; } if ((error = snd_pcm_avail(pcm_handle)) < 0) { if (error == -EPIPE) { g_printerr("xrun! %s\n", snd_strerror(error)); continue; //return GINT_TO_POINTER(FALSE); } else { g_printerr("alsa_pcm_avail_update error %s\n",
snd_strerror(error));
continue; //return GINT_TO_POINTER(FALSE); } } frames = error; if (frames == 0) continue; frames = frames > MIC_BUFSIZE ? MIC_BUFSIZE : frames; g_printerr ("frames: %ld\n", frames); g_static_mutex_lock(&mutex); error = snd_pcm_readi(pcm_handle, Mic_Buffer[Mic_WriteBuf], frames); g_static_mutex_unlock(&mutex); if (error < 0) error = snd_pcm_recover(pcm_handle, error, 0); if (error < 0) { LOG("snd_pcm_readi FAIL!: %s\n", snd_strerror(error)); }
}
return GINT_TO_POINTER(TRUE); }
BOOL Mic_Init() { snd_pcm_hw_params_t *hwparams; snd_pcm_sw_params_t *swparams; int err;
if (Mic_Inited) return TRUE; // Open the default sound card in capture if ((err = snd_pcm_open(&pcm_handle, "default",
SND_PCM_STREAM_CAPTURE,
/*SND_PCM_NONBLOCK*/ 0)) < 0) { g_printerr("Failed to open device: %s\n", snd_strerror(err)); return FALSE; }
// Allocate the snd_pcm_hw_params_t structure and fill it. snd_pcm_hw_params_alloca(&hwparams); if ((err = snd_pcm_hw_params_any(pcm_handle, hwparams)) < 0) { g_printerr("Failed to setup hw parameters: %s\n",
snd_strerror(err));
return FALSE; } //Set the access if ((err = snd_pcm_hw_params_set_access(pcm_handle, hwparams,
SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { g_printerr("Failed to set access: %s\n", snd_strerror(err)); return FALSE; }
//dir 0 == exacte (Rate = 16K exacte) if ((err = snd_pcm_hw_params_set_rate(pcm_handle, hwparams, 16000,
0)) < 0) {
g_printerr("Failed to set rate: %s\n", snd_strerror(err)); return FALSE; } /* Set sample format */ if ((err = snd_pcm_hw_params_set_format(pcm_handle, hwparams,
SND_PCM_FORMAT_S8)) < 0) {
g_printerr("Failed to set format: %s\n", snd_strerror(err)); return FALSE; } // Set one channel (mono) if ((err = snd_pcm_hw_params_set_channels(pcm_handle, hwparams, 1))
< 0) {
g_printerr("Failed to set channels: %s\n", snd_strerror(err)); return FALSE; } //Set the params if ((err = snd_pcm_hw_params(pcm_handle, hwparams)) < 0) { g_printerr("Failed to set hw parameters: %s\n",
snd_strerror(err));
return FALSE; } snd_pcm_sw_params_alloca(&swparams); if ((err = snd_pcm_sw_params_current (pcm_handle, swparams)) < 0) { g_printerr("Failed to set current sw parameters: %s\n",
snd_strerror(err));
return FALSE; } if ((err = snd_pcm_sw_params_set_avail_min (pcm_handle, swparams,
MIC_BUFSIZE)) < 0) {
g_printerr("Failed to set minimum available count: %s\n",
snd_strerror(err));
return FALSE; } if ((err = snd_pcm_sw_params_set_start_threshold (pcm_handle,
swparams, 0U)) < 0) {
g_printerr("Failed to set start mode: %s\n", snd_strerror(err)); return FALSE; } if ((err = snd_pcm_sw_params (pcm_handle, swparams)) < 0) { g_printerr("Failed to set sw parameters: %s\n",
snd_strerror(err));
return FALSE; } if ((err = snd_pcm_prepare (pcm_handle)) < 0) { g_printerr("Failed to prepare audio interface to use: %s\n",
snd_strerror(err));
return FALSE; } Mic_Inited = TRUE; Mic_Reset(); mic_reader = g_thread_create(snd_pcm_read, NULL, TRUE, NULL); return TRUE;
}
thanks, Riccardo
Even 4096 bytes is x86 DMA page size , seem to be a good choice for those PCI sound cards, however you cannot assume all sound cards/plugins support this buffer size
If you did not set period_size, buffer_size or periods (period_time, buffer_time or periods) , you should call snd_pcm_hw_params_get_buffer_size() and snd_pcm_hw_params_get_period_size() after snd_pcm_hw_params()
Raymond Yau ha scritto:
2010/1/6 Riccardo Magliocchetti riccardo.magliocchetti@gmail.com
Hi Pierre,
pl bossart ha scritto:
You haven't specified the buffer/period size in the hw params. See alsa-lib/test/pcm.c
- Pierre
They fail when opening default device so I had to remove them, work fine when opening plughw:0,0 though.
On Mon, Jan 4, 2010 at 11:39 AM, Riccardo Magliocchetti riccardo.magliocchetti@gmail.com wrote:
[the same message is waiting in moderator queue, sorry if you receive it
two times]
Hello,
i'm trying to capture audio data from the microphone, but i'm not able
to
read any frames. The frames are always 0 and delay is fixed to 2730. I've tried calling snd_pcm_avail_delay, snd_pcm_avail_update but does not make a
difference.
The soundcard is driven by snd_hda_intel. The code is more or less the same as Paul Davis' tutorial on using the alsa api.
Even 4096 bytes is x86 DMA page size , seem to be a good choice for those PCI sound cards, however you cannot assume all sound cards/plugins support this buffer size
If you did not set period_size, buffer_size or periods (period_time, buffer_time or periods) , you should call snd_pcm_hw_params_get_buffer_size() and snd_pcm_hw_params_get_period_size() after snd_pcm_hw_params()
Thank you both Pierre and Raymond, using the get functions after snd_pcm_hw_params() is working, now i have some concurrency issues to resolve before i can say everything is working properly.
Thanks again, riccardo
Riccardo Magliocchetti ha scritto:
Raymond Yau ha scritto:
2010/1/6 Riccardo Magliocchetti riccardo.magliocchetti@gmail.com
Hi Pierre,
pl bossart ha scritto:
You haven't specified the buffer/period size in the hw params. See alsa-lib/test/pcm.c
- Pierre
They fail when opening default device so I had to remove them, work fine when opening plughw:0,0 though.
On Mon, Jan 4, 2010 at 11:39 AM, Riccardo Magliocchetti riccardo.magliocchetti@gmail.com wrote:
[the same message is waiting in moderator queue, sorry if you receive it
two times]
Hello,
i'm trying to capture audio data from the microphone, but i'm not able
to
read any frames. The frames are always 0 and delay is fixed to 2730. I've tried calling snd_pcm_avail_delay, snd_pcm_avail_update but does not make a
difference.
The soundcard is driven by snd_hda_intel. The code is more or less the same as Paul Davis' tutorial on using the alsa api.
Even 4096 bytes is x86 DMA page size , seem to be a good choice for those PCI sound cards, however you cannot assume all sound cards/plugins support this buffer size
If you did not set period_size, buffer_size or periods (period_time, buffer_time or periods) , you should call snd_pcm_hw_params_get_buffer_size() and snd_pcm_hw_params_get_period_size() after snd_pcm_hw_params()
Thank you both Pierre and Raymond, using the get functions after snd_pcm_hw_params() is working, now i have some concurrency issues to resolve before i can say everything is working properly.
The init works fine but snd_pcm_avail() always returns 0, full code is here http://pastebin.com/f687bf37a
thanks, riccardo
On Mon, 11 Jan 2010, Riccardo Magliocchetti wrote:
Riccardo Magliocchetti ha scritto:
Raymond Yau ha scritto:
2010/1/6 Riccardo Magliocchetti riccardo.magliocchetti@gmail.com
Hi Pierre,
pl bossart ha scritto:
You haven't specified the buffer/period size in the hw params. See alsa-lib/test/pcm.c
- Pierre
They fail when opening default device so I had to remove them, work fine when opening plughw:0,0 though.
On Mon, Jan 4, 2010 at 11:39 AM, Riccardo Magliocchetti riccardo.magliocchetti@gmail.com wrote:
[the same message is waiting in moderator queue, sorry if you receive it
two times]
Hello,
i'm trying to capture audio data from the microphone, but i'm not able
to
read any frames. The frames are always 0 and delay is fixed to 2730. I've tried calling snd_pcm_avail_delay, snd_pcm_avail_update but does not make a
difference.
The soundcard is driven by snd_hda_intel. The code is more or less the same as Paul Davis' tutorial on using the alsa api.
Even 4096 bytes is x86 DMA page size , seem to be a good choice for those PCI sound cards, however you cannot assume all sound cards/plugins support this buffer size
If you did not set period_size, buffer_size or periods (period_time, buffer_time or periods) , you should call snd_pcm_hw_params_get_buffer_size() and snd_pcm_hw_params_get_period_size() after snd_pcm_hw_params()
Thank you both Pierre and Raymond, using the get functions after snd_pcm_hw_params() is working, now i have some concurrency issues to resolve before i can say everything is working properly.
The init works fine but snd_pcm_avail() always returns 0, full code is here http://pastebin.com/f687bf37a
The PCM stream must be triggered via snd_pcm_start() or using snd_pcm_read*() when sw_param->start_threshold is set appropriately.
Jaroslav
----- Jaroslav Kysela perex@perex.cz Linux Kernel Sound Maintainer ALSA Project, Red Hat, Inc.
2010/1/11 Jaroslav Kysela perex@perex.cz
On Mon, 11 Jan 2010, Riccardo Magliocchetti wrote:
Riccardo Magliocchetti ha scritto:
Raymond Yau ha scritto:
2010/1/6 Riccardo Magliocchetti riccardo.magliocchetti@gmail.com
Hi Pierre,
pl bossart ha scritto:
You haven't specified the buffer/period size in the hw params. See alsa-lib/test/pcm.c
- Pierre
They fail when opening default device so I had to remove them, work
fine
when opening plughw:0,0 though.
On Mon, Jan 4, 2010 at 11:39 AM, Riccardo Magliocchetti riccardo.magliocchetti@gmail.com wrote: > [the same message is waiting in moderator queue, sorry if you > receive it
two times]
> Hello, > > i'm trying to capture audio data from the microphone, but i'm not
able
to
> read any frames. > The frames are always 0 and delay is fixed to 2730. I've tried
calling
> snd_pcm_avail_delay, snd_pcm_avail_update but does not make a
difference.
> The soundcard is driven by snd_hda_intel. The code is more or less > the > same as Paul Davis' tutorial on using the alsa api.
Even 4096 bytes is x86 DMA page size , seem to be a good choice for
those
PCI sound cards, however you cannot assume all sound cards/plugins support this buffer size
If you did not set period_size, buffer_size or periods (period_time, buffer_time or periods) , you should call snd_pcm_hw_params_get_buffer_size() and snd_pcm_hw_params_get_period_size() after snd_pcm_hw_params()
Thank you both Pierre and Raymond, using the get functions after snd_pcm_hw_params() is working, now i have some concurrency issues to resolve before i can say everything is working properly.
The init works fine but snd_pcm_avail() always returns 0, full code is
here
The PCM stream must be triggered via snd_pcm_start() or using snd_pcm_read*() when sw_param->start_threshold is set appropriately.
Jaroslav
Are there any PCM state diagram ?
http://equalarea.com/paul/alsa-audio.html
http://www.alsa-project.org/main/index.php/Tutorials_and_Presentations
The tutorial program call snd_pcm_hw_params_free() before any playback and capture, this cause au88x0 fail since callback snd_vortex_pcm_hw_free() delete the dynamic route between SRC , mixer
if ((err = snd_pcm_hw_params (playback_handle, hw_params)) < 0) { fprintf (stderr, "cannot set parameters (%s)\n", snd_strerror (err)); exit (1); } snd_pcm_hw_params_free (hw_params); if ((err = snd_pcm_prepare (playback_handle)) < 0) { fprintf (stderr, "cannot prepare audio interface for use (%s)\n", snd_strerror (err)); exit (1); }
participants (5)
-
Jaroslav Kysela
-
Marc Garnier
-
pl bossart
-
Raymond Yau
-
Riccardo Magliocchetti