nesdev.com
http://forums.nesdev.com/

FM synth BRR sample generator
http://forums.nesdev.com/viewtopic.php?f=12&t=14727
Page 1 of 5

Author:  psycopathicteen [ Mon Aug 22, 2016 4:31 pm ]
Post subject:  FM synth BRR sample generator

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:
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.

Author:  psycopathicteen [ Tue Aug 23, 2016 12:32 pm ]
Post subject:  Re: FM synth BRR sample generator

I guess most people here don't like FM synth, and those that do only like FM with at least 4 operators.

Author:  Espozo [ Tue Aug 23, 2016 12:44 pm ]
Post subject:  Re: FM synth BRR sample generator

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?

Author:  Ramsis [ Tue Aug 23, 2016 1:18 pm ]
Post subject:  Re: FM synth BRR sample generator

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! :)

Author:  psycopathicteen [ Tue Aug 23, 2016 3:24 pm ]
Post subject:  Re: FM synth BRR sample generator

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 103 times

Author:  Espozo [ Tue Aug 23, 2016 3:40 pm ]
Post subject:  Re: FM synth BRR sample generator

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:

Quote:
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.

Author:  psycopathicteen [ Tue Aug 23, 2016 4:18 pm ]
Post subject:  Re: FM synth BRR sample generator

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

Code:
+---      +
|   \     |
|    \    |
|     \   |
+      ---+


...and also an LFO modulating the modulator's amplitude.

Attachments:
Alisha's Adventure with FM synth (2).zip [86.05 KiB]
Downloaded 72 times

Author:  ccovell [ Tue Aug 23, 2016 4:27 pm ]
Post subject:  Re: FM synth BRR sample generator

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.

Author:  psycopathicteen [ Tue Aug 23, 2016 7:44 pm ]
Post subject:  Re: FM synth BRR sample generator

I should also double buffer the FM waveform to have smoother wave transistions.

Author:  Stef [ Wed Aug 24, 2016 1:38 am ]
Post subject:  Re: FM synth BRR sample generator

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).

Author:  psycopathicteen [ Wed Aug 24, 2016 2:59 pm ]
Post subject:  Re: FM synth BRR sample generator

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 83 times

Author:  Bregalad [ Thu Aug 25, 2016 4:24 am ]
Post subject:  Re: FM synth BRR sample generator

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.

Quote:
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.

Author:  ikari_01 [ Thu Aug 25, 2016 5:01 am ]
Post subject:  Re: FM synth BRR sample generator

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...

Author:  Bregalad [ Thu Aug 25, 2016 11:16 am ]
Post subject:  Re: FM synth BRR sample generator

ikari_01 wrote:
Btw the S-SMP has pitch modulation which can be cascaded if I'm correct.

You are correct.

Quote:
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.

Author:  rainwarrior [ Thu Aug 25, 2016 11:41 am ]
Post subject:  Re: FM synth BRR sample generator

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.

Page 1 of 5 All times are UTC - 7 hours
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/