29 #include <OgreResourceGroupManager.h>
31 #define LOGSTREAM Ogre::LogManager::getSingleton().stream() << "[RoR|Audio] "
35 int err = alGetError();
36 if (err != AL_NO_ERROR)
39 snprintf(buf, 1000,
"OpenAL Error: %s (0x%x), @ %s:%d", alGetString(err), err, filename, linenum);
46 #define hasALErrors() _checkALErrors(__FILE__, __LINE__)
59 LOGSTREAM <<
"No audio device configured, opening default.";
60 audio_device = alcOpenDevice(
nullptr);
69 audio_device = alcOpenDevice(
nullptr);
75 LOGSTREAM <<
"Failed to open default audio device. Sound disabled.";
80 sound_context = alcCreateContext(audio_device, NULL);
84 alcCloseDevice(audio_device);
90 alcMakeContextCurrent(sound_context);
92 if (alGetString(AL_VENDOR)) LOG(
"SoundManager: OpenAL vendor is: " + String(alGetString(AL_VENDOR)));
93 if (alGetString(AL_VERSION)) LOG(
"SoundManager: OpenAL version is: " + String(alGetString(AL_VERSION)));
94 if (alGetString(AL_RENDERER)) LOG(
"SoundManager: OpenAL renderer is: " + String(alGetString(AL_RENDERER)));
95 if (alGetString(AL_EXTENSIONS)) LOG(
"SoundManager: OpenAL extensions are: " + String(alGetString(AL_EXTENSIONS)));
96 if (alcGetString(audio_device, ALC_DEVICE_SPECIFIER)) LOG(
"SoundManager: OpenAL device is: " + String(alcGetString(audio_device, ALC_DEVICE_SPECIFIER)));
97 if (alcGetString(audio_device, ALC_EXTENSIONS)) LOG(
"SoundManager: OpenAL ALC extensions are: " + String(alcGetString(audio_device, ALC_EXTENSIONS)));
100 for (hardware_sources_num = 0; hardware_sources_num < MAX_HARDWARE_SOURCES; hardware_sources_num++)
103 alGenSources(1, &hardware_sources[hardware_sources_num]);
104 if (alGetError() != AL_NO_ERROR)
106 alSourcef(hardware_sources[hardware_sources_num], AL_REFERENCE_DISTANCE, REFERENCE_DISTANCE);
107 alSourcef(hardware_sources[hardware_sources_num], AL_ROLLOFF_FACTOR, ROLLOFF_FACTOR);
108 alSourcef(hardware_sources[hardware_sources_num], AL_MAX_DISTANCE, MAX_DISTANCE);
111 alDopplerFactor(1.0f);
112 alDopplerVelocity(343.0f);
114 for (
int i = 0; i < MAX_HARDWARE_SOURCES; i++)
116 hardware_sources_map[i] = -1;
123 alDeleteSources(MAX_HARDWARE_SOURCES, hardware_sources);
124 alDeleteBuffers(MAX_AUDIO_BUFFERS, audio_buffers);
127 sound_context = alcGetCurrentContext();
128 audio_device = alcGetContextsDevice(sound_context);
129 alcMakeContextCurrent(NULL);
130 alcDestroyContext(sound_context);
133 alcCloseDevice(audio_device);
135 LOG(
"SoundManager destroyed.");
142 camera_position = position;
143 recomputeAllSources();
145 float orientation[6];
147 orientation[0] = direction.x;
148 orientation[1] = direction.y;
149 orientation[2] = direction.z;
151 orientation[3] = up.x;
152 orientation[4] = up.y;
153 orientation[5] = up.z;
155 alListener3f(AL_POSITION, position.x, position.y, position.z);
156 alListener3f(AL_VELOCITY, velocity.x, velocity.y, velocity.z);
157 alListenerfv(AL_ORIENTATION, orientation);
162 return a.second > b.second;
170 if (!audio_device)
return;
172 for (
int i=0; i < audio_buffers_in_use_count; i++)
174 audio_sources[i]->computeAudibility(camera_position);
175 audio_sources_most_audible[i].first = i;
176 audio_sources_most_audible[i].second = audio_sources[i]->audibility;
180 if ((audio_buffers_in_use_count - 1) > hardware_sources_num)
182 std::nth_element(audio_sources_most_audible, audio_sources_most_audible+hardware_sources_num, audio_sources_most_audible + audio_buffers_in_use_count - 1,
compareByAudibility);
185 for (
int i=0; i < audio_buffers_in_use_count; i++)
187 if (audio_sources[audio_sources_most_audible[i].first]->hardware_index != -1 && (i >= hardware_sources_num || audio_sources_most_audible[i].second == 0))
188 retire(audio_sources_most_audible[i].first);
191 for (
int i=0; i < std::min(audio_buffers_in_use_count, hardware_sources_num); i++)
193 if (audio_sources[audio_sources_most_audible[i].first]->hardware_index == -1 && audio_sources_most_audible[i].second > 0)
195 for (
int j=0; j < hardware_sources_num; j++)
197 if (hardware_sources_map[j] == -1)
199 assign(audio_sources_most_audible[i].first, j);
212 audio_sources[source_index]->computeAudibility(camera_position);
214 if (audio_sources[source_index]->audibility == 0.0f)
216 if (audio_sources[source_index]->hardware_index != -1)
219 retire(source_index);
225 if (audio_sources[source_index]->hardware_index != -1)
227 ALuint hw_source = hardware_sources[audio_sources[source_index]->hardware_index];
238 case Sound::REASON_LOOP: alSourcei(hw_source, AL_LOOPING, (vfl > 0.5) ? AL_TRUE : AL_FALSE);
242 case Sound::REASON_POSN: alSource3f(hw_source, AL_POSITION, vvec->x, vvec->y, vvec->z);
244 case Sound::REASON_VLCT: alSource3f(hw_source, AL_VELOCITY, vvec->x, vvec->y, vvec->z);
253 if (hardware_sources_in_use_count < hardware_sources_num)
255 for (
int i = 0; i < hardware_sources_num; i++)
257 if (hardware_sources_map[i] == -1)
259 assign(source_index, i);
270 for (
int i = 0; i < hardware_sources_num; i++)
272 if (hardware_sources_map[i] >= 0 && audio_sources[hardware_sources_map[i]]->audibility < fv)
274 fv = audio_sources[hardware_sources_map[i]]->audibility;
279 if (fv < audio_sources[source_index]->audibility)
282 retire(hardware_sources_map[al_faintest]);
283 assign(source_index, al_faintest);
295 audio_sources[source_index]->hardware_index = hardware_index;
296 hardware_sources_map[hardware_index] = source_index;
298 ALuint hw_source = hardware_sources[hardware_index];
299 SoundPtr& audio_source = audio_sources[source_index];
302 alSourcei(hw_source, AL_BUFFER, audio_source->
buffer);
304 alSourcei(hw_source, AL_LOOPING, (audio_source->
loop) ? AL_TRUE : AL_FALSE);
305 alSourcef(hw_source, AL_PITCH, audio_source->
pitch);
311 alSourcePlay(hw_source);
314 hardware_sources_in_use_count++;
321 if (audio_sources[source_index]->hardware_index == -1)
323 alSourceStop(hardware_sources[audio_sources[source_index]->hardware_index]);
324 hardware_sources_map[audio_sources[source_index]->hardware_index] = -1;
325 audio_sources[source_index]->hardware_index = -1;
326 hardware_sources_in_use_count--;
334 alListenerf(AL_GAIN, 0.0f);
351 alListenerf(AL_GAIN, v);
359 if (audio_buffers_in_use_count >= MAX_AUDIO_BUFFERS)
361 LOG(
"SoundManager: Reached MAX_AUDIO_BUFFERS limit (" +
TOSTRING(MAX_AUDIO_BUFFERS) +
")");
368 for (
int i = 0; i < audio_buffers_in_use_count; i++)
370 if (filename == audio_buffer_file_name[i])
372 buffer = audio_buffers[i];
380 alGenBuffers(1, &audio_buffers[audio_buffers_in_use_count]);
381 if (loadWAVFile(filename, audio_buffers[audio_buffers_in_use_count], resource_group_name))
384 alDeleteBuffers(1, &audio_buffers[audio_buffers_in_use_count]);
385 audio_buffer_file_name[audio_buffers_in_use_count] =
"";
388 buffer = audio_buffers[audio_buffers_in_use_count];
389 audio_buffer_file_name[audio_buffers_in_use_count] = filename;
392 audio_sources[audio_buffers_in_use_count] =
new Sound(buffer,
this, audio_buffers_in_use_count);
394 return audio_sources[audio_buffers_in_use_count++];
401 LOG(
"Loading WAV file "+filename);
404 ResourceGroupManager* rgm = ResourceGroupManager::getSingletonPtr();
405 if (resource_group_name ==
"")
407 resource_group_name = rgm->findGroupContainingResource(filename);
409 DataStreamPtr stream = rgm->openResource(filename, resource_group_name);
418 if (stream->read(magic, 4) != 4)
420 LOG(
"Could not read file "+filename);
423 if (String(magic) != String(
"RIFF"))
425 LOG(
"Invalid WAV file (no RIFF): "+filename);
431 if (stream->read(magic, 4) != 4)
433 LOG(
"Could not read file "+filename);
436 if (String(magic) != String(
"WAVE"))
438 LOG(
"Invalid WAV file (no WAVE): "+filename);
442 if (stream->read(magic, 4) != 4)
444 LOG(
"Could not read file "+filename);
447 if (String(magic) != String(
"fmt "))
449 LOG(
"Invalid WAV file (no fmt): "+filename);
453 if (stream->read(&lbuf, 4) != 4)
455 LOG(
"Could not read file "+filename);
458 unsigned long subChunk1Size = lbuf;
459 if (subChunk1Size < 16)
461 LOG(
"Invalid WAV file (invalid subChunk1Size): "+filename);
465 if (stream->read(&sbuf, 2) != 2)
467 LOG(
"Could not read file "+filename);
470 unsigned short audioFormat = sbuf;
471 if (audioFormat != 1)
473 LOG(
"Invalid WAV file (invalid audioformat "+
TOSTRING(audioFormat)+
"): "+filename);
477 if (stream->read(&sbuf, 2) != 2)
479 LOG(
"Could not read file "+filename);
482 unsigned short channels = sbuf;
484 if (stream->read(&lbuf, 4) != 4)
486 LOG(
"Could not read file "+filename);
489 unsigned long freq = lbuf;
493 if (stream->read(&sbuf, 2) != 2)
495 LOG(
"Could not read file "+filename);
498 unsigned short bps = sbuf;
500 if (stream->read(magic, 4) != 4)
502 LOG(
"Could not read file "+filename);
505 if (String(magic) != String(
"data") && String(magic) != String(
"fact"))
507 LOG(
"Invalid WAV file (no data/fact): "+filename);
511 if (String(magic) == String(
"fact"))
515 if (stream->read(magic, 4) != 4)
517 LOG(
"Could not read file "+filename);
520 if (String(magic) != String(
"data"))
522 LOG(
"Invalid WAV file (no data): "+filename);
527 if (stream->read(&lbuf, 4) != 4)
529 LOG(
"Could not read file "+filename);
533 unsigned long dataSize = lbuf;
536 if (channels == 1 && bps == 8)
538 else if (channels == 1 && bps == 16)
539 format = AL_FORMAT_MONO16;
540 else if (channels == 2 && bps == 8)
541 format = AL_FORMAT_STEREO16;
542 else if (channels == 2 && bps == 16)
543 format = AL_FORMAT_STEREO16;
546 LOG(
"Invalid WAV file (wrong channels/bps): "+filename);
550 if (channels != 1) LOG(
"Invalid WAV file: the file needs to be mono, and nothing else. Will try to continue anyways ...");
553 void* bdata = malloc(dataSize);
556 LOG(
"Memory error reading file "+filename);
559 if (stream->read(bdata, dataSize) != dataSize)
561 LOG(
"Could not read file "+filename);
569 alBufferData(buffer,
format, bdata, dataSize, freq);
570 error = alGetError();
575 if (error != AL_NO_ERROR)
577 LOG(
"OpenAL error while loading buffer for "+filename+
" : "+
TOSTRING(error));