CLAM-Development  1.4.0
Audio.cxx
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG)
3  * UNIVERSITAT POMPEU FABRA
4  *
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  */
21 
22 #include "Audio.hxx"
23 #include "CLAM_Math.hxx"
24 #include "ProcessingDataPlugin.hxx"
25 
26 using namespace CLAM;
27 
28 namespace CLAM
29 {
30  namespace Hidden
31  {
32  static ProcessingDataPlugin::Registrator<CLAM::Audio> dataRegistratorAudio("lightcyan","CLAM::Audio (Buffer)");
33  }
34 }
35 
37 {
38 }
39 
41 {
42  // Attribute instantiation.
43  AddSampleRate();
44  AddBeginTime();
45  AddBuffer();
46  UpdateData();
47 
48  // Attribute initialization (Default values).
49  SetSampleRate(44100);
50  SetBeginTime(0);//By default, audio starts at 0
51 }
52 
54 {
55  CLAM_WARNING(false, "Audio::SetEndTime is about to be deprecated. Please use Audio::ResizeToEndTime instead");
56  ResizeToEndTime(time);
57 }
58 
60 {
61  const int newsizeRound = Round((time-GetBeginTime())/1000.0*GetSampleRate());
62  SetSize(newsizeRound);
63 }
64 
65 void Audio::SetSize(int newSize)
66 {
67  CLAM_ASSERT(HasBuffer(), "Audio::SetSize(int) needs a buffer (HasBuffer()==1)");
68  CLAM_ASSERT(newSize>=0,"Audio::SetSize(): Negative size specified");
69  int oldSize=GetSize();
70  if (newSize==oldSize) return;
71  int physicalSize = GetBuffer().AllocatedSize();
72  if (newSize>physicalSize)
73  GetBuffer().Resize(newSize);
74  GetBuffer().SetSize(newSize);
75  if(newSize<=oldSize) return;
76  memset(GetBuffer().GetPtr()+oldSize,0,(newSize-oldSize)*sizeof(TData));
77 }
78 
79 void Audio::SetDuration(TTime duration)
80 {
81  CLAM_WARNING(false, "Audio::SetDuration is about to be deprecated. Please use Audio::ResizeToDuration instead");
82  ResizeToDuration(GetIndexFromTime(duration));
83 }
84 
86 {
87  SetSize(GetIndexFromTime(duration));
88 }
89 
90 TTime Audio::GetTimeFromIndex(TIndex index) const
91 {
92  return (TTime)((TTime)index / GetSampleRate()*1000.0 );
93 }
94 
95 TIndex Audio::GetIndexFromTime(TTime time) const
96 {
97  return Round(time*((TData)GetSampleRate()/1000.0));
98 }
99 
100 void Audio::GetAudioChunk(TTime beginTime, TTime endTime,Audio& chunk, bool configureChunk) const
101 {
102  GetAudioChunk(GetIndexFromTime(beginTime),GetIndexFromTime(endTime),chunk, configureChunk);
103 }
104 
105 void Audio::GetAudioSlice(TTime beginTime, TTime endTime,Audio& slice, bool configureSlice) const
106 {
107  GetAudioSlice(GetIndexFromTime(beginTime),GetIndexFromTime(endTime),slice, configureSlice);
108 }
109 
110 
111 
112 void Audio::GetAudioSlice( TIndex beginIndex, TIndex endIndex, Audio& slice, bool configureChunk ) const
113 {
114  CLAM_ASSERT( beginIndex >=0, "Negative indexes are not allowed for audio slices" );
115  CLAM_ASSERT( endIndex <= GetSize(), "Slices are not allowed to surpass audio size" );
116 
117 
118  TIndex size=endIndex-beginIndex;
119 
120  DataArray tmpArray;
121  tmpArray.SetPtr( GetBuffer().GetPtr() + beginIndex );
122  tmpArray.SetSize( size );
123  slice.SetBuffer( tmpArray );
124 
125  if(configureChunk)
126  {
127  slice.SetBeginTime(GetTimeFromIndex(beginIndex));
128  slice.SetSampleRate( GetSampleRate() );
129  slice.GetBuffer().SetSize(size);
130  }
131  CLAM_ASSERT(HasBuffer(),"Audio::GetAudioChunk: Buffer not initialized");
132 
133 }
134 
135 void Audio::GetAudioChunk(TIndex beginIndex,TIndex endIndex,Audio& chunk, bool configureChunk) const
136 {
137 
138  /*Note that begin index is allowed to be less than zero and the end index to be beyond the end*/
139  CLAM_ASSERT(endIndex>beginIndex,
140  "Audio::GetAudioChunk: Incorrect index boundaries for audio chunk");
141  TSize nBytesToCopy,offset=0;
142 
143  if(beginIndex>=GetSize()){
144  TIndex size=endIndex-beginIndex;
145  if(configureChunk) chunk.SetSize(size);
146  //make sure that 0's are set in non written part of audio
147  memset(chunk.GetBuffer().GetPtr(),0,size*sizeof(TData));
148  return;
149  }
150 
151  chunk.SetBeginTime(GetTimeFromIndex(beginIndex));
152 
153  if(configureChunk)
154  {
155  chunk.SetSampleRate( GetSampleRate() );
156  TIndex size=endIndex-beginIndex;
157  chunk.SetSize(size);
158  chunk.SetSampleRate( GetSampleRate() );
159  chunk.SetBeginTime( GetTimeFromIndex(beginIndex) );
160  }
161 
162 
163  CLAM_ASSERT(HasBuffer(),"Audio::GetAudioChunk: Buffer not initialized");
164 
165  /*Whenever trying to copy samples before the beginning or after end of
166  actual audio, zeros will be added at the beginning or end of chunk*/
167 
168  if(beginIndex<0)
169  {
170  offset=-beginIndex;
171  beginIndex=0;
172  //make sure that 0's are set in non written part of audio
173  memset(chunk.GetBuffer().GetPtr(),0,offset*sizeof(TData));
174  }
175  if(endIndex>=GetSize())
176  {
177  TSize ending=endIndex-GetSize();
178  memset(chunk.GetBuffer().GetPtr()+GetSize()-beginIndex ,0,ending*sizeof(TData));
179  endIndex=GetSize();
180  }
181 
182 
183  nBytesToCopy=(endIndex-beginIndex)*sizeof(TData);
184 
185  CLAM_ASSERT(
186  nBytesToCopy>=0
187  && beginIndex>=0
188  && int(nBytesToCopy+beginIndex*sizeof(TData))<=GetBuffer().SizeInBytes(),
189  "Error");
190 
191  memcpy(chunk.GetBuffer().GetPtr()+offset,GetBuffer().GetPtr()+beginIndex,nBytesToCopy);
192 }
193 
194 void Audio::SetAudioChunk(TTime beginTime,const Audio& chunk)
195 {
196  SetAudioChunk(GetIndexFromTime(beginTime),chunk);
197 }
198 
199 void Audio::SetAudioChunk(TIndex beginIndex,const Audio& chunk)
200 {
201  CLAM_ASSERT(beginIndex<GetSize(),"Audio::SetAudioChunk: Incorrect begin index");
202  TSize nBytesToCopy,offset=0;
203  TIndex endIndex=beginIndex+chunk.GetSize();
204  if(endIndex>GetSize()) endIndex=GetSize();
205  if(beginIndex<0){
206  offset=-beginIndex;
207  beginIndex=0;}
208 
209  CLAM_ASSERT(chunk.HasBuffer()&&HasBuffer(),"Audio::SetAudioChunk: one of the buffers is not initialized") ;
210  nBytesToCopy=(endIndex-beginIndex)*sizeof(TData);
211  memcpy(GetBuffer().GetPtr()+beginIndex,chunk.GetBuffer().GetPtr()+offset,nBytesToCopy);
212 }
213