You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
93 lines
2.0 KiB
93 lines
2.0 KiB
#pragma once |
|
|
|
#include <chrono> |
|
#include <cstdint> |
|
#include <cstring> |
|
#include <memory> |
|
#include <mutex> |
|
#include <queue> |
|
#include <variant> |
|
|
|
#include <Aulib/Decoder.h> |
|
|
|
#ifdef USE_SDL3 |
|
#include <SDL3/SDL_mutex.h> |
|
#else |
|
#include <SDL_mutex.h> |
|
#endif |
|
|
|
#include "utils/sdl_compat.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_IOStream *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
|
|
|