![]() |
Mixxx
|
00001 #include <QVector> 00002 #include <QtDebug> 00003 #include <time.h> 00004 00005 #include "trackinfoobject.h" 00006 #include "analyserwaveform.h" 00007 00008 00009 AnalyserWaveform::AnalyserWaveform() { 00010 downsample = NULL; 00011 downsampleVector = NULL; 00012 } 00013 00014 void AnalyserWaveform::initialise(TrackPointer tio, int sampleRate, int totalSamples) { 00015 00016 if(tio->getVisualWaveform() != NULL) { 00017 return; 00018 } 00019 00020 if(totalSamples == 0) { 00021 return; //? 00022 } 00023 00024 double mz = tio->getVisualResampleRate(); 00025 double n = double(sampleRate) / mz; 00026 00027 QByteArray err_tmp = QString("TrackPointer %1 returned bad data: VisualResampleRate=%2, n=%3") .arg(tio->getId()).arg(mz).arg(n).toAscii(); 00028 00029 if (mz == 0 || n <= 0) { 00030 qDebug() << err_tmp 00031 << "Track must not be loaded to a player with a waveform display." 00032 << "Skipping analysis."; 00033 return; 00034 } 00035 00036 int samplesPerDownsample = n; 00037 int numDownsamples = totalSamples / samplesPerDownsample; 00038 00039 if(numDownsamples % 2 != 0) 00040 numDownsamples++; 00041 00042 // Downsample from curSamples -> numDownsamples 00043 00044 // TODO(XXX) leaked memory 00045 downsample = new QVector<float>(numDownsamples); 00046 downsampleVector = downsample->data(); 00047 int i; 00048 00049 // Set the buffer to zero 00050 for(i=0;i<numDownsamples;i++) { 00051 (*downsample)[i] = 0; 00052 } 00053 00054 // Allow the visual waveform to display this before we've populated it so 00055 // that it displays the wave as we work. 00056 tio->setVisualWaveform(downsample); 00057 00058 //qDebug() << "AnalyserWaveform: f " << sampleRate << " samplesPerDownsample: " << samplesPerDownsample << " downsamples " << numDownsamples << " from " << totalSamples; 00059 00060 m_iStrideLength = samplesPerDownsample*2; 00061 m_iCurPos = 0; 00062 m_iBufferPos = 0; 00063 m_fLMax = 0.0; 00064 m_fRMax = 0.0; 00065 m_fOldLMax = 0.0f; 00066 m_fOldRMax = 0.0f; 00067 00068 m_iStartTime = clock(); 00069 } 00070 00071 00072 void AnalyserWaveform::process(const CSAMPLE *pIn, const int iLen) { 00073 if(downsample == NULL) { 00074 return; 00075 } 00076 00077 const float fAlpha = 0.5f; 00078 00079 //qDebug() << "AnalyserWaveform::process() processing " << iLen << " samples"; 00080 for(int i=0; i < iLen && (downsampleVector+1-downsample->data()) < downsample->size(); i+=2) { 00081 00082 if(m_iBufferPos >= m_iStrideLength) { 00083 //(*downsample)[m_iCurPos] = m_fLMax; 00084 *(downsampleVector++) = m_fOldLMax + fAlpha * (m_fLMax - m_fOldLMax); 00085 m_iCurPos++; 00086 00087 //(*downsample)[m_iCurPos] = m_fRMax; 00088 *(downsampleVector++) = m_fOldRMax + fAlpha * (m_fRMax - m_fOldRMax); 00089 m_iCurPos++; 00090 00091 m_fOldRMax = m_fRMax; 00092 m_fOldLMax = m_fLMax; 00093 00094 m_iBufferPos = 0; 00095 m_fLMax = -1.0f; 00096 m_fRMax = -1.0f; 00097 00098 } 00099 00100 if(m_iBufferPos < m_iStrideLength/4) { //m_iStrideLength) { 00101 CSAMPLE sl = fabs(pIn[i]); 00102 CSAMPLE sr = fabs(pIn[i+1]); 00103 if(sl > m_fLMax) 00104 m_fLMax = sl; 00105 if(sr > m_fRMax) 00106 m_fRMax = sr; 00107 } 00108 00109 m_iBufferPos += 2; 00110 } 00111 } 00112 00113 void AnalyserWaveform::finalise(TrackPointer tio) { 00114 Q_UNUSED(tio); 00115 if(downsample == NULL) { 00116 return; 00117 } 00118 00119 downsample = NULL; 00120 downsampleVector = NULL; 00121 00122 //qDebug() << "AnalyserWaveform :: Waveform downsampling finished."; 00123 m_iStartTime = clock() - m_iStartTime; 00124 //qDebug() << "AnalyserWaveform :: Generation took " << double(m_iStartTime) / CLOCKS_PER_SEC << " seconds"; 00125 }