CPCWiki forum

General Category => Programming => Topic started by: AMSDOS on 09:09, 03 December 10

Title: Trying to understand the bare fundumentals of Sound using Firmware
Post by: AMSDOS on 09:09, 03 December 10
Okay, I'm no rocket scientist or looking for any music award prizes, though given people say it's a crime not to have sound in a game, I thought I'd better acknowledge that. Unfortunately I don't know the first thing, I've looked at the Sound Manager which gives me a list:
   The ones I can exclude for now are the last 4 (Sound Ampl Envelope, Sound Tone Envelope, Sound A Address, Sound T Address), because they deal with Volume and Tone, which is the next phase to deal with after one understands Sound!

Here are some BASIC examples, which perhaps aren't the best, though I was hoping someone could explain how they would be dealt with if I was using those Firmware routines if it's possible! (If the last one is way too difficult then don't worry about it  :-[ ).


sound 1,142,2000
sound 1,90,200



10 for s=15 to 0 step -1
20 sound 1,0,3,s,,,31
30 sound 2,1000,3,s,,,31
40 next



10 FOR octave=-1 TO 2
20 FOR x=1 TO 7: REM notes per octave
30 READ note
40 SOUND 1,note/2^octave
50 NEXT
60 RESTORE
70 NEXT
80 DATA 426,379,358,319,284,253,239
Title: Re: Trying to understand the bare fundumentals of Sound using Firmware
Post by: AMSDOS on 13:59, 27 December 10
Okay I've worked out the first two Sound routines with a bit of help from the BIOS Sound Functions (http://www.cpcwiki.eu/index.php/BIOS_Sound_Functions) which, I had so much trouble finding only to realise "Sound Queue" is the Firmware Equivalent to SOUND in BASIC!  :-[

To do something like this:

sound 1,142,2000

Took me a while to realise how the 9-Byte Data Block (as outlined in the BIOS Sound Functions section) worked - so I was asking myself what does this mean quite a bit!  ???  Mainly because this Data Block is structured differently to the paramaters used in BASIC and key words which are expressed in the BIOS Sound Functions are expressed differently in the Manual (CPC6128 Edition) - there are simularaties which help define it though.

So a Sound statement like the one shown above would look like this:


org &4000

ld hl,sdata2
call &bcaa
ret

.sdata  defb 1,0,0,142,0,0,12,208,07


The Sound Data looks like this:-


1 : Represents the Channel

0,0 : These are Envelope Tone and Envelope Volume paramaters - 0 is used which
represents none.

142 : Represents Tone Period, this paramater is the Lower 8bit since the value is below
255, this position is filled and the next paramater is 0.

0 : Represents the upper value for the Tone Period, because tone periods can range
upto 4095, this second paramater allows a value upto 15 - it's a 4bit value so largest
allowed value is "1111" in binary or 15 decimal or F in hexidecimal.

0 : This handles noise frequency, which I think is the last paramater in the Sound
command in BASIC which refers to the "noise period", haven't gone this far yet so
haven't used it, since there is none 0 is specified for none.

12 : This is the tricky one - this is used for the Volume which follows the "duration" in
the Sound command. The reason I specified 12 is because this is the default value
used in BASIC when no Volume has been specified - as in this case.

208, 07 : These last 2 paramaters deal with the duration. The tricky bit is explaining
how I came up with 208,07 from what is 2000 as used in BASIC, they are indeed the
same though. Like the Tone Period, this is a two paramater job which deals in an upper
8bit value and a lower 8bit value (notice their both 8bit). The best way to describe it is
to convert 2000 into Hexidecimal. 2000 in Hexidecimal is &7D0. So now what I can do is
literally take the &D0 - in decimal that is 208 and this value goes into the Lower bit of
the Duration, and 7 in Hexidecimal is 7 in Decimal and that becomes the High bit for the
Duration.


Therefore this result is revealed and I hope this makes it clearer to those looking to pop in some sounds using the Firmware.

The other little example which I just converted using the firmware looked like this in BASIC:

sound 1,90,200

Here is the routine which follows that:

org &4000

ld hl,sdata2
call &bcaa
ret

.sdata  defb 1,0,0,90,0,0,12,200,0


It's perhaps more clear cut than the first one!  ;)
Title: Re: Trying to understand the bare fundumentals of Sound using Firmware
Post by: AMSDOS on 01:42, 28 December 10
This next one is a lot harder than what I thought, following down from my initial post I'm working on this one:

for s=15 to 0 step -1:sound 1,0,3,s,,,31:next

Which produces a really like Blasting sound - good for shooting the aliens with!  ;D

On this occassion though I've applied an Assembly Loop to run though the effect:

org &4000
.sque equ &bcaa
ld b,15
.loop ld hl,volume
ld (hl),b   
push bc
ld hl,sdata
call sque
pop bc
djnz loop
ld b,0
ld hl,volume
ld (hl),b
ld hl,sdata
call sque
ret
.sdata defb 1
defb 0
defb 0
defb 0
defb 0
defb 31
.volume defb 15
defb 3
defb 0


This produces a simular effect, though because I'm using something significantly faster than BASIC, the result is somewhat different!  ???

I've put some "halt" statements to slow things down a little, though it still sounds a little different from the BASIC version!  :(  Almost as if one of the values is different and the sound a bit higher, I've check and check this over and over, though it appears to be correct and I've checked to make sure the value of volume is correct which it appears to be, only problem I had earlier was the program exiting and not producing the zero volume, so for this I've applied a further sound burst on exit to simulate the zero volume effect!

org &4000
.sque equ &bcaa
ld b,15
.loop ld hl,volume
ld (hl),b   
push bc
ld hl,sdata
call sque
pop bc
halt
halt
halt
halt
halt
halt
halt
halt
halt
halt
djnz loop
ld b,0
ld hl,volume
ld (hl),b
ld hl,sdata
call sque
ret
.sdata defb 1
defb 0
defb 0
defb 0
defb 0
defb 31
.volume defb 15
defb 3
defb 0


After modifying the program to run within a BASIC Loop, this is what I've done:

org &4000
.sque equ &bcaa
ld hl,sdata
call sque
ret
.sdata  defb 1
defb 0
defb 0
defb 0
defb 0
defb 31
.volume defb 15
defb 3
defb 0


Using a routine like this:

for s=15 to 0 step -1:poke &400d,s:call &4000:next

should produce something like the BASIC equivalent, though for some reason it sounds quite different - shorter, I can only imagine it's like this because Sound Que works faster than Sound in BASIC. Just seems rather off putting that in this situation something is faster though one wants to make it a bit more like the effect BASIC is producing!  :(
Title: Re: Trying to understand the bare fundumentals of Sound using Firmware
Post by: redbox on 10:22, 28 December 10
Interesting to see what you're doing with the sound firmware as it's something I've never messed around with.

You can see the assembly behind these firmware routines by looking at the disassembly of the OS ROM (http://www.cpctech.org.uk/docs/os.asm) on the cpctech website.
Title: Re: Trying to understand the bare fundumentals of Sound using Firmware
Post by: AMSDOS on 14:06, 28 December 10
redbox wrote:

Interesting to see what you're doing with the sound firmware as it's something I've never messed around with.

It's perhaps something which isn't very well much covered and before yesterday there probably wasn't anything like this for the average smuck (like myself!  ;D ).

I only ever saw AA have one little segment about this (somewhere after AA71 but before AA82 in an Assembly guide), though I think they also threw in Envelopes and Tones for good measure.

You can see the assembly behind these firmware routines by looking at the disassembly of the OS ROM (http://www.cpctech.org.uk/docs/os.asm) on the cpctech website.

All very interesting, though above my head. The firmware routine is pretty much fine as it is, only trouble is the output (Sound generated) varies from the BASIC "sound" statement. Both of these one would think are derived from the same routine, though perhaps the BASIC version is slower cause it has to do something else before producing the effect therefore having something which is longer.

Everything else is probably in books - though my Assembly book forgot to cover that! :(
Title: Re: Trying to understand the bare fundumentals of Sound using Firmware
Post by: andycadley on 16:03, 29 December 10
&BCAA Sound Queue returns a status result in the carry flag, if it returns with carry false then the sound wasn't added to the queue so it needs to be re-tried. HL doesn't get corrupted in that case so it's probably sufficient to just use a JP NC back to the CALL instruction. The end result should be the same as using SOUND in Basic and you shouldn't need to delay things with HALT instructions.
Title: Re: Trying to understand the bare fundumentals of Sound using Firmware
Post by: AMSDOS on 07:27, 30 December 10
andycadley wrote:

&BCAA Sound Queue returns a status result in the carry flag, if it returns with carry false then the sound wasn't added to the queue so it needs to be re-tried. HL doesn't get corrupted in that case so it's probably sufficient to just use a JP NC back to the CALL instruction. The end result should be the same as using SOUND in Basic and you shouldn't need to delay things with HALT instructions.

Don't think I tried that loop, though I tried other JR NZ loops with simular results, in this case I think DJNZ is good value because I'm decreasing the value of B register and poking it into volume. True I have to preserve BC, though in this situation where the original BASIC is decreasing the value of a variable in the sound statement, a second variable is required to store that for the Sound Que to play as the loop passes through again.

Okay, so what your saying is my loop is running to fast and even though I'm doing everything correctly, the Sound Queue hasn't had enough time to process the next bit? It seems it's like that - especally when I reverse the process because I'm not getting the Louder volumes. Perhaps for this kind of routine I need to do a Sound Check (&BCAD) - unfortunately this look like a complicated process! :(
Title: Re: Trying to understand the bare fundumentals of Sound using Firmware
Post by: redbox on 09:29, 30 December 10
Quote from: CP/M User on 07:27, 30 December 10
Okay, so what your saying is my loop is running to fast and even though I'm doing everything correctly, the Sound Queue hasn't had enough time to process the next bit? It seems it's like that - especally when I reverse the process because I'm not getting the Louder volumes. Perhaps for this kind of routine I need to do a Sound Check (&BCAD) - unfortunately this look like a complicated process! :(

Does the sound queue wait for the frame-flyback?

If not, you might need to put a CALL &BD19 at the beginning of your loop.
Title: Re: Trying to understand the bare fundumentals of Sound using Firmware
Post by: AMSDOS on 10:29, 30 December 10
redbox wrote:

Does the sound queue wait for the frame-flyback?

If not, you might need to put a CALL &BD19 at the beginning of your loop.


Genius.

Here's those AA pages I mentioned earlier dealing with using Sound in Assembly - on CPC Oxygen of course!  ;D

http://cpcoxygen.fxwebdevelopment.com/amstrad_action/AA078/jpg/scans/aa78-24.jpg (http://cpcoxygen.fxwebdevelopment.com/amstrad_action/AA078/jpg/scans/aa78-24.jpg)
http://cpcoxygen.fxwebdevelopment.com/amstrad_action/AA078/jpg/scans/aa78-25.jpg (http://cpcoxygen.fxwebdevelopment.com/amstrad_action/AA078/jpg/scans/aa78-25.jpg)

Having a look at it again I can see why it's confusing, simply the way the Sound Parameters have been arranged and don't include the full set!

There's a Random Number Routine Accompanying that too! (Though that's for another thread!  :laugh: )
Title: Re: Trying to understand the bare fundumentals of Sound using Firmware
Post by: arnoldemu on 11:18, 30 December 10
CP/M user, when you are ready, please document this in the wiki.
I too have not used the firmware sound functions, so your discoveries will definitely help myself and others.
Title: Re: Trying to understand the bare fundumentals of Sound using Firmware
Post by: Targhan on 15:25, 30 December 10
Hmmm, maybe you're going to say my remark is stupid, but you can do sound effects very easily by using the Arkos Tracker player and include them in your Basic program... Along with music if you want to... But I guess you want to make your program 100% Basic, perhaps ?
Title: Re: Trying to understand the bare fundumentals of Sound using Firmware
Post by: arnoldemu on 22:08, 30 December 10
Quote from: Targhan on 15:25, 30 December 10
Hmmm, maybe you're going to say my remark is stupid, but you can do sound effects very easily by using the Arkos Tracker player and include them in your Basic program... Along with music if you want to... But I guess you want to make your program 100% Basic, perhaps ?
Your remark is completely valid.

I think it is always good to understand all parts of the Amstrad, including the firmware.
So I think understanding how the firmware makes sounds, and compare this to the way BASIC makes the sounds is good for somebody who is comming to the CPC from the BASIC side of things.
Title: Re: Trying to understand the bare fundumentals of Sound using Firmware
Post by: AMSDOS on 09:13, 31 December 10
What I was trying to do with this thread is look at BASIC examples of Sound and apply those using the Firmware.

Benefits:
   In a situation where Tunes are used, an Interrupt Driven Music is far more appropriate - the concept here is to simply analyse the simple sound effects which can enable me to understand how to apply them using Assembly and the Firmware!

Unfortunately I have no concept of what makes a sound on the CPC!  :(  Which means I don't know much when it comes to what the values represent, obviously things like Channel and Volume are obvious, I think that's where it's good to have programs on the CPC which allow you to create the Sound FX, otherwise I'm not sure how programmers approached this in the early periods, it might have been experimentation? Who knows!  ;D

With this article on the Wiki site, I can stick it on the Source Code in the Sound Routines, or is there some rule that I need to submit the page for it to be evaluated and put in a suitable spot on the Wiki?
Title: Re: Trying to understand the bare fundumentals of Sound using Firmware
Post by: AMSDOS on 12:21, 02 January 11
I've added this topic to the wiki (http://www.cpcwiki.eu/index.php/Programming:Tutorial_-_Understanding_the_fundamentals_of_BASIC_SOUND_and_the_Firmware_SOUND_QUEUE). I've added it to the source code page, though I've done something wrong and it's coming up with programming!  :(  The page is coming up fine through the link - added with the other Sound routines.
Title: Re: Trying to understand the bare fundumentals of Sound using Firmware
Post by: redbox on 12:32, 02 January 11
Quote from: CP/M User on 12:21, 02 January 11
I've added this topic to the wiki (http://www.cpcwiki.eu/index.php/Programming:Tutorial_-_Understanding_the_fundamentals_of_BASIC_SOUND_and_the_Firmware_SOUND_QUEUE). I've added it to the source code page, though I've done something wrong and it's coming up with programming!  :(  The page is coming up fine through the link - added with the other Sound routines.

That's a useful information, thank you.

It should be in the 'Programming' section and appears to be labelled properly?
Title: Re: Trying to understand the bare fundumentals of Sound using Firmware
Post by: AMSDOS on 00:09, 03 January 11
Thanks.

Yep I think I've applied all the correct procedures to ensure it's in the right place.

Fixed the Link to it on the Source Code page - simply needed a '|' to separate the Link and the text to display.

The final example I've got in my initial post I'll eventually add to that page.
Title: Re: Trying to understand the bare fundumentals of Sound using Firmware
Post by: AMSDOS on 10:51, 30 September 18

I'm reviving this old thread after making some recent improvements to my understanding of the Sound Queue.

Quote from: andycadley on 16:03, 29 December 10
&BCAA Sound Queue returns a status result in the carry flag, if it returns with carry false then the sound wasn't added to the queue so it needs to be re-tried. HL doesn't get corrupted in that case so it's probably sufficient to just use a JP NC back to the CALL instruction. The end result should be the same as using SOUND in Basic and you shouldn't need to delay things with HALT instructions.


Unfortunately when I was looking for solutions to my Sound Loop back in 2010, I was thinking in terms of Singular Loops and after the Frame Flyback suggestion was made I never got around to looking at anything else! :(
Recently when I was coding something for Hisoft Pascal, I took the time to put in a loop which continues to Loop until the HL register is corrupt, so the same should apply with assembly if I simply do something like this I hope:



.holdnote
CALL &bcaa
JP NC,holdnote





Initially, when I was asking about Sound I posted this example and wondered how it could be written in Assembly:




10 FOR octave=-1 TO 2
20 FOR x=1 TO 7: REM notes per octave
30 READ note
40 SOUND 1,note/2^octave
50 NEXT
60 RESTORE
70 NEXT
80 DATA 426,379,358,319,284,253,239



Don't blame anyone for not giving it a go because it's taking the data and dividing with an exponent sum. I think it can be done in Assembly, though it's perhaps at a higher level of assembly I'm not at.


The simplest approach would be to convert the data into a string of values closest to the nearest whole value (since some of those values from the calculations become decimal numbers).


This is the data I ended up with:




852, 758, 716, 638, 568, 506, 478
426, 379, 358, 319, 284, 253, 239
213, 190, 179, 160, 142, 127, 120
107,  95,  90,  80,  71,  63,  60



A loop can then be setup to read through those values, similar to how I'm reading the volume value from my explosion example.


At the moment I haven't got access to my sound capable emulator to test this.  :o
Title: Re: Trying to understand the bare fundumentals of Sound using Firmware
Post by: AMSDOS on 03:36, 07 October 18
I made updates on my BASIC to Assembly Sound Tutorial (http://www.cpcwiki.eu/index.php/Programming:Tutorial_-_Understanding_the_fundamentals_of_BASIC_SOUND_and_the_Firmware_SOUND_QUEUE), to include properly using the Sound Queue Firmware with the appropriate flag to hold the note while sound is being played, and have also updated the last BASIC example I posted here in 2010/11 to produce a workable Assembly version.
Powered by SMFPacks Menu Editor Mod