summaryrefslogtreecommitdiffstats
path: root/servers/audio_server.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'servers/audio_server.cpp')
-rw-r--r--servers/audio_server.cpp149
1 files changed, 146 insertions, 3 deletions
diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp
index d37836ed96..fefb8bfd41 100644
--- a/servers/audio_server.cpp
+++ b/servers/audio_server.cpp
@@ -120,16 +120,18 @@ int AudioDriver::_get_configured_mix_rate() {
StringName audio_driver_setting = "audio/driver/mix_rate";
int mix_rate = GLOBAL_GET(audio_driver_setting);
+#ifdef WEB_ENABLED
+ // `0` is an acceptable value (resorts to the browser's default).
+ return MAX(0, mix_rate);
+#else // !WEB_ENABLED
// In the case of invalid mix rate, let's default to a sensible value..
if (mix_rate <= 0) {
-#ifndef WEB_ENABLED
WARN_PRINT(vformat("Invalid mix rate of %d, consider reassigning setting \'%s\'. \nDefaulting mix rate to value %d.",
mix_rate, audio_driver_setting, AudioDriverManager::DEFAULT_MIX_RATE));
-#endif
mix_rate = AudioDriverManager::DEFAULT_MIX_RATE;
}
-
return mix_rate;
+#endif
}
AudioDriver::SpeakerMode AudioDriver::get_speaker_mode_by_total_channels(int p_channels) const {
@@ -181,6 +183,18 @@ PackedStringArray AudioDriver::get_input_device_list() {
return list;
}
+void AudioDriver::start_sample_playback(const Ref<AudioSamplePlayback> &p_playback) {
+ if (p_playback.is_valid()) {
+ if (p_playback->stream.is_valid()) {
+ WARN_PRINT_ED(vformat(R"(Trying to play stream (%s) as a sample (%s), but the driver doesn't support sample playback.)", p_playback->get_instance_id(), p_playback->stream->get_instance_id()));
+ } else {
+ WARN_PRINT_ED(vformat(R"(Trying to play stream (%s) as a null sample, but the driver doesn't support sample playback.)", p_playback->get_instance_id()));
+ }
+ } else {
+ WARN_PRINT_ED("Trying to play a null sample playback from a driver that don't support sample playback.");
+ }
+}
+
AudioDriverDummy AudioDriverManager::dummy_driver;
AudioDriver *AudioDriverManager::drivers[MAX_DRIVERS] = {
&AudioDriverManager::dummy_driver,
@@ -367,6 +381,10 @@ void AudioServer::_mix_step() {
continue;
}
+ if (playback->stream_playback->get_is_sample()) {
+ continue;
+ }
+
bool fading_out = playback->state.load() == AudioStreamPlaybackListNode::FADE_OUT_TO_DELETION || playback->state.load() == AudioStreamPlaybackListNode::FADE_OUT_TO_PAUSE;
AudioFrame *buf = mix_buffer.ptrw();
@@ -770,6 +788,8 @@ void AudioServer::set_bus_count(int p_count) {
unlock();
+ AudioDriver::get_singleton()->set_sample_bus_count(p_count);
+
emit_signal(SNAME("bus_layout_changed"));
}
@@ -785,6 +805,8 @@ void AudioServer::remove_bus(int p_index) {
buses.remove_at(p_index);
unlock();
+ AudioDriver::get_singleton()->remove_sample_bus(p_index);
+
emit_signal(SNAME("bus_layout_changed"));
}
@@ -839,6 +861,8 @@ void AudioServer::add_bus(int p_at_pos) {
buses.insert(p_at_pos, bus);
}
+ AudioDriver::get_singleton()->add_sample_bus(p_at_pos);
+
emit_signal(SNAME("bus_layout_changed"));
}
@@ -863,6 +887,8 @@ void AudioServer::move_bus(int p_bus, int p_to_pos) {
buses.insert(p_to_pos - 1, bus);
}
+ AudioDriver::get_singleton()->move_sample_bus(p_bus, p_to_pos);
+
emit_signal(SNAME("bus_layout_changed"));
}
@@ -934,6 +960,8 @@ void AudioServer::set_bus_volume_db(int p_bus, float p_volume_db) {
MARK_EDITED
buses[p_bus]->volume_db = p_volume_db;
+
+ AudioDriver::get_singleton()->set_sample_bus_volume_db(p_bus, p_volume_db);
}
float AudioServer::get_bus_volume_db(int p_bus) const {
@@ -952,6 +980,8 @@ void AudioServer::set_bus_send(int p_bus, const StringName &p_send) {
MARK_EDITED
buses[p_bus]->send = p_send;
+
+ AudioDriver::get_singleton()->set_sample_bus_send(p_bus, p_send);
}
StringName AudioServer::get_bus_send(int p_bus) const {
@@ -965,6 +995,8 @@ void AudioServer::set_bus_solo(int p_bus, bool p_enable) {
MARK_EDITED
buses[p_bus]->solo = p_enable;
+
+ AudioDriver::get_singleton()->set_sample_bus_solo(p_bus, p_enable);
}
bool AudioServer::is_bus_solo(int p_bus) const {
@@ -979,6 +1011,8 @@ void AudioServer::set_bus_mute(int p_bus, bool p_enable) {
MARK_EDITED
buses[p_bus]->mute = p_enable;
+
+ AudioDriver::get_singleton()->set_sample_bus_mute(p_bus, p_enable);
}
bool AudioServer::is_bus_mute(int p_bus) const {
@@ -1214,6 +1248,13 @@ void AudioServer::set_playback_bus_exclusive(Ref<AudioStreamPlayback> p_playback
void AudioServer::set_playback_bus_volumes_linear(Ref<AudioStreamPlayback> p_playback, const HashMap<StringName, Vector<AudioFrame>> &p_bus_volumes) {
ERR_FAIL_COND(p_bus_volumes.size() > MAX_BUSES_PER_PLAYBACK);
+ // Samples.
+ if (p_playback->get_is_sample() && p_playback->get_sample_playback().is_valid()) {
+ Ref<AudioSamplePlayback> sample_playback = p_playback->get_sample_playback();
+ AudioDriver::get_singleton()->set_sample_playback_bus_volumes_linear(sample_playback, p_bus_volumes);
+ return;
+ }
+
AudioStreamPlaybackListNode *playback_node = _find_playback_list_node(p_playback);
if (!playback_node) {
return;
@@ -1265,6 +1306,13 @@ void AudioServer::set_playback_all_bus_volumes_linear(Ref<AudioStreamPlayback> p
void AudioServer::set_playback_pitch_scale(Ref<AudioStreamPlayback> p_playback, float p_pitch_scale) {
ERR_FAIL_COND(p_playback.is_null());
+ // Samples.
+ if (p_playback->get_is_sample() && p_playback->get_sample_playback().is_valid()) {
+ Ref<AudioSamplePlayback> sample_playback = p_playback->get_sample_playback();
+ AudioServer::get_singleton()->update_sample_playback_pitch_scale(sample_playback, p_pitch_scale);
+ return;
+ }
+
AudioStreamPlaybackListNode *playback_node = _find_playback_list_node(p_playback);
if (!playback_node) {
return;
@@ -1385,6 +1433,7 @@ void AudioServer::init() {
if (AudioDriver::get_singleton()) {
AudioDriver::get_singleton()->start();
+ AudioDriver::get_singleton()->set_sample_bus_count(1);
}
#ifdef TOOLS_ENABLED
@@ -1597,6 +1646,9 @@ void AudioServer::set_bus_layout(const Ref<AudioBusLayout> &p_bus_layout) {
}
buses.resize(p_bus_layout->buses.size());
bus_map.clear();
+
+ AudioDriver::get_singleton()->set_sample_bus_count(buses.size());
+
for (int i = 0; i < p_bus_layout->buses.size(); i++) {
Bus *bus = memnew(Bus);
if (i == 0) {
@@ -1604,6 +1656,7 @@ void AudioServer::set_bus_layout(const Ref<AudioBusLayout> &p_bus_layout) {
} else {
bus->name = p_bus_layout->buses[i].name;
bus->send = p_bus_layout->buses[i].send;
+ AudioDriver::get_singleton()->set_sample_bus_send(i, bus->send);
}
bus->solo = p_bus_layout->buses[i].solo;
@@ -1611,6 +1664,10 @@ void AudioServer::set_bus_layout(const Ref<AudioBusLayout> &p_bus_layout) {
bus->bypass = p_bus_layout->buses[i].bypass;
bus->volume_db = p_bus_layout->buses[i].volume_db;
+ AudioDriver::get_singleton()->set_sample_bus_solo(i, bus->solo);
+ AudioDriver::get_singleton()->set_sample_bus_mute(i, bus->mute);
+ AudioDriver::get_singleton()->set_sample_bus_volume_db(i, bus->volume_db);
+
for (int j = 0; j < p_bus_layout->buses[i].effects.size(); j++) {
Ref<AudioEffect> fx = p_bus_layout->buses[i].effects[j].effect;
@@ -1638,6 +1695,8 @@ void AudioServer::set_bus_layout(const Ref<AudioBusLayout> &p_bus_layout) {
set_edited(false);
#endif
unlock();
+
+ // Samples bus sync.
}
Ref<AudioBusLayout> AudioServer::generate_bus_layout() const {
@@ -1705,6 +1764,82 @@ void AudioServer::get_argument_options(const StringName &p_function, int p_idx,
}
#endif
+AudioServer::PlaybackType AudioServer::get_default_playback_type() const {
+ int playback_type = GLOBAL_GET("audio/general/default_playback_type");
+ ERR_FAIL_COND_V_MSG(
+ playback_type < 0 || playback_type >= PlaybackType::PLAYBACK_TYPE_MAX,
+ PlaybackType::PLAYBACK_TYPE_STREAM,
+ vformat(R"(Project settings value (%s) for "audio/general/default_playback_type" is not supported)", playback_type));
+
+ switch (playback_type) {
+ case 1: {
+ return PlaybackType::PLAYBACK_TYPE_SAMPLE;
+ } break;
+
+ case 0:
+ default: {
+ return PlaybackType::PLAYBACK_TYPE_STREAM;
+ } break;
+ }
+}
+
+bool AudioServer::is_stream_registered_as_sample(const Ref<AudioStream> &p_stream) {
+ ERR_FAIL_COND_V_MSG(p_stream.is_null(), false, "Parameter p_stream is null.");
+ return AudioDriver::get_singleton()->is_stream_registered_as_sample(p_stream);
+}
+
+void AudioServer::register_stream_as_sample(const Ref<AudioStream> &p_stream) {
+ ERR_FAIL_COND_MSG(p_stream.is_null(), "Parameter p_stream is null.");
+ ERR_FAIL_COND_MSG(!(p_stream->can_be_sampled()), "Parameter p_stream cannot be sampled.");
+ Ref<AudioSample> sample = p_stream->generate_sample();
+ register_sample(sample);
+}
+
+void AudioServer::unregister_stream_as_sample(const Ref<AudioStream> &p_stream) {
+ ERR_FAIL_COND_MSG(p_stream.is_null(), "Parameter p_stream is null.");
+ ERR_FAIL_COND_MSG(!(p_stream->can_be_sampled()), "Parameter p_stream cannot be sampled.");
+ Ref<AudioSample> sample = p_stream->generate_sample();
+ unregister_sample(sample);
+}
+
+void AudioServer::register_sample(const Ref<AudioSample> &p_sample) {
+ ERR_FAIL_COND_MSG(p_sample.is_null(), "Parameter p_sample is null.");
+ ERR_FAIL_COND_MSG(p_sample->stream.is_null(), "Parameter p_sample->stream is null.");
+ ERR_FAIL_COND_MSG(!(p_sample->stream->can_be_sampled()), "Parameter p_stream cannot be sampled.");
+ AudioDriver::get_singleton()->register_sample(p_sample);
+}
+
+void AudioServer::unregister_sample(const Ref<AudioSample> &p_sample) {
+ ERR_FAIL_COND_MSG(p_sample.is_null(), "Parameter p_sample is null.");
+ ERR_FAIL_COND_MSG(p_sample->stream.is_null(), "Parameter p_sample->stream is null.");
+ AudioDriver::get_singleton()->unregister_sample(p_sample);
+}
+
+void AudioServer::start_sample_playback(const Ref<AudioSamplePlayback> &p_playback) {
+ ERR_FAIL_COND_MSG(p_playback.is_null(), "Parameter p_playback is null.");
+ AudioDriver::get_singleton()->start_sample_playback(p_playback);
+}
+
+void AudioServer::stop_sample_playback(const Ref<AudioSamplePlayback> &p_playback) {
+ ERR_FAIL_COND_MSG(p_playback.is_null(), "Parameter p_playback is null.");
+ AudioDriver::get_singleton()->stop_sample_playback(p_playback);
+}
+
+void AudioServer::set_sample_playback_pause(const Ref<AudioSamplePlayback> &p_playback, bool p_paused) {
+ ERR_FAIL_COND_MSG(p_playback.is_null(), "Parameter p_playback is null.");
+ AudioDriver::get_singleton()->set_sample_playback_pause(p_playback, p_paused);
+}
+
+bool AudioServer::is_sample_playback_active(const Ref<AudioSamplePlayback> &p_playback) {
+ ERR_FAIL_COND_V_MSG(p_playback.is_null(), false, "Parameter p_playback is null.");
+ return AudioDriver::get_singleton()->is_sample_playback_active(p_playback);
+}
+
+void AudioServer::update_sample_playback_pitch_scale(const Ref<AudioSamplePlayback> &p_playback, float p_pitch_scale) {
+ ERR_FAIL_COND_MSG(p_playback.is_null(), "Parameter p_playback is null.");
+ return AudioDriver::get_singleton()->update_sample_playback_pitch_scale(p_playback, p_pitch_scale);
+}
+
void AudioServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_bus_count", "amount"), &AudioServer::set_bus_count);
ClassDB::bind_method(D_METHOD("get_bus_count"), &AudioServer::get_bus_count);
@@ -1774,6 +1909,9 @@ void AudioServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_enable_tagging_used_audio_streams", "enable"), &AudioServer::set_enable_tagging_used_audio_streams);
+ ClassDB::bind_method(D_METHOD("is_stream_registered_as_sample", "stream"), &AudioServer::is_stream_registered_as_sample);
+ ClassDB::bind_method(D_METHOD("register_stream_as_sample", "stream"), &AudioServer::register_stream_as_sample);
+
ADD_PROPERTY(PropertyInfo(Variant::INT, "bus_count"), "set_bus_count", "get_bus_count");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "output_device"), "set_output_device", "get_output_device");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "input_device"), "set_input_device", "get_input_device");
@@ -1789,6 +1927,11 @@ void AudioServer::_bind_methods() {
BIND_ENUM_CONSTANT(SPEAKER_SURROUND_31);
BIND_ENUM_CONSTANT(SPEAKER_SURROUND_51);
BIND_ENUM_CONSTANT(SPEAKER_SURROUND_71);
+
+ BIND_ENUM_CONSTANT(PLAYBACK_TYPE_DEFAULT);
+ BIND_ENUM_CONSTANT(PLAYBACK_TYPE_STREAM);
+ BIND_ENUM_CONSTANT(PLAYBACK_TYPE_SAMPLE);
+ BIND_ENUM_CONSTANT(PLAYBACK_TYPE_MAX);
}
AudioServer::AudioServer() {