Descriptors comparison (oldschool vs newschool)

I thought fluid. didn’t play nice with polybuffer~s after the alpha02? Or did I misunderstand that.

Again, I could be misunderstanding this, but if I use @fft settings 512 64 in something like fluid.loudness~, I would be restricted to a temporal accuracy of my hopsize (in this case 64), so if I’m interested in analyzing example 512 samples, I will potentially have +/- 64 samples on either end of it as well.

Whereas with the buf counterpart, my temporal accuracy is 1sample, and I can analyze exactly the 512 samples (or whatever) I want.

Unless what your theorizing would mean that fluid.onsetslice~'s “fft clock” (is that a thing?) would only ‘fire’ when it recelives a click~ at it’s input, and then it would analyze the last n amount of samples with the given @fftsettings.

Plus, if there are diff fft settings (and potentially hopsizes) between fluid.loudness~ and fluid.pitch things get messy again in trying to resync that data together.

But yes, it one/could be trading one set of problems for another.

I think you might, but this is my fault :smiley:

tl;dr The difference from alpha 2 was that fluid objects don’t know about polybuffer~s, they only know about buffer~s, but this has no bearing on whether you can use polybuffer~ in your Max code to manage large / dynamic quantities of buffer~s that you pass into fluid processes.

Longer Story

Back in the olden days, I had thought it would be neat if people could pass into a fluid process either the name of a buffer~ or the name of a polybuffer~ (a collection of buffer~s) so that, for instance, all your NMF components end up in separate buffer~s automagically. However, internally, the downsides far outweighed the benefits because the objects are so different. In particular, it proved beyond me to get stable behaviour from objects that needed to access data in the audio thread with this scheme, so I axed it.

All that means, though, is that fluid objects, like all other Max objects that deal with buffers~ only understand buffer~ objects, it has no effect on whether people use polybuffer~ in their patching. As far as fluid.x is concerned there is no difference between a ‘standalone’ buffer~, mybuf and one inside a polybuffer~, say mypolybuf.1.

So, for these things where one needs to throw lots of buffers around, if it’s easier to programatically control the creation of buffers~, go ahead and use polybuffer~

Oh right. So if I set a (single buffer~ inside a) polybuffer~ as output from a fluid. object (say @features mybuffer.1) that would work correctly?

And similarly for source/destination buffers from bufcompose~?

So effectively you could read/write from polybuffer~s, but not address it as an aggregate?

On that note, will something like bufcompose~ automatically populate/size a .1 single buffer~ inside a polybuffer~? Or would it involve “manually” creating the .1 buffer and sizing it and then bufcompose~-ing into it?

Well, fluid.loudness~ doesn’t have fft settings, but your general point remains that your effective sampling rate with a feature extractor is a function of the hop size, yes. However, the temporal accuracy between the signal and buffer versions is no different: the difference is in how much control one has over submitting the portion that gets analysed (which is pretty much what you said, I know).

rambling aside about buffers (click to reveal)
  • Even then, the things don’t behave all that differently (at the moment): the reason you get more frames in the buf versions than you expect is because I also return ‘padding’ frames where the beginning of the sample to analysed is lined up with the middle of a window. This will possibly change for descriptors (i.e. we’ve been talking about it) because whilst the current behaviour is correct for things that you’d want to resynthesise later, it makes less sense for descriptors.

The equivalent issue in the signal domain is where time-zero is, and how that lines up with the beginning of a sample block of interest. As it stands, time-zero is when you turn DSP on, and we have no further say in how moments of interest line up with analysis windows. I was imagining that click inputs could be used to essentially reset time-zero, but have given absolutely no thought at all to how difficult / disruptive this would be.

But let’s imagine it’s a thing: you have some Rod-grade onset detector, and this emits spikes on events, these spikes could then be used to align the ‘re-starts’ of a bunch of feature extractors, and to some kind of summary object (e.g. a signal rate stats that doesn’t currently exist). At the point that this produces output, you might be interested either in message or signal domain output depending on want you want to happen next. If it’s some kind of query, probably a message.

In my mind, at least, this seems pretty straightforward in terms of alignment and causality, but maybe I’m missing something.

So, totally ignoring actual fluid stuff for the moment, if I were imaging a featurer-y thing in the signal domain, where I really cared about timing, it might look like this:

Obviously, like all MSP things, this scales poorly with the number of features, though mc.* can probably alleviate that from 8 onwards, or framelib, which was was quite literally made for this sort of game.

1 Like

Yes!

Yes!

Yes!

Should be exactly the same as using any other buffer~, i.e. bufcompose~ will resize, populate etc. polybuffer~ exerts minimal ownership over its contents, beyond naming and offering controls for adding etc.

1 Like

That’s great!

There should be stuff in the helpfiles for this, as that (potentially) solves many of the n amount of buffer~s problems, and after alpha02 my understanding was that polybuffer~s were a no-go zone.

Might be useful for @jamesbradbury’s problem with scalability in the thread about analyzing slices.

Yeah that makes sense, and doing this pseudo-realtime/JIT stuff is just something I nabbed from @tremblap as a way to being more precise with analysis frames/windows for realtime purposes. But it is actually a real-time process that I’m after.

Something like your (“deep fake”!) screenshot would work well, but is pretty different from a conceptual standpoint to how things presently work in the fluid.-verse.

And if there’s a click~ triggering it, it could (hopefully) theoretically not be limited to a hop’s worth of resolution and also account for different @fftsettings per descriptor type.

I remember ages ago asking for something similar for fluid.nmfmatch~ where you could be very precise about returning a single frame of analysis based on an onset.

There would be tons of uses for this “real-time-but-only-when-you-ask-for-it” type workflow, which would alleviate all the potential issues/problems with the buf stuff.

Totes, that would be great. And obviously makes lots more sense for real-time stuff.

this is funny.

Not really. You are after a discrete time - SC has demand-rate concept, which is what you are after. RT is a stream concept, and Demand is accurately whenever you want, as fast as possible. It is actually nearer NRT for me…

TLDR for all the posts above, but some quick thoughts.

1 - the bottom line here is that the issue is deferring a time critical process - that Max deals badly with threads in terms of user ciliary is pretty obvious from the amount of confusion here, but the reality is most max users thing if a metro is trigging something (or snapshot~ etc.) then it happens straightaway, with no delay. Suffering the defer for something expected to take a long time is fine, but for something fast it is not.

2 - the deferring is all about resizing buffers/nothing else, but it is brought about here by the use of storing buffers as an intermediary - the real time objects don’t/won’t have this issue.

3 - from an engineering perspective the infrastructure in the client layer doesn’t care what the buffer it is writing to is (it’s an abstraction of a buffer that could write to any kind of structure you like), and it might in fact represent anything, so the design implications of being able to output to something other than a buffer would remain at the wrapper/environment level. That is to say it is technically possible to get all the buffer analysis objects to output directly to some other format in max without having to touch anything within the core code. Whether that is a design that might be considered is another matter.

4 - the idea that turning overdrive off will provide an answer is for me quite problematic - I don’t think it is generally viable on a retina screen - see next point…

5 - yes graphics might get put at the back of the queue, but even if they do then once they start processing you have to wait for them to finish to get the next thing to happen. That is why the times are erratic without the defer low (which is giving you the operational time). You’ll get noticeably better performance by opening Max in low resolution mode, but the timing for events on the main thread when hopping between threads is basically an unknown - bear in mind also that anything you trigger off that is still low priority, or you have to up the priority again - not nice. It’s sort of OK for response to triggering general events with a low rhythmic tightness, but it won’t cut it for musical timings.

1 Like

Thanks Alex,

  1. Yes. Somewhere in the tl;dr is acknowledgement that this mode of use is not (yet/ever) accounted for in the design of the non-real-time objects

  2. Somewhere further in the tl;dr is me wondering if it would make sense to consider how the real-time objects could be augmented to better support the specific type of thing that Rod is attempting, but in the signal domain. You might have good reasons for thinking this is a naff idea though.

  3. True, but there are cans of worms (how is the mode specified? different input and output container types possible? how do we handle intrinsically one dimensional containers (i.e lists)? how could this facility replicate across different hosts?)

  4. / 5. Thanks for the info. My only response is to shrug and say depends on the music and depends on the patch. I have a piece that currently runs without overdrive (otherwise it deadlocks), and that is fine for those particular musical needs. I think I was clear enough that it wasn’t without temporal consequence, somewhere in the tl;dr.

1 - sure

2 - the issue there is that chunks of audio at specific times looks quite like a whole new infrastructure (a la frame lib).

3 - yes - I’m not arguing it would be easy.

4/5 - For me I don’t think that overdrive off answers either the specific set of concerns here or a more generally applicable set of concerns. Of course there may be situations where overdrive off might be viable, but I’d consider them few and far between. I believe the situation with timing on Max7/8 to be far worse with respect to the main thread than older versions (e.g. Max 4) as the graphics are considerably more involved and also the retina resolution comes at significant cost. If rod removed various graphics from his patches the times would most likely improve significantly, but I think that having to consider what is on the screen in terms of speed is considerably more burden than is ideal. Scrolling around a window with a metro into a click~ and overdrive off on a retina screen should give some indication of how bad it can get. Resizing the window can stop the metro indefinitely. For me that is far too flimsy a scenario to be reliable for realtime usage.

Ok, finally got around to testing this with the latest alpha and it seems about the same.

Sans defer, the results are around 100x slower:

With the defer in place, it is “faster” (back in the 0.5ms range), but the gains here are artificial (rather measuring only the intrinsic and not operational latency).

I may mess around with using the fluid.descriptors~ for the database creation, and then (not.fluid.)descriptors~ for the “real-time” stuff as an experiment since in my intended use case I’m not really going for perfect resynthesis, but rather corpus browsing, so consistency between algorithms (although not great) isn’t paramount.

I’m sure that once you have a working prototype, there are way to spy on the actual read operational load of each solution, with something from developper tools. At the moment, if I was you, I’d use all fluid* approach and focus on quality, but you might prefer quick and dirty. One thing for sure, I’d like to hear the difference both in lag and in sound…

I’ll put something together with rudimentary matching (the simple/core “four descriptors”) and see how that sounds and post the results.

1 Like

Ok, here is an early test/results. At the moment I’m only matching on 3 descriptors (loudness/centroid/sfm) since pitch isn’t very accurate/consistent (more on this below).

The patch is messy, and the rest of it is still pretty big so I’ll post some patch once I tidy it up, but here is the relevant bit of patch, and I’ve thrown a red panel and labelled the important section:

The audio file I’m playing is about 40s long, and I left it going for about 5minutes just to be thorough on the min/max ranges. The timing is between when an onset is detected and a result is returned from entrymatcher, so this includes entrymatcher latency, which is nominal since the database only contains 3094 entries (vs 100k+).

You can see that it’s pretty fast on occasion, but there are spikes of up to 500ms latency in the mix, with a pretty high average spike as well.

Sonically it’s kind of hard to tell on my laptop speakers since the audio files I’m playing are flurries of notes anyways, so I don’t really “hear” the latency, but this test wasn’t designed to do that (though I’m certain I would hear that 500ms late example…).

///////////////////////////////////////////////////////////////////////////////////////////////////////////////

Part of what I want to test/compare as well is the “accuracy” of the fluid.descriptors~ objects, but that becomes tricky here since my corpus and JIT analyses are looking at very different things.

The corpus is made up of robust stats across the length of entire samples, including statistics based on length (duration, time centroid, amount of onsets, etc…), whereas the JIT stuff is looking at 512 samples and a limited number of descriptors and corresponding stats. So accuracy is more like “accuracy”, at best. A perfect apples to orange-shaped-apples comparison.

This is inherent in this approach though, as I want to analyze audio now and have results even now-er, that there will be a tradeoff. Hopefully in the future (toolbox2) I will be able to stitch together bits of audio ala multiconvolve~ so I can get fast and responsive analysis and matching, but there will always some kind of projection required if I want to trigger longer samples from shorter inputs. (on that note I started experimenting with creating a time series of descriptor data on a microscale, which I would then stretch out to apply to longer-than-the-original target samples (i.e. the pitch contour of a tom mapped to a long string gliss)).

From what I can tell (listening wise), it is consistent though, which is important. The opening onset from my audio clip always triggers the same sample in the corpus. I don’t know if this is the case throughout, and perhaps it’s worth testing to see if I get the same exact results each time the 41s sample plays through.

Here’s the relevant/main bit of the patch for testing. This uses @a.harker’s most recent entrymatcher, but it probably works just the same with older/other versions of it.


----------begin_max5_patcher----------
17131.3oc68s2iaijcu+smOEDMBB1MWas06G2jMvY2jrI.yjDfA3FDrafA6V
raqwpEUzC6w6h3O625AoZ9nXwhRjTT8vFvsUSQIV0u5TmyoNO+Ke2at69zeN
Y+cQ+ei9iQu4M+ku6MuwbI8EdS1e+l6dN9meXc7dysc2CoO+bxlC28V66cH4
mOXt9tia1rZySQweNYW7SI4u+5UaRdH83FyMgJ7gdHcc5N6CFr.PkTfjyj.A
BvjuUcIJ.JQRIVvkXn.oujTJHTBmHoBBTJdaDbAH5+N66b0RyvH89e5cPBK+
wu43yq1rN4fYrCe4hoGOjeUP1U2Fe3gOplAeXWxCGrCLnfs.ywb0ymAU+lSe
aDCiV.T+GP+aLtvH3wzMGdL9gDyiReo+2u66z+5sWHxplA+F0MlirQqiOjr4
gudcQXZ+fvDDzflb9BE1BAnQGUWtROZlFfJoe.UJEqgQJCpAU43QoVADGb7B
2O3ElvzPDQX9OpAuPfdDudNY+9B7DOgWHAXADwwv6bL6vBmyNjyYGzyVLNtF
SLJiqmjby1MDpvT09cd3qaSre56tK5+tGmwpEbDFgINmvx9YBikxEB2SXFcn
lvaR9hZRTa9dXW5wm9nhn10Dl.5vDF6YElPqOgUSRy7t8I7iqSiU6kita0lS
+WehAaSh+TSH.reP.Jptf5LDfHFSD33y2mryIw8IUR1FuK94jCI69Pxl36Wm
Tj4T.7wPMiBH0bst5JBCc.H.Be0L+93MO0u634zEbLgJ3NQEPOsk2xAmIvC6
t7lljzERry4GreleHVcVZC9j8bXogQ8yFZLrNKsbR4oMKMLtmP.IrIDXbYo4
FAdNIdiiouPbW+vJyp0ZlXarriS39bl9mWG8jhjeq5zItVuQ7NrdGvLFIsbx
Bie84MSUXkZb4X1PggHkRqN79U+Yq5vZUH67Jt9aXi5627f+G1sJd8cshLDA
w9e0PlGS28br4lYCirsl3BD8v1iGV8rSI9xSTKg.W9kHbVvkEnBQ7fcqyo22
7clrKCOx.D0fX05jOmra+pzMEFau4t3saKb42T3inQwexd5OwaOcoUarWBb5
R6R97p7OO6zUi2olYGTSqi6rS7elkerA8WS5xjcaNt5zQxLqmYCIyJmFv1uM
6TalE372tndiF3Qwi07eRC2FDl+BZoHMdZc5CeJYYww7coaS1rZy1cI6UmCN
9P1f+zauL4w3iqO7gRK8pSiKoPASl+iq6N+XlN+pbRC7l6dZ2pkoazCoRKL5
Km+v+iQP6LkVbpYtiMwac7gUjvJTpg2buZJeb+8w6zqaYLGP4u4gzz0keqSe
t0IOdH6s2tZylJX5gzsM+l6V8zG87YuOU8lO66617N6+vwM128CJRjCeXe7m
Ki1GhWuNa2d4u9eNdyJESlD81cyzEb5MsLH+39G1ktdco4q8c9ri2Yohj+gj
urZ4gOZdPKJrdqt8UayIot6zp7xUOkr+P4qcH9o8kux9Ce0B5Etzw6y1R+gC
IOuUajlx2PIa.Wb+aQ9hktdE9iVNJm1bVQBYwq6RFQyFqoY08MzxbiBv1svn
hD1Fd.Y1nROLTpDjr6ywqiVsI548Qq1GsKYa5tCIKiTnRRoA9lkI+bAlJYxJ
x3ubl3SI4GkkgbeDrAbCU75AwHoC.Lrx2saNKMYVbf05QVIw7plKysPlBReG
dTUIW9AMW6FfV7TGZg.hU82vv1bA3iC39tWN4SUfkb4.KZX.1LVFDCKCrwxP
SMbsYVAzIK8pUIyaWNAroKxl4QrqMi.yDsAzi2nncPPfRyL.IbOh1ahhpAo+
52MZuR6x8QJs2L9ndyxLM.TJCjoafSk.PiDPJ5efztyb.vwXMpkAjdAOWZP8
xYOzdXsAkNMyF866FU2mdb2C4C4LzKp7LSoD8gUaNctr+3I1n56Kn0ztNF3A
NFPC3XfE3XPIkNBNPiAZfiA1.hCj.GCvAbLf6vZwPMFPANFvMNFxtXtkUtSe
d4kevZafODe3vtU2e7fcabQSE0oyvFlMRdZc58wqyNG6IAoNNH728xTnu7fE
h5zvur9w2NTqsdybgUPNpqWcmiRjK.D8NWwf.EzOVymyp6eZq8nBwYNWpGLT
jnGRc4rhW7+9E5SVXml5jrvtfj+6lm5CfIqS2rO4v+X1Fzzc6c5CqtDHRDew
OmrlCoQJ0PfLFV.EXpDyMJ4JCyaG6W8zFsxFE71SIUV9EkoqkELT.2d1KFmL
HVtFs.Laq5YaU+52V0nAvV0PaXZfrR4A4+twiY47rTjd7fnis05gV4cJw.WB
BfFG6EsM5YEGrU6WuRwj9+2pjuzDNAJYqyRg4JQoPEfH.DkfTrMLWE5qfoBj
DxPrrnbUhkPJihQHQ4nbsKVEsEvmxoVulafcYMmm6RrYYnqQwmMIBsxG2knz
FDm1rH01Eq1jn0RhWCPDqOwrJJ4rHqlTFAcKqM.4sgHysU4tAJ60i72vjA2h
b3VkE2p73VjI2tb4VkMGf74PjQ2E4zdjU2p7Z+xr8K21urauxuaRFta43MHK
OH44tkoWkCRU950deu4mPcl7OpFGaTm1u5MTh+d02rIgg94I2nPQ0AfVXOHr
0B+DWV32c1G7lpRBKKMbnQuGTu4tTEV0L5IGVvSlkoFPONGYRBcaWolKdvMw
vhaTobA5EZNL+lA3VmdbYK6X4C7FVoMgJrPGCdy.cKqYqm1bw7PfdLqFTXkF
nHDlgQBnlRje6v16w0GWsbQXnIYbPSnjTBMg.7jANKbLppfw9jCJzPc21YiN
QnzCaWi5htpu1FbOVs8b.dT..OBxLRswJ8yKh7X64qzLIpOIZJxsqCKmzhBe
StBIlPqPPf3WPqPP6jiz1Jj75uBIPlzR9WV6fBb8gClLqOuF1+TyNekkneby
OktZSDwifbFq5a9wUKWV2rFcbYf19x.NqvHTZQHSsyvWBJ9uW7v+zFxoWKHG
RwTiriaNTu+ETft9LhHHl4zpyRJbs.QlNKP+xRUq2IBQWX5DPSKqHjegcTkv
VcDSkUmWC6cpFYy0skNxq8P.dgRXnPoRuUaLCpPRh9+wM4s4FCqtJ2RCNktg
vb9phv3gEgOoZzUBjQd.4x9mrVbkWG6cEGsNVApGe05fVFUaB3NnZ0GkKpNf
TPW1yht4hF63.G6LwzarCCcrSldicPfic5DC2ocfdWaZoo1XOX5c9zarGL8N
Z5M1CldeZQyXjhF7fugY50avi5xfmcAC9BlznXjU0V1gTMrxNqnOwedf3JWP
JOAF5nGz5kv6O93m8E6fvwL1AAWZrCRL+mfNG6fcK1AQhrXnyDfJvrjOWqI8
bvCNG7fyAO3zL3AKmFf04wuO4fh89iI6hLQy0Gzzj6Q9NbNy6YyQWr0OrksJ
LZgZsG.QH.GfswCBB0AOWLNdpnanqObEAFEbUw8tJtJA23vZ.DsnQAbU+90G
Q6GTZ99rWvEOJfKDAqitP9qXVBP53.rJMheMwSHO5ZsrEvmcfce43KtIIYD5
sO75CXgvw.YcHKCZyOwWCDt93LvFC30kzrWCDtsJPiOFnqSwYjWArcQmcFgz
WHqC4Y2z7EJnjqOgYiyAHfBWnK60BWWeB0FEhWWvKV7Z3LD93KLNztHfzAsK
3UhHMeFWXLHccht3IGe2Vho20owK0K.ZGS3AQwWPNQE.hRssCEHinidcwjiD
sTOWvE9Pl.gbaNHJktaZPu3VmpsbA+wnVkR95UjSvm+yooOG8WA8sPLvVmIC
jQpM5U272oHMeJr2eajd2uOvjLrAlF0VWcbAljtAltdVk8qYcrxq+M84iSGe
UM4qSO96zuOOCyum978YM+eFnOPq3GzR0PEFAbpfzTEza1SnA5MzP8HZPdEs
CdFsEuiFtGRCvKoA4ozf7VZ.dLMLulFjmSCz6og5A0t5E0V7jZPdSscOp1tW
Ua2yps5cUedXsYur5wSqA6s0l83pKFZtj0379BQlSC5bV5XSK+nqOjmCj1pJ
TsKTpQM74mTwWuQudKLqSR2qIgutT9q0Jv8q1ltNdWDrErGgGOvGxyRtBaxT
.d0B9V0YaC5kiGxSA2t.esBiXP9t8b.SPm.SFeAiw3PNEIQRloL51bNWjESg
MlTE1IjyrWoA7ttFJNSxB2KEMEOqMrfTKtVcFhvdhrUXkpY9EQGcoCdD9Vdz
CGtAecRJilIARS8hh3GWtJ8GMp49geHYyw5j54JvGFDb+Spyys9T.49lV+DJ
dxYbuxBi2253VJEfuHIABE5n3ECwba77hUufRcDy+E97vSQHLkHAH8GivPbB
07JABSwNS6wBeEnWFC.nz9jARAfXek5RvZgRbgSRt4oriPvqqupkdaWptmpj
etrEXoyumiGReZW7xUY7m.0tmZzK0ODp05XpuglUnUycWm1ntdFgr64DQ12e
7g3KmvpDQfDPfbavcKoDN27JBRxMqlTlyMcIqSz7zK8EwEJACTaThCEB6qHT
.B03JYk3MmSgXyGCIwpAi4UTHPG54M8ErWMRdPuLWdnfTeHCgsRfExRLJ..H
o4uHs9LluiOrZi1JIImHPwRDjYGK4T6Htffal.8h16dhdLfsumwVmxafEm11
J3.pPXek2IW0MvLJvB0L8Ob6qreqSh8uNVdJZ.Ek7h+8sIah9w3M6i9wjmWc
e55k24bUM9gGpRyi0zDFbmjCCZ9mjbJ1IEyiOYyZ8+SsQ3tTlHEPA6waJ9qI
17VoXMygUAuH9lUlzJFkciqhst.j8qlXi3ffytC8DKId1F+oIn6JUwuDJMkH
BktEHYwsYZlwDJbpBAt8ATmAgKiNZXEGUPXRt.f5uJPgIbgV6w257U9+JdUq
OYybv5OJ0lr3vEra0PWV3LBp0C7jTxn0LW+t0GSbYV1tg.tzR.xYDqlQm.Co
9RvILXrK8KaFDz3ELfdhGNdhiF+9uFOLfA.oNzkUTNGiQVdlHHDhmtfweXWR
x.gFFpBr9G6g2zmOY5BD+WIqWm9kKGIJ5c3+nw+vTI.HBVmP0gj4VIkPAznK
.UQUQmj.2wmuOY2ePcFqAg.RyFAX1NQUpHSMnBrnz+IEXrydfLMZzyF0oUbn
MawvHLFVlwMhmYUHEMkbRxW5Eb7xoppXbLNDXl7RLgAjYFGiCoc5TaS.xxJO
ipOfPJXFth4nKJ1.Zu.ZTIDB9tlUkdfh4reZ+wU9BorypPvqCTqSS2RUoiE+
z9gMzTyikZNy1nWyBv2a2fS2Wej.NNwkti38SPtcCbZ.BNPsSh.vTDTVHzok
3atPmFMAJmm4f3unCcZz.u6OCj+kQnSCG3PmVueeNzom3gNcVVXJoywN8brS
OG6zywN8fD6zMzd8pIQZ7hiTD2pNkPXUMENG9zygOcuC9ygO8alCe54vmdN7
omCe54vmdN7oGD+DMG9zUYTLG9zygO8b3SGDyi4vmt+3aNG9zA.5ygO8b3SO
G9z8f9jygO8b3SOG9zWQzXN7omCe54vmdN7o6WvXN7omCe54vm9VN7oo2ZQO
M9USvS2PXVTx+niRqTvUL+AA2vkj98aUyvcwq2+w3sIs2FaDCb48lSoM0Ha3
nWInrW7kNJ3aVi07VtGf3fv0W6.gHFEf0Uir4UCgaqcyFhbT.Ym8yF1qElv9
.XJXb.XWs0lWYLK7wDdjHic0+UXzWSLK704q3iBH6rSgv.2xI7luVEBZXORg
rbuBgeykvavIPBuIm6UH+z6PCrhtxeI0qPvfgMg2jy8Jj4DdaNg2lS3s4Ddy
oopmS3sZ5YMmva89hvbBucEA+4Dd6MyI71bBuMmvayI71bBuMmvaCRj8Lmva
UYTLmvayI71bBuEDyi4Ddq+3aNmvaA.5yI71bBuMmva8f9jyI71bBuMmvaWQ
zXNg2lS3s4DdaNg25WvXNg2lS3s4Dd6ltegvtwx3s7X980PJuUJXp8sHAGm3
n1Uhug6sNdQoOuaudVF1axkaU.+5d4D3xWaM3mMcCyope1Blv3rGgcX.RuBi
OQWFfZVHi+HjN4GgnI+HbxuOQLw2mv4S80X9DGAYS7wGEN02iPAScZPxjWZB
QL4GgjoNcHAO4GgcRhL9ZLBgSd5vNL.Qhqv.D2kEY3UYDN4YX2ocxnqv.D0E
90H30XDN4OeBBNwU8BM4OdBZhifvNsM4pLBm5mOAxl5DgP5jeDRl5KxSdUWg
nI+HbpKNoeGekMls67sn73Nv7rnAe8UY14If3p5fK+4TwkjOEWXtTbg4Qg+X
dq83cqkXcqpy4d62EtqLc6FSeD0dxOhPIHtnbhnOxGhKJWH5k7fn2xAhyZ+U
SAZ5kEdmWX9NbY45vfuGqV0voq40vklSCi1F6lycgv1f2g7UXzlSNip2yfeU
64hv4G+3WRNHLp.oibMnyTFcK+BF0omynhHrI34u12+rwO6bE3BySfKTHxTR
WI2bMtLpKWw9+Yr6Iz38ez14zbb8G1r6Rik+wdh5Jl8O6YZmhS+Qdl5Jd7O6
IZmhA+Qdh5LV6O+YZfwW+HOIcGG8gMKCL14uv3le7.jFiO9ydQuSAe7nMQaL
12OqCr2w3c+Bh08QCfZNl1OCIycLN1ucHiNDu8b4ZT3jxee7gznuWWR.uaHl
GE9NK9EFRL2WXb6MV6aJN6CHF6cEe8unR5oW8xxwowTkH69kwZ4H59KpootP
89sBO0RkwJPwhyZ4fylV3Mrg88o4P5l8IkJR4Uhb6BEgTmEEOpHuDiqN1AVI
B.q1wqMXGAonwAu7CTauLIq71DSwwrrlgY5Fodk1fRlSUPpY615g88iqSiOn
qNwddw5U6M+eAxydXgoV0c6knr2h0eKxBx5xOInwUuhUT66ZtXm1XlLzb8g9
NuU6TOqpH0xUkUUHzYci2y5QkpEcO.3qW84jEFLtv.3ywuPS67FNsnnllo6V
1z5.jTFapmGJvKbcROPx38TenziKhPonPk6iBCacKa+QM9qmXrF.K1OGqNqX
5ikDdTTzQAXc0lUGzSE6HtrDzB219Olt6f202JKVGeNa9nFKZmto+ezcM98m
C.nFd+0oadJ7Ge1jxMMSo67YEgckh1WA6XzqxO7vl54j3MMrePHt6x383h6h
ZmhtfzKrsfIYGYnrZygQiA9edczS6ROtUsKpI.R1H.gtT.hX56ALQm141i.S
stbPoVDCrMFkfIj.sLDEfrUqbmHpy1fPPs.ggkHbazCaOpKg06ZXoPBNGcGZ
l7D1CPMgYxYOVmTWnz83nl8WTHimZ0eS0o+RxfbWe9an172bc4u8ZxeS0i+R
mJJf5vewZvOJqw9frM3Ca+QAyqbFzFq+9AT68cW28gpisRgBlL+ml9Dtp.+A
V888T48Cqp62RE2u0pseqUZ+Vpx9sWg8as55GPk0OjppeWpn9dpl9sVI88WE
88WA88W87Ouiq6rh42P0xOnJku6pj+kjf1NKTT9pr8cIE1AAzlQIl8NbalUS
y+sCa78RcmVo4UxNkhzQq1D879nU6i1kn8YWxxHE5UO4wcVRpuNs1l6i71jf
t6sMaObuL8dykUaAZsOj37fc.C+dtUKFKuePHoF+303lZY0PoOyCZIS9Z0P2
hKIP.4ktdZXqI4J9b8WTdmh0qu5+P+sffF9EjL1a1JyA1nQ5s15geVVzap8G
1Sb85liE61ZEgufN0YX4px2Vp0dNrcitLl5Vqv3QEolnZ8nIk9Nh1qNEv9Hk
F0pGaT7lkYZSoTrJSOqFUnBMA.ewvB9VNFCH1GqQ5LvuU.GNEJoPS9BQRWRz
uIdY9PmsXvwtHZzgw2TOs6gS8LFehmot3.R9qqW3PDtMAm.ANgGKqeHZcz8M
4eCR+64Ka6+JyKDHSaYNL+5Lp9a3PzplQE5PgJDns8JhPgAKZ2.N9dh4ed8w
ee5OD+uk96N93uO84so6SZxoLk7OVoXbgBfRJiy.BAFiMA6hdeCCIQTIDXyS
M.FBvRHEgjDrrd.8GJ3CCB7sdqQ8zBzWiydpILO0.ynps9ACRHDqKcoCtqZP
K.yNmY14LyNmY.LFz5UaUPgZ6rWKlh7dBY7kdBYph0hNGD3jrHrTmbITfNPL
4HLCiDlhmKi2W0N2QxTaOp13zQSQ2uU2Ym.KgUEXIzaLfMOZTKUwm+fle5dr
OC8bIvMJDyrADKnBrjhyN.ggPVBWnzNhAEPFAvLkAZVGJCzME+oWe3e6JEDD
.rSGVXWnXLDDpCeUf548S9..d1U.3IbVMfGydM.7k41bX2pm8A9LwUgYCUny
UABhiz40iMR2o7WObaZE1kWClMtPcf3UE2l1.dN3ZvrgfqC7X3qNtM9.dB3p
vnAQsEQnSZQ9JA2MrY7g23qBGlZvs.9Zh8hW.WbM3r.AUousQXvjEwy8LbSP
dkbioF+a1vFll5b.QgiXJL6rn55OFlhpbVzrjnAr.LEHSODA7QXNvGemKHKP
.gBoxR7TcVoioxJPFBENcY4TNZpBrPwUvtHXJ3U.vFnE8fvA1ldXs2upe1P7
stM89ozUahH9PVfe8CHWLwq00q0XCPohaLrbaRxm5rQ7j3qfwnwRbUsAnc93
cSDs.Vtxqd.RzPmtFrEpyoIwfLFCV8.pRMmkYiikd.sBaw+7pmKkAo0L1FeX
wMNagDJPTAGKzXDhnMkutXxBDDDRPgTiw1XvojBTs6BDNcXk06VPDFeq6CjC
QTenJ9JfpuVTMk4KaE.Crpo1nXQgjU2XeKhkMKg2KHSjCqLdF2rauNW.HaZJ
UOHXNP2wQDWAM+wlBvSYyoHucg5v8AGlNvpqZ4Wnf2p7KfXzsH.ep+Waf1uE
8dazGWwd3pKqea2rVduImHdTWGOh.QuWgolWuOh6KFWFXuTy.rRFyAn6GD55
REEq1T.vbXl+KnjNrtYLu3amJw6RCKcVSpmujUjMUokJTokJye7vG0kqdX1s
o+q51MRG+5OjdzlSLXOGLefsauS9dHZ8EXjUWSh7UyB7Iq3muFWg+nmcj8+x
7.GzCVFtHlr95pM4Cmhqqsc7Vc08bW5pkQ+FEG0cIwlW7ojunWCUu7SG2cHc
+J8K2ktN8wGUu3w0wGxd6G1oCOReqWHe1KCLrGblA.0Y7pcVItRTpXqAMJcB
mFlbHeOjBfOr6Xx1jXe4rqjOznnIKaIjZvVVTUMUrTiQ7hlnLcyiqVlr4gDe
nFcfM1EluPgYBABhABpDI3tAwrDoYr.QmsOhBfXA10+Uv2FYYV0rNt9Y4h5G
cbyJ+icJJ9lXRMKpr5KROypopu+wjXcBcrulptO93A0cbPAJ60BYhXjhhPo0
ckSw0F7UPsVHuF2UJ+lWq1bFx0W49xpMKS+hNiQLqOu+ioaM+gdg5zpZAkj9
zWRzIdgNgsUZCkycurlQNVVKIRk3YMGNFp.4XQFQLZ.wtgWjMhObr2zwVvSq
r4muId8So6Vc3iOW9nLssR5QYVL3JblEWKrbvTU011ptC3gs5NjY+E0uM+Xr
tEQpyxQr4cvfvsWqmR8vUshj0ZEdaf0hxhwLHrZrB0LBewX2nUKLjmQx9Wkb
Z2RaNqBF0p.PmF4lvhPwWrwwNbbqvGcoDU.gWih7AuSDFhqvHj1kVJO9ZTHW
zNRpijn3wdH1khgSCjsWIF.cZnaQW3TgA.YhWhevcoF+fwSIxhtMzg9G5nI7
PG3enOtDzXZm2LN5zzcYSG4pLB6hLWz0PhVC6WZXY9ZTbsvcQq.nbhWdsvWC
HD0k8x3I0gB5zPGJlRbPgcQYQN9JPW.6hBWxqxHrKBPyO+v3NBAxds5SV1PA
lh+RKVJ3kZRzwkqR+QSU.5C+PxlimWiur68ja6c2RKwl.glF6NFh4HaywV2C
zoNzguZy7tPKelo6V5lWoaF23Zs+tBebzqh1wcu0IK+9iOD2CcBUIf.4196o
jRxZloDjjaVUnrZ6CRVm7bsd8ofwre.A.JD1WQn.DJf1oJgSg1NxNRhE1RBG
hBALo6O7d0H3A8xU4g.R8AD1tTLGYIjD.ftsJ55KowlbOBKQPlcLjSkh35Fz
3X0y6Oax7xaxDm1ZI3.pPXeUiSjpaxXTfENY5erMv7ruwqxdr25sgr9uuMYS
zOpCRneL44U2qaRvgziZwm5S4j7oKNq2ke8ZQsex1Ie+O0UvuKrQ9ZR0iR+5
JMmdN9mYUJcfmE+pJSHECpv2Yat+7eEXSL1tq4DKAd1FwqKP5viVmQKdlnj2
hjEI40L5HT30d54L1SBaBd9q88Oa7BLhyYfV+UAvHlKzZF8Vmup4O9qBckby
03xntb4qxyX2igVpfdrJrEeUkZXiege25iImW6e2kzQntCUaj7eZhJyZZ0W8
I5tzuro2louL+nm3EhmHyze+Wi6uIJ.oTx2JJiiwHKuHDDBwW+I5eXWRRONS
Mql5D0FaOTfVe3q+j7+JY85zubdyxhE83+norGSk.fHH8XTGnhakb.Elxvs5
yROoL+0APN978I69CJc06sEc8VVfg7lpTYiZlwvhR6tJSzcVE50yzd3.6sNG
8cVaFgwvxrc87rS6qnCjW08+ufOmGkPECZvg.yDSh007sLCZvgzf05eZRFcH
d64x0nvIk+93CoQeuN5RuaHlGWyd0wztCbrMJ8wG2WR0yRkGBbisaBv41wCf
D5BHhgDvrZBA0lQgpydfUxAvTadIQDysBgdsUHfPLaOPvluWY3KAL2IDl6DB
ycBgJNCapzIDZKkmrbuiX3yMQFG3jfBAx5y0LamWxD5yzoSRPoj2eHcSW50A
JMPT7jNnHCrzqMDO98XwUAVpKLRx+8Tp6s1V5M9OsYuImSN7w3CQZVp6+X5g
uEcH9SlKlDo42DsOVsuJQoQh4ReVA.o6hTJFF+YcR9l2qH2u+Xx9EmatoLv0
ILDTjmNtJpdIHuIZNIJBH6RThwVVWiupXDWNrUKHH.m2pw3J0QfDAKKocdaj
3VqhV8NusIZAXX4ulAkbt5.ybLfSvDf.AztS0c+syMRNUp7RwKsJUEse0Sed
uObEdA3ZHoXF8kswhtTsOe6HBlslgS3gkYW99XcknlCkpsx7rB4yqjrbRSk4
H3+cGzUhqQbgI5RXqxuFgsJW1w1pKbpDTncZjimRwDZWhXcAbR2pam5lO6iq
1puuF5Aon658FFpDVnrR3tibUWrjRb5l30ylJKPSkIssITjsqgRsUHILctog
NaprYSkci1zPWmFuTaMsHgud3v.2BGxL9NRjcnsI1QcayLNJYBGR1krLJVmC
.QpQ44Z1Q4vdxDosJsJ0ALCPxUmPQxDZuJwlVUKMKNtZy4BiCb4SCkc9NsgD
HvIExY06J5giGRe7wyE9F3J.BBIewjsVi3NYvOxgOFYNcRj1D3I69R5N0U9n
RHYE8Y6DfNzcggr1GFDaJqeHwnBosVA1uO5wgpuKgBV1h.rfJDXAihoLBgpM
EHW18pX1Dp3UmY25G2k7+bLYyCe0GHiFVA3Hf0I5JhNBPBzgqt.KEDrni0F7
oQ8CyHOWoPn53gQu2xNfD8d0wV1pKgXmXGD8dk50oqSe5qE4V3qcBwGE8nfB
1BESVFmhjnLI73tzkpWtxjyVw695znMXEu+g3kIeyGxRGVGJXOxKR2P6n.LB
SDEp88fvQ1SVbXJTL0nCa0TKCyNYw6PqeZNrJSMCj2jFhSqRoFYnqFxVDV2c
zKqOeftYn8CtLwb7vYTIElv0sE22b4.jU+CCJnX.hiMYDj9JXIPP.pKZtBf.
AXLFPQHNm5Nv4GipASntDBiBXhKX5t.MQRTyNhcZB3PDfKDJRcrvjAHJPgfI
PgPvQTN6pMyCdIm29Lud5uMtyGTOOetYVIaXx3YyK70xLuKrsHf4xnwbYzXt
LZLWFMlKiFykQi9Yi8bYznY9UykQi4xnwbYzXtLZLWFMpN2lKiFykQi4xnwb
YzXtLZLWFMZVr0bYzXtLZLWFMtR4AvtjGR2sro7.n4xnA5ByC.BvFh5y4Av.
jG.JVmF2KaCzLgMW1YR7bd.LmG.y4AvDMO.ZqjY.A.vhyNE.t71BrMoho1FB
LEbiExf5Zzvd0ti89BRsAuY1CskvHVWSihL4eia3s1FAIg.8SQNvg7GVXDuQ
v7oIEYq0nE40uFsfnnEBLFSvT.UjUByPL1zsjszdyTOcaWpKN8KMIwlAOXaF
Tfg2ZbISVGA7VXP7Gm5Xu3GN.7SXI8vYbJ6d7+Os5GxvgMBdIxrxTEtqwv6Y
1.jQWeZTcBQZWjadSNbfCiegI0xv.i.HFniToSgc5+MQPehtgfZ0fEOGz6B4
i5+zeMI4RW8VTqADoQ.FDIEuTUNCuBBMcRWnk62pOlo+rn..tjkE+D9jdYYw
kBE4aT5PFtnKFQmT28sm96oRAeZa5mR9VjNYiN3qbOIoWxxEtSoevYtbQVvk
PFApizwrZfDgSWnVBQBDgC3.rYSkn.WtqO9++4aQsd7C4jmElNMvTfOhJ4LE
xqyVY0oropC5iATHmxs7y5x9lwL+kZKqvzId62T5S15JkPLwWoxE3KglPOjx
TJdA0E9O0EkzaxUm.4fQYSbNXPqODlB7rZMe9HC6oAxfBnUZaemQeS6L4COv
0DALhTkWMkvLjbTnjZo2dUT7.kcogMKyxxlQMaXjcp2qeUJugmSqCtxM+7pk
aSU56lsLCk15eut1lHz5WCr+niRJjRFDuhhD0uuoRU9qSfCskRqHZ5NzaHWS
uRUERVWJInWgM0DXWJ9ihqvlZxTe.1oLcUNonN6zPmxlREsTTW1XcMHK5R9B
StJ8HdbWkVBaSZIx5cUr.s.pOvFUZ+QH0EdIYUokNtuohHmtgNBgewk3I7Xm
MkXH0sgN0OpCG4gNnCrjNMQG2wXG.WzPlN6yIA3bR.NmDfyIA3bR.Nmh.0+B
mSQf61FodSqeBhVlbvVkKZHeAJG0.8TiC.xI056lYoO.DMm+.CQ9C.ssbSjs
ABHv1x9sNp.myef47GXN+AJcRioR9CzZ3Fiu9gaLlacVqb5Few6ePsC1WLXg
pEbg6TCtrA56L5lFwc4BvNDzBgTj1Ufnoy.jwyhaiDTqyGmB3Dj4EmnYm5Yf
gIhMRroX1DEknSAThYyTvoKJQZeOmR6yAGmnYYFA55rmyVcB7BT0Xxq0Nz0b
u+hvJTeDFObrsaSvf5p7Fki4X.wVqjorKIQobL3boJoQt8pmxzWXDVKUiOEL
5aoDNvxqCIi0rs0VbVCEq4.c+wzcOGen1oWZpUiNdhyaElkWeTlXCsCrsI+b
Khxs0qg8wxhBl5A+IvjOAXEqIgDiD.vKcsAHjbSF8mlpax2hnpQNf5KSZ3CW
3e1qKN5ghtmbykPoDAMKNBvs7ZiNpoM+x2xiXhu7f.jFWdf.zM45S7gzk26i
iFgMz8gdaBNo.UjRSIDICPIraR7Tcuqd93yeSqHuOTEOzsjdKppjBCwT4K8O
FaZle6Ef+06wu0fT3n.oPEgpVO9yIMVb8PRZ0SndLduOC363qpIC46wX99Mn
eXF02mg8c30qfLveEi7GXyB1qg9CzX+gZv+fL5eGL7eKF+ObG.DfS.BxQ.A4
Lf.bHPXNEHHGCDnyAB0AAc0IAs3nffbVP6NLncmFztiCZ04A9bfPyNQviiDB
1YBM6PAWbzbImw48ETq4rrPmVaXUVJWOsky1Nedq5S0tk8ZRbUm69t0CbjZB
3G6EfF56ZcF14iGrGR25cBhz95jucFtoiGbCscU0L7leyf2cpy+14E.z3s.D
X2.djWBbdZhxq.t5Tv0bxLoG.RTfTxmSmC1i+kan7pM8VHZqyBWaQoOntgAx
M+75zvMXE6o9JQu1Ihq4AH93srcdclX2qZM1chmdqeMz4ha0K8sZrjyek375
jwcvbTi7pfqphPMFTsiufdFeaoqG2IyRkEE1s18isSamY6+TbQQLdKJYreNu
Uk1WOZUWc2E3tQdQwYQtnlMaAimlpmQ6qtFzGlEA5zlh5llyY4vv8RSSYrVC
KP0yTYmk.fbiC4oOW6DmFflQ6YSzdwHCsiHCjFHxzO8X6qGv3r2a6ijA8KER
FRWIY3ggL96Q2Wu4KZflu27TBdlnco+d+ZDY5JaUW8+6Fkj5ui1FP5u4x8qW
jWRZOc3p3LEu4w4Uwy6YlmY4wcwUxVtZlcDLrgJBBX8tKCtfnn3kbIIO7ajx
arhS9y6OjZZiCdC.Z4v1CGfVKlSgvEZSjjabKMfN4anCsfuOkr4aQuOmns0P
OaThwIlBmQBFkAdoZBCQj4.IYTCjjk62tPQc3IXR3VeZXM6tzFTrTBXNVRli
kj4XIYNVRb3v2kINBOs23ueLYYI6eOeO4hjRLC969A0VPC6vk+82EpW1s9SA
Z3HxxbgBldY1zzGeL6IerI60c+KqTJKs6qQV9C+JE02u9u8Os6Os4+PmbKmT
L8WYqL2pQlBu9sP6sn+2pMOrKQaBuneq4jP+lSejWtkGi9U1u8n+teq53F+0
+0QO7QcR48qVsA9qi9spO3u9uXt4CY2l5J1O8g+W8+krdeRTguk+9HvuNp5m
H6EuK5WcZH8qK9k7mNn+sB8fpaN+ax7r+auaZ64oUap0mcpoK6HZ+8LxUzK1
e+UjWZUi3VAaxXFAN1R4KzF4Gb2Eo7onwuYc0TDAaIhQvNJcbry5fUTpodvx
UGzq4UZS1lRYV9upagoQw1EtC0phYeT5WhR174j0JkNqdW9hnpRalF5pwdNi
J1BZ0zJhZSHL7HkS1sgmOpzV8xwSxvhmTvsBbpO6nlc9gzn3OmtZYziqiUeh
kQwGND+vm1etHLFOrHLxxlmAfKXHAlxjXbl8Lxx92oBBu+gO97pCJDVcPtmR
1ct.JhOv.ZV8OgPgp+mBQr7tvPFw7TAOiuee55iGRh1jtRow6iqSSOePcf4q
hTjm5bfSAgRj5rAHt.ixZlJroEYZVHcn3CnNVP5mSh9G+8mMpJGVTExDKrgu
EeAkBx5pSY8rQ7zngZcbi53seJ5wZA3aIfhMbcetdoJhjizDnho.GJIHHVv3
VIYbtggQW5KfSJ6ye3i6R1+wuoHihfTuMIP4sQR66pXu.wrvadiSnrscWplE
ucIJJWIECu9rzvMxTHd5P6auKqYLuqYr9XMCSElzUPslQABJ4jeDQcoDXX5L
uU+2jHaos1EMd2S5X01tLZ1nsH581kw2wAQuOasDpdq2qWPsEFUeEcuZoXc0
hFt+x+7DiAaNUPIIYXlniT.SBMH9rRsrmShVt5wGSz0LXEBDc1pPLbBF6m97
Ixpsr5fGKvUKhMbvTRSDk9x9bvuTNbPceJbCxPKvbAigTWv1Eb4Sy5HQq8vb
9.21ByzF.7KutVHTLvm7HKJJjjZVc30QuJrKsBPB6JznS5VuJTdEZ7Z53YGE
JD5t4K0aAbo+l5DIKIQH3EXDBk06lfY0mmhW8J.g3PgP3UEBsEzQnjWQKdIx
60s1EBZKgOl+5J.wA2vfb2Io5lh2U.tLcbwR0+oPbPdiBiqyzfLKK33MuBnT
vM9IYanzfRHB31JANYgfAX5O4KA3G0VaBp+diLbRAcgpCNk5eYcZnaE7LY5n
hjN0fXASoduVmF5vIUK3jv6JpOcHX5xPGNo5yfDVWzf8Zzp9HcoQH1.8e0dY
MLqRKoz1fqypOHh.PXSMhH2bh0euoRG4ra.B2O0Fd5NzgjI0d7NMzwSp83co
aWlej1IaqsFdUZs0vN19x6Y0+4Pi5pPh53SHIigA4JqlcvfZuyXCPcowzCuF
cgZ1j2RHlgHrSCQzXODAcuYdOTGvabaXvxNr1z.JciNy6hxsjqwVaHryasQi
dOlW18MNdsv8b+B0c+BMY4SkJmVkiLE5YzePQ96OnRa0TTxVvTReEPQtGNHn
vZNn409uJsKkgElz4029OldnYnh0HTgN2VoZdjQxqBUMzFSZJrnFKPxlPQMC
Q79uaylQMQEUgHZWa0riCDsLYc7W+VDEhz+qQjRz+DSYHkBQpfT4uwDCo1G+
wlojjCE9.EfZa1.nZMz3qCZU0y+kvDTy6t.8YubFgZ1u+g0Imave0N7UcOfY
07oe41uG5LXIABgqcVKZrAbZJAA39GBP1NHxEhAXGXvoug5govKvhKsNK.N0
c5esSi2liWBZ0oyCCTfCCIdHGEv.GETxPNJ.gNJfC3nPHCbTHDC4nPDJ4IdH
ILDguKgU1ZP85vfRCcWxPRYPqUNyZZTTmPttE4uNCMTyiLvvLxHcAzJeiUMv
Kv1.jyb9Dp9eQn1ySZs2q4uFJZARv6OQCIIYnLtECoPLidngs+DM16LBerAA
3wdyADR5h3eu6NP53821oqeIGcL+0PspCjAirhQGY6vfqlWOp4Kb.v1LGg0r
3fz4aLpD3ffUU.vGRl.fv2nQGzwAKT0HG1gAsqDfCz3naGzANt6RCdv0M4Fu
bjQSo1pgyL9Rdinq64+noxD8geHYywWNZZdkmy8D59mdb050m7YkK2GjaWjL
OaUzC.k70ERRfPg1eVXHliXlWg0gUYUepY+bv7OHgRj.iivHLDmPMuRfvTrw
4XN9nnWdl.nz9j.RgsFci0WBV2g62Eu4orZWGubgR6ts6R2lt6Tg.bAVV5yc
7P5S6hWtJ6b+.mt63sEngzI5kqJj1cOqVHVU76vEM3oE0u+3CwguPV1wi.Bj
aJBLBIknieX0qHHI2ftTVIBwj0lZdUou.cREYuYA.JD1WQn.DpFxVlLfvoPr
41QRr5gadEUwhPV+CtW8jMcwkxOZj5lMDRPFGYIBD..jT+KPa2Uym8Cq1nKQ
lImHLvRDjYe14TWHtffqSXzo8.mnC7rMnCjjk2HHNQ9K3.pPXekyAc0MBLJv
BYL8Ob6qreaix9fBvYw7YSw66eeaxlneLdy9neL44U2mtdYY6pF+vCUo8v50
LCtQxmVZ9Hjp0ynAYS2+w+vgOX9Z.m8VO6hsqWUamy5j3c0iYHoZGK0tbpnD
33V1xIoZdu1M1DNvP7oo8vxNriwWvJUJ6G+il7e7U2NnN8QG2sP1jBsscMsw
BXP207o8qWozl4+TWmfCceSU59R+ZfGuOG+yrRkFzNrEuxf0b9zKdGliETKI
3IAY7rMCiC3TwqcAuRpT.Po4FRVjosVzKgBGqg9yI62G+Tvjgm25U+vxq.iq
78r0eUKLt3Bstxu04qb+Quozdt9N0tSQT0WhcfZ1r9W3DJEEqNnTx1fL32s9
XRwRzp+QtKcofbkNAFgAmlDR8kfi3jXW5W1bQyhWF6zS7Tvi7r32+03KaR.P
pihYYkywXjcONBBg3waR7G1kjbgyByp.V+i8HZZEmFuIvOn3ru4P7EMEDD.i
YOWICnl.lkDlDJoi273+JY85zuD9zntF3TI.HZUGB0Qu4VIBPg4HBpOGcbzI
bywmuOY2ePchuKZ0he5LMTkpPTyrAVTJ0fNI1YUrUOKNyyC153uoi0wHJpTY
FWBdlMbTqcxQgewKy6vW8pbNXNDXFzRLgAjYlfhCoAo860cY+P71tryrvg09
93CoQeut8TbWeLFy9Nx+BZK1uyFWMFy2th26Vh06pw4sUsMyusPn4YVHptri
AOgLYgBhVz8G0EFq7JpaoX75TIAxYbA5N1tbWDWwJkEvbn.wfYkoQcMHE1Vr
2Vs+8jCtMzudb0mdxoSbzWdbzOdb2Gd72+cb02cNQt4pO6TPY5B8VGpzVzML
Ai.yVljHhhle2YO0okdoSa8PGu8Nm.5YNMzqbZuG43o233sm33sW33oG33u2
23sm2zRutosdbSn81lF5oMd6kMM2CaZt20zbOqoaLsp0aZbzSZZsWzTuGzzi
wBtk012h1uUQNsKd89OFuM4CZBn8MDVqHT+m4JJYm4UaYg5PGJMJxqaL1ZfR
GxHiwN8UxAvsqTyJ+.Gd3.NH1Jo.AUrEYHhA3.7aAfac5wkaR1u2O1wFLrCp
aUalev53vmXI5PxaArSo+6CIMgYBd+iY4sGAiA7gXgE3.ZKFvuMPrh74Z.3J
0X46UfCQ4NXvgH2LL3Z.wvxgBwfRZcDiSukXr0DlIFLLSmPHU4nIu9BCzmDT
cDflxxpKLEF0e6Yo21yaKA5MucD4Z6HEDFRMlfCY7AGHykbwoH3PuBfisYAd
gvwfjxUvPiHR7PlYMAGx03gMj4CbTTsSwWZQ5UgwsTCxCmZ.6kTSL2xoZi9o
dzGTmC0dv3JFxp11J2aobtoAisQ7Q1OTs8Uw4Ew17eexjVtKLA1EhNNsK6m8
BsPcKVu+kien9XQ+cu6uWa2VHBE8N0I.XRpfCizl8cW5pke34j3Ml6gpTJQF
IDp+GIwRBU27sNX+ZxuGwBAGKopunEbDjKxOAiyJoewEDNyoIEQcFzEpCEJI
DJOS3lN7qPDitS3LE4o9P8yCwavJp+T5pMQjn2m0Ls1Gcxh8Na.Qkm6jtN2I
bKUEDa6ujpS5IvX9I47nJFQcXm6JUpVpID09KwwjFmedi693pkKKYKuKbemf
CrSbR9A0j4GTSTqlfLdffP5BEPCEJjQLjMukC07tbW1nP4V3wmi1oKeG+luj
Xb4Rf7AN05HCY5C5HQ.DY1Yv4ka3E8zTNmi44Muk8y7liEKvBgDlUDpEZeKO
ry6bgIm07lA5m4cF4d+LSUGGT8fcrckgNa0FTWZ0ypuzhFV284b0ik7aEtny
z31dMdcczu6wzcOGenfCrb2cdNe0NZF1HSIXy8VjoHrwmRvV9NrqGP0nqpM5
09Oo39tJwk+p4fNnaIpc8qXFsHpWmiZraW8KOmVCI1BlJJyvAVvR.Dytsd1s
0yts97rwt4zj3lbVXi1CDe1kqKHW6fUNI+rz5rXgByJ.F3qgMQ8V6oX8ekmR
2DRz5SZOR84V4oPiUQaq+KYabavWg6TUZ6tqG7TuqOVnIGuOwXjp38QKWo36
t4gjn+miI69ptMRqO71WyLPVwOcSs.Rm1xnGo7XnrxNibAWoZuRRp8GXVo2n
VKabfAuLaJ5CpJxMRz+HBjZzofaKrqvLCoBFQLHWdR5tH6obWoKcr8WbuDF.
jM+skj9de96i+BZ.Xv3THisWYd4raTKXdWuFhxinOBHaf2qNuhdujZvn2M8b
7mzcN5DkhK5+DtvZGknmOte0CJUn9Zjhu0iGW2HSIbCBCFfsfTdl2KzQ7s5G
VFSIf3DSIsh+iUPGbbi0.6MINDdFH.8LHWEJdz5ztgmCGLkdRJffy4BLL+9j
AotTycG6gV8IDe.XYofKBUPvjb3hn3f6c6cw8ugHzYH1Ca2mFTX44wzL9wwB
lnIrPeofgZnsA6BfE1o4TjRcriKba4lfrUyvuada7CexZJmHXSPOo+KTyNIQ
YVOEItJA9gGL5Pz8QqaBbFfH3yM3.dom2zkJr+3QIsKYaxlkQ496tI4Cx9u.
x6DvnLqoSCM1juazzn8g0q1p4ttK44zOmD8u9u8O20y9vg8uTCLNOfaAJopn
SPITq8+fbxmyWIiyJfiaSICI1pjQdnFqSDYr5jfFkLJ5OeJgGN27gSuh1LZ0
KA.ArQc0FhFdADWVYMAQGWDnEHc73fJrCURmXL5CF1n8OrgE5JQ.BINohK+U
FrIFH8HpcxfaCTKWdYs34pI3C2+BNcuWkQWfpY8K5TE+pEybMgen9G+buo0M
9wmn3W0vRrI3CLL5sUe26sA4mQINktRvHDcQiBJ.8uChz6Y4TcjilgO5JOBF
PMUgjxpsM0vr8ODu1XxM3B0IhAMKf0SuAhc96UgKnTJ6TJXnKHnHJZAqpQ0j
7aQZMO84s90Yj2FzZ+MJ.qQnBOLp8Vaao1eI0LRIxViwmX88s3622LhIoCit
G0.Lm6GI3oXixK9P5x6ajBCLR.FTJM46.kVvh2D3DaynWhK1XoYwqEhK9HgW
C.s0vz5uBtx7Cq2Heb1hxcU1U6ytvTncVAQ8lsS0pOGrbM4b3Fu3f.XluA73
BvnfFvz.FvzSUt5gcTGZlLJ7RFOdjEg1rGPk69z86f.0gAwP0OyDfNLHFpkC
Fnq8qkqL8CJzF6BhLfqcnP20gFxtsCBFrLrgbT.BssywaqGKoU1RV0a3babr
BQL66UJ.EfhEC57JXJsAaTD5R7fln5g1GsXidK9JzQFZzaGivPUXiMMjLa0C
KHUIvSBMhgAWKIbHu+povlqyS3Sw3o.NG5.lOQHjCUQdG8GvqHcQnmWBz4se
iHSutMKfW5r3p23HgzIDITvsaPGmZ7prSsC8kvogUXbMNZnYsRmFC3PoHZU4
bNirvTWbvKvLFSl6+Zg1D7.j1peUhCp52YK12atOMN2mFCYgbtOMN2mFm6Si
ycbt4NN2bGmatiyM2w4l63bycbN2yh4NN2TniyM2o1l6TaW+N01q69.VwztN
ZY7g36i2mDAsliI5TawwYs+HjR5Ho0xsFFXq2ERQ60as0q1eHOC2xes4+O8Q
Bb0IQssqbUuxWddW3MeNd61SucuuZ727sHWEPX3opMxEV8jgBYsFxFLy.cf1
g+8qdZioen2ey3JYeYoHAVdQ0NWZ2fADiogAVnU8u54ZYeUVHkjdp1kepbr9
zlT0je8pG9zYPefw1RLLeBU4LOEj3SDHBBtVPTqEs2ekZ20xe2u9Os4Oswzr
aLW3G9W+G+W0JQr2b80pqbp3FW+syyZv7uJmk9WtiEoSkE7REyQ7BPuTQfwv
lVGxZtZvhUiRCx7SG2eX0iqd3jWLP8JQIeZQTJYSu8shoEDwDSNH5kVpPOAQ
tZRbTdSx+tF082j+7x3G9lyFQaWpru93UfI5FWQ4ILhVsQzZK3ID5YVVwyKc
n4i4OuJ4KlR65p0qN70hqToO939jrw16LZA+NbAD2V1bWtSo1+oxgZ9ryPqe
3i6RO9zGKd8ZUV0xuwmq+F2+jtV.W5JuDfD4Hb9YQVl7b5dEy9kKTS4swGbt
ZA811fi28TlSZu685ZhrgnY2w8eLY+h3UOp+y2uNMcqN.Ozu9yoqK5b4KSKW
aQ0CAO0tDFUsb2FoaTDNvLpnCcZYu8DCclLyAXncJKzGJlZmsDXPMGheA14k
ypWV1xNoMdgwX3bIrdtDVOWBq8jLg0b5VANcnlpe0CPdPixJQrztU26FqDq7
OuNZcxlNWJmQmcsbSlUwbs0x4tT3n5UHwG4w536SVq4d2bs6gN.U7HjgBI6.
QSM5DspA1Rnm6F26PTE6r5DX2xPEcnL+MZTJFA3Q5eGs73NiT1HM23ObxREo
aT5PWoW2c5OT5Gr5ypO0mSJdsOux9EY6q4OmrbUb9e7P5lGWsLQWyvsWPIdZ
0yJ4oUK6Om9qBOhBWK+QTtVKc5uJ7gJbs7OjVvg5rAloR9qK7Id4R4ef8JsP
hyFXYutv8e5JY2di09OZC7rQCPYzxR5IsESXaiKSW0gmLcY.5PTlby0AmcIs
Y.3Xkk6zPCHb5PlmhjPildGC2ANeEBdngQicpsgQcbsa7PsfGZvQOe.Cc4rw
jCdNZzmiF84nQeNZzmiF8QNZz+O9GN7AyWC3r25kmkc0eUscNqSh2UOerjpc
rT6xohRfiaYKmjhLssZ8F673dBTLXSu3HLudjv8paGTm9ni6VHq4ZaaWSar.
lygi4b3XNGNlygi4b3XNGNlygi4b331LGN9AEm8MGhunoff.XL64JY.0Dvrj
vjPIcNWTlyEkeIkKJdl3uLuCe0qx4f4PfYPKwDFPlYBJNjFj1uW2k8Cwa6xN
yBGV66iOjF885vM4t4rEpAOyVnC4d74sNBiMbOkeJbNrTXrYLKM1FetAFFa8
XP6k00RLoHkqIMuC4AUWmzYwtmfNxS5FZvRkBHA3.tXSrcfV4XOuU7xVGEuI
d8W2uZuqIMoeR5MNAWKRjIHav5ATrdU+fyJ7QBshlcHSjN+bfaJjUgrdBect
YhA0w19urRwvlXgqCIjST5KN7yNCkaYOsE2A0NlRVPXPHRoLu57UlqMba22F
uIYsqYXKbueIT3wcMYCfTnis3ld+.0FHZXXw.P29nJqKl5PZJcvHRBf.IFC8
.TpmoHrEBfjiElyVCPJ7k.EBEUNkyJol1cUiseW1CpppuPLDSHBkZaHkJrVa
OHkLNGQ.BhRWV6IRPXl8BBoPHK4z2ZFWhVXMybSkiSE6RXU20msPV2M8nRE9
OusdA3KTRkhcfZzOCwCGT+gCunGtNWXeo3j1TsCTT5QWHqYu7mMtsmMe3d1s
g4kqYh86yF11ylLLOaP.yaZg5y9Y+jDhPnpwL2T0nw3Yic+rAiwyFMD6lEvP
npAuDrQm8ShCBfFly5qmTayIjnGnXY7PdRx93IQB8IgtzmDJzmD9BeRzPn6Y
8.3QCgHGRfCwl6.e1Chn5vd1k6pE8ECUZHa2sXduqeDEDLlOLOaXPBRf895M
HXAI89ylDBCpJK2UqOyTb8jk0VETDT1BdMCzvfKtTVCDR.KWj9P6FRHaFw79
3IEjFafd3Ig4iDGbbHG3gP5imTHh+XMdDi9cSUXCFRnClKiyFNDxpJZOzWGB
AExgu38AIsQuv1XHHfCg35fdzPDaPLofbr1fAChQHDK5gSB.IgIQT1GOKbHR
.qXEgdhxw9rwgbLNPuLMay9OBVu8nBZWe+ueHHINPLnWnbPA8rf8wyBEhHaQ
eb33.sRYkE4d53GPXXm8AWahZMMbkhIh9wToHhTo.hTu3gzbgCoZQCw3h9JY
qkc51RVZUI7B9KeWSAXZtmfbmQVmS1XclYh0YlEVtigzliezFhczbuW81uq4
vonbnTTj1yQ1U0zBvYkQUWR1TcVYR0EkEUWbFTEDcZ0.f97BC4yLWONuLkp2
nUKTxBCKqnN2Lh5h2PTMymBbaQPY6zYkoSmUVN08342S1McyQcG7GaXIuKmw
Rma1JcwTz0yJI2zzAjIRW7XoTdLDvVqlyxnyfB+LxtndYBWHKhZE4CKyg5kg
UoPYw8.q6X74ypnyYAzYlAPmIiowPqsx6NBaUrXV8D.0UaYxyESYUOicbOpN
2rzouFfEyFmfGgAkAN8zHrXl1D7.LnrqomFfkxhlvGgsj4L8zfqRFxD7vKnr
homFiky9E2CwVx3kyLaWt7IPsrZIXDNnTZ3hGf0xXkfziOvrT4LxPkKdBUOS
TBfaefYex0aY5TFlzL0uurJoaOeq4vZnP19c+ue2+eEP3Hd.
-----------end_max5_patcher-----------

You also need this text file to load into the coll, then dump it into entrymatcher.

analysis.txt.zip (329.0 KB)

1 Like

thanks for this. I’ll give it a go as soon as Beta00 is out.

1 Like

Here is some further testing, under different circumstances.

This is playing the 40s sample just once:

So it looks like the 50ms spikes are “real” even under a short period of time.

Here it is again being left running for around 5min (doing nothing else on the computer or Max):

This is what happens if I browse Safari in the background (since I thought this might impact the scheduler):

Pretty big jump there. So much for checking emails while performing then…

I then decided to see what happens if I push Max harder, so I opened the helpfile for hirt.convolutionreverb~ and saw this results after opening it:

And then I reset the trough and peak and got a few instances of hirt.convolutionreverb~ playing to get the CPU up to around 40%. That gives me this:

My takeaway from that is that the performance is super variable in terms of what you are doing. Shit like opening massive helpfiles and fucking around in Safari aren’t exactly good “realworld” tests, but the high CPU load is.

1 Like

I can’t imagine much has changed on this in beta00, but I did some more testing including a couple more variables.

First was putting a really wide open query in entrymatcher~ just in case some of outliers were a combination of the onset detection working, but entrymatcher~ not finding a result therefore creating an artificially long measurement.

I only left it running for about a minute or so:

So still some slow/high values.

And then to rule out possible funny business with entrymatcher~ altogether, I removed it and just measured the latency for the fluid.descriptors~ part of the patch:

So pretty slow, and now actually measuring the peak times, it’s clear that there are some really long spikes inherent in the process itself. (earlier tests didn’t measure the peak and trough, only the average)

Would it not be better to use a zl stream if you’re measuring the latency over some period of time? A moving window would be much better to smooth than blocks of 10.

I’ve tested that too, but I just wanted to know what the value is for any given clump of readings without seeing the numbers change each reading.