FAQ  •  Register  •  Login

Sound effects?

<<

LTee

Posts: 153

Joined: Tue Jul 07, 2009 2:54 pm

Post Fri Mar 25, 2011 8:48 am

Sound effects?

Can anyone suggest how I could make some half-reasonable beeper sound effects? My initial experiments with BEEP are.... uninspiring. :-D

I was wondering if there was a tool or something that I could use to create some snazzier effects and then somehow integrate those into my ZXBasic setup? Or are there any tricks that people use to get more out of BEEP?

Thanks!
<<

britlion

Posts: 766

Joined: Mon Apr 27, 2009 7:26 pm

Location: Slough, Berkshire, UK

Post Sun Mar 27, 2011 1:32 pm

Re: Sound effects?

For music, you could try beepola: http://freestuff.grok.co.uk/beepola/

What are you looking for? Lasers zaps and bangs?
<<

LTee

Posts: 153

Joined: Tue Jul 07, 2009 2:54 pm

Post Sun Mar 27, 2011 2:03 pm

Re: Sound effects?

I'm not really sure, just anything that doesn't sound like 'beep'. :-)

I've seen Beepola before but never had a play with it. I'm not exactly 'talented' in the music department, but we'll see how it goes.
<<

LTee

Posts: 153

Joined: Tue Jul 07, 2009 2:54 pm

Post Mon Mar 28, 2011 8:17 am

Re: Sound effects?

Beepola seems quite amusing, although I'm still not entirely convinced that I have any musical talent whatsoever! It would be nice to add a couple of little jingles to my game though, and the Special FX engine sounds quite nice even without any talent. :-)

Has anyone integrated Beepola output with ZXBasic before? Wondering if there any pitfalls to watch out for before I go too far. Some of the engines use IM2, for instance - any potential problems there? I think the best thing to do would be to make a tiny test tune and see if I can get it working in-game.

Still experimenting (and not having much luck) with sound effects.
<<

boriel

Site Admin

Posts: 1463

Joined: Wed Nov 01, 2006 6:18 pm

Location: Santa Cruz de Tenerife, Spain

Post Mon Mar 28, 2011 8:31 am

Re: Sound effects?

I was trying some special effects using Beeps (fast constant beeps) or just OUT 254, x. These techniques were uses on earlier games for the ZX Spectrum. I think there are some beep tutorials in WOS (probably someone has already asked for this at the WOS forum). Have you looked in there?
<<

LTee

Posts: 153

Joined: Tue Jul 07, 2009 2:54 pm

Post Mon Mar 28, 2011 8:57 am

Re: Sound effects?

Maybe that's my issue, I need to do more, faster beeps so that they sound less 'beep-like' - it's kind of tricky to do this by trial and error though, especially seeing as the same code sounds slightly different when compiled with ZXBasic than it does in proper Spectrum BASIC (I surmise Spectrum BASIC isn't quite fast enough to handle the very short beeps elegantly and it results in a slightly slower, lower-pitched sound).

I did do a search of the WOS forums but it's hard to know what to search for. I might pop a question into the development forum and see if anyone there has any pointers for either a tool or a tutorial. It seems strange that there are so many great tools for beeper music but very little for snappy little sound effects.

Is there any discernible difference between using BEEP or OUT 254 in ZXBasic, or are they ultimately different ways of calling the same code?
<<

LTee

Posts: 153

Joined: Tue Jul 07, 2009 2:54 pm

Post Mon Mar 28, 2011 12:44 pm

Re: Sound effects?

In case anyone was interested, Beepola music seems to integrate with ZXBasic just fine! Created a one-pattern ditty with the SpecialFX engine and got it working in my game with no issues. :-)
<<

britlion

Posts: 766

Joined: Mon Apr 27, 2009 7:26 pm

Location: Slough, Berkshire, UK

Post Mon Mar 28, 2011 12:47 pm

Re: Sound effects?

For those of us that haven't done it yet (and I've got some stuff I want to add into my game, space permitting) can you post source of how you put it in?
<<

LTee

Posts: 153

Joined: Tue Jul 07, 2009 2:54 pm

Post Mon Mar 28, 2011 1:16 pm

Re: Sound effects?

There's no real 'source' as yet, because I sort of hacked it in there to prove a point. :-)

Basically I created a tune and 'compiled' it from Beepola, then saved it as a .TAP file with a start address of 64000. I then added a 'randomize usr 64000' call into my game at the required point and compiled it to a low-enough address that I knew the game wouldn't overwrite the music. Then I loaded both the game code and the music code before starting the game.

This seems a little fiddly, but it works.

You can get Beepola to output an .asm file instead (which I think would be easier in the long run), but I've not had time to finish playing around with that method yet - it seems a neater way of including the music so that you can build the whole thing in one go.

The ASM *almost* compiles just by wrapping it in an asm/end asm block, there just seems to be a very slight incompatibility with how ZXBasic handles EQU. Beepola outputs this:

  Code:
; *** DATA ***
VECTOR_TABLE_LOC:    EQU $FE00
BORDER_CLR:          EQU $0


But ZXBasic doesn't like the colons at the end of the label before the EQUs. Remove those and it compiles fine!

i.e.
  Code:
; *** DATA ***
VECTOR_TABLE_LOC    EQU $FE00
BORDER_CLR          EQU $0
<<

britlion

Posts: 766

Joined: Mon Apr 27, 2009 7:26 pm

Location: Slough, Berkshire, UK

Post Mon Mar 28, 2011 1:36 pm

Re: Sound effects?

Good to know the asm can be levered in without too much trouble :)
<<

LTee

Posts: 153

Joined: Tue Jul 07, 2009 2:54 pm

Post Mon Mar 28, 2011 1:43 pm

Re: Sound effects?

Just had a quick go at integrating it via the asm file and it's proving a little more problematic than I expected, I suspect because of the 'org 64000' at the start of the file. If I #include it at the end of my game's code I end up with a tzx which is over 60000 bytes long!

I think I need to fiddle some more. :-)
<<

britlion

Posts: 766

Joined: Mon Apr 27, 2009 7:26 pm

Location: Slough, Berkshire, UK

Post Mon Mar 28, 2011 2:37 pm

Re: Sound effects?

That would be fairly normal - it tries to make it one file, so there's a lot of zeroes along the way.

Might be easier to use align to push it there, or write a routine to relocate it to where you need it to be. (there's a block move routine in zx basic)

Or rewrite the code somewhat so it doesn't matter what address it's at - it doesn't care so long as it's placed > 32768 - but does need to be compiled correctly.

What happens if you take out the org?
<<

LTee

Posts: 153

Joined: Tue Jul 07, 2009 2:54 pm

Post Tue Mar 29, 2011 7:43 am

Re: Sound effects?

Interestingly, that seems to work okay. I'm not exactly a Z80 whizz, but a quick glance over the code seems to suggest that the vast majority of it doesn't care where it's loaded. Only the IM2 service routine has to be at a fixed location and that's hard-coded to $FE00 and above by the player itself. So I suspect that it'll all work fine without the ORG, providing you ensure that your compiled code doesn't exceed address 65024.

This is with the Special FX engine, of course - some of the other players don't use the IM2 table if I'm reading it correctly. But they don't sound as nice. :-)
<<

LTee

Posts: 153

Joined: Tue Jul 07, 2009 2:54 pm

Post Tue Mar 29, 2011 7:51 am

Re: Sound effects?

Hmm... or maybe not. Something's not *quite* right still. The music will play once, but it doesn't exit properly at the end of the tune (or if you press a key) - the Spectrum locks up rather than ending play gracefully.

I'll paste what I've been messing around with, maybe someone else can see what the issue is:
  Code:
cls
while(1)
   print "PRESS ANY KEY TO PLAY"
   while inkey <> "": end while
   while inkey = "": end while
   while inkey <> "": end while
   playmusic()
   border 7
end while

sub playmusic()
   asm
   ;                ORG 64000
   ; *****************************************************************************
   ; * Special FX Music Player Engine
   ; *
   ; * Based on code written by Jonathan Smith for the Special FX game, Firefly.
   ; * Modified by Chris Cowley
   ; *
   ; * Produced by Beepola v1.06.01
   ; ******************************************************************************
   
   START:          DI
               EXX
               PUSH  HL                    ; Preserve HL' for return to BASIC
               CALL  PLAY_MUSIC
               IM    1
               POP   HL
               EXX
               EI
               RET

   PLAY_MUSIC:
               CALL  MAKE_VECTOR_TABLE
               CALL  INIT_ISR
               IM    2
               LD    A,VECTOR_TABLE_LOC / 256
               LD    I,A

               LD    HL,MUSICDATA         ;  <- Pointer to Music Data. Change
                                    ;     this to play a different song
               LD    E,(HL)
               INC   HL
               LD    D,(HL)
               INC   HL
               LD    (NEXT_PATT_PTR),HL
               LD    (NEXT_PERC_PATT_PTR),DE
               LD    (SAVED_SP),SP
               LD    HL,PLAYER_ISR
               LD    ($FFF5),HL           ; Set up the JP instruction to point
                                    ; to our player ISR
               LD    A,BORDER_CLR
               LD    (OUT_VAL1),A         ; Beeper out values for chan1
               LD    (OUT_VAL2),A         ; Beeper out values for chan1
               LD    (OUT_VAL3),A         ; Beeper out values for chan2
               LD    (OUT_VAL4),A         ; Beeper out values for chan2
               CALL  SET_NEXT_PATT
               CALL  SET_NEXT_PERC_PATT
               LD    C,$01
               EXX
               LD    BC,$0101
               EI
               HALT
   NEXT_NOTE:      CALL  C,LF02C
               LD    A,B
               OR    A
               JR    NZ,LEF99
   LEF61:          DEFB  $21               ; LD HL,nn
   CURR_PATT_CH1:
               DEFW  $0000             ; Current Pattern for chan1
   LEF64:          LD    A,(HL)
               OR    A
               JP    M,LEB9B           ; bit7 set - command (sustain, pattern end, etc)
               CALL  LF0F6
               LD    (LEFA2),A
               SRL   A
               SRL   A
               SRL   A
               LD    D,A
               LD    (LEFAD),A
               XOR   A
               LD    (LF02D),A
               INC   A
               LD    (LEFA4),A
               LD    A,(OUT_VAL1)      ; Adjust the EAR and MIC bits of this
               OR    $18               ; port output value for the tone
               LD    (OUT_VAL1),A      ; generator
               INC   HL
   POST_MUTE1:     LD    A,(HL)
               LD    (LEF96),A
               INC   HL
               LD    (CURR_PATT_CH1),HL
               DEFB  $06               ; LD    B,n
   LEF96:          DEFB  $54
               JR    LEF9E
   LEF99:          LD    A,$03
   LEF9B:          DEC   A
               JR    NZ,LEF9B
   LEF9E:          DEC   D
               JR    NZ,LEFB5

               DEFB  $16               ; LD D,n
   LEFA2:          DEFB  $3B
               DEFB  $3E               ; LD A,n
   LEFA4:          DEFB  $07
   LEFA5:          DEC   A
               JR    NZ,LEFA5

               DEFB  $3E               ; LD A,n
   OUT_VAL1:       DEFB  $0
               OUT   ($FE),A
               DEFB  $3E               ; LD A,n
   LEFAD:          DEFB  $01               ; frequency counter for CH1
   LEFAE:          DEC   A
               JR    NZ,LEFAE

               DEFB  $3E               ; LD A,n
   OUT_VAL2:       DEFB  $00
               OUT   ($FE),A
   LEFB5:          LD    A,C
               OR    A
               JR    NZ,LEFEF

               DEFB  $21               ; LD HL,nn
   CURR_PATT_CH2:  DEFW  $0000             ; Current pattern for CH2
   LEFBC:          LD    A,(HL)
               OR    A
               JP    M,LEBA6           ; bit7 set - command (sustain, pattern end, etc)
               CALL  LF0F6
               LD    (LEFF9),A
               SRL   A
               SRL   A
               LD    (LF004),A
               LD    E,A
               XOR   A
               LD    (LF045),A
               INC   A
               LD    (LEFFB),A
               LD    A,(OUT_VAL3)
               OR    $18
               LD    (OUT_VAL3),A
               INC   HL
   POST_MUTE2:     LD    A,(HL)
               LD    (LEFEC),A
               INC   HL
               LD    (CURR_PATT_CH2),HL
               DEFB  $0E               ; LD C,n
   LEFEC:          DEFB  $0E
               JR    LEFF4

   LEFEF:          LD    A,$03
   LEFF1:          DEC   A
               JR    NZ,LEFF1
   LEFF4:          DEC   E
               JP    NZ,NEXT_NOTE

               DEFB  $1E               ; LD E,n
   LEFF9:          DEFB  $3B
               DEFB  $3E               ; LD A,n
   LEFFB:          DEFB  $02
   LEFFC:          DEC   A
               JR    NZ,LEFFC

               DEFB  $3E               ; LD A,n
   OUT_VAL3:       DEFB  $18
               OUT   ($FE),A
               DEFB  $3E               ; LD A,n
   LF004:          DEFB  $0D               ; ch2 note frequency
   LF005:          DEC   A
               JR    NZ,LF005

               DEFB  $3E
   OUT_VAL4:       DEFB  $0
               OUT   ($FE),A
               JP    NEXT_NOTE

   LF00F:
               POP   HL
               LD    A,(HL)
               LD    (LF033),A
               INC   HL
               JP    LEF64

   LF018:          POP   HL
               LD    A,(HL)
               LD    (LF04B),A
               INC   HL
               JR    LEFBC

   MUTE_CH1:       POP   HL
               LD    A,(OUT_VAL1)
               AND   $07
               LD    (OUT_VAL1),A
               JP    POST_MUTE1

   MUTE_CH2:       POP   HL
               LD    A,(OUT_VAL3)
               AND   $07
               LD    (OUT_VAL3),A
               JP    POST_MUTE2
   NULL_NOTE1:     POP   HL
               JP    POST_MUTE1
   NULL_NOTE2:     POP   HL
               JP    POST_MUTE2

   LF021:
               POP   HL
               CALL  SET_NEXT_PATT
               JP    LEF61

   LF02C:          DEFB  $3E
   LF02D:          DEFB  $00
               INC   A
               LD    (LF02D),A
               DEFB  $FE               ; CP
   LF033:          DEFB  $02
               JR    C,LF044
               XOR   A
               LD    (LF02D),A
               LD    HL,LEFAD
               DEC   (HL)
               JR    Z,LF043
               LD    HL,LEFA4
   LF043:          INC   (HL)

   LF044:          DEFB  $3E               ; LD A,n
   LF045:          DEFB  $00
               INC   A
               LD    (LF045),A
               DEFB  $FE               ; CP
   LF04B:          DEFB  $04
               RET   C
               XOR   A
               LD    (LF045),A
               LD    HL,LF004
               DEC   (HL)
               JR    Z,LF05A
               LD    HL,LEFFB
   LF05A:          INC   (HL)
               RET

   LF0F6:          PUSH  HL
               PUSH  DE
               LD    HL,FREQ_TABLE
               LD    E,A
               LD    D,$0
               ADD   HL,DE
               LD    A,(HL)
               POP   DE
               POP   HL
               RET

   ; ** Reads and sets up the next melody pattern to play
   SET_NEXT_PATT:
               DEFB  $21   ; LD HL,nn
   NEXT_PATT_PTR: DEFW  $0000              ; holds a pointer to the
                                 ; next pattern in the patter list
   GET_PATT_ADDR: LD    E,(HL)
               INC   HL
               LD    D,(HL)
               INC   HL
               LD    A,E
               OR    D
               JR    NZ,STORE_NEXT_P
               JP    ISR_KEY_PRESSED
   STORE_NEXT_P:  LD    (NEXT_PATT_PTR),HL
               EX    DE,HL
               LD    E,(HL)
               INC   HL
               LD    D,(HL)
               INC   HL
               LD    (CURR_PATT_CH1),HL
               LD    (CURR_PATT_CH2),DE
               RET

   ; ** Reads and sets up the next percussion pattern to play
   SET_NEXT_PERC_PATT:
               DEFB  $21   ; LD HL,nn
   NEXT_PERC_PATT_PTR:
               DEFW  $0000
   GET_PERC_ADDR: LD    E,(HL)
               INC   HL
               LD    D,(HL)
               INC   HL
               LD    (NEXT_PERC_PATT_PTR),HL
               LD    (PERC_PATT),DE
               LD    A,E
               OR    D
               RET   NZ
               LD    E,(HL)
               INC   HL
               LD    D,(HL)
               EX    DE,HL
               JR    GET_PERC_ADDR
               CALL  SET_NEXT_PERC_PATT
               JR    PLAY_PERC

   LEB9B:
               INC   HL
               PUSH  HL
               AND   $7F
               CALL  JUMP_PERC_ADDR
               DEFW  LF021
               DEFW  LF00F
               DEFW  MUTE_CH1
               DEFW  NULL_NOTE1

   LEBA6:         INC   HL
               PUSH  HL
               AND   $7F
               CALL  JUMP_PERC_ADDR
               DEFW  LF021
               DEFW  LF018
               DEFW  MUTE_CH2
               DEFW  NULL_NOTE2

   PLAY_PERC:
               DEFB  $21                   ; LD HL,nn
   PERC_PATT:     DEFW  $0000                 ; Address of the percussion data
               LD    A,(HL)
               INC   HL
               LD    C,(HL)
               INC   HL
               LD    (PERC_PATT),HL        ; Point PERC_PATT at next datum
               AND   $7F
               CALL  JUMP_PERC_ADDR
               DEFW  DRUM00                ; F094
               DEFW  DRUM01                ; F09A
               DEFW  DRUM02                ; F0AC
               DEFW  DRUM03                ; F0BB
               DEFW  DRUM04                ; F0D4
               DEFW  DRUM05                ; F07C

   JUMP_PERC_ADDR:
               POP   HL                    ; F0ED
               ADD   A,A
               ADD   A,L
               LD    L,A
               LD    A,(HL)
               INC   HL
               LD    H,(HL)
               LD    L,A
               JP    (HL)

   DRUM00:        CALL  SET_NEXT_PERC_PATT
               JR    PLAY_PERC

   DRUM01:        LD    E,$0A
               LD    A,BORDER_CLR
               LD    HL,$0100
   DRUM01NOISE:   XOR   $18
               OUT   ($FE),A
               LD    B,(HL)
   DRUM01LOOP:    DJNZ  DRUM01LOOP
               INC   HL
               DEC   E
               JR    NZ,DRUM01NOISE
               RET

   DRUM02:        LD    HL,$005A
   DRUM02LOOP:    LD    A,(HL)
               OR    A
               RET   Z
               AND   $18
               OR    BORDER_CLR
               OUT   ($FE),A
               INC   HL
               JR    DRUM02LOOP

   DRUM03:        LD    HL,$0F18
               LD    D,$0A
   DRUM03LOOP3:   LD    B,(HL)
   DRUM03LOOP:    DJNZ  DRUM03LOOP
               LD    A,$18
               OR    BORDER_CLR
               OUT   ($FE),A
               INC   HL
               LD    B,(HL)
   DRUM03LOOP2:   DJNZ  DRUM03LOOP2
               LD    A,BORDER_CLR
               OUT   ($FE),A
               INC   HL
               DEC   D
               JR    NZ,DRUM03LOOP3
               RET

   DRUM04:        LD    E,$3F
               LD    D,$05
   DRUM04LOOP3:   LD    B,E
   DRUM04LOOP:    DJNZ  DRUM04LOOP
               LD    A,$18
               OR    BORDER_CLR
               OUT   ($FE),A
               LD    A,E
               RRCA
               LD    E,A
               LD    B,A
   DRUM04LOOP2:   DJNZ  DRUM04LOOP2
               LD    A,BORDER_CLR
               OUT   ($FE),A
               DEC   D
               JR    NZ,DRUM04LOOP3
   DRUM05:        RET

   ; ** Creates a vector table of 257 0xFF bytes at the location specified
   ; ** by VECTOR_TABLE_LOC
   MAKE_VECTOR_TABLE:
               LD    HL,VECTOR_TABLE_LOC
               LD    DE,VECTOR_TABLE_LOC + 1
               LD    BC,$0100
               LD    (HL),$FF
               LDIR
               RET

   ; *** The IM 2 service routine active throughout the life of the player
   ; *** updates counters, plays any active percussion sounds, and checks for
   ; *** keypresses or Kempston joystick fire button to terminate
   PLAYER_ISR:
               PUSH  AF
               PUSH  DE
               PUSH  HL
               DEC   C
               DEC   B
               EXX
               DEC   C
               CALL  Z,PLAY_PERC          ; EBB1
               ; Read keyboard
               XOR   A
               IN    A,($FE)
               CPL
               AND   $1F
               JR    NZ,ISR_KEY_PRESSED
               XOR   A
               IN    A,($1F)
               BIT   5,A
               JR    NZ,END_PLAYER_ISR
               BIT   4,A
               JR    NZ,ISR_FIRE_PRESSED
   END_PLAYER_ISR: EXX
               POP   HL
               POP   DE
               POP   AF
               SCF
               EI
               RETI
   ISR_FIRE_PRESSED:
   ISR_KEY_PRESSED:
               DEFB  $31                  ; LD SP,nn
   SAVED_SP:       DEFW  $0000                ;
               EI
               RETI

   ; ** Sets up everything for our IM2 service routine. Specifically, copies a JR
   ; ** instruction to $FFFF and a JP $F0FF to $FFF4
   INIT_ISR:
               LD    HL,$FFFF
               LD    (HL),$18               ; Copies in our JR for JR FFF4
               LD     HL,$FFF4
               LD    (HL),$C3               ; JP (jump address filled-in
                                     ; during player initialization)
               RET


   ; *** DATA ***
   VECTOR_TABLE_LOC    EQU $FE00
   BORDER_CLR          EQU $0
   FREQ_TABLE:          DEFB $FD,$EE,$E1,$D4,$C8,$BD,$B2,$A8,$9F,$96,$8E,$86,$7E
                   DEFB $77,$70,$6A,$64,$5E,$59,$54,$4F,$4B,$47,$43,$3F
                   DEFB $3B,$38,$35,$32,$2F,$2C,$2A,$27,$25,$23,$21,$1F
                   DEFB $1D,$1C,$1B,$19,$17,$16,$15,$13,$12,$11,$10,$0F
                   DEFB $0E,$0D,$0C,$01,$00


   MUSICDATA:        DEFW      PERCSTART
   SONGSTART:        DEFW      PAT1
                 DEFW      $0000
                 DEFW      SONGSTART

   PAT1:     DEFW  PAT1C2
       DEFB 6,14
       DEFB 10,14
       DEFB 8,7
       DEFB 10,7
       DEFB 11,7
       DEFB 8,7
       DEFB 6,14
       DEFB 10,14
       DEFB 8,7
       DEFB 10,7
       DEFB 11,7
       DEFB 8,7
       DEFB $80
   PAT1C2:
       DEFB 23,7
       DEFB 22,7
       DEFB 20,7
       DEFB 22,7
       DEFB 23,7
       DEFB 23,7
       DEFB 22,7
       DEFB 20,7
       DEFB 23,7
       DEFB 22,7
       DEFB 20,7
       DEFB 22,7
       DEFB 23,7
       DEFB 23,7
       DEFB 22,7
       DEFB 20,7
       DEFB $80
   PERCSTART:   DEFW      DRM1
             DEFW      $0000
             DEFW      PERCSTART

   DRM1:
       DEFB 129,28
       DEFB 131,28
       DEFB 129,28
       DEFB 131,28
       DEFB $80
   end asm
end sub
<<

oblo

Posts: 60

Joined: Tue Jul 12, 2011 5:23 pm

Post Thu Jul 14, 2011 4:54 pm

Re: Sound effects?

Hi all

LTee, How a song created with Beepola can be integrated in ZX Basic? I don't know how to handle the .bbsong format in Basic.

Thanks and regards
Next

Return to How-To & Tutorials

Who is online

Users browsing this forum: No registered users and 2 guests

cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by Vjacheslav Trushkin for Free Forums/DivisionCore.

phpBB SEO