/* audio/vorbis.cc This file is part of the Osirion project and is distributed under the terms of the GNU General Public License version 2 */ #include "string.h" #include #include #include "audio/vorbisfile.h" #include "filesystem/filesystem.h" #include "sys/sys.h" #ifdef _WIN32 /* READ vorbisfile.h! This works because I have a clean development environment */ #define OV_EXCLUDE_STATIC_CALLBACKS #endif #include #include namespace audio { PCM *Vorbis::load(std::string const & filename) { if (!filename.size()) return 0; filesystem::File *fs_file = filesystem::open(filename.c_str()); if (!fs_file) { return 0; } std::string vorbis_path(fs_file->path()); vorbis_path.append(fs_file->name()); filesystem::close(fs_file); OggVorbis_File vorbis_file; // workaround for Ubuntu 10: ov_fopen parameter 1 is char * instead of const char * char tmpstr[vorbis_path.size()+1]; ::strncpy((char *)tmpstr, vorbis_path.c_str(), vorbis_path.size()); if (ov_fopen(tmpstr, &vorbis_file) < 0 ) { return 0; } vorbis_info* vorbis_streaminfo; vorbis_streaminfo = ov_info(&vorbis_file, -1); unsigned int samplerate = vorbis_streaminfo->rate; unsigned int channels = vorbis_streaminfo->channels; unsigned int bitspersample = 16; // always. const size_t blocksize = 1024*1024; // 1Mb blocks PCM *pcm = new PCM(samplerate, bitspersample, channels, blocksize); pcm->set_size(0); long bytesread = 0; do { // enlarge the pcm buffer if required if (pcm->size() + 4096 > pcm->buff_size()) { pcm->grow(pcm->buff_size() + blocksize); } bytesread = ov_read(&vorbis_file, (char *)pcm->data() + pcm->size(),4096,0,2,1,0); pcm->set_size( pcm->size() + bytesread); } while (bytesread > 0); ov_clear(&vorbis_file); con_debug << " " << filename << " " << pcm->samplerate() << "Hz " << pcm->bitspersample() << "bit " << pcm->channels() << " chan " << pcm->size() << " bytes" << std::endl; return pcm; } }