# HG changeset patch # User Chris Cannam # Date 1161085334 0 # Node ID 1016a8ceceda027539b028ffe694a7cd17ebe237 # Parent f7cb156508ccfd3cb95e53d4604bc2a36b0826de * Introduce PlaySpeedRangeMapper for playback speed dial diff -r f7cb156508cc -r 1016a8ceceda audioio/PlaySpeedRangeMapper.cpp --- /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 + + +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 "%"; +} diff -r f7cb156508cc -r 1016a8ceceda audioio/PlaySpeedRangeMapper.h --- /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 diff -r f7cb156508cc -r 1016a8ceceda main/MainWindow.cpp --- 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 ? "+" : "-") diff -r f7cb156508cc -r 1016a8ceceda sv.pro --- 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 \