FM synth BRR sample generator

Discussion of hardware and software development for Super NES and Super Famicom. See the SNESdev wiki for more information.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
psycopathicteen
Posts: 3140
Joined: Wed May 19, 2010 6:12 pm

FM synth BRR sample generator

Post by psycopathicteen »

I felt like writing a spc700 code to generate a 2 operator FM wave sample. To keep the spc700 time down, it's not going to render every single sample. Instead it's going to generate a single cycle waveform that gets updated every frame. I'm not sure how many channels it can do per frame, but if it can't do enough, you can lower the frame rate.

This code is supposed to generate a 64 sample loop. Carrier volume is not calculated, because it can be handled in hardware by the DSP.

Code: Select all

fm_synth:                                  //this uses bass.exe as the assembler
lda #$82
sta {brr_buffer}
sta {brr_buffer}+9
sta {brr_buffer}+18                      //BRR samples need a header byte every 9th byte
inc
sta {brr_buffer}+27                      //first 3 BRR blocks have a header byte of $82 (range = 8, filter = 0, loop flag set)
ldx #$00                                     //last block has a header byte of $83 (same as above, but with end flag set)
str {#_of_blocks}=#$04               //4 blocks of 16 samples = 64 samples

-;
inx
str {countdown}=#$08                 //8 pairs of samples per block
-;
clc
adc {modulator_phase}={modulator_frequency}      //add modulator frequency to phase
ldy {modulator_phase}
lda sine_table,y                                                  //use modulator phase to index an 8-bit sine wave
ldy {modulator_amplitude}                                  //with a range from 0 to 255
mul                                                                 //multiply the sine wave (A) with amplitude (Y) to get the modulation height (Y)
clc                                                                   //I believe SPC700 uses unsigned multiply.  I'll fix it if I'm wrong
adc {carrier_phase}={carrier_frequency}              //add carrier frequency to carrier phase
tya
clc
adc {carrier_phase}                                           //take the carrier phase and add the current modulation height
tay
lda waveform,y                                                 //use that to get the final 4-bit sample
sta {temp}

clc
adc {modulator_phase}={modulator_frequency}      //do it all again for another sample
ldy {modulator_phase}
lda sine_table,y
ldy {modulator_amplitude}
mul
clc
adc {modulator_phase}={modulator_frequency}
tya
clc
adc {carrier_phase}
tay
lda {temp}
xcn                                                                //this time, grab the previous sample, and swap nibbles
ora waveform,y                                               //OR it with the new sample, to have 2 samples in 1 byte
sta {brr_buffer},x                                            //save the result

inx
dec {countdown}
bne -
dec {#_of_blocks}
bne --
rts
Did some cycle counting. Only ~54 cycles per sample. Fast enough to generate 4 channels at once, with 64 samples per waveform.
Last edited by psycopathicteen on Tue Aug 23, 2016 3:55 pm, edited 4 times in total.
psycopathicteen
Posts: 3140
Joined: Wed May 19, 2010 6:12 pm

Re: FM synth BRR sample generator

Post by psycopathicteen »

I guess most people here don't like FM synth, and those that do only like FM with at least 4 operators.
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: FM synth BRR sample generator

Post by Drew Sebastino »

To be honest, I really don't know what FM, or operators, even are. Isn't it just that the sound signal is generated by a mathematical equation, kind of like a graphing calculator or something?
User avatar
Ramsis
Posts: 341
Joined: Sun Jul 01, 2012 6:44 am
Location: Lion's den :3
Contact:

Re: FM synth BRR sample generator

Post by Ramsis »

Dear Andy, once again, do you really, honestly expect people to actively become acquainted with random ideas/code snippets of yours that have literally zero comments, let alone there not being a demo ROM of some sorts to show off what you've come up with?

BTW, I'm not meaning to troll you. On the contrary, personally I respect you as one of the most skilled SNES programmers in this day and age, and I very much appreciate your work. :) However, I fear your accomplishments may forever go unnoticed, and unappreciated, should you choose to continue presenting them in a way that, every time, feels not like an enlightenment to everyone else (as was probably intended), but rather like a huge dragon turd. ("Here's proof that dragons exist, people! Who wants to dig in?" -- "Dragons? Yay! Dig in? Err ...")

So, please give us some more information. What SPC700 assembler is your code meant to be for? What do all those curly brackets stand for? What does mul, or xcn do? And so on and so on ...

Thanks! :)
Some of my projects:
Furry RPG!
Unofficial SNES PowerPak firmware
(See my GitHub profile for more)
psycopathicteen
Posts: 3140
Joined: Wed May 19, 2010 6:12 pm

Re: FM synth BRR sample generator

Post by psycopathicteen »

So here's how Alisha's Adventure sounds like with an FM synth main instrument, with these settings:

carrier frequency = #$04
modulation frequency = #$08
modulation amplitude = #$FF

Not too interesting though. I tried sliding the modulation amplitude and frequency up and down, neither sounded interesting enough to post. Maybe if I had a 3rd oscillator, I could do more interesting timbre changes.
Attachments
Alisha's Adventure with FM synth.zip
(86.05 KiB) Downloaded 298 times
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: FM synth BRR sample generator

Post by Drew Sebastino »

Ramsis wrote:become acquainted with random ideas/code snippets of yours that have literally zero comments, let alone there not being a demo ROM of some sorts to show off what you've come up with?
Hmm... :lol:
Maybe faster way of ordering object palettes
psycopathicteen wrote:Did some cycle counting. Only ~54 cycles per sample. Fast enough to generate 4 channels at once, with 64 samples per waveform.
:)

I downloaded the rom, and regarding the music, I like the main chime sound effect, but I'm not as crazy about the background instrument. I'm probably have the opposite opinion as most people when I say I like more "gritty" sounding FM. https://www.youtube.com/watch?v=rlmbkKtjfSc, https://www.youtube.com/watch v=fPdVe183EVQ&list=PLCE893C44A08A961D&index=10

Man though, you've come a long way... It's really impressive considering it was made by a one man production team. I especially like level 2.
psycopathicteen
Posts: 3140
Joined: Wed May 19, 2010 6:12 pm

Re: FM synth BRR sample generator

Post by psycopathicteen »

This time I changed the carrier wave from a triangle, to a half-triangle half-square wave.

Code: Select all

+---      +
|   \     |
|    \    |
|     \   |
+      ---+
...and also an LFO modulating the modulator's amplitude.
Attachments
Alisha's Adventure with FM synth (2).zip
(86.05 KiB) Downloaded 249 times
ccovell
Posts: 1045
Joined: Sun Mar 19, 2006 9:44 pm
Location: Japan
Contact:

Re: FM synth BRR sample generator

Post by ccovell »

I love FM. How about a simple 1-channel FM demo with slowly changing operators so we can hear what's going on?

Right now, your in-game music sounds a bit too dissonant and hyper for me to appreciate your technical innovation.
psycopathicteen
Posts: 3140
Joined: Wed May 19, 2010 6:12 pm

Re: FM synth BRR sample generator

Post by psycopathicteen »

I should also double buffer the FM waveform to have smoother wave transistions.
Stef
Posts: 263
Joined: Mon Jul 01, 2013 11:25 am

Re: FM synth BRR sample generator

Post by Stef »

Thanks for the demo rom, honestly i think that is totally crazy that you're doing live FM synthesis on the SPC700 ;)
And the result is definitely quite good ! Being limited to 2 op will limit the sound varieties but still that is a nice achievement.
If i understand correctly currently you're limited to a 64 samples generated loop per frame, also it seems you're updating the modulator amplitude only once per frame (or even not at all) ?
Maybe you could setup a sound engine having 6 PCM channels + 2 FM channels (4+4 would be probably too heavy for the SPC700).
psycopathicteen
Posts: 3140
Joined: Wed May 19, 2010 6:12 pm

Re: FM synth BRR sample generator

Post by psycopathicteen »

Today I implemented double buffering and the modulator amplitude sweeps are a whole lot clearer.
Attachments
Alisha's Adventure with FM synth (3).zip
(86.07 KiB) Downloaded 265 times
User avatar
Bregalad
Posts: 8055
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Re: FM synth BRR sample generator

Post by Bregalad »

I like the concept, however I ask myself, what is the advantage of calculating this in runtime and not simply pre-render the waveforms you're going to use ? One of the disadvantage of runtime computation is not only the CPU time, but also the fact you're bound to using only filter #0 and as such the result is lower quality (just 4-bit PCM basically). Perhaps you should use filer #1 instead, and considering each sample to be the delta from the previous one (which is a good approximation), and since the derivate of a sine is a cosine, the concept would still apply ?

And to be honest, the example probably do not show the limit of what is possible to do.
I guess most people here don't like FM synth, and those that do only like FM with at least 4 operators.
I used to really dislike the concept of FM synth, but I changed my mind. Used well it can be amazing, however yes, 4 operators are pretty much a must to sound good. 2 operators remembers me the terrible sound of my OPL-3 soundblaster MIDI card when I was a kid - which is one of the rare things about old computers I am not nostalgic about so much it sucked.

I do not know if any 3-operator FM synth exist, but if not, you could always create one and it'd be a good compromise between sound quality and fast processing.
User avatar
ikari_01
Posts: 141
Joined: Sat Jul 04, 2009 2:28 pm
Location: Wunstorf, Germany

Re: FM synth BRR sample generator

Post by ikari_01 »

Btw the S-SMP has pitch modulation which can be cascaded if I'm correct. (Use ch0 amplitude as pitch control for ch1, use ch1 amplitude as pitch control for ch2, etc). I wonder if that can be used for some sort of FM synthesis. However the number of channels would be very low (4x2op or 2x4op, e.g.) and the op configuration ("algorithm") would always be the same...
User avatar
Bregalad
Posts: 8055
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Re: FM synth BRR sample generator

Post by Bregalad »

ikari_01 wrote:Btw the S-SMP has pitch modulation which can be cascaded if I'm correct.
You are correct.
I wonder if that can be used for some sort of FM synthesis.
I wonder too. I guess if you are playing same waves it's basically the same thing BUT the phase is not the same between channels, and also the pitch is bounded so you cannot use modulators out of audio range just to get nice effects on lower frequencies.
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: FM synth BRR sample generator

Post by rainwarrior »

What's commonly called FM synthesis is actually phase modulation and not frequency modulation.

There's a mathematical proof that they're equivalent under ideal conditions, but there's a very good reason that the practical implementations are all phase modulation. Unless you can modulate frequency in a perfectly symmetrical way, it's just not stable. You'll have a constantly shifting timbre, lots of strange sidebands.
Post Reply