//==============================================================================
void AudioFileConverter::run()
{
	
	while ( getQueueSize() > 0 )
	{	
		{   // lock jobQueue before retrieving a task
			const ScopedLock lock (queueLock);
			task  = jobQueue[0];
		}

		/* try opening the file */
		File	inputDataFile( task->getFileName() );
		String  inputFileName( inputDataFile.getFullPathName() );

		if ( !inputDataFile.existsAsFile() || (inputDataFile.getSize() == 0) )
		{
			dbgOut(L"** AudioFileConverter ** Invalid or corrupted temporary file:\t" + inputFileName);
			removeFromQueue();
			continue;
		}
	
		/* try creating the input stream */
		FileInputStream*	fileInputStream	=	inputDataFile.createInputStream();
		if (fileInputStream == NULL)
		{
			dbgOut(L"** AudioFileConverter ** Unable to create input stream for file:\t" + inputFileName);
			removeFromQueue();
			continue;
		}
		
		dbgOut(L"");
		dbgOut(L" ***  AudioFileConverter ***");
		dbgOut(L"** AudioFileConverter ** Converting file:\t" + inputFileName 
               + L" (" + String( inputDataFile.getSize() ) + L" b)");

		int		processorOutputs = task->getChannelNumber();
		const int bytesPerSample = processorOutputs * sizeof(float);
		int		bufferSize		= task->getBufferSize();
		double	samplingRate	= task->getSamplingRate();
		int		bitDepth		= task->getBitDepth();
		String	audioFormatName = task->getFormat();

		AudioSampleBuffer tempBuffer(1, bufferSize);

		// declare classes needed to save the format
		OwnedArray<AudioFormat>			someAudioFormats;
		OwnedArray<AudioFormatWriter>	audioFormatWriters;
		OwnedArray<File>				audioFiles;
		Array<FileOutputStream*>		outStreams;
		String							audioFileName;

		AudioFormatWriter*	tmpWriter;
		FileOutputStream*	tmpStream;
		File*				tmpAudioFile;

		String outputDir = inputDataFile.getParentDirectory().getFullPathName();
	
		for (int i=0; i < processorOutputs ; i++)
		{
			// Delete temporary files
			File tmpDataFile(outputDir + File::separatorString + L"channel" + String::formatted("%.2d", i ) + ".dat");

			if ( tmpDataFile != File::nonexistent)
			{
				dbgOut( L"** AudioFileConverter ** \tDeleting temporary file:\t" + tmpDataFile.getFullPathName() );
				tmpDataFile.deleteFile();
			}
			else
			{
				dbgOut( "** AudioFileConverter ** Unable to delete temporary file:\t\t" + tmpDataFile.getFullPathName() );
			}

		
			// Define the format (wav is default)
			if (audioFormatName == "wav")
				someAudioFormats.add( new WavAudioFormat() );			
		
			else if (audioFormatName == "aiff")
				someAudioFormats.add( new AiffAudioFormat() );
		
			else if (audioFormatName == "flac")
				someAudioFormats.add( new FlacAudioFormat() );

//			else if (audioFormatName == "ogg")
//				someAudioFormats.add( new OggVorbisAudioFormat() );

			else
				someAudioFormats.add( new WavAudioFormat() );	
		
			audioFileName = outputDir + File::separatorString + "channel" + String::formatted("%.2d",i) + someAudioFormats[i]->getFileExtensions()[0];
		
			tmpAudioFile = new File (audioFileName);
			if (*tmpAudioFile == File::nonexistent)
			{
				dbgOut( L"** AudioFileConverter ** Unable to create file:\t" + audioFileName );
				audioFormatWriters.clear(true);
				someAudioFormats.clear(true);
				audioFiles.clear(true);
				outStreams.clear();

				delete fileInputStream;
				
				removeFromQueue();

				continue;
			}
		
			audioFiles.add( tmpAudioFile );

			// Delete existing files
			if (audioFiles[i]->existsAsFile())
			{
				dbgOut( "** AudioFileConverter ** \tDeleting existing audio file:\t\t" + audioFileName );			
				if	(!audioFiles[i]->deleteFile())
				{
					dbgOut( L"** AudioFileConverter ** Unable to delete existing file:\t" + audioFileName );
					audioFormatWriters.clear(true);
					someAudioFormats.clear(true);
					audioFiles.clear(true);
					outStreams.clear();
					delete fileInputStream;

					removeFromQueue();

					continue;
				}
			}

			dbgOut( "** AudioFileConverter ** \tSaving audio file:\t\t" + audioFileName );

			/* Create output stream for this file */
			tmpStream = audioFiles[i]->createOutputStream();
			if (tmpStream == NULL)
				{
					dbgOut( L"** AudioFileConverter ** Unable to create output stream for file:\t" + audioFileName );
					delete tmpAudioFile;
					audioFormatWriters.clear(true);
					someAudioFormats.clear(true);
					audioFiles.clear(true);
					outStreams.clear();
					delete fileInputStream;

					removeFromQueue();

					continue;
				}

			outStreams.add( tmpStream );
		

			/* Create Audio Format Writer */
			tmpWriter = someAudioFormats[i]->createWriterFor(	outStreams[i],		// streamToWriteTo,
																			samplingRate,		// sampleRateToUse,  
																			1,					// numberOfChannels,  
																			someAudioFormats[i]->getPossibleBitDepths().getLast(),	// bitsPerSample - Get the maximum possible bit depth for this format
																			NULL,				//  metadataValues,  
																			0 );


			if (tmpWriter == NULL)
			{
					dbgOut( L"** AudioFileConverter ** Unable to create audio format writer for:\t" + audioFileName );
					delete tmpAudioFile;
					audioFormatWriters.clear(true);
					someAudioFormats.clear(true);
					audioFiles.clear(true);
					outStreams.clear();
					delete fileInputStream;

					removeFromQueue();
		
					continue;
			}
			audioFormatWriters.add( tmpWriter );
		}

		// Write data to wav file
		int dataBlockSize = processorOutputs * bufferSize * bitDepth/8 ;
		MemoryBlock*	buffer = new MemoryBlock( dataBlockSize, true);
	
		int64 bytesSaved = inputDataFile.getSize();

		while ( !fileInputStream->isExhausted() && (fileInputStream->getPosition() <  bytesSaved) )
		{
			float* x = (float *) buffer->getData() ;

			int bytesRead = fileInputStream->read( (void *)x, dataBlockSize );
			int numSamples = (int)( bytesRead / bytesPerSample );

			for (int ch=0; ch < processorOutputs; ch++)
			{
//				const int numBytes = (int) (bytesRead/processorOutputs);

				tempBuffer.copyFrom(	0,					//  const int   	 destChannel,
										0,					//	const int  	destStartSample,
										x+ch*numSamples,	//	const float *  	source,
										numSamples			//	int  	numSamples	 
									);

				audioFormatWriters[ch]->write(	(const int**)(tempBuffer.getArrayOfChannels()),	//AudioFormatWriter *  writer,  
												numSamples				//const int  numSamples   
											  );
			}
		}

		// clean up
		delete	buffer;

		//	this should delete 'owned' objects 
		audioFormatWriters.clear(true);
		someAudioFormats.clear(true);
		audioFiles.clear(true);
		// clear the outStreams without deleting objects (already deleted)
		outStreams.clear();
	
		// Delete and close the stream
		delete fileInputStream;	

		// Delete the data.dat file
		dbgOut( L"** AudioFileConverter ** \tDeleting temporary file:\t" + inputFileName );
		inputDataFile.deleteFile();

		// Delete the task
		removeFromQueue();		
		
		dbgOut( "** AudioFileConverter ** Files saved." );

	}

	dbgOut( "** AudioFileConverter ** Thread terminates." );

}
Esempio n. 2
0
int main ( int argc, char *argv[] )
{
    cmdline::parser cmdOpt;
    specifyCommandLineParameters(cmdOpt);
    if (!cmdOpt.parse(argc, argv)) {
        std::cout << cmdOpt.error()<< std::endl << cmdOpt.usage() << std::endl;
        return EXIT_FAILURE;
    }

    // reading command line
    std::string parametersFile(cmdOpt.get<std::string>(CFG));
    std::string inputDataFile(cmdOpt.get<std::string>(IN));

    // Setup logger
    cpplog::OstreamLogger *log;
    if (cmdOpt.exist(LOGF))
    {
        log = new cpplog::FileLogger(cmdOpt.get<std::string>(LOGF)+".log", true);
    }
    else
    {
        log = new cpplog::StdErrLogger();
    }

    // load lmclus parameters from parameters file
    CSimpleIniA ini(false, false, false);
    SI_Error rc = ini.LoadFile(parametersFile.c_str());
    if (rc < 0) {
        LOG_ERROR(log) << "Problem reading parameters file: " << parametersFile;
        return EXIT_FAILURE;
    }

    // Set parameters from ini-file
    clustering::lmclus::Parameters params;
    params.MAX_DIM = static_cast<int>(ini.GetLongValue(SECTION, "MAX_DIM", 2));
    params.NUM_OF_CLUS = static_cast<int>(ini.GetLongValue(SECTION, "NUM_OF_CLUS", 2));
    params.LABEL_COL = static_cast<int>(ini.GetLongValue(SECTION, "LABEL_COL", 0));
    params.CONST_SIZE_HIS = static_cast<int>(ini.GetLongValue(SECTION, "CONST_SIZE_HIS", 0));
    params.NOISE_SIZE = static_cast<unsigned int>(ini.GetLongValue(SECTION, "NOISE_SIZE", 2));
    params.BEST_BOUND = ini.GetDoubleValue(SECTION, "BEST_BOUND", 1.0);
    params.ERROR_BOUND = ini.GetDoubleValue(SECTION, "ERROR_BOUND", 0.0001);
    params.MAX_BIN_PORTION = ini.GetDoubleValue(SECTION, "MAX_BIN_PORTION", 0.1);

    params.RANDOM_SEED = static_cast<unsigned int>(ini.GetLongValue(SECTION, "RANDOM_SEED", 0));
    params.SAMPLING_HEURISTIC = static_cast<int>(ini.GetLongValue(SECTION, "SAMPLING_HEURISTIC", 3));
    params.SAMPLING_FACTOR = ini.GetDoubleValue(SECTION, "SAMPLING_FACTOR", 0.003);
    params.HIS_SAMPLING = ini.GetBoolValue(SECTION, "HIS_SAMPLING", false);
    params.SAVE_RESULT = ini.GetBoolValue(SECTION, "SAVE_RESULT", false);

    // Load dataset
    arma::mat data;
    arma::vec original_labels;
    data.load(inputDataFile, arma::csv_ascii);
    //data = arma::randu<arma::mat>(100,11);
    if (params.LABEL_COL > 0 && params.LABEL_COL <= data.n_cols) {
        LOG_INFO(log) << "Labels in column " << params.LABEL_COL << " will be removed";
        original_labels = data.col(params.LABEL_COL-1);
        data.shed_col(params.LABEL_COL-1);
    }

    LOG_INFO(log) << "Parameters file: " << parametersFile;
    LOG_INFO(log) << "Parameters: \n" << params;
    LOG_INFO(log) << "Input: " << inputDataFile;
    LOG_INFO(log) << "Input rows: " << data.n_rows;
    LOG_INFO(log) << "Input cols: " << data.n_cols;
    //LOG_INFO(log) << "Data: \n" << data;

    //TEST(log, data.n_cols == 11, "Invalid column number")
    //TEST(log, data.n_rows == 3000, "Invalid row number")
    //TEST(log, data.n_cols == 10, "Invalid column number")

    TEST(log, params.MAX_DIM < static_cast<int>(data.n_cols),
         "Linear manifold dimension must be less than the dimension of the data !!!")

    // Process data
    clustering::lmclus::LMCLUS lmclus(log);
    std::vector<arma::uvec> labels;
    std::vector<double> thresholds;
    std::vector<arma::mat> basises;
    std::vector<int> clusterDims;
    lmclus.cluster(data, params, labels, thresholds, basises, clusterDims, progress);

    // Process results
    size_t clusterNum = labels.size();
    TEST(log, clusterDims.size() == clusterNum, "Invalid number of clusters")
    for(size_t i=0; i < clusterNum; ++i)
    {
        LOG_INFO(log) << "Cluster " << i << " dimension: " << clusterDims[i] << ", size: " << labels[i].n_elem <<"\n";
        //LOG_INFO(log) << "Labels: " << labels[i].t();
        LOG_INFO(log) << "Basis: \n"<< basises[i];
    }

    LOG_INFO(log) << "labels found: " << labels.size();
    LOG_INFO(log) << "thresholds found: " << thresholds.size();
    LOG_INFO(log) << "basises found: " << basises.size();
    LOG_INFO(log) << "clusterDims found: " << clusterDims.size();

    // Clear log
    delete log;

    return EXIT_SUCCESS;
}