changeset 449:12d982e52190

Merge from branch tonioni
author Chris Cannam
date Mon, 20 Apr 2015 09:21:08 +0100
parents 9876a1db566c (current diff) b36042cb972a (diff)
children d9d132c0e240 dc1a360f2b69
files
diffstat 26 files changed, 730 insertions(+), 384 deletions(-) [+]
line wrap: on
line diff
--- a/acinclude.m4	Mon Mar 02 17:20:23 2015 +0000
+++ b/acinclude.m4	Mon Apr 20 09:21:08 2015 +0100
@@ -112,3 +112,146 @@
 
 ])
 
+# From autoconf archive:
+
+# ============================================================================
+#  http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html
+# ============================================================================
+#
+# SYNOPSIS
+#
+#   AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional])
+#
+# DESCRIPTION
+#
+#   Check for baseline language coverage in the compiler for the C++11
+#   standard; if necessary, add switches to CXXFLAGS to enable support.
+#
+#   The first argument, if specified, indicates whether you insist on an
+#   extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
+#   -std=c++11).  If neither is specified, you get whatever works, with
+#   preference for an extended mode.
+#
+#   The second argument, if specified 'mandatory' or if left unspecified,
+#   indicates that baseline C++11 support is required and that the macro
+#   should error out if no mode with that support is found.  If specified
+#   'optional', then configuration proceeds regardless, after defining
+#   HAVE_CXX11 if and only if a supporting mode is found.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
+#   Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
+#   Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
+#   Copyright (c) 2014 Alexey Sokolov <sokolov@google.com>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [[
+  template <typename T>
+    struct check
+    {
+      static_assert(sizeof(int) <= sizeof(T), "not big enough");
+    };
+
+    struct Base {
+    virtual void f() {}
+    };
+    struct Child : public Base {
+    virtual void f() override {}
+    };
+
+    typedef check<check<bool>> right_angle_brackets;
+
+    int a;
+    decltype(a) b;
+
+    typedef check<int> check_type;
+    check_type c;
+    check_type&& cr = static_cast<check_type&&>(c);
+
+    auto d = a;
+    auto l = [](){};
+]])
+
+AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl
+  m4_if([$1], [], [],
+        [$1], [ext], [],
+        [$1], [noext], [],
+        [m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl
+  m4_if([$2], [], [ax_cxx_compile_cxx11_required=true],
+        [$2], [mandatory], [ax_cxx_compile_cxx11_required=true],
+        [$2], [optional], [ax_cxx_compile_cxx11_required=false],
+        [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])])
+  AC_LANG_PUSH([C++])dnl
+  ac_success=no
+  AC_CACHE_CHECK(whether $CXX supports C++11 features by default,
+  ax_cv_cxx_compile_cxx11,
+  [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
+    [ax_cv_cxx_compile_cxx11=yes],
+    [ax_cv_cxx_compile_cxx11=no])])
+  if test x$ax_cv_cxx_compile_cxx11 = xyes; then
+    ac_success=yes
+  fi
+
+  m4_if([$1], [noext], [], [dnl
+  if test x$ac_success = xno; then
+    for switch in -std=gnu++11 -std=gnu++0x; do
+      cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
+      AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
+                     $cachevar,
+        [ac_save_CXXFLAGS="$CXXFLAGS"
+         CXXFLAGS="$CXXFLAGS $switch"
+         AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
+          [eval $cachevar=yes],
+          [eval $cachevar=no])
+         CXXFLAGS="$ac_save_CXXFLAGS"])
+      if eval test x\$$cachevar = xyes; then
+        CXXFLAGS="$CXXFLAGS $switch"
+        ac_success=yes
+        break
+      fi
+    done
+  fi])
+
+  m4_if([$1], [ext], [], [dnl
+  if test x$ac_success = xno; then
+    for switch in -std=c++11 -std=c++0x; do
+      cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
+      AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
+                     $cachevar,
+        [ac_save_CXXFLAGS="$CXXFLAGS"
+         CXXFLAGS="$CXXFLAGS $switch"
+         AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
+          [eval $cachevar=yes],
+          [eval $cachevar=no])
+         CXXFLAGS="$ac_save_CXXFLAGS"])
+      if eval test x\$$cachevar = xyes; then
+        CXXFLAGS="$CXXFLAGS $switch"
+        ac_success=yes
+        break
+      fi
+    done
+  fi])
+  AC_LANG_POP([C++])
+  if test x$ax_cxx_compile_cxx11_required = xtrue; then
+    if test x$ac_success = xno; then
+      AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.])
+    fi
+  else
+    if test x$ac_success = xno; then
+      HAVE_CXX11=0
+      AC_MSG_NOTICE([No compiler with C++11 support was found])
+    else
+      HAVE_CXX11=1
+      AC_DEFINE(HAVE_CXX11,1,
+                [define if the compiler supports basic C++11 syntax])
+    fi
+
+    AC_SUBST(HAVE_CXX11)
+  fi
+])
+
--- a/audioio/AudioCallbackPlaySource.cpp	Mon Mar 02 17:20:23 2015 +0000
+++ b/audioio/AudioCallbackPlaySource.cpp	Mon Apr 20 09:21:08 2015 +0100
@@ -149,7 +149,7 @@
 {
     if (m_models.find(model) != m_models.end()) return;
 
-    bool canPlay = m_audioGenerator->addModel(model);
+    bool willPlay = m_audioGenerator->addModel(model);
 
     m_mutex.lock();
 
@@ -225,7 +225,7 @@
 	clearRingBuffers(true, getTargetChannelCount());
 	buffersChanged = true;
     } else {
-	if (canPlay) clearRingBuffers(true);
+	if (willPlay) clearRingBuffers(true);
     }
 
     if (buffersChanged || srChanged) {
@@ -256,8 +256,8 @@
 	emit modelReplaced();
     }
 
-    connect(model, SIGNAL(modelChangedWithin(int, int)),
-            this, SLOT(modelChangedWithin(int, int)));
+    connect(model, SIGNAL(modelChangedWithin(sv_frame_t, sv_frame_t)),
+            this, SLOT(modelChangedWithin(sv_frame_t, sv_frame_t)));
 
 #ifdef DEBUG_AUDIO_PLAY_SOURCE
     cout << "AudioCallbackPlaySource::addModel: awakening thread" << endl;
@@ -267,11 +267,11 @@
 }
 
 void
-AudioCallbackPlaySource::modelChangedWithin(int 
+AudioCallbackPlaySource::modelChangedWithin(sv_frame_t 
 #ifdef DEBUG_AUDIO_PLAY_SOURCE
                                             startFrame
 #endif
-                                            , int endFrame)
+                                            , sv_frame_t endFrame)
 {
 #ifdef DEBUG_AUDIO_PLAY_SOURCE
     SVDEBUG << "AudioCallbackPlaySource::modelChangedWithin(" << startFrame << "," << endFrame << ")" << endl;
@@ -291,8 +291,8 @@
     cout << "AudioCallbackPlaySource::removeModel(" << model << ")" << endl;
 #endif
 
-    disconnect(model, SIGNAL(modelChangedWithin(int, int)),
-               this, SLOT(modelChangedWithin(int, int)));
+    disconnect(model, SIGNAL(modelChangedWithin(sv_frame_t, sv_frame_t)),
+               this, SLOT(modelChangedWithin(sv_frame_t, sv_frame_t)));
 
     m_models.erase(model);
 
@@ -306,7 +306,7 @@
 	m_sourceSampleRate = 0;
     }
 
-    int lastEnd = 0;
+    sv_frame_t lastEnd = 0;
     for (std::set<Model *>::const_iterator i = m_models.begin();
 	 i != m_models.end(); ++i) {
 #ifdef DEBUG_AUDIO_PLAY_SOURCE
@@ -362,21 +362,27 @@
 {
     if (!haveLock) m_mutex.lock();
 
+#ifdef DEBUG_AUDIO_PLAY_SOURCE
     cerr << "clearRingBuffers" << endl;
+#endif
 
     rebuildRangeLists();
 
     if (count == 0) {
-	if (m_writeBuffers) count = m_writeBuffers->size();
+	if (m_writeBuffers) count = int(m_writeBuffers->size());
     }
 
+#ifdef DEBUG_AUDIO_PLAY_SOURCE
     cerr << "current playing frame = " << getCurrentPlayingFrame() << endl;
 
     cerr << "write buffer fill (before) = " << m_writeBufferFill << endl;
-
+#endif
+    
     m_writeBufferFill = getCurrentBufferedFrame();
 
+#ifdef DEBUG_AUDIO_PLAY_SOURCE
     cerr << "current buffered frame = " << m_writeBufferFill << endl;
+#endif
 
     if (m_readBuffers != m_writeBuffers) {
 	delete m_writeBuffers;
@@ -388,6 +394,8 @@
 	m_writeBuffers->push_back(new RingBuffer<float>(m_ringBufferSize));
     }
 
+    m_audioGenerator->reset();
+    
 //    cout << "AudioCallbackPlaySource::clearRingBuffers: Created "
 //	      << count << " write buffers" << endl;
 
@@ -397,7 +405,7 @@
 }
 
 void
-AudioCallbackPlaySource::play(int startFrame)
+AudioCallbackPlaySource::play(sv_frame_t startFrame)
 {
     if (!m_sourceSampleRate) {
         cerr << "AudioCallbackPlaySource::play: No source sample rate available, not playing" << endl;
@@ -593,29 +601,29 @@
 AudioCallbackPlaySource::getTargetBlockSize() const
 {
 //    cout << "AudioCallbackPlaySource::getTargetBlockSize() -> " << m_blockSize << endl;
-    return m_blockSize;
+    return int(m_blockSize);
 }
 
 void
-AudioCallbackPlaySource::setTargetPlayLatency(int latency)
+AudioCallbackPlaySource::setTargetPlayLatency(sv_frame_t latency)
 {
     m_playLatency = latency;
 }
 
-int
+sv_frame_t
 AudioCallbackPlaySource::getTargetPlayLatency() const
 {
     return m_playLatency;
 }
 
-int
+sv_frame_t
 AudioCallbackPlaySource::getCurrentPlayingFrame()
 {
     // This method attempts to estimate which audio sample frame is
     // "currently coming through the speakers".
 
-    int targetRate = getTargetSampleRate();
-    int latency = m_playLatency; // at target rate
+    sv_samplerate_t targetRate = getTargetSampleRate();
+    sv_frame_t latency = m_playLatency; // at target rate
     RealTime latency_t = RealTime::zeroTime;
 
     if (targetRate != 0) {
@@ -625,13 +633,13 @@
     return getCurrentFrame(latency_t);
 }
 
-int
+sv_frame_t
 AudioCallbackPlaySource::getCurrentBufferedFrame()
 {
     return getCurrentFrame(RealTime::zeroTime);
 }
 
-int
+sv_frame_t
 AudioCallbackPlaySource::getCurrentFrame(RealTime latency_t)
 {
     // We resample when filling the ring buffer, and time-stretch when
@@ -640,8 +648,8 @@
     // Because of the multiple rates involved, we do the actual
     // calculation using RealTime instead.
 
-    int sourceRate = getSourceSampleRate();
-    int targetRate = getTargetSampleRate();
+    sv_samplerate_t sourceRate = getSourceSampleRate();
+    sv_samplerate_t targetRate = getTargetSampleRate();
 
     if (sourceRate == 0 || targetRate == 0) return 0;
 
@@ -655,8 +663,8 @@
 	}
     }
 
-    int readBufferFill = m_readBufferFill;
-    int lastRetrievedBlockSize = m_lastRetrievedBlockSize;
+    sv_frame_t readBufferFill = m_readBufferFill;
+    sv_frame_t lastRetrievedBlockSize = m_lastRetrievedBlockSize;
     double lastRetrievalTimestamp = m_lastRetrievalTimestamp;
     double currentTime = 0.0;
     if (m_target) currentTime = m_target->getCurrentTime();
@@ -665,7 +673,7 @@
 
     RealTime inbuffer_t = RealTime::frame2RealTime(inbuffer, targetRate);
 
-    int stretchlat = 0;
+    sv_frame_t stretchlat = 0;
     double timeRatio = 1.0;
 
     if (m_timeStretcher) {
@@ -739,7 +747,7 @@
             - latency_t - stretchlat_t - lastretrieved_t - inbuffer_t
             + sincerequest_t;
         if (playing_t < RealTime::zeroTime) playing_t = RealTime::zeroTime;
-        int frame = RealTime::realTime2Frame(playing_t, sourceRate);
+        sv_frame_t frame = RealTime::realTime2Frame(playing_t, sourceRate);
         return m_viewManager->alignPlaybackFrameToReference(frame);
     }
 
@@ -755,7 +763,9 @@
         ++index;
     }
 
-    if (inRange >= (int)m_rangeStarts.size()) inRange = m_rangeStarts.size()-1;
+    if (inRange >= int(m_rangeStarts.size())) {
+        inRange = int(m_rangeStarts.size())-1;
+    }
 
     RealTime playing_t = bufferedto_t;
 
@@ -806,7 +816,7 @@
 
         if (inRange == 0) {
             if (looping) {
-                inRange = m_rangeStarts.size() - 1;
+                inRange = int(m_rangeStarts.size()) - 1;
             } else {
                 break;
             }
@@ -833,7 +843,7 @@
 
     if (playing_t < RealTime::zeroTime) playing_t = RealTime::zeroTime;
 
-    int frame = RealTime::realTime2Frame(playing_t, sourceRate);
+    sv_frame_t frame = RealTime::realTime2Frame(playing_t, sourceRate);
 
     if (m_lastCurrentFrame > 0 && !looping) {
         if (frame < m_lastCurrentFrame) {
@@ -854,7 +864,7 @@
     m_rangeStarts.clear();
     m_rangeDurations.clear();
 
-    int sourceRate = getSourceSampleRate();
+    sv_samplerate_t sourceRate = getSourceSampleRate();
     if (sourceRate == 0) return;
 
     RealTime end = RealTime::frame2RealTime(m_lastModelEndFrame, sourceRate);
@@ -916,7 +926,7 @@
 }
 
 void
-AudioCallbackPlaySource::setTargetSampleRate(int sr)
+AudioCallbackPlaySource::setTargetSampleRate(sv_samplerate_t sr)
 {
     bool first = (m_targetSampleRate == 0);
 
@@ -1033,7 +1043,7 @@
     clearRingBuffers();
 }
 
-int
+sv_samplerate_t
 AudioCallbackPlaySource::getTargetSampleRate() const
 {
     if (m_targetSampleRate) return m_targetSampleRate;
@@ -1053,35 +1063,35 @@
     return m_sourceChannelCount;
 }
 
-int
+sv_samplerate_t
 AudioCallbackPlaySource::getSourceSampleRate() const
 {
     return m_sourceSampleRate;
 }
 
 void
-AudioCallbackPlaySource::setTimeStretch(float factor)
+AudioCallbackPlaySource::setTimeStretch(double factor)
 {
     m_stretchRatio = factor;
 
     if (!getTargetSampleRate()) return; // have to make our stretcher later
 
-    if (m_timeStretcher || (factor == 1.f)) {
+    if (m_timeStretcher || (factor == 1.0)) {
         // stretch ratio will be set in next process call if appropriate
     } else {
         m_stretcherInputCount = getTargetChannelCount();
         RubberBandStretcher *stretcher = new RubberBandStretcher
-            (getTargetSampleRate(),
+            (int(getTargetSampleRate()),
              m_stretcherInputCount,
              RubberBandStretcher::OptionProcessRealTime,
              factor);
         RubberBandStretcher *monoStretcher = new RubberBandStretcher
-            (getTargetSampleRate(),
+            (int(getTargetSampleRate()),
              1,
              RubberBandStretcher::OptionProcessRealTime,
              factor);
         m_stretcherInputs = new float *[m_stretcherInputCount];
-        m_stretcherInputSizes = new int[m_stretcherInputCount];
+        m_stretcherInputSizes = new sv_frame_t[m_stretcherInputCount];
         for (int c = 0; c < m_stretcherInputCount; ++c) {
             m_stretcherInputSizes[c] = 16384;
             m_stretcherInputs[c] = new float[m_stretcherInputSizes[c]];
@@ -1093,11 +1103,9 @@
     emit activity(tr("Change time-stretch factor to %1").arg(factor));
 }
 
-int
-AudioCallbackPlaySource::getSourceSamples(int ucount, float **buffer)
+sv_frame_t
+AudioCallbackPlaySource::getSourceSamples(sv_frame_t count, float **buffer)
 {
-    int count = ucount;
-
     if (!m_playing) {
 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
         SVDEBUG << "AudioCallbackPlaySource::getSourceSamples: Not playing" << endl;
@@ -1148,12 +1156,12 @@
     RubberBandStretcher *ts = m_timeStretcher;
     RubberBandStretcher *ms = m_monoStretcher;
 
-    float ratio = ts ? ts->getTimeRatio() : 1.f;
+    double ratio = ts ? ts->getTimeRatio() : 1.0;
 
     if (ratio != m_stretchRatio) {
         if (!ts) {
             cerr << "WARNING: AudioCallbackPlaySource::getSourceSamples: Time ratio change to " << m_stretchRatio << " is pending, but no stretcher is set" << endl;
-            m_stretchRatio = 1.f;
+            m_stretchRatio = 1.0;
         } else {
             ts->setTimeRatio(m_stretchRatio);
             if (ms) ms->setTimeRatio(m_stretchRatio);
@@ -1188,10 +1196,10 @@
 
 		// this is marginally more likely to leave our channels in
 		// sync after a processing failure than just passing "count":
-		int request = count;
+		sv_frame_t request = count;
 		if (ch > 0) request = got;
 
-		got = rb->read(buffer[ch], request);
+		got = rb->read(buffer[ch], int(request));
 	    
 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
 		cout << "AudioCallbackPlaySource::getSamples: got " << got << " (of " << count << ") samples on channel " << ch << ", signalling for more (possibly)" << endl;
@@ -1217,20 +1225,20 @@
     }
 
     int channels = getTargetChannelCount();
-    int available;
+    sv_frame_t available;
+    sv_frame_t fedToStretcher = 0;
     int warned = 0;
-    int fedToStretcher = 0;
 
     // The input block for a given output is approx output / ratio,
     // but we can't predict it exactly, for an adaptive timestretcher.
 
     while ((available = ts->available()) < count) {
 
-        int reqd = lrintf((count - available) / ratio);
-        reqd = std::max(reqd, (int)ts->getSamplesRequired());
+        sv_frame_t reqd = lrint(double(count - available) / ratio);
+        reqd = std::max(reqd, sv_frame_t(ts->getSamplesRequired()));
         if (reqd == 0) reqd = 1;
                 
-        int got = reqd;
+        sv_frame_t got = reqd;
 
 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING
         cerr << "reqd = " <<reqd << ", channels = " << channels << ", ic = " << m_stretcherInputCount << endl;
@@ -1252,11 +1260,11 @@
             if (c >= m_stretcherInputCount) continue;
             RingBuffer<float> *rb = getReadRingBuffer(c);
             if (rb) {
-                int gotHere;
+                sv_frame_t gotHere;
                 if (stretchChannels == 1 && c > 0) {
-                    gotHere = rb->readAdding(m_stretcherInputs[0], got);
+                    gotHere = rb->readAdding(m_stretcherInputs[0], int(got));
                 } else {
-                    gotHere = rb->read(m_stretcherInputs[c], got);
+                    gotHere = rb->read(m_stretcherInputs[c], int(got));
                 }
                 if (gotHere < got) got = gotHere;
                 
@@ -1309,7 +1317,7 @@
 }
 
 void
-AudioCallbackPlaySource::applyAuditioningEffect(int count, float **buffers)
+AudioCallbackPlaySource::applyAuditioningEffect(sv_frame_t count, float **buffers)
 {
     if (m_auditioningPluginBypassed) return;
     RealTimePluginInstance *plugin = m_auditioningPlugin;
@@ -1343,7 +1351,7 @@
         }
     }
 
-    plugin->run(Vamp::RealTime::zeroTime, count);
+    plugin->run(Vamp::RealTime::zeroTime, int(count));
     
     for (int c = 0; c < getTargetChannelCount(); ++c) {
         for (int i = 0; i < count; ++i) {
@@ -1357,13 +1365,13 @@
 AudioCallbackPlaySource::fillBuffers()
 {
     static float *tmp = 0;
-    static int tmpSize = 0;
+    static sv_frame_t tmpSize = 0;
 
-    int space = 0;
+    sv_frame_t space = 0;
     for (int c = 0; c < getTargetChannelCount(); ++c) {
 	RingBuffer<float> *wb = getWriteRingBuffer(c);
 	if (wb) {
-	    int spaceHere = wb->getWriteSpace();
+	    sv_frame_t spaceHere = wb->getWriteSpace();
 	    if (c == 0 || spaceHere < space) space = spaceHere;
 	}
     }
@@ -1375,7 +1383,7 @@
         return false;
     }
 
-    int f = m_writeBufferFill;
+    sv_frame_t f = m_writeBufferFill;
 	
     bool readWriteEqual = (m_readBuffers == m_writeBuffers);
 
@@ -1398,8 +1406,8 @@
 
     int channels = getTargetChannelCount();
 
-    int orig = space;
-    int got = 0;
+    sv_frame_t orig = space;
+    sv_frame_t got = 0;
 
     static float **bufferPtrs = 0;
     static int bufferPtrCount = 0;
@@ -1410,7 +1418,7 @@
 	bufferPtrCount = channels;
     }
 
-    int generatorBlockSize = m_audioGenerator->getBlockSize();
+    sv_frame_t generatorBlockSize = m_audioGenerator->getBlockSize();
 
     if (resample && !m_converter) {
 	static bool warned = false;
@@ -1424,13 +1432,13 @@
 
 	double ratio =
 	    double(getTargetSampleRate()) / double(getSourceSampleRate());
-	orig = int(orig / ratio + 0.1);
+	orig = sv_frame_t(double(orig) / ratio + 0.1);
 
 	// orig must be a multiple of generatorBlockSize
 	orig = (orig / generatorBlockSize) * generatorBlockSize;
 	if (orig == 0) return false;
 
-	int work = std::max(orig, space);
+	sv_frame_t work = std::max(orig, space);
 
 	// We only allocate one buffer, but we use it in two halves.
 	// We place the non-interleaved values in the second half of
@@ -1492,7 +1500,7 @@
             err = src_process(m_converter, &data);
         }
 
-	int toCopy = int(got * ratio + 0.1);
+	sv_frame_t toCopy = sv_frame_t(double(got) * ratio + 0.1);
 
 	if (err) {
 	    cerr
@@ -1512,7 +1520,7 @@
 		tmp[i] = srcout[channels * i + c];
 	    }
 	    RingBuffer<float> *wb = getWriteRingBuffer(c);
-	    if (wb) wb->write(tmp, toCopy);
+	    if (wb) wb->write(tmp, int(toCopy));
 	}
 
 	m_writeBufferFill = f;
@@ -1521,7 +1529,7 @@
     } else {
 
 	// space must be a multiple of generatorBlockSize
-        int reqSpace = space;
+        sv_frame_t reqSpace = space;
 	space = (reqSpace / generatorBlockSize) * generatorBlockSize;
 	if (space == 0) {
 #ifdef DEBUG_AUDIO_PLAY_SOURCE
@@ -1547,13 +1555,13 @@
 	    }
 	}
 
-	int got = mixModels(f, space, bufferPtrs); // also modifies f
+	sv_frame_t got = mixModels(f, space, bufferPtrs); // also modifies f
 
 	for (int c = 0; c < channels; ++c) {
 
 	    RingBuffer<float> *wb = getWriteRingBuffer(c);
 	    if (wb) {
-                int actual = wb->write(bufferPtrs[c], got);
+                int actual = wb->write(bufferPtrs[c], int(got));
 #ifdef DEBUG_AUDIO_PLAY_SOURCE
 		cout << "Wrote " << actual << " samples for ch " << c << ", now "
 			  << wb->getReadSpace() << " to read" 
@@ -1580,14 +1588,14 @@
     return true;
 }    
 
-int
-AudioCallbackPlaySource::mixModels(int &frame, int count, float **buffers)
+sv_frame_t
+AudioCallbackPlaySource::mixModels(sv_frame_t &frame, sv_frame_t count, float **buffers)
 {
-    int processed = 0;
-    int chunkStart = frame;
-    int chunkSize = count;
-    int selectionSize = 0;
-    int nextChunkStart = chunkStart + chunkSize;
+    sv_frame_t processed = 0;
+    sv_frame_t chunkStart = frame;
+    sv_frame_t chunkSize = count;
+    sv_frame_t selectionSize = 0;
+    sv_frame_t nextChunkStart = chunkStart + chunkSize;
     
     bool looping = m_viewManager->getPlayLoopMode();
     bool constrained = (m_viewManager->getPlaySelectionMode() &&
@@ -1617,11 +1625,11 @@
 	nextChunkStart = chunkStart + chunkSize;
 	selectionSize = 0;
 
-	int fadeIn = 0, fadeOut = 0;
+	sv_frame_t fadeIn = 0, fadeOut = 0;
 
 	if (constrained) {
 
-            int rChunkStart =
+            sv_frame_t rChunkStart =
                 m_viewManager->alignPlaybackFrameToReference(chunkStart);
 	    
 	    Selection selection =
@@ -1643,9 +1651,9 @@
 
 	    } else {
 
-                int sf = m_viewManager->alignReferenceToPlaybackFrame
+                sv_frame_t sf = m_viewManager->alignReferenceToPlaybackFrame
                     (selection.getStartFrame());
-                int ef = m_viewManager->alignReferenceToPlaybackFrame
+                sv_frame_t ef = m_viewManager->alignReferenceToPlaybackFrame
                     (selection.getEndFrame());
 
 		selectionSize = ef - sf;
@@ -1761,7 +1769,7 @@
 	}
     }
 
-    int rf = m_readBufferFill;
+    sv_frame_t rf = m_readBufferFill;
     RingBuffer<float> *rb = getReadRingBuffer(0);
     if (rb) {
 	int rs = rb->getReadSpace();
@@ -1775,8 +1783,8 @@
     SVDEBUG << "AudioCallbackPlaySource::unifyRingBuffers: m_readBufferFill = " << m_readBufferFill << ", rf = " << rf << ", m_writeBufferFill = " << m_writeBufferFill << endl;
 #endif
 
-    int wf = m_writeBufferFill;
-    int skip = 0;
+    sv_frame_t wf = m_writeBufferFill;
+    sv_frame_t skip = 0;
     for (int c = 0; c < getTargetChannelCount(); ++c) {
 	RingBuffer<float> *wb = getWriteRingBuffer(c);
 	if (wb) {
@@ -1794,7 +1802,7 @@
 	    }
 
 //	    cout << "skipping " << skip << endl;
-	    wb->skip(skip);
+	    wb->skip(int(skip));
 	}
     }
 		    
@@ -1837,10 +1845,9 @@
 
 	} else {
 	    
-	    float ms = 100;
+	    double ms = 100;
 	    if (s.getSourceSampleRate() > 0) {
-		ms = float(s.m_ringBufferSize) /
-                    float(s.getSourceSampleRate()) * 1000.0;
+		ms = double(s.m_ringBufferSize) / s.getSourceSampleRate() * 1000.0;
 	    }
 	    
 	    if (s.m_playing) ms /= 10;
--- a/audioio/AudioCallbackPlaySource.h	Mon Mar 02 17:20:23 2015 +0000
+++ b/audioio/AudioCallbackPlaySource.h	Mon Apr 20 09:21:08 2015 +0100
@@ -83,7 +83,7 @@
      * from the given frame.  If playback is already under way, reseek
      * to the given frame and continue.
      */
-    virtual void play(int startFrame);
+    virtual void play(sv_frame_t startFrame);
 
     /**
      * Stop playback and ensure that no more data is returned.
@@ -99,18 +99,18 @@
      * Return the frame number that is currently expected to be coming
      * out of the speakers.  (i.e. compensating for playback latency.)
      */
-    virtual int getCurrentPlayingFrame();
+    virtual sv_frame_t getCurrentPlayingFrame();
     
     /** 
      * Return the last frame that would come out of the speakers if we
      * stopped playback right now.
      */
-    virtual int getCurrentBufferedFrame();
+    virtual sv_frame_t getCurrentBufferedFrame();
 
     /**
      * Return the frame at which playback is expected to end (if not looping).
      */
-    virtual int getPlayEndFrame() { return m_lastModelEndFrame; }
+    virtual sv_frame_t getPlayEndFrame() { return m_lastModelEndFrame; }
 
     /**
      * Set the target and the block size of the target audio device.
@@ -133,12 +133,12 @@
      * highest last frame across all channels) requested via
      * getSamples().  The default is zero.
      */
-    void setTargetPlayLatency(int);
+    void setTargetPlayLatency(sv_frame_t);
 
     /**
      * Get the playback latency of the target audio device.
      */
-    int getTargetPlayLatency() const;
+    sv_frame_t getTargetPlayLatency() const;
 
     /**
      * Specify that the target audio device has a fixed sample rate
@@ -147,13 +147,13 @@
      * source sample rate, this class will resample automatically to
      * fit.
      */
-    void setTargetSampleRate(int);
+    void setTargetSampleRate(sv_samplerate_t);
 
     /**
      * Return the sample rate set by the target audio device (or the
      * source sample rate if the target hasn't set one).
      */
-    virtual int getTargetSampleRate() const;
+    virtual sv_samplerate_t getTargetSampleRate() const;
 
     /**
      * Set the current output levels for metering (for call from the
@@ -189,19 +189,19 @@
      * safely be called from a realtime thread.  Returns 0 if there is
      * no source yet available.
      */
-    virtual int getSourceSampleRate() const;
+    virtual sv_samplerate_t getSourceSampleRate() const;
 
     /**
      * Get "count" samples (at the target sample rate) of the mixed
      * audio data, in all channels.  This may safely be called from a
      * realtime thread.
      */
-    int getSourceSamples(int count, float **buffer);
+    sv_frame_t getSourceSamples(sv_frame_t count, float **buffer);
 
     /**
      * Set the time stretcher factor (i.e. playback speed).
      */
-    void setTimeStretch(float factor);
+    void setTimeStretch(double factor);
 
     /**
      * Set the resampler quality, 0 - 2 where 0 is fastest and 2 is
@@ -244,7 +244,9 @@
 
     void playStatusChanged(bool isPlaying);
 
-    void sampleRateMismatch(int requested, int available, bool willResample);
+    void sampleRateMismatch(sv_samplerate_t requested,
+                            sv_samplerate_t available,
+                            bool willResample);
 
     void audioOverloadPluginDisabled();
     void audioTimeStretchMultiChannelDisabled();
@@ -260,7 +262,7 @@
     void playSelectionModeChanged();
     void playParametersChanged(PlayParameters *);
     void preferenceChanged(PropertyContainer::PropertyName);
-    void modelChangedWithin(int startFrame, int endFrame);
+    void modelChangedWithin(sv_frame_t startFrame, sv_frame_t endFrame);
 
 protected:
     ViewManagerBase                  *m_viewManager;
@@ -280,29 +282,29 @@
     std::set<Model *>                 m_models;
     RingBufferVector                 *m_readBuffers;
     RingBufferVector                 *m_writeBuffers;
-    int                               m_readBufferFill;
-    int                               m_writeBufferFill;
+    sv_frame_t                        m_readBufferFill;
+    sv_frame_t                        m_writeBufferFill;
     Scavenger<RingBufferVector>       m_bufferScavenger;
     int                               m_sourceChannelCount;
-    int                               m_blockSize;
-    int                               m_sourceSampleRate;
-    int                               m_targetSampleRate;
-    int                               m_playLatency;
+    sv_frame_t                        m_blockSize;
+    sv_samplerate_t                   m_sourceSampleRate;
+    sv_samplerate_t                   m_targetSampleRate;
+    sv_frame_t                        m_playLatency;
     AudioCallbackPlayTarget          *m_target;
     double                            m_lastRetrievalTimestamp;
-    int                               m_lastRetrievedBlockSize;
+    sv_frame_t                        m_lastRetrievedBlockSize;
     bool                              m_trustworthyTimestamps;
-    int                               m_lastCurrentFrame;
+    sv_frame_t                        m_lastCurrentFrame;
     bool                              m_playing;
     bool                              m_exiting;
-    int                               m_lastModelEndFrame;
+    sv_frame_t                        m_lastModelEndFrame;
     int                               m_ringBufferSize;
     float                             m_outputLeft;
     float                             m_outputRight;
     RealTimePluginInstance           *m_auditioningPlugin;
     bool                              m_auditioningPluginBypassed;
     Scavenger<RealTimePluginInstance> m_pluginScavenger;
-    int                               m_playStartFrame;
+    sv_frame_t                        m_playStartFrame;
     bool                              m_playStartFramePassed;
     RealTime                          m_playStartedAt;
 
@@ -328,12 +330,12 @@
 
     RubberBand::RubberBandStretcher *m_timeStretcher;
     RubberBand::RubberBandStretcher *m_monoStretcher;
-    float m_stretchRatio;
+    double m_stretchRatio;
     bool m_stretchMono;
     
-    int  m_stretcherInputCount;
+    int m_stretcherInputCount;
     float **m_stretcherInputs;
-    int *m_stretcherInputSizes;
+    sv_frame_t *m_stretcherInputSizes;
 
     // Called from fill thread, m_playing true, mutex held
     // Return true if work done
@@ -343,17 +345,17 @@
     // which will be count or fewer.  Return in the frame argument the
     // new buffered frame position (which may be earlier than the
     // frame argument passed in, in the case of looping).
-    int mixModels(int &frame, int count, float **buffers);
+    sv_frame_t mixModels(sv_frame_t &frame, sv_frame_t count, float **buffers);
 
     // Called from getSourceSamples.
-    void applyAuditioningEffect(int count, float **buffers);
+    void applyAuditioningEffect(sv_frame_t count, float **buffers);
 
     // Ranges of current selections, if play selection is active
     std::vector<RealTime> m_rangeStarts;
     std::vector<RealTime> m_rangeDurations;
     void rebuildRangeLists();
 
-    int getCurrentFrame(RealTime outputLatency);
+    sv_frame_t getCurrentFrame(RealTime outputLatency);
 
     class FillThread : public Thread
     {
--- a/audioio/AudioGenerator.cpp	Mon Mar 02 17:20:23 2015 +0000
+++ b/audioio/AudioGenerator.cpp	Mon Apr 20 09:21:08 2015 +0100
@@ -37,7 +37,7 @@
 #include <QDir>
 #include <QFile>
 
-const int
+const sv_frame_t
 AudioGenerator::m_processingBlockSize = 1024;
 
 QString
@@ -124,12 +124,20 @@
 	}
     }
 
+    const Playable *playable = model;
+    if (!playable || !playable->canPlay()) return 0;
+
+    PlayParameters *parameters =
+	PlayParameterRepository::getInstance()->getPlayParameters(playable);
+
+    bool willPlay = !parameters->isPlayMuted();
+    
     if (usesClipMixer(model)) {
         ClipMixer *mixer = makeClipMixerFor(model);
         if (mixer) {
             QMutexLocker locker(&m_mutex);
             m_clipMixerMap[model] = mixer;
-            return true;
+            return willPlay;
         }
     }
 
@@ -138,7 +146,7 @@
         if (synth) {
             QMutexLocker locker(&m_mutex);
             m_continuousSynthMap[model] = synth;
-            return true;
+            return willPlay;
         }
     }
 
@@ -209,7 +217,9 @@
         clipId = parameters->getPlayClipId();
     }
 
+#ifdef DEBUG_AUDIO_GENERATOR
     std::cerr << "AudioGenerator::makeClipMixerFor(" << model << "): sample id = " << clipId << std::endl;
+#endif
 
     if (clipId == "") {
         SVDEBUG << "AudioGenerator::makeClipMixerFor(" << model << "): no sample, skipping" << endl;
@@ -220,17 +230,19 @@
                                      m_sourceSampleRate,
                                      m_processingBlockSize);
 
-    float clipF0 = Pitch::getFrequencyForPitch(60, 0, 440.0f); // required
+    double clipF0 = Pitch::getFrequencyForPitch(60, 0, 440.0); // required
 
     QString clipPath = QString("%1/%2.wav").arg(m_sampleDir).arg(clipId);
 
-    float level = wantsQuieterClips(model) ? 0.5 : 1.0;
+    double level = wantsQuieterClips(model) ? 0.5 : 1.0;
     if (!mixer->loadClipData(clipPath, clipF0, level)) {
         delete mixer;
         return 0;
     }
 
+#ifdef DEBUG_AUDIO_GENERATOR
     std::cerr << "AudioGenerator::makeClipMixerFor(" << model << "): loaded clip " << clipId << std::endl;
+#endif
 
     return mixer;
 }
@@ -246,7 +258,9 @@
                                                  m_processingBlockSize,
                                                  m_waveType);
 
+#ifdef DEBUG_AUDIO_GENERATOR
     std::cerr << "AudioGenerator::makeSynthFor(" << model << "): created synth" << std::endl;
+#endif
 
     return synth;
 }
@@ -284,7 +298,9 @@
 {
     QMutexLocker locker(&m_mutex);
 
+#ifdef DEBUG_AUDIO_GENERATOR
     cerr << "AudioGenerator::reset()" << endl;
+#endif
 
     for (ClipMixerMap::iterator i = m_clipMixerMap.begin(); i != m_clipMixerMap.end(); ++i) {
 	if (i->second) {
@@ -310,7 +326,7 @@
     }
 }
 
-int
+sv_frame_t
 AudioGenerator::getBlockSize() const
 {
     return m_processingBlockSize;
@@ -334,9 +350,9 @@
     m_soloing = false;
 }
 
-int
-AudioGenerator::mixModel(Model *model, int startFrame, int frameCount,
-			 float **buffer, int fadeIn, int fadeOut)
+sv_frame_t
+AudioGenerator::mixModel(Model *model, sv_frame_t startFrame, sv_frame_t frameCount,
+			 float **buffer, sv_frame_t fadeIn, sv_frame_t fadeOut)
 {
     if (m_sourceSampleRate == 0) {
 	cerr << "WARNING: AudioGenerator::mixModel: No base source sample rate available" << endl;
@@ -393,13 +409,13 @@
     return frameCount;
 }
 
-int
+sv_frame_t
 AudioGenerator::mixDenseTimeValueModel(DenseTimeValueModel *dtvm,
-				       int startFrame, int frames,
+				       sv_frame_t startFrame, sv_frame_t frames,
 				       float **buffer, float gain, float pan,
-				       int fadeIn, int fadeOut)
+				       sv_frame_t fadeIn, sv_frame_t fadeOut)
 {
-    int maxFrames = frames + std::max(fadeIn, fadeOut);
+    sv_frame_t maxFrames = frames + std::max(fadeIn, fadeOut);
 
     int modelChannels = dtvm->getChannelCount();
 
@@ -420,7 +436,7 @@
 	m_channelBufSiz = maxFrames;
     }
 
-    int got = 0;
+    sv_frame_t got = 0;
 
     if (startFrame >= fadeIn/2) {
         got = dtvm->getData(0, modelChannels - 1,
@@ -428,7 +444,7 @@
                             frames + fadeOut/2 + fadeIn/2,
                             m_channelBuffer);
     } else {
-        int missing = fadeIn/2 - startFrame;
+        sv_frame_t missing = fadeIn/2 - startFrame;
 
         for (int c = 0; c < modelChannels; ++c) {
             m_channelBuffer[c] += missing;
@@ -462,25 +478,27 @@
 	float channelGain = gain;
 	if (pan != 0.0) {
 	    if (c == 0) {
-		if (pan > 0.0) channelGain *= 1.0 - pan;
+		if (pan > 0.0) channelGain *= 1.0f - pan;
 	    } else {
-		if (pan < 0.0) channelGain *= pan + 1.0;
+		if (pan < 0.0) channelGain *= pan + 1.0f;
 	    }
 	}
 
-	for (int i = 0; i < fadeIn/2; ++i) {
+	for (sv_frame_t i = 0; i < fadeIn/2; ++i) {
 	    float *back = buffer[c];
 	    back -= fadeIn/2;
-	    back[i] += (channelGain * m_channelBuffer[sourceChannel][i] * i) / fadeIn;
+	    back[i] +=
+                (channelGain * m_channelBuffer[sourceChannel][i] * float(i))
+                / float(fadeIn);
 	}
 
-	for (int i = 0; i < frames + fadeOut/2; ++i) {
+	for (sv_frame_t i = 0; i < frames + fadeOut/2; ++i) {
 	    float mult = channelGain;
 	    if (i < fadeIn/2) {
-		mult = (mult * i) / fadeIn;
+		mult = (mult * float(i)) / float(fadeIn);
 	    }
 	    if (i > frames - fadeOut/2) {
-		mult = (mult * ((frames + fadeOut/2) - i)) / fadeOut;
+		mult = (mult * float((frames + fadeOut/2) - i)) / float(fadeOut);
 	    }
             float val = m_channelBuffer[sourceChannel][i];
             if (i >= got) val = 0.f;
@@ -491,15 +509,15 @@
     return got;
 }
   
-int
+sv_frame_t
 AudioGenerator::mixClipModel(Model *model,
-                             int startFrame, int frames,
+                             sv_frame_t startFrame, sv_frame_t frames,
                              float **buffer, float gain, float pan)
 {
     ClipMixer *clipMixer = m_clipMixerMap[model];
     if (!clipMixer) return 0;
 
-    int blocks = frames / m_processingBlockSize;
+    int blocks = int(frames / m_processingBlockSize);
     
     //!!! todo: the below -- it matters
 
@@ -513,11 +531,12 @@
     //callback play source has to use that as a multiple for all the
     //calls to mixModel
 
-    int got = blocks * m_processingBlockSize;
+    sv_frame_t got = blocks * m_processingBlockSize;
 
 #ifdef DEBUG_AUDIO_GENERATOR
-    cout << "mixModel [clip]: frames " << frames
-	      << ", blocks " << blocks << endl;
+    cout << "mixModel [clip]: start " << startFrame << ", frames " << frames
+         << ", blocks " << blocks << ", have " << m_noteOffs.size()
+         << " note-offs" << endl;
 #endif
 
     ClipMixer::NoteStart on;
@@ -529,7 +548,7 @@
 
     for (int i = 0; i < blocks; ++i) {
 
-	int reqStart = startFrame + i * m_processingBlockSize;
+	sv_frame_t reqStart = startFrame + i * m_processingBlockSize;
 
         NoteList notes;
         NoteExportable *exportable = dynamic_cast<NoteExportable *>(model);
@@ -544,7 +563,7 @@
 	for (NoteList::const_iterator ni = notes.begin();
              ni != notes.end(); ++ni) {
 
-	    int noteFrame = ni->start;
+	    sv_frame_t noteFrame = ni->start;
 
 	    if (noteFrame < reqStart ||
 		noteFrame >= reqStart + m_processingBlockSize) continue;
@@ -552,7 +571,7 @@
 	    while (noteOffs.begin() != noteOffs.end() &&
 		   noteOffs.begin()->frame <= noteFrame) {
 
-                int eventFrame = noteOffs.begin()->frame;
+                sv_frame_t eventFrame = noteOffs.begin()->frame;
                 if (eventFrame < reqStart) eventFrame = reqStart;
 
                 off.frameOffset = eventFrame - reqStart;
@@ -568,7 +587,7 @@
 
             on.frameOffset = noteFrame - reqStart;
             on.frequency = ni->getFrequency();
-            on.level = float(ni->velocity) / 127.0;
+            on.level = float(ni->velocity) / 127.0f;
             on.pan = pan;
 
 #ifdef DEBUG_AUDIO_GENERATOR
@@ -583,7 +602,7 @@
 	while (noteOffs.begin() != noteOffs.end() &&
 	       noteOffs.begin()->frame <= reqStart + m_processingBlockSize) {
 
-            int eventFrame = noteOffs.begin()->frame;
+            sv_frame_t eventFrame = noteOffs.begin()->frame;
             if (eventFrame < reqStart) eventFrame = reqStart;
 
             off.frameOffset = eventFrame - reqStart;
@@ -609,10 +628,10 @@
     return got;
 }
 
-int
+sv_frame_t
 AudioGenerator::mixContinuousSynthModel(Model *model,
-                                        int startFrame,
-                                        int frames,
+                                        sv_frame_t startFrame,
+                                        sv_frame_t frames,
                                         float **buffer,
                                         float gain, 
                                         float pan)
@@ -624,11 +643,11 @@
     SparseTimeValueModel *stvm = qobject_cast<SparseTimeValueModel *>(model);
     if (stvm->getScaleUnits() != "Hz") return 0;
 
-    int blocks = frames / m_processingBlockSize;
+    int blocks = int(frames / m_processingBlockSize);
 
     //!!! todo: see comment in mixClipModel
 
-    int got = blocks * m_processingBlockSize;
+    sv_frame_t got = blocks * m_processingBlockSize;
 
 #ifdef DEBUG_AUDIO_GENERATOR
     cout << "mixModel [synth]: frames " << frames
@@ -639,7 +658,7 @@
 
     for (int i = 0; i < blocks; ++i) {
 
-	int reqStart = startFrame + i * m_processingBlockSize;
+	sv_frame_t reqStart = startFrame + i * m_processingBlockSize;
 
 	for (int c = 0; c < m_targetChannelCount; ++c) {
             bufferIndexes[c] = buffer[c] + i * m_processingBlockSize;
--- a/audioio/AudioGenerator.h	Mon Mar 02 17:20:23 2015 +0000
+++ b/audioio/AudioGenerator.h	Mon Apr 20 09:21:08 2015 +0100
@@ -32,6 +32,8 @@
 #include <map>
 #include <vector>
 
+#include "base/BaseTypes.h"
+
 class AudioGenerator : public QObject
 {
     Q_OBJECT
@@ -74,13 +76,13 @@
      * argument to all mixModel calls must be a multiple of this
      * value.
      */
-    virtual int getBlockSize() const;
+    virtual sv_frame_t getBlockSize() const;
 
     /**
      * Mix a single model into an output buffer.
      */
-    virtual int mixModel(Model *model, int startFrame, int frameCount,
-			    float **buffer, int fadeIn = 0, int fadeOut = 0);
+    virtual sv_frame_t mixModel(Model *model, sv_frame_t startFrame, sv_frame_t frameCount,
+			    float **buffer, sv_frame_t fadeIn = 0, sv_frame_t fadeOut = 0);
 
     /**
      * Specify that only the given set of models should be played.
@@ -97,7 +99,7 @@
     void playClipIdChanged(const Playable *, QString);
 
 protected:
-    int m_sourceSampleRate;
+    sv_samplerate_t m_sourceSampleRate;
     int m_targetChannelCount;
     int m_waveType;
 
@@ -106,10 +108,10 @@
 
     struct NoteOff {
 
-        NoteOff(float _freq, int _frame) : frequency(_freq), frame(_frame) { }
+        NoteOff(float _freq, sv_frame_t _frame) : frequency(_freq), frame(_frame) { }
 
         float frequency;
-	int frame;
+	sv_frame_t frame;
 
 	struct Comparator {
 	    bool operator()(const NoteOff &n1, const NoteOff &n2) const {
@@ -143,22 +145,22 @@
 
     static void initialiseSampleDir();
 
-    virtual int mixDenseTimeValueModel
-    (DenseTimeValueModel *model, int startFrame, int frameCount,
-     float **buffer, float gain, float pan, int fadeIn, int fadeOut);
+    virtual sv_frame_t mixDenseTimeValueModel
+    (DenseTimeValueModel *model, sv_frame_t startFrame, sv_frame_t frameCount,
+     float **buffer, float gain, float pan, sv_frame_t fadeIn, sv_frame_t fadeOut);
 
-    virtual int mixClipModel
-    (Model *model, int startFrame, int frameCount,
+    virtual sv_frame_t mixClipModel
+    (Model *model, sv_frame_t startFrame, sv_frame_t frameCount,
      float **buffer, float gain, float pan);
 
-    virtual int mixContinuousSynthModel
-    (Model *model, int startFrame, int frameCount,
+    virtual sv_frame_t mixContinuousSynthModel
+    (Model *model, sv_frame_t startFrame, sv_frame_t frameCount,
      float **buffer, float gain, float pan);
     
-    static const int m_processingBlockSize;
+    static const sv_frame_t m_processingBlockSize;
 
     float **m_channelBuffer;
-    int m_channelBufSiz;
+    sv_frame_t m_channelBufSiz;
     int m_channelBufCount;
 };
 
--- a/audioio/AudioJACKTarget.cpp	Mon Mar 02 17:20:23 2015 +0000
+++ b/audioio/AudioJACKTarget.cpp	Mon Apr 20 09:21:08 2015 +0100
@@ -439,14 +439,14 @@
 	buffers[ch] = (float *)jack_port_get_buffer(m_outputs[ch], nframes);
     }
 
-    int received = 0;
+    sv_frame_t received = 0;
 
     if (m_source) {
 	received = m_source->getSourceSamples(nframes, buffers);
     }
 
     for (int ch = 0; ch < (int)m_outputs.size(); ++ch) {
-        for (int i = received; i < (int)nframes; ++i) {
+        for (sv_frame_t i = received; i < nframes; ++i) {
             buffers[ch][i] = 0.0;
         }
     }
--- a/audioio/AudioPortAudioTarget.cpp	Mon Mar 02 17:20:23 2015 +0000
+++ b/audioio/AudioPortAudioTarget.cpp	Mon Apr 20 09:21:08 2015 +0100
@@ -52,7 +52,7 @@
     m_bufferSize = 2048;
     m_sampleRate = 44100;
     if (m_source && (m_source->getSourceSampleRate() != 0)) {
-	m_sampleRate = m_source->getSourceSampleRate();
+	m_sampleRate = int(m_source->getSourceSampleRate());
     }
 
     PaStreamParameters op;
@@ -185,7 +185,7 @@
 
 int
 AudioPortAudioTarget::process(const void *, void *outputBuffer,
-                              int nframes,
+                              sv_frame_t nframes,
                               const PaStreamCallbackTimeInfo *,
                               PaStreamCallbackFlags)
 {
@@ -244,7 +244,7 @@
 	}
     }
 	
-    int received = m_source->getSourceSamples(nframes, tmpbuf);
+    sv_frame_t received = m_source->getSourceSamples(nframes, tmpbuf);
 
     float peakLeft = 0.0, peakRight = 0.0;
 
--- a/audioio/AudioPortAudioTarget.h	Mon Mar 02 17:20:23 2015 +0000
+++ b/audioio/AudioPortAudioTarget.h	Mon Apr 20 09:21:08 2015 +0100
@@ -26,6 +26,8 @@
 
 #include "AudioCallbackPlayTarget.h"
 
+#include "base/BaseTypes.h"
+
 class AudioCallbackPlaySource;
 
 class AudioPortAudioTarget : public AudioCallbackPlayTarget
@@ -46,7 +48,7 @@
     virtual void sourceModelReplaced();
 
 protected:
-    int process(const void *input, void *output, int frames,
+    int process(const void *input, void *output, sv_frame_t frames,
                 const PaStreamCallbackTimeInfo *timeInfo,
                 PaStreamCallbackFlags statusFlags);
 
--- a/audioio/AudioPulseAudioTarget.cpp	Mon Mar 02 17:20:23 2015 +0000
+++ b/audioio/AudioPulseAudioTarget.cpp	Mon Apr 20 09:21:08 2015 +0100
@@ -57,7 +57,7 @@
     m_bufferSize = 20480;
     m_sampleRate = 44100;
     if (m_source && (m_source->getSourceSampleRate() != 0)) {
-	m_sampleRate = m_source->getSourceSampleRate();
+	m_sampleRate = int(m_source->getSourceSampleRate());
     }
     m_spec.rate = m_sampleRate;
     m_spec.channels = 2;
@@ -141,7 +141,7 @@
     
     pa_usec_t usec = 0;
     pa_stream_get_time(m_stream, &usec);
-    return usec / 1000000.f;
+    return double(usec) / 1000000.0;
 }
 
 void
@@ -151,19 +151,19 @@
 }
 
 void
-AudioPulseAudioTarget::streamWriteStatic(pa_stream *stream,
+AudioPulseAudioTarget::streamWriteStatic(pa_stream *,
                                          size_t length,
                                          void *data)
 {
     AudioPulseAudioTarget *target = (AudioPulseAudioTarget *)data;
     
-    assert(stream == target->m_stream);
+//    assert(stream == target->m_stream);
 
     target->streamWrite(length);
 }
 
 void
-AudioPulseAudioTarget::streamWrite(int requested)
+AudioPulseAudioTarget::streamWrite(sv_frame_t requested)
 {
 #ifdef DEBUG_AUDIO_PULSE_AUDIO_TARGET_PLAY
     cout << "AudioPulseAudioTarget::streamWrite(" << requested << ")" << endl;
@@ -175,21 +175,21 @@
     pa_usec_t latency = 0;
     int negative = 0;
     if (!pa_stream_get_latency(m_stream, &latency, &negative)) {
-        int latframes = (latency / 1000000.f) * float(m_sampleRate);
+        int latframes = int(double(latency) / 1000000.0 * double(m_sampleRate));
         if (latframes > 0) m_source->setTargetPlayLatency(latframes);
     }
 
     static float *output = 0;
     static float **tmpbuf = 0;
     static int tmpbufch = 0;
-    static int tmpbufsz = 0;
+    static sv_frame_t tmpbufsz = 0;
 
     int sourceChannels = m_source->getSourceChannelCount();
 
     // Because we offer pan, we always want at least 2 channels
     if (sourceChannels < 2) sourceChannels = 2;
 
-    int nframes = requested / (sourceChannels * sizeof(float));
+    sv_frame_t nframes = requested / (sourceChannels * sizeof(float));
 
     if (nframes > m_bufferSize) {
         cerr << "WARNING: AudioPulseAudioTarget::streamWrite: nframes " << nframes << " > m_bufferSize " << m_bufferSize << endl;
@@ -223,7 +223,7 @@
         output = new float[tmpbufsz * tmpbufch];
     }
 	
-    int received = m_source->getSourceSamples(nframes, tmpbuf);
+    sv_frame_t received = m_source->getSourceSamples(nframes, tmpbuf);
 
 #ifdef DEBUG_AUDIO_PULSE_AUDIO_TARGET_PLAY
     cerr << "requested " << nframes << ", received " << received << endl;
@@ -268,12 +268,12 @@
 }
 
 void
-AudioPulseAudioTarget::streamStateChangedStatic(pa_stream *stream,
+AudioPulseAudioTarget::streamStateChangedStatic(pa_stream *,
                                                 void *data)
 {
     AudioPulseAudioTarget *target = (AudioPulseAudioTarget *)data;
     
-    assert(stream == target->m_stream);
+//    assert(stream == target->m_stream);
 
     target->streamStateChanged();
 }
@@ -303,7 +303,7 @@
             cerr << "AudioPulseAudioTarget::streamStateChanged: Failed to query latency" << endl;
         }
         cerr << "Latency = " << latency << " usec" << endl;
-        int latframes = (latency / 1000000.f) * float(m_sampleRate);
+        int latframes = int(double(latency) / 1000000.0 * m_sampleRate);
         cerr << "that's " << latframes << " frames" << endl;
 
         const pa_buffer_attr *attr;
@@ -334,12 +334,12 @@
 }
 
 void
-AudioPulseAudioTarget::contextStateChangedStatic(pa_context *context,
+AudioPulseAudioTarget::contextStateChangedStatic(pa_context *,
                                                  void *data)
 {
     AudioPulseAudioTarget *target = (AudioPulseAudioTarget *)data;
     
-    assert(context == target->m_context);
+//    assert(context == target->m_context);
 
     target->contextStateChanged();
 }
--- a/audioio/AudioPulseAudioTarget.h	Mon Mar 02 17:20:23 2015 +0000
+++ b/audioio/AudioPulseAudioTarget.h	Mon Apr 20 09:21:08 2015 +0100
@@ -46,7 +46,7 @@
     virtual void sourceModelReplaced();
 
 protected:
-    void streamWrite(int);
+    void streamWrite(sv_frame_t);
     void streamStateChanged();
     void contextStateChanged();
 
--- a/audioio/ClipMixer.cpp	Mon Mar 02 17:20:23 2015 +0000
+++ b/audioio/ClipMixer.cpp	Mon Apr 20 09:21:08 2015 +0100
@@ -20,7 +20,9 @@
 
 #include "base/Debug.h"
 
-ClipMixer::ClipMixer(int channels, int sampleRate, int blockSize) :
+//#define DEBUG_CLIP_MIXER 1
+
+ClipMixer::ClipMixer(int channels, sv_samplerate_t sampleRate, sv_frame_t blockSize) :
     m_channels(channels),
     m_sampleRate(sampleRate),
     m_blockSize(blockSize),
@@ -43,7 +45,7 @@
 }
 
 bool
-ClipMixer::loadClipData(QString path, float f0, float level)
+ClipMixer::loadClipData(QString path, double f0, double level)
 {
     if (m_clipData) {
         cerr << "ClipMixer::loadClipData: Already have clip loaded" << endl;
@@ -53,7 +55,7 @@
     SF_INFO info;
     SNDFILE *file;
     float *tmpFrames;
-    int i;
+    sv_frame_t i;
 
     info.format = 0;
     file = sf_open(path.toLocal8Bit().data(), SFM_READ, &info);
@@ -83,7 +85,7 @@
 	int j;
 	m_clipData[i] = 0.0f;
 	for (j = 0; j < info.channels; ++j) {
-	    m_clipData[i] += tmpFrames[i * info.channels + j] * level;
+	    m_clipData[i] += tmpFrames[i * info.channels + j] * float(level);
 	}
     }
 
@@ -102,19 +104,19 @@
     m_playing.clear();
 }
 
-float
-ClipMixer::getResampleRatioFor(float frequency)
+double
+ClipMixer::getResampleRatioFor(double frequency)
 {
     if (!m_clipData || !m_clipRate) return 1.0;
-    float pitchRatio = m_clipF0 / frequency;
-    float resampleRatio = m_sampleRate / m_clipRate;
+    double pitchRatio = m_clipF0 / frequency;
+    double resampleRatio = m_sampleRate / m_clipRate;
     return pitchRatio * resampleRatio;
 }
 
-int
-ClipMixer::getResampledClipDuration(float frequency)
+sv_frame_t
+ClipMixer::getResampledClipDuration(double frequency)
 {
-    return int(ceil(m_clipLength * getResampleRatioFor(frequency)));
+    return sv_frame_t(ceil(double(m_clipLength) * getResampleRatioFor(frequency)));
 }
 
 void
@@ -146,12 +148,12 @@
             levels[c] = note.level * gain;
         }
         if (note.pan != 0.0 && m_channels == 2) {
-            levels[0] *= 1.0 - note.pan;
-            levels[1] *= note.pan + 1.0;
+            levels[0] *= 1.0f - note.pan;
+            levels[1] *= note.pan + 1.0f;
         }
 
-        int start = note.frameOffset;
-        int durationHere = m_blockSize;
+        sv_frame_t start = note.frameOffset;
+        sv_frame_t durationHere = m_blockSize;
         if (start > 0) durationHere = m_blockSize - start;
 
         bool ending = false;
@@ -167,7 +169,7 @@
             }
         }
 
-        int clipDuration = getResampledClipDuration(note.frequency);
+        sv_frame_t clipDuration = getResampledClipDuration(note.frequency);
         if (start + clipDuration > 0) {
             if (start < 0 && start + clipDuration < durationHere) {
                 durationHere = start + clipDuration;
@@ -199,46 +201,46 @@
 ClipMixer::mixNote(float **toBuffers,
                    float *levels,
                    float frequency,
-                   int sourceOffset,
-                   int targetOffset,
-                   int sampleCount,
+                   sv_frame_t sourceOffset,
+                   sv_frame_t targetOffset,
+                   sv_frame_t sampleCount,
                    bool isEnd)
 {
     if (!m_clipData) return;
 
-    float ratio = getResampleRatioFor(frequency);
+    double ratio = getResampleRatioFor(frequency);
     
-    float releaseTime = 0.01;
-    int releaseSampleCount = round(releaseTime * m_sampleRate);
+    double releaseTime = 0.01;
+    sv_frame_t releaseSampleCount = sv_frame_t(round(releaseTime * m_sampleRate));
     if (releaseSampleCount > sampleCount) {
         releaseSampleCount = sampleCount;
     }
-    float releaseFraction = 1.f/releaseSampleCount;
+    double releaseFraction = 1.0/double(releaseSampleCount);
 
-    for (int i = 0; i < sampleCount; ++i) {
+    for (sv_frame_t i = 0; i < sampleCount; ++i) {
 
-        int s = sourceOffset + i;
+        sv_frame_t s = sourceOffset + i;
 
-        float os = s / ratio;
-        int osi = int(floor(os));
+        double os = double(s) / ratio;
+        sv_frame_t osi = sv_frame_t(floor(os));
 
         //!!! just linear interpolation for now (same as SV's sample
         //!!! player). a small sinc kernel would be better and
         //!!! probably "good enough"
-        float value = 0.f;
+        double value = 0.0;
         if (osi < m_clipLength) {
             value += m_clipData[osi];
         }
         if (osi + 1 < m_clipLength) {
-            value += (m_clipData[osi + 1] - m_clipData[osi]) * (os - osi);
+            value += (m_clipData[osi + 1] - m_clipData[osi]) * (os - double(osi));
         }
          
         if (isEnd && i + releaseSampleCount > sampleCount) {
-            value *= releaseFraction * (sampleCount - i); // linear ramp for release
+            value *= releaseFraction * double(sampleCount - i); // linear ramp for release
         }
 
         for (int c = 0; c < m_channels; ++c) {
-            toBuffers[c][targetOffset + i] += levels[c] * value;
+            toBuffers[c][targetOffset + i] += float(levels[c] * value);
         }
     }
 }
--- a/audioio/ClipMixer.h	Mon Mar 02 17:20:23 2015 +0000
+++ b/audioio/ClipMixer.h	Mon Apr 20 09:21:08 2015 +0100
@@ -19,6 +19,8 @@
 #include <QString>
 #include <vector>
 
+#include "base/BaseTypes.h"
+
 /**
  * Mix in synthetic notes produced by resampling a prerecorded
  * clip. (i.e. this is an implementation of a digital sampler in the
@@ -29,7 +31,7 @@
 class ClipMixer
 {
 public:
-    ClipMixer(int channels, int sampleRate, int blockSize);
+    ClipMixer(int channels, sv_samplerate_t sampleRate, sv_frame_t blockSize);
     ~ClipMixer();
 
     void setChannelCount(int channels);
@@ -41,19 +43,19 @@
      * and should be scaled by level (in the range 0-1) when playing
      * back.
      */
-    bool loadClipData(QString clipFilePath, float clipF0, float level);
+    bool loadClipData(QString clipFilePath, double clipF0, double level);
 
     void reset(); // discarding any playing notes
 
     struct NoteStart {
-	int frameOffset; // within current processing block
+	sv_frame_t frameOffset; // within current processing block
 	float frequency; // Hz
 	float level; // volume in range (0,1]
 	float pan; // range [-1,1]
     };
 
     struct NoteEnd {
-	int frameOffset; // in current processing block
+	sv_frame_t frameOffset; // in current processing block
         float frequency; // matching note start
     };
 
@@ -64,27 +66,27 @@
 
 private:
     int m_channels;
-    int m_sampleRate;
-    int m_blockSize;
+    sv_samplerate_t m_sampleRate;
+    sv_frame_t m_blockSize;
 
     QString m_clipPath;
 
     float *m_clipData;
-    int m_clipLength;
-    float m_clipF0;
-    float m_clipRate;
+    sv_frame_t m_clipLength;
+    double m_clipF0;
+    sv_samplerate_t m_clipRate;
 
     std::vector<NoteStart> m_playing;
 
-    float getResampleRatioFor(float frequency);
-    int getResampledClipDuration(float frequency);
+    double getResampleRatioFor(double frequency);
+    sv_frame_t getResampledClipDuration(double frequency);
 
     void mixNote(float **toBuffers, 
                  float *levels,
                  float frequency,
-                 int sourceOffset, // within resampled note
-                 int targetOffset, // within target buffer
-                 int sampleCount,
+                 sv_frame_t sourceOffset, // within resampled note
+                 sv_frame_t targetOffset, // within target buffer
+                 sv_frame_t sampleCount,
                  bool isEnd);
 };
 
--- a/audioio/ContinuousSynth.cpp	Mon Mar 02 17:20:23 2015 +0000
+++ b/audioio/ContinuousSynth.cpp	Mon Apr 20 09:21:08 2015 +0100
@@ -19,11 +19,11 @@
 
 #include <cmath>
 
-ContinuousSynth::ContinuousSynth(int channels, int sampleRate, int blockSize, int waveType) :
+ContinuousSynth::ContinuousSynth(int channels, sv_samplerate_t sampleRate, sv_frame_t blockSize, int waveType) :
     m_channels(channels),
     m_sampleRate(sampleRate),
     m_blockSize(blockSize),
-    m_prevF0(-1.f),
+    m_prevF0(-1.0),
     m_phase(0.0),
     m_wavetype(waveType) // 0: 3 sinusoids, 1: 1 sinusoid, 2: sawtooth, 3: square
 {
@@ -40,46 +40,47 @@
 }
 
 void
-ContinuousSynth::mix(float **toBuffers, float gain, float pan, float f0)
+ContinuousSynth::mix(float **toBuffers, float gain, float pan, float f0f)
 {
-    if (f0 == 0.f) f0 = m_prevF0;
+    double f0(f0f);
+    if (f0 == 0.0) f0 = m_prevF0;
 
-    bool wasOn = (m_prevF0 > 0.f);
-    bool nowOn = (f0 > 0.f);
+    bool wasOn = (m_prevF0 > 0.0);
+    bool nowOn = (f0 > 0.0);
 
     if (!nowOn && !wasOn) {
-    m_phase = 0;
-    return;
+        m_phase = 0;
+        return;
     }
 
-    int fadeLength = 100; // samples
+    sv_frame_t fadeLength = 100;
 
     float *levels = new float[m_channels];
     
     for (int c = 0; c < m_channels; ++c) {
-    levels[c] = gain * 0.5; // scale gain otherwise too loud compared to source
+        levels[c] = gain * 0.5f; // scale gain otherwise too loud compared to source
     }
     if (pan != 0.0 && m_channels == 2) {
-    levels[0] *= 1.0 - pan;
-    levels[1] *= pan + 1.0;
+        levels[0] *= 1.0f - pan;
+        levels[1] *= pan + 1.0f;
     }
 
 //    cerr << "ContinuousSynth::mix: f0 = " << f0 << " (from " << m_prevF0 << "), phase = " << m_phase << endl;
 
-    for (int i = 0; i < m_blockSize; ++i) {
+    for (sv_frame_t i = 0; i < m_blockSize; ++i) {
 
         double fHere = (nowOn ? f0 : m_prevF0);
 
         if (wasOn && nowOn && (f0 != m_prevF0) && (i < fadeLength)) {
             // interpolate the frequency shift
-            fHere = m_prevF0 + ((f0 - m_prevF0) * i) / fadeLength;
+            fHere = m_prevF0 + ((f0 - m_prevF0) * double(i)) / double(fadeLength);
         }
 
         double phasor = (fHere * 2 * M_PI) / m_sampleRate;
     
         m_phase = m_phase + phasor;
 
-        int harmonics = (m_sampleRate / 4) / fHere - 1;
+        int harmonics = int((m_sampleRate / 4) / fHere - 1);
         if (harmonics < 1) harmonics = 1;
 
         switch (m_wavetype) {
@@ -95,7 +96,6 @@
             break;
         }
 
-
         for (int h = 0; h < harmonics; ++h) {
 
             double v = 0;
@@ -129,15 +129,15 @@
 
             if (!wasOn && i < fadeLength) {
                 // fade in
-                v = v * (i / double(fadeLength));
+                v = v * (double(i) / double(fadeLength));
             } else if (!nowOn) {
                 // fade out
                 if (i > fadeLength) v = 0;
-                else v = v * (1.0 - (i / double(fadeLength)));
+                else v = v * (1.0 - (double(i) / double(fadeLength)));
             }
 
             for (int c = 0; c < m_channels; ++c) {
-                toBuffers[c][i] += levels[c] * v;
+                toBuffers[c][i] += float(levels[c] * v);
             }
         }
     }    
--- a/audioio/ContinuousSynth.h	Mon Mar 02 17:20:23 2015 +0000
+++ b/audioio/ContinuousSynth.h	Mon Apr 20 09:21:08 2015 +0100
@@ -15,6 +15,8 @@
 #ifndef CONTINUOUS_SYNTH_H
 #define CONTINUOUS_SYNTH_H
 
+#include "base/BaseTypes.h"
+
 /**
  * Mix into a target buffer a signal synthesised so as to sound at a
  * specific frequency. The frequency may change with each processing
@@ -24,7 +26,7 @@
 class ContinuousSynth
 {
 public:
-    ContinuousSynth(int channels, int sampleRate, int blockSize, int waveType);
+    ContinuousSynth(int channels, sv_samplerate_t sampleRate, sv_frame_t blockSize, int waveType);
     ~ContinuousSynth();
     
     void setChannelCount(int channels);
@@ -45,14 +47,14 @@
      * sound switches on and off cleanly.
      */
     void mix(float **toBuffers,
-         float gain,
-         float pan,
-         float f0);
+             float gain,
+             float pan,
+             float f0);
 
 private:
     int m_channels;
-    int m_sampleRate;
-    int m_blockSize;
+    sv_samplerate_t m_sampleRate;
+    sv_frame_t m_blockSize;
 
     double m_prevF0;
     double m_phase;
--- a/audioio/PlaySpeedRangeMapper.cpp	Mon Mar 02 17:20:23 2015 +0000
+++ b/audioio/PlaySpeedRangeMapper.cpp	Mon Apr 20 09:21:08 2015 +0100
@@ -25,23 +25,23 @@
 }
 
 int
-PlaySpeedRangeMapper::getPositionForValue(float value) const
+PlaySpeedRangeMapper::getPositionForValue(double value) const
 {
     // value is percent
-    float factor = getFactorForValue(value);
+    double factor = getFactorForValue(value);
     int position = getPositionForFactor(factor);
     return position;
 }
 
 int
-PlaySpeedRangeMapper::getPositionForValueUnclamped(float value) const
+PlaySpeedRangeMapper::getPositionForValueUnclamped(double value) const
 {
     // We don't really provide this
     return getPositionForValue(value);
 }
 
 int
-PlaySpeedRangeMapper::getPositionForFactor(float factor) const
+PlaySpeedRangeMapper::getPositionForFactor(double factor) const
 {
     bool slow = (factor > 1.0);
 
@@ -49,8 +49,8 @@
     
     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);
+    factor = sqrt((factor - 1.0) * 1000.0);
+    int position = int(lrint(((factor * (half - m_minpos)) / 100.0) + m_minpos));
 
     if (slow) {
         position = half - position;
@@ -63,37 +63,37 @@
     return position;
 }
 
-float
+double
 PlaySpeedRangeMapper::getValueForPosition(int position) const
 {
-    float factor = getFactorForPosition(position);
-    float pc = getValueForFactor(factor);
+    double factor = getFactorForPosition(position);
+    double pc = getValueForFactor(factor);
     return pc;
 }
 
-float
+double
 PlaySpeedRangeMapper::getValueForPositionUnclamped(int position) const
 {
     // We don't really provide this
     return getValueForPosition(position);
 }
 
-float
-PlaySpeedRangeMapper::getValueForFactor(float factor) const
+double
+PlaySpeedRangeMapper::getValueForFactor(double factor) const
 {
-    float pc;
+    double pc;
     if (factor < 1.0) pc = ((1.0 / factor) - 1.0) * 100.0;
     else pc = (1.0 - factor) * 100.0;
 //    cerr << "position = " << position << " percent = " << pc << endl;
     return pc;
 }
 
-float
-PlaySpeedRangeMapper::getFactorForValue(float value) const
+double
+PlaySpeedRangeMapper::getFactorForValue(double value) const
 {
     // value is percent
     
-    float factor;
+    double factor;
 
     if (value <= 0) {
         factor = 1.0 - (value / 100.0);
@@ -105,7 +105,7 @@
     return factor;
 }
 
-float
+double
 PlaySpeedRangeMapper::getFactorForPosition(int position) const
 {
     bool slow = false;
@@ -124,7 +124,7 @@
 
     // position is between min and half (inclusive)
 
-    float factor;
+    double factor;
 
     if (position == m_minpos) {
         factor = 1.0;
--- a/audioio/PlaySpeedRangeMapper.h	Mon Mar 02 17:20:23 2015 +0000
+++ b/audioio/PlaySpeedRangeMapper.h	Mon Apr 20 09:21:08 2015 +0100
@@ -23,17 +23,17 @@
 public:
     PlaySpeedRangeMapper(int minpos, int maxpos);
 
-    virtual int getPositionForValue(float value) const;
-    virtual int getPositionForValueUnclamped(float value) const;
+    virtual int getPositionForValue(double value) const;
+    virtual int getPositionForValueUnclamped(double value) const;
 
-    virtual float getValueForPosition(int position) const;
-    virtual float getValueForPositionUnclamped(int position) const;
+    virtual double getValueForPosition(int position) const;
+    virtual double getValueForPositionUnclamped(int position) const;
 
-    int getPositionForFactor(float factor) const;
-    float getValueForFactor(float factor) const;
+    int getPositionForFactor(double factor) const;
+    double getValueForFactor(double factor) const;
 
-    float getFactorForPosition(int position) const;
-    float getFactorForValue(float value) const;
+    double getFactorForPosition(int position) const;
+    double getFactorForValue(double value) const;
 
     virtual QString getUnit() const;
     
--- a/configure	Mon Mar 02 17:20:23 2015 +0000
+++ b/configure	Mon Apr 20 09:21:08 2015 +0100
@@ -673,6 +673,7 @@
 EGREP
 GREP
 CXXCPP
+HAVE_CXX11
 MKDIR_P
 INSTALL_DATA
 INSTALL_SCRIPT
@@ -3449,6 +3450,146 @@
 $as_echo "$MKDIR_P" >&6; }
 
 
+# We are daringly making use of C++11 now
+
+    ax_cxx_compile_cxx11_required=true
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+  ac_success=no
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features by default" >&5
+$as_echo_n "checking whether $CXX supports C++11 features by default... " >&6; }
+if ${ax_cv_cxx_compile_cxx11+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+  template <typename T>
+    struct check
+    {
+      static_assert(sizeof(int) <= sizeof(T), "not big enough");
+    };
+
+    struct Base {
+    virtual void f() {}
+    };
+    struct Child : public Base {
+    virtual void f() override {}
+    };
+
+    typedef check<check<bool>> right_angle_brackets;
+
+    int a;
+    decltype(a) b;
+
+    typedef check<int> check_type;
+    check_type c;
+    check_type&& cr = static_cast<check_type&&>(c);
+
+    auto d = a;
+    auto l = [](){};
+
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ax_cv_cxx_compile_cxx11=yes
+else
+  ax_cv_cxx_compile_cxx11=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_cxx_compile_cxx11" >&5
+$as_echo "$ax_cv_cxx_compile_cxx11" >&6; }
+  if test x$ax_cv_cxx_compile_cxx11 = xyes; then
+    ac_success=yes
+  fi
+
+
+
+    if test x$ac_success = xno; then
+    for switch in -std=c++11 -std=c++0x; do
+      cachevar=`$as_echo "ax_cv_cxx_compile_cxx11_$switch" | $as_tr_sh`
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features with $switch" >&5
+$as_echo_n "checking whether $CXX supports C++11 features with $switch... " >&6; }
+if eval \${$cachevar+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_CXXFLAGS="$CXXFLAGS"
+         CXXFLAGS="$CXXFLAGS $switch"
+         cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+  template <typename T>
+    struct check
+    {
+      static_assert(sizeof(int) <= sizeof(T), "not big enough");
+    };
+
+    struct Base {
+    virtual void f() {}
+    };
+    struct Child : public Base {
+    virtual void f() override {}
+    };
+
+    typedef check<check<bool>> right_angle_brackets;
+
+    int a;
+    decltype(a) b;
+
+    typedef check<int> check_type;
+    check_type c;
+    check_type&& cr = static_cast<check_type&&>(c);
+
+    auto d = a;
+    auto l = [](){};
+
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval $cachevar=yes
+else
+  eval $cachevar=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+         CXXFLAGS="$ac_save_CXXFLAGS"
+fi
+eval ac_res=\$$cachevar
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+      if eval test x\$$cachevar = xyes; then
+        CXXFLAGS="$CXXFLAGS $switch"
+        ac_success=yes
+        break
+      fi
+    done
+  fi
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+  if test x$ax_cxx_compile_cxx11_required = xtrue; then
+    if test x$ac_success = xno; then
+      as_fn_error $? "*** A compiler with support for C++11 language features is required." "$LINENO" 5
+    fi
+  else
+    if test x$ac_success = xno; then
+      HAVE_CXX11=0
+      { $as_echo "$as_me:${as_lineno-$LINENO}: No compiler with C++11 support was found" >&5
+$as_echo "$as_me: No compiler with C++11 support was found" >&6;}
+    else
+      HAVE_CXX11=1
+
+$as_echo "#define HAVE_CXX11 1" >>confdefs.h
+
+    fi
+
+
+  fi
+
 
 ac_ext=cpp
 ac_cpp='$CXXCPP $CPPFLAGS'
@@ -4202,9 +4343,10 @@
 CXXFLAGS_MINIMAL="$AUTOCONF_CXXFLAGS"
 
 if test "x$GCC" = "xyes"; then
-        CXXFLAGS_DEBUG="-Wall -Wextra -Werror -Woverloaded-virtual -Wformat-nonliteral -Wformat-security -Winit-self -Wswitch-enum -g -pipe"
-   	CXXFLAGS_RELEASE="-g0 -O2 -Wall -pipe"
-   	CXXFLAGS_MINIMAL="-g0 -O0"
+   	CXXFLAGS_ANY="-Wall -Wextra -Woverloaded-virtual -Wformat-nonliteral -Wformat-security -Winit-self -Wswitch-enum -Wconversion -pipe"
+        CXXFLAGS_DEBUG="$CXXFLAGS_ANY -Werror -g"
+   	CXXFLAGS_RELEASE="$CXXFLAGS_ANY -g0 -O2"
+   	CXXFLAGS_MINIMAL="$CXXFLAGS_ANY -g0 -O0"
 fi
 
 CXXFLAGS_BUILD="$CXXFLAGS_RELEASE"
--- a/configure.ac	Mon Mar 02 17:20:23 2015 +0000
+++ b/configure.ac	Mon Apr 20 09:21:08 2015 +0100
@@ -25,6 +25,9 @@
 AC_PROG_INSTALL
 AC_PROG_MKDIR_P
 
+# We are daringly making use of C++11 now
+AX_CXX_COMPILE_STDCXX_11(noext)
+
 AC_HEADER_STDC
 
 # These are the flags Autoconf guesses for us; we use them later if
@@ -50,9 +53,10 @@
 CXXFLAGS_MINIMAL="$AUTOCONF_CXXFLAGS"
 
 if test "x$GCC" = "xyes"; then
-        CXXFLAGS_DEBUG="-Wall -Wextra -Werror -Woverloaded-virtual -Wformat-nonliteral -Wformat-security -Winit-self -Wswitch-enum -g -pipe"
-   	CXXFLAGS_RELEASE="-g0 -O2 -Wall -pipe"
-   	CXXFLAGS_MINIMAL="-g0 -O0"
+   	CXXFLAGS_ANY="-Wall -Wextra -Woverloaded-virtual -Wformat-nonliteral -Wformat-security -Winit-self -Wswitch-enum -Wconversion -pipe"
+        CXXFLAGS_DEBUG="$CXXFLAGS_ANY -Werror -g"
+   	CXXFLAGS_RELEASE="$CXXFLAGS_ANY -g0 -O2"
+   	CXXFLAGS_MINIMAL="$CXXFLAGS_ANY -g0 -O0"
 fi
 
 CXXFLAGS_BUILD="$CXXFLAGS_RELEASE"
--- a/framework/Document.cpp	Mon Mar 02 17:20:23 2015 +0000
+++ b/framework/Document.cpp	Mon Apr 20 09:21:08 2015 +0100
@@ -734,7 +734,7 @@
         applied.setPluginVersion
             (TransformFactory::getInstance()->
              getDefaultTransformFor(applied.getIdentifier(),
-                                    lrintf(applied.getSampleRate()))
+                                    applied.getSampleRate())
              .getPluginVersion());
 
         if (!model) {
--- a/framework/MainWindowBase.cpp	Mon Mar 02 17:20:23 2015 +0000
+++ b/framework/MainWindowBase.cpp	Mon Apr 20 09:21:08 2015 +0100
@@ -54,7 +54,6 @@
 #include "data/fileio/DataFileReaderFactory.h"
 #include "data/fileio/PlaylistFileReader.h"
 #include "data/fileio/WavFileWriter.h"
-#include "data/fileio/CSVFileWriter.h"
 #include "data/fileio/MIDIFileWriter.h"
 #include "data/fileio/BZipFileDevice.h"
 #include "data/fileio/FileSource.h"
@@ -106,9 +105,6 @@
 #include <cstdio>
 #include <errno.h>
 
-
-
-
 using std::vector;
 using std::map;
 using std::set;
@@ -161,6 +157,9 @@
 {
     Profiler profiler("MainWindowBase::MainWindowBase");
 
+    qRegisterMetaType<sv_frame_t>("sv_frame_t");
+    qRegisterMetaType<sv_samplerate_t>("sv_samplerate_t");
+
 #ifdef Q_WS_X11
     XSetErrorHandler(handle_x11_error);
 #endif
@@ -178,7 +177,7 @@
 
     // set a sensible default font size for views -- cannot do this
     // in Preferences, which is in base and not supposed to use QtGui
-    int viewFontSize = QApplication::font().pointSize() * 0.9;
+    int viewFontSize = int(QApplication::font().pointSize() * 0.9);
     QSettings settings;
     settings.beginGroup("Preferences");
     viewFontSize = settings.value("view-font-size", viewFontSize).toInt();
@@ -218,8 +217,8 @@
     m_playSource = new AudioCallbackPlaySource(m_viewManager,
                                                QApplication::applicationName());
 
-    connect(m_playSource, SIGNAL(sampleRateMismatch(int, int, bool)),
-	    this,           SLOT(sampleRateMismatch(int, int, bool)));
+    connect(m_playSource, SIGNAL(sampleRateMismatch(sv_samplerate_t, sv_samplerate_t, bool)),
+	    this,           SLOT(sampleRateMismatch(sv_samplerate_t, sv_samplerate_t, bool)));
     connect(m_playSource, SIGNAL(audioOverloadPluginDisabled()),
             this,           SLOT(audioOverloadPluginDisabled()));
     connect(m_playSource, SIGNAL(audioTimeStretchMultiChannelDisabled()),
@@ -228,14 +227,14 @@
     connect(m_viewManager, SIGNAL(outputLevelsChanged(float, float)),
 	    this, SLOT(outputLevelsChanged(float, float)));
 
-    connect(m_viewManager, SIGNAL(playbackFrameChanged(int)),
-            this, SLOT(playbackFrameChanged(int)));
-
-    connect(m_viewManager, SIGNAL(globalCentreFrameChanged(int)),
-            this, SLOT(globalCentreFrameChanged(int)));
-
-    connect(m_viewManager, SIGNAL(viewCentreFrameChanged(View *, int)),
-            this, SLOT(viewCentreFrameChanged(View *, int)));
+    connect(m_viewManager, SIGNAL(playbackFrameChanged(sv_frame_t)),
+            this, SLOT(playbackFrameChanged(sv_frame_t)));
+
+    connect(m_viewManager, SIGNAL(globalCentreFrameChanged(sv_frame_t)),
+            this, SLOT(globalCentreFrameChanged(sv_frame_t)));
+
+    connect(m_viewManager, SIGNAL(viewCentreFrameChanged(View *, sv_frame_t)),
+            this, SLOT(viewCentreFrameChanged(View *, sv_frame_t)));
 
     connect(m_viewManager, SIGNAL(viewZoomLevelChanged(View *, int, bool)),
             this, SLOT(viewZoomLevelChanged(View *, int, bool)));
@@ -345,6 +344,12 @@
     // "ambiguous shortcut" errors from the menu entry actions and
     // will need to update the code.)
 
+    // Update: The bug was fixed in Qt 5.4 for shortcuts with no
+    // modifier, and I believe it is fixed in Qt 5.5 for shortcuts
+    // with Shift modifiers. The below reflects that
+
+#if (QT_VERSION < QT_VERSION_CHECK(5, 5, 0))
+
     if (!m_menuShortcutMapper) {
         m_menuShortcutMapper = new QSignalMapper(this);
         connect(m_menuShortcutMapper, SIGNAL(mapped(QObject *)),
@@ -374,9 +379,17 @@
             // working and that we need to handle here includes those
             // with the Shift modifier mask as well as those with no
             // modifier at all
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0))
+            // Nothing needed
+            if (false) {
+#elif (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0))
+            if (sc.count() == 1 &&
+                (sc[0] & Qt::KeyboardModifierMask) == Qt::ShiftModifier) {
+#else
             if (sc.count() == 1 &&
                 ((sc[0] & Qt::KeyboardModifierMask) == Qt::NoModifier ||
                  (sc[0] & Qt::KeyboardModifierMask) == Qt::ShiftModifier)) {
+#endif
                 QShortcut *newSc = new QShortcut(sc, a->parentWidget());
                 QObject::connect(newSc, SIGNAL(activated()),
                                  m_menuShortcutMapper, SLOT(map()));
@@ -386,6 +399,7 @@
         }
     }
 #endif
+#endif
 }
 
 void
@@ -691,7 +705,7 @@
     // frame before switching to whichever one we decide we want to
     // switch to, regardless of our efforts.
 
-    int frame = m_playSource->getCurrentBufferedFrame();
+    sv_frame_t frame = m_playSource->getCurrentBufferedFrame();
 
     cerr << "currentPaneChanged: current frame (in ref model) = " << frame << endl;
 
@@ -780,7 +794,7 @@
     Pane *currentPane = m_paneStack->getCurrentPane();
     if (!currentPane) return;
 
-    int startFrame, endFrame;
+    sv_frame_t startFrame, endFrame;
 
     if (currentPane->getStartFrame() < 0) startFrame = 0;
     else startFrame = currentPane->getStartFrame();
@@ -851,11 +865,11 @@
 void
 MainWindowBase::pasteAtPlaybackPosition()
 {
-    int pos = getFrame();
+    sv_frame_t pos = getFrame();
     Clipboard &clipboard = m_viewManager->getClipboard();
     if (!clipboard.empty()) {
-        int firstEventFrame = clipboard.getPoints()[0].getFrame();
-        int offset = 0;
+        sv_frame_t firstEventFrame = clipboard.getPoints()[0].getFrame();
+        sv_frame_t offset = 0;
         if (firstEventFrame < 0) {
             offset = pos - firstEventFrame;
         } else if (firstEventFrame < pos) {
@@ -868,7 +882,7 @@
 }
 
 void
-MainWindowBase::pasteRelative(int offset)
+MainWindowBase::pasteRelative(sv_frame_t offset)
 {
     Pane *currentPane = m_paneStack->getCurrentPane();
     if (!currentPane) return;
@@ -936,7 +950,7 @@
 
 // FrameTimer method
 
-int
+sv_frame_t
 MainWindowBase::getFrame() const
 {
     if (m_playSource && m_playSource->isPlaying()) {
@@ -958,8 +972,8 @@
     MultiSelection::SelectionList selections = m_viewManager->getSelections();
     for (MultiSelection::SelectionList::iterator i = selections.begin();
          i != selections.end(); ++i) {
-        int start = i->getStartFrame();
-        int end = i->getEndFrame();
+        sv_frame_t start = i->getStartFrame();
+        sv_frame_t end = i->getEndFrame();
         if (start != end) {
             insertInstantAt(start);
             insertInstantAt(end);
@@ -968,7 +982,7 @@
 }
 
 void
-MainWindowBase::insertInstantAt(int frame)
+MainWindowBase::insertInstantAt(sv_frame_t frame)
 {
     Pane *pane = m_paneStack->getCurrentPane();
     if (!pane) {
@@ -1060,8 +1074,8 @@
     MultiSelection::SelectionList selections = m_viewManager->getSelections();
     for (MultiSelection::SelectionList::iterator i = selections.begin();
          i != selections.end(); ++i) {
-        int start = i->getStartFrame();
-        int end = i->getEndFrame();
+        sv_frame_t start = i->getStartFrame();
+        sv_frame_t end = i->getEndFrame();
         if (start < end) {
             insertItemAt(start, end - start);
         }
@@ -1069,7 +1083,7 @@
 }
 
 void
-MainWindowBase::insertItemAt(int frame, int duration)
+MainWindowBase::insertItemAt(sv_frame_t frame, sv_frame_t duration)
 {
     Pane *pane = m_paneStack->getCurrentPane();
     if (!pane) {
@@ -1078,10 +1092,10 @@
 
     // ugh!
 
-    int alignedStart = pane->alignFromReference(frame);
-    int alignedEnd = pane->alignFromReference(frame + duration);
+    sv_frame_t alignedStart = pane->alignFromReference(frame);
+    sv_frame_t alignedEnd = pane->alignFromReference(frame + duration);
     if (alignedStart >= alignedEnd) return;
-    int alignedDuration = alignedEnd - alignedStart;
+    sv_frame_t alignedDuration = alignedEnd - alignedStart;
 
     Command *c = 0;
 
@@ -1281,7 +1295,7 @@
 
     m_openingAudioFile = true;
 
-    int rate = 0;
+    sv_samplerate_t rate = 0;
 
     if (Preferences::getInstance()->getFixedSampleRate() != 0) {
         rate = Preferences::getInstance()->getFixedSampleRate();
@@ -1990,7 +2004,7 @@
 MainWindowBase::FileOpenStatus
 MainWindowBase::openLayersFromRDF(FileSource source)
 {
-    int rate = 0;
+    sv_samplerate_t rate = 0;
 
     SVDEBUG << "MainWindowBase::openLayersFromRDF" << endl;
 
@@ -2370,8 +2384,8 @@
     Model *model = getMainModel();
     if (!model) return;
     
-    int start = model->getStartFrame();
-    int end = model->getEndFrame();
+    sv_frame_t start = model->getStartFrame();
+    sv_frame_t end = model->getEndFrame();
     if (m_playSource) end = std::max(end, m_playSource->getPlayEndFrame());
     int pixels = currentPane->width();
 
@@ -2380,7 +2394,7 @@
     else pixels = 1;
     if (pixels > 4) pixels -= 4;
 
-    int zoomLevel = (end - start) / pixels;
+    int zoomLevel = int((end - start) / pixels);
     if (zoomLevel < 1) zoomLevel = 1;
 
     currentPane->setZoomLevel(zoomLevel);
@@ -2609,18 +2623,18 @@
 {
     if (!getMainModel()) return;
 
-    int frame = m_viewManager->getPlaybackFrame();
+    sv_frame_t frame = m_viewManager->getPlaybackFrame();
     ++frame;
 
     Pane *pane = m_paneStack->getCurrentPane();
     Layer *layer = getSnapLayer();
-    int sr = getMainModel()->getSampleRate();
+    sv_samplerate_t sr = getMainModel()->getSampleRate();
 
     if (!layer) {
 
         frame = RealTime::realTime2Frame
             (RealTime::frame2RealTime(frame, sr) + m_defaultFfwdRwdStep, sr);
-        if (frame > int(getMainModel()->getEndFrame())) {
+        if (frame > getMainModel()->getEndFrame()) {
             frame = getMainModel()->getEndFrame();
         }
 
@@ -2639,12 +2653,12 @@
     if (frame < 0) frame = 0;
 
     if (m_viewManager->getPlaySelectionMode()) {
-        frame = m_viewManager->constrainFrameToSelection(int(frame));
+        frame = m_viewManager->constrainFrameToSelection(frame);
     }
     
     m_viewManager->setPlaybackFrame(frame);
 
-    if (frame == (int)getMainModel()->getEndFrame() &&
+    if (frame == getMainModel()->getEndFrame() &&
         m_playSource &&
         m_playSource->isPlaying() &&
         !m_viewManager->getPlayLoopMode()) {
@@ -2663,7 +2677,7 @@
         stop();
     }
 
-    int frame = getMainModel()->getEndFrame();
+    sv_frame_t frame = getMainModel()->getEndFrame();
 
     if (m_viewManager->getPlaySelectionMode()) {
         frame = m_viewManager->constrainFrameToSelection(frame);
@@ -2681,7 +2695,7 @@
     if (!layer) { ffwd(); return; }
 
     Pane *pane = m_paneStack->getCurrentPane();
-    int frame = m_viewManager->getPlaybackFrame();
+    sv_frame_t frame = m_viewManager->getPlaybackFrame();
 
     int resolution = 0;
     if (pane) frame = pane->alignFromReference(frame);
@@ -2695,12 +2709,12 @@
     if (frame < 0) frame = 0;
 
     if (m_viewManager->getPlaySelectionMode()) {
-        frame = m_viewManager->constrainFrameToSelection(int(frame));
+        frame = m_viewManager->constrainFrameToSelection(frame);
     }
     
     m_viewManager->setPlaybackFrame(frame);
 
-    if (frame == (int)getMainModel()->getEndFrame() &&
+    if (frame == getMainModel()->getEndFrame() &&
         m_playSource &&
         m_playSource->isPlaying() &&
         !m_viewManager->getPlayLoopMode()) {
@@ -2713,12 +2727,12 @@
 {
     if (!getMainModel()) return;
 
-    int frame = m_viewManager->getPlaybackFrame();
+    sv_frame_t frame = m_viewManager->getPlaybackFrame();
     if (frame > 0) --frame;
 
     Pane *pane = m_paneStack->getCurrentPane();
     Layer *layer = getSnapLayer();
-    int sr = getMainModel()->getSampleRate();
+    sv_samplerate_t sr = getMainModel()->getSampleRate();
     
     // when rewinding during playback, we want to allow a period
     // following a rewind target point at which the rewind will go to
@@ -2734,7 +2748,7 @@
         
         frame = RealTime::realTime2Frame
             (RealTime::frame2RealTime(frame, sr) - m_defaultFfwdRwdStep, sr);
-        if (frame < int(getMainModel()->getStartFrame())) {
+        if (frame < getMainModel()->getStartFrame()) {
             frame = getMainModel()->getStartFrame();
         }
 
@@ -2753,7 +2767,7 @@
     if (frame < 0) frame = 0;
 
     if (m_viewManager->getPlaySelectionMode()) {
-        frame = m_viewManager->constrainFrameToSelection(int(frame));
+        frame = m_viewManager->constrainFrameToSelection(frame);
     }
 
     m_viewManager->setPlaybackFrame(frame);
@@ -2764,7 +2778,7 @@
 {
     if (!getMainModel()) return;
 
-    int frame = getMainModel()->getStartFrame();
+    sv_frame_t frame = getMainModel()->getStartFrame();
 
     if (m_viewManager->getPlaySelectionMode()) {
         frame = m_viewManager->constrainFrameToSelection(frame);
@@ -2782,7 +2796,7 @@
     if (!layer) { rewind(); return; }
 
     Pane *pane = m_paneStack->getCurrentPane();
-    int frame = m_viewManager->getPlaybackFrame();
+    sv_frame_t frame = m_viewManager->getPlaybackFrame();
 
     int resolution = 0;
     if (pane) frame = pane->alignFromReference(frame);
@@ -2796,7 +2810,7 @@
     if (frame < 0) frame = 0;
 
     if (m_viewManager->getPlaySelectionMode()) {
-        frame = m_viewManager->constrainFrameToSelection(int(frame));
+        frame = m_viewManager->constrainFrameToSelection(frame);
     }
     
     m_viewManager->setPlaybackFrame(frame);
@@ -3009,24 +3023,24 @@
 MainWindowBase::connectLayerEditDialog(ModelDataTableDialog *dialog)
 {
     connect(m_viewManager,
-            SIGNAL(globalCentreFrameChanged(int)),
+            SIGNAL(globalCentreFrameChanged(sv_frame_t)),
             dialog,
-            SLOT(userScrolledToFrame(int)));
+            SLOT(userScrolledToFrame(sv_frame_t)));
 
     connect(m_viewManager,
-            SIGNAL(playbackFrameChanged(int)),
+            SIGNAL(playbackFrameChanged(sv_frame_t)),
             dialog,
-            SLOT(playbackScrolledToFrame(int)));
+            SLOT(playbackScrolledToFrame(sv_frame_t)));
 
     connect(dialog,
-            SIGNAL(scrollToFrame(int)),
+            SIGNAL(scrollToFrame(sv_frame_t)),
             m_viewManager,
-            SLOT(setGlobalCentreFrame(int)));
+            SLOT(setGlobalCentreFrame(sv_frame_t)));
 
     connect(dialog,
-            SIGNAL(scrollToFrame(int)),
+            SIGNAL(scrollToFrame(sv_frame_t)),
             m_viewManager,
-            SLOT(setPlaybackFrame(int)));
+            SLOT(setPlaybackFrame(sv_frame_t)));
 }    
 
 void
@@ -3136,7 +3150,7 @@
 }
 
 void
-MainWindowBase::playbackFrameChanged(int frame)
+MainWindowBase::playbackFrameChanged(sv_frame_t frame)
 {
     if (!(m_playSource && m_playSource->isPlaying()) || !getMainModel()) return;
 
@@ -3172,7 +3186,7 @@
 }
 
 void
-MainWindowBase::globalCentreFrameChanged(int )
+MainWindowBase::globalCentreFrameChanged(sv_frame_t )
 {
     if ((m_playSource && m_playSource->isPlaying()) || !getMainModel()) return;
     Pane *p = 0;
@@ -3182,7 +3196,7 @@
 }
 
 void
-MainWindowBase::viewCentreFrameChanged(View *v, int frame)
+MainWindowBase::viewCentreFrameChanged(View *v, sv_frame_t frame)
 {
 //    SVDEBUG << "MainWindowBase::viewCentreFrameChanged(" << v << "," << frame << ")" << endl;
 
--- a/framework/MainWindowBase.h	Mon Mar 02 17:20:23 2015 +0000
+++ b/framework/MainWindowBase.h	Mon Apr 20 09:21:08 2015 +0100
@@ -111,7 +111,7 @@
     virtual bool saveSessionTemplate(QString path);
 
     /// Implementation of FrameTimer interface method
-    virtual int getFrame() const;
+    virtual sv_frame_t getFrame() const;
 
     void setDefaultFfwdRwdStep(RealTime step) {
         m_defaultFfwdRwdStep = step;
@@ -213,13 +213,13 @@
     virtual void playSelectionToggled();
     virtual void playSoloToggled();
 
-    virtual void sampleRateMismatch(int, int, bool) = 0;
+    virtual void sampleRateMismatch(sv_samplerate_t, sv_samplerate_t, bool) = 0;
     virtual void audioOverloadPluginDisabled() = 0;
     virtual void audioTimeStretchMultiChannelDisabled() = 0;
 
-    virtual void playbackFrameChanged(int);
-    virtual void globalCentreFrameChanged(int);
-    virtual void viewCentreFrameChanged(View *, int);
+    virtual void playbackFrameChanged(sv_frame_t);
+    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;
 
@@ -236,14 +236,14 @@
     virtual void copy();
     virtual void paste();
     virtual void pasteAtPlaybackPosition();
-    virtual void pasteRelative(int offset);
+    virtual void pasteRelative(sv_frame_t offset);
     virtual void deleteSelected();
 
     virtual void insertInstant();
-    virtual void insertInstantAt(int);
+    virtual void insertInstantAt(sv_frame_t);
     virtual void insertInstantsAtBoundaries();
     virtual void insertItemAtSelection();
-    virtual void insertItemAt(int, int);
+    virtual void insertItemAt(sv_frame_t, sv_frame_t);
     virtual void renumberInstants();
 
     virtual void documentModified();
@@ -366,7 +366,7 @@
 	virtual void setWindowSize(int width, int height) {
 	    m_mw->resizeConstrained(QSize(width, height));
 	}
-	virtual void addSelection(int start, int end) {
+	virtual void addSelection(sv_frame_t start, sv_frame_t end) {
 	    m_mw->m_viewManager->addSelectionQuietly(Selection(start, end));
 	}
     protected:
--- a/framework/SVFileReader.cpp	Mon Mar 02 17:20:23 2015 +0000
+++ b/framework/SVFileReader.cpp	Mon Apr 20 09:21:08 2015 +0100
@@ -450,7 +450,7 @@
 
     SVDEBUG << "SVFileReader::readModel: model name \"" << name << "\"" << endl;
 
-    READ_MANDATORY(int, sampleRate, toInt);
+    READ_MANDATORY(double, sampleRate, toDouble);
 
     QString type = attributes.value("type").trimmed();
     bool isMainModel = (attributes.value("mainModel").trimmed() == "true");
@@ -478,7 +478,7 @@
 
             file.waitForData();
 
-            int rate = sampleRate;
+            sv_samplerate_t rate = sampleRate;
 
             if (Preferences::getInstance()->getFixedSampleRate() != 0) {
                 rate = Preferences::getInstance()->getFixedSampleRate();
@@ -886,13 +886,18 @@
 	    } else {
 		cerr << "WARNING: SV-XML: Unknown model id " << modelId
 			  << " in layer definition" << endl;
+
+                // Don't add a layer with an unknown model id
+                m_document->deleteLayer(layer);
+                m_layers[id] = layer = 0;
+                return false;
 	    }
 	}
 
-	layer->setProperties(attributes);
+        if (layer) layer->setProperties(attributes);
     }
 
-    if (!m_inData && m_currentPane) {
+    if (!m_inData && m_currentPane && layer) {
 
         QString visible = attributes.value("visible");
         bool dormant = (visible == "false");
@@ -912,7 +917,7 @@
     }
 
     m_currentLayer = layer;
-    m_inLayer = true;
+    m_inLayer = (layer != 0);
 
     return true;
 }
@@ -999,7 +1004,7 @@
 	(m_currentDataset);
 
     if (stvm) {
-        cerr << "Current dataset is a sparse time-value model" << endl;
+//        cerr << "Current dataset is a sparse time-value model" << endl;
 	float value = 0.0;
 	value = attributes.value("value").trimmed().toFloat(&ok);
 	QString label = attributes.value("label");
@@ -1010,7 +1015,7 @@
     NoteModel *nm = dynamic_cast<NoteModel *>(m_currentDataset);
 
     if (nm) {
-        cerr << "Current dataset is a note model" << endl;
+//        cerr << "Current dataset is a note model" << endl;
 	float value = 0.0;
 	value = attributes.value("value").trimmed().toFloat(&ok);
 	int duration = 0;
@@ -1028,7 +1033,7 @@
     FlexiNoteModel *fnm = dynamic_cast<FlexiNoteModel *>(m_currentDataset);
 
     if (fnm) {
-        cerr << "Current dataset is a flexinote model" << endl;
+//        cerr << "Current dataset is a flexinote model" << endl;
 	float value = 0.0;
 	value = attributes.value("value").trimmed().toFloat(&ok);
 	int duration = 0;
@@ -1046,7 +1051,7 @@
     RegionModel *rm = dynamic_cast<RegionModel *>(m_currentDataset);
 
     if (rm) {
-        cerr << "Current dataset is a region model" << endl;
+//        cerr << "Current dataset is a region model" << endl;
 	float value = 0.0;
 	value = attributes.value("value").trimmed().toFloat(&ok);
 	int duration = 0;
--- a/framework/SVFileReader.h	Mon Mar 02 17:20:23 2015 +0000
+++ b/framework/SVFileReader.h	Mon Apr 20 09:21:08 2015 +0100
@@ -34,7 +34,7 @@
     virtual ~SVFileReaderPaneCallback();
     virtual Pane *addPane() = 0;
     virtual void setWindowSize(int width, int height) = 0;
-    virtual void addSelection(int start, int end) = 0;
+    virtual void addSelection(sv_frame_t start, sv_frame_t end) = 0;
 };
 
 /**
--- a/framework/TransformUserConfigurator.cpp	Mon Mar 02 17:20:23 2015 +0000
+++ b/framework/TransformUserConfigurator.cpp	Mon Apr 20 09:21:08 2015 +0100
@@ -46,8 +46,8 @@
     if (plugin && plugin->getType() == "Feature Extraction Plugin") {
 	Vamp::Plugin *vp = static_cast<Vamp::Plugin *>(plugin);
 	SVDEBUG << "TransformUserConfigurator::getChannelRange: is a VP" << endl;
-        minChannels = vp->getMinChannelCount();
-        maxChannels = vp->getMaxChannelCount();
+        minChannels = int(vp->getMinChannelCount());
+        maxChannels = int(vp->getMaxChannelCount());
         return true;
     } else {
 	SVDEBUG << "TransformUserConfigurator::getChannelRange: is not a VP" << endl;
@@ -62,8 +62,8 @@
 				     Vamp::PluginBase *plugin,
                                      Model *&inputModel,
 				     AudioPlaySource *source,
-				     int startFrame,
-				     int duration,
+				     sv_frame_t startFrame,
+				     sv_frame_t duration,
 				     const QMap<QString, Model *> &modelMap,
 				     QStringList candidateModelNames,
 				     QString defaultModelName)
--- a/framework/TransformUserConfigurator.h	Mon Mar 02 17:20:23 2015 +0000
+++ b/framework/TransformUserConfigurator.h	Mon Apr 20 09:21:08 2015 +0100
@@ -27,8 +27,8 @@
                            Vamp::PluginBase *plugin,
                            Model *&inputModel,
 			   AudioPlaySource *source,
-			   int startFrame,
-			   int duration,
+			   sv_frame_t startFrame,
+			   sv_frame_t duration,
 			   const QMap<QString, Model *> &modelMap,
                            QStringList candidateModelNames,
                            QString defaultModelName);
--- a/svapp.pro	Mon Mar 02 17:20:23 2015 +0000
+++ b/svapp.pro	Mon Apr 20 09:21:08 2015 +0100
@@ -30,7 +30,7 @@
     }
 }
 
-CONFIG += staticlib qt thread warn_on stl rtti exceptions
+CONFIG += staticlib qt thread warn_on stl rtti exceptions c++11
 QT += network xml gui widgets
 
 TARGET = svapp