{"id":20010614,"url":"https://github.com/bradhowes/sf2lib","last_synced_at":"2026-02-03T00:10:58.011Z","repository":{"id":61554727,"uuid":"465057061","full_name":"bradhowes/SF2Lib","owner":"bradhowes","description":"SoundFont synthesizer in C++","archived":false,"fork":false,"pushed_at":"2024-09-30T20:43:14.000Z","size":36958,"stargazers_count":7,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-23T06:17:10.402Z","etag":null,"topics":["audio","ios","macos","sf2","soundfont"],"latest_commit_sha":null,"homepage":"","language":"Objective-C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bradhowes.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"bradhowes"}},"created_at":"2022-03-01T21:08:24.000Z","updated_at":"2025-01-17T09:43:33.000Z","dependencies_parsed_at":"2024-07-08T06:58:14.485Z","dependency_job_id":null,"html_url":"https://github.com/bradhowes/SF2Lib","commit_stats":{"total_commits":123,"total_committers":1,"mean_commits":123.0,"dds":0.0,"last_synced_commit":"984d3330897aeb86c2c1c50ab9af163b02e25a11"},"previous_names":[],"tags_count":28,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bradhowes%2FSF2Lib","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bradhowes%2FSF2Lib/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bradhowes%2FSF2Lib/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bradhowes%2FSF2Lib/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bradhowes","download_url":"https://codeload.github.com/bradhowes/SF2Lib/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252395191,"owners_count":21740984,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["audio","ios","macos","sf2","soundfont"],"created_at":"2024-11-13T07:20:46.507Z","updated_at":"2026-02-03T00:10:58.005Z","avatar_url":"https://github.com/bradhowes.png","language":"Objective-C++","funding_links":["https://github.com/sponsors/bradhowes"],"categories":[],"sub_categories":[],"readme":"[![CI][status]][ci]\n[![COV][cov]][ci]\n[![][spiv]][spi]\n[![][spip]][spi]\n[![][mit]][license]\n\n# SF2Lib - a SoundFont (SF2) synthesizer in C++\n\nThis library can read SF2 SoundFont files and render audio samples from them in real-time. It properly reads in a\ncompliant SF2 file and can be used to obtain meta data such as preset names. It also has an audio rendering engine that\ncan generate audio samples for key events that come from (say) a MIDI keyboard. This library is currently being used by\nmy [SoundFonts][sf] and [SoundFontsPlus][sfp] applications for SF2 file parsing and, in the latter app, as the sample\ngenerating engine.\n\nAlthough most of the library code is generic C++17/23, there are a few bits that expect an Apple platform that has\nthe AudioToolbox and Accelerate frameworks available. The goal is to be a simple library for reading SF2 files as well\nas a competent SF2 audio renderer whose output can be fed to any sort of audio processing chain, but it would probably\ntake some effort to remove it from the Apple ecosystem.\n\nNote that this package depends on some general DSP headers and audio classes from my [DSPHeaders][dsp] package which is\nalso used by my various AUv3 extensions.\n\n# SF2 Spec Support\n\nCurrently, all SF2 generators and modulators are supported and/or implemented according to the [SoundFont Spec\nv2][spec]. However, this library does not currently contain chorus or reverb effects. When rendering, the library will\nproperly route a percentage of the signal to a chorus and reverb bus/channel if it is provided using the generator\nsettiings that configure the percentage.\n\nThe render [Engine][engine] `renderInto` method takes a [Mixer][mixer] instance which supports a main _dry_ bus and two\nadditional busses for the _chorus effect send_ and the _reverb effect send_. These are populated with samples from\nactive voices, and their levels are controlled by the `chorusEffectSend` and `reverbEffectSend` parameters mentioned\nabove. One can then connect bus 1 to a chorus effect and bus 2 to a reverb, and then connect those outputs and bus 0 of\nthis library to a mixer to generate the final output.\n\n# Code\n\nHere is a rough description of the top-level folders in SF2Lib:\n\n* [Engine](Sources/Engine) -- a collection of C++ wrappers that use Swift/C++ bridging annotations to allow for\neasy importing into Swift code of elements from the SF2File and SF2Lib packages.\n* [SF2File](Sources/SF2File) -- collection of classes that provides for loading an SF2 file according to the container\ndefinitions found in the SF2 v2 specification.\n* [SF2Lib](Sources/SF2Lib) -- collection of classes used for sample rendering and MIDI processing.\n* [SF2Util](Sources/SF2Util) -- various utility classes and functions used by the other libraries.\n* [TestUtils](Sources/TestUtils) -- various utility classes and functions used by the unit tests.\n\n# Unit Tests\n\nThere are quite a large number of unit tests that cover a good chunk of the code base. There are even some rendering\ntests that will play audio at the end if configured to do so. This option is found in the\n[Package.swift](Package.swift#L12) file, in the line `let playAudioDuringTests = false`. Change the `false` to `true` to \nenable the audio output for *all* tests. This will increase the test run time, but it can be helpful when making code changes.\n\nAlternatively, the unit tests with rendering capability have a `playAudio` attribute which can be set to `true` to play\nthe rendered output from a test. Note that the test results do not depend on this setting, but again enabling it does\nincrease the time it takes to run the tests due to the time it takes to play back the recorded audio samples.\n\n# Performance\n\nThe current code has not been optimized for speed, but it still performs very well on modern devices, including mobile.\nThere are two tests (currently) that provide performance metrics:\n\n* testEngineRenderPerformanceUsingCubic4thOrderInterpolation\n* testEngineRenderPerformanceUsingLinearInterpolation\n\nAs their name suggests, these exercise a specific interpolation method. They both generate 1 second of audio at a 48K\nsample rate, rendering 96 simultaneous notes. On an optimized build, the more expensive cubic 4th-order interpolation\ntests take ~0.27s to complete, or ~1/4 of the time budget. The faster linear interpolation is down to ~0.25s.\n\nAdditional performance gains could be had by following the approach of [FluidSynth][fluid] and render 64 samples at a\ntime with no changes to most of the modulators and generators. Furthermore, one could check the pending MIDI event list\nto see if it is empty, and choose a path that supports vectorized rendering.\n\n# Swift Integration\n\nAll of the code in this package is C++/Objective C++ but the Swift package now depends on Swift v6.0 or later in order\nto obtain access to the Swift C++ bridging that is now available. The bridging code is only found in the\n[Engine](Sources/Engine) library component. It defines three bridging wrappers:\n\n* [SF2Engine](Sources/Engine/include/SF2Engine.hpp) -- provides a way to create a new `SF2::Render::Engine` instance and\nsafely pass around in the Swift environment.\n* [SF2FileInfo](Sources/Engine/include/SF2FileInfo.hpp) -- wrapper the reveals meta data of an SF2 file, and an\ninterator for the presets it defines.\n* [SF2PresetInfo](Sources/Engine/include/SF2PresetInfo.hpp) -- wrapper for the meta data of a preset in an SF2 file.\n\nNote that the most of the rendering and SF2 containers are not exposed by the Swift bridge, as they are not pertinent\nwhen using the library for rendering in an AUv3 context.\n\n# Credits\n\nAll of the code has been written by myself over the course of several years, but I have benefitted from the existence of\nother projects, especially [FluidSynth][fluid] and their wealth of knowledge in all things SF2. In particular, if there\nis any confusion about what the SF2 spec means, I rely on their interpretation in code. That said, any\nmisrepresentations of SF2 functionality are of my own doing.\n\n[ci]: https://github.com/bradhowes/SF2Lib/actions/workflows/CI.yml\n[status]: https://github.com/bradhowes/SF2Lib/workflows/CI/badge.svg\n[cov]: https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/bradhowes/dbe62f18182c82eb36dc1030819bc54b/raw/SF2Lib-coverage.json\n[spi]: https://swiftpackageindex.com/bradhowes/SF2Lib\n[spiv]: https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fbradhowes%2FSF2Lib%2Fbadge%3Ftype%3Dswift-versions\n[spip]: https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fbradhowes%2FSF2Lib%2Fbadge%3Ftype%3Dplatforms\n[mit]: https://img.shields.io/badge/License-MIT-A31F34.svg\n[license]: https://opensource.org/licenses/MIT\n[dsp]: https://github.com/bradhowes/DSPHeaders\n[fluid]: https://www.fluidsynth.org\n[sf]: https://github.com/bradhowes/SoundFonts\n[sfp]: https://github.com/bradhowes/SoundFontsPlus\n[spec]: SoundFont%20Spec%202.01.pdf\n[engine]: Sources/SF2Lib/include/SF2Lib/Render/Engine/Engine.hpp\n[mixer]: Sources/SF2Lib/include/SF2Lib/Render/Engine/Mixer.hpp\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbradhowes%2Fsf2lib","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbradhowes%2Fsf2lib","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbradhowes%2Fsf2lib/lists"}