[alsa-devel] How does struct snd_pcm_hardware relate to the actual hardware
I am using DMA to transfer data to SPORT1 on my Blackfin BF537. I am using a CS42448 CODEC that has 8 DACs. I am using TDM mode and have set the following:
DMA Buffer Size For Each SPORT Data Line (Rx or Tx) = 131072 bytes DMA Periods = 8
static struct snd_pcm_hardware snd_pcm_hw = { .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_RESUME), .formats = SNDRV_PCM_FMTBIT_S32_LE, .rates = SNDRV_PCM_RATE_48000, .rate_min = 48000, .rate_max = 48000, .buffer_bytes_max = 32768, .channels_min = 2, .channels_max = 2, .period_bytes_min = 8, .period_bytes_max = 4096, .periods_min = 8, .periods_max = 8, };
Everytime I receive a DMA interrupt from the SPORT driver I call snd_pcm_period_elapsed for all of the substreams that are currently active. In the PCM Copy callback I calculate the position within the DMA buffer to write to based on the TDM slot for the channel and the position passed into the function.
The audio is not being placed into the DMA buffer properly. The audio plays faster than it should and has a constant stutter. I have read the "writing an ALSA driver" guide multiple times but it does not explain the relationship between struct snd_pcm_hardware, snd_pcm_period_elapsed, and the copy callback clearly enough for me to understand what I am doing wrong.
Please explain how these interact in more detail to help me fix this problem. I can also send the full source code to the CS42448 driver I am working on if more details are needed.
Thank you, Adam
On Wed, Jun 30, 2010 at 05:32:41PM -0400, Adam Rosenberg wrote:
The audio is not being placed into the DMA buffer properly. The audio plays faster than it should and has a constant stutter. I have read the "writing an ALSA driver" guide multiple times but it does not explain the relationship between struct snd_pcm_hardware, snd_pcm_period_elapsed, and the copy callback clearly enough for me to understand what I am doing wrong.
You probably want to provide a little more detail on how you're parsing the data in your DMA driver here... The simplest thing when debugging problems like this is often to place obviously tracable test data into the audio stream (eg, all but one channel zero) and then work through where the data ends up compared to where it ought to end up.
Note also that ASoC doesn't do anything explicit to support substreams, which aren't in themselves ASoC specific.
I determined that the secondary data lines of my SPORT were not being enabled properly. With that problem solved I am finally seeing test data sent to the DACs correctly. I am still having problems with placing the data correctly using my custom PCM copy operation.
I do not understand the relationship between snd_pcm_period_elapsed and the PCM copy and trigger functions. Where can I find a detailed description of how this works?
I am attempting to troubleshoot this problem but it seems to change based on values I enter into struct snd_pcm_hardware, which I copy to substream->runtime->hw when the PCM open operation occurs. What are the correct values for struct snd_pcm_hardware?
I have included the values I am currently using and a brief description of the hardware configuration below:
I am using one Blackfin BF537 SPORT to transfer 16 channels of audio to 2 CS42448 CODECs using TDM. There are 8 channels per TDM frame. The Primary SPORT data lines are connected to one CS42448 and the Secondary are connected to another. I use one DMA buffer of 131072 bytes and configure the DMA for 8 periods. I have to interleave the channel data so that each CODEC receives one TDM frame for every frame sync clock. With 8 channels in each TDM frame, there are 256 bits per frame sync clock. The frame sync clock and bit clock are generated from an ICS661 audio clock source configured for 12.288Mhz (256bits * 48Khz).
static struct snd_pcm_hardware ourCS42448PcmHw = { .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_RESUME),
.formats = SNDRV_PCM_FMTBIT_S32_LE,
.rates = SNDRV_PCM_RATE_48000, .rate_min = 48000, .rate_max = 48000,
.buffer_bytes_max = 32768,
.channels_min = 2, .channels_max = 2,
.period_bytes_min = 4096, .period_bytes_max = 4096,
.periods_min = 8, .periods_max = 8, };
Thanks, Adam
Adam Rosenberg Software Engineer
Alcorn McBride Inc. 3300 South Hiawassee Building 105 Orlando, FL 32835
(407) 296 - 5800 ext. 5490
participants (2)
-
Adam Rosenberg
-
Mark Brown