Hi Tim,

2012/11/21 Tim E. Real <termtech@rogers.com>
On November 20, 2012 05:02:09 PM Tim E. Real wrote:
> Hi. Someone recently asked about this.
> With lots of wave tracks, especially with OGG and FLAC files,
>  when you move the play cursor around there are brief annoying
>  non-muted loud repeated segments.
> I did a slight readjustment of audio prefetch and midi thread priorities
>  (-5 and -1 instead of +1 and +2).
> (Robert: Yes I dropped the midi slightly. I felt the audio should have
>  the utmost priority over the midi thread. Do you still think it
>  should be higher as we discussed long ago?  )

Maybe we need numbers (or ears) to weed out how it needs to be. What I do know is that our midi implementation with a timing source of it's own allows for some very exact timing without depending on other software. If we can preserve that I don't mind us changing things.

This is going off on a tangent but I was meaning to ponder this...
Sometime ago there was a discussion on LAD whether we should use the alsa-sequencer scheduling and/or jackmidi. Both solutions can work without the timer we are currently using and it might likely simplify our code.

Now, I don't know all the implications, but I have to say I'm reluctant we should abandon our timing solution and solely depend on other implementations.
In the Alsa case mostly because it means our dependency on it would grow stronger instead of the opposite.
In the Jack-midi case, since it does not allow for (near)zero latency, and some other shortcomings like no Sysex.

> The difference is dramatic. Tested with various Jack settings - 'default'
>  priority, or priority 50, or no realtime etc.
> MusE now mutes the brief times between seeking, with no stuttering.
> --------------------------
> Now, a word about those OGG and FLAC files:
> I mentioned in the forums that too many of these files can make MusE
> sluggish, because libsndfile of course takes more time to read them.
> Fair enough. Expected. Use a fast machine.
> However I just discovered that if you place two parts overlapping in time,
>  containing THE SAME ogg or flac file, MusE will choke badly. For example:
>               Track1: ====OGG file wave part=====
>               Track2:                 =====OGG file wave part======
> I recognize this as an all-too-familiar-to-me problem.
> As MusE is playing and attempting to read the same file twice but from
>  different locations, the sound file does not like this - it does not like
>  being forced to go to different locations, rapidly switching between
>  two locations like this.
> The reason (I think) is these are COMPRESSED files, and they do not like
>  being forced to new locations rapidly like this.
> These files want, and need, to progress forward naturally on their own
>  WITHOUT being forced to jump rapidly between two different locations.
> Why is this familiar to me?
> Well, remember I spoke of my attempts to add automatic resampling
>  to MusE using SRC and RubberBand and so on?
> And how it worked so beautifully.
> Until I discovered THIS SAME problem.
> The resamplers did not like being forced to new locations like this.
> They wanted, and needed, to progress forward on their own without being
>  forced between different locations rapidly.
> So... Looks like I may have to bring this issue to the forefront again.
> I believe the two problems are the same.

Here are some more test results on those two same-file OGG parts.
I mentioned that MusE chokes, choppy mouse and everything (!),
 while seeking among those two parts.

Knowing the outcome was likely going to be negative, I tried reeeal hard
 to prove that it was our audio cache system's fault.
I played with the number of cache buffers in main.cpp, I tried 8192:

      // setup the prefetch fifo length now that the segmentSize is known
      MusEGlobal::fifoLength = 131072 / MusEGlobal::segmentSize;

Same problem.

Each audio FIFO cache buffer has a size equal to audio segment size.
So I tried running with Jack buffers sizes from 128 to 2048.
Same problem.

I even tried without Jack.
Same problem.

Same if two or five parts using the same wave.
Same if parts are move around with respect to each other.

I began wondering, why would libsndfile be OK with ONE wave part
 using an OGG file but not TWO or more, and why always the same result?

You know, guys, have you ever had your PC go into choking 'denormals' hell?
Where the mouse chokes along at around once per second?
THAT is what it does!

My my, this sure is looking like a denormals problem.
But where? libsndfile does no processing on the numbers, does it?
I seem to recall checking if libsndfile handles them. Not much found in
 its ChangeLog or google on this topic. More research and tests needed.

Anyway, to make a murky story brighter, here's some good news:

To prove my theory that sharing one OGG sndfile among two or more parts
 is a no-no, I simply changed this line in wave.cpp: SndFileR getWave() :

      // only open one instance of wave file
      SndFile* f = SndFile::sndFiles.search(name);
      // NEVER share one instance of wave file
     SndFile* f = 0;

 which forces MusE to never share them, that is, to use multiple sndfiles
 even if they all point to the same file.


Right now I've got three same-file OGG overlapping parts open and I'm
 whipping around with the cursor and playing them just fine !

However, there are BIG problems. First, some more code would need to be
 changed (the stuff in SndFile::applyUndoFile() and friends could NOT pass
 simple text file names any more). This could be done fairly easily I think.

But worse, and this is the biggy which stopped me from doing the resampling:
Cloned wave parts !
Yep. Those puppies all share one single event list.

Thus it is impossible for the wave events in that list to know who is
 using them and to assign multiple same-file sndfiles accordingly.
Well, long ago I did pass the Part pointer down the chain in preparation
 for the resampling stuff, but the issue involves keeping a list of what
 Parts correspond to what wave events and so on, kind of defeating the
 whole shared event list concept. My list class I created for this sits empty,
 unfinished to this day.

However for non-clone parts, this fix will be excellent because I could simply
 assign ONE audio resampler per sndfile instead of using this weird
 Part<->Event list scheme.

I believe to move forward, these changes are actually required, so I may
 commit them at least so non-clone parts will work.

Sounds really cool.
So, if I understand you correctly, overlapping parts with any kind of wave-data will work, just not clones.
Clones will still have the same problem or is it worse?

Also, I believe they may even speed up regular old .wav file access,
 because libsndfile won't have to share the file and each instance
 can just progress along naturally without having to jump around.

Yap yap yap. Well you can see I'm racing with ideas. All for now.


> Possibly a side benefit being the resampling work could be forced to
>  continue, because I'll be forced to deal with this...
> But whew, it was tricky, that's why I never completed it.

Hehe, do lean back and enjoy the past months wonderful additions you've made to MusE first :-)

When the itch gets too strong you can continue ;)


> Cheers.
> Tim.

Monitor your physical, virtual and cloud infrastructure from a single
web console. Get in-depth insight into apps, servers, databases, vmware,
SAP, cloud infrastructure, etc. Download 30-day Free Trial.
Pricing starts from $795 for 25 servers or applications!
Lmuse-developer mailing list