From 86183d8a17c7561706d76afe678f49bee56e0000 Mon Sep 17 00:00:00 2001
From: John Glover <j@johnglover.net>
Date: Mon, 9 Jul 2012 23:39:35 +0200
Subject: [sms, peak_detection] Add realtime analysis parameter, avoid
 performing non-real-time specific checks when running in realtime mode.

---
 src/simpl/peak_detection.cpp |  9 +++++++++
 src/simpl/peak_detection.h   |  2 ++
 src/sms/analysis.c           | 39 ++++++++++++++++++++++++++++-----------
 src/sms/sms.c                | 27 +++++++++++++++++++--------
 src/sms/sms.h                |  1 +
 5 files changed, 59 insertions(+), 19 deletions(-)

(limited to 'src')

diff --git a/src/simpl/peak_detection.cpp b/src/simpl/peak_detection.cpp
index 35080e2..0f118b3 100644
--- a/src/simpl/peak_detection.cpp
+++ b/src/simpl/peak_detection.cpp
@@ -178,6 +178,7 @@ SMSPeakDetection::SMSPeakDetection() {
     _analysis_params.maxPeaks = _max_peaks;
     _analysis_params.nGuides = _max_peaks;
     _analysis_params.preEmphasis = 0;
+    _analysis_params.realtime = 0;
     sms_initAnalysis(&_analysis_params);
     _analysis_params.iSizeSound = _hop_size;
 
@@ -226,6 +227,14 @@ void SMSPeakDetection::max_peaks(int new_max_peaks) {
     sms_initSpectralPeaks(&_peaks, _max_peaks);
 }
 
+int SMSPeakDetection::realtime() {
+    return _analysis_params.realtime;
+}
+
+void SMSPeakDetection::realtime(int new_realtime) {
+    _analysis_params.realtime = new_realtime;
+}
+
 // Find and return all spectral peaks in a given frame of audio
 Peaks SMSPeakDetection::find_peaks_in_frame(Frame* frame) {
     Peaks peaks;
diff --git a/src/simpl/peak_detection.h b/src/simpl/peak_detection.h
index 577e0b5..e10c2c3 100644
--- a/src/simpl/peak_detection.h
+++ b/src/simpl/peak_detection.h
@@ -83,6 +83,8 @@ class SMSPeakDetection : public PeakDetection {
         int next_frame_size();
         void hop_size(int new_hop_size);
         void max_peaks(int new_max_peaks);
+        int realtime();
+        void realtime(int new_realtime);
         Peaks find_peaks_in_frame(Frame* frame);
         Frames find_peaks(int audio_size, sample* audio);
 };
diff --git a/src/sms/analysis.c b/src/sms/analysis.c
index 89d4b4a..c7aae0b 100644
--- a/src/sms/analysis.c
+++ b/src/sms/analysis.c
@@ -174,19 +174,36 @@ int sms_findPeaks(int sizeWaveform, sfloat *pWaveform, SMS_AnalParams *pAnalPara
         sms_analyzeFrame(iCurrentFrame, pAnalParams, fRefFundamental);
 
         /* set the size of the next analysis window */
-        if(pAnalParams->ppFrames[iCurrentFrame]->fFundamental > 0 &&
-            pAnalParams->iSoundType != SMS_SOUND_TYPE_NOTE)
-            pAnalParams->windowSize = sms_sizeNextWindow(iCurrentFrame, pAnalParams);
+        /* if(pAnalParams->ppFrames[iCurrentFrame]->fFundamental > 0 && */
+        /*     pAnalParams->iSoundType != SMS_SOUND_TYPE_NOTE) */
+        /* { */
+        /*     pAnalParams->windowSize = sms_sizeNextWindow(iCurrentFrame, pAnalParams); */
+        /* } */
 
-        /* figure out how much needs to be read next time
-         * how many processed - sample no. of end of next frame
-         * = no. samples that we haven't processed yet from whenever, if sizeNextRead was 0
-         */
-        iExtraSamples = (pAnalParams->soundBuffer.iMarker + pAnalParams->soundBuffer.sizeBuffer) -
-                        (pAnalParams->ppFrames[iCurrentFrame]->iFrameSample + pAnalParams->sizeHop);
+        if(pAnalParams->realtime == 0)
+        {
+            /* set the size of the next analysis window */
+            if(pAnalParams->ppFrames[iCurrentFrame]->fFundamental > 0 &&
+                pAnalParams->iSoundType != SMS_SOUND_TYPE_NOTE) 
+            {
+                pAnalParams->windowSize = sms_sizeNextWindow(iCurrentFrame, pAnalParams);
+            }
 
-        pAnalParams->sizeNextRead = MAX(0, (pAnalParams->windowSize+1)/2 - iExtraSamples);
-        ReAnalyzeFrame(iCurrentFrame, pAnalParams);
+            /* figure out how much needs to be read next time
+             * how many processed - sample no. of end of next frame
+             * = no. samples that we haven't processed yet from whenever, if sizeNextRead was 0
+             */
+            iExtraSamples = (pAnalParams->soundBuffer.iMarker + pAnalParams->soundBuffer.sizeBuffer) -
+                            (pAnalParams->ppFrames[iCurrentFrame]->iFrameSample + pAnalParams->sizeHop);
+
+            pAnalParams->sizeNextRead = MAX(0, (pAnalParams->windowSize+1)/2 - iExtraSamples);
+            ReAnalyzeFrame(iCurrentFrame, pAnalParams);
+        }
+        else
+        {
+            pAnalParams->windowSize = sizeWaveform;
+            pAnalParams->sizeNextRead = sizeWaveform;
+        }
 
         /* save peaks */
         pSpectralPeaks->nPeaksFound = pAnalParams->ppFrames[iCurrentFrame]->nPeaks;
diff --git a/src/sms/sms.c b/src/sms/sms.c
index 8501d4d..59e9fa9 100644
--- a/src/sms/sms.c
+++ b/src/sms/sms.c
@@ -112,6 +112,7 @@ void sms_initAnalParams(SMS_AnalParams *pAnalParams)
     pAnalParams->fPeakContToGuide = .4;
     pAnalParams->fFundContToGuide = .5;
     pAnalParams->fFreqDeviation = .45;
+    pAnalParams->realtime = 0;
     pAnalParams->iSamplingRate = 44100; /* should be set to the real samplingrate with sms_initAnalysis */
     pAnalParams->iDefaultSizeWindow = 1001;
     pAnalParams->windowSize = 0;
@@ -839,7 +840,6 @@ int sms_initFrame(int iCurrentFrame, SMS_AnalParams *pAnalParams, int sizeWindow
 
     pAnalParams->ppFrames[iCurrentFrame]->iFrameNum =  
         pAnalParams->ppFrames[iCurrentFrame - 1]->iFrameNum + 1;
-    pAnalParams->ppFrames[iCurrentFrame]->iFrameSize = sizeWindow;
 
     /* if first frame set center of data around 0 */
     if(pAnalParams->ppFrames[iCurrentFrame]->iFrameNum == 1)
@@ -849,19 +849,30 @@ int sms_initFrame(int iCurrentFrame, SMS_AnalParams *pAnalParams, int sizeWindow
         pAnalParams->ppFrames[iCurrentFrame]->iFrameSample = 
             pAnalParams->ppFrames[iCurrentFrame-1]->iFrameSample + pAnalParams->sizeHop;
 
-    /* check for end of sound */
-    if((pAnalParams->ppFrames[iCurrentFrame]->iFrameSample + (sizeWindow+1)/2) >= pAnalParams->iSizeSound
-         && pAnalParams->iSizeSound > 0)
+    if(pAnalParams->realtime == 0)
     {
-        pAnalParams->ppFrames[iCurrentFrame]->iFrameNum =  -1;
-        pAnalParams->ppFrames[iCurrentFrame]->iFrameSize =  0;
-        pAnalParams->ppFrames[iCurrentFrame]->iStatus =  SMS_FRAME_END;
+        pAnalParams->ppFrames[iCurrentFrame]->iFrameSize = sizeWindow;
+
+        /* check for end of sound */
+        if((pAnalParams->ppFrames[iCurrentFrame]->iFrameSample + (sizeWindow+1)/2) >= pAnalParams->iSizeSound
+             && pAnalParams->iSizeSound > 0)
+        {
+            pAnalParams->ppFrames[iCurrentFrame]->iFrameNum =  -1;
+            pAnalParams->ppFrames[iCurrentFrame]->iFrameSize =  0;
+            pAnalParams->ppFrames[iCurrentFrame]->iStatus =  SMS_FRAME_END;
+        }
+        else
+        {
+            /* good status, ready to start computing */
+            pAnalParams->ppFrames[iCurrentFrame]->iStatus = SMS_FRAME_READY;
+        }
     }
     else
     {
-        /* good status, ready to start computing */
+        pAnalParams->ppFrames[iCurrentFrame]->iFrameSize = pAnalParams->iSamplingRate / pAnalParams->iFrameRate;
         pAnalParams->ppFrames[iCurrentFrame]->iStatus = SMS_FRAME_READY;
     }
+
     return SMS_OK;
 }
 
diff --git a/src/sms/sms.h b/src/sms/sms.h
index c72b6c1..d1ac049 100644
--- a/src/sms/sms.h
+++ b/src/sms/sms.h
@@ -242,6 +242,7 @@ typedef struct SMSAnalysisParams
     sfloat fPeakContToGuide;         /*!< contribution of previous peak to current guide (between 0 and 1) */
     sfloat fFundContToGuide;         /*!< contribution of current fundamental to current guide (between 0 and 1) */
     sfloat fFreqDeviation;           /*!< maximum deviation from peak to peak */				     
+    int realtime;                    /*!< perform realtime analysis */
     int iSamplingRate;               /*! sampling rate of sound to be analyzed */
     int iDefaultSizeWindow;          /*!< default size of analysis window in samples */
     int windowSize;                  /*!< the current window size */
-- 
cgit v1.2.3