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/