[alsa-devel] Discarding the first few frames inside the kernel
Hello All,
I am interfacing the ICS43432 MEMS microphone with McBSP interface. The data sheet of the ICS43432 microphone shows that it takes about 4.5ms (16kHz sampling rate) for startup. Because of this, I hear a transient noise at the beginning of every stream. Is there in any way I can discard the frames inside the kernel space itself before reading the samples using snd_pcm_readi() call?
I was able to mute the first few frames after the readi() call, but would want to know if I could do it before the readi() call itself inside the kernel space.
Appreciate any help!
Thanks, Ankhit
Hi,
On Jan 19 2016 03:21, Ankhit Vivekananda wrote:
I am interfacing the ICS43432 MEMS microphone with McBSP interface. The data sheet of the ICS43432 microphone shows that it takes about 4.5ms (16kHz sampling rate) for startup. Because of this, I hear a transient noise at the beginning of every stream. Is there in any way I can discard the frames inside the kernel space itself before reading the samples using snd_pcm_readi() call?
I was able to mute the first few frames after the readi() call, but would want to know if I could do it before the readi() call itself inside the kernel space.
If the data transmission starts in 'struct snd_pcm_ops.prepare' callback of the driver, we can wait what we want, because ALSA PCM core guarantees to call it in process context.
In userspace, this looks like (here I describe in alsa-lib API): - calling snd_pcm_hw_params() - snd_pcm_prepare() is called library internal * struct snd_pcm_ops.prepare() is called in kernel mode. * mute * start data transmission * wait for the 4.5ms or somewhat * return * return - return - PCM frame operation such as snd_pcm_writei() * snd_pcm_ops.trigger(TRIGGER_START) is called in kernel mode. * demute * PCM frames starts to be transferred from userspace.
Regards
Takashi Sakamoto
Hello Takashi,
Thank you for your response. I am not sure as to how the wait for 4.5ms can be applied there? Alternatively, does calling snd_pcm_format_set_silence(), be a safe method to silence the first few samples coming out of the buffer?
Regards, Ankhit
On Mon, Jan 18, 2016 at 8:22 PM, Takashi Sakamoto o-takashi@sakamocchi.jp wrote:
Hi,
On Jan 19 2016 03:21, Ankhit Vivekananda wrote:
I am interfacing the ICS43432 MEMS microphone with McBSP interface. The data sheet of the ICS43432 microphone shows that it takes about 4.5ms (16kHz sampling rate) for startup. Because of this, I hear a transient noise at the beginning of every stream. Is there in any way I can discard the frames inside the kernel space itself before reading the samples using snd_pcm_readi() call?
I was able to mute the first few frames after the readi() call, but would want to know if I could do it before the readi() call itself inside the kernel space.
If the data transmission starts in 'struct snd_pcm_ops.prepare' callback of the driver, we can wait what we want, because ALSA PCM core guarantees to call it in process context.
In userspace, this looks like (here I describe in alsa-lib API):
- calling snd_pcm_hw_params()
- snd_pcm_prepare() is called library internal
- struct snd_pcm_ops.prepare() is called in kernel mode.
- mute
- start data transmission
- wait for the 4.5ms or somewhat
- return
- return
- return
- PCM frame operation such as snd_pcm_writei()
- snd_pcm_ops.trigger(TRIGGER_START) is called in kernel mode.
- demute
- PCM frames starts to be transferred from userspace.
Regards
Takashi Sakamoto
Hi,
On Jan 21 2016 02:24, Ankhit Vivekananda wrote:
I am not sure as to how the wait for 4.5ms can be applied there?
I think you asked about the way to achieve the idea.
Call kernel's process scheduler in the .prepare() implementation of your driver. For example, msleep() in <linux/delay.h> (More geneous logic is preferrable, I think.)
Don't do this in .trigger() implementation, because this can be called in interrupt context, or between spin_lock_irqsave()/spin_lock_irqstore() in process context.
Alternatively, does calling snd_pcm_format_set_silence(), be a safe method to silence the first few samples coming out of the buffer?
I don't know exactly because I have no supplemental information about your driver and hardware design.
Regards
Takashi Sakamoto
Hello Takashi,
Thank you very much for the explanation.
Regards, Ankhit
On Wed, Jan 20, 2016 at 8:18 PM, Takashi Sakamoto o-takashi@sakamocchi.jp wrote:
Hi,
On Jan 21 2016 02:24, Ankhit Vivekananda wrote:
I am not sure as to how the wait for 4.5ms can be applied there?
I think you asked about the way to achieve the idea.
Call kernel's process scheduler in the .prepare() implementation of your driver. For example, msleep() in <linux/delay.h> (More geneous logic is preferrable, I think.)
Don't do this in .trigger() implementation, because this can be called in interrupt context, or between spin_lock_irqsave()/spin_lock_irqstore() in process context.
Alternatively, does calling snd_pcm_format_set_silence(), be a safe
method to silence the first few samples coming out of the buffer?
I don't know exactly because I have no supplemental information about your driver and hardware design.
Regards
Takashi Sakamoto
participants (2)
-
Ankhit Vivekananda
-
Takashi Sakamoto