00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "sound.h"
00022
00023 #include "engine.h"
00024 #include "buffer.h"
00025
00026 #include <QtCore/QDebug>
00027 #include <sndfile.h>
00028
00029 #include <core/debughelper.h>
00030
00031 using namespace GluonAudio;
00032
00033 class Sound::SoundPrivate
00034 {
00035 public:
00036 SoundPrivate()
00037 {
00038 buffer = new Buffer;
00039 source = 0;
00040 position = QVector3D( 0, 0, 0 );
00041 volume = 1.0f;
00042 pitch = 1.0f;
00043 radius = 10000.0f;
00044
00045 alGenSources( 1, &source );
00046
00047 ALfloat sourcePosition[] = { position.x(), position.y() , position.z() };
00048 alSourcefv( source, AL_POSITION, sourcePosition );
00049 alSourcef( source, AL_GAIN, volume );
00050 alSourcef( source, AL_PITCH, pitch );
00051 alSourcef( source, AL_REFERENCE_DISTANCE, radius );
00052 }
00053 ~SoundPrivate()
00054 {
00055 alDeleteSources( 1, &source );
00056 delete buffer;
00057 }
00058
00059 Buffer* buffer;
00060 ALuint source;
00061 QVector3D position;
00062 ALfloat volume;
00063 ALfloat pitch;
00064 ALfloat radius;
00065 };
00066
00067 Sound::Sound( QObject* parent )
00068 : QObject( parent )
00069 , d( new SoundPrivate )
00070 {
00071 }
00072
00073 Sound::Sound( const QString& soundFile, QObject* parent )
00074 : QObject( parent )
00075 , d( new SoundPrivate )
00076 {
00077 load( soundFile );
00078 }
00079
00080 Sound::Sound( Buffer* buffer, QObject* parent )
00081 : QObject( parent )
00082 , d( new SoundPrivate )
00083 {
00084 load( buffer );
00085 }
00086
00087 Sound::Sound( ALuint buffer, QObject* parent )
00088 : QObject( parent )
00089 , d( new SoundPrivate )
00090 {
00091 load( buffer );
00092 }
00093
00094 Sound::~Sound()
00095 {
00096 delete d;
00097 }
00098
00099 void Sound::load( const QString& soundFile )
00100 {
00101 d->buffer->setBuffer( soundFile );
00102 setupSource();
00103 }
00104
00105 void Sound::load( Buffer* buffer )
00106 {
00107 delete d->buffer;
00108 d->buffer = buffer;
00109 setupSource();
00110 }
00111 void Sound::load( ALuint buffer )
00112 {
00113 delete d->buffer;
00114 d->buffer = new Buffer( buffer );
00115 setupSource();
00116 }
00117
00118 void Sound::setupSource()
00119 {
00120 alSourcei( d->source, AL_BUFFER, d->buffer->buffer() );
00121
00122 if( alGetError() != AL_NO_ERROR )
00123 {
00124 qDebug() << "Could not process sound while generating source:" << alGetError();
00125 return;
00126 }
00127
00128 if( !d->source )
00129 {
00130 qDebug() << "Could not process sound: generated source empty.";
00131 return;
00132 }
00133 }
00134
00135 ALfloat Sound::elapsedTime() const
00136 {
00137 ALfloat seconds = 0.f;
00138 alGetSourcef( d->source, AL_SEC_OFFSET, &seconds );
00139 return seconds;
00140 }
00141
00142 ALint Sound::status() const
00143 {
00144 ALint status;
00145 alGetSourcei( d->source, AL_SOURCE_STATE, &status );
00146 return status;
00147 }
00148
00149
00150 bool Sound::isLooping()
00151 {
00152 ALint loop;
00153 alGetSourcei( d->source, AL_LOOPING, &loop );
00154 return loop == AL_TRUE;
00155 }
00156
00157 bool Sound::isPlaying()
00158 {
00159 ALint state;
00160 alGetSourcei( d->source, AL_SOURCE_STATE, &state );
00161 return state == AL_PLAYING;
00162 }
00163
00164 void Sound::setLoop( bool enabled )
00165 {
00166 alSourcei( d->source, AL_LOOPING, enabled );
00167 }
00168
00169 QVector3D Sound::position() const
00170 {
00171 return d->position;
00172 }
00173
00174 ALfloat Sound::x() const
00175 {
00176 return d->position.x();
00177 }
00178
00179 ALfloat Sound::y() const
00180 {
00181 return d->position.y();
00182 }
00183
00184 ALfloat Sound::z() const
00185 {
00186 return d->position.z();
00187 }
00188
00189 ALfloat Sound::volume() const
00190 {
00191 return d->volume;
00192 }
00193
00194 ALfloat Sound::pitch() const
00195 {
00196 return d->pitch;
00197 }
00198
00199 ALfloat Sound::radius() const
00200 {
00201 return d->radius;
00202 }
00203
00204 void Sound::setPosition( ALfloat x, ALfloat y, ALfloat z )
00205 {
00206 QVector3D tempPosition( x, y, z );
00207 setPosition( tempPosition );
00208 }
00209
00210 void Sound::setPosition( QVector3D position )
00211 {
00212 d->position = position;
00213 ALfloat sourcePosition[] = { position.x(), position.y() , position.z() };
00214 alSourcefv( d->source, AL_POSITION, sourcePosition );
00215 }
00216
00217 void Sound::setVolume( ALfloat volume )
00218 {
00219 d->volume = volume;
00220 alSourcef( d->source, AL_GAIN, volume );
00221 }
00222
00223 void Sound::setPitch( ALfloat pitch )
00224 {
00225 d->pitch = pitch;
00226 alSourcef( d->source, AL_PITCH, pitch );
00227 }
00228
00229 void Sound::setRadius( ALfloat radius )
00230 {
00231 d->radius = radius;
00232 alSourcef( d->source, AL_REFERENCE_DISTANCE, radius );
00233 }
00234
00235 void Sound::play()
00236 {
00237 alSourcePlay( d->source );
00238 }
00239
00240 void Sound::pause()
00241 {
00242 alSourcePause( d->source );
00243 }
00244
00245 void Sound::stop()
00246 {
00247 alSourceStop( d->source );
00248 }
00249
00250 void Sound::rewind()
00251 {
00252 alSourceRewind( d->source );
00253 }
00254
00255 void Sound::setMinVolume( ALfloat min )
00256 {
00257 alSourcef( d->source, AL_MIN_GAIN, min );
00258 }
00259
00260 void Sound::setMaxVolume( ALfloat max )
00261 {
00262 alSourcef( d->source, AL_MAX_GAIN, max );
00263 }
00264
00265 void Sound::setVelocity( ALfloat vx, ALfloat vy, ALfloat vz )
00266 {
00267 ALfloat velocity[] = { vx, vy, vz };
00268 alSourcefv( d->source, AL_VELOCITY, velocity );
00269 }
00270
00271 void Sound::setDirection( ALfloat dx, ALfloat dy, ALfloat dz )
00272 {
00273 ALfloat direction[] = { dx, dy, dz };
00274 alSourcefv( d->source, AL_POSITION, direction );
00275 }
00276
00277 void Sound::setTimePosition( ALfloat time )
00278 {
00279 alSourcef( d->source, AL_SEC_OFFSET, time );
00280
00281 }
00282 ALfloat Sound::duration() const
00283 {
00284 return d->buffer->duration();
00285 }
00286 ALuint Sound::source() const
00287 {
00288 return d->source;
00289 }
00290
00291 #include "sound.moc"