|
CLAM-Development
1.3
|
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
1.7.6.1