mirror of
https://github.com/cookiengineer/audacity
synced 2025-07-13 15:17:42 +02:00
Vertical ruler zooming uses NumberScale in a generalized way
This commit is contained in:
parent
43b7df701b
commit
66e939275f
@ -4593,7 +4593,6 @@ void TrackPanel::HandleVZoomDrag( wxMouseEvent & event )
|
||||
/// - Zoom in; ensure we don't go too large.
|
||||
void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event )
|
||||
{
|
||||
int minBins = 0;
|
||||
if (!mCapturedTrack)
|
||||
return;
|
||||
|
||||
@ -4623,6 +4622,7 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event )
|
||||
// don't do anything if track is not wave
|
||||
if (mCapturedTrack->GetKind() != Track::Wave)
|
||||
return;
|
||||
|
||||
WaveTrack *track = static_cast<WaveTrack*>(mCapturedTrack);
|
||||
WaveTrack *partner = static_cast<WaveTrack *>(mTracks->GetLink(track));
|
||||
int height = track->GetHeight();
|
||||
@ -4635,223 +4635,173 @@ void TrackPanel::HandleVZoomButtonUp( wxMouseEvent & event )
|
||||
mZoomStart = temp;
|
||||
}
|
||||
|
||||
float min, max, c, l, binSize = 0.0;
|
||||
float min, max, c, l, minBand = 0;
|
||||
const double rate = track->GetRate();
|
||||
const float halfrate = rate / 2;
|
||||
const SpectrogramSettings &settings = track->GetSpectrogramSettings();
|
||||
NumberScale scale(track->GetSpectrogramSettings().GetScale(rate, false, false));
|
||||
const bool spectral = (track->GetDisplay() == WaveTrack::Spectrum);
|
||||
const bool spectrumLinear = spectral &&
|
||||
(track->GetSpectrogramSettings().scaleType == SpectrogramSettings::stLinear);
|
||||
const bool spectrumLog = spectral &&
|
||||
(track->GetSpectrogramSettings().scaleType == SpectrogramSettings::stLogarithmic);
|
||||
if (spectrumLinear) {
|
||||
const SpectrogramSettings &settings = track->GetSpectrogramSettings();
|
||||
min = settings.GetMinFreq(rate);
|
||||
max = settings.GetMaxFreq(rate);
|
||||
|
||||
if (spectral) {
|
||||
if (spectrumLinear) {
|
||||
min = settings.GetMinFreq(rate);
|
||||
max = settings.GetMaxFreq(rate);
|
||||
}
|
||||
else {
|
||||
min = settings.GetLogMinFreq(rate);
|
||||
max = settings.GetLogMaxFreq(rate);
|
||||
}
|
||||
const int fftLength = settings.GetFFTLength(false);
|
||||
binSize = rate / fftLength;
|
||||
minBins = std::min(10, fftLength / 2); //minimum 10 freq bins, unless there are less
|
||||
}
|
||||
else if (spectrumLog) {
|
||||
const SpectrogramSettings &settings = track->GetSpectrogramSettings();
|
||||
min = settings.GetLogMinFreq(rate);
|
||||
max = settings.GetLogMaxFreq(rate);
|
||||
const int fftLength = settings.GetFFTLength(false);
|
||||
binSize = rate / fftLength;
|
||||
minBins = std::min(10, fftLength / 2); //minimum 10 freq bins, unless there are less
|
||||
const float binSize = rate / fftLength;
|
||||
const int minBins =
|
||||
std::min(10, fftLength / 2); //minimum 10 freq bins, unless there are less
|
||||
minBand = minBins * binSize;
|
||||
}
|
||||
else
|
||||
track->GetDisplayBounds(&min, &max);
|
||||
|
||||
if (IsDragZooming()) {
|
||||
// Drag Zoom
|
||||
float p1, p2, tmin, tmax;
|
||||
tmin=min;
|
||||
tmax=max;
|
||||
const float tmin = min, tmax = max;
|
||||
|
||||
if(spectrumLog) {
|
||||
double xmin = 1-(mZoomEnd - ypos) / (float)height;
|
||||
double xmax = 1-(mZoomStart - ypos) / (float)height;
|
||||
double lmin=log10(tmin), lmax=log10(tmax);
|
||||
double d=lmax-lmin;
|
||||
min=std::max(1.0, pow(10, xmin*d+lmin));
|
||||
max=std::min(rate/2.0, pow(10, xmax*d+lmin));
|
||||
// Enforce vertical zoom limits
|
||||
// done in the linear freq domain for now, but not too far out
|
||||
if(max < min + minBins * binSize)
|
||||
max = min + minBins * binSize;
|
||||
if(max > rate/2.) {
|
||||
max = rate/2.;
|
||||
min = max - minBins * binSize;
|
||||
}
|
||||
if (spectral) {
|
||||
double xmin = 1 - (mZoomEnd - ypos) / (float)height;
|
||||
double xmax = 1 - (mZoomStart - ypos) / (float)height;
|
||||
const float middle = (xmin + xmax) / 2;
|
||||
const float middleValue = scale.PositionToValue(middle);
|
||||
|
||||
min = std::max(spectrumLinear ? 0.0f : 1.0f,
|
||||
std::min(middleValue - minBand / 2,
|
||||
scale.PositionToValue(xmin)
|
||||
));
|
||||
max = std::min(halfrate,
|
||||
std::max(middleValue + minBand / 2,
|
||||
scale.PositionToValue(xmax)
|
||||
));
|
||||
}
|
||||
else {
|
||||
p1 = (mZoomStart - ypos) / (float)height;
|
||||
p2 = (mZoomEnd - ypos) / (float)height;
|
||||
const float p1 = (mZoomStart - ypos) / (float)height;
|
||||
const float p2 = (mZoomEnd - ypos) / (float)height;
|
||||
max = (tmax * (1.0-p1) + tmin * p1);
|
||||
min = (tmax * (1.0-p2) + tmin * p2);
|
||||
|
||||
// Enforce vertical zoom limits
|
||||
if(spectrumLinear) {
|
||||
if(min < 0.)
|
||||
min = 0.;
|
||||
if(max < min + minBins * binSize)
|
||||
max = min + minBins * binSize;
|
||||
if(max > rate/2.) {
|
||||
max = rate/2.;
|
||||
min = max - minBins * binSize;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Waveform view - allow zooming down to a range of ZOOMLIMIT
|
||||
if (max - min < ZOOMLIMIT) { // if user attempts to go smaller...
|
||||
c = (min+max)/2; // ...set centre of view to centre of dragged area and top/bottom to ZOOMLIMIT/2 above/below
|
||||
min = c - ZOOMLIMIT/2.0;
|
||||
max = c + ZOOMLIMIT/2.0;
|
||||
}
|
||||
// Waveform view - allow zooming down to a range of ZOOMLIMIT
|
||||
if (max - min < ZOOMLIMIT) { // if user attempts to go smaller...
|
||||
c = (min+max)/2; // ...set centre of view to centre of dragged area and top/bottom to ZOOMLIMIT/2 above/below
|
||||
min = c - ZOOMLIMIT/2.0;
|
||||
max = c + ZOOMLIMIT/2.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (event.ShiftDown() || event.RightUp()) {
|
||||
// Zoom OUT
|
||||
// Zoom out to -1.0...1.0 first, then, and only
|
||||
// then, if they click again, allow one more
|
||||
// zoom out.
|
||||
if (spectrumLinear) {
|
||||
if (spectral) {
|
||||
if (event.ShiftDown() && event.RightUp()) {
|
||||
// Zoom out full
|
||||
min = 0.0;
|
||||
max = rate/2.;
|
||||
min = spectrumLinear ? 0.0f : 1.0f;
|
||||
max = halfrate;
|
||||
}
|
||||
else {
|
||||
// Zoom out
|
||||
c = 0.5*(min+max);
|
||||
l = (c - min);
|
||||
if(c - 2*l <= 0) {
|
||||
min = 0.0;
|
||||
max = std::min( rate/2., 2. * max);
|
||||
}
|
||||
else {
|
||||
min = std::max( 0.0f, c - 2*l);
|
||||
max = std::min( float(rate)/2, c + 2*l);
|
||||
}
|
||||
|
||||
// (Used to zoom out centered at midline, ignoring the click, if linear view.
|
||||
// I think it is better to be consistent. PRL)
|
||||
// Center zoom-out at the midline
|
||||
const float middle = // spectrumLinear ? 0.5f :
|
||||
1.0f - (mZoomStart - ypos) / (float)height;
|
||||
|
||||
min = std::max(spectrumLinear ? 0.0f : 1.0f, scale.PositionToValue(middle - 1.0f));
|
||||
max = std::min(halfrate, scale.PositionToValue(middle + 1.0f));
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(spectrumLog) {
|
||||
if (event.ShiftDown() && event.RightUp()) {
|
||||
// Zoom out full
|
||||
min = 1.0;
|
||||
max = rate/2.;
|
||||
}
|
||||
else {
|
||||
// Zoom out
|
||||
float p1;
|
||||
p1 = (mZoomStart - ypos) / (float)height;
|
||||
c = 1.0-p1;
|
||||
double xmin = c - 1.;
|
||||
double xmax = c + 1.;
|
||||
double lmin = log10(min), lmax = log10(max);
|
||||
double d = lmax-lmin;
|
||||
min = std::max(1.0f,float(pow(10, xmin*d+lmin)));
|
||||
max = std::min(rate/2., pow(10, xmax*d+lmin));
|
||||
}
|
||||
// Zoom out to -1.0...1.0 first, then, and only
|
||||
// then, if they click again, allow one more
|
||||
// zoom out.
|
||||
if (event.ShiftDown() && event.RightUp()) {
|
||||
// Zoom out full
|
||||
min = -1.0;
|
||||
max = 1.0;
|
||||
}
|
||||
else {
|
||||
if (event.ShiftDown() && event.RightUp()) {
|
||||
// Zoom out full
|
||||
min = -1.0;
|
||||
max = 1.0;
|
||||
// Zoom out
|
||||
if (min <= -1.0 && max >= 1.0) {
|
||||
min = -2.0;
|
||||
max = 2.0;
|
||||
}
|
||||
else {
|
||||
// Zoom out
|
||||
if (min <= -1.0 && max >= 1.0) {
|
||||
min = -2.0;
|
||||
max = 2.0;
|
||||
}
|
||||
else {
|
||||
c = 0.5*(min+max);
|
||||
l = (c - min);
|
||||
// limit to +/- 1 range unless already outside that range...
|
||||
float minRange = (min < -1) ? -2.0 : -1.0;
|
||||
float maxRange = (max > 1) ? 2.0 : 1.0;
|
||||
// and enforce vertical zoom limits.
|
||||
min = std::min(maxRange - ZOOMLIMIT, std::max(minRange, c - 2*l));
|
||||
max = std::max(minRange + ZOOMLIMIT, std::min(maxRange, c + 2*l));
|
||||
}
|
||||
c = 0.5*(min + max);
|
||||
l = (c - min);
|
||||
// limit to +/- 1 range unless already outside that range...
|
||||
float minRange = (min < -1) ? -2.0 : -1.0;
|
||||
float maxRange = (max > 1) ? 2.0 : 1.0;
|
||||
// and enforce vertical zoom limits.
|
||||
min = std::min(maxRange - ZOOMLIMIT, std::max(minRange, c - 2 * l));
|
||||
max = std::max(minRange + ZOOMLIMIT, std::min(maxRange, c + 2 * l));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Zoom IN
|
||||
float p1;
|
||||
if (spectrumLinear) {
|
||||
c = 0.5*(min+max);
|
||||
// Enforce maximum vertical zoom
|
||||
l = std::max( minBins * binSize, (c - min));
|
||||
if (spectral) {
|
||||
// Center the zoom-in at the click
|
||||
const float middle = 1.0f - (mZoomStart - ypos) / (float)height;
|
||||
const float middleValue = scale.PositionToValue(middle);
|
||||
|
||||
p1 = (mZoomStart - ypos) / (float)height;
|
||||
c = (max * (1.0-p1) + min * p1);
|
||||
min = std::max( 0.0, c - 0.5*l);
|
||||
max = std::min( float(rate)/2, min + l);
|
||||
min = std::max(spectrumLinear ? 0.0f : 1.0f,
|
||||
std::min(middleValue - minBand / 2,
|
||||
scale.PositionToValue(middle - 0.25f)
|
||||
));
|
||||
max = std::min(halfrate,
|
||||
std::max(middleValue + minBand / 2,
|
||||
scale.PositionToValue(middle + 0.25f)
|
||||
));
|
||||
}
|
||||
else {
|
||||
if(spectrumLog) {
|
||||
p1 = (mZoomStart - ypos) / (float)height;
|
||||
c = 1.0-p1;
|
||||
double xmin = c - 0.25;
|
||||
double xmax = c + 0.25;
|
||||
double lmin = log10(min), lmax = log10(max);
|
||||
double d = lmax-lmin;
|
||||
min = std::max(1.0f, float(pow(10, xmin*d+lmin)));
|
||||
max = std::min(rate/2., pow(10, xmax*d+lmin));
|
||||
// Enforce vertical zoom limits
|
||||
// done in the linear freq domain for now, but not too far out
|
||||
if(max < min + minBins * binSize)
|
||||
max = min + minBins * binSize;
|
||||
if(max > rate/2.) {
|
||||
max = rate/2.;
|
||||
min = max - minBins * binSize;
|
||||
}
|
||||
// Zoom in centered on cursor
|
||||
float p1;
|
||||
if (min < -1.0 || max > 1.0) {
|
||||
min = -1.0;
|
||||
max = 1.0;
|
||||
}
|
||||
else {
|
||||
// Zoom in centered on cursor
|
||||
if (min < -1.0 || max > 1.0) {
|
||||
min = -1.0;
|
||||
max = 1.0;
|
||||
}
|
||||
else {
|
||||
c = 0.5*(min+max);
|
||||
// Enforce maximum vertical zoom
|
||||
l = std::max( ZOOMLIMIT, (c - min));
|
||||
c = 0.5*(min + max);
|
||||
// Enforce maximum vertical zoom
|
||||
l = std::max(ZOOMLIMIT, (c - min));
|
||||
|
||||
p1 = (mZoomStart - ypos) / (float)height;
|
||||
c = (max * (1.0-p1) + min * p1);
|
||||
min = c - 0.5*l;
|
||||
max = c + 0.5*l;
|
||||
}
|
||||
p1 = (mZoomStart - ypos) / (float)height;
|
||||
c = (max * (1.0 - p1) + min * p1);
|
||||
min = c - 0.5*l;
|
||||
max = c + 0.5*l;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (spectrumLinear) {
|
||||
SpectrogramSettings &settings = track->GetSpectrogramSettings();
|
||||
settings.SetMinFreq(min);
|
||||
settings.SetMaxFreq(max);
|
||||
if (partner) {
|
||||
// To do: share memory with reference counting?
|
||||
SpectrogramSettings &settings = partner->GetSpectrogramSettings();
|
||||
if (spectral) {
|
||||
if (spectrumLinear) {
|
||||
SpectrogramSettings &settings = track->GetSpectrogramSettings();
|
||||
settings.SetMinFreq(min);
|
||||
settings.SetMaxFreq(max);
|
||||
if (partner) {
|
||||
// To do: share memory with reference counting?
|
||||
SpectrogramSettings &settings = partner->GetSpectrogramSettings();
|
||||
settings.SetMinFreq(min);
|
||||
settings.SetMaxFreq(max);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(spectrumLog) {
|
||||
SpectrogramSettings &settings = track->GetSpectrogramSettings();
|
||||
settings.SetLogMinFreq(min);
|
||||
settings.SetLogMaxFreq(max);
|
||||
if (partner) {
|
||||
// To do: share memory with reference counting?
|
||||
SpectrogramSettings &settings = partner->GetSpectrogramSettings();
|
||||
else {
|
||||
SpectrogramSettings &settings = track->GetSpectrogramSettings();
|
||||
settings.SetLogMinFreq(min);
|
||||
settings.SetLogMaxFreq(max);
|
||||
if (partner) {
|
||||
// To do: share memory with reference counting?
|
||||
SpectrogramSettings &settings = partner->GetSpectrogramSettings();
|
||||
settings.SetLogMinFreq(min);
|
||||
settings.SetLogMaxFreq(max);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user