diff options
author | Julian Offenhäuser <metalvoidzz@gmail.com> | 2020-12-02 15:40:32 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-12-02 16:31:30 +0100 |
commit | dff59837068b042114e46bde9893d1d92b7f012b (patch) | |
tree | 3dbde68f8a62ccbbccaeab1810475d4194d5a526 /Libraries/LibAudio | |
parent | bad8cd3d8f1d9a25e3cd9a9b9b4a68cc5aaa1193 (diff) | |
download | serenity-dff59837068b042114e46bde9893d1d92b7f012b.zip |
LibAudio: Move Audio::Buffer implementation into its own file
Diffstat (limited to 'Libraries/LibAudio')
-rw-r--r-- | Libraries/LibAudio/Buffer.cpp | 134 | ||||
-rw-r--r-- | Libraries/LibAudio/Buffer.h | 4 | ||||
-rw-r--r-- | Libraries/LibAudio/CMakeLists.txt | 1 |
3 files changed, 138 insertions, 1 deletions
diff --git a/Libraries/LibAudio/Buffer.cpp b/Libraries/LibAudio/Buffer.cpp new file mode 100644 index 0000000000..29bb24e908 --- /dev/null +++ b/Libraries/LibAudio/Buffer.cpp @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <LibAudio/Buffer.h> + +namespace Audio { + +template<typename SampleReader> +static void read_samples_from_stream(InputMemoryStream& stream, SampleReader read_sample, Vector<Sample>& samples, ResampleHelper& resampler, int num_channels) +{ + double norm_l = 0; + double norm_r = 0; + + switch (num_channels) { + case 1: + for (;;) { + while (resampler.read_sample(norm_l, norm_r)) { + samples.append(Sample(norm_l)); + } + norm_l = read_sample(stream); + + if (stream.handle_any_error()) { + break; + } + resampler.process_sample(norm_l, norm_r); + } + break; + case 2: + for (;;) { + while (resampler.read_sample(norm_l, norm_r)) { + samples.append(Sample(norm_l, norm_r)); + } + norm_l = read_sample(stream); + norm_r = read_sample(stream); + + if (stream.handle_any_error()) { + break; + } + resampler.process_sample(norm_l, norm_r); + } + break; + default: + ASSERT_NOT_REACHED(); + } +} + +static double read_norm_sample_24(InputMemoryStream& stream) +{ + u8 byte = 0; + stream >> byte; + u32 sample1 = byte; + stream >> byte; + u32 sample2 = byte; + stream >> byte; + u32 sample3 = byte; + + i32 value = 0; + value = sample1 << 8; + value |= (sample2 << 16); + value |= (sample3 << 24); + return double(value) / NumericLimits<i32>::max(); +} + +static double read_norm_sample_16(InputMemoryStream& stream) +{ + LittleEndian<i16> sample; + stream >> sample; + return double(sample) / NumericLimits<i16>::max(); +} + +static double read_norm_sample_8(InputMemoryStream& stream) +{ + u8 sample = 0; + stream >> sample; + return double(sample) / NumericLimits<u8>::max(); +} + +RefPtr<Buffer> Buffer::from_pcm_data(ReadonlyBytes data, ResampleHelper& resampler, int num_channels, int bits_per_sample) +{ + InputMemoryStream stream { data }; + return from_pcm_stream(stream, resampler, num_channels, bits_per_sample, data.size() / (bits_per_sample / 8)); +} + +RefPtr<Buffer> Buffer::from_pcm_stream(InputMemoryStream &stream, ResampleHelper& resampler, int num_channels, int bits_per_sample, int num_samples) +{ + Vector<Sample> fdata; + fdata.ensure_capacity(num_samples); + + switch (bits_per_sample) { + case 8: + read_samples_from_stream(stream, read_norm_sample_8, fdata, resampler, num_channels); + break; + case 16: + read_samples_from_stream(stream, read_norm_sample_16, fdata, resampler, num_channels); + break; + case 24: + read_samples_from_stream(stream, read_norm_sample_24, fdata, resampler, num_channels); + break; + default: + ASSERT_NOT_REACHED(); + } + + // We should handle this in a better way above, but for now -- + // just make sure we're good. Worst case we just write some 0s where they + // don't belong. + ASSERT(!stream.handle_any_error()); + + return Buffer::create_with_samples(move(fdata)); +} + +} diff --git a/Libraries/LibAudio/Buffer.h b/Libraries/LibAudio/Buffer.h index 24001176c3..5be0c2443a 100644 --- a/Libraries/LibAudio/Buffer.h +++ b/Libraries/LibAudio/Buffer.h @@ -27,6 +27,7 @@ #pragma once #include <AK/ByteBuffer.h> +#include <AK/MemoryStream.h> #include <AK/SharedBuffer.h> #include <AK/Types.h> #include <AK/Vector.h> @@ -108,7 +109,8 @@ private: // A buffer of audio samples, normalized to 44100hz. class Buffer : public RefCounted<Buffer> { public: - static RefPtr<Buffer> from_pcm_data(ReadonlyBytes, ResampleHelper& resampler, int num_channels, int bits_per_sample); + static RefPtr<Buffer> from_pcm_data(ReadonlyBytes data, ResampleHelper& resampler, int num_channels, int bits_per_sample); + static RefPtr<Buffer> from_pcm_stream(InputMemoryStream& stream, ResampleHelper& resampler, int num_channels, int bits_per_sample, int num_samples); static NonnullRefPtr<Buffer> create_with_samples(Vector<Sample>&& samples) { return adopt(*new Buffer(move(samples))); diff --git a/Libraries/LibAudio/CMakeLists.txt b/Libraries/LibAudio/CMakeLists.txt index 3293b31239..bde29e3aa7 100644 --- a/Libraries/LibAudio/CMakeLists.txt +++ b/Libraries/LibAudio/CMakeLists.txt @@ -1,4 +1,5 @@ set(SOURCES + Buffer.cpp ClientConnection.cpp Loader.cpp WavLoader.cpp |