On Tue, Nov 9, 2010 at 8:04 PM, Jaroslav Kysela perex@perex.cz wrote:
On Tue, 9 Nov 2010, Manu Abraham wrote:
On Tue, Nov 9, 2010 at 6:21 PM, Jaroslav Kysela perex@perex.cz wrote:
On Tue, 9 Nov 2010, Manu Abraham wrote:
On Tue, Nov 9, 2010 at 5:31 PM, Jaroslav Kysela perex@perex.cz wrote:
On Tue, 9 Nov 2010, Manu Abraham wrote:
testbox ~ # arecord -Dhw:2,0 Recording WAVE 'stdin' : Unsigned 8 bit, Rate 8000 Hz, Mono
Any idea, why saa7231_hw_params is not getting invoked ?
Your hw probably does not support directly 8-bit sample at 8000Hz, one channel. Use 'plughw:2,0' device instead 'hw:2,0' to let alsa-lib do all stream format conversions.
That didn't make any difference at all.
Check your code. You probably created wrong hw_ops, looking to your code:
.buffer_bytes_max = 512 * 4096, .period_bytes_min = 8192, .period_bytes_max = 8192, .periods_min = 8192, .periods_max = 8192,
It's definitely an empty configuration space.
You have buffer_bytes_max 2097152, but restricted number of periods to 8192 and period_bytes to 8192.
8192 * 8192 = 67108864 which is not less than 2097152 (and I'm not counting the bytes for channels and formats). Bingo, the ALSA PCM code does not know what to configure.
Decrease periods_min and probably also periods_max.
oh ! The error message was really a weird one. I can say that the hardware can do 192 audio frames in an interrupt, whatever the frame size is. So, what periods and period_bytes should I describe in the configuration ?
You cannot describe this using hw_ops. Leave period bytes in good range (192
- 1536?), periods (2-1024?) and add something like this to the open
callback:
err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 192, 192);
Note the difference between SNDRV_PCM_HW_PARAM_PERIOD_SIZE and SNDRV_PCM_HW_PARAM_PERIOD_BYTES.
Ok, thanks.
I modified it to look thus ...
static struct snd_pcm_hardware saa7231_capture_info = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID),
.formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE),
.rates = SNDRV_PCM_RATE_32000,
.rate_min = 32000, .rate_max = 48000,
.channels_min = 2, .channels_max = 2,
.buffer_bytes_max = 512 * 4096, .period_bytes_min = 192, .period_bytes_max = 1536, .periods_min = 2, .periods_max = 1024, };
static int saa7231_capture_open(struct snd_pcm_substream *pcm) { struct saa7231_audio *audio = snd_pcm_substream_chip(pcm); struct snd_pcm_runtime *rt = pcm->runtime; struct saa7231_dev *saa7231 = audio->saa7231; int err;
dprintk(SAA7231_DEBUG, 1, "()"); rt->hw = saa7231_capture_info; snd_pcm_hw_constraint_list(rt, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraint_rates); err = snd_pcm_hw_constraint_integer(rt, SNDRV_PCM_HW_PARAM_PERIODS); if (err < 0) { dprintk(SAA7231_ERROR, 1, "snd_pcm_hw_constraint_integer() failed. ret=%d", err); return err; } err = snd_pcm_hw_constraint_minmax(rt, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 192, 192); if (err < 0) { dprintk(SAA7231_ERROR, 1, "snd_pcm_hw_constraint_minmax() failed. ret=%d", err); return err; }
return 0; }
static int saa7231_hw_params(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params) { struct saa7231_audio *audio = snd_pcm_substream_chip(pcm); struct saa7231_dev *saa7231 = audio->saa7231;
struct saa7231_dmabuf *buffer; struct saa7231_stream *stream; struct saa7231_dmabuf *dmabuf;
struct page **ptable;
void *vma; void *dma_area;
int i, j, pages, bytes, periods, bufsiz;
dprintk(SAA7231_DEBUG, 1, "DEBUG: ()"); periods = params_periods(params); bytes = params_period_bytes(params);
bufsiz = periods * bytes; dprintk(SAA7231_DEBUG, 1, "bufsiz=%d periods=%d bytes=%d", bufsiz, periods, bytes);
pages = bufsiz / PAGE_SIZE;
/* enable stream */ stream = saa7231_stream_init(saa7231, AUDIO_CAPTURE, ADAPTER_INT, 0, 512); if (!stream) { dprintk(SAA7231_ERROR, 1, "ERROR: Registering stream"); return -ENOMEM; } audio->stream = stream; buffer = stream->dmabuf; saa7231_add_irqevent(saa7231, 43, SAA7231_EDGE_RISING, saa7231_audio_evhandler, "AS2D_AVIS"); dprintk(SAA7231_DEBUG, 1, "Mapping %d buffers with %d pages each", XS2D_BUFFERS, pages); return 0; }
testbox ~ # arecord -Dplughw:2,0 Recording WAVE 'stdin' : Unsigned 8 bit, Rate 8000 Hz, Mono ALSA lib pcm_mmap.c:369:(snd_pcm_mmap) mmap failed: Invalid argument arecord: set_params:1041: Unable to install hw params: ACCESS: RW_INTERLEAVED FORMAT: U8 SUBFORMAT: STD SAMPLE_BITS: 8 FRAME_BITS: 8 CHANNELS: 1 RATE: 8000 PERIOD_TIME: 6000 PERIOD_SIZE: 48 PERIOD_BYTES: 48 PERIODS: 83 BUFFER_TIME: 498000 BUFFER_SIZE: 3984 BUFFER_BYTES: 3984 TICK_TIME: 0
[ 819.928438] saa7231_capture_open (0): () [ 819.945466] saa7231_hw_params (0): DEBUG: () [ 819.945470] saa7231_hw_params (0): bufsiz=31872 periods=83 bytes=384 [ 819.945472] saa7231_stream_init (0): DEBUG: Initializing Stream with MODE=0x01 [ 819.945475] saa7231_xs2dtl_init (0): XS2DTL engine Initializing ..... [ 819.945477] saa7231_xs2dtl_init (0): Allocated 8 XS2DTL Buffer @0xf47b6000 [ 819.945479] saa7231_xs2dtl_init (0): Allocating DMA Buffers ... [ 819.945481] saa7231_xs2dtl_init (0): Allocating DMA buffer:0 @0xf47b6000.. [ 819.945492] saa7231_allocate_ptable (0): Virtual 0xf3bb7000 to Phys 0x33bb7000 mapped page [ 819.945598] saa7231_dmabuf_sgalloc (0): Virtual contiguous 2097152 byte region with 512 4k pages ... ...
bufsiz=31872 periods=83 bytes=384
Now, I wonder what a period really is. I guess I lack the basics here .. A basic explanation to the context, would be quite helpful.
Best Regards, Manu