A DX7 (Fm synthesis) replacement with Dexed on a Teensy

C0d3man

Well-known member
Hi all,

I started to port the a DX7 simulation named Dexed towards the Teensy. I already ported the code from JUCE to LV2 (https://github.com/dcoredump/dexed/tree/native-lv2) on i386 and ARM, for using it onto the Mod-Duo and Zynthian.

Currently I have some trouble with the basics of Teensy and the Audio library (see here) - but I hope this can be solved - or there maybe a better way. If someone has fun to help coding, please let me know!

Regards, Holger
 
Currently I am getting a kind of "sound" out of the Teensy... but there seems to be much problems to solve before it works :D

I created a simple MIDI shield for the Teensy for better testing and debugging:
MIDI-Teensy.jpg

Regards, Holger
 
Make sure you're using the latest beta. It has the newest audio library with the modulated waveform object.

https://forum.pjrc.com/threads/52090-Teensyduino-1-42-Beta-4

People who tried to do FM synthesis with the old FM sine object found it too limiting, because it only gives a 1 octave modulation range. That's just not enough for many of the classic FM effects. It's also not quite the linear CV to octave relationship you'd need.

The new modulated waveform object is meant to solve these old limitations. It can do FM up to 12 octaves range, allowing even sub-sonic waveforms to modulate all the way up to 20 kHz (though the default is 8 octaves, allowing a 0-1.0 signal to do roughly the "1 volt per octave" that's common with modular synth). It has octave proper scaling like you'd expect from any analog synth. It can also do 8 other non-sine waveforms, and you can use phase modulation instead of frequency, if you prefer.
 
Make sure you're using the latest beta. It has the newest audio library with the modulated waveform object.

https://forum.pjrc.com/threads/52090-Teensyduino-1-42-Beta-4

People who tried to do FM synthesis with the old FM sine object found it too limiting, because it only gives a 1 octave modulation range. That's just not enough for many of the classic FM effects. It's also not quite the linear CV to octave relationship you'd need.

The new modulated waveform object is meant to solve these old limitations. It can do FM up to 12 octaves range, allowing even sub-sonic waveforms to modulate all the way up to 20 kHz (though the default is 8 octaves, allowing a 0-1.0 signal to do roughly the "1 volt per octave" that's common with modular synth). It has octave proper scaling like you'd expect from any analog synth. It can also do 8 other non-sine waveforms, and you can use phase modulation instead of frequency, if you prefer.

Ok, will do so! But for the MicroDexed-project I only need the AudioQueue (and later some effects) because the complete engine is based onto Dexed which does the whole sine-modulator-carrier-thingy.

For now I have a running version which supports only one hard coded FM-Piano sound: BUT IT WORKS!!! Currently it is not really ready for using it widely. There is no MIDI input queue (so events get dropped) and no sysex sound loading - also some controllers are not mapped and so on... I will do this the next days/weeks, so I hope to have a full DX-7 compatible sound engine with a Teensy.

Regards, Holger
 
Here we go: A first working version of Dexed (a Yamaha DX7 like synth) is located at GitHub: https://github.com/dcoredump/MicroDexed.

What currently is working:
- Up to 10 tones at the same time (on a Teensy-3.5, perhaps the 3.6 can handle up to 16 tones a time)
- Only one hardcoded voice (FM-Piano)
- All controllers

What next?
- SysEx data reading from SD card
- Perhaps adding some effects (reverb, chorus, eq)
- Testing with a Teensy-3.6

Regards, Holger
 
Nice!

Unless you really do need double, it would be faster to declare your floating point variables as float (and use the single precision math calls like sinf, logf rather than sin, log). Then the hardware FPU in Teensy 3.5 and 3.6 will be used.

In Dexed::processMidiMessage your NoteOn code does not take account of MIDI running status. Given that your input is DIN MIDI, you are likely to encounter that in practice. Check for a NoteOn velocity of zero and if found, treat as a NoteOff (and if using release velocity, assign a release velocity of 64).
 
Nice!

Unless you really do need double, it would be faster to declare your floating point variables as float (and use the single precision math calls like sinf, logf rather than sin, log). Then the hardware FPU in Teensy 3.5 and 3.6 will be used.

In Dexed::processMidiMessage your NoteOn code does not take account of MIDI running status. Given that your input is DIN MIDI, you are likely to encounter that in practice. Check for a NoteOn velocity of zero and if found, treat as a NoteOff (and if using release velocity, assign a release velocity of 64).

Many thanks for your comments!!!

I replaced the doubles with a macro in synth.h (
Code:
#define FRAC_NUM float
), so only floats are used now. I also replaced all sin() and log() to their float variants. But mostly this does not affect anything while playing, because it seems that this all is mainly used in the initialization functions for the lookup tables (AFAIK the real DX7 also works with LUTs).

The NoteOn with a velocity of 0 is recognized in the underlying keydown() function:
Code:
void Dexed::keydown(uint8_t pitch, uint8_t velo) {
  TRACE("Hi");
  TRACE("pitch=%d, velo=%d\n", pitch, velo);
  if ( velo == 0 ) {
    keyup(pitch);
    return;
  }

And release velocity is ignored in keyup().

Again: many thanks! It is really a big help if someone else is looking at my code...

Regards, Holger
 
Any chance for a youtube video, or even just a photo?

We can probably show this on the website blog, but at least 1 picture is required.

I can try to make a video the next days/weeks. Currently I have to solder the line out on my audio shield for recording the sound directly into the cam :)

I have posted a picture some messages above - but this is not really spectacular... so a viceo with sound would be the better choice. I will post a link here when I am ready.

Regards, Holger
 
I don’t know if anybody else has tried, but yesterday I put MicroDexed on a T4 with PT8211, using DIN MIDI.
600Mhz allows for a large number of simultaneous voices.

Next I need to hook up some encoders and the LCD.
 
I don’t know if anybody else has tried, but yesterday I put MicroDexed on a T4 with PT8211, using DIN MIDI.
600Mhz allows for a large number of simultaneous voices.

Next I need to hook up some encoders and the LCD.

Thanks @tele_player for sharing! Can you try to increase MAX_NOTES to 32 or more (inside config.h)? I am curious about how many notes can be played with the T_4.0 simultaniously.

Currently there is a dev branch where optimizations for the T_4.0 are included. But I think I have messed up something while implementing multi-engine support, so it may not work yet.

Regards, Holger
 
I have it at 128 now. It plays fine, though sound gets a bit garbled above about 50-60 notes (using sustain pedal). Release the pedal, everything is back to normal.
 
I have it at 128 now. It plays fine, though sound gets a bit garbled above about 50-60 notes (using sustain pedal). Release the pedal, everything is back to normal.

Hey, that's pretty cool! Thanks for testing.

The noise can be buffer underrun or (what I think) overload (too loud). This is shown as XRUN or PEAK counter every 5 seconds on the serial console. Perhaps you have time and fun to check this.

Regards, Holger
 
With MAX_NOTES at 128, I can force XRUNS by pressing sustain and playing many notes.
With MAX_NOTES 64, it's much better, I couldn't get any XRUNS.

While all this CPU power is nice, USB Host support, as on T3.6, is a very nice feature. I'm fortunate I have a few controllers with DIN output.

This was playing whatever EP sound it defaults to when there is no SD card, and no way to change programs.

Holger, did you ever produce any more kits for MicroDexed?
 
With MAX_NOTES at 128, I can force XRUNS by pressing sustain and playing many notes.
With MAX_NOTES 64, it's much better, I couldn't get any XRUNS.

Great! 64 note are 4 times a DX7 :)
Currently I am writing the code for multi instances, so when it's ready it may be possible to run 4 different voices at a time :)

While all this CPU power is nice, USB Host support, as on T3.6, is a very nice feature. I'm fortunate I have a few controllers with DIN output.

This was playing whatever EP sound it defaults to when there is no SD card, and no way to change programs.

Holger, did you ever produce any more kits for MicroDexed?

Currently I have some kits available. But I havn't found any time to write down the building instructions. So the circuit diagram and some photos (and the infos from Revision 1.7) are the only help which is available (and of course my email address :) ). I hope to get everything ready (new code, manual, web-page and forum) start of next year. Building a MicroDexed is not very complicated but you should have some soldering practice. If you are interested in a kit, please write a PM.

Regards, Holger
 
Hi

I sent these gerber files from codeberg to PCBWAY for a run of TMA 1.8 pcbs:

https://www.dropbox.com/s/cfethsrvu1uibse/Teensy Midi Audio 1.8.zip?dl=0

PCBWAY sent the following failure message:

"Failed reason: No keepout layer(board outline),please add board outline in GKO/GM1/OUTLINE Layer.;"

Can anyone help?

I can take a look at this when I am back at home (next week). I made those PCBs at PCBGO a year ago, so I think everything should be fine.

Regards, Holger
 
Is the usb host function shut down when teensy 4 is used? I have Blacketter's breakout and usb host cards on a t4, running your code successfully but the usb host doesn't seem to work. It worked with usb host example code, so I know the host card is good.
 
Is the usb host function shut down when teensy 4 is used? I have Blacketter's breakout and usb host cards on a t4, running your code successfully but the usb host doesn't seem to work. It worked with usb host example code, so I know the host card is good.

I havn't tested the code with T_4.x. Have you compiled with "Serial + MIDI + Audio"?

Can you tell me which example code you used?
 
I used the most recent code on your codeburg repo.

Yes, compiled with serial+MIDI+audio, and that all works.

I refer to usb host that lets the device directly receive a usb midi keyboard. This appears to be supported on T3.6 but it doesn't work on T4 with hardware that does work with the USBHost_T36 library.

53624BF5-BC8F-4A9C-9D1C-6028AF61AF4F.jpeg
2514E598-955C-4334-B281-84ABEDCC6512.jpeg

https://oshpark.com/profiles/blackketter

However I understand if you haven't tested it on a T4. Seems to work very well, just no usb host.

I suspect this is happening in some #ifdefine but despite looking around it isn't obvious to me.
 
Gah!

Nevermind, I forgot to use the pin 27 enable!

* embarrassed *

It works, thanks for your time.
 
Hi

I sent these gerber files from codeberg to PCBWAY for a run of TMA 1.8 pcbs:

https://www.dropbox.com/s/cfethsrvu1uibse/Teensy Midi Audio 1.8.zip?dl=0

PCBWAY sent the following failure message:

"Failed reason: No keepout layer(board outline),please add board outline in GKO/GM1/OUTLINE Layer.;"

Can anyone help?

Hmmm, strange. I created a new version with slightly changed paramters for the drill file. As I wrote: it worked with Rev-1.8 at PCBWAY and REv-1.8 at PCBGO. You can try to use the new files from here.
 
Back
Top