bool CheckError(const char* msg) { ALenum e = alGetError(); if (e != AL_NO_ERROR) { char *alerr = (char*)alGetString(e); std::string err = msg; err += ": "; err += (alerr != NULL) ? alerr : "Unknown error"; LogObject(LOG_SOUND) << err.c_str(); return false; } return true; }
void Sound::SetUISoundsVolume(int vol) { ALenum m_openal_error; /* normalize value, then apply to all sound sources */ vol = std::max(0, std::min(vol, 255)); GetOptionsDB().Set<int>("UI.sound.volume", vol); if (alcGetCurrentContext() != 0) { for (int it = 1; it < NUM_SOURCES; ++it) alSourcef(m_sources[it],AL_GAIN, ((ALfloat) vol)/255.0); /* it is highly unlikely that we'll get an error here but better safe than sorry */ m_openal_error = alGetError(); if (m_openal_error != AL_NONE) Logger().errorStream() << "PlaySound: OpenAL ERROR: " << alGetString(m_openal_error); } }
//! [static] bool checkErrorStatus(const char * file, int line, const std::string & msg) { const ALenum error = alGetError(); if (error == AL_NO_ERROR) { return true; } std::cerr << "AL ERROR ("; const ALchar * errorString = alGetString(error); if(errorString != nullptr) { std::cerr << errorString; } else { std::cerr << error; } std::cerr << "): " << msg << " at " << file << ":" << line << std::endl; return false; }
void Sound::FreeSound(const boost::filesystem::path& path) { ALenum m_openal_error; std::string filename = path.string(); std::map<std::string, ALuint>::iterator it = m_buffers.find(filename); if (it != m_buffers.end()) { alDeleteBuffers(1, &(it->second)); m_openal_error = alGetError(); if (m_openal_error != AL_NONE) Logger().errorStream() << "FreeSound: OpenAL ERROR: " << alGetString(m_openal_error); else m_buffers.erase(it); /* we don't erase if there was an error, as the buffer may not have been removed - potential memory leak */ } }
Mixer::Mixer () { const ALCchar * device_name = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER); AudioError::reset(); _audio_device = _default_audio_device(); _audio_context = alcCreateContext(_audio_device, NULL); AudioError::check("Initializing Audio Context"); bool result = alcMakeContextCurrent(_audio_context); LogBuffer buffer; buffer << "OpenAL Context Initialized..." << std::endl; buffer << "OpenAL Vendor: " << alGetString(AL_VENDOR) << " " << alGetString(AL_VERSION) << std::endl; buffer << "OpenAL Device: '" << device_name << "'" << std::endl; logger()->log(LOG_INFO, buffer); //al_distance_model(AL_LINEAR_DISTANCE); set_listener_position(0); set_listener_velocity(0); set_listener_orientation(Vec3(0.0, 0.0, -1.0), Vec3(0.0, 1.0, 0.0)); DREAM_ASSERT(result && "Failed to initialize audio hardware!?"); }
// ------------------- LoadSound ------------------------- static ALuint LoadSound(const char* name) { SDL_AudioSpec wav_spec; Uint32 wav_length; Uint8 *wav_buffer; if (SDL_LoadWAV(name, &wav_spec, &wav_buffer, &wav_length) == NULL) { ERR("LoadSound(%s): SDL_LoadWAV failed: %s\n", name, SDL_GetError()); return 0; } ALenum format = 0; if (wav_spec.channels == 1) { switch(wav_spec.format) { case AUDIO_U8: format = AL_FORMAT_MONO8; break; case AUDIO_S16LSB: format = AL_FORMAT_MONO16; break; case AUDIO_F32LSB: format = AL_FORMAT_MONO_FLOAT32; break; } } else if (wav_spec.channels == 2) { switch(wav_spec.format) { case AUDIO_U8: format = AL_FORMAT_STEREO8; break; case AUDIO_S16LSB: format = AL_FORMAT_STEREO16; break; case AUDIO_F32LSB: format = AL_FORMAT_STEREO_FLOAT32; break; } } if (format == 0) { // TODO: if needed, more channels / other formats. ERR("LoadSound(%s): Unsupported format (TODO): 0x%X\n", name, wav_spec.format); SDL_FreeWAV(wav_buffer); return 0; } ALuint buffer; alGenBuffers(1, &buffer); alBufferData(buffer, format, wav_buffer, wav_length, wav_spec.freq); SDL_FreeWAV(wav_buffer); ALenum err = alGetError(); if(err != AL_NO_ERROR) { ERR("LoadSound(%s): alBufferData Error: %s\n", name, alGetString(err)); if(alIsBuffer(buffer)) alDeleteBuffers(1, &buffer); return 0; } return buffer; }
std::string checkALError() { #if defined(DF3D_DESKTOP) std::string errString; ALenum errCode = alGetError(); if (errCode != AL_NO_ERROR) { errString = (char *)alGetString(errCode); } return errString; #else return ""; #endif }
bool CSoundEngine::Initialize(void *pEngine) { if (m_bInit) return false; m_bInit = true; s_pEngine = (IEngine*)pEngine; // memory leaks detection #if defined(_DEBUG) && defined(_MSC_VER) && _MSC_VER >= 800 _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); //_CrtSetBreakAlloc(76); #endif CON(MSG_INFO, _W("= Sound Device initialization =")); m_device = alcOpenDevice(NULL); if(!m_device) { CON(MSG_ERR_FATAL, _W(" Can't initialize OpenAL! Please try to reinstall OpenAL libraries...")); return false; } m_extensions = new COALExtProvider(); if(m_extensions == NULL) { CON(MSG_INFO, _W(" Can't create OpenAL Extension provider instance!")); m_context = alcCreateContext(m_device, NULL); if(m_context != NULL) alcMakeContextCurrent(m_context); } else m_extensions->Create(m_device, m_context); if(m_context == NULL) { CON(MSG_ERR_FATAL, _W(" Can't create OpenAL context!")); return false; } if (!cSoundManager()->Create(m_extensions)) CON(MSG_ERR_FATAL, _W(" Can't create Sound Manager!")); CON(MSG_INFO, _W(" ...using OpenAL version %s"), _A2W(alGetString(AL_VERSION)) ); return true; }
static void playFile(const char *fileName) { ALenum format; void *data; ALsizei size; ALsizei frequency; #if !defined(__APPLE__) ALboolean loop; #endif ALuint buffer; ALuint source; ALenum error; ALint status; /* Create an AL buffer from the given sound file. */ alutLoadWAVFile((ALbyte *) "file1.wav", &format, &data, &size, &frequency #if !defined(__APPLE__) , &loop #endif ); alGenBuffers(1, &buffer); alBufferData(buffer, format, data, size, frequency); free(data); /* Generate a single source, attach the buffer to it and start playing. */ alGenSources(1, &source); alSourcei(source, AL_BUFFER, buffer); alSourcePlay(source); /* Normally nothing should go wrong above, but one never knows... */ error = alGetError(); if (error != ALUT_ERROR_NO_ERROR) { fprintf(stderr, "%s\n", alGetString(error)); alutExit(); exit(EXIT_FAILURE); } /* Check every 0.1 seconds if the sound is still playing. */ do { alutSleep(0.1f); alGetSourcei(source, AL_SOURCE_STATE, &status); } while (status == AL_PLAYING); }
// Start the sound sub-system void SokobanSoundManager::Setup(void) { // Initialise ALUT and eat any ALUT-specific command line flags if (!alutInit (NULL, NULL)) { ALenum error = alutGetError (); fprintf (stderr, "%s\n", alutGetErrorString (error)); // exit (EXIT_FAILURE); m_bIsSetup = false; return; } // Load the default sound ////////////////////////////////////////////////////////////////////////// // NOTE: Cant use LoadSampleFromFile because if it fails it returns m_DefaultSoundID // Create an AL buffer from the given sound file m_DefaultSoundID = alutCreateBufferFromFile (".\\audio\\default.wav"); if (m_DefaultSoundID == AL_NONE) { ALenum error = alutGetError (); fprintf (stderr, "Error loading file: '%s'\n", alutGetErrorString (error)); alutExit (); // exit (EXIT_FAILURE); m_bIsSetup = false; return; } // Generate a single source alGenSources (1, &source); // Error check source generation ALenum error = alGetError (); if (error != ALUT_ERROR_NO_ERROR) { // fprintf (stderr, "%s\n", alGetString (error)); MessageBox (HWND_DESKTOP, alGetString(error), "Error 1", MB_OK | MB_ICONEXCLAMATION); alutExit (); exit (EXIT_FAILURE); } // toggle IsSetup m_bIsSetup = true; return; }
int main( int argc, char *argv[] ) { int attributeList[] = { ALC_FREQUENCY, 22050, 0 }; time_t start = time( NULL ); time_t shouldEnd; ALCcontext *context; ALuint movingSource; ALCdevice *device = alcOpenDevice( NULL ); if( device == NULL ) { fprintf( stderr, "Could not open device\n" ); return EXIT_FAILURE; } /* Initialize context. */ context = alcCreateContext( device, attributeList ); if( context == NULL ) { fprintf( stderr, "Could not open context: %s\n", alGetString( alcGetError( device ) ) ); return EXIT_FAILURE; } alcMakeContextCurrent( context ); getExtensionEntries( ); palBombOnError( ); movingSource = init( ( argc == 1 ) ? "sample.wav" : argv[1] ); alSourcePlay( movingSource ); while( sourceIsPlaying( movingSource ) == AL_TRUE ) { iterate( movingSource ); shouldEnd = time( NULL ); if( ( shouldEnd - start ) > 30 ) { alSourceStop( movingSource ); } } alcMakeContextCurrent( NULL ); alcDestroyContext( context ); alcCloseDevice( device ); return EXIT_SUCCESS; }
static void checkForErrors() { { ALCdevice* device = alcGetContextsDevice(alcGetCurrentContext()); ALCenum error = alcGetError(device); if(error != ALC_NO_ERROR) { std::cout << boost::format("ALC error: '%s'\n") % static_cast<const char*>(alcGetString(device, error)); } } { ALenum error = alGetError(); if(error != AL_NO_ERROR) { std::cout << boost::format("AL error: '%s'\n") % static_cast<const char*>(alGetString(error)); } } }
void Sound::FreeAllSounds() { ALenum m_openal_error; for (std::map<std::string, ALuint>::iterator it = m_buffers.begin(); it != m_buffers.end();) { alDeleteBuffers(1, &(it->second)); m_openal_error = alGetError(); if (m_openal_error != AL_NONE) { ErrorLogger() << "FreeAllSounds: OpenAL ERROR: " << alGetString(m_openal_error); ++it; } else { std::map<std::string, ALuint>::iterator temp = it; ++it; m_buffers.erase(temp); // invalidates erased iterator only } } }
void Sound::Impl::SetMusicVolume(int vol) { if (!m_initialized) return; ALenum m_openal_error; /* normalize value, then apply to all sound sources */ vol = std::max(0, std::min(vol, 255)); GetOptionsDB().Set<int>("UI.sound.music-volume", vol); if (alcGetCurrentContext()) { alSourcef(m_sources[0], AL_GAIN, ((ALfloat) vol)/255.0); /* it is highly unlikely that we'll get an error here but better safe than sorry */ m_openal_error = alGetError(); if (m_openal_error != AL_NONE) ErrorLogger() << "PlaySound: OpenAL ERROR: " << alGetString(m_openal_error); } }
BOOL CSoundRender_TargetA::_initialize () { inherited::_initialize(); // initialize buffer A_CHK(alGenBuffers (sdef_target_count, pBuffers)); alGenSources (1, &pSource); ALenum error = alGetError(); if (AL_NO_ERROR==error){ A_CHK(alSourcei (pSource, AL_LOOPING, AL_FALSE)); A_CHK(alSourcef (pSource, AL_MIN_GAIN, 0.f)); A_CHK(alSourcef (pSource, AL_MAX_GAIN, 1.f)); A_CHK(alSourcef (pSource, AL_GAIN, cache_gain)); A_CHK(alSourcef (pSource, AL_PITCH, cache_pitch)); return TRUE; }else{ Msg ("! sound: OpenAL: Can't create source. Error: %s.",(LPCSTR)alGetString(error)); return FALSE; } }
COpenALSound::COpenALSound() { Sources = NULL; maxSounds = configHandler.GetInt("MaxSounds", 16); if (maxSounds <= 0) { throw content_error("Internal error, (maxSounds <= 0) in COpenALSound"); } globalVolume = 1.0f; cur = 0; ALCdevice *device = alcOpenDevice(NULL); if (device == NULL) { throw content_error("Could not create OpenAL audio device"); } else { ALCcontext *context = alcCreateContext(device, NULL); if (context != NULL) { alcMakeContextCurrent(context); } else { alcCloseDevice(device); throw content_error("Could not create OpenAL audio context"); } } printf("OpenAL: %s\n", (const char*)alGetString(AL_EXTENSIONS)); // Generate sound sources Sources = SAFE_NEW ALuint[maxSounds]; for (int a=0;a<maxSounds;a++) { Sources[a]=0; } // Set distance model (sound attenuation) alDistanceModel (AL_INVERSE_DISTANCE); posScale.x = 0.02f; posScale.y = 0.0005f; posScale.z = 0.02f; }
static void playFile (const char *fileName) { ALuint buffer; ALuint source; ALenum error; ALint status; /* Create an AL buffer from the given sound file. */ buffer = alutCreateBufferFromFile (fileName); if (buffer == AL_NONE) { error = alutGetError (); fprintf (stderr, "Error loading file: '%s'\n", alutGetErrorString (error)); alutExit (); exit (EXIT_FAILURE); } /* Generate a single source, attach the buffer to it and start playing. */ alGenSources (1, &source); alSourcei (source, AL_BUFFER, buffer); alSourcePlay (source); /* Normally nothing should go wrong above, but one never knows... */ error = alGetError (); if (error != ALUT_ERROR_NO_ERROR) { fprintf (stderr, "%s\n", alGetString (error)); alutExit (); exit (EXIT_FAILURE); } /* Check every 0.1 seconds if the sound is still playing. */ do { alutSleep (0.1f); alGetSourcei (source, AL_SOURCE_STATE, &status); } while (status == AL_PLAYING); }
//-------------------------------------------------------------------------- // openal_error_string() // // Returns the human readable error string if there is an error or NULL if not // const char *openal_error_string(int get_alc) { int i; if (get_alc) { ALCdevice *device = alcGetContextsDevice( alcGetCurrentContext() ); i = alcGetError(device); if ( i != ALC_NO_ERROR ) return (const char*) alcGetString(device, i); } else { i = alGetError(); if ( i != AL_NO_ERROR ) return (const char*)alGetString(i); } return NULL; }
bool AudioAsset::LoadFromRawPCMWavData(const u8 *data, size_t numBytes, bool stereo, bool is16Bit, int frequency) { // Clean up the previous OpenAL audio buffer handle, if old data existed. DoUnload(); #ifndef TUNDRA_NO_AUDIO if (!data || numBytes == 0) { LogError("Null data passed in AudioAsset::LoadFromWavData!"); return false; } if (!CreateBuffer()) return false; ALenum openALFormat; if (stereo && is16Bit) openALFormat = AL_FORMAT_STEREO16; else if (!stereo && is16Bit) openALFormat = AL_FORMAT_MONO16; else if (stereo && !is16Bit) openALFormat = AL_FORMAT_STEREO8; else /* (!stereo && !is16Bit)*/ openALFormat = AL_FORMAT_MONO8; // Copy the new data over. std::vector<u8> tmpData(data, data + numBytes); alBufferData(handle, openALFormat, &tmpData[0], tmpData.size(), frequency); ALenum error = alGetError(); if (error != AL_NONE) { const ALchar unknownError[] = "unknown error"; const ALchar *errorString = alGetString(error); if (!errorString) errorString = unknownError; LogError("Could not set OpenAL sound buffer data: OpenAL error number " + QString::number(error) + ": " + errorString); DoUnload(); return false; } return true; #else return false; #endif }
void idSoundHardware_OpenAL::PrintALCInfo( ALCdevice* device ) { ALCint major, minor; if( device ) { const ALCchar* devname = NULL; idLib::Printf( "\n" ); if( alcIsExtensionPresent( device, "ALC_ENUMERATE_ALL_EXT" ) != AL_FALSE ) { devname = alcGetString( device, ALC_ALL_DEVICES_SPECIFIER ); } if( CheckALCErrors( device ) != ALC_NO_ERROR || !devname ) { devname = alcGetString( device, ALC_DEVICE_SPECIFIER ); } idLib::Printf( "** Info for device \"%s\" **\n", devname ); } if( CheckALCErrors( device ) == ALC_NO_ERROR ) { alcGetIntegerv( device, ALC_MAJOR_VERSION, 1, &major ); alcGetIntegerv( device, ALC_MINOR_VERSION, 1, &minor ); idLib::Printf( "ALC version: %d.%d\n", major, minor ); } if( device ) { idLib::Printf( "OpenAL extensions:\n%s\n", alGetString( AL_EXTENSIONS ) ); //idLib::Printf("ALC extensions:"); //printList(alcGetString(device, ALC_EXTENSIONS), ' '); CheckALCErrors( device ); } }
__FORCE_ALIGN_STACK__ void CSound::StartThread(int maxSounds) { { boost::recursive_mutex::scoped_lock lck(soundMutex); // alc... will create its own thread it will copy the name from the current thread. // Later we finally rename `our` audio thread. Threading::SetThreadName("openal"); // NULL -> default device const ALchar* deviceName = NULL; std::string configDeviceName = ""; // we do not want to set a default for snd_device, // so we do it like this ... if (configHandler->IsSet("snd_device")) { configDeviceName = configHandler->GetString("snd_device"); deviceName = configDeviceName.c_str(); } ALCdevice* device = alcOpenDevice(deviceName); if ((device == NULL) && (deviceName != NULL)) { LOG_L(L_WARNING, "Could not open the sound device \"%s\", trying the default device ...", deviceName); configDeviceName = ""; deviceName = NULL; device = alcOpenDevice(deviceName); } if (device == NULL) { LOG_L(L_ERROR, "Could not open a sound device, disabling sounds"); CheckError("CSound::InitAL"); return; } else { ALCcontext *context = alcCreateContext(device, NULL); if (context != NULL) { alcMakeContextCurrent(context); CheckError("CSound::CreateContext"); } else { alcCloseDevice(device); LOG_L(L_ERROR, "Could not create OpenAL audio context"); return; } } maxSounds = GetMaxMonoSources(device, maxSounds); LOG("OpenAL info:"); if(alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT")) { LOG(" Available Devices:"); const char* deviceSpecifier = alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER); while (*deviceSpecifier != '\0') { LOG(" %s", deviceSpecifier); while (*deviceSpecifier++ != '\0') ; } LOG(" Device: %s", (const char*)alcGetString(device, ALC_DEVICE_SPECIFIER)); } LOG(" Vendor: %s", (const char*)alGetString(AL_VENDOR)); LOG(" Version: %s", (const char*)alGetString(AL_VERSION)); LOG(" Renderer: %s", (const char*)alGetString(AL_RENDERER)); LOG(" AL Extensions: %s", (const char*)alGetString(AL_EXTENSIONS)); LOG(" ALC Extensions: %s", (const char*)alcGetString(device, ALC_EXTENSIONS)); // Init EFX efx = new CEFX(device); // Generate sound sources for (int i = 0; i < maxSounds; i++) { CSoundSource* thenewone = new CSoundSource(); if (thenewone->IsValid()) { sources.push_back(thenewone); } else { maxSounds = std::max(i-1, 0); LOG_L(L_WARNING, "Your hardware/driver can not handle more than %i soundsources", maxSounds); delete thenewone; break; } } LOG(" Max Sounds: %i", maxSounds); // Set distance model (sound attenuation) alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED); alDopplerFactor(0.2f); alListenerf(AL_GAIN, masterVolume); } Threading::SetThreadName("audio"); Watchdog::RegisterThread(WDT_AUDIO); while (!soundThreadQuit) { boost::this_thread::sleep(boost::posix_time::millisec(50)); //! 20Hz Watchdog::ClearTimer(WDT_AUDIO); Update(); } Watchdog::DeregisterThread(WDT_AUDIO); sources.clear(); // delete all sources delete efx; // must happen after sources and before context efx = NULL; ALCcontext* curcontext = alcGetCurrentContext(); ALCdevice* curdevice = alcGetContextsDevice(curcontext); alcMakeContextCurrent(NULL); alcDestroyContext(curcontext); alcCloseDevice(curdevice); }
void Sound::Impl::PlaySound(const boost::filesystem::path& path, bool is_ui_sound/* = false*/) { if (!m_initialized || !GetOptionsDB().Get<bool>("UI.sound.enabled") || (is_ui_sound && UISoundsTemporarilyDisabled())) return; std::string filename = PathString(path); ALuint current_buffer; ALenum source_state; ALsizei ogg_freq; FILE *file = nullptr; int m_i; bool found_buffer = false; bool found_source = false; #ifdef FREEORION_WIN32 ov_callbacks callbacks = { (size_t (*)(void *, size_t, size_t, void *)) fread, (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap, (int (*)(void *)) fclose, (long (*)(void *)) ftell }; #endif if (alcGetCurrentContext()) { /* First check if the sound data of the file we want to play is already buffered somewhere */ std::map<std::string, ALuint>::iterator it = m_buffers.find(filename); if (it != m_buffers.end()) { current_buffer = it->second; found_buffer = true; } else { if ((file = fopen(filename.c_str(), "rb")) != nullptr) { // make sure we CAN open it OggVorbis_File ogg_file; vorbis_info *vorbis_info; ALenum ogg_format; #ifdef FREEORION_WIN32 if (!(ov_test_callbacks(file, &ogg_file, nullptr, 0, callbacks))) // check if it's a proper ogg #else if (!(ov_test(file, &ogg_file, nullptr, 0))) // check if it's a proper ogg #endif { ov_test_open(&ogg_file); // it is, now fully open the file /* now we need to take some info we will need later */ vorbis_info = ov_info(&ogg_file, -1); if (vorbis_info->channels == 1) ogg_format = AL_FORMAT_MONO16; else ogg_format = AL_FORMAT_STEREO16; ogg_freq = vorbis_info->rate; ogg_int64_t byte_size = ov_pcm_total(&ogg_file, -1) * vorbis_info->channels * 2; if (byte_size <= 1024 * 1024 * 1024) { /* fill up the buffers and queue them up for the first time */ ALuint sound_handle; alGenBuffers(1, &sound_handle); int loop = 0; RefillBuffer(&ogg_file, ogg_format, ogg_freq, sound_handle, byte_size, loop); current_buffer = sound_handle; found_buffer = true; m_buffers.insert(std::make_pair(filename, sound_handle)); } else { ErrorLogger() << "PlaySound: unable to open file " << filename.c_str() << " too big to buffer. Aborting\n"; } ov_clear(&ogg_file); } else { ErrorLogger() << "PlaySound: unable to open file " << filename.c_str() << " possibly not a .ogg vorbis file. Aborting\n"; } } } if (found_buffer) { /* Now that we have the buffer, we need to find a source to send it to */ for (m_i = 1; m_i < NUM_SOURCES; ++m_i) { // as we're playing sounds we start at 1. 0 is reserved for music alGetSourcei(m_sources[m_i], AL_SOURCE_STATE, &source_state); if ((source_state != AL_PLAYING) && (source_state != AL_PAUSED)) { found_source = true; alSourcei(m_sources[m_i], AL_BUFFER, current_buffer); alSourcePlay(m_sources[m_i]); break; // so that the sound won't block all the sources } } if (!found_source) ErrorLogger() << "PlaySound: Could not find aviable source - playback aborted\n"; } source_state = alGetError(); if (source_state != AL_NONE) ErrorLogger() << "PlaySound: OpenAL ERROR: " << alGetString(source_state); /* it's important to check for errors, as some functions won't work properly if * they're called when there is a unchecked previous error. */ } }
void Sound::Impl::PlayMusic(const boost::filesystem::path& path, int loops /* = 0*/) { if (!m_initialized) return; ALenum m_openal_error; std::string filename = PathString(path); FILE* m_f = nullptr; vorbis_info* vorbis_info; m_music_loops = 0; #ifdef FREEORION_WIN32 ov_callbacks callbacks = { (size_t (*)(void *, size_t, size_t, void *)) fread, (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap, (int (*)(void *)) fclose, (long (*)(void *)) ftell }; #endif if (alcGetCurrentContext()) { if (m_music_name.size() > 0) StopMusic(); if ((m_f = fopen(filename.c_str(), "rb")) != nullptr) // make sure we CAN open it { #ifdef FREEORION_WIN32 if (!(ov_test_callbacks(m_f, &m_ogg_file, nullptr, 0, callbacks))) // check if it's a proper ogg #else if (!(ov_test(m_f, &m_ogg_file, nullptr, 0))) // check if it's a proper ogg #endif { ov_test_open(&m_ogg_file); // it is, now fully open the file /* now we need to take some info we will need later */ vorbis_info = ov_info(&m_ogg_file, -1); if (vorbis_info->channels == 1) m_ogg_format = AL_FORMAT_MONO16; else m_ogg_format = AL_FORMAT_STEREO16; m_ogg_freq = vorbis_info->rate; m_music_loops = loops; /* fill up the buffers and queue them up for the first time */ if (!RefillBuffer(&m_ogg_file, m_ogg_format, m_ogg_freq, m_music_buffers[0], BUFFER_SIZE, m_music_loops)) { alSourceQueueBuffers(m_sources[0], 1, &m_music_buffers[0]); // queue up the buffer if we manage to fill it if (!RefillBuffer(&m_ogg_file, m_ogg_format, m_ogg_freq, m_music_buffers[1], BUFFER_SIZE, m_music_loops)) { alSourceQueueBuffers(m_sources[0], 1, &m_music_buffers[1]); m_music_name = filename; // yup, we're playing something that takes up more than 2 buffers } else { m_music_name.clear(); // m_music_name.clear() must always be called before ov_clear. Otherwise } alSourcePlay(m_sources[0]); // play if at least one buffer is queued } else { m_music_name.clear(); // m_music_name.clear() must always be called before ov_clear. Otherwise } } else { ErrorLogger() << "PlayMusic: unable to open file " << filename.c_str() << " possibly not a .ogg vorbis file. Aborting\n"; m_music_name.clear(); //just in case ov_clear(&m_ogg_file); } } else ErrorLogger() << "PlayMusic: unable to open file " << filename.c_str() << " I/O Error. Aborting\n"; } m_openal_error = alGetError(); if (m_openal_error != AL_NONE) ErrorLogger() << "PlayMusic: OpenAL ERROR: " << alGetString(m_openal_error); }
/// Initialize OpenAl and return true on success. // TODO rewrite with std::unique_ptr and custom deleter to remove long // chain of "destructor" code. void Sound::Impl::InitOpenAL() { ALCcontext *context; ALCdevice *device; ALenum error_code; ALboolean status; device = alcOpenDevice(nullptr); if (!device) { ErrorLogger() << "Unable to initialise default OpenAL device."; m_initialized = false; return; } context = alcCreateContext(device, nullptr); if (!context) { error_code = alGetError(); ErrorLogger() << "Unable to create OpenAL context: " << alGetString(error_code) << "\n"; alcCloseDevice(device); m_initialized = false; return; } status = alcMakeContextCurrent(context); error_code = alGetError(); if (status != AL_TRUE || error_code != AL_NO_ERROR) { ErrorLogger() << "Unable to make OpenAL context current: " << alGetString(error_code) << "\n"; alcDestroyContext(context); alcCloseDevice(device); m_initialized = false; return; } alListenerf(AL_GAIN, 1.0); error_code = alGetError(); if (error_code != AL_NO_ERROR) { ErrorLogger() << "Unable to create OpenAL listener: " << alGetString(error_code) << "\n" << "Disabling OpenAL sound system!\n"; alcMakeContextCurrent(nullptr); alcDestroyContext(context); alcCloseDevice(device); m_initialized = false; return; } alGenSources(NUM_SOURCES, m_sources); error_code = alGetError(); if (error_code != AL_NO_ERROR) { ErrorLogger() << "Unable to create OpenAL sources: " << alGetString(error_code) << "\n" << "Disabling OpenAL sound system!\n"; alcMakeContextCurrent(nullptr); alcDestroyContext(context); alcCloseDevice(device); m_initialized = false; return; } alGenBuffers(NUM_MUSIC_BUFFERS, m_music_buffers); error_code = alGetError(); if (error_code != AL_NO_ERROR) { ErrorLogger() << "Unable to create OpenAL buffers: " << alGetString(error_code) << "\n" << "Disabling OpenAL sound system!\n"; alDeleteSources(NUM_SOURCES, m_sources); alcMakeContextCurrent(nullptr); alcDestroyContext(context); alcCloseDevice(device); m_initialized = false; return; } for (int i = 0; i < NUM_SOURCES; ++i) { alSourcei(m_sources[i], AL_SOURCE_RELATIVE, AL_TRUE); error_code = alGetError(); if (error_code != AL_NO_ERROR) { ErrorLogger() << "Unable to set OpenAL source to relative: " << alGetString(error_code) << "\n" << "Disabling OpenAL sound system!\n"; alDeleteBuffers(NUM_MUSIC_BUFFERS, m_music_buffers); alDeleteSources(NUM_SOURCES, m_sources); alcMakeContextCurrent(nullptr); alcDestroyContext(context); alcCloseDevice(device); m_initialized = false; return; } } DebugLogger() << "OpenAL initialized. Version " << alGetString(AL_VERSION) << " Renderer " << alGetString(AL_RENDERER) << " Vendor " << alGetString(AL_VENDOR) << "\n" << " Extensions: " << alGetString(AL_EXTENSIONS) << "\n"; m_initialized = true; }
/** * Initializes the audio device and creates sources. * * @warning: * * @return TRUE if initialization was successful, FALSE otherwise */ bool FALAudioDevice::InitializeHardware( void ) { // Make sure no interface classes contain any garbage Effects = NULL; DLLHandle = NULL; // Default to sensible channel count. if( MaxChannels < 1 ) { MaxChannels = 32; } // Load ogg and vorbis dlls if they haven't been loaded yet //LoadVorbisLibraries(); // Open device HardwareDevice = alcOpenDevice(nullptr); if( !HardwareDevice ) { UE_LOG(LogALAudio, Log, TEXT( "ALAudio: no OpenAL devices found." ) ); return false ; } // Display the audio device that was actually opened const ALCchar* OpenedDeviceName = alcGetString( HardwareDevice, ALC_DEVICE_SPECIFIER ); UE_LOG(LogALAudio, Log, TEXT("ALAudio device opened : %s"), StringCast<TCHAR>(static_cast<const ANSICHAR*>(OpenedDeviceName)).Get()); // Create a context int Caps[] = { ALC_FREQUENCY, 44100, ALC_STEREO_SOURCES, 4, 0, 0 }; #if PLATFORM_HTML5_WIN32 || PLATFORM_LINUX SoundContext = alcCreateContext( HardwareDevice, Caps ); #elif PLATFORM_HTML5 SoundContext = alcCreateContext( HardwareDevice, 0 ); #endif if( !SoundContext ) { return false ; } alcMakeContextCurrent(SoundContext); // Make sure everything happened correctly if( alError( TEXT( "Init" ) ) ) { UE_LOG(LogALAudio, Warning, TEXT("ALAudio: alcMakeContextCurrent failed.")); return false ; } UE_LOG(LogALAudio, Log, TEXT("AL_VENDOR : %s"), StringCast<TCHAR>(static_cast<const ANSICHAR*>(alGetString(AL_VENDOR))).Get()); UE_LOG(LogALAudio, Log, TEXT("AL_RENDERER : %s"), StringCast<TCHAR>(static_cast<const ANSICHAR*>(alGetString(AL_RENDERER))).Get()); UE_LOG(LogALAudio, Log, TEXT("AL_VERSION : %s"), StringCast<TCHAR>(static_cast<const ANSICHAR*>(alGetString(AL_VERSION))).Get()); UE_LOG(LogALAudio, Log, TEXT("AL_EXTENSIONS : %s"), StringCast<TCHAR>(static_cast<const ANSICHAR*>(alGetString(AL_EXTENSIONS))).Get()); // Get the enums for multichannel support #if !PLATFORM_HTML5 Surround40Format = alGetEnumValue( "AL_FORMAT_QUAD16" ); Surround51Format = alGetEnumValue( "AL_FORMAT_51CHN16" ); Surround61Format = alGetEnumValue( "AL_FORMAT_61CHN16" ); Surround71Format = alGetEnumValue( "AL_FORMAT_71CHN16" ); #endif // Initialize channels. alError( TEXT( "Emptying error stack" ), 0 ); for( int i = 0; i < (( MaxChannels > MAX_AUDIOCHANNELS ) ? MAX_AUDIOCHANNELS : MaxChannels); i++ ) { ALuint SourceId; alGenSources( 1, &SourceId ); if( !alError( TEXT( "Init (creating sources)" ), 0 ) ) { FALSoundSource* Source = new FALSoundSource( this ); Source->SourceId = SourceId; Sources.Add( Source ); FreeSources.Add( Source ); } else { break; } } if( Sources.Num() < 1 ) { UE_LOG(LogALAudio, Warning, TEXT("ALAudio: couldn't allocate any sources")); return false ; } // Update MaxChannels in case we couldn't create enough sources. MaxChannels = Sources.Num(); UE_LOG(LogALAudio, Verbose, TEXT("ALAudioDevice: Allocated %i sources"), MaxChannels); // Use our own distance model. alDistanceModel( AL_NONE ); // Set up a default (nop) effects manager Effects = new FAudioEffectsManager( this ); return true ; }
value lime_al_get_string (value param) { return alloc_string (alGetString (val_int (param))); }
void SetupSound() { unsigned char buf[BUFFER_SIZE]; int i; // Get handle to device. pDevice = alcOpenDevice(NULL); if(checkALCError()) { fprintf(stderr, "[SPU] alcOpenDevice failed.\n"); return; } // ALC info. const ALCubyte* UNUSED_VARIABLE deviceName = (ALCubyte*)alcGetString(pDevice, ALC_DEVICE_SPECIFIER); //printf("[SPU] ALC_DEVICE_SPECIFIER = %s.\n", deviceName); const ALCubyte* UNUSED_VARIABLE extensionList = (ALCubyte*)alcGetString(pDevice, ALC_EXTENSIONS); //printf("[SPU] ALC_EXTENSIONS = %s.\n", extensionList); // Create audio context. pContext = alcCreateContext(pDevice, NULL); if(checkALCError()) { fprintf(stderr, "[SPU] alcCreateContext failed.\n"); return; } // Set active context. alcMakeContextCurrent( pContext ); if( checkALCError() ) { fprintf(stderr, "[SPU] alcMakeContextCurrent failed.\n"); return; } // AL info. const ALubyte* UNUSED_VARIABLE version = (ALubyte*)alGetString(AL_VERSION); //printf("[SPU] AL_VERSION = %s.\n", version); const ALubyte* UNUSED_VARIABLE renderer = (ALubyte*)alGetString(AL_RENDERER); //printf("[SPU] AL_RENDERER = %s.\n", renderer); const ALubyte* UNUSED_VARIABLE vendor = (ALubyte*)alGetString(AL_VENDOR); //printf("[SPU] AL_VENDOR = %s.\n", vendor); // Create buffers. alGenBuffers(BUFFER_QUANTITY, buffers); checkALError(); // Load sound data into a buffer. memset(buf, 0x00, BUFFER_SIZE); for(i = 0; i < BUFFER_QUANTITY; ++i) { alBufferData(buffers[i], format, buf, BUFFER_SIZE, sampleRate); } checkALError(); // Create source. alGenSources(1, &source); checkALError(); // Bind buffer with a source. alSourcef (source, AL_PITCH, 1.0f ); alSourcef (source, AL_GAIN, 1.0f ); alSourcefv(source, AL_POSITION, SourcePos); alSourcefv(source, AL_VELOCITY, SourceVel); alSourcefv(source, AL_DIRECTION, SourceDir); alSourcei (source, AL_SOURCE_RELATIVE, AL_TRUE ); alSourcei (source, AL_LOOPING, AL_FALSE ); // Listener properties. alListenerfv(AL_POSITION, ListenerPos); alListenerfv(AL_VELOCITY, ListenerVel); alListenerfv(AL_ORIENTATION, ListenerOri); // Add buffers to queue. alSourceQueueBuffers(source, BUFFER_QUANTITY, buffers); checkALError(); // Enable playing. alSourcePlay(source); checkALError(); }
bool cOpenALDeviceContext::initialize(const char* deviceName, int outputFrequency, int eaxEffectSlots) { cAudioMutexBasicLock lock(Mutex); if(Initialized) return false; //Stores the context attributes (MAX of 4, with 2 zeros to terminate) ALint attribs[6] = { 0 }; unsigned int currentAttrib = 0; if(outputFrequency > 0) { attribs[currentAttrib++] = ALC_FREQUENCY; attribs[currentAttrib++] = outputFrequency; } #if CAUDIO_EFX_ENABLED == 1 if(eaxEffectSlots > 0) { attribs[currentAttrib++] = ALC_MAX_AUXILIARY_SENDS; attribs[currentAttrib++] = eaxEffectSlots; } #endif //Create a new device Device = alcOpenDevice(deviceName); //Check if device can be created if (Device == NULL) { getLogger()->logError("AudioManager", "Failed to Create OpenAL Device."); checkError(); return false; } Context = alcCreateContext(Device, attribs); if (Context == NULL) { getLogger()->logError("AudioManager", "Failed to Create OpenAL Context."); checkError(); alcCloseDevice(Device); Device = NULL; return false; } if(!alcMakeContextCurrent(Context)) { getLogger()->logError("AudioManager", "Failed to make OpenAL Context current."); checkError(); alcDestroyContext(Context); alcCloseDevice(Device); Context = NULL; Device = NULL; return false; } getLogger()->logInfo("AudioManager", "OpenAL Version: %s", alGetString(AL_VERSION)); getLogger()->logInfo("AudioManager", "Vendor: %s", alGetString(AL_VENDOR)); getLogger()->logInfo("AudioManager", "Renderer: %s", alGetString(AL_RENDERER)); #if CAUDIO_EFX_ENABLED == 1 initEffects.getEFXInterface()->Mutex.lock(); EFXSupported = initEffects.getEFXInterface()->CheckEFXSupport(Device); initEffects.getEFXInterface()->Mutex.unlock(); initEffects.checkEFXSupportDetails(); if(EFXSupported) { int EFXMajorVersion = 0; int EFXMinorVersion = 0; alcGetIntegerv(Device, ALC_EFX_MAJOR_VERSION, 1, &EFXMajorVersion); alcGetIntegerv(Device, ALC_EFX_MINOR_VERSION, 1, &EFXMinorVersion); getLogger()->logInfo("AudioManager", "EFX Version: %i.%i", EFXMajorVersion, EFXMinorVersion); getLogger()->logInfo("AudioManager", "EFX supported and enabled."); } else { getLogger()->logWarning("AudioManager", "EFX is not supported, EFX disabled."); } #endif getLogger()->logInfo("AudioManager", "Supported Extensions: %s", alGetString(AL_EXTENSIONS)); return true; }
void ActualizarMusica ( ){ ALint error; int cont = 0; int contador = 0; int i; int posicion = 0; ALuint streambuffers[NUM_BUFFER_MUSICA]; /* Utilizado en la carga de archivos OGG */ ALshort waveout [BUFFER_MUSICA]; /* Donde almacenamos los OGG Vorbis decodificados */ ALuint streamsource[1]; /* Utilizado en la carga de archivos OGG */ /* Generamos buffers para hacer el streaming */ alGenBuffers ( NUM_BUFFER_MUSICA, streambuffers); if ( (error = alGetError()) != AL_NO_ERROR){ fprintf ( logs,"Fallo al crear los buffers para la musica:%s\n", alGetString(error)); exit (2); } /* Rellenamos los buffers creados con la musica decodificada */ for ( i=0; i < NUM_BUFFER_MUSICA ; i++){ cont = ov_read ( &buff, (char *)&waveout[posicion], BUFFER_MUSICA , 0, 2, 1, ¤t_section ) / 2; contador += cont; fprintf ( logs, "contador = \n"); alBufferData ( streambuffers[i], formato, waveout , BUFFER_MUSICA , informacion->rate ); if ( (error =alGetError ()) != AL_NO_ERROR ){ fprintf ( logs, "Error al anyadir datos al buffer %i:%s\n",i,alGetString(error)); } } /* Creamos la fuente y definimos sus propiedades */ alGenSources( 1, streamsource ); if ( (error = alGetError()) != AL_NO_ERROR ){ fprintf ( logs, "Error al generar la fuente de sonido: %s\n", alGetString (error)); } /* Defino propiedades para la fuente */ /*alSourcei ( streamsource[0], AL_SOURCE_RELATIVE, AL_TRUE ); /* Para que se mueva con el listener */ /*alSourcei ( streamsource[0], AL_LOOPING, AL_FALSE ); /* No se repite por ella sola */ /*alSourcef ( streamsource[0], AL_GAIN, 0.9f ); /* Para que suene menos que los sonidos */ /* Asignamos los buffers creados a la fuente */ alSourceQueueBuffers ( streamsource[0], NUM_BUFFER_MUSICA, streambuffers ); /* Se empieza a reproducir la musica */ alSourcePlay ( streamsource[0] ); if ( (error = alGetError ()) != AL_NO_ERROR ){ fprintf ( logs, "Error al reproducir musica:%s\n",alGetString (error)); } /* A partir de aqui es donde realmente empieza el Streaming*/ while ( contador < tamanyo_cancion ){ /* Comprobamos estado de los buffers */ alGetSourceiv ( streamsource[0], AL_BUFFERS_PROCESSED, &buffers_vacios); /* Si algun buffer esta vacio, lo rellenamos */ if ( buffers_vacios > 0 ){ while ( buffers_vacios ){ /* Desasignamos buffers para rellenarlos */ alSourceUnqueueBuffers ( streamsource[0], 1, &streambuffers ); if ( (alGetError( )) != AL_NO_ERROR ){ fprintf ( logs,"No va el streaming\n"); } /* Descomprimimos datos en el buffer intermedio */ cont = ov_read ( &buff, (char *)&waveout, BUFFER_MUSICA, 0, 2, 1, ¤t_section); contador += cont; /* Los anyadimos en el buffer */ alBufferData ( streambuffers, formato, waveout, BUFFER_MUSICA, frecuencia ); if ((alGetError()) != AL_NO_ERROR ){ fprintf ( logs, "No se puede añadir datos al buffer\n"); } /* Asignamos de nuevo los buffers al streamsource */ alSourceQueueBuffers ( streamsource[0], 1, &streambuffers ); buffers_vacios --; /* Compruebo si se ha acabado la cancion */ if ( contador < tamanyo_cancion){ break; } } } } /* Cuando se acaba la cancion, paramos todo y borramos buffers y fuentes */ alSourceStopv(1, streamsource); if (alGetError() != AL_NO_ERROR){ fprintf ( logs,"No se pueden parar el streamsource\n"); } alDeleteSources(1, streamsource); if (alGetError() != AL_NO_ERROR){ fprintf ( logs,"No se puede borrar el stremsource\n"); } alDeleteBuffers(NUM_BUFFER_MUSICA, streambuffers); if (alGetError() != AL_NO_ERROR){ fprintf ( logs,"No se pueden borrar los buffers\n"); } musica_on = 0; }
void sound_Update() { SAMPLE_LIST *node = active_samples; SAMPLE_LIST *previous = NULL; ALCenum err; ALfloat gain; if (!openal_initialized) { return; } // Update all streaming audio sound_UpdateStreams(); while (node != NULL) { ALenum state, err; // query what the gain is for this sample alGetSourcef(node->curr->iSample, AL_GAIN, &gain); err = sound_GetError(); // if gain is 0, then we can't hear it, so we kill it. if (gain == 0.0f) { sound_DestroyIteratedSample(&previous, &node); continue; } //ASSERT(alIsSource(node->curr->iSample), "Not a valid source!"); alGetSourcei(node->curr->iSample, AL_SOURCE_STATE, &state); // Check whether an error occurred while retrieving the state. // If one did, the state returned is useless. So instead of // using it continue with the next sample. err = sound_GetError(); if (err != AL_NO_ERROR) { // Make sure to invoke the "finished" callback sound_FinishedCallback(node->curr); // Destroy this object and move to the next object sound_DestroyIteratedSample(&previous, &node); continue; } switch (state) { case AL_PLAYING: case AL_PAUSED: // If we haven't finished playing yet, just // continue with the next item in the list. // sound_SetObjectPosition(i->curr->iSample, i->curr->x, i->curr->y, i->curr->z); // Move to the next object previous = node; node = node->next; break; // NOTE: if it isn't playing | paused, then it is most likely either done // or a error. In either case, we want to kill the sample in question. default: sound_DestroyIteratedSample(&previous, &node); break; } } // Reset the current error state alcGetError(device); alcProcessContext(context); err = sound_GetContextError(device); if (err != ALC_NO_ERROR) { debug(LOG_ERROR, "Error while processing audio context: %s", alGetString(err)); } }