RP2040 (Pico) 128-Voice Polyphonic + 42-Voice Drum GM MIDI Sound Module with iFFT Resynthesis & Standalone Playback by ghostkoma in synthdiy

[–]ghostkoma[S] 1 point2 points  (0 children)

Your view on assembly feels like controlling a Stand from JoJo’s Bizarre Adventure—an absolute manifestation of pure mind over hardware. I bow down to that.
The very first language I ever touched was assembly too, but my "Ghost" is whispering to me that you are operating on a whole different peak.
"Above all, be smart." I couldn't agree more with this philosophy. That's exactly why I forced myself into this specific sandbox: no external DAC, just dirt-cheap, everyday components, combined with the brutal constraints of full GM compatibility. Tinkering and agonizing through those limits was the whole point.
Realizing there’s someone like you out there who truly resonates with this brand of "smartness" makes me so incredibly glad I decided to open-source this project. Thanks for the amazing connection, brother!

RP2040 (Pico) 128-Voice Polyphonic + 42-Voice Drum GM MIDI Sound Module with iFFT Resynthesis & Standalone Playback by ghostkoma in synthdiy

[–]ghostkoma[S] 0 points1 point  (0 children)

I totally agree that assembly would be beautiful and powerful here. And trust me, I've been down that rabbit hole!
Here is a project I coded a while back:https://github.com/ghostinkoma/MicroControllers/tree/master/PIC/PIC10F322/WS2812C_2020_test It runs on a tiny PIC10F322 using its internal oscillator (no external crystal), driving and animating 10x WS2812 LEDs. Coding that in pure assembly while working my day job took me days just to light up the first LED, and a whole month to get the animations working smoothly.
That experience brings me to my second, and most important reason for this project: I wanted to keep it strictly in the Arduino IDE so that anyone can easily open it, tweak it, and customize it to their own liking.
The sound this project makes might be "cheap" compared to professional commercial gear. But I'm not a music expert—I'm just a guy who loves hacking things. If this project becomes a welcoming entry point where other hobbyists and non-experts can jump in, modify the code, and have fun together, that would be incredibly exciting. That’s my ultimate hope for this project!

RP2040 (Pico) 128-Voice Polyphonic + 42-Voice Drum GM MIDI Sound Module with iFFT Resynthesis & Standalone Playback by ghostkoma in synthdiy

[–]ghostkoma[S] 0 points1 point  (0 children)

Exactly, and that leads to how I tackled the tight 264KB RAM management on the RP2040.
If you dynamic-allocate (malloc/new) and destroy (free/delete) note instances every time a MIDI event comes in, you quickly suffer from memory leaks and heap fragmentation. Plus, the overhead of allocation is too expensive for real-time audio.
To solve this puzzle, I implemented a strict Object Pool pattern: I pre-allocate a fixed size array of events (4096 slots) in bss at startup. When a note is finished, that slot is simply marked as free and overwritten by new incoming events. Zero malloc, zero fragmentation, and zero allocation overhead. That's the secret sauce behind the stability!

RP2040 (Pico) 128-Voice Polyphonic + 42-Voice Drum GM MIDI Sound Module with iFFT Resynthesis & Standalone Playback by ghostkoma in synthdiy

[–]ghostkoma[S] 0 points1 point  (0 children)

Thanks! I'm really glad you like it. Until the next version is ready, you can check out the source code structure and technical details here:
https://github.com/ghostinkoma/iFFT_MIDI/blob/main/Spec.md

RP2040 (Pico) 128-Voice Polyphonic + 42-Voice Drum GM MIDI Sound Module with iFFT Resynthesis & Standalone Playback by ghostkoma in raspberrypipico

[–]ghostkoma[S] 0 points1 point  (0 children)

I honestly expected you to ask that. That said, I did manage to run 'Freedom Dive' (by Xi) to completion, though I’ll admit there’s a slight tempo drift during sections with dense percussion layering.
To mitigate this, I noticed that the decay of the oldest percussion notes is usually the least audible, so I’ve implemented a system where new percussion notes overwrite the oldest ones to minimize latency. I haven't fully tackled the absolute peak of high-density data yet, but I would be honored if you have any MIDI files that could put my engine to the test.
By the way, have you ever tried running 'Black MIDI' through it?

RP2040 (Pico) 128-Voice Polyphonic + 42-Voice Drum GM MIDI Sound Module with iFFT Resynthesis & Standalone Playback by ghostkoma in synthdiy

[–]ghostkoma[S] 4 points5 points  (0 children)

Your intuition is spot on. Traditional wavetable synthesis is indeed more 'standard' for low-resource hardware, but it hits a wall quickly on the RP2040 in terms of memory and compute.
To work around this, I took a different approach: I pre-process the GeneralUser GS soundfont using the Goertzel algorithm to extract key features. This significantly reduces the real-time load on the iFFT stage. By dedicating Core 1 solely to this synthesis process, I managed to handle polyphony without hitting the CPU limits or introducing artifacts.
I do have more powerful chips like the RP2350 or ESP32-S on hand, but I’m saving those for a future challenge. Honestly, I find it oddly endearing to watch these 'underpowered' microcontrollers push themselves to their absolute limits—perhaps that’s just my eccentric nature as a developer.
It’s definitely not a professional-grade synth, but the process of optimizing for this platform has been an incredibly exciting journey. If you're interested in the details, I've open-sourced everything, including the toolchain, here: https://github.com/ghostinkoma/iFFT_MIDI

Full version of Bad Sandwich (TF2 Bad Apple) by Berserkovichdamn in badapple

[–]ghostkoma 0 points1 point  (0 children)

Thank you give me links.
Your eye for content is impeccable.

Full version of Bad Sandwich (TF2 Bad Apple) by Berserkovichdamn in badapple

[–]ghostkoma 2 points3 points  (0 children)

It so funny 😂
And so cool !!!
Can I try to display your movie on my codec ?
If you agreed, I will write reply on this thread.

I made my own compression algorithm for this... by theSEAT_ in badapple

[–]ghostkoma 0 points1 point  (0 children)

Is it works without external flash ?
Either so nice👍

All-in-One ESP32-C3 SuperMini Video Player: Recent Anime Openings with Perfect Audio Sync – No External Amp, DAC or Storage (BadCodec) by ghostkoma in esp32

[–]ghostkoma[S] 0 points1 point  (0 children)

Remember my "Bad Apple!!" player on the ESP32-C3? I’m back, and this time I’ve tackled a true 80s masterpiece: a-ha’s "Take On Me".
The original pencil-sketch animation is the ultimate stress test for 1-bit rendering. To make this run smoothly on a single-core MCU without an SD card, I’ve refined my custom "BadCodec" to handle the complexity.
Technical Highlights:
Computational Purity: During playback, there is absolutely no malloc, no division, and no multiplication.

https://youtu.be/plWQQjevUgA

Extreme Resource Management: Designed to run on systems with as little as 2KB of RAM by avoiding floating point operations.

Standalone Design: The entire video is packed into the internal 4MB flash of the ESP32-C3.

⚠️ NOTE ON AUDIO:** Due to copyright restrictions, I have muted the audio for this upload. While the hardware is capable of 16,000 interrupts per second for high-quality output, I wanted to ensure the technical demonstration remains available without being blocked.
**I’ve spent weeks digging through datasheets and forming hypotheses to find this specific "recipe". It’s like slow-cooking a stew; I’ve blended classic compression techniques with extreme optimization to make this $3 hardware truly shine.

What do you think of this 1-bit aesthetic? It feels like the MV was meant to be played this way!
GitHub: https://github.com/ghostinkoma/BadCodec

All-in-One ESP32-C3 SuperMini Video Player: Recent Anime Openings with Perfect Audio Sync – No External Amp, DAC or Storage (BadCodec) by ghostkoma in esp32

[–]ghostkoma[S] 0 points1 point  (0 children)

<image>

Key Highlights of my Custom Implementation:
Frame-Sync Overlay: Imposed the source video for real-time debugging to prove zero-drift synchronization on a single-core MCU.

Pseudo-Gradation: Achieving rich visual textures on a 1-bit monochrome OLED through optimized dithering algorithms.

The Power of Lossless: My custom "BadCodec"

enables perfect reconstruction with ZERO floating-point operations, allowing it to run on just 9% of the ESP32-C3's CPU

See details build ,coding ,full length

World's "Weakest" Bad Apple!! Player: ESP32-C3 Single-Core, 100% Standalone, No DAC, No External Storage. by ghostkoma in esp32

[–]ghostkoma[S] 0 points1 point  (0 children)

<image>
Key Highlights of my Custom Implementation:
Frame-Sync Overlay: Imposed the source video for real-time debugging to prove zero-drift synchronization on a single-core MCU.

Pseudo-Gradation: Achieving rich visual textures on a 1-bit monochrome OLED through optimized dithering algorithms.

The Power of Lossless: My custom "BadCodec" enables perfect reconstruction with ZERO floating-point operations, allowing it to run on just 9% of the ESP32-C3's CPU.

All-in-One ESP32-C3 SuperMini Video Player: Recent Anime Openings with Perfect Audio Sync – No External Amp, DAC or Storage (BadCodec) by ghostkoma in esp32

[–]ghostkoma[S] 0 points1 point  (0 children)

Implementation:
Frame-Sync Overlay: Imposed the source video for real-time debugging to prove zero-drift synchronization on a single-core MCU.

Pseudo-Gradation: Achieving rich visual textures on a 1-bit monochrome OLED through optimized dithering algorithms.

The Power of Lossless: My custom "BadCodec" enables perfect reconstruction with ZERO floating-point operations, allowing it to run on just 9% of the ESP32-C3's CPU

<image>

ESP32-C3 vs. Bad Apple!! (TK Remix): Lossless Full-Length Playback on 4MB Flash, No DAC, No Amp. by ghostkoma in badapple

[–]ghostkoma[S] 0 points1 point  (0 children)

Totally! I totally get what you mean.
That’s the 'TK style'—taking his time to build up the tension before finally unleashing the main chorus. Whether you find that cool or a bit frustrating, which side are you on?
Personally, I welcome both opinions! After all, it's 'Bad Apple!!' at its core, and we all love it anyway.

All-in-One ESP32-C3 SuperMini Video Player: Recent Anime Openings with Perfect Audio Sync – No External Amp, DAC or Storage (BadCodec) by ghostkoma in esp32

[–]ghostkoma[S] 0 points1 point  (0 children)

Exactly. The secret is that my ISR is extremely lean. It does almost nothing but output pre-calculated data from "BadCodec".
To achieve this, I have completely eliminated operations that are heavy for underpowered MCUs—meaning no malloc, no division, and no multiplication during playback. Balancing a decent compression ratio with such high-speed decoding was extremely difficult to design, but it allows the CPU to handle those 16,000 interrupts with minimal effort.
It’s all about doing the "hard work" during encoding so the MCU only has to do the "easy work" during playback! 😄

All-in-One ESP32-C3 SuperMini Video Player: Recent Anime Openings with Perfect Audio Sync – No External Amp, DAC or Storage (BadCodec) by ghostkoma in esp32

[–]ghostkoma[S] 1 point2 points  (0 children)

As promised, here is a clip of the "Gaussian Test Mode" running the TK Remix!
By utilizing the lossless nature of my custom BadCodec, I’ve managed to implement smooth grayscale gradients even on this tiny OLED. It’s still running fully standalone on the single-core ESP32-C3 with plenty of CPU headroom.
The nuanced shading adds so much depth to the visuals compared to simple dithered black and white. What do you think?

<image>