Files
DevilutionX/Source/utils/push_aulib_decoder.h
Gleb Mazovetskiy ecdf7380a8 PushAulibDecoder: Support 8-bit samples directly
Previously, we converted 8-bit audio to 16-bit, and then to float.
Eliminates the 8->16 conversion step.

Also optimizes the 16-bit conversion a bit.
2023-08-15 17:17:33 +09:00

88 lines
1.9 KiB
C++

#pragma once
#include <chrono>
#include <cstdint>
#include <cstring>
#include <memory>
#include <mutex>
#include <queue>
#include <variant>
#include <Aulib/Decoder.h>
#include <SDL_mutex.h>
#include "utils/sdl_mutex.h"
namespace devilution {
/**
* @brief A Decoder interface implementations that simply has the samples pushed into it by the user.
*/
class PushAulibDecoder final : public ::Aulib::Decoder {
public:
PushAulibDecoder(int numChannels, int sampleRate)
: numChannels_(numChannels)
, sampleRate_(sampleRate)
{
}
template <typename T>
void PushSamples(const T *data, unsigned size) noexcept
{
AudioQueueItem item { data, size };
const auto lock = std::lock_guard(queue_mutex_);
queue_.push(std::move(item));
}
void DiscardPendingSamples() noexcept;
bool open(SDL_RWops *rwops) override;
[[nodiscard]] int getChannels() const override
{
return numChannels_;
}
[[nodiscard]] int getRate() const override
{
return sampleRate_;
}
bool rewind() override;
[[nodiscard]] std::chrono::microseconds duration() const override;
bool seekToTime(std::chrono::microseconds pos) override;
protected:
int doDecoding(float buf[], int len, bool &callAgain) override;
private:
struct AudioQueueItem {
std::variant<
std::unique_ptr<int16_t[]>,
std::unique_ptr<uint8_t[]>>
data;
unsigned len;
unsigned pos;
template <typename T>
AudioQueueItem(const T *data, unsigned size)
: data { std::unique_ptr<T[]> { new T[size] } }
, len { size }
, pos { 0 }
{
std::memcpy(std::get<std::unique_ptr<T[]>>(this->data).get(), data, size * sizeof(T));
}
};
const int numChannels_;
const int sampleRate_;
// Requires holding the queue_mutex_.
AudioQueueItem *Next();
std::queue<AudioQueueItem> queue_;
SdlMutex queue_mutex_;
};
} // namespace devilution