BoyScout Manual
Music tracking software for the GameBoy Advance

By: Christer Andersson © 2001-2005


Table of Contents

Terms of Usage

The BoyScout distribution is provided as is, and may only be changed by me, Christer Andersson
. It is okay to distribute this distribution, as long as it is done in a way to guarantee that it is available freely and free, unless another agreement is made with me.

I do not provide any guarantee of functionality of any part of this distribution.

This BoyScout distribution can be used freely in any commercial or non-commercial project.

The usage of this distribution is totally on the responsiblity of the user. For any damages of whatever property, possibly linked to this distribution, I cannot be held responsible.

By using this distribution, you, the user, agree to these terms.

Newest Version

You should always be able to find the newest version and news at:
http://www.pidelipom.com/boyscout/


To find out which version of BoyScout you have, click the system menu (top left icon on application title bar) and then "About BoyScout...".

For contact information see Credits.


Managing Songs

Creating a New Song

On startup of BoyScout a default new song is created. These settings might not be convenient for you. To create a new song with different settings:

Beat length (n/60): This is a measurement of how long each beat in pattern will take. A setting of 15 gives (15/60)s = 0.25 seconds per pattern beat. This setting will be viewable in the sequencer, where it also is postchangable (see The Sequencer).

Sequencer Beats/Row: How many beats it should go on one sequencer row. If a small Beat length is chosen, it can be inconvenient later on to place patterns in the sequencer, as you have a hard time to get an overview of the song. But, also know that by setting this high, you loose pattern placement resolution. Chose this parameter visely, as it is not editable later on.

Opening a Song or Preset file

There is one native format to be used together with BoyScout, the .BSF (BoyScout Song Format). This format stores just about all current data and states for you. To open a song:

 

This will bring up the standard Windows open dialog box, from which you can open a song.

You can also open preset files .BPT (BoyScout Presets), which contains presets for the sound channels. Opening a preset file will append the channel presets to the current song.

Saving

There are 5 file types that can be saved from the save menu:

BSF: The BoyScout Song Format. Which preserves all settings and is used for working with BoyScout.
BGF: The BoyScout GameBoy Format. This is the format that is used for playback on the GBA device. It is a compressed and compact format. Only Begin to End of song is is saved.
BPT: The BoyScout Preset Format. Saves all the presets in a song to a file. This allows to recycling of good presets in other songs, as the presets can be loaded into other songs.
WAV: Renders the song from Begin to End to a wave file (channel muting is supported).
CPP: Converts a file (any file) into a .cpp file containing a hexadecimal array of the file data.

In order to save a file:

 

This will bring up the standard Windows save dialog box, from which you can chose your save directory and file name.

Note: It is the file extension
that decides into which format the song is saved.

Note: The CPP file saving is a bit special. You first specify a file name to save to, then you select the file to create the array data from. It doesn't have to be a .BGF file, although this is the foremost intention of the feature.

Patterns

What?

If you are unfamiliar with the pattern concept and wonder about their function, let me explain. A pattern is a sequence of notes (or triggers in the case of Sound 4), and can for example be a melody or a beat. A pattern is connected to the channel in which it is created, and allows editing of that channels parameters. There are many cons of implementing patterns in a tracker:

  • You can reuse a pattern as many times as you want just by placing it in the sequencer.
  • By moving patterns in the sequencer you can easily remodel your song and test new combinations.
  • For a system like the GameBoy, patterns will in just about all cases save space, due to their reusability.
  • You can organize you songs in a convenients way by naming patterns.
  • You will see.

Creating

In order to create a pattern you must first be in a channel mode. There are four channels on the GameBoy and in BoyScout (see Channels). In order to view a channel you must have pressed one of these buttons:

These are Sound 1, Sound 2, Sound 3 and Sound 4 respectively. To create a pattern, after you've entered a channel mode:

Name: By naming your pattern you can more easily find your patterns later on.

Length: The number of beats in the pattern. The length of the pattern in seconds will depend on the song's Beat Length setting (see Managing Songs and The Sequencer).


After you have created a pattern you will see a view something like this:

The dotted columns are parameters you can set in the pattern (see Editing later in this topic). A dotted parameter means that the parameter is unchanged.

Selecting

In order to view a specific pattern, just select the one you want from the combo box, shown in the above picture.

Deleting

In order to delete a pattern, press the following button and confirm deletion:

Note: If the pattern is used somewhere in the sequencer, it will be mute. This is until you have created a new pattern that replaces the old pattern's index (see number before name in combo box), whereafter the new pattern will be played. Thus, unless you want this effect, remember to remove the pattern from the sequencer.

Copying

To create a copy of a pattern:

Name: Just fill in whatever name you want the copy to have.

Length: The option of changing the length of the pattern will either crop your pattern if less then original length or add empty parameters if larger than original length. The value of Length is always defaulted to the original length.

Note: You could create a new pattern and use the copy & paste functions, instead of pattern copying. This function is only provided as a more forward method.

Editing

In order to edit a pattern, you have a number of columns at your disposal. Parameters in the first column from the left is the note parameter (or trigger in Sound 4). The following columns, that comes directly after each other, after the separating space, are the sound parameters. The number of sound parameters is different between channels.

Each row in the pattern represents a beat. At each and everyone of these beats you can set a note, and together with a note change the sound parameters. A scroll bar is available to faster navigate the pattern:

Just click on a parameter in order to select it. When a parameter list has input, you can navigate the entire pattern using the arrow keys. Note that when standing in a parameter column, you can view the parameter name and value range at the lower right of the program window:

To set the note parameter: The keyboard layout for setting notes is kinda like the keyboard layout for an octave on a piano:

As you can see, you can access two octaves at a time through the keyboard. The lower octave keys number is decided by the current octave setting, and the octave keys above is the current octave setting + 1. If you wonder which key correspond to which note, just try it out, or if you know the piano octave layout, that the key Z is the note C and A is C#.

Changing octave: The current octave setting is displayed while in a sound mode:

In order to modify it, stand in a parameter column and press the divide key to decrease or the multiply key to increase the octave setting. Both these keys are located at the numerical extension of the keyboard.

To set the sound parameters: Stand at the parameter and just type in the value you want, using the numeric part of the keyboard. The program will stop you from entering invalid values as specified by the parameter range. In order to get negative number, enter the absolute number and then press the subtract key located at the numerical extension of the keyboard.

Preset transfer: You can move the current preset slider settings (see Presets) to the sound settings of the pattern row on which you are standing by pressing Page Up. Note that you do not transfer the settings of the preset shown in the combo box, but the current slider settings. Reversibly, you can press Page Down to set the preset sliders from the current pattern row sound settings.

Clearing a parameter: You can delete the current parameter in several ways. For numerical values you can press backspace or Delete to remove the least significant digit, these buttons can also be used to remove note parameters. For all parameters you can press period [.] to completely clear the setting.

Transposing notes: You can transpose a sequence of notes up or down by pressing Ctrl-T this can save you alot of time. For example if you are creating a reverb effect by using the same melody in two channels, but transposed one step in one of the channels.

Copy & Paste: Just as in most standard Windows programs BoyScout lets you use the short keys, Ctrl-C and Ctrl-V to copy & paste parameters.

Important: Sound parameters can only be changed together with a note. Thus, any sound parameters set between notes are ignored. You don't have to specify all sound parameters when setting a note, know that sound parameters are kept between notes and patterns. Also, sound parameters are always internally set to a default value at start of playback.

Causion: As sound parameters are kept between patterns, you might experience unexpected changes in you melodies, if not the first note in every pattern sets all of its sound parameters. This might be a desired effect, but is more likely to disturb the workflow. Also do not rely on the sound playback generated when setting notes, as these only reflects sound parameter changes within the current pattern, unless you know that no other pattern can influence the sound parameters of the pattern (such as setting all sound parameters of the first note or by knowing what you are doing).

Presets

What?

I guess you can have a faily good idea of what a preset is. The slider settings shown to the left of the program, when in a sound channel, can always be transferred to a pattern row (see Patterns, Editing):

If you have made a good sound setting that you like, you can save the settings as a preset, to easliy access this setting later on.

Saving

To save the current slider settings to a preset:


Just name your preset and click OK.

Note: You can save the song's presets to file (see Managing Songs).

Selecting

To set the preset sliders to a saved preset setting, just select the preset from the preset combo box.

Updating

To update the current preset with the new settings, just click this button and confirm update:

Note: There is no such Update button in Sound 3 channel. It uses a checkbox to update the waveform instead (see The Wave Edit).

Deleting

In order to delete a preset just press the following button and confirm deletion:

The Wave Edit

There is one preset mode that needs further explaination, in channel Sound 3, there is the wave edit controller. Sound 3 uses arbitary wave forms of 32 steps. Sound 3 can therefore create some rather interesting sounds. The Sound 3 channel does not have many settings, therefore the preset sliders are completely removed (no preset transfer can be done either) and are replaced by one wave editing controller:

When a wave form is saved to a preset it can be accessed by the Sound 3 patterns (Sound 3's Wave Preset parameter).

To draw a wave form, hold down the left mouse button and move the mose over the grid. The envelope is adjusted up and down, and the wave form steps increases to the left. The envelope is zero (mute) at the black line running across the grid.
Easy reset is done by holding the right button and moving the mouse across the desired steps.

The wave form preset works quite similar to the other presets when it comes to saving and deleting. But with one major difference:

This check box, located below the wave edit controller, allows you, when checked, to edit the wave contents of the currently selected preset. This means you can change the wave form as the song is being played. This is an interesting tool that allows you to experiment with Sound 3 output. Just select the preset you want to edit from the preset combo box, check the edit box and change the wave form shape.

Channels

Sound 1

Sound 1 channel generates a pulse wave form, of a certain distribution. To this wave form an envelope function and/or a sweep function can be applied. A sweep is kinda like note bend.

Parameter Range Description
Note C3 to B8 The note will create an appropriate frequency for the wave form, enabling creation of melodies like on a piano.
Envelope 0 to 15 Envelope = Volume, 15 is max, 0 is mute.
Envelope steps -7 to 7 This setting, if not 0, will cause the volume to increase (if positive) or decrease (if negative), changing the envelope every:
Envelope Change every ( |n| / 64) seconds
Length 0 to 63 This setting is the opposite of what one might think, the length is calculated according to:
Sound Length = ((64-n) / 256) seconds
Duty Cycle 0 to 3 Distribution of pulse: 0 = 12.5%, 1 = 25.0% 2 = 50.0% 3 = 75.0%
Sweep Shifts -7 to 7 Number of sweep changes to do. A negative value will sweep down and positive value will sweep up.
Sweep Time 0 to 7 Interval time between sweep shifts is calculated like this:
Sweep shift every (n / 128) Hz

Sound 2

Sound 2 channel generates a pulse wave form just like Sound 1, an envelope function can be applied to the wave form, but no sweep function is supported.

Parameter Range Description
Note C3 to B8 The note will create an appropriate frequency for the wave form, enabling creation of melodies like on a piano.
Envelope 0 to 15 Envelope = Volume, 15 is max, 0 is mute.
Envelope steps -7 to 7 This setting, if not 0, will cause the volume to increase (if positive) or decrease (if negative), changing the envelope every:
Envelope Change every ( |n| / 64) seconds
Length 0 to 63 This setting is the opposite of what one might think, the length is calculated according to:
Sound Length = ((64-n) / 256) seconds
Duty Cycle 0 to 3 Distribution of pulse: 0 = 12.5%, 1 = 25.0% 2 = 50.0% 3 = 75.0%

Sound 3

Sound 3 channel outputs arbitary 32-step wave forms which can be created in the wave editor.

Parameter Range Description
Note C3 to B8 The note will create an appropriate frequency for the wave form, enabling creation of melodies like on a piano.
Envelope 0 to 4 Envelope = Volume, 4 is max, 0 is mute.
Length 0 to 255 This setting is the opposite of what one might think, the length is calculated according to:
Sound Length = ((256-n) / 256) seconds
Wave Preset 0 to 255 A preset wave form index from the Sound 3 combo box, index is number in front of preset name.

Sound 4

Sound 4 channel generates white noise. An envelope function is supported.

Parameter Range Description
Note C3 to B8 The note has no effect on noise output, but acts only as a trigger.
Envelope 0 to 15 Envelope = Volume, 15 is max, 0 is mute.
Envelope steps -7 to 7 This setting, if not 0, will cause the volume to increase (if positive) or decrease (if negative), changing the envelope every:
Envelope Change every ( |n| / 64) seconds
Length 0 to 63 This setting is the opposite of what one might think, the length is calculated accodring to:
Sound Length = ((64-n) / 256) seconds
Dividing Ratio Frequency 0 to 7 Prescalar to polynomial noise function.
Polynomial Counter Shifts 0 to 13 Value to polynomial noise function. Noise shift frequency is calculated according to:
Shift Frequency = Div.Ratio.Freq x (1 / (2^(n+1)) ) Hz
Polynomial Counter Steps 0 to 1 This controls the "resolution" of the noise, more steps gives a less "repetetative" noise (if audible) 0 = 15 steps, 1 = 7 steps.

The Sequencer

What?

In non-pattern based software, you could say you only have a sequencer, nothing more. All song data is inserted into one long list, with all channel parameters viewable side by side. The sequencer in BoyScout is pattern based and shows the four GameBoy channels:


In these lists you place the pattern indices for each sound channel. One can say that you put the patterns into sequence.

Note: It is the "Sequencer Beats Per Row" setting (see Managing Songs), that controls at what resolution you are allowed to place patterns in the sequencer. This has to be a compromise between overview and how dynamically you can use the patterns in the sequencer (this setting is 4
in the above image, as can be seen by the interval).

Play & Stop

These buttons controls the playback of the song. Their use is just as straightforward as they should be. Play starts playback at the position specified by the "Begin" setting, and loops at the position specified by the "End" setting. Stop resets and stops playback.

Play and stop are not sequencer exclusive, but are exposed in the sound channel modes as well. Hitting play while in a sound channel has the same effect as in sequencer mode.

When playing a song, a playbar marks the position of the current playback, to give you a better overview. This playbar is also shown in the current pattern being played. This is useful for tuning you melodies, as you can set the Begin and End settings over a pattern in the sequencer, press play and go to the channel and pattern to view playback.


Note: It is possible to be editing in your patterns and in the sequencer while the song is being played. Playback might be stalled somewhat, but this is a very good thing when it comes to tuning your patterns and song.


Begin & End

To set Begin: Stand at the sequencer row from which playback should start, and press Home.

To set End: Stand at the sequencer row from which playback should loop, and press End.

Note: You cannot place Begin after End or wiseversa.

Beat Length & BPM

When being in the sequencer mode, you can view the song's Beat Length and calculated BPM (Beats per Minute). BPM is a common tracker setting and is calculated for recognition:

Modifying Beat Length: It is possible to change the Beat Length of the song after it has been created, just click the "Beat Length.." text in the sequencer (shown above):


The value will be defaulted to the current Beat Length value, valid values are greater than 0.


Editing

There is always a sequencer pattern in BoyScout and editing it works just like with pattern editing. For the four sound channel listings, stand on the row where you want to place a pattern, then just use the numeric part of the keyboard to type in the pattern index:


When a pattern index has been set at a sequencer step, the name and length of the pattern can be view in the lower right corner of the application. If the index is invalid, the text will say "Invalid pattern".


Note: Copy & Paste works in the sequencer just as in sound channel patterns.

Sound Channel On/Off

Above each sound channel in the sequencer there is a button. This button toggles the sound channel On/Off. This is good to tweak sound events in a particular channel without being disturbed by the other channels playing.

Programming

In this topic I will cover the BoyScout playback library. Please do not send me emails asking how to link a GBA project or how to get data into ROM. These are issues you will have to solve on you own. There are plenty of resource on net, see Credits for links. The playback library is in plain C, so there should be no compiler issues. Just for the record, I use GCC and I have not tried it with any ARM compiler.

Source files

The BoyScout distribution comes with a few playback library files:

File Description
BoyScout.c Compile and link this file with your project. The file contains the neccessary functions for song playback on the GameBoy Advance.
BoyScout.h Include this file in the files in which you want BoyScout playback capabilities.
GBASoundRegs.h Internally used file to manage GameBoy Advance sound registers.

Note: You are not required to use these files for playback. The files provided are just a robust playback shell written in C, and can be used for educational purposes. If you do decide to write your own playback functions, please share them for others to use and let me know about them.

Function overview

There are not many functions needed for BoyScout song playback:

void BoyScoutInitialize( );

Initializes BoyScout, call this function once, before any other BoyScout function. The function resets internal variables and structures.

unsigned short BoyScoutGetNeededSongMemory(unsigned char *pSongData);

Function returns the needed RAM area size for proper playback of a particular BoyScout song, input is a pointer to the BoyScout song data.

void BoyScoutSetMemoryArea(unsigned int nMemoryAddress);

Call this function to set the address of the beginning of a memory area allocated for BoyScout's internal structures. The size of this area will depend on the number of patterns in the BoyScout song, use BoyScoutGetNeededSongMemory to get the exact size.

void BoyScoutOpenSong(unsigned char *pSongData);

The function takes a pointer to BoyScout song data and does the neccessary preparations for playback.

void BoyScoutPlaySong(int nLoop);

Starts playback of the currently open BoyScout song. A loop setting of 0 stops the song when the end is reached, non zero and the song will restart from the beginning.

int BoyScoutUpdateSong( );

Function updates song playback. Call this function first thing when entering a new vertical blank. This will be crusial to the song syncronization. If playback is set to a non-looping mode, it will return 0 when playback has finished.

void BoyScoutStopSong( );

Stops song playback.

Code Example

The following example opens a BoyScout song and starts playback looping infinitly. The code demonstrates all the BoyScout functions and all you need to get started. Just a note, it may be easier to work with BoyScout if you put BoyScoutUpdateSong in a V-Blank interrupt. Note that the following code requires you to have a functioning malloc routine. A good linkscript should allocate memory in external RAM.

void AgbMain(void)
{
  unsigned int nBSSongSize;

// Initialize BoyScout
BoyScoutInitialize();

// Get needed song memory
nBSSongSize = BoyScoutGetNeededSongMemory((unsigned char *)SongData);

// Allocate and set BoyScout memory area
BoyScoutSetMemoryArea((unsigned int)malloc(nBSSongSize));

// Open song
BoyScoutOpenSong((unsigned char *)SongData);

// Play song and loop
BoyScoutPlaySong(1);

while(1)
{

  // Wait for vertical blank
WaitForVSync();

// Update song
BoyScoutUpdateSong();

  }

// This part will never be reached but just for completion
// Free memory
free((void *)BoyScoutGetMemoryArea());
}

Credits

Programming:
Christer Andersson

Additional Design:
Markus Hoglund

Programming help, testing & suggestions:
Johan Larsby (Scania demo group)

Playback library bug fixes and help:
Dave Murphy (WinterMute)
Willem Kokke

More or less moral support:
Jens Olsson
:O)

Greetings to:

Robert Kopsen ( Let me know if you need any help with SC9 )
IRC #GBADev @ EfNet
http://www.gbadev.org
http://www.devrs.com/gba/


BoyScout by: Christer Andersson - Copyright © 2001-2005