*** empty log message ***

This commit is contained in:
Josh Yelon 2006-05-15 15:29:22 +00:00
parent cb65e0c44e
commit be22aa9d15
28 changed files with 3723 additions and 1547 deletions

View File

@ -20,6 +20,7 @@
#define __AUDIO_H__ #define __AUDIO_H__
#include "audioSound.h" #include "audioSound.h"
#include "audioDSP.h"
#include "audioManager.h" #include "audioManager.h"
#endif /* __AUDIO_H__ */ #endif /* __AUDIO_H__ */

View File

@ -0,0 +1,195 @@
// Filename: audioDSP.cxx
// Created by: Stan Rosenbaum "Staque" - Spring 2006
//
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#include "audioDSP.h"
TypeHandle AudioDSP::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: AudioDSP::reset
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
void AudioDSP::
reset() {
// intentionally blank
}
////////////////////////////////////////////////////////////////////
// Function: AudioDSP::remove
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
void AudioDSP::
remove() {
// intentionally blank
}
////////////////////////////////////////////////////////////////////
// Function: AudioDSP::set_bypass
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
void AudioDSP::
set_bypass(bool bypass) {
// intentionally blank
}
////////////////////////////////////////////////////////////////////
// Function: AudioDSP::get_bypass
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
bool AudioDSP::get_bypass() {
// intentionally blank
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: AudioDSP::set_parameter
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
void AudioDSP::
set_parameter(const string &name, float value) {
// intentionally blank
}
////////////////////////////////////////////////////////////////////
// Function: AudioDSP::list_parameters_info
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
void AudioDSP::
list_parameters_info() {
int np = get_num_parameters();
for (int i=0; i<np; i++) {
string name = get_parameter_name(i);
string desc = get_parameter_description(i);
float minv = get_parameter_min(i);
float maxv = get_parameter_max(i);
cerr << "Parameter: " << name << " (" << desc << ") " << minv << " to " << maxv << endl ;
}
}
////////////////////////////////////////////////////////////////////
// Function: AudioDSP::get_num_parameters
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
int AudioDSP::
get_num_parameters() {
// intentionally blank
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: AudioDSP::get_parameter_name
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
string AudioDSP::
get_parameter_name(int index) {
// intentionally blank
return "";
}
////////////////////////////////////////////////////////////////////
// Function: AudioDSP::get_parameter_description
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
string AudioDSP::
get_parameter_description(int index) {
// intentionally blank
return "";
}
////////////////////////////////////////////////////////////////////
// Function: AudioDSP::get_parameter_min
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
float AudioDSP::
get_parameter_min(int index) {
// intentionally blank
return 0.0;
}
////////////////////////////////////////////////////////////////////
// Function: AudioDSP::get_parameter_max
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
float AudioDSP::
get_parameter_max(int index) {
// intentionally blank
return 1.0;
}
////////////////////////////////////////////////////////////////////
// Function: AudioDSP::get_parameter_value
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
float AudioDSP::
get_parameter_value(const string &name) {
// intentionally blank
return 1.0;
}
////////////////////////////////////////////////////////////////////
// Function: AudioDSP::Constructor
// Access: Protected
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
AudioDSP::AudioDSP() {
// Intentionally blank.
}
////////////////////////////////////////////////////////////////////
// Function: AudioDSP::Destructor
// Access: Published, Virtual
// Description:
////////////////////////////////////////////////////////////////////
AudioDSP::~AudioDSP() {
}

View File

@ -0,0 +1,80 @@
// Filename: audioDSP.h
// Created by: Stan Rosenbaum "Staque" - Spring 2006
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#ifndef __AUDIODSP_H__
#define __AUDIODSP_H__
#include "config_audio.h"
#include "typedReferenceCount.h"
#include "pointerTo.h"
class AudioManager;
class EXPCL_PANDA AudioDSP : public TypedReferenceCount {
PUBLISHED:
virtual void reset();
virtual void remove();
virtual void set_bypass(bool bypass);
virtual void set_parameter(const string &name, float value);
virtual float get_parameter_value(const string &name);
virtual bool get_bypass();
void list_parameters_info();
virtual int get_num_parameters();
virtual string get_parameter_name(int index);
virtual string get_parameter_description(int index);
virtual float get_parameter_min(int index);
virtual float get_parameter_max(int index);
virtual ~AudioDSP();
protected:
AudioDSP();
////////////////////////////////////////////////////////////
//These are needed for Panda's Pointer System. DO NOT ERASE!
////////////////////////////////////////////////////////////
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
TypedReferenceCount::init_type();
register_type(_type_handle, "AudioDSP",
TypedReferenceCount::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
////////////////////////////////////////////////////////////
//DONE
////////////////////////////////////////////////////////////
};
#endif /* __AudioDSP_H__ */

View File

@ -38,8 +38,7 @@ namespace {
Create_AudioManager_proc* AudioManager::_create_AudioManager Create_AudioManager_proc* AudioManager::_create_AudioManager
=create_NullAudioManger; =create_NullAudioManger;
void AudioManager:: void AudioManager::register_AudioManager_creator(Create_AudioManager_proc* proc) {
register_AudioManager_creator(Create_AudioManager_proc* proc) {
nassertv(_create_AudioManager==create_NullAudioManger); nassertv(_create_AudioManager==create_NullAudioManger);
_create_AudioManager=proc; _create_AudioManager=proc;
} }
@ -47,10 +46,8 @@ register_AudioManager_creator(Create_AudioManager_proc* proc) {
// Factory method for getting a platform specific AudioManager: // Factory method for getting a platform specific AudioManager:
PT(AudioManager) AudioManager:: PT(AudioManager) AudioManager::create_AudioManager() {
create_AudioManager() { audio_debug("create_AudioManager()\n audio_library_name=\""<<audio_library_name<<"\"");
audio_debug("create_AudioManager()\n audio_library_name=\""
<<audio_library_name<<"\"");
static int lib_load; static int lib_load;
if (!lib_load) { if (!lib_load) {
lib_load=1; lib_load=1;
@ -91,8 +88,7 @@ create_AudioManager() {
// Access: Published, Virtual // Access: Published, Virtual
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
AudioManager:: AudioManager::~AudioManager() {
~AudioManager() {
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -104,8 +100,7 @@ AudioManager::
// change your mind and want to play sounds again, you // change your mind and want to play sounds again, you
// will have to recreate all of these objects. // will have to recreate all of these objects.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void AudioManager:: void AudioManager::shutdown() {
shutdown() {
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -116,8 +111,7 @@ shutdown() {
// sound. This same object may also be returned by // sound. This same object may also be returned by
// get_sound() if it fails. // get_sound() if it fails.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
PT(AudioSound) AudioManager:: PT(AudioSound) AudioManager::get_null_sound() {
get_null_sound() {
if (_null_sound == (AudioSound *)NULL) { if (_null_sound == (AudioSound *)NULL) {
_null_sound = new NullAudioSound; _null_sound = new NullAudioSound;
} }
@ -125,13 +119,74 @@ get_null_sound() {
} }
////////////////////////////////////////////////////////////////////
// Function: AudioManager::create_dsp
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
PT(AudioDSP) AudioManager::
create_dsp(DSP_category) {
// intentionally blank.
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: AudioManager::add_dsp
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
bool AudioManager::
add_dsp(PT(AudioDSP) x) {
// intentionally blank
return false;
}
////////////////////////////////////////////////////////////////////
// Function: AudioManager::remove_dsp
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
bool AudioManager::
remove_dsp(PT(AudioDSP) x) {
// intentionally blank
return false;
}
////////////////////////////////////////////////////////////////////
// Function: AudioManager::getSpeakerSetup()
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
int AudioManager::
getSpeakerSetup() {
// intentionally blank
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: AudioManager::setSpeakerSetup()
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void AudioManager::
setSpeakerSetup(SPEAKERMODE_category cat) {
// intentionally blank
;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: AudioManager::audio_3d_update // Function: AudioManager::audio_3d_update
// Access: Public // Access: Public
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void AudioManager:: void AudioManager::audio_3d_update() {
audio_3d_update() {
// intentionally blank. // intentionally blank.
} }
@ -140,8 +195,7 @@ audio_3d_update() {
// Access: Public // Access: Public
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void AudioManager:: void AudioManager::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_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. // intentionally blank.
} }
@ -150,8 +204,7 @@ audio_3d_set_listener_attributes(float px, float py, float pz, float vx, float v
// Access: Public // Access: Public
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void AudioManager:: void AudioManager::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_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. // intentionally blank.
} }
@ -160,8 +213,7 @@ audio_3d_get_listener_attributes(float *px, float *py, float *pz, float *vx, flo
// Access: Public // Access: Public
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void AudioManager:: void AudioManager::audio_3d_set_distance_factor(float factor) {
audio_3d_set_distance_factor(float factor) {
// intentionally blank. // intentionally blank.
} }
@ -170,8 +222,7 @@ audio_3d_set_distance_factor(float factor) {
// Access: Public // Access: Public
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
float AudioManager:: float AudioManager::audio_3d_get_distance_factor() const {
audio_3d_get_distance_factor() const {
// intentionally blank. // intentionally blank.
return 0.0f; return 0.0f;
} }
@ -181,8 +232,7 @@ audio_3d_get_distance_factor() const {
// Access: Public // Access: Public
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void AudioManager:: void AudioManager::audio_3d_set_doppler_factor(float factor) {
audio_3d_set_doppler_factor(float factor) {
// intentionally blank. // intentionally blank.
} }
@ -191,8 +241,7 @@ audio_3d_set_doppler_factor(float factor) {
// Access: Public // Access: Public
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
float AudioManager:: float AudioManager::audio_3d_get_doppler_factor() const {
audio_3d_get_doppler_factor() const {
// intentionally blank. // intentionally blank.
return 0.0f; return 0.0f;
} }
@ -202,8 +251,7 @@ audio_3d_get_doppler_factor() const {
// Access: Public // Access: Public
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void AudioManager:: void AudioManager::audio_3d_set_drop_off_factor(float factor) {
audio_3d_set_drop_off_factor(float factor) {
// intentionally blank. // intentionally blank.
} }
@ -212,8 +260,7 @@ audio_3d_set_drop_off_factor(float factor) {
// Access: Public // Access: Public
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
float AudioManager:: float AudioManager::audio_3d_get_drop_off_factor() const {
audio_3d_get_drop_off_factor() const {
// intentionally blank. // intentionally blank.
return 0.0f; return 0.0f;
} }

View File

@ -22,12 +22,68 @@
#include "config_audio.h" #include "config_audio.h"
#include "audioSound.h" #include "audioSound.h"
#include "audioDSP.h"
typedef PT(AudioManager) Create_AudioManager_proc(); typedef PT(AudioManager) Create_AudioManager_proc();
class EXPCL_PANDA AudioManager : public TypedReferenceCount { class EXPCL_PANDA AudioManager : public TypedReferenceCount {
PUBLISHED: PUBLISHED:
//This is an enumerator for the FMOD DSPs.
//The reason why this is here, is because Panda's DTOOL interegator
//For the Python Bindings, does not seem to like getting 'PUBLISHED'
//Functions in the AudioTraits.
//I guess this is a bug, but it was beyond me.
enum DSP_category {
// These enumerants line up one-to-one
// with the FMOD DSP enumerants.
DSP_unknown,
DSP_mixer,
DSP_oscillator,
DSP_lowpass,
DSP_itlowpass,
DSP_highpass,
DSP_echo,
DSP_flange,
DSP_distortion,
DSP_normalize,
DSP_parameq,
DSP_pitchshift,
DSP_chorus,
DSP_reverb,
DSP_vstplugin,
DSP_winampplugin,
DSP_itecho,
DSP_compressor,
DSP_COUNT
};
enum SPEAKERMODE_category{
// These enumerants line up one-to-one
// with the FMOD SPEAKERMODE enumerants.
SPEAKERMODE_raw,
SPEAKERMODE_mono,
SPEAKERMODE_stereo,
SPEAKERMODE_quad,
SPEAKERMODE_surround,
SPEAKERMODE_5point1,
SPEAKERMODE_7point1,
SPEAKERMODE_prologic,
SPEAKERMODE_max,
SPEAKERMODE_COUNT
};
virtual PT(AudioDSP) create_dsp(DSP_category cat);
virtual bool add_dsp(PT(AudioDSP) x);
virtual bool remove_dsp(PT(AudioDSP) x);
virtual int getSpeakerSetup();
virtual void setSpeakerSetup(SPEAKERMODE_category cat);
// Create an AudioManager for each category of sounds you have. // Create an AudioManager for each category of sounds you have.
// E.g. // E.g.
// MySoundEffects = create_AudioManager::AudioManager(); // MySoundEffects = create_AudioManager::AudioManager();
@ -52,6 +108,7 @@ PUBLISHED:
// Get a sound: // Get a sound:
virtual PT(AudioSound) get_sound(const string& file_name, bool positional = false) = 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.

View File

@ -72,3 +72,71 @@ get_3d_max_distance() const {
// Intentionally blank. // Intentionally blank.
return 0.0f; return 0.0f;
} }
////////////////////////////////////////////////////////////////////
// Function: AudioManager::add_dsp
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
bool AudioSound::
add_dsp(PT(AudioDSP) x) {
// intentionally blank
return false;
}
////////////////////////////////////////////////////////////////////
// Function: AudioManager::remove_dsp
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
bool AudioSound::
remove_dsp(PT(AudioDSP) x) {
// intentionally blank
return false;
}
////////////////////////////////////////////////////////////////////
// Function: AudioManager::getSpeakerMix
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
float AudioSound::
get_speaker_mix(int speaker) {
// intentionally blank
return 0.0;
}
////////////////////////////////////////////////////////////////////
// Function: AudioManager::setSpeakerMix
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void AudioSound::
set_speaker_mix(float frontleft, float frontright, float center, float sub, float backleft, float backright, float sideleft, float sideright) {
// intentionally blank
;
}
////////////////////////////////////////////////////////////////////
// Function: AudioManager::get_priority
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
int AudioSound::
get_priority() {
// intentionally blank
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: AudioManager::set_priority
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void AudioSound::
set_priority(int priority) {
// intentionally blank
;
}

View File

@ -24,11 +24,13 @@
#include "typedReferenceCount.h" #include "typedReferenceCount.h"
#include "pointerTo.h" #include "pointerTo.h"
#include "audioDSP.h"
class AudioManager; class AudioManager;
class EXPCL_PANDA AudioSound : public TypedReferenceCount { class EXPCL_PANDA AudioSound : public TypedReferenceCount {
PUBLISHED: PUBLISHED:
virtual ~AudioSound(); virtual ~AudioSound();
// For best compatability, set the loop_count, // For best compatability, set the loop_count,
@ -124,15 +126,24 @@ PUBLISHED:
virtual void set_3d_max_distance(float dist); virtual void set_3d_max_distance(float dist);
virtual float get_3d_max_distance() const; virtual float get_3d_max_distance() const;
virtual bool add_dsp(PT(AudioDSP) x);
virtual bool remove_dsp(PT(AudioDSP) x);
virtual float get_speaker_mix(int speaker);
virtual void set_speaker_mix(float frontleft, float frontright, float center, float sub, float backleft, float backright, float sideleft, float sideright);
virtual int get_priority();
virtual void set_priority(int priority);
enum SoundStatus { BAD, READY, PLAYING }; enum SoundStatus { BAD, READY, PLAYING };
virtual SoundStatus status() const = 0; virtual SoundStatus status() const = 0;
protected: protected:
AudioSound(); AudioSound();
friend class AudioManager; friend class AudioManager;
public: public:
static TypeHandle get_class_type() { static TypeHandle get_class_type() {
return _type_handle; return _type_handle;
} }
@ -146,7 +157,7 @@ public:
} }
virtual TypeHandle force_init_type() {init_type(); return get_class_type();} virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private: private:
static TypeHandle _type_handle; static TypeHandle _type_handle;
}; };

View File

@ -2,6 +2,7 @@
#include "config_audio.cxx" #include "config_audio.cxx"
#include "audioManager.cxx" #include "audioManager.cxx"
#include "audioSound.cxx" #include "audioSound.cxx"
#include "audioDSP.cxx"
#include "nullAudioManager.cxx" #include "nullAudioManager.cxx"
#include "nullAudioSound.cxx" #include "nullAudioSound.cxx"

View File

@ -24,62 +24,38 @@
Configure(config_audio); Configure(config_audio);
NotifyCategoryDef(audio, ""); NotifyCategoryDef(audio, "");
ConfigVariableBool audio_active
("audio-active", true);
ConfigVariableInt audio_cache_limit
("audio-cache-limit", 15,
PRC_DESC("The number of sounds in the cache."));
ConfigVariableDouble audio_volume
("audio-volume", 1.0f);
ConfigVariableDouble audio_doppler_factor
("audio-doppler-factor", 1.0f);
ConfigVariableDouble audio_distance_factor
("audio-distance-factor", 1.0f);
ConfigVariableDouble audio_drop_off_factor
("audio-drop-off-factor", 1.0f);
ConfigVariableInt audio_min_hw_channels
("audio-min-hw-channels", 15,
PRC_DESC("Guarantee this many channels on the local sound card, or just "
"play EVERYTHING in software."));
ConfigVariableBool audio_software_midi
("audio-software-midi", false);
ConfigVariableFilename audio_dls_file
("audio-dls-file", "");
ConfigVariableBool audio_play_midi
("audio-play-midi", true);
ConfigVariableBool audio_play_wave
("audio-play-wave", true);
ConfigVariableBool audio_play_mp3
("audio-play-mp3", true);
ConfigVariableInt audio_output_rate
("audio-output-rate", 22050);
ConfigVariableInt audio_output_bits
("audio-output-bits", 16);
ConfigVariableInt audio_output_channels
("audio-output-channels", 2);
ConfigVariableString audio_library_name ConfigVariableString audio_library_name
("audio-library-name", "miles_audio"); ("audio-library-name", "miles_audio");
//I should note this somewhere.
//The actual number of sound one could play is 2 times whatever the default is here.
//In this case 32 * 2 = 64.
//The reason for this, is because of the way Panda creates two seperate audio managers.
//One for sound effects, the other for music files.
//At one time this used to be a concern, because wave files [WAV, AIF, MP3, etc...] and
//Music files [MID MOD IT] used to be treated differently.
//However in current Audio APIs [particularly FMOD] a sound file is treated the same
//no matter what it is.
ConfigVariableInt fmod_number_of_sound_channels
("fmod-number-of-sound-channels", 32,
PRC_DESC("Guarantee this many channels you will have with FMOD. AKA the max number of sounds you can play at one time.") );
ConfigVariableBool fmod_use_surround_sound
("fmod-use-surround-sound", false,
PRC_DESC("Determines if an FMOD Flavor of PANDA use 5.1 Surround Sound or Not.") );
//ConfigVariableInt
//ConfigVariableDouble
//ConfigVariableBool
//ConfigVariableFilename
ConfigureFn(config_audio) { ConfigureFn(config_audio) {
AudioManager::init_type(); AudioManager::init_type();
AudioSound::init_type(); AudioSound::init_type();
AudioDSP::init_type();
} }

View File

@ -33,29 +33,19 @@
NotifyCategoryDecl(audio, EXPCL_PANDA, EXPTP_PANDA); NotifyCategoryDecl(audio, EXPCL_PANDA, EXPTP_PANDA);
extern EXPCL_PANDA ConfigVariableBool audio_active; //We Need This one.
extern EXPCL_PANDA ConfigVariableInt audio_cache_limit;
extern EXPCL_PANDA ConfigVariableDouble audio_volume;
extern EXPCL_PANDA ConfigVariableDouble audio_doppler_factor;
extern EXPCL_PANDA ConfigVariableDouble audio_distance_factor;
extern EXPCL_PANDA ConfigVariableDouble audio_drop_off_factor;
extern EXPCL_PANDA ConfigVariableInt audio_min_hw_channels;
extern EXPCL_PANDA ConfigVariableBool audio_software_midi;
extern EXPCL_PANDA ConfigVariableFilename audio_dls_file;
extern EXPCL_PANDA ConfigVariableBool audio_play_midi;
extern EXPCL_PANDA ConfigVariableBool audio_play_wave;
extern EXPCL_PANDA ConfigVariableBool audio_play_mp3;
extern EXPCL_PANDA ConfigVariableInt audio_output_rate;
extern EXPCL_PANDA ConfigVariableInt audio_output_bits;
extern EXPCL_PANDA ConfigVariableInt audio_output_channels;
extern EXPCL_PANDA ConfigVariableString audio_library_name; extern EXPCL_PANDA ConfigVariableString audio_library_name;
//This Specifies the number of possible [max] audio channels.
extern EXPCL_PANDA ConfigVariableInt fmod_number_of_sound_channels;
//This is to turn on Surround Sound.
extern EXPCL_PANDA ConfigVariableBool fmod_use_surround_sound;
#ifndef NDEBUG //[ #ifndef NDEBUG //[
// Non-release build: // Non-release build:
#define audio_debug(msg) \ #define audio_debug(msg) \

View File

@ -0,0 +1,187 @@
// Filename: nullAudioDSP.cxx
// Created by: Stan Rosenbaum "Staque" - Spring 2006
//
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#include "nullAudioDSP.h"
TypeHandle nullAudioDSP::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: nullAudioDSP::reset
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
void nullAudioDSP::
reset() {
// intentionally blank
}
////////////////////////////////////////////////////////////////////
// Function: nullAudioDSP::remove
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
void nullAudioDSP::
remove() {
// intentionally blank
}
////////////////////////////////////////////////////////////////////
// Function: nullAudioDSP::set_bypass
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
void nullAudioDSP::
set_bypass(bool bypass) {
// intentionally blank
}
////////////////////////////////////////////////////////////////////
// Function: nullAudioDSP::get_bypass
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
bool nullAudioDSP::get_bypass() {
// intentionally blank
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: nullAudioDSP::set_parameter
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
void nullAudioDSP::
set_parameter(const string &name, float value) {
// intentionally blank
}
////////////////////////////////////////////////////////////////////
// Function: nullAudioDSP::list_parameters_info
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
void nullAudioDSP::
list_parameters_info() {
// intentionally blank
}
////////////////////////////////////////////////////////////////////
// Function: nullAudioDSP::get_num_parameters
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
int nullAudioDSP::
get_num_parameters() {
// intentionally blank
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: nullAudioDSP::get_parameter_name
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
string nullAudioDSP::
get_parameter_name(int index) {
return "";
}
////////////////////////////////////////////////////////////////////
// Function: nullAudioDSP::get_parameter_description
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
string nullAudioDSP::
get_parameter_description(int index) {
// intentionally blank
return "";
}
////////////////////////////////////////////////////////////////////
// Function: nullAudioDSP::get_parameter_min
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
float nullAudioDSP::
get_parameter_min(int index) {
// intentionally blank
return 0.0;
}
////////////////////////////////////////////////////////////////////
// Function: nullAudioDSP::get_parameter_max
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
float nullAudioDSP::
get_parameter_max(int index) {
// intentionally blank
return 1.0;
}
////////////////////////////////////////////////////////////////////
// Function: nullAudioDSP::get_parameter_value
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
float nullAudioDSP::
get_parameter_value(const string &name) {
// intentionally blank
return 1.0;
}
////////////////////////////////////////////////////////////////////
// Function: nullAudioDSP::Constructor
// Access: Protected
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
nullAudioDSP::nullAudioDSP() {
// Intentionally blank.
}
////////////////////////////////////////////////////////////////////
// Function: nullAudioDSP::Destructor
// Access: Published, Virtual
// Description:
////////////////////////////////////////////////////////////////////
nullAudioDSP::~nullAudioDSP() {
}

View File

@ -0,0 +1,80 @@
// Filename: nullAudioDSP.h
// Created by: Stan Rosenbaum "Staque" - Spring 2006
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#ifndef __NULLAUDIODSP_H__
#define __NULLAUDIODSP_H__
#include "config_audio.h"
#include "typedReferenceCount.h"
#include "pointerTo.h"
class AudioManager;
class EXPCL_PANDA nullAudioDSP : public TypedReferenceCount {
PUBLISHED:
virtual void reset();
virtual void remove();
virtual void set_bypass(bool bypass);
virtual void set_parameter(const string &name, float value);
virtual float get_parameter_value(const string &name);
virtual bool get_bypass();
void list_parameters_info();
virtual int get_num_parameters();
virtual string get_parameter_name(int index);
virtual string get_parameter_description(int index);
virtual float get_parameter_min(int index);
virtual float get_parameter_max(int index);
virtual ~nullAudioDSP();
protected:
nullAudioDSP();
////////////////////////////////////////////////////////////
//These are needed for Panda's Pointer System. DO NOT ERASE!
////////////////////////////////////////////////////////////
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
TypedReferenceCount::init_type();
register_type(_type_handle, "nullAudioDSP",
TypedReferenceCount::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
////////////////////////////////////////////////////////////
//DONE
////////////////////////////////////////////////////////////
};
#endif /* __nullAudioDSP_H__ */

View File

@ -23,6 +23,7 @@
#include "config_fmodAudio.h" #include "config_fmodAudio.h"
#include "fmodAudioManager.h" #include "fmodAudioManager.h"
#include "fmodAudioSound.h" #include "fmodAudioSound.h"
#include "fmodAudioDSP.h"
#include "pandaSystem.h" #include "pandaSystem.h"
#include "dconfig.h" #include "dconfig.h"
@ -52,6 +53,10 @@ init_libFmodAudio() {
AudioManager::register_AudioManager_creator(Create_AudioManager); AudioManager::register_AudioManager_creator(Create_AudioManager);
FmodAudioManager::init_type();
FmodAudioSound::init_type();
FmodAudioDSP::init_type();
PandaSystem *ps = PandaSystem::get_global_ptr(); PandaSystem *ps = PandaSystem::get_global_ptr();
ps->add_system("FMOD"); ps->add_system("FMOD");
ps->add_system("audio"); ps->add_system("audio");

View File

@ -0,0 +1,25 @@
// Filename: fmodAudioDSP.I
// Created by: Stan Rosenbaum "Staque" - Spring 2006
//
//
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,451 @@
// Filename: fmodAudioDSP.cxx
// Created by: Stan Rosenbaum "Staque" - Spring 2006
//
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#include "pandabase.h"
#include "dcast.h"
#ifdef HAVE_FMOD //[
//Panda Headers
#include "config_audio.h"
#include "fmodAudioDSP.h"
TypeHandle FmodAudioDSP::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: FmodAudioDSP::FmodAudioDSP
// Access: Protected
// Description: Constructor
// This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
FmodAudioDSP::FmodAudioDSP(AudioManager *manager, AudioManager::DSP_category cat) {
// Intentionally blank.
audio_debug("FmodAudioDSP::FmodAudioDSP() Creating new DSP " );
//Local Variables that are needed.
FMOD_RESULT result;
//Assign the values we need
DCAST_INTO_V(_manager, manager);
FMOD_DSP_TYPE dsptype = (FMOD_DSP_TYPE)cat;
result = _manager->_system->createDSPByType( dsptype, &_dsp);
ERRCHECK(result);
set_in_chain(false);
cerr << get_dsp_name() << endl;
audio_debug("DSP Loaded");
}
////////////////////////////////////////////////////////////////////
// Function: FmodAudioDSP::Destructor
// Access: Published, Virtual
// Description: DESTRUCTOR!!!
////////////////////////////////////////////////////////////////////
FmodAudioDSP::~FmodAudioDSP() {
audio_debug("FmodAudioSound::FmodAudioDSP() Destruction!!! " );
//Local Variables that are needed.
FMOD_RESULT result;
result = _dsp->remove();
ERRCHECK(result);
result = _dsp->release();
ERRCHECK(result);
audio_debug("DSP GONE");
}
////////////////////////////////////////////////////////////////////
// Function: FmodAudioDSP::reset
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
// [This resets an FMOD DSP to its default values]
////////////////////////////////////////////////////////////////////
void FmodAudioDSP::reset() {
audio_debug("FmodAudioSound::reset() Reset DSP to default settings." );
//Local Variables that are needed.
FMOD_RESULT result;
result = _dsp->reset();
ERRCHECK(result);
audio_debug("DSP Reset.");
}
////////////////////////////////////////////////////////////////////
// Function: FmodAudioDSP::remove
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
// [This removes the DSP from an Effects Chain]
////////////////////////////////////////////////////////////////////
void FmodAudioDSP::remove() {
audio_debug("FmodAudioSound::remove() Removes a DSP from and effect chain." );
//Local Variables that are needed.
FMOD_RESULT result;
result = _dsp->remove();
ERRCHECK(result);
audio_debug("DSP Removed from relative effects chain.");
}
////////////////////////////////////////////////////////////////////
// Function: FmodAudioDSP::set_bypass
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
// [This turns the Bypass for an Effect on and off]/
////////////////////////////////////////////////////////////////////
void FmodAudioDSP::set_bypass(bool bypass) {
audio_debug("FmodAudioSound::set_bypass() ." );
//Local Variables that are needed.
FMOD_RESULT result;
result = _dsp->setBypass(bypass);
ERRCHECK(result);
audio_debug("DSP Bypass set to:" << bypass );
}
////////////////////////////////////////////////////////////////////
// Function: FmodAudioDSP::get_bypass
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
bool FmodAudioDSP::get_bypass() {
audio_debug("FmodAudioSound::get_bypass() ." );
//Local Variables that are needed.
FMOD_RESULT result;
bool bypass;
result = _dsp->getBypass(&bypass);
ERRCHECK(result);
return bypass;
}
////////////////////////////////////////////////////////////////////
// Function: FmodAudioDSP::set_parameter
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
void FmodAudioDSP::set_parameter(const string &name, float value) {
int parameterIndex = find_parameter(name);
if (parameterIndex < 0) {
return;
}
//Local Variables that are needed.
FMOD_RESULT result;
result = _dsp->setParameter(parameterIndex, value);
ERRCHECK(result);
}
////////////////////////////////////////////////////////////////////
// Function: FmodAudioDSP::get_num_parameters
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
int FmodAudioDSP::get_num_parameters() {
audio_debug("FmodAudioSound::get_num_parameters() ." );
//Local Variables that are needed.
FMOD_RESULT result;
int numOfParameters;
result = _dsp->getNumParameters(&numOfParameters);
ERRCHECK(result);
return numOfParameters;
}
////////////////////////////////////////////////////////////////////
// Function: FmodAudioDSP::get_parameter_name
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
string FmodAudioDSP::get_parameter_name(int parameterIndex) {
// intentionally blank
audio_debug("FmodAudioSound::get_parameter_name()" );
//Local Variables that are needed.
FMOD_RESULT result;
//int parameterIndex;
char parameterName[32];
char parameterLabel[32];
char parameterDescription[32];
int parameterDescriptionLength = 0;
float parameterMin;
float parameterMax;
result = _dsp->getParameterInfo(parameterIndex, parameterName, parameterLabel, parameterDescription, parameterDescriptionLength, &parameterMin, &parameterMax);
ERRCHECK(result);
string returnInfo = (parameterName);
return returnInfo;
//return "";
}
////////////////////////////////////////////////////////////////////
// Function: FmodAudioDSP::get_parameter_description
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
// This Method actually returns FMOD's Parameter Label
// Information, and not Description.
// The reason is, that most of the FMOD's Description
// Properties seem to be empty.
// Also the Label sort of serves as as a description by
// return the type of unit the cooresponding parameter
// modifies for a DSP.
// IE. For the Echo. The first parameter is 'Delay'
// and the units for measuring the Delay is in Milliseconds.
// The Label returns Milliseconds letting you know that.
////////////////////////////////////////////////////////////////////
string FmodAudioDSP::get_parameter_description(int parameterIndex) {
// intentionally blank
audio_debug("FmodAudioSound::get_parameter_description()." );
//Local Variables that are needed.
FMOD_RESULT result;
//int parameterIndex;
char parameterName[32];
char parameterLabel[32];
char parameterDescription[32];
int parameterDescriptionLength = 0;
float parameterMin;
float parameterMax;
result = _dsp->getParameterInfo(parameterIndex, parameterName, parameterLabel, parameterDescription, parameterDescriptionLength, &parameterMin, &parameterMax);
ERRCHECK(result);
return parameterLabel;
}
////////////////////////////////////////////////////////////////////
// Function: FmodAudioDSP::get_parameter_min
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
float FmodAudioDSP::get_parameter_min(int parameterIndex) {
audio_debug("FmodAudioSound::get_parameter_min()." );
//Local Variables that are needed.
FMOD_RESULT result;
//int parameterIndex;
char parameterName[32];
char parameterLabel[32];
char parameterDescription[32];
int parameterDescriptionLength = 0;
float parameterMin;
float parameterMax;
result = _dsp->getParameterInfo(parameterIndex, parameterName, parameterLabel, parameterDescription, parameterDescriptionLength, &parameterMin, &parameterMax);
ERRCHECK(result);
return parameterMin;
}
////////////////////////////////////////////////////////////////////
// Function: FmodAudioDSP::get_parameter_max
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
float FmodAudioDSP::get_parameter_max(int parameterIndex) {
audio_debug("FmodAudioSound::get_parameter_min()." );
//Local Variables that are needed.
FMOD_RESULT result;
//int parameterIndex;
char parameterName[32];
char parameterLabel[32];
char parameterDescription[32];
int parameterDescriptionLength = 0;
float parameterMin;
float parameterMax;
result = _dsp->getParameterInfo(parameterIndex, parameterName, parameterLabel, parameterDescription, parameterDescriptionLength, &parameterMin, &parameterMax);
ERRCHECK(result);
return parameterMax;
}
////////////////////////////////////////////////////////////////////
// Function: FmodAudioDSP::get_parameter_value
// Access: Published, Virtual
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
float FmodAudioDSP::get_parameter_value(const string &name) {
int parameterIndex = find_parameter(name);
if (parameterIndex < 0) {
return 0.0;
}
//Local Variables that are needed.
FMOD_RESULT result;
float parameterValue;
char valuestr[32];
int valuestrlen = 32;
result = _dsp->getParameter(parameterIndex, &parameterValue, valuestr, valuestrlen);
ERRCHECK(result);
return parameterValue;
}
////////////////////////////////////////////////////////////////////
// Function: FmodAudioDSP::find_parameter
// Access: Private
// Description: Convert a parameter name to an fmod parameter index.
////////////////////////////////////////////////////////////////////
int FmodAudioDSP::find_parameter(const string &name) {
int np = get_num_parameters();
for (int i=0; i<np; i++) {
if ( name == get_parameter_name(i) ) {
audio_debug("FmodAudioSound::find_parameter() returning: " << get_parameter_name(i) << " " << i );
return i;
}
}
return -1;
}
////////////////////////////////////////////////////////////////////
// Function: FmodAudioDSP::get_dsp_name()
// Access: Protected
// Description: This is a thin wrapper around FMOD-EX.
// See the FMOD-EX documentation.
////////////////////////////////////////////////////////////////////
string FmodAudioDSP::get_dsp_name() {
audio_debug("FmodAudioSound::get_dsp_name()." );
//Local Variables that are needed.
FMOD_RESULT result;
char name[32];
unsigned int version;
int channels;
int configwidth;
int configheight;
result = _dsp->getInfo(name, &version, &channels, &configwidth, &configheight);
ERRCHECK(result);
string returnInfo = (name);
//returnInfo.append(" Version: ");
//returnInfo.append(version);
//returnInfo.append("\n");
return returnInfo;
}
////////////////////////////////////////////////////////////////////
// Function: FmodAudioDSP::get_in_chain()
// Access: Published, Virtual
// Description: This is a functiont to query if a DSP have been assigned
// to the GLOBAL or a SOUND's effect chain.
// This is to make sure you 'remove' an effect from a chain
// before you move it somewhere else or destroy it.
////////////////////////////////////////////////////////////////////
bool FmodAudioDSP::get_in_chain() {
audio_debug("FmodAudioSound::get_in_chain()." );
return _in_chain;
}
////////////////////////////////////////////////////////////////////
// Function: FmodAudioDSP::set_in_chain()
// Access: Published, Virtual
// Description: This is a functiont to set if a DSP have been assigned
// to the GLOBAL or a SOUND's effect chain.
////////////////////////////////////////////////////////////////////
void FmodAudioDSP::set_in_chain(bool chain_state) {
audio_debug("FmodAudioSound::set_in_chain()." );
_in_chain = chain_state;
}
#endif //]

View File

@ -0,0 +1,164 @@
// Filename: fmodAudioDSP.h
// Created by: Stan Rosenbaum "Staque" - Spring 2006
//
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
//[FIRST READ FmodAudioManager and then maybe FmodAudioSound for an Introduction
//if you haven't already].
//
//Hello, all future Panda audio code people! This is my errata documentation to
//Help any future programmer maintain FMOD and PANDA.
//
//Finally lets talk about the DSP, or Digital Signal Processing. To the layman,
//these are filters and shaders for sound.
//
//Currently FmodAudioDSP give you access to all of FMODs built in DSP functions.
//
//The enumerated list for the types are found in the AudioManager.h, but I will
//repeat it here for good fortune.
//
// enum DSP_category {
// // These enumerants line up one-to-one
// // with the FMOD DSP enumerants.
// DSP_unknown,
// DSP_mixer,
// DSP_oscillator,
// DSP_lowpass,
// DSP_itlowpass,
// DSP_highpass,
// DSP_echo,
// DSP_flange,
// DSP_distortion,
// DSP_normalize,
// DSP_parameq,
// DSP_pitchshift,
// DSP_chorus,
// DSP_reverb,
// DSP_vstplugin,
// DSP_winampplugin,
// DSP_itecho,
// DSP_COUNT
// };
//
//Now, I want to point a couple things out. First, we have to place the above list
//in AudioManager.h because that was the only way to them to be PUBLISHED in
//Pandas Python bindings when you build Panda.
//
//Second, you only need to use the it#### named DSP effects if you are using
//mod/tracker files. [If you dont know what a mod/tracker file is you probably
//arent using them so dont worry about it.]
//
//I think that is everything, the DSP info was pretty short.
////////////////////////////////////////////////////////////////////
//
#ifndef __FMOD_AUDIO_DSP_H__
#define __FMOD_AUDIO_DSP_H__
#include <pandabase.h>
#ifdef HAVE_FMOD //[
#include "audioManager.h"
#include "audioDSP.h"
#include <fmod.hpp>
#include <fmod_errors.h>
class EXPCL_FMOD_AUDIO FmodAudioDSP : public AudioDSP {
public:
FmodAudioDSP(AudioManager *mgr, AudioManager::DSP_category);
virtual void reset();
virtual void remove();
virtual void set_bypass(bool bypass);
virtual void set_parameter(const string &name, float value);
virtual float get_parameter_value(const string &name);
virtual bool get_bypass();
virtual int get_num_parameters();
virtual string get_parameter_name(int index);
virtual string get_parameter_description(int index);
virtual float get_parameter_min(int index);
virtual float get_parameter_max(int index);
bool get_in_chain();
void set_in_chain(bool chain_state);
virtual ~FmodAudioDSP();
protected:
virtual string get_dsp_name();
private:
int find_parameter(const string &pn);
bool _in_chain;
FmodAudioManager *_manager;
FMOD::DSP *_dsp;
friend class FmodAudioManager;
friend class FmodAudioSound;
////////////////////////////////////////////////////////////
//These are needed for Panda's Pointer System. DO NOT ERASE!
////////////////////////////////////////////////////////////
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
AudioDSP::init_type();
register_type(_type_handle, "FmodAudioDSP", AudioDSP::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {
init_type();
return get_class_type();
}
private:
static TypeHandle _type_handle;
////////////////////////////////////////////////////////////
//DONE
////////////////////////////////////////////////////////////
};
#include "fmodAudioDSP.I"
#endif //]
#endif /* __FMOD_AUDIO_DSP_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -2,6 +2,8 @@
// Created by: cort (January 22, 2003) // Created by: cort (January 22, 2003)
// Extended by: ben (October 22, 2003) // Extended by: ben (October 22, 2003)
// Prior system by: cary // Prior system by: cary
// Rewrite [for new Version of FMOD-EX] by: Stan Rosenbaum "Staque" - Spring 2006
//
// //
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// //
@ -18,43 +20,103 @@
// //
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
//
//Hello, all future Panda audio code people! This is my errata documentation to
//help any future programmer maintain FMOD and PANDA.
//
//This documentation more then that is needed, but I wanted to go all out, with
//the documentation. Because I was a totally newbie at programming [especially
//with C/C++] this semester I want to make sure future code maintainers have that
//insight I did not when starting on the PANDA project here at the ETC/CMU.
//
//As of Spring 2006, Panda's FMOD audio support has been pretty much completely
//rewritten. This has been done so PANDA can use FMOD-EX [or AKA FMOD 4] and some
//of its new features.
//
//First, the FMOD-EX API itself has been completely rewritten compared to previous
//versions. FMOD now handles any type of audio files, wave audio [WAV, AIF, MP3,
//OGG, etc...] or musical file [MID, TRACKERS] as the same type of an object. The
//API has also been structured more like a sound studio, with 'sounds' and
//'channels'. This will be covered more in the FmodAudioSound.h/.cxx sources.
//
//Second, FMOD now offers virtually unlimited sounds to be played at once via
//their virtual channels system. Actually the theoretical limit is around 4000,
//but that is still a lot. What you need to know about this, is that even thought
//you might only hear 32 sound being played at once, FMOD will keep playing any
//additional sounds, and swap those on virtual channels in and out with those on real channels
//depending on priority, or distance [if you are dealing with 3D audio].
//
//Third, FMOD's DSP support has been added. So you can now add GLOBAL or SOUND
//specific DSP effects. Right not you can only use FMOD's built in DSP effects.
//But adding support for FMOD's support of VST effects shouldn't be that hard.
//
//As for the FmodManager itself, it is pretty straight forward, I hope. As a
//manager class, it will create the FMOD system with the _system variable which
//is an instance of FMOD::SYSTEM. This class is also the one responsible for
//creation of Sounds, DSP, and maintaining the GLOBAL DSP chains [The GLOBAL DSP
//chain is the DSP Chain which affects ALL the sounds].
//
//Any way that is it for an intro, lets move on to looking at the rest of the
//code.
//
////////////////////////////////////////////////////////////////////
#ifndef __FMOD_AUDIO_MANAGER_H__ #ifndef __FMOD_AUDIO_MANAGER_H__
#define __FMOD_AUDIO_MANAGER_H__ #define __FMOD_AUDIO_MANAGER_H__
//First the includes.
#include "pandabase.h" #include "pandabase.h"
#include "pset.h"
#ifdef HAVE_FMOD //[ #ifdef HAVE_FMOD //[
#include "audioManager.h" #include "audioManager.h"
class FmodAudioSound;
#include "filename.h"
#include "pdeque.h"
#include "pmap.h"
#include "pset.h"
#include <fmod.h> // Is fmod.h really a system file? I think maybe this should be "fmod.h". //The Includes needed for FMOD
#include <fmod.hpp>
#include <fmod_errors.h>
class FmodAudioSound;
class FmodAudioDSP;
////////////////////////////////////////////////////////////////////
// OK I am not sure if there is the best place for this one,
// but it seems to work. IE, the FmodSound and FmodDSP classes can find it.
// All FMOD API calls return a success or failure error.
// [I am sure there is a name for this type of programming but I don't know it.]
// Anyway, by adding the line "notify-level-audio debug" to the config.prc file
// of Panda, of the config.in file of MAKEPANDA, you can see the Debugs printed out at the
// Python Prompt
/////////////////////////////////////////////////////////////////////
void ERRCHECK(FMOD_RESULT result);
class EXPCL_FMOD_AUDIO FmodAudioManager : public AudioManager { class EXPCL_FMOD_AUDIO FmodAudioManager : public AudioManager {
// All of these methods are stubbed out to some degree. // All of these methods are stubbed out to some degree.
// If you're looking for a starting place for a new AudioManager, // If you're looking for a starting place for a new AudioManager,
// please consider looking at the milesAudioManager. // please consider looking at the milesAudioManager.
friend class FmodAudioSound;
friend class FmodAudioDSP;
public: public:
//Constructor and Destructor
FmodAudioManager(); FmodAudioManager();
virtual ~FmodAudioManager(); virtual ~FmodAudioManager();
virtual bool is_valid(); virtual bool is_valid();
virtual PT(AudioSound) get_sound(const string&, bool positional = false); virtual PT(AudioSound) get_sound(const string&, bool positional = false);
virtual void uncache_sound(const string&);
virtual void clear_cache();
virtual void set_cache_limit(unsigned int count);
virtual unsigned int get_cache_limit() const;
// Indicates that the given sound was the most recently used. virtual PT(AudioDSP) create_dsp(DSP_category);
void most_recently_used(const string& path); virtual bool add_dsp(PT(AudioDSP) dspToAdd);
virtual bool remove_dsp(PT(AudioDSP) x);
// Uncaches the least recently used sound. virtual int getSpeakerSetup();
bool uncache_a_sound(); virtual void setSpeakerSetup(SPEAKERMODE_category cat);
virtual void set_volume(float); virtual void set_volume(float);
virtual float get_volume() const; virtual float get_volume() const;
@ -62,12 +124,6 @@ public:
virtual void set_active(bool); virtual void set_active(bool);
virtual bool get_active() const; virtual bool get_active() const;
virtual void set_concurrent_sound_limit(unsigned int limit = 0);
virtual unsigned int get_concurrent_sound_limit() const;
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 // Changes to the positions of 3D spacialized sounds and the listener
@ -85,6 +141,8 @@ public:
float vx, float xy, float xz, float vx, float xy, float xz,
float fx, float fy, float fz, float fx, float fy, float fz,
float ux, float uy, float uz); float ux, float uy, float uz);
// REMOVE THIS ONE
virtual void audio_3d_get_listener_attributes(float *px, float *py, float *pz, virtual void audio_3d_get_listener_attributes(float *px, float *py, float *pz,
float *vx, float *vy, float *vz, float *vx, float *vy, float *vz,
float *fx, float *fy, float *fz, float *fx, float *fy, float *fz,
@ -108,57 +166,87 @@ public:
virtual void audio_3d_set_drop_off_factor(float factor); virtual void audio_3d_set_drop_off_factor(float factor);
virtual float audio_3d_get_drop_off_factor() const; virtual float audio_3d_get_drop_off_factor() const;
protected: //THESE ARE NOT USED ANYMORE.
// increment or decrement the refcount of the given file's cache entry. //THEY ARE ONLY HERE BECAUSE THEY are still needed by Miles.
// sounds can only be uncached when their refcounts are zero. //THESE are stubs in FMOD-EX version
void inc_refcount(const string& file_name); ////////////////////////////////////////////////////////////////////
void dec_refcount(const string& file_name); virtual void set_concurrent_sound_limit(unsigned int limit = 0);
private: virtual unsigned int get_concurrent_sound_limit() const;
typedef struct { virtual void reduce_sounds_playing_to(unsigned int count);
size_t size; // size of the data field, in bytes virtual void uncache_sound(const string&);
unsigned int refcount; // how many AudioSound objects are referencing me? virtual void clear_cache();
bool stale; // can this entry be purged from the cache? virtual void set_cache_limit(unsigned int count);
char *data; // the memory-mapped audio file. virtual unsigned int get_cache_limit() const;
} SoundCacheEntry; ////////////////////////////////////////////////////////////////////
typedef phash_map<string, SoundCacheEntry, string_hash> SoundMap;
SoundMap _sounds;
typedef phash_set<FmodAudioSound*, pointer_hash> AudioSet; protected:
// The offspring of this manager:
AudioSet _soundsOnLoan;
unsigned int _concurrent_sound_limit;
typedef phash_set<FmodAudioSound*, pointer_hash> SoundsPlaying; // This is the main FMOD system varible. Without it you got nothing.
// The sounds from this manager that are currently playing FMOD::System *_system;
SoundsPlaying _sounds_playing;
// The Least Recently Used mechanism: private:
typedef pdeque<string> LRU;
LRU _lru;
// RobCode // This varible is something to receive the FMOD_RESULTs which we use to check
// List of supported sound formats // FMOD's State
typedef pvector<string> SupportedTypes; FMOD_VECTOR _position;
SupportedTypes _supported_types; FMOD_VECTOR _velocity;
FMOD_VECTOR _forward;
FMOD_VECTOR _up;
void release_sound(FmodAudioSound *audioSound);
int _cache_limit;
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 _distance_factor;
float _doppler_factor; float _doppler_factor;
float _drop_off_factor; float _drop_off_factor;
char* load(const Filename& filename, size_t &size) const; //The Data Structure that holds all the sounds.
//BTW. Notice that this IS NOT A PT Structure.
//It probably should never bee either.
//We tried it as a PT, and you run into a problem with
//PANDA's garbage collection system, when you finally get around
//to destroying the sounds.
//So you are probably wondering why we even need a set like the one below by now.
//Mainly becuase we need something for the 'stop_all_sounds()' function.
//Which does just take it stop all the sounds at once [and believe it is needed at times.]
typedef pset<FmodAudioSound *> SoundSet;
SoundSet _all_sounds;
//The Data Structure that holds all the DSPs.
typedef pset<PT (FmodAudioDSP) > DSPSet;
DSPSet _system_dsp;
friend class FmodAudioSound; friend class FmodAudioSound;
////////////////////////////////////////////////////////////
//These are needed for Panda's Pointer System. DO NOT ERASE!
////////////////////////////////////////////////////////////
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
AudioManager::init_type();
register_type(_type_handle, "FmodAudioManager", AudioManager::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {
init_type();
return get_class_type();
}
private:
static TypeHandle _type_handle;
////////////////////////////////////////////////////////////
//DONE
////////////////////////////////////////////////////////////
}; };
EXPCL_FMOD_AUDIO PT(AudioManager) Create_AudioManager(); EXPCL_FMOD_AUDIO PT(AudioManager) Create_AudioManager();

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,8 @@
// Filename: fmodAudioSound.h // Filename: fmodAudioSound.h
// Created by: cort (January 22, 2003) // Created by: cort (January 22, 2003)
// Prior system by: cary // Prior system by: cary
// Rewrite [for new Version of FMOD-EX] by: Stan Rosenbaum "Staque" - Spring 2006
//
// //
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// //
@ -16,20 +18,73 @@
// panda3d-general@lists.sourceforge.net . // panda3d-general@lists.sourceforge.net .
// //
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
//
//
//
////////////////////////////////////////////////////////////////////
//
//[FIRST READ FmodAudioManager for an Introduction if you haven't already].
//
//Hello, all future Panda audio code people! This is my errata documentation to
//Help any future programmer maintain FMOD and PANDA.
//
//Well, if you reading this you probably want to know how PANDA deals with sounds
//directly using FMOD-EX. Well I am going to tell you.
//
//The first thing, you as the programmer have to understand, especially if you
//never have done sound programming before, is how the FMOD-EX API works.
//
//With FMOD-EX the guys at Firelight, adopted a model of managing sounds with FMOD
//similar to how a Sound Designer creates sound in a sound studio using SOUNDS
//and CHANNELS. Although this may seem strange at first, if you are not familiar
//with sound programming, there is a very good metaphor you are probably already
//familiar with to explain how FMOD-EX works.
//
//Think of you standard GUI API. Usually a GUI API is made up of two things:
//Windows and Widgets. These correspond to CHANNELS and SOUNDS, where a
//Channel is a Window and a Sound is Widget. Sounds are played within channels,
//and channels dont exist unless they have something to display.
//
//Now why am I explaining all of this? When PANDA was created they set up the
//basic audio classes to handle only the idea of a SOUND. The idea of a
//Channel really wasn't prevalent as in more modern Audio APIs. With this rewrite
//of PANDA to use the FMOD-EX API, the PANDA FmodAudioSound Class, now has to
//handle two different parts of the FMOD-EX API in order to play a sound.
//
//SOUND: The object the handles the audio data in form of WAV, AIF, OGG, MID, IT,
//MP3, etc... And CHANNEL: The object that actually plays the sound and
//manipulates it in real time.
//
//Ultimately this isnt a problem expect for a couple situations when you go to
//play a sound, which I will explain in more detail in that part of the code. All
//that you have to know right now is that Channels in FMOD do not exist
//unless they are playing a sound. And in the PANDA FmodAudioSound API class there
//is only ONE dedicated channel per sound.
//Otherwise there is really nothing to worry about.
//
////////////////////////////////////////////////////////////////////
#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"
class FmodAudioManager;
#include <fmod.h> #include <fmod.hpp>
#include <fmod_errors.h>
class FmodAudioDSP;
class EXPCL_FMOD_AUDIO FmodAudioSound : public AudioSound { class EXPCL_FMOD_AUDIO FmodAudioSound : public AudioSound {
public: public:
FmodAudioSound(AudioManager *manager, string file_name, bool positional );
~FmodAudioSound(); ~FmodAudioSound();
// For best compatability, set the loop_count, start_time, // For best compatability, set the loop_count, start_time,
@ -71,13 +126,6 @@ public:
void set_play_rate(float play_rate=1.0f); void set_play_rate(float play_rate=1.0f);
float get_play_rate() const; float get_play_rate() const;
// inits to manager's state.
void set_active(bool active=true);
bool get_active() const;
void set_finished_event(const string& event);
const string& get_finished_event() const;
const string& get_name() const; const string& get_name() const;
// return: playing time in seconds. // return: playing time in seconds.
@ -86,47 +134,121 @@ public:
// Controls the position of this sound's emitter. // Controls the position of this sound's emitter.
// pos is a pointer to an xyz triplet of the emitter's position. // 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. // vel is a pointer to an xyz triplet of the emitter's velocity.
void set_3d_attributes(float px, float py, float pz, void set_3d_attributes(float px, float py, float pz, float vx, float vy, float vz);
float vx, float vy, float vz); void get_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);
void set_3d_min_distance(float dist); void set_3d_min_distance(float dist);
float get_3d_min_distance() const; float get_3d_min_distance() const;
void set_3d_max_distance(float dist); void set_3d_max_distance(float dist);
float get_3d_max_distance() const; float get_3d_max_distance() const;
AudioSound::SoundStatus status() const; AudioSound::SoundStatus status() const;
virtual bool add_dsp( PT(AudioDSP) dspToAdd );
virtual bool remove_dsp( PT(AudioDSP) x);
virtual float get_speaker_mix(int speaker);
virtual void set_speaker_mix(float frontleft, float frontright, float center, float sub, float backleft, float backright, float sideleft, float sideright);
//THESE ARE NOT USED ANYMORE.
//THEY ARE ONLY HERE BECAUSE THEY are still needed by Miles.
//THESE are stubs in FMOD-EX version
////////////////////////////////////////////////////////////////////
void set_active(bool active=true);
bool get_active() const;
void finished(); void finished();
void set_finished_event(const string& event);
const string& get_finished_event() const;
////////////////////////////////////////////////////////////////////
protected: protected:
private:
FmodAudioManager *_manager;
FMOD::Sound *_sound;
FMOD::Channel *_channel;
private:
PT(FmodAudioManager) _manager;
FSOUND_STREAM *_audio;
string _file_name; string _file_name;
string _finished_event;
float _volume; // 0..1.0 float _volume;
float _balance; // -1..1 float _balance;
float _pos [3]; float _playrate;
float _vel [3]; int _priority;
float _sampleFrequency;
mutable float _length; //in seconds.
FMOD_SPEAKERMODE _speakermode;
float _frontleft;
float _frontright;
float _center;
float _sub;
float _backleft;
float _backright;
float _sideleft;
float _sideright;
FMOD_VECTOR _location;
FMOD_VECTOR _velocity;
float _min_dist; float _min_dist;
float _max_dist; float _max_dist;
unsigned long _loop_count;
mutable float _length; // in seconds.
bool _active;
bool _paused;
bool _bExclusive; //stops all other sounds before playing when true
int _channel;
FmodAudioSound(FmodAudioManager* manager, FSOUND_STREAM *audio_data, void play2DSound();
string file_name, float length=0.0f); void play3DSound();
// forbidden functions! void prepareSound();
FmodAudioSound(const FmodAudioSound& rhs) {} void prepare2DSound();
const FmodAudioSound& operator=(const FmodAudioSound& rhs) { return *this; } void prepare3DSound();
friend class FmodAudioManager; void set_volume_on_channel();
void set_balance_on_channel();
void set_play_rate_on_channel();
void set_speaker_mix_on_channel();
void add_dsp_on_channel();
void set_speaker_mix_or_balance_on_channel();
virtual int get_priority();
virtual void set_priority(int priority);
//The Data Structure that holds all the DSPs.
typedef pset<PT (FmodAudioDSP) > DSPSet;
DSPSet _sound_dsp;
//THESE AREN'T USED ANYMORE.
//THEY ARE ONLY HERE BECAUSE THEY are still need by Miles.
//THESE are stubs in FMOD-EX version
string _finished_event;
////////////////////////////////////////////////////////////
//These are needed for Panda's Pointer System. DO NOT ERASE!
////////////////////////////////////////////////////////////
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
AudioSound::init_type();
register_type(_type_handle, "FmodAudioSound", AudioSound::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {
init_type();
return get_class_type();
}
private:
static TypeHandle _type_handle;
////////////////////////////////////////////////////////////
//DONE
////////////////////////////////////////////////////////////
}; };
#include "fmodAudioSound.I" #include "fmodAudioSound.I"

View File

@ -2,4 +2,5 @@
#include "config_fmodAudio.cxx" #include "config_fmodAudio.cxx"
#include "fmodAudioManager.cxx" #include "fmodAudioManager.cxx"
#include "fmodAudioSound.cxx" #include "fmodAudioSound.cxx"
#include "fmodAudioDSP.cxx"

View File

@ -140,6 +140,31 @@ specifies_mode(int bits) const {
return (_frame_buffer_mode & bits) != 0; return (_frame_buffer_mode & bits) != 0;
} }
////////////////////////////////////////////////////////////////////
// Function: FrameBufferProperties::is_basic
// Access: Published
// Description: Returns true if the properties are extremely basic.
// The following count as basic: rgb or rgba, depth.
// If anything else is specified, the properties are
// non-basic.
////////////////////////////////////////////////////////////////////
INLINE bool FrameBufferProperties::
is_basic() const {
if (_frame_buffer_mode & (~(FM_alpha | FM_depth))) {
return false;
}
if (_depth_bits || _color_bits || _alpha_bits || _stencil_bits) {
return false;
}
if (_multisamples) {
return false;
}
if (_aux_rgba || _aux_hrgba || _aux_float) {
return false;
}
return true;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: FrameBufferProperties::is_stereo // Function: FrameBufferProperties::is_stereo
// Access: Published // Access: Published
@ -544,6 +569,16 @@ set_specified() {
recalc_buffer_mask(); recalc_buffer_mask();
} }
////////////////////////////////////////////////////////////////////
// Function: FrameBufferProperties::get_specified
// Access: Public
// Description: Returns the specified flags.
////////////////////////////////////////////////////////////////////
INLINE int FrameBufferProperties::
get_specified() const {
return _specified;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: FrameBufferProperties::get_buffer_mask // Function: FrameBufferProperties::get_buffer_mask
// Access: Public // Access: Public

View File

@ -61,7 +61,55 @@ operator = (const FrameBufferProperties &copy) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool FrameBufferProperties:: bool FrameBufferProperties::
subsumes(const FrameBufferProperties &other) const { subsumes(const FrameBufferProperties &other) const {
// NOT IMPLEMENTED YET if (other._specified & S_depth_bits) {
if (((_specified & S_depth_bits)==0) || (other._depth_bits > _depth_bits)) {
return false;
}
}
if (other._specified & S_color_bits) {
if (((_specified & S_color_bits)==0) || (other._color_bits > _color_bits)) {
return false;
}
}
if (other._specified & S_alpha_bits) {
if (((_specified & S_alpha_bits)==0) || (other._alpha_bits > _alpha_bits)) {
return false;
}
}
if (other._specified & S_stencil_bits) {
if (((_specified & S_stencil_bits)==0) || (other._stencil_bits > _stencil_bits)) {
return false;
}
}
if ((other._specified & S_multisamples) && (other._multisamples > 1)) {
// Multisample spec of 1 is ignored - 1 multisample is tautologous.
if (((_specified & S_multisamples)==0) || (other._multisamples > _multisamples)) {
return false;
}
}
if (other._specified & S_aux_rgba) {
if (((_specified & S_aux_rgba)==0) || (other._aux_rgba > _aux_rgba)) {
return false;
}
}
if (other._specified & S_aux_hrgba) {
if (((_specified & S_aux_hrgba)==0) || (other._aux_hrgba > _aux_hrgba)) {
return false;
}
}
if (other._specified & S_aux_float) {
if (((_specified & S_aux_float)==0) || (other._aux_float > _aux_float)) {
return false;
}
}
if (other._specified & S_frame_buffer_mode) {
if ((_specified & S_frame_buffer_mode)==0) {
return false;
}
if (other._frame_buffer_mode & (~_frame_buffer_mode)) {
return false;
}
}
return true; return true;
} }
@ -74,6 +122,7 @@ subsumes(const FrameBufferProperties &other) const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
FrameBufferProperties FrameBufferProperties:: FrameBufferProperties FrameBufferProperties::
get_default() { get_default() {
FrameBufferProperties props; FrameBufferProperties props;
int mode = 0; int mode = 0;
@ -149,6 +198,9 @@ get_default() {
if (framebuffer_stereo) { if (framebuffer_stereo) {
mode |= FM_stereo; mode |= FM_stereo;
} }
if ((mode & FM_hardware) && (mode & FM_software)) {
mode = mode & ~(FM_hardware | FM_software);
}
props.set_frame_buffer_mode(mode); props.set_frame_buffer_mode(mode);
props.set_depth_bits(depth_bits); props.set_depth_bits(depth_bits);

View File

@ -45,7 +45,7 @@ PUBLISHED:
FM_index = 0x0001, FM_index = 0x0001,
FM_single_buffer = 0x0000, FM_single_buffer = 0x0000,
FM_double_buffer = 0x0002, FM_double_buffer = 0x0002,
FM_triple_buffer = 0x0004, FM_triple_buffer = 0x0006,
FM_buffer = 0x0006, // == (FM_single_buffer | FM_double_buffer | FM_triple_buffer) FM_buffer = 0x0006, // == (FM_single_buffer | FM_double_buffer | FM_triple_buffer)
FM_accum = 0x0008, FM_accum = 0x0008,
FM_alpha = 0x0010, FM_alpha = 0x0010,
@ -58,13 +58,31 @@ PUBLISHED:
FM_hardware = 0x0400, FM_hardware = 0x0400,
}; };
// This bitmask indicates which of the parameters in the properties
// structure have been filled in by the user, and which remain
// unspecified.
enum Specified {
S_frame_buffer_mode = 0x0001,
S_depth_bits = 0x0002,
S_color_bits = 0x0004,
S_alpha_bits = 0x0008,
S_stencil_bits = 0x0010,
S_multisamples = 0x0020,
S_aux_rgba = 0x0040,
S_aux_hrgba = 0x0080,
S_aux_float = 0x0100,
S_ALL_SPECIFIED = 0x01FF,
};
void clear(); void clear();
INLINE void set_specified(); INLINE void set_specified();
INLINE int get_specified() const;
INLINE int get_buffer_mask() const; INLINE int get_buffer_mask() const;
INLINE bool is_any_specified() const; INLINE bool is_any_specified() const;
INLINE bool specifies_mode(int bit) const; INLINE bool specifies_mode(int bit) const;
INLINE bool is_single_buffered() const; INLINE bool is_single_buffered() const;
INLINE bool is_stereo() const; INLINE bool is_stereo() const;
INLINE bool is_basic() const;
bool subsumes(const FrameBufferProperties &prop) const; bool subsumes(const FrameBufferProperties &prop) const;
@ -124,21 +142,6 @@ private:
void recalc_buffer_mask(); void recalc_buffer_mask();
private: private:
// This bitmask indicates which of the parameters in the properties
// structure have been filled in by the user, and which remain
// unspecified.
enum Specified {
S_frame_buffer_mode = 0x0001,
S_depth_bits = 0x0002,
S_color_bits = 0x0004,
S_alpha_bits = 0x0008,
S_stencil_bits = 0x0010,
S_multisamples = 0x0020,
S_aux_rgba = 0x0040,
S_aux_hrgba = 0x0080,
S_aux_float = 0x0100,
S_ALL_SPECIFIED = 0x01FF,
};
int _specified; int _specified;
int _flags; int _flags;

View File

@ -126,7 +126,8 @@ make_window(GraphicsStateGuardian *gsg, const string &name, int sort) {
// The hardwired size here is never used. // The hardwired size here is never used.
GraphicsOutput *result = make_output(gsg->get_pipe(), name, sort, GraphicsOutput *result = make_output(gsg->get_pipe(), name, sort,
gsg->get_default_properties(), 50, 50, gsg->get_default_properties(), 50, 50,
GraphicsPipe::BF_require_window, GraphicsPipe::BF_require_window |
GraphicsPipe::BF_fb_props_optional,
gsg, NULL); gsg, NULL);
return DCAST(GraphicsWindow, result); return DCAST(GraphicsWindow, result);
} }
@ -150,7 +151,8 @@ make_buffer(GraphicsStateGuardian *gsg, const string &name,
props.set_frame_buffer_mode(props.get_frame_buffer_mode() & (~clear)); props.set_frame_buffer_mode(props.get_frame_buffer_mode() & (~clear));
GraphicsOutput *result = make_output(gsg->get_pipe(), name, sort, GraphicsOutput *result = make_output(gsg->get_pipe(), name, sort,
gsg->get_default_properties(), x_size, y_size, gsg->get_default_properties(), x_size, y_size,
GraphicsPipe::BF_refuse_window, GraphicsPipe::BF_refuse_window |
GraphicsPipe::BF_fb_props_optional,
gsg, NULL); gsg, NULL);
return result; return result;
} }
@ -166,7 +168,8 @@ make_parasite(GraphicsOutput *host, const string &name,
FrameBufferProperties props; FrameBufferProperties props;
GraphicsOutput *result = make_output(host->get_pipe(), name, sort, GraphicsOutput *result = make_output(host->get_pipe(), name, sort,
props, x_size, y_size, props, x_size, y_size,
GraphicsPipe::BF_require_parasite, GraphicsPipe::BF_require_parasite |
GraphicsPipe::BF_fb_props_optional,
host->get_gsg(), host); host->get_gsg(), host);
return result; return result;
} }

View File

@ -332,6 +332,23 @@ make_output(GraphicsPipe *pipe,
gsg = make_gsg(pipe, prop); gsg = make_gsg(pipe, prop);
} }
// If there is a host window, and it is not yet initialized,
// then call open_windows to get the host ready. If that
// fails, give up on using the host window.
if (host != (GraphicsOutput *)NULL) {
if ((!host->is_valid())||
(!host->get_gsg()->is_valid())||
(host->get_gsg()->needs_reset())) {
open_windows();
}
if ((!host->is_valid())||
(!host->get_gsg()->is_valid())||
(host->get_gsg()->needs_reset())) {
host = NULL;
}
}
// Determine if a parasite buffer meets the user's specs. // Determine if a parasite buffer meets the user's specs.
bool can_use_parasite = false; bool can_use_parasite = false;
@ -340,24 +357,23 @@ make_output(GraphicsPipe *pipe,
((flags&GraphicsPipe::BF_refuse_parasite)==0)&& ((flags&GraphicsPipe::BF_refuse_parasite)==0)&&
((flags&GraphicsPipe::BF_can_bind_color)==0)&& ((flags&GraphicsPipe::BF_can_bind_color)==0)&&
((flags&GraphicsPipe::BF_can_bind_every)==0)&& ((flags&GraphicsPipe::BF_can_bind_every)==0)&&
((flags&GraphicsPipe::BF_rtt_cumulative)==0)&& ((flags&GraphicsPipe::BF_rtt_cumulative)==0)) {
(prop.specifies_mode(FrameBufferProperties::FM_index)==false)&& if ((flags&GraphicsPipe::BF_fb_props_optional) ||
(prop.specifies_mode(FrameBufferProperties::FM_buffer)==false)&& (host->get_fb_properties().subsumes(prop))) {
(prop.specifies_mode(FrameBufferProperties::FM_accum)==false)&&
(prop.specifies_mode(FrameBufferProperties::FM_stencil)==false)&&
(prop.specifies_mode(FrameBufferProperties::FM_multisample)==false)&&
(prop.get_aux_rgba() == 0)&&
(prop.get_aux_hrgba() == 0)&&
(prop.get_aux_float() == 0)) {
can_use_parasite = true; can_use_parasite = true;
} }
}
// If parasite buffers are preferred, then try a parasite first. // If parasite buffers are preferred, then try a parasite first.
// Even if prefer-parasite-buffer is set, parasites are not preferred
// if the host window is too small, or if the host window does not
// have the requested properties.
if ((prefer_parasite_buffer) && if ((prefer_parasite_buffer) &&
(can_use_parasite) && (can_use_parasite) &&
(x_size <= host->get_x_size())&& (x_size <= host->get_x_size())&&
(y_size <= host->get_y_size())) { (y_size <= host->get_y_size())&&
(host->get_fb_properties().subsumes(prop))) {
ParasiteBuffer *buffer = new ParasiteBuffer(host, name, x_size, y_size, flags); ParasiteBuffer *buffer = new ParasiteBuffer(host, name, x_size, y_size, flags);
buffer->_sort = sort; buffer->_sort = sort;
do_add_window(buffer, gsg, threading_model); do_add_window(buffer, gsg, threading_model);
@ -378,7 +394,14 @@ make_output(GraphicsPipe *pipe,
} }
open_windows(); open_windows();
if (window->is_valid()) { if (window->is_valid()) {
if (window->get_fb_properties().subsumes(prop)) {
return window; return window;
} else {
if (flags & GraphicsPipe::BF_fb_props_optional) {
display_cat.warning() << "FrameBufferProperties available less than requested.\n";
return window;
}
}
} }
// No good; delete the window and keep trying. // No good; delete the window and keep trying.
bool removed = remove_window(window); bool removed = remove_window(window);

View File

@ -89,6 +89,7 @@ PUBLISHED:
BF_can_bind_every = 0x0080, // Need capability: bind all bitplanes to a tex. BF_can_bind_every = 0x0080, // Need capability: bind all bitplanes to a tex.
BF_size_track_host = 0x0100, // Buffer should track the host size. BF_size_track_host = 0x0100, // Buffer should track the host size.
BF_rtt_cumulative = 0x0200, // Buffer supports cumulative render-to-texture. BF_rtt_cumulative = 0x0200, // Buffer supports cumulative render-to-texture.
BF_fb_props_optional = 0x0400, // FrameBufferProperties can be ignored.
}; };
INLINE bool is_valid() const; INLINE bool is_valid() const;

View File

@ -158,12 +158,16 @@ make_output(const string &name,
((flags&BF_size_track_host)!=0)|| ((flags&BF_size_track_host)!=0)||
((flags&BF_rtt_cumulative)!=0)|| ((flags&BF_rtt_cumulative)!=0)||
((flags&BF_can_bind_color)!=0)|| ((flags&BF_can_bind_color)!=0)||
((flags&BF_can_bind_every)!=0)|| ((flags&BF_can_bind_every)!=0)) {
(properties.get_aux_rgba() > 0)|| return NULL;
}
if ((flags & BF_fb_props_optional)==0) {
if ((properties.get_aux_rgba() > 0)||
(properties.get_aux_hrgba() > 0)|| (properties.get_aux_hrgba() > 0)||
(properties.get_aux_float() > 0)) { (properties.get_aux_float() > 0)) {
return NULL; return NULL;
} }
}
return new wglGraphicsWindow(this, name, properties, return new wglGraphicsWindow(this, name, properties,
x_size, y_size, flags, gsg, host); x_size, y_size, flags, gsg, host);
} }
@ -175,19 +179,28 @@ make_output(const string &name,
(!gl_support_fbo)|| (!gl_support_fbo)||
(host==0)|| (host==0)||
((flags&BF_require_parasite)!=0)|| ((flags&BF_require_parasite)!=0)||
((flags&BF_require_window)!=0)|| ((flags&BF_require_window)!=0)) {
(properties.specifies_mode(FrameBufferProperties::FM_index))||
(properties.specifies_mode(FrameBufferProperties::FM_buffer))||
(properties.specifies_mode(FrameBufferProperties::FM_accum))||
(properties.specifies_mode(FrameBufferProperties::FM_stencil))||
(properties.specifies_mode(FrameBufferProperties::FM_multisample))) {
return NULL; return NULL;
} }
// Early failure - if we are sure that this buffer WONT
// meet specs, we can bail out early.
if ((flags & BF_fb_props_optional)==0) {
if ((properties.has_mode(FrameBufferProperties::FM_index))||
(properties.has_mode(FrameBufferProperties::FM_buffer))||
(properties.has_mode(FrameBufferProperties::FM_accum))||
(properties.has_mode(FrameBufferProperties::FM_stencil))||
(properties.has_mode(FrameBufferProperties::FM_multisample))) {
return NULL;
}
}
// Early success - if we are sure that this buffer WILL
// meet specs, we can precertify it.
if ((wglgsg != 0) && if ((wglgsg != 0) &&
(wglgsg->is_valid()) && (wglgsg->is_valid()) &&
(!wglgsg->needs_reset()) && (!wglgsg->needs_reset()) &&
(wglgsg->_supports_framebuffer_object) && (wglgsg->_supports_framebuffer_object) &&
(wglgsg->_glDrawBuffers != 0)) { (wglgsg->_glDrawBuffers != 0)&&
(properties.is_basic())) {
precertify = true; precertify = true;
} }
return new GLGraphicsBuffer(this, name, properties, return new GLGraphicsBuffer(this, name, properties,
@ -202,16 +215,25 @@ make_output(const string &name,
((flags&BF_require_window)!=0)|| ((flags&BF_require_window)!=0)||
((flags&BF_size_track_host)!=0)|| ((flags&BF_size_track_host)!=0)||
((flags&BF_rtt_cumulative)!=0)|| ((flags&BF_rtt_cumulative)!=0)||
((flags&BF_can_bind_every)!=0)|| ((flags&BF_can_bind_every)!=0)) {
(properties.get_aux_rgba() > 0)|| return NULL;
}
// Early failure - if we are sure that this buffer WONT
// meet specs, we can bail out early.
if ((flags & BF_fb_props_optional) == 0) {
if ((properties.get_aux_rgba() > 0)||
(properties.get_aux_hrgba() > 0)|| (properties.get_aux_hrgba() > 0)||
(properties.get_aux_float() > 0)) { (properties.get_aux_float() > 0)) {
return NULL; return NULL;
} }
}
// Early success - if we are sure that this buffer WILL
// meet specs, we can precertify the window.
if ((wglgsg != 0) && if ((wglgsg != 0) &&
(wglgsg->is_valid()) && (wglgsg->is_valid()) &&
(!wglgsg->needs_reset()) && (!wglgsg->needs_reset()) &&
(wglgsg->_supports_pbuffer)) { (wglgsg->_supports_pbuffer) &&
(properties.is_basic())) {
precertify = true; precertify = true;
} }
return new wglGraphicsBuffer(this, name, properties, return new wglGraphicsBuffer(this, name, properties,