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 "Segment.hxx" 00023 00024 00025 00026 namespace CLAM 00027 { 00028 00030 // 00031 // Segment 00032 // 00034 00035 void Segment::DefaultInit() 00036 { 00037 pParent=NULL; 00038 mCurrentFrameIndex=0; 00039 AddprHoldsData(); 00040 AddBeginTime(); 00041 AddEndTime(); 00042 AddSamplingRate(); 00043 AddChildren();//All segments may have children 00044 UpdateData(); 00045 DefaultValues(); 00046 } 00047 00048 void Segment::DefaultValues() 00049 { 00050 SetBeginTime(0); 00051 SetEndTime(0); 00052 SetSamplingRate(44100); 00053 SetHoldsData( true ); 00054 00055 } 00056 00057 void Segment::CopyInit(const Segment& prototype) 00058 { 00059 pParent=prototype.pParent; 00060 mFramesSearch=prototype.mFramesSearch; 00061 mFramesSearch.Set(GetFramesArray()); 00062 mCurrentFrameIndex=prototype.mCurrentFrameIndex; 00063 } 00064 00065 00066 void Segment::CopyDataFromParent() 00067 { 00068 AddFramesArray(); 00069 AddAudio(); 00070 UpdateData(); 00071 TTime beginTime=GetBeginTime(); 00072 TTime endTime=GetEndTime(); 00073 GetAudio().SetDuration(endTime-beginTime); 00074 GetpParent()->GetAudio().GetAudioChunk(beginTime,endTime,GetAudio()); 00075 00076 /*TODO: right now frames with center after beginning of segment are added so 00077 they may include samples outside of range: is this correct?*/ 00078 TIndex position=0; 00079 if(beginTime>0)//if beginTime=0 it makes no sense searching and Find will return -1 00080 position=GetpParent()->FindFrame(beginTime); 00081 TIndex finalPosition=GetpParent()->FindFrame(endTime); 00082 while(position<=finalPosition) 00083 { 00084 AddFrame(GetpParent()->GetFramesArray()[position]); 00085 position++; 00086 } 00087 } 00088 00089 00090 int Segment::GetnFrames() const 00091 { 00092 // Faster method when available 00093 if(GetHoldsData()) 00094 return GetFramesArray().Size(); 00095 00096 /* TODO: if GetBeginTime()==0 Find in Search Array returns -1!! 00097 but, will it happen the same with the last one*/ 00098 if (GetBeginTime()==0) 00099 return FindFrame(GetEndTime()); 00100 00101 return FindFrame(GetEndTime())-FindFrame(GetBeginTime()); 00102 } 00103 00104 00105 const Frame& Segment::GetFrame(TIndex pos) const 00106 { 00107 CLAM_ASSERT(GetHoldsData()||pParent, 00108 "Segment::GetFrame: No available frames"); 00109 00110 if(GetHoldsData()) 00111 return GetFramesArray()[pos]; 00112 00113 return pParent->GetFrame(pos); 00114 00115 } 00116 00117 Frame& Segment::GetFrame(TIndex pos) 00118 { 00119 CLAM_ASSERT(GetHoldsData()||pParent, 00120 "Segment::GetFrame:No available frames"); 00121 00122 if(GetHoldsData()) 00123 return GetFramesArray()[pos]; 00124 00125 return pParent->GetFrame(pos); 00126 00127 } 00128 00129 void Segment::AddFrame(Frame& newFrame) 00130 { 00131 CLAM_ASSERT(GetHoldsData()||pParent, 00132 "Segment::AddFrame: No available frame array attribute"); 00133 00134 if(GetHoldsData()) 00135 GetFramesArray().AddElem(newFrame); 00136 else 00137 pParent->GetFramesArray().AddElem(newFrame); 00138 00139 SetEndTime(newFrame.GetCenterTime()); 00140 00141 } 00142 00143 void Segment::DeleteFrame(TIndex pos) 00144 { 00145 CLAM_ASSERT(pos<=GetnFrames(),"Segment::DeleteFrame: Index out of bounds"); 00146 CLAM_ASSERT(GetHoldsData()||pParent, 00147 "Segment::DeleteFrame: No available frame array attribute"); 00148 00149 if(GetHoldsData()) 00150 GetFramesArray().DeleteElem(pos); 00151 else 00152 pParent->GetFramesArray().DeleteElem(pos); 00153 00154 if (GetnFrames()==0) 00155 { 00156 SetEndTime(0); 00157 SetBeginTime(0); 00158 } 00159 00160 else 00161 { 00162 if(pos==GetnFrames())//it was the last frame 00163 SetEndTime(GetFrame(GetnFrames()-1).GetCenterTime()); 00164 00165 if(pos==0)//it was first frame 00166 SetBeginTime(GetFrame(0).GetCenterTime()); 00167 } 00168 } 00169 00170 TIndex Segment::FindFrame(TTime time) const 00171 { 00172 CLAM_ASSERT(GetHoldsData()||pParent, 00173 "Segment::FindFrame:No available frame array attribute"); 00174 00175 if(!GetHoldsData()) 00176 return pParent->FindFrame(time); 00177 Frame tmpFrame; 00178 tmpFrame.SetCenterTime(time); 00179 if (GetnFrames()<1) return -1; 00180 return GetFramesSearch().Find(tmpFrame); 00181 00182 } 00183 00184 Frame& Segment::GetFrame(TTime time) 00185 { 00186 return GetFrame(FindFrame(time)); 00187 } 00188 00189 const Frame& Segment::GetFrame(TTime time) const 00190 { 00191 return GetFrame(FindFrame(time)); 00192 } 00193 00194 void Segment::DeleteFrame(TTime time) 00195 { 00196 DeleteFrame(FindFrame(time)); 00197 } 00198 00199 void Segment::SetHoldsData(bool holdsData) 00200 { 00201 SetprHoldsData(holdsData); 00202 if(holdsData) 00203 { 00204 //Adding necessary attributes 00205 AddFramesArray(); 00206 AddAudio(); 00207 UpdateData(); 00208 00209 //Initializing some atributes 00210 GetFramesSearch().Set(GetFramesArray()); 00211 if(pParent!=NULL) 00212 { 00213 CopyDataFromParent(); 00214 pParent=NULL; 00215 } 00216 } 00217 else 00218 { 00219 RemoveFramesArray(); 00220 RemoveAudio(); 00221 UpdateData(); 00222 } 00223 } 00224 00225 } // namespace CLAM 00226