2 // Copyright (C) 2006 Matthias Braun <matze@braunis.de>
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include "audio/ogg_sound_file.hpp"
21 OggSoundFile::OggSoundFile(PHYSFS_file* file, double loop_begin, double loop_at) :
30 ov_callbacks callbacks = { cb_read, cb_seek, cb_close, cb_tell };
31 ov_open_callbacks(file, &vorbis_file, 0, 0, callbacks);
33 vorbis_info* vi = ov_info(&vorbis_file, -1);
35 channels = vi->channels;
38 size = static_cast<size_t> (ov_pcm_total(&vorbis_file, -1) * 2);
40 double samples_begin = loop_begin * rate;
41 double sample_loop = loop_at * rate;
43 this->loop_begin = (ogg_int64_t) samples_begin;
45 this->loop_at = (ogg_int64_t) -1;
47 this->loop_at = (ogg_int64_t) sample_loop;
51 OggSoundFile::~OggSoundFile()
53 ov_clear(&vorbis_file);
57 OggSoundFile::read(void* _buffer, size_t buffer_size)
59 char* buffer = reinterpret_cast<char*> (_buffer);
61 size_t totalBytesRead = 0;
63 while(buffer_size>0) {
64 #ifdef WORDS_BIGENDIAN
70 size_t bytes_to_read = buffer_size;
72 size_t bytes_per_sample = 2;
73 ogg_int64_t time = ov_pcm_tell(&vorbis_file);
74 ogg_int64_t samples_left_till_loop = loop_at - time;
75 ogg_int64_t bytes_left_till_loop
76 = samples_left_till_loop * bytes_per_sample;
77 if(bytes_left_till_loop <= 4)
80 if(bytes_left_till_loop < (ogg_int64_t) bytes_to_read) {
81 bytes_to_read = (size_t) bytes_left_till_loop;
86 = ov_read(&vorbis_file, buffer, bytes_to_read, bigendian,
91 buffer_size -= bytesRead;
93 totalBytesRead += bytesRead;
96 return totalBytesRead;
100 OggSoundFile::reset()
102 ov_pcm_seek(&vorbis_file, loop_begin);
106 OggSoundFile::cb_read(void* ptr, size_t size, size_t nmemb, void* source)
108 PHYSFS_file* file = reinterpret_cast<PHYSFS_file*> (source);
111 = PHYSFS_read(file, ptr, static_cast<PHYSFS_uint32> (size),
112 static_cast<PHYSFS_uint32> (nmemb));
116 return static_cast<size_t> (res);
120 OggSoundFile::cb_seek(void* source, ogg_int64_t offset, int whence)
122 PHYSFS_file* file = reinterpret_cast<PHYSFS_file*> (source);
126 if(PHYSFS_seek(file, static_cast<PHYSFS_uint64> (offset)) == 0)
130 if(PHYSFS_seek(file, PHYSFS_tell(file) + offset) == 0)
134 if(PHYSFS_seek(file, PHYSFS_fileLength(file) + offset) == 0)
145 OggSoundFile::cb_close(void* source)
147 PHYSFS_file* file = reinterpret_cast<PHYSFS_file*> (source);
153 OggSoundFile::cb_tell(void* source)
155 PHYSFS_file* file = reinterpret_cast<PHYSFS_file*> (source);
156 return static_cast<long> (PHYSFS_tell(file));