OfflineNetworkPlayer.cxx
Go to the documentation of this file.00001
00002 #include "OfflineNetworkPlayer.hxx"
00003 #include "MonoAudioFileReader.hxx"
00004 #include "MonoAudioFileWriter.hxx"
00005 #include "AudioSink.hxx"
00006 #include "AudioSource.hxx"
00007
00008 #include <iostream>
00009 #include <sstream>
00010
00011 namespace CLAM
00012 {
00013
00014 bool OfflineNetworkPlayer::IsWorking()
00015 {
00016 CacheSourcesAndSinks();
00017 return (_inFileNames.size() != GetNSources())
00018 && (_outFileNames.size() != GetNSinks());
00019 }
00020
00021 std::string OfflineNetworkPlayer::NonWorkingReason()
00022 {
00023 std::stringstream ss;
00024 ss << GetNSources() << " inputs and "
00025 << GetNSinks() << " outputs needed but just "
00026 << _inFileNames.size() << " input files provided"
00027 << _outFileNames.size() << " output files provided"
00028 << std::ends;
00029 return ss.str();
00030 }
00031
00032 std::string OfflineNetworkPlayer::listOfSourcesSinksAndFiles(const SndFileHandles & infiles, const SndFileHandles & outfiles)
00033 {
00034 std::ostringstream result;
00035
00036 unsigned inFileIndex = 0;
00037 unsigned inChannel = 0;
00038 for (unsigned i=0; i<GetNSources(); i++)
00039 {
00040 ++inChannel;
00041 result << " * source:\t" << SourceName(i) << "\t";
00042 result << "In:\t" << _inFileNames[inFileIndex] << "\tchannel " << inChannel << "\n";
00043
00044
00045 if((unsigned)infiles[inFileIndex]->channels() == inChannel)
00046 {
00047 inFileIndex++;
00048 inChannel = 0;
00049 }
00050 }
00051
00052 unsigned outFileIndex = 0;
00053 unsigned outChannel = 0;
00054 for (unsigned i=0; i<GetNSinks(); i++)
00055 {
00056 outChannel++;
00057 result << " * sink:\t" << SinkName(i) << "\t";
00058 result << "Out:\t" << _outFileNames[outFileIndex] << "\tchannel " << outChannel << "\n";
00059
00060
00061 if((unsigned)outfiles[outFileIndex]->channels() == outChannel)
00062 {
00063 outFileIndex++;
00064 outChannel = 0;
00065 }
00066 }
00067
00068 return result.str();
00069 }
00070
00071 void OfflineNetworkPlayer::Start()
00072 {
00073 if ( IsPlaying() )
00074 return;
00075
00076 BePlaying();
00077
00078 CacheSourcesAndSinks();
00079
00080 const int frameSize = 512;
00081
00082
00083 int sampleRate = 0;
00084 unsigned inputChannelsCount = 0;
00085 SndFileHandles infiles;
00086
00087 for(unsigned fileIndex = 0; fileIndex < _inFileNames.size(); fileIndex++)
00088 {
00089 CLAM_ASSERT(fileIndex < _inFileNames.size(),
00090 "Not all the network inputs could be fullfiled. Have you checked the IsWorking() method?");
00091 std::ifstream checkfile(_inFileNames[fileIndex].c_str());
00092
00093 CLAM_ASSERT(checkfile.is_open(),std::string("Could not open one of the input files: "+_inFileNames[fileIndex]).c_str());
00094 SndfileHandle* infile = new SndfileHandle(_inFileNames[fileIndex].c_str(), SFM_READ );
00095
00096 CLAM_ASSERT(*infile, "Can not create the infile ");
00097 inputChannelsCount += infile->channels();
00098
00099 if(fileIndex == 0)
00100 sampleRate = infile->samplerate();
00101
00102 CLAM_ASSERT(infile->samplerate() == sampleRate,
00103 "All the input audio files have to have the same sample rate");
00104
00105 infiles.push_back(infile);
00106 }
00107
00108
00109 CLAM_ASSERT(inputChannelsCount == GetNSources(),
00110 "The number of input channels is different than the number of sourceports in the provided network.");
00111
00112
00113 unsigned outputChannelsCount=0;
00114 SndFileHandles outfiles;
00115 for(unsigned fileIndex=0;fileIndex<_outFileNames.size();fileIndex++)
00116 {
00117 if (fileIndex>=_outFileNames.size())
00118 {
00119 std::cerr << "Not all the network outputs could be fullfiled.";
00120 break;
00121 }
00122
00123 SndfileHandle* outfile = new SndfileHandle(_outFileNames[fileIndex].c_str(), SFM_WRITE,
00124 _format,_outChannelsFiles[fileIndex],sampleRate);
00125 CLAM_ASSERT(*outfile, "Can not create the outfile ");
00126 outputChannelsCount +=_outChannelsFiles[fileIndex];
00127 outfiles.push_back(outfile);
00128 }
00129
00130
00131 CLAM_ASSERT(outputChannelsCount == GetNSinks(),
00132 "The number of output channels is different than the number of sinkports in the provided network.");
00133
00134 std::cout << "Sources and Sinks list:" <<std::endl;
00135 std::cout << listOfSourcesSinksAndFiles(infiles,outfiles)<<std::endl;
00136
00137
00138
00139
00140
00141 std::vector<DataArray> inbuffers(inputChannelsCount);
00142 for(unsigned i = 0; i < GetNSources(); ++i)
00143 {
00144 inbuffers[i].Resize( frameSize );
00145 inbuffers[i].SetSize( frameSize );
00146 const TData * data = &inbuffers[i][0];
00147 SetSourceBuffer(i, data, frameSize);
00148 }
00149
00150
00151
00152
00153
00154 std::vector<DataArray> outbuffers(outputChannelsCount);
00155 for( unsigned i = 0; i < GetNSinks(); ++i)
00156 {
00157 outbuffers[i].Resize( frameSize );
00158 outbuffers[i].SetSize( frameSize );
00159
00160 TData * data = &outbuffers[i][0];
00161 SetSinkBuffer(i, data, frameSize);
00162 }
00163
00164
00165 long iterationIndex = 0;
00166 bool timeLimitedMode = _resultWavsTime > 0.001;
00167 int fileIndex = 0;
00168 while(true)
00169 {
00170 std::cout << "." << std::flush;
00171 unsigned inAudioIndex =0;
00172 bool someInputFinished=false;
00173 for(SndFileHandles::iterator it = infiles.begin(); it != infiles.end(); ++it)
00174 {
00175 SndfileHandle * sndfileHandle = (*it);
00176 unsigned int nChannels = sndfileHandle->channels();
00177 CLAM_ASSERT(nChannels, "The audio had no channels");
00178 int bufferReaderSize = nChannels*frameSize;
00179 float * bufferReader = new float[bufferReaderSize];
00180 int readSize = sndfileHandle->read(bufferReader,bufferReaderSize);
00181
00182
00183 if(readSize<bufferReaderSize)
00184 {
00185 for(int i = readSize; i < bufferReaderSize; i++)
00186 {
00187 bufferReader[i] = 0;
00188 }
00189 if(_enableLoopInputWavs)
00190 sndfileHandle->seek(0,SEEK_SET);
00191 someInputFinished = true;
00192 }
00193
00194 for(int frameIndex=0; frameIndex <frameSize; frameIndex ++)
00195 {
00196 for(unsigned channel=0; channel < nChannels; channel++)
00197 {
00198 inbuffers[inAudioIndex+channel][frameIndex] = bufferReader[(frameIndex*nChannels)+channel];
00199 }
00200 }
00201 inAudioIndex += nChannels;
00202 fileIndex ++;
00203 delete[] bufferReader;
00204 }
00205
00206 GetNetwork().Do();
00207
00208 unsigned outAudioIndex = 0;
00209 for(SndFileHandles::iterator it = outfiles.begin(); it != outfiles.end(); ++it)
00210 {
00211 SndfileHandle * sndfileHandle = (*it);
00212 unsigned int nChannels = sndfileHandle->channels();
00213 int bufferWriterSize = nChannels*frameSize;
00214 float* bufferWriter = new float[bufferWriterSize];
00215
00216
00217 for(int frameIndex = 0; frameIndex < frameSize; frameIndex ++)
00218 {
00219 for(unsigned channel = 0; channel < nChannels; channel++)
00220 {
00221 bufferWriter[(frameIndex*nChannels) + channel] =
00222 outbuffers[outAudioIndex + channel][frameIndex];
00223 }
00224 }
00225 int writeSize = sndfileHandle->write(bufferWriter, bufferWriterSize);
00226 CLAM_ASSERT(writeSize == bufferWriterSize,"The outfile has not been written correctly");
00227 outAudioIndex += nChannels;
00228 delete[] bufferWriter;
00229 }
00230
00231 if (timeLimitedMode and float(iterationIndex * frameSize) / sampleRate > _resultWavsTime)
00232 {
00233 std::cout << "REACHED MAX TIME - finalizing"<< std::endl;
00234 break;
00235 }
00236 iterationIndex++;
00237
00238 if (someInputFinished and not _enableLoopInputWavs )
00239 break;
00240 }
00241
00242
00243 for(SndFileHandles::iterator it = infiles.begin(); it != infiles.end(); ++it)
00244 delete *it;
00245
00246 for(SndFileHandles::iterator it = outfiles.begin(); it != outfiles.end(); ++it)
00247 delete *it;
00248 }
00249
00250 void OfflineNetworkPlayer::Stop()
00251 {
00252 if ( IsStopped() )
00253 return;
00254 BeStopped();
00255
00256
00257 }
00258
00259 void OfflineNetworkPlayer::ProcessInputFile()
00260 {
00261 GetNetwork().Do();
00262 }
00263
00264 void OfflineNetworkPlayer::AddInputFile( const std::string& filename )
00265 {
00266 _inFileNames.push_back(filename);
00267 }
00268
00269 void OfflineNetworkPlayer::AddOutputFile( const std::string& filename )
00270 {
00271 _outFileNames.push_back(filename);
00272 }
00273
00274 void OfflineNetworkPlayer::AddNumChannels(int channel)
00275 {
00276 _outChannelsFiles.push_back(channel);
00277 }
00278
00279 void OfflineNetworkPlayer::SetFormat(int format)
00280 {
00281 _format = format;
00282 }
00283
00284 }
00285