Language…
17 users online: 0ne_bins211,  BeeKaay, Daizo Dee Von, Dilshacking, Flipipu, Jgb007, kaizogigi89, MagneticHibiscus, MorrieTheMagpie, Peyton, Saela, Sluwu, SusGodGaming, TheClassicOne88, X11Gbyte, yoshi3706, Zatara - Guests: 101 - Bots: 185
Users: 67,566 (2,005 active)
Latest user: Baschfire

Kellogg's® Presents: The Official SFX Creation Tutorial

Custom Music



Index
  1. Introduction
  2. The Instrument Table™
  3. SFX Making
  4. Examples





Introduction

Hello, if you are here, then that means you want to make your own sound effects. If that’s the case and you didn’t get lost in the forums (again), then let’s get started!!!

The tools we will be using are:
  1. AddmusicK, which I suppose you already have.





The Instrument Table™

In reality, SMW uses two instrument tables: one for music (which is subdivided into a melodic instruments table and a percussion instruments table) and one for sound effects, both of these can be found in InstrumentData.asm inside AMK's asm folder. The instrument table used for SFX is different, so your experience with music ports won’t help you here!

The instrument table for SFX works like this:
Code
; Byte 0: Left volume
; Byte 1: Right volume
; Byte 2: Starting pitch 1
; Byte 3: Starting pitch 2
; Byte 4: Sample (SRCN) number
; Byte 5: ADSR 1 / GAIN
; Byte 6: ADSR 2
; Byte 7: GAIN
; Byte 8: Tuning
$70, $70, $00, $10, $06, $DF, $E0, $B8, $02 

As you can see, it’s similar to the #instruments syntax, but with 4 extra bytes (ignoring Sample Number, which is present in every instrument table). These are “default” values in case you don’t specify volume or (somehow) pitch, which are inserted directly into the DSP registers. On the SNES SPC700 Player, you can view the DSP registers by pressing the right arrow key on your keyboard twice. Unlike #instruments, however, there’s only one byte for tuning. You can change these bytes if you want to, or even add new instruments, but vanilla sound effects will be affected, so do so with caution.
To elaborate on the Sample (SRCN) Number, this number represents the order in which every sample is inserted through sample groups:
Code
#default
{
	"default/00 SMW @0.brr"!
	"default/01 SMW @1.brr"!
	"default/02 SMW @2.brr"!
	"default/03 SMW @3.brr"!
	"default/04 SMW @4.brr"!
	"default/05 SMW @8.brr"!
	"default/06 SMW @22.brr"!
	"default/07 SMW @5.brr"!
	"default/08 SMW @6.brr"!
	"default/09 SMW @7.brr"!
	"default/0A SMW @9.brr"!
	"default/0B SMW @10.brr"!
	"default/0C SMW @13.brr"!
	"default/0D SMW @14.brr"
	"default/0E SMW @29.brr"!
	"default/0F SMW @21.brr"
	"default/10 SMW @12.brr"!
	"default/11 SMW @17.brr"
	"default/12 SMW @15.brr"!
	"default/13 SMW Thunder.brr"!
}

In this case, @0’s Sample Number is 00, @1’s is 01, @2’s is 02 and so on. These samples were named with the Sample Numbers in mind, as they are prefaced with their respective sample number given the default ordering of the sample group. If you were to insert a new sample at the end of the list, it would be sample 14, then 15, 16 and so on, but only until 7F. Sample numbers 80-9F are noise.
In short, sample numbers can only go from 00 to 7F, while 80 to 9F is noise.

Here’s the SFX Instrument Table as if we were using #instruments, for convenience. You can click on the commented line to play an example SPC.
Code
							;HEX/@
@22 $DF $E0 $B8 $02 $00					;00/@0
@0 $FE $0A $B8 $03 $00					;01/@1
@3 $FE $11 $B8 $03 $00					;02/@2
@4 $FE $6A $B8 $03 $00					;03/@3
@0 $FE $11 $B8 $03 $00					;04/@4
@6 $FE $6A $B8 $03 $00					;05/@5
@2 $FE $6A $B8 $06 $00					;06/@6
@22 $FE $6A $B8 $05 $00					;07/@7
@0 $CA $D7 $B8 $03 $00					;08/@8
@12 $0E $6A $7F $04 $00					;09/@9
@10 $FE $6A $B8 $02 $00					;0A/@10
@10 $FF $E0 $B8 $05 $00					;0B/@11
@29 $FE $00 $7F $06 $00					;0C/@12
@0 $B6 $30 $30 $06 $00					;0D/@13
@15 $0E $6A $70 $03 $00					;0E/@14
@1 $FA $6A $70 $03 $00					;0F/@15
@2 $FE $16 $70 $03 $00					;10/@16
"default/13 SMW Thunder.brr" $0E $16 $7F $03 $00	;11/@17
@2 $FE $33 $7F $03 $00					;12/@18





SFX Making

To start off, SFX commands are VERY limited, as you only have a handful to work with. The most important thing you need to know about how sound effects behave is that there is no tempo, no light staccato, no ties, and rests are only implemented in AddmusicK 1.0.9 and later. With this, I’m referring to the fact that sound effects play at a fixed speed (t56), there’s 2 ticks of silence between notes compared to music (which is more configurable between 1 and 2 ticks), and you can’t tie notes (^ or C6 in HEX). Ties will cause the last note to repeat. Rests (r or C7 in HEX) do the same thing in older AddmusicK versions as well.

AMK allows normal syntax like @0, vXXX, yXX, etc., but it gets buggy sometimes, so I really, really, REALLY recommend you type commands directly in HEX instead. Here’s how it works:

$XX = Notes
c
c+
d
d+
e
f
f+
g
g+
a
a+
b
o1
80
81
82
83
84
85
86
87
88
89
8A
8B
o2
8C
8D
8E
8F
90
91
92
93
94
95
96
97
o3
98
99
9A
9B
9C
9D
9E
9F
A0
A1
A2
A3
o4
A4
A5
A6
A7
A8
A9
AA
AB
AC
AD
AE
AF
o5
B0
B1
B2
B3
B4
B5
B6
B7
B8
B9
BA
BB
o6
BC
BD
BE
BF
C0
C1
C2
C3
C4
C5

$DA $XX $YY = Instrument
$XX is the instrument number in HEX. Check the #instruments table I put above and look for whatever instrument you want to use. Goes from 00 to 7F.
If you specify a value from 80 to 9F, then this will be noise. When you use noise, you can set an extra argument “$YY” to specify an instrument to get ADSR values from.

$DD $WW $XX $YY $ZZ = Pitch Bend (Extended)
$WW is the starting note, $XX is the delay, $YY is the duration, and $ZZ is the final note. This one is pretty similar to the one used when porting music but it has an extra “starting note” byte. It can only be used as a starting or one-shot pitch bend.

$EB $XX $YY $ZZ = Pitch Bend
$XX is the delay, $YY is the duration, and $ZZ is the final note. Must be put after $DD or other $EB commands for subsequent bends without resetting a note.

$FE
This command needs no arguments. It will repeat the SFX indefinitely.

$FF
This command needs no arguments. It will repeat the last note indefinitely.

$XX = Note Length
This can be any byte ranging from 00 to 7F, and can be put before a note or a pitch bend of any kind ($DD or $EB). If followed by another byte that is also in the 00 to 7F range, then that will be volume (see below). If a sound effect starts with a pitch bend ($DD), then the note length should be specified before it to last for as long as the pitch bend does ($XX + $YY arguments).

$XX $YY = Volume
This is volume; it can consist of one or two arguments. A channel has two DSP values for volume: left and right. If you specify only one value “$XX”, it will be copied into both left and right, which will result in the sound being centered. If you specify two values “$XX $YY”, the first one ($XX) will be left volume and the second one ($YY) will be right volume; this is used for panning. Surround is not allowed, as the command can only go from 00 to 7F (surround is 80 - FF, but those are notes and commands).
Even without ties, you can change the volume mid-note if you put it between pitch bends (after $DD and before/after $EB), the note length command should last for as long as the pitch bend does ($XX + $YY arguments).
VOLUME CAN ONLY BE PUT AFTER A NOTE LENGTH COMMAND.

$00
This will stop the SFX.

$NoteLength $00 $AnyNote = Rest
Not an actual command, but a technique to simulate rests in older AddmusicK versions. What we are doing here is setting the volume to 00 for as long as the note lasts, then setting it back to normal when another note should play.




Examples

I will do some breakdowns of vanilla SMW sound effects here:
Legend: Instrument, Note Length, Volume, Pitch Bend ($EB), Extended Pitch Bend ($DD), Note, Misc

08 Springboard.txt
Code
$DA $05 				;we start by setting our instrument
$08 $54 				;we specify starting note length and volume
$DD $9F $00 $08 $A3 			;starting pitch bend
$12 					;note length, used by the next pitch bend
$EB $00 $12 $AB 			;pitch bend, this one keeps going up
$06 $3F 				;we use this to change volume mid-note
$EB $00 $06 $A8 			;this pitch bend and subsequent ones are used to do “vibrato”
$11 $31 				;we change volume mid-note again
$EB $00 $11 $AB 
$08 $23 				;and again
$EB $00 $08 $A8 
$0F $15 				;and again
$EB $00 $0C $AB

0D Get cape.txt
Code
$DA $03 				;we start by setting our instrument
$0C $15 $07  				;we specify starting note length and volume (panned to the left)
$DD $95 $00 $0C $A4 			;starting pitch bend, goes up
$06 					;note length, used by the next pitch bend
$EB $00 $06 $97 			;pitch bend, goes down
$0C $07 $1C 				;note length and volume (panned to the right)
$DD $99 $00 $0C $A8 			;note resets, pitch bend, goes even more up
$06 					;note length, used by the next pitch bend
$EB $00 $06 $9A 			;goes down
$0C $23 $0E 				;note length and volume (panned to the left)
$DD $9D $00 $0C $AD 			;note resets, pitch bend, goes even more up, and so on...
$06 					;the cycle continues and the pitch will go higher and higher...
$EB $00 $06 $9D 			;until the sfx ends
$0C $0E $31 
$DD $A1 $00 $0C $B0 
$06 
$EB $00 $06 $A0 
$0C $38 $15 
$DD $A5 $00 $0C $B4 
$06 
$EB $00 $06 $A3 
$0C $15 $3F 
$DD $A9 $00 $0C $B9 
$09 
$EB $00 $06 $AD

05 1-up.txt
Code
$DA $02 				;we set the instrument
$08 $59					;note length and volume
$B4 $B7 $C0 $BC $BE $0C $C3		;notes

07 Dry bones collapse.txt
Code
$DA $02 				;we set the instrument
$09 $1C $1C 				;note length and volume (whoever programmed this set it twice??)
$B0 					;note
$08 $19 $1F 				;note length and volume (panned to the right)
$AE 					;note
$07 $1F $19 				;note length and volume (panned to the left)
$AC 					;and so on, with each note going lower and stronger panning...
$06 $15 $23 
$AA 
$05 $23 $15 
$A8 
$04 $0E $2A 
$A6

21 Valley of Bowser appears.txt
This one is interesting because it’s a rumbling effect and it seems to be stopped by the game because the SFX repeats indefinitely.
Code
$DA $11  				;we set the instrument (thunder)
$0C $00 $54 				;we set the note length and panning
$8C 					;we play a note in a very low pitch
$08 $1C $0E 				;note length and panning
$8C 					;note
$0C $46 $38				;note length and panning
$8C 					;note
$12 $38 $54 				;note length and panning
$8D 					;another note
$0C $0E $1C 				;and so on...
$8B 
$12 $2A $1C 
$89 
$18 $1C $0E 
$8B 
$08 $0E $1C 
$8C 
$0C $1C $0E 
$89 
$06 $2A $15 
$8B
$08 $0E $1C 
$8C 
$30 $1C $1C 
$8B 
$FE					;this restarts the sfx forever

19 Clap + pop.txt
Code
$DA $0C 				;set instrument
$04 $46  				;note length and volume
$B5 					;note
$DA $9C $10 				;set noise and use instrument 10’s adsr values for it
$18 $2A  				;note length and volume
$C3					;note

definitively better than what amk's readme says. so cool to see a comprehensive basis for people to read and make sfx.

one thing, i think the game stops the "Valley of Bowser" SFX by playing the "Silence" SFX (which is the one that follows), i've done that on my wip dark mind boss.

Originally posted by Pinciano
The most important thing you need to know about how sound effects behave is that there is no tempo, no staccato, no ties, and no rests. With this, I’m referring to the fact that sound effects play at a fixed speed, [...]


in fact, sfx's tempo is t56 according to amk source code's operations, so amk plays sfx at 140 BPM.

Code
	mov   a, #$38  ;> ($38 in dec is 56)
	mul   ya
	clrc
	adc   a, $44
	mov   $44, a
	bcc   L_0573
	inc   $45

;>  the same operations are done for song, but that #$38 is mapped to variable ARAM adress which contains the song's tempo


o la wea bacan

Userbar by Green Jerry

Also a Fortaleza Reznor user. If you... digo, si hablas español, hackeas, buscas ayuda, o simplemente se te da conocer gente, únete, somos puerta abierta.
Originally posted by LMPuny
in fact, sfx's tempo is t56 according to amk source code's operations


updated, ty
I'd like to explain why ties and rests don't work in SFX. According to LMPuny in the SnesLab server:

Originally posted by LMPuny
amk forces a key-on when reading $80-$C7 on sfx's data ($80-$C5 are notes, $C6 is rest, $C7 is tie), and since the latter two don't modify pitch, the note repeats instead of resting/tie


He then shortly proceeded to make a fix for it. The 'main.asm' is here; however, it doesn't have KungFuFurby's slowdown tolerance code. You can either paste the latter code into this 'main.asm', or do the following in AMK 1.0.7's version:

1. Under the '.playNote' label, paste this code:
Code
	push	a


2. Under this line:
Code
	call	NoteVCMD		; Loooooooong routine that starts playing the note in A on channel (X/2).


Paste this:
Code
	pop	a	
	cmp	a, #$C6	
	bcs	.setNoteLength


3. In this code:
Code
	setp
	mov	!ChSFXNoteTimer+x, a	; / And since it was actually a length, store it.
	clrp


Uncomment the 'setp' and 'clrp' and change '!ChSFXNoteTimer+x' to '!ChSFXNoteTimer|$0100+x'.

4. Finally, under this code:
Code
	mov	a, #$02			; \	
	;setp				; |	
	cmp	a, !ChSFXNoteTimer|$0100+x	; |	
	;clrp				; |	
	bne	.return1		; | If the time between notes is 2 ticks


Paste this:
Code
	mov	a, (!ChSFXPtrs+x)	
	cmp	a, #$C6	
	beq	.return1


I felt the urge to let you all know this. In retrospect, this fix is actually very simple. Kudos to LMPuny!
My Mode 0 guide.

My Discord server. It has a lot of archived ASM stuff, so check that out!

I don't like LMPuny's tie implementation, mostly because it's actually very limited as it can't be interrupted by any other VCMDs in between. The problem is that the SFX code has no readahead and I don't think it would be wise for me to try to implement that because of memory consumption of the code (just to implement ties, I might add).

I do know how to emulate ties (note that critically, I have this set up in order to be able to use note lengths from 127-254 ticks: chaining $EB commands beyond this point can extend the note even further):
$VV ($WW) $DD $XX $00 $YY $XX ($ZZ) ($WW) $XX
$VV is the initial length of the note.
$WW, optional, is the volume.
$XX is the note to use.
$YY is the number of ticks to hold the note for.
$ZZ is the length to add on. If it's the same as $VV, you don't need this byte.
To do this properly, ideally $YY should be greater than $VV at the absolute least.

Your tutorial has a couple of errors:
  1. SFX does have staccato, but the duration of silence between notes is fixed: it's like as if !WaitTime was set to 2. I think no staccato can be done via using the emulated tie method above roughly speaking, except you use it so that the bend lasts until one tick before the next note.
  2. You swapped $FE and $FF by mistake. Also $FF rewinds three bytes (one byte in vanilla SMW). This bug affects 21 Valley of Bowser appears.txt.


And with regards to my AMK 1.0.9 release (a prerelease build as of the time of this post):
  1. Pitch bend delays were non-functional in AMK 1.0.8. I made then functional in AMK 1.0.9.
  2. I actually implemented rests. I didn't implement ties because that would have required readahead (unless we were to accept the limitations from LMPuny's implementation, which I decided to decline on), which in turn consumes memory to code. I know LMPuny implemented rests as well, but I didn't use the exact implementation partially because I passed on implementing ties, and partially because I took advantage of the !inRest variable that gets set after NoteVCMD.
  3. I made $FF actually repeat the last note indefinitely by having it recycle saved parameters. I also fixed 21 Valley of Bowser appears.txt, as it was using the wrong command (the correct command at the very end is supposed to be $FE.


UPDATE: As of 12/12/23, the errors have generally been corrected.

Custom Music