mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-15 15:49:36 +02:00
Keep a constant set of gain/pan sliders -- this allows Audacity
to open projects with very large numbers of tracks without crashes (Windows) or major slowdows.
This commit is contained in:
parent
828481a3c8
commit
db39f6262b
@ -157,6 +157,7 @@ is time to refresh some aspect of the screen.
|
|||||||
#include "TrackPanel.h"
|
#include "TrackPanel.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
//#define DEBUG_DRAW_TIMING 1
|
//#define DEBUG_DRAW_TIMING 1
|
||||||
|
|
||||||
@ -1276,6 +1277,9 @@ void TrackPanel::OnPaint(wxPaintEvent & /* event */)
|
|||||||
// (See TrackPanel::Refresh())
|
// (See TrackPanel::Refresh())
|
||||||
if( mRefreshBacking || ( box == GetRect() ) )
|
if( mRefreshBacking || ( box == GetRect() ) )
|
||||||
{
|
{
|
||||||
|
// Update visible sliders
|
||||||
|
mTrackInfo.UpdateSliderOffset(mViewInfo->track);
|
||||||
|
|
||||||
// Reset (should a mutex be used???)
|
// Reset (should a mutex be used???)
|
||||||
mRefreshBacking = false;
|
mRefreshBacking = false;
|
||||||
|
|
||||||
@ -3622,9 +3626,9 @@ void TrackPanel::HandleSliders(wxMouseEvent &event, bool pan)
|
|||||||
LWSlider *slider;
|
LWSlider *slider;
|
||||||
|
|
||||||
if (pan)
|
if (pan)
|
||||||
slider = mTrackInfo.mPans[mCapturedTrack->GetIndex()];
|
slider = mTrackInfo.PanSlider(mCapturedTrack->GetIndex());
|
||||||
else
|
else
|
||||||
slider = mTrackInfo.mGains[mCapturedTrack->GetIndex()];
|
slider = mTrackInfo.GainSlider(mCapturedTrack->GetIndex());
|
||||||
|
|
||||||
slider->OnMouseEvent(event);
|
slider->OnMouseEvent(event);
|
||||||
|
|
||||||
@ -5988,7 +5992,7 @@ void TrackPanel::OnTrackPan()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LWSlider *slider = mTrackInfo.mPans[t->GetIndex()];
|
LWSlider *slider = mTrackInfo.PanSlider(t->GetIndex());
|
||||||
if (slider->ShowDialog()) {
|
if (slider->ShowDialog()) {
|
||||||
SetTrackPan(t, slider);
|
SetTrackPan(t, slider);
|
||||||
}
|
}
|
||||||
@ -6001,7 +6005,7 @@ void TrackPanel::OnTrackPanLeft()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LWSlider *slider = mTrackInfo.mPans[t->GetIndex()];
|
LWSlider *slider = mTrackInfo.PanSlider(t->GetIndex());
|
||||||
slider->Decrease(1);
|
slider->Decrease(1);
|
||||||
SetTrackPan(t, slider);
|
SetTrackPan(t, slider);
|
||||||
}
|
}
|
||||||
@ -6013,7 +6017,7 @@ void TrackPanel::OnTrackPanRight()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LWSlider *slider = mTrackInfo.mPans[t->GetIndex()];
|
LWSlider *slider = mTrackInfo.PanSlider(t->GetIndex());
|
||||||
slider->Increase(1);
|
slider->Increase(1);
|
||||||
SetTrackPan(t, slider);
|
SetTrackPan(t, slider);
|
||||||
}
|
}
|
||||||
@ -6040,7 +6044,7 @@ void TrackPanel::OnTrackGain()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LWSlider *slider = mTrackInfo.mGains[t->GetIndex()];
|
LWSlider *slider = mTrackInfo.GainSlider(t->GetIndex());
|
||||||
if (slider->ShowDialog()) {
|
if (slider->ShowDialog()) {
|
||||||
SetTrackGain(t, slider);
|
SetTrackGain(t, slider);
|
||||||
}
|
}
|
||||||
@ -6053,7 +6057,7 @@ void TrackPanel::OnTrackGainInc()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LWSlider *slider = mTrackInfo.mGains[t->GetIndex()];
|
LWSlider *slider = mTrackInfo.GainSlider(t->GetIndex());
|
||||||
slider->Increase(1);
|
slider->Increase(1);
|
||||||
SetTrackGain(t, slider);
|
SetTrackGain(t, slider);
|
||||||
}
|
}
|
||||||
@ -6065,7 +6069,7 @@ void TrackPanel::OnTrackGainDec()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LWSlider *slider = mTrackInfo.mGains[t->GetIndex()];
|
LWSlider *slider = mTrackInfo.GainSlider(t->GetIndex());
|
||||||
slider->Decrease(1);
|
slider->Decrease(1);
|
||||||
SetTrackGain(t, slider);
|
SetTrackGain(t, slider);
|
||||||
}
|
}
|
||||||
@ -7139,13 +7143,14 @@ void TrackPanel::OnKillFocus(wxFocusEvent & event)
|
|||||||
|
|
||||||
TrackInfo::TrackInfo(wxWindow * pParentIn)
|
TrackInfo::TrackInfo(wxWindow * pParentIn)
|
||||||
{
|
{
|
||||||
//To prevent flicker, we create an initial set of 16 sliders
|
|
||||||
//which won't ever be shown.
|
|
||||||
pParent = pParentIn;
|
pParent = pParentIn;
|
||||||
int i;
|
|
||||||
for (i = 0; i < 16; i++) {
|
// Populate sliders array
|
||||||
|
for (unsigned int i = 0; i < kInitialSliders; ++i) {
|
||||||
MakeMoreSliders();
|
MakeMoreSliders();
|
||||||
}
|
}
|
||||||
|
mSliderOffset = 0;
|
||||||
|
|
||||||
int fontSize = 10;
|
int fontSize = 10;
|
||||||
mFont.Create(fontSize, wxSWISS, wxNORMAL, wxNORMAL);
|
mFont.Create(fontSize, wxSWISS, wxNORMAL, wxNORMAL);
|
||||||
@ -7500,10 +7505,12 @@ void TrackInfo::MakeMoreSliders()
|
|||||||
mPans.Add(slider);
|
mPans.Add(slider);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This covers the case where kInitialSliders - kSliderPageFlip is not big
|
||||||
|
// enough
|
||||||
void TrackInfo::EnsureSufficientSliders(int index)
|
void TrackInfo::EnsureSufficientSliders(int index)
|
||||||
{
|
{
|
||||||
while (mGains.Count() < (unsigned int)index+1 ||
|
while (mGains.Count() < (unsigned int)index - mSliderOffset + 1 ||
|
||||||
mPans.Count() < (unsigned int)index+1)
|
mPans.Count() < (unsigned int)index - mSliderOffset + 1)
|
||||||
MakeMoreSliders();
|
MakeMoreSliders();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7519,18 +7526,113 @@ void TrackInfo::DrawSliders(wxDC *dc, WaveTrack *t, wxRect r)
|
|||||||
GetPanRect(r, panRect);
|
GetPanRect(r, panRect);
|
||||||
|
|
||||||
if (gainRect.y + gainRect.height < r.y + r.height - 19) {
|
if (gainRect.y + gainRect.height < r.y + r.height - 19) {
|
||||||
mGains[index]->Move(wxPoint(gainRect.x, gainRect.y));
|
GainSlider(index)->Move(wxPoint(gainRect.x, gainRect.y));
|
||||||
mGains[index]->Set(t->GetGain());
|
GainSlider(index)->Set(t->GetGain());
|
||||||
mGains[index]->OnPaint(*dc, t->GetSelected());
|
GainSlider(index)->OnPaint(*dc, t->GetSelected());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (panRect.y + panRect.height < r.y + r.height - 19) {
|
if (panRect.y + panRect.height < r.y + r.height - 19) {
|
||||||
mPans[index]->Move(wxPoint(panRect.x, panRect.y));
|
PanSlider(index)->Move(wxPoint(panRect.x, panRect.y));
|
||||||
mPans[index]->Set(t->GetPan());
|
PanSlider(index)->Set(t->GetPan());
|
||||||
mPans[index]->OnPaint(*dc, t->GetSelected());
|
PanSlider(index)->OnPaint(*dc, t->GetSelected());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TrackInfo::UpdateSliderOffset(Track *t)
|
||||||
|
{
|
||||||
|
if (!t)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Ensure that the specified track is: (a) at least the second track in the
|
||||||
|
// arrays (if it's the second track in a stereo pair the first must be in);
|
||||||
|
// (b) no farther in than kSliderPageFlip
|
||||||
|
int newSliderOffset = (int)mSliderOffset;
|
||||||
|
if ((unsigned int)t->GetIndex() < mSliderOffset + 1 ||
|
||||||
|
(unsigned int)t->GetIndex() > mSliderOffset + kSliderPageFlip) {
|
||||||
|
newSliderOffset = t->GetIndex() - (int)kSliderPageFlip / 2;
|
||||||
|
}
|
||||||
|
// Slider offset can't be negative
|
||||||
|
if (newSliderOffset < 0) newSliderOffset = 0;
|
||||||
|
|
||||||
|
// Rotate the array values if necessary
|
||||||
|
int delta = newSliderOffset - (int)mSliderOffset;
|
||||||
|
|
||||||
|
// If the rotation is greater than the array size, none of the old values
|
||||||
|
// are preserved, so don't bother rotating.
|
||||||
|
if (abs(delta) >= (int)mGains.Count())
|
||||||
|
delta = 0;
|
||||||
|
|
||||||
|
if (delta > 0) {
|
||||||
|
// Circularly shift values down in the arrays (temp arrays needed to
|
||||||
|
// avoid reading written-over values)
|
||||||
|
LWSliderArray tempGains;
|
||||||
|
LWSliderArray tempPans;
|
||||||
|
tempGains.SetCount(delta);
|
||||||
|
tempPans.SetCount(delta);
|
||||||
|
|
||||||
|
for (int i = 0; i < (int)mGains.Count(); ++i) {
|
||||||
|
int src = (i + delta) % (int)mGains.Count();
|
||||||
|
if (src < 0) src += (int)mGains.Count();
|
||||||
|
|
||||||
|
if (i < delta) {
|
||||||
|
// Save a copy of the first `delta` values
|
||||||
|
tempGains[i] = mGains[i];
|
||||||
|
tempPans[i] = mPans[i];
|
||||||
|
}
|
||||||
|
if (src >= delta) {
|
||||||
|
// These values have not been overwritten
|
||||||
|
mGains[i] = mGains[src];
|
||||||
|
mPans[i] = mPans[src];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// These ones have
|
||||||
|
mGains[i] = tempGains[src];
|
||||||
|
mPans[i] = tempPans[src];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (delta < 0) {
|
||||||
|
// Circularly shift values up in the arrays
|
||||||
|
LWSliderArray tempGains;
|
||||||
|
LWSliderArray tempPans;
|
||||||
|
tempGains.SetCount(mGains.Count());
|
||||||
|
tempPans.SetCount(mPans.Count());
|
||||||
|
|
||||||
|
// Iterating backwards to do this
|
||||||
|
for (int i = mGains.Count() - 1; i >= 0; --i) {
|
||||||
|
int src = (i + delta) % (int)mGains.Count();
|
||||||
|
if (src < 0) src += (int)mGains.Count();
|
||||||
|
|
||||||
|
if (i >= (int)mGains.Count() + delta) {
|
||||||
|
// Save a copy of the last `delta` values
|
||||||
|
tempGains[i] = mGains[i];
|
||||||
|
tempPans[i] = mPans[i];
|
||||||
|
}
|
||||||
|
if (src < (int)mGains.Count() + delta) {
|
||||||
|
// These values have not been overwritten
|
||||||
|
mGains[i] = mGains[src];
|
||||||
|
mPans[i] = mPans[src];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// These ones have
|
||||||
|
mGains[i] = tempGains[src];
|
||||||
|
mPans[i] = tempPans[src];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mSliderOffset = newSliderOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
LWSlider * TrackInfo::GainSlider(int trackIndex)
|
||||||
|
{
|
||||||
|
return mGains[trackIndex - mSliderOffset];
|
||||||
|
}
|
||||||
|
|
||||||
|
LWSlider * TrackInfo::PanSlider(int trackIndex)
|
||||||
|
{
|
||||||
|
return mPans[trackIndex - mSliderOffset];
|
||||||
|
}
|
||||||
|
|
||||||
// Indentation settings for Vim and Emacs and unique identifier for Arch, a
|
// Indentation settings for Vim and Emacs and unique identifier for Arch, a
|
||||||
// version control system. Please do not modify past this point.
|
// version control system. Please do not modify past this point.
|
||||||
|
@ -11,11 +11,11 @@
|
|||||||
#ifndef __AUDACITY_TRACK_PANEL__
|
#ifndef __AUDACITY_TRACK_PANEL__
|
||||||
#define __AUDACITY_TRACK_PANEL__
|
#define __AUDACITY_TRACK_PANEL__
|
||||||
|
|
||||||
|
#include <wx/dcmemory.h>
|
||||||
#include <wx/dynarray.h>
|
#include <wx/dynarray.h>
|
||||||
|
#include <wx/panel.h>
|
||||||
#include <wx/timer.h>
|
#include <wx/timer.h>
|
||||||
#include <wx/window.h>
|
#include <wx/window.h>
|
||||||
#include <wx/panel.h>
|
|
||||||
#include <wx/dcmemory.h>
|
|
||||||
|
|
||||||
//Stm: The following included because of the sampleCount struct.
|
//Stm: The following included because of the sampleCount struct.
|
||||||
#include "Sequence.h"
|
#include "Sequence.h"
|
||||||
@ -80,6 +80,16 @@ class AUDACITY_DLL_API TrackPanelListener {
|
|||||||
virtual void TP_HandleResize() = 0;
|
virtual void TP_HandleResize() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// TrackInfo sliders: we keep a constant number of sliders, and attach them to
|
||||||
|
// tracks as they come on screen (this helps deal with very large numbers of
|
||||||
|
// tracks, esp. on MSW).
|
||||||
|
//
|
||||||
|
|
||||||
|
const unsigned int kInitialSliders = 100;
|
||||||
|
// kInitialSliders-kSliderPageFlipshould be around the most tracks you could
|
||||||
|
// ever fit vertically on the screen (but if more fit on that's OK too)
|
||||||
|
const unsigned int kSliderPageFlip = 80;
|
||||||
|
|
||||||
class TrackInfo
|
class TrackInfo
|
||||||
{
|
{
|
||||||
@ -89,6 +99,8 @@ public:
|
|||||||
|
|
||||||
int GetTitleWidth() const;
|
int GetTitleWidth() const;
|
||||||
|
|
||||||
|
void UpdateSliderOffset(Track *t);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void MakeMoreSliders();
|
void MakeMoreSliders();
|
||||||
void EnsureSufficientSliders(int index);
|
void EnsureSufficientSliders(int index);
|
||||||
@ -111,9 +123,19 @@ private:
|
|||||||
void GetPanRect(const wxRect r, wxRect &dest) const;
|
void GetPanRect(const wxRect r, wxRect &dest) const;
|
||||||
void GetMinimizeRect(const wxRect r, wxRect &dest, bool minimized) const;
|
void GetMinimizeRect(const wxRect r, wxRect &dest, bool minimized) const;
|
||||||
|
|
||||||
public:
|
// These arrays are always kept the same size.
|
||||||
LWSliderArray mGains;
|
LWSliderArray mGains;
|
||||||
LWSliderArray mPans;
|
LWSliderArray mPans;
|
||||||
|
|
||||||
|
// index of track whose pan/gain sliders are at index 0 in the above arrays
|
||||||
|
unsigned int mSliderOffset;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Slider access by track index
|
||||||
|
LWSlider * GainSlider(int trackIndex);
|
||||||
|
LWSlider * PanSlider(int trackIndex);
|
||||||
|
|
||||||
wxWindow * pParent;
|
wxWindow * pParent;
|
||||||
wxFont mFont;
|
wxFont mFont;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user