*** empty log message ***
This commit is contained in:
parent
2b797f792e
commit
fdaaef70c3
|
|
@ -1,54 +0,0 @@
|
|||
// Filename: audio_linux_traits.I
|
||||
// Created by: cary (02Oct00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
INLINE LinuxSample::LinuxSample(byte* b, unsigned long s)
|
||||
: AudioTraits::SoundClass(), _data(b), _size(s) {
|
||||
}
|
||||
|
||||
INLINE byte* LinuxSample::get_data() const {
|
||||
return _data;
|
||||
}
|
||||
|
||||
INLINE unsigned long LinuxSample::get_size() const {
|
||||
return _size;
|
||||
}
|
||||
|
||||
INLINE LinuxMusic::LinuxMusic() : AudioTraits::SoundClass() {
|
||||
}
|
||||
|
||||
INLINE LinuxSamplePlaying::LinuxSamplePlaying(AudioTraits::SoundClass* s)
|
||||
: AudioTraits::PlayingClass(s), _buff((Buffer*)0L) {
|
||||
LinuxSample* smpl = (LinuxSample*)s;
|
||||
_buff = new Buffer(smpl->get_data(), smpl->get_size());
|
||||
}
|
||||
|
||||
INLINE Buffer* LinuxSamplePlaying::get_data() {
|
||||
return _buff;
|
||||
}
|
||||
|
||||
INLINE LinuxMusicPlaying::LinuxMusicPlaying(AudioTraits::SoundClass* s)
|
||||
: AudioTraits::PlayingClass(s) {
|
||||
}
|
||||
|
||||
INLINE LinuxSamplePlayer::LinuxSamplePlayer()
|
||||
: AudioTraits::PlayerClass() {
|
||||
}
|
||||
|
||||
INLINE LinuxMusicPlayer::LinuxMusicPlayer()
|
||||
: AudioTraits::PlayerClass() {
|
||||
}
|
||||
|
|
@ -1,416 +0,0 @@
|
|||
// Filename: audio_linux_traits.cxx
|
||||
// Created by: cary (02Oct00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "audio_linux_traits.h"
|
||||
|
||||
#ifdef AUDIO_USE_LINUX
|
||||
|
||||
#include "audio_manager.h"
|
||||
#include "config_audio.h"
|
||||
#include <ipc_thread.h>
|
||||
#include <ipc_mutex.h>
|
||||
#include "pset.h"
|
||||
#include <fcntl.h>
|
||||
#include <sys/soundcard.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
typedef pset<Buffer*> BufferSet;
|
||||
|
||||
static bool have_initialized = false;
|
||||
static mutex buffer_mutex;
|
||||
static byte* buffer1;
|
||||
static byte* buffer2;
|
||||
static byte* current_buffer;
|
||||
static byte* back_buffer;
|
||||
byte* zero_buffer;
|
||||
static byte* scratch_buffer;
|
||||
static byte* fetch_buffer;
|
||||
static int want_buffers = 0, have_buffers = 0;
|
||||
static bool initializing = true;
|
||||
static bool stop_mixing = false;
|
||||
static int output_fd;
|
||||
static thread* update_thread;
|
||||
static int sample_size = sizeof(short);
|
||||
|
||||
BufferSet buffers;
|
||||
|
||||
static void swap_buffers() {
|
||||
byte *tmp = current_buffer;
|
||||
current_buffer = back_buffer;
|
||||
back_buffer = tmp;
|
||||
}
|
||||
|
||||
INLINE static signed short read_buffer(byte* buf, int idx) {
|
||||
signed short ret = 0;
|
||||
switch (sample_size) {
|
||||
case 1:
|
||||
ret = *((signed char *)(&buf[idx]));
|
||||
break;
|
||||
case 2:
|
||||
ret = *((signed short *)(&buf[idx*2]));
|
||||
break;
|
||||
default:
|
||||
audio_cat->debug() << "unknown sample size (" << sample_size << ")"
|
||||
<< endl;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
INLINE static void write_buffer(byte* buf, int idx, signed short val) {
|
||||
switch (sample_size) {
|
||||
case 1:
|
||||
*((signed char *)(&buf[idx])) = val & 0xff;
|
||||
break;
|
||||
case 2:
|
||||
*((signed short *)(&buf[idx*2])) = val;
|
||||
break;
|
||||
default:
|
||||
audio_cat->debug() << "unknown sample size (" << sample_size << ")"
|
||||
<< endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
INLINE static signed short sound_clamp(signed int value) {
|
||||
signed short ret = 0;
|
||||
switch (sample_size) {
|
||||
case 1:
|
||||
ret = (value > 127)?127:((value < -128)?(-128):(value));
|
||||
break;
|
||||
case 2:
|
||||
ret = (value > 32767)?32767:((value < -32768)?(-32768):(value));
|
||||
break;
|
||||
default:
|
||||
audio_cat->debug() << "unknown sample size (" << sample_size << ")"
|
||||
<< endl;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void mix_in(byte* buf, byte* from, float vol, float pan) {
|
||||
int done = audio_buffer_size / sample_size;
|
||||
for (int i=0; i<done; i+=2) {
|
||||
signed short left = read_buffer(buf, i);
|
||||
signed short right = read_buffer(buf, i+1);
|
||||
|
||||
// now get the incoming data
|
||||
signed short in_left = read_buffer(from, i);
|
||||
signed short in_right = read_buffer(from, i+1);
|
||||
|
||||
// figure out panning at some point
|
||||
in_left = (short int)(in_left * vol);
|
||||
in_right = (short int)(in_right * vol);
|
||||
|
||||
// compute mixed values
|
||||
left = sound_clamp(left+in_left);
|
||||
right = sound_clamp(right+in_right);
|
||||
|
||||
// write it back to the buffer
|
||||
write_buffer(buf, i, left);
|
||||
write_buffer(buf, i+1, right);
|
||||
}
|
||||
}
|
||||
|
||||
static void mix_buffer(byte* buf) {
|
||||
memcpy(scratch_buffer, zero_buffer, audio_buffer_size);
|
||||
// do stuff
|
||||
for (BufferSet::iterator i=buffers.begin(); i!=buffers.end(); ++i)
|
||||
mix_in(scratch_buffer, (*i)->get_buffer(fetch_buffer), 1., 0.);
|
||||
BufferSet to_del;
|
||||
for (BufferSet::iterator j=buffers.begin(); j!=buffers.end(); ++j)
|
||||
if ((*j)->is_done())
|
||||
to_del.insert(*j);
|
||||
{
|
||||
mutex_lock m(buffer_mutex);
|
||||
memcpy(buf, scratch_buffer, audio_buffer_size);
|
||||
--want_buffers;
|
||||
++have_buffers;
|
||||
for (BufferSet::iterator k=to_del.begin(); k!=to_del.end(); ++k) {
|
||||
buffers.erase(*k);
|
||||
(*k)->reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void update_linux() {
|
||||
if (buffers.empty())
|
||||
return;
|
||||
if (!audio_is_active)
|
||||
return;
|
||||
switch (want_buffers) {
|
||||
case 0:
|
||||
// all buffers are full right now. This is a good state.
|
||||
break;
|
||||
case 1:
|
||||
// mix a buffer and put it in place.
|
||||
mix_buffer(back_buffer);
|
||||
break;
|
||||
case 2:
|
||||
if (!initializing)
|
||||
audio_cat->debug() << "audio buffers are being starved" << endl;
|
||||
mix_buffer(current_buffer);
|
||||
mix_buffer(back_buffer);
|
||||
initializing = false;
|
||||
break;
|
||||
default:
|
||||
audio_cat->error() << "audio system wants more then 2 buffers!" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
static void* internal_update(void*) {
|
||||
if ((output_fd = open(audio_device->c_str(), O_WRONLY, 0)) == -1) {
|
||||
audio_cat->error() << "could not open '" << audio_device << "'" << endl;
|
||||
audio_is_active = false;
|
||||
return (void*)0L;
|
||||
}
|
||||
// this one I don't know about
|
||||
int fragsize = 0x0004000c;
|
||||
if (ioctl(output_fd, SNDCTL_DSP_SETFRAGMENT, &fragsize) == -1) {
|
||||
audio_cat->error() << "faied to set fragment size" << endl;
|
||||
audio_is_active = false;
|
||||
return (void*)0L;
|
||||
}
|
||||
// for now signed, 16-bit, little endian
|
||||
int format = AFMT_S16_LE;
|
||||
if (ioctl(output_fd, SNDCTL_DSP_SETFMT, &format) == -1) {
|
||||
audio_cat->error() << "failed to set format on the dsp" << endl;
|
||||
audio_is_active = false;
|
||||
return (void*)0L;
|
||||
}
|
||||
// set stereo
|
||||
int stereo = 1;
|
||||
if (ioctl(output_fd, SNDCTL_DSP_STEREO, &stereo) == -1) {
|
||||
audio_cat->error() << "failed to set stereo on the dsp" << endl;
|
||||
audio_is_active = false;
|
||||
return (void*)0L;
|
||||
}
|
||||
// set the frequency
|
||||
if (ioctl(output_fd, SNDCTL_DSP_SPEED, &audio_mix_freq) == -1) {
|
||||
audio_cat->error() << "failed to set frequency on the dsp" << endl;
|
||||
audio_is_active = false;
|
||||
return (void*)0L;
|
||||
}
|
||||
while (!stop_mixing && !audio_is_active) {
|
||||
if (have_buffers == 0) {
|
||||
ipc_traits::sleep(0, audio_auto_update_delay);
|
||||
} else {
|
||||
write(output_fd, current_buffer, audio_buffer_size);
|
||||
{
|
||||
mutex_lock m(buffer_mutex);
|
||||
swap_buffers();
|
||||
--have_buffers;
|
||||
++want_buffers;
|
||||
}
|
||||
}
|
||||
}
|
||||
delete [] buffer1;
|
||||
delete [] buffer2;
|
||||
delete [] scratch_buffer;
|
||||
delete [] fetch_buffer;
|
||||
delete [] zero_buffer;
|
||||
stop_mixing = false;
|
||||
audio_cat->debug() << "exiting internal thread" << endl;
|
||||
return (void*)0L;
|
||||
}
|
||||
|
||||
static void shutdown_linux() {
|
||||
stop_mixing = true;
|
||||
while (stop_mixing);
|
||||
audio_cat->debug() << "I believe the internal thread has exited" << endl;
|
||||
}
|
||||
|
||||
static void initialize() {
|
||||
if (have_initialized)
|
||||
return;
|
||||
if (!audio_is_active)
|
||||
return;
|
||||
|
||||
buffer1 = new byte[audio_buffer_size];
|
||||
buffer2 = new byte[audio_buffer_size];
|
||||
scratch_buffer = new byte[audio_buffer_size];
|
||||
fetch_buffer = new byte[audio_buffer_size];
|
||||
zero_buffer = new byte[audio_buffer_size];
|
||||
|
||||
for (int i=0; i<audio_buffer_size; ++i)
|
||||
zero_buffer[i] = 0;
|
||||
|
||||
current_buffer = buffer1;
|
||||
back_buffer = buffer2;
|
||||
|
||||
want_buffers = 2;
|
||||
have_buffers = 0;
|
||||
initializing = true;
|
||||
stop_mixing = false;
|
||||
|
||||
audio_cat->info() << "spawning internal update thread" << endl;
|
||||
update_thread = thread::create(internal_update, (void*)0L,
|
||||
thread::PRIORITY_NORMAL);
|
||||
|
||||
AudioManager::set_update_func(update_linux);
|
||||
AudioManager::set_shutdown_func(shutdown_linux);
|
||||
have_initialized = true;
|
||||
}
|
||||
|
||||
LinuxSample::~LinuxSample() {
|
||||
}
|
||||
|
||||
float LinuxSample::length() const {
|
||||
return _size / (audio_mix_freq * sample_size * 2.);
|
||||
}
|
||||
|
||||
AudioTraits::PlayingClass* LinuxSample::get_state() const {
|
||||
return new LinuxSamplePlaying((LinuxSample*)this);
|
||||
}
|
||||
|
||||
AudioTraits::PlayerClass* LinuxSample::get_player() const {
|
||||
return LinuxSamplePlayer::get_instance();
|
||||
}
|
||||
|
||||
AudioTraits::DeletePlayingFunc* LinuxSample::get_delstate() const {
|
||||
return LinuxSamplePlaying::destroy;
|
||||
}
|
||||
|
||||
LinuxSample* LinuxSample::load_raw(byte* data, unsigned long size) {
|
||||
LinuxSample* ret = new LinuxSample(data, size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
LinuxMusic::~LinuxMusic() {
|
||||
}
|
||||
|
||||
float LinuxMusic::length() const {
|
||||
return -1.;
|
||||
}
|
||||
|
||||
AudioTraits::PlayingClass* LinuxMusic::get_state() const {
|
||||
return new LinuxMusicPlaying((LinuxMusic*)this);
|
||||
}
|
||||
|
||||
AudioTraits::PlayerClass* LinuxMusic::get_player() const {
|
||||
return LinuxMusicPlayer::get_instance();
|
||||
}
|
||||
|
||||
AudioTraits::DeletePlayingFunc* LinuxMusic::get_delstate() const {
|
||||
return LinuxMusicPlaying::destroy;
|
||||
}
|
||||
|
||||
LinuxSamplePlaying::~LinuxSamplePlaying() {
|
||||
}
|
||||
|
||||
AudioTraits::PlayingClass::PlayingStatus LinuxSamplePlaying::status() {
|
||||
BufferSet::iterator i = buffers.find(_buff);
|
||||
if (i != buffers.end())
|
||||
return AudioTraits::PlayingClass::PLAYING;
|
||||
return AudioTraits::PlayingClass::READY;
|
||||
}
|
||||
|
||||
void LinuxSamplePlaying::destroy(AudioTraits::PlayingClass* state) {
|
||||
delete state;
|
||||
}
|
||||
|
||||
LinuxMusicPlaying::~LinuxMusicPlaying() {
|
||||
}
|
||||
|
||||
AudioTraits::PlayingClass::PlayingStatus LinuxMusicPlaying::status() {
|
||||
return AudioTraits::PlayingClass::BAD;
|
||||
}
|
||||
|
||||
void LinuxMusicPlaying::destroy(AudioTraits::PlayingClass* state) {
|
||||
delete state;
|
||||
}
|
||||
|
||||
LinuxSamplePlayer* LinuxSamplePlayer::_global_instance =
|
||||
(LinuxSamplePlayer*)0L;
|
||||
|
||||
LinuxSamplePlayer::~LinuxSamplePlayer() {
|
||||
}
|
||||
|
||||
void LinuxSamplePlayer::play_sound(AudioTraits::SoundClass*,
|
||||
AudioTraits::PlayingClass* playing,
|
||||
float start_time, int) {
|
||||
initialize();
|
||||
LinuxSamplePlaying* lplaying = (LinuxSamplePlaying*)playing;
|
||||
if (!AudioManager::get_sfx_active())
|
||||
return;
|
||||
unsigned long l = lplaying->get_data()->get_size();
|
||||
float factor = ((float)l) / (audio_mix_freq * 2. * sample_size);
|
||||
factor = start_time / factor;
|
||||
if (factor > 1.)
|
||||
factor = 1.;
|
||||
unsigned long p = (unsigned long)(l * factor);
|
||||
p = ( p >> 2 ) << 2; // zero the last 2 bits
|
||||
lplaying->get_data()->reset(p);
|
||||
buffers.insert(lplaying->get_data());
|
||||
}
|
||||
|
||||
void LinuxSamplePlayer::stop_sound(AudioTraits::SoundClass*,
|
||||
AudioTraits::PlayingClass* playing) {
|
||||
initialize();
|
||||
LinuxSamplePlaying* lplaying = (LinuxSamplePlaying*)playing;
|
||||
if (!AudioManager::get_sfx_active())
|
||||
return;
|
||||
buffers.erase(lplaying->get_data());
|
||||
}
|
||||
|
||||
void LinuxSamplePlayer::set_volume(AudioTraits::PlayingClass* p, float v) {
|
||||
p->set_volume(v);
|
||||
}
|
||||
|
||||
bool LinuxSamplePlayer::adjust_volume(AudioTraits::PlayingClass*) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LinuxSamplePlayer* LinuxSamplePlayer::get_instance() {
|
||||
if (_global_instance == (LinuxSamplePlayer*)0L)
|
||||
_global_instance = new LinuxSamplePlayer();
|
||||
return _global_instance;
|
||||
}
|
||||
|
||||
LinuxMusicPlayer* LinuxMusicPlayer::_global_instance =
|
||||
(LinuxMusicPlayer*)0L;
|
||||
|
||||
LinuxMusicPlayer::~LinuxMusicPlayer() {
|
||||
}
|
||||
|
||||
void LinuxMusicPlayer::play_sound(AudioTraits::SoundClass*,
|
||||
AudioTraits::PlayingClass*, float, int) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
void LinuxMusicPlayer::stop_sound(AudioTraits::SoundClass*,
|
||||
AudioTraits::PlayingClass*) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
void LinuxMusicPlayer::set_volume(AudioTraits::PlayingClass* p, float v) {
|
||||
p->set_volume(v);
|
||||
}
|
||||
|
||||
bool LinuxMusicPlayer::adjust_volume(AudioTraits::PlayingClass*) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LinuxMusicPlayer* LinuxMusicPlayer::get_instance() {
|
||||
if (_global_instance == (LinuxMusicPlayer*)0L)
|
||||
_global_instance = new LinuxMusicPlayer();
|
||||
return _global_instance;
|
||||
}
|
||||
|
||||
#endif /* AUDIO_USE_LINUX */
|
||||
|
|
@ -1,166 +0,0 @@
|
|||
// Filename: audio_linux_traits.h
|
||||
// Created by: cary (02Oct00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
// yes, this needs to be outside the ifdef protection
|
||||
#include "audio_trait.h"
|
||||
|
||||
#ifdef AUDIO_USE_LINUX
|
||||
|
||||
#ifndef __AUDIO_LINUX_TRAITS_H__
|
||||
#define __AUDIO_LINUX_TRAITS_H__
|
||||
|
||||
#include "config_audio.h"
|
||||
|
||||
#ifndef HAVE_DEFINED_BYTE
|
||||
typedef unsigned char byte;
|
||||
#define HAVE_DEFINED_BYTE
|
||||
#endif /* HAVE_DEFINED_BYTE */
|
||||
|
||||
extern byte* zero_buffer;
|
||||
|
||||
class EXPCL_PANDA Buffer {
|
||||
private:
|
||||
byte* _data;
|
||||
unsigned long _size;
|
||||
unsigned long _pos;
|
||||
bool _done;
|
||||
|
||||
INLINE unsigned long buffer_min(unsigned long a, unsigned long b) {
|
||||
return (a<b)?a:b;
|
||||
}
|
||||
public:
|
||||
INLINE Buffer(byte* data, unsigned long size) : _data(data), _size(size),
|
||||
_pos(0), _done(false) {}
|
||||
INLINE byte* get_buffer(byte* buf) {
|
||||
unsigned long copy_size = buffer_min(_size-_pos, audio_buffer_size);
|
||||
unsigned long residue = audio_buffer_size - copy_size;
|
||||
memcpy(buf, &_data[_pos], copy_size);
|
||||
_pos += copy_size;
|
||||
if (residue != 0) {
|
||||
_pos -= _size;
|
||||
memcpy(&buf[copy_size], zero_buffer, residue);
|
||||
_done = true;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
INLINE bool is_done() const {
|
||||
return _done;
|
||||
}
|
||||
INLINE unsigned long get_size() const {
|
||||
return _size;
|
||||
}
|
||||
INLINE void reset(unsigned long p = 0) {
|
||||
_done = false;
|
||||
_pos = p;
|
||||
}
|
||||
};
|
||||
|
||||
class LinuxSamplePlaying;
|
||||
|
||||
class EXPCL_PANDA LinuxSample : public AudioTraits::SoundClass {
|
||||
private:
|
||||
byte* _data;
|
||||
unsigned long _size;
|
||||
public:
|
||||
INLINE LinuxSample(byte*, unsigned long);
|
||||
virtual ~LinuxSample();
|
||||
|
||||
virtual float length() const;
|
||||
virtual AudioTraits::PlayingClass* get_state() const;
|
||||
virtual AudioTraits::PlayerClass* get_player() const;
|
||||
virtual AudioTraits::DeletePlayingFunc* get_delstate() const;
|
||||
public:
|
||||
// used by the loader
|
||||
static LinuxSample* load_raw(byte*, unsigned long);
|
||||
// used by the players
|
||||
INLINE byte* get_data() const;
|
||||
INLINE unsigned long get_size() const;
|
||||
};
|
||||
|
||||
class EXPCL_PANDA LinuxMusic : public AudioTraits::SoundClass {
|
||||
public:
|
||||
INLINE LinuxMusic();
|
||||
virtual ~LinuxMusic();
|
||||
|
||||
virtual float length() const;
|
||||
virtual AudioTraits::PlayingClass* get_state() const;
|
||||
virtual AudioTraits::PlayerClass* get_player() const;
|
||||
virtual AudioTraits::DeletePlayingFunc* get_delstate() const;
|
||||
};
|
||||
|
||||
class EXPCL_PANDA LinuxSamplePlaying : public AudioTraits::PlayingClass {
|
||||
Buffer* _buff;
|
||||
public:
|
||||
INLINE LinuxSamplePlaying(AudioTraits::SoundClass*);
|
||||
virtual ~LinuxSamplePlaying();
|
||||
|
||||
virtual AudioTraits::PlayingClass::PlayingStatus status();
|
||||
public:
|
||||
INLINE Buffer* get_data();
|
||||
static void destroy(AudioTraits::PlayingClass*);
|
||||
};
|
||||
|
||||
class EXPCL_PANDA LinuxMusicPlaying : public AudioTraits::PlayingClass {
|
||||
public:
|
||||
INLINE LinuxMusicPlaying(AudioTraits::SoundClass*);
|
||||
virtual ~LinuxMusicPlaying();
|
||||
|
||||
virtual AudioTraits::PlayingClass::PlayingStatus status();
|
||||
static void destroy(AudioTraits::PlayingClass*);
|
||||
};
|
||||
|
||||
class EXPCL_PANDA LinuxSamplePlayer : public AudioTraits::PlayerClass {
|
||||
public:
|
||||
INLINE LinuxSamplePlayer();
|
||||
virtual ~LinuxSamplePlayer();
|
||||
|
||||
virtual void play_sound(AudioTraits::SoundClass*,
|
||||
AudioTraits::PlayingClass*, float, int);
|
||||
virtual void stop_sound(AudioTraits::SoundClass*,
|
||||
AudioTraits::PlayingClass*);
|
||||
virtual void set_volume(AudioTraits::PlayingClass*, float);
|
||||
virtual bool adjust_volume(AudioTraits::PlayingClass*);
|
||||
public:
|
||||
// used by the readers
|
||||
static LinuxSamplePlayer* get_instance();
|
||||
private:
|
||||
static LinuxSamplePlayer* _global_instance;
|
||||
};
|
||||
|
||||
class EXPCL_PANDA LinuxMusicPlayer : public AudioTraits::PlayerClass {
|
||||
public:
|
||||
INLINE LinuxMusicPlayer();
|
||||
virtual ~LinuxMusicPlayer();
|
||||
|
||||
virtual void play_sound(AudioTraits::SoundClass*,
|
||||
AudioTraits::PlayingClass*, float, int);
|
||||
virtual void stop_sound(AudioTraits::SoundClass*,
|
||||
AudioTraits::PlayingClass*);
|
||||
virtual void set_volume(AudioTraits::PlayingClass*, float);
|
||||
virtual bool adjust_volume(AudioTraits::PlayingClass*);
|
||||
public:
|
||||
// used by the readers
|
||||
static LinuxMusicPlayer* get_instance();
|
||||
private:
|
||||
static LinuxMusicPlayer* _global_instance;
|
||||
};
|
||||
|
||||
#include "audio_linux_traits.I"
|
||||
|
||||
#endif /* __AUDIO_LINUX_TRAITS_H__ */
|
||||
#endif /* AUDIO_USE_LINUX */
|
||||
|
|
@ -1,209 +0,0 @@
|
|||
// Filename: audio_manager.I
|
||||
// Created by: cary (24Sep00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::play (AudioSound)
|
||||
// Access: Public, Static
|
||||
// Description: Play some audio
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void AudioManager::play(AudioSound* sound, float start_time, int loop) {
|
||||
if (audio_is_active)
|
||||
get_ptr()->ns_play(sound, start_time, loop);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::update
|
||||
// Access: Public, Static
|
||||
// Description: make sure buffers are full
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void AudioManager::update() {
|
||||
if (!audio_is_active) {
|
||||
return;
|
||||
}
|
||||
// Copy the loopset under a mutex:
|
||||
{
|
||||
mutex_lock l(_manager_mutex);
|
||||
get_ptr()->copy_loopset();
|
||||
}
|
||||
if (_update_func) {
|
||||
(*_update_func)();
|
||||
}
|
||||
get_ptr()->ns_update();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::spawn_update
|
||||
// Access: Public, Static
|
||||
// Description: spawn a thread to call update
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void AudioManager::spawn_update() {
|
||||
if (audio_is_active) {
|
||||
get_ptr()->ns_spawn_update();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::shutdown
|
||||
// Access: Public, Static
|
||||
// Description: kill any internal threads, free any internal data
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void AudioManager::shutdown() {
|
||||
get_ptr()->ns_shutdown();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::set_volume (sound)
|
||||
// Access: Public, Static
|
||||
// Description: set the volume on a sound instance
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void AudioManager::set_volume(AudioSound* sound, float v) {
|
||||
if (audio_is_active) {
|
||||
get_ptr()->ns_set_volume(sound, v);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::stop
|
||||
// Access: Public, Static
|
||||
// Description: stop playing a given sound
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void AudioManager::stop(AudioSound* sound) {
|
||||
if (audio_is_active) {
|
||||
get_ptr()->ns_stop(sound);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef AUDIO_USE_RAD_MSS //[
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::stop
|
||||
// Access: Public, Static
|
||||
// Description: set the looping state of the given sound
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void AudioManager::set_loop(AudioSound* sound, bool state) {
|
||||
if (audio_is_active) {
|
||||
get_ptr()->ns_set_loop(sound, state);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::get_loop
|
||||
// Access: Public, Static
|
||||
// Description: return the looping state of the given sound
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool AudioManager::get_loop(AudioSound* sound) {
|
||||
return get_ptr()->ns_get_loop(sound);
|
||||
}
|
||||
#endif //]
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::Constructor
|
||||
// Access: Private
|
||||
// Description: The constructor is not intended to be called
|
||||
// directly; there's only supposed to be one AudioManager
|
||||
// in the universe and it constructs itself.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE AudioManager::AudioManager() {
|
||||
_sfx_active = _hard_sfx_active = audio_sfx_active;
|
||||
_music_active = _hard_music_active = audio_music_active;
|
||||
_master_sfx_volume = audio_master_sfx_volume;
|
||||
_master_music_volume = audio_master_music_volume;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::get_master_sfx_volume
|
||||
// Access: Public, Static
|
||||
// Description: return the overall volume of SFX
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float AudioManager::get_master_sfx_volume() {
|
||||
get_ptr();
|
||||
return AudioManager::_master_sfx_volume;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::get_master_music_volume
|
||||
// Access: Public, Static
|
||||
// Description: return the overall volume of music
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float AudioManager::get_master_music_volume() {
|
||||
get_ptr();
|
||||
return AudioManager::_master_music_volume;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::set_all_sound_active
|
||||
// Access: Public, Static
|
||||
// Description: turn on/off all audio
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void AudioManager::set_all_sound_active(bool f) {
|
||||
get_ptr();
|
||||
audio_is_active = f;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::set_all_sound_active
|
||||
// Access: Public, Static
|
||||
// Description: turn on/off all audio
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool AudioManager::get_all_sound_active() {
|
||||
get_ptr();
|
||||
return audio_is_active;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::get_sfx_active
|
||||
// Access: Public, Static
|
||||
// Description: return the state of SFX playing
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool AudioManager::get_sfx_active() {
|
||||
get_ptr();
|
||||
return (AudioManager::_sfx_active && audio_is_active);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::get_music_active
|
||||
// Access: Public, Static
|
||||
// Description: return the state of music playing
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool AudioManager::get_music_active() {
|
||||
get_ptr();
|
||||
return (AudioManager::_music_active && audio_is_active);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::set_hard_sfx_active
|
||||
// Access: Public, Static
|
||||
// Description: set the hardware availability state for SFX
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void AudioManager::set_hard_sfx_active(bool f) {
|
||||
get_ptr();
|
||||
AudioManager::_hard_sfx_active = f;
|
||||
if (!f)
|
||||
AudioManager::_sfx_active = f;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::set_hard_music_active
|
||||
// Access: Public, Static
|
||||
// Description: set the hardware availability state for music
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void AudioManager::set_hard_music_active(bool f) {
|
||||
get_ptr();
|
||||
AudioManager::_hard_music_active = f;
|
||||
if (!f)
|
||||
AudioManager::_music_active = f;
|
||||
}
|
||||
|
|
@ -1,404 +0,0 @@
|
|||
// Filename: audio_manager.cxx
|
||||
// Created by: cary (24Sep00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "audio_manager.h"
|
||||
#include "config_audio.h"
|
||||
|
||||
#ifdef AUDIO_USE_RAD_MSS //[
|
||||
#include "mss.h"
|
||||
#endif //]
|
||||
|
||||
|
||||
// Statics (all default to zero):
|
||||
AudioManager* AudioManager::_global_ptr;
|
||||
AudioManager::UpdateFunc* AudioManager::_update_func;
|
||||
AudioManager::ShutdownFunc* AudioManager::_shutdown_func;
|
||||
mutex AudioManager::_manager_mutex;
|
||||
volatile bool AudioManager::_quit;
|
||||
thread* AudioManager::_spawned;
|
||||
AudioManager::LoopSet* AudioManager::_loopset;
|
||||
AudioManager::LoopSet* AudioManager::_loopcopy;
|
||||
bool AudioManager::_sfx_active;
|
||||
bool AudioManager::_music_active;
|
||||
bool AudioManager::_hard_sfx_active;
|
||||
bool AudioManager::_hard_music_active;
|
||||
bool AudioManager::_master_volume_change;
|
||||
float AudioManager::_master_sfx_volume;
|
||||
float AudioManager::_master_music_volume;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::destructor
|
||||
// Access: Public
|
||||
// Description: delete the AudioManager singleton
|
||||
////////////////////////////////////////////////////////////////////
|
||||
AudioManager::
|
||||
~AudioManager() {
|
||||
shutdown();
|
||||
_global_ptr = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::set_update_func
|
||||
// Access: Public, Static
|
||||
// Description: register a function that will maintain the buffers
|
||||
// for audio output
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AudioManager::
|
||||
set_update_func(AudioManager::UpdateFunc* func) {
|
||||
if (_update_func) {
|
||||
audio_error("There maybe be more then one audio driver installed");
|
||||
}
|
||||
_update_func = func;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::copy_loopset
|
||||
// Access: Public, Static
|
||||
// Description: make a copy of the loopset to use for the rest of
|
||||
// update
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AudioManager::
|
||||
copy_loopset() {
|
||||
if (!_loopcopy) {
|
||||
_loopcopy = new LoopSet;
|
||||
}
|
||||
if (_loopset) {
|
||||
*_loopcopy = *_loopset;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::ns_update
|
||||
// Access: Public, Static
|
||||
// Description: do generic update stuff
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AudioManager::
|
||||
ns_update() {
|
||||
#ifndef AUDIO_USE_RAD_MSS //[
|
||||
// handle looping
|
||||
if (_loopcopy) {
|
||||
LoopSet::iterator i=_loopcopy->begin();
|
||||
for (; i!=_loopcopy->end(); ++i) {
|
||||
AudioSound* sound = *i;
|
||||
if (sound->status() == AudioSound::READY) {
|
||||
audio_debug("AudioManager::ns_update looping '"
|
||||
<< sound->get_name() << "'");
|
||||
AudioManager::play(sound);
|
||||
AudioManager::set_loop(sound, true);
|
||||
} else if (AudioManager::_master_volume_change) {
|
||||
if (sound->get_player()->adjust_volume(sound->get_state())) {
|
||||
audio_debug("AudioManager::ns_update sound is turned "
|
||||
<< "off, stopping '" << sound->get_name() << "'");
|
||||
AudioManager::stop(sound);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
AudioManager::_master_volume_change = false;
|
||||
#endif //]
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::set_shutdown_func
|
||||
// Access: Public, Static
|
||||
// Description: register a function that will shutdown the internal
|
||||
// audio state
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AudioManager::
|
||||
set_shutdown_func(AudioManager::ShutdownFunc* func) {
|
||||
if (_shutdown_func) {
|
||||
audio_error("There maybe be more then one audio driver installed");
|
||||
}
|
||||
_shutdown_func = func;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::get_ptr
|
||||
// Access: Private, Static
|
||||
// Description: Initializes and/or returns the global pointer to the
|
||||
// one AudioManager object in the system.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
AudioManager* AudioManager::
|
||||
get_ptr() {
|
||||
if (!_global_ptr) {
|
||||
_global_ptr = new AudioManager;
|
||||
}
|
||||
return _global_ptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::ns_play (AudioSound)
|
||||
// Access: Private
|
||||
// Description: get the player off the sound, and start it playing
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AudioManager::
|
||||
ns_play(AudioSound* sound, float start_time, int loop) {
|
||||
audio_debug("AudioManager::ns_play(sound=0x"<<(void*)sound<<", start_time="<<start_time<<", loop="<<loop<<")");
|
||||
audio_debug(" name="<<sound->get_name());
|
||||
if (sound->status() == AudioSound::PLAYING) {
|
||||
this->ns_stop(sound);
|
||||
}
|
||||
#ifndef AUDIO_USE_RAD_MSS //[
|
||||
sound->get_player()->play_sound(sound->get_sound(),
|
||||
sound->get_state(), start_time, loop);
|
||||
ns_set_loop(sound, loop);
|
||||
sound->get_player()->adjust_volume(sound->get_state());
|
||||
#else //][
|
||||
sound->get_player()->play_sound(sound->get_sound(),
|
||||
sound->get_state(), start_time, loop);
|
||||
#endif //]
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::ns_stop (AudioSound)
|
||||
// Access: Private
|
||||
// Description: get the player off the sound, and stop it playing
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AudioManager::
|
||||
ns_stop(AudioSound* sound) {
|
||||
audio_debug("AudioManager: stopping sound 0x"
|
||||
<< (void*)sound << " (" << sound->get_name() << ")");
|
||||
#ifndef AUDIO_USE_RAD_MSS //[
|
||||
this->ns_set_loop(sound, false);
|
||||
#endif //]
|
||||
if (sound->status() == AudioSound::PLAYING) {
|
||||
sound->get_player()->stop_sound(sound->get_sound(), sound->get_state());
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef AUDIO_USE_RAD_MSS //[
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::ns_set_loop (AudioSound)
|
||||
// Access: Private
|
||||
// Description: set the looping state of the given sound
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AudioManager::
|
||||
ns_set_loop(AudioSound* sound, bool state) {
|
||||
#ifndef AUDIO_USE_RAD_MSS //[
|
||||
mutex_lock l(_manager_mutex);
|
||||
if (!_loopset) {
|
||||
_loopset = new LoopSet;
|
||||
}
|
||||
if (state) {
|
||||
_loopset->insert(sound);
|
||||
} else {
|
||||
_loopset->erase(sound);
|
||||
}
|
||||
#else //][
|
||||
/////sound->get_player()->set_loop_count((state)?0:1);
|
||||
#endif //]
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::ns_get_loop (AudioSound)
|
||||
// Access: Private
|
||||
// Description: get the looping state of the given sound
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool AudioManager::
|
||||
ns_get_loop(AudioSound* sound) {
|
||||
mutex_lock l(_manager_mutex);
|
||||
if (!_loopset) {
|
||||
return false;
|
||||
}
|
||||
LoopSet::iterator i = _loopset->find(sound);
|
||||
return i != _loopset->end();
|
||||
}
|
||||
#endif //]
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::spawned_update
|
||||
// Access: static
|
||||
// Description: the thread function to call update forever.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void* AudioManager::
|
||||
spawned_update(void* data) {
|
||||
#ifndef HAVE_RAD_MSS //[
|
||||
bool* flag = (bool*)data;
|
||||
try {
|
||||
// *flag connects to AudioManager::_quit
|
||||
while (! (*flag)) {
|
||||
AudioManager::update();
|
||||
ipc_traits::sleep(0, audio_auto_update_delay);
|
||||
}
|
||||
} catch (...) {
|
||||
audio_error("Uncought Exception in audio update thread.");
|
||||
throw;
|
||||
}
|
||||
// Switch the flag back to false,
|
||||
// so AudioManager::ns_shutdown()
|
||||
// knows we're done:
|
||||
*flag = false;
|
||||
audio_debug("exiting update thread");
|
||||
return 0;
|
||||
#else //][
|
||||
return 0;
|
||||
#endif //]
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::ns_set_volume (AudioSound)
|
||||
// Access: Private
|
||||
// Description: get the player off the sound, and set volume on it
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AudioManager::
|
||||
ns_set_volume(AudioSound* sound, float v) {
|
||||
sound->get_player()->set_volume(sound->get_state(), v);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::set_master_sfx_volume
|
||||
// Access: Public, Static
|
||||
// Description: set the overall volume of SFX
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AudioManager::set_master_sfx_volume(float v) {
|
||||
AudioManager::_master_sfx_volume = v;
|
||||
AudioManager::_master_volume_change = true;
|
||||
#ifdef AUDIO_USE_RAD_MSS //[
|
||||
HDIGDRIVER dig;
|
||||
AIL_quick_handles(&dig, 0, 0);
|
||||
S32 volume=((int)(127*v))%128;
|
||||
AIL_set_digital_master_volume(dig, volume);
|
||||
#endif //]
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::set_master_music_volume
|
||||
// Access: Public, Static
|
||||
// Description: set the overall volume of music
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AudioManager::set_master_music_volume(float v) {
|
||||
get_ptr();
|
||||
AudioManager::_master_music_volume = v;
|
||||
AudioManager::_master_volume_change = true;
|
||||
#ifdef AUDIO_USE_RAD_MSS //[
|
||||
HMDIDRIVER mdi;
|
||||
AIL_quick_handles(0, &mdi, 0);
|
||||
S32 volume=((int)(127*v))%128;
|
||||
AIL_set_XMIDI_master_volume(mdi, volume);
|
||||
#endif //]
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::set_sfx_active
|
||||
// Access: Public, Static
|
||||
// Description: turn on/off SFX
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void AudioManager::set_sfx_active(bool f) {
|
||||
get_ptr();
|
||||
if (f) {
|
||||
if (AudioManager::_hard_sfx_active) {
|
||||
AudioManager::_sfx_active = f;
|
||||
AudioManager::_master_volume_change = true;
|
||||
}
|
||||
} else {
|
||||
AudioManager::_sfx_active = f;
|
||||
AudioManager::_master_volume_change = true;
|
||||
}
|
||||
#ifdef AUDIO_USE_RAD_MSS //[
|
||||
if (f) {
|
||||
set_master_sfx_volume(_master_sfx_volume);
|
||||
} else {
|
||||
HDIGDRIVER dig;
|
||||
AIL_quick_handles(&dig, 0, 0);
|
||||
AIL_set_digital_master_volume(dig, 0);
|
||||
}
|
||||
#endif //]
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::set_music_active
|
||||
// Access: Public, Static
|
||||
// Description: turn on/off music
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void AudioManager::set_music_active(bool f) {
|
||||
get_ptr();
|
||||
if (f) {
|
||||
if (AudioManager::_hard_music_active) {
|
||||
AudioManager::_music_active = f;
|
||||
AudioManager::_master_volume_change = true;
|
||||
}
|
||||
} else {
|
||||
AudioManager::_music_active = f;
|
||||
AudioManager::_master_volume_change = true;
|
||||
}
|
||||
#ifdef AUDIO_USE_RAD_MSS //[
|
||||
if (f) {
|
||||
set_master_music_volume(_master_music_volume);
|
||||
} else {
|
||||
HMDIDRIVER mdi;
|
||||
AIL_quick_handles(0, &mdi, 0);
|
||||
AIL_set_XMIDI_master_volume(mdi, 0);
|
||||
}
|
||||
#endif //]
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::ns_spawn_update
|
||||
// Access: Private
|
||||
// Description: spawn a thread that calls update every so often
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AudioManager::
|
||||
ns_spawn_update() {
|
||||
#ifndef HAVE_RAD_MSS //[
|
||||
if (!_spawned) {
|
||||
_quit = false;
|
||||
thread::priority_t pri;
|
||||
switch (audio_thread_priority) {
|
||||
case 0:
|
||||
pri = thread::PRIORITY_LOW;
|
||||
break;
|
||||
case 1:
|
||||
pri = thread::PRIORITY_NORMAL;
|
||||
break;
|
||||
case 2:
|
||||
pri = thread::PRIORITY_HIGH;
|
||||
break;
|
||||
default:
|
||||
audio_error("audio-thread-priority set to something other "
|
||||
<< "then low, normal, or high");
|
||||
audio_thread_priority = 1;
|
||||
pri = thread::PRIORITY_NORMAL;
|
||||
}
|
||||
_spawned = thread::create(spawned_update, (void*)&_quit, pri);
|
||||
} else {
|
||||
audio_error("tried to spawn 2 update threads");
|
||||
}
|
||||
#endif //]
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioManager::ns_shutdown
|
||||
// Access: Private
|
||||
// Description: non-static implementation of shutdown stuff
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AudioManager::
|
||||
ns_shutdown() {
|
||||
audio_debug("AudioManager::ns_shutdown()");
|
||||
_quit = true;
|
||||
if (_shutdown_func) {
|
||||
(*_shutdown_func)();
|
||||
}
|
||||
#ifndef HAVE_RAD_MSS //[
|
||||
if (_spawned) {
|
||||
while (_quit) {
|
||||
// waiting on update thread to stop spinning.
|
||||
}
|
||||
}
|
||||
#endif //]
|
||||
audio_debug("update thread has shutdown");
|
||||
}
|
||||
|
|
@ -1,112 +0,0 @@
|
|||
// Filename: audio_manager.h
|
||||
// Created by: cary (22Sep00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __AUDIO_MANAGER_H__
|
||||
#define __AUDIO_MANAGER_H__
|
||||
|
||||
#include "audio_trait.h"
|
||||
#include "audio_sound.h"
|
||||
#include "config_audio.h"
|
||||
|
||||
#include <ipc_mutex.h>
|
||||
#include <ipc_thread.h>
|
||||
#include "pset.h"
|
||||
|
||||
class EXPCL_PANDA AudioManager {
|
||||
typedef void UpdateFunc();
|
||||
typedef void ShutdownFunc();
|
||||
typedef pset<AudioSound*> LoopSet;
|
||||
|
||||
PUBLISHED:
|
||||
INLINE static void play(AudioSound*, float start_time= 0.0, int loop=0);
|
||||
INLINE static void stop(AudioSound*);
|
||||
|
||||
#ifndef AUDIO_USE_RAD_MSS //[
|
||||
INLINE static void set_loop(AudioSound*, bool loop);
|
||||
INLINE static bool get_loop(AudioSound*);
|
||||
#endif //]
|
||||
|
||||
INLINE static void set_volume(AudioSound*, float volume);
|
||||
|
||||
INLINE static void update();
|
||||
INLINE static void spawn_update();
|
||||
|
||||
INLINE static void shutdown();
|
||||
|
||||
static void set_master_sfx_volume(float volume);
|
||||
INLINE static float get_master_sfx_volume();
|
||||
|
||||
static void set_master_music_volume(float volume);
|
||||
INLINE static float get_master_music_volume();
|
||||
|
||||
INLINE static void set_all_sound_active(bool);
|
||||
INLINE static bool get_all_sound_active();
|
||||
|
||||
static void set_sfx_active(bool);
|
||||
INLINE static bool get_sfx_active();
|
||||
|
||||
static void set_music_active(bool);
|
||||
INLINE static bool get_music_active();
|
||||
|
||||
public:
|
||||
INLINE static void set_hard_sfx_active(bool);
|
||||
INLINE static void set_hard_music_active(bool);
|
||||
|
||||
virtual ~AudioManager();
|
||||
|
||||
static void set_update_func(UpdateFunc*);
|
||||
static void set_shutdown_func(ShutdownFunc*);
|
||||
|
||||
private:
|
||||
INLINE AudioManager();
|
||||
|
||||
void copy_loopset();
|
||||
void ns_play(AudioSound*, float start_time, int loop);
|
||||
void ns_stop(AudioSound*);
|
||||
#ifndef AUDIO_USE_RAD_MSS //[
|
||||
void ns_set_loop(AudioSound*, bool loop);
|
||||
bool ns_get_loop(AudioSound*);
|
||||
#endif //]
|
||||
void ns_set_volume(AudioSound*, float volume);
|
||||
void ns_spawn_update();
|
||||
void ns_shutdown();
|
||||
void ns_update();
|
||||
|
||||
static AudioManager* get_ptr();
|
||||
static void* spawned_update(void*);
|
||||
|
||||
static AudioManager* _global_ptr;
|
||||
static UpdateFunc* _update_func;
|
||||
static ShutdownFunc* _shutdown_func;
|
||||
static mutex _manager_mutex;
|
||||
volatile static bool _quit;
|
||||
static thread* _spawned;
|
||||
static LoopSet* _loopset;
|
||||
static LoopSet* _loopcopy;
|
||||
static bool _sfx_active;
|
||||
static bool _music_active;
|
||||
static bool _hard_sfx_active;
|
||||
static bool _hard_music_active;
|
||||
static float _master_sfx_volume;
|
||||
static float _master_music_volume;
|
||||
static bool _master_volume_change;
|
||||
};
|
||||
|
||||
#include "audio_manager.I"
|
||||
|
||||
#endif /* __AUDIO_MANAGER_H__ */
|
||||
|
|
@ -1,254 +0,0 @@
|
|||
// Filename: audio_midi.cxx
|
||||
// Created by: cary (26Sep00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "audio_midi.h"
|
||||
#include "config_audio.h"
|
||||
#include <pandabase.h> // get iostream and fstream
|
||||
|
||||
#define SHORT short
|
||||
#define LONG long
|
||||
|
||||
#define RIFF 0x52494646
|
||||
#define CTMF 0x43544d46
|
||||
#define MThd 0x4d546864
|
||||
#define MTrk 0x4d54726b
|
||||
|
||||
// take data off the supplimental stream until it's empty
|
||||
inline static unsigned char read8(istream& is, istream& supp) {
|
||||
unsigned char b;
|
||||
if (supp.eof()) {
|
||||
is >> b;
|
||||
} else {
|
||||
supp >> b;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
inline static unsigned SHORT read16(istream& is, istream& supp) {
|
||||
unsigned char b1, b2;
|
||||
b1 = read8(is, supp);
|
||||
b2 = read8(is, supp);
|
||||
unsigned SHORT ret = (b1 << 8) | (b2);
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline static unsigned LONG read32(istream& is, istream& supp) {
|
||||
unsigned char b1, b2, b3, b4;
|
||||
b1 = read8(is, supp);
|
||||
b2 = read8(is, supp);
|
||||
b3 = read8(is, supp);
|
||||
b4 = read8(is, supp);
|
||||
unsigned int LONG ret = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline static void scroll8(unsigned LONG& prev, unsigned LONG& curr,
|
||||
istream& is, istream& supp) {
|
||||
unsigned char b1 = ((curr >> 24) & 0xff);
|
||||
prev = ((prev << 8) & 0xffffff00) | (b1);
|
||||
b1 = read8(is, supp);
|
||||
curr = ((curr << 8) & 0xffffff00) | (b1);
|
||||
}
|
||||
|
||||
AudioMidi::AudioMidi(Filename filename, int header_idx) {
|
||||
filename.set_binary();
|
||||
ifstream in;
|
||||
if (!filename.open_read(in)) {
|
||||
cerr << "ACK, cannot read '" << filename << "'" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
istringstream dummy("");
|
||||
unsigned LONG prev = 0x0;
|
||||
unsigned LONG curr = read32(in, dummy);
|
||||
int count = 0;
|
||||
bool done = false;
|
||||
while (1) {
|
||||
if (curr == MThd) {
|
||||
++count;
|
||||
if (count == header_idx) {
|
||||
break;
|
||||
} else {
|
||||
scroll8(prev, curr, in, dummy);
|
||||
scroll8(prev, curr, in, dummy);
|
||||
scroll8(prev, curr, in, dummy);
|
||||
scroll8(prev, curr, in, dummy);
|
||||
}
|
||||
} else {
|
||||
scroll8(prev, curr, in, dummy);
|
||||
}
|
||||
if (in.eof()) {
|
||||
cerr << "fewer than " << header_idx << " headers in file (" << count
|
||||
<< ")" << endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (prev == RIFF) {
|
||||
if (audio_cat.is_debug()) {
|
||||
audio_cat->debug() << "it's a RIFF file" << endl;
|
||||
}
|
||||
curr = read32(in, dummy);
|
||||
curr = read32(in, dummy);
|
||||
curr = read32(in, dummy);
|
||||
curr = read32(in, dummy);
|
||||
}
|
||||
unsigned LONG tracklen;
|
||||
unsigned SHORT format;
|
||||
unsigned SHORT numtracks;
|
||||
unsigned SHORT division;
|
||||
if (curr == MThd) {
|
||||
if (audio_cat.is_debug())
|
||||
audio_cat->debug() << "easy header" << endl;
|
||||
tracklen = read32(in, dummy);
|
||||
format = read16(in, dummy);
|
||||
numtracks = read16(in, dummy);
|
||||
division = read16(in, dummy);
|
||||
} else if (curr == CTMF) {
|
||||
// Creative Labs CMF file. We're not supporting this yet
|
||||
cerr << "don't support Creative Labs CMF files yet" << endl;
|
||||
return;
|
||||
} else {
|
||||
if (audio_cat.is_debug())
|
||||
audio_cat->debug() << "hard header" << endl;
|
||||
done = false;
|
||||
do {
|
||||
if (curr == MThd)
|
||||
done = true;
|
||||
else
|
||||
scroll8(prev, curr, in, dummy);
|
||||
if (in.eof())
|
||||
done = true;
|
||||
} while (!done);
|
||||
if (in.eof()) {
|
||||
cerr << "truncated file!" << endl;
|
||||
return;
|
||||
}
|
||||
tracklen = read32(in, dummy);
|
||||
format = read16(in, dummy);
|
||||
numtracks = read16(in, dummy);
|
||||
division = read16(in, dummy);
|
||||
}
|
||||
if (audio_cat.is_debug()) {
|
||||
audio_cat->debug() << "Read header. tracklen = " << tracklen
|
||||
<< " format = " << format << " numtracks = "
|
||||
<< numtracks << " division = " << division << endl;
|
||||
}
|
||||
for (int currtrack = 0; currtrack < numtracks; ++currtrack) {
|
||||
string fudge;
|
||||
curr = read32(in, dummy);
|
||||
if (curr != MTrk) {
|
||||
if (audio_cat.is_debug()) {
|
||||
audio_cat->debug() << "having to seach for track #"
|
||||
<< currtrack << endl;
|
||||
}
|
||||
if (curr == MThd) {
|
||||
if (audio_cat.is_debug()) {
|
||||
audio_cat->debug() << "hit a header instead, skipping track" << endl;
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
done = false;
|
||||
if (currtrack > 0) {
|
||||
string stmp = (*(_seq.rbegin()));
|
||||
int i = stmp.rfind("MTrk");
|
||||
if (i != string::npos) {
|
||||
fudge = stmp.substr(i+4, string::npos);
|
||||
unsigned char b;
|
||||
b = ((curr >> 24) & 0xff);
|
||||
fudge += b;
|
||||
b = ((curr >> 16) & 0xff);
|
||||
fudge += b;
|
||||
b = ((curr >> 8) & 0xff);
|
||||
fudge += b;
|
||||
b = (curr & 0xff);
|
||||
fudge += b;
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
if (!done) {
|
||||
do {
|
||||
if (curr == MTrk) {
|
||||
done = true;
|
||||
} else {
|
||||
scroll8(prev, curr, in, dummy);
|
||||
}
|
||||
if (in.eof()) {
|
||||
done = true;
|
||||
}
|
||||
} while (!done);
|
||||
if (in.eof()) {
|
||||
cerr << "truncated file" << endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (audio_cat.is_debug()) {
|
||||
audio_cat->debug() << "fudge = '" << fudge << "'" << endl;
|
||||
}
|
||||
istringstream fudges(fudge);
|
||||
if (fudge.empty()) {
|
||||
// force EOF
|
||||
unsigned char b;
|
||||
fudges >> b;
|
||||
}
|
||||
unsigned LONG thislen = read32(in, fudges);
|
||||
if (audio_cat.is_debug())
|
||||
audio_cat->debug() << "found track #" << currtrack << " with length = "
|
||||
<< thislen << endl;
|
||||
{
|
||||
ostringstream os;
|
||||
int i;
|
||||
for (i=0; i<thislen; ++i) {
|
||||
unsigned char b;
|
||||
b = read8(in, fudges);
|
||||
os << b;
|
||||
if (in.eof() && ((i+1) < thislen))
|
||||
break;
|
||||
}
|
||||
if (in.eof() && (i != thislen)) {
|
||||
cerr << "truncated file" << endl;
|
||||
}
|
||||
string s = os.str();
|
||||
_seq.push_back(s);
|
||||
if (audio_cat.is_debug()) {
|
||||
audio_cat->debug() << "track data (" << s.length() << "): '" << s
|
||||
<< "'" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((_seq.size() != numtracks) && audio_cat.is_debug()) {
|
||||
audio_cat->debug()
|
||||
<< "actual number of tracks read does not match header. ("
|
||||
<< _seq.size() << " != " << numtracks << ")" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
AudioMidi::AudioMidi(const AudioMidi& c) : _seq(c._seq) {
|
||||
}
|
||||
|
||||
AudioMidi::~AudioMidi() {
|
||||
}
|
||||
|
||||
AudioMidi& AudioMidi::operator=(const AudioMidi&) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool AudioMidi::operator==(const AudioMidi&) const {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
// Filename: audio_midi.h
|
||||
// Created by: cary (26Sep00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __AUDIO_MIDI_H__
|
||||
#define __AUDIO_MIDI_H__
|
||||
|
||||
#include <filename.h>
|
||||
#include "plist.h"
|
||||
|
||||
// define an internal representation for a midi file
|
||||
class AudioMidi {
|
||||
private:
|
||||
typedef plist<string> StrList;
|
||||
StrList _seq;
|
||||
public:
|
||||
AudioMidi(Filename filename, int header_idx = 1);
|
||||
AudioMidi(const AudioMidi&);
|
||||
~AudioMidi();
|
||||
|
||||
AudioMidi& operator=(const AudioMidi&);
|
||||
bool operator==(const AudioMidi&) const;
|
||||
};
|
||||
|
||||
#endif /* __AUDIO_MIDI_H__ */
|
||||
|
|
@ -1,427 +0,0 @@
|
|||
// Filename: audio_mikmod_traits.cxx
|
||||
// Created by: cary (23Sep00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "audio_mikmod_traits.h"
|
||||
|
||||
#ifdef AUDIO_USE_MIKMOD
|
||||
|
||||
#include "audio_manager.h"
|
||||
#include "config_audio.h"
|
||||
#include "plist.h"
|
||||
#include <serialization.h>
|
||||
|
||||
static bool have_initialized = false;
|
||||
static bool initialization_error = false;
|
||||
|
||||
static void update_mikmod() {
|
||||
MikMod_Update();
|
||||
}
|
||||
|
||||
static void initialize() {
|
||||
if (have_initialized)
|
||||
return;
|
||||
if (initialization_error)
|
||||
return;
|
||||
/* register the drivers */
|
||||
MikMod_RegisterAllDrivers();
|
||||
/* initialize the mikmod library */
|
||||
md_mixfreq = audio_mix_freq;
|
||||
{
|
||||
// I think this is defined elsewhere
|
||||
typedef plist<string> StrList;
|
||||
typedef Serialize::Deserializer<StrList> OptBuster;
|
||||
StrList opts;
|
||||
OptBuster buster(*audio_mode_flags, " ");
|
||||
opts = buster();
|
||||
for (StrList::iterator i=opts.begin(); i!=opts.end(); ++i) {
|
||||
if ((*i) == "DMODE_INTERP") {
|
||||
md_mode |= DMODE_INTERP;
|
||||
} else if ((*i) == "DMODE_REVERSE") {
|
||||
md_mode |= DMODE_REVERSE;
|
||||
} else if ((*i) == "DMODE_SURROUND") {
|
||||
md_mode |= DMODE_SURROUND;
|
||||
} else if ((*i) == "DMODE_16BITS") {
|
||||
md_mode |= DMODE_16BITS;
|
||||
} else if ((*i) == "DMODE_HQMIXER") {
|
||||
md_mode |= DMODE_HQMIXER;
|
||||
} else if ((*i) == "DMODE_SOFT_MUSIC") {
|
||||
md_mode |= DMODE_SOFT_MUSIC;
|
||||
} else if ((*i) == "DMODE_SOFT_SNDFX") {
|
||||
md_mode |= DMODE_SOFT_SNDFX;
|
||||
} else if ((*i) == "DMODE_STEREO") {
|
||||
md_mode |= DMODE_STEREO;
|
||||
} else {
|
||||
audio_cat->error() << "unknown audio driver flag '" << *i << "'"
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
if (audio_cat.is_debug()) {
|
||||
audio_cat->debug() << "final driver mode is (";
|
||||
bool any_out = false;
|
||||
if (md_mode & DMODE_INTERP) {
|
||||
audio_cat->debug(false) << "DMODE_INTERP";
|
||||
any_out = true;
|
||||
}
|
||||
if (md_mode & DMODE_REVERSE) {
|
||||
if (any_out)
|
||||
audio_cat->debug(false) << ", ";
|
||||
audio_cat->debug(false) << "DMODE_REVERSE";
|
||||
any_out = true;
|
||||
}
|
||||
if (md_mode & DMODE_SURROUND) {
|
||||
if (any_out)
|
||||
audio_cat->debug(false) << ", ";
|
||||
audio_cat->debug(false) << "DMODE_SURROUND";
|
||||
any_out = true;
|
||||
}
|
||||
if (md_mode & DMODE_16BITS) {
|
||||
if (any_out)
|
||||
audio_cat->debug(false) << ", ";
|
||||
audio_cat->debug(false) << "DMODE_16BITS";
|
||||
any_out = true;
|
||||
}
|
||||
if (md_mode & DMODE_HQMIXER) {
|
||||
if (any_out)
|
||||
audio_cat->debug(false) << ", ";
|
||||
audio_cat->debug(false) << "DMODE_HQMIXER";
|
||||
any_out = true;
|
||||
}
|
||||
if (md_mode & DMODE_SOFT_MUSIC) {
|
||||
if (any_out)
|
||||
audio_cat->debug(false) << ", ";
|
||||
audio_cat->debug(false) << "DMODE_SOFT_MUSIC";
|
||||
any_out = true;
|
||||
}
|
||||
if (md_mode & DMODE_SOFT_SNDFX) {
|
||||
if (any_out)
|
||||
audio_cat->debug(false) << ", ";
|
||||
audio_cat->debug(false) << "DMODE_SOFT_SNDFX";
|
||||
any_out = true;
|
||||
}
|
||||
if (md_mode & DMODE_STEREO) {
|
||||
if (any_out)
|
||||
audio_cat->debug(false) << ", ";
|
||||
audio_cat->debug(false) << "DMODE_STEREO";
|
||||
any_out = true;
|
||||
}
|
||||
audio_cat->debug(false) << ")" << endl;
|
||||
}
|
||||
}
|
||||
md_device = audio_driver_select;
|
||||
if (MikMod_Init((char*)(audio_driver_params->c_str()))) {
|
||||
audio_cat->error() << "Could not initialize the audio drivers. '"
|
||||
<< MikMod_strerror(MikMod_errno) << "'" << endl;
|
||||
initialization_error = true;
|
||||
return;
|
||||
}
|
||||
if (audio_cat.is_debug()) {
|
||||
audio_cat->debug() << "driver info" << endl << MikMod_InfoDriver() << endl;
|
||||
}
|
||||
MikMod_SetNumVoices(-1, audio_sample_voices);
|
||||
AudioManager::set_update_func(update_mikmod);
|
||||
have_initialized = true;
|
||||
}
|
||||
|
||||
MikModSample::MikModSample(SAMPLE* sample) : _sample(sample) {
|
||||
}
|
||||
|
||||
MikModSample::~MikModSample() {
|
||||
Sample_Free(_sample);
|
||||
}
|
||||
|
||||
float MikModSample::length() const {
|
||||
float len = _sample->length;
|
||||
float speed = _sample->speed;
|
||||
return len / speed;
|
||||
}
|
||||
|
||||
AudioTraits::PlayingClass* MikModSample::get_state() const {
|
||||
return new MikModSamplePlaying((MikModSample*)this);
|
||||
}
|
||||
|
||||
AudioTraits::PlayerClass* MikModSample::get_player() const {
|
||||
return MikModSamplePlayer::get_instance();
|
||||
}
|
||||
|
||||
AudioTraits::DeletePlayingFunc* MikModSample::get_delstate() const {
|
||||
return MikModSamplePlaying::destroy;
|
||||
}
|
||||
|
||||
MikModSample* MikModSample::load_wav(Filename filename) {
|
||||
initialize();
|
||||
SAMPLE* sample = Sample_Load((char*)(filename.c_str()));
|
||||
if (sample == (SAMPLE*)0L) {
|
||||
audio_cat->error() << "error loading sample '" << filename << "' because '"
|
||||
<< MikMod_strerror(MikMod_errno) << "'" << endl;
|
||||
return (MikModSample*)0L;
|
||||
}
|
||||
return new MikModSample(sample);
|
||||
}
|
||||
|
||||
SAMPLE* MikModSample::get_sample() {
|
||||
return _sample;
|
||||
}
|
||||
|
||||
int MikModSample::get_freq() {
|
||||
return _sample->speed;
|
||||
}
|
||||
|
||||
MikModMusic::MikModMusic() {
|
||||
}
|
||||
|
||||
MikModMusic::~MikModMusic() {
|
||||
}
|
||||
|
||||
float MikModMusic::length() const {
|
||||
return -1.;
|
||||
}
|
||||
|
||||
AudioTraits::PlayingClass* MikModMusic::get_state() const {
|
||||
return new MikModMusicPlaying((MikModMusic*)this);
|
||||
}
|
||||
|
||||
AudioTraits::PlayerClass* MikModMusic::get_player() const {
|
||||
return MikModFmsynthPlayer::get_instance();
|
||||
}
|
||||
|
||||
AudioTraits::DeletePlayingFunc* MikModMusic::get_delstate() const {
|
||||
return MikModMusicPlaying::destroy;
|
||||
}
|
||||
|
||||
MikModMidi::MikModMidi() {
|
||||
}
|
||||
|
||||
MikModMidi::~MikModMidi() {
|
||||
}
|
||||
|
||||
MikModMidi* MikModMidi::load_midi(Filename) {
|
||||
initialize();
|
||||
return new MikModMidi();
|
||||
}
|
||||
|
||||
float MikModMidi::length() const {
|
||||
return -1.;
|
||||
}
|
||||
|
||||
AudioTraits::PlayingClass* MikModMidi::get_state() const {
|
||||
return new MikModMidiPlaying((MikModMidi*)this);
|
||||
}
|
||||
|
||||
AudioTraits::PlayerClass* MikModMidi::get_player() const {
|
||||
return MikModMidiPlayer::get_instance();
|
||||
}
|
||||
|
||||
AudioTraits::DeletePlayingFunc* MikModMidi::get_delstate() const {
|
||||
return MikModMidiPlaying::destroy;
|
||||
}
|
||||
|
||||
MikModSamplePlaying::MikModSamplePlaying(AudioTraits::SoundClass* s)
|
||||
: AudioTraits::PlayingClass(s) {
|
||||
}
|
||||
|
||||
MikModSamplePlaying::~MikModSamplePlaying() {
|
||||
}
|
||||
|
||||
AudioTraits::PlayingClass::PlayingStatus MikModSamplePlaying::status() {
|
||||
return AudioTraits::PlayingClass::BAD;
|
||||
}
|
||||
|
||||
void MikModSamplePlaying::set_voice(int v) {
|
||||
_voice = v;
|
||||
}
|
||||
|
||||
int MikModSamplePlaying::get_voice() const {
|
||||
return _voice;
|
||||
}
|
||||
|
||||
void MikModSamplePlaying::destroy(AudioTraits::PlayingClass* play) {
|
||||
delete play;
|
||||
}
|
||||
|
||||
MikModMusicPlaying::MikModMusicPlaying(AudioTraits::SoundClass* s)
|
||||
: AudioTraits::PlayingClass(s) {
|
||||
}
|
||||
|
||||
MikModMusicPlaying::~MikModMusicPlaying() {
|
||||
}
|
||||
|
||||
AudioTraits::PlayingClass::PlayingStatus MikModMusicPlaying::status() {
|
||||
return AudioTraits::PlayingClass::BAD;
|
||||
}
|
||||
|
||||
void MikModMusicPlaying::destroy(AudioTraits::PlayingClass* play) {
|
||||
delete play;
|
||||
}
|
||||
|
||||
MikModMidiPlaying::MikModMidiPlaying(AudioTraits::SoundClass* s)
|
||||
: AudioTraits::PlayingClass(s) {
|
||||
}
|
||||
|
||||
MikModMidiPlaying::~MikModMidiPlaying() {
|
||||
}
|
||||
|
||||
AudioTraits::PlayingClass::PlayingStatus MikModMidiPlaying::status() {
|
||||
return AudioTraits::PlayingClass::BAD;
|
||||
}
|
||||
|
||||
void MikModMidiPlaying::destroy(AudioTraits::PlayingClass* play) {
|
||||
delete play;
|
||||
}
|
||||
|
||||
MikModSamplePlayer* MikModSamplePlayer::_global_instance =
|
||||
(MikModSamplePlayer*)0L;
|
||||
|
||||
MikModSamplePlayer::MikModSamplePlayer() : AudioTraits::PlayerClass() {
|
||||
}
|
||||
|
||||
MikModSamplePlayer::~MikModSamplePlayer() {
|
||||
}
|
||||
|
||||
void MikModSamplePlayer::play_sound(AudioTraits::SoundClass* sample,
|
||||
AudioTraits::PlayingClass* playing,
|
||||
float) {
|
||||
if (!have_initialized)
|
||||
initialize();
|
||||
if (!MikMod_Active()) {
|
||||
if (MikMod_EnableOutput()) {
|
||||
audio_cat->error() << "could not enable sample output '"
|
||||
<< MikMod_strerror(MikMod_errno) << "'" << endl;
|
||||
}
|
||||
}
|
||||
// cast to the correct type
|
||||
MikModSample* msample = (MikModSample*)sample;
|
||||
MikModSamplePlaying* mplay = (MikModSamplePlaying*)playing;
|
||||
if (!AudioManager::get_sfx_active())
|
||||
return;
|
||||
// fire it off
|
||||
mplay->set_voice(Sample_Play(msample->get_sample(), 0, 0));
|
||||
Voice_SetFrequency(mplay->get_voice(), msample->get_freq());
|
||||
if (Voice_GetFrequency(mplay->get_voice()) != msample->get_freq())
|
||||
audio_cat->error() << "setting freq did not stick!" << endl;
|
||||
Voice_SetPanning(mplay->get_voice(), 127);
|
||||
}
|
||||
|
||||
void MikModSamplePlayer::stop_sound(AudioTraits::SoundClass* sample,
|
||||
AudioTraits::PlayingClass* playing) {
|
||||
if (!have_initialized)
|
||||
initialize();
|
||||
// stop it
|
||||
}
|
||||
|
||||
void MikModSamplePlayer::set_volume(AudioTraits::PlayingClass* state,
|
||||
float v) {
|
||||
initialize();
|
||||
MikModSamplePlaying* mplay = (MikModSamplePlaying*)state;
|
||||
if (!AudioManager::get_sfx_active())
|
||||
return;
|
||||
Voice_SetVolume(mplay->get_voice(),
|
||||
v * AudioManager::get_master_sfx_volume());
|
||||
state->set_volume(v);
|
||||
}
|
||||
|
||||
bool MikModSamplePlayer::adjust_volume(AudioTraits::PlayingClass* state) {
|
||||
initialize();
|
||||
MikModSamplePlaying* mplay = (MikModSamplePlaying*)state;
|
||||
if (!AudioManager::get_sfx_active())
|
||||
return true;
|
||||
Voice_SetVolume(mplay->get_voice(),
|
||||
state->get_volume() * AudioManager::get_master_sfx_volume());
|
||||
return false;
|
||||
}
|
||||
|
||||
MikModSamplePlayer* MikModSamplePlayer::get_instance() {
|
||||
if (_global_instance == (MikModSamplePlayer*)0L)
|
||||
_global_instance = new MikModSamplePlayer();
|
||||
return _global_instance;
|
||||
}
|
||||
|
||||
MikModFmsynthPlayer* MikModFmsynthPlayer::_global_instance =
|
||||
(MikModFmsynthPlayer*)0L;
|
||||
|
||||
MikModFmsynthPlayer::MikModFmsynthPlayer() {
|
||||
}
|
||||
|
||||
MikModFmsynthPlayer::~MikModFmsynthPlayer() {
|
||||
}
|
||||
|
||||
void MikModFmsynthPlayer::play_sound(AudioTraits::SoundClass*,
|
||||
AudioTraits::PlayingClass*, float) {
|
||||
audio_cat->error() << "trying to play a sample with a MikModFmsynthPlayer"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
void MikModFmsynthPlayer::stop_sound(AudioTraits::SoundClass*,
|
||||
AudioTraits::PlayingClass*) {
|
||||
}
|
||||
|
||||
void MikModFmsynthPlayer::set_volume(AudioTraits::PlayingClass* p, float v) {
|
||||
audio_cat->error()
|
||||
<< "trying to set volume on a sample with a MikModFmsynthPlayer" << endl;
|
||||
p->set_volume(v);
|
||||
}
|
||||
|
||||
bool MikModFmsynthPlayer::adjust_volume(AudioTraits::PlayingClass*) {
|
||||
audio_cat->error()
|
||||
<< "trying to adjust volume on a sample with a MikModFmsynthPlayer"
|
||||
<< endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
MikModFmsynthPlayer* MikModFmsynthPlayer::get_instance() {
|
||||
if (_global_instance == (MikModFmsynthPlayer*)0L)
|
||||
_global_instance = new MikModFmsynthPlayer();
|
||||
return _global_instance;
|
||||
}
|
||||
|
||||
MikModMidiPlayer* MikModMidiPlayer::_global_instance = (MikModMidiPlayer*)0L;
|
||||
|
||||
MikModMidiPlayer::MikModMidiPlayer() {
|
||||
}
|
||||
|
||||
MikModMidiPlayer::~MikModMidiPlayer() {
|
||||
}
|
||||
|
||||
void MikModMidiPlayer::play_sound(AudioTraits::SoundClass*,
|
||||
AudioTraits::PlayingClass*, float) {
|
||||
audio_cat->error() << "trying to play a sample with a MikModMidiPlayer"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
void MikModMidiPlayer::stop_sound(AudioTraits::SoundClass*,
|
||||
AudioTraits::PlayingClass*) {
|
||||
}
|
||||
|
||||
void MikModMidiPlayer::set_volume(AudioTraits::PlayingClass* p, float v) {
|
||||
audio_cat->error()
|
||||
<< "trying to set volume on a sample with a MikModMidiPlayer" << endl;
|
||||
p->set_volume(v);
|
||||
}
|
||||
|
||||
bool MikModMidiPlayer::adjust_volume(AudioTraits::PlayingClass*) {
|
||||
audio_cat->error()
|
||||
<< "trying to adjust volume on a sample with a mikModMidiPlayer" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
MikModMidiPlayer* MikModMidiPlayer::get_instance() {
|
||||
if (_global_instance == (MikModMidiPlayer*)0L)
|
||||
_global_instance = new MikModMidiPlayer();
|
||||
return _global_instance;
|
||||
}
|
||||
|
||||
#endif /* AUDIO_USE_MIKMOD */
|
||||
|
|
@ -1,167 +0,0 @@
|
|||
// Filename: audio_mikmod_traits.h
|
||||
// Created by: frang (06Jul00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
// yes, this should be outside
|
||||
#include "audio_trait.h"
|
||||
|
||||
#ifdef AUDIO_USE_MIKMOD
|
||||
#ifndef __AUDIO_MIKMOD_TRAITS_H__
|
||||
#define __AUDIO_MIKMOD_TRAITS_H__
|
||||
|
||||
#include <pandabase.h>
|
||||
#include <filename.h>
|
||||
#include <mikmod.h>
|
||||
|
||||
class MikModSamplePlaying;
|
||||
|
||||
class EXPCL_PANDA MikModSample : public AudioTraits::SoundClass {
|
||||
private:
|
||||
SAMPLE* _sample;
|
||||
|
||||
MikModSample(SAMPLE*);
|
||||
public:
|
||||
virtual ~MikModSample();
|
||||
|
||||
virtual float length() const;
|
||||
virtual AudioTraits::PlayingClass* get_state() const;
|
||||
virtual AudioTraits::PlayerClass* get_player() const;
|
||||
virtual AudioTraits::DeletePlayingFunc* get_delstate() const;
|
||||
public:
|
||||
// used by the readers
|
||||
static MikModSample* load_wav(Filename);
|
||||
// used by the players
|
||||
virtual SAMPLE* get_sample();
|
||||
virtual int get_freq();
|
||||
};
|
||||
|
||||
class EXPCL_PANDA MikModMusic : public AudioTraits::SoundClass {
|
||||
private:
|
||||
MODULE* _music;
|
||||
public:
|
||||
MikModMusic();
|
||||
virtual ~MikModMusic();
|
||||
|
||||
virtual float length() const;
|
||||
virtual AudioTraits::PlayingClass* get_state() const;
|
||||
virtual AudioTraits::PlayerClass* get_player() const;
|
||||
virtual AudioTraits::DeletePlayingFunc* get_delstate() const;
|
||||
};
|
||||
|
||||
class EXPCL_PANDA MikModMidi : public AudioTraits::SoundClass {
|
||||
private:
|
||||
public:
|
||||
MikModMidi();
|
||||
virtual ~MikModMidi();
|
||||
|
||||
virtual float length() const;
|
||||
virtual AudioTraits::PlayingClass* get_state() const;
|
||||
virtual AudioTraits::PlayerClass* get_player() const;
|
||||
virtual AudioTraits::DeletePlayingFunc* get_delstate() const;
|
||||
public:
|
||||
// used by the readers
|
||||
static MikModMidi* load_midi(Filename);
|
||||
};
|
||||
|
||||
class EXPCL_PANDA MikModSamplePlaying : public AudioTraits::PlayingClass {
|
||||
private:
|
||||
int _voice;
|
||||
public:
|
||||
MikModSamplePlaying(AudioTraits::SoundClass*);
|
||||
~MikModSamplePlaying();
|
||||
|
||||
virtual AudioTraits::PlayingClass::PlayingStatus status();
|
||||
static void destroy(AudioTraits::PlayingClass*);
|
||||
public:
|
||||
virtual void set_voice(int);
|
||||
virtual int get_voice() const;
|
||||
};
|
||||
|
||||
class EXPCL_PANDA MikModMusicPlaying : public AudioTraits::PlayingClass {
|
||||
public:
|
||||
MikModMusicPlaying(AudioTraits::SoundClass*);
|
||||
~MikModMusicPlaying();
|
||||
|
||||
virtual AudioTraits::PlayingClass::PlayingStatus status();
|
||||
static void destroy(AudioTraits::PlayingClass*);
|
||||
};
|
||||
|
||||
class EXPCL_PANDA MikModMidiPlaying : public AudioTraits::PlayingClass {
|
||||
public:
|
||||
MikModMidiPlaying(AudioTraits::SoundClass*);
|
||||
~MikModMidiPlaying();
|
||||
|
||||
virtual AudioTraits::PlayingClass::PlayingStatus status();
|
||||
static void destroy(AudioTraits::PlayingClass*);
|
||||
};
|
||||
|
||||
class EXPCL_PANDA MikModSamplePlayer : public AudioTraits::PlayerClass {
|
||||
public:
|
||||
MikModSamplePlayer();
|
||||
virtual ~MikModSamplePlayer();
|
||||
|
||||
virtual void play_sound(AudioTraits::SoundClass*,
|
||||
AudioTraits::PlayingClass*, float);
|
||||
virtual void stop_sound(AudioTraits::SoundClass*,
|
||||
AudioTraits::PlayingClass*);
|
||||
virtual void set_volume(AudioTraits::PlayingClass*, float);
|
||||
virtual bool adjust_volume(AudioTraits::PlayingClass*);
|
||||
public:
|
||||
// used by the readers
|
||||
static MikModSamplePlayer* get_instance();
|
||||
private:
|
||||
static MikModSamplePlayer* _global_instance;
|
||||
};
|
||||
|
||||
class EXPCL_PANDA MikModFmsynthPlayer : public AudioTraits::PlayerClass {
|
||||
public:
|
||||
MikModFmsynthPlayer();
|
||||
virtual ~MikModFmsynthPlayer();
|
||||
|
||||
virtual void play_sound(AudioTraits::SoundClass*,
|
||||
AudioTraits::PlayingClass*, float);
|
||||
virtual void stop_sound(AudioTraits::SoundClass*,
|
||||
AudioTraits::PlayingClass*);
|
||||
virtual void set_volume(AudioTraits::PlayingClass*, float);
|
||||
virtual bool adjust_volume(AudioTraits::PlayingClass*);
|
||||
public:
|
||||
// used by the readers
|
||||
static MikModFmsynthPlayer* get_instance();
|
||||
private:
|
||||
static MikModFmsynthPlayer* _global_instance;
|
||||
};
|
||||
|
||||
class EXPCL_PANDA MikModMidiPlayer : public AudioTraits::PlayerClass {
|
||||
public:
|
||||
MikModMidiPlayer();
|
||||
virtual ~MikModMidiPlayer();
|
||||
|
||||
virtual void play_sound(AudioTraits::SoundClass*,
|
||||
AudioTraits::PlayingClass*, float);
|
||||
virtual void stop_sound(AudioTraits::SoundClass*,
|
||||
AudioTraits::PlayingClass*);
|
||||
virtual void set_volume(AudioTraits::PlayingClass*, float);
|
||||
virtual bool adjust_volume(AudioTraits::PlayingClass*);
|
||||
public:
|
||||
// used by the readers
|
||||
static MikModMidiPlayer* get_instance();
|
||||
private:
|
||||
static MikModMidiPlayer* _global_instance;
|
||||
};
|
||||
|
||||
#endif /* __AUDIO_MIKMOD_TRAITS_H__ */
|
||||
#endif /* AUDIO_USE_MIKMOD */
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
// Filename: audio_null_traits.I
|
||||
// Created by: cary (25Sep00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
INLINE NullSound::NullSound() : AudioTraits::SoundClass() {
|
||||
}
|
||||
|
||||
INLINE NullPlaying::NullPlaying(AudioTraits::SoundClass* sound)
|
||||
: AudioTraits::PlayingClass(sound) {
|
||||
}
|
||||
|
||||
INLINE NullPlayer::NullPlayer() : AudioTraits::PlayerClass() {
|
||||
}
|
||||
|
|
@ -1,102 +0,0 @@
|
|||
// Filename: audio_null_traits.cxx
|
||||
// Created by: cary (25Sep00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "audio_null_traits.h"
|
||||
|
||||
#ifdef AUDIO_USE_NULL
|
||||
|
||||
#include "audio_manager.h"
|
||||
#include "config_audio.h"
|
||||
|
||||
static bool have_initialized = false;
|
||||
|
||||
static void update_null() {
|
||||
if (audio_cat.is_debug())
|
||||
audio_cat->debug() << "Update in Null audio driver" << endl;
|
||||
}
|
||||
|
||||
static void initialize() {
|
||||
if (have_initialized)
|
||||
return;
|
||||
AudioManager::set_update_func(update_null);
|
||||
have_initialized = true;
|
||||
}
|
||||
|
||||
NullSound::~NullSound() {
|
||||
}
|
||||
|
||||
float NullSound::length() const {
|
||||
if (audio_cat.is_debug())
|
||||
audio_cat->debug() << "in sample length in Null audio driver" << endl;
|
||||
return -1.;
|
||||
}
|
||||
|
||||
AudioTraits::PlayingClass* NullSound::get_state() const {
|
||||
return new NullPlaying((NullSound*)this);
|
||||
}
|
||||
|
||||
AudioTraits::PlayerClass* NullSound::get_player() const {
|
||||
return new NullPlayer();
|
||||
}
|
||||
|
||||
|
||||
AudioTraits::DeletePlayingFunc* NullSound::get_delstate() const {
|
||||
return NullPlaying::destroy;
|
||||
}
|
||||
|
||||
NullPlaying::~NullPlaying() {
|
||||
}
|
||||
|
||||
AudioTraits::PlayingClass::PlayingStatus NullPlaying::status() {
|
||||
if (audio_cat.is_debug())
|
||||
audio_cat->debug() << "in playing status in Null audio driver" << endl;
|
||||
return BAD;
|
||||
}
|
||||
|
||||
void NullPlaying::destroy(AudioTraits::PlayingClass* play) {
|
||||
delete play;
|
||||
}
|
||||
|
||||
NullPlayer::~NullPlayer() {
|
||||
}
|
||||
|
||||
void NullPlayer::play_sound(AudioTraits::SoundClass*,
|
||||
AudioTraits::PlayingClass*, float, int) {
|
||||
if (audio_cat.is_debug())
|
||||
audio_cat->debug() << "in play sound in Null audio driver" << endl;
|
||||
}
|
||||
|
||||
void NullPlayer::stop_sound(AudioTraits::SoundClass*,
|
||||
AudioTraits::PlayingClass*) {
|
||||
if (audio_cat.is_debug())
|
||||
audio_cat->debug() << "in stop sound in Null audio driver" << endl;
|
||||
}
|
||||
|
||||
void NullPlayer::set_volume(AudioTraits::PlayingClass* p, float v) {
|
||||
if (audio_cat.is_debug())
|
||||
audio_cat->debug() << "in set volume in Null audio driver" << endl;
|
||||
p->set_volume(v);
|
||||
}
|
||||
|
||||
bool NullPlayer::adjust_volume(AudioTraits::PlayingClass*) {
|
||||
if (audio_cat.is_debug())
|
||||
audio_cat->debug() << "in adjust volume in Null audio driver" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif /* AUDIO_USE_NULL */
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
// Filename: audio_null_traits.h
|
||||
// Created by: cary (25Sep00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
// yes, this needs to be outside the ifdef protection
|
||||
#include "audio_trait.h"
|
||||
|
||||
#ifdef AUDIO_USE_NULL
|
||||
|
||||
#ifndef __AUDIO_NULL_TRAITS_H__
|
||||
#define __AUDIO_NULL_TRAITS_H__
|
||||
|
||||
class NullPlaying;
|
||||
|
||||
class EXPCL_PANDA NullSound : public AudioTraits::SoundClass {
|
||||
public:
|
||||
INLINE NullSound();
|
||||
virtual ~NullSound();
|
||||
|
||||
virtual float length() const;
|
||||
virtual AudioTraits::PlayingClass* get_state() const;
|
||||
virtual AudioTraits::PlayerClass* get_player() const;
|
||||
virtual AudioTraits::DeletePlayingFunc* get_delstate() const;
|
||||
};
|
||||
|
||||
class EXPCL_PANDA NullPlaying : public AudioTraits::PlayingClass {
|
||||
public:
|
||||
INLINE NullPlaying(AudioTraits::SoundClass*);
|
||||
virtual ~NullPlaying();
|
||||
|
||||
virtual AudioTraits::PlayingClass::PlayingStatus status();
|
||||
static void destroy(AudioTraits::PlayingClass*);
|
||||
};
|
||||
|
||||
class EXPCL_PANDA NullPlayer : public AudioTraits::PlayerClass {
|
||||
public:
|
||||
INLINE NullPlayer();
|
||||
virtual ~NullPlayer();
|
||||
|
||||
virtual void play_sound(AudioTraits::SoundClass*,
|
||||
AudioTraits::PlayingClass*, float, int);
|
||||
virtual void stop_sound(AudioTraits::SoundClass*,
|
||||
AudioTraits::PlayingClass*);
|
||||
virtual void set_volume(AudioTraits::PlayingClass*, float);
|
||||
virtual bool adjust_volume(AudioTraits::PlayingClass*);
|
||||
};
|
||||
|
||||
#include "audio_null_traits.I"
|
||||
|
||||
#endif /* __AUDIO_NULL_TRAITS_H__ */
|
||||
#endif /* AUDIO_USE_NULL */
|
||||
|
|
@ -1,112 +0,0 @@
|
|||
// Filename: audio_pool.I
|
||||
// Created by: cary (22Sep00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioPool::has_sound
|
||||
// Access: Public, Static
|
||||
// Description: Returns true if the sound has ever been loaded,
|
||||
// false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool AudioPool::has_sound(const string& filename) {
|
||||
return get_ptr()->ns_has_sound(filename);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioPool::verify_sound
|
||||
// Access: Public, Static
|
||||
// Description: Loads the given filename up into a sound, if it has
|
||||
// not already been loaded, and returns true to indicate
|
||||
// success, or false to indicate failure. If this
|
||||
// returns true, it is guaranteed that a subsequent call
|
||||
// to load_sound() with the same sound name will
|
||||
// return a valid AudioSound pointer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool AudioPool::verify_sound(const string& filename) {
|
||||
PT(AudioSound) foo = load_sound(filename);
|
||||
return !(foo.is_null());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioPool::load_sound
|
||||
// Access: Public, Static
|
||||
// Description: Loads the given filename up into a sound, if it has
|
||||
// not already been loaded, and returns the new sound.
|
||||
// If a sound with the same filename was previously
|
||||
// loaded, returns that one instead. If the sound
|
||||
// file cannot be found, returns NULL.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE AudioSound* AudioPool::load_sound(const string& filename) {
|
||||
if (audio_is_active)
|
||||
return get_ptr()->ns_load_sound(filename);
|
||||
return (AudioSound*)0L;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioPool::release_sound
|
||||
// Access: Public, Static
|
||||
// Description: Removes the indicated sound from the pool,
|
||||
// indicating it will never be loaded again; the sound
|
||||
// may then be freed. If this function is never called,
|
||||
// a reference count will be maintained on every sound
|
||||
// ever loaded, and sounds will never be freed.
|
||||
//
|
||||
// The sound's name should not have been changed
|
||||
// during its lifetime, or this function may fail to
|
||||
// locate it in the pool.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void AudioPool::release_sound(AudioSound* sound) {
|
||||
get_ptr()->ns_release_sound(sound);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioPool::release_all_sounds
|
||||
// Access: Public, Static
|
||||
// Description: Releases all sounds in the pool and restores the
|
||||
// pool to the empty state.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void AudioPool::release_all_sounds() {
|
||||
get_ptr()->ns_release_all_sounds();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioPool::Constructor
|
||||
// Access: Private
|
||||
// Description: The constructor is not intended to be called
|
||||
// directly; there's only supposed to be one AudioPool
|
||||
// in the universe and it constructs itself.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE AudioPool::AudioPool() {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioPool::get_num_loaded_sounds
|
||||
// Access: Public, static
|
||||
// Description: return the number of sounds the audiopool thinks
|
||||
// are loaded at the moment
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int AudioPool::get_num_loaded_sounds() {
|
||||
return get_ptr()->_sounds.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioPool::get_nth_sound_name
|
||||
// Access: Public, static
|
||||
// Description: return the name of the nth loaded sound
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE string AudioPool::get_nth_sound_name(int n) {
|
||||
return get_ptr()->ns_get_nth_sound_name(n);
|
||||
}
|
||||
|
|
@ -1,206 +0,0 @@
|
|||
// Filename: audio_pool.cxx
|
||||
// Created by: cary (22Sep00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "audio_pool.h"
|
||||
#include "config_audio.h"
|
||||
#include <config_util.h>
|
||||
|
||||
AudioPool* AudioPool::_global_ptr; // static is 0 by default.
|
||||
typedef pmap<string, AudioPool::SoundLoadFunc*> SoundLoaders;
|
||||
static SoundLoaders* _sound_loaders; // static is 0 by default.
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: check_sound_loaders
|
||||
// Access: Static
|
||||
// Description: ensure that the sound loaders map has been initialized
|
||||
////////////////////////////////////////////////////////////////////
|
||||
static void
|
||||
check_sound_loaders() {
|
||||
if (!_sound_loaders) {
|
||||
_sound_loaders = new SoundLoaders;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioPool::get_ptr
|
||||
// Access: Private, Static
|
||||
// Description: Initializes and/or returns the global pointer to the
|
||||
// one AudioPool object in the system.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
AudioPool* AudioPool::
|
||||
get_ptr() {
|
||||
if (!_global_ptr) {
|
||||
_global_ptr = new AudioPool;
|
||||
}
|
||||
audio_load_loaders();
|
||||
return _global_ptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioPool::ns_has_sound
|
||||
// Access: Private
|
||||
// Description: The nonstatic implementation of has_sound().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool AudioPool::
|
||||
ns_has_sound(Filename filename) {
|
||||
filename.resolve_filename(get_sound_path());
|
||||
|
||||
SoundMap::const_iterator si;
|
||||
si = _sounds.find(filename);
|
||||
return si != _sounds.end();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioPool::call_sound_loader
|
||||
// Access: Private
|
||||
// Description: Call the sound loader to load the sound, without
|
||||
// looking in the sound pool.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(AudioTraits::SoundClass) AudioPool::
|
||||
call_sound_loader(Filename fileName) {
|
||||
if (!fileName.exists()) {
|
||||
audio_info("'" << fileName << "' does not exist");
|
||||
return 0;
|
||||
}
|
||||
audio_info("Loading sound " << fileName);
|
||||
// Determine which sound loader to use:
|
||||
string ext = fileName.get_extension();
|
||||
SoundLoaders::const_iterator sli;
|
||||
check_sound_loaders();
|
||||
sli = _sound_loaders->find(ext);
|
||||
if (sli == _sound_loaders->end()) {
|
||||
audio_error("no loader available for audio type '" << ext << "'");
|
||||
return 0;
|
||||
}
|
||||
// Call the sound loader:
|
||||
PT(AudioTraits::SoundClass) sound=(*((*sli).second))(fileName);
|
||||
if (!sound) {
|
||||
audio_error("could not load '" << fileName << "'");
|
||||
}
|
||||
return sound;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioPool::ns_load_sound
|
||||
// Access: Private
|
||||
// Description: The nonstatic implementation of load_sound().
|
||||
//
|
||||
// First we will search the pool for the sound.
|
||||
// If that fails, we will call the loader for the
|
||||
// sound, and then add this sound to the pool.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
AudioSound* AudioPool::
|
||||
ns_load_sound(Filename fileName) {
|
||||
audio_debug("in AudioPool::ns_load_sound");
|
||||
fileName.resolve_filename(get_sound_path());
|
||||
audio_debug("resolved fileName is '" << fileName << "'");
|
||||
|
||||
PT(AudioTraits::SoundClass) sound=0;
|
||||
// Get the sound, either from the pool or from a loader:
|
||||
SoundMap::const_iterator si;
|
||||
si = _sounds.find(fileName);
|
||||
if (si != _sounds.end()) {
|
||||
// ...found the sound in the pool.
|
||||
sound = (*si).second;
|
||||
audio_debug("sound found in pool (0x" << (void*)sound << ")");
|
||||
} else {
|
||||
// ...the sound was not found in the cache/pool.
|
||||
sound=call_sound_loader(fileName);
|
||||
if (sound) {
|
||||
// Put it in the pool:
|
||||
_sounds[fileName] = sound;
|
||||
}
|
||||
}
|
||||
// Create an AudioSound from the sound:
|
||||
AudioSound* audioSound = 0;
|
||||
if (sound) {
|
||||
audioSound = new AudioSound(sound,
|
||||
sound->get_state(), sound->get_player(),
|
||||
sound->get_delstate(), fileName);
|
||||
}
|
||||
audio_debug("AudioPool: returning 0x" << (void*)audioSound);
|
||||
return audioSound;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioPool::ns_release_sound
|
||||
// Access: Private
|
||||
// Description: The nonstatic implementation of release_sound().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AudioPool::ns_release_sound(AudioSound* sound) {
|
||||
audio_debug("AudioPool: releasing sound 0x" << (void*)sound);
|
||||
string filename = sound->get_name();
|
||||
SoundMap::iterator si;
|
||||
si = _sounds.find(filename);
|
||||
if (si != _sounds.end() && (*si).second == sound->get_sound()) {
|
||||
_sounds.erase(si);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioPool::ns_release_all_sounds
|
||||
// Access: Private
|
||||
// Description: The nonstatic implementation of release_all_sounds().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AudioPool::
|
||||
ns_release_all_sounds() {
|
||||
audio_debug("AudioPool: releasing all sounds");
|
||||
_sounds.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioPool::register_sound_loader
|
||||
// Access: Public, static
|
||||
// Description: A static function to register a function for loading
|
||||
// audio sounds.
|
||||
// ext: a file name extension (e.g. .mp3 or .wav).
|
||||
// func: a function that will be called to load a file
|
||||
// with the extension 'ext'.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AudioPool::
|
||||
register_sound_loader(const string& ext,
|
||||
AudioPool::SoundLoadFunc* func) {
|
||||
check_sound_loaders();
|
||||
#ifndef NDEBUG //[
|
||||
// Debug check: See if the loader is already registered:
|
||||
SoundLoaders::const_iterator sli = _sound_loaders->find(ext);
|
||||
if (sli != _sound_loaders->end()) {
|
||||
audio_cat->warning()
|
||||
<< "attempted to register a loader for audio type '"
|
||||
<< ext << "' more then once." << endl;
|
||||
return;
|
||||
}
|
||||
#endif //]
|
||||
(*_sound_loaders)[ext] = func;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioPool::ns_get_nth_sound_name
|
||||
// Access: Public
|
||||
// Description: return the name of the nth loaded sound
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string AudioPool::
|
||||
ns_get_nth_sound_name(int n) const {
|
||||
SoundMap::const_iterator i;
|
||||
int j;
|
||||
for (i=_sounds.begin(), j=0; j<n; ++i, ++j) {
|
||||
// the work is being done in the for statement.
|
||||
}
|
||||
return (*i).first;
|
||||
}
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
// Filename: audio_pool.h
|
||||
// Created by: cary (22Sep00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __AUDIO_POOL_H__
|
||||
#define __AUDIO_POOL_H__
|
||||
|
||||
#include "audio_sound.h"
|
||||
#include "audio_trait.h"
|
||||
#include "config_audio.h"
|
||||
#include "pmap.h"
|
||||
#include <pandabase.h>
|
||||
#include <filename.h>
|
||||
#include <pointerTo.h>
|
||||
|
||||
// The AudioPool is a cache of SoundClass objects. When retrieving
|
||||
// a sound, you will actually get an AudioSound object (which you own).
|
||||
class EXPCL_PANDA AudioPool {
|
||||
public:
|
||||
typedef AudioTraits::SoundClass* SoundLoadFunc(Filename);
|
||||
|
||||
PUBLISHED:
|
||||
INLINE static bool has_sound(const string& filename);
|
||||
INLINE static bool verify_sound(const string& filename);
|
||||
|
||||
INLINE static AudioSound* load_sound(const string& filename);
|
||||
|
||||
INLINE static void release_sound(AudioSound* sound);
|
||||
INLINE static void release_all_sounds();
|
||||
|
||||
INLINE static int get_num_loaded_sounds();
|
||||
INLINE static string get_nth_sound_name(int);
|
||||
|
||||
static void register_sound_loader(const string&, SoundLoadFunc*);
|
||||
|
||||
private:
|
||||
INLINE AudioPool();
|
||||
|
||||
bool ns_has_sound(Filename filename);
|
||||
PT(AudioTraits::SoundClass) call_sound_loader(Filename fileName);
|
||||
AudioSound* ns_load_sound(Filename filename);
|
||||
void ns_release_sound(AudioSound* sound);
|
||||
void ns_release_all_sounds();
|
||||
string ns_get_nth_sound_name(int) const;
|
||||
|
||||
static AudioPool* get_ptr();
|
||||
|
||||
static AudioPool *_global_ptr;
|
||||
typedef pmap<string, PT(AudioTraits::SoundClass) > SoundMap;
|
||||
SoundMap _sounds;
|
||||
};
|
||||
|
||||
#include "audio_pool.I"
|
||||
|
||||
#endif /* __AUDIO_POOL_H__ */
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
// Filename: audio_rad_mss_traits.I
|
||||
// Created by: cary (27Sep00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
INLINE MilesSound::
|
||||
MilesSound(HAUDIO audio)
|
||||
: AudioTraits::SoundClass(), _audio(audio) {
|
||||
}
|
||||
|
||||
INLINE MilesPlayer::
|
||||
MilesPlayer()
|
||||
: AudioTraits::PlayerClass() {
|
||||
}
|
||||
|
|
@ -1,289 +0,0 @@
|
|||
// Filename: audio_rad_mss_traits.cxx
|
||||
// Created by: cary (27Sep00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "audio_rad_mss_traits.h"
|
||||
|
||||
#ifdef AUDIO_USE_RAD_MSS //[
|
||||
|
||||
#include "audio_manager.h"
|
||||
#include "config_audio.h"
|
||||
#include <config_util.h>
|
||||
|
||||
#include <direct.h>
|
||||
|
||||
namespace {
|
||||
void initialize() {
|
||||
static bool have_initialized;
|
||||
if (have_initialized) {
|
||||
return;
|
||||
}
|
||||
if (!audio_is_active) {
|
||||
return;
|
||||
}
|
||||
audio_debug("audio_rad_mss_traits initialize");
|
||||
///S32 startup=AIL_quick_startup(1, 1, 22050, 16, 2);
|
||||
S32 startup=AIL_quick_startup(1, 1, 0, 0, 0); // Allow MSS to choose defaults.
|
||||
if (startup) {
|
||||
audio_debug(" AIL_quick_startup: ok "<<startup);
|
||||
} else {
|
||||
audio_error("AIL_quick_startup: **failed** "<<AIL_last_error());
|
||||
}
|
||||
have_initialized=true;
|
||||
audio_debug("out of milesAudio initialize");
|
||||
}
|
||||
|
||||
void shutdown() {
|
||||
audio_debug("audio_rad_mss_traits shutdown");
|
||||
AIL_quick_shutdown();
|
||||
audio_debug("out of milesaudio shutdown"<<AIL_last_error());
|
||||
}
|
||||
|
||||
bool isInactive(MilesPlaying::Category category) {
|
||||
if (!audio_is_active) {
|
||||
return true;
|
||||
}
|
||||
if (category == MilesPlaying::EFFECT
|
||||
&&
|
||||
!AudioManager::get_sfx_active()) {
|
||||
return true;
|
||||
} else if (category == MilesPlaying::MUSIC
|
||||
&&
|
||||
!AudioManager::get_music_active()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void set_volume_helper(HAUDIO audio, float volume,
|
||||
MilesPlaying::Category category) {
|
||||
// Account for the category of sound:
|
||||
if (category == MilesPlaying::EFFECT) {
|
||||
volume*=AudioManager::get_master_sfx_volume();
|
||||
} else if (category == MilesPlaying::MUSIC) {
|
||||
volume*=AudioManager::get_master_music_volume();
|
||||
}
|
||||
// Change to Miles:
|
||||
S32 milesVolume=S32(127*volume); // range is 0 to 127.
|
||||
milesVolume%=128;
|
||||
// Account for type:
|
||||
S32 audioType=AIL_quick_type(audio);
|
||||
if (audioType==AIL_QUICK_XMIDI_TYPE
|
||||
||
|
||||
audioType==AIL_QUICK_DLS_XMIDI_TYPE) {
|
||||
// ...it's a midi file.
|
||||
audio_debug("adjusting sound on midi file");
|
||||
volume*=0.05;
|
||||
AIL_quick_set_volume(audio, milesVolume, 0); // 0 delay.
|
||||
} else {
|
||||
// ...it's a wav or mp3.
|
||||
audio_debug("adjusting sound on wav or mp3 (non-midi) file");
|
||||
AIL_quick_set_volume(audio, milesVolume, 64); // 64 center stereo pan.
|
||||
}
|
||||
audio_debug(" Miles volume is "<<milesVolume);
|
||||
}
|
||||
}
|
||||
|
||||
MilesSound::~MilesSound() {
|
||||
audio_debug("MilesSound::~MilesSound");
|
||||
AIL_quick_unload(_audio);
|
||||
}
|
||||
|
||||
float MilesSound::length() const {
|
||||
float length=0;
|
||||
if (AIL_quick_status(_audio)!=QSTAT_PLAYING) {
|
||||
AIL_quick_play(_audio, 1);
|
||||
length=float(AIL_quick_ms_length(_audio))/1000.0;
|
||||
AIL_quick_halt(_audio);
|
||||
} else {
|
||||
length=float(AIL_quick_ms_length(_audio))/1000.0;
|
||||
}
|
||||
audio_debug("MilesSound::length returning "<<length);
|
||||
return length;
|
||||
}
|
||||
|
||||
AudioTraits::PlayingClass* MilesSound::get_state() const {
|
||||
MilesPlaying* ret = new MilesPlaying((MilesSound*)this);
|
||||
audio_debug("MilesSound::get_state returning 0x" << (void*)ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
AudioTraits::PlayerClass* MilesSound::get_player() const {
|
||||
AudioTraits::PlayerClass* ret = MilesPlayer::get_instance();
|
||||
audio_debug("MilesSound::get_player returning 0x" << (void*)ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
AudioTraits::DeletePlayingFunc* MilesSound::get_delstate() const {
|
||||
audio_debug("MilesSound::get_delstate returning 0x"
|
||||
<< (void*)(MilesPlaying::destroy));
|
||||
return MilesPlaying::destroy;
|
||||
}
|
||||
|
||||
MilesSound* MilesSound::load(Filename filename) {
|
||||
audio_debug("MilesSound::load");
|
||||
initialize();
|
||||
if (!audio_is_active) {
|
||||
return 0;
|
||||
}
|
||||
// Load the file:
|
||||
string stmp = filename.to_os_specific();
|
||||
audio_debug(" \"" << stmp << "\"");
|
||||
HAUDIO audio = AIL_quick_load(stmp.c_str());
|
||||
if (!audio) {
|
||||
audio_debug(" MilesSound::load failed " << AIL_last_error());
|
||||
return 0;
|
||||
}
|
||||
// Create the sound:
|
||||
MilesSound* sound = new MilesSound(audio);
|
||||
return sound;
|
||||
}
|
||||
|
||||
MilesSound* MilesSound::load_raw(unsigned char* data, unsigned long size) {
|
||||
audio_debug("MilesSound::load_raw(data=0x"<<(void*)data<<", size="<<size<<")");
|
||||
initialize();
|
||||
if (!audio_is_active) {
|
||||
return 0;
|
||||
}
|
||||
if (!data) {
|
||||
audio_debug(" data is null, returning same");
|
||||
return 0;
|
||||
}
|
||||
// Load the wave:
|
||||
HAUDIO audio = AIL_quick_load_mem(data, size);
|
||||
if (!audio) {
|
||||
audio_debug(" mss load_raw failed " << AIL_last_error());
|
||||
return 0;
|
||||
}
|
||||
// Create the sound:
|
||||
MilesSound* sound = new MilesSound(audio);
|
||||
return sound;
|
||||
}
|
||||
|
||||
MilesPlaying::MilesPlaying(AudioTraits::SoundClass* sound)
|
||||
: AudioTraits::PlayingClass(sound) {
|
||||
initialize();
|
||||
if (!audio_is_active) {
|
||||
return;
|
||||
}
|
||||
nassertv(sound);
|
||||
audio_debug("MilesPlaying::MilesPlaying(sound=0x"<<(void*)sound<<")");
|
||||
// Make our own copy of the sound header data:
|
||||
MilesSound* milesSound=static_cast<MilesSound*>(sound);
|
||||
_audio=AIL_quick_copy(milesSound->_audio);
|
||||
audio_debug("in MilesPlaying constructor");
|
||||
}
|
||||
|
||||
MilesPlaying::~MilesPlaying() {
|
||||
audio_debug("MilesPlaying::~MilesPlaying");
|
||||
AIL_quick_unload(_audio);
|
||||
}
|
||||
|
||||
void MilesPlaying::destroy(AudioTraits::PlayingClass* playing) {
|
||||
audio_debug("MilesPlaying::destroy(playing=0x" << (void*)playing<<")");
|
||||
delete playing;
|
||||
}
|
||||
|
||||
AudioTraits::PlayingClass::PlayingStatus MilesPlaying::status() {
|
||||
if (!_audio) {
|
||||
return AudioTraits::PlayingClass::BAD;
|
||||
}
|
||||
switch (AIL_quick_status(_audio)) {
|
||||
case QSTAT_LOADED:
|
||||
case QSTAT_DONE:
|
||||
return AudioTraits::PlayingClass::READY;
|
||||
case QSTAT_PLAYING:
|
||||
return AudioTraits::PlayingClass::PLAYING;
|
||||
default:
|
||||
return AudioTraits::PlayingClass::BAD;
|
||||
}
|
||||
}
|
||||
|
||||
MilesPlayer* MilesPlayer::_global_instance = (MilesPlayer*)0L;
|
||||
|
||||
MilesPlayer::~MilesPlayer() {
|
||||
audio_debug("MilesPlayer::~MilesPlayer");
|
||||
}
|
||||
|
||||
void MilesPlayer::play_sound(AudioTraits::SoundClass* sound,
|
||||
AudioTraits::PlayingClass* playing, float start_time, int loop) {
|
||||
audio_debug("MilesPlayer::play_sound(sound=0x"<<(void*)sound<<", playing=0x"<<(void*)playing<<", start_time="<<start_time<<")");
|
||||
initialize();
|
||||
if (!audio_is_active) {
|
||||
return;
|
||||
}
|
||||
nassertv(sound);
|
||||
nassertv(playing);
|
||||
MilesPlaying* milesPlaying = static_cast<MilesPlaying*>(playing);
|
||||
if (isInactive(milesPlaying->get_category())) {
|
||||
return;
|
||||
}
|
||||
// Set the start time:
|
||||
S32 milisecond_start_time=S32(1000*start_time);
|
||||
//audio_debug(" setting milisecond start time to "<<milisecond_start_time);
|
||||
AIL_quick_set_ms_position(milesPlaying->_audio, milisecond_start_time);
|
||||
// Set the volume:
|
||||
//audio_debug(" playing->get_volume "<<playing->get_volume());
|
||||
//audio_debug(" AudioManager::get_master_sfx_volume "<<AudioManager::get_master_sfx_volume());
|
||||
//audio_debug(" AudioManager::get_master_music_volume "<<AudioManager::get_master_music_volume());
|
||||
set_volume_helper(milesPlaying->_audio, playing->get_volume(), playing->get_category());
|
||||
// Start playing:
|
||||
if (AIL_quick_play(milesPlaying->_audio, (loop)?0:1)) {
|
||||
audio_debug("started sound");
|
||||
} else {
|
||||
audio_debug("failed to play sound "<<AIL_last_error());
|
||||
}
|
||||
audio_debug("out of MilesPlayer play_sound");
|
||||
}
|
||||
|
||||
void MilesPlayer::stop_sound(AudioTraits::SoundClass*,
|
||||
AudioTraits::PlayingClass* playing) {
|
||||
audio_debug("MilesPlayer::stop_sound");
|
||||
initialize();
|
||||
nassertv(playing);
|
||||
MilesPlaying* milesPlaying = static_cast<MilesPlaying*>(playing);
|
||||
if (isInactive(milesPlaying->get_category())) {
|
||||
return;
|
||||
}
|
||||
AIL_quick_halt(milesPlaying->_audio);
|
||||
}
|
||||
|
||||
void MilesPlayer::set_volume(AudioTraits::PlayingClass* playing, float volume) {
|
||||
audio_debug("MilesPlayer::set_volume(playing=0x"<<(void*)playing<<", volume="<<volume<<")");
|
||||
initialize();
|
||||
nassertv(playing);
|
||||
MilesPlaying* milesPlaying = static_cast<MilesPlaying*>(playing);
|
||||
if (isInactive(milesPlaying->get_category())) {
|
||||
return;
|
||||
}
|
||||
set_volume_helper(milesPlaying->_audio, volume, milesPlaying->get_category());
|
||||
}
|
||||
|
||||
bool MilesPlayer::adjust_volume(AudioTraits::PlayingClass* playing) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MilesPlayer* MilesPlayer::get_instance() {
|
||||
audio_debug("MilesPlayer::get_instance");
|
||||
if (!_global_instance) {
|
||||
_global_instance = new MilesPlayer();
|
||||
}
|
||||
audio_debug("MilesPlayer returning 0x" << (void*)_global_instance);
|
||||
return _global_instance;
|
||||
}
|
||||
|
||||
#endif //]
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
// Filename: audio_rad_mss_traits.h
|
||||
// Created by: cary (27Sep00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
// yes, this needs to be outside the ifdef protection
|
||||
#include "audio_trait.h"
|
||||
|
||||
#ifdef AUDIO_USE_RAD_MSS //[
|
||||
#ifndef __AUDIO_RAD_MSS_TRAITS_H__
|
||||
#define __AUDIO_RAD_MSS_TRAITS_H__
|
||||
|
||||
#include <filename.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <dsound.h>
|
||||
#include <dmusici.h>
|
||||
#include "config_audio.h"
|
||||
#include "mss.h"
|
||||
|
||||
class MilesPlaying;
|
||||
|
||||
class EXPCL_PANDA MilesSound : public AudioTraits::SoundClass {
|
||||
public:
|
||||
INLINE MilesSound(HAUDIO audio);
|
||||
virtual ~MilesSound();
|
||||
|
||||
virtual float length() const;
|
||||
virtual AudioTraits::PlayingClass* get_state() const;
|
||||
virtual AudioTraits::PlayerClass* get_player() const;
|
||||
virtual AudioTraits::DeletePlayingFunc* get_delstate() const;
|
||||
|
||||
public:
|
||||
static MilesSound* load(Filename);
|
||||
static MilesSound* load_raw(unsigned char* data, unsigned long size);
|
||||
private:
|
||||
HAUDIO _audio;
|
||||
friend MilesPlaying;
|
||||
};
|
||||
|
||||
class MilesPlayer;
|
||||
|
||||
class EXPCL_PANDA MilesPlaying : public AudioTraits::PlayingClass {
|
||||
public:
|
||||
MilesPlaying(AudioTraits::SoundClass*);
|
||||
~MilesPlaying();
|
||||
|
||||
virtual AudioTraits::PlayingClass::PlayingStatus status();
|
||||
static void destroy(AudioTraits::PlayingClass*);
|
||||
|
||||
private:
|
||||
HAUDIO _audio;
|
||||
friend MilesPlayer;
|
||||
};
|
||||
|
||||
class EXPCL_PANDA MilesPlayer : public AudioTraits::PlayerClass {
|
||||
public:
|
||||
INLINE MilesPlayer();
|
||||
virtual ~MilesPlayer();
|
||||
|
||||
virtual void play_sound(AudioTraits::SoundClass*,
|
||||
AudioTraits::PlayingClass*,
|
||||
float start_time,
|
||||
int loop);
|
||||
virtual void stop_sound(AudioTraits::SoundClass*,
|
||||
AudioTraits::PlayingClass*);
|
||||
virtual void set_volume(AudioTraits::PlayingClass*, float volume);
|
||||
virtual bool adjust_volume(AudioTraits::PlayingClass*);
|
||||
public:
|
||||
// used by the readers
|
||||
static MilesPlayer* get_instance();
|
||||
private:
|
||||
static MilesPlayer* _global_instance;
|
||||
};
|
||||
|
||||
#include "audio_rad_mss_traits.I"
|
||||
|
||||
#endif /* __AUDIO_RAD_MSS_TRAITS_H__ */
|
||||
#endif //]
|
||||
|
|
@ -1,102 +0,0 @@
|
|||
// Filename: audio_sound.I
|
||||
// Created by: cary (17Oct00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioSound::constructor
|
||||
// Access: Protected
|
||||
// Description: initialize a new sound
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE AudioSound::AudioSound(AudioTraits::SoundClass* sound,
|
||||
AudioTraits::PlayingClass* state,
|
||||
AudioTraits::PlayerClass* player,
|
||||
AudioTraits::DeletePlayingFunc* destroy,
|
||||
const string& filename) : Namable(filename),
|
||||
_sound(sound),
|
||||
_state(state),
|
||||
_player(player),
|
||||
_delstate(destroy) {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioSound::copy constructor
|
||||
// Access: Protected
|
||||
// Description: copy a sound, but we don't really want to allow this
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE AudioSound::AudioSound(const AudioSound& c) : Namable(c.get_name()),
|
||||
_sound(c._sound),
|
||||
_state(c._state),
|
||||
_player(c._player),
|
||||
_delstate(c._delstate) {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioSound::assignment operator
|
||||
// Access: Protected
|
||||
// Description: copy a sound, but we don't really want to allow this
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE AudioSound& AudioSound::operator=(const AudioSound& c) {
|
||||
this->set_name(c.get_name());
|
||||
this->_sound = c._sound;
|
||||
this->_state = c._state;
|
||||
this->_player = c._player;
|
||||
this->_delstate = c._delstate;
|
||||
return *this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioSound::get_player
|
||||
// Access: Protected
|
||||
// Description: return the player for this sound
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE AudioTraits::PlayerClass* AudioSound::get_player() const {
|
||||
return _player;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioSound::get_sound
|
||||
// Access: Protected
|
||||
// Description: return the trait sound class for this sound
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE AudioTraits::SoundClass* AudioSound::get_sound() const {
|
||||
return _sound;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioSound::get_state
|
||||
// Access: Protected
|
||||
// Description: return the trait playing class for this sound
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE AudioTraits::PlayingClass* AudioSound::get_state() const {
|
||||
return _state;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioSound::equality operator
|
||||
// Access: Public
|
||||
// Description: test to see if two sounds are the same
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool AudioSound::operator==(const AudioSound& c) const {
|
||||
return ((_sound == c._sound) && (_state == c._state));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioSound::inequality operator
|
||||
// Access: Public
|
||||
// Description: test to see if two sounds are not the same
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool AudioSound::operator!=(const AudioSound& c) const {
|
||||
return ((_sound != c._sound) || (_state != c._state));
|
||||
}
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
// Filename: audio_sound.cxx
|
||||
// Created by: cary (17Oct00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "audio_sound.h"
|
||||
#include "config_audio.h"
|
||||
#include "audio_manager.h"
|
||||
|
||||
TypeHandle AudioSound::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioSound::destructor
|
||||
// Access: Public
|
||||
// Description: deletes the sound data and then lets the system
|
||||
// destroy this structure
|
||||
////////////////////////////////////////////////////////////////////
|
||||
AudioSound::
|
||||
~AudioSound() {
|
||||
audio_debug("AudioSound destructor (" << get_name() << ")");
|
||||
AudioManager::stop(this);
|
||||
(*_delstate)(_state);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioSound::length
|
||||
// Access: Public
|
||||
// Description: return the length (in seconds) of the sound
|
||||
////////////////////////////////////////////////////////////////////
|
||||
float AudioSound::
|
||||
length() const {
|
||||
return _sound->length();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AudioSound::status
|
||||
// Access: Public
|
||||
// Description: return the current play status of this sound
|
||||
////////////////////////////////////////////////////////////////////
|
||||
AudioSound::SoundStatus AudioSound::
|
||||
status() const {
|
||||
AudioTraits::PlayingClass::PlayingStatus stat = _state->status();
|
||||
switch (stat) {
|
||||
case AudioTraits::PlayingClass::BAD:
|
||||
return BAD;
|
||||
case AudioTraits::PlayingClass::READY:
|
||||
return READY;
|
||||
case AudioTraits::PlayingClass::PLAYING:
|
||||
return PLAYING;
|
||||
}
|
||||
audio_error("unknown status for sound");
|
||||
return BAD;
|
||||
}
|
||||
|
|
@ -1,104 +0,0 @@
|
|||
// Filename: audio_sound.h
|
||||
// Created by: cary (17Oct00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __AUDIO_SOUND_H__
|
||||
#define __AUDIO_SOUND_H__
|
||||
|
||||
#include "audio_trait.h"
|
||||
#include <typedReferenceCount.h>
|
||||
#include <typedObject.h>
|
||||
#include <namable.h>
|
||||
#include <pointerTo.h>
|
||||
|
||||
|
||||
class AudioPool;
|
||||
class AudioManager;
|
||||
|
||||
/*
|
||||
class EXPCL_PANDA AudioSound : public TypedObject, public Namable {
|
||||
*/
|
||||
class EXPCL_PANDA AudioSound : public TypedReferenceCount, public Namable {
|
||||
PUBLISHED:
|
||||
virtual ~AudioSound();
|
||||
INLINE bool operator==(const AudioSound&) const;
|
||||
INLINE bool operator!=(const AudioSound&) const;
|
||||
|
||||
enum Category { EFFECT, MUSIC }; // sync with AudioTraits::PlayingClass.
|
||||
enum SoundStatus { BAD, READY, PLAYING };
|
||||
|
||||
float length() const;
|
||||
SoundStatus status() const;
|
||||
|
||||
void set_category(Category category) {
|
||||
_state->set_category(
|
||||
(AudioTraits::PlayingClass::Category)(category)
|
||||
);
|
||||
}
|
||||
Category get_category() const {
|
||||
return (Category)(_state->get_category());
|
||||
}
|
||||
|
||||
private:
|
||||
PT(AudioTraits::SoundClass) _sound;
|
||||
AudioTraits::PlayingClass *_state;
|
||||
AudioTraits::PlayerClass *_player;
|
||||
AudioTraits::DeletePlayingFunc *_delstate;
|
||||
|
||||
protected:
|
||||
INLINE AudioSound(AudioTraits::SoundClass*, AudioTraits::PlayingClass*,
|
||||
AudioTraits::PlayerClass*, AudioTraits::DeletePlayingFunc*,
|
||||
const string&);
|
||||
INLINE AudioSound(const AudioSound&);
|
||||
INLINE AudioSound& operator=(const AudioSound&);
|
||||
|
||||
INLINE AudioTraits::PlayerClass* get_player() const;
|
||||
INLINE AudioTraits::SoundClass* get_sound() const;
|
||||
INLINE AudioTraits::PlayingClass* get_state() const;
|
||||
|
||||
friend class AudioPool;
|
||||
friend class AudioManager;
|
||||
|
||||
public:
|
||||
// type stuff
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
/*
|
||||
TypedObject::init_type();
|
||||
register_type(_type_handle, "AudioSound",
|
||||
TypedObject::get_class_type());
|
||||
*/
|
||||
TypedReferenceCount::init_type();
|
||||
register_type(_type_handle, "AudioSound",
|
||||
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;
|
||||
};
|
||||
|
||||
#include "audio_sound.I"
|
||||
|
||||
#endif /* __AUDIO_SOUND_H__ */
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
// Filename: audio_trait.cxx
|
||||
// Created by: cary (23Sep00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "audio_trait.h"
|
||||
#include "config_audio.h"
|
||||
|
||||
AudioTraits::SoundClass::~SoundClass() {
|
||||
}
|
||||
|
||||
float AudioTraits::SoundClass::length() const {
|
||||
audio_cat->error() << "In abstract SoundClass::length!" << endl;
|
||||
return -1.0;
|
||||
}
|
||||
|
||||
AudioTraits::PlayingClass* AudioTraits::SoundClass::get_state() const {
|
||||
audio_cat->error() << "In abstract SoundClass::get_state!" << endl;
|
||||
return (AudioTraits::PlayingClass*)0L;
|
||||
}
|
||||
|
||||
AudioTraits::PlayerClass* AudioTraits::SoundClass::get_player() const {
|
||||
audio_cat->error() << "In abstract SoundClass::get_player!" << endl;
|
||||
return (AudioTraits::PlayerClass*)0L;
|
||||
}
|
||||
|
||||
AudioTraits::DeletePlayingFunc*
|
||||
AudioTraits::SoundClass::get_delstate() const {
|
||||
audio_cat->error() << "In abstract SoundClass::get_delstate!" << endl;
|
||||
return (AudioTraits::DeletePlayingFunc*)0L;
|
||||
}
|
||||
|
||||
AudioTraits::PlayingClass::~PlayingClass() {
|
||||
}
|
||||
|
||||
AudioTraits::PlayingClass::PlayingStatus
|
||||
AudioTraits::PlayingClass::status() {
|
||||
audio_cat->error() << "In abstract PlayingClass::status!" << endl;
|
||||
return BAD;
|
||||
}
|
||||
|
||||
AudioTraits::PlayerClass::~PlayerClass() {
|
||||
}
|
||||
|
||||
void AudioTraits::PlayerClass::play_sound(AudioTraits::SoundClass*,
|
||||
AudioTraits::PlayingClass*, float, int) {
|
||||
audio_cat->error() << "In abstract PlayerClass::play_sound!" << endl;
|
||||
}
|
||||
|
||||
void AudioTraits::PlayerClass::stop_sound(AudioTraits::SoundClass*,
|
||||
AudioTraits::PlayingClass*) {
|
||||
audio_cat->error() << "In abstract PlayerClass::stop_sound!" << endl;
|
||||
}
|
||||
|
||||
void AudioTraits::PlayerClass::set_volume(AudioTraits::PlayingClass*, float) {
|
||||
audio_cat->error() << "In abstract PlayerClass::set_volume!" << endl;
|
||||
}
|
||||
|
||||
bool AudioTraits::PlayerClass::adjust_volume(AudioTraits::PlayingClass*) {
|
||||
audio_cat->error() << "In abstract PlayerClass::adjust_volume!" << endl;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
// Filename: audio_trait.h
|
||||
// Created by: frang (06Jul00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __AUDIO_TRAIT_H__
|
||||
#define __AUDIO_TRAIT_H__
|
||||
|
||||
#include <pandabase.h>
|
||||
#include <referenceCount.h>
|
||||
|
||||
#if ! defined(HAVE_RAD_MSS)
|
||||
#error where is rad mss?
|
||||
#endif
|
||||
|
||||
class EXPCL_PANDA AudioTraits {
|
||||
public:
|
||||
class SoundClass;
|
||||
class PlayingClass;
|
||||
class PlayerClass;
|
||||
|
||||
typedef void DeleteSoundFunc(SoundClass*);
|
||||
typedef void DeletePlayingFunc(PlayingClass*);
|
||||
|
||||
class EXPCL_PANDA SoundClass : public ReferenceCount {
|
||||
public:
|
||||
SoundClass() {}
|
||||
virtual ~SoundClass();
|
||||
|
||||
virtual float length() const = 0;
|
||||
virtual PlayingClass* get_state() const = 0;
|
||||
virtual PlayerClass* get_player() const = 0;
|
||||
virtual DeletePlayingFunc* get_delstate() const = 0;
|
||||
};
|
||||
class EXPCL_PANDA PlayingClass {
|
||||
public:
|
||||
PlayingClass(SoundClass* s)
|
||||
: _sound(s), _volume(1.0), _category(EFFECT) {}
|
||||
virtual ~PlayingClass();
|
||||
|
||||
enum Category { EFFECT, MUSIC }; // sync with AudioSound.
|
||||
|
||||
enum PlayingStatus { BAD, READY, PLAYING };
|
||||
|
||||
virtual PlayingStatus status() = 0;
|
||||
INLINE void set_volume(float v) { _volume = v; }
|
||||
INLINE float get_volume() const { return _volume; }
|
||||
|
||||
void set_category(Category category) { _category=category; }
|
||||
Category get_category() const { return _category; }
|
||||
protected:
|
||||
SoundClass* _sound;
|
||||
float _volume;
|
||||
Category _category;
|
||||
};
|
||||
class EXPCL_PANDA PlayerClass {
|
||||
public:
|
||||
PlayerClass() {}
|
||||
virtual ~PlayerClass();
|
||||
|
||||
virtual void play_sound(SoundClass*, PlayingClass*, float start_time, int loop) = 0;
|
||||
virtual void stop_sound(SoundClass*, PlayingClass*) = 0;
|
||||
virtual void set_volume(PlayingClass*, float) = 0;
|
||||
virtual bool adjust_volume(PlayingClass*) = 0;
|
||||
};
|
||||
};
|
||||
|
||||
#endif /* __AUDIO_TRAIT_H__ */
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
// Filename: audio_win_traits.I
|
||||
// Created by: cary (27Sep00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
INLINE WinSample::
|
||||
WinSample()
|
||||
: AudioTraits::SoundClass(), _data(NULL), _len(0) {
|
||||
}
|
||||
|
||||
INLINE DWORD WinSample::
|
||||
get_length() const {
|
||||
return _len;
|
||||
}
|
||||
|
||||
INLINE WAVEFORMATEX WinSample::
|
||||
get_format() const {
|
||||
return _info;
|
||||
}
|
||||
|
||||
INLINE WinMusic::
|
||||
WinMusic()
|
||||
: AudioTraits::SoundClass(),
|
||||
_performance(NULL), _music(NULL),
|
||||
_buffer(NULL), _synth(NULL) {
|
||||
init();
|
||||
}
|
||||
|
||||
INLINE IDirectMusicPerformance* WinMusic::
|
||||
get_performance() const {
|
||||
return _performance;
|
||||
}
|
||||
|
||||
INLINE IDirectMusicSegment* WinMusic::
|
||||
get_music() {
|
||||
return _music;
|
||||
}
|
||||
|
||||
INLINE LPDIRECTSOUNDBUFFER WinSamplePlaying::
|
||||
get_channel() {
|
||||
return _channel;
|
||||
}
|
||||
|
||||
INLINE IDirectMusicPerformance* WinMusicPlaying::
|
||||
get_performance() const {
|
||||
WinMusic* wmusic = (WinMusic*)_sound;
|
||||
return wmusic->get_performance();
|
||||
}
|
||||
|
||||
INLINE WinSamplePlayer::
|
||||
WinSamplePlayer()
|
||||
: AudioTraits::PlayerClass() {
|
||||
}
|
||||
|
||||
INLINE WinMusicPlayer::
|
||||
WinMusicPlayer()
|
||||
: AudioTraits::PlayerClass() {
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,148 +0,0 @@
|
|||
// Filename: audio_win_traits.h
|
||||
// Created by: cary (27Sep00)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, 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://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
// yes, this needs to be outside the ifdef protection
|
||||
#include "audio_trait.h"
|
||||
|
||||
#ifdef AUDIO_USE_WIN32
|
||||
#ifndef __AUDIO_WIN_TRAITS_H__
|
||||
#define __AUDIO_WIN_TRAITS_H__
|
||||
|
||||
#error You should try the Miles version.
|
||||
|
||||
#include <filename.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <dsound.h>
|
||||
#include <dmusici.h>
|
||||
#include "config_audio.h"
|
||||
|
||||
class WinSamplePlaying;
|
||||
|
||||
class EXPCL_PANDA WinSample : public AudioTraits::SoundClass {
|
||||
public:
|
||||
BYTE* _data;
|
||||
DWORD _len;
|
||||
WAVEFORMATEX _info;
|
||||
public:
|
||||
INLINE WinSample();
|
||||
virtual ~WinSample();
|
||||
|
||||
virtual float length() const;
|
||||
virtual AudioTraits::PlayingClass* get_state() const;
|
||||
virtual AudioTraits::PlayerClass* get_player() const;
|
||||
virtual AudioTraits::DeletePlayingFunc* get_delstate() const;
|
||||
|
||||
// used by play_sound
|
||||
INLINE DWORD get_length() const;
|
||||
INLINE WAVEFORMATEX get_format() const;
|
||||
public:
|
||||
static WinSample* load_wav(Filename);
|
||||
static WinSample* load_raw(unsigned char*, unsigned long);
|
||||
};
|
||||
|
||||
class EXPCL_PANDA WinMusic : public AudioTraits::SoundClass {
|
||||
private:
|
||||
IDirectMusicPerformance* _performance;
|
||||
IDirectMusicSegment* _music;
|
||||
IDirectSoundBuffer* _buffer;
|
||||
IDirectMusicPort* _synth;
|
||||
|
||||
void init();
|
||||
public:
|
||||
INLINE WinMusic();
|
||||
virtual ~WinMusic();
|
||||
|
||||
virtual float length() const;
|
||||
virtual AudioTraits::PlayingClass* get_state() const;
|
||||
virtual AudioTraits::PlayerClass* get_player() const;
|
||||
virtual AudioTraits::DeletePlayingFunc* get_delstate() const;
|
||||
// these are used by the loaders
|
||||
static WinMusic* load_midi(Filename);
|
||||
// these are used by the players
|
||||
INLINE IDirectMusicPerformance* get_performance() const;
|
||||
INLINE IDirectMusicSegment* get_music();
|
||||
};
|
||||
|
||||
class EXPCL_PANDA WinSamplePlaying : public AudioTraits::PlayingClass {
|
||||
private:
|
||||
LPDIRECTSOUNDBUFFER _channel;
|
||||
BYTE* _data;
|
||||
public:
|
||||
WinSamplePlaying(AudioTraits::SoundClass*);
|
||||
~WinSamplePlaying();
|
||||
|
||||
virtual AudioTraits::PlayingClass::PlayingStatus status();
|
||||
static void destroy(AudioTraits::PlayingClass*);
|
||||
// these are used by the laoders
|
||||
BYTE* lock();
|
||||
void unlock();
|
||||
// these are used by the player
|
||||
INLINE LPDIRECTSOUNDBUFFER get_channel();
|
||||
};
|
||||
|
||||
class EXPCL_PANDA WinMusicPlaying : public AudioTraits::PlayingClass {
|
||||
public:
|
||||
WinMusicPlaying(AudioTraits::SoundClass*);
|
||||
~WinMusicPlaying();
|
||||
|
||||
virtual AudioTraits::PlayingClass::PlayingStatus status();
|
||||
static void destroy(AudioTraits::PlayingClass*);
|
||||
INLINE IDirectMusicPerformance* get_performance() const;
|
||||
};
|
||||
|
||||
class EXPCL_PANDA WinSamplePlayer : public AudioTraits::PlayerClass {
|
||||
public:
|
||||
INLINE WinSamplePlayer();
|
||||
virtual ~WinSamplePlayer();
|
||||
|
||||
virtual void play_sound(AudioTraits::SoundClass*,
|
||||
AudioTraits::PlayingClass*, float);
|
||||
virtual void stop_sound(AudioTraits::SoundClass*,
|
||||
AudioTraits::PlayingClass*);
|
||||
virtual void set_volume(AudioTraits::PlayingClass*, float);
|
||||
virtual bool adjust_volume(AudioTraits::PlayingClass*);
|
||||
public:
|
||||
// used by the readers
|
||||
static WinSamplePlayer* get_instance();
|
||||
private:
|
||||
static WinSamplePlayer* _global_instance;
|
||||
};
|
||||
|
||||
class EXPCL_PANDA WinMusicPlayer : public AudioTraits::PlayerClass {
|
||||
public:
|
||||
INLINE WinMusicPlayer();
|
||||
virtual ~WinMusicPlayer();
|
||||
|
||||
virtual void play_sound(AudioTraits::SoundClass*,
|
||||
AudioTraits::PlayingClass*, float);
|
||||
virtual void stop_sound(AudioTraits::SoundClass*,
|
||||
AudioTraits::PlayingClass*);
|
||||
virtual void set_volume(AudioTraits::PlayingClass*, float);
|
||||
virtual bool adjust_volume(AudioTraits::PlayingClass*);
|
||||
public:
|
||||
// used by the readers
|
||||
static WinMusicPlayer* get_instance();
|
||||
private:
|
||||
static WinMusicPlayer* _global_instance;
|
||||
};
|
||||
|
||||
#include "audio_win_traits.I"
|
||||
|
||||
#endif /* __AUDIO_WIN_TRAITS_H__ */
|
||||
#endif /* AUDIO_USE_WIN32 */
|
||||
Loading…
Reference in New Issue