Skip to content

Commit

Permalink
Implement "looped" signal for AudioStreamPlayer, 2D and 3D
Browse files Browse the repository at this point in the history
Emit a signal from a playback whenever a loop occurs, the player
connects to that signal and forwards it.
  • Loading branch information
vaartis committed Jan 10, 2023
1 parent fcba87e commit d1709fb
Show file tree
Hide file tree
Showing 14 changed files with 68 additions and 0 deletions.
7 changes: 7 additions & 0 deletions doc/classes/AudioStreamPlayback.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,11 @@
</description>
</method>
</methods>
<signals>
<signal name="looped">
<description>
Emitted when the audio loops.
</description>
</signal>
</signals>
</class>
5 changes: 5 additions & 0 deletions doc/classes/AudioStreamPlayer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@
Emitted when the audio stops playing.
</description>
</signal>
<signal name="looped">
<description>
Emitted when the audio loops.
</description>
</signal>
</signals>
<constants>
<constant name="MIX_TARGET_STEREO" value="0" enum="MixTarget">
Expand Down
5 changes: 5 additions & 0 deletions doc/classes/AudioStreamPlayer2D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -91,5 +91,10 @@
Emitted when the audio stops playing.
</description>
</signal>
<signal name="looped">
<description>
Emitted when the audio loops.
</description>
</signal>
</signals>
</class>
5 changes: 5 additions & 0 deletions doc/classes/AudioStreamPlayer3D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@
Emitted when the audio stops playing.
</description>
</signal>
<signal name="looped">
<description>
Emitted when the audio loops.
</description>
</signal>
</signals>
<constants>
<constant name="ATTENUATION_INVERSE_DISTANCE" value="0" enum="AttenuationModel">
Expand Down
4 changes: 4 additions & 0 deletions modules/minimp3/audio_stream_mp3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,19 @@ int AudioStreamPlaybackMP3::_mix_internal(AudioFrame *p_buffer, int p_frames) {
}
loop_fade_remaining = 0;
seek(mp3_stream->loop_offset);

loops++;
emit_signal(SNAME("looped"));
}
}

else {
//EOF
if (mp3_stream->loop) {
seek(mp3_stream->loop_offset);

loops++;
emit_signal(SNAME("looped"));
} else {
frames_mixed_this_step = p_frames - todo;
//fill remainder with silence
Expand Down
5 changes: 5 additions & 0 deletions modules/vorbis/audio_stream_ogg_vorbis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,10 @@ int AudioStreamPlaybackOggVorbis::_mix_internal(AudioFrame *p_buffer, int p_fram
}

seek(vorbis_stream->loop_offset);

loops++;
emit_signal(SNAME("looped"));

// We still have buffer to fill, start from this element in the next iteration.
continue;
}
Expand All @@ -128,6 +131,8 @@ int AudioStreamPlaybackOggVorbis::_mix_internal(AudioFrame *p_buffer, int p_fram

seek(vorbis_stream->loop_offset);
loops++;
emit_signal(SNAME("looped"));

// We still have buffer to fill, start from this element in the next iteration.

} else {
Expand Down
7 changes: 7 additions & 0 deletions scene/2d/audio_stream_player_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ void AudioStreamPlayer2D::_notification(int p_what) {
ERR_FAIL_COND_MSG(new_playback.is_null(), "Failed to instantiate playback.");
AudioServer::get_singleton()->start_playback_stream(new_playback, _get_actual_bus(), volume_vector, setplay.get(), pitch_scale);
stream_playbacks.push_back(new_playback);
new_playback->connect(SNAME("looped"), callable_mp(this, &AudioStreamPlayer2D::_looped), CONNECT_REFERENCE_COUNTED);
setplay.set(-1);
}

Expand All @@ -92,6 +93,7 @@ void AudioStreamPlayer2D::_notification(int p_what) {
// Now go through and remove playbacks that have finished. Removing elements from a Vector in a range based for is asking for trouble.
for (Ref<AudioStreamPlayback> &playback : playbacks_to_remove) {
stream_playbacks.erase(playback);
playback->disconnect(SNAME("looped"), callable_mp(this, &AudioStreamPlayer2D::_looped));
}
if (!playbacks_to_remove.is_empty() && stream_playbacks.is_empty()) {
// This node is no longer actively playing audio.
Expand Down Expand Up @@ -350,6 +352,10 @@ void AudioStreamPlayer2D::_bus_layout_changed() {
notify_property_list_changed();
}

void AudioStreamPlayer2D::_looped() {
emit_signal(SNAME("looped"));
}

void AudioStreamPlayer2D::set_max_distance(float p_pixels) {
ERR_FAIL_COND(p_pixels <= 0.0);
max_distance = p_pixels;
Expand Down Expand Up @@ -476,6 +482,7 @@ void AudioStreamPlayer2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "area_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_area_mask", "get_area_mask");

ADD_SIGNAL(MethodInfo("finished"));
ADD_SIGNAL(MethodInfo("looped"));
}

AudioStreamPlayer2D::AudioStreamPlayer2D() {
Expand Down
2 changes: 2 additions & 0 deletions scene/2d/audio_stream_player_2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ class AudioStreamPlayer2D : public Node2D {
void _update_panning();
void _bus_layout_changed();

void _looped();

static void _listener_changed_cb(void *self) { reinterpret_cast<AudioStreamPlayer2D *>(self)->_update_panning(); }

uint32_t area_mask = 1;
Expand Down
7 changes: 7 additions & 0 deletions scene/3d/audio_stream_player_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,10 @@ float AudioStreamPlayer3D::_get_attenuation_db(float p_distance) const {
return att;
}

void AudioStreamPlayer3D::_looped() {
emit_signal(SNAME("looped"));
}

void AudioStreamPlayer3D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
Expand Down Expand Up @@ -292,6 +296,7 @@ void AudioStreamPlayer3D::_notification(int p_what) {
bus_map[_get_actual_bus()] = volume_vector;
AudioServer::get_singleton()->start_playback_stream(new_playback, bus_map, setplay.get(), actual_pitch_scale, linear_attenuation, attenuation_filter_cutoff_hz);
stream_playbacks.push_back(new_playback);
new_playback->connect(SNAME("looped"), callable_mp(this, &AudioStreamPlayer3D::_looped), CONNECT_REFERENCE_COUNTED);
setplay.set(-1);
}

Expand All @@ -306,6 +311,7 @@ void AudioStreamPlayer3D::_notification(int p_what) {
// Now go through and remove playbacks that have finished. Removing elements from a Vector in a range based for is asking for trouble.
for (Ref<AudioStreamPlayback> &playback : playbacks_to_remove) {
stream_playbacks.erase(playback);
playback->disconnect(SNAME("looped"), callable_mp(this, &AudioStreamPlayer3D::_looped));
}
if (!playbacks_to_remove.is_empty() && stream_playbacks.is_empty()) {
// This node is no longer actively playing audio.
Expand Down Expand Up @@ -913,6 +919,7 @@ void AudioStreamPlayer3D::_bind_methods() {
BIND_ENUM_CONSTANT(DOPPLER_TRACKING_PHYSICS_STEP);

ADD_SIGNAL(MethodInfo("finished"));
ADD_SIGNAL(MethodInfo("looped"));
}

AudioStreamPlayer3D::AudioStreamPlayer3D() {
Expand Down
2 changes: 2 additions & 0 deletions scene/3d/audio_stream_player_3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ class AudioStreamPlayer3D : public Node3D {
float panning_strength = 1.0f;
float cached_global_panning_strength = 0.5f;

void _looped();

protected:
void _validate_property(PropertyInfo &p_property) const;
void _notification(int p_what);
Expand Down
7 changes: 7 additions & 0 deletions scene/audio/audio_stream_player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ void AudioStreamPlayer::_notification(int p_what) {
// Now go through and remove playbacks that have finished. Removing elements from a Vector in a range based for is asking for trouble.
for (Ref<AudioStreamPlayback> &playback : playbacks_to_remove) {
stream_playbacks.erase(playback);
playback->disconnect(SNAME("looped"), callable_mp(this, &AudioStreamPlayer::_looped));
}
if (!playbacks_to_remove.is_empty() && stream_playbacks.is_empty()) {
// This node is no longer actively playing audio.
Expand Down Expand Up @@ -146,6 +147,7 @@ void AudioStreamPlayer::play(float p_from_pos) {

AudioServer::get_singleton()->start_playback_stream(stream_playback, bus, _get_volume_vector(), p_from_pos, pitch_scale);
stream_playbacks.push_back(stream_playback);
stream_playback->connect(SNAME("looped"), callable_mp(this, &AudioStreamPlayer::_looped), CONNECT_REFERENCE_COUNTED);
active.set();
set_process_internal(true);
while (stream_playbacks.size() > max_polyphony) {
Expand Down Expand Up @@ -307,6 +309,10 @@ void AudioStreamPlayer::_bus_layout_changed() {
notify_property_list_changed();
}

void AudioStreamPlayer::_looped() {
emit_signal(SNAME("looped"));
}

Ref<AudioStreamPlayback> AudioStreamPlayer::get_stream_playback() {
if (!stream_playbacks.is_empty()) {
return stream_playbacks[stream_playbacks.size() - 1];
Expand Down Expand Up @@ -362,6 +368,7 @@ void AudioStreamPlayer::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus");

ADD_SIGNAL(MethodInfo("finished"));
ADD_SIGNAL(MethodInfo("looped"));

BIND_ENUM_CONSTANT(MIX_TARGET_STEREO);
BIND_ENUM_CONSTANT(MIX_TARGET_SURROUND);
Expand Down
2 changes: 2 additions & 0 deletions scene/audio/audio_stream_player.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ class AudioStreamPlayer : public Node {
void _bus_layout_changed();
void _mix_to_bus(const AudioFrame *p_frames, int p_amount);

void _looped();

Vector<AudioFrame> _get_volume_vector();

protected:
Expand Down
8 changes: 8 additions & 0 deletions servers/audio/audio_stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ void AudioStreamPlayback::_bind_methods() {
GDVIRTUAL_BIND(_seek, "position")
GDVIRTUAL_BIND(_mix, "buffer", "rate_scale", "frames");
GDVIRTUAL_BIND(_tag_used_streams);

ADD_SIGNAL(MethodInfo("looped"));
}
//////////////////////////////

Expand Down Expand Up @@ -761,12 +763,18 @@ void AudioStreamPlaybackRandomizer::start(double p_from_pos) {

if (playing.is_valid()) {
playing->start(p_from_pos);
playing->connect(SNAME("looped"), callable_mp(this, &AudioStreamPlaybackRandomizer::_looped));
}
}

void AudioStreamPlaybackRandomizer::_looped() {
emit_signal(SNAME("looped"));
}

void AudioStreamPlaybackRandomizer::stop() {
if (playing.is_valid()) {
playing->stop();
playing->disconnect(SNAME("looped"), callable_mp(this, &AudioStreamPlaybackRandomizer::_looped));
}
}

Expand Down
2 changes: 2 additions & 0 deletions servers/audio/audio_stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,8 @@ class AudioStreamPlaybackRandomizer : public AudioStreamPlayback {
float pitch_scale;
float volume_scale;

void _looped();

public:
virtual void start(double p_from_pos = 0.0) override;
virtual void stop() override;
Expand Down

0 comments on commit d1709fb

Please sign in to comment.