How can I play sound files programmatically? [Solved]

Hi, All.

Usually, you play sound files by “hardcoding” their names onto the slots, like so:

(see attachment)

Can I do it the programmatic way? As I may have a thousand files to play, and would like to use an “expression” like: VariableString(FileName[Child]) in the file name slot.

No, sorry, the string is “fixed”. But would be a nice suggestion, some time ago the file entry (for storage actions/conditions) was fixed too, and now it’s a dynamic string :slight_smile:

Oh, thanks for replying, Liz.

Then, I would have to make a pull request on the core engine of GDevelop, if I ever wanted to have this feature right away like what had been done to the file entry for storage.

I would have to do it for I have a huge number of different sound files to play on different conditions.

:frowning:

Or I think I should try using Javascript (or C++, as code event) to achieve what I want. :slight_smile:

If you know C++, otherwise you can create a topic here in the Feature Request section, or open an “issue” on GitHub.

Yeah, again, if you know C++ (or JS) this is an option too :slight_smile:

I was able to do it in JavaScript, instead the action to play a sound, I used this JS code:

var random_1_3 = Math.floor(Math.random()*3) + 1; // random number between 1 and 3 var sound_manager = runtimeScene.getGame().getSoundManager(); // get the sound manager sound_manager.playSoundOnChannel("Sound " + random_1_3.toString() + ".wav", 0, false, 100, 1); // play random sound, channel = 0, loop = false, volume = 100, pitch = 1
But you have to add the sound files in the resources manager (as if the sound file were an image), in this example, 3 files named “Sound 1.wav”, “Sound 2.wav” and “Sound 3.wav” were used :wink:

For native games, I have recompiled GDevelop with just some modifications, in the file GD/Core/GDCore/Extensions/Builtin/AudioExtension.cpp: In the actions that has a parameter “soundfile” or “musicfile”, change it to “string”. But with this modification, the play sound actions doesn’t work on web (the JS code still works) :neutral_face:
Maybe you can do it through C++ code, but C++ code extension is broken here :frowning:

EDIT: It seems that the C++ event is not as broken as I thought, it works very well, sorry developers! :smiley:
Anyway, I can’t play the sound. The program compiles, but even with static filenames in the PlaySoundOnChannel() function the sound doesn’t start, the rest of the code runs ok (for example change scene background color).
I’m just guessing, because I can’t test it, but maybe this code does the same than the JS code :laughing:
Includes:

<iostream> <stdlib.h> "GDCpp/Runtime/String.h" "GDCpp/Runtime/CommonTools.h" "GDCpp/Runtime/RuntimeGame.h" "GDCpp/Runtime/SoundManager.h"
Body:

// Get the sound manager RuntimeGame* game = scene.game; SoundManager sound_manager = game->GetSoundManager(); // Generate random file int random_number = rand()%3 + 1; gd::String random_file = "Sound " + gd::String::From(random_number) + ".wav"; // Play it sound_manager.PlaySoundOnChannel(random_file, 1, false, 100, 1);

1 Like

Wow, thanks for the efforts looking into both sides, js and C++. Yes, your approach in js was what I was thinking (including the resources manager).

C++ is not my thing, but I m planning to do more via C++ code event anyway (good to know it works). Shall let you know if I stumble into anything intresting.

Cheers

Salut! Lizard.

Issues solved!

First , our code should not be exposed to the general game loop, otherwise the sound(s) playing will be started over and over virtually infinitely.

However, we CANNOT use this code, either:

If (scene.IsFirstLoop){}
(Perhaps , it has been made broken by some newer update. The wiki needs update with this point)

I, thus, first created an event in the Scene Editor, then added the present C++ code as sub-event, like so:

[code]// To show the code event can work
scene.SetBackgroundColor(100,100,240);

// Generate random file
int random_number = rand()%5 + 1;
gd::String random_file = “sentence” + gd::String::From(random_number) + “.ogg”;

// Play it
scene.game->GetSoundManager().PlaySoundOnChannel(random_file,0,false,100,1.0);[/code]
(Yes, we now can use Code Event as sub-event in the Event Editor.)

Of course, the include list in the Code Event editor:

<iostream> <stdlib.h> "GDCpp/Runtime/String.h" "GDCpp/Runtime/CommonTools.h" "GDCpp/Runtime/RuntimeGame.h" "GDCpp/Runtime/SoundManager.h"

I have included the project, including the sound files (ogg) for you all’s reference and test. :slight_smile: See the scene: PlayByCode.

P.S.
Lizard,

I don’t quite comprehend C++ Pointer anyway, and I found your relevant seemed not working (idk how):

// Get the sound manager RuntimeGame* game = scene.game; SoundManager sound_manager = game->GetSoundManager();

So, ignoring possible drawbacks (or bugs) I used: scene.game->GetSoundManager().PlaySoundOnChannel…
:exclamation: Please enlighten me as to the reason and how I can use pointer properly in the current case.
CodePlaySound.zip (90 KB)

Yes, you did it! :smiley:
The problem was not the pointer, but for not use a pointer in the SoundManager variable, when I do:

SoundManager sound_manager = game->GetSoundManager()

It creates a copy of the sound manager in the memory. But surely other code of GD, to update the sound manager and so, uses a pointer, the pointer to the original sound manager pointing to another memory block different than my variable. In other words, this sound_manager variable is useless.
To fix it, just save the pointer instead a copy:

SoundManager* sound_manager = &(game->GetSoundManager())

I hope I’m not saying a lot of trash, as I’m not a C++ developer, I’m just “learning” it for curiosity :stuck_out_tongue:

And instead:

sound_manager.PlaySoundOnChannel()

You have to do:

sound_manager->PlaySoundOnChannel()    // because sound_manager is a pointer

Makes my example to work, thanks