Sunday, November 17, 2013

New wiki and dictation exercise specifications

The project continues advancing, but not as quick as I would like, as I'm the only developer. Most of my time is devoted to programming the score editor. It is advancing at good pace and now can be used for simple scores. But a full score editor, with all kind of options is very complex and will take a lot of time. So, as my short term objective is not that, but an score editor to be used by students to enter the answers for the exercises, I have decided to start using current score editor in exercises, in particular, in dictation exercises. My objective is to release a new LenMus version by February, that will include dictation exercises.

Also I'm starting an experiment: to use a wiki as a tool for developing specifications and documentation. For this, I've set up a wiki, in LenMus project at SourceForge, with preliminary specifications for the dictation exercise. Feel free to add comments or improve specifications in the page. As any logged user at SourceForge has authorization for editing the LenMus wiki pages, practically any people is allowed to contribute to the specifications. Your help is welcome!

The page is at:

https://sourceforge.net/p/lenmus/wiki/Dictation%20exercise%20specifications/

Best regards,
Cecilio

Sunday, May 26, 2013

MusTeacH and LenMus projects start collaboration

MusTeacH and LenMus projects have started a collaboration initiative to join efforts for providing you with great tools for your music studies. As you know, LenMus project is focused on providing software for desktop computers, but does not provide exercises and materials on-line. On the contrary, MusTeacH project is focused on providing these materials on-line. Both projects, MusTeacH and LenMus, have similar aims and are complementary. Therefore, by joining efforts our users can greatly benefit!

MusTeacH (www.musteach.com) is a website managed by Dimitris Regginos, a music teacher, classical guitar performer and guitar pedagogue, based in Cyprus.

I'm glad to count at LenMus project on the experience of such an enthusiastic and great musician as Dimitris. Visit MusTeach website were you will find many on-line interactive exercises for practicing music theory and training your ear.

Cecilio

Friday, May 3, 2013

Release of Phonascus v5.3.1

LenMus Phonascus version 5.3.1 has been released. This version is focused on
fixing bugs, in particular on those causing unexpected program termination and errors in exercises.

This version also completes translation to Chinese and adds options for clefs reading exercise. You can find  the list of changes in the website, page New in this version.

Hope you enjoy it!
Cecilio

Sunday, December 30, 2012

RPM packages available and tutorials update

A few days ago we have received an unexpected Christmas gift: Joop Boonen has been working on preparing RPM packages for Lomse and for LenMus (https://build.opensuse.org/package/show?package=lenmus&project=home%3Aworldcitizen). The people at the openSUSE Education project (http://en.opensuse.org/Portal:Education) are now including them in their repositories, and are preparing and maintaining them. Please the check availability of a package for your distro and download it from the openSUSE project page (https://build.opensuse.org/package/show?project=Education&package=lenmus and https://build.opensuse.org/package/show?project=Education&package=lomse).

Linux is a cost-effective alternative for schools and the best way for children to get good PC knowledge not biased by the commercial interests of big corporations. The openSUSE Education project tries to support schools using openSUSE. I would like to give my thanks to the openSUSE Education project people and, in particular, to Joop Boonen and Lars Vogdt for creating and maintaining the LenMus and Lomse packages.

I have updated the download pages at LenMus website to include all these new packages.

Also, I've been updating the tutorials for using the Lomse library. They were written in January-March 2011 and, since then, the Lomse library has evolved. In particular, the need to inform Lomse about the files containing the fonts to use has been removed. Also, there was a small change to improve flexibility in using Lomse for score playback.

I take the opportunity to wish you a Happy New Year!

Sunday, December 16, 2012

Undo/redo approaches

I have started to work on the score editor. One of the things I've done is to review all the documentation I had from the editor in 4.0 LenMus series and to re-think about the design. Just in case it could be of help for other people, I will summarize here my findings/thoughts about the issue of implementing undo/redo in an application.

There are two basic approaches for implementing undo/redo:

1. Based on actions.

    All possible operations to modify a document are enclosed in "commands" by using the well known "Command pattern". The basic idea is to create an object that represents a user action and encapsulates all the information needed to perform the operation. The Command object receives the additional responsibility of undoing the operation when requested. With this, it is very easy to implement undo/redo. If all user actions in a program are implemented as command objects, the program can keep a stack of the most recently executed commands. When the user wants to undo a command, the program simply pops the most recent command object and executes its undo() method. There are two main approaches for implementing the undo responsibility in commands:

    1.1. Save state
        The Command just saves the object state before performing the actions. When the command undo() method is invoked, it simply restores the state which was saved by the command. Instead of saving the whole state of the object, an alternative is to save just the changes to the state.

    1.2. Regenerate state
        Instead of saving the state or the changes to the state, the Command just restores the state by carrying out the inverse operation, that is, by doing a logical reverse of the particular actions performed by the command. Regenerating the state this way is not always possible, as implementing the logical inverse of a command could be difficult or impossible, or be too expensive in computational time or resources. For instance, regenerate state is usually simple to do when the command just changes object properties, but for commands deleting objects or parts of the document the only feasible approach is to save a copy of the deleted objects.

    So, depending on the situation - possibility of a logical inverse action and the feasibility of it, you need to choose between these two broad categories, and then implement them the way you want. Of course, it is possible to have a hybrid strategy: for some commands use the save strategy, and for others the regenerate strategy. It all will depends on the feasibility and cost of each approach. 

    A useful design pattern to be used by Command for saving/restoring the state of an object is the Memento pattern. It solves the problem of capturing and externalizing an object’s internal state so that the object can be returned to this state later, without violating document encapsulation.


2. Based on checkpoints.

    The other broad alternative is to base undo/redo on checkpoints and rollback. In this approach the Command object is not responsible for undoing the operations. Instead, whenever a command is going to be executed, the command interpreter establishes a new checkpoint. Undo is then implemented by rolling back to a previous checkpoint. 

    The checkpoints are usually implemented by saving the complete state of the document. For this you can use any suitable mechanism: deep copies, memory snapshots, serialization to memory or to temporary files, etc.

    Serialization is one of the simplest ways of implementing checkpoints and has the advantage of reusing existing infrastructure (i.e. part of the file load/save code). But poor time performance and huge memory consumption could be observed if the document is large. In some cases, these problems could be alleviated by saving only the differences between states (differential checkpoints) but this requires building additional support in your model for this.

    The undo/redo based on checkpoints approach has important advantages: it is simple to implement, very scalable and requires no-maintenance when adding new actions to operate on the model, as they don't need to do anything for supporting undo/redo. In addition, the approach of serializing the state to disk instead of saving it to memory has the great advantage of facilitating the implementation of a mechanism to recover from system errors and program crashes, so ensuring that the user does not lose the work.



Tips
------

a) Use the Command pattern

Independently of the undo/redo chosen approach, using Command objects to modify the Document has many advantages. Materializing commands as objects means they can be passed, staged, shared, loaded in a table, and otherwise instrumented or manipulated like any other object. It forces to organize actions and make them more consistent. It also tends to reveal opportunities to factor out repetitive code (i.e., you can separate similar commands into families, and re-factor repeated code into shared base classes). When you turn all user actions into a stream of Commands it is easy to implement scripting, and save the command stream to implement recordable macros. Also, it is easy to insert synthetic commands into the stream for special processing or to redirect the command stream to another computer to remote control another application over the Internet.


b) Analyse the implications of restoring a previous state

In theory, restoring a previous state is just replacing one object with another. But in practise there could be lots of unforeseen consequences that go unnoticed in the beginning stages of implementation. The big problem are pointers or references used in other parts of the application to point to specific parts or objects in the model. When the model is replaced by another copy, these pointers and references are no longer valid, and this causes many many bugs, sometimes difficult to debug, as they will manifest much later, when performing actions difficult to correlate with an undo/redo operation (by the way, this was one of the big problems in LenMus 4.x editor).

The biggest thing you have to do is avoid, outside the model, the use of pointers or references to model objects. A simple technique is to use instead safer undo aware “identifiers” (like unique integers). Whenever a model object is needed, you lookup the current 'good' pointer/reference for the object from a table in the model. 


c) Think about transient actions

By transient actions I refer to those user actions that do not affect the document information, only to its presentation (i.e. Select objects or Scroll to a point). In many cases it is not necessary to provide undo/redo for transient actions, as the user can easily return to a prior state. Nevertheless, you should consider the convenience of providing undo/redo:

* For tedious user interface operations.
* If your application will support recordable macros.


d) Dealing with aggregate actions and composite commands

If the chosen approach for undo/redo is based on commands, you should consider the implications for aggregate actions (actions on several objects, e.g. user Shift-Selects a set of objects to do an operation on, such as delete, rename, change attribute) as well as for composite commands (commands created by aggregation, in sequence, of other commands). In these cases you should pay attention to two points:

1. Design the commands so that they can be coded the same whether they are executed in isolation, as part of one aggregate operation, or as part of a composite command.

2. Design the undo support so that aggregate and composite commands can be undone/redone in a single step.


And this is the summary of my findings/thoughts about the issue of implementing undo/redo in an application. Hope this could be of help for you,

Cecilio


References
---------------

Undo/redo
    http://stackoverflow.com/questions/49755/design-pattern-for-undo-engine
    http://stackoverflow.com/questions/3541383/undo-redo-implementation

The Command pattern
    http://en.wikipedia.org/wiki/Command_pattern
    http://c2.com/cgi/wiki?CommandPattern

The Memento pattern
    http://en.wikipedia.org/wiki/Memento_pattern
    http://sourcemaking.com/design_patterns/memento
    http://c2.com/cgi/wiki?MementoPattern

Saturday, December 1, 2012

LenMus Phonascus 5.3 released. The Leitner method

Yesterday I released the 5.3 version of LenMus Phonascus. You can find  the list of changes in the website, page New in this version.

This release mainly restores all other missing features, present in previous version 4.2, that were disabled for moving to 5.0. Among them, all exercise modes (learning, practise, exam, quiz) have been restored.

Originally, LenMus exercises were not based on any particular learning methodology. Questions were selected just at random and easy questions were repeated annoyingly. By autumn of 2009 I was reading on learning techniques and I considered the idea of improving LenMus Phonascus by adding support for a learning methodology. As a proof of concept, in version 4.1, I implemented the Leitner methodology (also known as spaced repetition learning technique or flashcards method).

The first experiments were just a direct implementation of Leitner method. I did some tests with the intervals identification exercise and the results were quite bad. It was because the Leitner method is suited for problem spaces where you have to memorize the answers to the questions. But in most music theory exercises, the objective is not to memorize an answer but to learn a concept (i.e. "3rd major interval") and quickly identify examples of the concept that can have different representations in a music score.

Therefore, I had to introduce modifications in the Leitner method to adapt it for learning concepts instead of facts. I have taken the opportunity of the release of version 5.3 for documenting in detail all this issues and algorithms. You can find this documentation in the website, at page Learning techniques and exercises operation modes)

I would be more than happy if a music teacher would like to join me to make LenMus a great tool for music students and teachers. It is necessary to continue defining and reviewing all pedagogical issues of the LenMus program: syllabus, exercises, Leitner method issues, etc. Programming and managing the project takes most of my time and I can not do more! Of course, no need to say that developers are also welcome!

Saturday, October 27, 2012

LenMus Phonascus 5.2 released: the new LMD file format

A few minutes ago I have released a new version of LenMus. The 5.2 version fixes a couple of important bugs, and includes a new translation: to German (thanks to Undine Peters for doing this translation). 

Although users will not see much more improvements (you can find  a list of changes in the website, page New in this version), the main change in new 5.2 version has been to use the new LMD format for books and scores.

But, why a new format? Why I developed LDP instead of using an existing language? This is the story.

When I started the LenMus Phonascus program, in 2002, I didn't have any previous experience about  representing music notation in computers. And it was just a hobby program with no particular aims apart from helping me to practice music reading and aural training. 

I googled for information about existing languages and for academic papers on music representation, but I couldn't find any. Contrary to general believe, all academic documentation is not free knowledge but very expensive pay-walled information, normally not affordable by general public, unless you have access to a public library with a deep budget. 

As to existing languages, I found references to languages such as abc (http://abcnotation.com/), LillyPond (http://lilypond.org/), SCORE (http://253.ccarh.org/handout/scoreinput/), and MusicXML (http://www.makemusic.com/musicxml). Except MusicXML, all others didn't have (IMHO) a clean syntax: they were too oriented to preparing files manually so, their syntaxes were full of implicit assumed information, abbreviated constructs and `tricks', making it more complex to process and to understand. On the contrary, MusicXML had a clear, modern syntax based on XML. As my needs were, at that time, very simple, basically representing notes and rests, I immediately thought about using MusicXML: as it was XML it would be easy to parse and to ignore all information that I was not going to process. Unfortunately, in those days (2002), MusicXML was a starting project (version 0.7) and it was inadequate to my purposes as I needed symbols positioning information and MusicXML 0.7 didn't have plans to include it. 

As I needed something, simple to process, with positioning information, and I only aimed at displaying simple melodic lines with just notes, rest, clefs and barlines, I decided to design a simple language for data entry. I also valued the additional advantage of being a good opportunity to gain first hand experience about music representation problems, as it was not possible for me to learn from academic publications. So I started designing my own representation language. I named it "LDP" (Lenguaje De Partituras, Spanish for 'language for music scores').

But I also though that, as I had not experience in music representation, it would be wise to have some grounding references and so I decided to follow the MusicXML model. A second reason to follow it was that I liked to implement export/import MusicXML and so, to simplify this objective, my internal representation should not deviate too much from MusicXML. This was the main reason for the "goFwd" and "goBack" elements in LDP. I didn't like these procedural tags inside a declarative language. For me, a better solution would have been something similar to the overlay constructor in the GUIDO language (http://www.noteserver.org/diss_kai_final/diss_final.pdf) but:
  • I gave priority to not deviating too much from MusicXML.
  • I didn't knew about GUIDO much more later, when some LDP decisions had been taken.

Although recognizing the advantages of XML syntax, I decided to use a LISP like syntax instead of XML. This was due to the work involved in typing XML files. I had no XML editor and typing paired opening/closing XML tags was much more typing than the real content itself! And, in future, if necessary or convenient, it would be trivial to switch to XML and convert existing LDP files to XML syntax (by the way, time for this switching has already arrived).

Later, in version 2.0, MusicXML changed its mind and allowed including positioning information. But it was too late for me. I had already created LDP, a lot of code was in place, and Phonascus was running.

Nowadays, I've learned a lot about music representation and, for scores, I feel no need to continue using and developing LDP, so a switch to MusicXML would be perfectly possible. The only deterrent is that MusicXML is limited to describing scores, but I need to describe full books, with texts, images, exercises, scores and any other content common in music books. But MusicXML idea is not allowing additional content other than music scores. MusicXML answer for additional content is to use  HTML + CSS and embed MusicXML scores on it. This could be a good solution if web browsers supported MusicXML as any other standard web content, and were able to render the scores. But that's not the current situation.

So, to have a solution today and to not depend on how MusicXML evolves, I am, somehow, forced to continue developing and extending LDP. This evolution is the new LMD (LenMus Document) file format. It borrows ideas mainly from DocBook (http://www.docbook.org/), MusicXML and the Open Document Format (ODF). And it uses XML syntax. When finished, I will upload the documentation to the website.

Thanks for reading.