Skip to content

Simple audio playback

Finalspace edited this page May 29, 2026 · 1 revision

Table of Contents

main.cpp

#define FPL_IMPLEMENTATION
#define FPL_NO_WINDOW
#include <final_platform_layer.h>
#include <math.h> // sinf

struct AudioTest {
    uint32_t toneHz;
    uint32_t toneVolume;
    uint32_t runningSampleIndex;
    uint32_t wavePeriod;
    bool useSquareWave;
};

static const float PI32 = 3.14159265359f;

static uint32_t FillAudioBuffer(const  *nativeFormat, const uint32_t frameCount, void *outputSamples, void *userData) {
    AudioTest *audioTest = (AudioTest *)userData;
    (audioTest != nullptr);
    (nativeFormat-> == );
    uint32_t result = 0;
    int16_t *outSamples = (int16_t *)outputSamples;
    uint32_t halfWavePeriod = audioTest->wavePeriod / 2;
    for (uint32_t frameIndex = 0; frameIndex < frameCount; ++frameIndex) {
        int16_t sampleValue;
        if (audioTest->useSquareWave) {
            sampleValue = ((audioTest->runningSampleIndex++ / halfWavePeriod) % 2) ? (int16_t)audioTest->toneVolume : -(int16_t)audioTest->toneVolume;
        } else {
            float t = 2.0f * PI32 * (float)audioTest->runningSampleIndex++ / (float)audioTest->wavePeriod;
            sampleValue = (int16_t)(sinf(t) * audioTest->toneVolume);
        }
        for (uint32_t channelIndex = 0; channelIndex < nativeFormat->; ++channelIndex) {
             *outSamples++ = sampleValue;
            ++result;
        }
    }
    return result;
}

int main(int argc, char **argv) {
    int result = -1;

    // Initialize to default settings which is 48 kHz and 2 Channels
     settings;
    (&settings);

    // Optionally overwrite audio settings if needed

    // Setup some state for the sine/square wave generation
    AudioTest audioTest = {};
    audioTest.toneHz = 256;
    audioTest.toneVolume = 1000;
    audioTest.wavePeriod = settings..deviceFormat.sampleRate / audioTest.toneHz;
    audioTest.useSquareWave = false;

    // Provide client read callback and optionally user data
    settings.. = FillAudioBuffer;
    settings..userData = &audioTest;
    settings..deviceFormat.type = ;
    settings..deviceFormat.channels = 2;
    settings..deviceFormat.sampleRate = 48000;

    // Disable auto start/stop of audio playback
    settings.. = false;
    settings.. = false;

    // Find audio device
    if ((, &settings)) {
         audioDevices[16] = {};
        uint32_t deviceCount = (audioDevices, (audioDevices));
        if (deviceCount > 0) {
            settings..deviceID = audioDevices[0];
            ("Using audio device: %s\n", settings..deviceID.name);
        }
        ();
    }

    // Initialize the platform with audio enabled and the settings
    if ((, &settings)) {
        // You can overwrite the client read callback and user data if you want to
        (FillAudioBuffer, &audioTest);
        // Start audio playback (This will start calling clientReadCallback regularly)
        if (() == fplAudioResult_Success) {
            // Print out the native audio format
             nativeFormat = ();
            ("Audio with %lu kHz and %lu channels is playing, press any key to stop playback...\n", nativeFormat., nativeFormat.);
            // Wait for any key presses
            ();
            // Stop audio playback
            ();
        }
        // Release the platform
        ();
        result = 0;
    }
    return(result);
}

Final Platform Layer

Pages

Topics

Data Structures

Clone this wiki locally