23 #include <opus/opusfile.h> 31 int cb_read(
void *stream,
unsigned char *ptr,
int nbytes) {
32 istream *in = (istream *)stream;
33 nassertr(in !=
nullptr, -1);
35 in->read((
char *)ptr, nbytes);
45 int cb_seek(
void *stream, opus_int64 offset,
int whence) {
46 if (!opus_enable_seek) {
50 istream *in = (istream *)stream;
51 nassertr(in !=
nullptr, -1);
55 in->seekg(offset, std::ios::beg);
59 in->seekg(offset, std::ios::cur);
63 in->seekg(offset, std::ios::end);
68 <<
"Illegal parameter to seek in cb_seek\n";
74 <<
"Failure to seek to byte " << offset;
78 movies_cat.error(
false)
79 <<
" from current location!\n";
83 movies_cat.error(
false)
84 <<
" from end of file!\n";
88 movies_cat.error(
false) <<
"!\n";
97 opus_int64 cb_tell(
void *stream) {
98 istream *in = (istream *)stream;
99 nassertr(in !=
nullptr, -1);
104 int cb_close(
void *stream) {
105 istream *in = (istream *)stream;
106 nassertr(in !=
nullptr, EOF);
113 static const OpusFileCallbacks callbacks = {cb_read, cb_seek, cb_tell, cb_close};
122 OpusAudioCursor(OpusAudio *src, istream *stream) :
127 nassertv(stream !=
nullptr);
128 nassertv(stream->good());
131 _op = op_open_callbacks((
void *)stream, &callbacks,
nullptr, 0, &error);
132 if (_op ==
nullptr) {
134 <<
"Failed to read Opus file (error code " << error <<
").\n";
138 ogg_int64_t samples = op_pcm_total(_op, -1);
139 if (samples != OP_EINVAL) {
141 _length = (double)samples / 48000.0;
144 _audio_channels = op_channel_count(_op, -1);
147 _can_seek = opus_enable_seek && op_seekable(_op);
148 _can_seek_fast = _can_seek;
158 if (_op !=
nullptr) {
168 void OpusAudioCursor::
170 if (!opus_enable_seek) {
174 t = std::max(t, 0.0);
177 int error = op_pcm_seek(_op, (ogg_int64_t)(t * 48000.0));
180 <<
"Seek failed (error " << error <<
"). Opus stream may not be seekable.\n";
184 _last_seek = op_pcm_tell(_op) / 48000.0;
193 void OpusAudioCursor::
194 read_samples(
int n, int16_t *data) {
195 int16_t *end = data + (n * _audio_channels);
200 int read_samples = op_read(_op, data, end - data, &link);
201 if (read_samples > 0) {
202 data += read_samples * _audio_channels;
203 _samples_read += read_samples;
211 int channels = op_channel_count(_op, link);
212 if (channels != _audio_channels) {
214 <<
"Opus file has inconsistent channel count!\n";
217 _audio_channels = channels;
226 memset(data, 0, (
unsigned char *)end - (
unsigned char *)data);
A hierarchy of directories and files that appears to be one continuous file system,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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.
TypeHandle is the identifier used to differentiate C++ class types.