SFXR - pure GLBasic code

Previous topic - Next topic

Kitty Hello


I wrapped the SFXR from Dr.Petter now.

The "README.txt"
Code (glbasic) Select

+++ SFXR port for GLBasic +++

V1.0 - added generator buttons

This file features a quick port of the famous "SFXR" program by DrPetter.
I'm not streaming the data to the sound card, but rather write a temp file and read that.

I included the Flash version of the program (as3sfxr.mht) which you can also find on:
It can copy/paste settings strings to the clipboard. You can use these strings in the one any only call:

   SFXR(data$, filename$)

to generate a .wav file that you later on can read with LOADSOUND.

The data$ is a comma seperated list of these values, in this order:
waveType%          [ 0] Shape of the wave (0:square, 1:saw, 2:sin or 3:noise)
attackTime         [ 1] Length of the volume envelope attack (0 to 1)
sustainTime        [ 2] Length of the volume envelope sustain (0 to 1)
sustainPunch       [ 3] Tilts the sustain envelope for more 'pop' (0 to 1)
decayTime          [ 4] Length of the volume envelope decay (yes, I know it's called release) (0 to 1)
startFrequency     [ 5] Base note of the sound (0 to 1)
minFrequency       [ 6] If sliding, the sound will stop at this frequency, to prevent really low notes (0 to 1)
slide              [ 7] Slides the note up or down (-1 to 1)
deltaSlide         [ 8] Accelerates the slide (-1 to 1)
vibratoDepth       [ 9] Strength of the vibrato effect (0 to 1)
vibratoSpeed       [10] Speed of the vibrato effect (i.e. frequency) (0 to 1)
changeAmount       [11] Shift in note, either up or down (-1 to 1)
changeSpeed        [12] How fast the note shift happens (only happens once) (0 to 1)
squareDuty         [13] Controls the ratio between the up and down states of the square wave, changing the tibre (0 to 1)
dutySweep          [14] Sweeps the duty up or down (-1 to 1)
repeatSpeed        [15] Speed of the note repeating - certain variables are reset each time (0 to 1)
phaserOffset       [16] Offsets a second copy of the wave by a small phase, changing the tibre (-1 to 1)
phaserSweep        [17] Sweeps the phase up or down (-1 to 1)
lpFilterCutoff     [18] Frequency at which the low-pass filter starts attenuating higher frequencies (0 to 1)
lpFilterCutoffSweep[19] Sweeps the low-pass cutoff up or down (-1 to 1)
lpFilterResonance  [20] Changes the attenuation rate for the low-pass filter, changing the timbre (0 to 1)
hpFilterCutoff     [21] Frequency at which the high-pass filter starts attenuating lower frequencies (0 to 1)
hpFilterCutoffSweep[22] Sweeps the high-pass cutoff up or down (-1 to 1)

Up to you is to write a GUI (DDgui) for that thing now :P


26-aug-2010 www.glbasic.com

and the project:


Nice. I see it's gained a GUI since earlier today :)

I've put together some code to open .sfs files that have been saved from SFXR, but I've no idea how to implement a save/load function with the GUI at the moment. So here's the loading code, maybe someone wants to tidy it up and integrate it.

Code (glbasic) Select
FUNCTION loadSFXR$: filename$
LOCAL data$, data1$, data2$, data3$, data4$, dataAll$
LOCAL version%, waveType%, masterVolume, startFrequency, minFrequency, slide, deltaSlide
LOCAL squareDuty, dutySweep, vibratoDepth, vibratoSpeed, unusedVibratoDelay
LOCAL attackTime, sustainTime, decayTime, sustainPunch, unusedFilterOn%
LOCAL lpFilterResonance, lpFilterCutoff, lpFilterCutoffSweep, hpFilterCutoff, hpFilterCutoffSweep
LOCAL phaserOffset, phaserSweep, repeatSpeed, changeSpeed, changeAmount

READLONG 1, version%
READLONG 1, waveType%
READSHORTIEEE 1, masterVolume
READSHORTIEEE 1, startFrequency
READSHORTIEEE 1, minFrequency

READSHORTIEEE 1, vibratoDepth
READSHORTIEEE 1, vibratoSpeed
READSHORTIEEE 1, unusedVibratoDelay

READSHORTIEEE 1, sustainTime
READSHORTIEEE 1, sustainPunch
READBYTE 1, unusedFilterOn%

READSHORTIEEE 1, lpFilterResonance
READSHORTIEEE 1, lpFilterCutoff
READSHORTIEEE 1, lpFilterCutoffSweep
READSHORTIEEE 1, hpFilterCutoff
READSHORTIEEE 1, hpFilterCutoffSweep

READSHORTIEEE 1, phaserOffset
READSHORTIEEE 1, phaserSweep
READSHORTIEEE 1, repeatSpeed
READSHORTIEEE 1, changeSpeed
READSHORTIEEE 1, changeAmount

data$ = waveType% + "," + attackTime + "," + sustainTime + "," + sustainPunch + "," + decayTime
data1$= startFrequency + "," + minFrequency + "," + slide + "," + deltaSlide
data2$= vibratoDepth + "," + vibratoSpeed + "," + changeAmount + "," + changeSpeed + "," + squareDuty
data3$= dutySweep + "," + repeatSpeed + "," + phaserOffset + "," + phaserSweep + "," + lpFilterCutoff
data4$= lpFilterCutoffSweep + "," + lpFilterResonance + "," + hpFilterCutoff + "," + hpFilterCutoffSweep

dataAll$ = data$ + "," + data1$ + "," + data2$ + "," + data3$ + "," + data4$

RETURN dataAll$

You can put it at the end of SFXR.gbas and call it as follows: LOCAL SFXRdata$ = loadSFXR$("sample.sfs")
After that you can use: SFXR(SFXRdata$, "wavefile.wav")
To generate the WAV file


Maybe needed:

- Extand it to make "savefiles" for a sound, that you can load in! ( so you can tweek it a bit later )
- SaveWavAs! ;)

Can help if you want, i like the idea to make sounds with GLBasic :D <3
Never search the net for cool gamesounds... now i can do it by my own :D  :good:
I <3 DGArray's :D

AMD Ryzen 7 3800X 16@4.5GHz, 16GB Corsair Vengeance LPX DDR4-3200 RAM, ASUS Dual GeForce RTX™ 3060 OC Edition 12GB GDDR6, Windows 11 Pro 64Bit, MSi Tomahawk B350 Mainboard


Kitty Hello


I've implemented a Load SFS button that gives you a file dialog to open an SFS file. There's no error checking, so if you open something that isn't a valid file, I'm guessing it will all go horribly wrong!

Next step is to add saving of SFS and a dialog for saving WAV files.

However I'm supposed to be 'working' so I don't know if I'll get a chance to do that during the day. If not, I'll carry on with it this evening.


next think i'd like to see added is able to use a function call in progam to to play the sound from inside setting the varuables to generate the soiund live.. as opposed to reading in .wav etc..

Code (glbasic) Select

CreatePlaySFX(waveType%, attackTime, sustainTime, sustainPunch, decayTime, startFrequency, minFrequency, slide, deltaSlide, vibratoDepth, vibratoSpeed, changeAmount, changeSpeed, squareDuty, dutySweep, repeatSpeed, phaserOffset, phaserSweep, lpFilterCutoff, lpFilterCutoffSweep, lpFilterResonance, hpFilterCutoff, hpFilterCutoffSweep)

Straight from in my game program
this way i can have sinfle file and also maybe even able to convert some old code from my C64 ;)


Today I started designing a gui that i think is worthy for sfxr, but i see that there is already a ddgui one.
Do you guys think I should finish this one ?

[attachment deleted by admin]
"Sugar makes the world go 'round. Caffeine makes it spin faster."


I'd say continue it.. I'd also like to be able to input values directly or use the slider gadgets to change their values (if you add inputing the values please remember to check that they are within the min/max ranges)


Ketil - Looks very C64'ish, and that's a good thing :) I'd also love the ability to play sounds without having to create the WAV file first, but I guess that'll mean some upgrades to GLB in order to create sound files in memory rather than having to read them from disk. You'd also need a way of freeing that memory block afterwards, otherwise you could rapidly use up vast amounts of RAM. Guess that's no different from the current setup where you read the WAV files in though.

But with playing from RAM, you could have DATA statements for each sound effect, removing the need to distribute WAV files.

Kitty Hello

I know. But playing from RAM is very complicated, especially on iPhone platform. I'll see if I can find a way, though.

The C64 interface looks very nice.

New update will have PLATFORMINFO$("TEMP") for the temp directory at least.


Quote from: Kitty Hello on 2010-Aug-27
I know. But playing from RAM is very complicated, especially on iPhone platform. I'll see if I can find a way, though.

It doesn't have to be an either/or situation. The current system of loading WAV files can remain, you just have an extra set of commands available for creating them direct in RAM. If it created a handle in the same way that loading a WAV does, then the play back code doesn't need to change either.


Quote from: Bursar on 2010-Aug-27
Ketil - Looks very C64'ish, and that's a good thing :)

It is actually made from the original C64 charset, and the sfxr is IFLI font from a demo we made in 1991 (http://noname.c64.org/csdb/release/download.php?id=38642).
The colorscheme is from WinVICE-2.2 (c64 emulator)  =D

I am also thinking about adding a box for note-values so it's possible to tune (at least the start of ) the FX to the same note/key/scale as the background music. 
I think that will sound better.
"Sugar makes the world go 'round. Caffeine makes it spin faster."

Kitty Hello

If you ported the code for Coin/pickup/Explosion and such, please GIMME! :D


No. I have not ported that code, but I'll look into it.
By a quick look at the original gui, I think the "generator concept" is just locking of some parameters while others are randomized within a predefined range.
This could easily be done without touching the synth-code.
"Sugar makes the world go 'round. Caffeine makes it spin faster."