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"
19 OggSoundFile::OggSoundFile(PHYSFS_file* file, double loop_begin, double loop_at) :
28 ov_callbacks callbacks = { cb_read, cb_seek, cb_close, cb_tell };
29 ov_open_callbacks(file, &vorbis_file, 0, 0, callbacks);
31 vorbis_info* vi = ov_info(&vorbis_file, -1);
33 channels = vi->channels;
36 size = static_cast<size_t> (ov_pcm_total(&vorbis_file, -1) * 2);
38 double samples_begin = loop_begin * rate;
39 double sample_loop = loop_at * rate;
41 this->loop_begin = (ogg_int64_t) samples_begin;
43 this->loop_at = (ogg_int64_t) -1;
45 this->loop_at = (ogg_int64_t) sample_loop;
49 OggSoundFile::~OggSoundFile()
51 ov_clear(&vorbis_file);
55 OggSoundFile::read(void* _buffer, size_t buffer_size)
57 char* buffer = reinterpret_cast<char*> (_buffer);
59 size_t totalBytesRead = 0;
61 while(buffer_size>0) {
62 #ifdef WORDS_BIGENDIAN
68 size_t bytes_to_read = buffer_size;
70 size_t bytes_per_sample = 2;
71 ogg_int64_t time = ov_pcm_tell(&vorbis_file);
72 ogg_int64_t samples_left_till_loop = loop_at - time;
73 ogg_int64_t bytes_left_till_loop
74 = samples_left_till_loop * bytes_per_sample;
75 if(bytes_left_till_loop <= 4)
78 if(bytes_left_till_loop < (ogg_int64_t) bytes_to_read) {
79 bytes_to_read = (size_t) bytes_left_till_loop;
84 = ov_read(&vorbis_file, buffer, bytes_to_read, bigendian,
89 buffer_size -= bytesRead;
91 totalBytesRead += bytesRead;
94 return totalBytesRead;
100 ov_pcm_seek(&vorbis_file, loop_begin);
104 OggSoundFile::cb_read(void* ptr, size_t size, size_t nmemb, void* source)
106 PHYSFS_file* file = reinterpret_cast<PHYSFS_file*> (source);
109 = PHYSFS_read(file, ptr, static_cast<PHYSFS_uint32> (size),
110 static_cast<PHYSFS_uint32> (nmemb));
114 return static_cast<size_t> (res);
118 OggSoundFile::cb_seek(void* source, ogg_int64_t offset, int whence)
120 PHYSFS_file* file = reinterpret_cast<PHYSFS_file*> (source);
124 if(PHYSFS_seek(file, static_cast<PHYSFS_uint64> (offset)) == 0)
128 if(PHYSFS_seek(file, PHYSFS_tell(file) + offset) == 0)
132 if(PHYSFS_seek(file, PHYSFS_fileLength(file) + offset) == 0)
146 OggSoundFile::cb_close(void* source)
148 PHYSFS_file* file = reinterpret_cast<PHYSFS_file*> (source);
154 OggSoundFile::cb_tell(void* source)
156 PHYSFS_file* file = reinterpret_cast<PHYSFS_file*> (source);
157 return static_cast<long> (PHYSFS_tell(file));