mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 12:07:45 +00:00
LibAudio: Refactor and modernize WavLoader
* All clang-tidy warnings fixed except read_header cognitive complexity * Use size_t in more places * Replace #define's with constexpr constants * Some variable renaming for readability
This commit is contained in:
parent
53d3d2daaa
commit
81a336ea45
2 changed files with 31 additions and 33 deletions
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
namespace Audio {
|
namespace Audio {
|
||||||
|
|
||||||
static constexpr size_t maximum_wav_size = 1 * GiB; // FIXME: is there a more appropriate size limit?
|
static constexpr size_t const maximum_wav_size = 1 * GiB; // FIXME: is there a more appropriate size limit?
|
||||||
|
|
||||||
WavLoaderPlugin::WavLoaderPlugin(StringView path)
|
WavLoaderPlugin::WavLoaderPlugin(StringView path)
|
||||||
: m_file(Core::File::construct(path))
|
: m_file(Core::File::construct(path))
|
||||||
|
@ -47,12 +47,12 @@ WavLoaderPlugin::WavLoaderPlugin(Bytes const& buffer)
|
||||||
m_memory_stream = static_cast<InputMemoryStream*>(m_stream.ptr());
|
m_memory_stream = static_cast<InputMemoryStream*>(m_stream.ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
LoaderSamples WavLoaderPlugin::get_more_samples(size_t max_bytes_to_read_from_input)
|
LoaderSamples WavLoaderPlugin::get_more_samples(size_t max_samples_to_read_from_input)
|
||||||
{
|
{
|
||||||
if (!m_stream)
|
if (!m_stream)
|
||||||
return LoaderError { LoaderError::Category::Internal, static_cast<size_t>(m_loaded_samples), "No stream" };
|
return LoaderError { LoaderError::Category::Internal, static_cast<size_t>(m_loaded_samples), "No stream" };
|
||||||
|
|
||||||
int remaining_samples = m_total_samples - m_loaded_samples;
|
auto remaining_samples = m_total_samples - m_loaded_samples;
|
||||||
if (remaining_samples <= 0)
|
if (remaining_samples <= 0)
|
||||||
return FixedArray<Sample> {};
|
return FixedArray<Sample> {};
|
||||||
|
|
||||||
|
@ -62,9 +62,9 @@ LoaderSamples WavLoaderPlugin::get_more_samples(size_t max_bytes_to_read_from_in
|
||||||
= m_num_channels * pcm_bits_per_sample(m_sample_format) / 8;
|
= m_num_channels * pcm_bits_per_sample(m_sample_format) / 8;
|
||||||
|
|
||||||
// Might truncate if not evenly divisible by the sample size
|
// Might truncate if not evenly divisible by the sample size
|
||||||
int max_samples_to_read = static_cast<int>(max_bytes_to_read_from_input) / bytes_per_sample;
|
auto max_samples_to_read = max_samples_to_read_from_input / bytes_per_sample;
|
||||||
int samples_to_read = min(max_samples_to_read, remaining_samples);
|
auto samples_to_read = min(max_samples_to_read, remaining_samples);
|
||||||
size_t bytes_to_read = samples_to_read * bytes_per_sample;
|
auto bytes_to_read = samples_to_read * bytes_per_sample;
|
||||||
|
|
||||||
dbgln_if(AWAVLOADER_DEBUG, "Read {} bytes WAV with num_channels {} sample rate {}, "
|
dbgln_if(AWAVLOADER_DEBUG, "Read {} bytes WAV with num_channels {} sample rate {}, "
|
||||||
"bits per sample {}, sample format {}",
|
"bits per sample {}, sample format {}",
|
||||||
|
@ -73,11 +73,11 @@ LoaderSamples WavLoaderPlugin::get_more_samples(size_t max_bytes_to_read_from_in
|
||||||
|
|
||||||
auto sample_data_result = ByteBuffer::create_zeroed(bytes_to_read);
|
auto sample_data_result = ByteBuffer::create_zeroed(bytes_to_read);
|
||||||
if (sample_data_result.is_error())
|
if (sample_data_result.is_error())
|
||||||
return LoaderError { LoaderError::Category::IO, static_cast<size_t>(m_loaded_samples), "Couldn't allocate sample buffer" };
|
return LoaderError { LoaderError::Category::IO, m_loaded_samples, "Couldn't allocate sample buffer" };
|
||||||
auto sample_data = sample_data_result.release_value();
|
auto sample_data = sample_data_result.release_value();
|
||||||
m_stream->read_or_error(sample_data.bytes());
|
m_stream->read_or_error(sample_data.bytes());
|
||||||
if (m_stream->handle_any_error())
|
if (m_stream->handle_any_error())
|
||||||
return LoaderError { LoaderError::Category::IO, static_cast<size_t>(m_loaded_samples), "Stream read error" };
|
return LoaderError { LoaderError::Category::IO, m_loaded_samples, "Stream read error" };
|
||||||
|
|
||||||
auto buffer = LegacyBuffer::from_pcm_data(
|
auto buffer = LegacyBuffer::from_pcm_data(
|
||||||
sample_data.bytes(),
|
sample_data.bytes(),
|
||||||
|
@ -85,24 +85,24 @@ LoaderSamples WavLoaderPlugin::get_more_samples(size_t max_bytes_to_read_from_in
|
||||||
m_sample_format);
|
m_sample_format);
|
||||||
|
|
||||||
if (buffer.is_error())
|
if (buffer.is_error())
|
||||||
return LoaderError { LoaderError::Category::Internal, static_cast<size_t>(m_loaded_samples), "Couldn't allocate sample buffer" };
|
return LoaderError { LoaderError::Category::Internal, m_loaded_samples, "Couldn't allocate sample buffer" };
|
||||||
|
|
||||||
// m_loaded_samples should contain the amount of actually loaded samples
|
// m_loaded_samples should contain the amount of actually loaded samples
|
||||||
m_loaded_samples += samples_to_read;
|
m_loaded_samples += samples_to_read;
|
||||||
return LOADER_TRY(buffer.value()->to_sample_array());
|
return LOADER_TRY(buffer.value()->to_sample_array());
|
||||||
}
|
}
|
||||||
|
|
||||||
MaybeLoaderError WavLoaderPlugin::seek(int const sample_index)
|
MaybeLoaderError WavLoaderPlugin::seek(int sample_index)
|
||||||
{
|
{
|
||||||
dbgln_if(AWAVLOADER_DEBUG, "seek sample_index {}", sample_index);
|
dbgln_if(AWAVLOADER_DEBUG, "seek sample_index {}", sample_index);
|
||||||
if (sample_index < 0 || sample_index >= m_total_samples)
|
if (sample_index < 0 || sample_index >= static_cast<int>(m_total_samples))
|
||||||
return LoaderError { LoaderError::Category::Internal, static_cast<size_t>(m_loaded_samples), "Seek outside the sample range" };
|
return LoaderError { LoaderError::Category::Internal, m_loaded_samples, "Seek outside the sample range" };
|
||||||
|
|
||||||
size_t sample_offset = m_byte_offset_of_data_samples + (sample_index * m_num_channels * (pcm_bits_per_sample(m_sample_format) / 8));
|
size_t sample_offset = m_byte_offset_of_data_samples + static_cast<size_t>(sample_index * m_num_channels * (pcm_bits_per_sample(m_sample_format) / 8));
|
||||||
|
|
||||||
// AK::InputStream does not define seek, hence the special-cases for file and stream.
|
// AK::InputStream does not define seek, hence the special-cases for file and stream.
|
||||||
if (m_file) {
|
if (m_file) {
|
||||||
m_file->seek(sample_offset);
|
m_file->seek(static_cast<int>(sample_offset));
|
||||||
} else {
|
} else {
|
||||||
m_memory_stream->seek(sample_offset);
|
m_memory_stream->seek(sample_offset);
|
||||||
}
|
}
|
||||||
|
@ -244,7 +244,7 @@ MaybeLoaderError WavLoaderPlugin::parse_header()
|
||||||
|
|
||||||
// Read chunks until we find DATA
|
// Read chunks until we find DATA
|
||||||
bool found_data = false;
|
bool found_data = false;
|
||||||
u32 data_sz = 0;
|
u32 data_size = 0;
|
||||||
u8 search_byte = 0;
|
u8 search_byte = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
search_byte = read_u8();
|
search_byte = read_u8();
|
||||||
|
@ -262,7 +262,7 @@ MaybeLoaderError WavLoaderPlugin::parse_header()
|
||||||
if (search_remaining != 0x6174) // TA
|
if (search_remaining != 0x6174) // TA
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
data_sz = read_u32();
|
data_size = read_u32();
|
||||||
found_data = true;
|
found_data = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -270,13 +270,13 @@ MaybeLoaderError WavLoaderPlugin::parse_header()
|
||||||
ok = ok && found_data;
|
ok = ok && found_data;
|
||||||
CHECK_OK(LoaderError::Category::Format, "Found no data chunk");
|
CHECK_OK(LoaderError::Category::Format, "Found no data chunk");
|
||||||
|
|
||||||
ok = ok && data_sz < maximum_wav_size;
|
ok = ok && data_size < maximum_wav_size;
|
||||||
CHECK_OK(LoaderError::Category::Format, "Data was too large");
|
CHECK_OK(LoaderError::Category::Format, "Data was too large");
|
||||||
|
|
||||||
m_total_samples = data_sz / block_size_bytes;
|
m_total_samples = data_size / block_size_bytes;
|
||||||
|
|
||||||
dbgln_if(AWAVLOADER_DEBUG, "WAV data size {}, bytes per sample {}, total samples {}",
|
dbgln_if(AWAVLOADER_DEBUG, "WAV data size {}, bytes per sample {}, total samples {}",
|
||||||
data_sz,
|
data_size,
|
||||||
block_size_bytes,
|
block_size_bytes,
|
||||||
m_total_samples);
|
m_total_samples);
|
||||||
|
|
||||||
|
|
|
@ -22,12 +22,12 @@
|
||||||
|
|
||||||
namespace Audio {
|
namespace Audio {
|
||||||
|
|
||||||
// defines for handling the WAV header data
|
// constants for handling the WAV header data
|
||||||
#define WAVE_FORMAT_PCM 0x0001 // PCM
|
static constexpr unsigned const WAVE_FORMAT_PCM = 0x0001; // PCM
|
||||||
#define WAVE_FORMAT_IEEE_FLOAT 0x0003 // IEEE float
|
static constexpr unsigned const WAVE_FORMAT_IEEE_FLOAT = 0x0003; // IEEE float
|
||||||
#define WAVE_FORMAT_ALAW 0x0006 // 8-bit ITU-T G.711 A-law
|
static constexpr unsigned const WAVE_FORMAT_ALAW = 0x0006; // 8-bit ITU-T G.711 A-law
|
||||||
#define WAVE_FORMAT_MULAW 0x0007 // 8-bit ITU-T G.711 µ-law
|
static constexpr unsigned const WAVE_FORMAT_MULAW = 0x0007; // 8-bit ITU-T G.711 µ-law
|
||||||
#define WAVE_FORMAT_EXTENSIBLE 0xFFFE // Determined by SubFormat
|
static constexpr unsigned const WAVE_FORMAT_EXTENSIBLE = 0xFFFE; // Determined by SubFormat
|
||||||
|
|
||||||
// Parses a WAV file and produces an Audio::LegacyBuffer.
|
// Parses a WAV file and produces an Audio::LegacyBuffer.
|
||||||
class WavLoaderPlugin : public LoaderPlugin {
|
class WavLoaderPlugin : public LoaderPlugin {
|
||||||
|
@ -37,18 +37,16 @@ public:
|
||||||
|
|
||||||
virtual MaybeLoaderError initialize() override;
|
virtual MaybeLoaderError initialize() override;
|
||||||
|
|
||||||
// The Buffer returned contains input data resampled at the
|
virtual LoaderSamples get_more_samples(size_t max_samples_to_read_from_input = 128 * KiB) override;
|
||||||
// destination audio device sample rate.
|
|
||||||
virtual LoaderSamples get_more_samples(size_t max_bytes_to_read_from_input = 128 * KiB) override;
|
|
||||||
|
|
||||||
virtual MaybeLoaderError reset() override { return seek(0); }
|
virtual MaybeLoaderError reset() override { return seek(0); }
|
||||||
|
|
||||||
// sample_index 0 is the start of the raw audio sample data
|
// sample_index 0 is the start of the raw audio sample data
|
||||||
// within the file/stream.
|
// within the file/stream.
|
||||||
virtual MaybeLoaderError seek(int const sample_index) override;
|
virtual MaybeLoaderError seek(int sample_index) override;
|
||||||
|
|
||||||
virtual int loaded_samples() override { return m_loaded_samples; }
|
virtual int loaded_samples() override { return static_cast<int>(m_loaded_samples); }
|
||||||
virtual int total_samples() override { return m_total_samples; }
|
virtual int total_samples() override { return static_cast<int>(m_total_samples); }
|
||||||
virtual u32 sample_rate() override { return m_sample_rate; }
|
virtual u32 sample_rate() override { return m_sample_rate; }
|
||||||
virtual u16 num_channels() override { return m_num_channels; }
|
virtual u16 num_channels() override { return m_num_channels; }
|
||||||
virtual String format_name() override { return "RIFF WAVE (.wav)"; }
|
virtual String format_name() override { return "RIFF WAVE (.wav)"; }
|
||||||
|
@ -68,8 +66,8 @@ private:
|
||||||
PcmSampleFormat m_sample_format;
|
PcmSampleFormat m_sample_format;
|
||||||
size_t m_byte_offset_of_data_samples { 0 };
|
size_t m_byte_offset_of_data_samples { 0 };
|
||||||
|
|
||||||
int m_loaded_samples { 0 };
|
size_t m_loaded_samples { 0 };
|
||||||
int m_total_samples { 0 };
|
size_t m_total_samples { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue