changeset 574:b3c35447ef31 3.0-integration

Wire up record monitoring
author Chris Cannam
date Wed, 04 Jan 2017 16:03:12 +0000
parents 9fb190c6521b
children c2e27ad7f408
files audio/AudioCallbackPlaySource.cpp audio/AudioCallbackPlaySource.h audio/AudioCallbackRecordTarget.cpp audio/AudioCallbackRecordTarget.h audio/AudioRecordTarget.cpp audio/AudioRecordTarget.h files.pri framework/MainWindowBase.cpp framework/MainWindowBase.h
diffstat 9 files changed, 349 insertions(+), 320 deletions(-) [+]
line wrap: on
line diff
--- a/audio/AudioCallbackPlaySource.cpp	Wed Jan 04 14:22:39 2017 +0000
+++ b/audio/AudioCallbackPlaySource.cpp	Wed Jan 04 16:03:12 2017 +0000
@@ -965,8 +965,8 @@
 void
 AudioCallbackPlaySource::setOutputLevels(float left, float right)
 {
-    m_outputLeft = left;
-    m_outputRight = right;
+    if (left > m_outputLeft) m_outputLeft = left;
+    if (right > m_outputRight) m_outputRight = right;
 }
 
 bool
@@ -974,6 +974,8 @@
 {
     left = m_outputLeft;
     right = m_outputRight;
+    m_outputLeft = 0.f;
+    m_outputRight = 0.f;
     return true;
 }
 
--- a/audio/AudioCallbackPlaySource.h	Wed Jan 04 14:22:39 2017 +0000
+++ b/audio/AudioCallbackPlaySource.h	Wed Jan 04 16:03:12 2017 +0000
@@ -13,8 +13,8 @@
     COPYING included with this distribution for more information.
 */
 
-#ifndef AUDIO_CALLBACK_PLAY_SOURCE_H
-#define AUDIO_CALLBACK_PLAY_SOURCE_H
+#ifndef SV_AUDIO_CALLBACK_PLAY_SOURCE_H
+#define SV_AUDIO_CALLBACK_PLAY_SOURCE_H
 
 #include "base/RingBuffer.h"
 #include "base/AudioPlaySource.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/audio/AudioCallbackRecordTarget.cpp	Wed Jan 04 16:03:12 2017 +0000
@@ -0,0 +1,239 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#include "AudioCallbackRecordTarget.h"
+
+#include "base/ViewManagerBase.h"
+#include "base/TempDirectory.h"
+
+#include "data/model/WritableWaveFileModel.h"
+
+#include <QDir>
+
+AudioCallbackRecordTarget::AudioCallbackRecordTarget(ViewManagerBase *manager,
+                                                     QString clientName) :
+    m_viewManager(manager),
+    m_clientName(clientName.toUtf8().data()),
+    m_recording(false),
+    m_recordSampleRate(44100),
+    m_recordChannelCount(2),
+    m_frameCount(0),
+    m_model(0),
+    m_inputLeft(0.f),
+    m_inputRight(0.f)
+{
+    m_viewManager->setAudioRecordTarget(this);
+
+    connect(this, SIGNAL(recordStatusChanged(bool)),
+            m_viewManager, SLOT(recordStatusChanged(bool)));
+}
+
+AudioCallbackRecordTarget::~AudioCallbackRecordTarget()
+{
+    QMutexLocker locker(&m_mutex);
+    m_viewManager->setAudioRecordTarget(0);
+}
+
+int
+AudioCallbackRecordTarget::getApplicationSampleRate() const
+{
+    return 0; // don't care
+}
+
+int
+AudioCallbackRecordTarget::getApplicationChannelCount() const
+{
+    return m_recordChannelCount;
+}
+
+void
+AudioCallbackRecordTarget::setSystemRecordBlockSize(int)
+{
+}
+
+void
+AudioCallbackRecordTarget::setSystemRecordSampleRate(int n)
+{
+    m_recordSampleRate = n;
+}
+
+void
+AudioCallbackRecordTarget::setSystemRecordLatency(int)
+{
+}
+
+void
+AudioCallbackRecordTarget::setSystemRecordChannelCount(int c)
+{
+    m_recordChannelCount = c;
+}
+
+void
+AudioCallbackRecordTarget::putSamples(const float *const *samples, int, int nframes)
+{
+    bool secChanged = false;
+    sv_frame_t frameToEmit = 0;
+
+    {
+        QMutexLocker locker(&m_mutex); //!!! bad here
+        if (!m_recording) return;
+
+        m_model->addSamples(samples, nframes);
+
+        sv_frame_t priorFrameCount = m_frameCount;
+        m_frameCount += nframes;
+
+        RealTime priorRT = RealTime::frame2RealTime
+            (priorFrameCount, m_recordSampleRate);
+        RealTime postRT = RealTime::frame2RealTime
+            (m_frameCount, m_recordSampleRate);
+
+        secChanged = (postRT.sec > priorRT.sec);
+        if (secChanged) {
+            m_model->updateModel(); //!!! v bad here
+            frameToEmit = m_frameCount;
+        }
+    }
+
+    if (secChanged) {
+        emit recordDurationChanged(frameToEmit, m_recordSampleRate);
+    }
+}
+
+void
+AudioCallbackRecordTarget::setInputLevels(float left, float right)
+{
+    if (left > m_inputLeft) m_inputLeft = left;
+    if (right > m_inputRight) m_inputRight = right;
+}
+
+bool
+AudioCallbackRecordTarget::getInputLevels(float &left, float &right)
+{
+    left = m_inputLeft;
+    right = m_inputRight;
+    m_inputLeft = 0.f;
+    m_inputRight = 0.f;
+    return true;
+}
+
+void
+AudioCallbackRecordTarget::modelAboutToBeDeleted()
+{
+    QMutexLocker locker(&m_mutex);
+    if (sender() == m_model) {
+        m_model = 0;
+        m_recording = false;
+    }
+}
+
+QString
+AudioCallbackRecordTarget::getRecordContainerFolder()
+{
+    QDir parent(TempDirectory::getInstance()->getContainingPath());
+    QString subdirname("recorded");
+
+    if (!parent.mkpath(subdirname)) {
+        SVCERR << "ERROR: AudioCallbackRecordTarget::getRecordContainerFolder: Failed to create recorded dir in \"" << parent.canonicalPath() << "\"" << endl;
+        return "";
+    } else {
+        return parent.filePath(subdirname);
+    }
+}
+
+QString
+AudioCallbackRecordTarget::getRecordFolder()
+{
+    QDir parent(getRecordContainerFolder());
+    QDateTime now = QDateTime::currentDateTime();
+    QString subdirname = QString("%1").arg(now.toString("yyyyMMdd"));
+
+    if (!parent.mkpath(subdirname)) {
+        SVCERR << "ERROR: AudioCallbackRecordTarget::getRecordFolder: Failed to create recorded dir in \"" << parent.canonicalPath() << "\"" << endl;
+        return "";
+    } else {
+        return parent.filePath(subdirname);
+    }
+}
+
+WritableWaveFileModel *
+AudioCallbackRecordTarget::startRecording()
+{
+    {
+        QMutexLocker locker(&m_mutex);
+    
+        if (m_recording) {
+            SVCERR << "WARNING: AudioCallbackRecordTarget::startRecording: We are already recording" << endl;
+            return 0;
+        }
+
+        m_model = 0;
+        m_frameCount = 0;
+
+        QString folder = getRecordFolder();
+        if (folder == "") return 0;
+        QDir recordedDir(folder);
+
+        QDateTime now = QDateTime::currentDateTime();
+
+        // Don't use QDateTime::toString(Qt::ISODate) as the ":" character
+        // isn't permitted in filenames on Windows
+        QString nowString = now.toString("yyyyMMdd-HHmmss-zzz");
+    
+        QString filename = tr("recorded-%1.wav").arg(nowString);
+        QString label = tr("Recorded %1").arg(nowString);
+
+        m_audioFileName = recordedDir.filePath(filename);
+
+        m_model = new WritableWaveFileModel(m_recordSampleRate,
+                                            m_recordChannelCount,
+                                            m_audioFileName);
+
+        if (!m_model->isOK()) {
+            SVCERR << "ERROR: AudioCallbackRecordTarget::startRecording: Recording failed"
+                   << endl;
+            //!!! and throw?
+            delete m_model;
+            m_model = 0;
+            return 0;
+        }
+
+        m_model->setObjectName(label);
+        m_recording = true;
+    }
+
+    emit recordStatusChanged(true);
+    return m_model;
+}
+
+void
+AudioCallbackRecordTarget::stopRecording()
+{
+    {
+        QMutexLocker locker(&m_mutex);
+        if (!m_recording) {
+            SVCERR << "WARNING: AudioCallbackRecordTarget::startRecording: Not recording" << endl;
+            return;
+        }
+
+        m_model->writeComplete();
+        m_model = 0;
+        m_recording = false;
+    }
+
+    emit recordStatusChanged(false);
+    emit recordCompleted();
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/audio/AudioCallbackRecordTarget.h	Wed Jan 04 16:03:12 2017 +0000
@@ -0,0 +1,91 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#ifndef SV_AUDIO_CALLBACK_RECORD_TARGET_H
+#define SV_AUDIO_CALLBACK_RECORD_TARGET_H
+
+#include "base/AudioRecordTarget.h"
+
+#include <bqaudioio/ApplicationRecordTarget.h>
+
+#include <string>
+
+#include <QObject>
+#include <QMutex>
+
+#include "base/BaseTypes.h"
+
+class ViewManagerBase;
+class WritableWaveFileModel;
+
+class AudioCallbackRecordTarget : public QObject,
+                                  public AudioRecordTarget,
+                                  public breakfastquay::ApplicationRecordTarget
+{
+    Q_OBJECT
+
+public:
+    AudioCallbackRecordTarget(ViewManagerBase *, QString clientName);
+    virtual ~AudioCallbackRecordTarget();
+
+    virtual std::string getClientName() const override { return m_clientName; }
+    
+    virtual int getApplicationSampleRate() const override;
+    virtual int getApplicationChannelCount() const override;
+
+    virtual void setSystemRecordBlockSize(int) override;
+    virtual void setSystemRecordSampleRate(int) override;
+    virtual void setSystemRecordLatency(int) override;
+    virtual void setSystemRecordChannelCount(int) override;
+
+    virtual void putSamples(const float *const *samples, int nchannels, int nframes) override;
+    
+    virtual void setInputLevels(float peakLeft, float peakRight) override;
+
+    virtual void audioProcessingOverload() override { }
+
+    QString getRecordContainerFolder();
+    QString getRecordFolder();
+    
+    virtual bool isRecording() const override { return m_recording; }
+    virtual sv_frame_t getRecordDuration() const override { return m_frameCount; }
+
+    virtual bool getInputLevels(float &left, float &right) override;
+
+    WritableWaveFileModel *startRecording(); // caller takes ownership of model
+    void stopRecording();
+
+signals:
+    void recordStatusChanged(bool recording);
+    void recordDurationChanged(sv_frame_t, sv_samplerate_t); // emitted occasionally
+    void recordCompleted();
+
+protected slots:
+    void modelAboutToBeDeleted();
+    
+private:
+    ViewManagerBase *m_viewManager;
+    std::string m_clientName;
+    bool m_recording;
+    sv_samplerate_t m_recordSampleRate;
+    int m_recordChannelCount;
+    sv_frame_t m_frameCount;
+    QString m_audioFileName;
+    WritableWaveFileModel *m_model;
+    float m_inputLeft;
+    float m_inputRight;
+    QMutex m_mutex;
+};
+
+#endif
--- a/audio/AudioRecordTarget.cpp	Wed Jan 04 14:22:39 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,222 +0,0 @@
-/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
-
-/*
-    Sonic Visualiser
-    An audio file viewer and annotation editor.
-    Centre for Digital Music, Queen Mary, University of London.
-    
-    This program is free software; you can redistribute it and/or
-    modify it under the terms of the GNU General Public License as
-    published by the Free Software Foundation; either version 2 of the
-    License, or (at your option) any later version.  See the file
-    COPYING included with this distribution for more information.
-*/
-
-#include "AudioRecordTarget.h"
-
-#include "base/ViewManagerBase.h"
-#include "base/TempDirectory.h"
-
-#include "data/model/WritableWaveFileModel.h"
-
-#include <QDir>
-
-AudioRecordTarget::AudioRecordTarget(ViewManagerBase *manager,
-				     QString clientName) :
-    m_viewManager(manager),
-    m_clientName(clientName.toUtf8().data()),
-    m_recording(false),
-    m_recordSampleRate(44100),
-    m_recordChannelCount(2),
-    m_frameCount(0),
-    m_model(0)
-{
-}
-
-AudioRecordTarget::~AudioRecordTarget()
-{
-    QMutexLocker locker(&m_mutex);
-}
-
-int
-AudioRecordTarget::getApplicationSampleRate() const
-{
-    return 0; // don't care
-}
-
-int
-AudioRecordTarget::getApplicationChannelCount() const
-{
-    return m_recordChannelCount;
-}
-
-void
-AudioRecordTarget::setSystemRecordBlockSize(int)
-{
-}
-
-void
-AudioRecordTarget::setSystemRecordSampleRate(int n)
-{
-    m_recordSampleRate = n;
-}
-
-void
-AudioRecordTarget::setSystemRecordLatency(int)
-{
-}
-
-void
-AudioRecordTarget::setSystemRecordChannelCount(int c)
-{
-    m_recordChannelCount = c;
-}
-
-void
-AudioRecordTarget::putSamples(const float *const *samples, int, int nframes)
-{
-    bool secChanged = false;
-    sv_frame_t frameToEmit = 0;
-
-    {
-        QMutexLocker locker(&m_mutex); //!!! bad here
-        if (!m_recording) return;
-
-        m_model->addSamples(samples, nframes);
-
-        sv_frame_t priorFrameCount = m_frameCount;
-        m_frameCount += nframes;
-
-        RealTime priorRT = RealTime::frame2RealTime
-            (priorFrameCount, m_recordSampleRate);
-        RealTime postRT = RealTime::frame2RealTime
-            (m_frameCount, m_recordSampleRate);
-
-        secChanged = (postRT.sec > priorRT.sec);
-        if (secChanged) {
-            m_model->updateModel(); //!!! v bad here
-            frameToEmit = m_frameCount;
-        }
-    }
-
-    if (secChanged) {
-        emit recordDurationChanged(frameToEmit, m_recordSampleRate);
-    }
-}
-
-void
-AudioRecordTarget::setInputLevels(float left, float right)
-{
-    cerr << "AudioRecordTarget::setInputLevels(" << left << "," << right << ")"
-         << endl;
-}
-
-void
-AudioRecordTarget::modelAboutToBeDeleted()
-{
-    QMutexLocker locker(&m_mutex);
-    if (sender() == m_model) {
-        m_model = 0;
-        m_recording = false;
-    }
-}
-
-QString
-AudioRecordTarget::getRecordContainerFolder()
-{
-    QDir parent(TempDirectory::getInstance()->getContainingPath());
-    QString subdirname("recorded");
-
-    if (!parent.mkpath(subdirname)) {
-        SVCERR << "ERROR: AudioRecordTarget::getRecordContainerFolder: Failed to create recorded dir in \"" << parent.canonicalPath() << "\"" << endl;
-        return "";
-    } else {
-        return parent.filePath(subdirname);
-    }
-}
-
-QString
-AudioRecordTarget::getRecordFolder()
-{
-    QDir parent(getRecordContainerFolder());
-    QDateTime now = QDateTime::currentDateTime();
-    QString subdirname = QString("%1").arg(now.toString("yyyyMMdd"));
-
-    if (!parent.mkpath(subdirname)) {
-        SVCERR << "ERROR: AudioRecordTarget::getRecordFolder: Failed to create recorded dir in \"" << parent.canonicalPath() << "\"" << endl;
-        return "";
-    } else {
-        return parent.filePath(subdirname);
-    }
-}
-
-WritableWaveFileModel *
-AudioRecordTarget::startRecording()
-{
-    {
-        QMutexLocker locker(&m_mutex);
-    
-        if (m_recording) {
-            SVCERR << "WARNING: AudioRecordTarget::startRecording: We are already recording" << endl;
-            return 0;
-        }
-
-        m_model = 0;
-        m_frameCount = 0;
-
-        QString folder = getRecordFolder();
-        if (folder == "") return 0;
-        QDir recordedDir(folder);
-
-        QDateTime now = QDateTime::currentDateTime();
-
-        // Don't use QDateTime::toString(Qt::ISODate) as the ":" character
-        // isn't permitted in filenames on Windows
-        QString nowString = now.toString("yyyyMMdd-HHmmss-zzz");
-    
-        QString filename = tr("recorded-%1.wav").arg(nowString);
-        QString label = tr("Recorded %1").arg(nowString);
-
-        m_audioFileName = recordedDir.filePath(filename);
-
-        m_model = new WritableWaveFileModel(m_recordSampleRate,
-                                            m_recordChannelCount,
-                                            m_audioFileName);
-
-        if (!m_model->isOK()) {
-            SVCERR << "ERROR: AudioRecordTarget::startRecording: Recording failed"
-                   << endl;
-            //!!! and throw?
-            delete m_model;
-            m_model = 0;
-            return 0;
-        }
-
-        m_model->setObjectName(label);
-        m_recording = true;
-    }
-
-    emit recordStatusChanged(true);
-    return m_model;
-}
-
-void
-AudioRecordTarget::stopRecording()
-{
-    {
-        QMutexLocker locker(&m_mutex);
-        if (!m_recording) {
-            SVCERR << "WARNING: AudioRecordTarget::startRecording: Not recording" << endl;
-            return;
-        }
-
-        m_model->writeComplete();
-        m_model = 0;
-        m_recording = false;
-    }
-
-    emit recordStatusChanged(false);
-    emit recordCompleted();
-}
-
-
--- a/audio/AudioRecordTarget.h	Wed Jan 04 14:22:39 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
-
-/*
-    Sonic Visualiser
-    An audio file viewer and annotation editor.
-    Centre for Digital Music, Queen Mary, University of London.
-    
-    This program is free software; you can redistribute it and/or
-    modify it under the terms of the GNU General Public License as
-    published by the Free Software Foundation; either version 2 of the
-    License, or (at your option) any later version.  See the file
-    COPYING included with this distribution for more information.
-*/
-
-#ifndef AUDIO_RECORD_TARGET_H
-#define AUDIO_RECORD_TARGET_H
-
-#include <bqaudioio/ApplicationRecordTarget.h>
-
-#include <string>
-
-#include <QObject>
-#include <QMutex>
-
-#include "base/BaseTypes.h"
-
-class ViewManagerBase;
-class WritableWaveFileModel;
-
-class AudioRecordTarget : public QObject,
-			  public breakfastquay::ApplicationRecordTarget
-{
-    Q_OBJECT
-
-public:
-    AudioRecordTarget(ViewManagerBase *, QString clientName);
-    virtual ~AudioRecordTarget();
-
-    virtual std::string getClientName() const override { return m_clientName; }
-    
-    virtual int getApplicationSampleRate() const override;
-    virtual int getApplicationChannelCount() const override;
-
-    virtual void setSystemRecordBlockSize(int) override;
-    virtual void setSystemRecordSampleRate(int) override;
-    virtual void setSystemRecordLatency(int) override;
-    virtual void setSystemRecordChannelCount(int) override;
-
-    virtual void putSamples(const float *const *samples, int nchannels, int nframes) override;
-    
-    virtual void setInputLevels(float peakLeft, float peakRight) override;
-
-    virtual void audioProcessingOverload() override { }
-
-    QString getRecordContainerFolder();
-    QString getRecordFolder();
-    
-    bool isRecording() const { return m_recording; }
-    WritableWaveFileModel *startRecording(); // caller takes ownership
-    void stopRecording();
-
-signals:
-    void recordStatusChanged(bool recording);
-    void recordDurationChanged(sv_frame_t, sv_samplerate_t); // emitted occasionally
-    void recordCompleted();
-
-protected slots:
-    void modelAboutToBeDeleted();
-    
-private:
-    ViewManagerBase *m_viewManager;
-    std::string m_clientName;
-    bool m_recording;
-    sv_samplerate_t m_recordSampleRate;
-    int m_recordChannelCount;
-    sv_frame_t m_frameCount;
-    QString m_audioFileName;
-    WritableWaveFileModel *m_model;
-    QMutex m_mutex;
-};
-
-#endif
--- a/files.pri	Wed Jan 04 14:22:39 2017 +0000
+++ b/files.pri	Wed Jan 04 16:03:12 2017 +0000
@@ -1,7 +1,7 @@
 
 SVAPP_HEADERS += \
            audio/AudioCallbackPlaySource.h \
-           audio/AudioRecordTarget.h \
+           audio/AudioCallbackRecordTarget.h \
            audio/AudioGenerator.h \
            audio/ClipMixer.h \
            audio/ContinuousSynth.h \
@@ -15,7 +15,7 @@
 
 SVAPP_SOURCES += \
            audio/AudioCallbackPlaySource.cpp \
-           audio/AudioRecordTarget.cpp \
+           audio/AudioCallbackRecordTarget.cpp \
            audio/AudioGenerator.cpp \
            audio/ClipMixer.cpp \
            audio/ContinuousSynth.cpp \
--- a/framework/MainWindowBase.cpp	Wed Jan 04 14:22:39 2017 +0000
+++ b/framework/MainWindowBase.cpp	Wed Jan 04 16:03:12 2017 +0000
@@ -48,7 +48,7 @@
 #include "widgets/InteractiveFileFinder.h"
 
 #include "audio/AudioCallbackPlaySource.h"
-#include "audio/AudioRecordTarget.h"
+#include "audio/AudioCallbackRecordTarget.h"
 #include "audio/PlaySpeedRangeMapper.h"
 
 #include "data/fileio/DataFileReaderFactory.h"
@@ -231,11 +231,12 @@
     connect(m_paneStack, SIGNAL(paneDeleteButtonClicked(Pane *)),
             this, SLOT(paneDeleteButtonClicked(Pane *)));
     
-    m_playSource = new AudioCallbackPlaySource(m_viewManager,
-                                               QApplication::applicationName());
+    m_playSource = new AudioCallbackPlaySource
+        (m_viewManager, QApplication::applicationName());
+
     if (m_soundOptions & WithAudioInput) {
-        m_recordTarget = new AudioRecordTarget(m_viewManager,
-                                               QApplication::applicationName());
+        m_recordTarget = new AudioCallbackRecordTarget
+            (m_viewManager, QApplication::applicationName());
         connect(m_recordTarget,
                 SIGNAL(recordDurationChanged(sv_frame_t, sv_samplerate_t)),
                 this,
@@ -251,8 +252,8 @@
     connect(m_playSource, SIGNAL(audioTimeStretchMultiChannelDisabled()),
             this,           SLOT(audioTimeStretchMultiChannelDisabled()));
 
-    connect(m_viewManager, SIGNAL(outputLevelsChanged(float, float)),
-	    this, SLOT(outputLevelsChanged(float, float)));
+    connect(m_viewManager, SIGNAL(monitoringLevelsChanged(float, float)),
+	    this, SLOT(monitoringLevelsChanged(float, float)));
 
     connect(m_viewManager, SIGNAL(playbackFrameChanged(sv_frame_t)),
             this, SLOT(playbackFrameChanged(sv_frame_t)));
--- a/framework/MainWindowBase.h	Wed Jan 04 14:22:39 2017 +0000
+++ b/framework/MainWindowBase.h	Wed Jan 04 16:03:12 2017 +0000
@@ -46,7 +46,7 @@
 class WaveformLayer;
 class WaveFileModel;
 class AudioCallbackPlaySource;
-class AudioRecordTarget;
+class AudioCallbackRecordTarget;
 class CommandHistory;
 class QMenu;
 class AudioDial;
@@ -258,7 +258,7 @@
     virtual void globalCentreFrameChanged(sv_frame_t);
     virtual void viewCentreFrameChanged(View *, sv_frame_t);
     virtual void viewZoomLevelChanged(View *, int, bool);
-    virtual void outputLevelsChanged(float, float) = 0;
+    virtual void monitoringLevelsChanged(float, float) = 0;
     virtual void recordDurationChanged(sv_frame_t, sv_samplerate_t);
 
     virtual void currentPaneChanged(Pane *);
@@ -348,7 +348,7 @@
     SoundOptions             m_soundOptions;
 
     AudioCallbackPlaySource *m_playSource;
-    AudioRecordTarget       *m_recordTarget;
+    AudioCallbackRecordTarget *m_recordTarget;
     breakfastquay::ResamplerWrapper *m_resamplerWrapper;
     breakfastquay::SystemPlaybackTarget *m_playTarget; // only one of this...
     breakfastquay::SystemAudioIO *m_audioIO;           // ... and this exists