CLAM-Development  1.4.0
MultiChannelAudioFileWriter.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 
23 #include "AudioCodecs_Stream.hxx"
24 #include "FileSystem.hxx"
25 #include "AudioInPort.hxx"
26 #include "Audio.hxx"
27 #include "XMLStorage.hxx" // TODO: jsut for testing
28 #include "ProcessingFactory.hxx"
29 
30 
31 
32 namespace CLAM
33 {
34 
35 namespace Hidden
36 {
37  static const char * metadata[] = {
38  "key", "MultiChannelAudioFileWriter",
39  "category", "Audio File I/O",
40  "description", "MultiChannelAudioFileWriter",
41  0
42  };
43  static FactoryRegistrator<ProcessingFactory, MultiChannelAudioFileWriter> reg = metadata;
44 }
45 
46 
48  : mNativeStream( NULL )
49  {
51  }
52 
54  : mNativeStream( NULL )
55  {
56  Configure( cfg );
57  }
58 
60  {
61  if ( mNativeStream )
62  delete mNativeStream;
63 
65 
66  if ( mConfig.HasTargetFile() )
67  FileSystem::GetInstance().UnlockFile( mConfig.GetTargetFile() );
68 
69  }
70 
72  {
73  return "MultiChannelAudioFileWriter";
74  }
75 
77  {
78  return true;
79  }
80 
82  {
83  return mConfig;
84  }
85 
86  bool MultiChannelAudioFileWriter::Do( std::vector<Audio>& inputs )
87  {
88  typedef std::vector<Audio> InputVec;
89 
90  if ( !AbleToExecute() )
91  return false;
92 
93  // Checking that all inputs have the same size
94  bool allInputsSameSize = true;
95  TSize inputsSize = 0;
96 
97  inputsSize = inputs[0].GetSize();
98 
99  for ( InputVec::iterator i = inputs.begin();
100  i!= inputs.end() && allInputsSameSize;
101  i++ )
102  {
103  allInputsSameSize = ( inputsSize == (*i).GetSize() );
104  }
105 
106 
107  CLAM_ASSERT( allInputsSameSize, "Input sizes differ!" );
108 
109  // Now, let's build the samples matrix
110 
111  int j = 0;
112 
113  for( InputVec::iterator i = inputs.begin();
114  i != inputs.end(); i++ )
115  mSamplesMatrix[ j++ ] = (*i).GetBuffer().GetPtr();
116 
118  mSamplesMatrix.GetPtr(), inputsSize );
119 
120  return true;
121 
122  }
123 
125  {
126  if ( !AbleToExecute() )
127  return false;
128 
129  // Checking that all inputs have the same size
130  bool allInputsSameSize = true;
131  TSize inputsSize = 0;
132 
133  InputsRefVector inputsRef;
134 
135  for ( VectorOfInputs::iterator i = mInputs.begin();
136  i!= mInputs.end(); i++ )
137  {
138  inputsRef.push_back( &((*i)->GetAudio()) );
139  }
140 
141  inputsSize = inputsRef[0]->GetSize();
142 
143  for ( InputsRefVector::iterator i = inputsRef.begin();
144  i!= inputsRef.end() && allInputsSameSize;
145  i++ )
146  {
147  allInputsSameSize = ( inputsSize == (*i)->GetSize() );
148  }
149 
150 
151  CLAM_ASSERT( allInputsSameSize, "Input sizes differ!" );
152 
153  // Now, let's build the samples matrix
154 
155  int j = 0;
156 
157  for( InputsRefVector::iterator i = inputsRef.begin();
158  i != inputsRef.end(); i++ )
159  mSamplesMatrix[ j++ ] = (*i)->GetBuffer().GetPtr();
160 
162  mSamplesMatrix.GetPtr(), inputsSize );
163 
164  for( VectorOfInputs::iterator i = mInputs.begin();
165  i!=mInputs.end(); i++ )
166  {
167  (*i)->Consume();
168  }
169 
170  return true;
171  }
172 
174  {
175  if ( mConfig.HasTargetFile() )
176  FileSystem::GetInstance().UnlockFile( mConfig.GetTargetFile() );
177 
179 
180  const AudioOutFilename & filename = mConfig.GetTargetFile();
181  if (filename=="")
182  {
183  return AddConfigErrorMessage("No file selected");
184  }
185 
186  unsigned nChannels = mConfig.HasNChannels()? mConfig.GetNChannels() : 1;
187  if ( nChannels < 1 )
188  {
189  return AddConfigErrorMessage("Channels should be, at least, 1.");
190  }
191  AudioFileHeader header;
192  header.SetValues(
193  mConfig.GetSampleRate(),
194  nChannels,
196  mAudioFile.CreateNew(filename, header);
197  if ( !mAudioFile.IsWritable() )
198  {
199  return AddConfigErrorMessage("The format does not support such number of channels, endiannes or sampling rate.");
200  }
201 
202  if ( FileSystem::GetInstance().IsFileLocked( filename ) )
203  {
204  AddConfigErrorMessage("The file '");
205  AddConfigErrorMessage( filename );
206  AddConfigErrorMessage("' has been locked by another Processing");
207 
208  return false;
209  }
210 
211  FileSystem::GetInstance().LockFile( filename );
212 
213 
214  if ( !mInputs.empty() )
216 
217  mChannelsToWrite.Resize( nChannels );
218  mChannelsToWrite.SetSize( nChannels );
219  mSamplesMatrix.Resize( nChannels );
220  mSamplesMatrix.SetSize( nChannels );
221 
222  for ( unsigned i = 0; i < nChannels; i++ )
223  {
224  mChannelsToWrite[ i ] = i;
225  mSamplesMatrix[ i ] = NULL;
226  std::stringstream sstr;
227  sstr << i;
228 
229  mInputs.push_back(
230  new AudioInPort( "Channel #" + sstr.str(), this) );
231  }
232 
234 
235  if ( !mNativeStream )
236  {
237  return AddConfigErrorMessage("Could not acquire an audio file stream!");
238  }
239 
240  return true;
241  }
242 
244  {
245  if (mNativeStream == NULL )
248 
249  return true;
250  }
251 
253  {
255  delete mNativeStream;
257 
258  return true;
259  }
260 
262  {
263  for ( VectorOfInputs::iterator i = mInputs.begin();
264  i != mInputs.end(); i++ )
265  {
266  if ( *i ) delete *i;
267  }
268 
269  mInputs.clear();
270  GetInPorts().Clear();
271  }
272 }
273