//============================================================================== 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." ); }
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; }