Sound_Buffer::Sound_Buffer(const String &filename) : #ifndef DISABLE_AL m_buffer(AL_NONE), #endif m_duration(float()) //, m_loader(0) //, m_thread(0) { Sound &sr = get_Sound(); #ifndef DISABLE_AL if(dynamic_cast<Sound_Renderer_AL *>(&sr.get_Renderer())) { //m_loader = new Loader(filename); //m_thread = new Thread(*m_loader); std::pair<ALuint, float> loaded_ogg = load_ogg_vorbis(filename); if(loaded_ogg.first == AL_NONE) { std::cerr << "OpenAL error on '" << filename << "': " << Sound_Renderer_AL::errorString() << std::endl; throw Sound_Buffer_Init_Failure(); } m_buffer = loaded_ogg.first; m_duration = loaded_ogg.second; } #endif #ifdef ENABLE_SLES init_SLES(filename); #endif }
pair<ALuint, float> Sound_Buffer::load_ogg_vorbis(const string & #ifndef DISABLE_AL filename #endif ) { #ifndef DISABLE_AL /*** Open VorbisFile ***/ OggVorbis_File oggFile; if(ov_fopen(const_cast<char *>(filename.c_str()), &oggFile)) return make_pair(AL_NONE, 0.0f); /*** Get Information About the Audio File ***/ vorbis_info *pInfo = ov_info(&oggFile, -1); const ALenum format = pInfo->channels == 2 ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16; const ALsizei freq = pInfo->rate; const ALsizei bytes_per_sample = format == AL_FORMAT_STEREO16 ? 4 : 2; const ogg_int64_t num_samples = ov_pcm_total(&oggFile, -1); const ogg_int64_t pcm_size = num_samples * bytes_per_sample; const float duration = float(num_samples) / freq; #ifndef NDEBUG if(format == AL_FORMAT_STEREO16) cerr << "WARNING: '" << filename << "' is stereo and will be unaffected by the OpenAL positional audio system." << endl; #endif /*** Load the Audio File ***/ int bytes = 0; int buffer_size = int(pcm_size); vector<char> buffer( static_cast<size_t>(buffer_size) ); for(char *begin = &buffer[0], *end = begin + pcm_size; begin != end; begin += bytes, buffer_size -= bytes) { bytes = ov_read(&oggFile, begin, buffer_size, 0, 2, 1, 0); if(!bytes) { ov_clear(&oggFile); throw Sound_Buffer_Init_Failure(); } } /*** Generate Audio Buffer ***/ ALuint bufferID = AL_NONE; alGenBuffers(1, &bufferID); alBufferData(bufferID, format, &buffer[0], static_cast<ALsizei>(buffer.size()), freq); return make_pair(bufferID, duration); #else return make_pair(AL_NONE, 0.0f); #endif }
void Sound_Buffer::finish_loading() const { delete m_thread; m_thread = 0; const int status = m_loader->status; m_buffer = m_loader->m_buffer; m_duration = m_loader->m_duration; delete m_loader; m_loader = 0; if(status) throw Sound_Buffer_Init_Failure(); }
Sound_Buffer::Sound_Buffer() : m_buffer(AL_NONE), m_loader(0), m_thread(0) { get_Sound(); #ifndef DISABLE_AL m_buffer = alutCreateBufferHelloWorld(); if(m_buffer == AL_NONE) { cerr << "ALUT error on Hello World: " << alutGetErrorString(alutGetError()) << endl; throw Sound_Buffer_Init_Failure(); } #endif }
void Sound_Buffer::init_SLES(const String &filename) { if(dynamic_cast<Sound_Renderer_SLES *>(&get_Sound().get_Renderer())) { // use asset manager to open asset by filename AAsset* asset = AAssetManager_open(File_Ops::get_AAssetManager(), (filename + ".wav").c_str(), AASSET_MODE_UNKNOWN); if(!asset) throw Sound_Buffer_Init_Failure(); // open asset as file descriptor off_t start, length; int fd = AAsset_openFileDescriptor(asset, &start, &length); assert(0 <= fd); AAsset_close(asset); // configure audio source loc_fd = {SL_DATALOCATOR_ANDROIDFD, fd, start, length}; format_mime = {SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED}; audioSrc = {&loc_fd, &format_mime}; } }
Sound_Buffer::Sound_Buffer() : m_buffer(AL_NONE) //, m_loader(0) //, m_thread(0) { #ifndef DISABLE_AL Sound &sr = get_Sound(); if(dynamic_cast<Sound_Renderer_AL *>(&sr.get_Renderer())) { Sound_Renderer_AL::alGenBuffers()(1, &m_buffer); if(m_buffer == AL_NONE) { std::cerr << "OpenAL error on alGenBuffers: " << Sound_Renderer_AL::errorString() << std::endl; throw Sound_Buffer_Init_Failure(); } char buffer[64]; memset(buffer, 0, sizeof(buffer)); Sound_Renderer_AL::alBufferData()(m_buffer, AL_FORMAT_MONO16, buffer, sizeof(buffer), 22050); } #endif }
std::pair<ALuint, float> Sound_Buffer::load_ogg_vorbis(const String & #ifndef DISABLE_AL filename #endif ) { #ifndef DISABLE_AL /*** Open VorbisFile ***/ OggVorbis_File oggFile; if(ov_fopen(const_cast<char *>((filename + ".ogg").c_str()), &oggFile)) return std::make_pair(AL_NONE, 0.0f); /*** Get Information About the Audio File ***/ vorbis_info *pInfo = ov_info(&oggFile, -1); const ALenum format = pInfo->channels == 2 ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16; const ALsizei freq = ALsizei(pInfo->rate); const ALsizei bytes_per_sample = format == AL_FORMAT_STEREO16 ? 4 : 2; const ogg_int64_t num_samples = ov_pcm_total(&oggFile, -1); const ogg_int64_t pcm_size = num_samples * bytes_per_sample; const float duration = float(num_samples) / freq; #ifndef NDEBUG if(format == AL_FORMAT_STEREO16) std::cerr << "WARNING: '" << filename << "' is stereo and will be unaffected by the OpenAL positional audio system." << std::endl; #endif /*** Load the Audio File ***/ long bytes = 0; ogg_int64_t remaining = pcm_size; if(pcm_size > std::numeric_limits<size_t>::max()) throw Sound_Buffer_Init_Failure(); std::vector<char> buffer(static_cast<size_t>(pcm_size)); for(char *begin = &buffer[0], *end = begin + pcm_size; begin != end; begin += bytes, remaining -= bytes) { int read_size = remaining > std::numeric_limits<int>::max() ? std::numeric_limits<int>::max() : int(remaining); bytes = ov_read(&oggFile, begin, read_size, 0, 2, 1, 0); if(bytes < 0) { ov_clear(&oggFile); throw Sound_Buffer_Init_Failure(); } } /*** Generate Audio Buffer ***/ ALuint bufferID = AL_NONE; Sound_Renderer_AL::alGenBuffers()(1, &bufferID); Sound_Renderer_AL::alBufferData()(bufferID, format, &buffer[0], static_cast<ALsizei>(buffer.size()), freq); return std::make_pair(bufferID, duration); #else return std::make_pair(AL_NONE, 0.0f); #endif }