FGFX::~FGFX ()
{
+ for (unsigned int i = 0; i < _sound.size(); i++ )
+ delete _sound[i];
}
void
// static double _fg_pow3(double v) { return pow(v, 3); };
static const struct {
- string name;
+ char *name;
double (*fn)(double);
} __fg_snd_fn[] = {
// {"lin", _fg_lin},
SG_LOG( SG_GENERAL, SG_INFO, "Unknown sound type, default to 'level'");
}
-
#if 0
//
// set position properties
// Initialize the sample
//
FGSoundMgr * mgr = globals->get_soundmgr();
- if (mgr->find(_name) == NULL) {
+ if ((_sample = mgr->find(_name)) == NULL)
_sample = mgr->add(_name, _node->getStringValue("path"));
- _sample->set_volume(v);
- _sample->set_pitch(p);
- } else {
- _sample = mgr->find(_name);
- _sample->set_volume(_sample->get_volume() + v);
- _sample->set_pitch(_sample->get_pitch() + p);
- }
+ _sample->set_volume(v);
+ _sample->set_pitch(p);
}
void
// If the state changes to false, stop playing.
//
if (!check) {
- _active = false;
- if (mgr->is_playing(_name)) {
+ if (_active) {
SG_LOG(SG_GENERAL, SG_INFO, "Stopping sound: " << _name);
- mgr->stop(_name);
+ _sample->stop( mgr->get_scheduler(), false );
+ _active = false;
}
return;
// Check for state changes.
// If the state changed, and the sound is still playing: stop playing.
//
- if (mgr->is_playing(_name)) {
+ if (_sample->is_playing()) {
SG_LOG(SG_GENERAL, SG_INFO, "Stopping sound: " << _name);
- mgr->stop(_name);
+ _sample->stop( mgr->get_scheduler() );
}
if ( ((_type == FGSound::RAISE) && !check) ||
((_type == FGSound::FALL) && check) )
return;
+
}
- //
- // Update the volume
- //
- int max = _volume.size();
+ //
+ // Update the volume
+ //
+ int max = _volume.size();
- int i;
- double volume = 1.0, volume_offset = 0.0;
- for(i = 0; i < max; i++) {
- double v = _volume[i].prop->getDoubleValue();
+ int i;
+ double volume = 1.0, volume_offset = 0.0;
+ for(i = 0; i < max; i++) {
+ double v = _volume[i].prop->getDoubleValue();
- if (_volume[i].fn)
- v = _volume[i].fn(v);
+ if (_volume[i].fn)
+ v = _volume[i].fn(v);
- v *= _volume[i].factor;
+ v *= _volume[i].factor;
- if (v > _volume[i].max)
- v = _volume[i].max;
- else
- if (v < _volume[i].min)
- v = 0; // v = _volume[i].min;
+ if (v > _volume[i].max)
+ v = _volume[i].max;
+ else
+ if (v < _volume[i].min)
+ v = 0; // v = _volume[i].min;
- if (_volume[i].subtract) // Hack!
- volume = _volume[i].offset - v;
- else {
- volume_offset += _volume[i].offset;
- volume *= v;
+ if (_volume[i].subtract) // Hack!
+ volume = _volume[i].offset - v;
+ else {
+ volume_offset += _volume[i].offset;
+ volume *= v;
+ }
}
- }
- //
- // Update the pitch
- //
- max = _pitch.size();
- double pitch = 1.0, pitch_offset = 0.0;
- for(i = 0; i < max; i++) {
- double p = _pitch[i].prop->getDoubleValue();
-
- if (_pitch[i].fn)
- p = _pitch[i].fn(p);
-
- p *= _pitch[i].factor;
-
- if (p > _pitch[i].max)
- p = _pitch[i].max;
- else
- if (p < _pitch[i].min)
- p = _pitch[i].min;
-
- if (_pitch[i].subtract) // Hack!
- pitch = _pitch[i].offset - p;
- else {
- pitch_offset += _pitch[i].offset;
- pitch *= p;
+ //
+ // Update the pitch
+ //
+ max = _pitch.size();
+ double pitch = 1.0, pitch_offset = 0.0;
+ for(i = 0; i < max; i++) {
+ double p = _pitch[i].prop->getDoubleValue();
+
+ if (_pitch[i].fn)
+ p = _pitch[i].fn(p);
+
+ p *= _pitch[i].factor;
+
+ if (p > _pitch[i].max)
+ p = _pitch[i].max;
+ else
+ if (p < _pitch[i].min)
+ p = _pitch[i].min;
+
+ if (_pitch[i].subtract) // Hack!
+ pitch = _pitch[i].offset - p;
+ else {
+ pitch_offset += _pitch[i].offset;
+ pitch *= p;
+ }
}
- }
- //
- // Change sample state
- //
- _sample->set_pitch( pitch_offset + pitch );
- _sample->set_volume( volume_offset + volume );
+ //
+ // Change sample state
+ //
+ _sample->set_pitch( pitch_offset + pitch );
+ _sample->set_volume( volume_offset + volume );
//
// Do we need to start playing the sample?
//
- if (_active && ((_type == FGSound::LEVEL) || (_type == FGSound::INVERTED)))
- return;
+ if (_active && (_type == FGSound::LEVEL) || (_type == FGSound::INVERTED))
+ return;
//
// This is needed for FGSound::FLIPFLOP and it works for
SG_LOG(SG_GENERAL, SG_INFO, "Starting audio playback for: " << _name);
SG_LOG(SG_GENERAL, SG_BULK,
"Playing " << ((_mode == ONCE) ? "once" : "looped"));
- SG_LOG(SG_GENERAL, SG_BULK, "Initial volume: " << volume_offset);
- SG_LOG(SG_GENERAL, SG_BULK, "Initial pitch: " << pitch_offset);
}
//
// constructor
-FGSimpleSound::FGSimpleSound( string file ) {
+FGSimpleSound::FGSimpleSound( string file )
+ : requests(0),
+ volume(1.0),
+ pitch(1.0)
+{
SGPath slfile( globals->get_fg_root() );
slfile.append( file );
sample = new slSample ( (char *)slfile.c_str() );
volume_envelope->setStep ( 0, 0.01, 1.0 );
}
-FGSimpleSound::FGSimpleSound( unsigned char *buffer, int len ) {
+FGSimpleSound::FGSimpleSound( unsigned char *buffer, int len )
+ : requests(0),
+ volume(1.0),
+ pitch(1.0)
+{
sample = new slSample ( buffer, len );
pitch_envelope = new slEnvelope( 1, SL_SAMPLE_ONE_SHOT );
volume_envelope = new slEnvelope( 1, SL_SAMPLE_ONE_SHOT );
delete sample;
}
-void FGSimpleSound::play_once( slScheduler *sched ) {
- sched->stopSample(sample);
- sched->playSample(sample);
+void FGSimpleSound::play( slScheduler *sched, bool looped ) {
+
+ requests++;
+ if (requests > 1)
+ return;
+
+ // sched->stopSample(sample);
+ if (looped)
+ sched->loopSample(sample);
+ else
+ sched->playSample(sample);
+
sched->addSampleEnvelope(sample, 0, 0, pitch_envelope, SL_PITCH_ENVELOPE);
sched->addSampleEnvelope(sample, 0, 1, volume_envelope, SL_VOLUME_ENVELOPE);
}
-void FGSimpleSound::play_looped( slScheduler *sched ) {
- sched->loopSample(sample);
- sched->addSampleEnvelope(sample, 0, 0, pitch_envelope, SL_PITCH_ENVELOPE);
- sched->addSampleEnvelope(sample, 0, 1, volume_envelope, SL_VOLUME_ENVELOPE);
+void FGSimpleSound::stop( slScheduler *sched, bool quick ) {
+
+ if (quick)
+ requests = 0;
+ else
+ if (--requests < 0)
+ requests = 0;
+
+ if (requests > 0)
+ return;
+
+ sched->stopSample( sample );
}
//
slEnvelope *volume_envelope;
double pitch;
double volume;
- int clients;
+ int requests;
public:
FGSimpleSound( unsigned char *buffer, int len );
~FGSimpleSound();
- void play_once( slScheduler *sched );
- void play_looped( slScheduler *sched );
+ void play( slScheduler *sched, bool looped );
+ void stop( slScheduler *sched, bool quick = true );
- inline void play( slScheduler *sched, bool looped ) {
- if (looped) play_looped( sched );
- else play_once( sched );
- }
- inline void stop( slScheduler *sched ) {
- sched->stopSample( sample );
- }
- inline bool is_playing( ) {
- return (sample->getPlayCount() > 0 );
- }
+ inline void play_once( slScheduler *sched ) { play( sched, false); }
+ inline void play_looped( slScheduler *sched ) { play( sched, true); }
+ inline bool is_playing( ) { return (requests > 0 ); }
inline double get_pitch() const { return pitch; }
inline void set_pitch( double p ) {
glGenTextures(1, &texName);
glBindTexture(GL_TEXTURE_2D, texName);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEXRES_X, TEXRES_Y, 0, GL_RGBA, GL_UNSIGNED_BYTE, env_map);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
+ /*
glBegin(GL_QUADS);
glNormal3f(0.0, 0.0, 1.0);
glVertex3f(1.0, 1.0, 0.0);
glVertex3f(-1.0, -1.0, 0.0);
glVertex3f(1.0, -1.0, 0.0);
glEnd();
+ */
+
+ glPointSize(48.0);
+ glBegin(GL_POINTS);
+ glNormal3f(0.0, 0.0, 1.0);
+ glVertex3f(0.0, 0.0, 0.0);
+ glEnd();
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);