Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <cstdint>
/// @brief Enum representing the direction of buffer processing, either forward or reverse.
namespace audioapi {
enum class BufferProcessingDirection : std::int8_t { FORWARD = 1, REVERSE = -1 };
} // namespace audioapi
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

namespace audioapi {

/// @brief Struct to hold the state of the buffer cursor during processing.
struct CursorState {
size_t index = 0;
size_t nextIndex = 0;
Expand All @@ -17,22 +18,32 @@ struct CursorState {
bool isCrossBuffer = false;
};

/// @brief Abstract base class for processing audio buffers, handling position tracking, looping, and interpolation logic.
class BufferProcessorBase {
public:
virtual ~BufferProcessorBase() = default;
DELETE_COPY_AND_MOVE(BufferProcessorBase);

/// @brief Process the audio buffer, applying looping and interpolation as needed.
/// @param output The output buffer to write processed audio into.
/// @param writeIndex The starting index in the output buffer to write to.
/// @param framesLeft The number of frames left to process in this block.
/// @param rate The playback rate, which may affect processing direction and interpolation.
/// @param interpolate Whether to apply interpolation when processing.
void process(
const std::shared_ptr<DSPAudioBuffer> &output,
size_t writeIndex,
size_t framesLeft,
double rate,
bool interpolate);

/// @brief Get the current position of the buffer cursor.
/// @return The current position in frames.
[[nodiscard]] double getPosition() const {
return position_;
}

/// @brief Set the current position of the buffer cursor.
void setPosition(double position) {
position_ = position;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,21 @@ using OnBufferConsumed = FatFunction<
ON_BUFFER_CONSUMED_CALLBACK_SIZE,
void(size_t &, const std::shared_ptr<AudioBuffer> &, bool &, bool &)>;

/// @brief Buffer processor that handles a queue of audio buffers.
class QueueBufferProcessor : public BufferProcessorBase {
public:
QueueBufferProcessor(
std::list<std::pair<size_t, std::shared_ptr<AudioBuffer>>> *buffers,
OnBufferConsumed onBufferConsumed = {});

/// Arm an in-place tail buffer. When the main queue would drain during
/// @brief Arm an in-place tail buffer. When the main queue would drain during
/// processing, handleBoundary() appends this tail instead of stopping.
void setPendingTail(std::shared_ptr<AudioBuffer> tailBuffer) {
pendingTailBuffer_ = std::move(tailBuffer);
}

/// @brief Check if the pending tail buffer has been consumed.
/// @return True if the tail buffer has been consumed, false otherwise.
[[nodiscard]] bool didConsumeTail() const {
return tailConsumed_;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ size_t SingleBufferProcessor::remainingInContiguousBlock() const {
// +1 because we read down to and including startFrame_
return currentIndex() - startFrame_ + 1;
}
// Pure size_t arithmetic — no double promotion, no fractional truncation.
return endFrame_ - currentIndex();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,31 @@

namespace audioapi {

/// @brief Buffer processor that handles a single audio buffer.
/// @note Before processing, the buffer, start frame, and end frame must be set. Looping can also be enabled if desired.
class SingleBufferProcessor : public BufferProcessorBase {
public:
SingleBufferProcessor() = default;

[[nodiscard]] bool atBoundary() const override;
[[nodiscard]] bool shouldStop() const override;

/// @brief Set the starting frame for processing.
void setStartFrame(size_t startFrame) {
startFrame_ = startFrame;
}

/// @brief Set the ending frame for processing.
void setEndFrame(size_t endFrame) {
endFrame_ = endFrame;
}

/// @brief Enable or disable looping for this buffer processor.
void setLoop(bool loop) {
loop_ = loop;
}

/// @brief Set the audio buffer to process.
void setBuffer(std::shared_ptr<const AudioBuffer> buffer) {
buffer_ = std::move(buffer);
}
Expand Down
Loading