News:

Don't forget to visit the main site! There's lots of helpful docs, patches, and more!

Main Menu

Metroid Tuner

Started by snarfblam, January 29, 2012, 08:21:38 PM

Previous topic - Next topic

snarfblam

So here's this thing I've been working on for a while: Metroid Tuner (alpha)

It's a song dumper/inserter for Metroid. Nothing too pretty. The format you have to work with looks like this:


<Track>
[Song:    A]
[Track:   Square1]
[Address: B000]
[MaxSize: 57]
// Remove or update MaxSize tag to embiggen data (be ever so careful).

// Track length: ~ 45 seconds
// Track size: 87 ($57) bytes

2 { // --------------
    :60
        B3 C4
} //   --------------
3 { // --------------
    :30
        B3 D4 C4 F4
} //   --------------
    :60
        B3
    :30
        C4 D4
3 { // --------------
    :48
        E4
    :08


Now I just need Grime to whip up some tunes for me to use in my hack. :colonrightv:

Here is a hack made to demonstrate the tool:
Metroid Music Editing

begrimed

I could take a crack at it sometime. What kind of limitations should I be keeping in mind?

snarfblam

That would be pretty sweet.

There are three channels. The two square-wave channels can have a relatively simple "instrument". You can't set the volume for individual notes, or use more than one instrument on a channel. Then there's the triangle-wave channel, which is a flat tone at a fixed volume, that most games use for bass. There's also a single percussion sound that's used in the Brinstar music (there are a couple other percussion sounds that aren't used, but they seem mostly useless).

My second attempt. I think this one came out better.
Metroid Music Editing II

begrimed

And I take it the songs should be no longer than 1 or maybe 2 minutes. Looping the beginning and end goes without saying.

snarfblam

Sounds about right. Of course that depends on the tempo and how much you utilize looping (no nested loops).

Grimlock

This looks really cool.  Would it work with an expanded rom or would you have to edit the music first?  I'd definitely be up to using a tool like this, do you think you would be able to create something complete with this tool as is or would you have to do some more work on it before you can get real productivity out of it?

snarfblam

As long as you're okay with dealing with a text based format, the tool is fully functional and should work fine with an expanded ROM. (In other words, it can't insert MIDIs or NSFs or do anything like that.)

Example:

<Context>
[Bank:            1]
[SongTable:       BD31]
[VolumeTable:     BCB0]
[NoteTable:       BE77]
[NoteLengthTable: BEF7]


<Song>
[Song:            A]
[NoteLengthTable: 0B]
[TriangleLength:  00]
[Sq1VolumeTable:  2]
[Sq2VolumeTable:  3]
[Repeat:          True]


<Track>
[Song:    A]
[Track:   Square1]
[Address: B000]
[MaxSize: 57]
// Delete MaxSize tag to allow insertion of larger track data (be careful of overwriting/overlapping data)

// Track length: ~ 45 seconds
// Track size: 87 ($57) bytes

2 { // --------------
    :60
        B3 C4
} //   --------------
3 { // --------------
    :30
        B3 D4 C4 F4
} //   --------------
    :60
        B3
    :30
        C4 D4
3 { // --------------
    :48
        E4
    :08
        C4 G3 C4
    :30
        F4 D4
} //   --------------
    :60
        E4 E4
    :18
        F4 C4 A3
    :08
        C4 A#3 C4
    :18
        D4 F4
    :30
        C4
    :18
        D#4 A3 F3
    :08
        C3 A#3 C3
    :18
        D3 F3 A#3
    :08
        C3 F3 A3
    :30
        B3 A3 G3 D4
    :18
        D#4 F4 Ab3
    :08
        G3 F3 D#3
    :18
        F3 A#3 G3
    :08
        F3 A#4 D4
    :60
        D4
    :30
        B3 G3
00 // Song terminator


<Track>
[Song:    A]
[Track:   Square2]
[Address: B057]
[MaxSize: 6A]
// Delete MaxSize tag to allow insertion of larger track data (be careful of overwriting/overlapping data)

// Track length: ~ 45 seconds
// Track size: 106 ($6A) bytes

2 { // --------------
    :18
        G2
    :08
        G2 D2 G2
    :18
        G2
    :08
        G2 D2 G2
    :18
        A#2
    :08
        A#2 F2 A#2
    :18
        A#2
    :08
        A#2 F2 A#2
} //   --------------
3 { // --------------
    :60
        G4
    :48
        A#4
    :06
        A4 A#4 A4 F4
} //   --------------
    :60
        G4 G4
3 { // --------------
    :48
        C5
    :18
        G4
    :48
        A#4
    :06
        A4 A#4 A4 F4
} //   --------------
    :60
        G4 G3
    :48
        A4
    :08
        A4 G4 A4
    :30
        A#4
    :18
        F4
    :08
        C4 F4 G4
    :48
        A4
    :08
        A4 G4 A4
    :30
        A#4
    :18
        F4
    :08
        F4 A#4 C5
    :60
        D5
    :30
        C5 B4
    :48
        C5
    :08
        D#5 D5 C5
    :30
        D5
    :18
        A#4
    :08
        A#4 D5 F5
    :60
        F#5 F#5


<Track>
[Song:    A]
[Track:   Triangle]
[Address: B0C1]
[MaxSize: 69]
// Delete MaxSize tag to allow insertion of larger track data (be careful of overwriting/overlapping data)

// Track length: ~ 45 seconds
// Track size: 105 ($69) bytes

4 { // --------------
    :60
        -
} //   --------------
3 { // --------------
    :18
        G3
    :08
        G3 G4 D4
    :18
        G3
    :08
        G3 D4 G3
    :18
        A#3
    :08
        A#3 F4 A#3
    :18
        A#3
    :08
        A#3 F4 A#3
} //   --------------
4 { // --------------
    :18
        G3
    :08
        D4 G3 G3
} //   --------------
16 { // --------------
    :08
        C3 G3 C3
    :18
        C3
} //   --------------
2 { // --------------
    :18
        D#3
    :08
        D#3 C3 D#3
    :18
        D#3
    :08
        D#3 C3 D#3
    :18
        D3
    :08
        D3 A#2 D3
    :18
        D3
    :08
        D3 A#2 D3
} //   --------------
    :18
        G3 A2 B2 C3 D3 E3 F#3 G3 Ab3
    :08
        Ab3 D#3 C3
    :18
        Ab2
    :08
        C4 A#3 Ab3
    :18
        D#3 D3 C3 A#2 A3 A3 A3 A3
12 { // --------------
    :08
        A3
} //   --------------



<Track>
[Song:    A]
[Track:   Noise]
[Address: B12B]
[MaxSize: A]
// Delete MaxSize tag to allow insertion of larger track data (be careful of overwriting/overlapping data)

// Track length: ~ 60 seconds
// Track size: 10 ($A) bytes

40 { // --------------
    :18
        $04 $04 $04
    :08
        $04 $04 $04
} //   --------------

Grimlock

I saw the  youtube video on your other audio editing app just now (dumper/inserter).  Is that something you have released, or are you still working on it?  That's pretty cool that you where able to take audio from a super nintendo game (Super Metroid) and insert it into Metroid.  Can you source any super nintendo game or was it converted from a midi file (would be great because the potential would be limitless.)

snarfblam

Metroid Tuner is the dumper/inserter. As far as inserting the SM music into Metroid, I did that by listening to the music and writing the notes down in the format I posted above. Metroid Tuner is a very basic program. All it does is convert Metroid's raw music data to/from a human readable format. If you want to hack the music, it's still a lot of work.

Grimlock

How much time did you have to put into that audio edit to get it where it was in your video?

snarfblam

Probably an hour or two.

Grimlock

That sounds do able.  I'm going to mess around with it and see if I can make the text input work for me.  I have some musical background (guitar and bass) so maybe that'll help.

DemickXII

This reminds me of MML-MCK format just a bit, but more simplified and more restrictive (probably to save space). Glad I have FamiTracker to help me hear what I am going to put down before I make garbage my first time round.

By the way, FamiTracker is a must have for those who even remotely dabble into the 2a03/07 sound/music editing. This will give you insight into exactly what is going on inside the chip. It also has added tracker-specific features as well, but for Metroid editing, all one needs is to learn what the chip can do first. You will find that the volume envelopes in FamiTracker are identical to how MML-MCK and Metroid does volume envelopes.

Famitracker has its own .com, so it should be very easy to find on Google (or whatever search engine you use). Unfortunately, it doesn't do what the Metroid sound editor can do and is there for tracking purposes. However it DOES have .NSF and .NES exporting, the latter which may pique some interest here.

snarfblam

Also worth mentioning, there is a general purpose NES sound engine written by Shiru called FamiTone, along with a handy tool to convert a FamiTracker song into the FamiTone format. While it's very handy for homebrewing, since sound engines tend to be very self-contained it's also possible to replace a game's sound engine with FamiTone. I know someone was talking about doing this with Metroid a while back, but I don't know if he ever took a crack at it.

Yuki

So, if I'm understanding this right, if the sound engine of Metroid is replaced by Famitone, we could just write Famitracker songs and put them in game? That would be badass

passarbye

Quote from: Drevan Zero on December 10, 2012, 08:10:27 AM
we could just write Famitracker songs and put them in game? That would be badass
fucking this
i've been playing with famitracker lately anyway, would be great to see some good use of it!  :bounce:

Entroper

Can someone explain how this works in a bit more detail? As a veteran recording musician, I have already written some candidate tunes for my Metroid hack and would like to try them out, but I don't understand this format yet. What are the numbers before the open brackets { ?  Clearly the letters are notes, but what about the number that accompanies them (B3 C4 etc.)? Are these chords, or choosing which octave to play the note, or...?  Presumably the :30, :60 etc. numbers indicate time in seconds, but how is it structured?  I'm also wondering why you can set note length for both <Context> and <Song>; what happens when they don't match?  Do all the notes on the square wave channels have to be the same length (e.g. quarter notes)?

On the plus side, if I ever figure this out, I may well have extra tunes that can be used in other hacks...

Grimlock

Snarfblam can probably assist you.  In the end you may have to just do some experimentation.  If you have an opportunity to write up a short tutorial (once you figure out how to use the app) I know there are many, including myself, who would greatly appreciate it.

snarfblam

#18
Quote from: Entroper on June 18, 2014, 07:51:58 PM
What are the numbers before the open brackets { ?

The brackets indicate looping. The number before the brackets specifies how many times to loop. Example: 2 { A4 B4 C4 } plays exactly the same tune as A4 B4 C4 A4 B4 C4, but takes up less space in the ROM. Loops can not be nested.

Quote from: Entroper on June 18, 2014, 07:51:58 PM
Clearly the letters are notes, but what about the number that accompanies them (B3 C4 etc.)?

The number specifies the octave.

Quote from: Entroper on June 18, 2014, 07:51:58 PM
Presumably the :30, :60 etc. numbers indicate time in seconds, but how is it structured?
These actually specify note length, in frames (in hex!). The game runs at 60 FPS, so :3C (decimal 60) specifies one-second notes, :1E (decimal 30) specifies 1/2 second-notes, etc. The songs in the game tend to use more hex-friendly note durations (:08, :10, :18, etc.). When you specify a note length, all subsequent notes will play for that duration.

One gotcha is that for some absurd reason the sound engine uses a list of predefined note lengths, so you need to make sure all note lengths used in a song are listed in the note length table.

Quote from: Entroper on June 18, 2014, 07:51:58 PM
I'm also wondering why you can set note length for both <Context> and <Song>; what happens when they don't match?
The [NoteLengthTable] attribute has a different meaning for a <Context> section than for a <Song> section. For <Context>, it is a pointer to the beginning of the note length data. For <Song>, it is the index of the first byte in the note length table that the song uses. If you dump the note length table, you'll see something like this:

<NoteLengthTable>
// Note durations are specified in number of frames. 60 = 1 second.

// Table 1, used by these songs: 3 9
04 08 10 20 40 18 30 0C 0B 05 02

// Table 2, used by these songs: 0 1 2 4 5 8 A B
06 0C 18 30 60 24 48 12 10 08 03 10

// Table 3, used by these songs: 6 7
07 0E 1C 38 70


So, for example, songs 0, 1, 2, 4, 5, 8, A, and B would specify [NoteLengthTable: 0B] to indicate that they use the table that appears eleven bytes into the note length data ($0B = 11).


This page right here might also help clear things up a bit, and the disassembly is handy for finding free space if you need it. Most if not all banks contain at least one song that is not used. For example, the Brinstar bank contains a copy of the Tourian music, but you are free to overwrite it because, naturally, the Tourian music never plays in Brinstar.

Kitsune_Phoenix

#19
*a retarded person talking about retarded concepts: disregard this post*

Vismund Cygnus

Quote from: Kitsune_Phoenix on June 20, 2014, 04:44:06 PM
I know that this is off-topic, but I saw a few posts above about the concept of replacing Metroid's sound engine. In theory, would it be possible to do the same thing for Super Metroid so that it could play 8-channel Tracker music?
Quote from: Kitsune_Phoenix on June 20, 2014, 04:44:06 PM
8-channel Tracker music?


Quote from: Quietus on June 09, 2014, 05:39:34 PM
* Kitsune_Phoenix mentions 'tracker' in a reply.
* Quietus quietly leaves.
You sure do love them trackers.  :heheh:

Entroper

Thanks snarfblam. I'll put some time and energy into it tomorrow and see if I can muddle through.

Crashtour99

The tricky part of replacing a games audio engine isn't the music, it's the sound fx.  Making sure that the new engine interacts properly with a vanilla ROM to produce things like shot sounds, enemy deaths, etc. is the challenge.  The music itself is easy.  Hell, I could take the audio engine from Chrono Trigger right now and put it in SM, but that doesn't mean that everything is going to work the same.  In all probability it'll most likely corrupt ARAM and crash the audio.

FamiTone is handy for homebrew because you're building the games sounds around an already existing audio engine.  To add a different engine to an already existing game you'll have to edit it to match that game, which is why it hasn't been done yet.

Kitsune_Phoenix

Quote from: Vismund Cygnus on June 21, 2014, 08:51:39 AM
You sure do love them trackers.  :heheh:

My post was directly above yours, and you decided to quote the whole thing?

Hawntah

Quote from: Kitsune_Phoenix on June 23, 2014, 02:47:10 AM
My post was directly above yours, and you decided to quote the whole thing?
Is this the first time you have seen someone quote a passage of text multiple times for emphasis while progressively shortening the quoted phrase each time by omitting irrelevant words, possibly adding capitalisation along the way, until all that remains is a succinct summary of the original quote which serves as the base for the witty remark that inevitably follows immediately afterwards?