00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00024
00026
00028 #include <SFML/Audio/SoundStream.hpp>
00029 #include <SFML/Audio/SoundBuffer.hpp>
00030 #include <SFML/Audio/OpenAL.hpp>
00031 #include <SFML/System/Sleep.hpp>
00032
00033
00037 sfSoundStream::sfSoundStream() :
00038 myIsStreaming (false),
00039 myChannelsCount(0),
00040 myFrequency (0)
00041 {
00042
00043 }
00044
00045
00049 sfSoundStream::~sfSoundStream()
00050 {
00051
00052 Stop();
00053 }
00054
00055
00059 void sfSoundStream::Initialize(unsigned int ChannelsCount, unsigned int Frequency)
00060 {
00061 myChannelsCount = ChannelsCount;
00062 myFrequency = Frequency;
00063 }
00064
00065
00069 void sfSoundStream::Play()
00070 {
00071
00072 if ((myChannelsCount == 0) || (myFrequency == 0))
00073 {
00074 std::cerr << "Failed to play audio stream : sound parameters have not been initialized (call Initialize first)" << std::endl;
00075 return;
00076 }
00077
00078
00079 if (myIsStreaming)
00080 {
00081 sfALCheck(alSourcePlay(mySource->Source));
00082 return;
00083 }
00084
00085
00086 float Position[3] = {0.f, 0.f, 0.f};
00087 mySource = new sf_private::sfSoundImpl(false, 1.f, 100.f, Position);
00088
00089
00090 if (OnStart())
00091 {
00092
00093 myIsStreaming = true;
00094 Launch();
00095 }
00096 }
00097
00098
00102 void sfSoundStream::Pause()
00103 {
00104 sfALCheck(alSourcePause(mySource->Source));
00105 }
00106
00107
00111 void sfSoundStream::Stop()
00112 {
00113
00114 myIsStreaming = false;
00115 Wait();
00116 }
00117
00118
00122 unsigned int sfSoundStream::GetChannelsCount() const
00123 {
00124 return myChannelsCount;
00125 }
00126
00127
00131 unsigned int sfSoundStream::GetFrequency() const
00132 {
00133 return myFrequency;
00134 }
00135
00136
00140 void sfSoundStream::SetPitch(float Pitch)
00141 {
00142 sfALCheck(alSourcef(mySource->Source, AL_PITCH, Pitch));
00143 }
00144
00145
00149 void sfSoundStream::SetVolume(float Volume)
00150 {
00151 sfALCheck(alSourcef(mySource->Source, AL_GAIN, Volume * 0.01f));
00152 }
00153
00154
00158 void sfSoundStream::SetPosition(float X, float Y, float Z)
00159 {
00160 sfALCheck(alSource3f(mySource->Source, AL_POSITION, X, Y, Z));
00161 }
00162
00163
00167 float sfSoundStream::GetPitch() const
00168 {
00169 ALfloat Pitch;
00170 sfALCheck(alGetSourcef(mySource->Source, AL_PITCH, &Pitch));
00171
00172 return Pitch;
00173 }
00174
00175
00179 float sfSoundStream::GetVolume() const
00180 {
00181 ALfloat Gain;
00182 sfALCheck(alGetSourcef(mySource->Source, AL_GAIN, &Gain));
00183
00184 return Gain * 100.f;
00185 }
00186
00187
00191 void sfSoundStream::GetPosition(float& X, float& Y, float& Z) const
00192 {
00193 sfALCheck(alGetSource3f(mySource->Source, AL_POSITION, &X, &Y, &Z));
00194 }
00195
00196
00200 sfSoundStatus sfSoundStream::GetStatus() const
00201 {
00202 ALint State;
00203 sfALCheck(alGetSourcei(mySource->Source, AL_SOURCE_STATE, &State));
00204
00205 switch (State)
00206 {
00207 case AL_INITIAL :
00208 case AL_STOPPED : return myIsStreaming ? Playing : Stopped;
00209 case AL_PAUSED : return Paused;
00210 case AL_PLAYING : return Playing;
00211 }
00212
00213 return Stopped;
00214 }
00215
00216
00220 void sfSoundStream::Run()
00221 {
00222
00223 for (int i = 0; i < BuffersCount; ++i)
00224 {
00225
00226 Chunk Data = {NULL, 0};
00227 if (OnGetData(Data))
00228 {
00229
00230 if (Data.Samples && Data.NbSamples)
00231 {
00232 myBuffers[i] = new sf_private::sfSoundBufferImpl(Data.Samples, Data.NbSamples, myChannelsCount, myFrequency);
00233 sfALCheck(alSourceQueueBuffers(mySource->Source, 1, &myBuffers[i]->Buffer));
00234 }
00235 }
00236 }
00237
00238
00239 sfALCheck(alSourcePlay(mySource->Source));
00240
00241 while (myIsStreaming)
00242 {
00243
00244 if (GetStatus() == Stopped)
00245 sfALCheck(alSourcePlay(mySource->Source));
00246
00247
00248 ALint NbProcessed;
00249 sfALCheck(alGetSourcei(mySource->Source, AL_BUFFERS_PROCESSED, &NbProcessed));
00250
00251 for (ALint i = 0; i < NbProcessed; ++i)
00252 {
00253
00254 ALuint Buffer;
00255 sfALCheck(alSourceUnqueueBuffers(mySource->Source, 1, &Buffer));
00256
00257
00258 Chunk Data = {NULL, 0};
00259 if (OnGetData(Data))
00260 {
00261
00262 if (Data.Samples && Data.NbSamples)
00263 {
00264 for (int j = 0; j < BuffersCount; ++j)
00265 {
00266 if (myBuffers[j]->Buffer == Buffer)
00267 {
00268 myBuffers[j]->Fill(Data.Samples, Data.NbSamples, myChannelsCount, myFrequency);
00269 sfALCheck(alSourceQueueBuffers(mySource->Source, 1, &Buffer));
00270 break;
00271 }
00272 }
00273 }
00274 }
00275 else
00276 {
00277
00278 myIsStreaming = false;
00279 break;
00280 }
00281 }
00282
00283
00284 sfSleep(0.1f);
00285 }
00286
00287
00288 CleanUp();
00289 }
00290
00291
00295 void sfSoundStream::CleanUp()
00296 {
00297
00298 sfALCheck(alSourceStop(mySource->Source));
00299
00300
00301 ALint NbQueued;
00302 ALuint Buffer;
00303 sfALCheck(alGetSourcei(mySource->Source, AL_BUFFERS_QUEUED, &NbQueued));
00304 for (ALint i = 0; i < NbQueued; ++i)
00305 sfALCheck(alSourceUnqueueBuffers(mySource->Source, 1, &Buffer));
00306 }
00307
00308
00312 bool sfSoundStream::OnStart()
00313 {
00314
00315
00316 return true;
00317 }