Proposal TrackPanel Evolution
|Proposal pages help us get from feature requests into actual plans. This proposal page is about a radical change to the TrackPanel.|
Proposal pages are used on an ongoing basis by the Audacity development team and are open to edits from visitors to the wiki. They are a good way to get community feedback on a proposal.
- Note: Proposals for Google Summer of Code projects are significantly different in structure, are submitted via Google's web app and may or may not have a corresponding proposal page.
This proposal is a bit different to most proposals. The intent is to find an evolutionary path to a major reworking of the TrackPanel. The proposal is mostly about doing these steps in a non-destructive way - that is not destructive to the work to reach 2.0 - rather than details of exactly how Audacity will behave with the new panel.
Should be started this year (2011). Time to complete years, if ever, since there are research projects in there. However, from start of coding to something that is actually useful to some people should be less than four months elapsed time. It's possible to break the log-jam that TrackPanel is causing in about one year of coding.
Some Changes we Want
Lots and lots of upgrades to tracks, that would overload the current track panel.
- API: for registering a track type. This will allow new track types to arrive as plug-ins.
- MIDI tracks: based initially on Roger's code, recast as a plug-in.
- Diff track: see Proposal Audio Diff, initially just the display side of this.
- Source separation Track: see Proposal Source Separation, initially just the display side of this and a Lo-pass/Hi-pass filter pair.
- Automation Tracks: used for example to control echo delay or a panning that varies with time.
- Computed Data: show a graph that is calculated in some way, rather than being stored.
- Multiple channels and modes: on the same track. For example show spectrum view and waveform view of the same mono audio in the one track - or show tracks for surround sound.
- Overlays: ability to show labels on top of a waveform, or add a draggable 'threshold' marker to a track.
- Themability: see Proposal New Skins.
- Discontinuous Selections: for Proposal Select Then Act.
- Fixed Cursor, Moving Wave: a mode, mostly for playback, where the cursor stays fixed, that can make editing easier.
- Antigrain/Cairo Rendering: sub-pixel resolution and antialiasing waveform repaint - more modern look.
Steps to Get There
- Rather than risk hard-won stability of the existing code, create a new plug-in with an alternative TrackPanel. Initially it will only be invoked for special purposes, such as MIDI or diff.
- General plug-in preparation, removing cleanspeech (or making it a plug-in), moving mixer panel to a plug-in, adding hooks into preferences to show available dlls and the plug-ins they contain. Reorganizing menu so that menu items are registered with a central menu manager, rather than all being coded in one place.
- Use lightweight widgets and create lightweight sizers. Current TrackPanel layout is tangled due to using constants for positioning and putting too much of the painting/hit-testing code into one class - rather than a class for each widget.
- The modified display will need more complex caching and partial recalculation to avoid full repaints. The code to do this will use a dependency graph, and step through that graph to work out what to update.
- Classes will be more fragmented.
- We will have caching classes, mostly using a random-drop cache which behaves well even in worst case situations.
- We will have separate classes for keeping track of data from those used to draw it. This will allow us to attach different rendering code to the same data without having two copies of the data.
- Code written rather like an extension of wxWidgets. I.e. the code for positioning tracks and info panels and so on is using a sizer based mechanism. It is oblivious of what is in the tracks and panels it positions.
- More information in effects.
- Rather than custom code for syncing labels, have a central mechanism that describes any time-warping by an effect. The label syncing is one client of this code.
These may or may not happen, they are just current thinking
- Dragging and stretching, of the time track, the labels, the clips, will be put 'on the same footing'. The intent is to use closely related code, and closely related visuals. Stretching a clip will offer you the option to use the change-tempo effect to lock-in the change.
- Causing clips to overlap will be corrected by Audacity automatically adding an extra track to take the overlapped clip.
- Sync-lock grouped tracks will be shown with no space between them.
Create a branch of Audacity.
- Initially an SVN branch, because main repository is SVN and we're better off all on just one type of version control.
- Plan to later move to a Mercurial branch, because eventually we can host that on Google code. (Mercurial is supported under Windows by TortoiseHg, whereas Git is aimed at Linux, so Hg in preference to Git).
- OR don't branch, and just be very careful that the new code is all in a plug-in 'mod-track-panel' with minimal safe #ifdeffed change to the core of Audacity to allow it to hook in.
- James Crook
- Vaughan Johnson
- Leland Lucius
Summary of Current State
- SVN now has mod-null, mod-nyq-bench, mod-script-pipe and mod-track-panel projects under the lib-src subdirectory. The ability to patch into Audacity from a plug-in with minimal disturbance to the core Audacity code is established.
- Experiments have been done, but not checked in, with using antigrain to allow continuous zoom of the ruler rather than only zooming in steps.
- Experiments with a more generic drawing framework have highlighted a problem that comes with it - that the generic code uses void* pointers, to avoid a lot of repetitive code - with the downside that the debugger then does not know what it is dealing with. That's too important an issue for maintainability. The critical issue is in an application created stack object. Whilst it leads to small efficiency loss, a stack of pointers to objects rather than a stack of objects could be used. The speed loss is minuscule if we make leaf routines process lists rather than individual items.