Music with SFXR?

BlitzMax Forums/BlitzMax Programming/Music with SFXR?

zoqfotpik(Posted 2014) [#1]
Has anyone experimented with music using SFXR, either the excellent port by Brucey or some other port? Is there an established conversion rate between frequency and musical notes?


GW(Posted 2014) [#2]
I never could get Brucey's mod to compile. have you tried it?


zoqfotpik(Posted 2014) [#3]
Worked for me. I was ecstatic when I found it.


BlitzSupport(Posted 2014) [#4]
I've never actually seen a formula (probably hard to represent a musical note such as A# directly in a formula!), but there are plenty of tables of notes and their frequencies...

http://www.phy.mtu.edu/~suits/notefreqs.html
http://www.liutaiomottola.com/formulae/freqtab.htm


zoqfotpik(Posted 2014) [#5]
I bet it's possible to make a SID clone using SFXR. Looks like there are a bunch of possibilities among Brucey's modules, perhaps his Game Music Emulator port will be easier...


2 Unlimited(Posted 2014) [#6]
After I discovered FindSounds, I removed sfxr from my computer.


Derron(Posted 2014) [#7]
Glad "findsounds" finds 0 results for a "jump" sound.

Dunno what the site thinks about licences ... you wont like to get sued using others sound creations.

bye
Ron


Brucey(Posted 2014) [#8]
I bet it's possible to make a SID clone using SFXR.

There's already a SID decoder module, although at the moment it only works with libBASS - as one needs to write an audio driver to play the sounds it generates.


2 Unlimited(Posted 2014) [#9]
Actually, jumping doesn't produce a sound but your shoes hitting the floor do.


angros47(Posted 2014) [#10]
Commodore SID is a subtractive synthesizer: it features three envelope generators, with four waveforms (pulse, sawtooth, triangle, noise), envelope generators, three filters (lowpass, highpass, bandpass), ring modulation.

SFXR is also a subtractive synth, it just have only one voice, and doesn't have ring modulation (but has vibrato and tremolo): so, it's close to SID.


Derron(Posted 2014) [#11]
So in a jumpnrun you play different sounds according to the ground the figure is standing on?

Next time you will tell me, that the player shouldnt eat mushrooms taller than a head. Or that snails cannot jump (same for some other animals).

Seriously: I think you know what sounds I mean... "swooshes" etc. But people wont search for "English sounds" (in German we would pronounce it differently - eg "Plöpp" when jumping on the head of an enemy creature).

Without proper tagging such sound searching engines lose really much of their potential.


bye
Ron


zoqfotpik(Posted 2014) [#12]
I think sites like that are great. I do own a huge multi-DVD collection of sounds from the advertising industry.

But what I'm interested in is not digitized sounds but writing a system to produce music in a similar way to the C64 so that I can have procedurally generated music in a game I'm writing.


angros47(Posted 2014) [#13]
Have you considered using Midi to procedurally generate music? It would be easier to build music note-by-note than sample-by-sample.

Or, you could try fm-synthesis: have you ever tried adlibemu.c (it should not be hard to integrate it in a BlitzMax program)? It emulates the OPL2 chip used in old SoundBlaster, that had a nice sound.


AdamStrange(Posted 2014) [#14]
Here's some real nice code for you.
it's the frequency tables of all notes :)

just copy/paste. any problems let me know :)


'this is the sample frequency data in octaves (12 notes per octave, 9 octaves)

#SampleNoteData
DefData 16.35, 17.32, 18.35, 19.45, 20.60, 21.83, 23.12, 24.50, 25.96, 27.50, 29.14, 30.87
DefData 32.70, 34.65, 36.71, 38.89, 41.20, 43.65, 46.25, 49.00, 51.91, 55.00, 58.27, 61.74
DefData 65.41, 69.30, 73.42, 77.78, 82.41, 87.31, 92.50, 98.00, 103.8, 110.0, 116.5, 123.5
DefData 130.8, 138.6, 146.8, 155.6, 164.8, 174.6, 185.0, 196.0, 207.7, 220.0, 233.1, 246.9
DefData 261.6, 277.2, 293.7, 311.1, 329.6, 349.2, 370.0, 392.0, 415.3, 440.0, 466.2, 493.9
DefData 523.3, 554.4, 587.3, 622.3, 659.3, 698.5, 740.0, 784.0, 830.6, 880.0, 932.3, 987.8
DefData 1047, 1109, 1175, 1245, 1319, 1397, 1480, 1568, 1661, 1760, 1865, 1976
DefData 2093, 2217, 2349, 2489, 2637, 2794, 2960, 3136, 3322, 3520, 3729, 3951
DefData 4186, 4435, 4699, 4978, 5274, 5588, 5920, 6272, 6645, 7040, 7459, 7902

'initialise the data with a call to SetupNotes()
'rate=SampleNotes[octave,note] 
'the notes go up to 17 so you can use an octave and 5 more notes on top
Global SampleNotes:Float[9,17]

'rate=SamplePureNotes[flat note number 0 to 108]
Global SamplePureNotes:Float[109]

function SetupNotes()
Local k:Int
Local j:Int
Local freq:Float
Local count:Int = 0

RestoreData SampleNoteData
For k = 0 To 8
For j = 0 To 11
ReadData freq
SampleNotes[k,j] = freq/220
If j < 5 SampleNotes[k,j+12] = freq/110
SamplePureNotes[count] = freq/220
count = count + 1
Next
Next	
end function



zoqfotpik(Posted 2014) [#15]
Wow that's just what I was looking for :)

Angros I am probably going to write a step sequencer.


AdamStrange(Posted 2014) [#16]
Let me know if you need any help with the sequencer. I've got 2 versions here.


zoqfotpik(Posted 2014) [#17]
I'd be very interested in what you have, yes. I always end up writing stuff on my own (AKA "reinventing the wheel) but I like looking at other peoples' code.


AdamStrange(Posted 2014) [#18]
The first version is basically an 8 track sequencer using standard blitzmax sound controls (called Wave and abandoned)

The second (Wave2) takes the concept and recodes everything from scratch including the core blitzmax audio system (to allow for precise synth control over sounds plus additional effects)
there's more information:
sequencer
http://www.blitzbasic.com/Community/posts.php?topic=100837#1193758
overview
http://www.blitzbasic.com/Community/posts.php?topic=99682#1175376
website
http://www.blitzbasic.com/Community/posts.php?topic=101153#1199752


zoqfotpik(Posted 2014) [#19]
Geez, wtf? You did that? It looks like a beta version of a professional DAW.

What I would like to do is make some sort of small, stripped down parametric synth of some sort, like SFXR but but with the samples modifiable realtime or at the very least generated at runtime from parameter sets. Once I have something I will release it to the community.

I like how on post #3 they immediately start harping on your site photo quality and say nothing about the synth. Oh, programmers...


AdamStrange(Posted 2014) [#20]
yup, can't please everyone.

here's the soundcloud - everything was done with wave2, no overdubs, no additional effects...

OK. Parametric is not as straightforward as you will need to be constructing waveforms.

Internally BlitzMax operates in 16bit stereo or mono waveforms (sample). Each channel does the actual playing.

In theory (off the top of my head) Blitz supports 4096 simultaneous channels. In practice it is actually a single stereo sample with some complex mixing to produce the mixed sample channels.

This is a good place to start with creating waveforms (on the fly)
http://www.blitzbasic.com/Community/posts.php?topic=95529#1100844


I can provide you with info about directly accessing the sample buffer - it's quite simple :)
In essence you create a looped sample, then just write directly to it while playing!

I'm on a mac (am assuming you'r on a pc)?


angros47(Posted 2014) [#21]
There are many ways to build a software synth.

The first step is to generate a sine waveform:

W=sin(t)

And send it to the sound card. By setting the frequency, you can set the note.

A note is defined by four aspects: pitch (the frequency) , volume, timbre, duration.

Of course, when you can generate a sound frequency, setting pitch, volume and duration is trivial; the hard part is to define the timbre, and there are many ways to do that; the timbre is the waveform.

As Fourier demonstrated, all possible forms of a wave can be created by the sum of many sinusal wave that are multiple to the base frequency (they are called "harmonics"); so you could just make a waveform that is the sum of many sine functions:

W=sin(a*t)+sin(b*2*t)+sin(c*3*t)....

This is called "additive synthesis". Too complicate? Ok, there is an alternative: if you sum ALL possible harmonics:

W=sin(t)+1/2*sin(2*t)+1/3*sin(3*t)....

You will get a waveform that approximates a sawtooth wave; if you sum only odd harmonics, you will get a square wave. These functions are really easy to implement (a sawtooth can be achieved with Mod operator, a square can be achieved with Mod and If); then, you will have a wave that contains all the harmonics, and you could just remove the ones you don't want, by using a function called "filter"

A filter can remove only higher frequencies (lowpass), or only lower frequencies (highpass): the simple way to remove a frequency is to calculate the weighted mean of current and previous value:

cut=.5
W=OldW*cut+Waveform*(1-cut)
OldW=W

An higher value of "cut" will make the filter remove more frequencies (the value of the wave is more affected by the old value, so it requires more time to change... and higher frequencies impulses don't last enough to affect the result); you can use this formula to build a "lowpass" function.

How to build an highpass filter? The above formula cannot be use to remove low frequencies while keeping higher ones; but you still have the original wave, unfiltered: if you filter it and get a wave with only low frequencies, the difference is a wave with high frequencies!

W=W-lowpass (W)

Hope this help.


zoqfotpik(Posted 2014) [#22]
Wow, you two have a lot of knowledge.

Adam, the soundcloud link was not linked. Also I have a PC. by parametric synth I am not using it in any specific way, like additive synthesis-- I just mean something that can modify parameters of the sound while it is playing, so yes a little more complicated, and yes we have to modify the waveform while it is playing.

Angros that was a great primer on synthesis. Tell me this-- we could also do granular synthesis fairly easily, right?

Just so you know, I am learning about this for a game I am working on where many or most of the assets will be generated procedurally in some way including music and sounds.


zoqfotpik(Posted 2014) [#23]
Wow, you two have a lot of knowledge.

Adam, the soundcloud link was not linked. Also I have a PC. by parametric synth I am not using it in any specific way, like additive synthesis-- I just mean something that can modify parameters of the sound while it is playing, so yes a little more complicated, and yes we have to modify the waveform while it is playing.

Angros that was a great primer on synthesis. Tell me this-- we could also do granular synthesis fairly easily, right?

Just so you know, I am learning about this for a game I am working on where many or most of the assets will be generated procedurally in some way including music and sounds.


AdamStrange(Posted 2014) [#24]
Sorry about that. here's the soundcloud link
https://soundcloud.com/mavryck-james

Wave2 does full harmonic synthesis exactly the same way the fair lights did it by breaking down the sample into parts and creating a waveform for each part. I was surprised that the system is powerful to do all this realtime.

OK. Granular synthesis is playing many tiny looped parts of a sample at the same time. you fadein/out each tiny looped part to smooth out the result - or it will click. BlitzMax can't do that, but you could write a new audio core to do it, but it's not a simple task. It would be better to take a sample and resynthesises a new one using granular techniques.

Some things are simple, some are not.

Blitz is powerful enough to allow control of pitch, volume, pan per sample. so a simple sequencer is not too hard.


angros47(Posted 2014) [#25]
You could do granular synthesis, but you need grains data (granular synthesis is based of "grains" of sampled sound).

Another approach I like is modulation: there is amplitude modulation, or frequency modulation; formula is

Modulator=sin(a*t)
W=sin(b*t)*Modulator

for amplitude modulation, and:

Modulator=sin(a*t)
W=sin(b*t+Modulator)

for frequency modulation.

Frequency modulation (FM synthesis) was used on many synthesizer, and on earlier sound cards (Adlib, Sound Blaster): it can produce almost all timbres, it's computationally light, and you don't have too much parameters to set; the drawback is that producing the sound you have in mind is hard: maybe you have a sound that is close to what you wanted, you slightly change a parameter, and the sound becomes completely different.


BlitzSupport(Posted 2014) [#26]
Do read the thread Adam linked to, if you haven't already, as even I understood how the basics worked from Taron's code at the top!


zoqfotpik(Posted 2014) [#27]
Holy shit! AdamStrange that's impressive in the extreme, it sounds amazing!

BlitzSupport yes now I remember seeing Taron's sequencer, I remember thinking it was strange that he was using GL quads. Maybe it's faster? I guess that's a potentially huge number of draws.


AdamStrange(Posted 2014) [#28]
thanks :)
Yep Wave2 is a very powerful beast, but also expressive.
the second track "awaken" has a random buzzing sound that is a form of granular synthesis. It also uses a large number of voices with slow envelopes to shape the sounds.

You could think of wave as 32 fairlight Series 3's. or 1024 single voice samplers. or 1024 voice soudtracker (you can view and edit in soundtrack mode if you really want). The song structure allows for voices to be individually muted, changed in volume, so a single pattern can be used many times each sounding completely different.

I should add that the UI is all custom too. it uses maxgui for the initial window and canvas, then everything else is custom.

Wave2 is also a full sample editor, you can cut, edit, change volume, fade sections, mangle, etc both mono and stereo sample, also there are a lot of conversion options. So I can help there too :)


zoqfotpik(Posted 2014) [#29]
How processor intensive is simple real time synthesis? It doesn't seem like it should be much of a problem at all since it just uses the Blitzmax sound routines while modifying the sample real time (with a sin call of all things.)


AdamStrange(Posted 2014) [#30]
I wouldn't have thought too much.

You would have to watch how you called the routine though as realtime audio will click or stutter if timing is affected. It's the main reason I modified/rewrote the sound subsystem to support the features I needed.

My concern would be that for multiple channels you might start to get a bigger cpu hit (and then stuttering). Whereas playing samples has virtually no hit.


angros47(Posted 2015) [#31]
I wrote a set of routines to achieve real time synthesis; they are in FreeBasic, but porting them to BlitzMax should not be hard (or you could just compile as a library in FreeBasic and use them in BlitzMax):

http://www.freebasic.net/forum/viewtopic.php?f=8&t=23127