From: Tim Harvey <tim_harvey@yahoo.com>
To: alsa-devel@alsa-project.org
Subject: Re: Questions about writing a new ALSA driver for a very limitted device
Date: Thu, 19 Apr 2007 14:30:29 -0700 (PDT) [thread overview]
Message-ID: <95415.40128.qm@web35606.mail.mud.yahoo.com> (raw)
In-Reply-To: <s5hwt0cvgjg.wl%tiwai@suse.de>
--- Takashi Iwai <tiwai@suse.de> wrote:
> The "period" defines the frequency to update the status, usually via
> the invokation of interrupts. The "period_size" defines the frame
> sizes corresponding to the "period time". This term corresponds to
> the "fragment size" on OSS. On major sound hardwares, a ring-buffer
> is divided to several parts and an irq is issued on each boundary.
> The period_size defines the size of this chunk.
>
> On some hardwares, the irq is controlled on the basis of a timer. In
> this case, the period is defined as the timer frequency to invoke an
> irq.
>
>
My system has a hardware buffer of 4096 bytes (so I will use an intermediate
buffer ) and is fixed at 8KHz 16bit stereo. The 4K hw buffer would accommodate
128ms of data which is pretty small. Therefore I'll choose to use a 32K
intermediate buffer which will accommodate about 1sec of audio data. My IRQ is
timer based so I will need to decide upon a reasonable period. As the period
seems to dictate the ability for the middle layer to see the status of the
buffer I'll use 4 periods allowing a 250ms granularity in my intermediate
buffer.
I'm assuming that the snd_pcm_hardware struct has a min AND max period_bytes
and periods because the framesize can vary if your hardware supports multiple
configurations. As mine only supports 8Khz 16bit stereo, my min/max values
should all be the same correct?
So using the above info my struct should look like:
static snd_pcm_hardware_t snd_my_playback_hw = {
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID),
.formats = SNDRV_PCM_FMTBIT_U16_BE,
.rates = SNDRV_PCM_RATE_8000,
.rate_min = 8000,
.rate_max = 8000,
.channels_min = 2,
.channels_max = 2,
.buffer_bytes_max = 32768,
.period_bytes_min = 8192,
.period_bytes_max = 8192,
.periods_min = 4,
.periods_max = 4,
};
Does this seem reasonable?
Because I'm using a 32K intermediate buffer I'll preallocate it with
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
snd_dma_continuous_data(GFP_KERNEL), 0, 32768);
I want to make sure I'm implementing things properly for full duplex
capability. I'm creating the pcm device via:
snd_pcm_new(card, "my dev", 0, 1 /* play streams */, 1 /* capt streams */,
&pcm)
If I understand this preallocation a 32K DMAable buffer will be allocated by
ALSA for each stream my device can play/capture (= 2 streams, 1 playback and 1
capture). I can obtain the buffer pre-allocated from the runtime data in the
prepare callback and use that buffer as my intermediate buffer correct? I
don't have a great grasp of the 'prepare' callback yet, but because thats the
first time you've got access to valid format/buffer info I'll assume that each
time 'prepare' is called your PCM buffer/hardware/stream should be initialized.
If I understand correctly the pointer callback should return the num of frames
processed in the 'intermediate buffer'. Because this is a virtual ring buffer,
I guess I should simply return the offset in the buffer (divided by my
bytes_per_frame which is 4) that I last pulled data from?
I've looked at the example dealing with the hw interrupt and period_elapsed in
http://www.alsa-project.org/~iwai/writing-an-alsa-driver/x773.htm. The example
doesn't specify where it was getting runtime pointer from so I am assuming that
I'll need to keep a pointer to each (playback and capture) substream so that I
can call period_elapsed appropriately for each if they are concurrent?
Thanks for all the help. I've got rudimentary playback working but I'm pretty
sure I'm not implementing the period_elapsed and the pointer callback correctly
as the relatively simple playback app I'm using sits for a few seconds after
playback of the 2 sec test sample I'm using completes.
Tim
next parent reply other threads:[~2007-04-19 21:30 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <s5hwt0cvgjg.wl%tiwai@suse.de>
2007-04-19 21:30 ` Tim Harvey [this message]
2007-04-24 13:13 ` Questions about writing a new ALSA driver for a very limitted device Takashi Iwai
2007-04-26 22:30 Tim Harvey
2007-04-27 17:09 ` Takashi Iwai
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=95415.40128.qm@web35606.mail.mud.yahoo.com \
--to=tim_harvey@yahoo.com \
--cc=alsa-devel@alsa-project.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.