Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a reverse option to AudioStreamPlayer #3207

Open
Moebits opened this issue Aug 26, 2021 · 12 comments
Open

Add a reverse option to AudioStreamPlayer #3207

Moebits opened this issue Aug 26, 2021 · 12 comments

Comments

@Moebits
Copy link

Moebits commented Aug 26, 2021

Describe the project you are working on

2D Platformer

Describe the problem or limitation you are having in your project

I would like to have the ability to reverse the audio in an AudioStreamPlayer. Right now you basically need to have two audio files (one forwards and one reversed), but that can get a bit cumbersome.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

With a reverse option, you will only need to toggle it on/off instead of rendering a separate audio file which is reversed.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

It can just be a checkbox on the AudioStreamPlayer that says "reverse".

If this enhancement will not be used often, can it be worked around with a few lines of script?

I don't think that this is possible to do with scripts currently.

Is there a reason why this should be core and not an add-on in the asset library?

I feel that this will be more suitable as a core feature instead of a plugin.

@Calinou
Copy link
Member

Calinou commented Aug 26, 2021

I don't see how audio could be reversed in real-time. This may need to be an import option, which means you'd still need to have two copies of the original file lying around (because Godot's import system only supports 1:1 mappings).

I also don't know if reversed audio playback is a very common thing in games. It often doesn't sound pleasant after all, so using edited sounds is regularly done in practice instead.

@foxydevloper
Copy link

Maybe this could be supported as a form of variable playback speeds, where negative speed reverses the audio. If it's not in demand as a core feature I don't see why it couldn't be done as an addon/plugin though

@Calinou
Copy link
Member

Calinou commented Aug 26, 2021

Maybe this could be supported as a form of variable playback speeds, where negative speed reverses the audio. If it's not in demand as a core feature I don't see why it couldn't be done as an addon/plugin though

Variable playback speed is already supported by adjusting the pitch_scale property. However, playing audio in reverse implies that time can be reversed somehow. It might be possible (this is supported in AnimationPlayer already), but I'm not sure.

@foxydevloper
Copy link

foxydevloper commented Aug 26, 2021

Variable playback speed is already supported by adjusting the pitch_scale property. However, playing audio in reverse implies that time can be reversed somehow. It might be possible (this is supported in AnimationPlayer already), but I'm not sure.

Then allowing negative pitch_scale would be good for reversing audio, since reversing audio doesn't seem too common of a feature to warrant it's own dedicated property. Since AnimationPlayer supports reversing by setting negative speed, It would also be consistent to have that behavior in AudioStreamPlayer as well

@Moebits
Copy link
Author

Moebits commented Aug 26, 2021

I also don't know if reversed audio playback is a very common thing in games. It often doesn't sound pleasant after all, so using edited sounds is regularly done in practice instead.

Well, this is more of a niche feature that I want specifically for my game.

However, playing audio in reverse implies that time can be reversed somehow. It might be possible (this is supported in AnimationPlayer already), but I'm not sure.

Time itself doesn't have to be reversed. Let's say that you are 30 seconds into a 100 second long audio file. When you reverse it, then internally it will jump to the 70 second mark (because this corresponds to the same position in the forwards playing file).

In other words, you can calculate the position in a reverse-playing file with the formula (1 - (current_position / total_duration)) * total_duration.

Then allowing negative pitch_scale would be good for reversing audio, since reversing audio doesn't seem too common of a feature to warrant it's own dedicated property.

Yes, I'd be good with this implementation as well. I am not at all familiar with the Godot codebase, but if I can receive some pointers on which files I have to edit I could try to PR it myself.

@Calinou
Copy link
Member

Calinou commented Aug 26, 2021

but if I can receive some pointers on which files I have to edit I could try to PR it myself.

The change needs to be made in 3 different places.

AudioStreamPlayer (non-positional sound): https://github.com/godotengine/godot/blob/master/scene/audio/audio_stream_player.cpp

AudioStreamPlayer2D: https://github.com/godotengine/godot/blob/master/scene/2d/audio_stream_player_2d.cpp

AudioStreamPlayer3D: https://github.com/godotengine/godot/blob/master/scene/2d/audio_stream_player_3d.cpp

@KoBeWi
Copy link
Member

KoBeWi commented Aug 28, 2021

The change needs to be made in 3 different places.

Not after godotengine/godot#51296 was merged.

@Calinou
Copy link
Member

Calinou commented Mar 6, 2022

Closing due to lack of support (see lack of reactions on OP and overall low activity here).
On the Godot Contributors Chat, ellenhp said:

I don't think vorbis lets you do this natively, so we'd need to buffer chunks unless it was just for wavs. I'd be willing to review something like this but I don't want to try to implement it, it sounds very difficult.

For reference, this is how you can reverse an audio clip using Audacity:

  • Select all audio by pressing Ctrl + A.
  • Select Effect > Reverse:

image

  • Export the selected audio (preferably to WAV to avoid losing any quality).

This process might be automatable using something like FFmpeg too.

@Moebits
Copy link
Author

Moebits commented Mar 7, 2022

I thought most of the changes had to be made in the function int AudioStreamPlaybackResampled::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames), but my attempts were unsuccessful, I don't really understand it tbh.

Since this seems very difficult to implement based on how the code is structured, then fair enough, forget about it.

@RobotoSkunk
Copy link

Closing due to lack of support (see lack of reactions on OP and overall low activity here). On the Godot Contributors Chat, ellenhp said:

I don't think vorbis lets you do this natively, so we'd need to buffer chunks unless it was just for wavs. I'd be willing to review something like this but I don't want to try to implement it, it sounds very difficult.

For reference, this is how you can reverse an audio clip using Audacity:

* Select all audio by pressing Ctrl + A.

* Select **Effect > Reverse**:

image

* Export the selected audio (preferably to WAV to avoid losing any quality).

This process might be automatable using something like FFmpeg too.

I think we should reconsider to open this issue again and add this missing option after 3 years of lacking, because the option you gave is not really useful for some games.

For example, if I'm working on a rhythm game and I need to play an audio backwards because the player lost and needs to restart the level, that can't be made with edited files, especially if I want to add something like a level editor support with custom songs given by my players.

@Calinou Calinou reopened this Jul 9, 2024
@Calinou Calinou removed the archived label Jul 9, 2024
@RobotoSkunk
Copy link

As an update, I'm trying to add this in int AudioStreamPlaybackResampled::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) and I think I almost found how to achieve it, but it's still hard.

If someone wants to help, I'm sending updates in Godot Contribuitors Chat.

@Calinou

This comment was marked as resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants