TinySoundFont: a SoundFont2 synthesizer in one C header
SoundFont2 synthesizer library in a single C/C++ file
At a glance
- What is it?
- TinySoundFont is a SoundFont2 software synthesizer delivered as a single C header, so integrating it means defining TSF_IMPLEMENTATION and including one file. The trade is that the whole engine, its API documentation and its examples live in that one file, and the project has an explicit policy against generated contributions.
- Who is it for?
- Adopt TinySoundFont if you need to play SoundFont2 banks in a C or C++ program and want a synthesizer you can drop into the build as one file with no dependency to manage. Do not adopt it if you need samplers, effects, MIDI routing or anything beyond a basic render loop, because the library is a synthesizer and nothing more.
- 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 96 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 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem: a sound bank you cannot play
SoundFont2 is a file format for sampled instruments. A sound bank holds a set of samples plus the envelopes, filters and key mappings needed to play them like an instrument, and the format is old enough that a large body of music libraries, game assets and shareware instruments exist in it. If you have one, you need something that can synthesise from it.
The heavyweight answer is a full audio library, and the heavyweight answer brings a build system, a platform layer and a dependency tree with it. For a game, a tool or a piece of educational software, that is a lot of structure to answer the question of what a piano sounds like.
TinySoundFont is the small answer. It is a software synthesizer using SoundFont2 sound bank files, and the library is a single C header file so that it is extremely simple to integrate in your C and C++ projects. The project description calls it a SoundFont2 synthesizer library in a single C or C++ file, and the licence is MIT.
The audience is a developer who needs sound without a sound system: a game with a handful of instruments, a tool that previews a bank, an embedded device with no audio framework, a teaching example of how synthesis works from the sample data upwards.
Two things frame the rest of the project. The library code is based on SFZero by Steve Folta, so it inherits a lineage that is about as small and as readable as a sampler can be. And the project carries a strict no LLM and no AI policy, which is unusual enough to be worth reading before you look at the code.
The repository is not archived, the last push was on 2026-07-19, and there are no GitHub releases, so the header file in the repository is the artefact.
The single header design, and what TSF_IMPLEMENTATION does
The integration model is the same one used by several other single file C libraries, and it is worth spelling out because it changes how you think about the dependency.
The whole library is tsf.h. In one translation unit you define TSF_IMPLEMENTATION before including it, which compiles the implementation, and in every other translation unit you include it without that define, which gives you the declarations and the API documentation. The example shows the pattern:
#define TSF_IMPLEMENTATION
#include "tsf.h"There is nothing to install and nothing to link beyond the library itself. There is no configure step, no generated file and no version mismatch to manage, because there is no package to depend on. For a project that already builds C, this is close to zero integration cost.
The repository layout backs that up. There is tsf.h, the library; tml.h, a second header that ships alongside it; an examples/ directory with the working programs; an sfotool/ directory, which by its name is a command line tool built on the same code; and a .github/ directory for the workflow.
The cost of the approach is that the API documentation is not separate. The documentation can be found on top of the library source code, which means the reference, the implementation and the manual are the same artefact, and reading the library means reading several thousand lines of C to find out what a function does. For a project that treats the header as a vendored dependency and never intends to modify it, that is a reasonable trade. For a project that intends to extend the synthesizer, it is a real cost, and there is no separate header-only interface layer to fork.
The API in five calls
The example in the documentation is short enough to be the whole tutorial.
tsf* TinySoundFont = tsf_load_filename("soundfont.sf2");
tsf_set_output(TinySoundFont, TSF_MONO, 44100, 0); //sample rate
tsf_note_on(TinySoundFont, 0, 60, 1.0f); //preset 0, middle C
short HalfSecond[22050]; //synthesize 0.5 seconds
tsf_render_short(TinySoundFont, HalfSecond, 22050, 0);The sequence is: load a bank from a file, set the output format and sample rate, start a note on a given preset, allocate a buffer, and render into it. The comments in the example carry the details that would otherwise need explaining, namely that the second argument to tsf_set_output is the output type with TSF_MONO as the value shown, the third is the sample rate of 44100 and the fourth is a gain of zero, that tsf_note_on takes the preset index of zero, the note number of sixty for middle C and a velocity of 1.0f, and that the buffer of 22050 shorts at 44100 samples per second is half a second of mono audio.
The rendering call is the interesting design point. Rather than giving you a callback to fill, the library renders into a buffer you provide, and it does so in one call with a count of frames. That means the audio callback in your program is a memcpy, and it also means the library has no opinion about your audio API, which is what lets the same code drive DirectSound on Windows, ALSA on Linux and CoreAudio on macOS.
The other thing to notice is that the note handling is explicit. You turn a note on, you render, and there is a matching note off somewhere in the API for when you want the voice to stop. The library is a rendering engine with an event interface, not a scheduler, so the note timing logic is yours.
The examples, and the sound bank they ship with
The examples directory is more than sample code, because it comes with the data needed to make it run.
The documentation says there are examples available which come with a sample SoundFont file and build and play sound on Win32, Win64, Linux and MacOSX with no further dependencies. The file list confirms it: a subset sound bank named florestan-subset.sf2 sits next to the example programs, and a MIDI file named venture.mid is there as well, which suggests the examples include a MIDI driven path rather than only a note on and render path.
The build coverage is complete for the four platforms the library targets. There are shell scripts for Linux with both clang and gcc, and one for macOS, and on Windows there is a Visual Studio solution with a project file per example, along with a DirectSound project file for one of them. The Windows examples use miniaudio_io.h for audio input and output, so the Windows path is not a hand rolled device layer but a small vendored helper.
The sfotool/ directory is the other half of the story. A tool built on the same library is what you use to convert a sound bank or to inspect one, and it is a good sign that the library is not just a player but something you can build a tool on.
For a reader evaluating the project, the examples are the documentation that matters, because the API block at the top of the header tells you what is possible and the examples tell you what it looks like in practice.
The dependency list is three functions long
The dependencies section is the shortest in the project and it is the point of the whole design.
The library needs C standard libraries for fopen, math and malloc, and the documentation notes that these can be removed by providing custom functions with defines. That is the entire list: one file input function, the maths routines, and an allocator.
The malloc dependency is the one to think about in an embedded context, because replacing it means writing an allocator, and the fopen dependency is the one to think about in a console or browser target, where there is no filesystem in the conventional sense. The math dependency is usually free, since every hosted C implementation has it.
The reason the list is this short is that the library does no audio output itself. It renders samples into your buffer, so the platform audio API is your problem, and the examples demonstrate that this is manageable: miniaudio_io.h covers the Windows case, and the Linux and macOS scripts are shell scripts, which suggests the platform audio calls in those examples are short enough to live next to the render loop.
That is the architectural statement of the library. TinySoundFont is not an audio framework, and it is not a sound system. It is the part that turns a sound bank into samples, which is the part that is genuinely hard to write and the part that a lot of projects end up copying from somewhere.
The no LLM policy, and what a contributor is signing
The project has a section titled Strict No LLM / No AI Policy, and its content is worth quoting because it is unusual and because it changes what a contribution is.
No LLMs for issues. No LLMs for source contributions, patches or pull requests. AI must not be used to generate code for contributions to this project. Any pull request to the project will ask you to confirm that you are the author and that you are contributing your changes under the license of the project.
The reasoning behind the policy is visible in the shape of the repository. This is a single header file that people vendor, a single header file is the artefact that gets copied into other projects, and a defect in it is a defect in every project that copied it. A synthesiser that mishandles a preset or a modulation envelope does not fail loudly in a test, it produces wrong audio, and wrong audio that has been copied into a dozen codebases is expensive to trace back.
The author confirmation request in the pull request flow is the enforcement mechanism, and it is a licence question as much as a process one. MIT already requires that the copyright notice and permission notice travel with copies, and asking a contributor to confirm they are the author and that they contribute under the project licence is the point where that obligation is made explicit for the code itself.
For an outside reader, the practical consequence is that the code in tsf.h is written by people who wrote it. That is a meaningful property for a file you are about to paste into your product.
Where TinySoundFont is the wrong tool
The boundaries are clear, and they come from what the library is.
It is a synthesizer, not a sampler in the modern sense. There is no effect chain, no mixer, no MIDI routing, no sample rate conversion policy beyond the one you configure, and no file output. If you are building a music application, you will be writing the mixer and the effect processing yourself, and you will be looking for a fuller audio library.
It is also not a SoundFont editor or converter. The sfotool/ directory suggests a tool exists in the tree, but the documentation in the repository does not describe a command line interface for converting between bank formats, so a team that needs to author or repair sound banks should not assume that is what this project gives them.
And the single header model has a cost that shows up in a specific place: if you need to modify the synthesis engine, or if your project already has a conflicting symbol, you are editing a file that other projects also vendor, and the MIT licence gives you the right to do it but not the convenience.
The honest summary is that TinySoundFont is small, readable, dependency free and licensed permissively, and it does one thing well. For a game that needs a piano and a drum kit from two sound banks, it is an unusually good fit. For a DAW, a media framework or anything with a mixer, it is a component at best.
The check before you adopt it is short: read the API block at the top of tsf.h, confirm the five calls in the example cover what you need, and confirm that the three standard library dependencies are available on your target. If they are, the integration is one define and one include.
Editorial conclusion
Adopt TinySoundFont if you need to play SoundFont2 banks in a C or C++ program and want a synthesizer you can drop into the build as one file with no dependency to manage. Do not adopt it if you need samplers, effects, MIDI routing or anything beyond a basic render loop, because the library is a synthesizer and nothing more. Before you vendor it, read the API block at the top of tsf.h, check that the three standard library calls it relies on match your target platform, and decide early whether you need the MIDI loader header as well as the synthesizer.
Frequently asked questions
What is TinySoundFont and how do I use it?
It is a software synthesizer for SoundFont2 sound bank files, delivered as a single C header. You define TSF_IMPLEMENTATION in one translation unit, include tsf.h, load a bank with tsf_load_filename, configure the output with tsf_set_output, start a note with tsf_note_on and render samples into a buffer with tsf_render_short.
What dependencies does TinySoundFont need?
C standard libraries for fopen, math and malloc, and the documentation notes that these can be removed by providing custom functions with defines. There is no other dependency, and the examples build and play sound on Win32, Win64, Linux and MacOSX with no further dependencies.
Is TinySoundFont based on an existing project?
Yes. The library code is based on SFZero by Steve Folta, and the project credits that lineage explicitly in its documentation. The API documentation is at the top of the library source code in tsf.h rather than in a separate manual.
What is the AI contribution policy for TinySoundFont?
The project states that no LLMs are to be used for issues or for source contributions, patches or pull requests, and that AI must not be used to generate code for contributions. Any pull request asks you to confirm that you are the author and that you contribute your changes under the project licence.
What licence is TinySoundFont released under?
MIT, with the LICENSE file at the root of the repository. The project has no GitHub releases, and the last push was on 2026-07-19, so the header file in the repository is the artefact you vendor.
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/schellingb-tinysoundfont)Was this useful?