Panda3D
Loading...
Searching...
No Matches
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
16TypeHandle 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 */
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 */
39MovieAudioCursor::
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 */
49read_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 */
73read_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 */
96read_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 */
133seek(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 */
161ready() const {
162 return 0x40000000;
163}
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition datagram.h:38
void add_int16(int16_t value)
Adds a signed 16-bit integer to the datagram.
Definition datagram.I:58
MovieAudioCursor(MovieAudio *src)
This constructor returns a null audio stream — a stream of total silence, at 8000 samples per second.
virtual int ready() const
Returns the number of audio samples that are ready to read.
virtual void seek(double offset)
Skips to the specified offset within the file.
void read_samples(int n, Datagram *dg)
Read audio samples from the stream into a Datagram.
A MovieAudio is actually any source that provides a sequence of audio samples.
Definition movieAudio.h:44
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.