* pointer callback in pcm @ 2006-03-09 22:21 Adrian McMenamin 2006-03-10 0:53 ` Lee Revell 0 siblings, 1 reply; 19+ messages in thread From: Adrian McMenamin @ 2006-03-09 22:21 UTC (permalink / raw) To: alsa-devel The documentation states: "This callback is called when the PCM middle layer inquires the current hardware position on the buffer." Does that mean the position the hardware is at (in its ring buffer in my case) or does it mean the position we are at in the dma buffer. ie I have a 128k DMA buffer which transfers samples into the 32k hardware memory buffer. Which position am I meant to be reporting? ------------------------------------------------------- This SF.Net email is sponsored by xPML, a groundbreaking scripting language that extends applications into web and mobile media. Attend the live webcast and join the prime developer group breaking into this new coding territory! http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: pointer callback in pcm 2006-03-09 22:21 pointer callback in pcm Adrian McMenamin @ 2006-03-10 0:53 ` Lee Revell 2006-03-10 19:51 ` Adrian McMenamin 0 siblings, 1 reply; 19+ messages in thread From: Lee Revell @ 2006-03-10 0:53 UTC (permalink / raw) To: Adrian McMenamin; +Cc: alsa-devel On Thu, 2006-03-09 at 22:21 +0000, Adrian McMenamin wrote: > The documentation states: > > "This callback is called when the PCM middle layer inquires the current > hardware position on the buffer." > > > Does that mean the position the hardware is at (in its ring buffer in my > case) or does it mean the position we are at in the dma buffer. > > ie I have a 128k DMA buffer which transfers samples into the 32k > hardware memory buffer. Which position am I meant to be reporting? > The DMA buffer should be the same size as the hardware buffer, so the positions should be the same. The pointer callback should return the position of sample that the hardware is currently playing. Lee ------------------------------------------------------- This SF.Net email is sponsored by xPML, a groundbreaking scripting language that extends applications into web and mobile media. Attend the live webcast and join the prime developer group breaking into this new coding territory! http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: pointer callback in pcm 2006-03-10 0:53 ` Lee Revell @ 2006-03-10 19:51 ` Adrian McMenamin 2006-03-10 20:16 ` Takashi Iwai 2006-03-11 11:16 ` James Courtier-Dutton 0 siblings, 2 replies; 19+ messages in thread From: Adrian McMenamin @ 2006-03-10 19:51 UTC (permalink / raw) To: Lee Revell; +Cc: alsa-devel On Thu, 2006-03-09 at 19:53 -0500, Lee Revell wrote: > On Thu, 2006-03-09 at 22:21 +0000, Adrian McMenamin wrote: > > The documentation states: > > > > "This callback is called when the PCM middle layer inquires the current > > hardware position on the buffer." > > > > > > Does that mean the position the hardware is at (in its ring buffer in my > > case) or does it mean the position we are at in the dma buffer. > > > > ie I have a 128k DMA buffer which transfers samples into the 32k > > hardware memory buffer. Which position am I meant to be reporting? > > > > The DMA buffer should be the same size as the hardware buffer, so the > positions should be the same. > > The pointer callback should return the position of sample that the > hardware is currently playing. > Thanks. I am sure I am driving you round the twist now, but that (both buffers being the same size) was a key piece of information I was unaware of. There are several pints in it if you are ever around in North London :) But my basic problem remains - my buffer is 8 periods long and I get to hear them over and over again :( - nothing new is ever fed into the DMA buffer and so nothing new therefore ever gets fed into the hardware buffer. I start the process by transferring a whole eight periods worth into the hardware buffer is that a mistake? Should I always be feeding in one period at a time only? ------------------------------------------------------- This SF.Net email is sponsored by xPML, a groundbreaking scripting language that extends applications into web and mobile media. Attend the live webcast and join the prime developer group breaking into this new coding territory! http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: pointer callback in pcm 2006-03-10 19:51 ` Adrian McMenamin @ 2006-03-10 20:16 ` Takashi Iwai 2006-03-10 20:21 ` Adrian McMenamin 2006-03-10 20:23 ` Lee Revell 2006-03-11 11:16 ` James Courtier-Dutton 1 sibling, 2 replies; 19+ messages in thread From: Takashi Iwai @ 2006-03-10 20:16 UTC (permalink / raw) To: Adrian McMenamin; +Cc: Lee Revell, alsa-devel At Fri, 10 Mar 2006 19:51:01 +0000, Adrian McMenamin wrote: > > On Thu, 2006-03-09 at 19:53 -0500, Lee Revell wrote: > > On Thu, 2006-03-09 at 22:21 +0000, Adrian McMenamin wrote: > > > The documentation states: > > > > > > "This callback is called when the PCM middle layer inquires the current > > > hardware position on the buffer." > > > > > > > > > Does that mean the position the hardware is at (in its ring buffer in my > > > case) or does it mean the position we are at in the dma buffer. > > > > > > ie I have a 128k DMA buffer which transfers samples into the 32k > > > hardware memory buffer. Which position am I meant to be reporting? > > > > > > > The DMA buffer should be the same size as the hardware buffer, so the > > positions should be the same. > > > > The pointer callback should return the position of sample that the > > hardware is currently playing. > > > Thanks. I am sure I am driving you round the twist now, but that (both > buffers being the same size) was a key piece of information I was > unaware of. There are several pints in it if you are ever around in > North London :) > > But my basic problem remains - my buffer is 8 periods long and I get to > hear them over and over again :( - nothing new is ever fed into the DMA > buffer and so nothing new therefore ever gets fed into the hardware > buffer. > > I start the process by transferring a whole eight periods worth into the > hardware buffer is that a mistake? Should I always be feeding in one > period at a time only? Hm, I've not checked your code and thread due to lack of my free time for ALSA recently, but the symptom above sounds like you implemented copy callback but still using mmap. The copy callback is designed basically only for read/write transfer. In the mmap mode, of course, such read/write transfer is eliminated, and no copy action occurs. Thus, first try not to set MMAP flag and let alsa-lib use the traditional read/write method. Some hardwares have actually separate h/w buffer and the memory buffer (s/w buffer). Even with such hardwares, mmap can be implemented. Instead of DMA transfer by hardware, the driver copies data between h/w and s/w buffers on demand, namely, before starting the stream (in trigger callback) and when each period is consumed (via ack callback). There are userful functions for such a case, found in pcm-indirect.h. They are used emu10k1 FX mode and cs46xx. HTH, Takashi ------------------------------------------------------- This SF.Net email is sponsored by xPML, a groundbreaking scripting language that extends applications into web and mobile media. Attend the live webcast and join the prime developer group breaking into this new coding territory! http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: pointer callback in pcm 2006-03-10 20:16 ` Takashi Iwai @ 2006-03-10 20:21 ` Adrian McMenamin 2006-03-10 20:23 ` Lee Revell 1 sibling, 0 replies; 19+ messages in thread From: Adrian McMenamin @ 2006-03-10 20:21 UTC (permalink / raw) To: Takashi Iwai; +Cc: Lee Revell, alsa-devel On Fri, 2006-03-10 at 21:16 +0100, Takashi Iwai wrote: > > Hm, I've not checked your code and thread due to lack of my free time > for ALSA recently, but the symptom above sounds like you implemented > copy callback but still using mmap. > No, I'm not using copy or mmap (the code is at http://newgolddream.dyndns.info/cgi-bin/cvsweb these days) > The copy callback is designed basically only for read/write transfer. > In the mmap mode, of course, such read/write transfer is eliminated, > and no copy action occurs. > > Thus, first try not to set MMAP flag and let alsa-lib use the > traditional read/write method. > > Some hardwares have actually separate h/w buffer and the memory > buffer (s/w buffer). Even with such hardwares, mmap can be > implemented. Instead of DMA transfer by hardware, the driver copies > data between h/w and s/w buffers on demand, namely, before starting > the stream (in trigger callback) and when each period is consumed (via > ack callback). This is quite like my device - but I know nothing about the ack device > > There are userful functions for such a case, found in pcm-indirect.h. > They are used emu10k1 FX mode and cs46xx. > I'll look > > HTH, > > Takashi ------------------------------------------------------- This SF.Net email is sponsored by xPML, a groundbreaking scripting language that extends applications into web and mobile media. Attend the live webcast and join the prime developer group breaking into this new coding territory! http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: pointer callback in pcm 2006-03-10 20:16 ` Takashi Iwai 2006-03-10 20:21 ` Adrian McMenamin @ 2006-03-10 20:23 ` Lee Revell 1 sibling, 0 replies; 19+ messages in thread From: Lee Revell @ 2006-03-10 20:23 UTC (permalink / raw) To: Takashi Iwai; +Cc: Adrian McMenamin, alsa-devel On Fri, 2006-03-10 at 21:16 +0100, Takashi Iwai wrote: > Some hardwares have actually separate h/w buffer and the memory > buffer (s/w buffer). Even with such hardwares, mmap can be > implemented. Instead of DMA transfer by hardware, the driver copies > data between h/w and s/w buffers on demand, namely, before starting > the stream (in trigger callback) and when each period is consumed (via > ack callback). > > There are userful functions for such a case, found in pcm-indirect.h. > They are used emu10k1 FX mode and cs46xx. > Adrian has a weird case - his hardware *does* have DMA but it must be reprogrammed every period. So no copying is required in the driver. The driver guide assumes that once the DMA is started, it will repeatedly fill the buffer until we tell it to stop. So, I thought that the DMA could be programmed in the copy callback each period. But maybe this should go in the ack callback. Lee ------------------------------------------------------- This SF.Net email is sponsored by xPML, a groundbreaking scripting language that extends applications into web and mobile media. Attend the live webcast and join the prime developer group breaking into this new coding territory! http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: pointer callback in pcm 2006-03-10 19:51 ` Adrian McMenamin 2006-03-10 20:16 ` Takashi Iwai @ 2006-03-11 11:16 ` James Courtier-Dutton 2006-03-11 11:27 ` Adrian McMenamin 1 sibling, 1 reply; 19+ messages in thread From: James Courtier-Dutton @ 2006-03-11 11:16 UTC (permalink / raw) To: Adrian McMenamin; +Cc: Lee Revell, alsa-devel Adrian, Here is a quick summary of what I think you have been saying. 1) Your hardware has min and max periods set to 8. 2) Your hardware can do DMA, but not periodic DMA. <- This is really the crux of the problem. 3) You wish to use DMA. 4) Unknown: What triggers the audio interrupt? It should be triggered once each period is completed. Now, here is what the ALSA model assumes: 1) hardware period sizes are exactly the same size as the memory mapped DMA pages. 2) snd_period_ellapsed() is called at periodic intervals dependent on where the ADC is playing samples. 3) If the copy callback is NULL, ALSA assumes the DMA has already completed. 4) If the copy callback is not NULL, ALSA calls it, but when the copy callback returns, the copy has been completed. 5) The pointer callback is then called that should return the position of the ADC in frames (not bytes) within the audio buffer. So, if you wish to use DMA, you should be calling snd_period_ellapsed() only after the DMA has completed, alternatively, the copy() callback should only return after the DMA transaction has completed, but I don't know if delaying the copy() return is allowed. Can you get it to interrupt on each DMA completion? I would recommend you trying to do the following: 1) Discover when the ADC has played the entire period. 2) start the DMA transfer. 3) At the DMA transfer complete interrrupt, call period_ellapsed(). So, the problem might be how to discover that the ADC has played the entire period. You might have to use some sort of timer based polling to discover this. James ------------------------------------------------------- This SF.Net email is sponsored by xPML, a groundbreaking scripting language that extends applications into web and mobile media. Attend the live webcast and join the prime developer group breaking into this new coding territory! http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: pointer callback in pcm 2006-03-11 11:16 ` James Courtier-Dutton @ 2006-03-11 11:27 ` Adrian McMenamin 2006-03-11 15:42 ` James Courtier-Dutton 0 siblings, 1 reply; 19+ messages in thread From: Adrian McMenamin @ 2006-03-11 11:27 UTC (permalink / raw) To: James Courtier-Dutton, Lee Revell, Alsa-devel On Sat, 2006-03-11 at 11:16 +0000, James Courtier-Dutton wrote: > Adrian, > > Here is a quick summary of what I think you have been saying. > 1) Your hardware has min and max periods set to 8. > 2) Your hardware can do DMA, but not periodic DMA. <- This is really > the crux of the problem. > 3) You wish to use DMA. I really need to because transfers between the sound memory and the main memory are very slow otherwise. When I wrote the OSS driver for this a few years ago I simply copied stuff over, but it would effectively lock the machine up at high sample rates. > 4) Unknown: What triggers the audio interrupt? It should be triggered > once each period is completed. This is done by the ARM7 spu that controls the sound output. I write the "firmware" for that so I have written some code that puts an IRQ on the SH4 (main CPU) bus every time a period has been played out. > > Now, here is what the ALSA model assumes: > 1) hardware period sizes are exactly the same size as the memory mapped > DMA pages. I wasn't aware of that but I think I've done that anyway (4k period size) > 2) snd_period_ellapsed() is called at periodic intervals dependent on > where the ADC is playing samples. > 3) If the copy callback is NULL, ALSA assumes the DMA has already completed. > 4) If the copy callback is not NULL, ALSA calls it, but when the copy > callback returns, the copy has been completed. I haven't got a copy callback - should I write one? > 5) The pointer callback is then called that should return the position > of the ADC in frames (not bytes) within the audio buffer. > > So, if you wish to use DMA, you should be calling snd_period_ellapsed() > only after the DMA has completed, alternatively, the copy() callback > should only return after the DMA transaction has completed, but I don't > know if delaying the copy() return is allowed. > Can you get it to interrupt on each DMA completion? > In theory yes, but nobody seems have managed to reverse that bit of the spu function effectively yet, so I'd have to use polling on the progress of the transfer. > I would recommend you trying to do the following: > 1) Discover when the ADC has played the entire period. > 2) start the DMA transfer. > 3) At the DMA transfer complete interrrupt, call period_ellapsed(). > > So, the problem might be how to discover that the ADC has played the > entire period. I've got that covered (see above). How do I start? I am copying over 8 periods via DMA on the trigger, is that ok? (These are all I ever hear getting played). What about the ack callback that was recommended to me yesterday? > You might have to use some sort of timer based polling to discover this. > > James ------------------------------------------------------- This SF.Net email is sponsored by xPML, a groundbreaking scripting language that extends applications into web and mobile media. Attend the live webcast and join the prime developer group breaking into this new coding territory! http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: pointer callback in pcm 2006-03-11 11:27 ` Adrian McMenamin @ 2006-03-11 15:42 ` James Courtier-Dutton 2006-03-11 15:53 ` Adrian McMenamin 2006-03-11 17:30 ` Adrian McMenamin 0 siblings, 2 replies; 19+ messages in thread From: James Courtier-Dutton @ 2006-03-11 15:42 UTC (permalink / raw) To: Adrian McMenamin; +Cc: Lee Revell, Alsa-devel Adrian McMenamin wrote: > On Sat, 2006-03-11 at 11:16 +0000, James Courtier-Dutton wrote: > >> Adrian, >> >> Here is a quick summary of what I think you have been saying. >> 1) Your hardware has min and max periods set to 8. >> 2) Your hardware can do DMA, but not periodic DMA. <- This is really >> the crux of the problem. >> 3) You wish to use DMA. >> > > I really need to because transfers between the sound memory and the main > memory are very slow otherwise. When I wrote the OSS driver for this a > few years ago I simply copied stuff over, but it would effectively lock > the machine up at high sample rates. > The "problem" is that the DMA is not periodic, DMA itself is not the problem. > >> 4) Unknown: What triggers the audio interrupt? It should be triggered >> once each period is completed. >> > > > This is done by the ARM7 spu that controls the sound output. I write the > "firmware" for that so I have written some code that puts an IRQ on the > SH4 (main CPU) bus every time a period has been played out. > Can you get the "firmware" to initiate the DMA transfer, and then only IRQ the SH4 when the DMA completes? > >> Now, here is what the ALSA model assumes: >> 1) hardware period sizes are exactly the same size as the memory mapped >> DMA pages. >> > > I wasn't aware of that but I think I've done that anyway (4k period > size) > > >> 2) snd_period_ellapsed() is called at periodic intervals dependent on >> where the ADC is playing samples. >> 3) If the copy callback is NULL, ALSA assumes the DMA has already completed. >> 4) If the copy callback is not NULL, ALSA calls it, but when the copy >> callback returns, the copy has been completed. >> > > I haven't got a copy callback - should I write one? > You have to write one, but the ack() callback is probably more suitable in your case, if the period_ellapsed is called without the audio samples already being in main memory. (i.e. after the DMA is complete) > >> 5) The pointer callback is then called that should return the position >> of the ADC in frames (not bytes) within the audio buffer. >> >> So, if you wish to use DMA, you should be calling snd_period_ellapsed() >> only after the DMA has completed, alternatively, the copy() callback >> should only return after the DMA transaction has completed, but I don't >> know if delaying the copy() return is allowed. >> Can you get it to interrupt on each DMA completion? >> >> > > In theory yes, but nobody seems have managed to reverse that bit of the > spu function effectively yet, so I'd have to use polling on the progress > of the transfer. > > > >> I would recommend you trying to do the following: >> 1) Discover when the ADC has played the entire period. >> 2) start the DMA transfer. >> 3) At the DMA transfer complete interrrupt, call period_ellapsed(). >> >> So, the problem might be how to discover that the ADC has played the >> entire period. >> > > I've got that covered (see above). > > How do I start? I am copying over 8 periods via DMA on the trigger, is > that ok? (These are all I ever hear getting played). What about the ack > callback that was recommended to me yesterday? > > >> You might have to use some sort of timer based polling to discover this. >> >> James >> Some questions: 1) How does the main CPU discover the hardware pointer of the current ADC position? Needed for the pointer() callback. 2) Can you start and stop the samples being played? Initialisation: 1) Wait for the application to fill 8 periods. (you can simulate other periods models later if you wish. e.g You could simulate 2 periods to the application, even though you have 8 in hardware.) 2) The application will then call trigger to start playing the samples in the buffer. I would recommend you try the following in the audio interrupt: 1) receive audio interrupt 2) start DMA transfer of one period. Which period you copy is the important bit here. At this point the hardware will have played 1 period, so you replace the period that has just played, not the period that is about to be played. 3) call snd_period_elapsed() 4) poll for DMA complete in the ack() callback. 5) period_elapsed will in turn call the pointer() callback. James ------------------------------------------------------- This SF.Net email is sponsored by xPML, a groundbreaking scripting language that extends applications into web and mobile media. Attend the live webcast and join the prime developer group breaking into this new coding territory! http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: pointer callback in pcm 2006-03-11 15:42 ` James Courtier-Dutton @ 2006-03-11 15:53 ` Adrian McMenamin 2006-03-11 17:30 ` Adrian McMenamin 1 sibling, 0 replies; 19+ messages in thread From: Adrian McMenamin @ 2006-03-11 15:53 UTC (permalink / raw) To: James Courtier-Dutton; +Cc: Lee Revell, Alsa-devel On Sat, 2006-03-11 at 15:42 +0000, James Courtier-Dutton wrote: > >> > > Some questions: > 1) How does the main CPU discover the hardware pointer of the current > ADC position? Needed for the pointer() callback. Reads a value in a register in the ARM7/SPU memory - simple proceedure > 2) Can you start and stop the samples being played? > Yes - by poking a value into a different register > Initialisation: > 1) Wait for the application to fill 8 periods. (you can simulate other > periods models later if you wish. e.g You could simulate 2 periods to > the application, even though you have 8 in hardware.) > 2) The application will then call trigger to start playing the samples > in the buffer. > Not sure I understand this! How can my kernel code know what the application has done? > I would recommend you try the following in the audio interrupt: > 1) receive audio interrupt > 2) start DMA transfer of one period. > Which period you copy is the important bit here. At this point the > hardware will have played 1 period, so you replace the period that has > just played, not the period that is about to be played. I do this already. the problem is that the buffer contents never change - ie when I replay period 0 after it has played I am just replacing it with exactly the same sample as was there in the first place - nothing new gets sucked in from userspace > 3) call snd_period_elapsed() > 4) poll for DMA complete in the ack() callback. This is something I am not doing now but it's easy to do if somewhat processor intensive. Can the ack callback sleep? > 5) period_elapsed will in turn call the pointer() callback. > > James > ------------------------------------------------------- This SF.Net email is sponsored by xPML, a groundbreaking scripting language that extends applications into web and mobile media. Attend the live webcast and join the prime developer group breaking into this new coding territory! http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: pointer callback in pcm 2006-03-11 15:42 ` James Courtier-Dutton 2006-03-11 15:53 ` Adrian McMenamin @ 2006-03-11 17:30 ` Adrian McMenamin 2006-03-11 18:47 ` James Courtier-Dutton 1 sibling, 1 reply; 19+ messages in thread From: Adrian McMenamin @ 2006-03-11 17:30 UTC (permalink / raw) To: James Courtier-Dutton; +Cc: Lee Revell, Alsa-devel On Sat, 2006-03-11 at 15:42 +0000, James Courtier-Dutton wrote: > 2) start DMA transfer of one period. > Which period you copy is the important bit here. At this point the > hardware will have played 1 period, so you replace the period that has > just played, not the period that is about to be played. I am just sitting down to write this code now, but where in the dma buffer should I look for this period. The relevant code at the moment looks like this: dma_xfer(0, runtime->dma_area + (0x1000 * dreamcastcard->clicks), 0x11000 + (0x1000 * dreamcastcard->clicks), 0x1000, 5); (clicks is always equal to the period that has just played out ie the code does this Get interrupt Reset interrupt flag on ARM7 side dma transfer clicks++ if (clicks == 8) clicks = 0 call pcm_elapsed return with acknowledge interrupt The hardware buffer begins at 0x11000 in the ARM7 space and each period is 0x1000 in size - but I am rather assuming you can rely on the DMA buffer (8 periods long) being filled up at 8 period intervals -is that right? ------------------------------------------------------- This SF.Net email is sponsored by xPML, a groundbreaking scripting language that extends applications into web and mobile media. Attend the live webcast and join the prime developer group breaking into this new coding territory! http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: pointer callback in pcm 2006-03-11 17:30 ` Adrian McMenamin @ 2006-03-11 18:47 ` James Courtier-Dutton 2006-03-11 19:08 ` Adrian McMenamin 2006-03-11 19:26 ` Adrian McMenamin 0 siblings, 2 replies; 19+ messages in thread From: James Courtier-Dutton @ 2006-03-11 18:47 UTC (permalink / raw) To: Adrian McMenamin; +Cc: Lee Revell, Alsa-devel Adrian McMenamin wrote: > On Sat, 2006-03-11 at 15:42 +0000, James Courtier-Dutton wrote: > > > >> 2) start DMA transfer of one period. >> Which period you copy is the important bit here. At this point the >> hardware will have played 1 period, so you replace the period that has >> just played, not the period that is about to be played. >> > > I am just sitting down to write this code now, but where in the dma > buffer should I look for this period. The relevant code at the moment > looks like this: > > dma_xfer(0, runtime->dma_area + (0x1000 * dreamcastcard->clicks), > 0x11000 + (0x1000 * dreamcastcard->clicks), 0x1000, 5); > > > (clicks is always equal to the period that has just played out ie the > code does this > > Get interrupt > Reset interrupt flag on ARM7 side > dma transfer > clicks++ > if (clicks == 8) clicks = 0 > call pcm_elapsed > return with acknowledge interrupt > > > The hardware buffer begins at 0x11000 in the ARM7 space and each period > is 0x1000 in size - but I am rather assuming you can rely on the DMA > buffer (8 periods long) being filled up at 8 period intervals -is that > right? > > > Ok, I looked at the code now, and there are a few things that need fixing. 1) static snd_pcm_hardware_t snd_pcm_aica_playback_hw = { .info = (SNDRV_PCM_INFO_NONINTERLEAVED), .formats = (SNDRV_PCM_FMTBIT_S8|SNDRV_PCM_FMTBIT_U8|SNDRV_PCM_FMTBIT_S16_LE|SNDRV_PCM_FMTBIT_IMA_ADPCM), .rates = SNDRV_PCM_RATE_8000_48000, .rate_min = 8000, .rate_max = 48000, .channels_min = 1, .channels_max = 1, .buffer_bytes_max = 32768, .period_bytes_min = 4096, .period_bytes_max = 4096, .periods_min = 1, .periods_max = 8, }; If the card can only do 8 periods, make .periods_min = 8, Can the card handle all these formats and rates in hardware. Is it really only a mono sound channel? You will need to set the .buffer_bytes_min as well. 2) static snd_pcm_uframes_t snd_aicapcm_pcm_pointer(snd_pcm_substream_t *substream) { return readl(0xa0810004 + 4); } What sort of values should this return during playback? Add a printk to log some of them. The value should be in "frames" and not "bytes" Use the ALSA function bytes_to_frames(runtime, value) to automatically do the adjustments from bytes to frames. If the returned value is just period number, then you will have to multiply it up to the "frames" scale. In case you missed it in the docs. "Frames" are units of samples equivalent to all the bytes needed to play one PCM sample in all channels. E.g. 16 bit Stereo sound takes 4 bytes per sample for all channels. This equals 1 frame. 16 bit mono takes 2 bytes per sample for all channels. This equals 1 frame. James ------------------------------------------------------- This SF.Net email is sponsored by xPML, a groundbreaking scripting language that extends applications into web and mobile media. Attend the live webcast and join the prime developer group breaking into this new coding territory! http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: pointer callback in pcm 2006-03-11 18:47 ` James Courtier-Dutton @ 2006-03-11 19:08 ` Adrian McMenamin 2006-03-11 19:15 ` James Courtier-Dutton 2006-03-11 19:26 ` Adrian McMenamin 1 sibling, 1 reply; 19+ messages in thread From: Adrian McMenamin @ 2006-03-11 19:08 UTC (permalink / raw) To: James Courtier-Dutton; +Cc: Lee Revell, Alsa-devel On Sat, 2006-03-11 at 18:47 +0000, James Courtier-Dutton wrote: > Adrian McMenamin wrote: > > On Sat, 2006-03-11 at 15:42 +0000, James Courtier-Dutton wrote: > > > > > > > >> 2) start DMA transfer of one period. > >> Which period you copy is the important bit here. At this point the > >> hardware will have played 1 period, so you replace the period that has > >> just played, not the period that is about to be played. > >> > > > > I am just sitting down to write this code now, but where in the dma > > buffer should I look for this period. The relevant code at the moment > > looks like this: > > > > dma_xfer(0, runtime->dma_area + (0x1000 * dreamcastcard->clicks), > > 0x11000 + (0x1000 * dreamcastcard->clicks), 0x1000, 5); > > > > > > (clicks is always equal to the period that has just played out ie the > > code does this > > > > Get interrupt > > Reset interrupt flag on ARM7 side > > dma transfer > > clicks++ > > if (clicks == 8) clicks = 0 > > call pcm_elapsed > > return with acknowledge interrupt > > > > > > The hardware buffer begins at 0x11000 in the ARM7 space and each period > > is 0x1000 in size - but I am rather assuming you can rely on the DMA > > buffer (8 periods long) being filled up at 8 period intervals -is that > > right? > > > > > > > Ok, I looked at the code now, and there are a few things that need fixing. > 1) > > static snd_pcm_hardware_t snd_pcm_aica_playback_hw = { > > .info = (SNDRV_PCM_INFO_NONINTERLEAVED), > .formats = (SNDRV_PCM_FMTBIT_S8|SNDRV_PCM_FMTBIT_U8|SNDRV_PCM_FMTBIT_S16_LE|SNDRV_PCM_FMTBIT_IMA_ADPCM), > .rates = SNDRV_PCM_RATE_8000_48000, > .rate_min = 8000, > .rate_max = 48000, > .channels_min = 1, > .channels_max = 1, > .buffer_bytes_max = 32768, > .period_bytes_min = 4096, > .period_bytes_max = 4096, > .periods_min = 1, > .periods_max = 8, > }; > > If the card can only do 8 periods, make .periods_min = 8, OK, will do > Can the card handle all these formats and rates in hardware. yes > Is it really only a mono sound channel? no, but the stereo separation stuff is a second order task - getting it to play mono is a necessary first step :) To play stereo I need two channels with one panned to the left and the other to the right (I can set that up in the "firmware") and that means writing sep code in SH4 and two dma transfers > You will need to set the .buffer_bytes_min as well. > To what value? 1 or 32768? > > 2) > static snd_pcm_uframes_t snd_aicapcm_pcm_pointer(snd_pcm_substream_t > *substream) > > { > return readl(0xa0810004 + 4); > } > > What sort of values should this return during playback? > Add a printk to log some of them. > The value should be in "frames" and not "bytes" It should be doing all that anyway - it returns the numbers of samples (ie frames) played in the chosen (in ARM7 code) channel - and as all this is mono that ought to work unchanged for now, but I will check it as you suggest. > Use the ALSA function bytes_to_frames(runtime, value) to automatically > do the adjustments from bytes to frames. > If the returned value is just period number, then you will have to > multiply it up to the "frames" scale. > In case you missed it in the docs. "Frames" are units of samples > equivalent to all the bytes needed to play one PCM sample in all channels. > E.g. 16 bit Stereo sound takes 4 bytes per sample for all channels. This > equals 1 frame. > 16 bit mono takes 2 bytes per sample for all channels. This equals 1 frame. > > > James > > > > ------------------------------------------------------- > This SF.Net email is sponsored by xPML, a groundbreaking scripting language > that extends applications into web and mobile media. Attend the live webcast > and join the prime developer group breaking into this new coding territory! > http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642 > _______________________________________________ > Alsa-devel mailing list > Alsa-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/alsa-devel ------------------------------------------------------- This SF.Net email is sponsored by xPML, a groundbreaking scripting language that extends applications into web and mobile media. Attend the live webcast and join the prime developer group breaking into this new coding territory! http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: pointer callback in pcm 2006-03-11 19:08 ` Adrian McMenamin @ 2006-03-11 19:15 ` James Courtier-Dutton 2006-03-11 19:18 ` Adrian McMenamin 0 siblings, 1 reply; 19+ messages in thread From: James Courtier-Dutton @ 2006-03-11 19:15 UTC (permalink / raw) To: Adrian McMenamin; +Cc: Lee Revell, Alsa-devel Adrian McMenamin wrote: >> You will need to set the .buffer_bytes_min as well. >> >> > > To what value? 1 or 32768? > > 32768 >> 2) >> static snd_pcm_uframes_t snd_aicapcm_pcm_pointer(snd_pcm_substream_t >> *substream) >> >> { >> return readl(0xa0810004 + 4); >> } >> >> What sort of values should this return during playback? >> Add a printk to log some of them. >> The value should be in "frames" and not "bytes" >> > > It should be doing all that anyway - it returns the numbers of samples > (ie frames) played in the chosen (in ARM7 code) channel - and as all > this is mono that ought to work unchanged for now, but I will check it > as you suggest. > Ok, that is not what is needed. The value returned should be the position of the ADC in the hardware's ring buffer in units of frames. Not the cumulative number of samples played. E.g. If the buffer is 32768 frames long, the returned value should only have a value from 0 to 32767 Once it gets to 32767, it should then role over to 0 again. James ------------------------------------------------------- This SF.Net email is sponsored by xPML, a groundbreaking scripting language that extends applications into web and mobile media. Attend the live webcast and join the prime developer group breaking into this new coding territory! http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: pointer callback in pcm 2006-03-11 19:15 ` James Courtier-Dutton @ 2006-03-11 19:18 ` Adrian McMenamin 2006-03-11 19:37 ` James Courtier-Dutton 0 siblings, 1 reply; 19+ messages in thread From: Adrian McMenamin @ 2006-03-11 19:18 UTC (permalink / raw) To: James Courtier-Dutton; +Cc: Lee Revell, Alsa-devel On Sat, 2006-03-11 at 19:15 +0000, James Courtier-Dutton wrote: > > > Ok, that is not what is needed. > The value returned should be the position of the ADC in the hardware's > ring buffer in units of frames. > Not the cumulative number of samples played. > E.g. If the buffer is 32768 frames long, the returned value should only > have a value from 0 to 32767 > Once it gets to 32767, it should then role over to 0 again. > Yes, that's what I meant :) Sorry if I wasn't clear enough. ------------------------------------------------------- This SF.Net email is sponsored by xPML, a groundbreaking scripting language that extends applications into web and mobile media. Attend the live webcast and join the prime developer group breaking into this new coding territory! http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: pointer callback in pcm 2006-03-11 19:18 ` Adrian McMenamin @ 2006-03-11 19:37 ` James Courtier-Dutton 2006-03-11 19:55 ` Adrian McMenamin 0 siblings, 1 reply; 19+ messages in thread From: James Courtier-Dutton @ 2006-03-11 19:37 UTC (permalink / raw) To: Adrian McMenamin; +Cc: Lee Revell, Alsa-devel Adrian McMenamin wrote: > On Sat, 2006-03-11 at 19:15 +0000, James Courtier-Dutton wrote: > > >>> >>> >> Ok, that is not what is needed. >> The value returned should be the position of the ADC in the hardware's >> ring buffer in units of frames. >> Not the cumulative number of samples played. >> E.g. If the buffer is 32768 frames long, the returned value should only >> have a value from 0 to 32767 >> Once it gets to 32767, it should then role over to 0 again. >> >> > Yes, that's what I meant :) Sorry if I wasn't clear enough. > Which application are you using to test. Have you tried "speaker-test" James ------------------------------------------------------- This SF.Net email is sponsored by xPML, a groundbreaking scripting language that extends applications into web and mobile media. Attend the live webcast and join the prime developer group breaking into this new coding territory! http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: pointer callback in pcm 2006-03-11 19:37 ` James Courtier-Dutton @ 2006-03-11 19:55 ` Adrian McMenamin 0 siblings, 0 replies; 19+ messages in thread From: Adrian McMenamin @ 2006-03-11 19:55 UTC (permalink / raw) To: James Courtier-Dutton; +Cc: Lee Revell, Alsa-devel On Sat, 2006-03-11 at 19:37 +0000, James Courtier-Dutton wrote: > Adrian McMenamin wrote: > > On Sat, 2006-03-11 at 19:15 +0000, James Courtier-Dutton wrote: > > > > > >>> > >>> > >> Ok, that is not what is needed. > >> The value returned should be the position of the ADC in the hardware's > >> ring buffer in units of frames. > >> Not the cumulative number of samples played. > >> E.g. If the buffer is 32768 frames long, the returned value should only > >> have a value from 0 to 32767 > >> Once it gets to 32767, it should then role over to 0 again. > >> > >> > > Yes, that's what I meant :) Sorry if I wasn't clear enough. > > > Which application are you using to test. > Have you tried "speaker-test" I cannot get aplay to work so I am just do cat somefile.wav > /dev/dsp As I couldn't get the ack callback to work I have just rewritten the interrupt handler as below: static irqreturn_t aica_period_elapsed(int irq, void *dev_id, struct pt_regs *regs) { int transferred; snd_pcm_runtime_t *runtime; if (dev_id != dreamcastcard) return IRQ_NONE; /* clear the interrupt on the ARM side */ spu_memset(0x28BC, 0x20, 4); runtime = (((snd_card_aica_t *)dev_id)->substream)->runtime; dma_xfer(0, runtime->dma_area + (0x1000 * dreamcastcard->clicks), 0x11000 + (0x1000 * dreamcastcard->clicks), 0x1000, 5); do { mdelay(1); transferred = get_dma_residue(0); snd_printk("Transfer reports 0x%X\n", transferred); } while (transferred < 0x1000); snd_pcm_period_elapsed(((snd_card_aica_t *)dev_id)->substream); dreamcastcard->clicks++; if (dreamcastcard->clicks == 8) dreamcastcard->clicks = 0; snd_printk("Clicks is %d\n", dreamcastcard->clicks); return IRQ_HANDLED; } which shows the transfers work (the rate is about 12 Mb/s so it's fast) but still just plays the same stuff over and over in an endless loop :( ------------------------------------------------------- This SF.Net email is sponsored by xPML, a groundbreaking scripting language that extends applications into web and mobile media. Attend the live webcast and join the prime developer group breaking into this new coding territory! http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: pointer callback in pcm 2006-03-11 18:47 ` James Courtier-Dutton 2006-03-11 19:08 ` Adrian McMenamin @ 2006-03-11 19:26 ` Adrian McMenamin 2006-03-11 19:35 ` James Courtier-Dutton 1 sibling, 1 reply; 19+ messages in thread From: Adrian McMenamin @ 2006-03-11 19:26 UTC (permalink / raw) To: James Courtier-Dutton; +Cc: Lee Revell, Alsa-devel On Sat, 2006-03-11 at 18:47 +0000, James Courtier-Dutton wrote: > > You will need to set the .buffer_bytes_min as well. Are you sure this exists? I get a compiler error ------------------------------------------------------- This SF.Net email is sponsored by xPML, a groundbreaking scripting language that extends applications into web and mobile media. Attend the live webcast and join the prime developer group breaking into this new coding territory! http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: pointer callback in pcm 2006-03-11 19:26 ` Adrian McMenamin @ 2006-03-11 19:35 ` James Courtier-Dutton 0 siblings, 0 replies; 19+ messages in thread From: James Courtier-Dutton @ 2006-03-11 19:35 UTC (permalink / raw) To: Adrian McMenamin; +Cc: Lee Revell, Alsa-devel Adrian McMenamin wrote: > On Sat, 2006-03-11 at 18:47 +0000, James Courtier-Dutton wrote: > > > > >> You will need to set the .buffer_bytes_min as well. >> > > Are you sure this exists? I get a compiler error > > > Sorry, my mistake. ------------------------------------------------------- This SF.Net email is sponsored by xPML, a groundbreaking scripting language that extends applications into web and mobile media. Attend the live webcast and join the prime developer group breaking into this new coding territory! http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642 ^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2006-03-11 19:55 UTC | newest] Thread overview: 19+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-03-09 22:21 pointer callback in pcm Adrian McMenamin 2006-03-10 0:53 ` Lee Revell 2006-03-10 19:51 ` Adrian McMenamin 2006-03-10 20:16 ` Takashi Iwai 2006-03-10 20:21 ` Adrian McMenamin 2006-03-10 20:23 ` Lee Revell 2006-03-11 11:16 ` James Courtier-Dutton 2006-03-11 11:27 ` Adrian McMenamin 2006-03-11 15:42 ` James Courtier-Dutton 2006-03-11 15:53 ` Adrian McMenamin 2006-03-11 17:30 ` Adrian McMenamin 2006-03-11 18:47 ` James Courtier-Dutton 2006-03-11 19:08 ` Adrian McMenamin 2006-03-11 19:15 ` James Courtier-Dutton 2006-03-11 19:18 ` Adrian McMenamin 2006-03-11 19:37 ` James Courtier-Dutton 2006-03-11 19:55 ` Adrian McMenamin 2006-03-11 19:26 ` Adrian McMenamin 2006-03-11 19:35 ` James Courtier-Dutton
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.