diff options
Diffstat (limited to 'servers/audio_server.cpp')
| -rw-r--r-- | servers/audio_server.cpp | 196 |
1 files changed, 164 insertions, 32 deletions
diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index 070099a3d8..2cf6a67bef 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -68,26 +68,43 @@ void AudioDriver::audio_server_process(int p_frames, int32_t *p_buffer, bool p_u void AudioDriver::update_mix_time(int p_frames) { - _mix_amount += p_frames; + _last_mix_frames = p_frames; if (OS::get_singleton()) _last_mix_time = OS::get_singleton()->get_ticks_usec(); } -double AudioDriver::get_mix_time() const { +double AudioDriver::get_time_since_last_mix() const { + + return (OS::get_singleton()->get_ticks_usec() - _last_mix_time) / 1000000.0; +} + +double AudioDriver::get_time_to_next_mix() const { double total = (OS::get_singleton()->get_ticks_usec() - _last_mix_time) / 1000000.0; - total += _mix_amount / (double)get_mix_rate(); - return total; + double mix_buffer = _last_mix_frames / (double)get_mix_rate(); + return mix_buffer - total; } -void AudioDriver::input_buffer_write(int32_t sample) { +void AudioDriver::capture_buffer_init(int driver_buffer_frames) { - input_buffer.write[input_position++] = sample; - if (input_position >= input_buffer.size()) { - input_position = 0; - } - if (input_size < input_buffer.size()) { - input_size++; + const int capture_buffer_channels = 2; + capture_buffer.resize(driver_buffer_frames * capture_buffer_channels * 4); + capture_position = 0; + capture_size = 0; +} + +void AudioDriver::capture_buffer_write(int32_t sample) { + + if ((int)capture_position < capture_buffer.size()) { + capture_buffer.write()[capture_position++] = sample; + if ((int)capture_position >= capture_buffer.size()) { + capture_position = 0; + } + if ((int)capture_size < capture_buffer.size()) { + capture_size++; + } + } else { + WARN_PRINTS("capture_buffer_write: Invalid capture_position=" + itos(capture_position) + " capture_buffer.size()=" + itos(capture_buffer.size())); } } @@ -136,7 +153,9 @@ Array AudioDriver::capture_get_device_list() { AudioDriver::AudioDriver() { _last_mix_time = 0; - _mix_amount = 0; + _last_mix_frames = 0; + capture_position = 0; + capture_size = 0; #ifdef DEBUG_ENABLED prof_time = 0; @@ -164,6 +183,7 @@ int AudioDriverManager::get_driver_count() { } void AudioDriverManager::initialize(int p_driver) { + GLOBAL_DEF_RST("audio/enable_audio_input", false); int failed_driver = -1; // Check if there is a selected driver @@ -189,7 +209,7 @@ void AudioDriverManager::initialize(int p_driver) { } } - if (driver_count > 1 && AudioDriver::get_singleton()->get_name() == "Dummy") { + if (driver_count > 1 && String(AudioDriver::get_singleton()->get_name()) == "Dummy") { WARN_PRINT("All audio drivers failed, falling back to the dummy driver."); } } @@ -244,11 +264,13 @@ void AudioServer::_driver_process(int p_frames, int32_t *p_buffer) { float l = CLAMP(buf[from + j].l, -1.0, 1.0); int32_t vl = l * ((1 << 20) - 1); - p_buffer[(from_buf + j) * (cs * 2) + k * 2 + 0] = vl << 11; + int32_t vl2 = (vl < 0 ? -1 : 1) * (ABS(vl) << 11); + p_buffer[(from_buf + j) * (cs * 2) + k * 2 + 0] = vl2; float r = CLAMP(buf[from + j].r, -1.0, 1.0); int32_t vr = r * ((1 << 20) - 1); - p_buffer[(from_buf + j) * (cs * 2) + k * 2 + 1] = vr << 11; + int32_t vr2 = (vr < 0 ? -1 : 1) * (ABS(vr) << 11); + p_buffer[(from_buf + j) * (cs * 2) + k * 2 + 1] = vr2; } } else { @@ -264,13 +286,6 @@ void AudioServer::_driver_process(int p_frames, int32_t *p_buffer) { to_mix -= to_copy; } - // Calculate latency for Performance.AUDIO_OUTPUT_LATENCY - if (OS::get_singleton()) { - uint64_t ticks = OS::get_singleton()->get_ticks_usec(); - output_latency = (ticks - output_latency_ticks) / 1000000.f; - output_latency_ticks = ticks; - } - #ifdef DEBUG_ENABLED prof_time += OS::get_singleton()->get_ticks_usec() - prof_ticks; #endif @@ -323,6 +338,8 @@ void AudioServer::_mix_step() { E->get().callback(E->get().userdata); } + emit_signal("audio_mix_callback"); + for (int i = buses.size() - 1; i >= 0; i--) { //go bus by bus Bus *bus = buses[i]; @@ -452,6 +469,14 @@ void AudioServer::_mix_step() { to_mix = buffer_size; } +bool AudioServer::thread_has_channel_mix_buffer(int p_bus, int p_buffer) const { + if (p_bus < 0 || p_bus >= buses.size()) + return false; + if (p_buffer < 0 || p_buffer >= buses[p_bus]->channels.size()) + return false; + return true; +} + AudioFrame *AudioServer::thread_get_channel_mix_buffer(int p_bus, int p_buffer) { ERR_FAIL_INDEX_V(p_bus, buses.size(), NULL); @@ -721,6 +746,12 @@ float AudioServer::get_bus_volume_db(int p_bus) const { return buses[p_bus]->volume_db; } +int AudioServer::get_bus_channels(int p_bus) const { + + ERR_FAIL_INDEX_V(p_bus, buses.size(), 0); + return buses[p_bus]->channels.size(); +} + void AudioServer::set_bus_send(int p_bus, const StringName &p_send) { ERR_FAIL_INDEX(p_bus, buses.size()); @@ -845,6 +876,15 @@ int AudioServer::get_bus_effect_count(int p_bus) { return buses[p_bus]->effects.size(); } +Ref<AudioEffectInstance> AudioServer::get_bus_effect_instance(int p_bus, int p_effect, int p_channel) { + + ERR_FAIL_INDEX_V(p_bus, buses.size(), Ref<AudioEffectInstance>()); + ERR_FAIL_INDEX_V(p_effect, buses[p_bus]->effects.size(), Ref<AudioEffectInstance>()); + ERR_FAIL_INDEX_V(p_channel, buses[p_bus]->channels.size(), Ref<AudioEffectInstance>()); + + return buses[p_bus]->channels[p_channel].effect_instances[p_effect]; +} + Ref<AudioEffect> AudioServer::get_bus_effect(int p_bus, int p_effect) { ERR_FAIL_INDEX_V(p_bus, buses.size(), Ref<AudioEffect>()); @@ -906,6 +946,15 @@ bool AudioServer::is_bus_channel_active(int p_bus, int p_channel) const { return buses[p_bus]->channels[p_channel].active; } +void AudioServer::set_global_rate_scale(float p_scale) { + + global_rate_scale = p_scale; +} +float AudioServer::get_global_rate_scale() const { + + return global_rate_scale; +} + void AudioServer::init_channels_and_buffers() { channel_count = get_channel_count(); temp_buffer.resize(channel_count); @@ -926,6 +975,7 @@ void AudioServer::init() { channel_disable_threshold_db = GLOBAL_DEF_RST("audio/channel_disable_threshold_db", -60.0); channel_disable_frames = float(GLOBAL_DEF_RST("audio/channel_disable_time", 2.0)) * get_mix_rate(); + ProjectSettings::get_singleton()->set_custom_property_info("audio/channel_disable_time", PropertyInfo(Variant::REAL, "audio/channel_disable_time", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater")); buffer_size = 1024; //hardcoded for now init_channels_and_buffers(); @@ -953,7 +1003,7 @@ void AudioServer::update() { uint64_t driver_time = AudioDriver::get_singleton()->get_profiling_time(); uint64_t server_time = prof_time; - // Substract the server time from the driver time + // Subtract the server time from the driver time if (driver_time > server_time) driver_time -= server_time; @@ -971,7 +1021,7 @@ void AudioServer::update() { values.push_back(String(bus->name) + bus->effects[j].effect->get_name()); values.push_back(USEC_TO_SEC(bus->effects[j].prof_time)); - // Substract the effect time from the driver and server times + // Subtract the effect time from the driver and server times if (driver_time > bus->effects[j].prof_time) driver_time -= bus->effects[j].prof_time; if (server_time > bus->effects[j].prof_time) @@ -1004,12 +1054,21 @@ 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); + } + + emit_signal("audio_update_callback"); } void AudioServer::load_default_bus_layout() { - if (FileAccess::exists("res://default_bus_layout.tres")) { - Ref<AudioBusLayout> default_layout = ResourceLoader::load("res://default_bus_layout.tres"); + String layout_path = ProjectSettings::get_singleton()->get("audio/default_bus_layout"); + + if (ResourceLoader::exists(layout_path)) { + Ref<AudioBusLayout> default_layout = ResourceLoader::load(layout_path); if (default_layout.is_valid()) { set_bus_layout(default_layout); } @@ -1059,13 +1118,19 @@ AudioServer *AudioServer::get_singleton() { return singleton; } -double AudioServer::get_mix_time() const { +double AudioServer::get_output_latency() const { - return 0; + return AudioDriver::get_singleton()->get_latency(); } -double AudioServer::get_output_delay() const { - return 0; +double AudioServer::get_time_to_next_mix() const { + + return AudioDriver::get_singleton()->get_time_to_next_mix(); +} + +double AudioServer::get_time_since_last_mix() const { + + return AudioDriver::get_singleton()->get_time_since_last_mix(); } AudioServer *AudioServer::singleton = NULL; @@ -1129,6 +1194,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); @@ -1222,6 +1306,14 @@ void AudioServer::set_device(String device) { AudioDriver::get_singleton()->set_device(device); } +Error AudioServer::capture_start() { + return AudioDriver::get_singleton()->capture_start(); +} + +Error AudioServer::capture_stop() { + return AudioDriver::get_singleton()->capture_stop(); +} + Array AudioServer::capture_get_device_list() { return AudioDriver::get_singleton()->capture_get_device_list(); @@ -1237,6 +1329,18 @@ void AudioServer::capture_set_device(const String &p_name) { AudioDriver::get_singleton()->capture_set_device(p_name); } +PoolVector<int32_t> AudioServer::get_capture_buffer() { + return AudioDriver::get_singleton()->get_capture_buffer(); +} + +unsigned int AudioServer::get_capture_position() { + return AudioDriver::get_singleton()->get_capture_position(); +} + +unsigned int AudioServer::get_capture_size() { + return AudioDriver::get_singleton()->get_capture_size(); +} + void AudioServer::_bind_methods() { ClassDB::bind_method(D_METHOD("set_bus_count", "amount"), &AudioServer::set_bus_count); @@ -1250,6 +1354,8 @@ void AudioServer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_bus_name", "bus_idx"), &AudioServer::get_bus_name); ClassDB::bind_method(D_METHOD("get_bus_index", "bus_name"), &AudioServer::get_bus_index); + ClassDB::bind_method(D_METHOD("get_bus_channels", "bus_idx"), &AudioServer::get_bus_channels); + ClassDB::bind_method(D_METHOD("set_bus_volume_db", "bus_idx", "volume_db"), &AudioServer::set_bus_volume_db); ClassDB::bind_method(D_METHOD("get_bus_volume_db", "bus_idx"), &AudioServer::get_bus_volume_db); @@ -1270,6 +1376,7 @@ void AudioServer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_bus_effect_count", "bus_idx"), &AudioServer::get_bus_effect_count); ClassDB::bind_method(D_METHOD("get_bus_effect", "bus_idx", "effect_idx"), &AudioServer::get_bus_effect); + ClassDB::bind_method(D_METHOD("get_bus_effect_instance", "bus_idx", "effect_idx", "channel"), &AudioServer::get_bus_effect_instance, DEFVAL(0)); ClassDB::bind_method(D_METHOD("swap_bus_effects", "bus_idx", "effect_idx", "by_effect_idx"), &AudioServer::swap_bus_effects); ClassDB::bind_method(D_METHOD("set_bus_effect_enabled", "bus_idx", "effect_idx", "enabled"), &AudioServer::set_bus_effect_enabled); @@ -1278,6 +1385,9 @@ void AudioServer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_bus_peak_volume_left_db", "bus_idx", "channel"), &AudioServer::get_bus_peak_volume_left_db); ClassDB::bind_method(D_METHOD("get_bus_peak_volume_right_db", "bus_idx", "channel"), &AudioServer::get_bus_peak_volume_right_db); + ClassDB::bind_method(D_METHOD("set_global_rate_scale", "scale"), &AudioServer::set_global_rate_scale); + ClassDB::bind_method(D_METHOD("get_global_rate_scale"), &AudioServer::get_global_rate_scale); + ClassDB::bind_method(D_METHOD("lock"), &AudioServer::lock); ClassDB::bind_method(D_METHOD("unlock"), &AudioServer::unlock); @@ -1287,16 +1397,35 @@ void AudioServer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_device"), &AudioServer::get_device); ClassDB::bind_method(D_METHOD("set_device", "device"), &AudioServer::set_device); + ClassDB::bind_method(D_METHOD("get_time_to_next_mix"), &AudioServer::get_time_to_next_mix); + ClassDB::bind_method(D_METHOD("get_time_since_last_mix"), &AudioServer::get_time_since_last_mix); + ClassDB::bind_method(D_METHOD("get_output_latency"), &AudioServer::get_output_latency); + + ClassDB::bind_method(D_METHOD("capture_start"), &AudioServer::capture_start); + ClassDB::bind_method(D_METHOD("capture_stop"), &AudioServer::capture_stop); + ClassDB::bind_method(D_METHOD("capture_get_device_list"), &AudioServer::capture_get_device_list); ClassDB::bind_method(D_METHOD("capture_get_device"), &AudioServer::capture_get_device); ClassDB::bind_method(D_METHOD("capture_set_device", "name"), &AudioServer::capture_set_device); + ClassDB::bind_method(D_METHOD("get_capture_buffer"), &AudioServer::get_capture_buffer); + ClassDB::bind_method(D_METHOD("get_capture_position"), &AudioServer::get_capture_position); + ClassDB::bind_method(D_METHOD("get_capture_size"), &AudioServer::get_capture_size); + ClassDB::bind_method(D_METHOD("set_bus_layout", "bus_layout"), &AudioServer::set_bus_layout); ClassDB::bind_method(D_METHOD("generate_bus_layout"), &AudioServer::generate_bus_layout); + ADD_PROPERTY(PropertyInfo(Variant::INT, "bus_count"), "set_bus_count", "get_bus_count"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "device"), "set_device", "get_device"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "capture_device"), "capture_set_device", "capture_get_device"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "global_rate_scale"), "set_global_rate_scale", "get_global_rate_scale"); + ADD_SIGNAL(MethodInfo("bus_layout_changed")); + ADD_SIGNAL(MethodInfo("audio_mix_callback")); + ADD_SIGNAL(MethodInfo("audio_update_callback")); BIND_ENUM_CONSTANT(SPEAKER_MODE_STEREO); + BIND_ENUM_CONSTANT(SPEAKER_SURROUND_31); BIND_ENUM_CONSTANT(SPEAKER_SURROUND_51); BIND_ENUM_CONSTANT(SPEAKER_SURROUND_71); } @@ -1315,6 +1444,9 @@ AudioServer::AudioServer() { #ifdef DEBUG_ENABLED prof_time = 0; #endif + mix_time = 0; + mix_size = 0; + global_rate_scale = 1; } AudioServer::~AudioServer() { |