heraldofgargos / godot-fmod-integration

FMOD Studio middleware integration and scripting API bindings for the Godot game engine.
MIT License
177 stars 13 forks source link

Playing a MOD file #2

Open Domarius opened 5 years ago

Domarius commented 5 years ago

Sorry, this is the only way I can see to ask this kind of question. Godot is compiled, and the demo project works!

But none of the examples show me how to just play a simple file from the hard drive - all the examples use "banks".

In C++ it's pretty straight forward; system->createSound("path to sound", &sound) gives you a pointer to the sound, which you play with system->playSound(sound). But I can't see any equivalent functions available from the Fmod Godot object.

Specifically I have those old MOD "tracker" songs and I want my games to be able to play them. S3M, MOD, IT, XM etc. It's the sole reason I'm using your module :)

heraldofgargos commented 5 years ago

Hey there.

You should be able to get this done as of https://github.com/alexfonseka/godot-fmod-integration/commit/8e0db73fbad07ed58edc3144de6a557c5936acb0.

In GDScript you would do:

var my_sound = FMOD.sound_load(UUID.new(), "<your-file-name>.mod", Fmod.FMOD_DEFAULT)
FMOD.sound_play(my_sound)

I've also updated the documentation with some more code snippets.

The Godot integration mainly focuses on Studio functions (for now at least) so not many low level functions are exposed as of yet :)

Domarius commented 5 years ago

That's amazing, thank you. MOD playback is literally the one thing I personally miss in Godot, I'm looking forward to making use of this.

So I notice usually we have 2 separate functions, generally in sound libraries, one for quick sound effects, and another for ongoing background music. The example you have there, looks like it's used for sound effects (as per your documentation) AND music (as per your example above), I assume there's no issue with this?

heraldofgargos commented 5 years ago

You can use the example code for quick sounds. For music you can set the mode to Fmod.FMOD_CREATESTREAM. I wouldn;t use this for MOD files but it is useful if you're playing back large .wav files for example.

Also, for quick sounds there are play_one_shotand play_one_shot_attached functions available. These only work with Studio events though.

Domarius commented 5 years ago

Ah, I assume we wouldn't do "FMOD_CREATESTREAM" unless the file was actually big, and MOD files are usually very small?

I'm getting an error with the above code snippit, it doesn't recognise the FMOD_DEFAULT enum I think. Invalid get index 'FMOD_DEFAULT' (on base: 'GDScriptNativeClass').

I'm a little new to using git, so just to be sure I've updated correctly, below I've pasted the terminal output of how I updated your module and recompiled, that way you can make sure I did it correctly. (Path name is a bit long, so I shortened it before pasting)

domarius@Domarius-Ubuntu /(long path)/Godot3_FMOD $ cd godot
domarius@Domarius-Ubuntu /(long path)/Godot3_FMOD/godot $ cd modules
domarius@Domarius-Ubuntu /(long path)/Godot3_FMOD/godot/modules $ cd fmod
domarius@Domarius-Ubuntu /(long path)/Godot3_FMOD/godot/modules/fmod $ git checkout master
M   .gitignore
M   LICENSE
M   README.md
M   SCsub
M   api/.gitkeep
M   api/COPY_FMOD_API_HERE
M   config.py
M   demo/Banks/Desktop/Master Bank.bank
M   demo/Banks/Desktop/Master Bank.strings.bank
M   demo/Scenes/Main.tscn
M   demo/Scripts/FMOD.gd
M   demo/Scripts/Listener.gd
M   demo/Scripts/Main.gd
M   demo/default_env.tres
M   demo/icon.png
M   demo/icon.png.import
M   demo/project.godot
M   godot_fmod.cpp
M   godot_fmod.h
M   register_types.cpp
M   register_types.h
Already on 'master'
Your branch is up to date with 'origin/master'.
domarius@Domarius-Ubuntu /(long path)/Godot3_FMOD/godot/modules/fmod $ git pull
remote: Enumerating objects: 38, done.
remote: Counting objects: 100% (38/38), done.
remote: Compressing objects: 100% (9/9), done.
remote: Total 27 (delta 18), reused 27 (delta 18), pack-reused 0
Unpacking objects: 100% (27/27), done.
From https://github.com/alexfonseka/godot-fmod-integration
   523fb28..a0c6a3d  master     -> origin/master
Updating 523fb28..a0c6a3d
error: Your local changes to the following files would be overwritten by merge:
    .gitignore
    README.md
    SCsub
    config.py
    demo/Scripts/FMOD.gd
    demo/Scripts/Main.gd
    godot_fmod.cpp
    godot_fmod.h
Please commit your changes or stash them before you merge.
Aborting
domarius@Domarius-Ubuntu /(long path)/Godot3_FMOD/godot/modules/fmod $ cd ..
domarius@Domarius-Ubuntu /(long path)/Godot3_FMOD/godot/modules $ cd ..
domarius@Domarius-Ubuntu /(long path)/Godot3_FMOD/godot $ scons -j8 platform=x11
scons: Reading SConscript files ...
Enabling ALSA
Enabling PulseAudio
Checking for C header file mntent.h... (cached) yes
scons: done reading SConscript files.
scons: Building targets ...
[ 99%] progress_finish(["progress_finish"], [])
[100%] scons: done building targets.
domarius@Domarius-Ubuntu /(long path)/Godot3_FMOD/godot $ 

And here's my code:

extends Node2D

var FMOD = Fmod.new()
const UUID = preload("res://uuid.gd")

# Called when the node enters the scene tree for the first time.
func _ready():
        # set up FMOD
    FMOD.system_set_software_format(0, Fmod.FMOD_SPEAKERMODE_STEREO, 0)
    # initializing with the LIVE_UPDATE flag lets you
    # connect to Godot from the FMOD Studio editor
    # and author events in realtime
    FMOD.system_init(1024, Fmod.FMOD_STUDIO_INIT_LIVEUPDATE, Fmod.FMOD_INIT_NORMAL)

    var my_sound = FMOD.sound_load(UUID.new(), "music/SCORES.mod", Fmod.FMOD_DEFAULT)
    FMOD.sound_play(my_sound)
heraldofgargos commented 5 years ago

It seems Git didn't merge some of the changes because of conflicts. You can stash your local changes using git stash and then pull.

Also I should mention that I've upgraded the FMOD version of the integration to 2.00.00. So you need to download this version of the API from FMOD's website. Just follow the instructions as described here.

Domarius commented 5 years ago

Thanks :) Ok that's weird because I never changed anything - it's possible I saved over the demo project files when experimenting, but certainly not the .cpp and .h files...

Ok I restarted and got the latest Godot and godot-fmod. Now compiling gives me this error, any idea what this could mean?

modules/fmod/godot_fmod.cpp: In member function 'void Fmod::updateInstance3DAttributes(FMOD::Studio::EventInstance*, Object*)':
modules/fmod/godot_fmod.cpp:92:58: error: cannot bind non-const lvalue reference of type 'FMOD_VECTOR&' to an rvalue of type 'FMOD_VECTOR'
    FMOD_3D_ATTRIBUTES attr = get3DAttributes(toFmodVector(pos), toFmodVector(up), toFmodVector(forward), toFmodVector(vel));
                                              ~~~~~~~~~~~~^~~~~
In file included from modules/fmod/godot_fmod.cpp:30:0:

That error occurs about 4 times in different places but I figured it was redundant to paste all of them since they seem to all be the same problem.

As far as getting the latest FMOD 2.00.00, I have downloaded it and copied it into the modiles/fmod/api folder again as well. Though the first instruction "You must download FMOD and install it" worries me every time, because I don't know what it means by "installing it". In Windows I'd expect an .exe or .msi to install with, and in Linux (Ubuntu), I'd expect one of those package files you can install with the Software Installer. Is this instruction to "install it" just referring to the copying of the api folder in the later instruction?

heraldofgargos commented 5 years ago

That's quite interesting. I'm not getting this error on MSVC. Using different compilers can sometimes result in compiler errors so I'm guessing this is one of those cases.

Can you try updating the module again (make sure it includes https://github.com/alexfonseka/godot-fmod-integration/commit/4daf9cb636e94f417ee624d3106ad6dd9a849db4) and see if it successfully compiles now?

As far as getting the latest FMOD 2.00.00, I have downloaded it and copied it into the modiles/fmod/api folder again as well. Though the first instruction "You must download FMOD and install it" worries me every time, because I don't know what it means by "installing it". In Windows I'd expect an .exe or .msi to install with, and in Linux (Ubuntu), I'd expect one of those package files you can install with the Software Installer. Is this instruction to "install it" just referring to the copying of the api folder in the later instruction?

They essentially mean the same thing. The installation section describes this in two steps, first to install the API (on Windows it's an installer and on Linux it's just a gzip that you can extract somewhere). The second step is to copy the files to the module's /api directory.

Domarius commented 5 years ago

Ok, I started from scratch, deleted the entire godot source folder and got the latest godot and your fmod module - and I still have compile errors :( Since you mentioned different compilers, it's worth mentioning I'm on Ubuntu and using the relevant compile command for that from the Godot docs - scons -j8 platform=x11.

Here is the complete output of the terminal of me doing all this, at this pastebin link https://pastebin.com/FVyPpkAq As it's a lot of text, here's the parts of interest;

Here's the start, where I downloaded everything then kicked off the build

domarius@Domarius-Ubuntu /mnt/stuff/To Sort/Software/Game Development/Godot/Godot3_FMOD $ git clone https://github.com/godotengine/godot
Cloning into 'godot'...
remote: Enumerating objects: 7, done.
remote: Counting objects: 100% (7/7), done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 212058 (delta 1), reused 0 (delta 0), pack-reused 212051
Receiving objects: 100% (212058/212058), 292.16 MiB | 1.67 MiB/s, done.
Resolving deltas: 100% (163317/163317), done.
Checking out files: 100% (6928/6928), done.
domarius@Domarius-Ubuntu /mnt/stuff/To Sort/Software/Game Development/Godot/Godot3_FMOD $ cd godot
domarius@Domarius-Ubuntu /mnt/stuff/To Sort/Software/Game Development/Godot/Godot3_FMOD/godot $ cd modules
domarius@Domarius-Ubuntu /mnt/stuff/To Sort/Software/Game Development/Godot/Godot3_FMOD/godot/modules $ cd ..
domarius@Domarius-Ubuntu /mnt/stuff/To Sort/Software/Game Development/Godot/Godot3_FMOD/godot $ git submodule add https://github.com/alexfonseka/godot-fmod-integration modules/fmod
Cloning into '/mnt/stuff/To Sort/Software/Game Development/Godot/Godot3_FMOD/godot/modules/fmod'...
remote: Enumerating objects: 198, done.
remote: Counting objects: 100% (198/198), done.
remote: Compressing objects: 100% (119/119), done.
remote: Total 198 (delta 122), reused 147 (delta 76), pack-reused 0
Receiving objects: 100% (198/198), 898.27 KiB | 749.00 KiB/s, done.
Resolving deltas: 100% (122/122), done.
domarius@Domarius-Ubuntu /mnt/stuff/To Sort/Software/Game Development/Godot/Godot3_FMOD/godot $ scons -j8 platform=x11
(snip)

And here's the end, where it failed the compile;

(snip)
[Initial build] modules/libmodules.x11.tools.64.a(godot_fmod.x11.tools.64.o): In function `Fmod::setGlobalParameter(String const&, float)':
/mnt/stuff/To Sort/Software/Game Development/Godot/Godot3_FMOD/godot/modules/fmod/godot_fmod.cpp:152: undefined reference to `FMOD::Studio::System::setParameterByName(char const*, float, bool)'
modules/libmodules.x11.tools.64.a(godot_fmod.x11.tools.64.o): In function `Fmod::getGlobalParameter(String const&)':
/mnt/stuff/To Sort/Software/Game Development/Godot/Godot3_FMOD/godot/modules/fmod/godot_fmod.cpp:157: undefined reference to `FMOD::Studio::System::getParameterByName(char const*, float*, float*) const'
modules/libmodules.x11.tools.64.a(godot_fmod.x11.tools.64.o): In function `Fmod::getEventParameter(String const&, String const&)':
/mnt/stuff/To Sort/Software/Game Development/Godot/Godot3_FMOD/godot/modules/fmod/godot_fmod.cpp:249: undefined reference to `FMOD::Studio::EventInstance::getParameterByName(char const*, float*, float*) const'
modules/libmodules.x11.tools.64.a(godot_fmod.x11.tools.64.o): In function `Fmod::setEventParameter(String const&, String const&, float)':
/mnt/stuff/To Sort/Software/Game Development/Godot/Godot3_FMOD/godot/modules/fmod/godot_fmod.cpp:256: undefined reference to `FMOD::Studio::EventInstance::setParameterByName(char const*, float, bool)'
modules/libmodules.x11.tools.64.a(godot_fmod.x11.tools.64.o): In function `Fmod::playOneShotWithParams(String const&, Object*, Dictionary const&)':
/mnt/stuff/To Sort/Software/Game Development/Godot/Godot3_FMOD/godot/modules/fmod/godot_fmod.cpp:523: undefined reference to `FMOD::Studio::EventInstance::setParameterByName(char const*, float, bool)'
modules/libmodules.x11.tools.64.a(godot_fmod.x11.tools.64.o): In function `Fmod::playOneShotAttachedWithParams(String const&, Object*, Dictionary const&)':
/mnt/stuff/To Sort/Software/Game Development/Godot/Godot3_FMOD/godot/modules/fmod/godot_fmod.cpp:563: undefined reference to `FMOD::Studio::EventInstance::setParameterByName(char const*, float, bool)'
modules/libmodules.x11.tools.64.a(godot_fmod.x11.tools.64.o): In function `Fmod::Fmod()':
/mnt/stuff/To Sort/Software/Game Development/Godot/Godot3_FMOD/godot/modules/fmod/godot_fmod.cpp:867: undefined reference to `FMOD::Studio::System::getCoreSystem(FMOD::System**) const'
collect2: error: ld returned 1 exit status
scons: *** [bin/godot.x11.tools.64] Error 1
scons: building terminated because of errors.

Oh and I have definitely copied the fmod "api" folder in. I've downloaded the appropriate linux fmod api "fmodstudioapi20000linux.tar.gz" and copied the contents of its api folder into godot/modules/fmod/api

heraldofgargos commented 5 years ago

Hey there. It seems you have no compiler errors this time. What you got there is a bunch of linker errors. Are you 100% positive you removed any existing files in /api before copying over the FMOD files? because all of those linker errors are associated with functions that were changed on the 2.00.00 update.

Domarius commented 5 years ago

Ah yes, they are linker errors. But no matter how sure I am that I've got the latest files in the api folder, I still get them. I made a 3 minute video showing me flushing out the folder, re-downloading the latest api, putting it in and re-compiling, and still getting the linker errors :( https://youtu.be/HTjVmKA1nGM

heraldofgargos commented 5 years ago

I'll have a closer look at this on Linux. It's probably a libpath config issue.

In the meantime you can simply revert to a previous commit before the 2.00.00 changes were applied. git checkout 66db3d47d2999f895f227129e1319226fb497067

This commit should play MOD files and it won't have the 2.00.00 changes. Use the FMOD version and API libs that worked for you before.

Domarius commented 5 years ago

Thanks man. Ok did the git checkout you suggested, and downgraded to fmod 1.10.12, and I'm back to the previous "cannot bind non-const lvalue reference" error. Is this something that will be fixed by walking back through fmod versions?

Here's me using the git checkout you gave me, then re-compiling, and the error. I've pasted in fmod api 1.10.12 in the api folder.

domarius@Domarius-Ubuntu /(long path)/Godot3_FMOD/godot/modules/fmod $ git checkout 66db3d47d2999f895f227129e1319226fb497067
Note: checking out '66db3d47d2999f895f227129e1319226fb497067'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at 66db3d4 Updated README
domarius@Domarius-Ubuntu /(long path)/Godot3_FMOD/godot/modules/fmod $ cd ..
domarius@Domarius-Ubuntu /(long path)/Godot3_FMOD/godot/modules $ cd ..
domarius@Domarius-Ubuntu /(long path)/Godot3_FMOD/godot $ scons -j8 platform=x11
scons: Reading SConscript files ...
Enabling ALSA
Enabling PulseAudio
Checking for C header file mntent.h... (cached) yes
scons: done reading SConscript files.
scons: Building targets ...
[ 22%] Compiling ==> modules/fmod/godot_fmod.cpp
[ 22%] Compiling ==> modules/fmod/register_types.cpp
[ 38%] modules/fmod/godot_fmod.cpp: In member function 'void Fmod::updateInstance3DAttributes(FMOD::Studio::EventInstance*, Object*)':
modules/fmod/godot_fmod.cpp:92:58: error: cannot bind non-const lvalue reference of type 'FMOD_VECTOR&' to an rvalue of type 'FMOD_VECTOR'
    FMOD_3D_ATTRIBUTES attr = get3DAttributes(toFmodVector(pos), toFmodVector(up), toFmodVector(forward), toFmodVector(vel));
                                              ~~~~~~~~~~~~^~~~~
In file included from modules/fmod/godot_fmod.cpp:30:0:
modules/fmod/godot_fmod.h:76:21: note:   initializing argument 1 of 'FMOD_3D_ATTRIBUTES Fmod::get3DAttributes(FMOD_VECTOR&, FMOD_VECTOR&, FMOD_VECTOR&, FMOD_VECTOR&)'
  FMOD_3D_ATTRIBUTES get3DAttributes(FMOD_VECTOR &pos, FMOD_VECTOR &up, FMOD_VECTOR &forward, FMOD_VECTOR &vel);
                     ^~~~~~~~~~~~~~~
[ 38%] modules/fmod/godot_fmod.cpp:102:58: error: cannot bind non-const lvalue reference of type 'FMOD_VECTOR&' to an rvalue of type 'FMOD_VECTOR'
    FMOD_3D_ATTRIBUTES attr = get3DAttributes(toFmodVector(pos), toFmodVector(up), toFmodVector(forward), toFmodVector(vel));
                                              ~~~~~~~~~~~~^~~~~
In file included from modules/fmod/godot_fmod.cpp:30:0:
modules/fmod/godot_fmod.h:76:21: note:   initializing argument 1 of 'FMOD_3D_ATTRIBUTES Fmod::get3DAttributes(FMOD_VECTOR&, FMOD_VECTOR&, FMOD_VECTOR&, FMOD_VECTOR&)'
  FMOD_3D_ATTRIBUTES get3DAttributes(FMOD_VECTOR &pos, FMOD_VECTOR &up, FMOD_VECTOR &forward, FMOD_VECTOR &vel);
                     ^~~~~~~~~~~~~~~
[ 38%] modules/fmod/godot_fmod.cpp: In member function 'void Fmod::setListenerAttributes()':
modules/fmod/godot_fmod.cpp:126:57: error: cannot bind non-const lvalue reference of type 'FMOD_VECTOR&' to an rvalue of type 'FMOD_VECTOR'
   FMOD_3D_ATTRIBUTES attr = get3DAttributes(toFmodVector(pos), toFmodVector(up), toFmodVector(forward), toFmodVector(vel));
                                             ~~~~~~~~~~~~^~~~~
In file included from modules/fmod/godot_fmod.cpp:30:0:
modules/fmod/godot_fmod.h:76:21: note:   initializing argument 1 of 'FMOD_3D_ATTRIBUTES Fmod::get3DAttributes(FMOD_VECTOR&, FMOD_VECTOR&, FMOD_VECTOR&, FMOD_VECTOR&)'
  FMOD_3D_ATTRIBUTES get3DAttributes(FMOD_VECTOR &pos, FMOD_VECTOR &up, FMOD_VECTOR &forward, FMOD_VECTOR &vel);
                     ^~~~~~~~~~~~~~~
modules/fmod/godot_fmod.cpp:137:57: error: cannot bind non-const lvalue reference of type 'FMOD_VECTOR&' to an rvalue of type 'FMOD_VECTOR'
   FMOD_3D_ATTRIBUTES attr = get3DAttributes(toFmodVector(pos), toFmodVector(up), toFmodVector(forward), toFmodVector(vel));
                                             ~~~~~~~~~~~~^~~~~
In file included from modules/fmod/godot_fmod.cpp:30:0:
modules/fmod/godot_fmod.h:76:21: note:   initializing argument 1 of 'FMOD_3D_ATTRIBUTES Fmod::get3DAttributes(FMOD_VECTOR&, FMOD_VECTOR&, FMOD_VECTOR&, FMOD_VECTOR&)'
  FMOD_3D_ATTRIBUTES get3DAttributes(FMOD_VECTOR &pos, FMOD_VECTOR &up, FMOD_VECTOR &forward, FMOD_VECTOR &vel);
                     ^~~~~~~~~~~~~~~
[ 38%] modules/fmod/godot_fmod.cpp: In constructor 'Fmod::Fmod()':
modules/fmod/godot_fmod.cpp:853:2: warning: left operand of comma operator has no effect [-Wunused-value]
  system, lowLevelSystem, listener = nullptr;
  ^~~~~~
modules/fmod/godot_fmod.cpp:853:10: warning: right operand of comma operator has no effect [-Wunused-value]
  system, lowLevelSystem, listener = nullptr;
          ^~~~~~~~~~~~~~
[100%] progress_finish(["progress_finish"], [])
[100%] scons: *** [modules/fmod/godot_fmod.x11.tools.64.o] Error 1
scons: building terminated because of errors.
heraldofgargos commented 5 years ago

Haha. Yeah I guess going back also reverts "fixes". I should have split those two into separate commits, my bad.

In your godot_fmod.h file, change lines 76 and 77 to:

line 76: FMOD_3D_ATTRIBUTES get3DAttributes(FMOD_VECTOR pos, FMOD_VECTOR up, FMOD_VECTOR forward, FMOD_VECTOR vel);
line 77: FMOD_VECTOR toFmodVector(Vector3 vec);

And in your godot_fmod.cpp file change lines 458 and 466 to:

line 458: FMOD_VECTOR Fmod::toFmodVector(Vector3 vec) {
...
line 466: FMOD_3D_ATTRIBUTES Fmod::get3DAttributes(FMOD_VECTOR pos, FMOD_VECTOR up, FMOD_VECTOR forward, FMOD_VECTOR vel) {

You should be able to play your MOD file now 🤞

Domarius commented 5 years ago

Success! My games can have MOD music in them now! Thanks man :) I'm curious to know what happens from here with the Linux linker errors, because I'd like to get your updates in the future.

heraldofgargos commented 5 years ago

I'll have to test it out for myself on Linux when I have the time. If you want notifications for future updates you can add the repository to your Github watch list.

Domarius commented 5 years ago

Just a heads up - I have a suspicion I may have previously put the fmod library files in a system location, and it may be referring to those. I'm thinking this is the case because I'm now trying out a different install of linux and it's complaining it can't find the library files at all, even though I'm using the same folder as previously. So it was probably ignoring that fmod/api folder entirely and using older library files that I'd previously placed in the linux system folder for libraries. (usr/lib or something)

Domarius commented 5 years ago

Ahah - I remember what I did - that's the issue with the instructions that I was mentioning earlier.

In step 1, where it says "Download the FMOD Studio API (You need to create an account) and install it on your system.", I took this to mean I had to put the library files somewhere. So I looked up where to put them in a Linux system and did that!

If "installing it" is already covered in step 4 when you copy the api folder, I would suggest removing "and install it on your system" from step 1.

heraldofgargos commented 5 years ago

Hey there! Thanks for letting me know. I noticed that there is a slight issue in the build config file and it is not specifying the correct libpath for Linux. It worked for you earlier because the linker searches for the libs firstly in the LIBRARY_PATH env variable and if it does not find them it will then proceed to check the usr/lib folder which in your case was where it eventually found them.

I pushed a fix e6f02935f1d122b06e779827f463ba07f603a5b7 that should hopefully solve all the linking errors.

If "installing it" is already covered in step 4 when you copy the api folder, I would suggest removing "and install it on your system" from step 1.

On Windows (and on macOS as well I believe) it's an installation package that you need to run. On Linux though it is just an archive with the lib files. I guess I'll update the docs to reflect this to prevent any sort of confusion.

Domarius commented 5 years ago

Awesome! I'll try updating soon. Heh, I guess I'm your Linux QA for the moment.

So after the update, it should look in godot/modules/fmod/api?

heraldofgargos commented 5 years ago

Yeah, it should look in that directory now. Let me know how you go.