新增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() {
|
bool port_audio_device::init() {
|
||||||
Pa_Initialize();
|
Pa_Initialize();
|
||||||
try {
|
try {
|
||||||
open_stream(0, Pa_GetDefaultOutputDevice(), sample_rate(), buffer_size());
|
open_stream(-1, Pa_GetDefaultOutputDevice(), sample_rate(), buffer_size());
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
spdlog::error("Init failed: {}", e.what());
|
spdlog::error("Init failed: {}", e.what());
|
||||||
return false;
|
return false;
|
||||||
@ -36,12 +36,14 @@ void port_audio_device::stop() {
|
|||||||
Pa_StopStream(stream_);
|
Pa_StopStream(stream_);
|
||||||
Pa_CloseStream(stream_);
|
Pa_CloseStream(stream_);
|
||||||
stream_ = nullptr;
|
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) {
|
void port_audio_device::open_stream(PaDeviceIndex input_device, PaDeviceIndex output_device, double in_sample_rate, uint32_t in_buffer_size) {
|
||||||
PaStreamParameters* input_params = nullptr;
|
const PaStreamParameters* input_params = nullptr;
|
||||||
if (input_device > 0) {
|
if (input_device >= 0) {
|
||||||
input_params_.device = input_device;
|
input_params_.device = input_device;
|
||||||
input_params_.channelCount = 2;
|
input_params_.channelCount = 2;
|
||||||
input_params_.sampleFormat = paFloat32 | paNonInterleaved;
|
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) {
|
bool port_audio_device::on_set_buffer_size(uint32_t in_buffer_size) {
|
||||||
stop();
|
stop();
|
||||||
|
render_buffer_size_ = in_buffer_size * 4;
|
||||||
try {
|
try {
|
||||||
open_stream(input_params_.device, output_params_.device, sample_rate(), in_buffer_size);
|
open_stream(input_params_.device, output_params_.device, sample_rate(), in_buffer_size);
|
||||||
} catch (const std::exception& e) {
|
} 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() {
|
void port_audio_device::render_thread() {
|
||||||
dummy_track* master = g_mixer.get_master();
|
dummy_track* master = g_mixer.get_master();
|
||||||
|
render_thread_running_ = true;
|
||||||
|
spdlog::info("port_audio render thread started");
|
||||||
while (stream_) {
|
while (stream_) {
|
||||||
const uint32_t frames = buffer_size();
|
const uint32_t frames = buffer_size();
|
||||||
const double rate = sample_rate();
|
const double rate = sample_rate();
|
||||||
@ -124,4 +127,6 @@ void port_audio_device::render_thread() {
|
|||||||
render_buffer_.Push(element, frames);
|
render_buffer_.Push(element, frames);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
spdlog::info("port_audio render thread stopped");
|
||||||
|
render_thread_running_ = false;
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ public:
|
|||||||
|
|
||||||
void stop();
|
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);
|
int stream_callback(float** input, float** output, unsigned long frame_count, const PaStreamCallbackTimeInfo* time_info, PaStreamCallbackFlags status_flags);
|
||||||
protected:
|
protected:
|
||||||
@ -24,7 +24,8 @@ private:
|
|||||||
void render_thread();
|
void render_thread();
|
||||||
std::thread render_thread_;
|
std::thread render_thread_;
|
||||||
circular_audio_buffer<float> render_buffer_;
|
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
|
#pragma endregion
|
||||||
|
|
||||||
PaStreamParameters input_params_ = {};
|
PaStreamParameters input_params_ = {};
|
||||||
|
@ -51,8 +51,8 @@ public:
|
|||||||
Capacity = InCapacity + 1;
|
Capacity = InCapacity + 1;
|
||||||
ReadCounter = 0;
|
ReadCounter = 0;
|
||||||
WriteCounter = 0;
|
WriteCounter = 0;
|
||||||
InternalBuffer.Reset();
|
InternalBuffer.clear();
|
||||||
InternalBuffer.AddZeroed(Capacity);
|
InternalBuffer.resize(Capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Reserve capacity.
|
/** Reserve capacity.
|
||||||
|
@ -73,7 +73,7 @@ void mixer::init(singleton_initliazer& initliazer) {
|
|||||||
|
|
||||||
void mixer::release() {
|
void mixer::release() {
|
||||||
singleton_t<mixer>::release();
|
singleton_t<mixer>::release();
|
||||||
for (mixer_track* const track: tracks_) {
|
for (const mixer_track* track : tracks_) {
|
||||||
delete track;
|
delete track;
|
||||||
}
|
}
|
||||||
delete zero_track;
|
delete zero_track;
|
||||||
|
@ -2,26 +2,39 @@
|
|||||||
|
|
||||||
#include "singleton.h"
|
#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) {
|
void singleton_manager::add(singleton* s) {
|
||||||
singletons_.push_back(s);
|
singletons_.push_back(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void singleton_manager::init() const {
|
void singleton_manager::init() {
|
||||||
singleton_initliazer initliazer;
|
singleton_initliazer initliazer;
|
||||||
for (const auto s : singletons_) {
|
for (const auto s : singletons_) {
|
||||||
s->init(initliazer);
|
initliazer.init_singleton(s);
|
||||||
initliazer.singletons_.push_back(s);
|
|
||||||
}
|
}
|
||||||
for (const auto s : singletons_) {
|
for (const auto s : singletons_) {
|
||||||
s->post_init();
|
s->post_init();
|
||||||
}
|
}
|
||||||
|
singletons_ = initliazer.singletons_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void singleton_manager::release() const {
|
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();
|
s->begin_release();
|
||||||
}
|
}
|
||||||
for (const auto s : singletons_) {
|
for (int32_t j = singletons_.size() - 1; j >= 0; --j) {
|
||||||
|
auto s = singletons_[j];
|
||||||
s->release();
|
s->release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,14 @@ class singleton;
|
|||||||
|
|
||||||
class singleton_initliazer {
|
class singleton_initliazer {
|
||||||
public:
|
public:
|
||||||
|
bool has_init(singleton* s);
|
||||||
|
|
||||||
|
void init_singleton(singleton* s);
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
T* require() {
|
T* require() {
|
||||||
auto instance = T::get();
|
auto instance = T::get();
|
||||||
if (std::find(singletons_.begin(), singletons_.end(), instance) != singletons_.end()) {
|
if (has_init(instance)) {
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
singletons_.push_back(instance);
|
singletons_.push_back(instance);
|
||||||
@ -27,7 +31,7 @@ public:
|
|||||||
|
|
||||||
void add(singleton* s);
|
void add(singleton* s);
|
||||||
|
|
||||||
void init() const;
|
void init();
|
||||||
void release() const;
|
void release() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user