LibAudio+Userland: Remove Audio::LegacyBuffer

The file is now renamed to Queue.h, and the Resampler APIs with
LegacyBuffer are also removed. These changes look large because nobody
actually needs Buffer.h (or Queue.h). It was mostly transitive
dependencies on the massive list of includes in that header, which are
now almost all gone. Instead, we include common things like Sample.h
directly, which should give faster compile times as very few files
actually need Queue.h.
This commit is contained in:
kleines Filmröllchen 2022-04-23 12:30:36 +02:00 committed by Linus Groh
parent f14a71eb34
commit ab49fcfb7c
27 changed files with 39 additions and 297 deletions

View file

@ -8,8 +8,9 @@
#pragma once
#include "Music.h"
#include <LibAudio/Buffer.h>
#include <LibAudio/ConnectionFromClient.h>
#include <LibAudio/Resampler.h>
#include <LibAudio/Sample.h>
#include <LibAudio/WavWriter.h>
#include <LibCore/Event.h>
#include <LibCore/Object.h>

View file

@ -13,7 +13,6 @@
#include <AK/Noncopyable.h>
#include <AK/NonnullRefPtr.h>
#include <AK/SinglyLinkedList.h>
#include <LibAudio/Buffer.h>
#include <LibDSP/Effects.h>
#include <LibDSP/Music.h>
#include <LibDSP/Synthesizers.h>

View file

@ -11,7 +11,6 @@
#include "MainWidget.h"
#include "TrackManager.h"
#include <AK/Queue.h>
#include <LibAudio/Buffer.h>
#include <LibAudio/ConnectionFromClient.h>
#include <LibAudio/WavWriter.h>
#include <LibCore/EventLoop.h>

View file

@ -8,7 +8,6 @@
#pragma once
#include "VisualizationWidget.h"
#include <LibAudio/Buffer.h>
#include <LibGUI/Frame.h>
class AlbumCoverVisualizationWidget final : public VisualizationWidget {

View file

@ -11,7 +11,6 @@
#include <AK/Array.h>
#include <AK/Complex.h>
#include <AK/FixedArray.h>
#include <LibAudio/Buffer.h>
#include <LibGUI/Frame.h>
class BarsVisualizationWidget final : public VisualizationWidget {

View file

@ -10,9 +10,9 @@
#include <AK/FixedArray.h>
#include <AK/Queue.h>
#include <AK/Vector.h>
#include <LibAudio/Buffer.h>
#include <LibAudio/ConnectionFromClient.h>
#include <LibAudio/Loader.h>
#include <LibAudio/Resampler.h>
#include <LibAudio/Sample.h>
#include <LibCore/Timer.h>

View file

@ -7,7 +7,6 @@
#include "SampleWidget.h"
#include <AK/Math.h>
#include <LibAudio/Buffer.h>
#include <LibGUI/Painter.h>
SampleWidget::SampleWidget()

View file

@ -9,7 +9,7 @@
#include <AK/FixedArray.h>
#include <AK/Forward.h>
#include <AK/TypedTransfer.h>
#include <LibAudio/Buffer.h>
#include <LibAudio/Sample.h>
#include <LibGUI/Frame.h>
#include <LibGUI/Painter.h>

View file

@ -1,139 +0,0 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2021, kleines Filmröllchen <filmroellchen@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "Buffer.h"
#include <AK/Atomic.h>
#include <AK/Debug.h>
#include <AK/StdLibExtras.h>
#include <AK/String.h>
namespace Audio {
i32 LegacyBuffer::allocate_id()
{
static Atomic<i32> next_id;
return next_id++;
}
template<typename SampleReader>
static void read_samples_from_stream(InputMemoryStream& stream, SampleReader read_sample, Vector<Sample>& samples, int num_channels)
{
double left_channel_sample = 0;
double right_channel_sample = 0;
switch (num_channels) {
case 1:
for (;;) {
left_channel_sample = read_sample(stream);
samples.append(Sample(left_channel_sample));
if (stream.handle_any_error()) {
break;
}
}
break;
case 2:
for (;;) {
left_channel_sample = read_sample(stream);
right_channel_sample = read_sample(stream);
samples.append(Sample(left_channel_sample, right_channel_sample));
if (stream.handle_any_error()) {
break;
}
}
break;
default:
VERIFY_NOT_REACHED();
}
}
static double read_float_sample_64(InputMemoryStream& stream)
{
LittleEndian<double> sample;
stream >> sample;
return double(sample);
}
static double read_float_sample_32(InputMemoryStream& stream)
{
LittleEndian<float> sample;
stream >> sample;
return double(sample);
}
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();
}
ErrorOr<NonnullRefPtr<LegacyBuffer>> LegacyBuffer::from_pcm_data(ReadonlyBytes data, int num_channels, PcmSampleFormat sample_format)
{
InputMemoryStream stream { data };
return from_pcm_stream(stream, num_channels, sample_format, data.size() / (pcm_bits_per_sample(sample_format) / 8));
}
ErrorOr<NonnullRefPtr<LegacyBuffer>> LegacyBuffer::from_pcm_stream(InputMemoryStream& stream, int num_channels, PcmSampleFormat sample_format, int num_samples)
{
Vector<Sample> fdata;
fdata.ensure_capacity(num_samples);
switch (sample_format) {
case PcmSampleFormat::Uint8:
read_samples_from_stream(stream, read_norm_sample_8, fdata, num_channels);
break;
case PcmSampleFormat::Int16:
read_samples_from_stream(stream, read_norm_sample_16, fdata, num_channels);
break;
case PcmSampleFormat::Int24:
read_samples_from_stream(stream, read_norm_sample_24, fdata, num_channels);
break;
case PcmSampleFormat::Float32:
read_samples_from_stream(stream, read_float_sample_32, fdata, num_channels);
break;
case PcmSampleFormat::Float64:
read_samples_from_stream(stream, read_float_sample_64, fdata, num_channels);
break;
default:
VERIFY_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.
VERIFY(!stream.handle_any_error());
return LegacyBuffer::create_with_samples(move(fdata));
}
}

View file

@ -1,104 +0,0 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2021, kleines Filmröllchen <filmroellchen@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include "AK/TypedTransfer.h"
#include <AK/ByteBuffer.h>
#include <AK/Error.h>
#include <AK/FixedArray.h>
#include <AK/MemoryStream.h>
#include <AK/NonnullRefPtr.h>
#include <AK/RefPtr.h>
#include <AK/String.h>
#include <AK/Types.h>
#include <AK/Vector.h>
#include <AK/kmalloc.h>
#include <LibAudio/Resampler.h>
#include <LibAudio/Sample.h>
#include <LibAudio/SampleFormats.h>
#include <LibCore/AnonymousBuffer.h>
#include <LibCore/SharedCircularQueue.h>
#include <string.h>
namespace Audio {
static constexpr size_t AUDIO_BUFFERS_COUNT = 128;
// The audio buffer size is specifically chosen to be about 1/1000th of a second (1ms).
// This has the biggest impact on latency and performance.
// The currently chosen value was not put here with much thought and a better choice is surely possible.
static constexpr size_t AUDIO_BUFFER_SIZE = 50;
using AudioQueue = Core::SharedSingleProducerCircularQueue<Array<Sample, AUDIO_BUFFER_SIZE>, AUDIO_BUFFERS_COUNT>;
using namespace AK::Exponentials;
// A buffer of audio samples.
class LegacyBuffer : public RefCounted<LegacyBuffer> {
public:
static ErrorOr<NonnullRefPtr<LegacyBuffer>> from_pcm_data(ReadonlyBytes data, int num_channels, PcmSampleFormat sample_format);
static ErrorOr<NonnullRefPtr<LegacyBuffer>> from_pcm_stream(InputMemoryStream& stream, int num_channels, PcmSampleFormat sample_format, int num_samples);
template<ArrayLike<Sample> ArrayT>
static ErrorOr<NonnullRefPtr<LegacyBuffer>> create_with_samples(ArrayT&& samples)
{
return adopt_nonnull_ref_or_enomem(new (nothrow) LegacyBuffer(move(samples)));
}
static ErrorOr<NonnullRefPtr<LegacyBuffer>> create_with_anonymous_buffer(Core::AnonymousBuffer buffer, i32 buffer_id, int sample_count)
{
return adopt_nonnull_ref_or_enomem(new (nothrow) LegacyBuffer(move(buffer), buffer_id, sample_count));
}
static NonnullRefPtr<LegacyBuffer> create_empty()
{
// If we can't allocate an empty buffer, things are in a very bad state.
return MUST(adopt_nonnull_ref_or_enomem(new (nothrow) LegacyBuffer));
}
Sample const* samples() const { return (Sample const*)data(); }
ErrorOr<FixedArray<Sample>> to_sample_array() const
{
FixedArray<Sample> samples = TRY(FixedArray<Sample>::try_create(m_sample_count));
AK::TypedTransfer<Sample>::copy(samples.data(), this->samples(), m_sample_count);
return samples;
}
int sample_count() const { return m_sample_count; }
void const* data() const { return m_buffer.data<void>(); }
int size_in_bytes() const { return m_sample_count * (int)sizeof(Sample); }
int id() const { return m_id; }
Core::AnonymousBuffer const& anonymous_buffer() const { return m_buffer; }
private:
template<ArrayLike<Sample> ArrayT>
explicit LegacyBuffer(ArrayT&& samples)
: m_buffer(Core::AnonymousBuffer::create_with_size(samples.size() * sizeof(Sample)).release_value())
, m_id(allocate_id())
, m_sample_count(samples.size())
{
memcpy(m_buffer.data<void>(), samples.data(), samples.size() * sizeof(Sample));
}
explicit LegacyBuffer(Core::AnonymousBuffer buffer, i32 buffer_id, int sample_count)
: m_buffer(move(buffer))
, m_id(buffer_id)
, m_sample_count(sample_count)
{
}
// Empty Buffer representation, to avoid tiny anonymous buffers in EOF states
LegacyBuffer() = default;
static i32 allocate_id();
Core::AnonymousBuffer m_buffer;
const i32 m_id { -1 };
int const m_sample_count { 0 };
};
// This only works for double resamplers, and therefore cannot be part of the class
ErrorOr<NonnullRefPtr<LegacyBuffer>> resample_buffer(ResampleHelper<double>& resampler, LegacyBuffer const& to_resample);
}

View file

@ -1,6 +1,4 @@
set(SOURCES
Buffer.cpp
Resampler.cpp
SampleFormats.cpp
ConnectionFromClient.cpp
Loader.cpp

View file

@ -11,7 +11,7 @@
#include <AK/FixedArray.h>
#include <AK/NonnullOwnPtr.h>
#include <AK/OwnPtr.h>
#include <LibAudio/Buffer.h>
#include <LibAudio/Queue.h>
#include <LibAudio/UserSampleQueue.h>
#include <LibCore/EventLoop.h>
#include <LibCore/Object.h>

View file

@ -13,14 +13,13 @@
#include <AK/ScopeGuard.h>
#include <AK/StdLibExtras.h>
#include <AK/String.h>
#include <AK/StringBuilder.h>
#include <AK/Try.h>
#include <AK/TypedTransfer.h>
#include <AK/UFixedBigInt.h>
#include <LibAudio/Buffer.h>
#include <LibAudio/FlacLoader.h>
#include <LibAudio/FlacTypes.h>
#include <LibAudio/LoaderError.h>
#include <LibAudio/Resampler.h>
#include <LibCore/MemoryStream.h>
#include <LibCore/Stream.h>

View file

@ -6,7 +6,6 @@
#pragma once
#include "Buffer.h"
#include "FlacTypes.h"
#include "Loader.h"
#include <AK/Error.h>

View file

@ -6,7 +6,8 @@
#pragma once
#include "Buffer.h"
#include "Queue.h"
#include "SampleFormats.h"
#include <AK/ByteBuffer.h>
#include <AK/Types.h>
#include <AK/Variant.h>

View file

@ -6,6 +6,7 @@
#pragma once
#include <AK/FixedArray.h>
#include <AK/NonnullOwnPtr.h>
#include <AK/NonnullRefPtr.h>
#include <AK/RefCounted.h>
@ -14,8 +15,9 @@
#include <AK/Span.h>
#include <AK/StringView.h>
#include <AK/Try.h>
#include <LibAudio/Buffer.h>
#include <LibAudio/LoaderError.h>
#include <LibAudio/Sample.h>
#include <LibAudio/SampleFormats.h>
#include <LibCore/File.h>
namespace Audio {

View file

@ -6,9 +6,9 @@
#pragma once
#include "Buffer.h"
#include "Loader.h"
#include "MP3Types.h"
#include <AK/MemoryStream.h>
#include <AK/Tuple.h>
#include <LibCore/FileStream.h>
#include <LibDSP/MDCT.h>

View file

@ -0,0 +1,21 @@
/*
* Copyright (c) 2018-2022, the SerenityOS developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <LibAudio/Sample.h>
#include <LibCore/SharedCircularQueue.h>
namespace Audio {
static constexpr size_t AUDIO_BUFFERS_COUNT = 128;
// The audio buffer size is specifically chosen to be about 1/1000th of a second (1ms).
// This has the biggest impact on latency and performance.
// The currently chosen value was not put here with much thought and a better choice is surely possible.
static constexpr size_t AUDIO_BUFFER_SIZE = 50;
using AudioQueue = Core::SharedSingleProducerCircularQueue<Array<Sample, AUDIO_BUFFER_SIZE>, AUDIO_BUFFERS_COUNT>;
}

View file

@ -1,28 +0,0 @@
/*
* Copyright (c) 2022, kleines Filmröllchen <filmroellchen@serenityos.org>.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "Resampler.h"
#include "Buffer.h"
#include "Sample.h"
namespace Audio {
ErrorOr<NonnullRefPtr<LegacyBuffer>> resample_buffer(ResampleHelper<double>& resampler, LegacyBuffer const& to_resample)
{
Vector<Sample> resampled;
resampled.ensure_capacity(to_resample.sample_count() * ceil_div(resampler.source(), resampler.target()));
for (size_t i = 0; i < static_cast<size_t>(to_resample.sample_count()); ++i) {
auto sample = to_resample.samples()[i];
resampler.process_sample(sample.left, sample.right);
while (resampler.read_sample(sample.left, sample.right))
resampled.append(sample);
}
return LegacyBuffer::create_with_samples(move(resampled));
}
}

View file

@ -84,7 +84,4 @@ private:
SampleType m_last_sample_r {};
};
class LegacyBuffer;
ErrorOr<NonnullRefPtr<LegacyBuffer>> resample_buffer(ResampleHelper<double>& resampler, LegacyBuffer const& to_resample);
}

View file

@ -10,7 +10,7 @@
#include <AK/Types.h>
#include <AK/Variant.h>
#include <AK/Vector.h>
#include <LibAudio/Buffer.h>
#include <LibAudio/Sample.h>
#include <LibDSP/Envelope.h>
namespace LibDSP {

View file

@ -7,6 +7,7 @@
#include <AK/HashMap.h>
#include <AK/Math.h>
#include <AK/Random.h>
#include <LibAudio/Sample.h>
#include <LibDSP/Envelope.h>
#include <LibDSP/Processor.h>
#include <LibDSP/Synthesizers.h>

View file

@ -1,5 +1,5 @@
#include <LibCore/AnonymousBuffer.h>
#include <LibAudio/Buffer.h>
#include <LibAudio/Queue.h>
endpoint AudioServer
{

View file

@ -7,7 +7,7 @@
#include "ConnectionFromClient.h"
#include "Mixer.h"
#include <AudioServer/AudioClientEndpoint.h>
#include <LibAudio/Buffer.h>
#include <LibAudio/Queue.h>
namespace AudioServer {

View file

@ -9,7 +9,7 @@
#include <AK/HashMap.h>
#include <AudioServer/AudioClientEndpoint.h>
#include <AudioServer/AudioServerEndpoint.h>
#include <LibAudio/Buffer.h>
#include <LibAudio/Queue.h>
#include <LibCore/EventLoop.h>
#include <LibIPC/ConnectionFromClient.h>

View file

@ -16,7 +16,7 @@
#include <AK/Queue.h>
#include <AK/RefCounted.h>
#include <AK/WeakPtr.h>
#include <LibAudio/Buffer.h>
#include <LibAudio/Queue.h>
#include <LibCore/File.h>
#include <LibCore/Timer.h>
#include <LibThreading/ConditionVariable.h>

View file

@ -8,7 +8,6 @@
#include <AK/Variant.h>
#include <AK/Vector.h>
#include <LibAudio/Buffer.h>
#include <LibAudio/ConnectionFromClient.h>
#include <LibCore/ArgsParser.h>
#include <LibCore/EventLoop.h>