std::vector<int16_t> AudioFile::getSampleData() const { if(mSampleAmount == 0) return std::vector<int16_t>(); std::vector<int16_t> sampleData(mSampleAmount); ov_raw_seek(mFile, 0); int64_t read = 0; int64_t totalRead = 0; int bitstream = 0; while((read = ov_read(mFile, ((char*)sampleData.data()) + totalRead, (mSampleAmount * 2) - (int32_t)totalRead, 0, 2, 1, &bitstream))) { if(read < 0) { break; } totalRead += read; } sampleData.resize((size_t)totalRead / 2); return sampleData; }
/// Write the summary to disk, using the derived ReadData() to get the data void ODPCMAliasBlockFile::WriteSummary() { // To build the summary data, call ReadData (implemented by the // derived classes) to get the sample data // Call this first, so that in case of exceptions from ReadData, there is // no NEW output file SampleBuffer sampleData(mLen, floatSample); this->ReadData(sampleData.ptr(), floatSample, 0, mLen, true); ArrayOf< char > fileNameChar; FILE *summaryFile{}; { //the mFileName path may change, for example, when the project is saved. //(it moves from /tmp/ to wherever it is saved to. ODLocker locker { &mFileNameMutex }; //wxFFile is not thread-safe - if any error occurs in opening the file, // it posts a wxlog message which WILL crash // Audacity because it goes into the wx GUI. // For this reason I left the wxFFile method commented out. (mchinen) // wxFFile summaryFile(mFileName.GetFullPath(), wxT("wb")); // ...and we use fopen instead. wxString sFullPath = mFileName.GetFullPath(); fileNameChar.reinit( strlen(sFullPath.mb_str(wxConvFile)) + 1 ); strcpy(fileNameChar.get(), sFullPath.mb_str(wxConvFile)); summaryFile = fopen(fileNameChar.get(), "wb"); } // JKC ANSWER-ME: Whay is IsOpened() commented out? if (!summaryFile){//.IsOpened() ){ // Never silence the Log w.r.t write errors; they always count //however, this is going to be called from a non-main thread, //and wxLog calls are not thread safe. wxPrintf("Unable to write summary data to file: %s", fileNameChar.get()); throw FileException{ FileException::Cause::Read, wxFileName{ fileNameChar.get() } }; } ArrayOf<char> cleanup; void *summaryData = CalcSummary(sampleData.ptr(), mLen, floatSample, cleanup); //summaryFile.Write(summaryData, mSummaryInfo.totalSummaryBytes); fwrite(summaryData, 1, mSummaryInfo.totalSummaryBytes, summaryFile); fclose(summaryFile); // wxPrintf("write successful. filename: %s\n", fileNameChar); mSummaryAvailableMutex.Lock(); mSummaryAvailable=true; mSummaryAvailableMutex.Unlock(); }
/// Write the summary to disk, using the derived ReadData() to get the data void ODPCMAliasBlockFile::WriteSummary() { //the mFileName path may change, for example, when the project is saved. //(it moves from /tmp/ to wherever it is saved to. mFileNameMutex.Lock(); //wxFFile is not thread-safe - if any error occurs in opening the file, // it posts a wxlog message which WILL crash // Audacity because it goes into the wx GUI. // For this reason I left the wxFFile method commented out. (mchinen) // wxFFile summaryFile(mFileName.GetFullPath(), wxT("wb")); // ...and we use fopen instead. wxString sFullPath = mFileName.GetFullPath(); char* fileNameChar = new char[strlen(sFullPath.mb_str(wxConvFile)) + 1]; strcpy(fileNameChar, sFullPath.mb_str(wxConvFile)); FILE* summaryFile = fopen(fileNameChar, "wb"); mFileNameMutex.Unlock(); if( !summaryFile){//.IsOpened() ){ // Never silence the Log w.r.t write errors; they always count //however, this is going to be called from a non-main thread, //and wxLog calls are not thread safe. printf("Unable to write summary data to file: %s", fileNameChar); delete [] fileNameChar; return; } delete [] fileNameChar; // To build the summary data, call ReadData (implemented by the // derived classes) to get the sample data SampleBuffer sampleData(mLen, floatSample); this->ReadData(sampleData.ptr(), floatSample, 0, mLen); ArrayOf<char> cleanup; void *summaryData = CalcSummary(sampleData.ptr(), mLen, floatSample, cleanup); //summaryFile.Write(summaryData, mSummaryInfo.totalSummaryBytes); fwrite(summaryData, 1, mSummaryInfo.totalSummaryBytes, summaryFile); fclose(summaryFile); // printf("write successful. filename: %s\n", fileNameChar); mSummaryAvailableMutex.Lock(); mSummaryAvailable=true; mSummaryAvailableMutex.Unlock(); }
PCA& PCA::fit( const std::vector< std::vector< double > >& data ) { const size_t nSamples = data.size(); const size_t nFeatures = data.front().size(); // Calculate the means vector arma::mat meansVector( nFeatures, 1 ); for ( size_t iFeature = 0; iFeature < nFeatures; ++iFeature ) { double sx = 0; for ( size_t iSample = 0; iSample < nSamples; ++iSample ) { const double value = data[iSample][iFeature]; if ( std::isnan(value) ) throw std::runtime_error( "PCA::fit : nan value encountered at input!" ); sx += value; } meansVector(iFeature, 0) = sx / nSamples; } // Construct the covariance matrix from the scatter matrix arma::mat covMatrix( nFeatures, nFeatures, arma::fill::zeros ); for ( size_t iSample = 0; iSample < nSamples; ++iSample ) { arma::mat sampleData( data[iSample ] ); arma::mat d = sampleData - meansVector; covMatrix += d * d.t(); } covMatrix /= nSamples; // Now find the eigenvalues and eigenvectors arma::cx_vec eigval; arma::cx_mat eigvec; bool result = arma::eig_gen(eigval, eigvec, covMatrix ); if (! result ) { throw std::runtime_error("PCA::fit : eigenvalue decomposition failed!"); } // Normalise the eigenvalues m_eigPairs.clear(); m_eigPairs.reserve( nFeatures ); double eigSum = 0; for ( size_t iFeature = 0; iFeature < nFeatures; ++iFeature ) { const double eigMagnitude = std::abs( eigval(iFeature) ); arma::cx_vec eigenVectorFromCalculation = eigvec.row( iFeature ); std::vector<double> eigenVector( nFeatures, 0.0 ); for (size_t j = 0; j < nFeatures; ++j ) eigenVector[j] = eigenVectorFromCalculation(j).real(); m_eigPairs.push_back( std::make_pair( eigMagnitude, eigenVector ) ); eigSum += eigMagnitude; } for ( size_t iFeature = 0; iFeature < nFeatures; ++iFeature ) { m_eigPairs[iFeature].first /= eigSum; } // Sort the eigenValues std::sort( m_eigPairs.begin(), m_eigPairs.end(), [] (const std::pair<double, std::vector<double> >&a, const std::pair<double, std::vector<double> >&b ) { return a.first > b.first; } ); return *this; }