Skip to content

Audio IO

audio_reader_flac

audio_reader_flac class

template <typename T> audio_reader_flac

FLAC format reader

Source code
template <typename T>
struct audio_reader_flac : audio_reader<T>
{
    /// @brief Constructs FLAC reader
    audio_reader_flac(std::shared_ptr<abstract_reader<>>&& reader) : reader(std::move(reader))
    {
        f              = drflac_open((drflac_read_proc)&internal_generic::drflac_reader_read_proc,
                                     (drflac_seek_proc)&internal_generic::drflac_reader_seek_proc, this->reader.get(),
                                     nullptr);
        fmt.channels   = f->channels;
        fmt.samplerate = f->sampleRate;
        fmt.length     = static_cast<imax>(f->totalPCMFrameCount);
        fmt.type       = audio_sample_type::i32;
    }
    ~audio_reader_flac() override { drflac_close(f); }

    /// @brief Returns audio format description
    const audio_format_and_length& format() const override { return fmt; }

    /// @brief Reads and decodes audio data
    size_t read(T* data, size_t size) override
    {
        if (fmt.type == audio_sample_type::unknown)
            return 0;
        if (audio_sample_traits<T>::type == audio_sample_type::i32)
        {
            const size_t sz =
                drflac_read_pcm_frames_s32(f, size / fmt.channels, reinterpret_cast<i32*>(data));
            position += sz;
            return sz * fmt.channels;
        }
        else
        {
            univector<i32> native(size * sizeof(i32));
            const size_t sz = drflac_read_pcm_frames_s32(f, size / fmt.channels, native.data());
            position += sz;
            convert(data, native.data(), sz * fmt.channels);
            return sz * fmt.channels;
        }
    }

    /// @brief Returns current position
    imax tell() const override { return position; }

    /// @brief Seeks to specific sample
    bool seek(imax offset, seek_origin origin) override
    {
        switch (origin)
        {
        case seek_origin::current:
            return drflac_seek_to_pcm_frame(f, static_cast<drmp3_uint64>(this->position + offset));
        case seek_origin::begin:
            return drflac_seek_to_pcm_frame(f, static_cast<drmp3_uint64>(offset));
        case seek_origin::end:
            return drflac_seek_to_pcm_frame(f, static_cast<drmp3_uint64>(fmt.length + offset));
        }
        return false;
    }

private:
    std::shared_ptr<abstract_reader<>> reader;
    drflac* f;
    audio_format_and_length fmt;
    imax position = 0;
}

https://github.com/kfrlib/kfr/blob//include/kfr/io/audiofile.hpp#L360

audio_reader_flac<T> function

audio_reader_flac(
    std::shared_ptr<abstract_reader<>> &&reader)
    : reader(std::move(reader))

Constructs FLAC reader

Source code
audio_reader_flac(std::shared_ptr<abstract_reader<>>&& reader) : reader(std::move(reader))
{
    f              = drflac_open((drflac_read_proc)&internal_generic::drflac_reader_read_proc,
                                 (drflac_seek_proc)&internal_generic::drflac_reader_seek_proc, this->reader.get(),
                                 nullptr);
    fmt.channels   = f->channels;
    fmt.samplerate = f->sampleRate;
    fmt.length     = static_cast<imax>(f->totalPCMFrameCount);
    fmt.type       = audio_sample_type::i32;
}

https://github.com/kfrlib/kfr/blob//include/kfr/io/audiofile.hpp#L363

format function

const audio_format_and_length &format() const override

Returns audio format description

Source code
const audio_format_and_length& format() const override { return fmt; }

https://github.com/kfrlib/kfr/blob//include/kfr/io/audiofile.hpp#L376

read function

size_t read(T *data, size_t size) override

Reads and decodes audio data

Source code
size_t read(T* data, size_t size) override
{
    if (fmt.type == audio_sample_type::unknown)
        return 0;
    if (audio_sample_traits<T>::type == audio_sample_type::i32)
    {
        const size_t sz =
            drflac_read_pcm_frames_s32(f, size / fmt.channels, reinterpret_cast<i32*>(data));
        position += sz;
        return sz * fmt.channels;
    }
    else
    {
        univector<i32> native(size * sizeof(i32));
        const size_t sz = drflac_read_pcm_frames_s32(f, size / fmt.channels, native.data());
        position += sz;
        convert(data, native.data(), sz * fmt.channels);
        return sz * fmt.channels;
    }
}

https://github.com/kfrlib/kfr/blob//include/kfr/io/audiofile.hpp#L379

tell function

imax tell() const override

Returns current position

Source code
imax tell() const override { return position; }

https://github.com/kfrlib/kfr/blob//include/kfr/io/audiofile.hpp#L401

seek function

bool seek(imax offset, seek_origin origin) override

Seeks to specific sample

Source code
bool seek(imax offset, seek_origin origin) override
{
    switch (origin)
    {
    case seek_origin::current:
        return drflac_seek_to_pcm_frame(f, static_cast<drmp3_uint64>(this->position + offset));
    case seek_origin::begin:
        return drflac_seek_to_pcm_frame(f, static_cast<drmp3_uint64>(offset));
    case seek_origin::end:
        return drflac_seek_to_pcm_frame(f, static_cast<drmp3_uint64>(fmt.length + offset));
    }
    return false;
}

https://github.com/kfrlib/kfr/blob//include/kfr/io/audiofile.hpp#L404

audio_reader_mp3

audio_reader_mp3 class

template <typename T> audio_reader_mp3

MP3 format reader

Source code
template <typename T>
struct audio_reader_mp3 : audio_reader<T>
{
    /// @brief Constructs MP3 reader
    audio_reader_mp3(std::shared_ptr<abstract_reader<>>&& reader) : reader(std::move(reader))
    {
        drmp3_init(&f, (drmp3_read_proc)&internal_generic::drmp3_reader_read_proc,
                   (drmp3_seek_proc)&internal_generic::drmp3_reader_seek_proc, this->reader.get(), &config,
                   nullptr);
        fmt.channels   = f.channels;
        fmt.samplerate = f.sampleRate;
        fmt.length     = static_cast<imax>(drmp3_get_pcm_frame_count(&f));
        fmt.type       = audio_sample_type::i16;
    }
    ~audio_reader_mp3() override { drmp3_uninit(&f); }

    drmp3_config config{ 0, 0 };

    /// @brief Returns audio format description
    const audio_format_and_length& format() const override { return fmt; }

    /// @brief Reads and decodes audio data
    size_t read(T* data, size_t size) override
    {
        if (fmt.type == audio_sample_type::unknown)
            return 0;
        if (audio_sample_traits<T>::type == audio_sample_type::i16)
        {
            const size_t sz =
                drmp3_read_pcm_frames_s16(&f, size / fmt.channels, reinterpret_cast<i16*>(data));
            position += sz;
            return sz * fmt.channels;
        }
        else
        {
            univector<i16> native(size * sizeof(i16));
            const size_t sz = drmp3_read_pcm_frames_s16(&f, size / fmt.channels, native.data());
            position += sz;
            convert(data, native.data(), sz * fmt.channels);
            return sz * fmt.channels;
        }
    }

    /// @brief Returns current position
    imax tell() const override { return position; }

    /// @brief Seeks to specific sample
    bool seek(imax offset, seek_origin origin) override
    {
        switch (origin)
        {
        case seek_origin::current:
            return drmp3_seek_to_pcm_frame(&f, static_cast<drmp3_uint64>(this->position + offset));
        case seek_origin::begin:
            return drmp3_seek_to_pcm_frame(&f, static_cast<drmp3_uint64>(offset));
        case seek_origin::end:
            return drmp3_seek_to_pcm_frame(&f, static_cast<drmp3_uint64>(fmt.length + offset));
        }
        return false;
    }

private:
    std::shared_ptr<abstract_reader<>> reader;
    drmp3 f;
    audio_format_and_length fmt;
    imax position = 0;
}

https://github.com/kfrlib/kfr/blob//include/kfr/io/audiofile.hpp#L430

audio_reader_mp3<T> function

audio_reader_mp3(
    std::shared_ptr<abstract_reader<>> &&reader)
    : reader(std::move(reader))

Constructs MP3 reader

Source code
audio_reader_mp3(std::shared_ptr<abstract_reader<>>&& reader) : reader(std::move(reader))
{
    drmp3_init(&f, (drmp3_read_proc)&internal_generic::drmp3_reader_read_proc,
               (drmp3_seek_proc)&internal_generic::drmp3_reader_seek_proc, this->reader.get(), &config,
               nullptr);
    fmt.channels   = f.channels;
    fmt.samplerate = f.sampleRate;
    fmt.length     = static_cast<imax>(drmp3_get_pcm_frame_count(&f));
    fmt.type       = audio_sample_type::i16;
}

https://github.com/kfrlib/kfr/blob//include/kfr/io/audiofile.hpp#L433

format function

const audio_format_and_length &format() const override

Returns audio format description

Source code
const audio_format_and_length& format() const override { return fmt; }

https://github.com/kfrlib/kfr/blob//include/kfr/io/audiofile.hpp#L448

read function

size_t read(T *data, size_t size) override

Reads and decodes audio data

Source code
size_t read(T* data, size_t size) override
{
    if (fmt.type == audio_sample_type::unknown)
        return 0;
    if (audio_sample_traits<T>::type == audio_sample_type::i16)
    {
        const size_t sz =
            drmp3_read_pcm_frames_s16(&f, size / fmt.channels, reinterpret_cast<i16*>(data));
        position += sz;
        return sz * fmt.channels;
    }
    else
    {
        univector<i16> native(size * sizeof(i16));
        const size_t sz = drmp3_read_pcm_frames_s16(&f, size / fmt.channels, native.data());
        position += sz;
        convert(data, native.data(), sz * fmt.channels);
        return sz * fmt.channels;
    }
}

https://github.com/kfrlib/kfr/blob//include/kfr/io/audiofile.hpp#L451

tell function

imax tell() const override

Returns current position

Source code
imax tell() const override { return position; }

https://github.com/kfrlib/kfr/blob//include/kfr/io/audiofile.hpp#L473

seek function

bool seek(imax offset, seek_origin origin) override

Seeks to specific sample

Source code
bool seek(imax offset, seek_origin origin) override
{
    switch (origin)
    {
    case seek_origin::current:
        return drmp3_seek_to_pcm_frame(&f, static_cast<drmp3_uint64>(this->position + offset));
    case seek_origin::begin:
        return drmp3_seek_to_pcm_frame(&f, static_cast<drmp3_uint64>(offset));
    case seek_origin::end:
        return drmp3_seek_to_pcm_frame(&f, static_cast<drmp3_uint64>(fmt.length + offset));
    }
    return false;
}

https://github.com/kfrlib/kfr/blob//include/kfr/io/audiofile.hpp#L476

audio_reader_wav

audio_reader_wav class

template <typename T> audio_reader_wav

WAV format reader

Source code
template <typename T>
struct audio_reader_wav : audio_reader<T>
{
    using audio_reader<T>::read;

    /// @brief Constructs WAV reader
    audio_reader_wav(std::shared_ptr<abstract_reader<>>&& reader) : reader(std::move(reader))
    {
        drwav_init(&f, (drwav_read_proc)&internal_generic::drwav_reader_read_proc,
                   (drwav_seek_proc)&internal_generic::drwav_reader_seek_proc, this->reader.get(), nullptr);
        fmt.channels   = f.channels;
        fmt.samplerate = f.sampleRate;
        fmt.length     = static_cast<imax>(f.totalPCMFrameCount);
        switch (f.translatedFormatTag)
        {
        case DR_WAVE_FORMAT_IEEE_FLOAT:
            switch (f.bitsPerSample)
            {
            case 32:
                fmt.type = audio_sample_type::f32;
                break;
            case 64:
                fmt.type = audio_sample_type::f64;
                break;
            default:
                fmt.type = audio_sample_type::unknown;
                break;
            }
            break;
        case DR_WAVE_FORMAT_PCM:
            switch (f.bitsPerSample)
            {
            case 8:
                fmt.type = audio_sample_type::i8;
                break;
            case 16:
                fmt.type = audio_sample_type::i16;
                break;
            case 24:
                fmt.type = audio_sample_type::i24;
                break;
            case 32:
                fmt.type = audio_sample_type::i32;
                break;
            case 64:
                fmt.type = audio_sample_type::i64;
                break;
            default:
                fmt.type = audio_sample_type::unknown;
                break;
            }
            break;
        default:
            fmt.type = audio_sample_type::unknown;
            break;
        }
    }
    ~audio_reader_wav() override { drwav_uninit(&f); }

    /// @brief Returns audio format description
    const audio_format_and_length& format() const override { return fmt; }

    /// @brief Reads and decodes audio data
    size_t read(T* data, size_t size) override
    {
        if (fmt.type == audio_sample_type::unknown)
            return 0;
        if (fmt.type == audio_sample_traits<T>::type)
        {
            const size_t sz = drwav_read_pcm_frames(&f, size / fmt.channels, data);
            position += sz;
            return sz * fmt.channels;
        }
        else
        {
            univector<uint8_t> native(size * audio_sample_sizeof(fmt.type));
            const size_t sz = drwav_read_pcm_frames(&f, size / fmt.channels, native.data());
            position += sz;
            convert(data, native.data(), fmt.type, sz * fmt.channels);
            return sz * fmt.channels;
        }
    }

    /// @brief Returns current position
    imax tell() const override { return position; }

    /// @brief Seeks to specific sample
    bool seek(imax offset, seek_origin origin) override
    {
        switch (origin)
        {
        case seek_origin::current:
            return drwav_seek_to_pcm_frame(&f, static_cast<drmp3_uint64>(this->position + offset));
        case seek_origin::begin:
            return drwav_seek_to_pcm_frame(&f, static_cast<drmp3_uint64>(offset));
        case seek_origin::end:
            return drwav_seek_to_pcm_frame(&f, static_cast<drmp3_uint64>(fmt.length + offset));
        }
        return false;
    }

private:
    std::shared_ptr<abstract_reader<>> reader;
    drwav f;
    audio_format_and_length fmt;
    imax position = 0;
}

https://github.com/kfrlib/kfr/blob//include/kfr/io/audiofile.hpp#L248

audio_reader_wav<T> function

audio_reader_wav(
    std::shared_ptr<abstract_reader<>> &&reader)
    : reader(std::move(reader))

Constructs WAV reader

Source code
audio_reader_wav(std::shared_ptr<abstract_reader<>>&& reader) : reader(std::move(reader))
{
    drwav_init(&f, (drwav_read_proc)&internal_generic::drwav_reader_read_proc,
               (drwav_seek_proc)&internal_generic::drwav_reader_seek_proc, this->reader.get(), nullptr);
    fmt.channels   = f.channels;
    fmt.samplerate = f.sampleRate;
    fmt.length     = static_cast<imax>(f.totalPCMFrameCount);
    switch (f.translatedFormatTag)
    {
    case DR_WAVE_FORMAT_IEEE_FLOAT:
        switch (f.bitsPerSample)
        {
        case 32:
            fmt.type = audio_sample_type::f32;
            break;
        case 64:
            fmt.type = audio_sample_type::f64;
            break;
        default:
            fmt.type = audio_sample_type::unknown;
            break;
        }
        break;
    case DR_WAVE_FORMAT_PCM:
        switch (f.bitsPerSample)
        {
        case 8:
            fmt.type = audio_sample_type::i8;
            break;
        case 16:
            fmt.type = audio_sample_type::i16;
            break;
        case 24:
            fmt.type = audio_sample_type::i24;
            break;
        case 32:
            fmt.type = audio_sample_type::i32;
            break;
        case 64:
            fmt.type = audio_sample_type::i64;
            break;
        default:
            fmt.type = audio_sample_type::unknown;
            break;
        }
        break;
    default:
        fmt.type = audio_sample_type::unknown;
        break;
    }
}

https://github.com/kfrlib/kfr/blob//include/kfr/io/audiofile.hpp#L253

format function

const audio_format_and_length &format() const override

Returns audio format description

Source code
const audio_format_and_length& format() const override { return fmt; }

https://github.com/kfrlib/kfr/blob//include/kfr/io/audiofile.hpp#L307

read function

size_t read(T *data, size_t size) override

Reads and decodes audio data

Source code
size_t read(T* data, size_t size) override
{
    if (fmt.type == audio_sample_type::unknown)
        return 0;
    if (fmt.type == audio_sample_traits<T>::type)
    {
        const size_t sz = drwav_read_pcm_frames(&f, size / fmt.channels, data);
        position += sz;
        return sz * fmt.channels;
    }
    else
    {
        univector<uint8_t> native(size * audio_sample_sizeof(fmt.type));
        const size_t sz = drwav_read_pcm_frames(&f, size / fmt.channels, native.data());
        position += sz;
        convert(data, native.data(), fmt.type, sz * fmt.channels);
        return sz * fmt.channels;
    }
}

https://github.com/kfrlib/kfr/blob//include/kfr/io/audiofile.hpp#L310

tell function

imax tell() const override

Returns current position

Source code
imax tell() const override { return position; }

https://github.com/kfrlib/kfr/blob//include/kfr/io/audiofile.hpp#L331

seek function

bool seek(imax offset, seek_origin origin) override

Seeks to specific sample

Source code
bool seek(imax offset, seek_origin origin) override
{
    switch (origin)
    {
    case seek_origin::current:
        return drwav_seek_to_pcm_frame(&f, static_cast<drmp3_uint64>(this->position + offset));
    case seek_origin::begin:
        return drwav_seek_to_pcm_frame(&f, static_cast<drmp3_uint64>(offset));
    case seek_origin::end:
        return drwav_seek_to_pcm_frame(&f, static_cast<drmp3_uint64>(fmt.length + offset));
    }
    return false;
}

https://github.com/kfrlib/kfr/blob//include/kfr/io/audiofile.hpp#L334

audio_writer_wav

audio_writer_wav class

template <typename T> audio_writer_wav

WAV format writer

Source code
template <typename T>
struct audio_writer_wav : audio_writer<T>
{
    /// @brief Constructs WAV writer using target writer and format
    audio_writer_wav(std::shared_ptr<abstract_writer<>>&& writer, const audio_format& fmt)
        : writer(std::move(writer)), fmt(fmt)
    {
        drwav_data_format wav_fmt;
        wav_fmt.channels   = static_cast<drwav_uint32>(fmt.channels);
        wav_fmt.sampleRate = static_cast<drwav_uint32>(fmt.samplerate);
        wav_fmt.format =
            fmt.type >= audio_sample_type::first_float ? DR_WAVE_FORMAT_IEEE_FLOAT : DR_WAVE_FORMAT_PCM;
        wav_fmt.bitsPerSample = static_cast<drwav_uint32>(audio_sample_bit_depth(fmt.type));
        wav_fmt.container     = fmt.use_w64 ? drwav_container_w64 : drwav_container_riff;
        closed = !drwav_init_write(&f, &wav_fmt, (drwav_write_proc)&internal_generic::drwav_writer_write_proc,
                                   (drwav_seek_proc)&internal_generic::drwav_writer_seek_proc,
                                   this->writer.get(), nullptr);
    }
    ~audio_writer_wav() override { close(); }

    using audio_writer<T>::write;

    /// @brief Write data to underlying binary writer
    /// data is PCM samples in interleaved format
    /// size is the number of samples (PCM frames * channels)
    size_t write(const T* data, size_t size) override
    {
        if (closed)
            return 0;
        if (fmt.type == audio_sample_type::unknown)
            return 0;
        if (fmt.type == audio_sample_traits<T>::type)
        {
            const size_t sz = drwav_write_pcm_frames_le(&f, size, data);
            fmt.length += sz;
            return sz * fmt.channels;
        }
        else
        {
            univector<uint8_t> native(size * audio_sample_sizeof(fmt.type));
            convert(native.data(), fmt.type, data, size);
            const size_t sz = drwav_write_pcm_frames_le(&f, size / fmt.channels, native.data());
            fmt.length += sz;
            return sz * fmt.channels;
        }
    }

    void close() override
    {
        if (!closed)
        {
            drwav_uninit(&f);
            writer.reset();
            closed = true;
        }
    }

    const audio_format_and_length& format() const override { return fmt; }

    imax tell() const override { return fmt.length; }

    bool seek(imax, seek_origin) override { return false; }

private:
    std::shared_ptr<abstract_writer<>> writer;
    drwav f;
    audio_format_and_length fmt;
    bool closed = false;
}

https://github.com/kfrlib/kfr/blob//include/kfr/io/audiofile.hpp#L177

audio_writer_wav<T> function

audio_writer_wav(
    std::shared_ptr<abstract_writer<>> &&writer,
    const audio_format &fmt)
    : writer(std::move(writer)), fmt(fmt)

Constructs WAV writer using target writer and format

Source code
audio_writer_wav(std::shared_ptr<abstract_writer<>>&& writer, const audio_format& fmt)
    : writer(std::move(writer)), fmt(fmt)
{
    drwav_data_format wav_fmt;
    wav_fmt.channels   = static_cast<drwav_uint32>(fmt.channels);
    wav_fmt.sampleRate = static_cast<drwav_uint32>(fmt.samplerate);
    wav_fmt.format =
        fmt.type >= audio_sample_type::first_float ? DR_WAVE_FORMAT_IEEE_FLOAT : DR_WAVE_FORMAT_PCM;
    wav_fmt.bitsPerSample = static_cast<drwav_uint32>(audio_sample_bit_depth(fmt.type));
    wav_fmt.container     = fmt.use_w64 ? drwav_container_w64 : drwav_container_riff;
    closed = !drwav_init_write(&f, &wav_fmt, (drwav_write_proc)&internal_generic::drwav_writer_write_proc,
                               (drwav_seek_proc)&internal_generic::drwav_writer_seek_proc,
                               this->writer.get(), nullptr);
}

https://github.com/kfrlib/kfr/blob//include/kfr/io/audiofile.hpp#L180

write function

size_t write(const T *data, size_t size) override

Write data to underlying binary writer data is PCM samples in interleaved format size is the number of samples (PCM frames * channels)

Source code
size_t write(const T* data, size_t size) override
{
    if (closed)
        return 0;
    if (fmt.type == audio_sample_type::unknown)
        return 0;
    if (fmt.type == audio_sample_traits<T>::type)
    {
        const size_t sz = drwav_write_pcm_frames_le(&f, size, data);
        fmt.length += sz;
        return sz * fmt.channels;
    }
    else
    {
        univector<uint8_t> native(size * audio_sample_sizeof(fmt.type));
        convert(native.data(), fmt.type, data, size);
        const size_t sz = drwav_write_pcm_frames_le(&f, size / fmt.channels, native.data());
        fmt.length += sz;
        return sz * fmt.channels;
    }
}

https://github.com/kfrlib/kfr/blob//include/kfr/io/audiofile.hpp#L201

close function

virtual void close() = 0

Finishes writing and closes underlying writer

Source code
virtual void close() = 0

https://github.com/kfrlib/kfr/blob//include/kfr/io/audiofile.hpp#L122

format function

virtual const audio_format_and_length &format() const = 0

Returns audio format description

Source code
virtual const audio_format_and_length& format() const = 0

https://github.com/kfrlib/kfr/blob//include/kfr/io/audiofile.hpp#L102

virtual const audio_format_and_length &format() const = 0

Returns audio format description

Source code
virtual const audio_format_and_length& format() const = 0

https://github.com/kfrlib/kfr/blob//include/kfr/io/audiofile.hpp#L119

read function

using abstract_reader<T>::read

Reads interleaved audio

Source code
using abstract_reader<T>::read

https://github.com/kfrlib/kfr/blob//include/kfr/io/audiofile.hpp#L88

write function

using abstract_writer<T>::write

Writes interleaved audio

Source code
using abstract_writer<T>::write

https://github.com/kfrlib/kfr/blob//include/kfr/io/audiofile.hpp#L109


Auto-generated from sources, Revision , https://github.com/kfrlib/kfr/blob//include/kfr/