Author Topic: I made some changes to PreenFM2 firmware  (Read 2852 times)

dx100

  • Team member
  • *
  • Posts: 6
    • View Profile
I made some changes to PreenFM2 firmware
« on: November 05, 2026, 05:39:35 AM »
I (or perhaps we could say Claude) made some updates - two small bug fixes (no more glitch between patch changes with long decay) and the screen saver now works while on Load screen. The big change is the DX7 import now uses an engine based on Dexed (and sounds quite correct in my tests).

I've run it for a while with no problems.

https://github.com/jstefani/preenfm2/releases/tag/v2.30

Let me know if you find any problems or have requests.

« Last Edit: November 05, 2026, 05:41:22 AM by dx100 »

dx100

  • Team member
  • *
  • Posts: 6
    • View Profile
Re: I made some changes to PreenFM2 firmware
« Reply #1 on: November 05, 2026, 02:52:36 PM »
To clarify, only imported DX7 sysex uses the new engine. Everything else uses the existing engine and sounds the same.
« Last Edit: November 06, 2026, 02:50:05 AM by dx100 »

Xavier

  • Administrator
  • Hero Member
  • *
  • Posts: 2263
    • View Profile
Re: I made some changes to PreenFM2 firmware
« Reply #2 on: November 10, 2026, 07:33:41 AM »
Very interesting.
I'll have to take a look at this one !!

I'm wondering how it found some free Ram to run this.
Can you have both Dexed and Preenfm2 patch playing at the same time ?

Thanks for sharing  :)

dx100

  • Team member
  • *
  • Posts: 6
    • View Profile
Re: I made some changes to PreenFM2 firmware
« Reply #3 on: November 12, 2026, 03:21:21 AM »
For future reference this was done with Fable I believe but maybe Opus 5.5, I don't recall. I'm a long time developer but Claude surely makes things I've always wanted to find time to do much more feasible.

I asked Claude for more details and got this:

"The RAM came from about 11.5 KB that was still free in main RAM, made possible by moving msfa's large tables into flash. And yes, DX7 and native preenfm2 patches play at the same time, on different parts.

Where the RAM came from

Stock 2.21b leaves about 22 KB of main RAM free; the 64 KB CCM is nearly full and was not touched. The DX7 engine uses about 11.7 KB of that, leaving about 10 KB free:

┌───────────────────────────────────────────────────────────────────────────────┬────────┐
│                                     Item                                                                           │  RAM   │
├───────────────────────────────────────────────────────────────────────────────┼────────┤
│ DX7 voice pool: 8 msfa voices plus per-part LFO and controller state                    │ 6.6 KB │
├───────────────────────────────────────────────────────────────────────────────┼────────┤
│ msfa frequency table, which depends on the sample rate so is computed at boot   │ 4 KB   │
├───────────────────────────────────────────────────────────────────────────────┼────────┤
│ The four parts' DX7 voices (155 bytes each) plus one copy for menu undo            │0.8 KB │
└───────────────────────────────────────────────────────────────────────────────┴───_─────┘

The trick that made it fit: msfa normally builds its sine and exp2 tables in RAM at startup, 16 KB together. In this port they're generated offline and stored as const arrays in flash, where there was plenty of space. Flash use went from about 274 KB to about 357 KB, out of 768 KB.

Playing both at once?

Yes. The engine is chosen per part by the patch loaded into it. Part 1 can play a DX7 patch on the msfa engine while parts 2 to 4 play preenfm2 patches on the native engine. Everything is summed into the same output, and each part keeps its own filter and effect, gain, pan and arpeggiator.

Caveats worth mentioning:
- The 8 DX7 voices are one pool shared by all DX7 parts.
- A DX7 part still reserves its native voices and operators in the existing budget, even though the msfa engine renders it. That's conservative but wasteful; a DX7 part could be budgeted separately.
- CPU load with 8 DX7 voices plus native voices has not been measured yet. A DEBUG_CPU_USAGE build is the next step. If it's tight, the DX7 pool can drop to 6."


Are we hurting the flash by storing there? or do we just store there once?

"No harm. The tables are written to flash once, as part of the firmware image, and after that they're only ever read.

- Written once. The sine and exp2 tables are const data compiled into the .bin. They're written to flash in the same erase-and-program pass as the rest of the firmware, when you flash it from the bootloader. Nothing at runtime ever writes to them.
- Reading doesn't wear flash. Flash wears from erase and program cycles, rated at a minimum of 10,000 per sector on this chip. Reads are unlimited. The audio engine reads these tables millions of times per second, the same way it reads the program code itself, which also lives in flash.
- So the only wear is per firmware update, exactly as with stock firmware. The tables add a few kilobytes to an image that's rewritten anyway.

The one cost of flash versus RAM is speed. Flash has wait states at 168 MHz, but the STM32F4's flash accelerator caches recent reads, and the inner loops hit the same small regions of the tables repeatedly. It's how the stock firmware already stores most of its own tables.

Nothing in our changes writes to flash at runtime. Patches, DX7 banks and settings all go to the USB key."
« Last Edit: November 12, 2026, 03:36:48 AM by dx100 »

dx100

  • Team member
  • *
  • Posts: 6
    • View Profile
Re: I made some changes to PreenFM2 firmware
« Reply #4 on: November 12, 2026, 03:22:23 AM »
And very much worth noting - the PreenFM2 engine itself is beautiful sounding. I'd never give it up. I was mainly working on the small glitch sound fix and thought I might as well see if we could add dexed (as everyone seems to add to everything these days ha ha).

Xavier

  • Administrator
  • Hero Member
  • *
  • Posts: 2263
    • View Profile
Re: I made some changes to PreenFM2 firmware
« Reply #5 on: November 12, 2026, 08:11:40 AM »
Thanks for the details. That's really great.
Many people are interested in Real DX7 emulation :)

That motivates me do try to do the same thing with the preenfm3.

I use Opus 5.5 at work, but it's too expensive for hobbyist project ;)
I tried "Deepseek 4.1 Flash" which gave good result for my first steps for cheap.
Cmake micration (from IntelliJ project), folder reorgansation and documentation.


dx100

  • Team member
  • *
  • Posts: 6
    • View Profile
Re: I made some changes to PreenFM2 firmware
« Reply #6 on: Today at 01:52:32 AM »
Send me any prompts you want run on the PreenFM3 codebase. I don't own one unfortunately but I likely will have some tokens left this week and would be happy to help out with any FM3 work.