Descriptors comparison (oldschool vs newschool)

yes it is. like in jitter, you have to decide who is the boss. When we go public with the multithread implementation I’ll put examples in there.

to a certain extent. FrameLib allows to do frame accurate at (multi) audio rate. What you do is ‘slow’ in computer terms, and easy to sync when disciplined. I’ll do examples. The main hurdle here is that you still think in parallel. Computers are mostly serial machines, so you could recode your example and take the chain of events in total control.

and interface. FFTYin is more expensive, but better, than the pitch in descriptor~ For info, ircam.descriptor has it too, and is more expensive than Alexs, but for many other reasons too. Implementation, interface, quality, are all intertwined.

For instance, forking in code has a cost. Every option you give to a user implies forking in the code somewhere, at best. Architecture is everything in code optimisation. For instance, asking for different ffts in alex’s would raise the cost significantly, since one thing that makes it efficient is Alex’s clever order of manipulations to compute as less as possible. This comes at the cost of flexibility. That is why he spent so many years on FrameLib

Then use something else if the cost is not worth it. it’s that simple. But first, try to compare for real, i.e. how better you describe (and more importantly, match) when you have what you want for real. Then, like plugins, pick your best cost-to-feature ratio.

if you do that you need:

  1. description
  2. matching
  3. matching with what you gain with the 2nd interface, which should yield better results

then you can compare implementation cost vs results on original task and aims, not on using a ferrari to plough a field… which is an analogy used in other threads. It is an important one: there is no free ride, not object/architecture that is better, only some better for some tasks. Here we try to help you find the knowledge to actually compare that -what you think you need to do a task you think you want, then by having access to the tools and knowledge to explore all your dream implementations, finding which one is best for the task at hand.

In other words: in some of my composition patches, I will still use descriptors~ (when it is corrected :wink: ) when it is the best for the job at hands. What I learnt through the fluid* version (and the python prototypes, and the audioguide software) is that what I thought was better is at times worse… and at times has better results, at higher cost.

So are you saying that something like this would all correspond to the same frame of time?

I thought the right-to-left thing only applied if you stayed in Max land, but since each of these objects was getting audio, and their outputs wouldn’t correspond to right-to-left order, or a known order since it would be different each time you loaded the patch(?).

Yeah totally, but I’m saying that the present method/architecture has an overhead that has nothing to with what you’re discussing. Going in and out of Max that much has a baseline cost beyond what’s going on in the object(s). I’m all for fancy algorithms that cost more, but this isn’t that.

I’ve started coding another comparison. I’ll post it once I get the right values out of (it’s not producing the same results for some reason), but I’m slimming it up by pre-bufcompose~-ing only the “rows” of descriptors that I want before bufstats~-ing them.

So far, this is actually slower than the previous version I posted (though going to the same fft settings for pitch speeds it up some).

As I said, I’ll post it once the numbers are correct, but the amount of channels and such being processed is correct.

I wonder if having an extra bufcompose~ step is responsible for the loss in speed? (so perhaps analyzing “all” the channels is cheaper than separating the channels you want to analyze first)

definitely not, as you are streaming, which is not what you do in your original. I would go through a buddy object, as this is one way Max-land has tried to help their idiosyncratic timings… but I would do like you do elsewhere (inspired by my JIT buf processes) and process a given windowed buffer.

I know that is what you say, but I tell you I disagree. It has everything to do with what I’m saying. Flexibility and power comes at a cost. Your desire of a good pitch (fft param A with algo) amplitude/loudness (other settings) and spectral shapes (another setting) with the bias of window size you want and nervousness and post attack, all 3 having different consequences on what works well, would make the blackbox approach impossible apart if it is coded for that specific case. So you need flexibility. So you need the current architecture to get it. So it has 100% to do with architecture, because, as I said many posts ago, these are all intertwined.

Yeah totally, what I’m doing (for now) is better in a JIT context, but I was pointing out another (potentially big) problem with the current architecture in that if you wanted to analyze in incoming audio stream for more than one type of descriptor, you can’t synchronize that data (as in my screenshot).

It’s another place where this architecture is working against the ideas you’re putting forward (flexible, powerful, etc…). If you can only do realtime analysis of one desriptor type at a time, I wouldn’t say that’s very powerful.

I’m actually quite curious what you guys are/were thinking for doing matching in the future if it’s not possible to synchronize realtime objects (would all analysis/matching be JIT?)

I have not read all of the thread, but I will comment on some of the issues.

First, the descriptor computations are interrelated. In order to compute the spectral spread you need the centroid, for the skewness you need the spread, etc. So you will be computing them anyway depending on what you request. The algorithm for pitch and confidence is also the same, there is not a specifically added cost of computing the confidence.

About the interface, I think an important point is many people, even people that have a good understanding of the DSP, do not necessarily have an understanding of the musical utility of descriptors. By grouping descriptors coneptually I hope we are helping to make them more easy to understand and use as well. This interface is also easier to port across platforms other than Max.

I get the point about RT synchronization, and I personally don’t know enough about Max scheduling to understand how it works in detail, but clearly with sufficient overlap the evolution is going to be smooth, and the descriptors will correspond to approximately the same point in time. With this configuration you can also use different STFT parameters for different things. For instance pitch may require a larger window, but other descriptors you may need for rhythmic events you may want to use shorter windows and less overlap, which I think is also interesting.
We have not considered “matching” too much as a use case for the first toolbox, as it woud be more of a topic of the second toolbox

I totally get how splitting them up into categories makes sense, though I don’t know that the general level pitch of the project (“being able to code a granular synth from scratch”) would need too much help with descriptors. When you’re dealing with stuff like nmfs, audio descriptors seems like the least of one’s worries!

It is also possible that one can use multiple fluid.descriptors~ objects at the same time, going to separate parts of a patch, so synchronicity isn’t important.

I only brought up the realtime (and later, matching) use cases because those also seem to be problematic with this architecture, on top of the problems in my specific use case(s).

So at the moment my options are using JIT (with a 10-20x latency increase in computation time) or use the realtime objects and have decorrelated frames of analysis for each descriptor.

This sentence is wrong in both cases.

  • The computation time in JIT is 6 times, not 10-20, for similar features.

  • For RT, you just need, like for any real time thing in max, to be discipline about sync. I recommend buddy which will give you as true as you will get.

Continue your tests, as now, you can do them, and see the cost/benefit analysis in your case. As they way, your mileage may vary.

A significant part of the cost with the flucoma objects is the pitch analysis (c. 3 quarters - this is a more complex algorithm, although having read the yin paper at the time (when it was under IP restrictions - I don’t remember the complexity being so high).

Another part of the cost will be due to 64bit floating point calculations (rather than 32 bit). Another part will be calculating much more values at various stages than you need each time/calculating multiple FFTs, copying between buffers and so on.

I have already criticised the use of FFT bins as a parameter. If log freq is used these actually won’t be relevant units any more (nor will Hz or normalised frequency). I see no reason to return in these units, and indeed I’d prefer normalised freq (my preference is nyquist at 1.0, not sr at 1.0 but there are in fact two variants of this). Returning in midicents is not relevant to the outputs other than centroid, as they are linear valued output that cannot be meaningfully translated in a log representation. As the sample rate is in all cases known there is no reason not to convert, and indeed, even without the sample rate you always know the normalised frequency. There is absolutely nothing to be gained in returning these in bins.

Finally, the main additional flexibility here is being able to take time series from the objects (a feature that I had planned for a future descriptors version) and you have the power to deal with edge cases as you wish, but I do not believe that to be particularly useful. I am sure we will continue the conversations about relevant interface, particularly in the case of edge cases, but PA seems quite sure of some of the decisions so far, and I have a limited desire to argue out these points, given my investment in this area for many years if that input is not wanted. At present I personally find the solutions to be technically, rather than musically centred in a number of ways that I find frustrating, although the grouping is indeed helpful.

My original test was 1ms vs 0.05ms, the improvement left it at 0.5ms vs 0.05ms, hence the 10-20x speed difference.

Unless I’m not understanding, I don’t think buddy does what you’re saying.

buddy will spit out once three messages are received, but based on whatever the slowest message is, so it won’t be time aligning/syncing anything.

Do you mean something like this?

Does that work? I didn’t think signal->control worked that way, to allow syncing of data back up.

Now that I understand what is happening and how to convert the values, I don’t understand the reason for using something like bins in the first place.

Real-time values from these cannot be relied on to have the same analysis frames exactly in all cases even in the case of the same hop size (the other FFT settings are irrelevant - if the hop sizes are the same then in theory the values can be aligned).

However I think that if the hop sizes are the same, then you probably don’t even need a buddy to get exactly synced frames. The reasons for this are fairly involved, and this assumes that all objects receive their audio input from a single common source. This behaviour, however, cannot be relied upon. As soon as you change fft settings on the fly then all bets are off.

In fact it will, like in your live example below, as long as your slowest computation is not longer than its period, your certain to catch the last valid value of the other 2. That is, as @a.harker explains, if your fft parameters are of compatible values by design . But for RT descriptions that need to be sync’d I’d either use JIT for time series management, or other options for short, time-critical, efficient methods, like FrameLib or descriptors~

Indeed and that has been taken on board. It might even be actioned soon but that depends on the whole reasoning of all party involved, and often times, I’m explained good reasons :slight_smile:

really? That might have been my call, as I thought it was abstract as hell (and 2 variants made it ambiguous). Interesting!

As mentioned elsewhere I only prefer normalised frequency to FFT bins (not to Hz which would be my preference). I could have been clearer above.

Normalised frequency is common in the DSP literature. I don’t find it abstract at all and it is much more likely that the user knows the sample rate rather than knows what FFT size they set, and how many bins to expect from that etc. But Hz is unambiguous and easy for all to understand.

Another interim test, with surprising results.

Having no bufcompose~ at all, and just using the frame/chan messages to bufstats~ is even slower for some reason…

Left to right is the vanilla implementation from my first patch (analysis->compose->stats->peek), a version with more curated bufcompose~ where I narrow down the channels I want before stats, then a version with no bufcompose~ at all (analysis->stats->peek), and finally the vanilla descriptors one.

I also tested @algorithm 1 and it is faster, but not by much. It goes down to about 0.3ms average instead of 0.5ms.

Ok, it took a bit to fix all the numbers and to make a more comprehensive comparison patch (we have friends staying over at the moment), but here is the patch.

The processing time of all the fluid.descriptors~ patches are all pretty slow, but the performance of @a.harker’s descriptors~ is quite erratic in places.

Have a poke through the different sound examples at the top and look at the results at the bottom to see what I mean. (playing the same exact sample of frozen noise is a good example) [is this due to what happens with edge cases if the fft size doesn’t perfectly match the window being analyzed?]

There are a few blue subpatches that you can see the results in different ways with, so have a poke at those. You can also play the frame that’s being analyzed. In order for this to work properly you should stop the record in the main patch to make sure you play the correct bit.

Let me know your thoughts.

edit: updated code to work with alpha07.


----------begin_max5_patcher----------
18847.3oc68s+iiiict+bO+UHTYQvLapwCe+3lrK56N4l8FfYRxECPBB1Ing
pxxU4scY43GcO8tH8e6WRQIa8fRhRVRVUOr1cp1krkE4GO7vCO7bNe+0u5M2
8P7uDc3tf+WA+of27l+5W8l2jbI8EdS5e+l6dI7WdbS3gjO1cuDc3P3SQ2cu
48NF8KGSt9l3vkODt8or2X6oWhOcbSzwjaCld00KS9vwO7m+VHQj8YMevieZ
Wjokb2cA+Wou0tviO975sO8t8QOdz7tP.Bu.be.Bgz+CUX9iEfy2j5Yuda1i
FkdwGd5w3Mw6MeGfERACQX.hj.HPB4d0k..NDA3BAPxwBTxkPbBl.EBAGQ4r
6Cf4dLoeinA7q7o8gKWGs8XdL6gmVsdyljG06xvn6L8EKehjeCGzdYou7y82
j6M6WMdKiTyQItsIANPb0cY6Cb5XbdH09mZ293cw6OtNdq4yP0ej+mu5qz+5
dGmVrM5iJg5JyJN975CIhvQ6sOw.YahAs9IF265jCJW+OLdySNxjwND9grGw
ey+h9gTngGb2eu9W+M++z+NZ6RyUB9u5ANUm5iCGC2eL.nZ+p+u65Pfr9oCg
SjKXPnDKHbFkgn2Gf4KT+lSaQaxHzmQ5+eG5y7AqOyjiUetl4C61D9oOGrMd
8gH2mO.qeghCqeZa3Fs7XxZOma+qh2d7v5+RxGChNOqWe4sguXTg9+d+Z8s1
E7RxzHEG0xjpgCu9seNftnChFz1PpNJf.wI8XLYxjPND9wOGv4cX9.FbMcZo
.sPB4BBiwkLA+7nLCLcZB.5k8nATkx.p68bInuFPAEk6yzjUMlRse8rOC6We
VYKwhwseVi77l0ai9r655vvNqqy5HLUZWpdBmI20dNZH54RjXwMo29a+bGzX
gGXMVopoMc54W2kbMcWgZJa993zMj93mdbSzmUpN5xhQzgnultBDa5sEsa1e
K5oonLkw1krzX5W.peleKXCVWVBm30h5i02b9Mw3aKvUpBfwv56FrQAsHwDk
trAMbOEQnDld6XzjNnZqYSqoX.X26n8b5OgBuzQEnYqEIhgvhjzQUyj8Yr4W
xgnylNxN4c1tXNB4p1uHEjnuNUYjZShz4XWDdMcQRhR6rtHULYcwcq29d26k
W299S6joRphgeMkGNc7X71NLlgtrb3d0xjGi1+tnsgOX7vMnttZqSIwDzBp.
KoXo4Gh77NEHY+dzcj0iaV+XGFaIrqYr0ZWNyUVxIy4c6BTMo38K+Wp2fKfE
AAjnI6hTZbJYWDAJVPjRNU0koRLmp6sBbycSP9GQz9zNWZuSYq15MQeHZ+gz
yDIcD5M2EtaWtK+lb2hFR9ylS5Qb+4Ksdq4RfyWZezGVmc+zyWMbupidT0KO
s2Xe3uvx1zn9qIdYz9smVed7IYvIsIkLLnsq7vtvGM2rdzJ6syo4NYjGBRD5
YjD26QDfKHj9Tg1D+36iVluIeW7tnsq2taezgnsGCOeLQYu8xnUgm1b7c1s5
s36uJsEZ8MsZar9HAWuLdqtQTXjPe4rG2eJ.ZVThluyj7I1FtyxMqjyTvRMu
oZeQGOc3gv85ApT0Onr27Xb7lhu046aSzpiousRQ91Rn3w3c0+l6W+zyMbuO
DqdyWZ56N4cN7tSaMu66TxDGeW1gZc4yEtYS5b0he8+R310uDdL53ZyP.Bb9
MMpfe9vi6i2roP+07Nevx6rTIi+XzGWu73yEN0Q86n93q2kIDc24Q4kqeJ5v
whW6X3SGJdkCG+jAzycoSOjNG9cGidQsCuik9.ENg+7SXyqUqv0abWCEUwol
d+R3FkXnpym+CXUAeksVJxeK0uEhF1TYyarrV2iRLSWfI5.3UbyRMF47lrUF
RU.0S7rvpEUChBMbG.6NXJuQfIEXTqBru47ZVgc7wx7FS5NLd1WeNY7wfCll
ksg3DqRIfYCXZLjonui5.nBuofpwUJPyA5IHsCp3oATe3zpUQ6SAU8LHP8HK
pFjE0HxtRoP4XkMtOZ5SMVXmpVs6xsWLcQ66hZVyJ4wqee6X+g3S6eLq6mMg
NnXCQsH7w0aOaI2e5hPp9C5zXeWaEZsyyfVgv0VAp1VQ5Eyr+NIxgV9NiAku
K73w8qUa70L3keCEcxvGkU3ODtI0rlyRhVrK5qtz353V1dL9kWzAEV48rAWD
7Os4z2G+igAeLd+6USf9XvWm03i2e3a+8pYspadW7gnu82qMU9v27yaQKB9o
nMJDX8GhZ69e7zdkMZKCr88fs88j7l07kjcijEA+6JaX2rILH2mKq2oEQdL9
jIF3HtuQTdCaDkZ7YBgCVn1fMki3pcaCLQRkTlE.EC2drqa.SigmLaKKHw7c
a8Yj684yme2Cmdn3NbRuxg0KStJtgiwCjbJdpcjmDdUIwfGlOMgKDzcONgtt
ig1rppv3UkQHXYpaD+ed6wn8gOdL3iqO9bvA8rk3sGBhWEb74nfjVp5UgGCB
2GErdavCaNEs3ZEKfM4SFXpyVLHhwfXLdR7vzS6CWu8eaS3mb2+Rvyd5uPr4
RT1e.HB.AhIXlTejPB8UvTARBYHl9JRoPhkPJihQHgnXn4Zyx.bBzPAhJZIZ
6.tf+J2CUDjw0zTn2CUdOT48PUC6wp3JEEUQp0MlrvfFvMpKW7ya+4sesNB2
SrQ6PvCpNVv5UAeJ9jxhp3L+1qTkoW+PeyuntszkVhU+89Op2wl9iue8g2Gn
iqB8GNLXe31kwujsnT1ZRZcUeS9VWgUg30toOf8M8gZY6XHTdWx.MQVSxeMM
9QnvIe4tWBfHRwNVsmB1YaVRfwgbMLGNisZidZix6ziRrxIqcybcyemZC4KX
c2ghWxshl7sPanBDyyAKDwrwUqGBeYmZt9KG9bmc5xkvrus3kvMLpnGT4yGO
nF936CLQI2J0+quhQvN3X55mWwwKXLFV.SOjSMf4fi6ICHTE8WVF9XChKf5P
.9ctzEQpsKBK1EM9UiPmAyWLwN3wD2E8TmmxfbcFSGT0hfIAeiKGeyPNgI4a
sGSCDCf1TilBy4BfO+65624kHyLRJuoWIMxsKi9kI0krZgAmbCYxLmReRkcY
lMCBGEWj1w1FzdaCLJssDCjbrwMltQNQV1w1AcTaGrNgGnQqcPqHJTW6fUu.
M3l23f0KQCGoFGzwQPD8K8SjXy5ODsHY41z9wGBu7jp7l1Cn2RmW6c179Goo
vLD5VhmWSD9qe7onYwFPmB8eTpcclCAmBcOC1WdY3tgA9ODt4TT7pptG7Bfr
d65i5FoYKLWDOy8QN7b79i0N9TBdO8RJLpd1ZId8+hty52aFlir7dah29jaO
xzNP0Q1BepWTBfE7X4vedZVNMJG7PMnwzxN4TUjF6e3lMZCZS7HuuMGxieZ0
lSqWtnW8RfrgdIVn1uChgDPcUwP.QW5xP.dZ5y0dnCubZyw0G1rVs1v+95nO
1gtLY5N5AIJMdewk2UkzwJFyuVO4AH2TCQnLh+nG7G8f+nG54QOrR87TaZ9P
28XDns.tRoNyTNCfIyXoUVEr1UEruxv.4ajlPiGUuw930K6LZHaALjlPPHCJ
XyenX2ZUmny3fns.wUJWftHSXb797FH1DeZYulgzlGUgRzhKPACN+ghplP5N
ZPaCMXlE1wJKePHLCmZPI+UfZi5Lv1czg3H5.kjBniE6ruMvSNyscyw6GTWK
awPrcPgw65YsVu6.pEXQPVxpTXkIe4QVrvrQFIxUnU0iTuS51U+SA5j3cgIq
0czmd2PjVLgHMDH9ULRKGejVfRRv8AWh1Dy7If8rGm4fICmGb44wBma3jSOs
8OGuda.od7mVi7byAfQBNl++J.HOud4xh6csNOMASKTn4wYFb1DEB8G9nSA7
AoXZhp2aLBNJJTQi+DcBhkrqkeUqQkQlNf9UiJ0w.noSfIBFEpCuMuhWMFhQ
ESEJO716NNnbOCZH.55hcNCHoLkxTFTTXDQ+u3IJ5glZzBecn04kxmD.CMUg
ak1LRcruzZLVvqlpr4LCZTB.jj1F1g1FSbaZatD3LLxsos4RbyPuA3F0Q4Ml
71z1bRdieaZaNIugtMsMmj2l9wzD89N03rzKF+FGx0FGqiMtuPh6sZixDim+
e3zpOzsXLAN8wXBUTNFSDTe8WqTLlfDowgQZUBgXBxDL0GjI9fLwGjI8rBro
1+poNBEjDUAuKohff59lmXW4NMklpbAZgZjC.QH.GfMGiJBMsI8WGPqtiSHv
ffSJcfkwIIX1BS8VnBMHfk52ulDpdmxxqW5AXgGDvBhfUQKH+Knofsj8sNCT
D5qj4fYQIkYZHty.l7JwKbcZ1Iz4Lbg6QRZNDHkEc6PHd9KX08Yhrg.troce
dKX0SE77g.srpdmLqUa0cjRLHHkE86yz4g4Lxp6J2GFCRgBanEa9q0p6J4GD
gKavEVLusIcnKFxtJag.RKxVfYuJ9tu4vgPzxJZgwyuZTNXgryHzUtGGZZ8w
lQzAGnXhqO1q1Dqyj2tV6SHWeTT4TUQICbjIj5L0EvoPvqu+kvjuI1DMq6C+
k33WB9McujBQFFoHjZRU4IZtD0dSUA2IPOSq6fC4JAGjnNvg3.3.J+se4rMJ
hC0dFG0cNGktcam2QMm4Q8m6Q6m8Qcm+Qgy.wgyAoo7s0JWzT6og3vIh3xoh
z5Ii33oizvIj31ojzxIkz5okz5Ilzxolz9Imz5om3vIn3xonzkSRogSSo0ST
o4SUo4SVo4SWowSXotSYw9IsTyos3zItX+TWJq.orN5Juea5pKm.eJCH2D+w
xefZ0Z2j0iNn7t137MkfK34RL3RpravLoBqqUbssQF+NaWYgstr74dimvgAO
w7ylkmTHKku9PzGVuKdS39.X+kMwCCXB4v7klVvqPvzX1Z+gR4vfjEJZnyJf
zzeZFe.MLsshnVs8djfoKJnbHmhjHISjjroVCT2F27SSAraMQ4rE7qnEMUBf
2pvpsXIyB3VIlxpDhcMDUYkHxkNMr221GBO2afcn8Aw2fFHbPAvhBlI1T0hj
4ES8Osbc7OkXb869wnsmJNwHa6AM26d3I0N81bNX7dSseRk11Tkfogt28kd6
BAzGRRfPgNp8vPL2D+dX0KnzRQQat6EdNZ.oDI.ouEBCwIzjWIPXJNM2Ord6
nKOa.TZdh.o.PLuRcIXkpId5dL29T5lR3EsV1HlrOdW79y6haAVV49OcL9o8
gKWmpgBT38KLdWbaoFONotK6lRq0cqS.nxemMITeV33GN8XXeDHh1Do0zVXz
jKT5wolnxDJDlWQn.DxJhd2ACMIEus32BBvjIxDPFGYFKE..jX+KoX.hxoPb
xyEIwBo4UTHPGqn1tYskAIeAua8VsuJhNKbfkHHyb6YRYHtffsKbzq4GmkEZ
YJRGESKNIQbdpgfCnBg4U01QJOIgQAlwBl9Gt4UluwaxbjJvdArRBHPtIrfk
TBmaD.QRiPIkUYXKuKQTph+W2EsM3mB2dH3mhdY8CwaVV0LtvGerrbOFkPWy
pWPxfKsNLRlP2MYh86M4C3+g1sX8YBdtdnwb+7+5F0mTlnxJ4ONW6N0NS2jn
fo+x9T65gBkPkKBHlYcmUovSmHeaAxxInWejLTZbUq2hj4E40JJIT3st6U8T
KlDYkgdYfbJxyT.W8UNnHmKzVFcu0WU+s+EgsR10ZbcRW11ebOl8jHKkyNVE
1huoqZXbfxeXyonxtdysdmsUGgbFwX4v4NpTeI3LnitO9iaGrd5k9G8rtP7L
om98eJb35n.jx7JyRYbLFYzEgfPH912Q+i6ihFvdZxnIV+iYGIZ6ou8cx+yn
Mah+X+5k4OKw+TxoIRk.fvI6XT6khaV4.JfIqCRURBzaJfb5kGh1+GU1pOXC
55orfDwapxjMZROFle0taRGcuwfdcO8pW2gQXLrLcZKOciRpARI1Aafmq.zE
7oeRBk1JIGBR5XRLgAjoakjCsauzLQLJ22Y9uv1Rq3xQ0QuN82lSyXaoZbQS
4FfHw4Oe3z5tGrMWYUzrPbzniGly88BI+7h+7g6bKRKMjgEljFtfSW0Gy8PQ
syfLENLQgpkHZRPligUI.0iXh65vHDTlKvJk3WEAVIRLMAVYF37EefUhfChT
zWlAVI7Jmhoma4CrxQOvJSyvGI0GYk9HqzGYk9Hqb3hrxr76R75OxJsP7F2j
fqDkxtyBgw7SnO3J8AWoO3JmEAWoD6CtRevU5CtRevU5CtRevU5CtRevU5Ct
RevU5CtRevU5CtRevU5CtRevU5CtRevU5CtRevU5CtRevU5CtRevUNrAWIct
Dak3WAgVokCz0wvZZPJKw1hpIHXVV9XOrS012Gt4vyg6h5aIUWbkk5SNkVWQ
Umil8nVOvK5ffWoTGz7rdWaQvp6k9ZhXP.JaEU8WABV8rxpSjCBnYs1pyl+J
w5NfQACCfYqDq+pYxY2UhMPhY1pc3L5qiImcm0C3CBnYspXy.yyz2n6kE6qz
bBYw5hM+UQ5a.mnz2P9qk5hMhNHRQeYl9F3qbIOoutX6SeCe5a3SeCe5a7Zs
vXaLjz3CAe5a3SeCe5a3SeiufSeCoO8M7ougO8M7ougO8M7ougO8M7ougO8M
7ougO8M7ougO8M7ougO8M7ougO8M7ougO8M7ougO8M7ougO8M7ouw.WarYyj
72HKBBm2IvQgPsr6fMbXhxRaowAF2uX+57mt548bABscJ.4.xpmuCnr6+qw0
+5Rydde+23.YmaEN1HniXaP3ZiPOQb7ZEzYQq.MKZEyBYSwLP1jymCiG7Y.R
vlAsAJbNHWRAyAYBxrPqIQLKZEj4fbAAOKZENuBBdLaEvYgbgiMBjXDaDXWG
PfiZqXVnzx4YHnQrQfbUmEBNlshYg8lH3LXYczrvbSzL.IfNKZNpsh4f8lP1
bPn.RmEsBxbX.YVXdCDMKZEyA0lWea3hispFunWZWNDmnV7edtVdMA8PdGJW
eLg123A8JhEzqHNPqOtFZNlFZHdFx6.76+p1c+eUW+aSXql36r4AxqLlNu53
4r2wx4fDGmcRN1VP6z+Pl4JhYy9GulihrbA3r2wlYGiKyqIlLGkIc1i8xlm7
4X7VNJs2JQHUyM0dEebcINJ6aLTNZfSoXkz4QR2iOxQqoW4T8Fmw1gP0Yuh0
wqHNGuBE12J6.pNSs6RDkicwNHM6R7JNJRx1iKwla4WSrHNlchxwbXm6ENGm
giXunb7D14NgywP3H1IpDqfcuW3P7ANhcfpwAXy8.Gh8uqHt+FmNp036qyCT
NGLViRmvZr60A8tcHd85cr5MJcb6wjWG54cHN7leC6GC20kYl41wyODdLN3G
zEjl6Fh1X52Q1WPawCXZ6p13.zVL.1R7+UN1+Ll6j7aCDl7LyEoZl1PCk2gK
Am1os+430aCxJ5SkhDszhEUgxS.HqHaYubsU3+xDwt640KWVnxEYK.0XlBCE
mk7OUKzHVBeuaDHHkiEFPgpIYHFR.4Xg525nyaDAjBk0O6kzuB86yPTCw5oC
kwOW64BL0dwNzZor3t0OsMV8EtY8iuO+kKUd+FYHhNwPDfcygnrRGR44UYkv
nfuVM6Z4e3a94s+71cqUcqjK7i+y+i+y5EcNjb8Mpqn+q8wqWZ4sWsI7X9up
rmk9PAdL9jYGgbqCRfbMq+7oCGWuZ8imOH.aifYA0bAS9RzMU6HClhpajAlV
PqAha4DW9DKUJQu5l3JlXHptB457EhDiHDkt3+qPM9P33iJdk7NpjO+DZT20
iyAPCdymMptIzwW75Un1Z73iJu9TPSPiGpvAfEW1LR0RrscT45590resWhB2
5NlfqcuZJzU01Tc90ZUKNz2QFFcQNY6L8urI3o8wm1ozA4dGl27lScnixLB8
LQycTz3KQSGpEWsWInuq1Z6bSnCAYJY02vo.6Bdb2Ic0MducnDZAJQsLQXTv
Jfw2EzVjjx+Ecorom4LsZJW51JU5Y9EzRIR2R4Q2doQu4xhtsRh9Y2K1RoPO
eYPGkxTHHCyEXVlAyy4XVqk.8VJ+41K84vETIEJXxrer8oKWDzcn.nWSwOu8
BedCE87FK34MVryanPm2bQNuwBbdKE271Jr4tVTyqofl2XwLu9BYd8Ew75Kf
4cym0UJZ4VJX4sVrxqVnx6ZlWWoZBUek1sthisUG5jT6vUaW2TOwy9sa7IR9
Roqxzhn8eHbSfZKMubHX8gf8Q5fbHZYfBUJjE3UqxtiKKa7PPO3ejFyA8pb0
hSZgZbwk5FgffDMlbypvFsmfoJe+a.UUqK+nVqc2YujFg1hKQOMXKDPtvHey
Bv8aUpq5dgSX9.ropUL0mBbxttaFWQyWUAzYip.ik3e4nIfMeDXIFGgcaTDT
tLa5Haz0Q4x50+Q3tt5OnlU+0OsfCJqKODnrdS8PBB2tL0B.kw.o1FX0H.zM
GHEWOPZlYNX3XnF0RAxFAO3TUqZlEUhCWyLxYPMvPmtdvwp5S3XaXNjW8v4P
pjOCRYXbCYf23G2Ut4ijaWzYcLXSvCt6qTxcW2oTiEFF4yPhzITo4j3k6iAq
6R2jVa2T6G+NzSoTC0VgPSVWcWv+zlSee7OF9uD+GNs56ieYW7gH2cgKq9Q3
yM8BAwIE.kTFmADBLFmD+wZQaFRhnRHvjZf.LDfkPJBIIXYwDEoIAEiucU2m
aNB+WQN20b9IXPJEZSHliSgNJN2Es.3cmq2cteQ3N2l1N8l06TcuD1mef8aY
q6igBkKzIpBm.L+nybHpZ5MSmW1LbZLcwbfUtwSiyGVoDhGdmk0OfhvJCTD5
zRe4M45qjZy5mKVbVemVuzAbm46bgK9Z7dm8BAPrfJvRJN0hzDoNIbgZsbFT
.YD.Ko7sxvyN3LIDv5MLRGPXTnlU5DJBmenXVv00afjM1.Igyp.jX1Le1sZy
iuzcvjIF+I2T0EUJMQbjNisv7jnPjOSmc2SXTN5Stsgh.w7c1c+.RNXzmbSv
UARLbdO6t6.IAL9SrQTSM74rIPyQbLYZc2wO73OitB7Ify1oy8..Ei9LYHnr
7m4L8lNDrXBDTaD85dL7vYsb3kTBegpuhovzMinKgV5T0p3lQRim24vQFeL.
z83Fo48bjO1lqMXMEjEHfPgOFbBpSXdLUVBnPnYybt9.TPwUCTV2dKlBlu.0
U40DH7J8aBV6Z8paY.Oe8aRgLAuCHEPdkNNAjchDEgFssrshMjoAa1EE89t5
njZvKYmi1MmmMJwkWoyEHDOYqzsbcOVqShZMxxXKT1mKwfzYZl05JKNklzBf
Ywh9g+x5WNmKHtiEBdarAEagDJPTQZ11hHZePpKCm.AAgDTHMwQEoUTg4vB+
80csb5XnfFimu9q8X.s6nD9pW42JPMyMQh08X5Db8lHkrPFQgLkmtMivl5WI
qGfFQN.qkw3ISwpN0CxDyFiiLvlat1uNvRL.fk8IiRVYnCHmYPmy9yut85QG
BylLyPUvU4YnPLZ9b.lYL.YBT84f2ZhwrR95ScY8aaep7aShXzU57FM.D7VU
uH40GB3c1CMHGh186cX8VFfUXm1.cgZGoFJnXkbK.ygotYkRlOZKqanv3tvr
gf7pEJ.8nBPexe73y5JRML8io+qh6muPEe.20AKnbXFrrplAQqNXgL1GQjy3
AqydmLa7pjtnFlsLECYrgYHKstDvjUGiLYuvzMF0zVeNWDT9Nklq8QgIu38Q
eLo5m7cAu+z9iwGVqe493MwqVodw4hix2E73dc36TG1i5btPB.20lVKPUsV5
Cv.W5jeMIyrlMYu8X74BSy2Ebb+oncQguu6a6l2JxjjeLDREnHMZBlE6z1TO
dTBNwaWsdYz1Gi5NRPayADX9BENHDHHFHnRjfaGX.noEXZjalunx62.uOvnl
oq1jwFBO+olDl7OvdxDyi5JI4Mt5xJJGShn+mBd6pnPcvzdnhsYqVc7fBLTe
nCZ8uALR90UnE8tramTFdDsCCxqnQixmglgkoYyxPwGWucY7G0wpaBf+1mi2
k7GZj+7vTNSAd+GizgCq9dUq4momr35+kFmJrXCoyCfvgbgdKiXHSsFgMqFw
RT.aalikIHmGlxLuNbySw6We74WJZIcSCKc19KLXDMY11nDGLsVi0uTfDOTt
CS86jeRbMAQpSxBLvji.8IeHG8xFQOKqFsYjfAMXPX4if2Ar.dsXwnj.nx4P
11wcM0GgvwLIP4NiEh4.IjioyARHO4jiCv2ZVHmSmCrM8XlUrtlhx3pRww6W
ZxaMvMtoAquogtwMMP8MM33zzncZF1nIW4pvMYTaE34.8Hick3Ugr4.gtCky
frvGylCTotEo3QVomyMMKL+8HqYA0IEKnwhDic0BBNdNv65R7bfxyyL9aj31
5tIYLVE5jyKn4I3ZOAW6I3ZOAW6I3ZOAW+FOAW6I3ZOAW6I3ZOAW6PK2Sv0d
Btt4Ngmfq8DbsmfqGyNtmfq8Dbcp8eCPITsqr133wTZDD6UISogtdhRKqq+p
fnzv8mmzR6myHdRaFQSZYfyqSZRCBlRZRKCq7zjlmlz70UWec00SSZdZRySS
ZdZRySSZdZRySSZdZRySSZdZRqy3nmlz7zjVC4Gimlz7zj1uhoIMH55nIMjo
RcM2oIMH9poIszd5sjlz921G0URRCNOHIsLwjTRRCy8jjVIW6RLyfvbomkz7
dy06M2gsjS7nQsYMENOTvayYogE5wA0i5AF07kd4BvdTjpP8dWVtTeJj5JNQ
kR5FFUlCiHF14.SesWB28Demm36rCTQ+xt8A+lUvfeqZkXc4mJ36RJRdc2Cm
hN.cEVSFmO7ncGUwkYvCnwzADddymfHOeB1a3LW0EE44Sv9hhEq4mHOeBNLy
tSLXxymfCAeBh77I30O6te.omOAsN6F44SvqZZMxymfW2zYjmOAsgfSOeBxL
wkhx3DOCB5YPv9ATVK7vyZfxyffcCu7LHXO3cIjmAA8LHX2gBOCB5YPvdrxu
mAA8LH3nsRV.xyfftyffHOCBdELHHxyffWICBlKXGrSifngKFFlbRDDaNBpY
QTLzHIBVbTnN0CWG5OtrBnzFq.BWvIRBJcTBNyGIJd7A1oIvgb7XPo7up5tQ
lPtbdA42fnxBTNprFRZaDMlZzpFVVX8QAm6GntRwNuncyJivlCAo3HaYkdcj
pTGwQT1Xpjr5.JR6IOj5Ojoin55W0Le.874xTbL0h5yQahZmocsAk00rMNlx
rSHO6p9FO6p5YWUO6p5YW0QkcUQcjcUuR5gbhocUjIXVlWFBLTztJ5KRZWkC
pZv2WJjvJ5KTRX03cSOIr5Ig0ekPBqTgmEVmFVXkMG3fOpXFTiG77QqmOZ87
Q6a77QqmOZszJDStvsqsLKj83XKAAmCkEIvLn9P4IOWO449FO449EE44hlCL
T9WRT36.zJtd5Z2yivddD1yivddD1yivddD1yivddDdLGa87H7jXGfmGg87H
rmGg87HrmGg87HrmGg87H7ut3Q3ZqH8YMz38GbtVzSHyhZQuf.yUK549RQe1
y6RQVyTTDUp.Mb6fIfwD.eon2WJ58kh9dlv5A5ZRR2KDRWYAIQMWdQZtOCgJ
klpUzID0ByZebRboF0U9qOpV+MTipv5TGV51soVrFUi0qdrcUj0olrryTaSc
YIUlDjopRjxx2lZLAFvJ6ECaZMcPyoKZOaUCpiZQaPSpaZSaQiZqZUaUyZKZ
WaWCaqZYcPSqKZa6hF2Fz51pl2l091rF3l0B2nl35zFaWibMZkcRyrcsyk0f
TVKck2uMs0E0Xq1PvxGJ+t0pzto3N2Ac20o+VYT6BNEnswMKmf0oCIdAkyjL
J3R0TfXsls1PJLTzGnE1Y00hrUSPvR0Ro3.kR02+cOpEFaDgA0ivPvcsiebC
ijYJZ5bqEnr4IDsZe7KV1kU2gIgynDIAjj7WOfz2GqOxjil7RJglTOmsyq1G
8eeJZ6ieRS5mwAurd4ZyGPW.OUW3zAsBwf8gaeJZQ4GPcYtT2PdlCHORjrKT
yjW0dXyn9zaO12h1wJE1ytodDMLpGM0Z3zbAWmAWUzU1tBQxsGLOs0E3j1ft
v1gy6K8etCuRSdBywlpCZVdzIQykkaZAcqr0qtIpBEjgQXExXKT+G6BcgxLb
gHDhERX1Ew0syrF2cVc6PqJ103N0ZZ2ZV9ppaWaMrysl28la6fqocwUYmbNt
atR6nKklOM0wchvLfvsrpX8apywM145l6bZCdcXSdsrQO22rmCa3yoM84zF+
bXyetsAPm1DniaDz0MC10MD1xlBcZigsu4v12fX6aRr0MJ1zlEqeCiMroQm2
3X8adzlBMaq8X8y4jop1MW8hsom1t9XNCT2FeLJ4Z2GDdH3iQa1n+WsIq6Rn
u9iGBTK8r6zQ61s1psqsa+Za1vVucrorAgQCAuN6Xaw.gJFIT0PgodP6QyfV
zxyaeXm505gqVQez0h9DGQeylHfR1BIkxAmsPSY+qPZqLI85bnn7dhuLQZ7G
JPcZnvLOPJ9xA6y1279nvCwaur24wG4gbWmF.QjEHLQvxJnNIwqJQG.zLFJq
xiBDmqLTegLzjtrR9UQNLEiK.WGWTnckwEgXg.yoTRlxJMCBn1.OiBw42fz7
eLx51OsL6oJsw31lQq.7Ltsui12TZciOF5H.po7hxSTXx51IZ0w.77dLnJmP
zW3mNFvuTW95JMefvcG8uky.JWJi5IvJfiAvZVK1d87wNTZSwW956S2rCoZE
.5FLBUo5I0Sc9BWsCJUmhxDHRYSR6xPArkghtYcdmFJp5iiJEoo5Gkrk7oML
VYIYoqjNp42ls0zRsTxwdURYWc6WuFU2Z+Bzrp8S6L9yct8W5CU1cksEsn04
W2qx+KMGMoVbSyWUem7Upe9wCje9AIUbPLIuROue989426meue989426meue
989426meue989426meue989426meue989426meue989426meue9+0te9ssLi
69wucu3uY8gicH+GLImS8ZyZbQkFWPobK0tdqQBkstTg6Y2D4NWwuT9KyU.D
1..1ThC5D3ULKkspnuHlVmBlRHaUhNwlZkFXVCbQcENOl221GtCsOXUEdid6
C0g1G4Fz9RxJnNMBil7VHtisP3T2BMx8N09n2hw3Nhe2h1Gx04vBxMpEBctE
hasEl6MKT5icvPp+50VQCZ2vIaFMkuJiNlD6nNAR6NYBhttpKCBKzLXJAetP
DnqMoRjNQQgnrsBJvY4V9rfqY+1.MY+A6LXgZtT7rZSb3wdhXD0tmUaYlREX
pDyI5Tq0rw5YAhcH7kcGNF+xgOeWmoZcdif1g0OsUGsBVgu5iQh6ZLhGrh6.
pEb2PDxboC0AooAo2E99fPEh7oCWnjUn1gxE7moaxqjtL4dHwZcvzHokvZDt
jVgDxN1v9lMC8zoA5yssrO28xzUyjUakMbNA3MmnS1brHKdyHJcJb1zJo2OJ
tk.uZNt05zcBn9sg95ljaI39HhforphHSBu2NBSeUKerzvIzcUZizNOSOdKK
Yyb.DSVUUICLsScqvhA4OgsUG2EtO7kLFB+9BGRRFytqV3R8MlVad.KT+Uzx
0gaCTai3cmKSOHPPxwPpdS0acX0KEuRszINpyCyxazpgVGhwPtdHFQQ.NPMR
SzCwXiQxXZWM4aTnQ5NvQtiI4zNKHvSBZVfENyPY7wjMJcEKHnQj5jcmNJGS
ZKNAngt1JfSIoX5bSyBRNxjhIz0wNxnRDjtRsqPpmu+778WsCpd99yy2ed99
yy2ed99yy2ei4Xqmu+lD6.778mmu+778mmu+778mmu+lM782W1rI2wfMAOXm
E4PVXQNP8rH28kNulln+MCU8fL7CQ8z+VO5lq1Dq9NbtCgOSKdIGpRzwn8uy
jk94Nwud1YkDht+wYIYqZ0Sa2NW2sJd+KgIeCrgaTN2w43.lPqcP1DnH2W7b
fapuiLYGjrk99v0S+KaBdZe7ocAmiJ.G5vrFkpcoixDIYQlg6opuihl.IZw.
IQa+b3p+L3ZBcRolKwMbJvtfG2cRW8N16LmYhksLQXTvJC0XxnsHI8qOpwjZ
TljR3HvTtxAyGElwDpLnfBuvVDROOY54IyuH3IydFlSvVB0BbRsoAxM7UCM6
2cOPlTlVDs+CgaBVuM3kCAqODrOR6yonkAJTI5VFmSODziHW9Zhvo5zB0yPU
LQiI2rJrUlF6lD2sp0keTq0t6QPeWiI7QGaSKkcT1rAb+1dE8xyGfMUsBwTw
ePIaXDLCBK+9nJfNaTEXrD+KGMAr4i.KgqkQuQJB5WLey6nbY85+RqkJNr5e
cQ4s9oEbPYc4g.k0a5TvPWyILV.bHHy1.qFAft4.o35ARyLyACGC0nVJP1H3
AmpPaU3XjeQGwvOi6XaXLCeQlqwgWwbCdPaCtFKfrwLvZcMR.GyvpsCiEiUa
v0H6E2P.QN9GTga9H4VdbFq6vwYfw05fOsCt6vIZPSKk0Hzs+HMfi2QZ.YvW
kGoARd8GoQVe+UwQZfD8+HMR6nymiz.JmQGoQF5757HMPvo7HMxvJ+QZ3ORC
+QZ3ORC+QZ3ORC+QZ3ORC+QZ3ORC+QZ3ORC+QZ3ORC+QZ3ORC+QZ3ORC+QZL
HYnAjdcYnAULxInwfbvMPxUevMlN5XdtM0501+oMm993eLzYm11P5Ibt0VHq
nn.njx3LfPnqkYI4AplnmPRDUBAlpMA.CAXIjhPRBVVL2iaPxH0Wtb2768uh
7kK1PDcRSJjqvUCNQFEe4hV.7du0681uH7daS6d1NktMDtor8ssfw5xDHlSx
3SOo9HuoKX5B8CCiDPD0llvpZCwSiuFpR9ZCguw5GPQXkAJWpo1SkSuOsZUz
9OGbXmpSrObygmC2E8NsdoCctHaKbwyh263VkkTpl85kzLp7hjTpXEFkurYG
.lTeQ6KvQGPfS.I0Cb.9rC3xpSq8E6XiM1gLtmFhjy7Ysp8.9RmwOlXzmzhH
5pTl.HABjtJyp8fJENSmA2OPTN5SfsAh.37c1buvQNXzmLCjUwQDYdOyty3H
AL1SpQRn1RGFT.YD.atBiIyo6L7gG8oyVfONc1NYt6.nXrAPHmUF.kSrsMU4
Jcqgjq6AgCm0xoORMmejpWWZCEogf6b3TdOF.5dndPtZl1fISJu8.TJmuCwI
V8JKATHzrYRVe.Jn3pAJpRJIOPARJ4+yYf5p77ADdk99.CwU09P334quOzTv
V.oGbGj75PJSNPPqHJQoh1wFxDQrUQQuuiN6nF3RhG.ZXy9jQ0BYvBHXpGzm
NoqlWZSSeJcdwMIpsXACyWf4TIFjQ2LXaJlRSy.vrXU9veY8KmdoyXgf2BVn
LtQBEHpfiE59MhnW0GTVmCb1rpee82JmNFZmw34qCWOFP6NJgu5k8sBTyb6i
XcOFLAWu8QFhGaNiL0tHVOPLhbHVFSXHn9Jy6fLzrwrHCp4ja5qCqDC.VYeh
njUF4.yMjyU+zW2d7FBZqMcxYUzBQmOG83lSqWt3gSqRvoOG7VSvfYwW8p2J
YVaKli5Hgyg5EcAa3pPWrt2lopH0HAEqFG.XtZ+CXMGefHx1oON3scr3hq9y
FCpQuPArG2YVGVNLXuUcF1vdnIE70i.yVruvIDjA+0qb4JGAXCjzuI+9sA4l
DVcdA4pMsrK9PTMJeBdatfOsN8R6OtRmf4Aff2p5JIu9P.e.GYPiodILZgnn
2gQDjkcJLuG0LbVZgQqRZtxFkPiznDaLUfgEUFj.uFlLclYYKLxTUu1nOEZP
0sYYJCjLsiFM4qkyT062ozXsOJL4EuO5iICDeWv6Os+X7g05WtOdS7pUpWrZ
S3wz29w85P9q6FUUW5RC.scTMXQU0RPb0CM0r7gZmSy.L9rf82Ebb+oncQgu
u694qMeaw.IoPGgTAJf34iq8LpdUBNwaWsdYz1Gi5NRPayimHwBENHDHHFHn
RjfaGXR2KHXNP514zq8af2GzKtNGyFhSZPMIzDe43126GZps4MuQUWV43Xx5
EOE71UQg5.v+PYCyVs53AEVn9LYjZd90NnEMZ55V8.iGQCvf7JZ5dEX.Vl9O
KCXeb81kweTmE.IiKu843cI+gd.57f4ECCd+GizwYu9VUq9moLsnk.MMZR57
n4fZLfsgOcALp7vGCMmF9RzYaaxlkIUmGyRswNbySw6We74WJZJ8vNFAFQqo
sLjAkl7TBMuSPc7.4ydh52I+j3UPhTmHWXiCCA8IIqG8ZQSOqUOsYVgAMXvJ
AIjCXA7ZwhQIqxkygT3k6Z9TmDxIiWyvYrPLCxucsGPGsFg9z9bKqpGyxM.Q
5JVnCvl.7X0LbszKvoyf78eLmgfcU3DWcpT79klTzEbiaZv5aZnabSCTeSCN
NMMZmlgMZxUtJbSF0Vgq5+G0UgrHedCJrGfYPENw0gC7X1HPtNCwhL7Hqxy4
lFTL05UPcRsBZjF6ftZ+.GOhRPPWMePNpsBWWDJyzuwoU3pfAZLMkBB6l74X
UFoNun5Msnd475MrFpfREpsC0r2zKkFjSKWG+SIEni28iQaO4Jed+vSqVuYy
4hPyap7IdycYt2HsT0bet2pPwqAIIPnPWgZvPLGkPt2X0Knzjg6J2GL6FITh
DfzebBCwIIE4Fh.goIjWOvxsht7L0bFdxSBHE.h4U4nQ772Z31mRKZI7KUdC
y369XcQ8KqBtr.KKbemNF+z9vkqS8uv4kdtLdMN7y9Ob5wPWGHi1D8RE1kWv
X7D3T.fBg4UDJ.gpxO6GTeAOpQfheCH.SlLllDi+IiGB..Rp9ET39HbJDm77
PRrvT2hPTn5Kq5MpcMZxM+t0a0EQnnyCtXIBxL2ZlDBhKHXnM5k2c43yikMH
J2AwphByhyhvBNfJDlWYsQWVXlQAFrlo+gadk4aaRjkK.mEvCIf.4xjthjR3
bifDRZDtnrJ0yzLQXkdt+0cQaC9ovsGB9onWV+P7lkE8PZ3iOVVtEqGuSvbR
Fjn0iPxDdF0Icu+vl0JC49Oz0cJWm7kq0mDRaE90H2deI7WX4JrUs0Tqc1F3
9b+p5zq56hJAf1FPMyBNOclmNoZZ.mR9424QRkVL0ZPHYdwOsBHBENUM8JGs
83L1NDpNyo.LS4U0W0hBPtPup+8Vek8a8Ukc.Umo1cIhxmBSGjlSF+yYqkBm
vShFUyog9G1bJJePf0bK21pBPNiXVU7bmPpuDbB6D6i+31qpWbosSOqSAOw8
hu+SgWWm.fTlAXTkywXjYNNBBg3oqS7G2GEck8hjQAcEPCarvUa61z0A9Oi1
rI9it2CxWGI+SIURRpD.Dst1qxtatQSJTjTRQU2G8rQkiaG8zKODs+Opr46p
FnzSO.IhaTkIDzjdCLu18QsSr2XPntWzK8tLBigkoSQ3oFOqF.j3Vry5V2wu
zucezqz1F3PPRiVhILfLcaCbX00ymeC6GC20kYl41wyODdLN3GzQT0cCQabJ
pk12tpj8tf3UqNb1jl1KpxBrCUUYazBAEu.hXHALMM00YZMhq2rMVoYDSMYH
SaDCH3WeEHYDhYH9lj+gjhPDfu.I6KPx9BjbOiLciVu.FtG44QuXdnViKQDH
k17XW3H3lyK1gLN0UqgcLd60UBjafkYaHHVakOgJv.Njree6y5i+OaOjDTvG
eN7XfVkzgmiO94figuO4hQA54xAGBUx1QpUYStzGTcq38AJCTB+fN+jx3imC
GNEcXQOhWefC0vaaBaPQVlDoC8WPFSCc6KWE6iTp0WVzpjNT7StxxREDfy30
BtZAWHQvRCQ56CDym5By21CJmSb8k6jTzgyUafhiAbBlXJLp1n7jaVd0DtzX
HPvg0O8gdTinaN4HJS440F28zKSvD7oMoi5YrhiuysIGL9BJGJUyO3HAER0S
Nd8Fu35w6hGPdMQKfXLCiDgqgmFeLiWPtrCAIGbJiLLmaY3oNvvbMPOEvaJc
ccKcwvyq2Edtv.2tKFP7ZcwfRk9V0VLaxQCRS4sEmb3nLrmukJ4NAIwXCMiZ
p.mLyFMnd2I3cmf2cB8yjyMwgK0daHP.FXlh0gsGan2FQpk4ylpZtR24wn8Q
KCB0wFYfpmMbkTCYKVpltFfTe1t.IWYwpjIztWlMiJfFFbY81gCVZqZZfRse
WuUMSw+ZdfDF6CBd7zQ019GN3nsbeEkRROjK7r77.OHGeNHwp0.sa4h1+w38
pq7rZwgb1QM..TqUYYgonAqSgbsSQDSKD0X8d8gfUcmoIHNkS8tUdISU7J.K
nBAVvnXJiPnZmgvmOj+Tl+zVsO5+9Tz1G+T2y3dz05WaywWojaH.IPGTeBrT
PvBcUYY9fTl0qTFln1hQvaMS+HAuUYtqx3vCQmm9E7VkIbwahe5S4mc18JnO
uQXc45jnAOb+mbUPDJXKTZzXbJRhRWtCyvyGlYH7vigKi9b2QplKJok1RXsU
RJi2a0jeBEfQXhHW4yELs9mqmk9hgDGN6tt9VvKrY8xbpvWPZqnqkBDRnNSA
xai303JylM58F3byNlpm23Txt5GrX.MkvF2PAECPbLIietwRff.TWL4J.BDf
wX.Eg3bZ0.JbnSxaWbcLF0RGSvPDFfHIpVOwzM.bHBvEBkrIVjDwppNMASfB
gfinb1n2ybZHi2bOqZnuONsWz.0dmciDVZvML4A9Zpm4pZABvmll9zzzmll9
zzzmll9zzzmll9zzzmll9zzzmll9zzzmll9zzzmll9zzzmll9zz7K7Xnbezi
w6W5bLThGhXnjCMgHXywPI5WewPoRqTxYDYhHBgIysXRrOFJ8wPoOFJ6YJYB
AfdPJ3WY3SRMYnC0vKPTvrgcfz4M3Akj5gOe2vxCeop+u2cZz0PSnlnLYpiv
zlDXHDXejXtVVjWHL7WM+VHwzy7zUN94oKhlvIfXBlBnhzx4.hwtEosaybRV
7tqKOm6tLCwXPE1DvolTSYdnkIZS.nojIE6PjiVafT5LIEQDrbIsSZBpLY7y
c+BGK30JRjlt+3qMRrrFgQSj7iNwG5Eq9QbfBxZMvGEIQxNFXXtJvrITG+sp
Md2c4I.tqjdeMaSn7lsKtIf5TeqypWEXRjIZwgHoHqL8Lixs6kG1o2RQSQQJ
wIVX0Z9ue1ln6O+2UR06AEyssjYl377Ixc2E+9nOmwPdWIylNrvGYAWBYDnN
JXRSDcBmpo1Nj.Q3.N.mHAa3M2oaEkF.y+tOGzS6Vk3NG+uCJZqiubEZinRN
ilvYfD0lmnZNzCPgbJ2nsfMeXX0jLi4yJCb5IhKD2TDOa8MILIVWnLkMCvT5
ZTRmMn70odfxFK0CPiiKmEJD5YD+SFhH9OEGfl0U9RjjKwsSd1jx5tnDVhXA
EJo3esP4kR5Hx8KtSsgiZgToqbSTtO3KqWtKVYwW5vBTZp3h5zlUnsRKkyp0
meORo.lWZ0vpetorNj3bGm1PwaAcaaZVxTjQttxvbs3+LhSbHtxWQBwLfMNG
0Fgy4chbxkTbtoQY2BtoCdqG5Py.ZWNwGJtq8G1j1ej4nNvJSEgZquoo7mtP
pyAdYYs+V9bSoJV264BQ8p+w231FapmT6dSiVOpAGolFvwo0m6D2TxzCMTIo
kOT88gpuOT88gp+7MT88A83vFzieT0rWEu+kOaO7FYVJQjfZCuwymfSCuXy5
CGKbvz28voUqx08J5MyjveqXVVjlKBpWoSZwjomjB4gq8fMx3BNDqLsWfUFa
RAW9Ap+JEz5B4R5vEYolN9Y+2pCWMf8gAjkgAR6CCENJ2Zbva8N2sNXTWtNz
4XaJZoqmYBkF.ImRSA0j7fD1RrqBGxPzU8FA5REzwfkQGMoIrywqq7ZBWWnd
uGk3Vkzf2Ehn9JfZon2EZHTEjozmJLSJ45HUxG8t9n20G8tCcvGhG+fOTouO
wU8xaQzFd3Q0LmO24SsBUHDn1q5loc4uMwJ9.d4Shx1gxq5wI00zzo8bSPk0
7gXgt88cHq19NMcecsF.clfojhYut54zqtmyLocxqtdNoY48uE5PemlFPwna
j7tIWM6dL4Cw8On70V8T9qt2AJg5IUbknZ.ZN1TVbYPcEWgxwbLfXJPdTlCw
dRoFzY6cFvwBETodlcen.dUqGUYOM0JpZHLHbZg12kvSs.ns+kvjuI1sGxjS
ChQLG3N1TktmGHVSrvT2qkoTvsMhx.IgxKVMoVHwH09muTqXgPx7IsDz4T8m
CnpVCf18XKmOK.Y82ilCw3RnThfIfr.LaBD0TLVGZjI+p6v7sM5H07kXcvLD
LeB32viwKen6ZJHrAI1+LxhHEHgTqgiHo.DgMahtb0ma8Kmd4yZy.6NJgGRT
RstCDSkWpLzBw7IJaKxhRCVl1zMHBpDjzV.h6lEfkbtX4SiqFmLVmiFKc61b
3XMNcrdGO1tyGqyAjkNAmVcDYImQ5.cLUqCIcvojt3XxVcNoiNnrAmT5liJa
wYks5vxVcZYKNtrcmW1pCLcvIlt3Hyt3LyFbnYqN0rYGa1ryMa1AmM5jy5bz
ocmcViCOcxom1c7YYMHk0OW48ak7VJprtwx.+4n+1Fwszr6TZZeYsTKWbkKj
ZvNfhAFPgE5Fa.0BaCLfvH2AXrctSZdhb0wsRCH7Qc.9fFNwIE+3udvOm4ho
ADPQN.nNwMS2FHshUrEQzxb2Tytgpwbhp4xOPUWoVqzYW4xoYIv1DWO079Ep
.xnVAYmv0dv8SyRjcv3FptML.4sNLTCOQ0hfdG3JpY43gEtjpiHKsUj0xFiq
8.45L2R0faDFQTsbVn1QkBiAl0.OT0XdoVICLqyBwpYi47EfECiV2LJgcvv1
FsgrZImYDA3JIHb2Lrp.of0hjoqDCViGJUEnr8cF5j.aQWlTIUhqBy1x5CKf
c0rdqRpa1T5aRr9gGbZHpSBX8tmS6POGRcnme8rW1zzwqvpYMMji9RZHmzkg
bd6875Y+roo+fF39yqlQxZ5LtxbZul64cQsUYlUy5JM149nVR0jxGwSu7Dby
odhszOobtKMETq7xS6CyEq+texbHv0xrxlyLhAU6tlKjbII6.vkyGdU9kCGi
SJls8Hn4jCZkrEZ76HEBWn22aluHz30TWVaa.udJZ6mCdalPkdPFLvkqztcj
uLEbgDLJCboF0AQjtEaV+p+.fWdX2B0HaMGBL23LWiuFkl.whR.9y.1eFv9y
.d1dFvKiJEVGcxaOrd3rmFl7VIF59G9Q0jiDEPK+8Nc.cFOCCSzAwRcFLl1U
mcTmtCiE0l.Y+t+uqUFEr+SAl4oesRh4a96+48+71+McnEe1fpu1T1FUsC0y
62AMeD8+sd6i6S3w0feWhE1e24a4xGYUvWa91C9G9cJSb+a+aCd7YcJG70q2
B+lfem5F+l+ZxG9X5GScEyce7+Q+OQaNDEj6a42G.9lfx2Q5K91fu9bS5ax+
k7yG0+VMvBUe3ruojm8e+c2dunudagJ+cG8f9.4qxTwNzEeU1tuxA2drS0aa
C7ZxOjtOgTmWyZnge8GNyj4zPVW1BZq6.cD1ibGZeLG1gbgkJWtVmG8uqL2.
eeteUzq.C59UqFNC4i363OFDs8CQaTFMk+STWTK3VdcQZs5alM6lsfVNRsol
XkGOUa7pI7Ykxxpw.eH20FCq7p.dz68Pq16XbP3GhWuLX0lP0mdYP3wigO99
CCGhgwsE6+F0gL.bACIvTlDmUIMRSgnYAhc3wmeY8QEho1LvSpc+NX.Dhema
4ELgBU+KEhXYU41TgsYA9D9vg3MmNFErMdsxZqUahiGRPh1ZFj.SB6eEjHQJ
SMQbAFkVfnYyHwnzieUMuSYhY7GhB9G+9ADkjskNSLwBSjLvWPofzp7dJskf
mANLSsyXk5mfUEBpL2bvHh4.kab+ny8FYPLAplsxgRBBhELtYI.NOYl7rv2j
Gedezgm+rRVH.R6ACmHmCIlmsTZFhYsywISTBisOVqRz.0AYK5lnaLMEfBRR
H7ZQeVuHJu6s7ei1HAlJRhZU0HAEHnjymaAxkjPchRu2TeJEt+Icb8YFNRD7
WD7Vyvw2xAAuMcLApdq2pGXLk.pNqJBCae7w0wixk1x5KUh8djqvhAXlXZO9
jlVs7CJSJdIJX4ZccMS8gT8ofAb4xQiLaPFK1TFyt.WN2r4fYypsJa15dxrJ
mEJ9gLzBLWvXH0ERK6dSqbaOYZN9.dbdDvWpr.BT3lX.SRprqwWwb+gqztAg
MhEIZ249C4HRjB5XUD4BTTs3uOXA6S8ET9TFzEQvKvHDJstwCSyw77WcDgGr
KvC7l.OlxkCTxKYSnD030MahGZRI8j+ZDgOmJD5Uqh8taPVIPI0xJrT8OJjD
jQt.bcjgltyPKu4Hh.NUP5kMg.il.DfapAfjEBFfouqKArB0j3gUeuQBpn.W
kVfSMmG3bSynrdRYxDhyjXDXp4iAmaZvImZZH7tfZS6.pqMM3jy8GDlqVNMl
zqAwUBHwh7WY9JCllp+pUJ45rL.hH.DNIaKybrR02aJYoF26r75kFv21lFjL
4ygbtogm74PtxNLYaS4lRcYvQk5xfcfJ4FHyC4vDSdfDkoyHIigAmYQZigiU
dmwpy6JA+AGSFHiMK1EJh4LuMIMaXcbZFftQHaigw5iCgTIcDesf.y7dlqFK
QFyoQPXmlFgFMt7Sd0LJ3WH7iSMLNRzxmh9r6b0BpVJFIqfoTjpVpsVRQP7x
7WCAMY7rhNr+O7b7wO6L2pvgsvRMMxYOBSYvVTtKaod4ZohNLL8YSnK6dOlg
uF5jwLJiExxcY5zwlNKi1D9oOGPgH8+4bGGMDcbJtbGWBmrg5CgO693743W4
Z5tPXEQafE9DZP67Q+kkgOVS+DTseRZfMnzjAUk1pQOEM62CWCOKSSxZPeXc
zGSxhn0aVe7S4GlhWsRGG.FFNHQUw2l67auyjIWK2qVd3bV0j0yeby5Ge+wm
2Ge5omye8JIoSw23CUeiGdJi7.NekK6HrQoryqjsL5kX0hyaWtPAD6ByNWt6
zwEQpr1a04uWxBH6Oc34nCKBWuR+mucSb7NswZ5W+g3M4WO2V826JjhYXScN
N4OTZtpYHGzig7cgai13rnJ7bAK2pvpZgRcZmRwo9pWyRYbsSYTZWSKwf5R4
Vyb0U4wTa7+3ckB.chlnzHBkktXBlkDI5Z5SifoBjlIiYl5QgPhkPJihQHgn
v9OqvkjzwGKuXyhs5zRVADiXN.HyB0nWefWxGp3YBavxxlLmhnULUlWvhcmb
NTYOIvLhfDRBI5IXX94HFFIH07dm+xJ51vJxDCa+nv9Uu7nIi+iF2WHTPANC
gfwuePo8rePIbm6GvqpeHk4OK+5bpXAWoc2yqWtLMYfu9mMtsmMe7d1sM9Io
i2yF11ylLNOa2Tgkijw6+iB3ziBNDOJGdRYtK7pdPBtCOINe.5RB1j8jvt7j
fC.5wcA8fnl09qTMBgPIVP3Yg1C2DZJ.SHyxOGZJi7BjEC+hRGbV+e1cAitp
mDykAdzPnJvEY4riy+pdPTWdRTxP7jnt7jXC0SpskKnCwvDk35SBV2zSpY6A
LCgAxM7vTw+hZBnLtgBNR9qqscibYrXHVng5hhAxPnU1EwqgPI.wE8MjA4Iw
tds+XpRZo795Gd8+DhKfBXH.EWzASFhI2DfCStwxllbKXvbSmg.LMINuK9mz
r3EE.Fp42DmrjDTT6UNKlqo2X1rXVyGZpxak9SrfajsfFVPS+mC8dIcr6Apa
CAC6NBwtXLMVL.RjEq4s08jFhkPwbW2fvU+jbQIGdHL0A6zJDCgoNXmzQMXO
ImzQc0OImlyULrqFrYXt8rA1e1WmtFmL4e.vWjSZQFBSxPtnEAMDxLHWzhfG
Bi+PLW2RdsVJkZMj9fPJcpiF+NV4MFZobm5Ckr1afDxQtHkyFBaZQnNLPccO
ImbIwfHl6xCZ.dNPm7Z2PXnAzscdLDOIWVTtjumGMK4ft33.DrIK9442MOhj
2d+z+J0bejIBYGBq8cBCMV6Cb2ZeiVuKV2yJZruoLzHRzYJMajI4uFZUSPhv
oE+GBKDgDWlJSXCxiBd8atmffKFE24BcaGVM25nlc.NFsNWVsZPFjbUevU+j
bZSjPxPbnBPrvYyou9mkSdmeP1gBzosRBGjchCcZyjvAY2jPL45mLJX3EiyQ
+.cZ2tsz7jpkAIPtfvNSpQiQKE47f10K3614FiGjmEv4m00KL5xihMTOIXqV
0LDOIm19izgMOhL0DWnTW9GKE5mv7QO2PYbjSsbxXbpqt+ngCczX41itjyGF
psHfbUpr1sHfj48aN0v7vE+qz8HPDnAaOBPmVzePNSYHzoE8gCxBwtsU0A5Y
Qu9U53T43GNFPmLQNw1r5ESgIapCwLMNB47ecsMtjClo0PnCOJgyk4g21DXg
XDe3sE.eD5H9vaelxH8vcIfCpLG0D.xkHZG8ynDw5ThPcpRjN0SfNkINmjTx
yPnGkB54KU1MMCY9SIblv69wnsmLgBdFGzTDId3oUq2r4bLamOY9xxlfzb+L
Ku7JDe2HIQo6RGD2X0VoLgyMFqKRL4yzTy8.OGT3ThDjjhnDFhSnIuRfvTbR
ZiV51PWdV.nz7D.Rgg0Gw5KAKlt2VCL8pARNVd9ye5X7S6CWtNsvjAJjvg2m
JHoKIhk4Qk6dQAnqytm7BdmGL9gSOF1z.PzlD1un.ppK0dbpIX4gBg4UDJ.g
JFa7GT2bBKVW7tQ.lLYLAx3HClJ..Ho3MWLN84T0VFuOAkwBo4UTHfIKdS5r
sJ4Fe25sZY9nyCNXIBxL2V1nKRseIbwAGmj2NOVTiHmihAEE5DmE0Db.UHLu
pRCrrPGiBLXIS+C27Jy2znHyYOMJj.0lOMYOgjR3bi.ARZDRnryva9J7nRq0
+5tnsA+T31CA+TzKqeHdyxKYDT3iOVVtCqG6RvSRV2VOWljm4Et5IDu+vl0J
MZ+GZ0cMMwnbscnvuFn1xKg+B6LUDYuYTqDeckahhickZ5fbNf1x.fQp77TI
dp.9v1gyUKMaE4UZFT5kQx7hB5I1DJbnaVuDc3P3SQC8XQeU2jSwQ1D+pupA
EGbgdEs6s9pp21rbMthyNbaTLeIH0Aoqjwrb1Cn5y3AUaiIYg+CaNEkQ7R1a
U1zFB4LhQi+4FnTeI3Hz.2G+wsctEdocQOO2DORsvu+SgcuABPpkqLpx3XLx
L2Ao1dId3af+w8QQ8nElfdX8OFKlz1IL7Mt+ynMah+Xyst7Et4+TRoalJA.Q
iqWnrQiazr.EvD8eTEhSGzNvoWdHZ+eTY6PmAWsnHHY3mpVRilzRg40lMHMv
8FCJzsPm06vHLFVlJNxSMnRAbRbCqkOUcnK8mlQ7RlHxgfjFjDSX.YpIhbXw
0atcCSGC20lzeNKW+gviwA+flJPuqOOeyFysPmr50y9p+mu5+OGd+REC
-----------end_max5_patcher-----------
1 Like

At this point I think it is worth mentioning we are focusing on design rather than optimization, which is a common practice in software development, so hopefully there will be further optimizations once we freeze the design. I can’t load your patch as it is missing bufview.js, but if your focus is performance I think I would try to analyze each descriptor object differently, and they are definitely not direcltly comparable to framelib.
I do appreciate your effort playing with the descriptor objects, I don’t see them as newschool with respect to framelib performance-wise, but they do have a different interface.

1 Like

(the bufview.js should be part of the FluCoMa package, but either way it’s not integral to the way the patch works)

Yeah, I appreciate that it’s a different paradigm interface, which I don’t find optimal, but it’s not huge problem. I’m just trying to see what the practical cost of the paradigm is as I think there will be a performance hit/limit regardless of optimization since it has to go in and out of Max-land and buffers a whole bunch for each step.

I’m working on a comparison patch between using an even smaller analysis window (256frames vs 512 in the posted patch) to see if that makes up for some of the loss in speed/performance. I have to play with it more though because it is super spike-y in terms of CPU (getting 40ms delays in the middle of everything else).

I don’t know if the deferlow mucks things up for the purposes of timing, but I’ll post what I have as soon as I get it working.

Hmm, I don’t know if other things have changed in the code in this latest update, but in testing it now with alpha07 and sans derferlow the performance is significantly slower. Like 500x slower…

If someone can test the patch I posted above to compare that would be useful, but this seems pretty crazy.

edit: it looks like removing the deferlow slows things down. Even with the deferlow in, it’s still much slower than before (taking 5ms instead of 0.5ms).

I wonder if using deferlow makes it actually faster or if it just reports it being faster due to how slop is calculated?

OK I compiled again with all optimisation on, and I get the same results as you. What I cannot get is the quicker version you had when I revert to alpha06! Do you have the code you used to use? Also, I’m sure @weefuzzy will have some wisdom here…

It’s the same as what was posted before. I just ran it with the plenary version of alpha06.

Well, first thing is to see if any version gets back to prior performance, so try Alpha 5.

Then, rather than guessing, you can use Instruments to check the heaviest thread with each behaviour, and then we’ll know what the culprit is.