1. Summary
  2. Files
  3. Support
  4. Report Spam
  5. Create account
  6. Log in

Developers Guide

From canorus

Jump to: navigation, search

This is a document primarily meant for Canorus source code developers and explains Canorus primitives and score representation. It also gives you an idea of the common principles and solutions used for common problems when faced to Canorus source code.

Users should read Users guide instead.

Plugin developers should read Plugins.

Contents

Introduction

Canorus is a music score editor written in C++ and based on a Qt4 cross-platform library. It was founded and developed primarily by NoteEdit developers, so we could say that Canorus was actually an answer and a new challenge to create a better, cross-platform and open source music score editor - the composer's best friend.

License

Canorus is open source software licensed under GNU General Public License. Shipped libraries are licensed under the same license or other GPL-compatible licenses (like LGPL).

Development environment

  • Project language: C++
  • Primary GUI and core library: Qt4
  • Primary IDE: Eclipse
  • Primary MIDI library: RtMidi
  • Primary compiler: GNU gcc on POSIX systems and MinGW under Microsoft Windows
  • Build tools: CMake for cross-platform configuring and GNU Make for compilation
  • Scripting language: Python, Ruby

SVN

Canorus has a common source for all platforms in Berlios SVN tree. If you don't know what Subversion (SVN) is, read this. You can browse the source on-line here. Details how to checkout the source code can be found here.

Anonymous access is allowed for reading the source only. Registered developers to this project have write support to SVN as well.

Needed libraries

Debian-based Linux

To compile Canorus under Debian or Debian-based distributions (Ubuntu, Mepis, Knoppix etc.) the following packages should be installed:

$ sudo apt-get install libqt4-dev make cmake swig g++ gdb subversion python-dev ruby1.8-dev libasound2-dev

Mandriva-based Linux

To compile Canorus under Mandriva 2006 (older versions weren't tested) you to install a newer cmake version than the one include (recommended 2.4.3 from 2007 Beta). To do this add Mandriva 2007 as installation source and install it via

# urpmi cmake

If you don't wish to do update your system this way you can alternatively download cmake and compile it manually from the above page. Other required packages to compile Canorus are gcc-c++, libqt4-devel, subversion (to be installed like cmake). Recommanded packages for development are Eclipse (see below, included in Mandriva contrib), gdb, qt4-designer, qt4-assistant.

Microsoft Windows

Canorus was tested on x86 Microsoft Windows XP with SP2. 64-bit Windows and Vista should be supported as well but weren't tested yet.

In order to compile Canorus on Windows, you should first install the following prerequisites:

  1. Download and install cmake cross-platform make-file creator.
  2. Download and install MinGW prebuilt Qt4 for Windows. When asked for MinGW, select the installer should download the neccessary MinGW componenets automatically.
  3. Recommended! If you want to use scripting languages inside Canorus, download SWIG, Python and Ruby for Windows.

RtMidi is shipped with Canorus.

Mac OS X

Canorus has been tested on Mac OS X version 10.4 on both PowerPC and Intel machines and supports building with universal binaries. Versions of Mac OS prior to 10.4 have not been tested; there may be problems running Canorus on versions of OS X prior to 10.3.9 due to gcc compatibility issues.

Prerequisites:

  1. Download and install the cmake cross-platform make-file creator. Use version 2.4 or later.
  2. Download and install Qt/Mac open source edition. Use version 4.2 or later.
  3. For scripting support you will need to install SWIG by downloading it from the swig site or from other repositories (for example Fink). Use the latest version; as of this writing it is version 1.3.31. After installing SWIG you may need to add a symlink so CMake can find it, as described here.
  4. Although Mac OS X ships with Python, you will need to install a later version: OS X ships with Python 2.3, but Canorus requires version 2.4 or later. The newest version is 2.5, which you can get here.

Compilation and installation

For specific compilation issues not mentioned below, see Compilation issues.

POSIX compliant systems (Linux, Mac)

After all prerequisites are met, move to your Canorus root directory and type:

$ cmake .
$ make

This will build the sources. Executable src/canorus is generated.

The same commands should be executed under Eclipse when Debug or Execute buttons are clicked.

To generic install Canorus, type

$ sudo make install

and

$ sudo make uninstall

to remove it.

In order to clean the project, type:

$ make clean

The same command is executed under Eclipse, if Build->Clean is selected.

Debian packages

Canorus already supports creation of .deb packages for various Debian-based Linux distributions. Download the package

$ sudo apt-get install debhelper

and run

$ sudo debian/rules

to compile and create a .deb package of Canorus.

C++11 Support

Canorus does not officially support any C++11 features. It has been compiled with the latest gcc 4.8.1 Compiler. There is a good chance that compilation will break if you add the -std=c++11 options as warnings are treated as error. We have planned to check at least compilation for a 0.7.1 release candidate.
Plans are that we switch the compiler to Clang (as major distributions will do for many applications). This officially will happen in the 0.8 series of Canorus (though we use it as test compiler for 0.7.x as well). Starting with 0.8 we may start using C++11 features.

Microsoft Windows

First configure Canorus using CMake. CD to your Canorus root directory. A typical CMake command should look like this

 c:\cmake\bin\cmake -G "MinGW Makefiles" -D QT_QMAKE_EXECUTABLE=C:/Qt/4.4.3/bin/qmake.exe -D SWIG_DIR=C:/swigwin-1.3.38 -D SWIG_EXECUTABLE=C:/swigwin-1.3.38/swig.exe -D PYTHON_LIBRARIES=C:/python26/libs -D PYTHON_LIBRARY=C:/windows/system32/python26.dll -D PYTHON_INCLUDE_PATH=C:/python26/include -D CMAKE_INSTALL_PREFIX=windows\canorus -D NO_RUBY=1 -D CMAKE_CXX_COMPILER=C:/mingw/bin/g++.exe .

Change your Qt4, Python, Swig and other options to the current version respectively. You should always use forward slashes for directory separators.

You're now able to make the project by typing (depending on your MingW installation):

C:\MingW\bin\mingw32-make.exe

This will build the project. Executable src/canorus.exe file will be generated, (if Python enabled) CanorusPython.py and some other libraries.

C:\MingW\bin\mingw32-make.exe clean

will clean all the object files and a complete recompile will be needed the next time.

Compilation under Wine

If you want to compile Canorus in Wine emulator, the steps are exactly the same as the ordinary Windows installation.

However, when compiling, you might get

C:\windows\system32/winmm.dll: file not recognized: File format not recognized

There is a problem with DLLs stored inside Wine's system32 directory. The -LC:\windows\system32 switch should be removed from the g++ command. This -L flag was probably added by CMake automatically because C:\windows\system32\python26.dll was set as PYTHON_LIBRARY. You should copy python26.dll to C:\python26 directory for example and set PYTHON_LIBRARY to C:\python26\python26.dll instead.

One click installation

Canorus uses nsis to create a nice and simple installation packages for Microsoft Windows. See Readme.txt in windows subdirectory in your Canorus source package for detailed instructions. This kind of package allows you to cleanly remove Canorus using Add/Remove Programs.

Configuring without scripting support

If Python, Ruby and SWIG development files aren't found by cmake or you wish to disable scripting (and therefore plugin subsystem), you have to define flags NO_PYTHON, NO_RUBY and NO_SWIG.

cmake -DNO_PYTHON=1 -DNO_RUBY=1 -DNO_SWIG=1 .

You can also define NO_PYTHON, NO_RUBY and NO_SWIG flags to something non-empty using the cmake GUI, if you prefer it that way.

Integrated Development Environment

Canorus development team mostly uses Eclipse SDK with CDT (C and C++ development tools) as a primary user interface and visual debugger for development. However, it is not needed for the compilation itself, but is easier to develop applications using it. The team uses Eclipse because it's free, cross-platform, widely known and because it works. Its downsides are the specialization to Java programming, memory hunger, C/C++ indexer (works from time to time) and autocompletion bugs (works from time to time).

If you don't want to use any IDEs, you can download the sources manually by using svn and compile the project using cmake and make manually without any GUIs which IDEs usually provide for these kind of operations.

For those on small netbook computers like the EEE or Wind you might want a less resources needing but still useable IDE. There is one called Geany which we like very much. A simple project file is in the canorus trunk (geany subdirectory).

Eclipse

Eclipse is a free cross-platform IDE for software development which runs in Java. This chapter is meant to guide you through the installation and preparation process of Eclipse as a development environment for Canorus.

Note! These instructions are how to install Eclipse only. You should already have the compiler and all the necessary development libraries installed (see Building chapter).

  1. Download Eclipse CDT version from the main Eclipse site for your favourite platform (preferred) or by using the native package systems under Linux environments (platform version might conflict with the plugins, if older version is present in repository!). Currently used Version is Eclipse Helios.
  2. Canorus team uses the following plugins (Help->Install New Software):
    1. Activate (Window->Preferences->Search for "Update"->Select URL http://download.eclipse.org/tools/cdt/releases/helios) CDT Update site for Eclipse Helios Extra CDT plugins like Codan (Code Analysis)]
    2. Subclipse (Subversion plugin)
    3. Eclox (Doxygen plugin)
    4. CMake editor (CMake syntax highlighting etc.)
    5. Checlipse cppcheck integration, cppcheck needs to be installed separately
    6. Python Integration (Optional for python scripts)
    7. Ruby Integration (Optional for Ruby scripts)
  3. Checkout the latest Canorus trunk: File->Import...->Other->Checkout Projects from SVN. Select "Create new repository" and use the following URL:
    1. For developers (registered at Berlios): https://developername@svn.berlios.de/svnroot/repos/canorus
    2. For anonymous users: http://svn.berlios.de/svnroot/repos/canorus
  4. Choose a trunk directory. You should be able to select Canorus now as a new project.
  5. Select the New Project Wizard option and choose C/C++ Project (Helios)
  6. Eclipse will checkout the latest trunk and create a new project for you.
  7. Define include paths (for autocompletion) and build settings (for cmake & make combination). You can set this in Project->Properties.
  8. Set the file association for .ui (Qt UI forms, which should be opened by Qt Designer designer-qt) files in Window->Preferences...->General->Editor->File associations...
  9. Alternatively you can download the Qt4 Eclipse Integration from this place
  10. Build the project using CTRL+B key.

Note! Currently, you should run cmake outside Eclipse for the first time. After that, only simple "make" should be called by Eclipse (this is default behaviour for C/C++ type projects in Eclipse) when building the project which also automatically refreshes the cmake configuration.

Other tools

The following is a list of arbitrary tools used for creating non-programming part of Canorus. They should all be cross-platform and freely accessible.

  1. Gimp: Tool for drawing / manipulating Bitmaps (prefered format: PNG)
  2. Inkscape: Tool for drawing / manipulating vector graphics (prefered format: SVG)
  3. Still open: Tool for software design (low-priced commercial with officially supported wine-Linux-Version: Sparx Enterprise Architect, integrates into eclipse with separate tool), bouml, argouml, umbrello. I'd like to have support for roundtrip engineering
  4. TestUnits: CppUnit (basic tool helping to write test cases, more advanced tools like Froglogix Squish would be extremely helpful), not yet researched.

Coding conventions

All developers should use the same coding conventions. Coding conventions are very similar to Qt4 library.

File names

  • All file names should be lower-cased.
  • C++ Source files should have .h extension for headers and .cpp for implementation.
  • SWIG interface files should have .i extension.
  • Files are usually named by the class they represent without the CA prefix.

Directory hierarchy starting with versions > 0.7.0

  • /
Root Canorus directory. Includes README, INSTALL, AUTHORS, TODO, NEWS, LICENSE.GPL text files, CMakeLists.txt rules and other user's start points.
  • /debian
Debian and Debian-based distribution package creation rules.
  • /doc
Doxygen documentation compilation rules
User Guide, contains lyx files and images to create online and pdf help via make
Developers Guide with some analysis and concepts of the more tricky Canorus parts or just simple information on some code (source code itself also contains many hints)
  • /examples
Examples in Canorus own format (both the Canorus xml and archive variant).
subdirectory musicxml contains scores working with Canorus musicxml import filter (also serve as regression test base)
  • /macosx
Mac OS X application and package creation rules.
  • /src
Root source directory.
Home of main.cpp.
Another CMakeLists.txt for source compilation only is located here.
When compiled, Canorus .exe file is located here and any Canorus library for scripting languages.
Qt's ui_*.h User Interface helper headers, moc_*.cxx files and qrc_* resource files get generated here.
    • src/control
    Control files for about any aspect of Canorus except direct physical device handling
    • src/core
    Core files like archive, file formats, settings, transpose, undo/redo
    • /src/export
    Export filters like LilyPond, MusicXML, NoteEdit and ABC music.
    • /src/fonts
    Fonts used in Canorus in TrueType format.
    These are LilyPond's Emmentaler font (for music elements), FreeType (for function markings) and Bookman old style (for fingerings, time signatures etc.)
    • /src/import
    Import filters like simple Lilypond, MusicXML, Midi.
      • /src/import/pmidi
      Midi parser from pmidi project
    • /src/interface
    Other mainly physical handling user interfaces like playback, midi, keyboard but also plugins backend, python console
    • /src/lang
    Internationalization.
    • /src/layout
    User interface part of core elements that are drawable on the score canvas.
    • /src/plugins
    Plugins shipped with Canorus
    • /src/rtmidi
    External RtMidi library.
    • /src/score
    Score files like notes, rests, document, sheet etc.
    • /src/scripting
    Scripting classes and SWIG interfaces.
    • /src/scripts
    Scripts shipped with Canorus like new document.
    • /src/ui
    Larger User Interface entities like main window, dialogs and other windows.
    *.ui files are Qt designer forms. When compiling, uic tool generates a corresponding ui_filename.h header file one directory higher which get included into implementation then.
      • /src/ui/images
      Icons and other image resources for Canorus.
      Canorus prefers icons in scalable SVG format. Bitmap PNG is used as well.
    • /src/widgets
    Smaller User Interface entities than windows like custom viewports, special buttons, LCD number, action command editor etc..
  • /windows
Microsoft Windows install package creation rules for nsis.

Classes

  • Always use CA prefix for any Canorus classes.
class CAMainWin : public QMainWindow;
class CAMusElement;
class CANote : public CAMusElement;
  • Describe the usage of the class at the beginning of the class implementation .cpp file. Right after the #include lines and before the implementation of the first class function.

Class members

  • Developer should use TABs for idents instead of spaces.
  • Private class members have prefix _.
private:
    int _length;
    CAMainWin *_mainWin;
  • Getter methods should be named exactly by their returned variable name without the prefix.
  • Getter methods which don't only return a property, but also generate a list or do some slower algorithm have get + variable name.
  • An exception is a boolean variable type, which have is + variable name without the prefix.
  • Setter methods should be named set + vairable name without the prefix.
public:
    int length() { return _length; }
    bool isPlayable() { return _playable; }
    void setLength(int length) { _length = length; }
    
    QList<CANote*> getChord() { for (int i=0; i<eltCount; i++) if (timeStart=curElt.timeStart) QList << elt; }

private:
    int _length;
    bool _playable;

Functions

  • Lower-cased. Use upper-cases for blanks.
findNearestChord();

Code documentation

  • Every source file should include a copyright notice at the beginning. It must include copyright date and developers name, optionally Canorus development team (for discussions, ideas, smaller patches etc.) and a license information (link to LICENSE.GPL file).
  • Header files to be used by developers (aka dev(el) files) should be clean of any comments. For the parts of the classes which aren't straight-forward but vital for understanding, ordinary C++ style // comments should be used. Note that 3rd party developers should mostly use online documentation as an API reference, but a quick peek at the header file should be understandable. Otherwise, keep in mind that header files should be as clean as possible.

Comments

  • Remember: Comments are for you, I bet you don't know exactly any longer what a certain code line was meant to do when working on it after a year!
  • Use only // for commenting the code.
  • Use /* and */ only for exclusion of a block of the code.
  • Code procedural description should not be under-commented nor over-commented. The code itself should be written the way it has a meaning by itself.
  • Use spaces between the code line and a comment instead of tabs. Add a single space after //.
int _length;   // length of the current note
    • Usage of upper-cases at the beginning and final marks for one-line comments is custom. If you write the whole sentence, use them, otherwise, use lower-case for quick notes.

Doxygen

Canorus uses Doxygen for the dynamic generation of the online API reference. This documentation describes in detail each class, function and members.

  • Use /*! to start it and */ to end it.
  • Use Qt's \name for doxygen instructions (not Javadoc style @name)
  • Doxygen documentation should only go into .cpp source implementation files, header files should be clean:
    • Before each class, a \class block with class description
    • Before each function, a description of the function
    • For getter/setter and other methods already implemented in header file, use \fn CAClassName::methodName(arguments) and description at the end of .cpp file
    • For class attributes, use \var CAClassName::_attributeName and description at the end of .cpp file

Doxygen compilation

Developer can build his latest Doxygen documentation by installing the doxygen compiler and running

$ cd doc
$ doxygen canorus.Doxyfile

Doxygen generated API reference can always be accessed online.

Canorus internal structure

Resources

Canorus as any other application uses many resources like icons, images, sounds etc.. Qt supports two ways of dealing with various resources:

  • Compile them into .exe file
This method copies all the icons to the executable exe file. It uses the Qt Resources description file (.qrc). One of the upsides is immediate availability of any resources (no problems with locating them on the file system in runtime). Downside is the final executable size which gets quite big in our case (Windows even returns message "Program too big to fit in memory" sometimes!).
  • Load them dynamically
Using this method, you only point the icon locations using the file system path and icons are found in runtime.

Canorus uses the second method since version 0.3. Currently, icons for menus and toolbars are located in src/ui/images directory. All the icons are in vector SVG format (preferred) or bitmap PNG format.

Resources are installed by CMake automatically. It installs all the src/ui/images/*.png and src/ui/images/*.svg files.

Model-View-Controller design

See Model View Controller on WikiPedia. This is a programming pattern which incorporates a separation of application to its abstract data part (Model), the user interface (View) and the glue between the two (Controller).

  • Model part is the core of the application. It includes all the internal score manipulation and representation code. It's located in src/core, src/import, src/export, src/scripting directories.
  • View part is located in src/drawable for drawable instances of the abstract objects and src/ui or src/widgets for Qt4-based structures. Other interfaces (like playback, plugins etc.) can be found in src/interface directory.
  • Controller part is currently mostly located in src/ui/mainwin.cpp and its header file. This is the glue between various states in user interface and its behaviour dependent on the current data.

The most important part is of course the data (Model) part. According to the paradigm it should be completely independent from the user interface and controller whatsoever. This means that for every data object, there doesn't exist, exists a single or multiple user interfaces for showing and/or manipulation with it. This approach is very useful and Canorus tries to incorporate this model as its base architectural pattern. A nice example of this approach is visible, if you use multiple viewports of the same score. When you place a note in one, others get refreshed and show the new note as well.

Score hierarchy

Canorus tries to have a similar score concept to LilyPond.

Below is a hierarchy of classes how the score is seen from Canorus point of view. Class name in bold is a Model class name. Class name in parenthesis are one or more of the View user interface part of the MVC pattern.

Going from Macro structures to Micro structures, the score looks like this:

  • CADocument (CAMainWin)
Is a topmost structure.
LilyPond has a \book block for this.
  • CASheet (CAViewPortContainer, CAViewPort)
Represents a working sheet (similar to OpenOffice.org Calc or Microsoft Excel).
LilyPond has a \score block for this.
  • CAContext (CAContext)
Represents one of the "tracks" in the score. This may be a staff, lyrics, tablature, function markings context etc.
LilyPond has a similar structure Context.
    • CAStaff (CADrawableStaff)
    The mostly used context - n-line staff.
    LilyPond has Staff class for this.
      • CAVoice
      Voice is a part of the staff. Staff itself doesn't include any music elements by itself. Voices do.
      LilyPond has Voice class for this.
  • CAMusElement (CADrawableMusElement)
Represents a single music element on the score like note, rest, barline, function marking etc.
    • CAClef (CADrawableClef), CAKeySignature (CADrawableKeySignature, CADrawableAccidental), CATimeSignature (CADrawableTimeSignature), CABarline (CADrawableBarline)
    Shared music elements found in staff in all the voices. timeLength = 0.
    • CAPlayable
    Playable music elements which timeLength != 0 and are not shared among the voices.
      • CANote (CADrawableNote, CADrawableAccidental), CARest (CADrawableRest), not related, but part of the note, CASlur (CADrawableSlur)
      Note, rest and slur (tie, slur, phrasing slur).
    • CALyricsContext (CADrawableLyricsContext)
    Context for voice lyrics.
    • CASyllable (CADrawableSyllable)
      Basic element of lyrics - one word.
    • CAFunctionMarkingContext (CADrawableFunctionMarkingContext)
    Context for function markings.
    • CAFunctionMarking (CADrawableFunctionMarking)
    Function marking.

Graphical User Interface

The central window user operates with score is CAMainWindow. This window includes menus, toolbars, various viewports, status bar etc. Every document as seen in the previous chapter consists of various sheets which are represented by a QTabWidget (every sheet in its own tab). Every tab also consists of the splitter which adds the possibility to show different viewports of the score in a single tab (used when we call vertical/horizontal split).

The whole document or parts of it are represented by one or more of CAViewPort classes. These are currently:

    • CAScoreViewPort (shows sheet)
    2D canvas which draws music elements like notes, clefs, staffs, lyrics etc. This widget is probably the most used viewport for showing the score.
    • CASourceViewPort (LilyPond currently shows voice, CanorusML shows document)
    This is a multi-purpose viewport which consists of the text widget (the content of the score in text format), commit and revert buttons. This viewport represents a score or parts of it in the text format which is easier to edit than using the GUI in some circumstances.

Viewports can be independent (parent=0 - own window) or nested inside the QTabWidget as seen in main window. Canorus supports both multiple viewports and main windows which share the same document data or own.

External libraries

Needed libraries:

  • Qt4 or Qt5
    Base library for the application. Qt5 has not been much tested but should work.
  • RtMidi (shipped with Canorus)
    Fast and small portable Midi library. Default for I/O.

Optional libraries:

  • SWIG
    Scripting interfaces generator.
  • Python
    Python bindings for scripting support.
  • Ruby
    Ruby binsings for scripting support.

Future libraries which might be useful:

  • libpoppler
    PDF print preview and User's guide. Qt4 widgets available.
  • LilyPond
    Best typesetting application around used for printing or exporting to PDF the score. No library version available yet - only separate executable application.
  • FluidSynth
    Software synthesizer used for common playback on all the platforms. Instrument patches should also be included.
    This should also be used for recording the score into an audio file.
  • zlib (shipped with qt4)
    Compression of Canorus file format

Releases

When a new release should be made, project manager should:

  1. Create a new tag in SVN for the specific version.
    Copy the latest trunk to tags/${LATEST_VERSION} directory.
  2. Set a new product version in VERSION file.
    This will change the version in application and some build systems (nightly builds, Debian-based Linux).
  3. Set a new product version in doc/canorus.Doxyfile.
    This will set a new product version in generated Doxygen documentation.
  4. Set a new product version in windows/setup.nsi.
    This will change the version in Windows installer.
  5. Put release files to Berlios project and make an announcement on the canorus-devel and canorus-user mailing lists and website.
  6. Upload the latest Doxygen documentation to the website.
  7. Change the version of trunk to ${LATEST_VERSION}svn. Where LATEST_VERSION is the latest released version around.

Selected topics

Personal tools