C Sound Libraries

Since we do not have native C compilers on the Oric, this forum will be mostly be used by people using CC65 or the OSDK. But any general C related post will be welcome !
User avatar
barnsey123
Flight Lieutenant
Posts: 379
Joined: Fri Mar 18, 2011 10:04 am
Location: Birmingham

C Sound Libraries

Post by barnsey123 »

Has anyone got any sound libraries for use in C programs? I'm looking for various sound effects to supplement/replace the ROM routines.
In particular, anything metallic (clash of swords, hammer on anvil? etc)

Any advice would be welcome.
User avatar
Dbug
Site Admin
Posts: 4437
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Post by Dbug »

You can try to use the following function:
void w8912(unsigned char reg,unsigned char value);

It's very low level, but with that you have access to all the registers of the sound-chip.

Alternatively, if you have some free memory, and if you can afford to not do anything while a sound is playing, then possibly you could just replay sample sounds, either using 8 bits or 4 bit samples.

As usual, it's a size/cost/quality trade-off :)

Imo, if you have few kilobytes free, sample sounds could be cool, because with that you can even have voices, growls, laughs, etc...
User avatar
waskol
Flight Lieutenant
Posts: 414
Joined: Wed Jun 13, 2007 8:20 pm
Location: FRANCE, Paris

Re: C Sound Libraries

Post by waskol »

OK, this post is a bit old... but

Since a few, I am working about sound effects with Oric, the way they are generated by PING, EXPLODE or SHOOT (Not zap, because, it does not works the same way).

According to Theoric (Special issue, August 1985, page 36/37) , it works as it :

You have a table of 14 bytes at some address.
for PING, it is located at #FAA7( 64167) : 24,0,0,0,0,0,0,62,16,0,0,0,15,0
for SHOOT, at #FABD( 64189) : 0,0,0,0,0,0,15,7,16,16,16,0,8,0
for EXPLODE, at #FAD3( 64211) : 0,0,0,0,0,0,31,7,16,16,16,0,24,0

Whenever you call PING, SHOOT or EXPLODE :
1 ) Register X is loaded with lower order byte of the table starting address
2 ) Register Y is loaded with higher order byte of the table starting address
3) an Oric routine is called, playing the sound with this table.

Calling SHOOT, calls this piece of code

Code: Select all

ldx #$BD
ldy #$FA 
JSR $FA86
RTS
(JSR #FA6C for Oric1)


by trying and guess, luck I discovered a few interesting sound effects :
Electricity : 0,4,0,184,0,3,120,190,12,0,0,0,167,194
Helicopter : 168,191,0,3,184,191,14,0,0,0,167,194,76,176
Engine : 1,5,193,7,7,8,7,8,53,151,47,151,0,152
Inside the cockpit of a plane : 150,0,152,46,4,255,255,112,7,80,0,102,5,65
A plane (turboprop) : 32,2,140,0,5,132,14,136,132,12,140,0,69,173
Helicopter (far away) : 14,136,132,12,140,0,69,173,0,5,208,4,169,192
Forge hammer hitting an anvil : 32,134,250,96,0,0,0,0,0,0,31,7,16,16

all of these have to be a bit cleaned up (it's a non sense to have some data for channel A for instance, but with channel A non-activated)

found on the web, here (another helicopter) :
206,108,231,36,137,112,70,182,170,239,83,246,12,165

Found in the Theoric magazine :
PONG : EE 02 00 00 00 00 00 3E 10 00 00 D0 07 00
PCHH: 00 00 00 00 00 00 01 37 10 00 00 D6 0B 00

Now, what is the meaning of each byte of the table ?
Simply, they correspond to the AY-3-8912 registers :
- 0 and 1 : tone (pitch) on channel A (n between 0 and 4096) (12 bits)
- 2 et 3 : tone (pitch) on channel B (between 0 and 4096) (12 bits)
- 4 et 5 : tone (pitch) on channel C (between 0 and 4096) (12 bits)

note:n=real_period/16/T0 (TO=1µS for Oric) or in short Frequency=1MHz/16/n (n=0 acts as n=1)
Possible frequencies are in range from 62500Hz (n=1) down to approx. 15.26Hz (n=4095)

6 : period of the noise generator (between 0 and 31) note: only bits 0 to 4 are used, Frequency=1MHz/16/n (n=0 acts as n=1)

7: Channels activation
bit 0: channel A
bit 1: channel B
bit 2: channel C
bit 3,4 et 5 mixing of the noise into the three primary channels
becarefull: bit=0 means "activated" bit=1 means NOT activated, for the 6 bits
(note: bit 6 is the port A direction and bit 7 the port B direction, not used for sound generation)

8,9,10 --> volume A,B,C (0 to 16)
more precisely :
- bits 0 to 3 (amplitude): maximum amplitude or volume (0 to 15)
- bit 4 (modulation) : 0 -->fixed amplitude 1-->amplitude controlled by B0-B3 and the envelop generator
Note : The volume is non-linear. The "real world" amplitude can be computed like this :

Code: Select all

 real_world_amplitude = max / sqrt(2)^(15-n),
This amplitude corresponds to the voltage output to a speaker. (15 --> max/1, 14 --> max/1.414, 13 --> max/2, etc...)


11 and 12 --> Envelope step frequency - sound duration - (0 to 65535) note:Frequency=1MHz/16/n (n=0 acts as n=1)
Depending on the envelope shape, the volume is incremented from 0 to 15, or decremented from 15 to 0. In either case it takes 16 steps to complete, the completion time for 16 steps is therefore:

Code: Select all

 T = n*256 / 1MHz      ;with n in range 1..65535 (256µs .. 16.7 seconds)
13 --> envelop (0 to 15) note:only bits 0 to 3 are used.
According to wikipedia (french) : bits 0 to 3 permit to control the sound envelop but only 10 are available because only B2 is taken into account when B3 is equal to zero :

Code: Select all

      B3 - Continue
      B2 - Attack
      B1 - Alternate
      B0 - Hold

Code: Select all

Binary  Hex      Shape
 00XX    00h-03h  \_________  (same as 09h)
 01XX    04h-07h  /_________  (same as 0Fh)
 1000    08h      \\\\\\\\\\
 1001    09h      \_________  (volume remains quiet)
 1010    0Ah      \/\/\/\/\/
 1011    0Bh      \"""""""""  (volume remains high)
 1100    0Ch      //////////
 1101    0Dh      /"""""""""  (volume remains high)
 1110    0Eh      /\/\/\/\/\
 1111    0Fh      /_________  (volume remains quiet)
Registers+envelops :
http://download.abandonware.org/magazin ... e%2021.jpg

Pong sample for OSDK :

main.c

Code: Select all

#include <lib.h>

void Pong();

void main()
{   
	setflags(SCREEN+NOKEYCLICK);
	while(get()!='Q') Pong();
}
pongsound.s

Code: Select all

Pongtable
	.byt 238,2,0,0,0,0,0,62,16,0,0,208,7,0

_Pong	
	ldx #<Pongtable
	ldy #>Pongtable
	jsr $FA86
	rts
There's a lot to dig in with this, because it is rather simple to put in practice, it does not consume a lot of memory.
Moreover (I would like to study that closely), it may be interesting to look out around with what can exist for the cpc464, for instance, or other microcomputer, for instance :
https://cpcrulez.fr/coding_basic-le_son_sur_AMSTRAD.htm
https://cpcrulez.fr/coding_src-list-sou ... mstrad.htm
Last edited by waskol on Wed Oct 10, 2018 12:43 pm, edited 2 times in total.
User avatar
Dbug
Site Admin
Posts: 4437
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Re: C Sound Libraries

Post by Dbug »

I wonder if we can find random sequences of bytes in ROM that would create decent sounds :)
User avatar
waskol
Flight Lieutenant
Posts: 414
Joined: Wed Jun 13, 2007 8:20 pm
Location: FRANCE, Paris

Re: C Sound Libraries

Post by waskol »

My "trying and guess" are coming from this "random " exploration, I used those values :
- for y --> 0
- for x --> 11,12,13, 14 ,23 , 25, 147, 149,154,165,184,185

some interesting sounds too with y=$FA (like for SHOOT, PING EXPLODE), testing x from 0 to 255
:D

Adding the "Anvil/Hammer metallic sound for the final of Oric Kong (when all the metallic structure of the building is falling down) :)

For sure it opens soooooooooooo many possibilities to the Oric World.
I am very surprised that nobody digged that out since 80's

Just for the pleasure to see how it is simple to use it in BASIC too :

Code: Select all

10 FOR X=#400 TO #415 
 20 READ R : POKE X,R : NEXT 
 40 DATA #A2,#8         'LDX $8 (data file - low) 
 50 DATA #A0,#4         'LDY $4 (data file - high) 
 60 DATA #20,#6C,#FA    'JSR $FA6C (for Atmos replace #6C by #86) 
 70 DATA #60            'RTS 
 80 REM HERE COMES THE 14 BYTE DATA FILE 
 90 REM CHANGE THE VALUES IF YOU LIKE 
100 DATA 32,134,250,96,0,0,0,0,0,0,31,7,16,16
120 POKE#26A,11
130 CLS
140 PRINT "Hit the anvil with your hammer by"
145 PRINT "pressing any key !"
150 GET A$
160 CALL#400
170 GOTO 150
Last edited by waskol on Tue Oct 09, 2018 9:59 pm, edited 1 time in total.
User avatar
iss
Wing Commander
Posts: 1637
Joined: Sat Apr 03, 2010 5:43 pm
Location: Bulgaria
Contact:

Re: C Sound Libraries

Post by iss »

Nice effects and useful too!
User avatar
Chema
Game master
Posts: 3013
Joined: Tue Jan 17, 2006 10:55 am
Location: Gijón, SPAIN
Contact:

Re: C Sound Libraries

Post by Chema »

Someone did: Twilighte, of course. Do you remember this thread? viewtopic.php?f=15&t=516

In fact I used that technique for the sfx in 1337. However, the effects produced this way are quite simple and do not offer many possibilities. I took a totally different path for Oricium, but it is also much more complicated as my engine (it is documented and the sources are in the repo) is used for playing the music too.

A quick note... you can replace the jsr xxxx / rts pair with a jmp xxxx. 1 byte and some cycles are saved this way.
User avatar
waskol
Flight Lieutenant
Posts: 414
Joined: Wed Jun 13, 2007 8:20 pm
Location: FRANCE, Paris

Re: C Sound Libraries

Post by waskol »

Chema wrote: Tue Oct 09, 2018 9:58 pm A quick note... you can replace the jsr xxxx / rts pair with a jmp xxxx. 1 byte and some cycles are saved this way.
I was not sure about that, I am a very beginner in machine code.

I was wondering to if there was a possibility to call a C array from a function in order to load the x index and y index with the address in argument, like this :

Code: Select all

unsigned char mysoundfx[14];
...
soundfx(&mysoundfx);
looking at the OSDK lib, I see that the y index is already used to load arguments, so I can't figure out how to implement the machine code.
OK, I found another way (see above), but it was a practice question to myself, just wondering how to do it.

Edit : I found a way, but it's ugly (OSDK article about "preprocessor abuse")

Code: Select all

#define soundfx(soundtableadr)  ldx #<soundtableadr:ldy #>soundtableadr:jmp $FA86
Twilighte did ? THE GOD among the Oric world...

PS : between I have edited my preceeding post to show a BASIC (funny if it is) example
PS2 : some more details and clarifications about the registers and envelops in my first post
User avatar
NekoNoNiaow
Flight Lieutenant
Posts: 272
Joined: Sun Jan 15, 2006 10:08 pm
Location: Montreal, Canadia

Re: C Sound Libraries

Post by NekoNoNiaow »

Dbug wrote: Tue Oct 09, 2018 7:29 pm I wonder if we can find random sequences of bytes in ROM that would create decent sounds :)
I love the idea, it would allow to play nice sounds using only a two bytes index into the corresponding address.

I guess it would be quite easy to write a small C program to incrementally "play" the entire ROM this way, one "sample" every two seconds with a few keyboard commands to pause/rewind/save when an interesting sound is heard. ;)
Post Reply