Jump to content
IGNORED

My new Sound System


Richi_S

Recommended Posts

That's it... the sound system which I'm going to use for my games.

 

The features are:

- It fits in the Vsync area for all conditions (verified)

- Needs 9 bytes of RAM

- Variable Music Speed.

- It enfeatures one Melodic Instrument with ADSR-Envelope waveform functionalty (AUDF and AUFV are modulated every TV frame)

- It enfeatures one percussion track with up to 30 freely designable Percussion Instruments (AUDC, AUDF and AUV are modulated every TV frame)

- The song can be Programmed with a Tracker.

- In order to save ROM space and coding time, repetitive music data (beats) can be "compressed".

- Selectable Song Start position, Song End position, "Loop to when song has ended" Position.

- Both Tracks: "Melodic Instrument" and "Percussion Instrument" can be muted with flags separately, thus the game developer can regain control of the TIA for his own sound effects.

 

This file demonstrates:

- Enable / Disable the tracks (Joystick 0 & 1 Fire Button)

- The TV Frame comes up normaly (Vsync works as desired)

 

With minor changes following additions can be made to the sound system:

- Change Music speed (Speed Up / Down)

- Change Music volume (-50%, -75%)

- Switch between multiple songs

- Pause playback and resume playback

- Change the Melodic Instrument during runtime

Most of these changes just require extra RAM; no extra code in the VSYNC area needed.

 

Following in the next days I'm going to post tutorials of how to use the system:

- Design your own Percussion Instruments

- Design your own Melodic Instrument

- Understand the Tracker

- Type in songs in the Tracker

- Using the generic software functions

- Gain additional benefit for your games (e.g. read the Sound Systems timers)

- Adding the mentioned software features to the Sound System.

soundsys.bin

soundsys.asm.txt

Link to comment
Share on other sites

Session #1

This session and the following session will show how to unse the percussion instrument.

This session shows how to arrange percussion beats in the tracker unit.

 

Lets have a look on the relevant code:

Lines 129 to 139:

;The Tracker:
;Initial starting Point of the Song
MUSIC_SONG_START = #0
;Loop to Point of the Song after the end point is reached
MUSIC_SONG_LOOP_TO = #0
;End Point of the Song
MUSIC_SONG_END = #9
;Song Timer prescaler: 5 -> 90 BPM @NTSC (with Note Base: 1/8)
MUSIC_TIMER_PRESCALER  = #5

Lines 154 to 175:

;Stella Pattern 1: Percussion sequences
Music_Tracker_Pattern1_table
        ;Audio0: pointer to the Patterns (1 Pattern = 1 Beat)
        ;        0    1    2    3    4    5    6    7    8 9=END
        .byte #$08,#$10,#$18,#$08,#$10,#$18,#$08,#$10,#$18

        ;Audio0: percussion instruments
        ; 0 - None
        ; 1 - Kick Drum
        ; 2 - High Hat
        ; 3 - Snare

Music_Tracker_beat1_Percussion_table
        ;$00 - Silence
        .byte  #0 ,#0 ,#0 ,#0 ,#0 ,#0 ,#0 ,#0

        ;$08 - Bassline 1
        .byte  #1 ,#0 ,#0 ,#0 ,#2 ,#0 ,#0 ,#0
        ;$10 - Bassline 1
        .byte  #1 ,#0 ,#1 ,#0 ,#2 ,#0 ,#1 ,#0
        ;$18 - Bassline 1
        .byte  #0 ,#0 ,#1 ,#0 ,#2 ,#0 ,#0 ,#0

 

In this example 4 percussion instruments are given:

0 - None

1 - Kick Drum

2 - High Hat

3 - Snare

You can work with them to try things out.

 

 

Lets see how things work:

 

Music_Tracker_beat1_Percussion_table

It is comparable to a pattern of the TR-909

8 bytes or one line of the "Music_Tracker_beat1_Percussion_table" define one Beat. One Beat consists of 8 notes - here instrumets. The instruments are played from left to right.

The Numbers #0 to #3 represent the instruments to be played.

e.g. at Position $10 it goes:

Kick Drum -> None -> Kick Drum -> None -> High Hat -> None -> Kick Drum -> None

 

Music_Tracker_Pattern1_table

The pattern table aramges the beats or patterns in one song.

It is played from left to right.

All elements point to addresses of the Music_Tracker_beat1_Percussion_table

1. When a beat has ended, the next location of the Music_Tracker_Pattern1_table is loaded, the patterns address is loaded from the table.

2. Starting at this address 8 notes are loaded from the "Music_Tracker_beat1_Percussion_table".

3. When 8 notes are layed the procedure starts over at point 1.

 

This system of linking beats (or patterns) allows you to reuse the once defined drum sequences. This saves ROM and your typing time.

 

Start and end of the Song:

There is just one question: Where in table "Music_Tracker_beat1_Percussion_table" does the song start and where does it end...

This is defined by the Constants:

MUSIC_SONG_START: Where teh song shall start at the first time the Game has started

MUSIC_SONG_END: Where the end if the song is (is thas to be the last address of Music_Tracker_beat1_Percussion_table + 1)

MUSIC_SONG_LOOP_TO: Where to loop to when the song has ended

 

Finally the song speed:

MUSIC_TIMER_PRESCALER: Defines the songs speed. Particullarly: For how many TV Frames one note shall be played. In this example the Range goes from 1 to 6. We will come to that later.

 

Now how does it work like during execution:

..............Variable & Description............... ------- Time --------->

Music_pattern_pointer______________________________$00 $00 $00 $00 $00 $00 $00 $00 $01 $01 $01 $01 $01 $01 $01 $01 $02 $02 $02 $02 $02 $02 $02 $02

Address in Music_Tracker_Pattern1_table

runs from MUSIC_SONG_START/MUSIC_SONG_LOOP_TO to MUSIC_SONG_END-1 and reprats

Music_beat_pointer_1_______________________________$08 $08 $08 $08 $08 $08 $08 $08 $10 $10 $10 $10 $10 $10 $10 $10 $18 $18 $18 $18 $18 $18 $18 $18

is loadad from Music_Tracker_Pattern1_table (Music_pattern_pointer is a pointer)

 

Music_beat_pointer_offset__________________________$00 $01 $02 $03 $04 $05 $06 $07 $00 $01 $02 $03 $04 $05 $06 $07 $00 $01 $02 $03 $04 $05 $06 $07

runs from 0 o 7

 

"Address in Music_Tracker_beat1_Percussion_table"__$08 $09 $0A $0B $0C $0D $0E $0F $10 $11 $12 $13 $14 $15 $16 $17 $18 $19 $1A $1B $1C $1D $1E $1F

= Music_beat_pointer_offset + Music_beat_pointer_1

 

Instrument to be played_____________________________#01 #00 #00 #00 #02 #00 #00 #00 #01 #00 #01 #00 #02 #00 #01 #00 #00 #00 #01 #00 #02 #00 #00 #00

loadad from Music_Tracker_beat1_Percussion_table ("Address in Music_Tracker_beat1_Percussion_table" is the pointer)

 

Have fun playing around with the code, why not create your own beats. There is still an unused instrument: 3 - Snare.

Next session I'll describe how to create your own percussion instruments.

session1.asm.txt

Edited by Richi_S
Link to comment
Share on other sites

  • 2 weeks later...

Session #2:

This session will show how to create your own percusion instruments.

This demo file shows some neat instruments that I gathered from all around...

 

The basic theory is that when a percussion instrument has to be played, the instruments number is loaded out of the "Music_Tracker_beat1_Percussion_table".

So every X TV-frames a instrument has to be played for X TV-Frames (X depends on the MUSIC_TIMER_PRESCALER).

While the X TV-frames pass by the values for AUDC1, AUDF1 and AUDV1 have to be loaded every TV-Frame from tables.

 

So You've got full control:

You can change all sound registers of the Track 1. This allows you to design your own percussion instruments, you can even design small melodies (as done in this demos) or design neat pecial effects.

 

E.g. An Instrument I call Advanced Snare (Instrument No. 1):

...... ----- TV Frames ---->

Frame: 0.. 1.. 2.. 3.. 4.. 5.. 6.. ...

AUDF1: #14,#14,#1 ,#1 ,#1 ,#0 ,#0 ,#0 ...

AUDV1: #14,#14,#5 ,#5 ,#5 ,#5 ,#0 ,#0 ...

AUDC1: #15,#15,#8 ,#8 ,#8 ,#8 ,#0 ,#0 ...

 

For the beginning I recommend to use the instruments Paul Slocum introduced:

http://www.qotile.net/files/2600_music_guide.txt

 

The actual sound slighty varys from emulator to emulator... I like Z26 best.

 

Lets have a look on the relevant code:

Lines 67 to 102

Music_Percussion_table
        ;Percussion Instruments 
        ; 0 - None
        ; 1 - Advanced Snare
        ; 2 - Clap
        ; 3 - Bassdrum
        .byte  #0 ,#10 ,#20 , #30
Music_percussion_AUDF1_table
        ;      --- TV Frames ---->
        ;      0    1    2    3    4    5     6     7    8    9
        ;00 No Instrument
        .byte  #0  ,#0  ,#0  ,#0  ,#0  ,#0   ,#0  ,#0  ,#0  ,#0
        ;10  Advanced Snare
        .byte  #14 ,#14 ,#1  ,#1  ,#1  ,#0   ,#0  ,#0  ,#0  ,#0
        ;20  Clap
        .byte  #5  ,#5  ,#5  ,#0  ,#0  ,#0   ,#0  ,#0  ,#0  ,#0
        ;30  Bassdrum
        .byte  #8  ,#8  ,#16 ,#16 ,#20 ,#24  ,#0  ,#0  ,#0  ,#0
Music_percussion_AUDV1_table
        ;00 No Instrument
        .byte  #0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0
        ;10  Advanced Snare
        .byte  #12 ,#12 ,#4  ,#4  ,#4  ,#4  ,#0  ,#0  ,#0  ,#0
        ;20  Clap
        .byte  #7  ,#7  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0
        ;30  Bassdrum
        .byte  #10 ,#10 ,#10 ,#10 ,#10 ,#10  ,#0  ,#0  ,#0 ,#0
Music_percussion_AUDC1_table
        ;00 No Instrument
        .byte  #12 ,#12 ,#12 ,#12 ,#12 ,#12 ,#0  ,#0  ,#0  ,#0
        ;10  Advanced Snare
        .byte  #15 ,#15 ,#8  ,#8  ,#8  ,#8  ,#0  ,#0  ,#0  ,#0
        ;20  Clap
        .byte  #8  ,#8  ,#8  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0
        ;30  Bassdrum
        .byte  #10 ,#10 ,#10 ,#10 ,#10 ,#0   ,#0  ,#0  ,#0  ,#0

 

And thats how it works:

When the adress in the "Music_Tracker_beat1_Percussion_table" has changed (a new note is played) the instruments nunber is loaded out of the table.

The instruments number is a pointer in the "Music_Percussion_table".

The values in "Music_Percussion_table" represent the starting address in the tables where the AUDC1, AUDF1, and AUDV1 values are stored in (Music_percussion_AUDF1_table, Music_percussion_AUDV1_table, Music_percussion_AUDC1_table).

 

In this demo file for example:

.......Location & Descritpion.......... ------ TV Frames ---->

Instrument to be played:_______________ #1, #1, #1, #1, #1, #0, #0, #0, #0, #0,

loaded from Music_Tracker_beat1_Percussion_table , see session #1

Value of Music_Percussion_table:_______ #10,#10,#10,#10,#10,#0 ,#0 ,#0 ,#0 ,#0

the instrument is the pointer to Music_Percussion_table.

 

Music_timer:___________________________ #0, #1, #2, #3, #4, #0, #1, #2, #3, #4

runs from 0 to MUSIC_TIMER_PRESCALER -1

 

Adress in Music_percussion_AUDx1_table: #10,#11,#12,#13,#14,#00,#01,#02,#03,#04

= Value of Music_Percussion_table + Music_timer

 

value of Music_percussion_AUDF1_table__ #14,#14,#1 ,#1 ,#1 ,#0 ,#0 ,#0 ,#0 ,#0

value of Music_percussion_AUDV1_table__ #12,#12,#4 ,#4 ,#4 ,#0 ,#0 ,#0 ,#0 ,#0

value of Music_percussion_AUDC1_table__ #15,#15,#8 ,#8 ,#8 ,#12,#12,#12,#12,#12

These values are stored to AUDF1, AUDV1, AUDC1

 

The the AUDx tables have to contain at least (MUSIC_TIMER_PRESCALER -1) elements for every percussion instrument.

In the demo file - just for convenience - every instrument has got 10 elements. So there is much wasted ROM space. On the other hand side it keeps the system flexible. The Music speed (MUSIC_TIMER_PRESCALER) can be changed up to 11.

 

The original music is from BMX Airmaster for the 2600. Feel free to compare the results.

session 2_3.asm.txt

session 2_3.bin

Edited by Richi_S
Link to comment
Share on other sites

Session #3:
This session shows how to compose tunes for the melodic instrument.
I assume to use Anvil studio to do the actual composing work and then to "convert" the tune into code.
With Anvil you can also edit and check given midi files without big musical knowledge (I love the piano roll editor).

All you need is:
Anvil Studio: http://www.anvilstudio.com/
http://anvil-studio.softonic.de/

A conversion table Real notes to 2600 AUDF values:
http://qotile.net/files/2600_music_guide.txt
http://www.randomterrain.com/atari-2600-memories-batari-basic-music-toy.html

First the theory, how the sound system processes the notes:
It's almost like the percussion system:
Music_Tracker_beat0_instrument_notes_table stores the notes to be played.
Basically these values are the AUDF values to be played:
Values from 0 to 31: Normal AUDF values.
Values from 32 to 63: Subtract 32 and you've got the AUDF values - will be explained later on.
Value 99: PAUSE - will be explained later on.
Eight notes form a Beat.

Music_Tracker_Pattern0_table stores the sequence the beats shal be played. It represents the starting Address in the Music_Tracker_beat0_instrument_notes_table.

For Example:

Music_pattern_pointer:_____________________________________ $00 $00 $00 $00 $00 $00 $00 $00 $01 $01 $01 $01 $01 $01 $01 $01 $02 $02 $02 $02 $02 $02 $02 $02
Address in Music_Tracker_Pattern0_table
runs from MUSIC_SONG_START/MUSIC_SONG_LOOP_TO to MUSIC_SONG_END-1 and reprats

Music_beat_pointer_0:______________________________________ $00 $00 $00 $00 $00 $00 $00 $00 $08 $08 $08 $08 $08 $08 $08 $08 $10 $10 $10 $10 $10 $10 $10 $10
is loadad from Music_Tracker_Pattern0_table (Music_pattern_pointer is a pointer)
Music_beat_pointer_offset:_________________________________ $00 $01 $02 $03 $04 $05 $06 $07 $00 $01 $02 $03 $04 $05 $06 $07 $00 $01 $02 $03 $04 $05 $06 $07
runs from 0 o 7
Address in "Music_Tracker_beat0_instrument_notes_table"____ $00 $01 $02 $03 $04 $05 $06 $07 $08 $09 $0A $0B $0C $0D $0E $0F $10 $11 $12 $13 $14 $15 $16 $17
= Music_beat_pointer_offset + Music_beat_pointer_0
Note loaded from Music_Tracker_beat0_instrument_notes_table: #99 #99 #99 #99 #99 #99 #99 #99 #11 #11 #11 #11 #43 #43 #11 #11 #99 #99 #11 #11 #15 #15 #47 #47



As with the percussion instruments the use of the Music_Tracker_Pattern0_table allows you the save ROM space and coding time...

Now how the thing with the "notes" is working:
One Beat is divided in 8 timeslots. The values written in these timeslots show what a person playing the piano would be doing.
For Example:

Music_Tracker_beat0_instrument_notes_table: #99 .......... #99 .......... #11 .......... #11 .......... #15 ................... #15 .......... #47 ....................................... #47 ...
Piano player: ............................: Hands off The Keyboard ....... Press E2...... Hold E2 ...... Releae E2 and press B1, Hold B1 ...... Release B1 and press B1 immedialtely again, Hold B1 ...

So the "Piano player" follows Simple rules:
#99: Hands off the keyboard (Pause)
#0 to #31: Piano key to be played (AUDF value) if the value remains constant in the next time slot the key is hold down. If the value changes in the next time slot, the key is relesed and the next key is pressed again.
#32 to #63: If you want the piano player to lift the key, and then press the same key again, add or subtract 32 to the AUDF value thets tov notes of #32 to 63 can result (see the example).

The previous song: session 2_3.asm.txt

Lets look at the relevant code:
Lines 110 to 146
;Initial starting Point of the Song
MUSIC_SONG_START = #0
;Loop to Point of the Song after the end point is reached
MUSIC_SONG_LOOP_TO = #19
;End Point of the Song
MUSIC_SONG_END = #37
;Song Timer prescaler: 5 -> 90 BPM @NTSC (with Note Base: 1/
MUSIC_TIMER_PRESCALER = #5


;Stella Tracker Pattern 0: Notes for the Melodic Instrument
Music_Tracker_Pattern0_table
;Audio0: pointer to the Patterns (1 Pattern = 1 Beat)
; silence|<-- Sequence 1 without beat ---------> | | <-- Sequence 2 with beat ---------> |
; | <- Melody 1 -> | | <- Melody 2->| | <-Melody 1-> | | <- Melody 3->| | <- Melody 1 -> | | <- Melody 2->| | <-Melody 1-> | | <- Melody 3->|
; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 END
.byte #$00,#$08,#$10,#$08,#$10,#$08,#$10,#$18,#$20,#$18,#$20,#$08,#$10,#$08,#$10,#$28,#$30,#$28,#$30,#$08,#$10,#$08,#$10,#$08,#$10,#$18,#$20,#$18,#$20,#$08,#$10,#$08,#$10,#$28,#$30,#$28,#$30,#$00

Music_Tracker_beat0_instrument_notes_table
;Audio0: Frequency (0..31 & 32..63 = Notes, 99 = Pause)
;$00 - Silence
.byte #99,#99,#99,#99,#99,#99,#99,#99

;$08 - Melody 1
.byte #11,#11,#11,#11,#43,#43,#11,#11
;$10 - Melody 1
.byte #99,#99,#11,#11,#15,#15,#47,#47

;$18 - Melody 2
.byte #7 ,#7 ,#7 ,#7 ,#39,#39,#7 ,#7
;$20 - Melody 2
.byte #99,#99,#7 ,#7 ,#11,#11,#43,#43

;$28 - Melody 3
.byte #15,#15,#15,#15,#47,#47,#15,#15
;$30 - Melody 3
.byte #99,#99,#54,#54,#22,#22,#54,#54

The image shows how the code is created from the the ANVIL piano roll editor.
post-23660-126340425036_thumb.jpg Edited by Richi_S
Link to comment
Share on other sites

Session #4

 

In this session I'll show how to change the waveform of the melodic instrument.

 

The melodic instrument is working - like most synthesizers and the C64 SID chip - with an ADSR envelope system. It can also change the instruments frequency, generatig some sort of LFO effects.

http://en.wikipedia.org/wiki/ADSR_envelope

http://en.wikipedia.org/wiki/Low-frequency_oscillation

 

To some extend you can even modulate the waveform of the Volume/Frequency (Square, Sawtooth, ...)

 

 

So, how does the sound system utilize these effects....

 

 

The relevant code from session2_3.asm:

Lines 54 to 64:

MUSIC_INSTRUMENT0_AUDC = #6             ;Possible Instruments 4, 13,1,7,6, 15 with higher pitch
MUSIC_INSTRUMENT0_SUSTAIN_END = #9
MUSIC_INSTRUMENT0_SUSTAIN_START = #5
MUSIC_INSTRUMENT0_END = #20
Music_instrument_AUDF0_table
        ;      --- TV Frames ---->
        ;      |<-ATTACK & Decay-> |    |<-  SUSTAIN ->     |    |<- RELEASE ->                                |  END
        ;      0    1    2    3    4    5    6    7    8    9    10   11   12   13   14   15   16   17   18   19   20
       .byte  #0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0
Music_instrument_AUDV0_table
        .byte  #14 ,#14 ,#10 ,#8  ,#8  ,#8  ,#8  ,#8  ,#8  ,#8  ,#8  ,#7  ,#6  ,#5  ,#4  ,#3  ,#2  ,#2  ,#2  ,#1  ,#0

 

The theory goes line this:

The AUDC0, AUDF0 and AUFV0 registers are changed every TV frame. Every "note"a new frequency is loaded (session #3).

 

The AUDC0 register is fixed at MUSIC_INSTRUMENT0_AUDC, here it is #6.

 

The AUDV0 register is loaded with the current value from Music_instrument_AUDV0_table

The AUDF0 register ls loaded with the frequency to be played + the current value from Music_instrument_AUDV0_table

 

So Music_instrument_AUDV0_table defines the envelope (Volume, Range 0 to 15)

and Music_instrument_AUDF0_table defines the frequency shift (e.g. for LFOs, range -15 to +15, depending on the base frequency that shall be played).

 

The pointer to the two tables is increased every TV frame, thus new values are loaded every TV frame, so "waveforms" are generated.

The system has got four Phases:

1. Attack & Decay

2. Sustian

3. Release

4. End

 

Lets play it through:

1. When a new Key is hit (a new frequency value shall be played) The Pointer starts at #0 (Attack & Decay).

2. The pointer is increased, until it reaches MUSIC_INSTRUMENT0_SUSTAIN_END. when it does so, the next note the pointer starts back at MUSIC_INSTRUMENT0_SUSTAIN_START (Sustain phase).

3a. This infinite loop is left when the key is released (a pause note has to be played), then the pointer is adding up until it reaches MUSIC_INSTRUMENT0_END (Release pahse, the preqiously played frequency is kept) .

4. When the pointer has reached MUSIC_INSTRUMENT0_END the values stored in that loation are applied to the AUDx0 regsiters, until a new note is loaded (end, silence).

 

3b. If the Instrument is in the Sustian phase and another KEy (a note, that is not pause) has to be played, the Pointer starts back at #0 (back to Attack & Decay).

 

 

Now here comes an Example:

 

Lets say MUSIC_TIMER_PRESCALER = 5

And the notes to be played: #10 #15 #15 #15 #99 #99 #04

We are using the values for the waveform from the code above.

 

TV frame:__________ 00. 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34.

Note to be played:_ #10 #10 #10 #10 #10 #15 #15 #15 #15 #15 #15 #15 #15 #15 #15 #15 #15 #15 #15 #15 #99 #99 #99 #99 #99 #99 #99 #99 #99 #99 #04 #04 #04 #04 #04 ...

Pointer: __________ #00 #01 #02 #03 #04 #00 #01 #02 #03 #04 #05 #06 #07 #08 #09 #05 #06 #07 #08 #09 #10 #11 #12 #13 #14 #15 #16 #17 #18 #19 #00 #01 #02 #03 #04 ...

 

AUDV0: ____________ #14 #14 #10 #08 #08 #14 #14 #10 #08 #08 #08 #08 #08 #08 #08 #08 #08 #08 #08 #08 #08 #07 #06 #05 #04 #03 #02 #02 #02 #01 #14 #14 #10 #08 #08 ...

AUDF0:_____________ #10 #10 #10 #10 #10 #15 #15 #15 #15 #15 #15 #15 #15 #15 #15 #15 #15 #15 #15 #15 #15 #15 #15 #15 #15 #15 #15 #15 #15 #15 #04 #04 #04 #04 #04 ...

And This is how it looks like:

post-23660-126401932028_thumb.jpg

 

 

In the next Session I'm going to show some nice instruents that can be generated with his feature.

Edited by Richi_S
Link to comment
Share on other sites

This system really begs for a small composer programm, a feature to design the waveforms of the instruments,

plus some generic percussion- and melodic instruments.

 

It would be great for Visual bB.

I'm curious what batari himself thinks of this. I so wish for everything you stated up above to come true... :ponder:

Link to comment
Share on other sites

Session #5

You are free to design almost every Instrument you want to... This Session will give you a little guideline of what sounds good, and what doesn't.

 

You can use session2_3.asm and exchange Lines 54 to 64 with the instrument code shown here.

Every Instrument has got a Range, from which note to which note it sounds best.

 

This Instrument could represent a electonic guitar, (Range: Note 7 to 15):

MUSIC_INSTRUMENT0_AUDC = #7              ;Possible Instruments 4, 13,1,7,6, 15 with higher pitch
MUSIC_INSTRUMENT0_SUSTAIN_END = #9
MUSIC_INSTRUMENT0_SUSTAIN_START = #5
MUSIC_INSTRUMENT0_END = #20
Music_instrument_AUDF0_table
        ;      --- TV Frames ---->
        ;      |<-ATTACK & Decay-> |    |<-  SUSTAIN ->     |    |<- RELEASE ->                                |  END
        ;      0    1    2    3    4    5    6    7    8    9    10   11   12   13   14   15   16   17   18   19   20
       .byte  #0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0
Music_instrument_AUDV0_table
        .byte  #10 ,#10 ,#8  ,#6  ,#6  ,#6  ,#6  ,#6  ,#6  ,#6  ,#6  ,#5  ,#4  ,#4  ,#3  ,#3  ,#2  ,#2  ,#2  ,#1  ,#0

 

 

Thats the same Instrument with a little bit more distorsion, (Range: Note 7 to 15):

MUSIC_INSTRUMENT0_AUDC = #7              ;Possible Instruments 4, 13,1,7,6, 15 with higher pitch
MUSIC_INSTRUMENT0_SUSTAIN_END = #9
MUSIC_INSTRUMENT0_SUSTAIN_START = #5
MUSIC_INSTRUMENT0_END = #20
Music_instrument_AUDF0_table
        ;      --- TV Frames ---->
        ;      |<-ATTACK & Decay-> |    |<-  SUSTAIN ->     |    |<- RELEASE ->                                |  END
        ;      0    1    2    3    4    5    6    7    8    9    10   11   12   13   14   15   16   17   18   19   20
       .byte  #0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#1  ,#0  ,#1  ,#0  ,#0  ,#1  ,#0  ,#1  ,#0  ,#1  ,#0  ,#1  ,#0  ,#0  ,#0
Music_instrument_AUDV0_table
        .byte  #10 ,#10 ,#8  ,#6  ,#6  ,#6  ,#6  ,#6  ,#6  ,#6  ,#6  ,#5  ,#4  ,#4  ,#3  ,#3  ,#2  ,#2  ,#2  ,#1  ,#0

 

 

The Instrument from the current example:

MUSIC_INSTRUMENT0_AUDC = #6             ;Possible Instruments 4, 13,1,7,6, 15 with higher pitch
MUSIC_INSTRUMENT0_SUSTAIN_END = #9
MUSIC_INSTRUMENT0_SUSTAIN_START = #5
MUSIC_INSTRUMENT0_END = #20
Music_instrument_AUDF0_table
        ;      --- TV Frames ---->
        ;      |<-ATTACK & Decay-> |    |<-  SUSTAIN ->     |    |<- RELEASE ->                                |  END
        ;      0    1    2    3    4    5    6    7    8    9    10   11   12   13   14   15   16   17   18   19   20
       .byte  #0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0
Music_instrument_AUDV0_table
        .byte  #14 ,#14 ,#10 ,#8  ,#8  ,#8  ,#8  ,#8  ,#8  ,#8  ,#8  ,#7  ,#6  ,#5  ,#4  ,#3  ,#2  ,#2  ,#2  ,#1  ,#0

 

 

Another Instrument, one that uses "LFO"

MUSIC_INSTRUMENT0_AUDC = #13             ;Possible Instruments 4, 13,1,7,6, 15 with higher pitch
MUSIC_INSTRUMENT0_SUSTAIN_END = #9
MUSIC_INSTRUMENT0_SUSTAIN_START = #5
MUSIC_INSTRUMENT0_END = #20
Music_instrument_AUDF0_table
        ;      --- TV Frames ---->
        ;      |<-ATTACK & Decay-> |    |<-  SUSTAIN ->     |    |<- RELEASE ->                                |  END
        ;      0    1    2    3    4    5    6    7    8    9    10   11   12   13   14   15   16   17   18   19   20
       .byte  #0  ,#-1 ,#-2 ,#-2 ,#-1  ,#0  ,#-1 ,#-2 ,#-2 ,#-1 ,#0  ,#-1 ,#-2 ,#-2 ,#-1 ,#0  ,#0  ,#0  ,#0  ,#0  ,#0
Music_instrument_AUDV0_table
        .byte  #10 ,#10 ,#8  ,#6  ,#6  ,#6  ,#6  ,#6  ,#6  ,#6  ,#6  ,#5  ,#4  ,#4  ,#3  ,#3  ,#2  ,#2  ,#2  ,#1  ,#0

 

Some Siren like sound

MUSIC_INSTRUMENT0_AUDC = #13             ;Possible Instruments 4, 13,1,7,6, 15 with higher pitch
MUSIC_INSTRUMENT0_SUSTAIN_END = #9
MUSIC_INSTRUMENT0_SUSTAIN_START = #5
MUSIC_INSTRUMENT0_END = #20
Music_instrument_AUDF0_table
        ;      --- TV Frames ---->
        ;      |<-ATTACK & Decay-> |    |<-  SUSTAIN ->     |    |<- RELEASE ->                                |  END
        ;      0    1    2    3    4    5    6    7    8    9    10   11   12   13   14   15   16   17   18   19   20
       .byte  #5  ,#4  ,#3  ,#2  ,#1   ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0  ,#0
Music_instrument_AUDV0_table
        .byte  #10 ,#10 ,#8  ,#6  ,#6  ,#6  ,#6  ,#6  ,#6  ,#6  ,#6  ,#5  ,#4  ,#4  ,#3  ,#3  ,#2  ,#2  ,#2  ,#1  ,#0

If not designed propperly the Melodic instrument will sound anoying.

 

I suggest to consider following rules:

  • The length of ATTACK & Decay and Release should be multiples of MUSIC_TIMER_PRESCALER.
  • Simple ADSR Effects work best. Be carefull with "Modulized waveforms". You can't go wrong with Constant values in the Sustian phase.
  • Do not write a 0 in the first Item of Music_instrument_AUDV0_table. The instrument will sound like a beginner playing the piano.
  • Be carefull with Music_instrument_AUDF0_table. When overexceeding this tool the instrument will sound anoying. Epecially for instruments #6 and #7
  • A long Release Phase (>30 TV Frames & Enough pause notes) lead to an echo effect

Edited by Richi_S
Link to comment
Share on other sites

  • 3 weeks later...

Session #6

 

The Sound System allows you to design three different types of sequence

 

1. Loop One Song continiously.

MUSIC_SONG_START = #0
MUSIC_SONG_LOOP_TO = #0
MUSIC_SONG_END = #37

 

2. Start with an intro, then loop the main theme continious

MUSIC_SONG_START = #0
MUSIC_SONG_LOOP_TO = #20
MUSIC_SONG_END = #37

 

3. Play the Song once (then loop the last beat, which is silence)

MUSIC_SONG_START = #0
MUSIC_SONG_LOOP_TO = #36
MUSIC_SONG_END = #37

 

 

The Music speed

Following Table shows how the MUSIC_TIMER_PRESCALER is linked to the BPM.

Lets assume that 8 notes form one Beat.

post-23660-126573636435_thumb.jpg

Typically MUSIC_TIMER_PRESCALER is 4 to 7

Edited by Richi_S
Link to comment
Share on other sites

Session #7

When designing music with this sound system I formulated these "rules of thumb":

 

  • When making your songs, be aware of: The music will sound different from what you expect... It wil sound like Atari.
  • What sounds funky on General midi sounds crummy on the 2600.
  • The system is great as a beat box. You should start with a simple bassline.
  • Use simple tunes for the melodic instrument
  • Don't use too many differnt notes. 8 differnt notes per tune max.
  • You should not convert music that thas notes < 1/16
  • To keep your music from getting boring / anoying place some drum loops or simple music pauses. Keep the melody as "somthing special"
  • First use one of the generic instruments, design some beats, and then start to tune your instruents (specially the melodic instrument). When it sounds right you can go on finalizing the song.
  • Start with one silent beat, to make sure that the emulator / TV has set up.
     

Edited by Richi_S
Link to comment
Share on other sites

  • 2 weeks later...

Session #8

Muting the Stella Tracks.

If You want to play your own sound on one of the two tracks, you can mute the Stella Tracks of my sound system separately.

(In both examples you are able to mute the Tracks by pressing the Fire buttons).

When muted you regain full control over the Registers AUDV0, AUDF0, AUDC0,AUDV1, AUDF1, AUDC1

 

Therefore the Music_control_register is used

 

;Music_control_register

;Bit 7 -> Mute Track 0 - Melodic Instrument(0-> Mute 1 ->100% Volume)

;Bit 6

;Bit 5 -> Mute Track 1 - Percussion Instruments (0-> Mute 1 ->100% Volume)

;Bit 4

;Bit 3 -> Release Control Mode (Don't change on your own, 0 -> Instrument 0 is in ADS Mode, 1 -> Instrument 0 is in release Mode)

;Bit 2

;Bit 1

;Bit 0

 

Since Bit 3 is used to control the Release mode of the Melodic instrument, you need to mask the Mute Bits 7 and 5.

Also when chnging AUDC0 you need to restore it when unmuting the melodic instrument.

 

Muting the melodic instrument

        LDA  Music_control_register
        AND  #$7F
        STA  Music_control_register

        ;Needed If you want to just silence the track:
        LDA  #0
        STA  AUDV0

 

Unmuting the melodic instrument

        LDA  Music_control_register
        ORA  #$80
        STA  Music_control_register

        ;Needed if you've changed AUDC0; Restore AUDC0:
        LDA MUSIC_INSTRUMENT0_AUDC
        STA AUDC0

 

Muting the percussion track

        LDA  Music_control_register
        AND  #$DF
        STA  Music_control_register

        ;Needed If you want to just silence the track:
        LDA  #0
        STA  AUDV1

 

Unmuting the percussion track

        LDA  Music_control_register
        ORA  #$20
        STA  Music_control_register

Link to comment
Share on other sites

Session #9

Adding variable Music speed

 

Variable music speed will give the game more appeal. Like speed up the music when the timer is almost up.

By adding one byte of RAM to the sound system (now it is 10 bytes) you can control the music speed.

 

The programm attached lets you slow down / speed up the music by pressing the left / right button of Joystick 0.

Session #6 shows reasonable values for Music_timer_prescaler.

 

Which parts of the code hve been changed...

 

Line 41..42 and 118..121

Previously MUSIC_TIMER_PRESCALER was a simple constant, now it is a variable. Plus there are three constants to fill Music_timer_prescaler

;Music Speed
Music_timer_prescaler       ds 1
;Song Timer prescaler: 5 -> 90 BPM @NTSC (with Note Base: 1/8)
MUSIC_TIMER_PRESCALER_1  = #6
MUSIC_TIMER_PRESCALER_2  = #5
MUSIC_TIMER_PRESCALER_3  = #4

 

Line 201..203

Initialize music speed

         
        ;Initialize music speed
        LDA MUSIC_TIMER_PRESCALER_2
        STA Music_timer_prescaler

 

Line 300

         
         CMP Music_timer_prescaler 

Changing the Music Speed: Line 503..529

It is save to change the music speed (Music_timer_prescaler) when Music_timer == #0, so you have to check if it is #0 before changing Music_timer_prescaler

(just setting is to 0 won't help). If not done so the sound system will scramble up the music.

Joystick0_check_Dpad
        ;Check Joystick Left pressed
        LDA SWCHA
        AND #$40
        BNE Joystick0_Not_Left
        ;-- Joy 0 Left is pressed
        ;Check if the timer is Up (its safe to change the speed)
        LDA Music_timer
        CMP #0
        BNE Joystick0_Not_Left
        ;-- Joy 0 Left is pressed and the Music_timer is up
        LDA MUSIC_TIMER_PRESCALER_1
        STA Music_timer_prescaler
Joystick0_Not_Left
        ;Check Joystick right pressed
        LDA SWCHA
        AND #$80
        BNE Joystick0_Not_right
        ;-- Joy 0 Right is pressed
        ;Check if the timer is Up (its safe to change the speed)
        LDA Music_timer
        CMP #0
        BNE Joystick0_Not_right
        ;-- Joy 0 Right is pressed and Music_timer is up
        LDA MUSIC_TIMER_PRESCALER_3
        STA Music_timer_prescaler
Joystick0_Not_right

variable_BPM.bin

variable_BPM.asm.txt

Edited by Richi_S
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...