On May 1, 2013 03:18:50 PM Florian Jung wrote:
> Am 01.05.2013 08:34, schrieb Tim E. Real:
> > On May 1, 2013 01:33:25 AM Florian Jung wrote:
> >> Hi
> >>
> >> I need a way to find out a tick-to-frame mapping, even if we're synced
> >> to an external device, thus not using our built-in tempomap.
> >>
> >> I already know at which frame we are currently and how many frames i
> >> need to retrieve.
> >> I need to know at which tick we are currently (easy), and how many
> >> (sub)ticks will pass during these retrieved frames. Looking further into
> >> future would be even better (it would be great to know the (sub)tick
> >> position we'll be at after 1000-10000 audio frames.)
> >>
> >> How can I get such one?
> >>
> >> I need this already in AudioPrefetch::prefetch. Is there guesswork
> >> involved, because i don't know the tempo yet (in case of external sync)?
> >
> > Ew, that's a really tough one.
> >
> > You see, originally someone had written the syncing code (you can see it)
> >
> > to try and dynamically update the tempo map as it went along.
> >
> > I found this was not practical as it involved lengthy filtering delays so
> >
> > the tempo map could not really be in immediate 'sync' with the
> > incoming midi clock ticks. I could not find a way around it at the time.
> >
> > So you will see that what I did was remove all that and simply drive
> >
> > the tick position *directly* from the incoming midi clocks.
> >
> > It resulted in *rock* solid performance *guaranteed* not to drift no
> > matter
> >
> > how wildly the incoming midi clock (clock basically means external tempo
> > )
> > may swing or vary.
> >
> > Unfortunately it means during external sync the tempo map is *not* used
> >
> > at all and is *not* to be used at all. That was the price paid.
> >
> > It is *very* difficult to smooth out the incoming clock pulses and filter
> > them>
> > and derive a fairly 'stable' tempo from them - without delay - unless
> > thousands of tempo fluctuations per second are acceptable.
> >
> > Take a look at my tempo *recording* clock filtering options in the Sync
> > Dialog>
> > to see what I mean. I offer several options to the user depending on
> > their needs, including no filtering at all for the utmost *accuracy*
> > upon playback of the recorded tempo stream.
> >
> > Ironically I do realize that this very same code *could* be used for
> >
> > dynamically updating the tempo map as it rolls along - which was
> > the original plan way back.
> >
> > Still, even with no filtering I think there would be an inherent delay in
> > the>
> > dynamic tempo being 'valid', and there *still* would be slight
> > accuracy/drift problems as it rolls along.
> >
> > That's why my direct-drive-ticks method is still the ultimate method, I
> > think.
> >
> > But if we can find a way to additionally dynamically update the tempo map
> > too>
> > as it rolls along, so that stretchers/resamplers can use it, that would
> > be
> > good.
>
> i don't really want to update the tempo map in the way you say. That
> would introduce evil locking problems, and still not help me.
>
> Buuuut:
> > my tempo recording clock filtering code
>
> couldn't we during every playback record the tempo into a *temporary*
> tempomap, which is then freed of any lag (offline, that is), and
> afterwards the real tempomap is replaces by this recording?
>
> So there's no live-recording, but in the n-th playback, we always have
> the (n-1)-th tempomap, which should be the same, right?
Oh OK, that is exactly what I do for the tempo recording.
In the sync code (see below) I add each incoming tempo to a temporary list,
first via a special dedicated TempoFIFO ring buffer (to decouple the threads):
song->addExternalTempo(...)
The TempoFIFO ring buffer needs periodic processing, so at the relatively slow
heartbeat rate I transfer these FIFO items into the temporary tempo_rec_list
here:
Song::beat()
{
...
// Process external tempo changes:
while(!_tempoFifo.isEmpty())
MusEGlobal::tempo_rec_list.addTempo(_tempoFifo.get());
...
}
When recording is finished, *then* I transfer these recorded tempos to the real
tempo map. (But *first* I ask the user in a popup dialog whether this is
what they really want, because there may be thousands of tempo changes.)
Do take a look here for the full story, here's a snippet:
Song::processMasterRec()
{
...
if(QMessageBox::question(MusEGlobal::muse,
tr("MusE: Tempo list"),
tr("External tempo changes were recorded.\nTransfer
them to master tempo list?"),
...
for(int i = 0; i < tempo_rec_list_sz; ++i)
MusEGlobal::tempomap.addTempo(MusEGlobal::tempo_rec_list[i].tick,
MusEGlobal::tempo_rec_list[i].tempo,
...
}
> Can you please me tell me the class, function or even source code line,
> where incoming tick synth is handled?
The exact place where incoming midi clocks are handled is here:
sync.cpp : MidiSeq::realtimeSystemInput()
{
...
case ME_CLOCK:
...
song->addExternalTempo(...).
...
}
That's where all my filtering takes place.
You can also see the older commented code I mentioned yesterday.
I forgot to point out that the older original code simply did not work,
which is another reason I removed it and went with my simpler
direct-drive method.
The old code was highly experimental and quite terrible.
One example of the problems it caused was that it could produce
*negative* tempo, causing the playhead to move *backwards* and
midi to play backwards while the audio (always) marches forward !!!
----
So, with a few changes you can probably leverage all this code
to produce the off-line tempo map you want.
It almost does exactly what you need as is, I reckon.
Ask if you have any more questions about how it works.
Tim.
------------------------------------------------------------------------------
Introducing AppDynamics Lite, a free troubleshooting tool for Java/.NET
Get 100% visibility into your production application - at no cost.
Code-level diagnostics for performance bottlenecks with <2% overhead
Download for free and get started troubleshooting in minutes.
http://p.sf.net/sfu/appdyn_d2d_ap1
_______________________________________________
Lmuse-developer mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/lmuse-developer