-
Notifications
You must be signed in to change notification settings - Fork 249
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Idea: MiniDexed, a FM synthesizer on Circle #274
Comments
This is an interesting project idea and the Raspberry Pi 4 (maybe 3 too) should have the required performance. I would also support such a project by answering questions regarding Circle or MiniSynth Pi. |
An LV2 host on circle would be ideal, because it would enable many other synths to be easily ported to Circle as well. However, I'm not certain if the effort involved would be huge or not. Looking at the libraries available, https://github.com/lv2/lilv seems to be the only game in town, and nearly all current host implementations use it. I notice that there are a lot of OS-specific compiler pragmas that might make this a pain to port to Circle. |
Hi! I am the one who used the Dexed engine and put it into LV2. This one we are using on Zynthian (https://zynthian.org) - a Raspi based multi purpose Synth. The same engine I am using for MicroDexed (based on a Teensy (3.6/4.1). The engine for the Teensy is located here. This could be the base for a usage based on circle. The central rendering method is void There are much more needed methods mentioned in the README of the mentioned repository. Unfortunately I don't have enough time to work on this project permanently, but I can help to find the right places in the code. It can't be very complicated. Don't hesitate to contact me by email (dcoredump@googlemail.com). Regards, Holger |
Thanks for chiming in!
What do the experts think about the use of LV2 on Circle? Useful abstraction or unnecessary overhead hassle? Fwiw, just stumbled upon https://github.com/dwhinham/mt32-pi: a bare metal MIDI synthesizer for the Raspberry Pi 3 or above, based on the Munt Roland MT-32 emulator, FluidSynth SoundFont player, and Circle. |
I won't call me an expert - but I will write down what I think :) On one hand it sounds really cool, but on the other hand there wouldn't be much LV2 clients which would work (IMHO). Most LV2 plugins have much dependencies to other libraries and you have to port them also to circle. Most plugins have GUIs for X11... I think you have to strip down everything. Only the raw sound engine has to be there - and the LV2 code. That's exactly what I have done with Dexed. If you have to write the LV2 code around a stripped down synth, it would be easier to use the synth code directly with circle. But as I said: I am not an expert - maybe there are better ways to do this... Regards, Holger |
I think, one of the strengths of Circle is, that you don't have that much software layers to deal with, which is good for understanding and performance. That's why to keep it simple I would vote for a solution without LV2 too, at least for the moment. I tried to build the code in the Source/msfa/ subdirectory of Dexed with Circle and despite from two warnings, I wasn't able to fix so far, that worked. I think, this directory contains the basic synth engine of Dexed. I used the Standard C and C++ Library Support for Circle project, not Circle directly, because the msfa code requires Standard C and C++ bindings. |
Nice @rsta2! The msfa directory is the main engine for Dexed but around this engine there are some improvements/extensions. I also manually added a portamento patch for the Teensy object Synth_Dexed. Furthermore there is a loader/extractor for sysex data, so you can load sysex sounds directly. Perhaps I can find time to try to add the Sysnth_Dexed code into the mentioned C/C++ project at weekend. Regards, Holger |
Great! Would you mind uploading your almost-working code somewhere? That way we could all have a look to see if we can find out a way to fix the two warnings. |
I meant, I was able to build the msfa code, it did not run yet. The files, which I used to build msfa in the circle-stdlib environment, are in the attached archive. You have to clone the circle-stdlib project with submodules libs/circle and libs/circle-newlib and need one of the toolchains, mentioned in the README.md file. Then the path to the circle-stdlib root directory must be set in the Makefile, which is provided in the archive below. The circle-stdlib project must be configured and build separately for the target Raspberry Pi model. Then you can go to src/ directory in the archive and do make. Let me know, when you have questions. |
This comment was marked as outdated.
This comment was marked as outdated.
FreeBSD is not supported as build platform, only Linux and Windows (to some degree). You definitely need a toolchain from here, the C++ standard library support will not work otherwise. |
Started a repository over at https://github.com/probonopd/MiniDexed/. First step is to get it to compile on GitHub Actions CI. |
There are now continuous CI builds: If I put the content of the zip file onto a FAT32-formatted microSD card and boot it in the Raspberry Pi 4, I see
That's a start. |
@rsta2 looking at https://github.com/rsta2/circle/blob/master/sample/29-miniorgan/miniorgan.cpp, it seems like it contains the logic to get MIDI data, convert it to sound samples, and feed the sound data into the sound system using @rsta2 how are you running your test/debug cycles when working on Circle? Writing files to microSD all the time must be quite the hassle during development... @dcoredump do you know how one sends MIDI packets (or is it keydown/keyup method calls?) to the Dexed engine, and how one gets sound data back from Dexed? @dcoredump looking at https://codeberg.org/dcoredump/MicroDexed it seems it has a lot of stuff MiniDexed would also want. Should we be using the MicroDexed codebase rather than the Dexed/mstfa codebase? Or https://codeberg.org/dcoredump/Synth_Dexed? |
@probonopd I think, the sample/29-miniorgan is a good base to start with Circle sound. It's correct, Please have a look into doc/bootloader.txt for using a serial bootloader, which I do for development. |
Trying to port over sample/29-miniorgan to https://github.com/probonopd/MiniDexed I am running into errors like
Is it my cursory understanding of C++ or are there differences between circle and circle_stdlib that make this more than a copy-and-paste exercise? |
Without the concrete source code this is hard to tell. I see that the minimal test program in https://github.com/probonopd/MiniDexed/tree/main/src builds without error. How is your new program different? |
I created a pull request in the MiniDexed repository with a fix for the build errors. You are right that it is not a simple copy-and-paste exercise because the circle-stdlib convenience base class CStdlibAppStdio() already bundles most of the individual classes that are used explicitly in the Circle miniorgan sample program. So several things that happen explicitly in the Circle miniorgan program happen implicitly in the circle-stdlib variant. |
Excellent, thank you very much for you help @smuehlst. Now we should have MIDI input working (I will test this soon) and the Dexed code building. Next we need to figure out how to use those MIDI messages to feed them into Dexed, and how to get the sound data out of Dexed and feed it into the circle-stdlib sound system. |
Oops! Now it stalls on the "rainbow" Raspberry Pi boot screen, does not blink 5 times (do we never reach |
Please apply the following patch and it should work as before:
The problem was, that the serial interface at GPIO14/15 is already initialized in the constructor of the class The solution is to use an other serial interface at GPIO12/13 in I don't know, if you use the serial bootloader in the meantime. If so, please use the new bootloader (Flashy) for that large kernel images, as described in doc/bootloader.txt. It loads quicker and the older bootloader sometimes has problems with larger kernel images. |
Thanks @rsta2, now I no longer get the crash. But I see "Function is not supported" under the entry for my USB MIDI keyboard, and I can hear no sound when I play using either the USB computer keyboard or USB MIDI keyboard (the same hardware works with https://github.com/rsta2/minisynth/). Can you spot what I am missing? Sorry for asking so many questions!
I would connect the output of a 6N137 optocoupler to GPIO13 (Physical/Board pin 33) for MIDI IN? Image Source: https://hackaday.com/tag/6n137/ (Have not switched to the serial bootloader yet as my dev and run machines are too far apart atm.) |
The miniorgan wasn't initialized and started properly yet. Another patch:
Some MIDI keyboards do have additional USB interfaces, which are not needed for the normal MIDI function and which are not supported by Circle. Normally you can ignore this "Function is not supported" message here. If your keyboard works with MiniSynth, it should work now with the upcoming MiniDexed too. ;) Yes, you can feed serial MIDI to GPIO13. This is a SoC number, not the position on the header (see this). BTW. There is also a bootloader, which works over Ethernet using TFTP or HTTP. You have to build the Circle sample/38-bootloader for this. |
@rsta2 I see that the |
Thanks, now I hear sound when I press keys on the USB MIDI keyboard! 👍 and also when I press keys on the USB computer keyboard. One strange thing though: When I use the computer keyboard, then I can play long notes, but when I use the MIDI keyboard which is attached to the original raspberry Pi keyboard which is attached to a Raspberry Pi 4 USB 3 port, then they are all "staccato" independently of how long I keep a key pressed. It works when I use the MIDI keyboard which is attached to the original raspberry Pi keyboard when it is attached to a Raspberry Pi 4 USB 2 port. |
Now the 💯 question is, how can we get Dexed (which already is getting built as part of MiniDexed) or Synth_Dexed (which would need to be ported first) hooked in? Perhaps @dcoredump can have a look or give some hints? |
@smuehlst Yes, there was only one instance of |
@probonopd When I test this with my AKAI LPK25 keyboard, there are no problems on both USB2 and USB3 sockets. The tone sounds as long a key is pressed without interruption. Even when I insert an USB2 hub between the USB3 socket and the LPK25, it does work. Unfortunately I have currently no explanation for this behavior with your hardware. |
Thanks @rsta2! I used your
Help would be very good, because I think I'm not getting anywhere at the moment. My problem is: I am trying to inherit for the class
The implementation is in
But something is wrong with the constructor. I can't manage to call the two constructors of the parent class. I always get the following error:
Do you have any idea what I am doing wrong?
Got it: https://github.com/rsta2/circle/blob/master/doc/new-operator.txt |
@dcoredump You are welcome. Please try the following in Synth_Dexed/src/synth_dexed.cpp:
The constructors will be specified after a colon after the prototype and before the function body. Multiple constructors will be delimited with a comma. |
Perfect!
The next step is to initialize the object... |
Thanks @dcoredump. I have updated https://github.com/probonopd/MiniDexed accordingly. |
Another question @rsta2: On Teensy the audio backend works with int16_t. It seems like circle is using uint32_t. If so I had to convert the audio block like this: uint32_signal[i]=(int16_signal[i]+0xffff)<<15; |
@dcoredump Because you have to write directly to the DMA buffer in
The zero level can be calculated as follows in any case: Because the DMA engine is 32 bit, all samples have to converted to 32 bit values, before they will be written to the DMA buffer. For information the range is as follows:
For HDMI there is an additional framing required, which is applied like here. |
@rsta Thanks! Now I understand this strange code in minirogan :) Of course it makes sense to do it this way. I am used to a unified audio interface from the Teensy and was a bit confused. Another simple question: Is there any macro I can put in my @probonopd @rsta2 |
@dcoredump Yes, such macro exists: No problem, just take the time you need. |
I've now got the whole thing working in @probonopd fork so I think it should run (according to Murphy it won't, but whatever). My fork: PR to @probonopd is also out. Unfortunately I don't have a free Raspi for testing. That will be something towards the weekend. If it works, you should hear a FM piano on some audio output triggered by MIDI-USB/Serial or keyboard. I have taken over some things from midiorgan. |
Thank you very much @dcoredump. This is great progress! Your PR refers to Synth_Dexed Anyway, I think I found a way to tell Git to just use the latest commit
|
Thank you @dcoredump! I did a quick test and with some small modifications, I can play on a USB audio class MIDI keyboard using a Raspberry Pi 4B. That's great! You find the patches attached. Currently it does work with a MIDI keyboard only and only via the headphone jack with PWM. |
Thanks a lot @dcoredump @rsta2, new build is up on I can hear sounds when I play on my MIDI keyboard. It's not one of the well-known DX7 sounds so I am not 100% sure where it is coming from but I assume it's Dexed 👍 |
So, I can report that it works on a RPi4. I loaded a simple FM-Piano - the typical sound :) |
@dcoredump Sounds good! :) How can this FM-Piano sound loaded into Synth_Dexed? |
This rocks! What a progress. Totally awesome @dcoredump @rsta2
Did you load it as sysex via MIDI-over-USB? |
I havn't checked this in into my repo, sorry. The way to do this is shown in There is also a tool for convert sysex files into compatible C-header files inside this repo. Currently I have to update Synth_Dexed with a method for handling MIDI messages. This is currently solved externally in MicroDexed - would be better to do this inside the library. |
Added loading Dexed can read Many USB keyboards can send Bank LSB and Bank MSB Changes, and Program Changes. If we put several In addition, we may want to listen to and use sysex messages sent over MIDI. Or is this already the default behavior? (Couldn't test due to the lack of a USB MIDI adapter that I could use for sending sysex from Dexed on the PC to MiniDexed.) @dcoredump I would like to print out MIDI messages for debugging around here and possibly react to those MIDI messages in an if/switch statement to load different default sysex - is this possible? |
I was able to test the FM-Piano too, of course a much more exciting sound than the init voice. ;) Thanks for info! With circle-stdlib you should be able to simply use |
Very weird: I mentioned earlier that USB is flaky on my device. Now I found out that if no display is attached to the HDMI 1 port, then I always get Tried with the original Raspberry Pi 4 Power supply and with another USB-C one. Does it work for you when you have no display attached? |
Sysex will work, but let me put the MIDI code (with sysex support) from MicroDexed into Synth_Dexed, so all projects using the library will get full sysex support. MicroDexed can currently handle all: beside the normal MIDI implementation also voice upload and voice parameter changes. |
@probonopd I copied the files from your MiniDexed Releases page to an empty µSD card and tried it with a display connected to the second HDMI port. No problems. What Raspberry Pi 4 model do you have? I have a very early RPi 4B 2GB version. Do you use an USB hub or any other USB devices beside the USB MIDI keyboard? Currently there must be a display attached to one of the HDMI ports in any case on the Raspberry Pi 4. This is different on Raspberry Pi 3, which works without a display. If you want to run without a display, you have to add the following line to the file circle-stdlib/libs/circle/Config.mk after running configure:
There will be no display output then, even when a display is attached. |
I have a very early RPi 4B 1GB but updated the flash ROM. The only combination that works for me is when I plug in a display in HDMI port 1, the Original Raspberry Pi keyboard into a USB 2 port, and the USB MIDI keyboard into the Original Raspberry Pi keyboard. At this point I cannot entirely exclude the possibility of some of my hardware being particular/faulty, athough things work on Linux. |
I use the current default version of the boot flash and the VL805 flash. It's strange, that this behavior is triggered by the HDMI port, which is in use. Does this mean, that it does not work, when the Original Raspberry Pi keyboard is not attached? This is odd too. Can you please try to create a file cmdline.txt on the µSD card with this contents:
Are there additional messages before the |
@probonopd My current versions of the flash ROMs are:
Can you please compare this under Raspberry Pi OS with your versions? Thanks! |
Yes. (One could also read this as: The USB MIDI keyboard was not correctly initialized when attached to any but the built-in Raspberry Pi USB ports directly.) VL805 flash versions were identical. Bootloader said "up to date" for me as well but I actually had a different version:
I thought I had the latest version, when in fact I didn't... the Running All USB problems gone! 💯 Thank you. This thread is getting long and unwieldy. |
This is a good idea. We should do so. It's good, that USB is working now! |
@rsta2 @dcoredump @smuehlst thanks for your enormous help to pull this off. 👍 Again, thanks for your tremendous help! |
https://github.com/probonopd/MiniDexed/
Dexed is a multi platform, multi format synth that is closely modeled on the famous DX7 synthesizer by a well-known Japanese manufacturer.
While https://github.com/rsta2/minisynth/ implements subtractive "analog" synthesis, Dexed implements additive "digital" FM synthesis. So it would be a great complement.
I am wondering whether Dexed could be ported to Circle, in order to recreate basically an open source equivalent of the TX802 (8 DX7 instances without the keyboard in one box).
Dexed has a sound engine written in C++ and has already been ported to:
The author of MicroDexed says he'd be happy to see a it on Raspi-bare-metal and while he doesn't have the time to do the port on his own, he is happy to help by answering questions. I hope a lot could be reused from https://github.com/rsta2/minisynth/, but the sound engine would have be to swapped out.
Performance wise, a Raspberry Pi 4 1GB running REAPER on Linux could handle 8 (and probably more) instances of Dexed simultaneously in my tests.
And it looks like a lot of code, e.g., for handling USB MIDI keyboards, etc. is already there in minisynth.
The text was updated successfully, but these errors were encountered: