06 February 2023, 14:52 | #1 |
Registered User
Join Date: May 2022
Location: Canada
Posts: 140
|
Understanding DMA audio
Hello Amiga coders,
I would like some guidance or help understanding correctly the audio DMA of the Amiga, while I am attempting to fix the 'audio DMA hack' warnings I am seeing, thanks to WinUAE being able to detect such cases. My example scenario would be: How do you change the sound on a channel that is already playing? (bonus: Ideally, without interrupts). The way I see it, and please help me understand if I am wrong: - a DMA audio channel is currently playing something - In order to change the sound, first step is turning off DMA for that channel - Wait until Paula take notice of the disabled DMA (approximately on color clock #15 of the next scaneline (is this step necessary?) - Set new sound data and sound length in AUD* registers - Turn audio channel DMA on - Wait until Paula starts the DMA (approx clock #15 on the next scanline (?)) - Now set sound data and length again (either for setting up loop, or for setting it to first empty word and length of 1 to 'play once' What I understand from the documentation is that an interrupt request will be raised on intreqr in two cases: - Either Paula starts the DMA - Or Paula reached the length of the sound and refetched the sample data and length: basically, it signals "hey, this audio channel has looped." I noticed that there is not always a DMA fetch on each scanline: If I set a period higher than 226, for example period 3000, I will only see a DMA fetch every 26 scanlines. |
06 February 2023, 16:48 | #2 | |||||
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,539
|
Quote:
Quote:
Quote:
Quote:
Quote:
|
|||||
06 February 2023, 18:30 | #3 | |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 54
Posts: 4,491
|
Quote:
Is it due to faster IRQ response? For the rest Paula and the transfer through DMAL is the same so it's not due to the chipset, I hope.. I should put myself in a good will and deeply check your code for what exactly happens. I don't like a value whose choice I don't accurately understand |
|
06 February 2023, 19:34 | #4 |
Registered User
Join Date: Sep 2009
Location: Norway
Posts: 1,715
|
Unless... you do a carefully crafted combination of 1xx (pitch slide up) and a high note (low period), it will underflow because of a signed/unsigned comparison bug in the period clamping. I think this bug exists in every PT player. You can reach periods up to 4095 this way.
https://16-bits.org/etc/period_underflow.mod Yeah, I'll leave now. |
06 February 2023, 19:48 | #5 |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 54
Posts: 4,491
|
|
06 February 2023, 22:07 | #6 |
Registered User
Join Date: May 2022
Location: Canada
Posts: 140
|
Many thanks (all of you), this is going to be very helpful.
Now, can I use intreqr to read the interrupt bit, even if I don't intend to enable or use interrupts? (meaning my code would notice with intreqr is raised for a channel and would know "something happened"). Follow-up question: When I turn audio dma off, can I immediately set AC ptr and len? Since they won't be fetched by Paula because at the next dma request, it will take notice that DMA is now off, which will shut the channel? Then when re-enabling DMA, Paula will fetch the ptr+len? (This brings me an additional technical question: does it mean that Paula "senses" if DMA became enabled at every scanline? Since there is no running audio, thus no period, is it how it works? Meaning that "turning off" is not as fast as turning on, because turning off depends on currently set period, which could be up to 65535 -> over 2 frames of delay before the turn off takes effect...?) Of course, this 65535 period is silly and would be inaudible and not useful, but curiosity and for the sake of understanding.. |
07 February 2023, 08:14 | #7 | ||||
WinUAE developer
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,570
|
Quote:
Quote:
Quote:
DMA off: it is usually checked when audio state changes. For example it is never checked during period counting (which explains need for "dma wait": EDIT: it has to work this way because of non-DMA mode) Quote:
Check HRM audio state diagram. It explains (mostly) everything. Last edited by Toni Wilen; 07 February 2023 at 11:18. |
||||
07 February 2023, 10:46 | #8 |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 54
Posts: 4,491
|
Just a small note about the period: the underflow occurs in the transition 1 -> 0, therefore the value 0 is valid and corresponds to 65536 cycles.
The same is true for AUDxLEN. It may seem silly but if you activate DMA and the value contained in those registers is 0... I seem to recall having to make a fix for this in a couple of old games |
07 February 2023, 11:04 | #9 |
Alien Bleed
Join Date: Aug 2022
Location: UK
Posts: 4,444
|
I have a related question. If a channel is being used as a volume modulator for another channel and let's say each is initialised to begin DMA from their own buffers. Let's say the period of the volume modulator is some power of two longer than the carrier. For example, such for every 16 words the carrier fetches, the modulator will fetch one. Every time the modulator fetches a word, it's going to use the value in it to change the volume of the carrier.
Finally imagine that there's a correlation between the samples being played by the carrier and the values being used to modulate the volume. Essentially there's a frame of say 32 audio samples that we wish to play at the specific volume indicated by the modulator. Is there any appreciable delay between the modulator getting a new value and updating the volume of the carrier that would result in the previous frame's volume being used for the first x samples of the current frame? |
07 February 2023, 11:31 | #10 | |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 54
Posts: 4,491
|
Quote:
Or better, you need to wait the DMA fetch, near video line start, that insert the new volume value. Then the usual stuff: the PWM Volume counter is free running for the carrier and the channel is muted when AUDxVOL equals the value. In any case I don't think it's an audible difference, at most you could see something with an oscilloscope. But in fact it would be better if the multiples were also in sync with the DMA fetches.. |
|
07 February 2023, 14:27 | #11 | ||
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,539
|
Quote:
Quote:
|
||
07 February 2023, 15:22 | #12 |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 54
Posts: 4,491
|
opsss..
Code:
do_porta_up: move.w n_period(a2),d1 sub.w d0,d1 cmp.w #113,d1 bhs .1 <------ moveq #113,d1 .1: move.w d1,n_period(a2) move.w d1,AUDPER(a5) rts |
07 February 2023, 15:24 | #13 |
Registered User
Join Date: Sep 2009
Location: Norway
Posts: 1,715
|
Heh, that code allows even higher periods than 4095 (since original PT masks out the highest nybble in the slide routines). Another way to reach periods outside of 108..907 is to use vibrato on min/max notes with min/max finetune values. It doesn't clamp the period after adding the vibrato value.
In other words, do not expect 108..907 to be the min/max periods in PT. EDIT: I think you can get the buggy slide to set a period of 0, which is 65536 cycles. Last edited by 8bitbubsy; 07 February 2023 at 15:32. |
07 February 2023, 19:12 | #14 | ||
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,539
|
Indeed, that's a bug. Should be a signed comparison. Fixed it. Thanks!
Quote:
Quote:
|
||
07 February 2023, 19:43 | #15 |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 54
Posts: 4,491
|
|
25 February 2023, 14:52 | #16 | |
Registered User
Join Date: Sep 2009
Location: Norway
Posts: 1,715
|
Quote:
907 (C-1 finetune -8) + 29 ((15*255)/128). Highest vibrato depth at modulation waveform peak. As far as I know, the only way to go higher than 936 (other than the period slide bug) is through arpeggio B-3 overflow on finetune -1. This reads out of bounds from the finetuned period table. However, ProTracker constantly sets a period of 0 for voices that have never been triggered/initialized, so maybe this could require a very long delay when a channel first gets active? EDIT: The replayers used in the trackers have a zero for padding the octave sections in the period table. So any arpeggio at any finetune that results in note B-3 + 1 will set the period to 0. They removed the zeroes in the standalone replayer source codes, for some reason. Last edited by 8bitbubsy; 26 February 2023 at 11:37. |
|
30 December 2023, 02:42 | #17 |
Registered User
Join Date: Jul 2017
Location: Oxford
Posts: 107
|
Hi, I'm trying to write an os-friendly CDXL player (working under 1.3 too), using all OS functions just for the sake of "it can be done" next step would be to make a game around it.
Now my issue is that I don't really understand how to replicate what the OS does with audio. Explanation: if I play a sample from each frame via audio.device and just wait for the IO to complete, everything works fine (I can queue chunks of audio streaming before the playback is complete and the duration of any given frame is automatically dictated by the audio frequency). If I try to manually program the audio chipset myself (using audio.device just to allocate the channels), I can't find a way to know when a sample has finished playing. I tried to use interrupts and *count* the times the interrupt is triggered (waiting for *even* values to assess when a full sample for a frame is over), but this doesn't seem to produce the desired effect (playback goes too fast and of course the audio stutters too). At the moment I have an (imperfect) attempt using timer.device to wait for a frame, but I can see the audio flow is not 100% good as it should be (even though I reload the audio registers before the current buffer has stopped playing), there is some stuttering. My second question is similar: is there some example code on how to interrupt a playing sound properly and restart it? Again I am using interrupts, but the sound doesn't always restart properly, I assume it has to do with the way Paula works and reads data related to DMA cycles. Am I correct to assume that I should do most things in the audio interrupt? My next idea is to only set a flag from the main program and check that in the interrupt to know what to do next (restart playing or set silence). By reading this thread and a few others, my understanding is that resetting registers after the interrupt has fired is always safe, as Paula is ready to accept new values. EDIT: I managed to fix my code. The stuttering was as simple as me not setting the volume to zero before turning DMA off, whereas setting a flag every time the audio interrupt is triggered would allow the main task to use it as a signal to move onto the next frame. It’d be nice if there were more examples for audio, covering the most common use-cases. Last edited by emiespo; 29 January 2024 at 01:36. Reason: Solved my problem. |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Audio IRQ still triggering after DMA is disabled | Quagliarulo | Coders. Asm / Hardware | 1 | 16 January 2022 21:03 |
strange way to set dma audio | leonard | Coders. Asm / Hardware | 44 | 27 March 2021 13:21 |
DMA-free audio | robinsonb5 | Coders. Asm / Hardware | 3 | 05 November 2012 08:43 |
CPU execution on odd cycles if no Audio/Disk/Sprite DMA | mc6809e | Coders. Asm / Hardware | 2 | 02 April 2012 19:50 |
understanding floppy disk dma in amiga | a500l0ver | support.Hardware | 12 | 12 August 2010 07:26 |
|
|