新增singleton_manager释放顺序整理, 新增audio_device_manager

This commit is contained in:
Nanako 2024-02-27 16:25:18 +08:00
parent 8b328cc0d6
commit dc28bf6e0f
8 changed files with 81 additions and 19 deletions

View File

@ -0,0 +1,21 @@
#include "audio_device_manager.h"
#include "dummy_audio_device.h"
#include "port_audio_device.h"
#include "audio/mixer/mixer.h"
void audio_device_manager::init(singleton_initliazer& initliazer) {
singleton_t<audio_device_manager>::init(initliazer);
initliazer.require<mixer>();
dummy_audio_device_ = new dummy_audio_device();
main_audio_device_ = new port_audio_device();
main_audio_device_->init();
dummy_audio_device_->init();
}
void audio_device_manager::release() {
singleton_t<audio_device_manager>::release();
delete dummy_audio_device_;
delete main_audio_device_;
}

View File

@ -0,0 +1,18 @@
#pragma once
#include "misc/singleton/singleton.h"
class dummy_audio_device;
class port_audio_device;
class audio_device_manager : public singleton_t<audio_device_manager> {
public:
void init(singleton_initliazer& initliazer) override;
void release() override;
const char* get_name() override { return "audio_device_manager"; }
private:
port_audio_device* main_audio_device_ = nullptr;
dummy_audio_device* dummy_audio_device_ = nullptr;
};
CORE_API inline audio_device_manager g_audio_device_manager;

View File

@ -19,7 +19,7 @@ port_audio_device::~port_audio_device() {
bool port_audio_device::init() {
Pa_Initialize();
try {
open_stream(0, Pa_GetDefaultOutputDevice(), sample_rate(), buffer_size());
open_stream(-1, Pa_GetDefaultOutputDevice(), sample_rate(), buffer_size());
} catch (const std::exception& e) {
spdlog::error("Init failed: {}", e.what());
return false;
@ -36,12 +36,14 @@ void port_audio_device::stop() {
Pa_StopStream(stream_);
Pa_CloseStream(stream_);
stream_ = nullptr;
render_thread_.join();
while (!render_thread_running_)
std::this_thread::sleep_for(std::chrono::milliseconds(1));
spdlog::info("port_audio stopped");
}
void port_audio_device::open_stream(uint32_t input_device, uint32_t output_device, double in_sample_rate, uint32_t in_buffer_size) {
PaStreamParameters* input_params = nullptr;
if (input_device > 0) {
void port_audio_device::open_stream(PaDeviceIndex input_device, PaDeviceIndex output_device, double in_sample_rate, uint32_t in_buffer_size) {
const PaStreamParameters* input_params = nullptr;
if (input_device >= 0) {
input_params_.device = input_device;
input_params_.channelCount = 2;
input_params_.sampleFormat = paFloat32 | paNonInterleaved;
@ -79,6 +81,7 @@ int port_audio_device::stream_callback(float** input, float** output, unsigned l
bool port_audio_device::on_set_buffer_size(uint32_t in_buffer_size) {
stop();
render_buffer_size_ = in_buffer_size * 4;
try {
open_stream(input_params_.device, output_params_.device, sample_rate(), in_buffer_size);
} catch (const std::exception& e) {
@ -101,8 +104,8 @@ bool port_audio_device::on_set_sample_rate(double in_sample_rate) {
void port_audio_device::render_thread() {
dummy_track* master = g_mixer.get_master();
render_thread_running_ = true;
spdlog::info("port_audio render thread started");
while (stream_) {
const uint32_t frames = buffer_size();
const double rate = sample_rate();
@ -124,4 +127,6 @@ void port_audio_device::render_thread() {
render_buffer_.Push(element, frames);
}
}
spdlog::info("port_audio render thread stopped");
render_thread_running_ = false;
}

View File

@ -12,7 +12,7 @@ public:
void stop();
void open_stream(uint32_t input_device, uint32_t output_device, double in_sample_rate, uint32_t in_buffer_size);
void open_stream(PaDeviceIndex input_device, PaDeviceIndex output_device, double in_sample_rate, uint32_t in_buffer_size);
int stream_callback(float** input, float** output, unsigned long frame_count, const PaStreamCallbackTimeInfo* time_info, PaStreamCallbackFlags status_flags);
protected:
@ -24,7 +24,8 @@ private:
void render_thread();
std::thread render_thread_;
circular_audio_buffer<float> render_buffer_;
uint32_t render_buffer_size_ = 0;
uint32_t render_buffer_size_ = 2048;
std::atomic_bool render_thread_running_ = false;
#pragma endregion
PaStreamParameters input_params_ = {};

View File

@ -51,8 +51,8 @@ public:
Capacity = InCapacity + 1;
ReadCounter = 0;
WriteCounter = 0;
InternalBuffer.Reset();
InternalBuffer.AddZeroed(Capacity);
InternalBuffer.clear();
InternalBuffer.resize(Capacity);
}
/** Reserve capacity.

View File

@ -73,7 +73,7 @@ void mixer::init(singleton_initliazer& initliazer) {
void mixer::release() {
singleton_t<mixer>::release();
for (mixer_track* const track: tracks_) {
for (const mixer_track* track : tracks_) {
delete track;
}
delete zero_track;

View File

@ -2,26 +2,39 @@
#include "singleton.h"
bool singleton_initliazer::has_init(singleton* s) {
return std::ranges::find(singletons_, s) != singletons_.end();
}
void singleton_initliazer::init_singleton(singleton* s) {
if (!has_init(s)) {
singletons_.push_back(s);
s->init(*this);
}
}
void singleton_manager::add(singleton* s) {
singletons_.push_back(s);
}
void singleton_manager::init() const {
void singleton_manager::init() {
singleton_initliazer initliazer;
for (const auto s : singletons_) {
s->init(initliazer);
initliazer.singletons_.push_back(s);
initliazer.init_singleton(s);
}
for (const auto s : singletons_) {
s->post_init();
}
singletons_ = initliazer.singletons_;
}
void singleton_manager::release() const {
for (const auto s : singletons_) {
for (int32_t j = singletons_.size() - 1; j >= 0; --j) {
auto s = singletons_[j];
s->begin_release();
}
for (const auto s : singletons_) {
for (int32_t j = singletons_.size() - 1; j >= 0; --j) {
auto s = singletons_[j];
s->release();
}
}

View File

@ -4,10 +4,14 @@ class singleton;
class singleton_initliazer {
public:
bool has_init(singleton* s);
void init_singleton(singleton* s);
template<class T>
T* require() {
auto instance = T::get();
if (std::find(singletons_.begin(), singletons_.end(), instance) != singletons_.end()) {
if (has_init(instance)) {
return instance;
}
singletons_.push_back(instance);
@ -27,7 +31,7 @@ public:
void add(singleton* s);
void init() const;
void init();
void release() const;
private: