mirror of
https://github.com/godotengine/godot.git
synced 2024-11-22 04:06:14 +00:00
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 {
|
||||
return true;
|
||||
}
|
||||
|
||||
void AudioEffectRecordInstance::_io_thread_process() {
|
||||
|
||||
//Reset recorder status
|
||||
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) {
|
||||
//Check: The current recording has been requested to stop
|
||||
@ -65,13 +70,9 @@ void AudioEffectRecordInstance::_io_thread_process() {
|
||||
is_recording = false;
|
||||
}
|
||||
|
||||
//Case: Frames are remaining in the buffer
|
||||
if (ring_buffer_read_pos < ring_buffer_pos) {
|
||||
//Read from the buffer into recording_data
|
||||
_io_store_buffer();
|
||||
}
|
||||
//Case: The buffer is empty
|
||||
else if (is_recording) {
|
||||
_update_buffer();
|
||||
|
||||
if (is_recording) {
|
||||
//Wait to avoid too much busy-wait
|
||||
OS::get_singleton()->delay_usec(500);
|
||||
}
|
||||
@ -103,7 +104,35 @@ void AudioEffectRecordInstance::_thread_callback(void *_instance) {
|
||||
}
|
||||
|
||||
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);
|
||||
#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() {
|
||||
@ -145,8 +174,8 @@ Ref<AudioEffectInstance> AudioEffectRecord::instance() {
|
||||
|
||||
void AudioEffectRecord::ensure_thread_stopped() {
|
||||
recording_active = false;
|
||||
if (current_instance != 0 && current_instance->thread_active) {
|
||||
Thread::wait_to_finish(current_instance->io_thread);
|
||||
if (current_instance != 0) {
|
||||
current_instance->finish();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,14 +62,18 @@ class AudioEffectRecordInstance : public AudioEffectInstance {
|
||||
void _io_store_buffer();
|
||||
static void _thread_callback(void *_instance);
|
||||
void _init_recording();
|
||||
void _update_buffer();
|
||||
static void _update(void *userdata);
|
||||
|
||||
public:
|
||||
void init();
|
||||
void finish();
|
||||
virtual void process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count);
|
||||
virtual bool process_silence() const;
|
||||
|
||||
AudioEffectRecordInstance() :
|
||||
thread_active(false) {}
|
||||
~AudioEffectRecordInstance();
|
||||
};
|
||||
|
||||
class AudioEffectRecord : public AudioEffect {
|
||||
|
@ -1004,6 +1004,11 @@ void AudioServer::update() {
|
||||
AudioDriver::get_singleton()->reset_profiling_time();
|
||||
prof_time = 0;
|
||||
#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() {
|
||||
@ -1129,6 +1134,25 @@ void AudioServer::remove_callback(AudioCallback p_callback, void *p_userdata) {
|
||||
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) {
|
||||
|
||||
ERR_FAIL_COND(p_bus_layout.is_null() || p_bus_layout->buses.size() == 0);
|
||||
|
@ -262,6 +262,7 @@ private:
|
||||
};
|
||||
|
||||
Set<CallbackItem> callbacks;
|
||||
Set<CallbackItem> update_callbacks;
|
||||
|
||||
friend class AudioDriver;
|
||||
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 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);
|
||||
Ref<AudioBusLayout> generate_bus_layout() const;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user