Devin #1 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 Share this post Link to post Share on other sites
supercat #2 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 Share this post Link to post Share on other sites
Devin #3 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 Share this post Link to post Share on other sites
+batari #4 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 Share this post Link to post Share on other sites
Devin #5 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 Share this post Link to post Share on other sites
vdub_bobby #6 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 Share this post Link to post Share on other sites
Devin #7 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 Share this post Link to post Share on other sites
Devin #8 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 Share this post Link to post Share on other sites
vdub_bobby #9 Posted April 3, 2008 Just a quick DASM note: you don't need the constant-signifying '#' in data statements. Quote Share this post Link to post Share on other sites
Zach #10 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 Share this post Link to post Share on other sites