Gameboy Development Forum

Discussion about software development for the old-school Gameboys, ranging from the "Gray brick" to Gameboy Color
(Launched in 2008)

You are not logged in.

Ads

#1 2017-10-04 15:45:04

jobalisk
Member
From: I don't even know anymore...
Registered: 2017-05-28
Posts: 55
Website

How to music

Pretty much, I've got some wave files for wave, drum and base that I want to use as a background theme for a game I'm working on.

How do I convert them into hex or whatever it is I need to do and get them into my project?

Offline

 

#2 2017-10-04 18:09:53

ISSOtm
Member
From: Somewhere in Echo RAM
Registered: 2017-04-18
Posts: 160
Website

Re: How to music

What audio engine are you using ?


The French Lord Of Laziness.
Legend of Zelda and Undertale fan, I also tend to break Pokémon R/B/Y a little too much.

Twitter | Me on GCL | Discord : ISSOtm#9015 | Skype : isso.tm (I don't login anymore)

Offline

 

#3 2017-10-04 20:27:07

jobalisk
Member
From: I don't even know anymore...
Registered: 2017-05-28
Posts: 55
Website

Re: How to music

actually I had done it on an old Yamaha keyboard then transcribed it to 8bit using Audacity, however that's been put out the window. I have coded a tune, the next step for me is working out how to pretty much multithread so that the song plays in the background while your doing other stuff. So for example, how would I press SELECT half way through the song causing the game to stop the song and exit the menu. Here is the code:

    while(looping1 != loops1){
        looping1 = looping1 + 1;
        NR52_REG = 0x80;
        NR51_REG = 0x11;
        NR50_REG = 0x77;
       
        //square 1 (NR10-14)
       
        NR10_REG = 0x00;
        NR11_REG = 0x00;
        NR12_REG = 0xAA;
        NR13_REG = 0x00;
        NR14_REG = 0x87;
       
        delay(tempo1);
       
        NR52_REG = 0x80;
        NR51_REG = 0x11;
        NR50_REG = 0x77;
       
        NR10_REG = 0x00;
        NR11_REG = 0x10;
        NR12_REG = 0xAA;
        NR13_REG = 0x22;
        NR14_REG = 0x87;

       
        delay(tempo1);
       
        NR52_REG = 0x80;
        NR51_REG = 0x11;
        NR50_REG = 0x77;
       
        NR10_REG = 0x00;
        NR11_REG = 0x10;
        NR12_REG = 0xAA;
        NR13_REG = 0x55;
        NR14_REG = 0x87;
       
        delay(tempo1);
       
        NR52_REG = 0x80;
        NR51_REG = 0x11;
        NR50_REG = 0x77;
       
        NR10_REG = 0x00;
        NR11_REG = 0x10;
        NR12_REG = 0xAA;
        NR13_REG = 0x33;
        NR14_REG = 0x87;
       
        delay(tempo1);
       
        NR52_REG = 0x80;
        NR51_REG = 0x11;
        NR50_REG = 0x77;
       
        NR10_REG = 0x00;
        NR11_REG = 0x10;
        NR12_REG = 0xAA;
        NR13_REG = 0x00;
        NR14_REG = 0x87;

        delay(tempo1);
       
        NR52_REG = 0x80;
        NR51_REG = 0x11;
        NR50_REG = 0x77;
       
        NR10_REG = 0x00;
        NR11_REG = 0x10;
        NR12_REG = 0xAA;
        NR13_REG = 0x33;
        NR14_REG = 0x87;
       
        delay(tempo1);
       
        NR52_REG = 0x80;
        NR51_REG = 0x11;
        NR50_REG = 0x77;
       
        NR10_REG = 0x00;
        NR11_REG = 0x10;
        NR12_REG = 0xAA;
        NR13_REG = 0x22;
        NR14_REG = 0x87;
       
        delay(tempo1);
       
        NR52_REG = 0x80;
        NR51_REG = 0x11;
        NR50_REG = 0x77;
       
        NR10_REG = 0x00;
        NR11_REG = 0x10;
        NR12_REG = 0xAA;
        NR13_REG = 0x00;
        NR14_REG = 0x87;
       
        delay(tempo1);
       
    }

Last edited by jobalisk (2017-10-04 20:27:59)

Offline

 

#4 2017-10-06 22:04:30

jobalisk
Member
From: I don't even know anymore...
Registered: 2017-05-28
Posts: 55
Website

Re: How to music

Ok, I actually fixed this in the end using some rather cunning code I cooked up myself, works perfectly:

unsigned int MusicLooper = 0; //where the tune is at
void ThemeMusicPlay1()
{
        NR52_REG = 0x80; //turn sound channel on
        NR51_REG = 0x11; //set which channel we are using
        NR50_REG = 0x44; //set volume for left and right speakers
        if (MusicLooper == 1){
           
            //square 1 (NR10-14)
           
            NR10_REG = 0x00; //set sweep (like going down gradually) off
            NR11_REG = 0x00; //tone
            NR12_REG = 0xAA; //how long the sound is
            NR13_REG = 0x00; //note (I think 00 is C)
            NR14_REG = 0x87; //something else to do with notes I think
        }
        else if (MusicLooper == 800){ //the loops are the timer, each loop will play one of these and continue on until the loop is broken
            NR10_REG = 0x00;
            NR11_REG = 0x10;
            NR12_REG = 0xAA;
            NR13_REG = 0x22;
            NR14_REG = 0x87;
        }
        else if (MusicLooper == 1600){
            NR10_REG = 0x00;
            NR11_REG = 0x10;
            NR12_REG = 0xAA;
            NR13_REG = 0x55;
            NR14_REG = 0x87;           
        }

        else if (MusicLooper == 2400){
            NR10_REG = 0x00;
            NR11_REG = 0x10;
            NR12_REG = 0xAA;
            NR13_REG = 0x33;
            NR14_REG = 0x87;
        }
        else if (MusicLooper == 3200){
       
            NR10_REG = 0x00;
            NR11_REG = 0x10;
            NR12_REG = 0xAA;
            NR13_REG = 0x00;
            NR14_REG = 0x87;
        }

        else if (MusicLooper == 4000){       
            NR10_REG = 0x00;
            NR11_REG = 0x10;
            NR12_REG = 0xAA;
            NR13_REG = 0x33;
            NR14_REG = 0x87;
        }

        else if (MusicLooper == 4800){       
            NR10_REG = 0x00;
            NR11_REG = 0x10;
            NR12_REG = 0xAA;
            NR13_REG = 0x22;
            NR14_REG = 0x87;
        }
       
        else if (MusicLooper == 5600){
       
            NR10_REG = 0x00;
            NR11_REG = 0x10;
            NR12_REG = 0xAA; //AA goes on forever
            NR13_REG = 0x00;
            NR14_REG = 0x87;
        }

        else if (MusicLooper == 6200){
            NR10_REG = 0x00;
            NR11_REG = 0x10;
            NR12_REG = 0xF3;
            NR13_REG = 0xFF; //no sound, just a good way of cutting an AA
            NR14_REG = 0x87;
        }
       
        else if (MusicLooper == 6400){
            MusicLooper = 0;
        }

}


    printf("\n\n\n\n\n\n     MID AUTUMN\n        WIND\n\n\n\n\n\n");
    delay(2000);
    printf("\n\n\n\n\n\n     PRESS START\n"); //wait for start
    SWITCH_ROM_MBC1(8);
    while(MusicLooper != 10000){
        if(joypad() == J_START){ //if start is pressed stop the music and end the loop
           
            NR10_REG = 0x00;
            NR11_REG = 0x10;
            NR12_REG = 0xF3;
            NR13_REG = 0xFF; //no sound, just a good way of cutting an AA
            NR14_REG = 0x87;
           
            SWITCH_ROM_MBC1(1);
            break;
        }
        else{
            ThemeMusicPlay1(); //otherwise keep playing!
        }
        MusicLooper += 1; //keep adding one on to continue the song.
    }


Just ignore the comments.

Offline

 

#5 2017-10-07 07:24:38

Jonas
Member
From: Frankfurt, Germany
Registered: 2016-06-06
Posts: 112
Website

Re: How to music

To play music, there are two options: Either you use an existing player (like GBTPlayer or Carillon) or you go for the do-it-youself approach. I have no experience with any of the players, so I can't help you with them. But what you're trying to do in your code example is the do-it-youself approach. I'll give you a brief explanation on how that can work and a code example. I'm not saying that it's the only, easiest or smartest way but it's one that works. Proceed as follows:

1. Set up a data array with values that represent the sounds you want to play (MusicData in the example below).

2. Write a function (PlaySound in the example below) that reads one value from your data array, translates it into the respective values for the Game Boy's sound registers and writes the respective values to the sound registers. Make sure that this function only plays one sound at a time depending on the value of a counter variable (SongCounter in the example below). It is not supposed to play the complete song.

3. Write an interrupt service routine that will be triggered by the timer interrupt. Each time the timer interrupt service routine is called, it increases a counter variable (SongInterruptCounter in the example below). If the counter reaches a maximum (SongSpeed in the example below), it resets the SongInterruptCounter to zero, increases the SongCounter by one and calls the PlaySound function. If the SongCounter reaches the end of the song (SongLength in the example), it must also be reset to zero, so the song loops.

4. In your main function you only have to take the following steps:

    a. Initialize the Game Boy's sound unit.

    b. Initialize your variables (SongCounter, SongInterruptCounter, SongSpeed, SongLength).

    c. Set up the timer interrupt.

    d. Enter your main loop. Do, whatever your game needs to do. The music will play in the background.

Code:

#include <\gb\gb.h>
#include <stdio.h>

UINT16 SongLength;
UINT8  SongSpeed;
UINT8  SongInterruptCounter;
UINT16 SongCounter;

const UINT8 MusicData[] = {

    // Data array that contains the notes of your song.

};

void PlaySound()
{

    // Read the value at the position of SongCounter from the MusicData array...
    // ...translate it into the respective values for the sound registers...
    // ...and write these values to the registers.
    // Make sure you only play one note at a time.
    // For testing purposes you can ignore the array and always play the same note.

}

void TimerISR()
{

    SongInterruptCounter++;
    
    if (SongInterruptCounter == SongSpeed)
    {
                
        PlaySound();
        SongCounter++;
        if (SongCounter == SongLength) SongCounter = 0;
        SongInterruptCounter = 0;
        
    }
        
}
    
void main()
{

    // Initialize sound unit.
    
    NR52_REG = 0x80;
    NR51_REG = 0xFF;
    NR50_REG = 0x77;
    
    // Dont' forget to initialize the waveform data for channel 3 if you want to use it.
    
    // Initialize variables.
    
    SongInterruptCounter = 0;
    SongCounter          = 0;
    SongSpeed            = 20;  // Higher value results in a slower tempo.
    SongLength           = 327; // Number of notes of your song.
    
    // Set up the timer interrupt.
    
    disable_interrupts();
    add_TIM(TimerISR);
    enable_interrupts();
    TAC_REG = 0x06;
    set_interrupts(TIM_IFLAG);

    // Main loop.
    
    while(!0) {
    
        // Fill in the code for your game here. The music will play in the background.
    
    }
        
}

Offline

 

#6 2017-10-07 15:49:29

jobalisk
Member
From: I don't even know anymore...
Registered: 2017-05-28
Posts: 55
Website

Re: How to music

thank you, as you can see by the above post I have worked out a way of doing it myself but this is quite useful. I can't however get more than 1 channel to play at once, not sure why.

Offline

 

#7 2017-10-07 23:45:07

chris
Member
From: USA
Registered: 2016-11-27
Posts: 142
Website

Re: How to music

The above code can be shortened a little if you use a switch statement instead of all those else if statements.
https://www.tutorialspoint.com/cprogram … t_in_c.htm

Last edited by chris (2017-10-07 23:47:35)


My avatar is from Nintendo Power. I miss those days, so I decided to bring them back.

Offline

 

#8 2017-10-08 05:21:59

chris
Member
From: USA
Registered: 2016-11-27
Posts: 142
Website

Re: How to music

Here's how I do music:
First, I figure out the notes to play and put them in the code like so:

Code:

const unsigned char level1_notes_2[] = {
    14, 64, 94, 14, 64, 94, 14, 64, 94,  44, 94, 4, 
    44, 74, 94, 44, 74, 94, 44, 74, 94, 74, 64, 44, 44
    };

const unsigned char level1_notes[] = {
    144, 164, 144, 94, 44, 94, 44, 94, 144, 164, 144, 164, 94,
    164, 204, 164, 144, 94, 144, 164, 204, 164, 144, 94, 144, 44
    };

const unsigned char level1_notelength[] = {
    48, 16, 16, 16, 48, 16, 16, 16, 48, 16, 16, 16, 96,
    48, 16, 16, 16, 48, 16, 16, 16, 48, 16, 16, 16, 96
};

Then I made a music_player part like so. (This is where the switch function comes in handy, for different songs)

Code:

void music_player()
{
    NR52_REG = 0x80;  // POWER SOUNDS
    NR50_REG = 0xCC;  // MASTER VOLUME
    NR51_REG = 0xff;   // L/R ENABLES
    

    NR12_REG = 0xd0;  // SQUARE 1 volume (I thought that was controlled by NR50!)
    NR22_REG = 0xd0; 
    
    if (tsnote<0) NR12_REG = 0x00, NR22_REG = 0x00;
    
    //if gameinprocess =2 then game has begun. Otherwise, 0 means it's at the title screen.
    switch (gameinprocess)
    {
    case 2:
    NR11_REG = 0x86;
    NR14_REG = 0x86;
    NR24_REG = 0x87;
    
    if (tsnote>25) tsnote=0, titlescreentimer2=0, tsnote2=0;    
    NR13_REG = level1_notes[tsnote];     
    NR23_REG = level1_notes_2[tsnote2];     
    break;

    case 0:
    NR11_REG = 0x86;
    NR14_REG = 0x87;    
    NR24_REG = 0x86;
    NR21_REG = 0x86;

    if (tsnote>36) tsnote=0, titlescreentimer2=0, tsnote2=0;
    NR13_REG = nr13_ts_notes[tsnote]; 
    NR23_REG = nr23_ts_notes[tsnote2]; 
    break;    
    }
}

Then, inside the main loop, I pointed to the music_player like so:

Code:

    // play the song.
    songtimer++, titlescreentimer2++;
    length=level1_notelength[tsnote];
    if (songtimer>length) tsnote++, songtimer=0, music_player();    
    if (titlescreentimer2>32) tsnote2++, titlescreentimer2=0, music_player();

I figured this out all by myself and my experience with C.


My avatar is from Nintendo Power. I miss those days, so I decided to bring them back.

Offline

 

#9 2017-10-08 08:19:24

Jonas
Member
From: Frankfurt, Germany
Registered: 2016-06-06
Posts: 112
Website

Re: How to music

jobalisk wrote:

thank you, as you can see by the above post I have worked out a way of doing it myself but this is quite useful. I can't however get more than 1 channel to play at once, not sure why.

I guess the reason is that you change the value of NR51_REG before you play each sound. Try to set NR51_REG only once in the initialization procedure of your game and set it to 0xFF. That will waste a bit of battery life on the real hardware but should enable you to use all channels simultaneously.

Last edited by Jonas (2017-10-08 08:20:05)

Offline

 

#10 2017-10-08 15:59:52

jobalisk
Member
From: I don't even know anymore...
Registered: 2017-05-28
Posts: 55
Website

Re: How to music

Thank you both of you, this has been most enlightening.



EDIT: Thanks for the multi-channel code, worked like a charm.

Last edited by jobalisk (2017-10-08 16:34:20)

Offline

 

#11 2018-07-31 05:22:50

26F
Member
Registered: 2018-07-25
Posts: 13
Website

Re: How to music

8-bit integer notes for chromatic scale from C to B.

C      13,
C#    40,
D      68,
EF     91,
E      114,
F      137,
F#    157,
G      177,
G#    195,
A       214,
BF     231,
B       247

Offline

 

Board footer

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson