Devin Posted April 2, 2008 Share Posted April 2, 2008 Hello all, I've been working on a MIDI to Atari 2600 routine. Most of the work I created previously with an MIDI to QBasic converter. The main work is done by a VB program that reads a MIDI file, filters the channels and then is able to determine style (staccato, legato, etc..) and merge notes. Anyway, I've attached a few of a simple MIDI files I imported. I still have a a lot of work to do to make it match missing musical notes (mostly sharps). I plan to eventually to be able to also import and convert the beat track - drums, snares, etc... Each audible note takes one byte - so a long song will not take a ton of storage. Note use a timing table and a second table that is used to look up the AUDCn and AUDFn codes. The idea is that a PAL version should be able to sound identical. A few of the notes are a tad fast - I haven't written the code for dotted notes yet. I've attached very simple programs that play Angry Video Game Nerd theme Take Me Out to the Ballgame (baseball) Ghostbusters Jingle Bells Family Guy Here Comes Santa Clause AVGN.bin Baseball.bin Family_Guy.bin Ghostbusters.bin Here_Comes_Santa_Clause.bin Jingle_Bells.bin Quote Link to comment Share on other sites More sharing options...
supercat Posted April 2, 2008 Share Posted April 2, 2008 I've been thinking a MIDI to BTP2 music converter might be nice, though I'd have to settle on what format I'd want to store the actual music in. BTP2 has a five-octave chromatic range with four voices, so it should be possible to make things sound pretty good. Quote Link to comment Share on other sites More sharing options...
Devin Posted April 2, 2008 Author Share Posted April 2, 2008 (edited) I've been thinking a MIDI to BTP2 music converter might be nice, though I'd have to settle on what format I'd want to store the actual music in. BTP2 has a five-octave chromatic range with four voices, so it should be possible to make things sound pretty good. I'm trying to make the file format incredibly compact. Each melody contains a series of bytes where the first 4 bits contain the note/command (octave up, down up, tempo up, tempo down, change style,...) and the lower four bits contain length/data. For notes it has the following format: NNNNDLLL NNNN is the note from 0-11, 12 is a rest, D is a dotted note (1.5 times length), and LLL is the length of the note. The melodies have the following format: TableSong .byte #STYLE_NORMAL .byte #NOTE_G | LENGTH_2 .byte #NOTE_G | LENGTH_4 | DOTTED .byte #NOTE_E | LENGTH_8 .byte #NOTE_E | LENGTH_2 .byte #NOTE_G | LENGTH_2 .byte #NOTE_G | LENGTH_4 | DOTTED .byte #NOTE_D | LENGTH_8 .byte #NOTE_D | LENGTH_2 .byte #NOTE_E | LENGTH_2 .byte #NOTE_F | LENGTH_2 .... Each note is looked up in another table that contains the AUDCn and AUDFn codes. I compact it further by storing each of these using one byte with a second table containing the AUDCn values. VOICE_1 = #%00000000 ;0 Buzzy tones (AUDCn = 1) VOICE_4 = #%00100000 ;1 Pure tones (AUDCn = 4) VOICE_6 = #%01000000 ;2 Semi-buzzy (AUDCn = 6) VOICE_7 = #%01100000 ;3 Reedy tones (AUDCn = 7) VOICE_8 = #%10000000 ;4 White noise (AUDCn = 8) VOICE_12 = #%10100000 ;5 Pure tones (AUDCn = 12) VOICE_14 = #%11000000 ;6 Electronic tones 1 (AUDCn = 14) TableNotes ... ;=========== Octave 3 .byte VOICE_12 | 19;C .byte VOICE_12 | 18;C# .byte VOICE_12 | 17;D .byte VOICE_12 | 16;D# .byte VOICE_12 | 15;E .byte VOICE_12 | 14;F .byte VOICE_12 | 13;F# .byte VOICE_12 | 12;G .byte VOICE_1 | 4 ;G# .byte VOICE_12 | 11;A .byte VOICE_12 | 10;A# .byte VOICE_4 | 31;B ... TableVoiceControl .byte 1 ;0 Buzzy tones .byte 4 ;1 Pure tones .byte 6 ;2 Semi-buzzy .byte 7 ;3 Reedy tones .byte 8 ;4 White noise .byte 12 ;5 Pure tones .byte 14 ;6 Electronic tones 1 .byte 15 ;7 Electronic tones 2 Edited April 2, 2008 by Devin Quote Link to comment Share on other sites More sharing options...
+batari Posted April 2, 2008 Share Posted April 2, 2008 Have you seen music.h? Not saying your ideas aren't valid, just that much of the same work has already been done. Quote Link to comment Share on other sites More sharing options...
Devin Posted April 2, 2008 Author Share Posted April 2, 2008 Have you seen music.h? Not saying your ideas aren't valid, just that much of the same work has already been done. Ironically, that's also what I named my library! This is probably a duplicate project - but it is a good way for myself to master Atari 2600 music. Well, "master", might be too strong a word. The whole idea was to store a simple sheet-music byte-code and use it to create sound. When complete, I can use all the old QBasic Play strings. I doubt I can even come close to tapping the full sound qualities of the Atari. Quote Link to comment Share on other sites More sharing options...
vdub_bobby Posted April 2, 2008 Share Posted April 2, 2008 Am I reading this correctly: your music data supports 12 notes per song? If so, that really isn't enough, I'd say... Quote Link to comment Share on other sites More sharing options...
Devin Posted April 3, 2008 Author Share Posted April 3, 2008 Am I reading this correctly: your music data supports 12 notes per song? If so, that really isn't enough, I'd say... Sorry about that. The library currently supports 6 octaves (with varying support). With each octave, you can specify the 12 different notes. In the array, you can move up and down octaves. The idea is that a song can be started in a different octave (and tempo) based on gameplay. Quote Link to comment Share on other sites More sharing options...
Devin Posted April 3, 2008 Author Share Posted April 3, 2008 Here's the song for the Family Guy using the format. It spans several octaves. .byte #STYLE_NORMAL .byte #TEMPO_150 .byte #OCTAVE_UP .byte #NOTE_C | LENGTH_4 .byte #OCTAVE_DOWN .byte #NOTE_B | LENGTH_8 .byte #OCTAVE_UP .byte #NOTE_C | LENGTH_2 .byte #OCTAVE_DOWN .byte #NOTE_F | LENGTH_8 .byte #NOTE_B | LENGTH_4 .byte #NOTE_AS | LENGTH_8 .byte #NOTE_B | LENGTH_2 .byte #NOTE_F | LENGTH_8 .byte #NOTE_AS | LENGTH_8 .byte #NOTE_A | LENGTH_8 .byte #NOTE_AS | LENGTH_8 .byte #NOTE_A | LENGTH_8 .byte #NOTE_AS | LENGTH_8 .byte #OCTAVE_UP .byte #NOTE_C | LENGTH_4 .byte #OCTAVE_DOWN .byte #NOTE_G | LENGTH_8 .byte #NOTE_A | LENGTH_8 .byte #REST | LENGTH_32 .byte #NOTE_A | LENGTH_8 .byte #REST | LENGTH_32 .byte #NOTE_A | LENGTH_8 .byte #NOTE_A | LENGTH_4 .byte #REST | LENGTH_8 .byte #NOTE_F | LENGTH_8 .byte #NOTE_G | LENGTH_8 .byte #NOTE_G | LENGTH_8 .byte #NOTE_F | LENGTH_4 .byte #NOTE_GS | LENGTH_4 .byte #NOTE_F | LENGTH_4 .byte #NOTE_A | LENGTH_8 .byte #REST | LENGTH_32 .byte #NOTE_A | LENGTH_8 .byte #REST | LENGTH_32 .byte #NOTE_AS | LENGTH_4 .byte #NOTE_A | LENGTH_2 .byte #STYLE_NORMAL .byte #NOTE_G | LENGTH_8 .byte #NOTE_A | LENGTH_8 .byte #OCTAVE_UP .byte #NOTE_D | LENGTH_8 .byte #OCTAVE_DOWN .byte #NOTE_A | LENGTH_8 .byte #NOTE_F | LENGTH_8 .byte #NOTE_D | LENGTH_8 .byte #OCTAVE_UP .byte #NOTE_C | LENGTH_1 .byte #REST | LENGTH_8 .byte #NOTE_D | LENGTH_8 .byte #NOTE_CS | LENGTH_8 .byte #NOTE_D | LENGTH_8 .byte #NOTE_E | LENGTH_8 .byte #NOTE_F | LENGTH_8 .byte #NOTE_E | LENGTH_8 .byte #NOTE_D | LENGTH_8 .byte #NOTE_C | LENGTH_1 .byte #REST | LENGTH_2 .byte #OCTAVE_DOWN .byte #NOTE_AS | LENGTH_8 .byte #NOTE_A | LENGTH_8 .byte #NOTE_AS | LENGTH_8 .byte #NOTE_A | LENGTH_8 .byte #NOTE_AS | LENGTH_8 .byte #OCTAVE_UP .byte #NOTE_C | LENGTH_4 .byte #REST | LENGTH_16 .byte #OCTAVE_DOWN .byte #NOTE_A | LENGTH_8 .byte #NOTE_GS | LENGTH_8 .byte #NOTE_A | LENGTH_8 .byte #NOTE_GS | LENGTH_8 .byte #NOTE_A | LENGTH_8 .byte #NOTE_AS | LENGTH_4 .byte #REST | LENGTH_16 .byte #NOTE_G | LENGTH_8 .byte #NOTE_FS | LENGTH_8 .byte #NOTE_G | LENGTH_8 .byte #NOTE_FS | LENGTH_8 .byte #NOTE_G | LENGTH_8 .byte #NOTE_A | LENGTH_4 .byte #REST | LENGTH_16 .byte #NOTE_F | LENGTH_8 .byte #NOTE_A | LENGTH_4 .byte #OCTAVE_UP .byte #NOTE_D | LENGTH_4 .byte #REST | LENGTH_4 .byte #NOTE_C | LENGTH_2 .byte #NOTE_CS | LENGTH_2 .byte #NOTE_D | LENGTH_2 .byte #NOTE_E | LENGTH_2 .byte #NOTE_F | LENGTH_2 | DOTTED .byte #SONG_END This is basically the quick-n-dirty MIDI import. Quote Link to comment Share on other sites More sharing options...
vdub_bobby Posted April 3, 2008 Share Posted April 3, 2008 Just a quick DASM note: you don't need the constant-signifying '#' in data statements. Quote Link to comment Share on other sites More sharing options...
Zach Posted April 6, 2008 Share Posted April 6, 2008 Hi Devin, That's great that your sample songs came originally from MIDI files. Nice job on the conversion. I think we are all a little spoiled around here having heard some great Atari 2600 music by talented programmers. By comparison, your demos are, shall we say, primitive. The notes need more variation with the volume to show more flavor. However as I understand it, your tool just extracts notes from the MIDI file and converts it to ASM data. It's still up to the programmer to write a music driver to play the notes, right? Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.