IMPORTANT: Floe is heavily under development. This manual is a work-in-progress.

Some things may be incorrect, missing or broken. We are bit-by-bit filling in the gaps ahead of version 1.0.0.


Floe


No-hassle sample library player: free for all

Floe is a free, open-source sample library engine in CLAP, VST3 and AU audio plugin formats. It provides expressive playback and sound-shaping of sample libraries in the [Floe format](./sample-library-format.md).

Floe’s GUI

Overview

Floe is a free, open-source sample library engine.

It loads sample libraries in the Floe format: supporting both realistic virtual instruments and sample-based synthesis. Sample libraries are installed separately from Floe.

Floe is a CLAP, VST3 or AU plugin on Windows and macOS.

Developed by FrozenPlain. Floe’s ancestor, Mirage, has been used by thousands of musicians and producers in 13 products.

Floe’s mission

  1. Make sample libraries more expressive, playable and effective in music production.
  2. Lengthen the lifespan of sample libraries by providing a open-source platform for them with no lock-in.
  3. Prioritise helping users make meaningful music; not technical hassle, commercial pressure or unnecessary complexity.

Key features

Simple and effective

  • Three-layer architecture for blending timbres into new sounds
  • Sound-shaping parameters: envelopes, filters, LFOs and an effects rack
  • Supports realistic multi-sampled instruments: velocity layers, round-robin, crossfade layers [coming soon]
  • Supports sample-based synthesis: using samples like ‘oscillators’ with sound-looping features
  • Powerful tag-based browsers for finding new sounds and presets [coming soon]
  • Make samples come alive with MIDI MPE support [coming soon]
  • Combine sounds across all sample libraries
  • CPU-efficient

Focused on helping you make music

  • 100% free: no lock-in, no sign-up, no nagging, no features behind a paywall
  • ‘Organic’ software: made by a passionate developer who cares about making great software and is always open to feedback
  • Open-source, free software. Floe is always yours: the GPL license guarantees anyone can use, modify and share the code
  • Floe sample libraries are open packs of FLAC/WAV files: use them in other software too
  • Thoughtfully designed; thoroughly documented

Sample library development

  • Create your own sample libraries using Lua scripts
  • Great developer-experience for creating sample libraries; just write Lua code and Floe instantly applies the changes
  • No recreating GUIs: Floe provides a powerful GUI for your sample library (GUI customisation will be added in the future)

Continuously improving

  • Regular updates
  • Always backwards-compatible

About this website

This website contains everything you need to know about Floe. It’s presented in a book-like format, with chapters in the sidebar.

Latest Floe version: 0.0.1

If you’re viewing this online, you might find the search feature useful: open it by clicking the magnifying glass icon at the top of the page. Additionally, there is a printer icon in the top right for either printing this book, or saving it to a PDF.

Previously known as Mirage

Floe is a continuation of FrozenPlain’s Mirage plugin (developed from 2018 to 2023). It adds new features and improvements but is based on the same core architecture. Mirage will no longer be developed. Floe starts from version 1.0 rather than continuing from Mirage’s version number.

Why the name change?

The project has taken a new direction and so we decided to give it a new name.

  • Floe is free and open-source, whereas Mirage was closed-source.
  • Floe is not directly tied to FrozenPlain. It’s a separate project that’s open to anyone.
  • Mirage is already the name of a hardware sampler from the 80s - we wanted to avoid confusion.

Backwards-compatible with Mirage

Floe can load Mirage’s libraries and presets. If you have Mirage installed already, Floe will be able to find the same libraries and presets as Mirage.

You can leave Mirage installed if you want to keep using it: Floe will not interfere with Mirage’s installation.

However, Floe is a new plugin with a new name that targets new plugin formats. Your old DAW projects that use Mirage will still need Mirage, Floe can’t replace Mirage in that sense.

The old Mirage installer

Previously, when Floe was known as Mirage, the installer would also install sample libraries. This is no longer the case. For Floe, sample libraries have a separate installation process.

Additionally, the installer used to require an internet connection and an account or download-ticket. For Floe, the installer is just a simple offline program with no credentials required.

Requirements

Floe is an audio plugin for Windows and macOS. It’s available in the following audio plugin formats: CLAP (Windows and macOS), VST3 (Windows and macOS) and AU (macOS only).

There’s no ‘standalone’ version at the moment. And also no Linux version, but it’s planned. Finally, there’s no AAX (Pro Tools) version.

Windows

  • Windows 10 or later
  • 64-bit computer
  • CLAP or VST3 host

macOS

  • macOS 11 (Big Sur) or later
  • Apple Silicon or Intel (Floe is a universal binary)
  • CLAP, AU (v2) or VST3 host

Plugin Hosts (DAWs)

Examples of CLAP/VST3 hosts on Windows & macOS include: Reaper, Bitwig, Cubase, Ableton Live, Studio One, and countless others.

Examples of AU hosts on macOS include: Logic Pro, GarageBand, and more.

Installing Floe

There’s two ways to install Floe: using the installer, or manually. Floe is backwards-compatible. This means that you can install a new version of Floe over an old version.

  1. Unzip the installer file. This is normally just a matter of double-clicking the file.
  2. Close your DAW.
  3. Run the installer program.
  4. Follow the instructions, including choosing the plugin formats you want to install.
  5. Done. Floe will be available to your DAW - but you might yet need to install sample libraries.

Manual Installation

Normally you’ll want to use the installer, but there could be some cases where you’d prefer to install Floe manually. To allow for this, we provide a zip file that contains Floe’s plugin files.

Windows:

  • CLAP: Move Floe.clap into C:\Program Files\Common Files\CLAP
  • VST3: Move Floe.vst3 into C:\Program Files\Common Files\VST3

macOS:

  • CLAP: Move Floe.clap into /Library/Audio/Plug-Ins/CLAP
  • VST3: Move Floe.vst3 into /Library/Audio/Plug-Ins/VST3
  • AU: Move Floe.component into /Library/Audio/Plug-Ins/Components

Next, you might need to install sample libraries.

Installing sample libraries

Floe Package

A Floe Package is a zip file with the ending .floe.zip. It must contain either a subfolder called Libraries containing sample libraries, or a subfolder called Presets containing preset folders, or both.

Floe can install Floe Packages via the GUI.

Single library + factory presets

Floe Packages typically contain a single library and a set of factory presets.

📦FrozenPlain - Arctic Strings.floe.zip/
├── 📁Libraries/
│   └── 📁Arctic Strings/
│       ├── 📄arctic-strings.floe.lua
│       ├── 📁Samples/
│       │   ├── 📄strings_c4.flac
│       │   └── 📄strings_d4.flac
│       └── 📁Images/
│           ├── 📄background.png
│           └── 📄icon.png
└── 📁Presets/
    └── 📁Arctic Strings Factory/
        ├── 📁Realistic/
        │   ├── 📄Octaved.floe-preset
        │   └── 📄Soft.floe-preset
        └── 📁Synthetic/
            ├── 📄Bright.floe-preset
            └── 📄Warm.floe-preset

Bundle of libraries

Floe Packages can contain multiple libraries or presets.

📦Audioata - Synthwave Bundle.floe.zip/
├── 📁Libraries/
│   ├── 📁Synthwave Bass/
│   │   ├── 📄synthwave-bass.floe.lua
│   │   └── 📁Samples/
│   │       ├── 📄bass_c1.flac
│   │       └── 📄bass_d1.flac
│   ├── 📁Synthwave Drums/
│   │   ├── 📄synthwave-drums.floe.lua
│   │   └── 📁Samples/
│   │       ├── 📄kick.flac
│   │       └── 📄snare.flac
│   └── 📁Synthwave Synths/
│       ├── 📄synthwave-synths.floe.lua
│       └── 📁Samples/
│           ├── 📄synth_c4.flac
│           └── 📄synth_d4.flac
└── 📁Presets/
    └── 📁Synthwave Factory/
        ├── 📄Clean.floe-preset
        ├── 📄Dirty.floe-preset
        ├── 📄Big.floe-preset
        ├── 📄Small.floe-preset
        ├── 📄Bright.floe-preset
        └── 📄Warm.floe-preset

Uninstalling

Floe doesn’t yet have an uninstaller program. But you can manually uninstall it by deleting Floe’s files.

Firstly, you will want to delete Floe’s libraries and presets. The easiest way to do this is as follows:

  • Open Floe
  • Click on the cog icon at the top.
  • For each of the paths click the open folder icon . This will open the folder in your file manager.
  • Delete the folder that opens.
  • Repeat this for each path.

Next, you can delete Floe’s settings file.

Floe Library Format

Overview

Floe sample libraries are plain, open folders of audio files (FLAC or WAV). They are accompanied by a floe.lua file that describes how the samples are mapped and configured.

It is a new format, along the same lines as SFZ or DecentSampler but focusing on ease-of-use and extensibility, and bringing the power of a full programming language to ease developing complicated library configurations.

📂FrozenPlain - Slow/
├── 📄slow.floe.lua
├── 📄Licence.html
├── 📄About Slow.html
├── 📁Samples/
│   ├── 📄synth_sustain_c4.flac
│   └── 📄synth_sustain_d4.flac
└── 📁Images/
    ├── 📄background.png
    └── 📄icon.png

Developer documentation

Sample libraries are configured using a file written in the Lua programming language1 (version 5.4).

Let’s start with a simple example of a floe.lua file:

local library = floe.new_library({
    name = "Iron Vibrations",
    tagline = "Organic sounds from resonating metal objects",
    url = "https://example.com/iron-vibrations",
    description = "A collection of resonating metal objects sampled using a handheld stereo recorder.",
    author = "Found-sound Labs",
    minor_version = 1,
    background_image_path = "images/background.jpg",
    icon_image_path = "images/icon.png",
})

local instrument = floe.new_instrument(library, {
    name = "Metal Fence Strike",
    folders = "Fences/Steel",
    description = "Tonal pluck metallic pluck made from striking a steel fence.",
    tags = { "Pluck", "Metallic", "Organic" },
    waveform_audio_path = "samples/file1.flac",
})

floe.add_region(instrument, {
    file = {
        path = "One-shots/Resonating String.flac",
        root_key = 60,
        loop = { 24, 6600, 100, false },
    },
    trigger_criteria = {
        trigger_event = "note-on",
        key_range = { 60, 64 },
        velocity_range = { 0, 100 },
        round_robin_index = 0,
    },
    options = {
        timbre_crossfade_region = { 0, 50 },
        auto_map_key_range_group = "group1",
        feather_overlapping_velocity_regions = false,
    },
})

floe.add_ir(library, {
    name = "Cathedral",
    path = "irs/cathedral.flac",
})

return library

Floe automatically scans for Lua files in its sample library folders (these are configurable in the settings). It looks for files called floe.lua, or files ending with .floe.lua; for example, woodwind-textures.floe.lua. Floe automatically detects when files are added, removed or changed, and will immediately apply the changes.

Floe provides an API (a set of functions) to floe.lua files. This API is available under a table called floe, for example, floe.new_instrument(...). It features functions for creating a library, creating instruments, adding regions and impulse responses. At the end of your floe.lua file, you return the library object created with floe.new_library(...).

A floe.lua file is only concerned with mapping and configuring audio-files. Sound-shaping parameters such as envelopes, filters and effects are offered by-default on Floe’s GUI.

In other sample library formats such as SFZ or Kontakt, regions are arranged into ‘groups’. Floe does not have this concept. Instead, the features of the Lua programming language (such as functions or loops) can be used to apply similar configuration to a set of regions. Additionally, Floe offers a function called floe.extend_table(base_table, table), which allows new tables to be created that are based off an existing table.

Additionally, a floe.lua file has access to some of Lua’s standard libraries: math, string, table, utf8. The other standard libraries are not accessible to Lua - including the require function. This is to minimise security risks.

Core Functions

floe.new_library

Creates a new library. It takes one parameter: a table of configuration and returns a new library object. You should only call this once.

local library = floe.new_library({
    -- The name of the library. [required]
    name = "Iron Vibrations",

    -- A few words to describe the library. [required]
    tagline = "Organic sounds from resonating metal objects",

    -- The URL associated with the library.
    -- [optional, default: no url]
    url = "https://example.com/iron-vibrations",

    -- A description of the library.
    -- [optional, default: no description]
    description = "A collection of resonating metal objects sampled using a handheld stereo recorder.",

    -- The name of the creator of this library. [required]
    author = "Found-sound Labs",

    -- The minor version of this library - backwards-compatible changes are 
    -- allowed on a library; this field represents that. Non-backwards-compatibile 
    -- changes are not allowed: you'd need to create a new library such as: 
    -- "Strings 2".
    -- [optional, default: 1]
    minor_version = 1,

    -- Path relative to this script for the background image. It should be a jpg 
    -- or png.
    -- [optional, default: ]
    background_image_path = "images/background.jpg",

    -- Path relative to this script for the icon image. It should be a square jpg 
    -- or png.
    -- [optional, default: ]
    icon_image_path = "images/icon.png",
})

The library is the top-level object. It contains all the instruments, regions, and impulse responses.

floe.new_instrument

Creates a new instrument on the library. It takes 2 parameters: the library object and a table of configuration. It returns a new instrument object. You can call this function multiple times to create multiple instruments.

local instrument = floe.new_instrument(library, {
    -- The name of the instrument. Must be unique. [required]
    name = "Metal Fence Strike",

    -- Words separated by slashes used to hierarchically categorise the 
    -- instrument.
    -- [optional, default: no folders]
    folders = "Fences/Steel",

    -- A description of the instrument.
    -- [optional, default: no description]
    description = "Tonal pluck metallic pluck made from striking a steel fence.",

    -- An array of strings to denote properties of the instrument.
    -- [optional, default: no tags]
    tags = { "Pluck", "Metallic", "Organic" },

    -- Path to an audio file relative to this script that should be used as the 
    -- waveform on Floe's GUI.
    -- [optional, default: first region path]
    waveform_audio_path = "samples/file1.flac",
})

An instrument is like a musical instrument. It is a sound-producing entity that consists of one or more samples (samples are specified in regions). Each library can have multiple instruments.

floe.add_region

Adds a region to an instrument. It takes 2 parameters: the instrument object and a table of configuration. You can call this function multiple times to create multiple regions. Doesn’t return anything.

floe.add_region(instrument, {
    -- The file for this region. [required]
    file = {
        -- A path to an audio file, relative to this current lua file. [required]
        path = "One-shots/Resonating String.flac",

        -- The pitch of the audio file as a number from 0 to 127 (a MIDI note 
        -- number). On a range from 0 to 127. [required]
        root_key = 60,

        -- The region of the file that can be looped. It should be an array: 3 
        -- integers and 1 boolean: { start, end, crossfade, is_ping_pong boolean 
        -- }. Note that the end number is not inclusive. The start and end numbers 
        -- can be negative meaning they index the file from the end rather than 
        -- the start. For example, -1 == number_frames_in_file, -2 == 
        -- (number_frames_in_file - 1), etc.
        -- [optional, default: no loop]
        loop = { 24, 6600, 100, false },
    },

    -- How this region should be triggered.
    -- [optional, default: defaults]
    trigger_criteria = {
        -- What event triggers this region. Must be one of: "note-on" or 
        -- "note-off".
        -- [optional, default: note-on]
        trigger_event = "note-on",

        -- The pitch range of the keyboard that this region is mapped to. These 
        -- should be MIDI note numbers, from 0 to 127. Note that the end number is 
        -- not inclusive.
        -- [optional, default: { 60, 64 }]
        key_range = { 60, 64 },

        -- The velocity range of the keyboard that this region is mapped to. This 
        -- should be an array of 2 numbers ranging from 0 to 100. The first number 
        -- represents the start of the velocity range and the second number 
        -- represents 1-past the end of the range.
        -- [optional, default: { 0, 100 }]
        velocity_range = { 0, 100 },

        -- Trigger this region only on this round-robin index. For example, if 
        -- this index is 0 and there are 2 other groups with round-robin indices 
        -- of 1 and 2, then this region will trigger on every third press of a key 
        -- only.
        -- [optional, default: no round-robin]
        round_robin_index = 0,
    },

    -- Additional options for this region.
    -- [optional, default: defaults]
    options = {
        -- The start and end point, from 0 to 100, of the Timbre knob on Floe's 
        -- GUI that this region should be heard. You should overlay this range 
        -- with other timbre_crossfade_regions. Floe will create an even crossfade 
        -- of all overlapping sounds. Note that the end number is not inclusive.
        -- [optional, default: no timbre-crossfade]
        timbre_crossfade_region = { 0, 50 },

        -- For every region that matches this group, automatically set the start 
        -- and end values for each region's key range based on its root key. Only 
        -- works if all region's velocity range are the same.
        -- [optional, default: no auto-map]
        auto_map_key_range_group = "group1",

        -- If another region is triggered at the same time as this one and is 
        -- overlapping this, then both regions will play crossfaded together. This 
        -- smooths the transitions between velocity layers.
        -- [optional, default: false]
        feather_overlapping_velocity_regions = false,
    },
})

A region is a part of an instrument. It defines an audio file and the conditions under which it will be played. For example, you might have a region that plays the audio file Piano_C3.flac when the note C3 is played. Each instrument must have one or more regions.

floe.add_ir

Adds an reverb impulse response to the library. It takes 2 parameters: the library object and a table of configuration. You can call this function multiple times to create multiple impulse responses. Doesn’t return anything.

floe.add_ir(library, {
    -- The name of the IR. Must be unique. [required]
    name = "Cathedral",

    -- File path to the impulse response file, relative to this script. [required]
    path = "irs/cathedral.flac",
})

Support Functions

floe.extend_table

Extends a table with another table, including all sub-tables. It takes 2 parameters: the base table and the table to extend it with. The base table is not modified. The extension table is modified and returned. It has all the keys of the base table plus all the keys of the extended table. If a key exists in both tables, the value from the extension table is used.


local group1 = {
    trigger_criteria = {
        trigger_event = "note-on",
        velocity_range = { 0, 100 },
    },
    options = {
        auto_map_key_range_group = "group1",
        feather_overlapping_velocity_regions = false,
    },
}

floe.add_region(instrument, floe.extend_table(group1, {
    file = {
        path = "One-shots/Resonating String 2.flac",
        root_key = 65,
    },
}))

floe.add_region(instrument, floe.extend_table(group1, {
    file = {
        path = "One-shots/Resonating String 3.flac",
        root_key = 68,
    },
}))
1

Floe also supports libraries in the MDATA format, but this is only for backwards compatibility with Mirage.

Changelog

0.0.1

  • Initial version

Mirage

Prior to 0.0.1, Floe was known as Mirage. The last Mirage version was 2.0.5.