1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 05:47:35 +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:
kleines Filmröllchen 2022-04-22 14:13:34 +02:00 committed by Linus Groh
parent 53d3d2daaa
commit 81a336ea45
2 changed files with 31 additions and 33 deletions

View file

@ -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);

View file

@ -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 };
}; };
} }