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 runtime file loading to AudioStreamWAV #93831

Merged
merged 1 commit into from
Dec 3, 2024

Conversation

what-is-a-git
Copy link
Contributor

@what-is-a-git what-is-a-git commented Jul 1, 2024

This PR adds a load_from_file and load_from_buffer method to AudioStreamWAV. The load_from_file method has the parameters path:String and options:Dictionary, and load_from_buffer has buffer:PackedBytesArray and options:Dictionary.

This is helpful in the use-case where you want to load audio files at runtime (ex: a music player), and need to load a WAV file. These methods reuse the code for the normal import functionality for WAV files to stay consistent with the rest of the engine, while allowing users to access this functionality in a convenient way.

This should fix godotengine/godot-proposals#732, although a slight refactor of WAV importing may be something to consider in the future.

Also: if there is a better way to provide the import parameters other than a Dictionary I would love to improve that for these new methods, I was just having issues trying to bind a static method using the HashMaps that are used when importing files normally, so I decided to switch it to a Dictionary for this specific function because of that. (I'm not the most knowledgeable on the Godot codebase currently, so I wasn't sure what else to do).

@Mickeon
Copy link
Contributor

Mickeon commented Jul 1, 2024

Also: if there is a better way to provide the import parameters other than a Dictionary I would love to improve that for these new methods, I was just having issues trying to bind a static method using the HashMaps that are used when importing files normally, so I decided to switch it to a Dictionary for this specific function because of that.

Because the passed parameters are identical to the contents of ResourceImporterWAV, why not just passing a singular ResourceImporterWAV object?

@what-is-a-git
Copy link
Contributor Author

Also: if there is a better way to provide the import parameters other than a Dictionary I would love to improve that for these new methods, I was just having issues trying to bind a static method using the HashMaps that are used when importing files normally, so I decided to switch it to a Dictionary for this specific function because of that.

Because the passed parameters are identical to the contents of ResourceImporterWAV, why not just passing a singular ResourceImporterWAV object?

Thanks for the idea, I don't know how I didn't think of that before 😅, will look into that ASAP!

@what-is-a-git what-is-a-git marked this pull request as draft July 1, 2024 21:22
@what-is-a-git
Copy link
Contributor Author

After looking into this further it doesn't seem like I can use a ResourceImporterWAV object directly to pass around the import options, as the options were never stored in this class to begin with, if another better solution is found I'll look into it.

@Mickeon
Copy link
Contributor

Mickeon commented Jul 1, 2024

Okay, indeed. Then what may be worth doing for the time being is providing a codeblock example because just saying the properties are the same makes the functionality harder to discover.

@Calinou
Copy link
Member

Calinou commented Jul 1, 2024

Out of curiosity, why is this functionality exposed both in AudioStreamWAV and ResourceImporterWAV, especially since their arguments are the same? I'd suggest only exposing it in AudioStreamWAV, as ResourceImporter is not meant to be used outside of editor builds.

@what-is-a-git
Copy link
Contributor Author

Okay, indeed. Then what may be worth doing for the time being is providing a codeblock example because just saying the properties are the same makes the functionality harder to discover.

Added a codeblock to the docs, it should be good for now I think. I decided against just relisting all the properties in a codeblock since the ResourceImporterWAV class is public and has proper descriptions for all the properties, but maybe I should? Not sure.

Out of curiosity, why is this functionality exposed both in AudioStreamWAV and ResourceImporterWAV, especially since their arguments are the same? I'd suggest only exposing it in AudioStreamWAV, as ResourceImporter is not meant to be used outside of editor builds.

I exposed it in both because I was using ResourceImporterOggVorbis as my main reference, and it also does that, but learning that normally you shouldn't (and looking at the currently failing builds other than editor) it seems like only exposing it in AudioStreamWAV is in fact the ideal solution.

I think now the main thing I'm looking at is getting this working outside editor builds, as currently it seems that (unsurprisingly) a file inside the editor/import folder isn't being compiled into non-editor templates. This can probably(?) be fixed by just relocating the file but I'm not sure if that's the most ideal solution in this case.

@what-is-a-git
Copy link
Contributor Author

Instead of moving the files around I realized I could just move the logic for load_from_file to AudioStreamWAV since that should always be included in the engine when compiling, relying on it for imports now but retaining the same compatibility. This seems like it might've fixed a small issue in audio_effect_record.cpp where it was relying on the editor folder when it shouldn't have, so that seems good.

Any other feedback appreciated if any improvements can be thought of here (currently I think everything is pretty alright as-is for this feature though).

@what-is-a-git what-is-a-git force-pushed the wav-runtime branch 3 times, most recently from 544da24 to 2ea1589 Compare July 2, 2024 19:35
@what-is-a-git what-is-a-git marked this pull request as ready for review July 2, 2024 19:40
@what-is-a-git what-is-a-git requested a review from a team as a code owner July 2, 2024 19:40
@what-is-a-git what-is-a-git changed the title Add runtime file loading to AudioStreamWAV and ResourceImporterWAV Add runtime file loading to AudioStreamWAV Jul 7, 2024
Copy link
Member

@Calinou Calinou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested locally, it works as expected. WAV files of varying sample rates are handled correctly out of the box, along with mono/stereo audio.

However, AudioStreamWAV.load_from_buffer() should be added for parity with AudioStreamOggVorbis. This allows loading audio data from memory, without needing it to be written to disk first. This is useful for networked scenarios and unit testing.

Testing project: runtime_save_load.zip1

Footnotes

  1. This is https://github.com/godotengine/godot-demo-projects/tree/master/loading/runtime_save_load modified to support WAV loading. No WAV samples are included in examples/.

@what-is-a-git
Copy link
Contributor Author

Added a load_from_buffer function to AudioStreamWAV as said before, everything seems to be working fine so far.

Copy link
Contributor

@Mickeon Mickeon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doc/classes/AudioStreamWAV.xml Outdated Show resolved Hide resolved
@what-is-a-git what-is-a-git force-pushed the wav-runtime branch 2 times, most recently from 4ecf1b2 to a58f8ab Compare July 7, 2024 13:53
Copy link
Member

@AThousandShips AThousandShips left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And fix the indentation

doc/classes/AudioStreamWAV.xml Outdated Show resolved Hide resolved
doc/classes/AudioStreamWAV.xml Outdated Show resolved Hide resolved
doc/classes/AudioStreamWAV.xml Outdated Show resolved Hide resolved
@what-is-a-git
Copy link
Contributor Author

Updated the commit to fix IMA ADPCM compression not being supported by AudioEffectRecord at runtime, since with the moving of the compression function it is now entirely possible to do it without referencing ResourceImporterWAV.

Copy link
Contributor

@Mickeon Mickeon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor nitpicks I may have caused.

Either way, now that it's been rebased someone could nicely test it.

doc/classes/AudioStreamWAV.xml Outdated Show resolved Hide resolved
doc/classes/AudioStreamWAV.xml Outdated Show resolved Hide resolved
@Mickeon Mickeon modified the milestones: 4.x, 4.4 Nov 11, 2024
@what-is-a-git
Copy link
Contributor Author

Fixed the minor nitpicks in the docs.

@akien-mga akien-mga requested review from aaronfranke and adamscott and removed request for aaronfranke November 29, 2024 13:56
@what-is-a-git
Copy link
Contributor Author

Fixed up remaining merge conflicts (due to some ResourceUID stuff).

Copy link
Member

@akien-mga akien-mga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.

Copy link
Member

@adamscott adamscott left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems ok!

@what-is-a-git
Copy link
Contributor Author

Fixed accidental reversion in the docs of the new functions.

@Repiteo Repiteo merged commit 42eb4fb into godotengine:master Dec 3, 2024
20 checks passed
@Repiteo
Copy link
Contributor

Repiteo commented Dec 3, 2024

Thanks! Congratulations on your first merged contribution! 🎉

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

Successfully merging this pull request may close these issues.

Easily load external audio (WAV) files at run-time
8 participants