|
CLAM-Development
1.3
|
00001 /* 00002 * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG) 00003 * UNIVERSITAT POMPEU FABRA 00004 * 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 * 00020 */ 00021 00022 #include "Audio.hxx" 00023 #include "CLAM_Math.hxx" 00024 #include "ProcessingDataPlugin.hxx" 00025 00026 using namespace CLAM; 00027 00028 namespace CLAM 00029 { 00030 namespace Hidden 00031 { 00032 static ProcessingDataPlugin::Registrator<CLAM::Audio> dataRegistratorAudio("lightcyan","CLAM::Audio (Buffer)"); 00033 } 00034 } 00035 00036 Audio::~Audio() 00037 { 00038 } 00039 00040 void Audio::DefaultInit(void) 00041 { 00042 // Attribute instantiation. 00043 AddSampleRate(); 00044 AddBeginTime(); 00045 AddBuffer(); 00046 UpdateData(); 00047 00048 // Attribute initialization (Default values). 00049 SetSampleRate(44100); 00050 SetBeginTime(0);//By default, audio starts at 0 00051 } 00052 00053 void Audio::SetEndTime(TTime time) 00054 { 00055 CLAM_WARNING(false, "Audio::SetEndTime is about to be deprecated. Please use Audio::ResizeToEndTime instead"); 00056 ResizeToEndTime(time); 00057 } 00058 00059 void Audio::ResizeToEndTime(TTime time) 00060 { 00061 const int newsizeRound = Round((time-GetBeginTime())/1000.0*GetSampleRate()); 00062 SetSize(newsizeRound); 00063 } 00064 00065 void Audio::SetSize(int newSize) 00066 { 00067 CLAM_ASSERT(HasBuffer(), "Audio::SetSize(int) needs a buffer (HasBuffer()==1)"); 00068 CLAM_ASSERT(newSize>=0,"Audio::SetSize(): Negative size specified"); 00069 int oldSize=GetSize(); 00070 if (newSize==oldSize) return; 00071 int physicalSize = GetBuffer().AllocatedSize(); 00072 if (newSize>physicalSize) 00073 GetBuffer().Resize(newSize); 00074 GetBuffer().SetSize(newSize); 00075 if(newSize<=oldSize) return; 00076 memset(GetBuffer().GetPtr()+oldSize,0,(newSize-oldSize)*sizeof(TData)); 00077 } 00078 00079 void Audio::SetDuration(TTime duration) 00080 { 00081 CLAM_WARNING(false, "Audio::SetDuration is about to be deprecated. Please use Audio::ResizeToDuration instead"); 00082 ResizeToDuration(GetIndexFromTime(duration)); 00083 } 00084 00085 void Audio::ResizeToDuration(TTime duration) 00086 { 00087 SetSize(GetIndexFromTime(duration)); 00088 } 00089 00090 TTime Audio::GetTimeFromIndex(TIndex index) const 00091 { 00092 return (TTime)((TTime)index / GetSampleRate()*1000.0 ); 00093 } 00094 00095 TIndex Audio::GetIndexFromTime(TTime time) const 00096 { 00097 return Round(time*((TData)GetSampleRate()/1000.0)); 00098 } 00099 00100 void Audio::GetAudioChunk(TTime beginTime, TTime endTime,Audio& chunk, bool configureChunk) const 00101 { 00102 GetAudioChunk(GetIndexFromTime(beginTime),GetIndexFromTime(endTime),chunk, configureChunk); 00103 } 00104 00105 void Audio::GetAudioSlice(TTime beginTime, TTime endTime,Audio& slice, bool configureSlice) const 00106 { 00107 GetAudioSlice(GetIndexFromTime(beginTime),GetIndexFromTime(endTime),slice, configureSlice); 00108 } 00109 00110 00111 00112 void Audio::GetAudioSlice( TIndex beginIndex, TIndex endIndex, Audio& slice, bool configureChunk ) const 00113 { 00114 CLAM_ASSERT( beginIndex >=0, "Negative indexes are not allowed for audio slices" ); 00115 CLAM_ASSERT( endIndex <= GetSize(), "Slices are not allowed to surpass audio size" ); 00116 00117 00118 TIndex size=endIndex-beginIndex; 00119 00120 DataArray tmpArray; 00121 tmpArray.SetPtr( GetBuffer().GetPtr() + beginIndex ); 00122 tmpArray.SetSize( size ); 00123 slice.SetBuffer( tmpArray ); 00124 00125 if(configureChunk) 00126 { 00127 slice.SetBeginTime(GetTimeFromIndex(beginIndex)); 00128 slice.SetSampleRate( GetSampleRate() ); 00129 slice.GetBuffer().SetSize(size); 00130 } 00131 CLAM_ASSERT(HasBuffer(),"Audio::GetAudioChunk: Buffer not initialized"); 00132 00133 } 00134 00135 void Audio::GetAudioChunk(TIndex beginIndex,TIndex endIndex,Audio& chunk, bool configureChunk) const 00136 { 00137 00138 /*Note that begin index is allowed to be less than zero and the end index to be beyond the end*/ 00139 CLAM_ASSERT(endIndex>beginIndex, 00140 "Audio::GetAudioChunk: Incorrect index boundaries for audio chunk"); 00141 TSize nBytesToCopy,offset=0; 00142 00143 if(beginIndex>=GetSize()){ 00144 TIndex size=endIndex-beginIndex; 00145 if(configureChunk) chunk.SetSize(size); 00146 //make sure that 0's are set in non written part of audio 00147 memset(chunk.GetBuffer().GetPtr(),0,size*sizeof(TData)); 00148 return; 00149 } 00150 00151 chunk.SetBeginTime(GetTimeFromIndex(beginIndex)); 00152 00153 if(configureChunk) 00154 { 00155 chunk.SetSampleRate( GetSampleRate() ); 00156 TIndex size=endIndex-beginIndex; 00157 chunk.SetSize(size); 00158 chunk.SetSampleRate( GetSampleRate() ); 00159 chunk.SetBeginTime( GetTimeFromIndex(beginIndex) ); 00160 } 00161 00162 00163 CLAM_ASSERT(HasBuffer(),"Audio::GetAudioChunk: Buffer not initialized"); 00164 00165 /*Whenever trying to copy samples before the beginning or after end of 00166 actual audio, zeros will be added at the beginning or end of chunk*/ 00167 00168 if(beginIndex<0) 00169 { 00170 offset=-beginIndex; 00171 beginIndex=0; 00172 //make sure that 0's are set in non written part of audio 00173 memset(chunk.GetBuffer().GetPtr(),0,offset*sizeof(TData)); 00174 } 00175 if(endIndex>=GetSize()) 00176 { 00177 TSize ending=endIndex-GetSize(); 00178 memset(chunk.GetBuffer().GetPtr()+GetSize()-beginIndex ,0,ending*sizeof(TData)); 00179 endIndex=GetSize(); 00180 } 00181 00182 00183 nBytesToCopy=(endIndex-beginIndex)*sizeof(TData); 00184 00185 CLAM_ASSERT( 00186 nBytesToCopy>=0 00187 && beginIndex>=0 00188 && int(nBytesToCopy+beginIndex*sizeof(TData))<=GetBuffer().SizeInBytes(), 00189 "Error"); 00190 00191 memcpy(chunk.GetBuffer().GetPtr()+offset,GetBuffer().GetPtr()+beginIndex,nBytesToCopy); 00192 } 00193 00194 void Audio::SetAudioChunk(TTime beginTime,const Audio& chunk) 00195 { 00196 SetAudioChunk(GetIndexFromTime(beginTime),chunk); 00197 } 00198 00199 void Audio::SetAudioChunk(TIndex beginIndex,const Audio& chunk) 00200 { 00201 CLAM_ASSERT(beginIndex<GetSize(),"Audio::SetAudioChunk: Incorrect begin index"); 00202 TSize nBytesToCopy,offset=0; 00203 TIndex endIndex=beginIndex+chunk.GetSize(); 00204 if(endIndex>GetSize()) endIndex=GetSize(); 00205 if(beginIndex<0){ 00206 offset=-beginIndex; 00207 beginIndex=0;} 00208 00209 CLAM_ASSERT(chunk.HasBuffer()&&HasBuffer(),"Audio::SetAudioChunk: one of the buffers is not initialized") ; 00210 nBytesToCopy=(endIndex-beginIndex)*sizeof(TData); 00211 memcpy(GetBuffer().GetPtr()+beginIndex,chunk.GetBuffer().GetPtr()+offset,nBytesToCopy); 00212 } 00213
1.7.6.1