32VorbisAudioCursor(VorbisAudio *src, istream *stream) :
37 nassertv(stream !=
nullptr);
38 nassertv(stream->good());
41 ov_callbacks callbacks;
42 callbacks.read_func = &cb_read_func;
43 callbacks.close_func = &cb_close_func;
44 callbacks.tell_func = &cb_tell_func;
46 if (vorbis_enable_seek) {
47 callbacks.seek_func = &cb_seek_func;
49 callbacks.seek_func =
nullptr;
52 if (ov_open_callbacks((
void*) stream, &_ov,
nullptr, 0, callbacks) != 0) {
54 <<
"Failed to read Ogg Vorbis file.\n";
58 double time_total = ov_time_total(&_ov, -1);
59 if (time_total != OV_EINVAL) {
63 vorbis_info *vi = ov_info(&_ov, -1);
64 _audio_channels = vi->channels;
65 _audio_rate = vi->rate;
67 _can_seek = vorbis_enable_seek && (ov_seekable(&_ov) != 0);
68 _can_seek_fast = _can_seek;
85void VorbisAudioCursor::
87 if (!vorbis_enable_seek) {
95 if (vorbis_seek_lap) {
96 result = ov_time_seek_lap(&_ov, t);
98 result = ov_time_seek(&_ov, t);
104 if (result == OV_ENOSEEK && t == 0.0) {
105 std::istream *stream = (std::istream *)_ov.datasource;
107 if (stream->rdbuf()->pubseekpos(0, std::ios::in) == (std::streampos)0) {
110 ov_callbacks callbacks = _ov.callbacks;
111 _ov.datasource =
nullptr;
114 if (ov_open_callbacks((
void *)stream, &_ov,
nullptr, 0, callbacks) != 0) {
116 <<
"Failed to reopen Ogg Vorbis file to seek to beginning.\n";
121 vorbis_info *vi = ov_info(&_ov, -1);
122 _audio_channels = vi->channels;
123 _audio_rate = vi->rate;
132 <<
"Seek failed. Ogg Vorbis stream may not be seekable.\n";
135 _last_seek = ov_time_tell(&_ov);
144void VorbisAudioCursor::
145read_samples(
int n, int16_t *data) {
146 int desired = n * _audio_channels;
148 char *buffer = (
char*) data;
149 int length = desired * 2;
156 long read_bytes = ov_read(&_ov, buffer, length, 0, 2, 1, &bitstream);
157 if (read_bytes > 0) {
158 buffer += read_bytes;
159 length -= read_bytes;
164 if (_bitstream != bitstream) {
167 vorbis_info *vi = ov_info(&_ov, -1);
168 if (vi->channels != _audio_channels || vi->rate != _audio_rate) {
170 <<
"Ogg Vorbis file has non-matching bitstreams!\n";
173 _audio_channels = vi->channels;
174 _audio_rate = vi->rate;
178 _bitstream = bitstream;
184 memset(buffer, 0, length);
185 n -= length / 2 / _audio_channels;
195size_t VorbisAudioCursor::
196cb_read_func(
void *ptr,
size_t size,
size_t nmemb,
void *datasource) {
197 istream *stream = (istream*) datasource;
198 nassertr(stream !=
nullptr, -1);
200 stream->read((
char *)ptr, size * nmemb);
207 return stream->gcount();
214int VorbisAudioCursor::
215cb_seek_func(
void *datasource, ogg_int64_t offset,
int whence) {
216 if (!vorbis_enable_seek) {
220 istream *stream = (istream*) datasource;
221 nassertr(stream !=
nullptr, -1);
225 stream->seekg(offset, std::ios::beg);
232 std::streambuf *buf = stream->rdbuf();
233 std::streampos pos = buf->pubseekoff(0, std::ios::cur, std::ios::in);
237 if (buf->pubseekoff(0, std::ios::end, std::ios::in) >= 0) {
239 buf->pubseekpos(pos, std::ios::in);
245 stream->seekg(offset, std::ios::cur);
249 stream->seekg(offset, std::ios::end);
254 <<
"Illegal parameter to seek in VorbisAudioCursor::cb_seek_func\n";
258 if (stream->fail()) {
261 <<
"Failure to seek to byte " << offset;
265 movies_cat.error(
false)
266 <<
" from current location!\n";
270 movies_cat.error(
false)
271 <<
" from end of file!\n";
275 movies_cat.error(
false) <<
"!\n";
288int VorbisAudioCursor::
289cb_close_func(
void *datasource) {
290 istream *stream = (istream*) datasource;
291 nassertr(stream !=
nullptr, -1);
304long VorbisAudioCursor::
305cb_tell_func(
void *datasource) {
306 istream *stream = (istream*) datasource;
307 nassertr(stream !=
nullptr, -1);
309 return stream->tellg();
A MovieAudio is actually any source that provides a sequence of audio samples.
TypeHandle is the identifier used to differentiate C++ class types.
A hierarchy of directories and files that appears to be one continuous file system,...
static void close_read_file(std::istream *stream)
Closes a file opened by a previous call to open_read_file().
static VirtualFileSystem * get_global_ptr()
Returns the default global VirtualFileSystem.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.