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/AudioDevice.hpp>
00031 #include <SFML/Audio/OpenAL.hpp>
00032 #include <SFML/System/Sleep.hpp>
00033
00034
00035 namespace sf
00036 {
00040 SoundStream::SoundStream() :
00041 myIsStreaming (false),
00042 myChannelsCount(0),
00043 mySampleRate (0),
00044 myFormat (0)
00045 {
00046
00047 }
00048
00049
00053 SoundStream::~SoundStream()
00054 {
00055
00056 Stop();
00057 }
00058
00059
00063 void SoundStream::Initialize(unsigned int ChannelsCount, unsigned int SampleRate)
00064 {
00065 myChannelsCount = ChannelsCount;
00066 mySampleRate = SampleRate;
00067
00068
00069 myFormat = priv::AudioDevice::GetInstance().GetFormatFromChannelsCount(ChannelsCount);
00070
00071
00072 if (myFormat == 0)
00073 {
00074 myChannelsCount = 0;
00075 mySampleRate = 0;
00076 std::cerr << "Unsupported number of channels (" << myChannelsCount << ")" << std::endl;
00077 }
00078 }
00079
00080
00084 void SoundStream::Play()
00085 {
00086
00087 if (myFormat == 0)
00088 {
00089 std::cerr << "Failed to play audio stream : sound parameters have not been initialized (call Initialize first)" << std::endl;
00090 return;
00091 }
00092
00093
00094 if (myIsStreaming)
00095 {
00096 Sound::Play();
00097 return;
00098 }
00099
00100
00101 if (OnStart())
00102 {
00103
00104 myIsStreaming = true;
00105 Launch();
00106 }
00107 }
00108
00109
00113 void SoundStream::Stop()
00114 {
00115
00116 myIsStreaming = false;
00117 Wait();
00118 }
00119
00120
00124 unsigned int SoundStream::GetChannelsCount() const
00125 {
00126 return myChannelsCount;
00127 }
00128
00129
00133 unsigned int SoundStream::GetSampleRate() const
00134 {
00135 return mySampleRate;
00136 }
00137
00138
00142 Sound::Status SoundStream::GetStatus() const
00143 {
00144 Status Status = Sound::GetStatus();
00145
00146
00147 if ((Status == Stopped) && myIsStreaming)
00148 Status = Playing;
00149
00150 return Status;
00151 }
00152
00153
00157 void SoundStream::Run()
00158 {
00159
00160 ALCheck(alGenBuffers(BuffersCount, myBuffers));
00161 for (int i = 0; i < BuffersCount; ++i)
00162 {
00163
00164 Chunk Data = {NULL, 0};
00165 if (OnGetData(Data))
00166 {
00167
00168 if (Data.Samples && Data.NbSamples)
00169 {
00170
00171 ALsizei Size = static_cast<ALsizei>(Data.NbSamples) * sizeof(Int16);
00172 ALCheck(alBufferData(myBuffers[i], myFormat, Data.Samples, Size, mySampleRate));
00173
00174
00175 ALCheck(alSourceQueueBuffers(Sound::mySource, 1, &myBuffers[i]));
00176 }
00177 }
00178 }
00179
00180
00181 Sound::Play();
00182
00183 while (myIsStreaming)
00184 {
00185
00186 if (Sound::GetStatus() == Stopped)
00187 Sound::Play();
00188
00189
00190 ALint NbProcessed;
00191 ALCheck(alGetSourcei(Sound::mySource, AL_BUFFERS_PROCESSED, &NbProcessed));
00192
00193 for (ALint i = 0; i < NbProcessed; ++i)
00194 {
00195
00196 ALuint Buffer;
00197 ALCheck(alSourceUnqueueBuffers(Sound::mySource, 1, &Buffer));
00198
00199
00200 Chunk Data = {NULL, 0};
00201 if (OnGetData(Data))
00202 {
00203
00204 if (Data.Samples && Data.NbSamples)
00205 {
00206
00207 ALsizei Size = static_cast<ALsizei>(Data.NbSamples) * sizeof(Int16);
00208 ALCheck(alBufferData(Buffer, myFormat, Data.Samples, Size, mySampleRate));
00209
00210
00211 ALCheck(alSourceQueueBuffers(Sound::mySource, 1, &Buffer));
00212 }
00213 }
00214 else
00215 {
00216
00217 myIsStreaming = false;
00218 break;
00219 }
00220 }
00221
00222
00223 Sleep(0.1f);
00224 }
00225
00226
00227 CleanUp();
00228 }
00229
00230
00234 void SoundStream::CleanUp()
00235 {
00236
00237 Sound::Stop();
00238
00239
00240 ALint NbQueued;
00241 ALuint Buffer;
00242 ALCheck(alGetSourcei(Sound::mySource, AL_BUFFERS_QUEUED, &NbQueued));
00243 for (ALint i = 0; i < NbQueued; ++i)
00244 ALCheck(alSourceUnqueueBuffers(Sound::mySource, 1, &Buffer));
00245
00246
00247 ALCheck(alDeleteBuffers(BuffersCount, myBuffers));
00248 }
00249
00250
00254 bool SoundStream::OnStart()
00255 {
00256
00257
00258 return true;
00259 }
00260
00261 }