新增singleton_manager释放顺序整理, 新增audio_device_manager
This commit is contained in:
parent
8b328cc0d6
commit
dc28bf6e0f
21
core/audio/device/audio_device_manager.cpp
Normal file
21
core/audio/device/audio_device_manager.cpp
Normal 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_;
|
||||
}
|
18
core/audio/device/audio_device_manager.h
Normal file
18
core/audio/device/audio_device_manager.h
Normal 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;
|
@ -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;
|
||||
}
|
||||
|
@ -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_ = {};
|
||||
|
@ -51,8 +51,8 @@ public:
|
||||
Capacity = InCapacity + 1;
|
||||
ReadCounter = 0;
|
||||
WriteCounter = 0;
|
||||
InternalBuffer.Reset();
|
||||
InternalBuffer.AddZeroed(Capacity);
|
||||
InternalBuffer.clear();
|
||||
InternalBuffer.resize(Capacity);
|
||||
}
|
||||
|
||||
/** Reserve capacity.
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user