music_file_format
This is an old revision of the document!
Table of Contents
Music File Format
How to do it?
Proposal 1: Text file
- on a row: CWND CWND CWND CWND
- “Channel, Waveform, Note, Duration” ex 12G4Q is channel 1, waveform 2, note G4, quarter note
- Can have commands like TEMPO = 90 and ROW=HalfNote (meaning 180 rows/minute for Tempo=90)
- This would require auto-shutoff of notes/a polling player (could be done using Int 11h music timers)
Proposal 2 (Data-File)
MUSIC FILE FORMAT v1.0
- Header (16 bytes):
- +0: [2] Magic: “SD” ($53 $44)
- +2: [1] Version (1)
- +3: [1] Flags
- +4: [2] Tempo (ms per row)
- +6: [1] Number of instruments
- +7: [1] Number of patterns
- +8: [1] Song length (orders)
- +9: [7] Reserved
- Instrument Table (10 bytes each):
- +0: [1] Instrument ID
- +1: [1] Instrument Type
- Waveforms:
- +2: [1] Waveform (WAVE_xx constant)
- +3: [1] Pulse width / duty cycle
- +4: [1] Attack
- +5: [1] Decay
- +6: [1] Sustain
- +7: [1] Release
- +8: [1] Default volume
- +9: [1] Reserved
- Samples:
- +2: [1] address (bank)
- +3: [1] address (low byte)
- +4: [1] address (high byte)
- +5: [1] Volume
- +6: [1] Playback speed
- +7: [1] reserved
- +8: [1] reserved
- +9: [1] reserved
NOTE: need to do more research on what data we should include with samples. How does SNES/etc. do it?
- Order List (1 byte each):
- Pattern numbers in playback order
- Terminated by $FF ($FFFF or $0000?)
- Patterns:
- Each pattern is a sequence of rows
- Each row is a sequence of channel commands
- Row terminated by $00
- Pattern terminated by $FF (see above)
Row Command Format
Command Byte:
- Bits 7-6: Channel (0-3)
- Bits 5-4: Command type
- Bits 3-0: Depends on command type
OR
- Command Byte
- Channel Byte
- Data Word + Data Word + Data Word (Reserved)
Command Types:
- 00 = Note On (3 bytes total)
- [Cmd] [Note] [Instrument]
- 01 = Note Off (1 byte)
- [Cmd]
- 10 = Set Volume (2 bytes)
- [Cmd] [Volume]
- 11 = Effect (3 bytes)
- [Cmd] [Effect Type] [Effect Param]
Note data
- $00 = Rest (no change)
- $01-$60 = Notes (C0 to B7)
- $61 = Note off
- $FF = End of pattern
- Note calculation:
- Note = (Octave * 12) + Semitone + 1
- C4 = (4 * 12) + 0 + 1 = 49 = $31
- A4 = (4 * 12) + 9 + 1 = 58 = $3A
Example Data File
; ============================================================================
; Simple test song: C-E-G-C chord progression
; ============================================================================
music_test_song:
; Header (16 bytes)
music_header:
.bytes "SD" ; Magic
.byte 1 ; Version
.byte 0 ; Flags
.word 250 ; Tempo: 250ms per row (240 BPM)
.byte 2 ; 2 instruments
.byte 2 ; 2 patterns
.byte 4 ; 4 orders (play pattern 0, 1, 0, 1)
.fill 7, 0 ; Reserved
; Instruments (8 bytes each)
music_instruments:
; Instrument 0: Lead (pulse wave)
.byte WAVE_PULSE ; Waveform
.byte $40 ; 50% duty
.byte $10 ; Attack
.byte $20 ; Decay
.byte $80 ; Sustain
.byte $40 ; Release
.byte $C0 ; Volume
.byte 0 ; Reserved
; Instrument 1: Bass (triangle)
.byte WAVE_TRIANGLE ; Waveform
.byte 0 ; Duty (ignored for triangle)
.byte $08 ; Attack
.byte $10 ; Decay
.byte $A0 ; Sustain
.byte $30 ; Release
.byte $FF ; Volume
.byte 0 ; Reserved
; Order list
music_orders:
.byte 0 ; Play pattern 0
.byte 1 ; Play pattern 1
.byte 0 ; Play pattern 0 again
.byte 1 ; Play pattern 1 again
.byte $FF ; End of song
; Patterns
music_patterns:
; Pattern 0 offset (for seeking)
music_pattern_0:
; Row 0: Channel 0 plays C4 with instrument 0
.byte $00, $31, $00 ; Ch0, Note On, C4, Inst 0
.byte $40, $19, $01 ; Ch1, Note On, C3, Inst 1 (bass)
.byte $00 ; End of row
; Row 1: Channel 0 plays E4
.byte $00, $35, $00 ; Ch0, Note On, E4, Inst 0
.byte $00 ; End of row
; Row 2: Channel 0 plays G4
.byte $00, $38, $00 ; Ch0, Note On, G4, Inst 0
.byte $00 ; End of row
; Row 3: Channel 0 plays C5
.byte $00, $3D, $00 ; Ch0, Note On, C5, Inst 0
.byte $00 ; End of row
.byte $FF ; End of pattern
music_pattern_1:
; Row 0: Note off on channel 0, bass plays G2
.byte $10 ; Ch0, Note Off
.byte $40, $14, $01 ; Ch1, Note On, G2, Inst 1
.byte $00 ; End of row
; Row 1: Channel 0 plays G4
.byte $00, $38, $00 ; Ch0, Note On, G4, Inst 0
.byte $00 ; End of row
; Row 2: Channel 0 plays B4
.byte $00, $3C, $00 ; Ch0, Note On, B4, Inst 0
.byte $00 ; End of row
; Row 3: Channel 0 plays D5
.byte $00, $3F, $00 ; Ch0, Note On, D5, Inst 0
.byte $00 ; End of row
.byte $FF ; End of pattern
music_end:
music_file_format.1770039234.txt.gz · Last modified: by appledog
