steve wrote:Perhaps you're not seeing what I'm seeing. I don't just mean that it's not snapping to the sample boundary. I mean it's way off.
Here is the result of the described steps with un-patched Audacity 2.1.3 RC2 version. Note that the selection fits almost exactly in the available window area:
fullwindow001.png
And here is the result with the patched version. Note that the selection does not fill the window:
fullwindow002.png
To be clear, what we're snapping to with this patch is the number of pixels between each sample, not the samples themselves. To do some napkin math, if the track in your image were 800 pixels wide, it's filled by ~0.012 seconds, which comes out to approximately 70,000 pixels/second. At a sample rate of 44,100 samples/second, (pixels/second)/(samples/second) = 1.51 pixels/sample. Since this only considers integer pixels/sample, it'd either have to reduce to 1 pixel/sample spacing, which would leave a large gap like the one you've posted, or it could move up to 2 pixels/sample, which would push the selection past the end of the screen.
You could probably mitigate this by changing the threshold where the "snap" to integer ratios of pixels/sample starts happening from 1 to 4. I've put the patch for that here. Looking at the example you've given, at a sample rate of 48000Hz, it looks like the snapping begins at [0, 290] samples and becomes most dramatic at something like [0, 232] samples. Still, I'd argue that this could be correct behavior if the user wanted equally spaced samples.
Code: Select all
diff --git a/src/TrackArtist.cpp b/src/TrackArtist.cpp
index 7d4385d..8fcaf9a 100644
--- a/src/TrackArtist.cpp
+++ b/src/TrackArtist.cpp
@@ -1308,6 +1308,7 @@ void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect & rect, const double env[
void TrackArtist::DrawIndividualSamples(wxDC &dc, int leftOffset, const wxRect &rect,
float zoomMin, float zoomMax,
+ int zeroLevelYCoordinate,
bool dB, float dBRange,
const WaveClip *clip,
const ZoomInfo &zoomInfo,
@@ -1363,12 +1364,13 @@ void TrackArtist::DrawIndividualSamples(wxDC &dc, int leftOffset, const wxRect &
}
// Draw lines
- for (decltype(slen) s = 0; s < slen - 1; s++) {
+ for (decltype(slen) s = 0; s < slen; s++) {
AColor::Line(dc,
rect.x + xpos[s], rect.y + ypos[s],
- rect.x + xpos[s + 1], rect.y + ypos[s + 1]);
+ rect.x + xpos[s], zeroLevelYCoordinate);
}
+
if (showPoints)
{
// Draw points where spacing is enough
@@ -1807,17 +1809,17 @@ void TrackArtist::DrawClipWaveform(const WaveTrack *track,
FindWavePortions(portions, rect, zoomInfo, params);
const unsigned nPortions = portions.size();
- // Require at least 1/2 pixel per sample for drawing individual samples.
- const double threshold1 = 0.5 * rate;
- // Require at least 3 pixels per sample for drawing the draggable points.
- const double threshold2 = 3 * rate;
+ // Require at least 4 pixels per sample for drawing individual samples.
+ const double threshold1 = 4 * rate;
+ // Require at least 4 pixels per sample for drawing the draggable points.
+ const double threshold2 = 4 * rate;
{
bool showIndividualSamples = false;
for (unsigned ii = 0; !showIndividualSamples && ii < nPortions; ++ii) {
const WavePortion &portion = portions[ii];
showIndividualSamples =
- !portion.inFisheye && portion.averageZoom > threshold1;
+ !portion.inFisheye && portion.averageZoom >= threshold1;
}
if (!showIndividualSamples) {
@@ -1839,8 +1841,8 @@ void TrackArtist::DrawClipWaveform(const WaveTrack *track,
for (unsigned ii = 0; ii < nPortions; ++ii) {
WavePortion &portion = portions[ii];
- const bool showIndividualSamples = portion.averageZoom > threshold1;
- const bool showPoints = portion.averageZoom > threshold2;
+ const bool showIndividualSamples = portion.averageZoom >= threshold1;
+ const bool showPoints = portion.averageZoom >= threshold2;
wxRect& rect = portion.rect;
rect.Intersect(mid);
wxASSERT(rect.width >= 0);
@@ -1917,6 +1919,7 @@ void TrackArtist::DrawClipWaveform(const WaveTrack *track,
}
else
DrawIndividualSamples(dc, leftOffset, rect, zoomMin, zoomMax,
+ track->ZeroLevelYCoordinate(mid),
dB, dBRange,
clip, zoomInfo,
bigPoints, showPoints, muted);
diff --git a/src/TrackArtist.h b/src/TrackArtist.h
index f5c76ae..aa1acb7 100644
--- a/src/TrackArtist.h
+++ b/src/TrackArtist.h
@@ -157,6 +157,7 @@ class AUDACITY_DLL_API TrackArtist {
);
void DrawIndividualSamples(wxDC & dc, int leftOffset, const wxRect & rect,
float zoomMin, float zoomMax,
+ int zeroLevelYCoordinate,
bool dB, float dBRange,
const WaveClip *clip,
const ZoomInfo &zoomInfo,
diff --git a/src/ViewInfo.cpp b/src/ViewInfo.cpp
index 089554e..fdc8485 100644
--- a/src/ViewInfo.cpp
+++ b/src/ViewInfo.cpp
@@ -90,6 +90,15 @@ bool ZoomInfo::ZoomOutAvailable() const
void ZoomInfo::SetZoom(double pixelsPerSecond)
{
zoom = std::max(gMinZoom, std::min(gMaxZoom, pixelsPerSecond));
+ AudacityProject * project = GetActiveProject();
+ if ( project ) {
+ double samplesPerSecond = project->GetRate();
+ double pixelsPerSample = pixelsPerSecond/samplesPerSecond;
+ if ( pixelsPerSample >= 4 ) {
+ zoom = floor(pixelsPerSample) * samplesPerSecond;
+ }
+ }
#ifdef EXPERIMENTAL_DA
// Disable snapping if user zooms in a long way.
// Helps stop users be trapped in snap-to.