new updates from CMU

This commit is contained in:
David Rose 2004-08-06 00:10:20 +00:00
parent d26d443f9d
commit b4eb31344f
25 changed files with 826 additions and 65 deletions

View File

@ -41,7 +41,10 @@ def squeezePandaFiles():
l = getSqueezeableFiles() l = getSqueezeableFiles()
pandaSqueezeTool.squeeze("PandaModules", "PandaModulesUnsqueezed", l) pandaSqueezeTool.squeeze("PandaModules", "PandaModulesUnsqueezed", l)
# Clean up the source files now that they've been squeezed. # Clean up the source files now that they've been squeezed. If
# you don't like this behavior (e.g. if you want to inspect the
# generated files), use genPyCode -n to avoid squeezing
# altogether.
for i in l: for i in l:
os.unlink(i) os.unlink(i)

View File

@ -312,6 +312,12 @@
#define VRPN_LIBS #define VRPN_LIBS
#defer HAVE_VRPN $[libtest $[VRPN_LPATH],$[VRPN_LIBS]] #defer HAVE_VRPN $[libtest $[VRPN_LPATH],$[VRPN_LIBS]]
// Is HELIX installed, and where?
#define HELIX_IPATH
#define HELIX_LPATH
#define HELIX_LIBS
#defer HAVE_HELIX $[libtest $[HELIX_LPATH],$[HELIX_LIBS]]
// Is ZLIB installed, and where? // Is ZLIB installed, and where?
#define ZLIB_IPATH #define ZLIB_IPATH
#define ZLIB_LPATH #define ZLIB_LPATH

View File

@ -123,6 +123,9 @@ $[cdefine HAVE_NURBSPP]
/* Define if we have VRPN installed. */ /* Define if we have VRPN installed. */
$[cdefine HAVE_VRPN] $[cdefine HAVE_VRPN]
/* Define if we have HELIX installed. */
$[cdefine HAVE_HELIX]
/* Define if we have CG installed. */ /* Define if we have CG installed. */
$[cdefine HAVE_CG] $[cdefine HAVE_CG]

View File

@ -146,6 +146,11 @@
#set VRPN_LIBS $[VRPN_LIBS] #set VRPN_LIBS $[VRPN_LIBS]
#set HAVE_VRPN $[HAVE_VRPN] #set HAVE_VRPN $[HAVE_VRPN]
#set HELIX_IPATH $[unixfilename $[HELIX_IPATH]]
#set HELIX_LPATH $[unixfilename $[HELIX_LPATH]]
#set HELIX_LIBS $[HELIX_LIBS]
#set HAVE_HELIX $[HAVE_HELIX]
#set ZLIB_IPATH $[unixfilename $[ZLIB_IPATH]] #set ZLIB_IPATH $[unixfilename $[ZLIB_IPATH]]
#set ZLIB_LPATH $[unixfilename $[ZLIB_LPATH]] #set ZLIB_LPATH $[unixfilename $[ZLIB_LPATH]]
#set ZLIB_LIBS $[ZLIB_LIBS] #set ZLIB_LIBS $[ZLIB_LIBS]

View File

@ -216,6 +216,13 @@
#define vrpn_libs $[VRPN_LIBS] #define vrpn_libs $[VRPN_LIBS]
#endif #endif
#if $[HAVE_HELIX]
#define helix_ipath $[wildcard $[HELIX_IPATH]]
#define helix_lpath $[wildcard $[HELIX_LPATH]]
#define helix_cflags $[HELIX_CFLAGS]
#define helix_libs $[HELIX_LIBS]
#endif
#if $[HAVE_MIKMOD] #if $[HAVE_MIKMOD]
#define mikmod_ipath $[wildcard $[MIKMOD_IPATH]] #define mikmod_ipath $[wildcard $[MIKMOD_IPATH]]
#define mikmod_lpath $[wildcard $[MIKMOD_LPATH]] #define mikmod_lpath $[wildcard $[MIKMOD_LPATH]]

View File

@ -2,6 +2,8 @@
algorithm deque ft2build.h iostream list map memory \ algorithm deque ft2build.h iostream list map memory \
pair queue set stack stdcompare.h stdtypedefs.h \ pair queue set stack stdcompare.h stdtypedefs.h \
string vector windows.h zlib.h md5.h files.h hex.h \ string vector windows.h zlib.h md5.h files.h hex.h \
nurbs.hh stddef.h krb5.h Python.h \ nurbs.hh stddef.h krb5.h MainHelix.h dllpath.h hxcom.h \
Cg/cg.h Cg/cgGL.h hxcomm.h hxcore.h hxengin.h hxerror.h hxfiles.h hxtbuf.h \
hxtbuff.h hxwin.h Python.h Cg/cg.h Cg/cgGL.h

View File

@ -17,7 +17,7 @@
parametrics pnm \ parametrics pnm \
pnmimagetypes pnmimage sgattrib sgmanip sgraph sgraphutil \ pnmimagetypes pnmimage sgattrib sgmanip sgraph sgraphutil \
switchnode pnmtext text tform tiff lerp loader putil \ switchnode pnmtext text tform tiff lerp loader putil \
audio pgui pandabase audio pgui pandabase helix
#define LOCAL_LIBS \ #define LOCAL_LIBS \
downloader express pandabase downloader express pandabase

View File

@ -49,7 +49,7 @@ PUBLISHED:
virtual bool is_valid() = 0; virtual bool is_valid() = 0;
// Get a sound: // Get a sound:
virtual PT(AudioSound) get_sound(const string& file_name) = 0; virtual PT(AudioSound) get_sound(const string& file_name, bool positional = false) = 0;
PT(AudioSound) get_null_sound(); PT(AudioSound) get_null_sound();
// Tell the AudioManager there is no need to keep this one cached. // Tell the AudioManager there is no need to keep this one cached.
@ -105,6 +105,45 @@ PUBLISHED:
// this call may be for efficient on some implementations. // this call may be for efficient on some implementations.
virtual void stop_all_sounds() = 0; virtual void stop_all_sounds() = 0;
// Changes to the positions of 3D spacialized sounds and the listener
// are all made at once when this method is called. It should be put
// in the main program loop.
virtual void audio_3d_update() = 0;
// This controls the "set of ears" that listens to 3D spacialized sound
// px, py, pz are position coordinates. Can be NULL to ignore.
// vx, vy, vz are a velocity vector in UNITS PER SECOND (default: meters). Can be NULL to ignore.
// fx, fy and fz are the respective components of a unit forward-vector
// ux, uy and uz are the respective components of a unit up-vector
// These changes will NOT be invoked until audio_3d_update() is called.
virtual void audio_3d_set_listener_attributes(float px, float py, float pz,
float vx, float vy, float vz,
float fx, float fy, float fz,
float ux, float uy, float uz) = 0;
// Values should all default to NULL, so you can just pass the one you want to get.
virtual void audio_3d_get_listener_attributes(float px = NULL, float py = NULL, float pz = NULL,
float vx = NULL, float vy = NULL, float vz = NULL,
float fx = NULL, float fy = NULL, float fz = NULL,
float ux = NULL, float uy = NULL, float uz = NULL) = 0;
// Control the "relative distance factor" for 3D spacialized audio. Default is 1.0
// Fmod uses meters internally, so give a float in Units-per meter
// Don't know what Miles uses.
virtual void audio_3d_set_distance_factor(float factor) = 0;
virtual float audio_3d_get_distance_factor() const = 0;
// Control the presence of the Doppler effect. Default is 1.0
// Exaggerated Doppler, use >1.0
// Diminshed Doppler, use <1.0
virtual void audio_3d_set_doppler_factor(float factor) = 0;
virtual float audio_3d_get_doppler_factor() const = 0;
// Exaggerate or diminish the effect of distance on sound. Default is 1.0
// Faster drop off, use >1.0
// Slower drop off, use <1.0
virtual void audio_3d_set_drop_off_factor(float factor) = 0;
virtual float audio_3d_get_drop_off_factor() const = 0;
public: public:
static void register_AudioManager_creator(Create_AudioManager_proc* proc); static void register_AudioManager_creator(Create_AudioManager_proc* proc);

View File

@ -95,6 +95,16 @@ PUBLISHED:
// return: playing time in seconds. // return: playing time in seconds.
virtual float length() const = 0; virtual float length() const = 0;
// Controls the position of this sound's emitter.
// px, py and pz are the emitter's position.
// vx, vy and vz are the emitter's velocity in UNITS PER SECOND (default: meters).
// You can pass NULL to either value for either function to ignore that value
// if you only want to set/get one of them for some reason.
virtual void set_3d_attributes(float px = NULL, float py = NULL, float pz = NULL,
float vx = NULL, float vy = NULL, float vz = NULL) = 0;
virtual void get_3d_attributes(float px = NULL, float py = NULL, float pz = NULL,
float vx = NULL, float vy = NULL, float vz = NULL) = 0;
enum SoundStatus { BAD, READY, PLAYING }; enum SoundStatus { BAD, READY, PLAYING };
virtual SoundStatus status() const = 0; virtual SoundStatus status() const = 0;

View File

@ -35,6 +35,20 @@ int audio_cache_limit
float audio_volume float audio_volume
=config_audio.GetFloat("audio-volume", 1.0f); =config_audio.GetFloat("audio-volume", 1.0f);
float audio_doppler_factor
=config_audio.GetFloat("audio-doppler-factor", 1.0f);
float audio_distance_factor
=config_audio.GetFloat("audio-distance-factor", 1.0f);
float audio_drop_off_factor
=config_audio.GetFloat("audio-drop-off-factor", 1.0f);
// Guarantee this many channels on local sound card, or just
// play EVERYTHING in software.
int audio_min_hw_channels
=config_audio.GetInt("audio-min-hw-channels", 15);
bool audio_software_midi bool audio_software_midi
=config_audio.GetBool("audio-software-midi", false); =config_audio.GetBool("audio-software-midi", false);

View File

@ -32,6 +32,12 @@ extern EXPCL_PANDA bool audio_active;
extern EXPCL_PANDA int audio_cache_limit; extern EXPCL_PANDA int audio_cache_limit;
extern EXPCL_PANDA float audio_volume; extern EXPCL_PANDA float audio_volume;
extern EXPCL_PANDA float audio_doppler_factor;
extern EXPCL_PANDA float audio_distance_factor;
extern EXPCL_PANDA float audio_drop_off_factor;
extern EXPCL_PANDA int audio_min_hw_channels;
extern EXPCL_PANDA bool audio_software_midi; extern EXPCL_PANDA bool audio_software_midi;
extern EXPCL_PANDA string* audio_dls_file; extern EXPCL_PANDA string* audio_dls_file;

View File

@ -19,6 +19,10 @@
#include "nullAudioManager.h" #include "nullAudioManager.h"
//namespace {
//static const string blank="";
//static float no_listener_attributes [] = {0.0f,0.0f,0.0f, 0.0f,0.0f,0.0f, 0.0f,0.0f,0.0f, 0.0f,0.0f,0.0f};
//}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: NullAudioManager::NullAudioManager // Function: NullAudioManager::NullAudioManager
@ -56,7 +60,7 @@ is_valid() {
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
PT(AudioSound) NullAudioManager:: PT(AudioSound) NullAudioManager::
get_sound(const string&) { get_sound(const string&, bool positional) {
return get_null_sound(); return get_null_sound();
} }
@ -180,3 +184,96 @@ void NullAudioManager::
stop_all_sounds() { stop_all_sounds() {
// intentionally blank. // intentionally blank.
} }
////////////////////////////////////////////////////////////////////
// Function: NullAudioManager::audio_3d_update
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void NullAudioManager::
audio_3d_update() {
// intentionally blank.
}
////////////////////////////////////////////////////////////////////
// Function: NullAudioManager::audio_3d_set_listener_attributes
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void NullAudioManager::
audio_3d_set_listener_attributes(float px, float py, float pz, float vx, float vy, float vz, float fx, float fy, float fz, float ux, float uy, float uz) {
// intentionally blank.
}
////////////////////////////////////////////////////////////////////
// Function: NullAudioManager::audio_3d_get_listener_attributes
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void NullAudioManager::
audio_3d_get_listener_attributes(float px, float py, float pz, float vx, float vy, float vz, float fx, float fy, float fz, float ux, float uy, float uz) {
// intentionally blank.
}
////////////////////////////////////////////////////////////////////
// Function: NullAudioManager::audio_3d_set_distance_factor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void NullAudioManager::
audio_3d_set_distance_factor(float factor) {
// intentionally blank.
}
////////////////////////////////////////////////////////////////////
// Function: NullAudioManager::audio_3d_get_distance_factor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
float NullAudioManager::
audio_3d_get_distance_factor() const {
// intentionally blank.
return 0.0f;
}
////////////////////////////////////////////////////////////////////
// Function: NullAudioManager::audio_3d_set_doppler_factor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void NullAudioManager::
audio_3d_set_doppler_factor(float factor) {
// intentionally blank.
}
////////////////////////////////////////////////////////////////////
// Function: NullAudioManager::audio_3d_get_doppler_factor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
float NullAudioManager::
audio_3d_get_doppler_factor() const {
// intentionally blank.
return 0.0f;
}
////////////////////////////////////////////////////////////////////
// Function: NullAudioManager::audio_3d_set_drop_off_factor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void NullAudioManager::
audio_3d_set_drop_off_factor(float factor) {
// intentionally blank.
}
////////////////////////////////////////////////////////////////////
// Function: NullAudioManager::audio_3d_get_drop_off_factor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
float NullAudioManager::
audio_3d_get_drop_off_factor() const {
// intentionally blank.
return 0.0f;
}

View File

@ -34,7 +34,7 @@ public:
virtual bool is_valid(); virtual bool is_valid();
virtual PT(AudioSound) get_sound(const string&); virtual PT(AudioSound) get_sound(const string&, bool positional = false);
virtual void uncache_sound(const string&); virtual void uncache_sound(const string&);
virtual void clear_cache(); virtual void clear_cache();
virtual void set_cache_limit(unsigned int); virtual void set_cache_limit(unsigned int);
@ -52,6 +52,26 @@ public:
virtual void reduce_sounds_playing_to(unsigned int count); virtual void reduce_sounds_playing_to(unsigned int count);
virtual void stop_all_sounds(); virtual void stop_all_sounds();
virtual void audio_3d_update();
virtual void audio_3d_set_listener_attributes(float px, float py, float pz,
float vx, float vy, float vz,
float fx, float fy, float fz,
float ux, float uy, float uz);
virtual void audio_3d_get_listener_attributes(float px = NULL, float py = NULL, float pz = NULL,
float vx = NULL, float vy = NULL, float vz = NULL,
float fx = NULL, float fy = NULL, float fz = NULL,
float ux = NULL, float uy = NULL, float uz = NULL);
virtual void audio_3d_set_distance_factor(float factor);
virtual float audio_3d_get_distance_factor() const;
virtual void audio_3d_set_doppler_factor(float factor);
virtual float audio_3d_get_doppler_factor() const;
virtual void audio_3d_set_drop_off_factor(float factor);
virtual float audio_3d_get_drop_off_factor() const;
}; };
#endif /* __NULL_AUDIO_MANAGER_H__ */ #endif /* __NULL_AUDIO_MANAGER_H__ */

View File

@ -22,6 +22,7 @@
namespace { namespace {
static const string blank=""; static const string blank="";
static float no_attributes [] = {0.0f,0.0f,0.0f, 0.0f,0.0f,0.0f};
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -109,6 +110,14 @@ float NullAudioSound::length() const {
return 0; return 0;
} }
void NullAudioSound::set_3d_attributes(float px, float py, float pz, float vx, float vy, float vz) {
// Intentionally blank.
}
void NullAudioSound::get_3d_attributes(float px, float py, float pz, float vx, float vy, float vz) {
// Intentionally blank.
}
AudioSound::SoundStatus NullAudioSound::status() const { AudioSound::SoundStatus NullAudioSound::status() const {
return AudioSound::READY; return AudioSound::READY;
} }

View File

@ -62,6 +62,9 @@ public:
float length() const; float length() const;
void set_3d_attributes(float px, float py, float pz, float vx, float vy, float vz);
void get_3d_attributes(float px, float py, float pz, float vx, float vy, float vz);
AudioSound::SoundStatus status() const; AudioSound::SoundStatus status() const;
// why protect the constructor?!? // why protect the constructor?!?

View File

@ -26,7 +26,7 @@
#define BUILD_TARGET $[HAVE_FMOD] #define BUILD_TARGET $[HAVE_FMOD]
#define USE_PACKAGES fmod #define USE_PACKAGES fmod
#define BUILDING_DLL BUILDING_FMOD_AUDIO #define BUILDING_DLL BUILDING_FMOD_AUDIO
#define LOCAL_LIBS audio #define LOCAL_LIBS audio event
#define WIN_SYS_LIBS $[WIN_SYS_LIBS] user32.lib advapi32.lib winmm.lib #define WIN_SYS_LIBS $[WIN_SYS_LIBS] user32.lib advapi32.lib winmm.lib
#define COMBINED_SOURCES $[TARGET]_composite1.cxx #define COMBINED_SOURCES $[TARGET]_composite1.cxx

View File

@ -20,12 +20,6 @@
#ifdef HAVE_FMOD //[ #ifdef HAVE_FMOD //[
// Please remove this as part of updating fmod:
#error The fmod audio needs repair by the fmod implementers
#include "config_fmodAudio.h" #include "config_fmodAudio.h"
#include "fmodAudioManager.h" #include "fmodAudioManager.h"
#include "fmodAudioSound.h" #include "fmodAudioSound.h"

View File

@ -51,8 +51,18 @@ FmodAudioManager() {
audio_debug("FmodAudioManager::FmodAudioManager()"); audio_debug("FmodAudioManager::FmodAudioManager()");
audio_debug(" audio_active="<<audio_active); audio_debug(" audio_active="<<audio_active);
audio_debug(" audio_volume="<<audio_volume); audio_debug(" audio_volume="<<audio_volume);
_active = audio_active; _active = audio_active;
_volume = audio_volume;
//positional audio data
_listener_pos[0] = 0.0f; _listener_pos[1] = 0.0f; _listener_pos[2] = 0.0f;
_listener_vel[0] = 0.0f; _listener_vel[1] = 0.0f; _listener_vel[2] = 0.0f;
_listener_forward[0] = 0.0f; _listener_forward[1] = 1.0f; _listener_forward[2] = 0.0f;
_listener_up[0] = 0.0f; _listener_up[1] = 0.0f; _listener_up[2] = 1.0f;
_distance_factor = audio_distance_factor;
_doppler_factor = audio_doppler_factor;
_drop_off_factor = audio_drop_off_factor;
_cache_limit = audio_cache_limit; _cache_limit = audio_cache_limit;
_concurrent_sound_limit = 0; _concurrent_sound_limit = 0;
@ -69,7 +79,12 @@ FmodAudioManager() {
break; break;
} }
if (FSOUND_Init(44100, 32, 0) == 0) { // If the local system doesn't have enough hardware channels,
// Don't even bother trying to use hardware effects. Play EVERYTHING in software.
audio_debug("Setting minimum hardware channels(min="<<audio_min_hw_channels<<")");
FSOUND_SetMinHardwareChannels(audio_min_hw_channels);
if (FSOUND_Init(audio_output_rate, audio_cache_limit, 0) == 0) {
audio_error("Fmod initialization failure."); audio_error("Fmod initialization failure.");
_is_valid = false; _is_valid = false;
break; break;
@ -78,6 +93,10 @@ FmodAudioManager() {
while(0); // curious -- why is there a non-loop here? while(0); // curious -- why is there a non-loop here?
} }
// set 3D sound characteristics as they are given in the configrc
audio_3d_set_doppler_factor(audio_doppler_factor);
audio_3d_set_distance_factor(audio_distance_factor);
audio_3d_set_drop_off_factor(audio_drop_off_factor);
// increment regardless of whether an error has occured -- the // increment regardless of whether an error has occured -- the
// destructor will do the right thing. // destructor will do the right thing.
++_active_managers; ++_active_managers;
@ -137,7 +156,7 @@ is_valid() {
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
PT(AudioSound) FmodAudioManager:: PT(AudioSound) FmodAudioManager::
get_sound(const string &file_name) { get_sound(const string &file_name, bool positional) {
audio_debug("FmodAudioManager::get_sound(file_name=\""<<file_name<<"\")"); audio_debug("FmodAudioManager::get_sound(file_name=\""<<file_name<<"\")");
if(!is_valid()) { if(!is_valid()) {
@ -200,6 +219,21 @@ get_sound(const string &file_name) {
// FMOD v4.0! // FMOD v4.0!
FSOUND_STREAM *stream = NULL; FSOUND_STREAM *stream = NULL;
int flags = FSOUND_LOADMEMORY | FSOUND_MPEGACCURATE; int flags = FSOUND_LOADMEMORY | FSOUND_MPEGACCURATE;
// 3D sounds have to be mono. Forcing stereo streams
// to be mono will create a speed hit.
if (positional) {
flags |= FSOUND_HW3D | FSOUND_FORCEMONO;
} else {
flags |= FSOUND_2D;
}
if (audio_output_bits == 8) {
flags |= FSOUND_8BITS;
} else if (audio_output_bits == 16) {
flags |= FSOUND_16BITS;
}
if (audio_output_channels == 1) {
flags |= FSOUND_FORCEMONO;
}
string os_path = path.to_os_specific(); string os_path = path.to_os_specific();
string suffix = downcase(path.get_extension()); string suffix = downcase(path.get_extension());
@ -223,12 +257,16 @@ get_sound(const string &file_name) {
PT(AudioSound) audioSound = 0; PT(AudioSound) audioSound = 0;
PT(FmodAudioSound) fmodAudioSound = new FmodAudioSound(this, stream, path, PT(FmodAudioSound) fmodAudioSound = new FmodAudioSound(this, stream, path,
length); length);
audio_debug("BOO!");
fmodAudioSound->set_active(_active); fmodAudioSound->set_active(_active);
audio_debug("GAH!");
_soundsOnLoan.insert(fmodAudioSound); _soundsOnLoan.insert(fmodAudioSound);
audio_debug("GIR!");
audioSound = fmodAudioSound; audioSound = fmodAudioSound;
audio_debug(" returning 0x" << (void*)audioSound); audio_debug(" returning 0x" << (void*)audioSound);
assert(is_valid()); assert(is_valid());
audio_debug("GOO!");
return audioSound; return audioSound;
} }
@ -379,8 +417,8 @@ set_cache_limit(unsigned int count) {
// Access: Public // Access: Public
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
int FmodAudioManager:: unsigned int FmodAudioManager::
get_cache_limit() { get_cache_limit() const {
audio_debug("FmodAudioManager::get_cache_limit() returning " audio_debug("FmodAudioManager::get_cache_limit() returning "
<<_cache_limit); <<_cache_limit);
return _cache_limit; return _cache_limit;
@ -405,8 +443,16 @@ release_sound(FmodAudioSound* audioSound) {
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void FmodAudioManager:: void FmodAudioManager::
set_volume(float) { set_volume(float volume) {
// intentionally blank. audio_debug("FmodAudioManager::set_volume(volume="<<volume<<")");
if (_volume!=volume) {
_volume = volume;
// Tell our AudioSounds to adjust:
AudioSet::iterator i=_soundsOnLoan.begin();
for (; i!=_soundsOnLoan.end(); ++i) {
(**i).set_volume((**i).get_volume());
}
}
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -415,14 +461,15 @@ set_volume(float) {
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
float FmodAudioManager:: float FmodAudioManager::
get_volume() { get_volume() const {
return 0; audio_debug("FmodAudioManager::get_volume() returning "<<_volume);
return _volume;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: FmodAudioManager::set_active // Function: FmodAudioManager::set_active
// Access: Public // Access: Public
// Description: // Description: turn on/off
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void FmodAudioManager:: void FmodAudioManager::
set_active(bool active) { set_active(bool active) {
@ -444,7 +491,8 @@ set_active(bool active) {
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool FmodAudioManager:: bool FmodAudioManager::
get_active() { get_active() const {
audio_debug("FmodAudioManager::get_active() returning "<<_active);
return _active; return _active;
} }
@ -476,15 +524,28 @@ get_concurrent_sound_limit() const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void FmodAudioManager:: void FmodAudioManager::
reduce_sounds_playing_to(unsigned int count) { reduce_sounds_playing_to(unsigned int count) {
// This is an example from Miles audio, this should be done for fmod: int limit = _sounds_playing.size() - count;
//int limit = _sounds_playing.size() - count; while (limit-- > 0) {
//while (limit-- > 0) { SoundsPlaying::iterator sound = _sounds_playing.begin();
// SoundsPlaying::iterator sound = _sounds_playing.begin(); assert(sound != _sounds_playing.end());
// assert(sound != _sounds_playing.end()); (**sound).stop();
// (**sound).stop(); }
//}
} }
////////////////////////////////////////////////////////////////////
// Function: FmodAudioManager::stop_a_sound
// Access: Public
// Description: Stop playback on one sound managed by this manager.
////////////////////////////////////////////////////////////////////
//void FmodAudioManager::
//stop_a_sound() {
// audio_debug("FmodAudioManager::stop_a_sound()");
// AudioSet::size_type s=_soundsOnLoan.size() - 1;
// reduce_sounds_playing_to(s);
//if (s == _soundsOnLoan.size()) return true;
//return false;
//}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: FmodAudioManager::stop_all_sounds // Function: FmodAudioManager::stop_all_sounds
// Access: Public // Access: Public
@ -493,14 +554,174 @@ reduce_sounds_playing_to(unsigned int count) {
void FmodAudioManager:: void FmodAudioManager::
stop_all_sounds() { stop_all_sounds() {
audio_debug("FmodAudioManager::stop_all_sounds()"); audio_debug("FmodAudioManager::stop_all_sounds()");
AudioSet::iterator i=_soundsOnLoan.begin(); reduce_sounds_playing_to(0);
for (; i!=_soundsOnLoan.end(); ++i) { //AudioSet::iterator i=_soundsOnLoan.begin();
if ((**i).status()==AudioSound::PLAYING) { //for (; i!=_soundsOnLoan.end(); ++i) {
(**i).stop(); // if ((**i).status()==AudioSound::PLAYING) {
// (**i).stop();
// }
//}
}
////////////////////////////////////////////////////////////////////
// Function: FmodAudioManager::audio_3d_update
// Access: Public
// Description: Commit position changes to listener and all
// positioned sounds. Normally, you'd want to call this
// once per iteration of your main loop.
////////////////////////////////////////////////////////////////////
void FmodAudioManager::
audio_3d_update() {
audio_debug("FmodAudioManager::audio_3d_update()");
//convert panda coordinates to fmod coordinates
float fmod_pos [] = {_listener_pos[0], _listener_pos[2], _listener_pos[1]};
float fmod_vel [] = {_listener_vel[0], _listener_vel[2], _listener_vel[1]};
float fmod_forward [] = {_listener_forward[0], _listener_forward[2], _listener_forward[1]};
float fmod_up [] = {_listener_up[0], _listener_up[2], _listener_up[1]};
FSOUND_3D_Listener_SetAttributes(fmod_pos, fmod_vel,
fmod_forward[0], fmod_forward[1], fmod_forward[2],
fmod_up[0], fmod_up[1], fmod_up[2]);
FSOUND_Update();
}
////////////////////////////////////////////////////////////////////
// Function: FmodAudioManager::audio_3d_set_listener_attributes
// Access: Public
// Description: Set position of the "ear" that picks up 3d sounds
////////////////////////////////////////////////////////////////////
void FmodAudioManager::
audio_3d_set_listener_attributes(float px, float py, float pz, float vx, float vy, float vz, float fx, float fy, float fz, float ux, float uy, float uz) {
audio_debug("FmodAudioManager::audio_3d_set_listener_attributes()");
_listener_pos[0] = px; _listener_pos[1] = py; _listener_pos[2] = pz;
_listener_vel[0] = vx; _listener_vel[1] = vy; _listener_vel[2] = vz;
_listener_forward[0] = fx; _listener_forward[1] = fy; _listener_forward[2] = fz;
_listener_up[0] = ux; _listener_up[1] = uy; _listener_up[2] = uz;
//FSOUND_3D_Listener_SetAttributes(_listener_pos, _listener_vel, fx, fz, fy, ux, uz, uy);
}
////////////////////////////////////////////////////////////////////
// Function: FmodAudioManager::audio_3d_get_listener_attributes
// Access: Public
// Description: Get position of the "ear" that picks up 3d sounds
////////////////////////////////////////////////////////////////////
void FmodAudioManager::
audio_3d_get_listener_attributes(float px, float py, float pz, float vx, float vy, float vz, float fx, float fy, float fz, float ux, float uy, float uz) {
audio_error("audio3dGetListenerAttributes: currently unimplemented. Get the attributes of the attached object");
//audio_debug("FmodAudioManager::audio_3d_get_listener_attributes()");
// NOTE: swap the +y with the +z axis to convert between FMOD
// coordinates and Panda3D coordinates
//float temp;
//temp = py;
//py = pz;
//pz = temp;
//temp = vy;
//vy = vz;
//vz = temp;
//float pos [] = {px, py, pz};
//float vel [] = {vx, vy, vz};
//float front [] = {fx, fz, fy};
//float up [] = {ux, uz, uy};
//FSOUND_3D_Listener_GetAttributes(pos, vel, &front[0], &front[1], &front[2], &up[0], &up[1], &up[2]);
}
////////////////////////////////////////////////////////////////////
// Function: FmodAudioManager::audio_3d_set_distance_factor
// Access: Public
// Description: Set units per meter (Fmod uses meters internally for
// its sound-spacialization calculations)
////////////////////////////////////////////////////////////////////
void FmodAudioManager::
audio_3d_set_distance_factor(float factor) {
audio_debug("FmodAudioManager::audio_3d_set_distance_factor(factor="<<factor<<")");
if (factor<0.0) {
audio_debug("Recieved value below 0.0. Clamping to 0.0.");
factor = 0.0;
} }
if (_distance_factor != factor){
_distance_factor = factor;
FSOUND_3D_SetDistanceFactor(_distance_factor);
} }
} }
////////////////////////////////////////////////////////////////////
// Function: FmodAudioManager::audio_3d_get_distance_factor
// Access: Public
// Description: Gets units per meter (Fmod uses meters internally for
// its sound-spacialization calculations)
////////////////////////////////////////////////////////////////////
float FmodAudioManager::
audio_3d_get_distance_factor() const {
audio_debug("FmodAudioManager::audio_3d_get_distance_factor()");
return _distance_factor;
}
////////////////////////////////////////////////////////////////////
// Function: FmodAudioManager::audio_3d_set_doppler_factor
// Access: Public
// Description: Exaggerates or diminishes the Doppler effect.
// Defaults to 1.0
////////////////////////////////////////////////////////////////////
void FmodAudioManager::
audio_3d_set_doppler_factor(float factor) {
audio_debug("FmodAudioManager::audio_3d_set_doppler_factor(factor="<<factor<<")");
if (factor<0.0) {
audio_debug("Recieved value below 0.0. Clamping to 0.0.");
factor = 0.0;
}
if (_doppler_factor != factor) {
_doppler_factor = factor;
FSOUND_3D_SetDopplerFactor(_doppler_factor);
}
}
////////////////////////////////////////////////////////////////////
// Function: FmodAudioManager::audio_3d_get_doppler_factor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
float FmodAudioManager::
audio_3d_get_doppler_factor() const {
audio_debug("FmodAudioManager::audio_3d_get_doppler_factor()");
return _doppler_factor;
}
////////////////////////////////////////////////////////////////////
// Function: FmodAudioManager::audio_3d_set_drop_off_factor
// Access: Public
// Description: Control the effect distance has on audability.
// Defaults to 1.0
////////////////////////////////////////////////////////////////////
void FmodAudioManager::
audio_3d_set_drop_off_factor(float factor) {
audio_debug("FmodAudioManager::audio_3d_set_drop_off_factor("<<factor<<")");
if (factor<0.0) {
audio_debug("Recieved value below 0.0. Clamping to 0.0");
factor = 0.0;
}
if (_drop_off_factor != factor) {
_drop_off_factor = factor;
FSOUND_3D_SetRolloffFactor(_drop_off_factor);
}
}
////////////////////////////////////////////////////////////////////
// Function: FmodAudioManager::audio_3d_get_drop_off_factor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
float FmodAudioManager::
audio_3d_get_drop_off_factor() const {
audio_debug("FmodAudioManager::audio_3d_get_drop_off_factor()");
return _drop_off_factor;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: FmodAudioManager::inc_refcount // Function: FmodAudioManager::inc_refcount
// Access: Protected // Access: Protected

View File

@ -1,5 +1,6 @@
// Filename: fmodAudioManager.h // Filename: fmodAudioManager.h
// Created by: cort (January 22, 2003) // Created by: cort (January 22, 2003)
// Extended by: ben (October 22, 2003)
// Prior system by: cary // Prior system by: cary
// //
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -43,11 +44,11 @@ public:
virtual bool is_valid(); virtual bool is_valid();
virtual PT(AudioSound) get_sound(const string&); virtual PT(AudioSound) get_sound(const string&, bool positional = false);
virtual void uncache_sound(const string&); virtual void uncache_sound(const string&);
virtual void clear_cache(); virtual void clear_cache();
virtual void set_cache_limit(unsigned int count); virtual void set_cache_limit(unsigned int count);
virtual int get_cache_limit(); virtual unsigned int get_cache_limit() const;
// Indicates that the given sound was the most recently used. // Indicates that the given sound was the most recently used.
void most_recently_used(const string& path); void most_recently_used(const string& path);
@ -56,18 +57,58 @@ public:
void uncache_a_sound(); void uncache_a_sound();
virtual void set_volume(float); virtual void set_volume(float);
virtual float get_volume(); virtual float get_volume() const;
virtual void set_active(bool); virtual void set_active(bool);
virtual bool get_active(); virtual bool get_active() const;
virtual void set_concurrent_sound_limit(unsigned int limit = 0); virtual void set_concurrent_sound_limit(unsigned int limit = 0);
virtual unsigned int get_concurrent_sound_limit() const; virtual unsigned int get_concurrent_sound_limit() const;
virtual void reduce_sounds_playing_to(unsigned int count); virtual void reduce_sounds_playing_to(unsigned int count);
//virtual void stop_a_sound();
virtual void stop_all_sounds(); virtual void stop_all_sounds();
// Changes to the positions of 3D spacialized sounds and the listener
// are all made at once when this method is called. It should be put
// in the main program loop.
virtual void audio_3d_update();
// This controls the "set of ears" that listens to 3D spacialized sound
// px, py, pz are position coordinates. Can be NULL to ignore.
// vx, vy, vz are a velocity vector in UNITS PER SECOND (default: meters). Can be NULL to ignore.
// fx, fy and fz are the respective components of a unit forward-vector
// ux, uy and uz are the respective components of a unit up-vector
// These changes will NOT be invoked until audio_3d_update() is called.
virtual void audio_3d_set_listener_attributes(float px, float py, float pz,
float vx, float xy, float xz,
float fx, float fy, float fz,
float ux, float uy, float uz);
// Values should all default to NULL, so you can just pass the one you want to get.
virtual void audio_3d_get_listener_attributes(float px = NULL, float py = NULL, float pz = NULL,
float vx = NULL, float vy = NULL, float vz = NULL,
float fx = NULL, float fy = NULL, float fz = NULL,
float ux = NULL, float uy = NULL, float uz = NULL);
// Control the "relative distance factor" for 3D spacialized audio. Default is 1.0
// Fmod uses meters internally, so give a float in Units-per meter
// Don't know what Miles uses.
virtual void audio_3d_set_distance_factor(float factor);
virtual float audio_3d_get_distance_factor() const;
// Control the presence of the Doppler effect. Default is 1.0
// Exaggerated Doppler, use >1.0
// Diminshed Doppler, use <1.0
virtual void audio_3d_set_doppler_factor(float factor);
virtual float audio_3d_get_doppler_factor() const;
// Exaggerate or diminish the effect of distance on sound. Default is 1.0
// Faster drop off, use >1.0
// Slower drop off, use <1.0
virtual void audio_3d_set_drop_off_factor(float factor);
virtual float audio_3d_get_drop_off_factor() const;
protected: protected:
// increment or decrement the refcount of the given file's cache entry. // increment or decrement the refcount of the given file's cache entry.
// sounds can only be uncached when their refcounts are zero. // sounds can only be uncached when their refcounts are zero.
@ -88,6 +129,10 @@ private:
AudioSet _soundsOnLoan; AudioSet _soundsOnLoan;
unsigned int _concurrent_sound_limit; unsigned int _concurrent_sound_limit;
typedef pset<FmodAudioSound* > SoundsPlaying;
// The sounds from this manager that are currently playing
SoundsPlaying _sounds_playing;
// The Least Recently Used mechanism: // The Least Recently Used mechanism:
typedef pdeque<string> LRU; typedef pdeque<string> LRU;
LRU _lru; LRU _lru;
@ -98,6 +143,14 @@ private:
static int _active_managers; static int _active_managers;
bool _is_valid; bool _is_valid;
bool _active; bool _active;
float _volume;
float _listener_pos [3];
float _listener_vel [3];
float _listener_forward [3];
float _listener_up [3];
float _distance_factor;
float _doppler_factor;
float _drop_off_factor;
char* load(const Filename& filename, size_t &size) const; char* load(const Filename& filename, size_t &size) const;

View File

@ -1,5 +1,6 @@
// Filename: fmodAudioSound.cxx // Filename: fmodAudioSound.cxx
// Created by: cort (January 22, 2003) // Created by: cort (January 22, 2003)
// Extended by: ben (October 22, 2003)
// Prior system by: cary // Prior system by: cary
// //
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -20,6 +21,7 @@
#include "pandabase.h" #include "pandabase.h"
#ifdef HAVE_FMOD //[ #ifdef HAVE_FMOD //[
#include "throw_event.h"
#include "fmodAudioSound.h" #include "fmodAudioSound.h"
#include "fmodAudioManager.h" #include "fmodAudioManager.h"
@ -32,18 +34,61 @@
#define fmod_audio_debug(x) ((void)0) #define fmod_audio_debug(x) ((void)0)
#endif //] #endif //]
////////////////////////////////////////////////////////////////////
// Function: pandaFmodFinishedCallback_Stream
// Access: file scope
// Description: What happens when a sound ends (not reaches the end
// of a loop, but really ends).
////////////////////////////////////////////////////////////////////
signed char
pandaFmodFinishedCallback_Stream( FSOUND_STREAM *audio, void *buff, int len, int p_sound ) {
FmodAudioSound* sound = (FmodAudioSound*)p_sound;
assert(sound); //sanity test
sound->finished();
return true; //make signed char happy
}
////////////////////////////////////////////////////////////////////
// Function: panda_Fmod_finished_callback
// Access: file scope
// Description: Sets up a finish callback for a sound.
////////////////////////////////////////////////////////////////////
void
panda_Fmod_finished_callback( FSOUND_STREAM *audio, FmodAudioSound* sound ) {
if ( !audio || !sound ) {//sanity test
return;
}
audio_debug("panda_Fmod_finished_callback(audio="<<((void*)audio)
<<", sound="<<((void*)sound)<<")");
FSOUND_STREAMCALLBACK callback = pandaFmodFinishedCallback_Stream;
//actual stream, callback func, pointer to FmodAudioSound
FSOUND_Stream_SetEndCallback( audio, callback, (int)sound );
}
////////////////////////////////////////////////////////////////////
// Function: FmodAudioSound::FmodAudioSound
// Access:
// Description: constructor
////////////////////////////////////////////////////////////////////
FmodAudioSound:: FmodAudioSound::
FmodAudioSound(FmodAudioManager* manager, FSOUND_STREAM *audio_data, FmodAudioSound(FmodAudioManager* manager, FSOUND_STREAM *audio_data,
string file_name, float length) string file_name, float length)
: _manager(manager), _audio(audio_data), _file_name(file_name), : _manager(manager), _audio(audio_data), _file_name(file_name),
_volume(1.0f), _balance(0), _loop_count(1), _length(length), _volume(1.0f), _balance(0), _loop_count(1), _length(length),
_active(true), _paused(false), _channel(-1) { _active(true), _paused(false), _bExclusive(false),_channel(-1) {
_pos[0] = 0.0f; _pos[1] = 0.0f; _pos[2] = 0.0f;
_vel[0] = 0.0f; _vel[1] = 0.0f; _vel[2] = 0.0f;
nassertv(!file_name.empty()); nassertv(!file_name.empty());
nassertv(audio_data != NULL); nassertv(audio_data != NULL);
audio_debug("FmodAudioSound(manager=0x"<<(void*)&manager fmod_audio_debug("FmodAudioSound(manager=0x"<<(void*)&manager
<<", file_name="<<file_name<<")"); <<", file_name="<<file_name<<")");
} }
////////////////////////////////////////////////////////////////////
// Function: FmodAudioSound::~FmodAudioSound
// Access: public
// Description: destructor
////////////////////////////////////////////////////////////////////
FmodAudioSound:: FmodAudioSound::
~FmodAudioSound() { ~FmodAudioSound() {
fmod_audio_debug("~FmodAudioSound()"); fmod_audio_debug("~FmodAudioSound()");
@ -51,6 +96,11 @@ FmodAudioSound::
_manager->release_sound(this); _manager->release_sound(this);
} }
////////////////////////////////////////////////////////////////////
// Function: FmodAudioSound:: play
// Access: public
// Description: Play a sound
////////////////////////////////////////////////////////////////////
void FmodAudioSound:: void FmodAudioSound::
play() { play() {
if (!_active) { if (!_active) {
@ -60,11 +110,12 @@ play() {
if (this->status() == AudioSound::PLAYING) { if (this->status() == AudioSound::PLAYING) {
this->stop(); this->stop();
} }
if (_manager->stop_a_sound()) { if (_bExclusive) {
// stop another sound that parent mgr is playing // stop another sound that parent mgr is playing
_manager->stop_all_sounds(); _manager->stop_all_sounds();
} }
panda_Fmod_finished_callback( _audio, this );
// Play the stream, but start it paused so we can set the volume and // Play the stream, but start it paused so we can set the volume and
// panning first. // panning first.
assert(_audio != NULL); assert(_audio != NULL);
@ -82,6 +133,16 @@ play() {
unsigned char new_balance = (unsigned char)( (_balance+1.0f)*0.5f*255.0f); unsigned char new_balance = (unsigned char)( (_balance+1.0f)*0.5f*255.0f);
FSOUND_SetPan(_channel, new_balance); FSOUND_SetPan(_channel, new_balance);
// Set 3d attributes, if needed
if (FSOUND_Stream_GetMode(_audio) & FSOUND_HW3D) {
// Convert from Panda coordinates to Fmod coordinates
float fmod_pos [] = {_pos[0], _pos[2], _pos[1]};
float fmod_vel [] = {_vel[0], _vel[2], _vel[1]};
if(!FSOUND_3D_SetAttributes(_channel, fmod_pos, fmod_vel)) {
audio_error("Unable to set 3d attributes for "<<_file_name<<"!");
}
}
// Set looping -- unimplemented // Set looping -- unimplemented
// Unpause and set status to playing // Unpause and set status to playing
@ -95,33 +156,103 @@ play() {
} }
} }
////////////////////////////////////////////////////////////////////
// Function: FmodAudioSound::stop
// Access: public
// Description: Stop a sound
////////////////////////////////////////////////////////////////////
void FmodAudioSound::stop() { void FmodAudioSound::stop() {
FSOUND_Stream_Stop(_audio); if(!FSOUND_Stream_Stop(_audio)) {
audio_error("Stop failed!");
}
_channel = -1; _channel = -1;
} }
////////////////////////////////////////////////////////////////////
// Function: FmodAudioSound::finished
// Access: public
// Description: called by finishedCallback function when a sound
// terminates (but doesn't loop).
////////////////////////////////////////////////////////////////////
void FmodAudioSound::finished() {
fmod_audio_debug("finished()");
stop();
if (!_finished_event.empty()) {
throw_event(_finished_event);
}
}
////////////////////////////////////////////////////////////////////
// Function: FmodAudioSound::set_loop
// Access: public
// Description: Turns looping on and off
////////////////////////////////////////////////////////////////////
void FmodAudioSound::set_loop(bool loop) { void FmodAudioSound::set_loop(bool loop) {
audio_error("FmodAudioSound::set_loop() -- not yet implemented");
fmod_audio_debug("set_loop() set to "<<loop); fmod_audio_debug("set_loop() set to "<<loop);
unsigned int mode = FSOUND_Stream_GetMode(_audio);
if (loop) {
// turn looping on
FSOUND_Stream_SetMode(_audio, mode | FSOUND_LOOP_NORMAL);
} else {
// turn looping off if and only if it is on
if (FSOUND_LOOP_NORMAL == (mode & FSOUND_LOOP_NORMAL)) {
FSOUND_Stream_SetMode(_audio, mode ^ FSOUND_LOOP_NORMAL);
}
}
// default to loop infinitely
_loop_count = loop ? 0 : 1; _loop_count = loop ? 0 : 1;
FSOUND_Stream_SetLoopCount(_audio, _loop_count - 1);
} }
////////////////////////////////////////////////////////////////////
// Function: FmodAudioSound::get_loop
// Access: public
// Description: Returns whether looping is on or off
////////////////////////////////////////////////////////////////////
bool FmodAudioSound::get_loop() const { bool FmodAudioSound::get_loop() const {
fmod_audio_debug("get_loop() returning "<<(_loop_count==0)); // 0 means loop forever,
return (_loop_count == 0); // >1 means loop that many times
// So _loop_count != 1 means we're looping
fmod_audio_debug("get_loop() returning "<<(_loop_count != 1));
return (_loop_count != 1);
} }
////////////////////////////////////////////////////////////////////
// Function: FmodAudioSound::set_loop_count
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
void FmodAudioSound::set_loop_count(unsigned long loop_count) { void FmodAudioSound::set_loop_count(unsigned long loop_count) {
audio_error("FmodAudioSound::set_loop_count() -- not yet implemented"); // Panda uses 0 to mean loop forever.
// Fmod uses negative numbers to mean loop forever.
// (0 means don't loop, 1 means play twice, etc.)
// We must convert!
fmod_audio_debug("set_loop_count() set to "<<loop_count); fmod_audio_debug("set_loop_count() set to "<<loop_count);
if (loop_count < 0) {
fmod_audio_debug("Value out of bounds. Default to loop infinitely.");
loop_count = 0;
}
_loop_count = loop_count; _loop_count = loop_count;
loop_count -= 1;
FSOUND_Stream_SetLoopCount(_audio, loop_count);
} }
////////////////////////////////////////////////////////////////////
// Function: FmodAudioSound::get_loop_count
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
unsigned long FmodAudioSound::get_loop_count() const { unsigned long FmodAudioSound::get_loop_count() const {
fmod_audio_debug("get_loop_count() returning "<<_loop_count); fmod_audio_debug("get_loop_count() returning "<<_loop_count);
return _loop_count; return _loop_count;
} }
////////////////////////////////////////////////////////////////////
// Function: FmodAudioSound::set_time
// Access: public
// Description: Sets the play position within the sound
////////////////////////////////////////////////////////////////////
void FmodAudioSound::set_time(float start_time) { void FmodAudioSound::set_time(float start_time) {
if (start_time < 0.0f) { if (start_time < 0.0f) {
fmod_audio_debug("set_time(): param "<<start_time<<" out of range."); fmod_audio_debug("set_time(): param "<<start_time<<" out of range.");
@ -136,6 +267,11 @@ void FmodAudioSound::set_time(float start_time) {
FSOUND_Stream_SetTime(_audio, (int)(start_time * 1000.0f)); FSOUND_Stream_SetTime(_audio, (int)(start_time * 1000.0f));
} }
////////////////////////////////////////////////////////////////////
// Function: FmodAudioSound::get_time
// Access: public
// Description: Gets the play position within the sound
////////////////////////////////////////////////////////////////////
float FmodAudioSound::get_time() const { float FmodAudioSound::get_time() const {
// A bug in stream WAV files causes FSOUND_Stream_GetTime() to // A bug in stream WAV files causes FSOUND_Stream_GetTime() to
// divide-by-zero somewhere if the stream isn't currently playing. // divide-by-zero somewhere if the stream isn't currently playing.
@ -150,6 +286,12 @@ float FmodAudioSound::get_time() const {
return current_time; return current_time;
} }
////////////////////////////////////////////////////////////////////
// Function: FmodAudioSound::set_volume
// Access: public
// Description: 0.0 to 1.0 scale of volume converted to Fmod's
// internal 0.0 to 255.0 scale.
////////////////////////////////////////////////////////////////////
void FmodAudioSound::set_volume(float vol) { void FmodAudioSound::set_volume(float vol) {
if (vol < 0.0f) { if (vol < 0.0f) {
fmod_audio_debug("set_volume(): param "<<vol<<" out of range."); fmod_audio_debug("set_volume(): param "<<vol<<" out of range.");
@ -165,11 +307,21 @@ void FmodAudioSound::set_volume(float vol) {
FSOUND_SetVolume(_channel, new_volume); FSOUND_SetVolume(_channel, new_volume);
} }
////////////////////////////////////////////////////////////////////
// Function: FmodAudioSound::get_volume
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
float FmodAudioSound::get_volume() const { float FmodAudioSound::get_volume() const {
fmod_audio_debug("get_volume() returning "<<_volume); fmod_audio_debug("get_volume() returning "<<_volume);
return _volume; return _volume;
} }
////////////////////////////////////////////////////////////////////
// Function: FmodAudioSound::set_balance
// Access: public
// Description: -1.0 to 1.0 scale
////////////////////////////////////////////////////////////////////
void FmodAudioSound::set_balance(float bal) { void FmodAudioSound::set_balance(float bal) {
if (bal < -1.0f) { if (bal < -1.0f) {
fmod_audio_debug("set_balance(): param "<<bal<<" out of range."); fmod_audio_debug("set_balance(): param "<<bal<<" out of range.");
@ -185,11 +337,21 @@ void FmodAudioSound::set_balance(float bal) {
FSOUND_SetPan(_channel, new_balance); FSOUND_SetPan(_channel, new_balance);
} }
////////////////////////////////////////////////////////////////////
// Function: FmodAudioSound::get_balance
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
float FmodAudioSound::get_balance() const { float FmodAudioSound::get_balance() const {
fmod_audio_debug("get_balance() returning "<<_balance); fmod_audio_debug("get_balance() returning "<<_balance);
return _balance; return _balance;
} }
////////////////////////////////////////////////////////////////////
// Function: FmodAudioSound::set_active
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
void FmodAudioSound::set_active(bool active) { void FmodAudioSound::set_active(bool active) {
fmod_audio_debug("set_active(active="<<active<<")"); fmod_audio_debug("set_active(active="<<active<<")");
if (!active) { if (!active) {
@ -200,20 +362,99 @@ void FmodAudioSound::set_active(bool active) {
_active = active; _active = active;
} }
////////////////////////////////////////////////////////////////////
// Function: FmodAudioSound::get_active
// Access: public
// Description:
////////////////////////////////////////////////////////////////////
bool FmodAudioSound::get_active() const { bool FmodAudioSound::get_active() const {
fmod_audio_debug("get_active() returning "<<_active); fmod_audio_debug("get_active() returning "<<_active);
return _active; return _active;
} }
////////////////////////////////////////////////////////////////////
// Function: FmodAudioSound::set_finished_event
// Access: public
// Description: Assign a string for the finished event to be referenced
// by in python by an accept method
////////////////////////////////////////////////////////////////////
void FmodAudioSound::
set_finished_event(const string& event) {
fmod_audio_debug("set_finished_event(event="<<event<<")");
_finished_event = event;
}
////////////////////////////////////////////////////////////////////
// Function: FmodAudioSound::get_finished_event
// Access: public
// Description: Return the string the finished event is referenced by
////////////////////////////////////////////////////////////////////
const string& FmodAudioSound::
get_finished_event() const {
fmod_audio_debug("get_finished_event() returning "<<_finished_event);
return _finished_event;
}
////////////////////////////////////////////////////////////////////
// Function: FmodAudioSound::get_name
// Access: public
// Description: Get name of sound file
////////////////////////////////////////////////////////////////////
const string& FmodAudioSound::get_name() const { const string& FmodAudioSound::get_name() const {
//fmod_audio_debug("get_name() returning "<<_file_name); fmod_audio_debug("get_name() returning "<<_file_name);
return _file_name; return _file_name;
} }
////////////////////////////////////////////////////////////////////
// Function: FmodAudioSound::length
// Access: public
// Description: Get length
////////////////////////////////////////////////////////////////////
float FmodAudioSound::length() const { float FmodAudioSound::length() const {
return _length; return _length;
} }
////////////////////////////////////////////////////////////////////
// Function: FmodAudioSound::set_3d_attributes
// Access: public
// Description: Set position and velocity of this sound
////////////////////////////////////////////////////////////////////
void FmodAudioSound::
set_3d_attributes(float px, float py, float pz, float vx, float vy, float vz) {
fmod_audio_debug("Set 3d position and velocity (px="<<px<<", py="<<py<<", pz="<<pz<<", vx="<<vx<<", vy="<<vy<<", vz="<<vz<<")");
_pos[0] = px; _pos[1] = py; _pos[2] = pz;
_vel[0] = vx; _vel[1] = vy; _vel[2] = vz;
}
////////////////////////////////////////////////////////////////////
// Function: FmodAudioSound::get_3d_attributes
// Access: public
// Description: Get position and velocity of this sound
////////////////////////////////////////////////////////////////////
void FmodAudioSound::
get_3d_attributes(float px, float py, float pz, float vx, float vy, float vz) {
audio_error("get3dAttributes: Currently unimplemented. Get the attributes of the attached object.");
// NOTE: swap the +y with the +z axis to convert between FMOD
// coordinates and Panda3D coordinates
//float temp;
//temp = py;
//py = pz;
//pz = temp;
//temp = vy;
//vy = vz;
//vz = temp;
//float pos [] = {px, py, pz};
//float vel [] = {vx, vy, vz};
//FSOUND_3D_GetAttributes(_channel, pos, vel);
}
////////////////////////////////////////////////////////////////////
// Function: FmodAudioSound::status
// Access: public
// Description: Get status of the sound.
////////////////////////////////////////////////////////////////////
AudioSound::SoundStatus FmodAudioSound::status() const { AudioSound::SoundStatus FmodAudioSound::status() const {
// If the stream's channel isn't playing anything, then the stream // If the stream's channel isn't playing anything, then the stream
// definitely isn't playing. // definitely isn't playing.

View File

@ -20,7 +20,7 @@
#ifndef __FMOD_AUDIO_SOUND_H__ #ifndef __FMOD_AUDIO_SOUND_H__
#define __FMOD_AUDIO_SOUND_H__ #define __FMOD_AUDIO_SOUND_H__
#include "pandabase.h" #include <pandabase.h>
#ifdef HAVE_FMOD //[ #ifdef HAVE_FMOD //[
#include "audioSound.h" #include "audioSound.h"
@ -78,20 +78,36 @@ public:
// return: playing time in seconds. // return: playing time in seconds.
float length() const; float length() const;
// Controls the position of this sound's emitter.
// pos is a pointer to an xyz triplet of the emitter's position.
// vel is a pointer to an xyz triplet of the emitter's velocity.
// You can pass NULL to either value for either function to ignore that value
// if you only want to set/get one of them for some reason.
void set_3d_attributes(float px = NULL, float py = NULL, float pz = NULL,
float vx = NULL, float vy = NULL, float vz = NULL);
void get_3d_attributes(float px = NULL, float py = NULL, float pz = NULL,
float vx = NULL, float vy = NULL, float vz = NULL);
AudioSound::SoundStatus status() const; AudioSound::SoundStatus status() const;
void finished();
protected: protected:
private: private:
PT(FmodAudioManager) _manager; PT(FmodAudioManager) _manager;
FSOUND_STREAM *_audio; FSOUND_STREAM *_audio;
string _file_name; string _file_name;
string _finished_event;
float _volume; // 0..1.0 float _volume; // 0..1.0
float _balance; // -1..1 float _balance; // -1..1
float _pos [3];
float _vel [3];
unsigned long _loop_count; unsigned long _loop_count;
mutable float _length; // in seconds. mutable float _length; // in seconds.
bool _active; bool _active;
bool _paused; bool _paused;
bool _bExclusive; //stops all other sounds before playing when true
int _channel; int _channel;
FmodAudioSound(FmodAudioManager* manager, FSOUND_STREAM *audio_data, FmodAudioSound(FmodAudioManager* manager, FSOUND_STREAM *audio_data,

View File

@ -108,6 +108,9 @@ public:
// return: playing time in seconds. // return: playing time in seconds.
float length() const; float length() const;
void set_3d_attributes(float* pos, float* vel);
void get_3d_attributes(float* pos, float* vel);
AudioSound::SoundStatus status() const; AudioSound::SoundStatus status() const;
void finished(); void finished();

View File

@ -121,11 +121,11 @@ get_num_textures() const {
// Access: Published // Access: Published
// Description: Returns the nth EggTexture in the collection. // Description: Returns the nth EggTexture in the collection.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
EggTexture EggTextureCollection:: EggTexture *EggTextureCollection::
get_texture(int index) const { get_texture(int index) const {
nassertr(index >= 0 && index < (int)_ordered_textures.size(), EggTexture(0,0)); nassertr(index >= 0 && index < (int)_ordered_textures.size(), NULL);
return *_ordered_textures[index]; return _ordered_textures[index];
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -66,7 +66,7 @@ PUBLISHED:
bool is_empty() const; bool is_empty() const;
int get_num_textures() const; int get_num_textures() const;
EggTexture get_texture(int index) const; EggTexture *get_texture(int index) const;
public: public:
EggGroupNode::iterator insert_textures(EggGroupNode *node); EggGroupNode::iterator insert_textures(EggGroupNode *node);
@ -84,9 +84,9 @@ PUBLISHED:
void uniquify_trefs(); void uniquify_trefs();
void sort_by_tref(); void sort_by_tref();
public:
// Can be used to traverse all the textures in the collection, in // Can be used to traverse all the textures in the collection, in
// order as last sorted. // order as last sorted.
public:
INLINE iterator begin() const; INLINE iterator begin() const;
INLINE iterator end() const; INLINE iterator end() const;
INLINE bool empty() const; INLINE bool empty() const;

View File

@ -215,6 +215,15 @@ show_text(const string &prefix, int indent_width, string text) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void ProgramBase:: void ProgramBase::
parse_command_line(int argc, char *argv[]) { parse_command_line(int argc, char *argv[]) {
// Setting this variable to zero reinitializes the options parser
// This is only necessary for processing multiple command lines in
// the same program (mainly the MaxToEgg converter plugin)
extern int optind;
optind = 0;
_program_name = Filename::from_os_specific(argv[0]); _program_name = Filename::from_os_specific(argv[0]);
int i; int i;
for (i = 1; i < argc; i++) { for (i = 1; i < argc; i++) {