1
/************************************************************************************
3
AstroMenace (Hardcore 3D space shooter with spaceship upgrade possibilities)
4
Copyright © 2006-2012 Michael Kurinnoy, Viewizard
7
AstroMenace is free software: you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation, either version 3 of the License, or
10
(at your option) any later version.
12
AstroMenace is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with AstroMenace. If not, see <http://www.gnu.org/licenses/>.
21
Web Site: http://www.viewizard.com/
22
Project: http://sourceforge.net/projects/openastromenace/
23
E-mail: viewizard@viewizard.com
25
*************************************************************************************/
29
#include "../System/System.h"
33
ALboolean CheckALError();
34
ALboolean CheckALUTError();
39
//------------------------------------------------------------------------------------
40
// Vorbis callback functions
41
//------------------------------------------------------------------------------------
42
size_t VorbisRead(void *ptr, size_t byteSize, size_t sizeToRead, void *datasource)
44
// нужно возвращать кол-во прочитаных byteSize
45
eFILE* vorbisData = (eFILE*)datasource;
46
return vorbisData->fread(ptr, byteSize, sizeToRead);
50
int VorbisSeek(void *datasource, ogg_int64_t offset, int whence)
52
eFILE* vorbisData = (eFILE*)datasource;
53
return vorbisData->fseek(offset, whence);
57
int VorbisClose(void *UNUSED(datasource))
58
{// похоже, без этой функции у линукс версии vorbis проблемы, хотя по документации...
63
long VorbisTell(void *datasource)
65
eFILE* vorbisData = (eFILE*)datasource;
66
return vorbisData->ftell();
73
//------------------------------------------------------------------------------------
74
// Читаем фрагмент ogg файла
75
//------------------------------------------------------------------------------------
76
bool eMusic::ReadOggBlock(ALuint BufID, size_t Size)
80
unsigned int TotalRet = 0;
84
if (Size < 1) return false;
88
while (TotalRet < Size)
90
ret = ov_read(mVF, PCM + TotalRet, Size - TotalRet, 0, 2, 1, ¤t_section);
92
// if end of file or read limit exceeded
94
else if (ret < 0) // Error in bitstream
105
alBufferData(BufID, Format, PCM, TotalRet, Rate);
118
//------------------------------------------------------------------------------------
119
// Проигрывание звука
120
//------------------------------------------------------------------------------------
121
bool eMusic::Play(const char * Name, float fVol, float fMainVol, bool Loop, const char *LoopFileName)
124
MainVolume = fMainVol;
126
if (LoopFileName == 0)
132
strcpy(LoopPart, LoopFileName);
136
FadeInStartVol = Volume;
137
FadeInEndVol = Volume;
141
LastTime = vw_GetTime();
144
// Position of the source sound.
145
ALfloat SourcePos[] = { 0.0f, 0.0f, 0.0f }; // -1.0 1.0 по иксам это баланс
146
// Velocity of the source sound.
147
ALfloat SourceVel[] = { 0.0f, 0.0f, 0.0f };
149
alGenSources(1, &Source);
150
if(!CheckALError()) return AL_FALSE;
152
alSourcef (Source, AL_PITCH, 1.0 ); // 1.0 only!!!
153
alSourcef (Source, AL_GAIN, fVol*fMainVol ); // фактически громкость
154
alSourcefv(Source, AL_POSITION, SourcePos);
155
alSourcefv(Source, AL_VELOCITY, SourceVel);
156
alSourcei (Source, AL_SOURCE_RELATIVE, AL_TRUE);
157
alSourcei(Source, AL_LOOPING, AL_FALSE);
158
alGetError(); // сброс ошибок
165
MusicFile = vw_fopen(Name);
166
if (MusicFile == 0) return false;
168
int i, DynBuffs = 1, BlockSize;
170
// OggVorbis specific structures
173
cb.close_func = VorbisClose;
174
cb.read_func = VorbisRead;
175
cb.seek_func = VorbisSeek;
176
cb.tell_func = VorbisTell;
177
// Create OggVorbis_File struct
178
mVF = new OggVorbis_File;
180
// Generate local buffers
181
if (ov_open_callbacks(MusicFile, mVF, NULL, 0, cb) < 0)
183
// This is not ogg bitstream. Return
189
// Check for existance of sound
190
BlockSize = DYNBUF_SIZE;
191
DynBuffs = NUM_OF_DYNBUF;
193
// Return vorbis_comment and vorbis_info structures
194
mComment = ov_comment(mVF, -1);
195
mInfo = ov_info(mVF, -1);
199
Format = (mInfo->channels == 1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
202
alGenBuffers(DynBuffs, Buffers);
203
if (!CheckALError()) return false;
205
for (i = 0; i < DynBuffs; i++)
207
// Read amount (DYNBUF_SIZE) data into each buffer
208
ReadOggBlock(Buffers[i], BlockSize);
209
if (!CheckALError()) return false;
211
alSourceQueueBuffers(Source, 1, &Buffers[i]);
212
if (!CheckALError()) return false;
218
// запускаем на проигрывание
220
alSourcePlay(Source);
221
if(!CheckALError()) return AL_FALSE;
228
//------------------------------------------------------------------------------------
230
//------------------------------------------------------------------------------------
231
bool eMusic::Update()
235
alGetSourcei(Source, AL_BUFFERS_PROCESSED, &Processed);
237
// We still have processed buffers
240
// не создаем новые буферы, просто берем уже использованный и заполняем новыми данными
241
// а потом ставим его опять в очередь
243
alSourceUnqueueBuffers(Source, 1, &bufferID);
244
if (!CheckALError()) return true;
246
if (ReadOggBlock(bufferID, DYNBUF_SIZE) != 0)
248
alSourceQueueBuffers(Source, 1, &bufferID);
249
if (!CheckALError()) return true;
254
if (LoopPart[0] != 0)
256
if (mVF != 0){ov_clear(mVF);delete mVF; mVF = 0;}
259
vw_fclose(MusicFile);
263
MusicFile = vw_fopen(LoopPart);
266
// OggVorbis specific structures
269
cb.close_func = VorbisClose;
270
cb.read_func = VorbisRead;
271
cb.seek_func = VorbisSeek;
272
cb.tell_func = VorbisTell;
273
// Create OggVorbis_File struct
274
mVF = new OggVorbis_File;
276
// Generate local buffers
277
if (ov_open_callbacks(MusicFile, mVF, NULL, 0, cb) < 0)
279
// This is not ogg bitstream. Return
291
// если не нужно больше повторять - выходим
292
if (!Looped) return false;
294
// устанавливаем на начало
296
alSourceQueueBuffers(Source, 1, &bufferID);
297
if (!CheckALError()) return true;
303
// обрабатываем эффекты
304
float TimeDelta = vw_GetTime() - LastTime;
307
if (Volume < FadeInEndVol)
309
FadeTime += TimeDelta;
310
Volume = FadeInEndVol*(FadeTime/FadeAge);
311
alSourcef(Source, AL_GAIN, MainVolume*Volume );
312
alGetError(); // сброс ошибок
318
FadeTime += TimeDelta;
319
Volume = FadeInStartVol*((FadeAge-FadeTime)/FadeAge);
320
alSourcef(Source, AL_GAIN, MainVolume*Volume);
321
alGetError(); // сброс ошибок
322
if (Volume <= 0.0f) return false;
325
LastTime = vw_GetTime();
329
// если по какой-то причине перестали играть...
331
alGetSourcei(Source, AL_SOURCE_STATE, &TMPS);
332
alGetError(); // сброс ошибок
333
if (TMPS == AL_STOPPED) return false;
342
//------------------------------------------------------------------------------------
343
// установка громкости
344
//------------------------------------------------------------------------------------
345
void eMusic::SetMainVolume(float NewMainVolume)
347
// если это не источник, уходим
348
if (!alIsSource(Source)) return;
350
MainVolume = NewMainVolume;
351
alSourcef(Source, AL_GAIN, MainVolume*Volume );
356
//------------------------------------------------------------------------------------
358
//------------------------------------------------------------------------------------
359
void eMusic::FadeIn(float EndVol, float Time)
363
FadeInEndVol = EndVol;
364
FadeTime = 0.0f; // начинаем с нуля!
366
LastTime = vw_GetTime();
371
//------------------------------------------------------------------------------------
372
// плавное уход на 0 с текущего
373
//------------------------------------------------------------------------------------
374
void eMusic::FadeOut(float Time)
378
FadeInStartVol = Volume;
379
FadeTime = 0.0f; // начинаем с нуля!
381
LastTime = vw_GetTime();