Mattilyn Mattroe contributions


#21

this looks awesome, was thinking about how to send more complex strings, I know you've basically just given me the guts but is there any chance you could upload your object so I can have a look at the rest?


#22

Sure, this is a patch with the object:
vlt touch sysex works.axp (2.1 KB)

If you wanna find out how it works with your hardware you need to find out all the specific bytes and how they package their data etc. (thats why they call it system exclusive, there is no standart for it)
With the voice live touch it was all documented in the sysex manual.


#23

superb, thanks very much, I'm cool with sysex implementation, but not so cool with coding, there's an old Akai S3000xl over there taunting me, saying I can't realtime mess with it's loop points


#24

wow, what good news! saves me a bit of money, and what's more important, simplifies my commutation scheme :star_struck: :money_mouth_face:

sending lots of SysEx via DIN is bad idea in any case, because MIDI DIN ports still work at 31250 baud, and SysEx messages are byte hogs.

so, to avoid many kinds of problems, some king of thinning has to be applied before actually sending them.

here's a quote from Gearslutz that explains it very well:

Another more thorough answer to this in case it's not already fully covered. (I wrote this out mostly for my own understanding of why this is necessary, so please do correct me on any of this that I got wrong.)

  1. MIDI runs at 31250 baud. That's 31250 bits every second
  2. To transmit each byte, actually takes 10 bits: 1 start bit, 8 data bits, and 1 stop bit. So that's 3125 bytes transmitted every second
  3. A "note on" message takes 3 bytes (noteon+channel, key, velocity), so that's 1042 note ons messages per second. Alternatively every note on message takes around 1 millisecond.
  4. A chord on a poly device might have up to for instance 16 note ons. A drum machine might have e.g. 8 voices. Add a few monos for good luck and you're in the realm of events that happen at the "same time" from a conceptual perspective are now around 30 milliseconds different in time.
  5. Also consider that we require a 3 byte "note off" message, regular clock messages, 3 byte CC messages, multi byte Sysex messages etc. all to take up the same time slices that we want to send note on info within.
  6. Now consider a bass note that might be as low as 30 Hz for sake of argument (i.e a period of 30 milliseconds). Imagine that you are trying to place two competing notes in a similar frequency band (perhaps these are actually a bass note and a kick drum). Place two 30Hz sine waves 15 ms apart and they cancel out. Place them 30 milliseconds apart and they play double as loud. You can see how being constrained about where note placement happens based on other messages on the same physical channel hurts things musically and sonically.
  7. The easiest way to get around the situation where playing notes for things that conflict like this at more exacting times is to add more physical channels.
  8. Note: This is one example, another similar example is to just consider the emotive feel to drums / piano. We notice small 10s of milliseconds changes in these values.
  9. Also consider the values that you might enter using percentage based swing. A 51% swing value at 120BPM shifts the delayed note just 10milliseconds (50% swing: notes at 0ms and 500ms, 51% swing: notes at 0ms and 510ms).

So how many physical channels is enough? The answer to this likely depends on how deep your GAS budget is and how much you face the above problems.


#25

I'm also super happy, been wanting this for like months :blush:

Allright thanks for pointing that out!
For now I only want to controll like 2 parameters in real time, but my voice live gets it's midi via a dsi tetra that is also receiving midi notes. So i have to see how that works.

The Ideal solution for me would be usb support and then having one midi stream for each device.

Should we move this discussion maybe? I feel a bit we are cluttering up Mattroe's thread.


#26

good idea. we could use my SysEx thread for that.


#27

That's this thread https://sebiik.github.io/community.axoloti.com.backup/t/solved-sysex-questions-and-answers/5089/18 for those that come after. Apologies Matt for plotting in your playground


#28

No worries, good luck on the sysex hunt!


#29

Hi Mat,

I'm curious to try your midi looper, however I get some errors when I want to compile your help patch:
Start compiling patch
Compiling patch... with /Applications/Axoloti.app/Contents/Java/firmware
BDIR = /Users/simonschmidt/Documents/axoloti/build
FIRMWARE = .
RM
APP
! /Users/simonschmidt/Documents/axoloti/build/xpatch.h.gch
. /Applications/Axoloti.app/Contents/Java/firmware/../chibios/ext/fatfs/src/ff.h
/Users/simonschmidt/Documents/axoloti/build/xpatch.cpp: In member function 'void rootc::instanceclock__2::dsp(bool, bool, int32_t, bool&, bool&, bool&, int, int, int, int)':
/Users/simonschmidt/Documents/axoloti/build/xpatch.cpp:1128:24: warning: integer overflow in expression [-Woverflow]
_posfrac &= (1<<31)-1;
^
/Users/simonschmidt/Documents/axoloti/build/xpatch.cpp: In member function 'void rootc::instancesave__1::dsp(const char*, bool)':
/Users/simonschmidt/Documents/axoloti/build/xpatch.cpp:1197:34: error: 'class rootc' has no member named 'instancemidiloopc_i'
int rem_sz = sizeof(parent->instancemidiloopc_i.array)parent->instancemidiloopc_i.LENGTH;
^
/Users/simonschmidt/Documents/axoloti/build/xpatch.cpp:1197:69: error: 'class rootc' has no member named 'instancemidiloopc_i'
int rem_sz = sizeof(parent->instancemidiloopc_i.array)parent->instancemidiloopc_i.LENGTH;
^
/Users/simonschmidt/Documents/axoloti/build/xpatch.cpp:1201:48: error: 'class rootc' has no member named 'instancemidiloopc_i'
memcpy((char *)fbuff,(char *)(&parent->instancemidiloopc_i.array[0]) + offset, sizeof(fbuff));
^
/Users/simonschmidt/Documents/axoloti/build/xpatch.cpp:1206:48: error: 'class rootc' has no member named 'instancemidiloopc_i'
memcpy((char *)fbuff,(char *)(&parent->instancemidiloopc_i.array[0]) + offset, rem_sz);
^
make: *** [/Users/simonschmidt/Documents/axoloti/build/xpatch.bin] Error 1
shell task failed, exit value: 2
Compiling patch failed ( /Users/simonschmidt/Dropbox/Axolonatics/Simons Patches/experimental/midi looper help.axh )

Any Ideas?

EDIT: Found it. There is a typo in the table/save object. There is a c after midiloop that doesnt belong there :wink:


#30

Whoops!

I've actually almost finished an entirely new midi Looper object which is simpler to set up, and better generally.

I'll post it as soon as I've had a chance to make a help patch


#31

Ah very interesting! I've been struggling a bit to set this one up with an internal synth somehow...it seems i got midi feedback. The first played note turns into a crazy synth drone and the patcher crashes.


#32

MIDI LOOPER PRO!

So, I haven't quite finished it yet, but it's pretty stable. Needs some tidying/optimizing and stuff. I haven't uploaded to the library yet, but here's an embedded patch-

midi looper PRO upload.axp (104.9 KB)

If you find any bugs/have suggestions, let me know!

It doesn't use a poly subpatch, which means the object is quite 'big' inside. I'm going to make some stripped back versions with less voices.

It's currently set up to record 9 voices at once and play back 15.

The patch is set to record up to 7 slots, and each slot can be 8 bars. You can vary this on the object settings.

Control is set up like Ableton's clip slots-

trigger an empty slot to start recording, trigger again to play back. If recording and it reaches the maximum bar length, it starts playing.
Trigger a full slot to play it, if playing it will restart.

Most controls are quantized to the bar (trigger, and it starts recording at the next bar).

It uses a few objects, one for sync to midi clock, one to record/play back notes, one to record/play pitch bend, cc and mono touch. Another that record/plays poly touch. Did them as separate objects so you can get rid of what you don't need.

It records at 128ppq, and can quantize to 1/4, 1/8, 1/16 and 1/32. Note lengths are preserved while quantizing.

It works fine with internal synths, as far as I've found!

Any suggestions, etc, let me know


Midi looper internal route problem
#33

Cool thanks for sharing! That was much easier to setup. I got it working looping and all. I was experiencing sometimes that a recorded note would sound sound like very short, although I had hold it very long.
Then I tried to just replace the fucked up note, by overdubbing it, which didn't really work either, only the extremly short note stayed.

I think the feature set looks very very good. It has almost all that I would expect from a midi looper! Making a launch style midi interface with buttons and leds on a controller could be a lot of fun.

I have some more observations:

I think a more common choice here is 96ppq and the option to quantize to 1/3, 1/6 etc. so you can do triplet grooves.

Is it really neccessary to take a 16b table? Wouldnt 8b be sufficient?


#34

Glad you got it working! Thanks for the feedback, always welcome.

The short note may be to do with the loop point, it will cut short notes that go over the loop point, I think. I may be able to fix that. Out of interest, were you quantizing? I haven't used it as much unquantized when testing recently and may have not noticed something.

Usually, if you record a note that is the same over a pre recorded note, it should overwrite the recorded note, either cutting it short or replacing it if it has the same, or a later, start point.

Re 96ppq- good point re triplets. I did it at 128 just because I was thinking in factors of 2 because it seemed seemed easier that way. But I hadn't factored in triplets, where I'll prob need a ppq divisible by three! Adding triplets was next on my to do list so I would have found the problem then... It shouldn't be hard to adjust. I might take it up to 192 instead of down to 96 in order to preserve resolution for cc/bend/touch recording. Though that would mean bigger tables for the cc/bend/touch recorders. Note recorder would be unaffected, other than resolution.

I think you need an 16b table unless I'm missing something... An 8b integer can't be larger than 256, and I need to store start/end points for the notes and they get much higher than that. A start point of 256 would only be around 2 and a half bars at 96ppq, so loops wouldn't be able to be longer than that

Thinking about it, an 8b table could be used for the cc/bend recorder as that works very differently to the note recorder and it's only storing the midi data. But then that leads to multiple tables for the Looper...

I've got the Looper working in a patch that has 3 midi loopers and an audio Looper, all controlled from a launchpad mini, Ableton style clip buttons for the Looper. It seems to be working well so far, but I haven't had a chance to play much yet. I'll probably start finding more little bugs while I'm jamming, rather than testing, as is usually the case.


#35

Thanks for the response!

I have been mainly testing the unquantised option. Yes it could be that the cut off note was supposed to be on the one but ended to be on the very end of the bar.

Yes that is also what I would expect, but somehow that did not happen...

I think recording the automation at 96ppq and then maybe interpolating should be fine, no?

Ah ok I understand. Yes that makes sense. But then I wonder, does the table have to be that huge? I mean I had my 4track AUDIO looper with this table size for quite a while.

Maybe you could use some black magic and write 2 7bit automation values into one byte of the 16bit table.

That sounds very dope! Would be curious to see that setup. You got any videos?


#36

I hadn't thought about interpolating, will have a think! Though I quite like just having the higher resolution because why not? Though I may think differently about that than some because I'm not trying to squeeze in an internal synth to the patch, I have an axo dedicated to just looping. So table size/processing isn't as much of an issue.

The table size is big because of the way the automation recording works. Note recording table size is pretty small. And the table size will reduce a lot if you set the objects to use less slots, and a shorter max bar length. I've got a couple of ideas for reducing the table size for the automation stuff, and I might split out the automation types and have separate objects for cc, bend and touch. That way you can take out what you don't need (I imagine a lot of the time just notes and bend would be enough)

The bit magic is a bit beyond me, I only know what I know about coding from playing around with other people's objects! Something to look into though.

No videos of the current set up yet, but soon!


#37

Oh and the shortened note, I think I can stop that from happening, by quantizing the note to the one if its slightly early. The Looper actually starts recording a 16th before the 1, so it catches a slightly early note. Which is fine when quantizing but I hadn't factored in unquantized recording, where it wouldn't get nudged into position.


#38

I've sorted most of the issues with this and posted a new thread. I'll post back here when it's ready for the library