M64 Documentation
Users browsing this thread: 1 Guest(s)

12: Question 
M64 Features, M64 Parser.




In M64, we have the header, the track and music event table, the header is the beginning of the M64, what all M64s must have, it contains necessary information about the M64, like the NLST, amount of channels, tempo and master volume.

HEADER FORMAT AND COMMAND TABLE
 Status Byte
 Parameters Description                    
0x90 - 0x9F
Offset (2 bytes)
Points to track data for a specific channel, indicated by the second nibble of status byte.
0xD3
1 byte
Sequence type 80 for variable sequence, 0x00 - 0x25 for bank 00 to 37or 20. 60 is used for the 'Mario sounds' sequence.
0xD6
Channels (16 bits)
Disable channels flag. Each bit = one channel.
0xDB
Master Volume (1 byte)
Master Volume (unsigned integer).
0xDD
Tempo in BMP (1 byte)
Tempo setting (BPM).
0xD5 16 bits
 Not sure. Used in the very beggining of sequences (before channel enable flag).
0xD7
Channels (16 bits)Enable channels flag. Each bit = one channel.
0xFD
Variable-length (1 or 2 bytes)
Timestamp (used between track chunks and to ensure right looping).
0xFB
Offset (2 bytes)
Loop from the specified offset.
0xFF
No param
End of header



TRACKER FORMAT AND COMMAND TABLE
 Status Byte
 Parameters Description                    
0x90 - 0x9F
Offset (2 bytes)
Loads music data (divided in "layers"). Since simultaneous notes (using a "0" timestamp) aren't possible, many layers are loaded and played simultaneously. The second nibble of the status byte indicates the layer number.
0xC1
Program (1 byte)
"Set program" related. There isn't a master index for instruments, this seems to refer to the current set of instruments, which is not specified in the sequence data but loaded by something external to it.

Drums tracks usually use program 0x7f (127).
0xC2Transposition (1 signed byte)
Transposition in semitones.
0xC4No Param.
Mark the beggining of track data.
0xD3Fine tune (1 byte)
signed integer, can also be used for transposition events
0xD4Reverb (1 byte)
 Amount of reverb for the track (1 byte)
0xD8Vibrato (1 byte)
Vibrato range
0xDC
Priority (1 byte)
 Usually set on drum tracks if there's too much things playing so Sound effects can be used on that channel
0xDD
Pan (1 byte)
Set pan for this track (01 = left, 64 = center, 127 = right)
0xDF
Track Volume (1 bytes)
Volume for this track (unsigned integer).
0xFD
Variable-length (1 or 2 bytes)
Timestamp (used between track chunks and to ensure right looping).
0xFF
No Param
End of Track Data



MUSIC FORMAT AND COMMAND TABLE
 Status Byte
 Parameters Description                    
 0x00-0x3F Timestamp (1 or 2 bytes)
 Velocity (1 byte)
 Duration (1 byte)
 "Play Note" commands ('Type 0'). Unlike MIDI, 0 = A0.
 Timestamp is variable lenght (see below).
 Duration byte seems to be timestamp before "NoteOff"
 0x40-0x7F
 Timestamp (1 or 2 bytes)
 Velocity (1 byte)
 "Play Note" commands ('Type 1')
 Duration = previous specified (producing more compact data).
 0x80-0xBF Velocity (1 byte)
 Duration (1 byte)
 "Play Note" commands ('Type 2').
 Timestamp = previous specified (producing more compact data).
 0xC0 Timestamp (1 or 2 bytes)
 Timestamp used for rests.
 0xC2Transposition (1 byte)
 Transposition in semitones. Since the 'PlayNote' commands just cover a range of 0x40 notes (as opposed to 0x7F possible MIDI notes), this is used to shift the range when needed.
 0xE0 - E8 ? ?
 0xFC2 bytes
 Jump (used for loops). There isn't a loop counter, so the command is repeated. Offset is relative to individual sequence start.
 0xFF No Param.
 End of music track / Return from jump



Playnote velocity goes up to 0xFF but it usually doesn't overclock 0x64.
(This post was last modified: 20-07-2016, 05:11 PM by Nutta.)
Gone for a while.

EDITED TO REFLECT CORRECT INFORMATION

Hey yo, I've been working a lot with this format and some of this information is confusing/missing/incorrect. I can't post a table to the forum so it's not worth me making a new post, but I'll put the issues here and perhaps you can add them to this post.

A Word On 0xFD Commands
If you intend to change multiple track parameters mid song (for pitch bends and other effects),0xFD track (and header) commands are in timestep deltas, so they are used as you would write out a sequence of note values


Header:

0xFD, "Define Following Commands At" (1 - 2 byte variable length delta timestep), Used to change header parameters mid-sequence by defining the next song position at which following header commands will apply

Track Command Table:
0xC2, "Coarse Transposition" (1 signed byte, semitones), adjust pitch in semitones
0xD3, "Fine Transposition" (1 signed byte, 9.375 cents negative and ~9.449 cents positive), adjust pitch over 2 octave range from negative to positive
0xFD, "Define Following Commands At" (1 - 2 byte variable length delta timestep), Used to change track parameters mid-sequence by defining the next song position at which following header commands will apply

Music Format:
Duration
Duration bytes define the percentage of the note value (defined by the so called "Timestamp" (its not a Timestamp) ) through which the note will play. This is done in an interesting way whereby "Duration" defines the 255's compliment of the actual duration percentage. So if you want to define a quarter note, then have the instrument play for only one third (0.3333~) of said quarter note (so somewhat of a quarter note staccato):

Duration = (int)((1 - 0.3333) * 255)

In other words, duration is very much not a timestamp!

In fact, I STRONGLY recommend (among all of the other musical travesties that have been committed like "clash cymbal" and "general percussion") we stop calling note timestamps "timestamps." Note's have a Duration (has a format of "timeSTEP or note value," and was previously called "timestamp," but itself IS NOT A TIMESTAMP), a Velocity, and a Play Percentage (what was just discussed).


Lastly if you look at the file format, MusicXML DOES support note velocities, but for the life of me I can't figure out why they weren't included in the converter.
(This post was last modified: 29-06-2016, 07:11 PM by Christopher Brown.)

aight apparently nobody was copying my findings over here from smwc so lets do it:
0xD4 isn't "amount of echoes" or whatever its the dry/wet mix of the effects loop. it just happens that in sm64 the only effect is a reverb.
0xDC is channel priority. all they do with it in sm64 is set the priority on drum channels to 0 so that if there's too many simultaneous sounds, itll prioritize sfx over drums.

timestamps are relative, not absolute. not sure what that stuff you're saying about ordering is. that isnt how it works. look at the hazy maze cave sequence for example. they work exactly the same way in the headers as they do for notes and rests.

frauber was right about note values too. its 48 ticks per beat. make an m64 with a note every 48 ticks and compare it to a metronome.

edit: also yeah timestamp isnt the correct term. in midi terminology they'd be called deltas. cuz ya they are relative, not absolute.
edit 2: the version of the play note command that doesnt include the duration/cutoff/play percentage/whatever (0x40-0x7F) doesnt use the previous value as frauber says in his notes, it just defaults to 0 (or 100% if you'd rather interpret it that way)
edit 3d: revelations
(This post was last modified: 05-08-2016, 02:07 AM by ergazoobi. Edit Reason: testing that editing works )

Yeah you're right about the time stamps I was testing them with one instead of multiple stamps (would make the difference clear). Also I'm not sure how you are getting 48, 24 ticks, as in 0x18 equates to one beat in every song I've worked with.

what do you mean "every song I've worked with", are you working with the importer? check that it didn't halve the tempo when it converted. ive ported songs by hand at 48 ticks per beat and the tempos were correct.

(29-06-2016, 01:03 PM)ergazoobi Wrote: what do you mean "every song I've worked with", are you working with the importer?  check that it didn't halve the tempo when it converted.  ive ported songs by hand at 48 ticks per beat and the tempos were correct.

I don't... don't know why you would think that... (notices that 0x37 is in fact 55 and not 110).

I've updated the info, the only thing left to find out would be 0xE0.
Gone for a while.

Probably not a documentation but I just found out Musescore and Musicxml(xml?) hates 1/128 notes so you have to quantize it to 1/64 unless the music won't play.
Gone for a while.

M64 Documentation
Users browsing this thread: 1 Guest(s)