Weekly status update June 6th to June 12th

Posted 8 years ago

Hi,
this is my weekly update. I'll divide this post into the different things I worked this week and provide some insight how things are.

Single note crescendo

Single note crescendo (aka CC11) is almost finished. There is a PR and after opening this one I had to fix some bugs (found through mtests) and improve some of the code style.

Most of the bugs were due to the fact that I tried to make the default setting for playback based upon features of the instrument. If the instrument is expression based (aka CC11 for Volume) than it should default to use this setting and otherwise it should not. But for some reason it was a bit complicated and actually not necessary since I ignore this setting anyways if the instrument is velocity based (and thus not using CC11 at all). So I made it the default that this setting is set.

But there were one bug that was a little bit strange. Sometimes during the instrument change test a segfault would occur. It seems sometimes the channel list or the instrument list got corrupted. After having fixed quite a few bugs this day I gave up and worked on zerberus the next days. But after coming back to that bug I realized that it was actually quite simple. It was not something I'm doing wrong it was actually interesting that it wasn't discovered earlier. As soon as you would modify the instrument class by adding a new variable to it this bug would occur occasionally. Using valgrind I found out that memory was accessed even though it was already freed before. It was actually freed either by the instrument change or by the instrument class. I think the score still hold references of these instruments and did access them in updating certain things (looping through everything that it has references to) and that is the reason sometimes a segfault happened. I did fix these errors (by not freeing memory during these situations) and the segfault didn't happened anymore.

So came to think if it might be a good thing to also run valgrind checks on the tests to find potential problems? There are also quite some memory leaks (and my changes didn't make it any better) which should probably get fixed. That is currently out of my focus but if I should have some time I might look more into these things.

Samples based volume changes for Fluidsynth

Sample based volume in Fluidsynth is also good to go! There is its PR. As I planned last time I also took care of the modlfo for volume now as well (and that is also the reason I changed quite some things how it is done). This also fixes a couple of problems with the modlfo. There could be done some optimization about stopping a voice when it falls below a certain threshold during release or if it has a volume of zero and is not changing it's volume. These are things that were there before but the way it is done is not compatible with how I do things now. Also I think the low volume detection was failing in MuseScore anyways (probably also because it doesn't use the internal buffer) and (at least for me) cut of parts of the release of some test soundfonts I created - ending in an annoying click sound.

Legato

I'll wait with the legato PR until the sample based volume PR went through since to get good crossfades I'd like to have sample accurate volume changes :)

But I also did some changing. I made the release during a legato the same shape as the attack. This makes the the violin and the flute sound a lot better. (I speculated that it might be because the crossfade time but with some experimenting I found out that this was not the case but instead having proper fades made a lot better) I also moved the notes after the first legato note a little bit in front of their actual start to mimic the midi the way it is produced by sibelius for example. (Have a look at the second picture in this post)

Here are updated sound renderings of the legato example from my last post about it:
Accordion
BaritoneSax
Cello
Clarinet
Flute
OhhVoices
TenorSax
Trumpet
Violin

It might be possible that there is some room for fine tuning this - but I'm actually quite happy how it sounds right now! I'm also saving the state of the slur right now (there is an option to enable or disable rendering of legato like in single note crescendo for hairpins). I haven't updated the instrument class yet. I'll wait until single note crescendo went through because it also changes the instrument class.

Zerberus

And now to the topic that is probably the most fun right now. Zerberus - what a joy to work on this piece of code after digging my way around in fluidsynth. It has a lot smaller codebase, is more modern and object oriented from ground and has a much better design. For example it calculates envelope values and everything during sample rendering - opposed to Fluidsynth which first calculates everything which might be important and than calls one of several interpolation functions which also share a lot of code. In Zerberus is just one interpolation mode - but I think that is actually good - because most MuseScore users don't care so much about interpolation as long as it sounds okay. It is probably also because Fluidsynth was started a long time ago when we had computers that were much slower than our phones today.

But I implemented looping support and it was actually not that hard. There is the PR. The loop is read from sample data (you could modify this either with polyphone or loopauditioneer) which will be overwritten by the loop_start and loop_end opcodes. As to spec if no loop mode is specified as soon as it finds a loop (either via sample information or opcode) it will play in loop continuous mode (which means as soon as it is in the loop it will loop as long as the sample plays). I also thought about if it would be nice if you could specify loop point in sub samples? What do you think about that? (that would be an addition to the sfz standard of course)

Next week I'll add sfz 1 style volume envelopes. Only thing that is a bit stupid about sfz 1 style envelopes is that they don't specify the shape. Currently Zerberus uses linear for attack and power for release (it has 1ms standard attack and release right now) - it seems reasonable but what do you think should be the standard? That is also the question for decay - since there is no decay right now. Maybe we could also add opcodes about the shape to the standard. If these opcodes are there I might also add sfz 2 style envelopes which just specify points in time you reach (and you could have up to 100 of them) and they also specify a shape. But also opcodes that define how envelopes change via midi signals are pretty important after having volume envelopes at all.

I'm looking forward to work more on Zerberus since it is a lot of fun!

A lot of things in this post wait for PRs to be added to the master branch (this will also help you guys out there to test these awesome new features!) but lasconic is out of office until Tuesday so please be patient.


Comments

Keep up the good work! But I have to say, the violin test still sounds legato without the new legato feature (and it always has), and it sounds like there's a (very) sharp attack only with the new legato. It's weird.