changeset 59:1016a8ceceda

* Introduce PlaySpeedRangeMapper for playback speed dial
author Chris Cannam
date Tue, 17 Oct 2006 11:42:14 +0000
parents f7cb156508cc
children 06b3c3f437e6
files audioio/PlaySpeedRangeMapper.cpp audioio/PlaySpeedRangeMapper.h main/MainWindow.cpp sv.pro
diffstat 4 files changed, 177 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/audioio/PlaySpeedRangeMapper.cpp	Tue Oct 17 11:42:14 2006 +0000
@@ -0,0 +1,121 @@
+/* -*- 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 file copyright 2006 Chris Cannam.
+    
+    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 "PlaySpeedRangeMapper.h"
+
+#include <iostream>
+
+
+PlaySpeedRangeMapper::PlaySpeedRangeMapper(int minpos, int maxpos) :
+    m_minpos(minpos),
+    m_maxpos(maxpos)
+{
+}
+
+int
+PlaySpeedRangeMapper::getPositionForValue(float value) const
+{
+    // value is percent
+
+    float factor = getFactorForValue(value);
+
+    bool slow = (factor > 1.0);
+
+    if (!slow) factor = 1.0 / factor;
+    
+    int half = (m_maxpos + m_minpos) / 2;
+
+    factor = sqrtf((factor - 1.0) * 1000.f);
+    int position = lrintf(((factor * (half - m_minpos)) / 100.0) + m_minpos);
+
+    if (slow) {
+        position = half - position;
+    } else {
+        position = position + half;
+    }
+
+//    std::cerr << "value = " << value << " slow = " << slow << " factor = " << factor << " position = " << position << std::endl;
+
+    return position;
+}
+
+float
+PlaySpeedRangeMapper::getValueForPosition(int position) const
+{
+    float factor = getFactorForPosition(position);
+    float pc;
+    if (factor < 1.0) pc = ((1.0 / factor) - 1.0) * 100.0;
+    else pc = (1.0 - factor) * 100.0;
+//    std::cerr << "position = " << position << " percent = " << pc << std::endl;
+    return pc;
+}
+
+float
+PlaySpeedRangeMapper::getFactorForValue(float value) const
+{
+    // value is percent
+    
+    float factor;
+
+    if (value <= 0) {
+        factor = 1.0 - (value / 100.0);
+    } else {
+        factor = 1.0 / (1.0 + (value / 100.0));
+    }
+
+//    std::cerr << "value = " << value << " factor = " << factor << std::endl;
+    return factor;
+}
+
+float
+PlaySpeedRangeMapper::getFactorForPosition(int position) const
+{
+    bool slow = false;
+
+    if (position < m_minpos) position = m_minpos;
+    if (position > m_maxpos) position = m_maxpos;
+
+    int half = (m_maxpos + m_minpos) / 2;
+
+    if (position < half) {
+        slow = true;
+        position = half - position;
+    } else {
+        position = position - half;
+    }
+
+    // position is between min and half (inclusive)
+
+    float factor;
+
+    if (position == m_minpos) {
+        factor = 1.0;
+    } else {
+        factor = ((position - m_minpos) * 100.0) / (half - m_minpos);
+        factor = 1.0 + (factor * factor) / 1000.f;
+    }
+
+    if (!slow) factor = 1.0 / factor;
+
+//    std::cerr << "position = " << position << " slow = " << slow << " factor = " << factor << std::endl;
+
+    return factor;
+}
+
+QString
+PlaySpeedRangeMapper::getUnit() const
+{
+    return "%";
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/audioio/PlaySpeedRangeMapper.h	Tue Oct 17 11:42:14 2006 +0000
@@ -0,0 +1,40 @@
+/* -*- 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 file copyright 2006 Chris Cannam.
+    
+    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 _PLAY_SPEED_RANGE_MAPPER_H_
+#define _PLAY_SPEED_RANGE_MAPPER_H_
+
+#include "base/RangeMapper.h"
+
+class PlaySpeedRangeMapper : public RangeMapper
+{
+public:
+    PlaySpeedRangeMapper(int minpos, int maxpos);
+
+    virtual int getPositionForValue(float value) const;
+    virtual float getValueForPosition(int position) const;
+
+    float getFactorForPosition(int position) const;
+    float getFactorForValue(float value) const;
+
+    virtual QString getUnit() const;
+    
+protected:
+    int m_minpos;
+    int m_maxpos;
+};
+
+
+#endif
--- a/main/MainWindow.cpp	Tue Oct 17 11:41:56 2006 +0000
+++ b/main/MainWindow.cpp	Tue Oct 17 11:42:14 2006 +0000
@@ -41,6 +41,7 @@
 #include "audioio/AudioCallbackPlaySource.h"
 #include "audioio/AudioCallbackPlayTarget.h"
 #include "audioio/AudioTargetFactory.h"
+#include "audioio/PlaySpeedRangeMapper.h"
 #include "data/fileio/AudioFileReaderFactory.h"
 #include "data/fileio/DataFileReaderFactory.h"
 #include "data/fileio/WavFileWriter.h"
@@ -177,7 +178,9 @@
     m_playSpeed->setNotchesVisible(true);
     m_playSpeed->setPageStep(10);
     m_playSpeed->setToolTip(tr("Playback speed: +0%"));
+    m_playSpeed->setObjectName(tr("Playback Speed"));
     m_playSpeed->setDefaultValue(100);
+    m_playSpeed->setRangeMapper(new PlaySpeedRangeMapper(0, 200));
     connect(m_playSpeed, SIGNAL(valueChanged(int)),
 	    this, SLOT(playSpeedChanged(int)));
 
@@ -3079,34 +3082,18 @@
 }
 
 void
-MainWindow::playSpeedChanged(int speed)
+MainWindow::playSpeedChanged(int position)
 {
-    bool slow = false;
-    bool something = false;
-    float factor;
-
-    if (speed < 100) {
-        slow = true;
-        speed = 100 - speed;
-    } else {
-        speed = speed - 100;
-    }
-
-    // speed is 0 -> 100
-
-    if (speed == 0) {
-        factor = 1.0;
-    } else {
-        factor = speed;
-        factor = 1.0 + (factor * factor) / 1000.f;
-        something = true;
-    }
-
-    int pc = lrintf((factor - 1.0) * 100);
-
-    if (!slow) factor = 1.0 / factor;
-
-    std::cerr << "speed = " << speed << " factor = " << factor << std::endl;
+    PlaySpeedRangeMapper mapper(0, 200);
+    float factor = mapper.getFactorForPosition(position);
+    float percent = mapper.getValueForPosition(position);
+
+//    std::cerr << "speed = " << position << " factor = " << factor << std::endl;
+
+    bool slow = (position < 100);
+    bool something = (position != 100);
+
+    int pc = lrintf(percent);
 
     m_playSpeed->setToolTip(tr("Playback speed: %1%2%")
                             .arg(!slow ? "+" : "-")
--- a/sv.pro	Tue Oct 17 11:41:56 2006 +0000
+++ b/sv.pro	Tue Oct 17 11:42:14 2006 +0000
@@ -37,6 +37,7 @@
            audioio/AudioPortAudioTarget.h \
            audioio/AudioTargetFactory.h \
            audioio/PhaseVocoderTimeStretcher.h \
+           audioio/PlaySpeedRangeMapper.h \
            document/Document.h \
            document/SVFileReader.h \
            main/MainWindow.h \
@@ -54,6 +55,7 @@
            audioio/AudioPortAudioTarget.cpp \
            audioio/AudioTargetFactory.cpp \
            audioio/PhaseVocoderTimeStretcher.cpp \
+           audioio/PlaySpeedRangeMapper.cpp \
            document/Document.cpp \
            document/SVFileReader.cpp \
            main/main.cpp \