FluidLite

repository·master·Indexed 41 days ago

https://github.com/divideconcept/fluidlite

A lightweight, dependency-independent C library for software synthesis providing a minimal version of FluidSynth functionality. It supports SF3 files and relies only on standard C libraries, requiring external implementation for MIDI file reading, realtime MIDI events, and audio output.

Tokens
1.3K
Snippets
3
Records
4
Agent score
50%

What's inside FluidLite

  1. Overview of FluidLite

    master

    FluidLite is a lightweight version of FluidSynth designed to be hardware, platform, and external dependency independent. It relies only on standard C libraries.

    Key Features:

    • Supports SF3 files (SF2 files compressed with ogg vorbis).
    • Allows removing the channel 9 (drums) constraint using fluid_settings_setstr(settings, "synth.drums-channel.active", "no");. You can still use drum kits by selecting bank 128 on any channel.

    Important Limitations: FluidLite provides minimal functionality (settings and synth only). You must implement the following externally:

    • MIDI file reading
    • Realtime MIDI events
    • Audio output
  2. Configure and build FluidLite with CMake

    master

    FluidLite uses CMake for configuration and building. You can enable SF3 support or use stb_vorbis for decompression via build flags.

    Build Options:

    • -DENABLE_SF3=YES: Enables SF3 support (default is disabled).
    • -DSTB_VORBIS=YES: Uses stb_vorbis to decompress SF3 instead of Xiph's libogg/libvorbis.

    Common Commands:

    Configure with debug symbols:

    cmake -S <source-directory> -B <build-directory> -DCMAKE_BUILD_TYPE=Debug

    Configure with an install prefix:

    cmake -S <source-directory> -B <build-directory> -DCMAKE_INSTALL_PREFIX=/usr/local

    Configure with additional dependency search paths:

    cmake -S <source-directory> -B <build-directory> -DCMAKE_PREFIX_PATH=${HOME}/tests

    Build (compile) the sources:

    cmake --build <build-directory>

    Install the compiled products (requires CMake 3.15+):

    cmake --install <build-directory>
    cmake -S <source-directory> -B <build-directory> -DCMAKE_INSTALL_PREFIX=/usr/local
  3. Integrate FluidLite into a CMake project

    master

    You can integrate FluidLite into your project using one of three methods:

    1. Using find_package(fluidlite): For installed versions.
    2. Using pkg-config:
      find_package(PkgConfig REQUIRED)
      pkg_check_modules(fluidlite REQUIRED fluidlite)
    3. Using a subdirectory (e.g., Git submodule): Use add_subdirectory() and include aliases.cmake to access the exported targets.

    Available Linkable Targets: Once aliases.cmake is included or find_package(fluidlite) is called, you can link directly to:

    • fluidlite::fluidlite-static: The static library.
    • fluidlite::fluidlite: The shared dynamic library.
    add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/FluidLite)
    include(${CMAKE_CURRENT_SOURCE_DIR}/FluidLite/aliases.cmake)
    
    target_link_libraries(${PROJECT_NAME} PRIVATE
        fluidlite::fluidlite-static
        ${MATH_LIB}
    )
  4. Basic usage example with FluidLite API

    master

    This example demonstrates the basic lifecycle of using FluidLite: creating settings, initializing a synth, loading a SoundFont, triggering a note, and writing audio to a buffer.

    Workflow:

    1. Create settings with new_fluid_settings().
    2. Create a synth with new_fluid_synth(settings).
    3. Load a SoundFont using fluid_synth_sfload(synth, "filename.sf2", bank).
    4. Trigger notes with fluid_synth_noteon(synth, channel, note, velocity).
    5. Write audio data using fluid_synth_write_float(...).
    6. Clean up with delete_fluid_synth(synth) and delete_fluid_settings(settings).
    #include <stdlib.h>
    #include <stdio.h>
    #include "fluidlite.h"
    
    #define SAMPLE_RATE 44100
    #define SAMPLE_SIZE sizeof(float)
    #define NUM_FRAMES SAMPLE_RATE
    #define NUM_CHANNELS 2
    #define NUM_SAMPLES (NUM_FRAMES * NUM_CHANNELS)
    
    int main() {
        fluid_settings_t* settings = new_fluid_settings();
        fluid_synth_t* synth = new_fluid_synth(settings);
        fluid_synth_sfload(synth, "soundfont.sf2", 1);
    
        float* buffer = calloc(SAMPLE_SIZE, NUM_SAMPLES);
        FILE* file = fopen("float32output.pcm", "wb");
    
        fluid_synth_noteon(synth, 0, 60, 127);
        fluid_synth_write_float(synth, NUM_FRAMES, buffer, 0, NUM_CHANNELS, buffer, 1, NUM_CHANNELS);
        fwrite(buffer, SAMPLE_SIZE, NUM_SAMPLES, file);
    
        fluid_synth_noteoff(synth, 0, 60);
        fluid_synth_write_float(synth, NUM_FRAMES, buffer, 0, NUM_CHANNELS, buffer, 1, NUM_CHANNELS);
        fwrite(buffer, SAMPLE_SIZE, NUM_SAMPLES, file);
    
        fclose(file);
        free(buffer);
        delete_fluid_synth(synth);
        delete_fluid_settings(settings);
        return 0;
    }