Genesis Digital Audio Workstation

Milestone: Basic Synth and MIDI Keyboard Support

2015 Mar 30

Today I reached a motivating milestone: I can play a polyphonic sine wave using a USB MIDI keyboard.

It's just a simple sine wave and there are no parameters to configure. I wasn't sure how to modulate the volume when there were multiple notes being pressed at the same time. Should it do simple addition? Then the synth could output samples above 1.0. That seems broken. Should it average the notes together? Then when you play 2 notes at once, each note is half volume of a single note. If one of the simultaneous notes had a low velocity, that seems weird.

Another problem is the clicking when you release a note. It's because the sine wave abruptly ends instead of gracefully fading towards zero:

These are problems for another day. Moving on.

I also got a delay example working. It connects your default recording device to a delay (echo) filter to your default playback device. Like the synth example, it's a C program which only depends on libgenesis. I took all the error checking code out for clarity.

#include "genesis.h"
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
    struct GenesisContext *context;

    // block until we have audio devices list

    int playback_device_index = genesis_get_default_playback_device_index(context);
    int recording_device_index = genesis_get_default_recording_device_index(context);

    struct GenesisAudioDevice *out_device = genesis_get_audio_device(context, playback_device_index);
    struct GenesisAudioDevice *in_device = genesis_get_audio_device(context, recording_device_index);

    struct GenesisNodeDescriptor *playback_node_descr;
    genesis_audio_device_create_node_descriptor(out_device, &playback_node_descr);

    struct GenesisNode *playback_node = genesis_node_descriptor_create_node(playback_node_descr);

    struct GenesisNodeDescriptor *recording_node_descr;
    genesis_audio_device_create_node_descriptor(in_device, &recording_node_descr);


    struct GenesisNode *recording_node = genesis_node_descriptor_create_node(recording_node_descr);

    struct GenesisNodeDescriptor *delay_descr = genesis_node_descriptor_find(context, "delay");
    fprintf(stderr, "delay: %s\n", genesis_node_descriptor_description(delay_descr));

    struct GenesisNode *delay_node = genesis_node_descriptor_create_node(delay_descr);

    genesis_connect_audio_nodes(recording_node, delay_node);
    genesis_connect_audio_nodes(delay_node, playback_node);


    for (;;)

Previous Post: Thread Safe Lock Free Queue Implementation

Next Post: Menu Widget Implemented

Genesis on GitHub