0
0

I have written an audio manager for use by my cross-platform high FPS visualization framework. Its functionality and performance in Windows is absolutely stellar. Applications built with this framework (and hence the audio manager) compile and execute without any errors on Linux. However, on Linux, even though I get no errors, I hear no sound in my apps that use the high FPS viz framework. I tried putting a call to FSOUND_Update() in the frame loop but that did not work. I tried using the audio manager in a simple console application and it worked fine … ??? Does anyone have a clue what would be causing this problem? I could post code but it would entail the posting of pages upon pages of code …

Thanks in advance,
Paul

  • You must to post comments
0
0

Note that this happens for both streaming and sampled audio.

  • You must to post comments
0
0

Ok here is the Audio Manager header :
[code:1bsz79w0]
// MgAudioManager.h

ifndef MGAUDIOMANAGER_INCLUDED

define MGAUDIOMANAGER_INCLUDED

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Description:
//
// Manages sound effects and music functions for MagnaSim.
//
// Author: Paul H. Leopard
//
// $Modtime: 7/02/04 12:33p $
//
// $Revision: 3 $
//
//——-0———0———0———0———0———0———0———0

// ____________________________________________________________________________
// Common definitions needed by all MgAudio header files.

include "MgAudioCommon.h"

// ............................................................................
// This class declaration requires knowledge of other class interfaces and/or
// declarations contained in the following header files:

// C++ Standard Library includes

include <vector>

// MAGNASIM includes

include "MgErrorTracking.h"

include "MgAudioTrack.h"

// ...........................................................................
// ...........................................................................
// The following class definition resides in the MAGNASIM namespace

namespace MAGNASIM {

// ...........................................................................
// This class declaration utilizes the following classes and/or types but
// does not require knowledge of their interfaces:

// MAGNASIM stubs

class MgAudioTrack;
class MgAudioTrackCollection;
class MgFile;

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/** Manages sound effects and music functions for MagnaSim.
*/
class MgAudioManager : public MgErrorTracking
{

// ____________________________________________________________________________
// Public methods.

public:

// ............................................................................
// Lifecycle methods

/** Constructor.
*/
MgAudioManager();

/** Destructor.
*/
~MgAudioManager();

// ............................................................................
// Accessor methods

/** Retrieve the names for all registered audio tracks.
@param trackNames Receptor for the track names.
*/
void getTrackNames(std::vector<MgStlString> &trackNames) const;

/** Retrieve the identifiers for all registered audio tracks.
@param trackIDS Receptor for the track identifiers.
*/
void getTrackIDS(std::vector<size_t> &trackIDS) const;

// ............................................................................
// Manipulator methods

/** Startup/initialization.
@return true if the operation succeeded, false otherwise.
*/
bool startup();

/** Stop all playing audio.
@return true if the operation succeeded, false otherwise.
*/
bool silence();

/** Reset this instance, releasing all audio resources.
@return true if the operation succeeded, false otherwise.
*/
bool reset();

/** Respond to a frame update request. This updates the 3d sound engine
and DMA engine (only on some platforms), and should be called once
a game frame
*/
void frameUpdate();

/** Load a sound track from disk and associate it with a unique track name.
Valid filename extensions for Stream are WAV, MP2, MP3, OGG and RAW.
Valid filename extensions for Sample are WAV, MP2, MP3, OGG and RAW.
Valid filename extensions for Song are MOD, S3M, XM, IT or MID.
@param audioFile Associated audio file on disk.
@param trackName A unique name for the sound track.
@param tType Track type.
@param is3D Set to true to enable 3D sound.
@return A unique identifier for the track on success, 0 on failure.
*/
size_t addTrack(
const MgFile &audioFile,
const MgStlString &trackName,
MgAudioTrack::TrackType tType,
bool is3D
);

/** Start playing a given track.
@param trackID Identifier of the track to play.
@param looping Continuous play option
@return true if the operation succeeded, false otherwise.
*/
bool playTrack(size_t trackID, bool looping);

/** Start playing a named track.
@param trackName Name of track to play.
@param looping Continuous play option
@return true if the operation succeeded, false otherwise.
*/
bool playTrack(const char *trackName, bool looping);

/** Start playing a named track.
@param trackName Name of track to play.
@param looping Continuous play option
@return true if the operation succeeded, false otherwise.
*/
bool playTrack(const MgStlString &trackName, bool looping);

/** Stop playing a given track.
@param trackName Name of track to stop.
@return true if the operation succeeded, false otherwise.
*/
bool stopTrack(size_t trackID);

/** Stop playing a named track.
@param trackName Name of track to stop.
@return true if the operation succeeded, false otherwise.
*/
bool stopTrack(const char *trackName);

/** Stop playing a named track.
@param trackName Name of track to stop.
@return true if the operation succeeded, false otherwise.
*/
bool stopTrack(const MgStlString &trackName);

/** Retrieve a reference to a given track.
@param trackID Identifier of the desired track.
@return A pointer to the given track or NULL if not found.
*/
MgAudioTrack *findTrack(size_t trackID);

/** Retrieve a reference to a named track.
@param trackID Identifier of the desired track.
@return A reference to the given track.
@return A pointer to the given track or NULL if not found.
*/
MgAudioTrack *findTrack(const char *trackName);

/** Retrieve a reference to a named track.
@param trackID Identifier of the desired track.
@return A reference to the given track.
@return A pointer to the given track or NULL if not found.
*/
MgAudioTrack *findTrack(const MgStlString &trackName);

// ____________________________________________________________________________
// Private methods.

private:

// ............................................................................
// Dis-allowed methods/operators.

/** Copy construction dis-allowed.
@param anInst Instance to copy.
*/
MgAudioManager(const MgAudioManager& anInst);

/** Assignment dis-allowed.
@param anInst Instance to copy.
@return A reference to this instance.
*/
MgAudioManager& operator = (const MgAudioManager& anInst);

// ____________________________________________________________________________
// Private properties.

private:

    /// Collection of audio tracks.
    MgAudioTrackCollection *p_Tracks;

}; // class MgAudioManager

// ____________________________________________________________________________
// Inlined methods.

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Start playing a named track.

inline bool MgAudioManager::
playTrack(const MgStlString &trackName, bool looping)
{
return playTrack(trackName.c_str(),looping);
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Stop playing a named track.

inline bool MgAudioManager::stopTrack(const MgStlString &trackName)
{
return stopTrack(trackName.c_str());
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Retrieve a reference to a named track.

inline MgAudioTrack *MgAudioManager::findTrack(const MgStlString &trackName)
{
return findTrack(trackName.c_str());
}

}; // namespace MAGNASIM

endif // MGAUDIOMANAGER_INCLUDED

// EOF: MgAudioManager.h
[/code:1bsz79w0]
And the audio manager implementation:
[code:1bsz79w0]
// MgAudioManager.cpp

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Description:
//
// Manages sound effects and music functions for NlGViz.
//
// Author: Paul H. Leopard
//
// $Modtime: 7/30/04 9:27a $
//
// $Revision: 7 $
//
//——-0———0———0———0———0———0———0———0

// ==================================================================== Includes

// C++ Standard Library includes

include <map>

// Third Party includes

include "fmod.h"

include "fmod_errors.h"

// MAGNASIM includes

include "MgDiagnosticsStream.h"

include "MgFile.h"

include "MgHashCode.h"

include "MgException.h"

// Other includes

include "MgAudioManager.h"

// ============================================================= End of includes

// Imply namespaces

using namespace MAGNASIM;
using namespace std;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Internal processing utilities

namespace
{
MgDiagnosticsStream dbg;

MgStlString GetFMODErrorDescription()
{
    MgString msg = FMOD_ErrorString(FSOUND_GetError());
    return msg;
}

}; // namespace

namespace MAGNASIM
{
class MgAudioTrackCollection : public map<size_t,MgAudioTrack*>
{
public:
MgAudioTrackCollection () {}
~MgAudioTrackCollection ()
{
}
private:
};

}; // namespace MAGNASIM

ifndef FALSE

define FALSE 0

endif

// END: Internal processing utilities
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Constructor.

MgAudioManager::MgAudioManager()
: p_Tracks(NULL)
{
p_Tracks = new MgAudioTrackCollection();
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Destructor.

MgAudioManager::~MgAudioManager()
{
reset();
MG_SAFE_DELETE(p_Tracks);
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Respond to a frame update request. This updates the 3d sound engine
// and DMA engine (only on some platforms), and should be called once
// a game frame

void MgAudioManager::frameUpdate()
{
FSOUND_Update();
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Retrieve the names for all registered audio tracks.

void MgAudioManager::getTrackNames(vector<MgStlString> &trackNames) const
{
trackNames.clear();
MgAudioTrackCollection::const_iterator it;
for (it=p_Tracks->begin(); it!=p_Tracks->end(); ++it)
{
const MgAudioTrack pTrk = (it).second;
trackNames.push_back(pTrk->trackName());
}
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Retrieve the identifiers for all registered audio tracks.

void MgAudioManager::getTrackIDS(vector<size_t> &trackIDS) const
{
trackIDS.clear();
MgAudioTrackCollection::const_iterator it;
for (it=p_Tracks->begin(); it!=p_Tracks->end(); ++it)
{
const MgAudioTrack pTrk = (it).second;
trackIDS.push_back(pTrk->identifier());
}
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Retrieve a reference to a named track.

MgAudioTrack MgAudioManager::findTrack(size_t trackID)
{
MgAudioTrackCollection::iterator it;
it = p_Tracks->find(trackID);
if (it==p_Tracks->end())
{
MgString tmp("Audio track not found, ID was ");
tmp << trackID;
m_LastErrorDescription = tmp;
return NULL;
}
return (
it).second;
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Retrieve a reference to a named track.

MgAudioTrack *MgAudioManager::findTrack(const char *trackName)
{
MgHashCode hc(trackName);
size_t hCode = hc.code();

MgAudioTrackCollection::iterator it;
it = p_Tracks-&gt;find(hCode);
if (it==p_Tracks-&gt;end())
{
    MgString tmp(&quot;Audio track not found : &quot;,trackName);
    m_LastErrorDescription = tmp;
    return NULL;
}
return (*it).second;

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Start playing a given track..

bool MgAudioManager::playTrack(size_t trackID, bool looping)
{
MgAudioTrackCollection::iterator it;
it = p_Tracks->find(trackID);
if (it==p_Tracks->end())
{
MgString msg("Failed playing audio track with ID ");
msg << trackID << "|Track not found";
m_LastErrorDescription = msg;
return false;
}

bool status = (*it).second-&gt;play(looping);
if (!status)
{
    m_LastErrorDescription = (*it).second-&gt;lastErrorDescription();
    (*it).second-&gt;clearLastError();
    return false;
}

return true;

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Start playing a named track.

bool MgAudioManager::playTrack(const char *trackName, bool looping)
{
MgHashCode hc(trackName);
size_t hCode = hc.code();

MgAudioTrackCollection::iterator it;
it = p_Tracks-&gt;find(hCode);
if (it==p_Tracks-&gt;end())
{
    MgString msg(&quot;Failed playing audio track named &quot;);
    msg &lt;&lt; trackName &lt;&lt; &quot;|Track not found&quot;;
    m_LastErrorDescription = msg;
    return false;
}

bool status = (*it).second-&gt;play(looping);
if (!status)
{
    m_LastErrorDescription = GetFMODErrorDescription();
    return false;
}

return true;

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Stop playing a given track.

bool MgAudioManager::stopTrack(size_t trackID)
{
MgAudioTrackCollection::iterator it;
it = p_Tracks->find(trackID);
if (it==p_Tracks->end())
{
MgString msg("Failed stopping audio track with ID ");
msg << trackID << "|Track not found";
m_LastErrorDescription = msg;
return false;
}

bool status = (*it).second-&gt;stop();
if (!status)
{
    m_LastErrorDescription = GetFMODErrorDescription();
    return false;
}

return true;

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Stop playing a named track.

bool MgAudioManager::stopTrack(const char *trackName)
{
MgHashCode hc(trackName);
size_t hCode = hc.code();

MgAudioTrackCollection::iterator it;
it = p_Tracks-&gt;find(hCode);
if (it==p_Tracks-&gt;end())
{
    MgString msg(&quot;Failed stopping audio track named &quot;);
    msg &lt;&lt; trackName &lt;&lt; &quot;|Track not found&quot;;
    m_LastErrorDescription = msg;
    return false;
}

bool status = (*it).second-&gt;stop();
if (!status)
{
    m_LastErrorDescription = GetFMODErrorDescription();
    return false;
}

return true;

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Stop all playing audio.

bool MgAudioManager::silence()
{
bool ret = true;
MgAudioTrackCollection::iterator it;
for (it=p_Tracks->begin(); it!=p_Tracks->end(); ++it)
{
MgAudioTrack pTrack = (it).second;
if (!pTrack->stop())
{
ret = false;
m_LastErrorDescription = pTrack->lastErrorDescription();
}
}
return ret;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Reset this instance, releasing all audio resources.

bool MgAudioManager::reset()
{
MgAudioTrackCollection::iterator it;
for (it=p_Tracks->begin(); it!=p_Tracks->end(); ++it)
{
MgAudioTrack pTrack = (it).second;
pTrack->stop();
delete pTrack;
}
p_Tracks->clear();
return true;
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Startup/initialization.

bool MgAudioManager::startup()
{
// Check FMOD Version
if (FSOUND_GetVersion() < FMOD_VERSION)
{
MgString msg("Incorrect FMOD DLL Version, Expected ");
msg << FMOD_VERSION << " Found Version " << FSOUND_GetVersion();
m_LastErrorDescription = msg;
return false;
}

// FMOD startup
int mixRate(44100);
int maxSWChannels(32);
unsigned int flags(FSOUND_INIT_GLOBALFOCUS);

// flags = FSOUND_INIT_STREAM_FROM_MAIN_THREAD;

signed char status = FSOUND_Init(mixRate,maxSWChannels,flags);

if (status==FALSE)
{
    MgString msg(&quot;Failed initializing FMOD|&quot;);
    msg &lt;&lt; GetFMODErrorDescription();
    m_LastErrorDescription = msg;
    return false;
}
return true;

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Add a sound track and associate it with a unique track name. Valid filename
// extensions for Stream are WAV, MP2, MP3, OGG and RAW. Valid filename
// extensions for Song are MOD, S3M, XM, IT or MID.

size_t MgAudioManager::
addTrack(
const MgFile &audioFile,
const MgStlString &trackName,
MgAudioTrack::TrackType tType,
bool is3D
)
{
MgAudioTrack *zTrack = findTrack(trackName);
if (zTrack)
{
if (
audioFile.absolutePath() ==
zTrack->audioFile().absolutePath()
)
{
return zTrack->identifier();
}
else
{
MgString msg("Failed adding audio track named ");
msg << trackName << " from file " << audioFile.path()
<< "|Track name is already in use by another file";
m_LastErrorDescription = msg;
return false;
}
}
clearLastError();

if (is3D &amp;&amp; tType!=MgAudioTrack::Sample)
{
    m_LastErrorDescription = &quot;3D Sound supported for Sampled audio only&quot;;
    return false;
}

const char *trName = trackName.c_str();
void *pRes = NULL;

switch(tType)
{
    case MgAudioTrack::Stream:
    {
        unsigned int mode(0);
        int offset(0);
        int length(0);

        FSOUND_STREAM *fs =
            FSOUND_Stream_Open(
            audioFile.absolutePath().c_str(),
            mode,
            offset,
            length
        );

        if (fs==NULL)
        {
            MgString msg(&quot;Failed loading sound stream|Name was&quot;);
            msg &lt;&lt; trackName &lt;&lt; &quot;|File was &quot; &lt;&lt; audioFile.path()
                &lt;&lt; &quot;|&quot; &lt;&lt; GetFMODErrorDescription();
            m_LastErrorDescription = msg;
            return 0;
        }

        pRes = (void*)fs;
    }
    break;

    case MgAudioTrack::Sample:
    {
        int index(FSOUND_FREE);
        unsigned int inputMode(0);
        if (is3D)
        {
            inputMode = FSOUND_HW3D;
        }
        int offset(0);
        int length(0);
        FSOUND_SAMPLE *fs =
            FSOUND_Sample_Load(
                index,
                audioFile.absolutePath().c_str(),
                inputMode,
                offset,
                length
            );

        if (fs==NULL)
        {
            MgString msg(&quot;Failed loading sound sample|Name was&quot;);
            msg &lt;&lt; trackName &lt;&lt; &quot;|File was &quot; &lt;&lt; audioFile.path()
                &lt;&lt; &quot;|&quot; &lt;&lt; GetFMODErrorDescription();
            m_LastErrorDescription = msg;
            return 0;
        }

        pRes = (void*)fs;
    }
    break;

    case MgAudioTrack::Song:
    {
        MgString tmp = audioFile.absolutePath().c_str();
        const char *fPath = tmp.c_str();
        FMUSIC_MODULE *fs =  FMUSIC_LoadSong(fPath);

        if (fs==NULL)
        {
            MgString msg(&quot;Failed loading song|Name was&quot;);
            msg &lt;&lt; trackName &lt;&lt; &quot;|File was &quot; &lt;&lt; audioFile.path()
                &lt;&lt; &quot;|&quot; &lt;&lt; GetFMODErrorDescription();
            m_LastErrorDescription = msg;
            return 0;
        }

        pRes = (void*)fs;
    }
    break;
}

MgAudioTrack *pTr = new MgAudioTrack(audioFile,trName,tType,is3D,pRes);
size_t identifier = pTr-&gt;identifier();

(*p_Tracks)[identifier] = pTr;

return identifier;

}

// EOF: MgAudioManager.cpp
[/code:1bsz79w0]
And the audio track header :
[code:1bsz79w0]
// MgAudioTrack.h

ifndef MGAUDIOTRACK_INCLUDED

define MGAUDIOTRACK_INCLUDED

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Description:
//
// Encapsulates the properties of a single audio track including a hash code
// based upon a specified track name, the audio channel the track is playing
// on (if playing), and a track type (Stream, Sample, Song). Valid audio file
// ypes for Stream are WAV, MP2, MP3, OGG and RAW. Valid audio file types
// for Sample are WAV, MP2, MP3, OGG and RAW. Valid audio file types for
// Song are MOD, S3M, XM, IT or MID.
//
// Author: Paul H. Leopard
//
// $Modtime: 7/02/04 12:33p $
//
// $Revision: 3 $
//
//——-0———0———0———0———0———0———0———0

// ____________________________________________________________________________
// Common definitions needed by all MgAudio header files.

include "MgAudioCommon.h"

// ............................................................................
// This class declaration requires knowledge of other class interfaces and/or
// declarations contained in the following header files:

// C++ Standard Library includes

include <vector>

// MagnaSim includes

include "MgErrorTracking.h"

include "MgFile.h"

// ...........................................................................
// ...........................................................................
// The following class definition resides in the MAGNASIM namespace

namespace MAGNASIM {

// ...........................................................................
// This class declaration utilizes the following classes and/or types but
// does not require knowledge of their interfaces:

// MagnaSim stubs

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/** Encapsulates the properties of a single audio track including a hash code
based upon a specified track name, the audio channel the track is playing
on (if playing), and a track type (Stream, Sample, Song). Valid audio file
types for Stream are WAV, MP2, MP3, OGG and RAW. Valid audio file types
for Sample are WAV, MP2, MP3, OGG and RAW. Valid audio file types for
Song are MOD, S3M, XM, IT or MID.
*/
class MgAudioTrack : public MgErrorTracking
{

// ____________________________________________________________________________
// Public methods.

public:

    /// Enumeration of sound Track type.s
    enum TrackType
    {
        /// Streaming
        Stream,
        /// Sample
        Sample,
        /// Song
        Song,
    };

// ............................................................................
// Static methods

/** Populate a vector with the track types supported by a given audio file
type as indicated by its file extension.
@param fileExtension File extension of the audio file in question.
@param tTypes Receptor vector.
*/
static void GetSupportedTrackTypes(
const char *fileExtension,
std::vector<TrackType> tTypes
);

/** Determine if an audio file type is compatible with a given track type.
@param fileExtension File extension of the audio file in question.
@param tType Track type to be checked.
@return true if the specified audio file type is compatible with the
given track type, false otherwise.
*/
static bool IsExtensionSupported(
const char *fileExtension,
TrackType tType
);

// ............................................................................
// Lifecycle methods

/** Construct given the track properties.
@param audioFile Associated audio file.
@param trackName Name for the track.
@param trackType Track storage/processing type.
@param is3D Set to true to enable 3D sound.
@param pTrackRes Track resource.
*/
MgAudioTrack(
const MgFile &audioFile,
const MgStlString &trackName,
TrackType trackType,
bool is3D,
void *pTrackRes
);

/** Construct given the track properties.
@param audioFile Associated audio file.
@param trackName Name for the track.
@param trackType Track storage/processing type.
@param is3D Set to true to enable 3D sound.
@param pTrackRes Track resource.
*/
MgAudioTrack(
const char *audioFile,
const char *trackName,
TrackType trackType,
bool is3D,
void *pTrackRes
);

/** Destructor.
*/
~MgAudioTrack();

// ............................................................................
// Accessor methods

/** Retrieve the ID of the sound channel this instance is playing
on (0 if not playing).
@return the ID of the sound channel this instance is playing
on (0 if not playing).
*/
int channel() const;

/** Retrieve the track storage and processing type.
@return the track storage and processing type.
*/
TrackType trackType() const;

/** Determine if this instance is 3D enabled.
@return true if this instance is 3D enabled, false otherwise.
*/
bool is3D() const;

/** Determine if this track is playing.
@return true if the track is playing, false if not.
*/
bool isPlaying() const;

/** Retrieve a const reference to the track name associated with this instance.
@return a const reference to the track name associated with this instance.
*/
const MgStlString& trackName() const;

/** Retrieve a const reference to the disk file associated with this instance.
@return a const reference to the disk file associated with this instance.
*/
const MgFile& audioFile() const;

/** Retrieve the identifier representation of this instance’s name.
@return the identifier representation of this instance’s name.
*/
size_t identifier() const;

/** Retrieve a const pointer to the track resource.
@return A const pointer to the track resource.
*/
const void *trackResource() const;

// ............................................................................
// Manipulator methods

/** Start this track playing.
@param looping Continuous play option
@return true if the operation succeeded, false otherwise.
*/
bool play(bool looping);

/** Stop this track if it is playing.
@return true if the operation succeeded, false otherwise.
*/
bool stop();

// ____________________________________________________________________________
// Private methods.

private:

// ............................................................................
// Dis-allowed methods/operators.

/** Copy construction dis-allowed.
@param anInst Instance to copy.
*/
MgAudioTrack(const MgAudioTrack& anInst);

/** Assignment dis-allowed.
@param anInst Instance to copy.
@return A reference to this instance.
*/
MgAudioTrack& operator = (const MgAudioTrack& anInst);

// ____________________________________________________________________________
// Private properties.

private:

    /// Track name associated with this instance.
    MgStlString m_TrackName;

    /// Disk file associated with this instance.
    MgFile m_AudioFile;

    /// Hash code representation of this instance's name.
    size_t m_HashCode;

    /// ID of the sound channel this instance is playing on (0=not playing).
    int m_Channel;

    /// Three dimensional sound enabled indicator.
    bool m_Is3D;

    /// Track storage and processing type
    TrackType m_TrackType;

    /// Track resource
    void *p_TrackResource;

}; // class MgAudioTrack

// ____________________________________________________________________________
// Inlined methods.

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Retrieve a const reference to the track name associated with this instance.

inline const MgStlString& MgAudioTrack::trackName() const
{
return m_TrackName;
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Retrieve a const reference to the disk file associated with this instance.

inline const MgFile& MgAudioTrack::audioFile() const
{
return m_AudioFile;
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Retrieve the ID of the sound channel this instance is playing on
// (0 if not playing).

inline int MgAudioTrack::channel() const
{
return m_Channel;
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Retrieve the identifier representation of this instance’s name.

inline size_t MgAudioTrack::identifier() const
{
return m_HashCode;
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Retrieve the track storage and processing type.

inline MgAudioTrack::TrackType MgAudioTrack::trackType() const
{
return m_TrackType;
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Retrieve a const pointer to the track resource.

inline const void *MgAudioTrack::trackResource() const
{
return p_TrackResource;
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Determine if this instance is 3D enabled.

inline bool MgAudioTrack::is3D() const
{
return m_Is3D;
}

}; // namespace MAGNASIM

endif // MGAUDIOTRACK_INCLUDED

// EOF: MgAudioTrack.h
[/code:1bsz79w0]
And the audio track implementation:
[code:1bsz79w0]
// MgAudioTrack.cpp

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Description:
//
// Encapsulates the properties of a single audio track including a hash code
// based upon a specified track name, the audio channel the track is playing
// on (if playing), and a track type (Stream, Sample, Song). Valid audio file
// ypes for Stream are WAV, MP2, MP3, OGG and RAW. Valid audio file types
// for Sample are WAV, MP2, MP3, OGG and RAW. Valid audio file types for
// Song are MOD, S3M, XM, IT or MID.
//
// Author: Paul H. Leopard
//
// $Modtime: 7/05/04 12:00p $
//
// $Revision: 5 $
//
//——-0———0———0———0———0———0———0———0

// ==================================================================== Includes

// C++ Standard Library includes

// Third Party includes

include "fmod.h"

include "fmod_errors.h"

// MAGNASIM includes

include "MgAudioTrack.h"

include "MgString.h"

include "MgHashCode.h"

include "MgDiagnosticsStream.h"

// ============================================================= End of includes

// Imply namespaces

using namespace MAGNASIM;
using namespace std;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Internal processing utilities

namespace
{
MgDiagnosticsStream dbg;

MgStlString GetFMODErrorDescription()
{
    MgString msg = FMOD_ErrorString(FSOUND_GetError());
    return msg;
}

}; // namespace

ifndef FALSE

define FALSE 0

endif

ifndef TRUE

define TRUE 1

endif

// END: Internal processing utilities
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Populate a vector with the track types supported by a given audio file
// type as indicated by its file extension.

void MgAudioTrack::
GetSupportedTrackTypes(
const char *fileExtension,
vector<TrackType> tTypes
)
{
tTypes.clear();
MgString ext(fileExtension);
ext.toLowerCase();
if (
ext == "wav" ||
ext == "mp2" ||
ext == "mp3" ||
ext == "ogg" ||
ext == "raw"
)
{
tTypes.push_back(Stream);
tTypes.push_back(Sample);
}
if (
ext == "mod" ||
ext == "s3m" ||
ext == "xm" ||
ext == "it" ||
ext == "mid"
)
{
tTypes.push_back(Song);
}
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Determine if an audio file type is compatible with a given track type.

bool MgAudioTrack::
IsExtensionSupported(
const char *fileExtension,
TrackType tType
)
{
MgString ext(fileExtension);
ext.toLowerCase();
switch(tType)
{
case Stream:
if (
ext == "wav" ||
ext == "mp2" ||
ext == "mp3" ||
ext == "ogg" ||
ext == "raw"
)
{
return true;
}
return false;
break;
case Sample:
if (
ext == "wav" ||
ext == "mp2" ||
ext == "mp3" ||
ext == "ogg" ||
ext == "raw"
)
{
return true;
}
return false;
break;
case Song:
if (
ext == "mod" ||
ext == "s3m" ||
ext == "xm" ||
ext == "it" ||
ext == "mid"
)
{
return true;
}
return false;
break;
}
return false;
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Construct given the track properties.

MgAudioTrack::
MgAudioTrack(
const MgFile &audioFile,
const MgStlString &trackName,
TrackType trackType,
bool is3D,
void *pTrackRes
)
: m_TrackName(trackName),
m_HashCode(0),
m_TrackType(trackType),
m_Channel(0),
p_TrackResource(pTrackRes),
m_AudioFile(audioFile),
m_Is3D(is3D)
{
m_HashCode = MgHashCode(trackName).code();
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Construct given the track properties.

MgAudioTrack::
MgAudioTrack(
const char *audioFile,
const char *trackName,
TrackType trackType,
bool is3D,
void *pTrackRes
)
: m_TrackName(trackName),
m_HashCode(0),
m_TrackType(trackType),
m_Channel(0),
p_TrackResource(pTrackRes),
m_AudioFile(audioFile),
m_Is3D(is3D)
{
m_HashCode = MgHashCode(trackName).code();
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Destructor.

MgAudioTrack::~MgAudioTrack()
{
switch(m_TrackType)
{
case Stream:
{
FSOUND_STREAM fs = (FSOUND_STREAM)p_TrackResource;
signed char status = FSOUND_Stream_Close(fs);
if (status==FALSE)
{
dbg << GetFMODErrorDescription() << endl;
}
}
break;

    case Sample:
    {
        FSOUND_SAMPLE *fs = (FSOUND_SAMPLE*)p_TrackResource;
        FSOUND_Sample_Free(fs);
    }
    break;

    case Song:
    {
        FMUSIC_MODULE *fs = (FMUSIC_MODULE*)p_TrackResource;
        signed char status = FMUSIC_FreeSong(fs);
        if (status==FALSE)
        {
            dbg &lt;&lt; GetFMODErrorDescription() &lt;&lt; endl;
        }
    }
    break;
}

}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Determine if this track is playing.

bool MgAudioTrack::isPlaying() const
{
switch(m_TrackType)
{
case Stream:
{
// FSOUND_STREAM fs = (FSOUND_STREAM)p_TrackResource;
signed char status = FSOUND_IsPlaying(m_Channel);
return (status==TRUE)?true:false;
}
break;

    case Sample:
    {

// FSOUND_SAMPLE fs = (FSOUND_SAMPLE)p_TrackResource;
signed char status = FSOUND_IsPlaying(m_Channel);
return (status==TRUE)?true:false;
}
break;

    case Song:
    {
        FMUSIC_MODULE *fs = (FMUSIC_MODULE*)p_TrackResource;
        signed char status = FMUSIC_IsPlaying(fs);
        return (status==TRUE)?true:false;
    }
    break;
}
return false;

}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Start this track playing.

bool MgAudioTrack::play(bool looping)
{
switch(m_TrackType)
{
case Stream:
{
FSOUND_STREAM fs = (FSOUND_STREAM)p_TrackResource;
int status = FSOUND_Stream_Play(0,fs);
if (status==-1)
{
m_LastErrorDescription = GetFMODErrorDescription();
return false;
}

        if (looping)
        {
            status = FSOUND_Stream_SetMode(fs,FSOUND_LOOP_NORMAL);
            if (status==FALSE)
            {
                m_LastErrorDescription = GetFMODErrorDescription();
                return false;
            }
            return true;
        }

        status = FSOUND_Stream_SetMode(fs,FSOUND_LOOP_OFF);
        if (status==FALSE)
        {
            m_LastErrorDescription = GetFMODErrorDescription();
            return false;
        }
        return true;
    }
    break;

    case Sample:
    {
        FSOUND_SAMPLE *fs = (FSOUND_SAMPLE*)p_TrackResource;
        int chan = FSOUND_PlaySound(FSOUND_FREE,fs);
        if (chan==-1)
        {
            m_LastErrorDescription = GetFMODErrorDescription();
            return false;
        }
        if (looping)
        {
            FSOUND_SetLoopMode(chan,FSOUND_LOOP_NORMAL);
        }
        else
        {
            FSOUND_SetLoopMode(chan,FSOUND_LOOP_OFF);
        }
        m_Channel = chan;
        return true;
    }
    break;

    case Song:
    {
        FMUSIC_MODULE *fs = (FMUSIC_MODULE*)p_TrackResource;
        signed char status(0);
        if (looping)
        {
            status = FMUSIC_SetLooping(fs,TRUE);
        }
        else
        {
            status = FMUSIC_SetLooping(fs,FALSE);
        }
        if (status==FALSE)
        {
            m_LastErrorDescription = GetFMODErrorDescription();
            return false;
        }

        status = FMUSIC_PlaySong(fs);
        if (status==FALSE)
        {
            m_LastErrorDescription = GetFMODErrorDescription();
            return false;
        }
        return true;
    }
    break;
}
m_LastErrorDescription = &quot;Something impossible happened&quot;;
return false;

}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Stop this track if it is playing.

bool MgAudioTrack::stop()
{
switch(m_TrackType)
{
case Stream:
{
FSOUND_STREAM fs = (FSOUND_STREAM)p_TrackResource;
signed char status = FSOUND_Stream_Stop(fs);
if (status==FALSE)
{
m_LastErrorDescription = GetFMODErrorDescription();
return false;
}
return true;
}
break;

    case Sample:
    {
        FSOUND_SAMPLE *fs = (FSOUND_SAMPLE*)p_TrackResource;
        signed char status = FSOUND_StopSound(m_Channel);
        if (status==FALSE)
        {
            m_LastErrorDescription = GetFMODErrorDescription();
            return false;
        }
        m_Channel = 0;
        return true;
    }
    break;

    case Song:
    {
        FMUSIC_MODULE *fs = (FMUSIC_MODULE*)p_TrackResource;
        signed char status = FMUSIC_StopSong(fs);
        if (status==FALSE)
        {
            m_LastErrorDescription = GetFMODErrorDescription();
            return false;
        }
        return true;
    }
    break;
}
return true;

}

// EOF: MgAudioTrack.cpp
[/code:1bsz79w0]

  • You must to post comments
0
0

I downloaded the latest SDK this morning and tried it so I have the latest .so

Note that the same audio manager classes work fine for non-performance critical apps but they don’t work for the high FPS apps where performance is being stressed.

No. No other audio apps were being run.

  • You must to post comments
0
0

The game loop is running full tilt … the entire application is written to run at as high of an FPS as possible … as is the modern game program paradigm. There are no other threads in the program other than the game loop.

  • You must to post comments
Showing 4 results
Your Answer

Please first to submit.