@@ -1319,6 +1319,59 @@ void AudioServer::stop_playback_stream(Ref<AudioStreamPlayback> p_playback) {
13191319 } while (!playback_node->state .compare_exchange_strong (old_state, new_state));
13201320}
13211321
1322+ Vector<AudioFrame> AudioServer::create_volume_vector (float p_volume_db, MixTarget p_mix_target) const {
1323+ Vector<AudioFrame> volume_vector;
1324+ // We need at most four stereo pairs (for 7.1 systems).
1325+ volume_vector.resize (4 );
1326+
1327+ // Initialize the volume vector to zero.
1328+ for (AudioFrame &channel_volume_db : volume_vector) {
1329+ channel_volume_db = AudioFrame (0 , 0 );
1330+ }
1331+
1332+ float volume_linear = Math::db_to_linear (p_volume_db);
1333+
1334+ // Set the volume vector up according to the speaker mode and mix target.
1335+ // TODO do we need to scale the volume down when we output to more channels?
1336+ if (get_speaker_mode () == AudioServer::SPEAKER_MODE_STEREO) {
1337+ volume_vector.write [0 ] = AudioFrame (volume_linear, volume_linear);
1338+ } else {
1339+ switch (p_mix_target) {
1340+ case MIX_TARGET_STEREO: {
1341+ volume_vector.write [0 ] = AudioFrame (volume_linear, volume_linear);
1342+ } break ;
1343+ case MIX_TARGET_SURROUND: {
1344+ // TODO Make sure this is right.
1345+ volume_vector.write [0 ] = AudioFrame (volume_linear, volume_linear);
1346+ volume_vector.write [1 ] = AudioFrame (volume_linear, /* LFE= */ 1 .0f );
1347+ volume_vector.write [2 ] = AudioFrame (volume_linear, volume_linear);
1348+ volume_vector.write [3 ] = AudioFrame (volume_linear, volume_linear);
1349+ } break ;
1350+ case MIX_TARGET_CENTER: {
1351+ // TODO Make sure this is right.
1352+ volume_vector.write [1 ] = AudioFrame (volume_linear, /* LFE= */ 1 .0f );
1353+ } break ;
1354+ }
1355+ }
1356+
1357+ return volume_vector;
1358+ }
1359+
1360+ void AudioServer::_start_playback_stream (Ref<AudioStreamPlayback> p_playback, const StringName &p_bus, float p_volume_db_offset, MixTarget p_mix_target, float p_start_time, float p_pitch_scale) {
1361+ ERR_FAIL_COND (p_playback.is_null ());
1362+
1363+ Vector<AudioFrame> volume_vector = create_volume_vector (p_volume_db_offset, p_mix_target);
1364+ start_playback_stream (p_playback, p_bus, volume_vector, p_start_time, p_pitch_scale);
1365+
1366+ if (p_playback->get_is_sample () && p_playback->get_sample_playback ().is_valid ()) {
1367+ Ref<AudioSamplePlayback> sample_playback = p_playback->get_sample_playback ();
1368+ sample_playback->offset = p_start_time;
1369+ sample_playback->bus = p_bus;
1370+ sample_playback->volume_vector = volume_vector;
1371+ start_sample_playback (sample_playback);
1372+ }
1373+ }
1374+
13221375void AudioServer::set_playback_bus_exclusive (Ref<AudioStreamPlayback> p_playback, const StringName &p_bus, Vector<AudioFrame> p_volumes) {
13231376 ERR_FAIL_COND (p_volumes.size () != MAX_CHANNELS_PER_BUS);
13241377
@@ -2113,6 +2166,9 @@ void AudioServer::_bind_methods() {
21132166 ClassDB::bind_method (D_METHOD (" is_stream_registered_as_sample" , " stream" ), &AudioServer::is_stream_registered_as_sample);
21142167 ClassDB::bind_method (D_METHOD (" register_stream_as_sample" , " stream" ), &AudioServer::register_stream_as_sample);
21152168
2169+ ClassDB::bind_method (D_METHOD (" start_playback_stream" , " playback" , " bus" , " volume_db_offset" , " mix_target" , " start_time" , " pitch_scale" ), &AudioServer::_start_playback_stream, DEFVAL (0 ), DEFVAL (MIX_TARGET_STEREO), DEFVAL (0 ), DEFVAL (1 ));
2170+ ClassDB::bind_method (D_METHOD (" stop_playback_stream" , " playback" ), &AudioServer::stop_playback_stream);
2171+
21162172 ADD_PROPERTY (PropertyInfo (Variant::INT, " bus_count" ), " set_bus_count" , " get_bus_count" );
21172173 ADD_PROPERTY (PropertyInfo (Variant::STRING, " output_device" ), " set_output_device" , " get_output_device" );
21182174 ADD_PROPERTY (PropertyInfo (Variant::STRING, " input_device" ), " set_input_device" , " get_input_device" );
@@ -2133,6 +2189,10 @@ void AudioServer::_bind_methods() {
21332189 BIND_ENUM_CONSTANT (PLAYBACK_TYPE_STREAM);
21342190 BIND_ENUM_CONSTANT (PLAYBACK_TYPE_SAMPLE);
21352191 BIND_ENUM_CONSTANT (PLAYBACK_TYPE_MAX);
2192+
2193+ BIND_ENUM_CONSTANT (MIX_TARGET_STEREO);
2194+ BIND_ENUM_CONSTANT (MIX_TARGET_SURROUND);
2195+ BIND_ENUM_CONSTANT (MIX_TARGET_CENTER);
21362196}
21372197
21382198AudioServer::AudioServer () {
0 commit comments