Faster Realtime MIDI Sample Triggering?
I have made a relatively simple Max 5 patch that plays back sample buffers (monophonically) according to incoming MIDI notes. The response from a MIDI controller is too slow, though. Roughly, I’m about 10-20ms behind.
Can someone please suggest how I might increase the performance?
My settings: IO and Signal Vector sizes are set to 128. (The audio interface is a Mac-based Firewire device, so the buffer size is set from Max.) The samples are 150 MB total, and fit in RAM. Dual 1.8 G5; 2.5 GB RAM; Leopard and Max 5 (latest versions).
Given that I am simply playing back small, monophonic RAM-based samples, I don’t see any way to make this faster.
Below is a VERY simple version of the patch. Most of the original has been removed; this is the basic algorithm for playback:
----------begin_max5_patcher---------- 2725.3oc6ck0jaiaD94Y9UvRoxKolQKt3UxSalb8PhqTwO500TThPZXVJRUj TicxVq+sGbQIRJRJPIAJNNicYIJvqFec2.n+PC3e496lsH8qz7YV+dqOYc2c +x82cmnHdA2o98cy1D70kwA4hKaVB8KoK92ydPdpB5WKDEuMnX4KzLq7fMai oaB1NOiFDRyJuvjcaR2UDSKDOEnpzUoIE4Q+WpnLxbfp3kowoYRgBL2Fy+yC ribI9.zCUJBNGX8Y08HDfnj0OmQWVHuWae1SzBhIhub83egvUtGoDU7e1Rk2 vrY6O0h00DBGWhMj+p8f9N.OgP3hrI90EBd8IIXi3wM6GyhBhKq+QghxXP2i dUvjnjlPhBHUZ.kJf8jihouRyxiRSpb02M6PsER7P7ZH1V9k.OsvfJUXd0JN c4OSEBCnrvP5pA9XR2RSNbK.9UT6i5WYTx1LZNMoHnPI9Ue0A6hKdtcCg5me UvRZm2bqn9cyVmEEllvEhZ2Iu3xWGqJaKLPrqJ2hqHIXaK2bQZZ7hfrWixiV DSqoMXtNAIQaBJnEQR4AA1eeQa1lEkTT+YEUHeDyd5kfhDlCzGXUjr8x+FZQ PXPQfTPqnGq51VwNol6asxa3FuglmGrlV9hp4KK8gel4D+XTRTw7BV4UttVc kO1cFsWK1g6IVXs3H9DpzAdUzA86gtWjq3mBEOipeT6pa5SCsc7bDtx1Hehz 8FIczadqcah0v4F0.oN3fiJK+Wu+9xCd3L0dRXoakxIPdns.zQD4W1keVqJW oRg6rRUU6uLcyFZRUSHlEjEugKAxcEq905CptsabZP3hfj0mgAKQOCVokpyQ 8lzt8pPVNOSIGX2v9UDLEOU8fqVvDDT.JD6drjNgSbkpb20XPGFZQI4EY63+ zZDsxX8mw5UHzhOFGSXoobPg9B.02UOasyzNydbry5qGGS0ECxVBfBzDila+ 8PWLD6QoOFMGgfITaPPE0lG96iQFPHihZqmVsxEi+bk0uMm+WS1tk5KYrCFq gKR2iKA2BhdXzywQIcM5YQkhe91g57zcYKKEa038rpW6Bo4EQI6C04SGj0FW 3KQgg0CsPnLiB2lxTS4kC4WKaigJ17wVnkbilThMbHnMbxH1bW+2hVI7dZzW tQSG4FqobaCmT3sst1232ldkj2lhs8UTrUExjeIce4AuRCel8ZX8g9bPQQVz hcExNmpR+mFTc0JEY5vqVamum2SuTxsNNcQPrhCy8OfY2e.EDeJUeWC5li3C DcN+MMYHbVQ6rmyDguYbq7MCtT9lcPRd08gxfqvRJkbGFcy57Tdms4qNayeT 32X8Oi1RELNa8up57XPdmuPlKUzMoHF4zLWBGNykRjYKGY9Ng2RH19.S6tXi Sboq+MmPIdeAVayRWmEr44bZLCKXMFXJZlT.ruJ32uSHrvw+VSXAqNF2s9hb oNDPjzivVSVJdnx+NSH0Sq1i3CJT8R+Mef+5j.g0r+P826IF7XcT+tYzMKTc Euuv85OCqI2krMX4Oaka0CsSnKVeJocxaH5yyj4IuA0BmQXdhKCM33n83WlV w3xaUQqvt39JSH41Ua41eZg2d5Flq26g4N4By05uEs9k3fjPwP0ys9nXhWxa OHWPaA45LGzc.qXQLpDfLO..flCmt93Lfx3sbXCv.JBIE6QvPxYDRJBXlXRg DUlMHxcIhbrtXdj3CKEnN8Swrwjh9+mXRMVjl8LZjE6Vshl8MqbdtorjV98Y LzDvomQLgwCQLE9PGIN6bpglrhENXAe7ImHJrmXs1GcHrc8C9cbF0WIN+hpQ rGW9RPRAM6wfGiS+h0OMaeqaOIOg0GRKnV+c149w4eI30eZl4TIxLVA6OpZD zjUir9QdQcpR3kZ8WMsNAIG5NA3NlJE7DVobJ2DiqRf2B2D2IqFY0i4ujssS Uxew5irSab2D6agah2jUoD1o93OYb2Cm58uONpB+Ir+AKtxdbO9PPgw8NP2h lrffIqNg1o93Oab2C+ag6Ab5Nv2k82+wSiR+GJ5RG49OfnIrVouVsdZLZ0Rk xqicqVS2w9tnS8wezz5B2aRiVjIbz5mN1PiGuNFdSZzx9xmnmaIW3n4ZSz3j gK75yqekzWmVzfoNcRxKTe7ei78k7NH3A2ws4D22WFao8D1elSVulI2U6qlX z0aNHX1mqWy70WbVYVWKfNgHQHIb6hNcZxUyEVObY+X.awocf3RLMr+pdO0Q 0R2BT9Y20QAu3e93Jh+Uqdn0J2WjIkpF9u8oRIBHykRka5sOWJgts6tcoSbk GQVCUgvhklMtCbhqz4o7dxT9Veo6eYKXW+JKhYcWutUaaR+ozn6krK6WLgxZ STXjUBaHjylPKMdPURjLwRi2DKH9Kyj.eFlDWwkvMGPFyTs0r4hlBLQiVpnc yIdrbwvmSKLR1KCTaMHBD02vKozaN0glJmWwUx00QLiWIn2BY75scoA+FcM1 NsDah1vMXZI2.MSiWxzJOdI2h0p56oU5UMjeUb9y2D80aaz9Jd3HNBd3fDM1 p9xiVmvv0wHneejYB52UNVFnbghJW1PXG3vh4WiGx6g7ahP9ES.x+nhmyXFx +qAGZeXGzCB..aemOA+7YGDHrxRXS2f.a3Cd4gBFrKLJ8ZFF3p3T1K1DyJkh GE0To6ewSJEquq7kARyKvb+ZcLxLRYUBwI.cuH.8bX+w8gVOp4h.jARkOSXs m4olarWZLsGrWgKv1Sz.6wGA6l3DuadR98CLsLX9vCY0WSSCYbqDYWZt5YZb dAY4CFkUp445LoIfIiJUMq6tFwU5B7X5WYb0bK7uQa5is2gx4yxr8UjRQG7f 6H40z3caLLux0fLGaIj4dAaJqURA9SS7rKXvLOe06csmFW+ceyb6.qk64nZt SFz1nTztoUuA0xpQ3QR2EvoK3MIORSqk4KeXIZK1SmcXNGc2wy7mVrH4qqUh +zx3tEwoCyD22o+ZxkIYt1WqDHifU+2i.r8cX3oeBjAwlNAxZr0Fc44OlDyQ tBbR94UO+wvDSm2U4L20shrenUbAMXbAiDrP3.aeJ9ZOsNdnQlmoE33Ptd1L 61rnKtmQC1cTAApMBFr2Qoc2hzrPZV8.0HXH1UxZMD5J7qDE0f15tfu5FWsF 6446paCf9NBGbrCv0ivOB4v8000U+riLs1nf8Ls2.2QHJwJncKA745LHoEGh gCxa3rbJ7tdYpYYPaMAozjeHc0pYUjpx9PQ5ugfzqCDDInewlH25KPG4.cj0 zA6xiOplEZ15EC9dzA2sAl11LLX42ZCzg5C5sNiYp8SE2893fSNQYPao9Ql0 zX7w6wns0TygY6omlZ7Ys8QDsC5icQ11hs5kVZVPOkhwGUw5rzzWoeq+UD.Z n5BOetxP.VpiN0LW53K0DxVxgHsm4xGNdNL0CZauyWbEnU7.qSAgDoaFliBu 6mxgt1VwpEYywQ0zdDMGo70UjvZHRdCShb73CW20Q8+mOpiuP4zlngf5iFUr qwqqi8B8Z6Y9SHYZDwIcDIxvDI9dIkMmJW4fQc81+qKTXgPcLzFU7qQSBWG. zwyL3mm1MxMdNEXcZ7.NtNEd53U3PFeYBpiLMd5NGczcddiJN0.B5vdBNLYB 6S39f9X41nEn7GWpsumAZ7nlLw9wud++CAc.e9. -----------end_max5_patcher-----------
(The stuff in the left-hand corner is just for getting the buffer names.)
Thank you for your consideration,
You can tighten the responsiveness of Max by opening the DSP Status panel and trying:
Max Scheduler in Overdrive (On)
Schedular in Audio Interrupt (On)
For good measure you might drop your Signal Vector to 64
Try making a latency measurement patcher by converting raw MIDI bytes to audio clicks so you can isolate the problem (hardware, max setup, your code).
I can’t look at your patch as I’m still using 4.6. But instinctually when you said Mono, I wondered if there was a envelope fade time to kill previous notes before bringing new notes to full volume. This would add a few ms.
Interfaces like the Echo AudioFire series have undocumented safety buffers (in the audio driver) that increases the latency by ~5ms.
WiFi should be adopted by all hardware manufacturers with OSC as the transport protocol. That’d get us past this silly MIDI stuff.
In the meantime good luck. You can easily get good performance out of Max.
Sorry I still don’t have Max 5 so I can’t open your patch.
Just one silly thing: have you cut the silence at the beginning of the audio files that you use in your sampler? If you are on Windows, the "Silence Remover" software is great for doing this:
(On OS X, I didn’t find any equivalent freeware).
Hello, thank you for taking the time to consider this issue.
> Max Scheduler in Overdrive (On)
> Schedular in Audio Interrupt (On)
I’ve got Overdrive on, and tried the other setting both ways. I didn’t seem to notice any difference. My patch is very simple; my instinct is that these settings (based on threads) would have no bearing in my case.
> For good measure you might drop your Signal Vector to 64
Anything below 128 is bad news for my test machines…I think a buffer size of 256 should fine, based on other instruments. Perhaps I really don’t know…
> Try making a latency measurement patcher by converting raw MIDI bytes to audio clicks so you can isolate the problem (hardware, max setup, your code).
That’s a cool idea; thanks. The hardware turned out not to be an issue; about 3ms. In terms of my patch, I can’t foresee any faster algorithm for triggering samples in Max. Nor can I think of any possible changes to the Max environment.
> I can’t look at your patch as I’m still using 4.6. But instinctually when you said Mono, I wondered if there was a envelope fade time to kill previous notes before bringing new notes to full volume. This would add a few ms.
Very true – I had a 1ms LINE ramp. In the patch I posted, though, I even eliminated that, and the latency is still too high.
> Interfaces like the Echo AudioFire series have undocumented safety buffers (in the audio driver) that increases the latency by ~5ms.
That interesting…never heard of that, but it’s obviously true. (I used to write audio drivers for commercial audio interfaces.) The Presonus doesn’t have a feature, though you can enable one in Logic, oddly enough. Thanks for the heads up on this; it certainly may be a tech support issue I will have to deal with.
> WiFi should be adopted by all hardware manufacturers with OSC as the transport protocol. That’d get us past this silly MIDI stuff.
Agreed…I had high hopes for MLAN, but that seems like ages ago…
> have you cut the silence at the beginning of the audio files
Indeed, though this is certainly the sort of thing that one can forget in the midst of looking for high-tech problems.
> You can easily get good performance out of Max.
I thought so…hopefully I don’t know what I’m doing. :)
Thank you for your time,
RESOLVED: I removed these things from patch:
1) All send & receive objects.
2) Sample playback rates other than 1 (sig object).
3) Pass-through of signal through Tap.Tool’s shift object. (I did not modulate the tuning.)
Hope this helps someone else, as well.
PS: Regardless of any issues I heartily recommend the Tap.Tools objects; I can’t imagine making patches without them.