Panda3D

movieAudioCursor.cxx
Go to the documentation of this file.
1 /**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file movieAudioCursor.cxx
10 * @author jyelon
11 * @date 2007-07-02
12 */
13
14 #include "movieAudioCursor.h"
15
16 TypeHandle MovieAudioCursor::_type_handle;
17
18 /**
19 * This constructor returns a null audio stream --- a stream of total silence,
20 * at 8000 samples per second. To get more interesting audio, you need to
21 * construct a subclass of this class.
22 */
23 MovieAudioCursor::
24 MovieAudioCursor(MovieAudio *src) :
25 _source(src),
26 _audio_rate(8000),
27 _audio_channels(1),
28 _length(1.0E10),
29 _can_seek(true),
30 _can_seek_fast(true),
31 _aborted(false),
32 _samples_read(0)
33 {
34 }
35
36 /**
37 *
38 */
39 MovieAudioCursor::
40 ~MovieAudioCursor() {
41 }
42
43 /**
44 * Read audio samples from the stream. N is the number of samples you wish to
45 * read. Your buffer must be equal in size to N * channels. Multiple-channel
46 * audio will be interleaved.
47 */
48 void MovieAudioCursor::
49 read_samples(int n, int16_t *data) {
50
51 // This is the null implementation, which generates pure silence. Normally,
52 // this method will be overridden by a subclass.
53
54 if (n <= 0) {
55 return;
56 }
57
58 int desired = n * _audio_channels;
59 for (int i=0; i<desired; i++) {
60 data[i] = 0;
61 }
62 _samples_read += n;
63 }
64
65 /**
66 * Read audio samples from the stream into a Datagram. N is the number of
67 * samples you wish to read. Multiple-channel audio will be interleaved.
68 *
69 * This is not particularly efficient, but it may be a convenient way to
70 * manipulate samples in python.
71 */
72 void MovieAudioCursor::
73 read_samples(int n, Datagram *dg) {
74 int16_t tmp[4096];
75 while (n > 0) {
76 int blocksize = (4096 / _audio_channels);
77 if (blocksize > n) blocksize = n;
78 int words = blocksize * _audio_channels;
79 read_samples(blocksize, tmp);
80 for (int i=0; i<words; i++) {
81 dg->add_int16(tmp[i]);
82 }
83 n -= blocksize;
84 }
85 }
86
87 /**
88 * Read audio samples from the stream and returns them as a string. The
89 * samples are stored little-endian in the string. N is the number of samples
90 * you wish to read. Multiple-channel audio will be interleaved.
91 *
92 * This is not particularly efficient, but it may be a convenient way to
93 * manipulate samples in python.
94 */
95 std::string MovieAudioCursor::
96 read_samples(int n) {
97 std::ostringstream result;
98 int16_t tmp[4096];
99 while (n > 0) {
100 int blocksize = (4096 / _audio_channels);
101 if (blocksize > n) blocksize = n;
102 int words = blocksize * _audio_channels;
103 read_samples(blocksize, tmp);
104 for (int i=0; i<words; i++) {
105 int16_t word = tmp[i];
106 result.put((char)(word & 255));
107 result.put((char)((word>>8) & 255));
108 }
109 n -= blocksize;
110 }
111 return result.str();
112 }
113
114
115 /**
116 * Skips to the specified offset within the file.
117 *
118 * If the movie reports that it cannot seek, then this method can still
119 * advance by reading samples and discarding them. However, to move backward,
120 * can_seek must be true.
121 *
122 * If the movie reports that it can_seek, it doesn't mean that it can do so
123 * quickly. It may have to rewind the movie and then fast forward to the
124 * desired location. Only if can_seek_fast returns true can seek operations
125 * be done in constant time.
126 *
127 * Seeking may not be precise, because AVI files often have inaccurate
128 * indices. After seeking, tell will indicate that the cursor is at the
129 * target location. However, in truth, the data you read may come from a
130 * slightly offset location.
131 */
132 void MovieAudioCursor::
133 seek(double offset) {
134 _last_seek = offset;
135 _samples_read = 0;
136 }
137
138 /**
139 * Returns the number of audio samples that are ready to read. This is
140 * primarily relevant for sources like microphones which produce samples at a
141 * fixed rate. If you try to read more samples than are ready, the result
142 * will be silent samples.
143 *
144 * Some audio streams do not have a limit on how fast they can produce
145 * samples. Such streams will always return 0x40000000 as the ready-count.
146 * This may well exceed the length of the audio stream. You therefore need to
147 * check length separately.
148 *
149 * If the aborted flag is set, that means the ready count is no longer being
150 * replenished. For example, a MovieAudioCursor might be reading from an
151 * internet radio station, and it might buffer data to avoid underruns. If it
152 * loses connection to the radio station, it will set the aborted flag to
153 * indicate that the buffer is no longer being replenished. But it is still
154 * ok to read the samples that are in the buffer, at least until they run out.
155 * Once those are gone, there will be no more.
156 *
157 * An audio consumer needs to check the length, the ready status, and the
158 * aborted flag.
159 */
160 int MovieAudioCursor::
161 ready() const {
162 return 0x40000000;
163 }
Datagram
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
Datagram::add_int16
void add_int16(int16_t value)
Adds a signed 16-bit integer to the datagram.
Definition: datagram.I:58
MovieAudioCursor::MovieAudioCursor
MovieAudioCursor(MovieAudio *src)
This constructor returns a null audio stream — a stream of total silence, at 8000 samples per second.
Definition: movieAudioCursor.cxx:24
MovieAudioCursor::ready
virtual int ready() const
Returns the number of audio samples that are ready to read.
Definition: movieAudioCursor.cxx:161
MovieAudioCursor::seek
virtual void seek(double offset)
Skips to the specified offset within the file.
Definition: movieAudioCursor.cxx:133
MovieAudioCursor::read_samples
void read_samples(int n, Datagram *dg)
Read audio samples from the stream into a Datagram.
Definition: movieAudioCursor.cxx:73
MovieAudio
A MovieAudio is actually any source that provides a sequence of audio samples.
Definition: movieAudio.h:44
TypeHandle
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
movieAudioCursor.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.