Jokosher Hackers Guide

This guide needs to be an evolving document that is current and useful for new developers. If you spot something wrong or outdated, or can elaborate on some of the concepts here, please update it. Thanks.

Well, well, well, if you are reading this there is every likely-hood that you want to hack on Jokosher. If this is the case, welcome to the Jokosher community, and pat yourself of the back for taking an interest in hacking on an important and interesting Open Source project.

The aim of this guide is to provide a simple overview of how to get involved, where to get started and how the code works. Hopefully, if everyone has been good, this guide should be fairly up to date and reflect the current codebase. If not, find the person who wrote the code that is not mentioned here, and give them a swift kick in the spuds. Job done.

Getting Started

OK, lets get cracking...

Can I hack on Jokosher?

To hack on Jokosher you will need a few core skills:

  • Python - how to write Python code
  • GTK+ - knowledge and experience of writing GTK applications, and how to use Glade
  • GStreamer - the GStreamer multimedia framework, which Jokosher is based upon

Now, if you don't have these skills, or have some of them but are lacking some, fear not. Start reading some of the documentation online for the different elements above and feel free to ask us for help where needed. This is particularly understandable for GStreamer and GTK+.

Getting up and running

To hack on Jokosher you will need to have a checkout of the Subversion source code, and you will need some key bits and pieces installed. See GettingJokosher for details about this. You will also need to install the CVS version of GStreamer as we require some bugfixes that are only in CVS at the present time. This may well have changed and this guide may be out of date, so do ask us if you are unsure. For more details about installing GStreamer, see InstallingCVSGstreamer.

Communication is important, and it is essential to stay in touch with whats going on the Jokosher community. This is important (a) to know what is going on, and (b) to ensure you don't hack on something that someone else may be hacking on.

The Jokosher community primarily communicate via two core resources:

  • IRC - most of the developers use IRC to talk about development and discuss solutions to problems. The place to be is #jokosher on irc.eu.freenode.net.
  • The mailing list - head over to the mailman page to join the mailing list. That page also has a link to the archives.

Much of the discussion tends to occur on IRC, although the mailing list is used for more complex and far-reaching discussions.

Contributing code and patches

When you have got the hang of the code and want to contribute something, first send us a few patches. Before we dish out Subversion accounts we prefer to accept a few patches, review them, and submit them if they are suitable. We are not overly fussy about this, but when patches are reviewed it can help point out common problems and tips.

To submit a patch, code your hack against the latest revision of Jokosher in Subversion, and send it to the Jokosher mailing list, preferably with [PATCH] in the title. Some developers use [PATCH] in their mail clients as a filter to dig out patches. When you send your patch, be sure to attach it and don't just cut and paste it. Also, in your message indicate which revision of Jokosher the patch was coded against, and any notes about what you have done. If all goes well. your patch will be committed. Thanks!

The Code

Jokosher is a fairly modular application, and the code is split into a number of different conceptual areas. These are the different areas:

  • Jokosher - (Jokosher class) - Jokosher itself is the application. The Jokosher class fires up much of the main window GUI and gets everything up and running.
  • Project (Project class) - the project is exactly what you imagine it is - it is a composition. The project keeps track of many of the other elements in the code.
  • Instruments (Instrument and InstrumentViewer classes) - each track that can be added to a project is called an instrument. The Instrument class deals with the instrument data, and the InstrumentViewer class is the visual representation of it.
  • Events (Event, EventViewer and EventLaneViewer classes) - events are the sound clips that live inside instrument tracks. So, when you import or record a piece of audio on an instrument, that piece of audio is an event. The Event class contains event data, the EventViewer class is its visual appearence (such as the waveform), and the EventLaneViewer is the visual container that the event appears in.

In Jokosher we also have two main views - the Recording and Mix views. Jokosher has been designed with ease of use in mind, and we have avoided the nightmare of overlapping windows. As such, in the top right hand corner of Jokosher, you can see two big buttons for switching between these different views. Naturally, these have their own classes:

  • RecordingView - inside the recording view, only the instruments are displayed. This is where the user will spend most of their time recording, editing and re-recording. Many of the above classes are used to display these instruments.
  • CompactMixView - this is the main mixing view. Please note that the DetailedMixView which is still in the code is no longer used. After some design considerations, we decided to use a single view instead of seperate Compact and Detailed mix views. As such, always hack on CompactMixView. This view displays some very small instrument tracks as well as mixing sliders for adjusting instrument volume levels. These volume sliders are in the MixerStrip and VUWidget classes. The MixerStrip essentially embeds a VUWidget into it.

In addition to these classes, there a bunch of other classes for dialog boxes and suchlike:

  • AddInstrumentDialog - this is the dialog box you see when you add an instrument. This dialog is populated with instruments that are read in from the instrument configuration files (*.instr). See 'Instruments in Jokosher' below for more details.
  • AlsaDevices - this class contains a helper method for finding Alsa devices using HAL.
  • NewProjectDialog - this dialog is used to create a new project. When a project is created, an 'audio' directory is created inside inside the specified project directory, and a configuration file is generated. See 'The Jokosher File Format' below.
  • WelcomeDialog - the dialog that appears when you start Jokosher, which allows the user to create a new project, open a project, change preferences, and shows a list of recent projects.

Other key classes:

  • Globals - this class contains some methods for reading and writing global configuration data. These generic application wide settings are stored in three dictionaries in Globals - general, recording and playback. These dictionaries are references in other parts of the code.
  • Monitored - this class implements a listener framework that makes updating different bits of the GUI simple. See 'Jokosher Listeners' below.
  • CommandManaged - along with other classes in CommandManager.py, it intercepts function calls to any class which interits the class, and logs the action performed to the undo stack where appropriate.

Instruments in Jokosher

Instruments are a key concept in Jokosher, and we want people to think in Instruments instead of Tracks. Instrument information lives in a series of .instr instrument files inside the instruments/ sub-directory. Currently, instrument configuration files are very simple - they just contain the name and icon of the instrument. In the future we plan on storing audio settings in these configuration files. As an example, it would be great that when you use a Snare drum for example, the EQ is optimised for that Snare drum.

The .instr files are read in AddInstrumentDialog.

Jokosher Listeners

One of the difficult tasks involved in writing a large application is updating different bits of program when a particular event happens. As an example, when you record a sound clip, you need to update some internal data structures, generate a waveform and update the recording and mixing views.

To do this, each class inherits the Monitored class that creates a listener system. The basic way that this works is that when the StateChanged() method is called (such as self.StateChanged()), each of the different parts of the application that have listeners will update.

The Jokosher File Format

See JokosherFileFormat.

Debugging Jokosher

When you are hacking on Jokosher, it is always useful to get accurate debugging information. There a few methods that you can achieve this, but often it depends on what exactly you are debugging. There are few techniques outlines here that you may find useful.

Debugging GStreamer

GStreamer has a rather useful debugging engine built into it. With it you can see detailed logs of how GStreamer constructs pipelines. To enable it, you need to set the GST_DEBUG_NO_COLOR and GST_DEBUG environmental variables. You can do this when you run Jokosher, and put the output into a log file:

GST_DEBUG_NO_COLOR=1 GST_DEBUG=3,python:5,gnl*:5 ./Jokosher.py > log 2>&1

You can then use grep to search for things.

Another useful tip is to use Globals.debug() to add debug messages in the code:

Globals.debug("Something happens here")

If you run ./Jokosher -d, all the debug output is send to the terminal. If you run ./Jokosher -g, all the debug output is sent to the gstreamer log. When you generate the log file, the message appear at the relavent points. You can pick these out easily with grep by searching for 'python'.

Debugging Jokosher

You can also use the JokDebug? class included with Jokosher to switch on some debugging methods that we have created. These methods display current pipelines and other useful information. To do this, you need to set a JOKOSHER_DEBUG environmental variable to 1. For most people this is:

export JOKOSHER_DEBUG=1

Inside the code there are debugging blocks, but they may have been removed for release. Add a debugging block such as this:

# [DEBUG]
# This debug block will be removed when we release. If you see this in a release version, we
# obviously suck. Please email us and tell us about how shit we are.
try:
    if os.environ['JOKOSHER_DEBUG']:
	print "Play Pipeline:"
	self.debug.ShowPipelineTree(self.mainpipeline)
    except:
	pass
# [/DEBUG]

Make sure you import JokDebug?.py.