https://github.com/anokta/barelymusician
a real-time music engine.
https://github.com/anokta/barelymusician
daisy game-audio game-development gamedev gdextension generative-music godot interactive-music livecoding unity webaudio
Last synced: 8 days ago
JSON representation
a real-time music engine.
- Host: GitHub
- URL: https://github.com/anokta/barelymusician
- Owner: anokta
- License: mit
- Created: 2018-01-16T07:40:31.000Z (over 8 years ago)
- Default Branch: main
- Last Pushed: 2026-04-01T23:59:15.000Z (3 months ago)
- Last Synced: 2026-04-02T09:41:43.204Z (3 months ago)
- Topics: daisy, game-audio, game-development, gamedev, gdextension, generative-music, godot, interactive-music, livecoding, unity, webaudio
- Language: C++
- Homepage: http://www.barelymusician.com
- Size: 11.2 MB
- Stars: 39
- Watchers: 7
- Forks: 0
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE.md
Awesome Lists containing this project
README
barelymusician
[](https://github.com/anokta/barelymusician/actions/workflows/ci.yml)
[](https://github.com/sponsors/anokta)
==============
barelymusician is a real-time music engine for interactive systems.
It provides a modern C/C++ API to generate and perform musical sounds from scratch with sample
accurate timing.
This repository includes build targets for Windows, macOS, Linux, Android, WebAssembly, and Daisy,
as well as a Godot GDExtension, a native Unity plugin, and a VST instrument plugin.
To use in a project, simply include [barelymusician.h](include/barelymusician.h).
To use in Godot, download the latest version of
[barelymusiciangodot.zip](https://github.com/anokta/barelymusician/releases/latest/download/barelymusiciangodot.zip).
To use in Unity, download the latest version of
[barelymusician.unitypackage](https://github.com/anokta/barelymusician/releases/latest/download/barelymusician.unitypackage).
Just curious? Try the experimental web toy at [barelymusician.com](http://www.barelymusician.com).
For background about this project, see the original research paper
[here](http://www.aes.org/e-lib/browse.cfm?elib=17598), and the legacy Unity implementation
[here](https://github.com/anokta/barelyMusicianLegacy).
Example usage
-------------
```cpp
#include
// Create the engine.
barely::Engine engine(/*sample_rate=*/48000);
// Set the global tempo.
engine.SetTempo(/*tempo=*/124.0);
// Create a new instrument.
auto instrument = engine.CreateInstrument();
// Set the instrument to use full oscillator mix.
instrument.SetControl(barely::InstrumentControlType::kOscMix, /*value=*/1.0f);
// Set an instrument note on.
//
// Notes are expressed in octaves relative to middle C as the center frequency. Fractional note
// values adjust the frequency logarithmically to ensure equally perceived pitch intervals within
// each octave.
constexpr float kC4Pitch = 0.0f;
instrument.SetNoteOn(kC4Pitch);
// Create a new performer.
auto performer = engine.CreatePerformer();
// Set the performer to looping.
performer.SetLooping(/*is_looping=*/true);
// Create a new task that plays an instrument note every beat.
auto task = performer.CreateTask(/*position=*/0.0, /*duration=*/1.0, /*priority=*/0,
[&](barely::TaskEventType type) {
constexpr float kC3Pitch = -1.0f;
if (type == barely::TaskEventType::kBegin) {
instrument.SetNoteOn(kC3Pitch);
} else if (type == barely::TaskEventType::kEnd) {
instrument.SetNoteOff(kC3Pitch);
}
});
// Start the performer playback.
performer.Start();
// Update the engine timestamp.
//
// Timestamp updates must occur before processing the engine with the respective timestamps.
// Otherwise, `Process` calls may be *late* in receiving relevant changes to the engine. To address
// this, `Update` should typically be called from the main thread update callback using a lookahead
// to prevent potential thread synchronization issues in real-time audio applications.
constexpr double kLookahead = 0.1;
double timestamp = 0.0;
engine.Update(timestamp + kLookahead);
// Process the next output samples of the engine.
//
// The engine processes output samples synchronously. Therefore, `Process` should typically be
// called from an audio thread process callback in real-time audio applications.
constexpr int kChannelCount = 2;
constexpr int kFrameCount = 512;
float output_samples[kChannelCount * kFrameCount];
engine.Process(output_samples, kChannelCount, kFrameCount, timestamp);
```
Further examples can be found in [examples/demo](examples/demo), e.g. to run the
[instrument_demo.cpp](examples/demo/instrument_demo.cpp):
```sh
python build.py --run_demo instrument_demo
```