32 VorbisAudioCursor(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;
77 ~VorbisAudioCursor() {
85 void VorbisAudioCursor::
87 if (!vorbis_enable_seek) {
94 if (vorbis_seek_lap) {
95 if (ov_time_seek_lap(&_ov, t) != 0) {
97 <<
"Seek failed. Ogg Vorbis stream may not be seekable.\n";
101 if (ov_time_seek(&_ov, t) != 0) {
103 <<
"Seek failed. Ogg Vorbis stream may not be seekable.\n";
108 _last_seek = ov_time_tell(&_ov);
117 void VorbisAudioCursor::
118 read_samples(
int n, int16_t *data) {
119 int desired = n * _audio_channels;
121 char *buffer = (
char*) data;
122 int length = desired * 2;
129 long read_bytes = ov_read(&_ov, buffer, length, 0, 2, 1, &bitstream);
130 if (read_bytes > 0) {
131 buffer += read_bytes;
132 length -= read_bytes;
137 if (_bitstream != bitstream) {
140 vorbis_info *vi = ov_info(&_ov, -1);
141 if (vi->channels != _audio_channels || vi->rate != _audio_rate) {
143 <<
"Ogg Vorbis file has non-matching bitstreams!\n";
146 _audio_channels = vi->channels;
147 _audio_rate = vi->rate;
151 _bitstream = bitstream;
157 memset(buffer, 0, length);
158 n -= length / 2 / _audio_channels;
168 size_t VorbisAudioCursor::
169 cb_read_func(
void *ptr,
size_t size,
size_t nmemb,
void *datasource) {
170 istream *stream = (istream*) datasource;
171 nassertr(stream !=
nullptr, -1);
173 stream->read((
char *)ptr, size * nmemb);
180 return stream->gcount();
187 int VorbisAudioCursor::
188 cb_seek_func(
void *datasource, ogg_int64_t offset,
int whence) {
189 if (!vorbis_enable_seek) {
193 istream *stream = (istream*) datasource;
194 nassertr(stream !=
nullptr, -1);
198 stream->seekg(offset, std::ios::beg);
202 stream->seekg(offset, std::ios::cur);
206 stream->seekg(offset, std::ios::end);
211 <<
"Illegal parameter to seek in VorbisAudioCursor::cb_seek_func\n";
215 if (stream->fail()) {
218 <<
"Failure to seek to byte " << offset;
222 movies_cat.error(
false)
223 <<
" from current location!\n";
227 movies_cat.error(
false)
228 <<
" from end of file!\n";
232 movies_cat.error(
false) <<
"!\n";
245 int VorbisAudioCursor::
246 cb_close_func(
void *datasource) {
247 istream *stream = (istream*) datasource;
248 nassertr(stream !=
nullptr, -1);
261 long VorbisAudioCursor::
262 cb_tell_func(
void *datasource) {
263 istream *stream = (istream*) datasource;
264 nassertr(stream !=
nullptr, -1);
266 return stream->tellg();
269 #endif // HAVE_VORBIS A hierarchy of directories and files that appears to be one continuous file system,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static void close_read_file(std::istream *stream)
Closes a file opened by a previous call to open_read_file().
A MovieAudio is actually any source that provides a sequence of audio samples.
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.
TypeHandle is the identifier used to differentiate C++ class types.