]> git.mxchange.org Git - simgear.git/blobdiff - simgear/sound/sample_openal.hxx
(try to) properly align model and viewer
[simgear.git] / simgear / sound / sample_openal.hxx
index e04889793af9981f7d87cc6749f2dd14b79b4017..5d4baf624886ef79261f2e617a5e29b9f96339e1 100644 (file)
@@ -2,7 +2,7 @@
 // 
 // Written by Curtis Olson, started April 2004.
 //
-// Copyright (C) 2004  Curtis L. Olson - curt@flightgear.org
+// Copyright (C) 2004  Curtis L. Olson - http://www.flightgear.org/~curt
 //
 // This program is free software; you can redistribute it and/or
 // modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
 //
 // You should have received a copy of the GNU General Public License
 // along with this program; if not, write to the Free Software
-// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //
 // $Id$
 
 # error This library requires C++
 #endif
 
-#include <simgear/compiler.h>
-
-#include STL_STRING
-
-#if defined(__APPLE__)
-# define AL_ILLEGAL_ENUM AL_INVALID_ENUM
-# define AL_ILLEGAL_COMMAND AL_INVALID_OPERATION
-# include <OpenAL/al.h>
-# include <OpenAL/alut.h>
-#else
-# include <AL/al.h>
-# include <AL/alut.h>
-#endif
+#include <string>
 
+#include <simgear/compiler.h>
 #include <simgear/debug/logstream.hxx>
+#include <simgear/structure/SGReferenced.hxx>
+#include <simgear/structure/SGSharedPtr.hxx>
+#include <simgear/math/SGMath.hxx>
 
-SG_USING_STD(string);
+#include <plib/sg.h>
 
+using std::string;
 
 /**
  * manages everything we need to know for an individual sound sample
  */
 
-class SGSoundSample {
+class SGSoundSample : public SGReferenced {
 
 private:
 
-    string sample_name;
+    // Position of the source sound.
+    SGVec3d _absolute_pos;     // absolute position
+    SGVec3f _relative_pos;     // position relative to the base position
+    SGVec3d _base_pos;         // base position
+
+    // The orientation of the sound (direction and cut-off angles)
+    SGVec3f _direction;
+
+    // Velocity of the source sound.
+    SGVec3f _velocity;
+
+    string _sample_name;
+    unsigned char *_data;
+
+    // configuration values
+    int _format;
+    int _size;
+    int _freq;
 
     // Buffers hold sound data.
-    ALuint buffer;
+    bool _valid_buffer;
+    unsigned int _buffer;
 
     // Sources are points emitting sound.
-    ALuint source;
+    bool _valid_source;
+    unsigned int _source;
 
-    // Position of the source sound.
-    ALfloat source_pos[3];
+    // The orientation of the sound (direction and cut-off angles)
+    float _inner_angle;
+    float _outer_angle;
+    float _outer_gain;
 
-    // Velocity of the source sound.
-    ALfloat source_vel[3];
+    float _pitch;
+    float _volume;
+    float _master_volume;
+    float _reference_dist;
+    float _max_dist;
+    bool _loop;
 
-    // configuration values
-    ALenum format;
-    ALsizei size;
-    ALvoid* data;
-    ALsizei freq;
+    bool _playing;
+    bool _changed;
+    bool _static_changed;
+    bool _is_file;
 
-    double pitch;
-    double volume;
-    double reference_dist;
-    double max_dist;
-    ALboolean loop;
+    void update_absolute_position();
 
 public:
 
+     /**
+      * Empty constructor, can be used to read data to the systems
+      * memory and not to the driver.
+      */
+    SGSoundSample();
+
     /**
      * Constructor
      * @param path Path name to sound
      * @param file File name of sound
-     * @param cleanup Request clean up the intermediate data (this
        should usually be true unless you want to manipulate the data
        later.)
      */
-    SGSoundSample( const char *path, const char *file, bool cleanup );
-    SGSoundSample( unsigned char *_data, int len, int _freq );
-    ~SGSoundSample();
+    SGSoundSample( const char *path, const char *file );
+
+    /**
+     * Constructor.
+     * @param _data Pointer to a memory buffer containing the sample data
+       the application is responsible for freeing the buffer data.
+     * @param len Byte length of array
+     * @param _freq Frequency of the provided data (bytes per second)
+       should usually be true unless you want to manipulate the data
+       later.)
+     */
+    SGSoundSample( unsigned char *data, int len, int freq, int format = AL_FORMAT_MONO8 );
+
+    ~SGSoundSample ();
+
+    /**
+     * detect wheter the sample holds the information of a sound file
+     */
+    inline bool is_file() const { return _is_file; }
+
+    /**
+     * Test whether this sample has a changed configuration since the last
+     * call. (Calling this function resets the value).
+     */
+    inline bool has_changed() {
+        bool b = _changed; _changed = false; return b;
+    }
+
+    inline bool has_static_data_changed() {
+        bool b = _static_changed; _static_changed = false; return b;
+    }
+
 
     /**
      * Start playing this sample.
      *
-     * @param _loop Define wether the sound should be played in a loop.
+     * @param _loop Define whether the sound should be played in a loop.
+     */
+    inline void play( bool loop ) {
+        _playing = true; _loop = loop; _changed = true;
+    }
+
+    /**
+     * Return if the sample is looping or not.
      */
-    void play( bool _loop );
+    inline bool get_looping() { return _loop; }
 
     /**
      * Stop playing this sample.
      *
      * @param sched A pointer to the appropriate scheduler.
      */
-    void stop();
+    inline void stop() {
+        _playing = false; _changed = true;
+    }
 
     /**
      * Play this sample once.
@@ -126,111 +182,229 @@ public:
     inline void play_looped() { play(true); }
 
     /**
-     * Test if a sample is curretnly playing.
+     * Test if a sample is currently playing.
      * @return true if is is playing, false otherwise.
      */
-    inline bool is_playing( ) {
-        ALint result;
-        alGetSourcei( source, AL_SOURCE_STATE, &result );
-        if ( alGetError() != AL_NO_ERROR) {
-            SG_LOG( SG_GENERAL, SG_ALERT,
-                    "Oops AL error in sample is_playing(): " << sample_name );
-        }
-        return (result == AL_PLAYING) ;
+    inline bool is_playing() { return _playing; }
+
+    /**
+     * set the data associated with this sample
+     */
+    inline void set_data( unsigned char* data ) {
+        _data = data;
+    }
+
+    /**
+     * @return the data associated with this sample
+     */
+    inline void* get_data() const { return _data; }
+
+    /**
+     * free the data associated with this sample
+     */
+    inline void free_data() {
+        if (_data != NULL) { delete[] _data; _data = NULL; }
+    }
+
+    /**
+     * set the source id of this source
+     */
+    inline void set_source(unsigned int s) {
+        _source = s; _valid_source = true; _changed = true;
+    }
+
+    /**
+     * get the source id of this source
+     */
+    inline unsigned int get_source() { return _source; }
+
+    /**
+     * detect wheter the source id of the sample is valid
+     */
+    inline bool is_valid_source() const { return _valid_source; }
+
+    /**
+     * set the source id of the sample to invalid.
+     */
+    inline void no_valid_source() {
+        _valid_source = false;
+    }
+
+    /**
+     * set the buffer id of this source
+     */
+    inline void set_buffer(unsigned int b) {
+        _buffer = b; _valid_buffer = true; _changed = true;
+    } 
+
+    /**
+     * get the buffer id of this source
+     */
+    inline unsigned int get_buffer() { return _buffer; }
+
+    /**
+     * detect wheter the source id of the sample is valid
+     */
+    inline bool is_valid_buffer() const { return _valid_buffer; }
+
+    /**
+     * set the source id of the sample to invalid.
+     */
+    inline void no_valid_buffer() {
+        _valid_buffer = false;
     }
 
     /**
      * Get the current pitch setting of this sample.
      */
-    inline double get_pitch() const { return pitch; }
+    inline float get_pitch() { return _pitch; }
 
     /**
      * Set the pitch of this sample.
      */
-    inline void set_pitch( double p ) {
-        // clamp in the range of 0.01 to 2.0
-        if ( p < 0.01 ) { p = 0.01; }
-        if ( p > 2.0 ) { p = 2.0; }
-        pitch = p;
-        alSourcef( source, AL_PITCH, pitch );
-        if ( alGetError() != AL_NO_ERROR) {
-            SG_LOG( SG_GENERAL, SG_ALERT,
-                    "Oops AL error in sample set_pitch()! " << p
-                    << " for " << sample_name );
-        }
+    inline void set_pitch( float p ) {
+        _pitch = p; _changed = true;
     }
 
     /**
      * Get the current volume setting of this sample.
      */
-    inline double get_volume() const { return volume; }
+    inline float get_volume() { return _volume * _master_volume; }
+
+    /**
+     * Set the master (sampel group) volume of this sample.
+     */
+    inline void set_master_volume( float v ) {
+        _master_volume = v; _changed = true;
+    }
 
     /**
      * Set the volume of this sample.
      */
-    inline void set_volume( double v ) {
-        volume = v;
-        alSourcef( source, AL_GAIN, volume );
-        if ( alGetError() != AL_NO_ERROR) {
-            SG_LOG( SG_GENERAL, SG_ALERT,
-                    "Oops AL error in sample set_volume()! " << v
-                    << " for " << sample_name  );
-        }
+    inline void set_volume( float v ) {
+        _volume = v; _changed = true;
     }
 
     /**
-     * Returns the size of the sounds sample
+     * Set the format of the sounds sample
      */
-    inline int get_size() {
-        return size;
+    inline void set_format( int format ) {
+        _format = format;
     }
 
     /**
-     * Return a pointer to the raw data
+     * Returns the format of the sounds sample
+     */
+    inline int get_format() { return _format; }
+
+
+    /**
+     * Set the frequency of the sounds sample
+     */
+    inline void set_frequency( int freq ) {
+        _freq = freq; _changed = true;
+    }
+
+    /**
+     * Returns the frequency of the sounds sample
+     */
+    inline int get_frequency() { return _freq; }
+
+    /**
+     * Returns the size of the sounds sample
      */
-    inline char *get_data() {
-        return (char *)data;
+    inline void set_size( int size ) {
+        _size = size;
     }
 
     /**
-     * Set position of sound source (uses same coordinate system as opengl)
+     * Returns the size of the sounds sample
+     */
+    inline int get_size() const { return _size; }
+
+    /**
+     * Set position of the sound source (uses same coordinate system as opengl)
      */
-    inline void set_source_pos( ALfloat *pos ) {
-        source_pos[0] = pos[0];
-        source_pos[1] = pos[1];
-        source_pos[2] = pos[2];
-        alSourcefv( source, AL_POSITION, source_pos );
+    void set_base_position( SGVec3d pos );
+    void set_relative_position( SGVec3f pos );
+
+    /**
+     * Get position of the sound source (uses same coordinate system as opengl)
+     */
+    inline float *get_position() const { return toVec3f(_absolute_pos).data(); }
+
+    /**
+     * Set the orientation of the sound source, both for direction
+     * and audio cut-off angles.
+     */
+    void set_orientation( SGVec3f dir );
+
+    /**
+     * Define the audio cone parameters for directional audio
+     */
+    inline void set_audio_cone( float inner, float outer, float gain ) {
+        _inner_angle = inner;
+        _outer_angle = outer;
+        _outer_gain = gain;
+        _static_changed = true;
     }
 
     /**
-     * Set velocity of sound source (uses same coordinate system as opengl)
+     * Get the orientation of the sound source, the inner or outer angle
+     * or outer gain.
+     */
+    inline float *get_orientation() { return _direction.data(); }
+    inline float *get_direction() { return _direction.data(); }
+    inline float get_innerangle() { return _inner_angle; }
+    inline float get_outerangle() { return _outer_angle; }
+    inline float get_outergain() { return _outer_gain; }
+
+    /**
+     * Set velocity of the sound source (uses same coordinate system as opengl)
      */
-    inline void set_source_vel( ALfloat *vel ) {
-        source_vel[0] = vel[0];
-        source_vel[1] = vel[1];
-        source_vel[2] = vel[2];
-        alSourcefv( source, AL_VELOCITY, source_vel );
+    inline void set_velocity( SGVec3f vel ) {
+        _velocity = SGVec3f(vel); _changed = true;
     }
 
+    /**
+     * Get velocity of the sound source (uses same coordinate system as opengl)
+     */
+    inline float *get_velocity() { return _velocity.data(); }
+
 
     /**
      * Set reference distance of sound (the distance where the gain
      * will be half.)
      */
-    inline void set_reference_dist( ALfloat dist ) {
-        reference_dist = dist;
-        alSourcef( source, AL_REFERENCE_DISTANCE, reference_dist );
+    inline void set_reference_dist( float dist ) {
+        _reference_dist = dist; _static_changed = true;
     }
 
+    /**
+     * Get reference distance of sound (the distance where the gain
+     * will be half.)
+     */
+    inline float get_reference_dist() { return _reference_dist; }
+
 
     /**
-     * Set maximume distance of sound (the distance where the sound is
+     * Set maximum distance of sound (the distance where the sound is
      * no longer audible.
      */
-    inline void set_max_dist( ALfloat dist ) {
-        max_dist = dist;
-        alSourcef( source, AL_MAX_DISTANCE, max_dist );
+    void set_max_dist( float dist ) {
+        _max_dist = dist; _static_changed = true;
     }
+
+    /**
+     * Get maximum istance of sound (the distance where the sound is
+     * no longer audible.
+     */
+    inline float get_max_dist() { return _max_dist; }
+
+    /**
+     * Get the name of this sample
+     */
+    inline string get_sample_name() { return _sample_name; }
 };