Panda3D
 All Classes Functions Variables Enumerations
userDataAudio.cxx
1 // Filename: userDataAudio.cxx
2 // Created by: jyelon (02Jul07)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "userDataAudio.h"
16 #include "userDataAudioCursor.h"
17 
18 TypeHandle UserDataAudio::_type_handle;
19 
20 ////////////////////////////////////////////////////////////////////
21 // Function: UserDataAudio::Constructor
22 // Access: Public
23 // Description: This constructor returns a UserDataAudio ---
24 // a means to supply raw audio samples manually.
25 ////////////////////////////////////////////////////////////////////
27 UserDataAudio(int rate, int channels, bool remove_after_read) :
28  MovieAudio("User Data Audio"),
29  _desired_rate(rate),
30  _desired_channels(channels),
31  _cursor(NULL),
32  _aborted(false),
33  _remove_after_read(remove_after_read)
34 {
35 }
36 
37 ////////////////////////////////////////////////////////////////////
38 // Function: UserDataAudio::Destructor
39 // Access: Public, Virtual
40 // Description:
41 ////////////////////////////////////////////////////////////////////
42 UserDataAudio::
43 ~UserDataAudio() {
44 }
45 
46 ////////////////////////////////////////////////////////////////////
47 // Function: UserDataAudio::open
48 // Access: Published, Virtual
49 // Description: Open this audio, returning a UserDataAudioCursor. A
50 // UserDataAudio can only be opened by one consumer
51 // at a time.
52 ////////////////////////////////////////////////////////////////////
54 open() {
55  if (_cursor) {
56  nassert_raise("A UserDataAudio can only be opened by one consumer at a time.");
57  return NULL;
58  }
59  _cursor = new UserDataAudioCursor(this);
60  return _cursor;
61 }
62 
63 ////////////////////////////////////////////////////////////////////
64 // Function: UserDataAudio::read_samples
65 // Access: Private
66 // Description: Read audio samples from the stream. N is the
67 // number of samples you wish to read. Your buffer
68 // must be equal in size to N * channels.
69 // Multiple-channel audio will be interleaved.
70 ////////////////////////////////////////////////////////////////////
71 void UserDataAudio::
72 read_samples(int n, PN_int16 *data) {
73  int ready = (_data.size() / _desired_channels);
74  int desired = n * _desired_channels;
75  int avail = ready * _desired_channels;
76  if (avail > desired) avail = desired;
77  for (int i=0; i<avail; i++) {
78  data[i] = _data[i];
79  }
80  for (int i=avail; i<desired; i++) {
81  data[i] = 0;
82  }
83  for (int i=0; i<avail; i++) {
84  _data.pop_front();
85  }
86 }
87 
88 ////////////////////////////////////////////////////////////////////
89 // Function: UserDataAudio::append
90 // Access: Public
91 // Description: Appends audio samples to the buffer.
92 ////////////////////////////////////////////////////////////////////
93 void UserDataAudio::
94 append(PN_int16 *data, int n) {
95  nassertv(!_aborted);
96  int words = n * _desired_channels;
97  for (int i=0; i<words; i++) {
98  _data.push_back(data[i]);
99  }
100 }
101 
102 ////////////////////////////////////////////////////////////////////
103 // Function: UserDataAudio::append
104 // Access: Published
105 // Description: Appends audio samples to the buffer from a
106 // datagram. This is intended to make it easy to
107 // send streaming raw audio over a network.
108 ////////////////////////////////////////////////////////////////////
109 void UserDataAudio::
110 append(DatagramIterator *src, int n) {
111  nassertv(!_aborted);
112  int maxlen = src->get_remaining_size() / (2 * _desired_channels);
113  if (n > maxlen) n = maxlen;
114  int words = n * _desired_channels;
115  for (int i=0; i<words; i++) {
116  _data.push_back(src->get_int16());
117  }
118 }
119 
120 ////////////////////////////////////////////////////////////////////
121 // Function: UserDataAudio::append
122 // Access: Published
123 // Description: Appends audio samples to the buffer from a
124 // string. The samples must be stored little-endian
125 // in the string. This is not particularly efficient,
126 // but it may be convenient to deal with samples in
127 // python.
128 ////////////////////////////////////////////////////////////////////
129 void UserDataAudio::
130 append(const string &str) {
131  nassertv(!_aborted);
132  int samples = str.size() / (2 * _desired_channels);
133  int words = samples * _desired_channels;
134  for (int i=0; i<words; i++) {
135  int c1 = ((unsigned char)str[i*2+0]);
136  int c2 = ((unsigned char)str[i*2+1]);
137  PN_int16 n = (c1 | (c2 << 8));
138  _data.push_back(n);
139  }
140 }
141 
142 ////////////////////////////////////////////////////////////////////
143 // Function: UserDataAudio::done
144 // Access: Published
145 // Description: Promises not to append any more samples, ie, this
146 // marks the end of the audio stream.
147 ////////////////////////////////////////////////////////////////////
148 void UserDataAudio::
149 done() {
150  _aborted = true;
151 }
void done()
Promises not to append any more samples, ie, this marks the end of the audio stream.
void append(PN_int16 *data, int n)
Appends audio samples to the buffer.
PN_int16 get_int16()
Extracts a signed 16-bit integer.
A UserDataAudioCursor is a means to manually supply a sequence of raw audio samples.
int get_remaining_size() const
Return the bytes left in the datagram.
A MovieAudio is actually any source that provides a sequence of audio samples.
A UserDataAudio is a way for the user to manually supply raw audio samples.
Definition: userDataAudio.h:35
UserDataAudio(int rate, int channels, bool remove_after_read=true)
This constructor returns a UserDataAudio — a means to supply raw audio samples manually.
A class to retrieve the individual data elements previously stored in a Datagram. ...
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
A MovieAudio is actually any source that provides a sequence of audio samples.
Definition: movieAudio.h:48