CLAM-Development
1.1
|
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 void Audio::DefaultInit(void) 00037 { 00038 // Attribute instantiation. 00039 AddSampleRate(); 00040 AddBeginTime(); 00041 AddBuffer(); 00042 UpdateData(); 00043 00044 // Attribute initialization (Default values). 00045 SetSampleRate(44100); 00046 SetBeginTime(0);//By default, audio starts at 0 00047 } 00048 00049 void Audio::SetEndTime(TTime time) 00050 { 00051 CLAM_WARNING(false, "Audio::SetEndTime is about to be deprecated. Please use Audio::ResizeToEndTime instead"); 00052 ResizeToEndTime(time); 00053 } 00054 00055 void Audio::ResizeToEndTime(TTime time) 00056 { 00057 const int newsizeRound = Round((time-GetBeginTime())/1000.0*GetSampleRate()); 00058 SetSize(newsizeRound); 00059 } 00060 00061 void Audio::SetSize(int s) 00062 { 00063 CLAM_ASSERT(HasBuffer(), "Audio::SetSize(int) needs a buffer (HasBuffer()==1)"); 00064 CLAM_ASSERT(s>=0,"Audio::SetSize(): Negative size specified"); 00065 00066 int oldSize=GetSize(); 00067 if (s==oldSize) return; 00068 00069 GetBuffer().Resize(s); 00070 GetBuffer().SetSize(s); 00071 if(s>oldSize) 00072 memset(GetBuffer().GetPtr()+oldSize,0,(s-oldSize)*sizeof(TData)); 00073 } 00074 00075 void Audio::SetDuration(TTime duration) 00076 { 00077 CLAM_WARNING(false, "Audio::SetDuration is about to be deprecated. Please use Audio::ResizeToDuration instead"); 00078 ResizeToDuration(GetIndexFromTime(duration)); 00079 } 00080 00081 void Audio::ResizeToDuration(TTime duration) 00082 { 00083 SetSize(GetIndexFromTime(duration)); 00084 } 00085 00086 TTime Audio::GetTimeFromIndex(TIndex index) const 00087 { 00088 return (TTime)((TTime)index / GetSampleRate()*1000.0 ); 00089 } 00090 00091 TIndex Audio::GetIndexFromTime(TTime time) const 00092 { 00093 return Round(time*((TData)GetSampleRate()/1000.0)); 00094 } 00095 00096 void Audio::GetAudioChunk(TTime beginTime, TTime endTime,Audio& chunk, bool configureChunk) const 00097 { 00098 GetAudioChunk(GetIndexFromTime(beginTime),GetIndexFromTime(endTime),chunk, configureChunk); 00099 } 00100 00101 void Audio::GetAudioSlice(TTime beginTime, TTime endTime,Audio& slice, bool configureSlice) const 00102 { 00103 GetAudioSlice(GetIndexFromTime(beginTime),GetIndexFromTime(endTime),slice, configureSlice); 00104 } 00105 00106 00107 00108 void Audio::GetAudioSlice( TIndex beginIndex, TIndex endIndex, Audio& slice, bool configureChunk ) const 00109 { 00110 CLAM_ASSERT( beginIndex >=0, "Negative indexes are not allowed for audio slices" ); 00111 CLAM_ASSERT( endIndex <= GetSize(), "Slices are not allowed to surpass audio size" ); 00112 00113 00114 TIndex size=endIndex-beginIndex; 00115 00116 DataArray tmpArray; 00117 tmpArray.SetPtr( GetBuffer().GetPtr() + beginIndex ); 00118 tmpArray.SetSize( size ); 00119 slice.SetBuffer( tmpArray ); 00120 00121 if(configureChunk) 00122 { 00123 slice.SetBeginTime(GetTimeFromIndex(beginIndex)); 00124 slice.SetSampleRate( GetSampleRate() ); 00125 slice.GetBuffer().SetSize(size); 00126 } 00127 CLAM_ASSERT(HasBuffer(),"Audio::GetAudioChunk: Buffer not initialized"); 00128 00129 } 00130 00131 void Audio::GetAudioChunk(TIndex beginIndex,TIndex endIndex,Audio& chunk, bool configureChunk) const 00132 { 00133 00134 /*Note that begin index is allowed to be less than zero and the end index to be beyond the end*/ 00135 CLAM_ASSERT(endIndex>beginIndex, 00136 "Audio::GetAudioChunk: Incorrect index boundaries for audio chunk"); 00137 TSize nBytesToCopy,offset=0; 00138 00139 if(beginIndex>=GetSize()){ 00140 TIndex size=endIndex-beginIndex; 00141 if(configureChunk) chunk.SetSize(size); 00142 //make sure that 0's are set in non written part of audio 00143 memset(chunk.GetBuffer().GetPtr(),0,size*sizeof(TData)); 00144 return; 00145 } 00146 00147 chunk.SetBeginTime(GetTimeFromIndex(beginIndex)); 00148 00149 if(configureChunk) 00150 { 00151 chunk.SetSampleRate( GetSampleRate() ); 00152 TIndex size=endIndex-beginIndex; 00153 chunk.SetSize(size); 00154 chunk.SetSampleRate( GetSampleRate() ); 00155 chunk.SetBeginTime( GetTimeFromIndex(beginIndex) ); 00156 } 00157 00158 00159 CLAM_ASSERT(HasBuffer(),"Audio::GetAudioChunk: Buffer not initialized"); 00160 00161 /*Whenever trying to copy samples before the beginning or after end of 00162 actual audio, zeros will be added at the beginning or end of chunk*/ 00163 00164 if(beginIndex<0) 00165 { 00166 offset=-beginIndex; 00167 beginIndex=0; 00168 //make sure that 0's are set in non written part of audio 00169 memset(chunk.GetBuffer().GetPtr(),0,offset*sizeof(TData)); 00170 } 00171 if(endIndex>=GetSize()) 00172 { 00173 TSize ending=endIndex-GetSize(); 00174 memset(chunk.GetBuffer().GetPtr()+GetSize()-beginIndex ,0,ending*sizeof(TData)); 00175 endIndex=GetSize(); 00176 } 00177 00178 00179 nBytesToCopy=(endIndex-beginIndex)*sizeof(TData); 00180 00181 CLAM_ASSERT( 00182 nBytesToCopy>=0 00183 && beginIndex>=0 00184 && int(nBytesToCopy+beginIndex*sizeof(TData))<=GetBuffer().SizeInBytes(), 00185 "Error"); 00186 00187 memcpy(chunk.GetBuffer().GetPtr()+offset,GetBuffer().GetPtr()+beginIndex,nBytesToCopy); 00188 } 00189 00190 void Audio::SetAudioChunk(TTime beginTime,const Audio& chunk) 00191 { 00192 SetAudioChunk(GetIndexFromTime(beginTime),chunk); 00193 } 00194 00195 void Audio::SetAudioChunk(TIndex beginIndex,const Audio& chunk) 00196 { 00197 CLAM_ASSERT(beginIndex<GetSize(),"Audio::SetAudioChunk: Incorrect begin index"); 00198 TSize nBytesToCopy,offset=0; 00199 TIndex endIndex=beginIndex+chunk.GetSize(); 00200 if(endIndex>GetSize()) endIndex=GetSize(); 00201 if(beginIndex<0){ 00202 offset=-beginIndex; 00203 beginIndex=0;} 00204 00205 CLAM_ASSERT(chunk.HasBuffer()&&HasBuffer(),"Audio::SetAudioChunk: one of the buffers is not initialized") ; 00206 nBytesToCopy=(endIndex-beginIndex)*sizeof(TData); 00207 memcpy(GetBuffer().GetPtr()+beginIndex,chunk.GetBuffer().GetPtr()+offset,nBytesToCopy); 00208 } 00209