Panda3D
|
00001 // Filename: userDataAudio.cxx 00002 // Created by: jyelon (02Jul07) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "userDataAudio.h" 00016 #include "userDataAudioCursor.h" 00017 00018 TypeHandle UserDataAudio::_type_handle; 00019 00020 //////////////////////////////////////////////////////////////////// 00021 // Function: UserDataAudio::Constructor 00022 // Access: Public 00023 // Description: This constructor returns a UserDataAudio --- 00024 // a means to supply raw audio samples manually. 00025 //////////////////////////////////////////////////////////////////// 00026 UserDataAudio:: 00027 UserDataAudio(int rate, int channels) : 00028 MovieAudio("User Data Audio"), 00029 _desired_rate(rate), 00030 _desired_channels(channels), 00031 _cursor(NULL), 00032 _aborted(false) 00033 { 00034 } 00035 00036 //////////////////////////////////////////////////////////////////// 00037 // Function: UserDataAudio::Destructor 00038 // Access: Public, Virtual 00039 // Description: 00040 //////////////////////////////////////////////////////////////////// 00041 UserDataAudio:: 00042 ~UserDataAudio() { 00043 } 00044 00045 //////////////////////////////////////////////////////////////////// 00046 // Function: UserDataAudio::open 00047 // Access: Published, Virtual 00048 // Description: Open this audio, returning a UserDataAudioCursor. A 00049 // UserDataAudio can only be opened by one consumer 00050 // at a time. 00051 //////////////////////////////////////////////////////////////////// 00052 PT(MovieAudioCursor) UserDataAudio:: 00053 open() { 00054 if (_cursor) { 00055 nassert_raise("A UserDataAudio can only be opened by one consumer at a time."); 00056 return NULL; 00057 } 00058 _cursor = new UserDataAudioCursor(this); 00059 return _cursor; 00060 } 00061 00062 //////////////////////////////////////////////////////////////////// 00063 // Function: UserDataAudio::read_samples 00064 // Access: Private 00065 // Description: Read audio samples from the stream. N is the 00066 // number of samples you wish to read. Your buffer 00067 // must be equal in size to N * channels. 00068 // Multiple-channel audio will be interleaved. 00069 //////////////////////////////////////////////////////////////////// 00070 void UserDataAudio:: 00071 read_samples(int n, PN_int16 *data) { 00072 int ready = (_data.size() / _desired_channels); 00073 int desired = n * _desired_channels; 00074 int avail = ready * _desired_channels; 00075 if (avail > desired) avail = desired; 00076 for (int i=0; i<avail; i++) { 00077 data[i] = _data[i]; 00078 } 00079 for (int i=avail; i<desired; i++) { 00080 data[i] = 0; 00081 } 00082 for (int i=0; i<avail; i++) { 00083 _data.pop_front(); 00084 } 00085 } 00086 00087 //////////////////////////////////////////////////////////////////// 00088 // Function: UserDataAudio::append 00089 // Access: Public 00090 // Description: Appends audio samples to the buffer. 00091 //////////////////////////////////////////////////////////////////// 00092 void UserDataAudio:: 00093 append(PN_int16 *data, int n) { 00094 nassertv(!_aborted); 00095 int words = n * _desired_channels; 00096 for (int i=0; i<words; i++) { 00097 _data.push_back(data[i]); 00098 } 00099 } 00100 00101 //////////////////////////////////////////////////////////////////// 00102 // Function: UserDataAudio::append 00103 // Access: Published 00104 // Description: Appends audio samples to the buffer from a 00105 // datagram. This is intended to make it easy to 00106 // send streaming raw audio over a network. 00107 //////////////////////////////////////////////////////////////////// 00108 void UserDataAudio:: 00109 append(DatagramIterator *src, int n) { 00110 nassertv(!_aborted); 00111 int maxlen = src->get_remaining_size() / (2 * _desired_channels); 00112 if (n > maxlen) n = maxlen; 00113 int words = n * _desired_channels; 00114 for (int i=0; i<words; i++) { 00115 _data.push_back(src->get_int16()); 00116 } 00117 } 00118 00119 //////////////////////////////////////////////////////////////////// 00120 // Function: UserDataAudio::append 00121 // Access: Published 00122 // Description: Appends audio samples to the buffer from a 00123 // string. The samples must be stored little-endian 00124 // in the string. This is not particularly efficient, 00125 // but it may be convenient to deal with samples in 00126 // python. 00127 //////////////////////////////////////////////////////////////////// 00128 void UserDataAudio:: 00129 append(const string &str) { 00130 nassertv(!_aborted); 00131 int samples = str.size() / (2 * _desired_channels); 00132 int words = samples * _desired_channels; 00133 for (int i=0; i<words; i++) { 00134 int c1 = ((unsigned char)str[i*2+0]); 00135 int c2 = ((unsigned char)str[i*2+1]); 00136 PN_int16 n = (c1 | (c2 << 8)); 00137 _data.push_back(n); 00138 } 00139 } 00140 00141 //////////////////////////////////////////////////////////////////// 00142 // Function: UserDataAudio::done 00143 // Access: Published 00144 // Description: Promises not to append any more samples, ie, this 00145 // marks the end of the audio stream. 00146 //////////////////////////////////////////////////////////////////// 00147 void UserDataAudio:: 00148 done() { 00149 _aborted = true; 00150 }