English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Language > Coders. Blitz Basic

 
 
Thread Tools
Old 28 December 2016, 02:09   #1
Shatterhand
Warhasneverbeensomuchfun
 
Shatterhand's Avatar
 
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.
Shatterhand is offline  
Old 31 December 2016, 06:53   #2
earok
Registered User
 
Join Date: Dec 2013
Location: Auckland
Posts: 3,547
Subscribing because I'm also interested in the answer to this.
earok is offline  
Old 01 January 2017, 06:10   #3
idrougge
Registered User
 
Join Date: Sep 2007
Location: Stockholm
Posts: 4,356
I think the best solution available would be to hook up phx's player routine to Blitz.
idrougge is online now  
Old 14 January 2017, 08:56   #4
Shatterhand
Warhasneverbeensomuchfun
 
Shatterhand's Avatar
 
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
Whenever I need to play a sound, I just call it, first argument is the sound I want to play, 2nd one is the time it will play and the last one is its priority. I think it's pretty easy to understand it. Everytime I update the screen, I subtract one from the "sndtimer" variable. I need to know for how long each sfx plays, but that's pretty easy to do. This is nothing fancy and you could easily adapt it to use 2 sound channels or something, but it worked for me.

Now, taken from Blitz manual:

Quote:
Interupt Control
#INTENA =$9A ;interupt enable write address #INTENAR =$1C ;interupt enable read address
#INTREQ = $9C ;interupt request write address #INTREQR =$1E ;interupt request read address
INTENA is used to enable or disable interupts. If the value written to INTENA has bit 15 set any other of the bits enable their corresponding interupts. If bit 15 is clear any of the other bits set will disable their corresponding interupts.
INTENAR will return which interupts are currently enabled.
INTREQ is used to initiate or clear an interupt. It is mostly used to clear the interupt by the interupt handler. Again Bit# 15 states whether the corrsponding interupts will be requested or cleared.
INTREQR returns which interupts are currently requested.
The following bit definitions relate to the 4 interupt control registers.
BIT# NAME LEVEL DESCRIPTION
15 SET/CLR determines if bits written with 1 are set or cleared 14 INTEN master interupt enable 13 EXTER 6 external interupt 12 DSKSYN 5 disk sync register (same as DSKSYNC) 11 RBF 5 serial port Receive Buffer Full 10 AUD3 4 audio channel 3 finished 09 AUD2 4 audio channel 2 finished 08 AUDI 4 audio channel 1 finished 07 AUD0 4 audio channel 0 finished 06 BLIT 3 blister finished 05 VERTB 3 start of vertical blank interupt 04 COPER 3 copper 03 PORTS 2 I/O ports and timers 02 SOFT 1 reserved for software initiated interupts 01 DSKBLK 1 disk block finished 00 TBE 1 serial port Transmit Buffer Empty
233
The following locations hold the address of the 68000 interupt handler code in memory for each level of interupt.
LEVEL 68000 Address 6 $78 5 $74 4 $70 3 $6c 2 $68 1 $64
It seems there's an interrupt whenever a sound channel is finished playing something. I really couldn't understand how to use it or even if it's possible at all, but maybe someone more experienced could have some idea.
Shatterhand is offline  
Old 14 January 2017, 20:51   #5
Daedalus
Registered User
 
Daedalus's Avatar
 
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.
Daedalus is offline  
Old 16 January 2017, 01:58   #6
Pat the Cat
Banned
 
Join Date: Dec 2016
Location: Nottingham, UK
Posts: 481
Quote:
Originally Posted by Daedalus View Post
. 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.


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.
Pat the Cat is offline  
Old 16 January 2017, 05:40   #7
Anakirob
Unregistered User
 
Anakirob's Avatar
 
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.
Anakirob is offline  
Old 14 February 2017, 04:01   #8
earok
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.
earok is offline  
Old 28 February 2017, 10:53   #9
Daedalus
Registered User
 
Daedalus's Avatar
 
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?
Daedalus is offline  
Old 01 March 2017, 22:59   #10
earok
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..)
earok is offline  
Old 02 March 2017, 10:51   #11
Daedalus
Registered User
 
Daedalus's Avatar
 
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.
Daedalus is offline  
Old 04 March 2017, 10:24   #12
Samurai_Crow
Total Chaos forever!
 
Samurai_Crow's Avatar
 
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...
Samurai_Crow is offline  
Old 24 October 2018, 11:40   #13
earok
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.
earok is offline  
Old 24 October 2018, 12:22   #14
Daedalus
Registered User
 
Daedalus's Avatar
 
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
The 11025 might also need to be adjusted if you change the playback period/frequency.
Daedalus is offline  
Old 24 October 2018, 13:02   #15
earok
Registered User
 
Join Date: Dec 2013
Location: Auckland
Posts: 3,547
Quote:
Originally Posted by Daedalus View Post
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
The 11025 might also need to be adjusted if you change the playback period/frequency.
Good point

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.
earok is offline  
Old 24 October 2018, 13:28   #16
Daedalus
Registered User
 
Daedalus's Avatar
 
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.
Daedalus is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
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

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 01:15.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.10568 seconds with 13 queries