Uze's 5 Minutes Sound Crash Course

Topics on software tools like TileStudio, comments on documentation and tutorials (or the lack of) should go here.
Post Reply
User avatar
uze6666
Site Admin
Posts: 4449
Joined: Tue Aug 12, 2008 9:13 pm
Location: Montreal, Canada
Contact:

Uze's 5 Minutes Sound Crash Course

Post by uze6666 » Sat Nov 29, 2008 9:21 pm

If you are like most, composing music is not your cup of tea. However, you will indeed want to quickly put some sound FXs in your games. Here's a quick crash course on how to do just that.

The current engine works with the concept of "patches". Patches are a sequence of parameters that defines how your notes or sound effects evolves over time. There's already a couples of patches I've made for Megatris I've regrouped in an include file. Add this include to your program file:

Code: Select all

#include "data/patches.inc"
IF you are useing the pre-beta3 kernel, look into it, you will see something like:

Code: Select all

//FX: "Echo Droplet"
const char patch01[] PROGMEM ={ 
0,
0,PC_ENV_SPEED,-12,
5,PC_NOTE_UP,12, 
5,PC_NOTE_DOWN,12,
5,PC_NOTE_UP,12, 
5,PC_NOTE_DOWN,12,
5,PC_NOTE_CUT,0,
0,PATCH_END
};
This is called a command stream. The first byte, is the sound type. 0 is for wavetable sounds, 1 for noise channels sound. (from beta3 and onwards, this byte is removed, more on that later). The rest is a sequence of commands. Commands are made of 3 bytes: the first one is a time delta in term of frames (frames happens at 1/60 of a sec) to wait until this command is executed. The second byte is the command type and the last byte is the command value. So in this example we have a wavetable sound (0), then when the sound is triggered (time zero), set the volume envelope decay speed to -12. On each frame after wards, -12 will automatically be subtracted from the sound's volume. Then, after a wait of 5 frames, raise's the sound pitch by 12 semitones (one octave). Then wait again for 5 frames then lower the sound's pitch by an octave. And so on, until the last command, which must be a PATCH_END command (no value byte for this one). Have a look at the .h files for all the possible commands.

From Beta3 the patch system has been tweaked to support a PCM channel which allows to play samples of arbitrary length. The sound type byte as been removed from the command stream and move into a special array of structs.

Code: Select all

const struct PatchStruct patches[] PROGMEM = {
{0,NULL,patch00,0,0},
{0,NULL,patch01,0,0},
{0,NULL,patch02,0,0},
{0,NULL,patch03,0,0},
{1,NULL,patch04,0,0},
...
};
Let's interpret one entry:

Code: Select all

{1,NULL,patch04,0,0} 
First parameter (1) is the sound type, in this case its to be played on the noise channel (0=wave,1=noise,2=PCM)
Second parameter (NULL) is a pointer to the PCM data if it were a PCM patch
Third parameter (patch04) is the patch's command stream pointer
Fourth (0) is the loop start position for PCM samples
Fifth (0) is the loop end position for PCM samples

Soooo....now let play some sounds! Add this line to your main() function:

Code: Select all

InitMusicPlayer(patches);
And *then* you can trigger fxs anywhere in your code. If you look in patches.inc, patch 19 is the "t-spin" fx from megatris

Code: Select all

TriggerFx(19,0xff,true);
In this case:
19 is the patch number
0xff is the volume
true is the 'retrig' attribute. It basically means that if another TriggerFx() call is made for the same patch *before* the previous one is finished playing, it will re-trigger it right away on the same channel instead of starting another simultaneous instance of the sound onto another channel (determined by the voice stealing algorithm).

Creating new patches is really trial an error. I suggest you make an empty project to create new patches. It will compile and flash faster.

That's it! Have fun. :)

Uze

havok1919
Posts: 474
Joined: Thu Aug 28, 2008 9:44 pm
Location: Vancouver, WA
Contact:

Re: Uze's 5 Minutes Sound Crash Course

Post by havok1919 » Sun Nov 30, 2008 12:05 am

uze6666 wrote:If you are like most, composing music is not your cup of tea. However, you will indeed want to quickly put some sound FXs in your games. Here's a quick crash course on how to do just that.
Thanks! That's really handy and one of those things that I've been putting off trying to learn.

So I'll ask the obvious question then... ;-) How much of a nightmare would it be to modify things where you could have a single patch descriptor (of reasonable length) in SRAM so that we could write a little interactive patch editor and use the SNES pad (or mouse?) to tweak values on the fly to make sounds?

-Clay

User avatar
DaveyPocket
Posts: 378
Joined: Sun Sep 14, 2008 8:33 pm
Contact:

Re: Uze's 5 Minutes Sound Crash Course

Post by DaveyPocket » Sun Nov 30, 2008 12:59 am

That was my idea too :lol:

User avatar
uze6666
Site Admin
Posts: 4449
Joined: Tue Aug 12, 2008 9:13 pm
Location: Montreal, Canada
Contact:

Re: Uze's 5 Minutes Sound Crash Course

Post by uze6666 » Sun Nov 30, 2008 1:15 am

Hehe, not much work, my friend, there's already some 'RAM patch' code for just that, creating patches. Just need somebody to write that tool ;) . I was thinking we could save the patches in the EEPROM for easy transfer to the PC. So to make that tool you need 2 things:

1.to have the #define MIDI_IN == 1
2.declare the ram patch buffer in your code with

Code: Select all

extern unsigned char ramPatch[128];
Put the command stream as defined previously. When trigging notes or FX use only TriggerNote() patch #127 (you much specify a channel for the ram patch to work:chan 0,1,2 for wavetable, chan 3 for noise fxs).

That should be it!

Uze

Post Reply

Who is online

Users browsing this forum: No registered users and 12 guests