Hi folks,
could anybody help me please with ASRC support for audio playback in i.MX6q-based board.
I use LTIB Linux kernel as a reference and wrote a driver for DAC, which is connected to SSI2. The code is derived from sgtl5000 and cs42888 drivers. I've added 2 dai links with names: "HiFi" and "HiFi_ASRC". The first link assumes to play the stream with sample rate it has, and the second - should use ASRC. "HiFi" configuration works, when I start the following command:
$ aplay -D "hw:0,0" my.wav
I see a data at oscilloscope and hear sound. But when I try to use "HiFi_ASRC":
$ aplay -D "hw:0,1" my.wav
I get an I/O error after some timeout. Moreover I see about 4-5 SDMA interrupts only in 'cat /proc/interrupts' after each execution, while for the first case there are about 100.
In my base driver implementation I used the following ASRC configuration:
config.input_word_width = get_asrc_input_width(params);
config.output_word_width = iprtd->p2p->p2p_width;
config.pair = iprtd->asrc_index;
config.channel_num = channel;
config.input_sample_rate = rate;
config.output_sample_rate = iprtd->p2p->p2p_rate;
config.inclk = INCLK_NONE;
config.outclk = OUTCLK_SSI2_TX;
But also I tried to use different combinations of clocks for 'inclk' and 'outclk', but result was the same.
So I have several question and any hints are highly appreciated:
1. How ASRC works, does it require both clocks: input and output? According to the RM, it uses input clock to process samples, but how the output clock is involved to this process?
2. How "asrc_clk" and "asrc_serial_clk" are used, should I set some magic rate for them?
3. Lets say I have an input stream with sample rate 44.1KHz and I want to play it over SSI2 at 48KHz rate. Which clocks should I use? Should I manually setup input clock rate to: F = 44100 * WORD_SIZE * CHANNELS Hz?
Thank you!
With best regards,
Alex
Solved! Go to Solution.
Hello again,
I'd like to share the results of my research, probably it will help somebody in future.
i.MX6 ASRC implementation has 2 interfaces:
1. First interface doesn't require any kernel modifications. The only thing is required - add necessary line to ALSA config. All the information can be found in fsl-alsa-plugins-1.0.25.tar.gz in file asrcrate.txt. Below is example for 44100KHz:
Write in your ~/.asoundrc or /etc/asound.conf, such as
defaults.pcm.rate_converter "asrcrate"
pcm.dmix_44100 {
type dmix
ipc_key 5678293
ipc_key_add_uid yes
slave{
pcm "hw:0,0"
period_time 10000
format S16_LE
rate 44100
}
}
pcm.asrc {
type plug
route_policy "average"
slave.pcm "dmix_44100"
}
But, as mentioned in the text file, there are limitations in convertion rates.
2. Kernel API uses the same functions as the interface above, but calls them directly instead of using IOCTL. I used cs42888 codec as a reference code, so derived all ASRC parts and put them in my codec - but it didn't work due to problems mentioned in previous posts.
The first approach works and completely fits my requirements, so I stopped digging kernel part here.
Alex
Hello again,
I got some status update. I've used the following clock setup:
...
config.channel_num = 2;
config.input_sample_rate = 48000;
config.output_sample_rate = 48000;
config.inclk = INCLK_SSI2_RX;
config.outclk = OUTCLK_NONE;
Also I checked the ASRC input clock divider and prescaler, so the Fs_in = 48KHz. Then I tried to play 48KHz audio by using aplay and I saw no error, but no data was observed at DAC side. But on the other hand I saw lots of SDMA interrupts in 'cat /proc/interrupts'. If I set outclk to OUTCLK_SSI2_TX - the I/O problem will be seen.
So, I'd like to add new question to the list, what do INCLK_NONE and OUTCLK_NONE clocks mean?
Alex
Hello again,
I'd like to share the results of my research, probably it will help somebody in future.
i.MX6 ASRC implementation has 2 interfaces:
1. First interface doesn't require any kernel modifications. The only thing is required - add necessary line to ALSA config. All the information can be found in fsl-alsa-plugins-1.0.25.tar.gz in file asrcrate.txt. Below is example for 44100KHz:
Write in your ~/.asoundrc or /etc/asound.conf, such as
defaults.pcm.rate_converter "asrcrate"
pcm.dmix_44100 {
type dmix
ipc_key 5678293
ipc_key_add_uid yes
slave{
pcm "hw:0,0"
period_time 10000
format S16_LE
rate 44100
}
}
pcm.asrc {
type plug
route_policy "average"
slave.pcm "dmix_44100"
}
But, as mentioned in the text file, there are limitations in convertion rates.
2. Kernel API uses the same functions as the interface above, but calls them directly instead of using IOCTL. I used cs42888 codec as a reference code, so derived all ASRC parts and put them in my codec - but it didn't work due to problems mentioned in previous posts.
The first approach works and completely fits my requirements, so I stopped digging kernel part here.
Alex