Playing music with AudioManager

Greetings !

I’ve got an issue while trying to play music. I made a very simple music manager, but the sound doesn’t play and I have absolutely no idea why.

I load my music like this:

_current_music = _audio_manager->get_sound("audio/traderslife.ogg");
_current_music->play();
if (_current_music->status() == AudioSound::BAD)
  cout << "Failed to start audio file" << endl;
else if (_current_music->status() == AudioSound::PLAYING)
  cout << "Now playing file 'audio/" << song.Value() << "'" << endl;
else
  cout << "What the fuck" << endl;

And then, everytime my do_task is executed, I do this:

if (_current_music->status() == AudioSound::PLAYING)
  cout << "haz current music (" << _current_music->get_time() << ")" <<  endl;

The music isn’t playing, and get_time always returns zero. Though, the status flag is indeed set to PLAYING.
I probably did something wrong, but reading the manual, I can’t figure out what… it seems alright to me.

Any ideas ?

In case this wasn’t enough, I found time to work on a piece of code that can reproduce the issue. Here it is:

#include <panda3d/pandaFramework.h>
#include <panda3d/pandaSystem.h>
#include <panda3d/audioManager.h>

int main(int argc, char *argv[])
{
  WindowFramework* window;

  framework.open_framework(argc, argv);
  framework.set_window_title("Fallout Equestria");
  window = framework.open_window();
  window->enable_keyboard();
  window->get_render().set_shader_auto();
  
  PT(AudioManager) am  = AudioManager::create_AudioManager();
  PT(AudioSound)   snd = am->get_sound("audio/brel.ogg");

  snd->play();
  
  if (snd->status() == AudioSound::PLAYING)
    cout << "It should be playing" << endl;
  else
    cout << "It shouldn't be playing" << endl;
  {
    framework.main_loop();
    framework.close_framework();
  }
  return (0);
}

This reproduce the exact same situation: “It should be playing” is printed, yet no sound is playing.
If we could print snd->get_time() at each turn of the loop, it would always return 0.

Is that normal ? What did I forget ?

I think you have to call am->set_active(true) to initially activate the AudioManager.

David

I tried it out, but I still have the same issue…

Could it actually not come from the code, but from OpenAL ?
I would like to think that, but I also play Heroes of Newerth, which uses OpenAL, and it has sounds.

What could possibly be the reason for this to fail.

I tried it out, but I still have the same issue…

Could it actually not come from the code, but from OpenAL ?
I would like to think that, but I also play Heroes of Newerth, which uses OpenAL, and it has sounds.

What could possibly be the reason for this to fail.

There clearly is something going wrong with OpenAL: when I try to debug the previous code, there is an infinite flow of memory errors (nothing critical, but still).
The most important one probably is this one:

==17944== Syscall param semctl(IPC_SET, arg.buf) points to uninitialised byte(s)
==17944==    at 0x52878CF: semctl@@GLIBC_2.2 (in /usr/lib/libc-2.16.so)
==17944==    by 0xB203794: ??? (in /usr/lib/libasound.so.2.0.0)
==17944==    by 0xB1FE7DF: snd_pcm_dmix_open (in /usr/lib/libasound.so.2.0.0)
==17944==    by 0xB1FF26A: _snd_pcm_dmix_open (in /usr/lib/libasound.so.2.0.0)
==17944==    by 0xB1BFB87: ??? (in /usr/lib/libasound.so.2.0.0)
==17944==    by 0xB1C01BD: ??? (in /usr/lib/libasound.so.2.0.0)
==17944==    by 0xFFFFFFFE: ???
==17944==  Address 0xbe90a200 is on thread 1's stack
==17944== 
Is audiomanager active ?1
==17944== Thread 2:
==17944== Source and destination overlap in memcpy(0xf24b4b0, 0xf24b4b0, 32768)
==17944==    at 0x402D2ED: memcpy (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==17944==    by 0xB1C34EE: snd_pcm_area_copy (in /usr/lib/libasound.so.2.0.0)

Is audiomanager active? comes from a check I added to check if get_active was true by default. So the syscall issue occurs when creating the audiomanager, and the memcpy issue when I load the sound.

Everything else is just conditional jumps on uninitialized values, when playing and reading the stream.

Hmm, does sound work in Panda3D via Python?

David

Unfortunately there’s no way to tell.
I couldn’t get the Python module to compile, and since I don’t need it, I didn’t.

Thanks for helping… I’ll wait a few weeks until I can finally compile it on a Windows machine, see if it comes from my environment.

Hi

Are you calling AudioManager update in your task ?

for example:

AsyncTask::DoneStatus updateAudioTask(GenericAsyncTask* task, void* data) {

  AudioManager *am = (AudioManager*)data;

  am->update();

  return AsyncTask::DS_cont;

}

Alright, indeed it was missing !
Thank you and sorry about that, the manual didn’t mention this method.

So new problem now: the samples are playing (I can see the return value of get_time changing).
Apparently everything is working. And I did check: the processus is using the sound device. So that’s a good start.

I also checked that the volume was at 1.0 and the balance at 0.0.
Still, my speakers remain quiet.

Also, the AudioFile::get_time() keeps going forward, even after the file is supposed to be finished. The file’s status never goes from PLAYING to STOP, it just stays at PLAYING.

Have you heard your sound file play in an audio program or tool (like VLC or Audacity) ?

If you are still having problems maybe post what you have again with task routine included and I’ll try it out with my own sound file.

I most certainly did, I tried three different files (mp3, ogg vorbis, flac), and the three of them didn’t work. And they do play on VLC.

I changed my reproducible test to include the task routine updating the audiomanager.
I confirm that it still doesn’t work, and have the same memory errors (uninitialized bytes freaking everywhere… but this might be normal).

It also turns out that wether the file exist or not isn’t important.
Even if the file doesn’t exist, the SoundFile will have the PLAYING status. There’s absolutely no difference when the file exist and when it doesn’t, it works exactly the same.

#include <panda3d/pandaFramework.h>
#include <panda3d/pandaSystem.h>
#include <panda3d/audioManager.h>
#include <iostream>

PT(AudioManager) am;
PT(AudioSound)   sound;
PandaFramework   framework;

using namespace std;

void OutputSound(PT(AudioSound) snd)
{
  if (snd->get_active())
  {
    float snd_time = snd->get_time();
    float volume   = snd->get_volume();
    float balance  = snd->get_balance();
    float len      = snd->length();

    cout << "[Sound (" << len << ")] at " << snd_time << ", vol: " << volume << ", bal: " << balance << endl;
  }
  else
    cout << "Sound isn't active" << endl;
}

class Task : public AsyncTask
{
public:
  DoneStatus do_task(void)
  {
    OutputSound(sound);
    am->update();
    return (DS_cont);
  }
};

int main(int argc, char *argv[])
{
  WindowFramework* window;

  framework.open_framework(argc, argv);
  framework.set_window_title("/dev/snd/test");
  window = framework.open_window();
  window->enable_keyboard();
  window->get_render().set_shader_auto();

  am    = AudioManager::create_AudioManager();
  sound = am->get_sound("audio/penis.flac");

  am->set_active(true);
  sound->play();

  if (sound->status() == AudioSound::PLAYING)
    cout << "It should be playing" << endl;
  else
    cout << "It shouldn't be playing" << endl;
  {
    Task task;

    AsyncTaskManager::get_global_ptr()->add(&task);
    framework.main_loop();
    framework.close_framework();
  }
  return (0);
}

Hi

Your code works on my PC, no problems, and I can hear my .ogg file.

Are you using Panda OpenAL or FMOD ?
Check your Config.prc for the line
audio-library-name p3openal_audio
and make sure it isn’t commented out with a # in the front of the line. I can’t get any sound using FMOD

I’m using OpenAL, and I did add that line to the prc file. Also the memory warnings that I have confirm that OpenAL stuff is called indeed.

The Gosu lib uses OpenAL for sound as well, and I can play those files with it.

Did I mention that the file was considered as “PLAYING” even if the loaded file didn’t exist ? Is that a normal behavior ?

Waait wait wait.
I just swapped my OS from 32 to 64bit, thus I had to recompile every source-based package.

And while doing so with Panda, I remembered that it wasn’t compatible with the latest versions of ffmpeg (which are already packaged for archlinux).
So I compile Panda without ffmpeg support. Don’t tell me… that’s why it doesn’t work ?

ffmpeg is used for audio decoding when OpenAL is used as backend. If you did not compile with ffmpeg, you will have to switch to fmod for sound.