7
9
#include "ALShared.h"
8
10
#include "VorbisShared.h"
13
const int BUFFER_SIZE = (4096 * 128);
15
size_t VorbisStreamRead(void* ptr, size_t size, size_t nmemb, void* datasource)
17
CFileHandler* buffer = (CFileHandler*)datasource;
18
return buffer->Read(ptr, size * nmemb);
21
int VorbisStreamClose(void* datasource)
23
CFileHandler* buffer = (CFileHandler*)datasource;
28
int VorbisStreamSeek(void* datasource, ogg_int64_t offset, int whence)
30
CFileHandler* buffer = (CFileHandler*)datasource;
31
if (whence == SEEK_SET)
33
buffer->Seek(offset, std::ios_base::beg);
35
else if (whence == SEEK_CUR)
37
buffer->Seek(offset, std::ios_base::cur);
39
else if (whence == SEEK_END)
41
buffer->Seek(offset, std::ios_base::end);
47
long VorbisStreamTell(void* datasource)
49
CFileHandler* buffer = (CFileHandler*)datasource;
50
return buffer->GetPos();
12
namespace VorbisCallbacks {
13
size_t VorbisStreamRead(void* ptr, size_t size, size_t nmemb, void* datasource)
15
CFileHandler* buffer = (CFileHandler*)datasource;
16
return buffer->Read(ptr, size * nmemb);
19
int VorbisStreamClose(void* datasource)
21
CFileHandler* buffer = (CFileHandler*)datasource;
26
int VorbisStreamSeek(void* datasource, ogg_int64_t offset, int whence)
28
CFileHandler* buffer = (CFileHandler*)datasource;
29
if (whence == SEEK_SET)
31
buffer->Seek(offset, std::ios_base::beg);
33
else if (whence == SEEK_CUR)
35
buffer->Seek(offset, std::ios_base::cur);
37
else if (whence == SEEK_END)
39
buffer->Seek(offset, std::ios_base::end);
45
long VorbisStreamTell(void* datasource)
47
CFileHandler* buffer = (CFileHandler*)datasource;
48
return buffer->GetPos();
55
55
COggStream::COggStream(ALuint _source)
58
, format(AL_FORMAT_MONO16)
64
for (unsigned i = 0; i < NUM_BUFFERS; ++i) {
67
69
COggStream::~COggStream()
85
87
ov_callbacks vorbisCallbacks;
86
vorbisCallbacks.read_func = VorbisStreamRead;
87
vorbisCallbacks.close_func = VorbisStreamClose;
88
vorbisCallbacks.seek_func = VorbisStreamSeek;
89
vorbisCallbacks.tell_func = VorbisStreamTell;
88
vorbisCallbacks.read_func = VorbisCallbacks::VorbisStreamRead;
89
vorbisCallbacks.close_func = VorbisCallbacks::VorbisStreamClose;
90
vorbisCallbacks.seek_func = VorbisCallbacks::VorbisStreamSeek;
91
vorbisCallbacks.tell_func = VorbisCallbacks::VorbisStreamTell;
91
93
CFileHandler* buf = new CFileHandler(path);
92
94
if ((result = ov_open_callbacks(buf, &oggStream, NULL, 0, vorbisCallbacks)) < 0) {
97
100
vorbisInfo = ov_info(&oggStream, -1);
99
102
vorbis_comment* vorbisComment;
100
103
vorbisComment = ov_comment(&oggStream, -1);
101
104
vorbisTags.resize(vorbisComment->comments);
102
for (unsigned i = 0; i < vorbisComment->comments; ++i)
106
for (unsigned i = 0; i < vorbisComment->comments; ++i) {
104
107
vorbisTags[i] = std::string(vorbisComment->user_comments[i], vorbisComment->comment_lengths[i]);
106
110
vendor = std::string(vorbisComment->vendor);
110
114
if (vorbisInfo->channels == 1) {
124
129
CheckError("COggStream");
127
float COggStream::GetPlayTime()
132
float COggStream::GetPlayTime() const
129
float time = float(msecsPlayed)/1000.0f;
134
return (msecsPlayed / 1000.0f);
133
137
float COggStream::GetTotalTime()
135
double time = ov_time_total(&oggStream,-1);
139
return ov_time_total(&oggStream, -1);
139
const COggStream::TagVector& COggStream::VorbisTags()
142
const COggStream::TagVector& COggStream::VorbisTags() const
141
144
return vorbisTags;
187
191
lastTick = SDL_GetTicks();
189
if (!DecodeStream(buffers[0]))
192
if (!DecodeStream(buffers[1]))
193
if (!DecodeStream(buffers[0])) { return false; }
194
if (!DecodeStream(buffers[1])) { return false; }
195
196
alSourceQueueBuffers(source, 2, buffers); CheckError("COggStream");
196
197
alSourcePlay(source); CheckError("COggStream");
232
236
// refill them, and push them back in line
233
237
bool COggStream::UpdateBuffers()
239
int buffersProcessed = 0;
236
240
bool active = true;
238
alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
242
alGetSourcei(source, AL_BUFFERS_PROCESSED, &buffersProcessed);
240
while (processed-- > 0) {
244
while (buffersProcessed-- > 0) {
242
246
alSourceUnqueueBuffers(source, 1, &buffer); CheckError("COggStream");
254
258
void COggStream::Update()
258
unsigned tick = SDL_GetTicks();
261
if (UpdateBuffers()) {
263
// source state changed
264
if (!StartPlaying()) {
268
// stream interrupted
264
unsigned tick = SDL_GetTicks();
267
if (UpdateBuffers()) {
269
// source state changed
270
if (!StartPlaying()) {
274
// stream interrupted
272
} else if (!IsPlaying()) {
273
// EOS and all chunks processed by OpenALs
276
msecsPlayed += (tick - lastTick);
278
} else if (!IsPlaying()) {
279
// EOS and all chunks processed by OpenALs
283
msecsPlayed += (tick - lastTick);
316
323
// dequeue any buffers pending on source
317
324
void COggStream::EmptyBuffers()
320
alGetSourcei(source, AL_BUFFERS_QUEUED, &queued); CheckError("COggStream");
326
int queuedBuffers = 0;
327
alGetSourcei(source, AL_BUFFERS_QUEUED, &queuedBuffers); CheckError("COggStream");
322
while (queued-- > 0) {
329
while (queuedBuffers-- > 0) {
324
331
alSourceUnqueueBuffers(source, 1, &buffer); CheckError("COggStream");