Technical How To
Below you'll find some pointers to documentation related to technology we are using in buzztrax, along with open questions (TODOs).
- 1 General development style
- 2 Song persistence
- 3 Wavetable handling
- 4 Visualisations
- 5 Features
- 6 Extensions for GStreamer
- 7 Desktop integration
- 8 User Interface
- 9 Preferences/Setting
- 10 Using Python for the GUI
- 11 Gnome-vfs implementation
- 12 Cooperative editing
General development style
OO development in C
- read this gobject tutorial
- we still need to decide:
- should we use PIML (private implementation) in Objects or rely on a private section. Currently PIML works nicely.
- should we stick to use object properties, or may we define get-methods as shortcut. Currently we avoid get-methods
- try glib-bind for easier property management
- how to handle errors, assertions are not the right way to do this
- using errno functions
- use of the g_error framework
Embed metadata into buzztrax songs
- is dublin core metadata enough
- we need all the meta data, that we later need for e.g. mp3 tags
- is there something interesting among the links at ?
Store songs as zip archives
The plan is to store the song-data in xml format, but to include the digital audio data. That could be done storing a song as a zip archive, which contains all required files.
- Zlib already has some example code (see contrib/minizip).
- it would be nice if we could use gnome-vfs. This means orbit needs to be ported to win32 or gnome-vfs could do without it
- another alternative would be to use the code from libgsf
- this is what we are using now
One XML vs. Multiple XML files
- should we split the data into multiple XML files to differenciate between the needs of various applications
- song.xml: our current XML with setup, patterns, sequences, but without the meta-section
- meta.xml: the sonf metadata
- bt-edit.xml: layout of machines, zoom state (everything we store in properties hashmaps)
Instead of loading and saving like we now do, real serialisation would be better. Unfortunately GObject still lacks in a few places:
- One can't mark properties as volatile or not. That would allow only storing non-volatile properties.
- Things like GList are not GObjects. So, when a property contains a list, one can't find that out by pure introspection applies to GList,GSList,Hashmap,...).
For in-depth thoughts see gobject serialisation.
Wavetable for tracker-like generators
- build a wavetable gst-plugin
- it will have params like filename009
- for each param there will be an output port with the same number
- gst-bml plugin will provide an interface, which can be used to attach the wave-table
- tracker plugins can use that interface to access the wavetable and use gst_bin_iterate() to pull the data as needed
- todo: wave data should be static to all instances
- todo: can gst handle plugins that deliver a pad on request
Writing gstreamer mem-sink, mem-source plugins
- we need these plugins to load and save samples in any gst supported format.
- we need to find out how to use a gst-element that is not a plugin and not in the registry (internal element)
GStreamer has fakesink and fakesource elements and these should be close to what we need.
- this would allow to use a visualisation on separate wires
- we could reimplement a buzz-style analyzer as a gstreamer visualisation
Add visualisation machines
- new machine type (audio->video)
- add pure video(-player) machines as well
- add a video sink
- this would allow to time and arrange visualisation (live video clip?)
- multi channel audio - mono, stereo, quadro and more
- gain handling - changing volumes
- machine states - mute, solo, bypass
- video support - make it also a video-sequencer
Extensions for GStreamer
Add a new interface for instruments. This interface allows to query additional metadata about properties/dparams (?) and multiple voices. This way an application can find out about which param is a note (frequency params can be used to control an LFO too).
We don't need the GST_TYPE_IMPLEMENTS_INTERFACE, as a plugin is an instrumnet or not (its not dynamic).
Audiosinks already have properties like samplerate. Shouldn't they have optional properties like BPM and bars? An mp3-player could fetch this from the id3tags. A music application gets this from the score. Visualisation plugins could then better react to the music. Problem is: what happens, when we mix two mp3s (supposed we store the new properties in the sink as well).
- integration into gnome, kde, windows environments
- adding to application-menu (done)
- adding default icons+mime types (done)
- session management (gnome-session)
Generally we try to use standard widgets whenever we can. Honestly we do not like these skinned GUI so much. Knobs are not a good match for a mouse. Further, we are not graphical artists. On the other hand, gtk+ supports themes and as we use gtk widgets, the look can be 'tuned' by building a special theme for the application.
Canvas for Machine View
- which way can we draw the machine view
Pattern and Sequence Grid
see sequence and pattern widget page
look at acast sources for how to use with gst (src/gststuff.c/level_callback())
Use GConf if it is available
For platform that does not support gconf, we should provide a windows-registry and a plain-file (ini or xml -style) backend. To make this transparent we hide this in an own class-tree in libbt-core. The root class could define the config-keys as enums and we can have subclasses for GConf/WinReg/IniFile. We can choose the sub-class to use at configure time.
Second question is if it is not better to extract the settings code from bt-edit and make it a stand-alone app. E.g. bt-cmd will use some of these settings too. Problem is, how to integrate app-specific pages?
Using Python for the GUI
The idea is to develop the core lib in C or whatever and supply a python wrapper for it. The the GUI can be developed easier using python.
- garbage collector, no need to care about freeing references, ressources
- no gobject-management overhead
- plugins need to be written in python as well (e.g. loaders)
- Python tutorials: 1
- How to wrap GObjects for python? (look at pygtk or libxml)
The buzztrax file extention should be a new extention which should be registered on the gnome mime database. The extention could be .bzt.
If buzztrax opens a file with this extention we create an internal gnome-vfs uri. The buzztrax file is a tar.gz file which contains a predefined set of files. The main file inside the tar.gz archive is the song.xml file. From this file we can retrieve references to other files like waves and so on.
To open a file from a tar.gz archive with gnome-vfs we need a uri which handles zip archives.
To open the bzt file we create a gnome-vfs uri in following format:
For example if we get a file request in following format:
bt-cmd --info great-song.bzt
we have to ceate a internal uri in following format:
The creation of absolute paths for local filesystems is handled by gnome-vfs. You can have a look into our design study in cvs.
If we get a gnome-vfs uri like this:
bt-cmd --info http://buzztrax.org/songs/great-song.bzt
we have to create a internal uri like this:
We need to check first the given path, if this is a gnome-vfs uri. We have also create an absolute path from an relative path, if the given path is relative (currently shown in the design example in cvs). If the given uri is a gnome-vfs uri we have expand the uri with the #gzip:#tar:/song.xml prefix to get the song.xml file for loading.
Look at libobby (as well as gobby) and how it handles structured data. The idea behind the lib is to add a irc like pane to the editor and highlight changes + cursors via colors per user.