Panda3D
|
00001 // Filename: userDataAudioCursor.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 "userDataAudioCursor.h" 00016 00017 TypeHandle UserDataAudioCursor::_type_handle; 00018 00019 //////////////////////////////////////////////////////////////////// 00020 // Function: UserDataAudioCursor::Constructor 00021 // Access: 00022 // Description: 00023 //////////////////////////////////////////////////////////////////// 00024 UserDataAudioCursor:: 00025 UserDataAudioCursor(UserDataAudio *src) : 00026 MovieAudioCursor(src) 00027 { 00028 _audio_rate = src->_desired_rate; 00029 _audio_channels = src->_desired_channels; 00030 _can_seek = !src->_remove_after_read; 00031 _can_seek_fast = !src->_remove_after_read; 00032 _aborted = false; 00033 if(!src->_remove_after_read) { 00034 assert(src->_aborted && "UserData was not closed before by a done() call"); 00035 _length = static_cast<double>(src->_data.size() / _audio_channels) / _audio_rate; 00036 } 00037 } 00038 00039 //////////////////////////////////////////////////////////////////// 00040 // Function: UserDataAudioCursor::Destructor 00041 // Access: Public, Virtual 00042 // Description: 00043 //////////////////////////////////////////////////////////////////// 00044 UserDataAudioCursor:: 00045 ~UserDataAudioCursor() { 00046 UserDataAudio *source = (UserDataAudio*)(MovieAudio*)_source; 00047 source->_cursor = NULL; 00048 } 00049 00050 //////////////////////////////////////////////////////////////////// 00051 // Function: UserDataAudioCursor::read_samples 00052 // Access: Private 00053 // Description: Read audio samples from the stream. N is the 00054 // number of samples you wish to read. Your buffer 00055 // must be equal in size to N * channels. 00056 // Multiple-channel audio will be interleaved. 00057 //////////////////////////////////////////////////////////////////// 00058 void UserDataAudioCursor:: 00059 read_samples(int n, PN_int16 *data) { 00060 UserDataAudio *source = (UserDataAudio*)(MovieAudio*)_source; 00061 00062 if(source->_remove_after_read) { 00063 source->read_samples(n, data); 00064 } 00065 else { 00066 int offset = _samples_read * _audio_channels; 00067 int avail = source->_data.size() - offset; 00068 int desired = n * _audio_channels; 00069 if (avail > desired) avail = desired; 00070 00071 for (int i=0; i<avail; i++) { 00072 data[i] = source->_data[i+offset]; 00073 } 00074 for (int i=avail; i<desired; i++) { 00075 data[i] = 0; 00076 } 00077 } 00078 00079 _samples_read += n; 00080 } 00081 00082 //////////////////////////////////////////////////////////////////// 00083 // Function: UserDataAudioCursor::ready 00084 // Access: Published 00085 // Description: Set the offset if possible. 00086 //////////////////////////////////////////////////////////////////// 00087 void UserDataAudioCursor:: 00088 seek(double t) { 00089 if(_can_seek && 0 <= t && _length <= t) { 00090 _samples_read = static_cast<int>(t * _audio_rate * _audio_channels + 0.5f); 00091 } 00092 else { 00093 _samples_read = 0; 00094 } 00095 _last_seek = t; 00096 } 00097 00098 //////////////////////////////////////////////////////////////////// 00099 // Function: UserDataAudioCursor::ready 00100 // Access: Private 00101 // Description: Returns the number of audio samples ready to be 00102 // read. 00103 //////////////////////////////////////////////////////////////////// 00104 int UserDataAudioCursor:: 00105 ready() const { 00106 UserDataAudio *source = (UserDataAudio*)(MovieAudio*)_source; 00107 ((UserDataAudioCursor*)this)->_aborted = source->_aborted; 00108 00109 if(source->_remove_after_read) return source->_data.size() / _audio_channels; 00110 else return source->_data.size() / _audio_channels - _samples_read; 00111 }