* capturing data from the microphone
@ 2010-01-04 17:39 Riccardo Magliocchetti
2010-01-05 15:24 ` Marc Garnier
2010-01-05 16:48 ` pl bossart
0 siblings, 2 replies; 15+ messages in thread
From: Riccardo Magliocchetti @ 2010-01-04 17:39 UTC (permalink / raw)
To: alsa-devel
[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
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: capturing data from the microphone
2010-01-04 17:39 capturing data from the microphone Riccardo Magliocchetti
@ 2010-01-05 15:24 ` Marc Garnier
2010-01-06 1:07 ` Raymond Yau
2010-01-05 16:48 ` pl bossart
1 sibling, 1 reply; 15+ messages in thread
From: Marc Garnier @ 2010-01-05 15:24 UTC (permalink / raw)
To: alsa-devel
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
>
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: capturing data from the microphone
2010-01-05 15:24 ` Marc Garnier
@ 2010-01-06 1:07 ` Raymond Yau
2010-01-06 7:58 ` Marc Garnier
0 siblings, 1 reply; 15+ messages in thread
From: Raymond Yau @ 2010-01-06 1:07 UTC (permalink / raw)
To: 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?
>
>
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: capturing data from the microphone
2010-01-06 1:07 ` Raymond Yau
@ 2010-01-06 7:58 ` Marc Garnier
2010-01-06 8:46 ` Raymond Yau
0 siblings, 1 reply; 15+ messages in thread
From: Marc Garnier @ 2010-01-06 7:58 UTC (permalink / raw)
To: alsa-devel@alsa-project.org
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
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: capturing data from the microphone
2010-01-06 7:58 ` Marc Garnier
@ 2010-01-06 8:46 ` Raymond Yau
2010-01-06 9:09 ` Marc Garnier
0 siblings, 1 reply; 15+ messages in thread
From: Raymond Yau @ 2010-01-06 8:46 UTC (permalink / raw)
To: 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>
> >
> >
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: capturing data from the microphone
2010-01-06 8:46 ` Raymond Yau
@ 2010-01-06 9:09 ` Marc Garnier
0 siblings, 0 replies; 15+ messages in thread
From: Marc Garnier @ 2010-01-06 9:09 UTC (permalink / raw)
To: alsa-devel@alsa-project.org
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
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: capturing data from the microphone
2010-01-04 17:39 capturing data from the microphone Riccardo Magliocchetti
2010-01-05 15:24 ` Marc Garnier
@ 2010-01-05 16:48 ` pl bossart
2010-01-05 22:12 ` Riccardo Magliocchetti
1 sibling, 1 reply; 15+ messages in thread
From: pl bossart @ 2010-01-05 16:48 UTC (permalink / raw)
To: Riccardo Magliocchetti; +Cc: 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
>
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: capturing data from the microphone
2010-01-05 16:48 ` pl bossart
@ 2010-01-05 22:12 ` Riccardo Magliocchetti
2010-01-06 23:59 ` Raymond Yau
0 siblings, 1 reply; 15+ messages in thread
From: Riccardo Magliocchetti @ 2010-01-05 22:12 UTC (permalink / raw)
To: pl bossart; +Cc: 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
>>
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: capturing data from the microphone
2010-01-05 22:12 ` Riccardo Magliocchetti
@ 2010-01-06 23:59 ` Raymond Yau
2010-01-07 18:34 ` Riccardo Magliocchetti
0 siblings, 1 reply; 15+ messages in thread
From: Raymond Yau @ 2010-01-06 23:59 UTC (permalink / raw)
To: 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()
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: capturing data from the microphone
2010-01-06 23:59 ` Raymond Yau
@ 2010-01-07 18:34 ` Riccardo Magliocchetti
2010-01-11 13:59 ` Riccardo Magliocchetti
0 siblings, 1 reply; 15+ messages in thread
From: Riccardo Magliocchetti @ 2010-01-07 18:34 UTC (permalink / raw)
To: Raymond Yau, pl bossart; +Cc: alsa-devel
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
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: capturing data from the microphone
2010-01-07 18:34 ` Riccardo Magliocchetti
@ 2010-01-11 13:59 ` Riccardo Magliocchetti
2010-01-11 14:03 ` Jaroslav Kysela
0 siblings, 1 reply; 15+ messages in thread
From: Riccardo Magliocchetti @ 2010-01-11 13:59 UTC (permalink / raw)
To: alsa-devel; +Cc: pl bossart
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
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: capturing data from the microphone
2010-01-11 13:59 ` Riccardo Magliocchetti
@ 2010-01-11 14:03 ` Jaroslav Kysela
2010-01-14 7:49 ` Raymond Yau
0 siblings, 1 reply; 15+ messages in thread
From: Jaroslav Kysela @ 2010-01-11 14:03 UTC (permalink / raw)
To: Riccardo Magliocchetti; +Cc: pl bossart, ALSA development
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.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: capturing data from the microphone
2010-01-11 14:03 ` Jaroslav Kysela
@ 2010-01-14 7:49 ` Raymond Yau
0 siblings, 0 replies; 15+ messages in thread
From: Raymond Yau @ 2010-01-14 7:49 UTC (permalink / raw)
To: alsa-devel
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
> > 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
>
>
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);
}
^ permalink raw reply [flat|nested] 15+ messages in thread
* How to use soc API without codec driver
@ 2009-12-08 14:46 Marc Garnier
2009-12-08 14:51 ` Mark Brown
0 siblings, 1 reply; 15+ messages in thread
From: Marc Garnier @ 2009-12-08 14:46 UTC (permalink / raw)
To: alsa-devel
Hi,
I need to receive and transmit PCM data through SSC port of a sam9261 to
a device which doesn't have any kind of I/O controls (neither i2c nor
spi). So, I wonder how to deal with the codec driver side.
Someone could explain me what are the minimum requirements to write a
Asoc driver of this kind?
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: How to use soc API without codec driver
2009-12-08 14:46 How to use soc API without codec driver Marc Garnier
@ 2009-12-08 14:51 ` Mark Brown
2009-12-09 6:39 ` Marc Garnier
0 siblings, 1 reply; 15+ messages in thread
From: Mark Brown @ 2009-12-08 14:51 UTC (permalink / raw)
To: Marc Garnier; +Cc: alsa-devel
On Tue, Dec 08, 2009 at 03:46:53PM +0100, Marc Garnier wrote:
> I need to receive and transmit PCM data through SSC port of a sam9261 to
> a device which doesn't have any kind of I/O controls (neither i2c nor
> spi). So, I wonder how to deal with the codec driver side.
> Someone could explain me what are the minimum requirements to write a
> Asoc driver of this kind?
There's a couple of drivers for such CODECs in the tree already - have a
look at the wm8727 driver for one example. You need to register at
least a DAI with whatever the capabilities of the hardware are and can
leave all the operations blank.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: How to use soc API without codec driver
2009-12-08 14:51 ` Mark Brown
@ 2009-12-09 6:39 ` Marc Garnier
2009-12-09 10:45 ` Mark Brown
0 siblings, 1 reply; 15+ messages in thread
From: Marc Garnier @ 2009-12-09 6:39 UTC (permalink / raw)
To: Mark Brown; +Cc: alsa-devel
You mean I just have to use snd_soc_register_dai()? Things like
soc_init_card() and snd_soc_new_pcms() are not mandatory?
So, i think code like this one could be ok :
#define Q2686_RATES (SNDRV_PCM_RATE_8000_192000)
#define Q2686_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE)
static struct snd_soc_dai_ops q2686_dai_ops = {
};
struct snd_soc_dai q2686_dai = {
.name = "Q2686",
.playback = {
.stream_name = "Playback",
.channels_min = 2,
.channels_max = 2,
.rates = Q2686_RATES,
.formats = Q2686_FORMATS,
},
.capture = {
.stream_name = "Capture",
.channels_min = 2,
.channels_max = 2,
.rates = Q2686_RATES,
.formats = Q2686_FORMATS,},
.ops = &wm8728_dai_ops,
};
EXPORT_SYMBOL_GPL(q2686_dai);
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");
Mark Brown wrote:
> On Tue, Dec 08, 2009 at 03:46:53PM +0100, Marc Garnier wrote:
>
>
>> I need to receive and transmit PCM data through SSC port of a sam9261 to
>> a device which doesn't have any kind of I/O controls (neither i2c nor
>> spi). So, I wonder how to deal with the codec driver side.
>> Someone could explain me what are the minimum requirements to write a
>> Asoc driver of this kind?
>>
>
> There's a couple of drivers for such CODECs in the tree already - have a
> look at the wm8727 driver for one example. You need to register at
> least a DAI with whatever the capabilities of the hardware are and can
> leave all the operations blank.
>
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: How to use soc API without codec driver
2009-12-09 6:39 ` Marc Garnier
@ 2009-12-09 10:45 ` Mark Brown
[not found] ` <4B44617B.2030002@heig-vd.ch>
0 siblings, 1 reply; 15+ messages in thread
From: Mark Brown @ 2009-12-09 10:45 UTC (permalink / raw)
To: Marc Garnier; +Cc: alsa-devel
On Wed, Dec 09, 2009 at 07:39:19AM +0100, Marc Garnier wrote:
> You mean I just have to use snd_soc_register_dai()? Things like
> soc_init_card() and snd_soc_new_pcms() are not mandatory?
init_card() has been removed now, but new_pcms() is still required -
like I say, look at one of the existing drivers like the spdif
transciever driver for examples of drivers which do what you're trying
to do here.
> static int __init q2686_modinit(void)
> {
> return snd_soc_register_dai(&q2686_dai);
> }
> module_init(q2686_modinit);
This should be done from a platform device, not from module init.
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2010-01-14 7:49 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-01-04 17:39 capturing data from the microphone Riccardo Magliocchetti
2010-01-05 15:24 ` Marc Garnier
2010-01-06 1:07 ` Raymond Yau
2010-01-06 7:58 ` Marc Garnier
2010-01-06 8:46 ` Raymond Yau
2010-01-06 9:09 ` Marc Garnier
2010-01-05 16:48 ` pl bossart
2010-01-05 22:12 ` Riccardo Magliocchetti
2010-01-06 23:59 ` Raymond Yau
2010-01-07 18:34 ` Riccardo Magliocchetti
2010-01-11 13:59 ` Riccardo Magliocchetti
2010-01-11 14:03 ` Jaroslav Kysela
2010-01-14 7:49 ` Raymond Yau
-- strict thread matches above, loose matches on Subject: below --
2009-12-08 14:46 How to use soc API without codec driver Marc Garnier
2009-12-08 14:51 ` Mark Brown
2009-12-09 6:39 ` Marc Garnier
2009-12-09 10:45 ` Mark Brown
[not found] ` <4B44617B.2030002@heig-vd.ch>
[not found] ` <20100106103937.GA25344@rakim.wolfsonmicro.main>
[not found] ` <4B446974.1090205@heig-vd.ch>
2010-01-06 11:39 ` capturing data from the microphone Mark Brown
2010-01-06 13:34 ` Riccardo Magliocchetti
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.