1

(3 replies, posted in Sinclair)

I did get it working (kinda) with a little assistance from the original poster of the sound effect engine.  It does seem to work rather well.  I do think that beepFX sounds better, but there's no harm in having other options.  It doesn't sound quite the same as the demo I've seen, but makes noises in the way I almost expect.

Anyway, here's the code I eventually used.

extern void __FASTCALL__ SFX(unsigned char fx) 
{
    #asm    
    ld a, l            ;
    ;//z88dk passes the L register from unsigned char

    
    ld (sonreq),a    ;
    ;//32991 shows 0
    ;//ld (sonnow),a//added

play_sound:
    call sound        ;
    ld a,(sonnow)    ;
    or a            ;
    jr nz, play_sound;
    ret                ;
    ;//return back to C
    
sound:
        ld a,(sonreq) ;play new sound? ;32777
        ;//loads contents of 32991 into register A
        ; 32991 shows 0
        
        
        and a    ;32780
        jr z,nonew  ;NO
        ;jumps to nonew
        
;YES
        ld (sonnow),a
        dec a
        jr z,noise    ;#01 noise

        ld hl,sfxData
        dec a
        add a,a
        add a,a
        add a,a
        ld e,a
        xor a
        ld (sonreq),a
        ld d,a
        add hl,de
        ld bc, 8
        ld de,sonfrq ;33245    <--start freq
        ldir        ;32809
        jr process

    nonew:
        ld a,(sonnow);32813
        
        ;//and the old sound is?
        ;//loads contents of 32990 into register A

        and a
        ret z
        
        dec a    ;//continue noise?
        jr nz,process ;//continue sound

        jr cnois

    noise:
        ld a,0xA
        ld (sonlen),a
        xor a
        ld (sonreq),a

    cnois:
        ld b,0x30

    gain:
        call random
        and 0x10
        out (0xfe),a
        ld c,2

    make:
        dec c
        jr nz,make
        djnz gain
        ld hl,sonlen
        dec (hl)
        ret nz
        xor a
        ld (sonnow),a
        ret

    process:
        ld a,(sonfrq)    ;<--start freq
        ld h,a
        ld a,0x10
        ld d,0xff

    sonlp:
        ld e,h
        out (0xfe),a
        xor 0x10

    freq:
        dec d
        jr z,mod
        dec e
        jr nz,freq
        jr sonlp

    mod:
        ld a,(soncfg)
        add a,h
        ld (sonfrq),a ;        <--start freq
        ld hl,sonmod
        dec (hl)
        ret nz
        ld hl,sonlen
        dec (hl)
        jr nz,modify
        xor a
        ld (sonnow),a
        ld a,(sonnex)
        and a
        ret z
        ld (sonreq),a
        ret

    modify:
        ld a,(sobrsf)
        ld c,a
        ld a,(sontyp)
        and a
        jr z,reset
        dec a
        jr z,typ1
        dec a
        jr z,typ2

    typoth:
        ld a,(soncfg)
        neg
        ld (soncfg),a
        jr mode

    typ2:
        inc c
        inc c
        ld a,c
        ld (sobrsf),a
        jr reset

    typ1:
        dec c
        dec c
        ld a,c
        ld (sobrsf),a
        jr reset

    reset:
        ld a,c
        ld (sonfrq),a    ;<--start freq

    mode:
        ld a,(sonrnd)
        ld (sonmod),a
        ret

    random:
        push hl
        ld hl,(rnseed)
        inc hl
        ld a,h
        and 3
        ld h,a
        
    rok:
        ld (rnseed),a
        ld a,r
        xor (hl)
        pop hl
        ret

rnseed:    defw 0x1000

sonfrq:    defb sfxData    ;start frequency        
soncfg:    defb sfxData+1    ;frequency change
sonmod:    defb sfxData+2    ;change times
sonlen:    defb sfxData+3    ;repeat times
sontyp:    defb sfxData+4    ;modulate type
                ;0 sawtooth
                ;1 2nd mod down
                ;2 2nd mod up
                ;3+ triangle
sobrsf:    defb sfxData+5    ;reset frequency
sonrnd:    defb sfxData+6    ;change reset temp
sonnex:    defb sfxData+7    ;linked sfx
    
sonnow:    defb 0    ;which effect playing
sonreq:    defb 0    ;we have an effect


;here all sounds excepts number 1 reserved for random noise
sfxData:
defb 0, 5, 5, 1, 0, 0, 0, 0;SFX 2
defb 40, 5, 10, 1, 0, 0, 0, 0;SFX 3
defb 0, 128, 30, 1, 0, 0, 0, 0;SFX 4
defb 0, 2, 30, 1, 0, 0, 0, 0;SFX 5
defb 0, 125, 32, 1, 0, 0, 0, 0;SFX 6
defb 255, 131, 32, 1, 0, 0, 0, 0;SFX 7
defb 255, 131, 40, 32, 1, 60, 1, 0;SFX 8
defb 240, 240, 8, 3, 0, 60, 6, 0;SFX 9
defb 2, 128, 10, 1, 0, 0, 0, 0;SFX 10
defb 40, 250, 8, 1, 0, 0, 0, 0;SFX 11
defb 250, 44, 6, 10, 1, 90, 1, 0;SFX 12
defb 0, 252, 20, 8, 1, 80, 8, 0;SFX 13
defb 230, 230, 4, 1, 1, 0, 0, 0;SFX 14
defb 45, 67, 20, 1, 1, 0, 0, 0;SFX 15
defb 64,  5,  10,  1,  0,  0,  0,  0;SFX 16
defb 40,  5,  10,  1,  0,  0,  0,  0;SFX 17
defb 64,  5,  20,  1,  0,  0,  0,  0;SFX 18
defb 20,220,  64,  1,  3,  10, 1,  0;SFX 19
defb 64,  4,  32,  1,  3,  96,  0,  2;SFX 20
defb 255,131, 32, 1, 0, 0, 0, 0;SFX 21
defb 240, 240, 8, 3, 0, 60, 6, 0;SFX 22
defb 2,120, 10, 1, 0, 0, 0, 0;SFX 23
defb 40,250, 8, 1, 0, 0, 0, 0;SFX 24
defb 250, 44, 6, 10, 1, 132, 1, 0;SFX 25
defb 0, 252, 20, 8, 1, 80, 8, 0;SFX 26
defb 230,230, 4, 1, 1, 0, 0, 0;SFX 27

#endasm
}

2

(3 replies, posted in Sinclair)

While searching around for different sound effects to use / play around with, I found the sound effect engine used in Steve Turner games.  The code I found was

....

;Steve Turner / Hewson Cons 
;sfx engine
;used in Ranarama, Quazatron,IronMan 
;you can use this routine on interrupts
;or in main game cicle

sound     
    ld a,(sonreq) ;new sound play?
    and a
    jr z,nonew  ;No new sound    
;да
    ld (sonnow),a
    dec a
    jr z,noise    ;#01 noise

    ld hl,sfx_data
    dec a
    add a,a
    add a,a
    add a,a
    ld e,a
    xor a
    ld (sonreq),a
    ld d,a
    add hl,de
    ld bc,08
    ld de,sonfrq
    ldir
    jr process

nonew     ld a,(sonnow) ;the old sound is?
    and a
    ret z
    
    dec a    ;continue noise?
    jr nz,process ;continue sound

    jr cnois

noise     ld a,0ah
    ld (sonlen),a
    xor a
    ld (sonreq),a

cnois     ld b,30h

gain    call random
    and 10h
    out (0feh),a
    ld c,02h

make    dec c
    jr nz,make
    djnz gain
    ld hl,sonlen
    dec (hl)
    ret nz
    xor a
    ld (sonnow),a
    ret

process    ld a,(sonfrq)
    ld h,a
    ld a,10h
    ld d,0ffh

sonlp     ld e,h
    out (0feh),a
    xor 10h

freq    dec d
    jr z,mod
    dec e
    jr nz,freq
    jr sonlp

mod    ld a,(soncfg)
    add a,h
    ld (sonfrq),a
    ld hl,sonmod
    dec (hl)
    ret nz
    ld hl,sonlen
    dec (hl)
    jr nz,modify
    xor a
    ld (sonnow),a
    ld a,(sonnex)
    and a
    ret z
    ld (sonreq),a
    ret

modify    ld a,(sobrsf)
    ld c,a
    ld a,(sontyp)
    and a
    jr z,reset
    dec a
    jr z,typ1
    dec a
    jr z,typ2

typoth    ld a,(soncfg)
    neg
    ld (soncfg),a
    jr mode

typ2    inc c
    inc c
    ld a,c
    ld (sobrsf),a
    jr reset

typ1    dec c
    dec c
    ld a,c
    ld (sobrsf),a
    jr reset

reset     ld a,c
    ld (sonfrq),a

mode    ld a,(sonrnd)
    ld (sonmod),a
    ret

random    push hl
    ld hl,(rnseed)
    inc hl
    ld a,h
    and 03
    ld h,a
rok    ld (rnseed),a
    ld a,r
    xor (hl)
    pop hl
    ret

rnseed    defw 1000h

sonfrq    defb 00    ;inital frequency
soncfg    defb 00    ;frequency change rate
sonmod    defb 00    ;number of sound modulations
sonlen    defb 00    ;number of times to repeat
sontyp    defb 00    ;modulate type
            ;0 sawtooth
            ;1 2nd mod down
            ;2 2nd mod up
            ;3+ triangle
sobrsf    defb 00    reset frequency
sonrnd    defb 00    ;change rate of reset frequency
sonnex    defb 00    ;linked sfx
sonnow    defb 00    ;what is being played
sonreq    defb 00    ;which effect?


sfx_data    
;here all souned excepts number 1 reserved for random noise     
;    defb       0,   5,   5,   1,   0,   0,   0,   0
;    defb     28h,   5, 0Ah,   1,   0,   0,   0,   0
;    defb       0, 80h, 1Eh,   1,   0,   0,   0,   0
;    defb           0,   2, 1Eh,   1,   0,   0,   0,   0
;    defb           0, 7Dh, 20h,   1,   0,   0,   0,   0
;    defb     0FFh, 83h, 20h,   1,   0,   0,   0,   0
;    defb     0FFh, 83h, 28h, 20h,   1, 3Ch,   1,   0
;    defb     0F0h,0F0h,   8,   3,   0, 3Ch,   6,   0
;    defb           2, 80h, 0Ah,   1,   0,   0,   0,   0
;    defb       28h,0FAh,   8,   1,   0,   0,   0,   0
;    defb     0FAh, 2Ch,   6, 0Ah,   1, 5Ah,   1,   0
;    defb           0,0FCh, 14h,   8,   1, 50h,   8,   0
;    defb     0E6h,0E6h,   4,   1,   1,   0,   0,   0
;    defb       2Dh, 43h, 14h,   1,   1,   0,   0,   0

Now to the real question(s).  I tried placing this in a C wrapper for usage in Z88DK, so I could call the effects within a single call.  It appears according to the comments that when this is called, only produces a small portion of the sound and returns back to the main loop. 

Can this be easily changed?

What would be more code friendly within Z88dk is to outpulse the entire sound at once and then return back to the game.  I realize that the game would pause while the effect takes place, I'm OK with that, just produce a really short sound while in action.

In Z88dk, I pass onto an assembly routine, L for char, HL for int and DEHL for long.  I am currently just sending L to the assembly and passing that onto a.  My wrapper for this is:

extern void __FASTCALL__ SFX(unsigned char fx) 
{
#asm
    
     ld a,l            ;32758
     ;rest of STEVE TURNER code ....

#endasm
}

Is that proper?  Sorry I am extremely weak on assembly and was hoping that someone much more experienced could help me out on this.

Thank you.

Andy

BTW, Here's my current game song using 1Tracker and AntEater with the loops and patterns I placed in anteater.

To make it easier for other to make games based with Z88dk and using various music engines, I'm now writing some articles on the music engines.

So far I've covered NanoBeep and Huby.  Coming up soon are articles on AntEater, Ntropic, Phaser and Tritone.

My articles can be found at:
zxspectrumcoding.wordpress.com

They are not meant to be technically advanced articles, as the advanced programmers already know how to do this sort of thing, but I think they can be a good reference point for anyone.

Andy

5

(0 replies, posted in Sinclair)

Been playing around with the excellent Ntropic engine.  I've now got a sample on how to include the Ntropic engine in a Z88dk build environment for menu music.

https://drive.google.com/open?id=1pQOfO … 3BD5JYprZ5

enjoy

Andy Dansby

6

(1 replies, posted in Sinclair)

Just sharing, rather trivial conversion to compile z88dk and sdcc.

https://drive.google.com/open?id=1fzERW … whcRvjZ3X5

I like the sound of Ant Eater.

7

(4 replies, posted in Sinclair)

I'm going to be doing a write up on some sound engines and their conversions working with z88dk with SDCC.  I'm also planning on talking to Alvin about including other sound engine to work naively with z88dk.

The Nanobeep code working with SDCC is at https://drive.google.com/open?id=1yzUqN … B10CQpM87G

With your suggestions, it should now be rather straightforward to convert any of the other engines.

Andy

8

(4 replies, posted in Sinclair)

I got it to work perfectly! 

ld (oldSP + 1),sp
..
ld (mLoopVar + 1),de
..
ld (speed + 2),de

Works like a champ.

Since I am doing this all with Z88dk and SDCC as the compiler, the compiler can place the music engine anywhere if finds fit, so I stripped out the #ORG and of course change all # to $, make the proper changes with the ld (oldSP + 1),sp   etc and I just got it to compile and play perfectly.

Thank you so much.

Andy

9

(4 replies, posted in Sinclair)

I've been playing around with the sound engines a bit and there are a number of them that I have not been able to convert to use with SDCC.

I am specifically working on Nanobeep, but I see this little line of code in many of the sound engines.

I have yet to find a way after much googling to find the SDCC equivalent of the command combo

oldSP equ $+1
ld sp,0

Which according to what I understand oldSP will read the value of sp prior to being changed back to 0.

The problems is that I am using SDCC assembly and me not knowing assembly very well I am having trouble converting this to some equivalent in SDCC.

Any help with this would be appreciated.

Thanks

10

(9 replies, posted in Sinclair)

I couldn't get it to ever work, but that's OK.  I'm just exploring each of the music engines to see what is appropriate for my game.  There's quite a few choices, but I'm starting to lean toward nanobeep2, which sounds pretty good with a good savings in memory.

BTW, I'm writing the game in Z88dk compiling using SDCC.  So there is a bit of code conversion to make it work proper in the build environment I'm using.

11

(9 replies, posted in Sinclair)

I could generate a pattern in 1tracker and then manually paste the sound data into pattern1, pattern2, etc...

such as this 2 note pattern.

;compiled music data
music_data:
    patterndata,0

patterndata:
    defw pattern1   
    defw pattern2
    defw music_data
   
pattern1:
    defb $14,$80,$49,$80,$49
    defb $0a,$01,$01
    defb $00;indicates end of pattern
   
pattern2:   
    defb $14,$82,$49,$82,$49
    defb $0a,$01,$01
    defb $00


Which plays the two notes and then crashes.

What I am thinking of for this is to create the pattern using 1 tracker and copy/paste the notes into a particular pattern and then set up the pattern in the pattern data section. 

I'm making a few assumptions, that the defb $00 indicates the end of the pattern and that the defb $0a,$01,$01 indicates a clearing of the pattern,  I'm certain that somehow I'm wrong in this

Also in music_data:
    patterndata,0

What does that ,0 mean

Forgive me for my naïvety

Thanks

12

(9 replies, posted in Sinclair)

Looping works great.

Code wise is there an easy way to introduce patterns into earshaver? I'm looking to save some data as opposed to re-coding parts of the song as redundant data.

13

(9 replies, posted in Sinclair)

I don't know if it is my version or some goofy thing happening on my machine, but ctrl-end seems to perform a mute operation on channel 1.  I'm running 1tracker 0.29

EDIT>>

This seems to be a problems with my laptop keyboard, I attached a 104 key keyboard and the  loop start and end works

14

(9 replies, posted in Sinclair)

I'm not a person who knows assembly, but I have a question about the Ear Shaver engine.

How to you get the song to Loop?

At the end of the assembly version, I see

music_data:
    defw song,0

followed later on by

loop:
    defb $01,$01,$01
    defb $00
    defw loop


But I don't know how to use the loop portion to make the song loop endlessly.

I also noticed another issue with the code produced by 1tracker.

In 1Tracker, I exported a song written with the Ear Shaver engine and was pretty happy with the results, but there seemed to be a large difference from the TAP vs the Assembly.  The assembly language version seems the fail on multiple notes being played simultaneously, while the TAP version works exactly as the tracker had it arranged.

So when I compiled the defective version, I did a disassembly on it and I found a difference at the very start of the code.

The working Tap version (export - Tap via 1tracker), produced

begin:
    ld hl,music_data
    rlca
    add a,b   
    call play
    ret


While the assembly version (export- assembly via 1 tracker) produced

begin:
    ld hl,music_data
    call play
    ret

When I added those two lines in, I got good results, so I wanted to point out that the assembly version seems to drop those commands.

As a bonus question, I'd like to ask to see if there was an easy way to get the border flashing with every note, which I found very attractive when playing a song.

Thanks

Andy

15

(2 replies, posted in Sinclair)

I am currently using the Phaser 1 sound engine in my game for a menu song and I quite like the sound it produces.  However, the size of Phaser (synth drums) eats quite a bit into the game.  Are there other engines that can product the Phase effect and take up few bytes?  I'm considering removing the drum routines to try to trim it a bit.

Any suggetions

Andy