P2 FM audio synthesizer
pik33
Posts: 2,366
in Propeller 2
As I started the project, we went offtopic in the MicroDOS topic. Is it possible to move this FM synth discussion branch here?
Comments
Now I have a 16 channel 1-op FM
1-op FM?? Yes, it has a feedback the operator is self modulating, and it seems this is enough to make playing fun. The latency is as low as it can be and the feedback makes the sound to dynamically change and react to the keyboard velocity. Playing the self made synth is much more fun than any ready made VSTs . I made ADSR in the DX7 style with these 4 level/rate parameters, and the CORDIC generates the sine wave and converts ADSR from linear to logarythmic. I assigned my keyboard (Novation Impulse 61) sliders and knobs to ADSR and feedback parameters.
Now, this is still way too slow (230 clocks per channel/operator, need to be reduced to 40 (average) to make a 6-op things possible, but there is a lot to optimize in it. Also it now uses a PSRAM based video driver. It seems I can use my vng050 driver instead in a text mode so all this thing should be possible without any additional RAM.
gots a video of it? Maybe I will understand what you are talking about if I see it in action.
I will create a topic after adding a second operator. And this is the start of the MIDI controlled FM synthesizer project.
A music midi keyboard is connected to the P2. This keyboard (Novation Impulse 61) has 61 music keys, but also 9 sliders, 9 switches and 8 knobs. All of these elements when moved, send MIDI reports on the keyboard output. There are a lot of different MIDI controller keyboard in the market so I will have to somewhat parametrize the input channels, but it is not a proper time to do this yet.
One of P2 cogs runs the audio driver. It generates sine waves (16 channels) with a parametrized envelope. As this will be an FM synth, every generator has also a modulation input. The value from this input is added to the phase of the generated wave. Such a thing - a generator+envelope+modulation input is called an operator in the FM synthesis world. Normally there are more (2..8) operators in the channel and they are connected so one of them can modulate another. This gives a harmonic rich, dynamically changing sound (eg: Yamaha DX7 - the 90s consoles also uses FM, so there is a 4-operator FM generator in the NeoYume code)
The P2 receives messages from the MIDI keyboard via a MIDI breakout board, so using the sliders I can set ADSR and a feedback amount. A feedback in FM is when the output of one operator modulates its own generator. This makes the output to be no more a sine wave, and, the louder it is, the more distortions it gets. So, when I play this using the keyboard, if I press the key gently, the output is near a sine wave, but when I hit it hard, it is heavily distorted. Then, if I set a release rate to something slow so the soud doesn't disappear after the key is released, these distortions disappear too.
As there is no audio buffers in this settings, the driver responds immediately (1 sample delay=about 12 us+computation time in the main cog, several more us) to the key pressed, so the lag is as low as possible. The keyboard needs about a milisecond to send the "key on" report and this makes all the lag, so you hit the key, you hear the sound, while in a PC environment, you hit the key, PC has to generate a buffer full of samples, then you can hear the sound. You need a low-latency audio driver to make live playing possible on a PC.
There is a monitor attached to a P2, which displays the parameters. The real synth, if it works, may be enclosed in a case with a small, 5..7" LCD to do this and a PSRAM-less video driver to use a standard PSRAM-less Edge board. FM parameters sets (called in the audio synthesis world "patches") are small, so even a SD card is not needed. Thousands of such patches can be stored in the Edge's flash.
I don't know yet how many polyphony and operators I can get from one cog. Now I have 16 channels with one operator in them and 230 clocks for one channel. I want at least a 6-op synth, but now, even this 1-op with a feedback is fun. Now I have to: optimize this, add the next operator, repeat.
@pik33
This is very cool....I want it! DX7 is great for the old synth-pop
I currently use VSTs and I have tons of them.
Next project (for you ) : Piezo hex guitar pickup (plenty available) to convert to MIDI
Craig
Now, I have no guitar.... my granddaughter has a guitar but it is accoustic one.
Guitar pickup to MIDI.... fast workaround... is to use Sunvox. It is an modular synth/tracker and don't know what else, but it has a module that input the audio and output MIDI. Piezo... needs a preamp with a high resistance input...
@pik33 I watched this video to kind of understand what you are talking about... I think. Is this a good demonstration of what FM synthesis can do?
Yes, it is. But this thing is more classic:
I an now working at the optimizing and adding operators and now there is a hope I can do 16-voices 6-op DX7-style (not replica) in one cog. Not at 80 kHz sample rate where I started, but 50kHz seems to be possible - optimizing is the key there. This DX1 is 2x 6op/16 voices
There is also this free open source VST called Dexed
Dexed had been ported to a bare metal Raspberry and several microcontrollers, I thought about translate this to a P2 but it is C++ - too much for me, so I decided to write my own to learn how to use P2 CORDIC, which is a strange and powerful beast when used properly: no sine and log table any more, that thing can be faster than rdlong and is more precise than a table in the limited LUT memory. Then, while programming and testing this I am learning FM synthesis basics fast.
Sure thing!
Could you PM me with the post numbers you want moved into this thread ?
Edit: Merge complete!
Nice surgery M
That does sound really good. So does this little setup:
Were you going to write the sequencer too?
Maybe yes. I have to write the synth first and I still don't know how much can be done in one cog. Every iteration now is near a full rewriting the driver.
I hope I can manage to do this 16 voices polyphony and 6 operators in 1 cog. I also need a main cog, a display cog and an input cog. Maybe the input can be done in the display cog or in main cog to save one of them. These are 4 cogs. To have the sound richer (as in DX1 and DX5) 2 synths are needed: there is a place for 4 synths and sequencer/effect processor.
To make something like a TX816 I need 8 synths. A P2 has 8 cogs - then it needs a second P2 (or something else) to rule them all
I have to have a working synth to go further. 1 working operator is not enough.
First working 2-op, 16 voices thing.
Doesn't need any PSRAM. HDMI at 0, midi at 29, audio at 14,15.
Controllers defined at the start of the program, for a Novation Impulse keyboard I have. First 8 sliders sets R and L for operator's envelope (rates and levels, as in DX7, not scaled to DX7 compatibility at all). 9th slider sets the operator output level. 6 knobs (2 actually works) set the modulation level from Op #n. Buttons 1,2(..6) switches operators on and off, button 7 select the operator to edit, button 9 sets the keyboard sensitivity. Knob7 7,8 sets frequency (coarse, fine)
A pitch bender works
There is no algorithms there. Instead, every operator can be directed to the output mix at the given level, and modulate every operator including itself at the defined level.
Alpha, work in progress, all will change No preset saving yet.
Neat!
I have now to solve the preset saving problem: the video buffer is too long to add a file system. The program doesn't fit. That means the only option, if I don't limit the synth to a PSRAM environment, is using a flash. One preset (for 6-ops) is 384 bytes. so several thousands of them can fit in it.
Looks nice. Got a video? What frequency are you running your P2 at?
P2 is at my "standard" 336 MHz (set by the video driver). Now it looks even more nice... I moved to the PSRAM environment for the video driver. 1024x576 and free hub instead of 800x480 and only 130k available for the program. And the parameter count is now HUGE, they didn't fit in these small boxes. I needed to make them bigger.
I have to try if a 7" 1024x600 can work with this... I tried 1024x600, it is possible at slightly less than 50 Hz. A 7" 1024x600+i2c touch would be a nice thing for this project.
The program can save the parameters in the flash, but this needs to be rewritten from scratch.
The sampling frequency, while developing, is about 40 kHz, 8192 clocks. Sufficient to work, has a free place for non-optimal code. 280..290 clocks per voice at 2 operators, ~ 4700 clocks. I hope 6-op version can fit in 6400 clocks, giving over 50 kHz sample rate.
This thing needs rather audio than video to present. Now it looks like this but the driver is still 2 operators. A lot of variables... the code has been moved to LUT leaving a place for them in the COG RAM