|Proposal pages help us get from feature requests into actual plans. This proposal page is about a 'Domain Object Model' for Audacity.|
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.
Analogous to the DOM for web pages, a tree like structure that 'holds' the data for Audacity.
- A facade class in Audacity, called AudacityDom that presents the underlying data.
- AudacityDom can be queried and modify:
- Envelope Points
- Audio Data
- Toolbar Layout
- Preference Settings
There is an interface to the Dom, that allows selection and modification of elements textually. This is for connecting to automation.
The DOM is abstract and non constraining, in the same way that a web page DOM is. For example tracks can contain other tracks, and clips can contain labels, even though Audacity currently does not support that. This is for
- Simplicity - no, or very few, special cases
- Future Proofing - we will want a tree of tracks, submixes and similar in future versions of Audacity.
What is a Facade?
A 'facade' is a piece of code in front of other code that makes it 'look' different. So for example, SQLite is a database engine that is in terms of tables and queries. Our blockfile system is in terms of joining and splitting blocks, and their underlying files. Either could form the basis for Audacity. The audio processing parts of Audacity need to 'see' the file or database facilities as facilities for dealing with sequences of audio samples. One approach is to have a 'facade' in front of the data back-end that makes SQLite or blockfiles look like a system for dealing with audio samples.
- The facade allows us to code the 'upper' parts of Audacity to a specific API suited for the audio task.
- The facade has functions like 'getAudioData()'.
- The facade hides the details of how the data is stored.
- The facade allows us to either have blockfiles or to have SQLite managing the data without changing the 'upper' parts of the code in Audacity.
Usually a facade involves a lot of functions that forward data to the functions that do the work. It allows you to create a 'clean' interface to a messy system. It lets you use the same interface with two or more different systems behind it.
What is a DOM?
A 'DOM' or 'Domain Object Model' describes the structure of data. The term is particularly applied to web pages, where code can 'walk around on a web page, changing styles in a systematic way'. A web page has a hierarchical structure, and queries to the DOM let you select, say, all text that is inside any tips-and-tricks box.
This 'AudacityDom' proposal draws an analogy between the user interface that Audacity has and the structure of a web page. Web page DOMs have a well worked out and uniform way of moving around them. That way of moving around and manipulating the data could be applicable to Audacity too. The main immediate benefit is that it gives an interface for external script that works with audacity data to query and change that data.
The details of this proposal show:
- How the concepts of a DOM are applicable to Audacity.
- How we could introduce a DOM and gradually transition to supporting other back-ends.
- Future features. Submixes and submixes with special properties, such as an auto-duck group.
- Progress towards Unitary Project format, since this could be the facade class behind which the project format sits.
Analogous to HTML DOMs with JQuery, we can 'select' in the DOM and then modify. For example,
Select all clips contained in a certain track, and modify their colour property. Select all first clips with a certain class of track as a parent, and fade in by 1 second.
Analogous to HTML DOMS the AudacityDom has Type, Class and Id.
|Field||Required?||HTML Dom||Audacity Dom|
|Type||YES!||e.g. Div, Span, H1||e.g. Track, Clip, Envelope, Label|
|Class||Optional||e.g. alert-box||e.g. green-label, stereo, mono, channel|
|Id||Optional||e.g. intro||e.g. the name of a track|
The point of adopting this system is that the navigation in the hierarchy is then very uniform. We can 'walk' the tree with one set of primitives. We can walk purely numerically (up/down,next/previous, item[n]). Borrowing the 'Class' concept from HTML allows us to subclass to repurpose a 'higher level' class.
<Track class="stereo" id="Sonata"> <Track class="channel" pan="0.0"> track data </Track> <Track class="channel" pan="1.0"> track data </Track> </Track>
Here (above) a stereo Track is behaving as a container for two channels.
Fundamental DOM methods
Navigation: getNumChildren() getFirstChild() getNextSibling() getPreviousSibling() getParent() findNext( sParamName, vValue ) Getters/Setters: hasParameter( sParameter ) getParameter( sParamName ) setParameter( sParamName, vValue ) getFirstParameter() getNextParameter() Structure Munging: insertElement( elt ) deleteElement( elt ) Accelerated Access: * getFastDataPointer( &Accessor ) * setFastData( Accessor.Mods( start, end) )
The functions marked * in this list are down in the bulk data.
- In HTML they would get the text on the page between tags.
- In AudacityDom, they are for the audio sample sequence data, which there is a lot of.
It is possible to regard the sequence data as if it were itself 'tagified', as a large number of items <sample value="0.79"/> and so on. Or as <block>s that in turn contain samples. This is inefficient, hence the provision of Accelerated Access. The acceleration is not part of the abstract model, and I am still working it out so it is likely to change a bit as the code develops!
HTML does things in a similar way. The tags are used only for meta data (mark up and formatting). The word 'The' on a web page could be done as <letter char="T"/><letter char="h"><letter char="e"> but is actually done without tags.
- Initially the facade will live 'above' AudacityProject.
- It is only for Automation.
- Requests to the facade to read or write data will be translated into requests to AudacityProject, by private code inside the facade class.
- Later we provide a binary interface, AudacityDomBinary, that allows getting/setting values using binary values, e.g. floats.
- The binary interface initially lives above the textual AudacityDom.
- AudacityDomBinary is auto-generated.
- It is generated off the combination of the DOM model and the specific queries we decide to support.
- By making a binary version of the DOM, we can bypass the textual AudacityDom, and so not pay the price of converting to/from binary.
- We recode the user interface to use AudacityDomBinary.
- AudacityDomBinary being auto-generated allows us to target alternative back ends for the DOM.
- Initially .aup file and .au blockfiles and audacity.cfg are the back end.
- Later we support SQLite as a back end
- Later we might support Blender DNA and Git-Plumbing as backends.
- We do NOT provide a direct translation of CSS. Instead styling is done by code. We WILL later provide a style in dom format, so that it can be inspected and modified via the dom interface.