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 {
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)
: m_file(Core::File::construct(path))
@ -47,12 +47,12 @@ WavLoaderPlugin::WavLoaderPlugin(Bytes const& buffer)
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)
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)
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;
// 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;
int samples_to_read = min(max_samples_to_read, remaining_samples);
size_t bytes_to_read = samples_to_read * bytes_per_sample;
auto max_samples_to_read = max_samples_to_read_from_input / bytes_per_sample;
auto samples_to_read = min(max_samples_to_read, remaining_samples);
auto bytes_to_read = samples_to_read * bytes_per_sample;
dbgln_if(AWAVLOADER_DEBUG, "Read {} bytes WAV with num_channels {} sample rate {}, "
"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);
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();
m_stream->read_or_error(sample_data.bytes());
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(
sample_data.bytes(),
@ -85,24 +85,24 @@ LoaderSamples WavLoaderPlugin::get_more_samples(size_t max_bytes_to_read_from_in
m_sample_format);
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 += samples_to_read;
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);
if (sample_index < 0 || sample_index >= m_total_samples)
return LoaderError { LoaderError::Category::Internal, static_cast<size_t>(m_loaded_samples), "Seek outside the sample range" };
if (sample_index < 0 || sample_index >= static_cast<int>(m_total_samples))
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.
if (m_file) {
m_file->seek(sample_offset);
m_file->seek(static_cast<int>(sample_offset));
} else {
m_memory_stream->seek(sample_offset);
}
@ -244,7 +244,7 @@ MaybeLoaderError WavLoaderPlugin::parse_header()
// Read chunks until we find DATA
bool found_data = false;
u32 data_sz = 0;
u32 data_size = 0;
u8 search_byte = 0;
while (true) {
search_byte = read_u8();
@ -262,7 +262,7 @@ MaybeLoaderError WavLoaderPlugin::parse_header()
if (search_remaining != 0x6174) // TA
continue;
data_sz = read_u32();
data_size = read_u32();
found_data = true;
break;
}
@ -270,13 +270,13 @@ MaybeLoaderError WavLoaderPlugin::parse_header()
ok = ok && found_data;
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");
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 {}",
data_sz,
data_size,
block_size_bytes,
m_total_samples);

View file

@ -22,12 +22,12 @@
namespace Audio {
// defines for handling the WAV header data
#define WAVE_FORMAT_PCM 0x0001 // PCM
#define WAVE_FORMAT_IEEE_FLOAT 0x0003 // IEEE float
#define WAVE_FORMAT_ALAW 0x0006 // 8-bit ITU-T G.711 A-law
#define WAVE_FORMAT_MULAW 0x0007 // 8-bit ITU-T G.711 µ-law
#define WAVE_FORMAT_EXTENSIBLE 0xFFFE // Determined by SubFormat
// constants for handling the WAV header data
static constexpr unsigned const WAVE_FORMAT_PCM = 0x0001; // PCM
static constexpr unsigned const WAVE_FORMAT_IEEE_FLOAT = 0x0003; // IEEE float
static constexpr unsigned const WAVE_FORMAT_ALAW = 0x0006; // 8-bit ITU-T G.711 A-law
static constexpr unsigned const WAVE_FORMAT_MULAW = 0x0007; // 8-bit ITU-T G.711 µ-law
static constexpr unsigned const WAVE_FORMAT_EXTENSIBLE = 0xFFFE; // Determined by SubFormat
// Parses a WAV file and produces an Audio::LegacyBuffer.
class WavLoaderPlugin : public LoaderPlugin {
@ -37,18 +37,16 @@ public:
virtual MaybeLoaderError initialize() override;
// The Buffer returned contains input data resampled at the
// destination audio device sample rate.
virtual LoaderSamples get_more_samples(size_t max_bytes_to_read_from_input = 128 * KiB) override;
virtual LoaderSamples get_more_samples(size_t max_samples_to_read_from_input = 128 * KiB) override;
virtual MaybeLoaderError reset() override { return seek(0); }
// sample_index 0 is the start of the raw audio sample data
// 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 total_samples() override { return m_total_samples; }
virtual int loaded_samples() override { return static_cast<int>(m_loaded_samples); }
virtual int total_samples() override { return static_cast<int>(m_total_samples); }
virtual u32 sample_rate() override { return m_sample_rate; }
virtual u16 num_channels() override { return m_num_channels; }
virtual String format_name() override { return "RIFF WAVE (.wav)"; }
@ -68,8 +66,8 @@ private:
PcmSampleFormat m_sample_format;
size_t m_byte_offset_of_data_samples { 0 };
int m_loaded_samples { 0 };
int m_total_samples { 0 };
size_t m_loaded_samples { 0 };
size_t m_total_samples { 0 };
};
}