![]() |
![]() |
#1 |
Warhasneverbeensomuchfun
Join Date: Jun 2001
Location: Rio de Janeiro / Brazil
Age: 41
Posts: 3,450
|
Doing a Sound Priority routine
Is there anyway to find out
a) If a Sound Channel is being currently used or b) If a determined sound is being played by any channel? I want to use just 1 channel to sfx on my game, so I can keep the other 3 to music. But to do this properly, it would be nice to have some kind of priority setting for the sound effects, so less important sound effects dont mute more important ones. Is there any easy way to do that? I thought about using a variable to count the time of a sound being played, and everytime I play a sound, I give a value to this variable and decrease it at each frame, so when it's 0 I know the sound isn't being played any long.... this also would work, but I guess it would wast more CPU/Memory than if I could just quickly know if a sound channel is being used or sound being played. |
![]() |
![]() |
#2 |
Registered User
Join Date: Dec 2013
Location: Auckland
Posts: 3,547
|
Subscribing because I'm also interested in the answer to this.
|
![]() |
![]() |
#3 |
Registered User
Join Date: Sep 2007
Location: Stockholm
Posts: 4,348
|
I think the best solution available would be to hook up phx's player routine to Blitz.
|
![]() |
![]() |
#4 | |
Warhasneverbeensomuchfun
Join Date: Jun 2001
Location: Rio de Janeiro / Brazil
Age: 41
Posts: 3,450
|
I wrote a very simple routine:
Code:
Statement soundplay {snd,tim.b,priority.b} shared sndtimer.b shared sndpri.b if sndtimer = 0 Sound snd,8,64 sndtimer = tim sndpri = priority else if priority >= sndpri Sound snd,8,64 sndtimer = tim sndpri = priority endif endif End Statement Now, taken from Blitz manual: Quote:
|
|
![]() |
![]() |
#5 |
Registered User
Join Date: Jun 2009
Location: Dublin, then Glasgow
Posts: 6,379
|
There are interrupts for when the buffer of a sound is empty and needs to be refilled, but not sure if that's any good as I think to use it that way you'd need to be feeding it the raw audio data yourself. You could always experiment a little, setting up interrupt code is easy - SetInt 7 for channel 0 up to SetInt 10 for channel 3. I suspect however that Blitz has its own interrupt routines that it uses internally for feeding the audio through, and thus these interrupts might not work for your code.
|
![]() |
![]() |
#6 | |
Banned
Join Date: Dec 2016
Location: Nottingham, UK
Posts: 481
|
Quote:
![]() It does depend on what you are developing with. Blitz does a very nice job of interrupt handling. Paula herself does not generate an interrupt ("exception") when reaching the end of a sample, just stops changing the DAC value. Am not sure if the subject is covered in ROM Kernal Manuals, probably is, but have never studied them. Assembly coders always had to do some kind of work here, although some just reused a generic "mod player" bit of code to do the work. Which was a bit of a problem when Octamed came out - because that lets you do 8 channels by softmixing. So, if you are trying to use assembly code or C to do this, study the Octamed player code. I'm pretty sure that hooks into the AmigaOS handling routines, and isn't "hacky" as such. IIRC the author of Octamed did release the source very early on, to show how softmixing works. Only 3 channels? Nope, you can have more than 4. You will lose a little bit of processor time, but not as much as you might think. |
|
![]() |
![]() |
#7 |
Unregistered User
Join Date: Nov 2005
Location: Tasmania
Age: 42
Posts: 893
|
If you calculate roughly how many frames it takes a sample to play (I would really pre-calculate these rather than attempting to do it on the fly), then start a timer which counts down from that value toward zero once every frame (put the counter in interrupt 5) every time you trigger that sample. Then check to see if any timers are above zero before triggering a lower priority sample. It's not the most elegant solution and wastes a little CPU time, but it should work. Otherwise, there does not seem to be much you can do.
Also it gives you the advantage of being able to be a bit more flexible with sample priorities. Say if for example you have a sound which starts really loud then has a long trailing fade out, like an explosion with a large amount of reverb for example. You could set it up to play not play other samples when the main explosion is happening, play loud (high priority) samples after the main explosion has finished but there's still a bit of reverb, then play all samples when the explosion sound has finished. Maybe it's possible to peek at some register to see if the contents of Paula's buffer is zero, I'm not that familiar with how the HW functions to know. Last edited by Anakirob; 16 January 2017 at 05:50. |
![]() |
![]() |
#8 |
Registered User
Join Date: Dec 2013
Location: Auckland
Posts: 3,547
|
I've been experimenting with "The Untouchables" and found that game has a routine for ensuring that no sound effect is played on a channel that already has a sound effect playing. The way this works is that it polls $DFF002 and checks the first four bits to check that there's no DMA access to that sound channel.
Presumably this can be adapted for Blitz? I'll try it myself unless someone points out this method won't work. |
![]() |
![]() |
#9 |
Registered User
Join Date: Jun 2009
Location: Dublin, then Glasgow
Posts: 6,379
|
Only saw this now, but I can't see why that wouldn't work - that's how code can be made to wait for the blitter to finish. Did you try it yourself in the end?
|
![]() |
![]() |
#10 |
Registered User
Join Date: Dec 2013
Location: Auckland
Posts: 3,547
|
I tried and it didn't seem to work - from my tests at least the channel DMA would be set when a sound is played, but it wasn't unset after the sound is finished. So I could tell when a channel had been used but not when it was free again.
Probably a dumb question but, is that behavior potentially a performance drain? Eg the channel still being set means that Paula is still sharing memory access time with the CPU (apologies if that sounds absurd, I don't have a clear understanding on DMA at all..) |
![]() |
![]() |
#11 |
Registered User
Join Date: Jun 2009
Location: Dublin, then Glasgow
Posts: 6,379
|
Not a dumb question, I actually don't know the answer myself for definite so it would be good to know. I suspect that it would actually continue to take up a DMA slot which could limit performance in chip RAM-heavy activities, but that's just pure speculation. My understanding is that the CPU can use free DMA slots for chip RAM access, so if the audio channel holds onto DMA channels unnecessarily it could affect things that way.
|
![]() |
![]() |
#12 |
Total Chaos forever!
Join Date: Aug 2007
Location: Waterville, MN, USA
Age: 49
Posts: 2,200
|
Audio.device has a priority mechanism if you want to resort to system friendly code...
![]() |
![]() |
![]() |
#13 |
Registered User
Join Date: Dec 2013
Location: Auckland
Posts: 3,547
|
I came up for a solution for this
First, you need to get the audio length like so: *S.sound = Addr Sound(ID) FramesPlayedFor = (*S\_length * 2 * 50) / 11025 (make sure to include bb2objs.res) The way we calculate the "FramesPlayedFor" is to multiply the word length by two (number of bytes), multiply that by 50 (assuming PAL, otherwise 60 for NTSC) and then divide that by the frequency. You then just need to subtract FramesPlayedFor by 1 every frame and then only play the next sound when FramesPlayedFor is zero again. |
![]() |
![]() |
#14 |
Registered User
Join Date: Jun 2009
Location: Dublin, then Glasgow
Posts: 6,379
|
Ah, of course, elegant solution! I actually use that approach for getting and changing the frequency of samples. You can use the NTSC function to determine if the machine's video is running at 60Hz (returns true) or 50Hz (returns false), so the same routine will work on both types without change:
Code:
If NTSC hz.w = 60 Else hz = 50 End If [...] FramesPlayedFor = (*S\_length * 2 * hz) / 11025 |
![]() |
![]() |
#15 | |
Registered User
Join Date: Dec 2013
Location: Auckland
Posts: 3,547
|
Quote:
![]() For the game I'm working on I know the frequency of each and every sound file is 11025, but maybe you could use *S\_period to calculate the frequency as well? I'm not quite sure how to convert between period and frequency but I'm sure it's simple enough. |
|
![]() |
![]() |
#16 |
Registered User
Join Date: Jun 2009
Location: Dublin, then Glasgow
Posts: 6,379
|
There is a clock constant that's related to the screen refresh rate, and dividing that by the frequency gives you the period. It's 3546895 for PAL and 3579545 according to the Autodocs, and ultimately is based on the length of DMA slots available for audio.
That technique would be useful when you're dealing with something that you keep modifying, but if you only have a couple of set frequencies, loading separate samples pre-rendered the required frequencies is probably a better approach. |
![]() |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
Blitter Priority - Blthog | Asman | Coders. Asm / Hardware | 3 | 12 December 2016 21:26 |
Setting RAM priority | ancalimon | support.Apps | 4 | 12 September 2014 01:56 |
More settings in priority panel | Thom87 | request.UAE Wishlist | 2 | 24 January 2008 15:23 |
priority resets after reset | jrom | support.WinUAE | 0 | 10 April 2004 16:05 |
|
|