diff --git a/src/AudioIO.cpp b/src/AudioIO.cpp
index a9b8599a5..95b7aff1e 100644
--- a/src/AudioIO.cpp
+++ b/src/AudioIO.cpp
@@ -3887,7 +3887,7 @@ void AudioIO::FillMidiBuffers()
          break;
       }
    int numMidiPlaybackTracks = gAudioIO->mMidiPlaybackTracks.size();
-   for(t = 0; t < numMidiPlaybackTracks; t++ )
+   for(unsigned t = 0; t < numMidiPlaybackTracks; t++ )
       if( gAudioIO->mMidiPlaybackTracks[t]->GetSolo() ) {
          hasSolo = true;
          break;
@@ -4360,7 +4360,7 @@ int audacityAudioCallback(const void *inputBuffer, void *outputBuffer,
                numSolo++;
 #ifdef EXPERIMENTAL_MIDI_OUT
          int numMidiPlaybackTracks = gAudioIO->mMidiPlaybackTracks.size();
-         for( t = 0; t < numMidiPlaybackTracks; t++ )
+         for( unsigned t = 0; t < numMidiPlaybackTracks; t++ )
             if( gAudioIO->mMidiPlaybackTracks[t]->GetSolo() )
                numSolo++;
 #endif
diff --git a/src/Printing.cpp b/src/Printing.cpp
index c7ff94004..860b9d845 100644
--- a/src/Printing.cpp
+++ b/src/Printing.cpp
@@ -109,7 +109,8 @@ bool AudacityPrintout::OnPrintPage(int WXUNUSED(page))
          r.y = y;
          r.width = width;
          r.height = (int)(n->GetHeight(true) * scale);
-         artist.DrawTrack(n, *dc, r, &viewInfo, false, false, false, false);
+         artist.DrawTrack(
+            n, *dc, r, SelectedRegion{}, zoomInfo, false, false, false, false);
          dc->SetPen(*wxBLACK_PEN);
          AColor::Line(*dc, 0, r.y, width, r.y);
       }
diff --git a/src/RealFFTf.cpp b/src/RealFFTf.cpp
index c30b7672f..53faa98fa 100644
--- a/src/RealFFTf.cpp
+++ b/src/RealFFTf.cpp
@@ -36,6 +36,7 @@
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
+#include "Audacity.h"
 #include <stdlib.h>
 #include <stdio.h>
 #include <math.h>
diff --git a/src/RealFFTf48x.cpp b/src/RealFFTf48x.cpp
index e623995a4..bed452578 100644
--- a/src/RealFFTf48x.cpp
+++ b/src/RealFFTf48x.cpp
@@ -51,6 +51,7 @@
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
+#include "Audacity.h"
 #include "Experimental.h"
 #ifdef EXPERIMENTAL_EQ_SSE_THREADED
 
@@ -376,7 +377,7 @@ void RealFFTf1xSinCosBRTable(fft_type *buffer,HFFT h)
             *(A++) = *(B++) + 2 * v2;
          }
          A = B;
-         B + =ButterfliesPerGroup * 2;
+         B += ButterfliesPerGroup * 2;
          sptr += 2;
       }
       ButterfliesPerGroup >>= 1;
diff --git a/src/RealFFTf48x.h b/src/RealFFTf48x.h
index f0e85ee72..c79824f94 100644
--- a/src/RealFFTf48x.h
+++ b/src/RealFFTf48x.h
@@ -93,7 +93,7 @@ public:
 };
 
 int SmallRB(int bits, int numberBits);
-int (*SmallVRB[])(int bits);
+extern int (*SmallVRB[])(int bits);
 
 
 #endif
diff --git a/src/Track.cpp b/src/Track.cpp
index ae319b915..0a2b94c7a 100644
--- a/src/Track.cpp
+++ b/src/Track.cpp
@@ -778,8 +778,10 @@ void TrackList::RecalcPositions(TrackNodePointer node)
 
 #ifdef EXPERIMENTAL_OUTPUT_DISPLAY
    int cnt = 0;
-   if (node->prev) {
-      t = node->prev->t;
+   if (hasPrev(node)) {
+      auto prev = node;
+      --prev;
+      t = prev->get();
       i = t->GetIndex() + 1;
       if(MONO_WAVE_PAN(t))
          y = t->GetY(true) + t->GetHeight(true);
@@ -787,8 +789,8 @@ void TrackList::RecalcPositions(TrackNodePointer node)
          y = t->GetY() + t->GetHeight();
    }
 
-   for (const TrackListNode *n = node; n; n = n->next) {
-      t = n->t;
+   for (auto n = node; n != end(); ++n) {
+      t = n->get();
       if(MONO_WAVE_PAN(t))
          cnt++;
 
@@ -1314,8 +1316,8 @@ int TrackList::GetHeight() const
    int height = 0;
 
 #ifdef EXPERIMENTAL_OUTPUT_DISPLAY
-   if (tail) {
-      const Track *t = tail->t;
+   if (!empty()) {
+      const Track *t = rbegin()->get();
       if(MONO_WAVE_PAN(t))
          height = t->GetY(true) + t->GetHeight(true);
       else
diff --git a/src/TrackArtist.cpp b/src/TrackArtist.cpp
index 7d4385d33..af375dfea 100644
--- a/src/TrackArtist.cpp
+++ b/src/TrackArtist.cpp
@@ -430,7 +430,7 @@ void TrackArtist::DrawTracks(TrackList * tracks,
             rr.y += mInsetTop;
             rr.width -= (mInsetLeft + mInsetRight);
             rr.height -= (mInsetTop + mInsetBottom);
-            DrawTrack(t, dc, rr, zoomInfo,
+            DrawTrack(t, dc, rr, selectedRegion, zoomInfo,
                       drawEnvelope, bigPoints, drawSliders, hasSolo);
          }
       }
@@ -1224,7 +1224,7 @@ void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect & rect, const double env[
 #ifdef EXPERIMENTAL_OUTPUT_DISPLAY
       r1[x0] = GetWaveYPos(-rms[x0] * env[x0]*gain, zoomMin, zoomMax,
                           rect.height, dB, true, dBRange, true);
-      r2[x0] = GetWaveYPos(rms[xx0 * env[x0]*gain, zoomMin, zoomMax,
+      r2[x0] = GetWaveYPos(rms[x0] * env[x0]*gain, zoomMin, zoomMax,
                           rect.height, dB, true, dBRange, true);
 #else
       r1[x0] = GetWaveYPos(-rms[x0] * env[x0], zoomMin, zoomMax,
@@ -2155,8 +2155,8 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache,
 
 #ifdef EXPERIMENTAL_FIND_NOTES
    const bool &fftFindNotes = settings.fftFindNotes;
-   const bool &findNotesMinA = settings.findNotesMinA;
-   const bool &numberOfMaxima = settings.numberOfMaxima;
+   const double &findNotesMinA = settings.findNotesMinA;
+   const int &numberOfMaxima = settings.numberOfMaxima;
    const bool &findNotesQuantize = settings.findNotesQuantize;
 #endif
 #ifdef EXPERIMENTAL_FFT_Y_GRID
@@ -2267,6 +2267,8 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache,
 #endif
 
 #ifdef EXPERIMENTAL_FIND_NOTES
+      float log2 = logf( 2.0f ),
+         lmin = logf( minFreq ), lmax = logf( maxFreq ), scale = lmax - lmin,
          lmins = lmin,
          lmaxs = lmax
          ;
@@ -2290,6 +2292,71 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache,
 #pragma omp parallel for
 #endif
       for (int xx = 0; xx < hiddenMid.width; ++xx) {
+#ifdef EXPERIMENTAL_FIND_NOTES
+         int maximas = 0;
+         const int x0 = half * xx;
+         if (fftFindNotes) {
+            for (int i = maxTableSize - 1; i >= 0; i--)
+               indexes[i] = -1;
+
+            // Build a table of (most) values, put the index in it.
+            for (int i = (int)(i0); i < (int)(i1); i++) {
+               float freqi = freq[x0 + (int)(i)];
+               int value = (int)((freqi + gain + range) / range*(maxTableSize - 1));
+               if (value < 0)
+                  value = 0;
+               if (value >= maxTableSize)
+                  value = maxTableSize - 1;
+               indexes[value] = i;
+            }
+            // Build from the indices an array of maxima.
+            for (int i = maxTableSize - 1; i >= 0; i--) {
+               int index = indexes[i];
+               if (index >= 0) {
+                  float freqi = freq[x0 + index];
+                  if (freqi < findNotesMinA)
+                     break;
+
+                  bool ok = true;
+                  for (int m = 0; m < maximas; m++) {
+                     // Avoid to store very close maxima.
+                     float maxm = maxima[m];
+                     if (maxm / index < minDistance && index / maxm < minDistance) {
+                        ok = false;
+                        break;
+                     }
+                  }
+                  if (ok) {
+                     maxima[maximas++] = index;
+                     if (maximas >= numberOfMaxima)
+                        break;
+                  }
+               }
+            }
+
+// The f2pix helper macro converts a frequency into a pixel coordinate.
+#define f2pix(f) (logf(f)-lmins)/(lmaxs-lmins)*hiddenMid.height
+
+            // Possibly quantize the maxima frequencies and create the pixel block limits.
+            for (int i = 0; i < maximas; i++) {
+               int index = maxima[i];
+               float f = float(index)*bin2f;
+               if (findNotesQuantize)
+               {
+                  f = expf((int)(log(f / 440) / log2 * 12 - 0.5) / 12.0f*log2) * 440;
+                  maxima[i] = f*f2bin;
+               }
+               float f0 = expf((log(f / 440) / log2 * 24 - 1) / 24.0f*log2) * 440;
+               maxima0[i] = f2pix(f0);
+               float f1 = expf((log(f / 440) / log2 * 24 + 1) / 24.0f*log2) * 440;
+               maxima1[i] = f2pix(f1);
+            }
+         }
+
+         int it = 0;
+         bool inMaximum = false;
+#endif //EXPERIMENTAL_FIND_NOTES
+
          for (int yy = 0; yy < hiddenMid.height; ++yy) {
             const float bin     = bins[yy];
             const float nextBin = bins[yy+1];
@@ -2300,72 +2367,6 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache,
                clip->mSpecPxCache->values[xx * hiddenMid.height + yy] = value;
             }
             else {
-               // Do we need this legacy experiment still?
-#ifdef EXPERIMENTAL_FIND_NOTES
-               int maximas = 0;
-               const int x0 = half * x;
-               if (fftFindNotes) {
-                  for (int i = maxTableSize - 1; i >= 0; i--)
-                     indexes[i] = -1;
-
-                  // Build a table of (most) values, put the index in it.
-                  for (int i = (int)(i0); i < (int)(i1); i++) {
-                     float freqi = freq[x0 + (int)(i)];
-                     int value = (int)((freqi + gain + range) / range*(maxTableSize - 1));
-                     if (value < 0)
-                        value = 0;
-                     if (value >= maxTableSize)
-                        value = maxTableSize - 1;
-                     indexes[value] = i;
-                  }
-                  // Build from the indices an array of maxima.
-                  for (int i = maxTableSize - 1; i >= 0; i--) {
-                     int index = indexes[i];
-                     if (index >= 0) {
-                        float freqi = freq[x0 + index];
-                        if (freqi < findNotesMinA)
-                           break;
-
-                        bool ok = true;
-                        for (int m = 0; m < maximas; m++) {
-                           // Avoid to store very close maxima.
-                           float maxm = maxima[m];
-                           if (maxm / index < minDistance && index / maxm < minDistance) {
-                              ok = false;
-                              break;
-                           }
-                        }
-                        if (ok) {
-                           maxima[maximas++] = index;
-                           if (maximas >= numberOfMaxima)
-                              break;
-                        }
-                     }
-                  }
-
-// The f2pix helper macro converts a frequency into a pixel coordinate.
-#define f2pix(f) (logf(f)-lmins)/(lmaxs-lmins)*hiddenMid.height
-
-                  // Possibly quantize the maxima frequencies and create the pixel block limits.
-                  for (int i = 0; i < maximas; i++) {
-                     int index = maxima[i];
-                     float f = float(index)*bin2f;
-                     if (findNotesQuantize)
-                     {
-                        f = expf((int)(log(f / 440) / log2 * 12 - 0.5) / 12.0f*log2) * 440;
-                        maxima[i] = f*f2bin;
-                     }
-                     float f0 = expf((log(f / 440) / log2 * 24 - 1) / 24.0f*log2) * 440;
-                     maxima0[i] = f2pix(f0);
-                     float f1 = expf((log(f / 440) / log2 * 24 + 1) / 24.0f*log2) * 440;
-                     maxima1[i] = f2pix(f1);
-                  }
-               }
-               int it = 0;
-               int oldBin0 = -1;
-               bool inMaximum = false;
-#endif //EXPERIMENTAL_FIND_NOTES
-
                float value;
 
 #ifdef EXPERIMENTAL_FIND_NOTES
diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp
index 5a4b1da71..3a1584ab4 100644
--- a/src/TrackPanel.cpp
+++ b/src/TrackPanel.cpp
@@ -725,7 +725,7 @@ void TrackPanel::DeleteMenus(void)
 #ifdef EXPERIMENTAL_OUTPUT_DISPLAY
 void TrackPanel::UpdateVirtualStereoOrder()
 {
-   TrackListOfKindIterator iter(TrackKind::Wave, mTracks);
+   TrackListOfKindIterator iter(Track::Wave, GetTracks());
    Track *t;
    int temp;
 
@@ -1232,8 +1232,13 @@ bool TrackPanel::HandleEscapeKey(bool down)
       Track *const next = mTracks->GetNext(mCapturedTrack);
       mCapturedTrack->SetHeight(mInitialUpperActualHeight);
       mCapturedTrack->SetMinimized(mInitialMinimized);
-      next->SetHeight(mInitialActualHeight);
-      next->SetMinimized(mInitialMinimized);
+#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
+      if( !MONO_WAVE_PAN(mCapturedTrack) )
+#endif
+      {
+         next->SetHeight(mInitialActualHeight);
+         next->SetMinimized(mInitialMinimized);
+      }
    }
       break;
    case IsResizingBelowLinkedTracks:
@@ -1241,8 +1246,13 @@ bool TrackPanel::HandleEscapeKey(bool down)
       Track *const prev = mTracks->GetPrev(mCapturedTrack);
       mCapturedTrack->SetHeight(mInitialActualHeight);
       mCapturedTrack->SetMinimized(mInitialMinimized);
-      prev->SetHeight(mInitialUpperActualHeight);
-      prev->SetMinimized(mInitialMinimized);
+#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
+      if( !MONO_WAVE_PAN(mCapturedTrack) )
+#endif
+      {
+         prev->SetHeight(mInitialUpperActualHeight);
+         prev->SetMinimized(mInitialMinimized);
+      }
    }
       break;
    default:
@@ -5397,77 +5407,58 @@ void TrackPanel::HandleResizeClick( wxMouseEvent & event )
 
 #ifdef EXPERIMENTAL_OUTPUT_DISPLAY
    // To do: escape key
-   if(MONO_WAVE_PAN(t)){
+   if(MONO_WAVE_PAN(track)){
       //STM:  Determine whether we should rescale one or two tracks
-      if (t->GetVirtualStereo()) {
+      if (track->GetVirtualStereo()) {
          // mCapturedTrack is the lower track
-         mInitialTrackHeight = t->GetHeight(true);
-         mInitialUpperTrackHeight = t->GetHeight();
-         SetCapturedTrack(t, IsResizingBelowLinkedTracks);
+         mInitialTrackHeight = track->GetHeight(true);
+         mInitialActualHeight = mInitialUpperActualHeight = track->GetActualHeight();
+         mInitialMinimized = track->GetMinimized();
+         mInitialUpperTrackHeight = track->GetHeight();
+         SetCapturedTrack(track, IsResizingBelowLinkedTracks);
       }
       else {
          // mCapturedTrack is the upper track
-         mInitialTrackHeight = t->GetHeight(true);
-         mInitialUpperTrackHeight = t->GetHeight();
-         SetCapturedTrack(t, IsResizingBetweenLinkedTracks);
+         mInitialTrackHeight = track->GetHeight(true);
+         mInitialActualHeight = mInitialUpperActualHeight = track->GetActualHeight();
+         mInitialMinimized = track->GetMinimized();
+         mInitialUpperTrackHeight = track->GetHeight();
+         SetCapturedTrack(track, IsResizingBetweenLinkedTracks);
       }
-   }else{
-      Track *prev = mTracks->GetPrev(t);
-      Track *next = mTracks->GetNext(t);
+   }
+   else
+#endif
+   {
+      Track *prev = mTracks->GetPrev(track);
+      Track *next = mTracks->GetNext(track);
 
       //STM:  Determine whether we should rescale one or two tracks
-      if (prev && prev->GetLink() == t) {
+      if (prev && prev->GetLink() == track) {
          // mCapturedTrack is the lower track
-         mInitialTrackHeight = t->GetHeight();
-         mInitialMinimized = t->GetMinimized();
+         mInitialTrackHeight = track->GetHeight();
+         mInitialActualHeight = track->GetActualHeight();
+         mInitialMinimized = track->GetMinimized();
          mInitialUpperTrackHeight = prev->GetHeight();
-         SetCapturedTrack(t, IsResizingBelowLinkedTracks);
+         mInitialUpperActualHeight = prev->GetActualHeight();
+         SetCapturedTrack(track, IsResizingBelowLinkedTracks);
       }
-      else if (next && t->GetLink() == next) {
+      else if (next && track->GetLink() == next) {
          // mCapturedTrack is the upper track
          mInitialTrackHeight = next->GetHeight();
+         mInitialActualHeight = next->GetActualHeight();
          mInitialMinimized = next->GetMinimized();
-         mInitialUpperTrackHeight = t->GetHeight();
-         SetCapturedTrack(t, IsResizingBetweenLinkedTracks);
+         mInitialUpperTrackHeight = track->GetHeight();
+         mInitialUpperActualHeight = track->GetActualHeight();
+         SetCapturedTrack(track, IsResizingBetweenLinkedTracks);
       }
       else {
          // DM: Save the initial mouse location and the initial height
-         mInitialTrackHeight = t->GetHeight();
-         mInitialMinimized = t->GetMinimized();
-         SetCapturedTrack(t, IsResizing);
+         mInitialTrackHeight = track->GetHeight();
+         mInitialActualHeight = track->GetActualHeight();
+         mInitialMinimized = track->GetMinimized();
+         SetCapturedTrack(track, IsResizing);
       }
    }
-#else // EXPERIMENTAL_OUTPUT_DISPLAY
-   Track *prev = mTracks->GetPrev(track);
-   Track *next = mTracks->GetNext(track);
-
-   //STM:  Determine whether we should rescale one or two tracks
-   if (prev && prev->GetLink() == track) {
-      // mCapturedTrack is the lower track
-      mInitialTrackHeight = track->GetHeight();
-      mInitialActualHeight = track->GetActualHeight();
-      mInitialMinimized = track->GetMinimized();
-      mInitialUpperTrackHeight = prev->GetHeight();
-      mInitialUpperActualHeight = prev->GetActualHeight();
-      SetCapturedTrack(track, IsResizingBelowLinkedTracks);
-   }
-   else if (next && track->GetLink() == next) {
-      // mCapturedTrack is the upper track
-      mInitialTrackHeight = next->GetHeight();
-      mInitialActualHeight = next->GetActualHeight();
-      mInitialMinimized = next->GetMinimized();
-      mInitialUpperTrackHeight = track->GetHeight();
-      mInitialUpperActualHeight = track->GetActualHeight();
-      SetCapturedTrack(track, IsResizingBetweenLinkedTracks);
-   }
-   else {
-      // DM: Save the initial mouse location and the initial height
-      mInitialTrackHeight = track->GetHeight();
-      mInitialActualHeight = track->GetActualHeight();
-      mInitialMinimized = track->GetMinimized();
-      SetCapturedTrack(track, IsResizing);
-   }
-#endif // EXPERIMENTAL_OUTPUT_DISPLAY
 }
 
 ///  This happens when the button is released from a drag.
@@ -5519,177 +5510,127 @@ void TrackPanel::HandleResizeDrag(wxMouseEvent & event)
 #endif
    }
 
+   // Common pieces of code for MONO_WAVE_PAN and otherwise.
+   auto doResizeBelow = [&] (Track *prev, bool vStereo) {
+      double proportion = static_cast < double >(mInitialTrackHeight)
+      / (mInitialTrackHeight + mInitialUpperTrackHeight);
+
+      int newTrackHeight = static_cast < int >
+      (mInitialTrackHeight + delta * proportion);
+
+      int newUpperTrackHeight = static_cast < int >
+      (mInitialUpperTrackHeight + delta * (1.0 - proportion));
+
+      //make sure neither track is smaller than its minimum height
+      if (newTrackHeight < mCapturedTrack->GetMinimizedHeight())
+         newTrackHeight = mCapturedTrack->GetMinimizedHeight();
+      if (newUpperTrackHeight < prev->GetMinimizedHeight())
+         newUpperTrackHeight = prev->GetMinimizedHeight();
+
+      mCapturedTrack->SetHeight(newTrackHeight
+#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
+                                , vStereo
+#endif
+                                );
+      prev->SetHeight(newUpperTrackHeight);
+   };
+
+   auto doResizeBetween = [&] (Track *next, bool vStereo) {
+      int newUpperTrackHeight = mInitialUpperTrackHeight + delta;
+      int newTrackHeight = mInitialTrackHeight - delta;
+
+      // make sure neither track is smaller than its minimum height
+      if (newTrackHeight < next->GetMinimizedHeight()) {
+         newTrackHeight = next->GetMinimizedHeight();
+         newUpperTrackHeight =
+         mInitialUpperTrackHeight + mInitialTrackHeight - next->GetMinimizedHeight();
+      }
+      if (newUpperTrackHeight < mCapturedTrack->GetMinimizedHeight()) {
+         newUpperTrackHeight = mCapturedTrack->GetMinimizedHeight();
+         newTrackHeight =
+         mInitialUpperTrackHeight + mInitialTrackHeight - mCapturedTrack->GetMinimizedHeight();
+      }
+
+#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
+      if (vStereo) {
+         float temp = 1.0f;
+         if(newUpperTrackHeight != 0.0f)
+            temp = (float)newUpperTrackHeight/(float)(newUpperTrackHeight + newTrackHeight);
+         mCapturedTrack->SetVirtualTrackPercentage(temp);
+      }
+#endif
+
+      mCapturedTrack->SetHeight(newUpperTrackHeight);
+      next->SetHeight(newTrackHeight
+#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
+                      , vStereo
+#endif
+      );
+   };
+
+   auto doResize = [&] {
+      int newTrackHeight = mInitialTrackHeight + delta;
+      if (newTrackHeight < mCapturedTrack->GetMinimizedHeight())
+         newTrackHeight = mCapturedTrack->GetMinimizedHeight();
+      mCapturedTrack->SetHeight(newTrackHeight);
+   };
+
    //STM: We may be dragging one or two (stereo) tracks.
    // If two, resize proportionally if we are dragging the lower track, and
    // adjust compensatively if we are dragging the upper track.
 #ifdef EXPERIMENTAL_OUTPUT_DISPLAY
-   switch( mMouseCapture )
-   {
-   case IsResizingBelowLinkedTracks:
+   if(MONO_WAVE_PAN(mCapturedTrack)) {
+      switch( mMouseCapture )
       {
-         if(MONO_WAVE_PAN(mCapturedTrack)){
-            double proportion = static_cast < double >(mInitialTrackHeight)
-                / (mInitialTrackHeight + mInitialUpperTrackHeight);
-
-            int newTrackHeight = static_cast < int >
-                (mInitialTrackHeight + delta * proportion);
-
-            int newUpperTrackHeight = static_cast < int >
-                (mInitialUpperTrackHeight + delta * (1.0 - proportion));
-
-            //make sure neither track is smaller than its minimum height
-            if (newTrackHeight < mCapturedTrack->GetMinimizedHeight())
-               newTrackHeight = mCapturedTrack->GetMinimizedHeight();
-            if (newUpperTrackHeight < mCapturedTrack->GetMinimizedHeight())
-               newUpperTrackHeight = mCapturedTrack->GetMinimizedHeight();
-
-            mCapturedTrack->SetHeight(newTrackHeight,true);
-            mCapturedTrack->SetHeight(newUpperTrackHeight);
-         }
-         else{
-            Track *prev = mTracks->GetPrev(mCapturedTrack);
-
-            double proportion = static_cast < double >(mInitialTrackHeight)
-                / (mInitialTrackHeight + mInitialUpperTrackHeight);
-
-            int newTrackHeight = static_cast < int >
-                (mInitialTrackHeight + delta * proportion);
-
-            int newUpperTrackHeight = static_cast < int >
-                (mInitialUpperTrackHeight + delta * (1.0 - proportion));
-
-            //make sure neither track is smaller than its minimum height
-            if (newTrackHeight < mCapturedTrack->GetMinimizedHeight())
-               newTrackHeight = mCapturedTrack->GetMinimizedHeight();
-            if (newUpperTrackHeight < prev->GetMinimizedHeight())
-               newUpperTrackHeight = prev->GetMinimizedHeight();
-
-            mCapturedTrack->SetHeight(newTrackHeight);
-            prev->SetHeight(newUpperTrackHeight);
-         }
-         break;
-      }
-   case IsResizingBetweenLinkedTracks:
-      {
-         if(MONO_WAVE_PAN(mCapturedTrack)){
-            int newUpperTrackHeight = mInitialUpperTrackHeight + delta;
-            int newTrackHeight = mInitialTrackHeight - delta;
-
-            // make sure neither track is smaller than its minimum height
-            if (newTrackHeight < mCapturedTrack->GetMinimizedHeight()) {
-               newTrackHeight = mCapturedTrack->GetMinimizedHeight();
-               newUpperTrackHeight =
-                   mInitialUpperTrackHeight + mInitialTrackHeight - mCapturedTrack->GetMinimizedHeight();
-            }
-            if (newUpperTrackHeight < mCapturedTrack->GetMinimizedHeight()) {
-               newUpperTrackHeight = mCapturedTrack->GetMinimizedHeight();
-               newTrackHeight =
-                   mInitialUpperTrackHeight + mInitialTrackHeight - mCapturedTrack->GetMinimizedHeight();
-            }
-            float temp = 1.0f;
-            if(newUpperTrackHeight != 0.0f)
-               temp = (float)newUpperTrackHeight/(float)(newUpperTrackHeight + newTrackHeight);
-
-            mCapturedTrack->SetVirtualTrackPercentage(temp);
-            mCapturedTrack->SetHeight(newUpperTrackHeight);
-            mCapturedTrack->SetHeight(newTrackHeight,true);
-         }
-         else{
-            Track *next = mTracks->GetNext(mCapturedTrack);
-            int newUpperTrackHeight = mInitialUpperTrackHeight + delta;
-            int newTrackHeight = mInitialTrackHeight - delta;
-
-            // make sure neither track is smaller than its minimum height
-            if (newTrackHeight < next->GetMinimizedHeight()) {
-               newTrackHeight = next->GetMinimizedHeight();
-               newUpperTrackHeight =
-                   mInitialUpperTrackHeight + mInitialTrackHeight - next->GetMinimizedHeight();
-            }
-            if (newUpperTrackHeight < mCapturedTrack->GetMinimizedHeight()) {
-               newUpperTrackHeight = mCapturedTrack->GetMinimizedHeight();
-               newTrackHeight =
-                   mInitialUpperTrackHeight + mInitialTrackHeight - mCapturedTrack->GetMinimizedHeight();
-            }
-
-            mCapturedTrack->SetHeight(newUpperTrackHeight);
-            next->SetHeight(newTrackHeight);
+         case IsResizingBelowLinkedTracks:
+         {
+            doResizeBelow( mCapturedTrack, true );
             break;
          }
-         break;
+         case IsResizingBetweenLinkedTracks:
+         {
+            doResizeBetween( mCapturedTrack, true );
+            break;
+         }
+         case IsResizing:
+         {
+            // Should imply !MONO_WAVE_PAN(mCapturedTrack),
+            // so impossible, but anyway:
+            doResize();
+            break;
+         }
+         default:
+            // don't refresh in this case.
+            return;
       }
-   case IsResizing:
-      {
-         int newTrackHeight = mInitialTrackHeight + delta;
-         if (newTrackHeight < mCapturedTrack->GetMinimizedHeight())
-            newTrackHeight = mCapturedTrack->GetMinimizedHeight();
-         mCapturedTrack->SetHeight(newTrackHeight);
-         break;
-      }
-   default:
-      // don't refresh in this case.
-      return;
    }
-#else // EXPERIMENTAL_OUTPUT_DISPLAY
-   switch( mMouseCapture )
+   else
+#endif
    {
-   case IsResizingBelowLinkedTracks:
+      switch( mMouseCapture )
       {
-         Track *prev = mTracks->GetPrev(mCapturedTrack);
-
-         double proportion = static_cast < double >(mInitialTrackHeight)
-             / (mInitialTrackHeight + mInitialUpperTrackHeight);
-
-         int newTrackHeight = static_cast < int >
-             (mInitialTrackHeight + delta * proportion);
-
-         int newUpperTrackHeight = static_cast < int >
-             (mInitialUpperTrackHeight + delta * (1.0 - proportion));
-
-         //make sure neither track is smaller than its minimum height
-         if (newTrackHeight < mCapturedTrack->GetMinimizedHeight())
-            newTrackHeight = mCapturedTrack->GetMinimizedHeight();
-         if (newUpperTrackHeight < prev->GetMinimizedHeight())
-            newUpperTrackHeight = prev->GetMinimizedHeight();
-
-         mCapturedTrack->SetHeight(newTrackHeight);
-         prev->SetHeight(newUpperTrackHeight);
-         break;
-      }
-   case IsResizingBetweenLinkedTracks:
-      {
-         Track *next = mTracks->GetNext(mCapturedTrack);
-         int newUpperTrackHeight = mInitialUpperTrackHeight + delta;
-         int newTrackHeight = mInitialTrackHeight - delta;
-
-         // make sure neither track is smaller than its minimum height
-         if (newTrackHeight < next->GetMinimizedHeight()) {
-            newTrackHeight = next->GetMinimizedHeight();
-            newUpperTrackHeight =
-                mInitialUpperTrackHeight + mInitialTrackHeight - next->GetMinimizedHeight();
+         case IsResizingBelowLinkedTracks:
+         {
+            Track *prev = mTracks->GetPrev(mCapturedTrack);
+            doResizeBelow(prev, false);
+            break;
          }
-         if (newUpperTrackHeight < mCapturedTrack->GetMinimizedHeight()) {
-            newUpperTrackHeight = mCapturedTrack->GetMinimizedHeight();
-            newTrackHeight =
-                mInitialUpperTrackHeight + mInitialTrackHeight - mCapturedTrack->GetMinimizedHeight();
+         case IsResizingBetweenLinkedTracks:
+         {
+            Track *next = mTracks->GetNext(mCapturedTrack);
+            doResizeBetween(next, false);
+            break;
          }
-
-         mCapturedTrack->SetHeight(newUpperTrackHeight);
-         next->SetHeight(newTrackHeight);
-         break;
+         case IsResizing:
+         {
+            doResize();
+            break;
+         }
+         default:
+            // don't refresh in this case.
+            return;
       }
-   case IsResizing:
-      {
-         int newTrackHeight = mInitialTrackHeight + delta;
-         if (newTrackHeight < mCapturedTrack->GetMinimizedHeight())
-            newTrackHeight = mCapturedTrack->GetMinimizedHeight();
-         mCapturedTrack->SetHeight(newTrackHeight);
-         break;
-      }
-   default:
-      // don't refresh in this case.
-      return;
    }
-#endif // EXPERIMENTAL_OUTPUT_DISPLAY
    Refresh(false);
 }
 
@@ -7346,15 +7287,11 @@ void TrackPanel::DrawOutsideOfTrack(Track * t, wxDC * dc, const wxRect & rect)
    dc->DrawRectangle(side);
 
    // Area between tracks of stereo group
+   if (t->GetLinked()
 #ifdef EXPERIMENTAL_OUTPUT_DISPLAY
-   if (t->GetLinked() || MONO_WAVE_PAN(t)) {
-      side = rect;
-      side.y += t->GetHeight() - 1;
-      side.height = kTopInset + 1;
-      dc->DrawRectangle(side);
-   }
-#else
-   if (t->GetLinked()) {
+       || MONO_WAVE_PAN(t)
+#endif
+       ) {
       // Paint the channel separator over (what would be) the shadow of the top
       // channel, and the top inset of the bottom channel
       side = rect;
@@ -7362,7 +7299,6 @@ void TrackPanel::DrawOutsideOfTrack(Track * t, wxDC * dc, const wxRect & rect)
       side.height = kTopInset + kShadowThickness;
       dc->DrawRectangle(side);
    }
-#endif
 }
 
 /// Draw a three-level highlight gradient around the focused track.
@@ -7984,14 +7920,11 @@ void TrackPanel::DrawBordersAroundTrack(Track * t, wxDC * dc,
 
    // The lines at bottom of 1st track and top of second track of stereo group
    // Possibly replace with DrawRectangle to add left border.
+   if (t->GetLinked()
 #ifdef EXPERIMENTAL_OUTPUT_DISPLAY
-   if (t->GetLinked() || MONO_WAVE_PAN(t)) {
-      int h1 = rect.y + t->GetHeight() - kTopInset;
-      AColor::Line(*dc, vrul, h1 - 2, rect.x + rect.width - 1, h1 - 2);
-      AColor::Line(*dc, vrul, h1 + kTopInset, rect.x + rect.width - 1, h1 + kTopInset);
-   }
-#else
-   if (t->GetLinked()) {
+       || MONO_WAVE_PAN(t)
+#endif
+       ) {
       // The given rect has had the top inset subtracted
       int h1 = rect.y + t->GetHeight() - kTopInset;
       // h1 is the top coordinate of the second tracks' rectangle
@@ -7999,7 +7932,6 @@ void TrackPanel::DrawBordersAroundTrack(Track * t, wxDC * dc,
       AColor::Line(*dc, vrul, h1 - kBottomMargin, rect.x + rect.width - 1, h1 - kBottomMargin);
       AColor::Line(*dc, vrul, h1 + kTopInset, rect.x + rect.width - 1, h1 + kTopInset);
    }
-#endif
 }
 
 void TrackPanel::DrawShadow(Track * /* t */ , wxDC * dc, const wxRect & rect)
@@ -8030,13 +7962,12 @@ void TrackPanel::DrawShadow(Track * /* t */ , wxDC * dc, const wxRect & rect)
 wxString TrackPanel::TrackSubText(WaveTrack * t)
 {
    wxString s = wxString::Format(wxT("%dHz"), (int) (t->GetRate() + 0.5));
+   if (t->GetLinked()
 #ifdef EXPERIMENTAL_OUTPUT_DISPLAY
-   if (t->GetLinked() && t->GetChannel() != Track::MonoChannel)
-      s = _("Stereo, ") + s;
-#else
-   if (t->GetLinked())
-      s = _("Stereo, ") + s;
+       && t->GetChannel() != Track::MonoChannel
 #endif
+   )
+      s = _("Stereo, ") + s;
    else {
       if (t->GetChannel() == Track::MonoChannel)
          s = _("Mono, ") + s;
@@ -8329,9 +8260,9 @@ void TrackPanel::OnSetDisplay(wxCommandEvent & event)
             : WaveformSettings::stLogarithmic;
    }
 #ifdef EXPERIMENTAL_OUTPUT_DISPLAY
-      if (wt->GetDisplay() == WaveTrack::WaveformDisplay) {
+      if (wt->GetDisplay() == WaveTrack::Waveform) {
          wt->SetVirtualState(false);
-      }else if (id == WaveTrack::WaveformDisplay) {
+      }else if (id == WaveTrack::Waveform) {
          wt->SetVirtualState(true);
       }
 #endif
diff --git a/src/VoiceKey.cpp b/src/VoiceKey.cpp
index 16b77c2d7..943663681 100644
--- a/src/VoiceKey.cpp
+++ b/src/VoiceKey.cpp
@@ -85,7 +85,8 @@ VoiceKey::~VoiceKey()
 
 
 //Move forward to find an ON region.
-sampleCount VoiceKey::OnForward (WaveTrack & t, sampleCount start, sampleCount len)
+sampleCount VoiceKey::OnForward (
+   const WaveTrack & t, sampleCount start, sampleCount len)
 {
 
    if((mWindowSize) >= (len + 10).as_double() ){
@@ -236,7 +237,8 @@ sampleCount VoiceKey::OnForward (WaveTrack & t, sampleCount start, sampleCount l
 }
 
 //Move backward from end to find an ON region.
-sampleCount VoiceKey::OnBackward (WaveTrack & t, sampleCount end, sampleCount len)
+sampleCount VoiceKey::OnBackward (
+   const WaveTrack & t, sampleCount end, sampleCount len)
 {
 
 
@@ -374,7 +376,8 @@ sampleCount VoiceKey::OnBackward (WaveTrack & t, sampleCount end, sampleCount le
 
 
 //Move froward from the start to find an OFF region.
-sampleCount VoiceKey::OffForward (WaveTrack & t, sampleCount start, sampleCount len)
+sampleCount VoiceKey::OffForward (
+   const WaveTrack & t, sampleCount start, sampleCount len)
 {
 
    if((mWindowSize) >= (len + 10).as_double() ){
@@ -509,7 +512,8 @@ sampleCount VoiceKey::OffForward (WaveTrack & t, sampleCount start, sampleCount
 
 
 //Move backward from the end to find an OFF region
-sampleCount VoiceKey::OffBackward (WaveTrack & t, sampleCount end, sampleCount len)
+sampleCount VoiceKey::OffBackward (
+   const WaveTrack & t, sampleCount end, sampleCount len)
 {
 
 
@@ -648,7 +652,8 @@ sampleCount VoiceKey::OffBackward (WaveTrack & t, sampleCount end, sampleCount l
 }
 
 //This tests whether a specified block region is above or below threshold.
-bool VoiceKey::AboveThreshold(WaveTrack & t, sampleCount start, sampleCount len)
+bool VoiceKey::AboveThreshold(
+   const WaveTrack & t, sampleCount start, sampleCount len)
 {
 
    double erg=0;
@@ -729,7 +734,7 @@ void VoiceKey::AdjustThreshold(double t)
 
 
 //This 'calibrates' the voicekey to noise
-void VoiceKey::CalibrateNoise(WaveTrack & t, sampleCount start, sampleCount len)
+void VoiceKey::CalibrateNoise(const WaveTrack & t, sampleCount start, sampleCount len)
 {
    //To calibrate the noise, we need to scan the sample block just like in the voicekey and
    //calculate the mean and standard deviation of the test statistics.
@@ -835,7 +840,8 @@ void VoiceKey::SetKeyType(bool erg, bool scLow , bool scHigh,
 
 
 //This might continue over a number of blocks.
-double VoiceKey::TestEnergy (WaveTrack & t, sampleCount start, sampleCount len)
+double VoiceKey::TestEnergy (
+   const WaveTrack & t, sampleCount start, sampleCount len)
 {
 
    double sum = 1;
@@ -876,7 +882,8 @@ void VoiceKey::TestEnergyUpdate (double & prevErg, int len, const float & drop,
 }
 
 
-double VoiceKey::TestSignChanges(WaveTrack & t, sampleCount start, sampleCount len)
+double VoiceKey::TestSignChanges(
+   const WaveTrack & t, sampleCount start, sampleCount len)
 {
 
 
@@ -932,7 +939,8 @@ void VoiceKey::TestSignChangesUpdate(double & currentsignchanges, int len,
 }
 
 
-double VoiceKey::TestDirectionChanges(WaveTrack & t, sampleCount start, sampleCount len)
+double VoiceKey::TestDirectionChanges(
+   const WaveTrack & t, sampleCount start, sampleCount len)
 {
 
 
diff --git a/src/VoiceKey.h b/src/VoiceKey.h
index 926548ed9..52e7f41c2 100644
--- a/src/VoiceKey.h
+++ b/src/VoiceKey.h
@@ -35,16 +35,16 @@ class VoiceKey {
  public:
    VoiceKey();
    ~VoiceKey();
-   sampleCount OnForward   (WaveTrack & t, sampleCount start, sampleCount len);
-   sampleCount OnBackward  (WaveTrack & t, sampleCount start, sampleCount len);
-   sampleCount OffForward  (WaveTrack & t, sampleCount start, sampleCount len);
-   sampleCount OffBackward (WaveTrack & t, sampleCount start, sampleCount len);
+   sampleCount OnForward   (const WaveTrack & t, sampleCount start, sampleCount len);
+   sampleCount OnBackward  (const WaveTrack & t, sampleCount start, sampleCount len);
+   sampleCount OffForward  (const WaveTrack & t, sampleCount start, sampleCount len);
+   sampleCount OffBackward (const WaveTrack & t, sampleCount start, sampleCount len);
 
-   void CalibrateNoise(WaveTrack & t, sampleCount start, sampleCount len);
+   void CalibrateNoise(const WaveTrack & t, sampleCount start, sampleCount len);
    void AdjustThreshold(double t);
 
 
-   bool AboveThreshold(WaveTrack & t, sampleCount start,sampleCount len);
+   bool AboveThreshold(const WaveTrack & t, sampleCount start,sampleCount len);
 
    void SetKeyType(bool erg, bool scLow, bool scHigh,
                    bool dcLow, bool dcHigh);
@@ -79,9 +79,11 @@ class VoiceKey {
    double mSilentWindowSize;           //Time in milliseconds of below-threshold windows required for silence
    double mSignalWindowSize;           //Time in milliseconds of above-threshold windows required for speech
 
-   double TestEnergy (WaveTrack & t, sampleCount start,sampleCount len);
-   double TestSignChanges (WaveTrack & t, sampleCount start, sampleCount len);
-   double TestDirectionChanges(WaveTrack & t, sampleCount start, sampleCount len);
+   double TestEnergy (const WaveTrack & t, sampleCount start,sampleCount len);
+   double TestSignChanges (
+      const WaveTrack & t, sampleCount start, sampleCount len);
+   double TestDirectionChanges(
+      const WaveTrack & t, sampleCount start, sampleCount len);
 
    void TestEnergyUpdate (double & prevErg, int length, const float & drop, const float & add);
    void TestSignChangesUpdate(double & currentsignchanges,int length, const float & a1,
diff --git a/src/WaveTrack.cpp b/src/WaveTrack.cpp
index b4ffe2cc5..ff8cf8052 100644
--- a/src/WaveTrack.cpp
+++ b/src/WaveTrack.cpp
@@ -402,7 +402,7 @@ bool WaveTrack::SetPan(float newPan)
    else
       mPan = newPan;
 
-   if(mDisplay == WaveTrack::WaveformDisplay && mChannel == Track::MonoChannel && (p == 0.0f && newPan != 0.0f || p != 0.0f && newPan == 0.0f) && mMonoAsVirtualStereo)
+   if(mDisplay == WaveTrack::Waveform && mChannel == Track::MonoChannel && (p == 0.0f && newPan != 0.0f || p != 0.0f && newPan == 0.0f) && mMonoAsVirtualStereo)
    {
       panZero=true;
       if(!mPan){
@@ -458,7 +458,7 @@ int WaveTrack::GetMinimizedHeight() const
       return 20;
    }
 
-   if(GetChannel() == MonoChannel && GetPan() != 0 && mMonoAsVirtualStereo &&  mDisplay == WaveformDisplay)
+   if(GetChannel() == MonoChannel && GetPan() != 0 && mMonoAsVirtualStereo &&  mDisplay == Waveform)
       return 20;
    else
       return 40;
diff --git a/src/WaveTrack.h b/src/WaveTrack.h
index 96acb034c..d2cf53058 100644
--- a/src/WaveTrack.h
+++ b/src/WaveTrack.h
@@ -34,9 +34,19 @@ class TimeWarper;
 #define WAVETRACK_MERGE_POINT_TOLERANCE 0.01
 
 #ifdef EXPERIMENTAL_OUTPUT_DISPLAY
-#define MONO_WAVE_PAN(T) (T != NULL && T->GetChannel() == Track::MonoChannel && T->GetKind() == Track::Wave && ((WaveTrack *)T)->GetPan() != 0 && WaveTrack::mMonoAsVirtualStereo && ((WaveTrack *)T)->GetDisplay() == WaveTrack::WaveformDisplay)
+#define MONO_WAVE_PAN(T) \
+   (T != NULL && \
+    T->GetChannel() == Track::MonoChannel && \
+    T->GetKind() == Track::Wave && \
+    ((const WaveTrack *)T)->GetPan() != 0 && \
+    WaveTrack::mMonoAsVirtualStereo && \
+    ((const WaveTrack *)T)->GetDisplay() == WaveTrack::Waveform)
 
-#define MONO_PAN  (mPan != 0.0 && mChannel == MonoChannel && mDisplay == WaveformDisplay && mMonoAsVirtualStereo)
+#define MONO_PAN \
+   (mPan != 0.0 && \
+    mChannel == MonoChannel && \
+    mDisplay == Waveform && \
+    mMonoAsVirtualStereo)
 #endif
 
 /// \brief Structure to hold region of a wavetrack and a comparison function
diff --git a/src/effects/EffectRack.cpp b/src/effects/EffectRack.cpp
index 96f7aced6..4dc7775c1 100644
--- a/src/effects/EffectRack.cpp
+++ b/src/effects/EffectRack.cpp
@@ -293,7 +293,8 @@ void EffectRack::OnApply(wxCommandEvent & WXUNUSED(evt))
    {
       if (mPowerState[i])
       {
-         project->OnEffect(mEffects[i]->GetID(), true);
+         project->OnEffect(mEffects[i]->GetID(),
+                           AudacityProject::OnEffectFlags::kConfigured);
 
          mPowerState[i] = false;
 
diff --git a/src/effects/Equalization48x.cpp b/src/effects/Equalization48x.cpp
index 20240e6b1..babbad567 100644
--- a/src/effects/Equalization48x.cpp
+++ b/src/effects/Equalization48x.cpp
@@ -44,7 +44,11 @@
 #endif
 
 #include <stdlib.h>
+
+#ifdef __WXMSW__
 #include <malloc.h>
+#endif
+
 #include <stdio.h>
 #include <math.h>
 #include <emmintrin.h>
@@ -182,10 +186,11 @@ bool EffectEqualization48x::AllocateBuffersWorkers(int nThreads)
    mWindowSize=mEffectEqualization->windowSize;
    wxASSERT(mFilterSize < mWindowSize);
    mBlockSize=mWindowSize-mFilterSize; // 12,384
-   mThreaded = (nThreads > 0 );
+   auto threadCount = wxThread::GetCPUCount();
+   mThreaded = (nThreads > 0 && threadCount > 0);
    if(mThreaded)
-   {  
-      mThreadCount=wxThread::GetCPUCount();
+   {
+      mThreadCount = threadCount;
       mWorkerDataCount=mThreadCount+2; // 2 extra slots (maybe double later)
    } else {
       mWorkerDataCount=1;
@@ -294,7 +299,7 @@ bool EffectEqualization48x::Process(EffectEqualization* effectEqualization)
    if(sMathPath)  // !!! Filter MUST BE QUAD WORD ALIGNED !!!!
       mEffectEqualization->mM=(mEffectEqualization->mM&(~15))+1;
    AllocateBuffersWorkers(sMathPath&MATH_FUNCTION_THREADED);
-   SelectedTrackListOfKindIterator iter(Track::Wave, mEffectEqualization->mOutputTracks);
+   SelectedTrackListOfKindIterator iter(Track::Wave, mEffectEqualization->mOutputTracks.get());
    WaveTrack *track = (WaveTrack *) iter.First();
    int count = 0;
    while (track) {
@@ -418,8 +423,8 @@ bool EffectEqualization48x::DeltaTrack(WaveTrack * t, WaveTrack * t2, sampleCoun
    auto originalLen = len;
    auto currentSample = start;
 
-   while(len) {
-      auto curretLength = std::min(len, trackBlockSize);
+   while(len > 0) {
+      auto curretLength = limitSampleBufferSize(trackBlockSize, len);
       t->Get((samplePtr)buffer1, floatSample, currentSample, curretLength);
       t2->Get((samplePtr)buffer2, floatSample, currentSample, curretLength);
       for(decltype(curretLength) i=0;i<curretLength;i++)
@@ -574,7 +579,7 @@ bool EffectEqualization48x::ProcessTail(WaveTrack * t, WaveTrack * output, sampl
    return true;
 }
 
-bool EffectEqualization48x::ProcessBuffer(fft_type *sourceBuffer, fft_type *destBuffer, sampleCount bufferLength)
+bool EffectEqualization48x::ProcessBuffer(fft_type *sourceBuffer, fft_type *destBuffer, size_t bufferLength)
 {
    BufferInfo bufferInfo;
    bufferInfo.mContiguousBufferSize=bufferLength;
@@ -589,12 +594,12 @@ bool EffectEqualization48x::ProcessBuffer1x(BufferInfo *bufferInfo)
    int bufferCount=bufferInfo->mContiguousBufferSize?1:4;
    for(int bufferIndex=0;bufferIndex<bufferCount;bufferIndex++)
    {
-      int bufferLength=bufferInfo->mBufferLength;
+      auto bufferLength=bufferInfo->mBufferLength;
       if(bufferInfo->mContiguousBufferSize)
          bufferLength=bufferInfo->mContiguousBufferSize;
 
-      sampleCount blockCount=bufferLength/mBlockSize;
-      sampleCount lastBlockSize=bufferLength%mBlockSize;
+      auto blockCount=bufferLength/mBlockSize;
+      auto lastBlockSize=bufferLength%mBlockSize;
       if(lastBlockSize)
          blockCount++;
 
@@ -602,7 +607,7 @@ bool EffectEqualization48x::ProcessBuffer1x(BufferInfo *bufferInfo)
       float *scratchBuffer=&workBuffer[mWindowSize*2];  // all scratch buffers are at the end
       float *sourceBuffer=bufferInfo->mBufferSouce[bufferIndex];
       float *destBuffer=bufferInfo->mBufferDest[bufferIndex];
-      for(int runx=0;runx<blockCount;runx++) 
+      for(size_t runx=0;runx<blockCount;runx++)
       {
          float *currentBuffer=&workBuffer[mWindowSize*(runx&1)]; 
          for(int i=0;i<mBlockSize;i++)
@@ -641,12 +646,12 @@ bool EffectEqualization48x::ProcessOne1x(int count, WaveTrack * t,
 
    mEffectEqualization->TrackProgress(count, 0.0);
    int subBufferSize=mBufferCount==8?(mSubBufferSize>>1):mSubBufferSize; // half the buffers if avx is active
-   int bigRuns=len/(subBufferSize-mBlockSize);
+   auto bigRuns=len/(subBufferSize-mBlockSize);
    int trackBlocksPerBig=subBufferSize/trackBlockSize;
    int trackLeftovers=subBufferSize-trackBlocksPerBig*trackBlockSize;
-   int singleProcessLength;
-   if(!bigRuns)
-      singleProcessLength=len;
+   size_t singleProcessLength;
+   if(bigRuns == 0)
+      singleProcessLength = len.as_size_t();
    else 
       singleProcessLength=(mFilterSize>>1)*bigRuns + len%(bigRuns*(subBufferSize-mBlockSize));
    auto currentSample=start;
@@ -665,7 +670,7 @@ bool EffectEqualization48x::ProcessOne1x(int count, WaveTrack * t,
       currentSample-=mBlockSize+(mFilterSize>>1);
 
       ProcessBuffer1x(mBufferInfo);
-      bBreakLoop=mEffectEqualization->TrackProgress(count, (double)(bigRun)/(double)bigRuns);
+      bBreakLoop=mEffectEqualization->TrackProgress(count, (double)(bigRun)/bigRuns.as_double());
       if( bBreakLoop )
          break;
       output->Append((samplePtr)&mBigBuffer[(bigRun?mBlockSize:0)+(mFilterSize>>1)], floatSample, subBufferSize-((bigRun?mBlockSize:0)+(mFilterSize>>1)));
@@ -673,7 +678,7 @@ bool EffectEqualization48x::ProcessOne1x(int count, WaveTrack * t,
    if(singleProcessLength && !bBreakLoop) {
       t->Get((samplePtr)mBigBuffer, floatSample, currentSample, singleProcessLength+mBlockSize+(mFilterSize>>1));
       ProcessBuffer(mBigBuffer, mBigBuffer, singleProcessLength+mBlockSize+(mFilterSize>>1));
-      output->Append((samplePtr)&mBigBuffer[bigRuns?mBlockSize:0], floatSample, singleProcessLength+mBlockSize+(mFilterSize>>1));
+      output->Append((samplePtr)&mBigBuffer[bigRuns > 0 ? mBlockSize : 0], floatSample, singleProcessLength+mBlockSize+(mFilterSize>>1));
    }
    output->Flush();
    if(!bBreakLoop)
@@ -730,7 +735,7 @@ bool EffectEqualization48x::ProcessBuffer4x(BufferInfo *bufferInfo)
    if(bufferInfo->mBufferLength%mBlockSize)
       return false;
 
-   sampleCount blockCount=bufferInfo->mBufferLength/mBlockSize;
+   auto blockCount=bufferInfo->mBufferLength/mBlockSize;
 
    __m128 *readBlocks[4]; // some temps so we dont destroy the vars in the struct
    __m128 *writeBlocks[4];
@@ -742,7 +747,7 @@ bool EffectEqualization48x::ProcessBuffer4x(BufferInfo *bufferInfo)
    __m128 *swizzledBuffer128=(__m128 *)bufferInfo->mScratchBuffer;
    __m128 *scratchBuffer=&swizzledBuffer128[mWindowSize*2];
 
-   for(int run4x=0;run4x<blockCount;run4x++) 
+   for(size_t run4x=0;run4x<blockCount;run4x++)
    {
       // swizzle the data to the swizzle buffer
       __m128 *currentSwizzledBlock=&swizzledBuffer128[mWindowSize*(run4x&1)]; 
@@ -825,10 +830,10 @@ bool EffectEqualization48x::ProcessOne4x(int count, WaveTrack * t,
    auto output = p->GetTrackFactory()->NewWaveTrack(floatSample, t->GetRate());
 
    mEffectEqualization->TrackProgress(count, 0.0);
-   int bigRuns=len/(subBufferSize-mBlockSize);
+   auto bigRuns = len/(subBufferSize-mBlockSize);
    int trackBlocksPerBig=subBufferSize/trackBlockSize;
    int trackLeftovers=subBufferSize-trackBlocksPerBig*trackBlockSize;
-   int singleProcessLength=(mFilterSize>>1)*bigRuns + len%(bigRuns*(subBufferSize-mBlockSize));
+   size_t singleProcessLength=(mFilterSize>>1)*bigRuns + len%(bigRuns*(subBufferSize-mBlockSize));
    auto currentSample=start;
 
    bool bBreakLoop = false;
@@ -846,7 +851,7 @@ bool EffectEqualization48x::ProcessOne4x(int count, WaveTrack * t,
       currentSample-=mBlockSize+(mFilterSize>>1);
 
       ProcessBuffer4x(mBufferInfo);
-      bBreakLoop=mEffectEqualization->TrackProgress(count, (double)(bigRun)/(double)bigRuns);
+      bBreakLoop=mEffectEqualization->TrackProgress(count, (double)(bigRun)/bigRuns.as_double());
       if( bBreakLoop )
          break;
       output->Append((samplePtr)&mBigBuffer[(bigRun?mBlockSize:0)+(mFilterSize>>1)], floatSample, subBufferSize-((bigRun?mBlockSize:0)+(mFilterSize>>1)));
@@ -854,7 +859,7 @@ bool EffectEqualization48x::ProcessOne4x(int count, WaveTrack * t,
    if(singleProcessLength && !bBreakLoop) {
       t->Get((samplePtr)mBigBuffer, floatSample, currentSample, singleProcessLength+mBlockSize+(mFilterSize>>1));
       ProcessBuffer(mBigBuffer, mBigBuffer, singleProcessLength+mBlockSize+(mFilterSize>>1));
-      output->Append((samplePtr)&mBigBuffer[bigRuns?mBlockSize:0], floatSample, singleProcessLength+mBlockSize+(mFilterSize>>1));
+      output->Append((samplePtr)&mBigBuffer[bigRuns > 0 ? mBlockSize : 0], floatSample, singleProcessLength+mBlockSize+(mFilterSize>>1));
 //      output->Append((samplePtr)&mBigBuffer[bigRuns?mBlockSize:0], floatSample, singleProcessLength);
    }
    output->Flush();
@@ -910,16 +915,16 @@ bool EffectEqualization48x::ProcessOne1x4xThreaded(int count, WaveTrack * t,
 
    auto trackBlockSize = t->GetMaxBlockSize();
    mEffectEqualization->TrackProgress(count, 0.0);
-   int bigRuns=len/(subBufferSize-mBlockSize);
+   auto bigRuns = len/(subBufferSize-mBlockSize);
    int trackBlocksPerBig=subBufferSize/trackBlockSize;
    int trackLeftovers=subBufferSize-trackBlocksPerBig*trackBlockSize;
-   int singleProcessLength=(mFilterSize>>1)*bigRuns + len%(bigRuns*(subBufferSize-mBlockSize));
+   size_t singleProcessLength=(mFilterSize>>1)*bigRuns + len%(bigRuns*(subBufferSize-mBlockSize));
    auto currentSample=start;
 
    int bigBlocksRead=mWorkerDataCount, bigBlocksWritten=0;
 
    // fill the first workerDataCount buffers we checked above and there is at least this data
-   int maxPreFill=bigRuns<mWorkerDataCount?bigRuns:mWorkerDataCount;
+   auto maxPreFill = bigRuns < mWorkerDataCount ? bigRuns : mWorkerDataCount;
    for(int i=0;i<maxPreFill;i++)
    {
       // fill the buffer
@@ -937,7 +942,7 @@ bool EffectEqualization48x::ProcessOne1x4xThreaded(int count, WaveTrack * t,
    int currentIndex=0;
    bool bBreakLoop = false;
    while(bigBlocksWritten<bigRuns && !bBreakLoop) {
-      bBreakLoop=mEffectEqualization->TrackProgress(count, (double)(bigBlocksWritten)/(double)bigRuns);
+      bBreakLoop=mEffectEqualization->TrackProgress(count, (double)(bigBlocksWritten)/bigRuns.as_double());
       if( bBreakLoop )
          break;
       mDataMutex.Lock(); // Get in line for data
@@ -1028,7 +1033,7 @@ bool EffectEqualization48x::ProcessBuffer8x(BufferInfo *bufferInfo)
    if(bufferInfo->mBufferLength%mBlockSize || mBufferCount!=8)
       return false;
 
-   sampleCount blockCount=bufferInfo->mBufferLength/mBlockSize;
+   auto blockCount=bufferInfo->mBufferLength/mBlockSize;
 
    __m128 *readBlocks[8]; // some temps so we dont destroy the vars in the struct
    __m128 *writeBlocks[8];
diff --git a/src/effects/Equalization48x.h b/src/effects/Equalization48x.h
index 37ae9139c..f80605fdb 100644
--- a/src/effects/Equalization48x.h
+++ b/src/effects/Equalization48x.h
@@ -44,11 +44,11 @@ public:
    BufferInfo() { mBufferLength=0; mBufferStatus=BufferEmpty; mContiguousBufferSize=0; };
    float* mBufferSouce[__MAXBUFFERCOUNT];
    float* mBufferDest[__MAXBUFFERCOUNT];
-   int mBufferLength;
+   size_t mBufferLength;
    size_t mFftWindowSize;
    size_t mFftFilterSize;
    float* mScratchBuffer;
-   int mContiguousBufferSize;
+   size_t mContiguousBufferSize;
    EQBufferStatus mBufferStatus;
 };
 
@@ -127,7 +127,7 @@ private:
 
    bool ProcessTail(WaveTrack * t, WaveTrack * output, sampleCount start, sampleCount len);
 
-   bool ProcessBuffer(fft_type *sourceBuffer, fft_type *destBuffer, sampleCount bufferLength);
+   bool ProcessBuffer(fft_type *sourceBuffer, fft_type *destBuffer, size_t bufferLength);
    bool ProcessBuffer1x(BufferInfo *bufferInfo);
    bool ProcessOne1x(int count, WaveTrack * t, sampleCount start, sampleCount len);
    void Filter1x(size_t len, float *buffer, float *scratchBuffer);
@@ -145,15 +145,15 @@ private:
 #endif
    
    EffectEqualization* mEffectEqualization;
-   int mThreadCount;
+   size_t mThreadCount;
    size_t mFilterSize;
    size_t mBlockSize;
    size_t  mWindowSize;
    int mBufferCount;
-   int mWorkerDataCount;
-   int mBlocksPerBuffer;
-   int mScratchBufferSize;
-   int mSubBufferSize;
+   size_t mWorkerDataCount;
+   size_t mBlocksPerBuffer;
+   size_t mScratchBufferSize;
+   size_t mSubBufferSize;
    float *mBigBuffer;
    BufferInfo* mBufferInfo;
    wxMutex mDataMutex;
diff --git a/src/effects/LoadEffects.cpp b/src/effects/LoadEffects.cpp
index ab137567a..712e85818 100644
--- a/src/effects/LoadEffects.cpp
+++ b/src/effects/LoadEffects.cpp
@@ -79,7 +79,7 @@
    EFFECT( NOISEREDUCTION, EffectNoiseReduction, () )
 #else
 #define NOISEREDUCTION_EFFECT \
-   EFFECT( NOISEREMOVAL, EffectNoiseRemoval() )
+   EFFECT( NOISEREMOVAL, EffectNoiseRemoval, () )
 #endif
 
 //
diff --git a/src/effects/NoiseRemoval.cpp b/src/effects/NoiseRemoval.cpp
index 1536acbf2..0cb4abc47 100644
--- a/src/effects/NoiseRemoval.cpp
+++ b/src/effects/NoiseRemoval.cpp
@@ -594,7 +594,7 @@ bool EffectNoiseRemoval::ProcessOne(int count, WaveTrack * track,
       samplePos += blockSize;
 
       // Update the Progress meter
-      if (TrackProgress(count, (samplePos - start) / (double)len)) {
+      if (TrackProgress(count, (samplePos - start).as_double() / len.as_double())) {
          bLoopSuccess = false;
          break;
       }
diff --git a/src/ondemand/ODDecodeFFmpegTask.cpp b/src/ondemand/ODDecodeFFmpegTask.cpp
index a89d7239c..4dd585141 100644
--- a/src/ondemand/ODDecodeFFmpegTask.cpp
+++ b/src/ondemand/ODDecodeFFmpegTask.cpp
@@ -265,7 +265,7 @@ mStreamIndex(streamIndex)
        sc->m_stream->start_time > 0) {
       stream_delay = sc->m_stream->start_time;
    }
-   mCurrentPos = double(stream_delay) / AV_TIME_BASE;
+   mCurrentPos = sampleCount{ double(stream_delay) / AV_TIME_BASE };
 
    //TODO: add a ref counter to scs?  This will be necessary if we want to allow copy and paste of not-yet decoded
    //ODDecodeBlockFiles that point to FFmpeg files.
@@ -340,7 +340,7 @@ int ODFFmpegDecoder::Decode(SampleBuffer & data, sampleFormat & format, sampleCo
             //printf("attempting seek to %llu, attempts %d\n", targetts, numAttempts);
             if(av_seek_frame(mFormatContext,stindex,targetts,0) >= 0){
                //find out the dts we've seekd to.
-               sampleCount actualDecodeStart = 0.5 + st->codec->sample_rate * st->cur_dts  * ((double)st->time_base.num/st->time_base.den);      //this is mostly safe because den is usually 1 or low number but check for high values.
+               sampleCount actualDecodeStart { 0.5 + st->codec->sample_rate * st->cur_dts  * ((double)st->time_base.num/st->time_base.den) };      //this is mostly safe because den is usually 1 or low number but check for high values.
 
                mCurrentPos = actualDecodeStart;
                seeking = true;
@@ -375,8 +375,8 @@ int ODFFmpegDecoder::Decode(SampleBuffer & data, sampleFormat & format, sampleCo
          // for some formats
          // The only other case for inserting silence is for initial offset and ImportFFmpeg.cpp does this for us
          if (seeking) {
-            actualDecodeStart = 0.52 + (sc->m_stream->codec->sample_rate * sc->m_pkt->dts
-                                        * ((double)sc->m_stream->time_base.num / sc->m_stream->time_base.den));
+            actualDecodeStart = sampleCount{ 0.52 + (sc->m_stream->codec->sample_rate * sc->m_pkt->dts
+                                        * ((double)sc->m_stream->time_base.num / sc->m_stream->time_base.den)) };
             //this is mostly safe because den is usually 1 or low number but check for high values.
 
             //hack to get rounding to work to neareset frame size since dts isn't exact
@@ -548,7 +548,7 @@ int ODFFmpegDecoder::FillDataFromCache(samplePtr & data, sampleFormat outFormat,
 
                case AV_SAMPLE_FMT_S32:
                   //printf("s32 in %lu out %lu cachelen %lu outLen %lu\n", inIndex, outIndex, mDecodeCache[i]->len, len);
-                  ((float *)outBuf)[outIndex] = (float) ((int32_t*)mDecodeCache[i]->samplePtr.get())[inIndex] * (1.0 / (1u << 31));
+                  ((float *)outBuf)[outIndex] = (float) ((int32_t*)mDecodeCache[i]->samplePtr)[inIndex] * (1.0 / (1u << 31));
                break;
 
                case AV_SAMPLE_FMT_FLT:
diff --git a/src/prefs/SpectrogramSettings.h b/src/prefs/SpectrogramSettings.h
index 02e527147..5eb8eea3c 100644
--- a/src/prefs/SpectrogramSettings.h
+++ b/src/prefs/SpectrogramSettings.h
@@ -138,8 +138,8 @@ public:
 
 #ifdef EXPERIMENTAL_FIND_NOTES
    bool fftFindNotes;
-   bool findNotesMinA;
-   bool numberOfMaxima;
+   double findNotesMinA;
+   int numberOfMaxima;
    bool findNotesQuantize;
 #endif //EXPERIMENTAL_FIND_NOTES
 
diff --git a/src/prefs/SpectrumPrefs.cpp b/src/prefs/SpectrumPrefs.cpp
index 21cfd8dcf..5693778d0 100644
--- a/src/prefs/SpectrumPrefs.cpp
+++ b/src/prefs/SpectrumPrefs.cpp
@@ -107,7 +107,7 @@ void SpectrumPrefs::Populate(size_t windowSize)
 
    //------------------------- Main section --------------------
    // Now construct the GUI itself.
-   ShuttleGui S(this, eIsCreating);
+   ShuttleGui S(this, eIsCreatingFromPrefs);
    PopulateOrExchange(S);
    // ----------------------- End of main section --------------
 }
@@ -265,18 +265,18 @@ void SpectrumPrefs::PopulateOrExchange(ShuttleGui & S)
          {
             mFindNotesMinA =
                S.TieNumericTextBox(_("Minimum Amplitude (dB):"),
-               mTempSettings.fftFindNotes,
+               mTempSettings.findNotesMinA,
                8);
 
             mFindNotesN =
                S.TieNumericTextBox(_("Max. Number of Notes (1..128):"),
-               mTempSettings.findNotesMinA,
+               mTempSettings.numberOfMaxima,
                8);
          }
          S.EndTwoColumn();
 
          S.TieCheckBox(_("&Find Notes"),
-            mTempSettings.numberOfMaxima);
+            mTempSettings.fftFindNotes);
 
          S.TieCheckBox(_("&Quantize Notes"),
             mTempSettings.findNotesQuantize);
@@ -353,7 +353,7 @@ bool SpectrumPrefs::Validate()
    }
 #endif //EXPERIMENTAL_FIND_NOTES
 
-   ShuttleGui S(this, eIsGettingFromDialog);
+   ShuttleGui S(this, eIsSavingToPrefs);
    PopulateOrExchange(S);
 
    // Delegate range checking to SpectrogramSettings class
@@ -376,7 +376,7 @@ bool SpectrumPrefs::Apply()
             static_cast<WaveTrack*>(mWt->GetLink())
           : nullptr;
 
-   ShuttleGui S(this, eIsGettingFromDialog);
+   ShuttleGui S(this, eIsSavingToPrefs);
    PopulateOrExchange(S);
 
 
diff --git a/src/prefs/WaveformPrefs.cpp b/src/prefs/WaveformPrefs.cpp
index 4081c916b..925b3cdd7 100644
--- a/src/prefs/WaveformPrefs.cpp
+++ b/src/prefs/WaveformPrefs.cpp
@@ -64,7 +64,7 @@ void WaveformPrefs::Populate()
 
    //------------------------- Main section --------------------
    // Now construct the GUI itself.
-   ShuttleGui S(this, eIsCreating);
+   ShuttleGui S(this, eIsCreatingFromPrefs);
    PopulateOrExchange(S);
    // ----------------------- End of main section --------------
 }
diff --git a/src/toolbars/TranscriptionToolBar.cpp b/src/toolbars/TranscriptionToolBar.cpp
index cf821dfb7..ae5f55585 100644
--- a/src/toolbars/TranscriptionToolBar.cpp
+++ b/src/toolbars/TranscriptionToolBar.cpp
@@ -393,7 +393,8 @@ void TranscriptionToolBar::SetButton(bool down, AButton* button)
    }
 }
 
-void TranscriptionToolBar::GetSamples(WaveTrack *t, sampleCount *s0, sampleCount *slen)
+void TranscriptionToolBar::GetSamples(
+   const WaveTrack *t, sampleCount *s0, sampleCount *slen)
 {
    // GetSamples attempts to translate the start and end selection markers into sample indices
    // These selection numbers are doubles.
@@ -528,15 +529,16 @@ void TranscriptionToolBar::OnStartOn(wxCommandEvent & WXUNUSED(event))
 
    Track *t = iter.First();   //Make a track
    if(t ) {
-      sampleCount start,len;
-      GetSamples((WaveTrack*)t, &start,&len);
+      auto wt = static_cast<const WaveTrack*>(t);
+      sampleCount start, len;
+      GetSamples(wt, &start, &len);
 
       //Adjust length to end if selection is null
       //if(len == 0)
-      //len = (WaveTrack*)t->GetSequence()->GetNumSamples()-start;
+      //len = wt->GetSequence()->GetNumSamples()-start;
 
-      auto newstart = mVk->OnForward(*(WaveTrack*)t,start,len);
-      double newpos = newstart / ((WaveTrack*)t)->GetRate();
+      auto newstart = mVk->OnForward(*wt, start, len);
+      double newpos = newstart.as_double() / wt->GetRate();
 
       p->SetSel0(newpos);
       p->RedrawProject();
@@ -561,15 +563,16 @@ void TranscriptionToolBar::OnStartOff(wxCommandEvent & WXUNUSED(event))
    SetButton(false, mButtons[TTB_StartOff]);
    Track *t = iter.First();   //Make a track
    if(t) {
-      sampleCount start,len;
-      GetSamples((WaveTrack*)t, &start,&len);
+      auto wt = static_cast<const WaveTrack*>(t);
+      sampleCount start, len;
+      GetSamples(wt, &start, &len);
 
       //Adjust length to end if selection is null
       //if(len == 0)
-      //len = (WaveTrack*)t->GetSequence()->GetNumSamples()-start;
+      //len = wt->GetSequence()->GetNumSamples()-start;
 
-      auto newstart = mVk->OffForward(*(WaveTrack*)t,start,len);
-      double newpos = newstart / ((WaveTrack*)t)->GetRate();
+      auto newstart = mVk->OffForward(*wt, start, len);
+      double newpos = newstart.as_double() / wt->GetRate();
 
       p->SetSel0(newpos);
       p->RedrawProject();
@@ -594,8 +597,9 @@ void TranscriptionToolBar::OnEndOn(wxCommandEvent & WXUNUSED(event))
 
    Track *t = iter.First();   //Make a track
    if(t) {
-      sampleCount start,len;
-      GetSamples((WaveTrack*)t, &start,&len);
+      auto wt = static_cast<const WaveTrack*>(t);
+      sampleCount start, len;
+      GetSamples(wt, &start, &len);
 
       //Adjust length to end if selection is null
       if(len == 0)
@@ -603,8 +607,8 @@ void TranscriptionToolBar::OnEndOn(wxCommandEvent & WXUNUSED(event))
             len = start;
             start = 0;
          }
-      auto newEnd = mVk->OnBackward(*(WaveTrack*)t,start+ len,len);
-      double newpos = newEnd / ((WaveTrack*)t)->GetRate();
+      auto newEnd = mVk->OnBackward(*wt, start + len, len);
+      double newpos = newEnd.as_double() / wt->GetRate();
 
       p->SetSel1(newpos);
       p->RedrawProject();
@@ -630,16 +634,17 @@ void TranscriptionToolBar::OnEndOff(wxCommandEvent & WXUNUSED(event))
 
    Track *t = iter.First();   //Make a track
    if(t) {
-      sampleCount start,len;
-      GetSamples((WaveTrack*)t, &start,&len);
+      auto wt = static_cast<const WaveTrack*>(t);
+      sampleCount start, len;
+      GetSamples(wt, &start, &len);
 
       //Adjust length to end if selection is null
       if(len == 0) {
          len = start;
          start = 0;
       }
-      auto newEnd = mVk->OffBackward(*(WaveTrack*)t,start+ len,len);
-      double newpos = newEnd / ((WaveTrack*)t)->GetRate();
+      auto newEnd = mVk->OffBackward(*wt, start + len, len);
+      double newpos = newEnd.as_double() / wt->GetRate();
 
       p->SetSel1(newpos);
       p->RedrawProject();
@@ -665,25 +670,27 @@ void TranscriptionToolBar::OnSelectSound(wxCommandEvent & WXUNUSED(event))
 
 
    TrackList *tl = p->GetTracks();
-   TrackListIterator iter(tl);
+   TrackListOfKindIterator iter(Track::Wave, tl);
 
    Track *t = iter.First();   //Make a track
    if(t)
       {
-         sampleCount start,len;
-         GetSamples((WaveTrack*)t, &start,&len);
+         auto wt = static_cast<const WaveTrack*>(t);
+         sampleCount start, len;
+         GetSamples(wt, &start, &len);
 
          //Adjust length to end if selection is null
          //if(len == 0)
-         //len = (WaveTrack*)t->GetSequence()->GetNumSamples()-start;
+         //len = wt->GetSequence()->GetNumSamples()-start;
 
-         double rate =  ((WaveTrack*)t)->GetRate();
-         auto newstart = mVk->OffBackward(*(WaveTrack*)t,start,start);
-         auto newend   = mVk->OffForward(*(WaveTrack*)t,start+len,(int)(tl->GetEndTime()*rate));
+         double rate =  wt->GetRate();
+         auto newstart = mVk->OffBackward(*wt, start, start);
+         auto newend   =
+            mVk->OffForward(*wt, start + len, (int)(tl->GetEndTime() * rate));
 
          //reset the selection bounds.
-         p->SetSel0(newstart / rate);
-         p->SetSel1(newend /  rate);
+         p->SetSel0(newstart.as_double() / rate);
+         p->SetSel1(newend.as_double() /  rate);
          p->RedrawProject();
 
       }
@@ -705,24 +712,26 @@ void TranscriptionToolBar::OnSelectSilence(wxCommandEvent & WXUNUSED(event))
 
 
    TrackList *tl = p->GetTracks();
-   TrackListIterator iter(tl);
+   TrackListOfKindIterator iter(Track::Wave, tl);
 
    Track *t = iter.First();   //Make a track
    if(t)
       {
-         sampleCount start,len;
-         GetSamples((WaveTrack*)t, &start,&len);
+         auto wt = static_cast<const WaveTrack*>(t);
+         sampleCount start, len;
+         GetSamples(wt, &start, &len);
 
          //Adjust length to end if selection is null
          //if(len == 0)
-         //len = (WaveTrack*)t->GetSequence()->GetNumSamples()-start;
-         double rate =  ((WaveTrack*)t)->GetRate();
-         auto newstart = mVk->OnBackward(*(WaveTrack*)t,start,start);
-         auto newend   = mVk->OnForward(*(WaveTrack*)t,start+len,(int)(tl->GetEndTime()*rate));
+         //len = wt->GetSequence()->GetNumSamples()-start;
+         double rate =  wt->GetRate();
+         auto newstart = mVk->OnBackward(*wt, start, start);
+         auto newend   =
+            mVk->OnForward(*wt, start + len, (int)(tl->GetEndTime() * rate));
 
          //reset the selection bounds.
-         p->SetSel0(newstart /  rate);
-         p->SetSel1(newend / rate);
+         p->SetSel0(newstart.as_double() /  rate);
+         p->SetSel1(newend.as_double() / rate);
          p->RedrawProject();
 
       }
@@ -745,15 +754,16 @@ void TranscriptionToolBar::OnCalibrate(wxCommandEvent & WXUNUSED(event))
    AudacityProject *p = GetActiveProject();
 
    TrackList *tl = p->GetTracks();
-   TrackListIterator iter(tl);
+   TrackListOfKindIterator iter(Track::Wave, tl);
    Track *t = iter.First();   //Get a track
 
    if(t)
       {
-         sampleCount start,len;
-         GetSamples((WaveTrack*)t, &start,&len);
+         auto wt = static_cast<const WaveTrack*>(t);
+         sampleCount start, len;
+         GetSamples(wt, &start, &len);
 
-         mVk->CalibrateNoise(*((WaveTrack*)t),start,len);
+         mVk->CalibrateNoise(*wt, start, len);
          mVk->AdjustThreshold(3);
 
          mButtons[TTB_StartOn]->Enable();
@@ -798,13 +808,14 @@ void TranscriptionToolBar::OnAutomateSelection(wxCommandEvent & WXUNUSED(event))
    mVk->AdjustThreshold(GetSensitivity());
    AudacityProject *p = GetActiveProject();
    TrackList *tl = p->GetTracks();
-   TrackListIterator iter(tl);
+   TrackListOfKindIterator iter(Track::Wave, tl);
 
    Track *t = iter.First();   //Make a track
    if(t)
       {
-         sampleCount start,len;
-         GetSamples((WaveTrack*)t, &start,&len);
+         auto wt = static_cast<const WaveTrack*>(t);
+         sampleCount start, len;
+         GetSamples(wt, &start, &len);
 
          //Adjust length to end if selection is null
          if(len == 0)
@@ -812,12 +823,12 @@ void TranscriptionToolBar::OnAutomateSelection(wxCommandEvent & WXUNUSED(event))
                len = start;
                start = 0;
             }
-         int lastlen = 0;
+         sampleCount lastlen = 0;
          double newStartPos, newEndPos;
 
 
          //This is the minumum word size in samples (.05 is 50 ms)
-         int minWordSize = (int)(((WaveTrack*)t)->GetRate() * .05);
+         int minWordSize = (int)(wt->GetRate() * .05);
 
          //Continue until we have processed the entire
          //region, or we are making no progress.
@@ -826,7 +837,7 @@ void TranscriptionToolBar::OnAutomateSelection(wxCommandEvent & WXUNUSED(event))
 
                lastlen = len;
 
-               auto newStart = mVk->OnForward(*(WaveTrack*)t,start,len);
+               auto newStart = mVk->OnForward(*wt, start, len);
 
                //JKC: If no start found then don't add any labels.
                if( newStart==start)
@@ -843,7 +854,8 @@ void TranscriptionToolBar::OnAutomateSelection(wxCommandEvent & WXUNUSED(event))
                //OK, now we have found a NEW starting point.  A 'word' should be at least
                //50 ms long, so jump ahead minWordSize
 
-               auto newEnd   = mVk->OffForward(*(WaveTrack*)t,newStart+minWordSize, len);
+               auto newEnd   =
+                  mVk->OffForward(*wt, newStart + minWordSize, len);
 
                //If newEnd didn't move, we should give up, because
                // there isn't another end before the end of the selection.
@@ -855,8 +867,8 @@ void TranscriptionToolBar::OnAutomateSelection(wxCommandEvent & WXUNUSED(event))
                len -= (newEnd - newStart);
 
                //Calculate the start and end of the words, in seconds
-               newStartPos = newStart / ((WaveTrack*)t)->GetRate();
-               newEndPos = newEnd / ((WaveTrack*)t)->GetRate();
+               newStartPos = newStart.as_double() / wt->GetRate();
+               newEndPos = newEnd.as_double() / wt->GetRate();
 
 
                //Increment
diff --git a/src/toolbars/TranscriptionToolBar.h b/src/toolbars/TranscriptionToolBar.h
index f039cacf4..8e13a53bb 100644
--- a/src/toolbars/TranscriptionToolBar.h
+++ b/src/toolbars/TranscriptionToolBar.h
@@ -129,7 +129,7 @@ class TranscriptionToolBar final : public ToolBar {
    void MakeAlternateImages(
       teBmps eFore, teBmps eDisabled,
       int id, unsigned altIdx);
-   void GetSamples(WaveTrack *t, sampleCount *s0, sampleCount *slen);
+   void GetSamples(const WaveTrack *t, sampleCount *s0, sampleCount *slen);
    void SetButton(bool newstate, AButton *button);
    void RegenerateTooltips() override;
 
diff --git a/src/tracks/ui/EditCursorOverlay.cpp b/src/tracks/ui/EditCursorOverlay.cpp
index 813067fa4..a9a1db32b 100644
--- a/src/tracks/ui/EditCursorOverlay.cpp
+++ b/src/tracks/ui/EditCursorOverlay.cpp
@@ -20,6 +20,10 @@ Paul Licameli split from TrackPanel.cpp
 #include "../../TrackPanelAx.h"
 #include "../../ViewInfo.h"
 
+#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
+#include "../../WaveTrack.h"
+#endif
+
 #include <wx/dc.h>
 
 namespace {
@@ -117,10 +121,10 @@ void EditCursorOverlay::Draw(OverlayPanel &panel, wxDC &dc)
             // ^^^ The whole point of this routine.
 
 #ifdef EXPERIMENTAL_OUTPUT_DISPLAY
-            if (MONO_WAVE_PAN(t)){
-               y = t->GetY(true) - mViewInfo->vpos + 1;
-               top = y + kTopInset;
-               bottom = y + t->GetHeight(true) - kTopInset;
+            if (MONO_WAVE_PAN(pTrack)){
+               auto y = pTrack->GetY(true) - viewInfo.vpos + 1;
+               auto top = y + kTopInset;
+               auto bottom = y + pTrack->GetHeight(true) - kTopInset;
                AColor::Line(dc, mLastCursorX, top, mLastCursorX, bottom);
             }
 #endif