musix 0.3.5

Music player library for esoteric audio formats (music from C64,Amiga etc)
Documentation
#pragma once

#include <array>
#include <coreutils/fifo.h>

struct resampler;

resampler* rs_create();
void rs_delete(resampler*);
resampler* rs_dup(const resampler*);
void rs_dup_inplace(resampler*, const resampler*);

int rs_get_free_count(resampler*);
void rs_write_sample(resampler*, short sample_l, short sample_r);
void rs_set_rate(resampler*, double new_factor);
int rs_ready(resampler*);
void rs_clear(resampler*);
int rs_get_sample_count(resampler*);
void rs_get_sample(resampler*, short* sample_l, short* sample_r);
void rs_remove_sample(resampler*);

template <int SIZE> struct Resampler
{
    int targetHz;
    bool active = false;
    int silence = 0;
    resampler* samp;
    utils::Ring<int16_t, SIZE> fifo;
    std::array<int16_t, 2> lr{};

    explicit Resampler(int hz = 44100) : targetHz(hz), samp(rs_create())
    {
        setHz(hz);
    }

    size_t filled() const { return fifo.filled(); }

    void setHz(int hz)
    {
        active = hz != targetHz;
        rs_set_rate(samp, static_cast<float>(hz) / targetHz);
    }

    void write(int16_t* left, int16_t* right, size_t size, int stride = 2)
    {
        int64_t total = 0;
        for (int i = 0; i < size; i++) {
            total += (static_cast<int>(left[i]) * static_cast<int>(left[i])) +
                     (static_cast<int>(right[i]) * static_cast<int>(right[i]));
        }
        total /= static_cast<int>(size);

        fflush(stdout);
        if (total < 16000) {
            silence++;
        } else {
            silence = 0;
        }

        if (!active && stride == 2) {
            fifo.write(left, size);
            return;
        }
        for (int i = 0; i < size; i += stride) {
            rs_write_sample(samp, left[i], right[i]);
            while (rs_get_sample_count(samp) > 0) {
                rs_get_sample(samp, &lr[0], &lr[1]);
                fifo.write(&lr[0], 2);
                rs_remove_sample(samp);
            }
        }
    }

    size_t read(int16_t* target, size_t n) { return fifo.read(target, n); }
};