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                 //We have read all the channels of infiles[inFileIndex]
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                 //We have read all the channels of outfiles[outFileIndex]
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         //Open the files, get the total number of channels and the sample rate
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         // Check that the number of input channels matches the number of ports in the network
00109         CLAM_ASSERT(inputChannelsCount == GetNSources(),
00110                 "The number of input channels is different than the number of sourceports in the provided network.");
00111 
00112         //Open the files and get the total number of channels
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         // Check that the number of output channels matches the of ports in the network
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         // Prepare the sources
00138         //CLAM_ASSERT(_audioSources.size() == infiles.size(),
00139         //              "The number of sources is greater than the intput files.");
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         //Prepare the sinks
00151         //CLAM_ASSERT(_audioSinks.size() == outfiles.size(),
00152         //              "The number of sinks is greater than the output files ");
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                         //We have read the last part (not complete) of the buffer file. Fill the buffer with zeros.
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                         //Save the bufferReader into the sources' buffers.
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                         //Save the sources' buffers into the bufferWriter.
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         //Deleting the sndfiles
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         //TODO close files
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 } //namespace
00285 
Generated by  doxygen 1.6.3