changeset 409:80a44fafd263

Merge
author Chris Cannam
date Tue, 24 Mar 2015 16:03:52 +0000
parents b5a374e6e0fa (diff) 79ee074fbb7f (current diff)
children 0e12cd0d1839
files .hgsubstate
diffstat 3 files changed, 89 insertions(+), 436 deletions(-) [+]
line wrap: on
line diff
--- a/.hgsubstate	Tue Mar 24 15:18:04 2015 +0000
+++ b/.hgsubstate	Tue Mar 24 16:03:52 2015 +0000
@@ -1,7 +1,7 @@
 e32a354434aa5fa7440efa17b716aacd761049fa chp
 d16f0fd6db6104d87882bc43788a3bb1b0f8c528 dataquay
-4cbbd87a8c7f95ccac8e7900eef4f08bbdbb032f pyin
+992e31b263779fc85282f2433c57e231fb61ec93 pyin
 55ece8862b6d3a54aad271a53f9c1615e5d3bcf8 sv-dependency-builds
 aa6fb3516e281bae6f9f57f368427374b9138b05 svapp
 5c5d4863b42849fdc0e2062858a0c4acc725047b svcore
-26da827e8fb52d5fa599b05c01e9360481fdccb9 svgui
+76f4b81b766d7a3eabc3a133dc8279b774d2826a svgui
--- a/src/MainWindow.cpp	Tue Mar 24 15:18:04 2015 +0000
+++ b/src/MainWindow.cpp	Tue Mar 24 16:03:52 2015 +0000
@@ -31,6 +31,7 @@
 #include "data/model/NoteModel.h"
 #include "view/ViewManager.h"
 #include "base/Preferences.h"
+#include "base/AudioLevel.h"
 #include "layer/WaveformLayer.h"
 #include "layer/TimeInstantLayer.h"
 #include "layer/TimeValueLayer.h"
@@ -40,6 +41,7 @@
 #include "widgets/AudioDial.h"
 #include "widgets/IconLoader.h"
 #include "widgets/KeyReference.h"
+#include "widgets/LevelPanWidget.h"
 #include "audioio/AudioCallbackPlaySource.h"
 #include "audioio/AudioCallbackPlayTarget.h"
 #include "audioio/PlaySpeedRangeMapper.h"
@@ -238,128 +240,23 @@
     connect(m_playSpeed, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredWidget()));
     connect(m_playSpeed, SIGNAL(mouseLeft()), this, SLOT(mouseLeftWidget()));
 
-    // Gain controls
-    m_gainAudio = new AudioDial(frame);
-    m_gainAudio->setMeterColor(Qt::darkRed);
-    m_gainAudio->setMinimum(-50);
-    m_gainAudio->setMaximum(50);
-    m_gainAudio->setValue(0);
-    m_gainAudio->setDefaultValue(0);
-    //m_gainAudio->setFixedWidth(40);
-    m_gainAudio->setFixedWidth(24);
-    m_gainAudio->setFixedHeight(24);
-    m_gainAudio->setNotchesVisible(true);
-    m_gainAudio->setPageStep(10);
-    m_gainAudio->setObjectName(tr("Audio Track Gain"));
-    m_gainAudio->setRangeMapper(new LinearRangeMapper(-50, 50, -25, 25, tr("dB")));
-    m_gainAudio->setShowToolTip(true);
-    connect(m_gainAudio, SIGNAL(valueChanged(int)),
-            this, SLOT(audioGainChanged(int)));
-    connect(m_gainAudio, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredWidget()));
-    connect(m_gainAudio, SIGNAL(mouseLeft()), this, SLOT(mouseLeftWidget()));
-
-    if (m_withSonification)
-    {   
-        m_gainPitch = new AudioDial(frame);
-        m_gainPitch->setMeterColor(Qt::darkRed);
-        m_gainPitch->setMinimum(-50);
-        m_gainPitch->setMaximum(50);
-        m_gainPitch->setValue(0);
-        m_gainPitch->setDefaultValue(0);
-        m_gainPitch->setFixedWidth(24);
-        m_gainPitch->setFixedHeight(24);
-        m_gainPitch->setNotchesVisible(true);
-        m_gainPitch->setPageStep(10);
-        m_gainPitch->setObjectName(tr("Pitch Track Gain"));
-        m_gainPitch->setRangeMapper(new LinearRangeMapper(-50, 50, -25, 25, tr("dB")));
-        m_gainPitch->setShowToolTip(true);
-        connect(m_gainPitch, SIGNAL(valueChanged(int)),
-                this, SLOT(pitchGainChanged(int)));
-        connect(m_gainPitch, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredWidget()));
-        connect(m_gainPitch, SIGNAL(mouseLeft()), this, SLOT(mouseLeftWidget()));
-
-        m_gainNotes = new AudioDial(frame);
-        m_gainNotes->setMeterColor(Qt::darkRed);
-        m_gainNotes->setMinimum(-50);
-        m_gainNotes->setMaximum(50);
-        m_gainNotes->setValue(0);
-        m_gainNotes->setDefaultValue(0);
-        m_gainNotes->setFixedWidth(24);
-        m_gainNotes->setFixedHeight(24);
-        m_gainNotes->setNotchesVisible(true);
-        m_gainNotes->setPageStep(10);
-        m_gainNotes->setObjectName(tr("Note Gain"));
-        m_gainNotes->setRangeMapper(new LinearRangeMapper(-50, 50, -25, 25, tr("dB")));
-        m_gainNotes->setShowToolTip(true);
-        connect(m_gainNotes, SIGNAL(valueChanged(int)),
-                this, SLOT(notesGainChanged(int)));
-        connect(m_gainNotes, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredWidget()));
-        connect(m_gainNotes, SIGNAL(mouseLeft()), this, SLOT(mouseLeftWidget()));
+    m_audioLPW = new LevelPanWidget(frame);
+    m_audioLPW->setObjectName(tr("Audio Track Level and Pan"));
+    connect(m_audioLPW, SIGNAL(levelChanged(float)), this, SLOT(audioGainChanged(float)));
+    connect(m_audioLPW, SIGNAL(panChanged(float)), this, SLOT(audioPanChanged(float)));
+
+    if (m_withSonification) {
+
+        m_pitchLPW = new LevelPanWidget(frame);
+        m_pitchLPW->setObjectName(tr("Pitch Track Level and Pan"));
+        connect(m_pitchLPW, SIGNAL(levelChanged(float)), this, SLOT(pitchGainChanged(float)));
+        connect(m_pitchLPW, SIGNAL(panChanged(float)), this, SLOT(pitchPanChanged(float)));
+
+        m_notesLPW = new LevelPanWidget(frame);
+        m_notesLPW->setObjectName(tr("Note Track Level and Pan"));
+        connect(m_notesLPW, SIGNAL(levelChanged(float)), this, SLOT(notesGainChanged(float)));
+        connect(m_notesLPW, SIGNAL(panChanged(float)), this, SLOT(notesPanChanged(float)));
     }
-    // End of Gain controls
-
-    // Pan controls
-    m_panAudio = new AudioDial(frame);
-    m_panAudio->setMeterColor(Qt::darkGreen);
-    m_panAudio->setMinimum(-100);
-    m_panAudio->setMaximum(100);
-    m_panAudio->setValue(-100);
-    m_panAudio->setDefaultValue(-100);
-    m_panAudio->setFixedWidth(24);
-    //m_panAudio->setFixedWidth(40);
-    m_panAudio->setFixedHeight(24);
-    m_panAudio->setNotchesVisible(true);
-    m_panAudio->setPageStep(10);
-    m_panAudio->setObjectName(tr("Audio Track Pan"));
-    m_panAudio->setRangeMapper(new LinearRangeMapper(-100, 100, -100, 100, tr("")));
-    m_panAudio->setShowToolTip(true);
-    connect(m_panAudio, SIGNAL(valueChanged(int)),
-            this, SLOT(audioPanChanged(int)));
-    connect(m_panAudio, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredWidget()));
-    connect(m_panAudio, SIGNAL(mouseLeft()), this, SLOT(mouseLeftWidget()));
-
-
-
-    if (m_withSonification)
-    {   
-        m_panPitch = new AudioDial(frame);
-        m_panPitch->setMeterColor(Qt::darkGreen);
-        m_panPitch->setMinimum(-100);
-        m_panPitch->setMaximum(100);
-        m_panPitch->setValue(100);
-        m_panPitch->setDefaultValue(100);
-        m_panPitch->setFixedWidth(24);
-        m_panPitch->setFixedHeight(24);
-        m_panPitch->setNotchesVisible(true);
-        m_panPitch->setPageStep(10);
-        m_panPitch->setObjectName(tr("Pitch Track Pan"));
-        m_panPitch->setRangeMapper(new LinearRangeMapper(-100, 100, -100, 100, tr("")));
-        m_panPitch->setShowToolTip(true);
-        connect(m_panPitch, SIGNAL(valueChanged(int)),
-                this, SLOT(pitchPanChanged(int)));
-        connect(m_panPitch, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredWidget()));
-        connect(m_panPitch, SIGNAL(mouseLeft()), this, SLOT(mouseLeftWidget()));
-
-        m_panNotes = new AudioDial(frame);
-        m_panNotes->setMeterColor(Qt::darkGreen);
-        m_panNotes->setMinimum(-100);
-        m_panNotes->setMaximum(100);
-        m_panNotes->setValue(100);
-        m_panNotes->setDefaultValue(100);
-        m_panNotes->setFixedWidth(24);
-        m_panNotes->setFixedHeight(24);
-        m_panNotes->setNotchesVisible(true);
-        m_panNotes->setPageStep(10);
-        m_panNotes->setObjectName(tr("Note Pan"));
-        m_panNotes->setRangeMapper(new LinearRangeMapper(-100, 100, -100, 100, tr("")));
-        m_panNotes->setShowToolTip(true);
-        connect(m_panNotes, SIGNAL(valueChanged(int)),
-                this, SLOT(notesPanChanged(int)));
-        connect(m_panNotes, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredWidget()));
-        connect(m_panNotes, SIGNAL(mouseLeft()), this, SLOT(mouseLeftWidget()));    
-    }
-    
-    // End of Pan controls
 
     layout->setSpacing(4);
     layout->addWidget(m_overview, 0, 1);
@@ -1177,14 +1074,12 @@
     connect(m_showAudio, SIGNAL(triggered()), this, SLOT(showAudioToggled()));
     connect(this, SIGNAL(canPlay(bool)), m_showAudio, SLOT(setEnabled(bool)));
 
-    m_playAudio = toolbar->addAction(il.load("speaker"), tr("Play Audio"));
-    m_playAudio->setCheckable(true);
-    connect(m_playAudio, SIGNAL(triggered()), this, SLOT(playAudioToggled()));
-    connect(this, SIGNAL(canPlayWaveform(bool)), m_playAudio, SLOT(setEnabled(bool)));
-
-    toolbar->addWidget(m_gainAudio);
-    toolbar->addWidget(m_panAudio);
-
+    int lpwSize = m_viewManager->scalePixelSize(30);
+    
+    m_audioLPW->setFixedWidth(lpwSize);
+    m_audioLPW->setFixedHeight(lpwSize);
+    toolbar->addWidget(m_audioLPW);
+    
     // Pitch (f0)
     QLabel *spacer = new QLabel; // blank
     spacer->setFixedWidth(40);
@@ -1195,17 +1090,11 @@
     connect(m_showPitch, SIGNAL(triggered()), this, SLOT(showPitchToggled()));
     connect(this, SIGNAL(canPlay(bool)), m_showPitch, SLOT(setEnabled(bool)));
 
-    if (!m_withSonification) 
-    {
-        m_playPitch = new QAction(tr("Play Pitch Track"), this);
-    } else {
-        m_playPitch = toolbar->addAction(il.load("speaker"), tr("Play Pitch Track"));
-        toolbar->addWidget(m_gainPitch);
-        toolbar->addWidget(m_panPitch);
+    if (m_withSonification) {
+        m_pitchLPW->setFixedWidth(lpwSize);
+        m_pitchLPW->setFixedHeight(lpwSize);
+        toolbar->addWidget(m_pitchLPW);
     }
-    m_playPitch->setCheckable(true);
-    connect(m_playPitch, SIGNAL(triggered()), this, SLOT(playPitchToggled()));
-    connect(this, SIGNAL(canPlayPitch(bool)), m_playPitch, SLOT(setEnabled(bool)));
 
     // Notes
     spacer = new QLabel;
@@ -1217,17 +1106,11 @@
     connect(m_showNotes, SIGNAL(triggered()), this, SLOT(showNotesToggled()));
     connect(this, SIGNAL(canPlay(bool)), m_showNotes, SLOT(setEnabled(bool)));
 
-    if (!m_withSonification) 
-    {
-        m_playNotes = new QAction(tr("Play Notes"), this);
-    } else {
-        m_playNotes = toolbar->addAction(il.load("speaker"), tr("Play Notes"));
-        toolbar->addWidget(m_gainNotes);
-        toolbar->addWidget(m_panNotes);
+    if (m_withSonification) {
+        m_notesLPW->setFixedWidth(lpwSize);
+        m_notesLPW->setFixedHeight(lpwSize);
+        toolbar->addWidget(m_notesLPW);
     }
-    m_playNotes->setCheckable(true);
-    connect(m_playNotes, SIGNAL(triggered()), this, SLOT(playNotesToggled()));
-    connect(this, SIGNAL(canPlayNotes(bool)), m_playNotes, SLOT(setEnabled(bool)));
 
     // Spectrogram
     spacer = new QLabel;
@@ -1246,6 +1129,7 @@
 
     Pane::registerShortcuts(*m_keyReference);
 
+    updateLayerStatuses();
 }
 
 
@@ -1449,20 +1333,9 @@
 {
     m_analyser->toggleVisible(Analyser::Audio);
 
-    QSettings settings;
-    settings.beginGroup("MainWindow");
-
-    bool playOn = false;
-    if (m_analyser->isVisible(Analyser::Audio)) {
-        // just switched layer on; check whether playback was also on previously
-        playOn = settings.value("playaudiowas", true).toBool();
-    } else {
-        settings.setValue("playaudiowas", m_playAudio->isChecked());
-    }
+    bool playOn = (m_analyser->isVisible(Analyser::Audio));
     m_analyser->setAudible(Analyser::Audio, playOn);
-    m_playAudio->setChecked(playOn);
-
-    settings.endGroup();
+    m_audioLPW->setEnabled(playOn);
 
     updateMenuStates();
 }
@@ -1472,20 +1345,9 @@
 {
     m_analyser->toggleVisible(Analyser::PitchTrack);
 
-    QSettings settings;
-    settings.beginGroup("MainWindow");
-
-    bool playOn = false;
-    if (m_analyser->isVisible(Analyser::PitchTrack)) {
-        // just switched layer on; check whether playback was also on previously
-        playOn = settings.value("playpitchwas", true).toBool();
-    } else {
-        settings.setValue("playpitchwas", m_playPitch->isChecked());
-    }
+    bool playOn = (m_analyser->isVisible(Analyser::PitchTrack));
     m_analyser->setAudible(Analyser::PitchTrack, playOn && m_withSonification);
-    m_playPitch->setChecked(playOn);
-
-    settings.endGroup();
+    m_pitchLPW->setEnabled(playOn);
 
     updateMenuStates();
 }
@@ -1501,20 +1363,9 @@
 {
     m_analyser->toggleVisible(Analyser::Notes);
 
-    QSettings settings;
-    settings.beginGroup("MainWindow");
-
-    bool playOn = false;
-    if (m_analyser->isVisible(Analyser::Notes)) {
-        // just switched layer on; check whether playback was also on previously
-        playOn = settings.value("playnoteswas", true).toBool();
-    } else {
-        settings.setValue("playnoteswas", m_playNotes->isChecked());
-    }
+    bool playOn = (m_analyser->isVisible(Analyser::Notes));
     m_analyser->setAudible(Analyser::Notes, playOn && m_withSonification);
-    m_playNotes->setChecked(playOn);
-
-    settings.endGroup();
+    m_notesLPW->setEnabled(playOn);
 
     updateMenuStates();
 }
@@ -1541,12 +1392,21 @@
 MainWindow::updateLayerStatuses()
 {
     m_showAudio->setChecked(m_analyser->isVisible(Analyser::Audio));
+    m_audioLPW->setEnabled(m_analyser->isVisible(Analyser::Audio));
+    m_audioLPW->setLevel(m_analyser->getGain(Analyser::Audio));
+    m_audioLPW->setPan(m_analyser->getPan(Analyser::Audio));
+
+    m_showPitch->setChecked(m_analyser->isVisible(Analyser::PitchTrack));
+    m_pitchLPW->setEnabled(m_analyser->isVisible(Analyser::PitchTrack));
+    m_pitchLPW->setLevel(m_analyser->getGain(Analyser::PitchTrack));
+    m_pitchLPW->setPan(m_analyser->getPan(Analyser::PitchTrack));
+
+    m_showNotes->setChecked(m_analyser->isVisible(Analyser::Notes));
+    m_notesLPW->setEnabled(m_analyser->isVisible(Analyser::Notes));
+    m_notesLPW->setLevel(m_analyser->getGain(Analyser::Notes));
+    m_notesLPW->setPan(m_analyser->getPan(Analyser::Notes));
+
     m_showSpect->setChecked(m_analyser->isVisible(Analyser::Spectrogram));
-    m_showPitch->setChecked(m_analyser->isVisible(Analyser::PitchTrack));
-    m_showNotes->setChecked(m_analyser->isVisible(Analyser::Notes));
-    m_playAudio->setChecked(m_analyser->isAudible(Analyser::Audio));
-    m_playPitch->setChecked(m_analyser->isAudible(Analyser::PitchTrack));
-    m_playNotes->setChecked(m_analyser->isAudible(Analyser::Notes));
 }
 
 void
@@ -2699,240 +2559,60 @@
 }
 
 void
-MainWindow::audioGainChanged(int position)
+MainWindow::audioGainChanged(float gain)
 {
-    double level = m_gainAudio->mappedValue();
-    double gain = pow(10, level / 20.0);
-
-    cerr << "gain = " << gain << " (" << position << " dB)" << endl;
-
-    contextHelpChanged(tr("Audio Gain: %1 dB").arg(position));
-
-    m_analyser->setGain(Analyser::Audio, float(gain));
-
+    double db = AudioLevel::multiplier_to_dB(gain);
+    cerr << "gain = " << gain << " (" << db << " dB)" << endl;
+    contextHelpChanged(tr("Audio Gain: %1 dB").arg(db));
+    m_analyser->setGain(Analyser::Audio, gain);
     updateMenuStates();
 } 
 
 void
-MainWindow::increaseAudioGain()
+MainWindow::pitchGainChanged(float gain)
 {
-    int value = m_gainAudio->value();
-    value = value + m_gainAudio->pageStep();
-    if (value > m_gainAudio->maximum()) value = m_gainAudio->maximum();
-    m_gainAudio->setValue(value);
-}
-
-void
-MainWindow::decreaseAudioGain()
-{
-    int value = m_gainAudio->value();
-    value = value - m_gainAudio->pageStep();
-    if (value < m_gainAudio->minimum()) value = m_gainAudio->minimum();
-    m_gainAudio->setValue(value);
-}
-
-void
-MainWindow::restoreNormalAudioGain()
-{
-    m_gainAudio->setValue(m_gainAudio->defaultValue());
-}
-
-void
-MainWindow::pitchGainChanged(int position)
-{
-    double level = m_gainPitch->mappedValue();
-    double gain = pow(10, level / 20.0);
-
-    cerr << "gain = " << gain << " (" << position << " dB)" << endl;
-
-    contextHelpChanged(tr("Pitch Gain: %1 dB").arg(position));
-
-    m_analyser->setGain(Analyser::PitchTrack, float(gain));
-
+    double db = AudioLevel::multiplier_to_dB(gain);
+    cerr << "gain = " << gain << " (" << db << " dB)" << endl;
+    contextHelpChanged(tr("Pitch Gain: %1 dB").arg(db));
+    m_analyser->setGain(Analyser::PitchTrack, gain);
     updateMenuStates();
 } 
 
 void
-MainWindow::increasePitchGain()
+MainWindow::notesGainChanged(float gain)
 {
-    int value = m_gainPitch->value();
-    value = value + m_gainPitch->pageStep();
-    if (value > m_gainPitch->maximum()) value = m_gainPitch->maximum();
-    m_gainPitch->setValue(value);
-}
-
-void
-MainWindow::decreasePitchGain()
-{
-    int value = m_gainPitch->value();
-    value = value - m_gainPitch->pageStep();
-    if (value < m_gainPitch->minimum()) value = m_gainPitch->minimum();
-    m_gainPitch->setValue(value);
-}
-
-void
-MainWindow::restoreNormalPitchGain()
-{
-    m_gainPitch->setValue(m_gainPitch->defaultValue());
-}
-
-void
-MainWindow::notesGainChanged(int position)
-{
-    double level = m_gainNotes->mappedValue();
-    double gain = pow(10, level / 20.0);
-
-    cerr << "gain = " << gain << " (" << position << " dB)" << endl;
-
-    contextHelpChanged(tr("Notes Gain: %1 dB").arg(position));
-
-    m_analyser->setGain(Analyser::Notes, float(gain));
-
+    double db = AudioLevel::multiplier_to_dB(gain);
+    cerr << "gain = " << gain << " (" << db << " dB)" << endl;
+    contextHelpChanged(tr("Notes Gain: %1 dB").arg(db));
+    m_analyser->setGain(Analyser::Notes, gain);
     updateMenuStates();
 } 
 
 void
-MainWindow::increaseNotesGain()
+MainWindow::audioPanChanged(float pan)
 {
-    int value = m_gainNotes->value();
-    value = value + m_gainNotes->pageStep();
-    if (value > m_gainNotes->maximum()) value = m_gainNotes->maximum();
-    m_gainNotes->setValue(value);
-}
-
-void
-MainWindow::decreaseNotesGain()
-{
-    int value = m_gainNotes->value();
-    value = value - m_gainNotes->pageStep();
-    if (value < m_gainNotes->minimum()) value = m_gainNotes->minimum();
-    m_gainNotes->setValue(value);
-}
-
-void
-MainWindow::restoreNormalNotesGain()
-{
-    m_gainNotes->setValue(m_gainNotes->defaultValue());
-}
-
-void
-MainWindow::audioPanChanged(int position)
-{
-    double level = m_panAudio->mappedValue();
-    double pan = level/100.0;
-
-    cerr << "pan = " << pan << " (" << position << ")" << endl;
-
-    contextHelpChanged(tr("Audio Pan: %1").arg(position));
-
-    m_analyser->setPan(Analyser::Audio, float(pan));
-
+    contextHelpChanged(tr("Audio Pan: %1").arg(pan));
+    m_analyser->setPan(Analyser::Audio, pan);
     updateMenuStates();
 } 
 
 void
-MainWindow::increaseAudioPan()
+MainWindow::pitchPanChanged(float pan)
 {
-    int value = m_panAudio->value();
-    value = value + m_panAudio->pageStep();
-    if (value > m_panAudio->maximum()) value = m_panAudio->maximum();
-    m_panAudio->setValue(value);
-}
-
-void
-MainWindow::decreaseAudioPan()
-{
-    int value = m_panAudio->value();
-    value = value - m_panAudio->pageStep();
-    if (value < m_panAudio->minimum()) value = m_panAudio->minimum();
-    m_panAudio->setValue(value);
-}
-
-void
-MainWindow::restoreNormalAudioPan()
-{
-    m_panAudio->setValue(m_panAudio->defaultValue());
-}
-
-void
-MainWindow::pitchPanChanged(int position)
-{
-    double level = m_panPitch->mappedValue();
-    double pan = level/100.0;
-
-    cerr << "pan = " << pan << " (" << position << ")" << endl;
-
-    contextHelpChanged(tr("Pitch Pan: %1").arg(position));
-
-    m_analyser->setPan(Analyser::PitchTrack, float(pan));
-
+    contextHelpChanged(tr("Pitch Pan: %1").arg(pan));
+    m_analyser->setPan(Analyser::PitchTrack, pan);
     updateMenuStates();
 } 
 
 void
-MainWindow::increasePitchPan()
+MainWindow::notesPanChanged(float pan)
 {
-    int value = m_panPitch->value();
-    value = value + m_panPitch->pageStep();
-    if (value > m_panPitch->maximum()) value = m_panPitch->maximum();
-    m_panPitch->setValue(value);
-}
-
-void
-MainWindow::decreasePitchPan()
-{
-    int value = m_panPitch->value();
-    value = value - m_panPitch->pageStep();
-    if (value < m_panPitch->minimum()) value = m_panPitch->minimum();
-    m_panPitch->setValue(value);
-}
-
-void
-MainWindow::restoreNormalPitchPan()
-{
-    m_panPitch->setValue(m_panPitch->defaultValue());
-}
-
-void
-MainWindow::notesPanChanged(int position)
-{
-    double level = m_panNotes->mappedValue();
-    double pan = level/100.0;
-
-    cerr << "pan = " << pan << " (" << position << ")" << endl;
-
-    contextHelpChanged(tr("Notes Pan: %1").arg(position));
-
-    m_analyser->setPan(Analyser::Notes, float(pan));
-
+    contextHelpChanged(tr("Notes Pan: %1").arg(pan));
+    m_analyser->setPan(Analyser::Notes, pan);
     updateMenuStates();
 } 
 
 void
-MainWindow::increaseNotesPan()
-{
-    int value = m_panNotes->value();
-    value = value + m_panNotes->pageStep();
-    if (value > m_panNotes->maximum()) value = m_panNotes->maximum();
-    m_panNotes->setValue(value);
-}
-
-void
-MainWindow::decreaseNotesPan()
-{
-    int value = m_panNotes->value();
-    value = value - m_panNotes->pageStep();
-    if (value < m_panNotes->minimum()) value = m_panNotes->minimum();
-    m_panNotes->setValue(value);
-}
-
-void
-MainWindow::restoreNormalNotesPan()
-{
-    m_panNotes->setValue(m_panNotes->defaultValue());
-}
-
-void
 MainWindow::updateVisibleRangeDisplay(Pane *p) const
 {
     if (!getMainModel() || !p) {
--- a/src/MainWindow.h	Tue Mar 24 15:18:04 2015 +0000
+++ b/src/MainWindow.h	Tue Mar 24 16:03:52 2015 +0000
@@ -21,6 +21,7 @@
 
 class VersionTester;
 class ActivityLog;
+class LevelPanWidget;
 
 class MainWindow : public MainWindowBase
 {
@@ -103,35 +104,13 @@
     virtual void slowDownPlayback();
     virtual void restoreNormalPlayback();
 
-    virtual void audioGainChanged(int);
-    virtual void increaseAudioGain();
-    virtual void decreaseAudioGain();
-    virtual void restoreNormalAudioGain();
+    virtual void audioGainChanged(float);
+    virtual void pitchGainChanged(float);
+    virtual void notesGainChanged(float);
 
-    virtual void pitchGainChanged(int);
-    virtual void increasePitchGain();
-    virtual void decreasePitchGain();
-    virtual void restoreNormalPitchGain();
-
-    virtual void notesGainChanged(int);
-    virtual void increaseNotesGain();
-    virtual void decreaseNotesGain();
-    virtual void restoreNormalNotesGain();
-
-    virtual void audioPanChanged(int);
-    virtual void increaseAudioPan();
-    virtual void decreaseAudioPan();
-    virtual void restoreNormalAudioPan();
-
-    virtual void pitchPanChanged(int);
-    virtual void increasePitchPan();
-    virtual void decreasePitchPan();
-    virtual void restoreNormalPitchPan();
-
-    virtual void notesPanChanged(int);
-    virtual void increaseNotesPan();
-    virtual void decreaseNotesPan();
-    virtual void restoreNormalNotesPan();
+    virtual void audioPanChanged(float);
+    virtual void pitchPanChanged(float);
+    virtual void notesPanChanged(float);
 
     virtual void sampleRateMismatch(sv_samplerate_t, sv_samplerate_t, bool);
     virtual void audioOverloadPluginDisabled();
@@ -217,15 +196,9 @@
     QAction       *m_showSpect;
     QAction       *m_showPitch;
     QAction       *m_showNotes;
-    QAction       *m_playAudio;
-    QAction       *m_playPitch;
-    QAction       *m_playNotes;
-    AudioDial     *m_gainAudio;
-    AudioDial     *m_gainPitch;
-    AudioDial     *m_gainNotes;
-    AudioDial     *m_panAudio;
-    AudioDial     *m_panPitch;
-    AudioDial     *m_panNotes;
+    LevelPanWidget *m_audioLPW;
+    LevelPanWidget *m_pitchLPW;
+    LevelPanWidget *m_notesLPW;
     
     ActivityLog   *m_activityLog;
     KeyReference  *m_keyReference;