Genesis is a cross-platform digital audio workstation with ambitious goals: peer-to-peer multiplayer editing, complete plugin safety, and a built-in community which shares plugins, projects, and samples.
Genesis aims to make music creation collaborative, global, free, and open source.
Genesis is not ready for serious users yet. If you're excited about the project, follow the development blog or sustain development with financial support.
delay.c
- default recording device connected to a delay effect connected
to default playback device.synth.c
- default midi keyboard connected to a synth connected to default
playback device.list_devices.c
- list available audio and midi devices and watch for when
devices are added or removed.list_supported_formats.c
- list available audio import and export formats.normalize_audio.c
- open an audio file, normalize it, and export it as a
new file.libgenesis is programmed in a tiny subset of C++:
new
or delete
.public
.mkdir build
cd build
cmake ..
make
./genesis
make test
sudo apt-get install lcov
make coverage
# view `coverage/index.html` in a browser
When you build, you have 2 choices:
Debug
: slower, but contains useful information for reporting and fixing
bugs. This is the default configuration.Release
: generates optimized code, but if the software crashes or
misbehaves, it is difficult to troubleshoot.To build in Release
mode:
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make
./genesis
Most operating systems do not attempt to make any real-time guarantees. This means that various operations do not guarantee a maximum bound on how long it might take. For example, when you allocate memory, it might be very quick, or the kernel might have to do some memory defragmentation and cache invalidation to make room for your new segment of memory. Writing to a hard drive might cause it to have to warm up and start spinning.
This can be a disaster if one of these non-bounded operations is in the audio rendering pipeline, especially if the latency is low. The buffer of audio going to the sound card might empty before it gets filled up, causing a nasty audio glitch sound known as a "buffer underrun".
In general, all syscalls are suspect when it comes to real-time guarantees. The careful audio programmer will avoid them all.
libgenesis meets this criteria with one exception. libgenesis takes advantage of hardware concurrency by using one worker thread per CPU core to render audio. It carefully uses a lock-free queue data structure to avoid making syscalls, but when there is not enough work to do and some threads are sitting idly by, those threads need to suspend execution until there is work to do.
So if there is more work to be done than worker threads, no syscalls are made.
However, if a worker thread has nothing to do and needs to suspend execution,
it makes a FUTEX_WAIT
syscall, and then is woken up by another worker thread
making a FUTEX_WAKE
syscall.
libgenesis follows semver. Major version is bumped when API or ABI compatibility is broken. Minor version is bumped when new features are added. Patch version is bumped only for bug fixes. Until 1.0.0 is released no effort is made toward backward compatibility whatsoever.
Genesis Audio Studio has an independent version from libgenesis. Major version is bumped when a project file will no longer generate the same output audio as the previous version. Minor version is bumped when new features are added. Patch version is bumped only for bug fixes. Until 1.0.0 is released no effort is made toward project files being backward compatible to previous versions.
Positions in the audio project are in floating point whole notes. This is to take into account the fact that the tempo and time signature could change at any point in the audio project. You can convert from whole notes to frames by calling a utility function which takes into account tempo and time signature changes.
The first 16 bytes of every Genesis project file are:
ca2f 5ef5 00d8 ef0b 8074 18d0 e40b 7a4f
This uniquely identifies the file as a Genesis project file. The default file
extension is .gdaw
.
After this contains an ordered list of transactions. A transaction is a set of edits. There are 2 types of edits: put and delete.
A put contains a key and a value, each of which is a variable number of bytes. A delete contains only a key, which is a variable number of bytes.
A transaction looks like this:
Offset | Description
-------+------------
0 | uint32be crc32 of this transaction, everything excluding this field
4 | uint32be length of transaction in bytes including this and crc32
8 | uint32be number of put edits in this transaction
12 | uint32be number of delete edits in this transaction
16 | the put edits in this transaction
- | the delete edits in this transaction
A put edit looks like:
Offset | Description
-------+------------
0 | uint32be key length in bytes
4 | uint32be value length in bytes
8 | key bytes
- | value bytes
A delete edit looks like:
Offset | Description
-------+------------
0 | uint32be key length in bytes
4 | key bytes
That's it. To read the file, apply the transactions in order. To update a file, append a transaction. Periodically "garbage collect" by creating a new project file with a single transaction with all the data, and then atomically rename the new project file over the old one.
Genesis is licensed with the General Public License. A full copy of the license text is included in the LICENSE file, but here's a non-normative summary:
As a user you have access to the source code, and if you are willing to compile from source yourself, you can get the software for free.
As a company you may use the source code in your software as long as you publish your software's source code under a free software license.