AMY, a fixed-point C synthesizer you can drop into a microcontroller
AMY - A high-performance fixed-point Music synthesizer librarY
At a glance
- What is it?
- AMY is a small C synthesis library that runs the same engine on a browser, a Raspberry Pi, an ESP32 and a Teensy, with Python, Arduino, JavaScript and GDScript bindings on top. Its value is that it is plain C with no dependencies, and its cost is that the interface is low level and the audio quality depends on the fixed-point design.
- Who is it for?
- AMY is the right choice for a microcontroller, a game engine, a web demo or a bespoke instrument where you want synthesis without a sound library dependency, and the wrong choice for a desktop production audio pipeline where you need a plugin, a mixer and tested output.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 9 days ago.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One synthesis core, many very different hosts
AMY is written in C and the interesting claim in the README is not what it can sound like but where it will run. The list of platforms it has been run on includes the web, Mac, Linux and Windows, small Linux devices such as the Raspberry Pi, ESP32 and ESP32S3 on Xtensa, ESP32-P4, ESP32-C3 and C6 on RISC-V, the Pi Pico RP2040 and Pi Pico 2 RP2350, the NRF52 series, Teensy 3.6 and 4.1, the Playdate and Electro-Smith Daisy on ARM Cortex M7, iOS devices, and the Godot game engine. The README says it is highly optimized for polyphony and poly-timbral operation even on the lowest power and constrained RAM microcontroller, and that it scales to as many oscillators as you want. It also powers the Alles multi-speaker mesh synthesizer and the Tulip Creative Computer, which is the kind of evidence that matters more than a benchmark table, because those are shipping instruments rather than demos.
Building the C example and hearing a tone
The quickest first run is the bundled C example. From a checkout, the Makefile builds the amy-example, amy-message and amy-piano targets, and the README gives the two commands:
make
./amy-example # you should hear tones out your default speaker, use ./amy-example -h for optionsThere is no configure step and no package manager. For a C build the dependency list is effectively empty: the README says to copy the .c and .h files in src to your program and compile them, and states that no other libraries should be required to synthesize audio. The Makefile is the only place where platform specifics live, and it is explicit about them. On Darwin it sets CC to clang, adds -DMACOS and links AudioUnit, CoreAudio, CoreFoundation, CoreMIDI and Cocoa. On Linux it uses gcc. The compile flags include -O3, -Wall, -Wextra and -DAMY_WAVETABLE, so the wavetable oscillator is compiled in by default and debug builds are a commented out flag you enable yourself.
Linux MIDI is detected, not required
The most instructive part of the Makefile is a block of comments explaining a design decision rather than a build rule. On Linux, MIDI runs on ALSA raw MIDI through src/linux_midi.c, and the Makefile treats it as optional. It probes for ALSA at configure time by compiling a tiny program that includes alsa/asoundlib.h and links -lasound, and only adds the source and -DAMY_ALSA when that probe succeeds. Otherwise it prints a notice that it is building without linux MIDI and carries on. The reasoning in the comment is worth repeating because it explains a general attitude: a synth library may not make itself unbuildable over a device layer, since CI runners, containers and headless Pis have no libasound2-dev. When ALSA is absent, linux_midi.c compiles to nothing and amy_midi.c keeps the no-op run_midi and stop_midi it always had. The install line it references is apt install libasound2-dev.
The Python binding is a compiled extension, not a pure-Python port
The Python route is convenient but hides a compiler toolchain. The README says you can import amy in Python and have it render either out to your speakers or to a buffer of samples you can process on your own, and to install the library with pip install . and run make test to install and run a series of tests. The packaging files explain what that builds. pyproject.toml names the package amy at version 1.2.200 with dependencies on numpy and soundfile, and requirements.txt lists the same two. The actual work happens in setup.py, which compiles a C extension module named c_amy from more than twenty sources including amy.c, oscillators.c, filters.c, envelope.c, sequencer.c, midi_mappings.c, pcm.c and amy_midi.c. It sets CC to gcc and CXX to g++, and on Darwin it appends src/macos_midi.m and links the CoreAudio, CoreMIDI and Cocoa frameworks. So a pip install that fails is usually a missing compiler or a missing audio framework rather than a Python problem.
Fixed-point rendering, and why it is the whole point
The repository description calls AMY a high-performance fixed-point music synthesizer library, and the synthesis models are built on that base. It can behave as a Juno-6 style analog synthesizer, a DX7 style operator and algorithm based FM synth, a partial breakpoint synthesizer in the Alles machine or Atari AMY lineage, a partials-driven piano, a PCM sampler, a wavetable synth and an 808 style drum machine, or a lower level toolkit you assemble yourself. The oscillator set is band-limited and includes pulse with adjustable duty cycle, sine, saw up and down, triangle and noise, with frequency, pan, phase and amplitude per oscillator. Biquad low-pass, bandpass and hi-pass filters can be assigned to any oscillator, and each oscillator carries two envelope generators that can move amplitude, frequency, PWM duty, filter cutoff or pan. Any oscillator can also modulate another, which is how a bass drum is described as a half phase sine wave at 0.25Hz modulating the frequency of another sine wave.
Getting DX7 and Juno-6 patches into an AMY patch
There is a front end for DX7 and Juno-6 SYSEX patches, plus conversion setup commands, and the conversion is done in Python rather than C. The FM side ships fm.py, which converts any DX7 patch into an AMY patch, including directly from DX7 sysex files, through a call named fm.load_syx(). The Juno-6 side ships juno.py, which reads Juno-6 SYSEX patches and converts them into AMY patches. Both live in the amy/ directory alongside the Python package. This is a real practical advantage over writing your own converter, since DX7 patch formats are the kind of thing that looks simple until the operator ratio and level encodings get in the way. The library also carries 300 or more built in preset patches for PCM, DX7, piano and Juno-6, so a first project can start from working sounds rather than from an empty oscillator.
Where AMY is the wrong tool
The most obvious limit is the interface, not the sound. This is a C library with a low level API, so the work of building a patch, routing events and keeping polyphony sensible sits with the calling program. There is no plugin format, no mixer, no recording, and the README does not document a DAW integration path. The second limit is audio quality. Fixed-point rendering is the reason AMY fits into a microcontroller with constrained RAM, and it is also the reason a full-rate desktop mix will sound different from a float engine. A third limit is that the browser path is an Emscripten build: to produce it you run make docs/amy.js, which generates amy.js in docs/, so the web version is a compile step rather than an npm install. The example directories show the intended shapes of use, from AMY_ESP32_manual_I2S and AMY_MIDI_Synth to AMY_custom_dsp, AMY_custom_osc and AMY_pico_PWM, but each of those is a program you write.
Sequencing, multicore rendering and the web build
AMY is not only a voice generator. It has a built in event clock and pattern sequencer that is clocked by rendered samples, which the README says makes it work in real time and in offline rendering, and it supports multi-core rendering including on microcontrollers where more than one core is available. It also has MIDI support built in, with synthesizer voice management including voice stealing, controllers and per-channel multi-timbral operation, so an application can hand AMY note and controller messages and let the library allocate voices. Effects are global rather than per oscillator, covering reverb, echo and chorus, with overall gain and a three band EQ. On the web side the project publishes an interactive tutorial, a demo page at shorepine.github.io/amy, an API document at docs/api.md and a MIDI specification at docs/midi.md, so the reference material for a binding is public even where the code is C.
Editorial conclusion
AMY is the right choice for a microcontroller, a game engine, a web demo or a bespoke instrument where you want synthesis without a sound library dependency, and the wrong choice for a desktop production audio pipeline where you need a plugin, a mixer and tested output. Before committing, check that the rendering path suits your host, since the Python build is a compiled extension with a numpy and soundfile dependency and Linux MIDI is optional and detected rather than assumed, then confirm that the C entry points in src/ are enough for your use or that the Python or Godot bindings cover it. The last push was on 2026-10-14 and release 1.2.200 landed the same day, so the tree is moving, but the version numbers advance on every commit and you should pin one.
Frequently asked questions
How do I install AMY in Python?
The README says to run pip install ., and make test installs the library and runs a series of tests. The Python package is a compiled extension built by setup.py, so a C compiler is needed as well as numpy and soundfile.
Can I use AMY without any third party libraries?
For C use, the README says to copy the .c and .h files in src to your program and compile them, and that no other libraries should be required to synthesize audio. Platform MIDI and audio frameworks are the exception, handled per platform by the Makefile.
Which microcontrollers does AMY run on?
The README lists ESP32, ESP32S3, ESP32-P4, ESP32-C3, ESP32-C6, the Pi Pico RP2040 and Pi Pico 2 RP2350, the NRF52 series, Teensy 3.6 and 4.1, the Playdate, the Electro-Smith Daisy and the Raspberry Pi, among others.
Does AMY need ALSA on Linux?
No. The Makefile detects libasound2-dev and builds without Linux MIDI if it is absent, keeping amy_midi.c on its no-op run_midi and stop_midi paths. The install line it references is apt install libasound2-dev.
How do I convert a DX7 sysex file to an AMY patch?
The Python library fm.py converts DX7 patches into AMY patches and can read .SYX files directly through fm.load_syx(). A matching juno.py handles Juno-6 SYSEX patches.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/shorepine-amy)Was this useful?