At Fri, 21 Mar 2003 13:31:02 +0100 (CET),
Jaroslav wrote:
> 
> On Fri, 21 Mar 2003, Pieter Palmers wrote:
> 
> > Hi all,
> > 
> > I face the following problem: The card I'm writing a driver for (SAM9707
> > based) doesn't support any form of DMA transfer. It requires you to
> > transfer the PCM data through a 'rep outsw' like mechanism. It raises an
> > interrupt when it needs new data. The transfer flow is as follows:
> >      1) allocate buffer on card
> >      2) start playback
> >      3) card raises interrupt
> >      4) transfer block of data in interrupt handler
> >      5) wait for next interrupt -> 4
> > 
> > How do I implement this in ALSA? After reading the 'Writing an ALSA
> > driver' document a few times, I still cannot figure out how to do this.
> > Should I use the copy/silence callbacks? Or can I access the PCM buffer
> > from within the interrupt handler? I'm currently using 'concept' code
> > from Uros Bizjak, and the interrupt handler looks like this:
> > 
> > (I removed irrelevant pieces)
> > 
> >      substream = voice->substream;
> >      runtime = substream->runtime;
> > 
> >      hwoff = runtime->hw_ptr_interrupt;
> > 
> >      hwbuf = (u16 *) runtime->dma_area;
> >             hwbuf += (frames_to_bytes(runtime, hwoff) >> 1);
> > 
> >      /* word transfer count */
> >      wcount = snd_pcm_lib_period_bytes(substream);
> >      wcount >>= 1;
> > 
> >      /* transfer to/from sam9407 buffers */
> >      if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
> >          sam->writeData16Burst(sam, hwbuf, wcount);
> >      else
> >          sam->readData16Burst(sam, hwbuf, wcount);
> > 
> >      snd_sam9407_command(sam, NULL, SAM_END_XFER,
> >              &voice->channel, 1, NULL, 0, -1);
> > 
> >      /* update hardware pointer mirror */
> >      voice->hwptr = runtime->hw_ptr_interrupt + runtime->period_size;
> > 
> >      snd_pcm_period_elapsed(substream);
> > 
> > But I'm not sure if this is correct.
> > 
> > What should I use here?
> > Is there a card driver that I can refer to that uses the same mechanism?
> 
> This code is ok. It might use probably a little bit better interrupt 
> resolution to sync the DMA ring buffer with hardware more precisely (I 
> mean use the transfer size in interrupt less than the period size).

in the case above, how about the timing?

if the data transfer from memory to the hardware is asynchronous with
the actually played samples (i.e. data is transferred to the h/w
buffer and pending there), which value should pointer() callback
return?

applications often refer to the hw_ptr as the sample position at which
DMA is running or has processed.  but if snd_pcm_period_elapsed() is
issued soon after the buffer transfer (not the buffer process), this
doesn't correspond to the real time (although this still will work in
most cases).


Takashi


-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
Alsa-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-devel

Reply via email to