News:

As a consequence of the forum being updated and repaired, the chatbox has been lost.
However, you can still come say hi on our Discord server!

Main Menu

Charon's New and Improved Music Hacking Tutorials

Started by Charon, 17, January, 2011, 06:04:21 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Charon



How to insert songs without using Sappy.

This is, bar none, the easiest and simpliest way to insert songs without using Sappy's auto compiler. Why wouldn't you want to use Sappy's auto compiler, you ask? Well, there's a LOT more you can do with the songs by inserting them manually. You can also track your steps - which makes it a lot easier to fix mistakes. In addition, it's easier to see what you're copying over, which makes it harder to mess up your rom in that way too.

This tutorial teaches you how to very easily import songs into a game without using Sappy. It does NOT teach you how to repeat the song or anything fancy like that. This tut is just showing the simpliest way to put in the song. If you're more advanced and know what you're doing, you can try doing things like repointing and all that fun stuff.

Tuts that will follow:
- How to insert repeating songs and change voices manually
- How to change voicegroups
- How to change voices and import from other games
- How to use a tile editor like a hex editor
- What Sappy 1.6 tells us

WHAT YOU NEED:
- A midi Editor (I personally use Anvil Studio - it may be useful to use this particular one since it has the "Repair Song" feature
- the Mid2agb Package
- Sappy 1.6
- A hex editor (or a tile editor, as in my case)

1. Make sure you edit your song so it can be imported using the program tr.exe. This program cannot read all midis, so it's important to check your midi for errors. Go into Anvil Studio and click "Repair Song". When it asks you if it wants to remove notes with a length of zero, click yes. Click no for anything else. In addition, order the tracks of the song in order of importance, because the later tracks may be cancelled out by earlier tracks.

2. Save your MIDI file into the /mid folder of your mid2agb folder. Open tr.exe. Click the button that says "??". If the song's name appears on the left side, it's all good. If it appears on the right side, then something is wrong with the midi and you need to fix it. Sometimes it's a whole track that's wrong so you have keep checking what it is until it appears on the left side.

3. Open both Song.gba (the file generated by tr.exe) and your Pokemon rom. Find the song at the end of Song.gba (the song file always starts with the byte 0xBC). Copy from that byte to the end of the file. (usually the song starts around 0x1B3BB8). An easy way to copy it is to find the offset of the song in Song.gba, and then change the pointer from 0x1XXXXX to 0xFXXXXX, but you can put it wherever you want. Make sure you know how to convert the pointers though.

4. Copy it into the Pokemon rom. If you're doing it the way I am, you're being lazy and just changing the pointer from 0x1XXXXX to 0xFXXXXX. Next, find the header of the song. The location of the header is different for every song, but an easy way to find it is that it's always the last part of the song, and it starts with a single byte - telling how many tracks are in the song. Also, the header's pointer always ends in 0, 4, 8 or C. If you're using Tile Molester like me, I show you what the header looks like in the video. Copy the address of this header down.

5. Open the Pokemon Ruby Rom in Sappy 1.6. (Pokemon Ruby's header is messed up in /data/sappy.lst, copy this:
AXVE, Pokémon Sapphire (U), sapphire, sapphire, sapp, &H45548C, &H15E, &H1D3
As the header and it should work)

Select your song, and when you play a song, three pointers will pop up.
DEF is the location of the song on the song table.
INST is the location of the voicegroup.
LOC is the location of the header.

Copy these values down as well.

6. In your hex editor, go to the header of your new song. Replace the first pointer with the pointer to the instrument set. Replace the rest of the pointers to where the tracks are. (If you did what I did, all you need to do is change all the first 1's to F's, ex. 0x123456 to 0xF23456).

7. Go to the pointer indicated by DEF. Replace this with the pointer to the header of the new song.

8. Test in Sappy 1.6. If it doesn't freeze, it will work. (it might also work if it get's an error, but it will definitely work if there are no errors)

9. Test in-game. If you don't like a certain track, you can change the song in the Midi editor and do the process again.. or change the values manually. But the latter will be covered in a later tutorial.


PLEASE WATCH PART 1 BEFORE WATCHING PART 2. I WILL NOT ANSWER ANY QUESTIONS INVOLVING PART 1 ON THIS VIDEO.

This is tutorial will teach you some more advanced techniques with music hacking, all without using Sappy! Why wouldn't you want to use Sappy's auto compiler, you ask? Well, there's a LOT more you can do with the songs by inserting them manually. You can also track your steps - which makes it a lot easier to fix mistakes. In addition, it's easier to see what you're copying over, which makes it harder to mess up your rom in that way too.

This song will teach you how to construct a simple loop. There's all sorts of ways you can put in loops into a song, the basics are shown here. You can try all sorts of different loops to get all sorts of different song styles.


Tuts that will follow:
- How to change voicegroups
- How to change voices and import from other games
- How to use a tile editor like a hex editor
- What Sappy 1.6 tells us


WHAT YOU NEED:
- A midi Editor (I personally use Anvil Studio - it may be useful to use this particular one since it has the "Repair Song" feature
- the Mid2agb Package
- Sappy 1.6
- A hex editor (or a tile editor, as in my case)

1. Have your midi ready for insertion. Make sure every track is exactly the same length. Copy the first track and paste it into a new file. Don't forget to change the tempo to the original song's tempo!

A note: With drumlines, make sure your instrument is "Acoustic Grand", and your channel is NOT 10.

2. Insert the song using tr.exe, and put the song data into the rom into some freespace. Copy the address.

3. Go to the end of the track in the rom (indicated by the byte 0xB1). Change 0xB1 into 0xB2. Put the pointer (08XXXXXX) after that. Then, finish by putting an end command (0xB1) after that. (altogether B208XXXXXX01). Without the 0xB1, it WILL FREEZE.

4. Repeat steps 1 through 3 for all the tracks in the song.

5. To set up a header, find a segment of freespace. MAKE SURE THE ADDRESS TO THE BEGINNING ENDS IN 0, 4, 8, OR C. The header is set up with three lines (consisting of four bytes of data each)
- the first line tells us the number of tracks.
- the second line is a pointer to the voicegroup.
- the third and other lines are pointers to the individual tracks.

Insert the data as shown n the video.

6. Test in Sappy.

7. Test in game.

For some REAL in depth info, here you go:
[spoiler=More stuff]
How Music Hacking Works. (for people who want to music hack)

Note! All hex is as shown in VBA's Memory Viewer.

Order of appearance in ROM: Voicegroups. Music Table. Song Header(s) and tracks. Instrument Samples.

Voicegroups

- A voice is determined by three four-byte long sections. There are five different kinds of voices. Voicegroups are word aligned.

   1. The most common is that does not seperate into two sections. The voice will be using the same WAV file no matter what the pitch. First four-byte section identifies the voicegroup type. Second section is the pointer to the actual sample. Third section is envelope of the instrument over time. (I currently don't understand how this works. You could investigate, if you like.)

   In hacking, this type of voice is the most useful, and personally, I always use it. There are many other roms that use this for all wave sample based instruments. I highly recommend using this type as a default for inserting voices in a voicegroup.

Example (in 8, 16 and 32 bit format)

00 3C 00 00
2C 09 2A 08
FF 00 FF A5

3C00 0000
092C 082A
00FF A5FF

00003C00
082A092C
A5FF00FF

   2. The second type is commonly used for instruments in Pokémon like the String Ensemble. First four-byte section identifies the voicegroup type. Second section is the pointer to two instruments. The two instruments are actually two separate wave samples, one for high notes and one for low notes. The final section is a pointer to the data that instructs the system how to separate this data.

   I have only seen this type in the Pokémon games, but it may be appearing elsewhere.

Example (in 8, 16 and 32 bit formats)

40 00 00 00
04 02 43 08
24 52 45 08

0040 0000
0204 0843
5224 0845

00000040
08430204
08455224

   3. The third type of voicegroup are the Drumkits. They seperate the notes into individual sounds of their own. The first four-byte section is used to identify the voice type. The second section is the pointer to the drum kit's individual samples. The third section is supposed to be the envelope, but it really doesn't matter because the samples have their own envelopes.

   This type is used in any game with a drumkit.

Example (in 8, 16 and 32 bit formats)

80 00 00 00
F8 FE 42 08
00 00 00 00

0080 0000
FEF8 0842
0000 0000

00000080
0842FEF8
00000000

   4. Digitally assigned. These voices are not practical for hacking as their sounds are derived from the programming itself. There are several types; in Pokémon the type is determined by the first four bytes (what normally identifies the voice type). In Golden Sun, this type looks like a type 1 voicegroup, but its pointer leads to an argument for the game's programming.

   5. Blank Voice. Blank Voices are voices that are not used. They look like so (in 8, 16 and 32 bit formats):

01 3C 00 00
02 00 00 00
00 00 0F 00

3C01 0000
0002 0000
0000 000F

00003C01
00000002
000F0000

Voicegroups can have 128 voices, starting at voice 0 (like a standard MIDI map).

Music Table

Each seperate section of the music table is 2 4-byte long sections. The first section is the pointer. The second section are value that may be 0000 0000, 0001 0001 or 0002 0002. Their function eludes me, but it may have something to do with how it interacts with the game.

Song Headers

Song headers are arranged in a very straight forward manner. It is always [the number of tracks in the song] + 2 4-byte sections.

The first section stars with how many tracks are in the song, along with an unknown byte and some zeros. The number of tracks can range from 0x0 to 0xF. The second section is the pointer to the voicegroup to be used. The third pointer leads to the tracks.



COMPLETE TRACK INFORMATION:

(This part is also included in my ELF guide; I owe Atrius for some of this information)

The audio track data is a list of commands and arguments for playing music/sound effects.

Anything below 0x80 is an argument, and anything 0x80 and above is a command.

0x80 - 0xB0 = Rest commands of varying lengths, to wait a certain amount of time before playing each note.

0xB1 = Stop command, to signal the end of the audio track. From what I've noticed even if a song loops it has one of these after the loop command.

0xB2 = Jump command, to jump the playback pointer to another location in memory. Often used to loop songs by jumping back to the beginning of it.

0xB3 = Jump command where playback can jump back to after it again later. Used when you want to repeat part of a song before continuing with the rest of it.

0xB4 = Return to last 0xB3 command.

0xB5-0xBA = Unidentified

0xBB = Set Tempo

0xBC = Set Pitch offset

0xBD = Set instrument

0xBE = Set Volume

0xBF = Set Panning

0xC0 - 0xCE = Unidentified

0xCF - 0xFF = Play notes of varying lengths.

BE FF = A volume command with an argument of 0xFF (Volume is an odd exception to the rule that arguments must be less than 0x80)

BC 00 = Set the pitch offset to zero

BB 01 = Very low tempo so that the note is drawn out long enough for voice samples to play their full length.

BD 00 = Set the instrument to the first entry in the instrument map.

CF 3C 7F = Play a note with a pitch of 0x3C (Right in the middle of the available range), and a volume of 0x7F (The maximum available)

B0 = Wait long enough for the note to finish playing

B1 = End the audio track

And some arguments for those commands:

Arguments:

Pitch

Pitch is very easy to understand. It is follows the byte 0xBC (which is usually the first byte in a given track anyhow). Pitch works like this:

0x00 is the base, equivalent to Middle C.
0x0C is one octave higher; High C.
0xF4 is one octave lower; Low C.

If you haven't noticed, it goes by increments of 0x0C, so for higher increments, they would be 0x18, 0x24, ect, while for lower increments they would be 0xE8, 0xDC, ect.

Tracks can be transposed by any value, however, so if you wanted it to be in a different key, you could change these values. If done, make sure to add/subtract 0x0C when raising/lowering octaves.

Tempo

Tempo is simply the tempo transfered into Hex. So, if your original tempo was 80, you would put in 0x50. It follows a 0xBB byte.

Instruments

The instruments correspond with the instruments of the voicegroup. Although the instruments can be anything you want, the typical way is to have the instruments correspond directly. It follows a 0xBD The direct map:

PIANO

0x00    Acoustic Grand (often used as a drum kit)
0x01    Bright Acoustic
0x02    Electric Grand
0x03    Honky-Tonk
0x04    Electric Piano 1
0x05    Electric Piano 2
0x06    Harpsichord
0x07    Clav

CHROMATIC PERCUSSION

0x08 Celesta
0x09 Glockenspiel
0x0A Music Box
0x0B Vibraphone
0x0C Marimba
0x0D Xylophone
0x0E Tubular Bells
0x0F Dulcimer

ORGAN

0x10 Drawbar Organ
0x11 Percussive Organ
0x12    Rock Organ
0x13    Church Organ
0x14    Reed Organ
0x15    Accoridan
0x16    Harmonica
0x17    Tango Accordian

GUITAR

0x18    Acoustic Guitar(nylon)
0x19    Acoustic Guitar(steel)
0x1A    Electric Guitar(jazz)
0x1B    Electric Guitar(clean)
0x1C    Electric Guitar(muted)
0x1D    Overdriven Guitar
0x1E    Distortion Guitar
0x1F    Guitar Harmonics

BASS

0x20    Acoustic Bass
0x21    Electric Bass(finger)
0x22    Electric Bass(pick)
0x23    Fretless Bass
0x24    Slap Bass 1
0x25    Slap Bass 2
0x26    Synth Bass 1
0x27    Synth Bass 2

STRINGS

0x28    Violin
0x29    Viola
0x2A    Cello
0x2B    Contrabass
0x2C    Tremolo Strings
0x2D    Pizzicato Strings
0x2E    Orchestral Strings
0x2F    Timpani

ENSEMBLE

0x30 String Ensemble 1

0x31    String Ensemble 2
0x32    SynthStrings 1
0x33    SynthStrings 2
0x34    Choir Aahs
0x35    Voice Oohs
0x36    Synth Voice
0x37    Orchestra Hit

BRASS

0x38    Trumpet
0x39    Trombone
0x3A    Tuba
0x3B    Muted Trumpet
0x3C    French Horn
0x3D    Brass Section
0x3E    SynthBrass 1
0x3F    SynthBrass 2

REED

0x40    Soprano Sax
0x41    Alto Sax
0x42    Tenor Sax
0x43    Baritone Sax
0x44    Oboe
0x45    English Horn
0x46    Bassoon
0x47    Clarinet

PIPE

0x48    Piccolo
0x49    Flute
0x4A    Recorder
0x4B    Pan Flute
0x4C    Blown Bottl
0x4D    Shakuhachi
0x4E    Whistle
0x4F    Ocarina

SYNTH LEAD

0x50    Lead 1 (square)
0x51    Lead 2 (sawtooth)
0x52    Lead 3 (calliope)
0x53    Lead 4 (chiff)
0x54    Lead 5 (charang)
0x55    Lead 6 (voice)
0x56    Lead 7 (fifths)
0x57    Lead 8 (bass+lead)

SYNTH PAD

0x58    Pad 1 (new age)
0x59    Pad 2 (warm)
0x5A    Pad 3 (polysynth)
0x5B    Pad 4 (choir)
0x5C    Pad 5 (bowed)
0x5D    Pad 6 (metallic)
0x5E    Pad 7 (halo)
0x5F    Pad 8 (sweep)

SYNTH EFFECTS

0x60    FX 1 (rain)
0x61    FX 2 (soundtrack)
0x62    FX 3 (crystal)
0x63    FX 4 (atmosphere)
0x64    FX 5 (brightness)
0x65    FX 6 (goblins)
0x66    FX 7 (echoes)
0x67    FX 8 (sci-fi)

ETHNIC

0x68    Sitar
0x69    Banjo
0x6A    Shamisen
0x6B    Koto
0x6C    Kalimba
0x6D    Bagpipe
0x6E    Fiddle
0x6F    Shanai

PERCUSSIVE

0x70    Tinkle Bell
0x71    Agogo
0x72    Steel Drums
0x73    Woodblock
0x74    Taiko Drum
0x75    Melodic Tom
0x76    Synth Dru
0x77    Reverse Cymbal

SOUND EFFECTS

0x78    Guitar Fret Noise
0x79    Breath Noise
0x7A    Seashore
0x7B    Bird Tweet
0x7C    Telephone Ring
0x7D    Helicopter
0x7E    Applause
0x7F    Gunshot (also commonly used as a drum kit)


Volume

Volume is a simple concept as well, but unlike most of the song arguments, it must be a value less than 0x80, or else (for some whacked out reason) it acts as a rest o.o

It follows 0xBE.

Panning

I need to investigate panning a little more, but I do believe that 0x00 is the neutral value. Either that, or it's 0x0C. I believe that pan's range is from 0x00 to 0x0F.

Note: By making your program locate the commands for changing volume, instrument, pitch, volume and panning, it could be very easy to edit (and very VERY useful).

Wave Samples.

Wave Samples are usually the last part of the music section. For the most part the waves should not be edited (unless using a program to convert and insert waves to the GBA's system), each wave sample has an important header that effects how the wave is played.

Here is a sample

40000000
1800 01A2
00000ED5
000014BD

The first word is a very important one. If it is 40000000, that means the wave sample will repeat its sound after it completes a cycle (like String Ensamble). If it is 00000000, that means it will simply stop after completing one cycle.

The next half-word... I have no clue what it does. But the one after it is pitch. Divide the value in half to lower the instrument an octave. Double it to raise it an octave. Standard is 0xCA.

The next word is only used if the sample repeats after a cycle. It indicates the exact byte to begin the repeat.

The last word indicates at which byte the sample ends.[/spoiler]

Atrius (He/Him)

Allow me to elaborate on some of the in-depth information.

[spoiler=Voice Groups]
Quote1. The most common is that does not seperate into two sections. The voice will be using the same WAV file no matter what the pitch. First four-byte section identifies the voicegroup type. Second section is the pointer to the actual sample. Third section is envelope of the instrument over time. (I currently don't understand how this works. You could investigate, if you like.)
And the example provided as 8-bit:
00 3C 00 00
2C 09 2A 08
FF 00 FF A5

I'll be elaborating on the Envelope data, for reference I point you to Wikipedia's article on ADSR envelopes in sound engineering.  This data is very similar to an ADSR envelope, but rather than providing times it provides increments of change in volume per frame.  Basically your attack value is how much the volume increases each frame during the attack period until maximum volume is achieved.

In this example our values are A=FF, D=00, S=FF, R=A5.  During the attack period the volume is increased by FF per frame, meaning it reaches full volume after the first frame, there is no decay period, and volume is sustained at FF.  During the release period (after the note stops playing) however volume decreases by A5 per frame resulting in a very quick fade off.


Quote2. The second type is commonly used for instruments in Pokémon like the String Ensemble. First four-byte section identifies the voicegroup type. Second section is the pointer to two instruments. The two instruments are actually two separate wave samples, one for high notes and one for low notes. The final section is a pointer to the data that instructs the system how to separate this data.

I have seen this instrument type used in other games as well with more than two samples defined, the Zelda games for GBA come to mind.  Just be aware of the fact that it's possible for there to be more than two instruments used in them.


Quote4. Digitally assigned. These voices are not practical for hacking as their sounds are derived from the programming itself. There are several types; in Pokémon the type is determined by the first four bytes (what normally identifies the voice type). In Golden Sun, this type looks like a type 1 voicegroup, but its pointer leads to an argument for the game's programming.

Golden Sun's digitally synthesized instruments cannot be grouped with traditional GBA digitally assigned instruments, they are specific to the modified music engine that Golden Sun uses.

For traditional GBA digitally synthesized instruments there is a pattern to the instrument type values, the first byte is of concern here.  XX 3C 00 00 (8-bit), 3CXX 0000 (16-bit), or 00003CXX (32-bit)

This value specifies which channel of the GBA hardware's programmable sound generators is used in generating the note, possible values include:
01 - Channel 1 (Tone & Sweep)
02 - Channel 2 (Tone)
03 - Channel 3 (Wave Output)
04 - Channel 4 (Noise)
09 - Channel 1 (Tone & Sweep)
0A - Channel 2 (Tone)
0B - Channel 3 (Wave Output)
0C - Channel 4 (Noise)

I'm not terrible familiar with the specifics of the data format for each, or the reason for them repeating at values 09+, but more information on the sound controllers themselves can be found at GBATek.[/spoiler]

[spoiler=Panning]As I recall panning can be specified between 00 and 7F with 3F being center.[/spoiler]

[spoiler=Wave Samples]Pitch is actually a full word sized value, the lower part of it just ends up getting rounded off in calculations many times.  This value can be used to calculate the sampling rate of the wave as well by converting it to decimal then dividing by 1024.
For example a value commonly seen for wave samples in Golden Sun is 01588800, converted this is equivalent to 22050 Hz, half of the sampling rate of a typical audio CD (44100 Hz)
[/spoiler]
[sprite=220,4,0]I'm shaking my head in general disapproval of everything[/sprite]

Tetsuya the Azure Blade

Hmm. Nice stuff. What, there's not a lot I can say about them two vids but awesome.

leaf

#3
So I wanted to try inserting a song I made into the game to see how it sounds, and maybe make some adjustments from there. I come to this thread, see that it instructs how to use a manual approach, but not what the benefits to using the manual approach are.

QuoteWhy wouldn't you want to use Sappy's auto compiler, you ask? Well, there's a LOT more you can do with the songs by inserting them manually.
What can you do by inserting the songs manually? Because if it isn't something that I need, it'd be a lot easier to just use an automated program.

edit: ...does this tutorial only apply to pokemon games? Cause you kept referring to a pokemon rom throughout the guide.
[spoiler=quotes]
[9:00:50 PM] Randel Peltier: Ok...what did I do last night?
[9:01:19 PM] Kain: Something boring, repetitive, and lasted for about sixty seconds.
---
[10:45:08 AM] Salanewt: But yeah, the elemental phalluses are being... Stroked up by Saturos and co., and the energy will go towards... Mt. Muffin, where the Golden Climax will arise.
[7:28:42 PM] Salanewt: An added bonus is that Isaac and co. were trying to stop Saturos and co. because their beliefs state that Mt. Muffin should remain a virgin.
---
[9:54:21 PM] Randel Peltier: Guess the number in my head an you get to pick what I say. Number between 1-10
[9:54:28 PM] leaf: 11
[9:54:36 PM] Randel Peltier: @#$%!
---
[8:38:13 PM] Randel Peltier: Shes like this queen up on a pedastal that I have yet to court.
[8:38:29 PM] Kain: You've tried courting her.
[8:38:43 PM] leaf: and failed spectacularly
[8:38:44 PM] Randel Peltier: Ive tried...shes the best dating game ever.
---
[12:24:35 AM] Salanewt: I need to find a picture of a naked person to put on the Christmas tree next year.
---
[2:19:06 PM] Zeadra: wait... Rief's a guy???
---
[1:09:57 PM] Zeadra: well if you want to know if its a new effect or something weird, just check GS1, if side step is there maby it is the nimble dodge thing
[1:10:35 PM] Kioll: For once, you've contributed something useful.  o.O[/spoiler]

Charon

#4
It applies to any ROM that can play songs via Sappy, so Golden Sun, Pokemon ect. Some later games don't use it though. You'll need a table offset for it to work though.

The thing that Sappy's Auto Compiler does not do (to the dismay of many rom hackers) is that it, from my knowledge, does not check if you have enough space. From what I've heard it doesn't even go as far as to check if you're overwriting something. Out of clumsiness or miscalculations you could overwrite crucial data, and without knowing what you're doing manually (or knowing how to fix it) you could easily end up with a messed up ROM. To make matters worse, Sappy's Auto Compiler doesn't even work on Vista - so you will need to do it manually in that case.

In addition, you can do the following without Sappy's Auto compiler:
- Change headers
- Change track details (pitch, volume, ect.) without recompiling
- Add loops (Since I can't use Sappy's Auto Compiler, I don't know if it inserts loops, but a lot of people have been asking me how to do it so I take it as a no. In addition, you can add more complicated loops, such as songs with an intro)
- Check if you have enough data, and if you don't, you can repoint tracks elsewhere instead of putting it in a huge chunk (I tend to do this a lot in my hacks, where if I find that I don't have enough room for 5 out of 5 of my tracks, but I have room for 4 out of 5, I'll put the 4 right where I was going to put it and the 5th somewhere else)
- Change voicegroup details (voices included; although that's not explained in my videos)
- Import songs directly from another Sappy-based game

So for the most part, it's not really musical stuff that it gives you the power to do, but more of the technical power so that you don't screw anything up. I can't really trust a program that overwrites your data without checking into it first.

Sorry if I didn't explain better.

Pkmn-Master

I cut and pasted the song into Ruby, but it doesn't look the same. What did I do wrong? Everything?
I'll update tomorrow with some screenshots if you need them.

leaf

Thanks for the explanation, charon. So basically, manual compiling is preferred because the auto-compiler is glitchy. Good enough for me. Well, now to sort out how to do this from the tutorial.
[spoiler=quotes]
[9:00:50 PM] Randel Peltier: Ok...what did I do last night?
[9:01:19 PM] Kain: Something boring, repetitive, and lasted for about sixty seconds.
---
[10:45:08 AM] Salanewt: But yeah, the elemental phalluses are being... Stroked up by Saturos and co., and the energy will go towards... Mt. Muffin, where the Golden Climax will arise.
[7:28:42 PM] Salanewt: An added bonus is that Isaac and co. were trying to stop Saturos and co. because their beliefs state that Mt. Muffin should remain a virgin.
---
[9:54:21 PM] Randel Peltier: Guess the number in my head an you get to pick what I say. Number between 1-10
[9:54:28 PM] leaf: 11
[9:54:36 PM] Randel Peltier: @#$%!
---
[8:38:13 PM] Randel Peltier: Shes like this queen up on a pedastal that I have yet to court.
[8:38:29 PM] Kain: You've tried courting her.
[8:38:43 PM] leaf: and failed spectacularly
[8:38:44 PM] Randel Peltier: Ive tried...shes the best dating game ever.
---
[12:24:35 AM] Salanewt: I need to find a picture of a naked person to put on the Christmas tree next year.
---
[2:19:06 PM] Zeadra: wait... Rief's a guy???
---
[1:09:57 PM] Zeadra: well if you want to know if its a new effect or something weird, just check GS1, if side step is there maby it is the nimble dodge thing
[1:10:35 PM] Kioll: For once, you've contributed something useful.  o.O[/spoiler]

Charon

#7
Quote from: Pkmn-Master on 14, February, 2011, 11:06:59 PM
I cut and pasted the song into Ruby, but it doesn't look the same. What did I do wrong? Everything?
I'll update tomorrow with some screenshots if you need them.
I'm thinking that you probably didn't repoint the pointers. If you're implanting from another game without doing it track by track, you'll find a ton of pointers scattered through the data - these are different loops. You need to repoint all of them if you want it to work properly. An easy way to do this is to transplant the song with almost the same offset, minus the first number. For example, say your offset to the beginning of the data is 0x123456, you could transplant it at 0x623456 and just change all the 1's in the pointers to 6's.

You could technically do it anywhere though if you wanted to, just that repointing all those pointers would be a total @#$%& because you would need to calculate all the new offsets individually.

Quote from: leafgreen386 on 15, February, 2011, 12:59:30 AM
Thanks for the explanation, charon. So basically, manual compiling is preferred because the auto-compiler is glitchy. Good enough for me. Well, now to sort out how to do this from the tutorial.
Yeah, to be honest I haven't been able to use it myself since I use Vista and it will not work in that program, but a lot of people have a problem with it not checking if it has enough space to write the song.

GSeriesFan

This seems to be what i was looking for...i ll try this later when i have more time, theres a lot of thing to read here!

Salanewt

Hey Charon? I have a quick question about the 0xBC byte. If a song always starts with that, then I only need to everything from the last occurrence of 0xBC to the end, right?
Oh yeah baby, £ me harder.

Fusion is just a cheap tactic to make weak Adepts stronger.

Yoshi's Lighthouse is a hacking website in progress. Why not check it out if you like Yoshi or the Mario & Luigi games?

Charon

#10
Yep.

A track starts with 0xBC and ends in 0xB1. 0xBC is actually the pitch change action, and 0xB1 is the end of the track, so watch out when importing a song with pitch bends. If it helps, the other parameters are defined at the beginning of a track as well (instrument, volume, and for the first track tempo), and the pitch bend is always defined as 0x00 at the beginning of the track in raw so look for those as well. (it should be noted that you can use the pitch bend action to change octaves)

Quote
0xBB = Set Tempo

0xBC = Set Pitch offset

0xBD = Set instrument

0xBE = Set Volume

0xBF = Set Panning
For reference.

Salanewt

Thanks for the help. The only audio hacking that I have done involves games with custom formats, so things are a bit different for me now.

Just to make sure, I should start at a 0xBC that does not have a preceding 0xB1, right?
Oh yeah baby, £ me harder.

Fusion is just a cheap tactic to make weak Adepts stronger.

Yoshi's Lighthouse is a hacking website in progress. Why not check it out if you like Yoshi or the Mario & Luigi games?

Charon

No, you start at the 0xBC defined as 0x00 (so it looks like BC 00), and with other commands defining other parts of the rest of the track.

If you're importing from Song.gba, the location of the beginning of the first track is around 0x1B3BB8. After you find that you just keep scrolling until you find a 0xB1 (a track can only have one), then copy-pasta into your rom and you have a track.

it's so hard to explain in hex editor terms because I don't use one :x

Salanewt

#13
Great, thanks! I just have one more question to ask before I am no longer being a newbie have a better grasp of this.

For reference, could you please restate how I make a loop?

Edit: Actually, I think I found it. This is where you explain it, right?

Quote1. Have your midi ready for insertion. Make sure every track is exactly the same length. Copy the first track and paste it into a new file. Don't forget to change the tempo to the original song's tempo!

A note: With drumlines, make sure your instrument is "Acoustic Grand", and your channel is NOT 10.

2. Insert the song using tr.exe, and put the song data into the rom into some freespace. Copy the address.

3. Go to the end of the track in the rom (indicated by the byte 0xB1). Change 0xB1 into 0xB2. Put the pointer (08XXXXXX) after that. Then, finish by putting an end command (0xB1) after that. (altogether B208XXXXXX01). Without the 0xB1, it WILL FREEZE.

4. Repeat steps 1 through 3 for all the tracks in the song.

5. To set up a header, find a segment of freespace. MAKE SURE THE ADDRESS TO THE BEGINNING ENDS IN 0, 4, 8, OR C. The header is set up with three lines (consisting of four bytes of data each)
- the first line tells us the number of tracks.
- the second line is a pointer to the voicegroup.
- the third and other lines are pointers to the individual tracks.

Insert the data as shown n the video.

6. Test in Sappy.

7. Test in game.
Oh yeah baby, £ me harder.

Fusion is just a cheap tactic to make weak Adepts stronger.

Yoshi's Lighthouse is a hacking website in progress. Why not check it out if you like Yoshi or the Mario & Luigi games?

Charon

#14
When inserting a track, write down the location of the first track, for example, if it were 0x654321. Unlike song headers, they can be at any location. Scroll along the track until you reach a 0xB1 byte (there's only one per track). Change it to 0xB2 and put the following after it:

[offset (in my case, 08654321)] B1

Please note that this only works if you are importing a song one track at a time.

There are multiple loop commands and they're posted in the first post. You can use clever use of loops to make/use loops, codas, and save space with looping tracks (I usually do this with drumlines). Just replace 0xB2 with the other loop commands to have different loops.

Salanewt

#15
Cool, thanks for all of your help! Just to make sure, the song's header goes right before the actual tracks start, right?

Never mind, I misread the guide. Thanks for all of your help!
Oh yeah baby, £ me harder.

Fusion is just a cheap tactic to make weak Adepts stronger.

Yoshi's Lighthouse is a hacking website in progress. Why not check it out if you like Yoshi or the Mario & Luigi games?

Charon

#16
If you're curious about header structure, its just

[# of tracks] 00 [flag] [flag]
[pointer to instruments (which is 0x1C3714 in TLA)]
[track 1 pointer]
[track 2 pointer]
...

[track 16 pointer]

It's usually after the last track in a song, and its always located at a location ending at 0, 4, 8, or C. Also, I have no idea what the flags do, I think they are really only used during certain SFX/fanfares. This means that a header will take up at least 12 bytes, and 4 extra bytes for each extra track.

Salanewt

Ah, so that explains why Sappy works until I try playing that one song. Excellent, thanks for clarifying that!

And... I just messed up the track pointers, so I shall go and fix them.
Oh yeah baby, £ me harder.

Fusion is just a cheap tactic to make weak Adepts stronger.

Yoshi's Lighthouse is a hacking website in progress. Why not check it out if you like Yoshi or the Mario & Luigi games?

Atrius (He/Him)

All of the tracks are played simultaneously.  Basically each one is the sheet music that an individual member of a band would play during a song.  Also, tracks don't necessarily have to start with BC 00

QuoteSo first there is a Music Table.
4Bytes, Song Header Pointer ?
4Bytes, Unknown
The last 4 bytes of each entry in the music table have to do with how the game prioritizes, and categorizes audio.

QuoteVoiceGroups ( Up to 128 voices )
Struct:
4Bytes, Voice Type
4Bytes, WAV Sample Pointer
4Bytes, Unknown
The last 4 bytes of a voice group are the ADSR envelope settings (Read second post in this topic)


As for the question on load order, you should know the GBA doesn't really "load" any of the raw audio data into RAM, it just streams it directly from the ROM as it plays.  As for the order it looks at things:

Music Table -> Song Header -> Tracks -> Voices as tracks ask for them (0xBD command in the track)
[sprite=220,4,0]I'm shaking my head in general disapproval of everything[/sprite]

Charon

Quote from: xTr on 07, March, 2012, 06:20:57 PM
So I've been diggin a bit and trying to figure what is the correct order of loading the music from rom, my goal is to play pokemon fire red music from ROM.
For this all you would really need to know is the pointer to the song table. I can't recall what it is atm but I could look it up later.

QuoteDoes it play like Track1, Track2, Track3, Track4 [...] ? But then how jump commands inside tracks itself behave with few track pointers?
Or maybe it's the fact that the Tracks itself are programmed to jump between Tracks inside the track data.
By tracks we mean an individual set of notes for one instrument, for example a song with a flute, guitar and drumline would have 3 tracks playing all at the same time. Its like a MIDI editor, actually. Although technically you can change the instrument midway, I hope this helps make the concept of a track in a MIDI piece a bit easier to grasp.

Hope we cleared it up for you a bit.