summaryrefslogtreecommitdiff
path: root/Libraries/LibAudio
diff options
context:
space:
mode:
authorJulian Offenhäuser <metalvoidzz@gmail.com>2020-12-02 15:40:32 +0100
committerAndreas Kling <kling@serenityos.org>2020-12-02 16:31:30 +0100
commitdff59837068b042114e46bde9893d1d92b7f012b (patch)
tree3dbde68f8a62ccbbccaeab1810475d4194d5a526 /Libraries/LibAudio
parentbad8cd3d8f1d9a25e3cd9a9b9b4a68cc5aaa1193 (diff)
downloadserenity-dff59837068b042114e46bde9893d1d92b7f012b.zip
LibAudio: Move Audio::Buffer implementation into its own file
Diffstat (limited to 'Libraries/LibAudio')
-rw-r--r--Libraries/LibAudio/Buffer.cpp134
-rw-r--r--Libraries/LibAudio/Buffer.h4
-rw-r--r--Libraries/LibAudio/CMakeLists.txt1
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