Fix AudioEffectRecord not working without thread support
This commit is contained in:
parent
4c1a5d9cfe
commit
7da55fb739
|
@ -44,20 +44,25 @@ void AudioEffectRecordInstance::process(const AudioFrame *p_src_frames, AudioFra
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AudioEffectRecordInstance::_update_buffer() {
|
||||||
|
//Case: Frames are remaining in the buffer
|
||||||
|
while (ring_buffer_read_pos < ring_buffer_pos) {
|
||||||
|
//Read from the buffer into recording_data
|
||||||
|
_io_store_buffer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioEffectRecordInstance::_update(void *userdata) {
|
||||||
|
AudioEffectRecordInstance *ins = (AudioEffectRecordInstance *)userdata;
|
||||||
|
ins->_update_buffer();
|
||||||
|
}
|
||||||
|
|
||||||
bool AudioEffectRecordInstance::process_silence() const {
|
bool AudioEffectRecordInstance::process_silence() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioEffectRecordInstance::_io_thread_process() {
|
void AudioEffectRecordInstance::_io_thread_process() {
|
||||||
|
|
||||||
//Reset recorder status
|
|
||||||
thread_active = true;
|
thread_active = true;
|
||||||
ring_buffer_pos = 0;
|
|
||||||
ring_buffer_read_pos = 0;
|
|
||||||
|
|
||||||
//We start a new recording
|
|
||||||
recording_data.resize(0); //Clear data completely and reset length
|
|
||||||
is_recording = true;
|
|
||||||
|
|
||||||
while (is_recording) {
|
while (is_recording) {
|
||||||
//Check: The current recording has been requested to stop
|
//Check: The current recording has been requested to stop
|
||||||
|
@ -65,13 +70,9 @@ void AudioEffectRecordInstance::_io_thread_process() {
|
||||||
is_recording = false;
|
is_recording = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Case: Frames are remaining in the buffer
|
_update_buffer();
|
||||||
if (ring_buffer_read_pos < ring_buffer_pos) {
|
|
||||||
//Read from the buffer into recording_data
|
if (is_recording) {
|
||||||
_io_store_buffer();
|
|
||||||
}
|
|
||||||
//Case: The buffer is empty
|
|
||||||
else if (is_recording) {
|
|
||||||
//Wait to avoid too much busy-wait
|
//Wait to avoid too much busy-wait
|
||||||
OS::get_singleton()->delay_usec(500);
|
OS::get_singleton()->delay_usec(500);
|
||||||
}
|
}
|
||||||
|
@ -103,7 +104,35 @@ void AudioEffectRecordInstance::_thread_callback(void *_instance) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioEffectRecordInstance::init() {
|
void AudioEffectRecordInstance::init() {
|
||||||
|
//Reset recorder status
|
||||||
|
ring_buffer_pos = 0;
|
||||||
|
ring_buffer_read_pos = 0;
|
||||||
|
|
||||||
|
//We start a new recording
|
||||||
|
recording_data.resize(0); //Clear data completely and reset length
|
||||||
|
is_recording = true;
|
||||||
|
|
||||||
|
#ifdef NO_THREADS
|
||||||
|
AudioServer::get_singleton()->add_update_callback(&AudioEffectRecordInstance::_update, this);
|
||||||
|
#else
|
||||||
io_thread = Thread::create(_thread_callback, this);
|
io_thread = Thread::create(_thread_callback, this);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioEffectRecordInstance::finish() {
|
||||||
|
|
||||||
|
#ifdef NO_THREADS
|
||||||
|
AudioServer::get_singleton()->remove_update_callback(&AudioEffectRecordInstance::_update, this);
|
||||||
|
#else
|
||||||
|
if (thread_active) {
|
||||||
|
Thread::wait_to_finish(io_thread);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioEffectRecordInstance::~AudioEffectRecordInstance() {
|
||||||
|
|
||||||
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<AudioEffectInstance> AudioEffectRecord::instance() {
|
Ref<AudioEffectInstance> AudioEffectRecord::instance() {
|
||||||
|
@ -145,8 +174,8 @@ Ref<AudioEffectInstance> AudioEffectRecord::instance() {
|
||||||
|
|
||||||
void AudioEffectRecord::ensure_thread_stopped() {
|
void AudioEffectRecord::ensure_thread_stopped() {
|
||||||
recording_active = false;
|
recording_active = false;
|
||||||
if (current_instance != 0 && current_instance->thread_active) {
|
if (current_instance != 0) {
|
||||||
Thread::wait_to_finish(current_instance->io_thread);
|
current_instance->finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,14 +62,18 @@ class AudioEffectRecordInstance : public AudioEffectInstance {
|
||||||
void _io_store_buffer();
|
void _io_store_buffer();
|
||||||
static void _thread_callback(void *_instance);
|
static void _thread_callback(void *_instance);
|
||||||
void _init_recording();
|
void _init_recording();
|
||||||
|
void _update_buffer();
|
||||||
|
static void _update(void *userdata);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void init();
|
void init();
|
||||||
|
void finish();
|
||||||
virtual void process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count);
|
virtual void process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count);
|
||||||
virtual bool process_silence() const;
|
virtual bool process_silence() const;
|
||||||
|
|
||||||
AudioEffectRecordInstance() :
|
AudioEffectRecordInstance() :
|
||||||
thread_active(false) {}
|
thread_active(false) {}
|
||||||
|
~AudioEffectRecordInstance();
|
||||||
};
|
};
|
||||||
|
|
||||||
class AudioEffectRecord : public AudioEffect {
|
class AudioEffectRecord : public AudioEffect {
|
||||||
|
|
|
@ -1004,6 +1004,11 @@ void AudioServer::update() {
|
||||||
AudioDriver::get_singleton()->reset_profiling_time();
|
AudioDriver::get_singleton()->reset_profiling_time();
|
||||||
prof_time = 0;
|
prof_time = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
for (Set<CallbackItem>::Element *E = update_callbacks.front(); E; E = E->next()) {
|
||||||
|
|
||||||
|
E->get().callback(E->get().userdata);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioServer::load_default_bus_layout() {
|
void AudioServer::load_default_bus_layout() {
|
||||||
|
@ -1129,6 +1134,25 @@ void AudioServer::remove_callback(AudioCallback p_callback, void *p_userdata) {
|
||||||
unlock();
|
unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AudioServer::add_update_callback(AudioCallback p_callback, void *p_userdata) {
|
||||||
|
lock();
|
||||||
|
CallbackItem ci;
|
||||||
|
ci.callback = p_callback;
|
||||||
|
ci.userdata = p_userdata;
|
||||||
|
update_callbacks.insert(ci);
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioServer::remove_update_callback(AudioCallback p_callback, void *p_userdata) {
|
||||||
|
|
||||||
|
lock();
|
||||||
|
CallbackItem ci;
|
||||||
|
ci.callback = p_callback;
|
||||||
|
ci.userdata = p_userdata;
|
||||||
|
update_callbacks.erase(ci);
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
|
||||||
void AudioServer::set_bus_layout(const Ref<AudioBusLayout> &p_bus_layout) {
|
void AudioServer::set_bus_layout(const Ref<AudioBusLayout> &p_bus_layout) {
|
||||||
|
|
||||||
ERR_FAIL_COND(p_bus_layout.is_null() || p_bus_layout->buses.size() == 0);
|
ERR_FAIL_COND(p_bus_layout.is_null() || p_bus_layout->buses.size() == 0);
|
||||||
|
|
|
@ -262,6 +262,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
Set<CallbackItem> callbacks;
|
Set<CallbackItem> callbacks;
|
||||||
|
Set<CallbackItem> update_callbacks;
|
||||||
|
|
||||||
friend class AudioDriver;
|
friend class AudioDriver;
|
||||||
void _driver_process(int p_frames, int32_t *p_buffer);
|
void _driver_process(int p_frames, int32_t *p_buffer);
|
||||||
|
@ -357,6 +358,9 @@ public:
|
||||||
void add_callback(AudioCallback p_callback, void *p_userdata);
|
void add_callback(AudioCallback p_callback, void *p_userdata);
|
||||||
void remove_callback(AudioCallback p_callback, void *p_userdata);
|
void remove_callback(AudioCallback p_callback, void *p_userdata);
|
||||||
|
|
||||||
|
void add_update_callback(AudioCallback p_callback, void *p_userdata);
|
||||||
|
void remove_update_callback(AudioCallback p_callback, void *p_userdata);
|
||||||
|
|
||||||
void set_bus_layout(const Ref<AudioBusLayout> &p_bus_layout);
|
void set_bus_layout(const Ref<AudioBusLayout> &p_bus_layout);
|
||||||
Ref<AudioBusLayout> generate_bus_layout() const;
|
Ref<AudioBusLayout> generate_bus_layout() const;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue