Revamping The Data Model

When coding the core data model for the score editor, I tried my best to keep any view-related information out of it. This was in an attempt to follow the Model-View-Controller (MVC) architectural pattern. Unfortunately, what I've realized is that this separation is actually making my life more difficult. What I've come to realize is that in my own case, this separation doesn't even make sense.

Why? Well I'm not trying to create a core music library that can be reused by others (not anytime in the near future anyways), but rather I'm attempting to create a professional and free piece of software so that people can create, edit, playback, and print musical scores and tablature. Intrinsic to that purpose is the display properties of the various elements in a score. In other words, view-related properties are part of the data model.

As another teaser, here's how far I've gotten so far in the rendering process:


There's a lot of work to be done, but I was getting close to something presentable. The need to tackle the display properties of elements and somehow integrate this into the data model is my next step, and unfortunately that will take time. Right now I model only the very basic elements:
  • Score
  • Part
  • Staff
  • Bar
  • Column (a single note / chord)
  • Note
  • Instrument
along with a few other small things (e.g., note bends, rests, grace notes). What I need to do is include other display elements in the model so that I can more easily allow the user to modify anything and everything in the score. For example, I should model a beam so that the user can change its slope. I should model the note head so that the user can change its size, color, etc. I should model the stem, so that the user can change its length. I would provide an automated system that will do its best to get the score as close as possible to what the user would like, but a "one size fits all" solution doesn't exist because everyone has their own preferences.

Oh the joys of designing a serious piece of software!

Data + Rendering -- Design Decisions

Sorry for the lack of posts over the summer, but it was my time to just relax and do very little after a lot of hard work to finish my M.Sc. thesis. I've finally gotten a start on score rendering (see image below). I'm currently at an interesting point where I have to make a design decision. For a part in a score there can be multiple staves. For example, a piano score usually has two: one for treble clef and one for bass clef. For guitar tabs, there is often the tablature and then the score notation affiliated with this tablature.

My design decision is focused on the best way to structure my data hierarchy and rendering process to render this. In particular, I'm focused on tablature. The tricky thing here is the fact that the score and the tab are two different views of the same data. I have considered two possibilities:
  1. Consider score and tablature two different staves that reference the same set of data. This comes with a set of things to think about:
    • Pros
      • The rendering process can blindly render everything
    • Cons
      • Other parts of the program should know that these refer to the same set of data (e.g., when saving to file).
      • Right now my data hierarchy is represented using a parent/child relationship. Since these two staves point to the same set of bars, each bar would technically have two parents. I'd rather not change the way things are currently, so I would just have to make sure that in no situation it would be a problem getting the initial parent.
      • User will most likely have to manually remove these staves. In other words, it might not be easy to implement a "Show Score/Show Tablature/Show Both" option. Maybe this isn't really much of a con?
      • Without any code that remembers the connection between the two staves, the user would be able to insert another staff in between them. Now if the user chooses to do this, it's his/her own choice so this may not be a bad thing, but it breaks up the connection between the two and the fact that they are connected (i.e., by the same data). Again, maybe this isn't really a con?
  2. Restrict this merely to the rendering process
    • Pros
      • Does not require any changes to the data hierarchy
    • Cons
      • Less flexible
      • Most likely will produce sloppier rendering code.
      • Code for user interaction would be uglier. For example, when the user clicks on the score rendering component, I need to figure out which staff is clicked. I would have to write code that checks the view type (score/tab/both) and understands that some staves would be rendered twice in the "both" viewing mode.
It's just one of those bigger decisions I have to make early. I'm pretty sure I'll go with the first one, but I'd like to hear thoughts and/or suggestions from other people (who I haven't confused yet).

And for those who want to see my latest work, click here to get a feel for the current state of score rendering. It's just the basics for now (note heads/stems), so I have a lot of work to do still (e.g., beams, grace notes).

Back in Business

The score editor project has come off the back burner and is now up front. I still have work to do with regards to my thesis but I expect I'll have that done before mid-summer. Right now the focus is on the following:
  • Completing the port from Java. This task is mostly done, and we just need to implement
    • MIDI playback, and
    • loading/saving of project files.
  • Rendering of both scores and tablature.
  • Create a website (partially done).
  • Fix some bugs and glitchy behaviour.'
So not much really. I'm really hoping to get the first public beta out before 2012, so here's hoping! For anyone interested, here are some of the technologies I'm currently using, all of which I enjoy:
  • Qt SDK
    • Qt Libraries
    • Qt Creator (highly recommended for C++ dev)
  • Boost C++ Libraries
    • Mostly for Boost Signals, which I prefer over the Qt signals/slots system due to it being far more flexible
  • Redmine
    • For internal project management (currently)
  • Django + virtualenv
    • For website dev (I edit everything with vim)
  • Inkscape
    • For vector graphics, which we use to produce the paths for various shapes (e.g., clefs and rests)
  • Git
    • For version control, which I highly recommend. Who knew branch-based development could be so easy? I also love being able to commit locally, and manually tweaking my commits.

New Beginnings

For anyone who still happens to read this blog, or for anyone who falls upon it, I'm hoping to get back to blogging a little more soon. I very recently successfully defended my M.Sc. thesis, so now I have plenty of free time to write code and blog, amongst other things.