Cabbage Logo
Back to Cabbage Site

Roli Seaboard MPE with Cabbage

Hmmm… yes it is strange. As my Block Seaboard isn’t doing the same stuck notes everywhere as your Rise. I think core Csound/Cabbage developers really do need Rise & Blocks Seaboards.

Then again, Roli continually re-iterate that the Seaboard just sends standard MIDI. So I don’t know where the issue is?

I have also seen stuck notes in Equator- so it’s also not 100% Cabbage’s issue. But if you are getting many then something is happening.

@rorywalsh would it be helpful to put together a fund for getting you a Seaboard? I’m sure between a few Csound users we could make this happen easily (if Roli doesn’t beat us to it).

@iainmccurdy just a question for Seaboard playing in general- do you find you need to use talcum powder to stop the silicone from bunching up?

Is there an equivalent dashboard for the Rise? Maybe Iain can try it and see if it matches what Alex is seeing. I’m kind of with Iain on this one though, I think it’s more likely an issue with Cabbage and how it is handling MIDI data. Iain, you could probably write a quick test instrument that would report if notes are being stuck, or not? Your hypothesis that some notes are getting MIDI off values seems like the mot likely candidate.

Having played more with Equator I am convinced that it’s doing some of its own processing, and at very least smoothing the MIDI data.

Also, I have noticed that long notes naturally die, even if one was to hold down a note it will stop sounding after a few bars (and not in an ASDR way either).

I do however agree it could be an issue with Cabbage, but I am also aware of how complex the Roli software & hardware is, and the possibility that firmware / software plays a large part with this instrument.

@iainmccurdy I would love to get your thoughts on a hybrid velocity function. I feel it’s too hard to get consistent velocity when striking the Seaboard. Yet in equator it isn’t that hard at all. I believe equator must be combining note-on velocity with after-touch to improve resolution of velocity. Also have you found that after-touch is a bit bouncy (at least currently) in Cabbage? (This also could be an area to look into for MPE data in Cabbage)

Really looking forward to all the new sonic landscapes that will be created with Csound and controlled by Seaboard!

I’ll try to get to this soon. I’ve just got a few other things I need to prioritise first. I’ll let you know. In the meantime, I’m happy for you guys to keep discovering stuff. Oh and I’ve no problem accepting a donation of an MPE device :wink:

@rorywalsh I think I’ve found the culprit. As soon as I filter out aftertouch everything is good, with aftertouch left in, nearly every note sticks. I have another normal keyboard which also outputs aftertouch and as soon as I start playing, pressing hard to send out aftertouch, notes stick again. I would suggest that it is nothing to do with MPE but simply aftertouch messages blocking out note offs somehow.
@alcomposer I haven’t used Equator too much. I think that any mapping or smoothing required can be done equally well in Csound so I haven’t even tweaked anything too much in Dashboard. I found velocity to be quite useable as it is. Naturally with a spongy keyboard if will feel different to a normal piano. If you have an example you want me to test let me know. I also haven’t encountered any problems with notes stopping before they should. You can see in the video I made that there are some long continuous notes played. I am quite happy with the surface stickiness so haven’t found the need to sprinkle it with talcum powder! I think that if it were too slippy your fingers might slide off the keywaves. BTW is this gets more off topic we should move it to the talcum powder forum.

@iainmccurdy unfortunately I searched on Cabbageaudio forum, couldn’t find the talcum powder thread. :wink:

On a serious note, I am also starting to think that there is something very odd about aftertouch. If I fire up Midi-Monitor, (or even Geert Bevin’s Juce based Midi monitor: https://github.com/gbevin/ReceiveMIDI/releases) I see that the Blocks Seaboard isn’t sending Polyphonic Aftertouch at all. And that makes sense. As it isn’t polyphonic- each channel is now a monophonic note, so it is actually sending out ChannelPressure (or Monophonic Aftertouch) - per note channel.

I researched the Csound docs and there used to be a chpress opcode: https://www.eumus.edu.uy/eme/ensenanza/electivas/csound/materiales/tutorials/nelson/

However I think that has been depreciated. There is however midichannelaftertouch.

What value I am seeing from aftouch opcode is quite strange, when I printk the value it is interlacing a 0 between each ‘real’ value. And when there are no new values (as checked in Midi-Monitor) it is still spitting out 0’s.

Using midichannelaftertouch I was able to get rid of the interlacing 0’s issue between real values, but not the constant stream of values.

I’m sure that this isn’t a good thing for Csound to be spammed with thousands of 0’s of aftertouch information, which are not being generated by the Seaboard Block, as checked by using Midi-Monitor & ReceiveMidi.

If you are able to get RecieveMIDI run:

receivemidi dev (device name) pp

and compare it to:

receivemidi dev (device name) cp

So the above commands for me show nothing for pp (polyphonicpressure) and good data for cp (channelpressure).

This issue possibly could be an issue with Csound itself? I have tested in QtCsound and there is the same spamming of Aftertouch values.

Having looked at the GitHub Csound source it looks like midichannelaftertouch is simply averaging out all of the polyphonic aftertouch values (OOps/midiinterop.c) so that would explain why its getting the stream of 0’s similar to aftouch:

int midichannelaftertouch(CSOUND *csound, MIDICHANNELAFTERTOUCH *p)
{
    MYFLT scale;
    IGN(csound);
    if (!p->h.insdshead->m_chnbp) {
      return OK;
    }
    scale = (*p->hhigh - *p->olow) * dv127;
    *p->xchannelaftertouch = *p->olow + p->h.insdshead->m_chnbp->aftouch * scale;
    return OK;
}

After reading: https://www.midi.org/specifications/item/table-1-summary-of-midi-message it looks like poly and channel aftertouch are two very different status values.

Roli support contacted me, and confirmed the behaviour of the Slide (in the Y direction) being reset to note-on value at note-off.

However the support person did not know if this was intended behaviour- simply that this is what is happening on Roli HQ’s devices with current firmware.

Just read this thread: Aftertouch problem

@iainmccurdy I made a test instrument that uses midiin like you suggested:


<CsoundSynthesizer>
<CsOptions>
-n -d -+rtmidi=NULL -M0 -m0d --midi-key-cps=4 --midi-velocity-amp=5
</CsOptions>
<CsInstruments>
; Initialize the global variables. 
sr = 44100
ksmps = 32
nchnls = 2
0dbfs = 1

massign 0, 1

;instrument will be triggered by keyboard widget

instr 1

kbnd pchbend 0, 48 
kbnd portk kbnd, .01
kpchbend = semitone(kbnd)

iInstrchan midichn

kstatus,kchan,kdata1,kdata2	midiin
if (kstatus==208 && kchan==iInstrchan ) then
kAftouch	=	kdata1
endif
 
kAftouchnew portk kAftouch/127, .05
//printk2	kAftouchnew

kEnv madsr .01, .0, 1, 1
ares pluck p5, p4*kpchbend, p4*100, 0, 1
ares2 oscil kAftouchnew, p4*kpchbend
out (ares+(ares2*0.5)) * kEnv

endin

</CsInstruments>
<CsScore>
f0 z
</CsScore>
</CsoundSynthesizer>

This actually works better in Cabbage than QtCsound for me. The Seaboard in Csound is now starting to feel like a real instrument!

One question regarding portk is there a better way to smooth out the k signal, so that swells are nice and smooth? I have tried interp but that doesn’t seam to work. I can just set the k-rate to 1, but I would prefer to have something less taxing on computer for live performance.

@rorywalsh after reading more about Geert’s github I found SendMIDI. This looks like it can easily generate virtual MIDI streams, with lots of control data. Possibly this could be used to make a ‘virtual’ Seaboard (lots of MIDI channels & pitchbend, pressure etc…):

Aftertouch

@alcomposer I’ve made a closer analysis of aftertouch and slide/Y coming from the Rise 49 and the results conflict with what you describe from your own analyses. In the graph above, the upper channel displays aftertouch and the strokes in the lower channel indicate note on and note off. I played three notes: the first with a long aftertouch crescendo-diminuendo, and the other two were short stabs. You can see that there are no interleaved zeroes. However, at the end of the long note, the aftertouch bumps up slightly as the note is released - this is unfortunate and is consistently repeatable but hasn’t caused problems in the synths I have made so far. Aftertouch in the short notes doesn’t really descend too far by the time the note is released, but I think this is to be expected given the sponginess of the playing surface. The other artefact I noticed is that the initial aftertouch value is always maximum (see the stroke in aftertouch at the start of the long note), but this can be easily dealt with in Csound.

Slide/Y

I did the same with Slide/Y data. I played two long notes, each beginning at the front of the note and sliding towards the back. You can notice that the value does not jump back to the note on position when the note is released, conflicting with what you observed and what the Roli employee stated. Maybe the Block behaves differently?

For reading aftertouch I think you should use aftouch. If it doesn’t work it should be fixed, but for me it works and the problem I have encountered seems to be Cabbage and not Csound. I was involved in the other discussion with Karamel1 regarding aftertouch issues but I was unable to replicate the problems he reported. midichannelaftertouch is for interoperability with a score alternative. MPE devices use channel aftertouch and not polyphonic aftertouch. A few devices in the past implemented polyphonic aftertouch (Ensoniq mainly), but it is rarely used today; I suspect it will be abandoned completely.

For smoothing data you could also try lineto. portk is a lowpass filter so the output slides in exponential decay to the new value, theoretically never reaching it. lineto will simply move in linear fashion, across a time duration prescribed, to reach the new value.

Hello,
Not sure this will be of any help but, based on Iain advice and some pieces if code, I manage to implement the midi + aftertouch as a UDo in the morpheur synth. May be this could be adapted to the roli?

Hey @iainmccurdy, thanks for doing the test for the Seaboard Rise. As Roli have confirmed the Slide Y value resetting to note-on value at note-off I can only conclude that this is something that they will fix on the Seaboard Blocks. I can even hear this issue in Equator.

It’s strange that I am getting lots of 0’s in after touch using aftouch. Especially as this isn’t data coming from the Roli Seaboard Block. However previous code suggestion of using MidiIn has completely fixed this problem for me as well. :wink: aftouch just isn’t working at all form me. :frowning:

I’ll put together a graphic of the issue in the Blocks Seaboard to clearly show the slide problem (Resetting Y data). Out of interest what software did you use to visualise the MPE data?

Ill try to find time to build Cabbage on Arch Linux to see if there are any issues there.

Other than that I can’t replicate your issues with stuck notes (apart from stuck notes that crash the Roli Seaboard Blocks hardware - which normally needs a hardware reset).

Thanks for the heads up regarding smoothing data! Will make sure to use that in future. :slight_smile:

I just write the aftertouch/slide and note on/off data to a sound file and examine it in Audacity. Here’s the aftertouch one (one note at a time will work best):

<CsoundSynthesizer>

<CsOptions>
-odac -dm0 -Ma
</CsOptions>

<CsInstruments>

ksmps		=	1

instr		1
 kaft aftouch
;      printk2  kaft
      chnset   a(kaft/127), "aft"
 gknote	init		1
 if release:k()==1 then
  gknote = 1
 endif
endin

instr	2
 aaft chnget "aft"
      fout   "Aftertouch.wav", 4, aaft, a(gknote)
 gknote	=	0 
endin

</CsInstruments>

<CsScore>
i 2 0 3600
</CsScore>

</CsoundSynthesizer>

Thanks @iainmccurdy, will do a quick recording tomorrow and post here. Yes, I didn’t think it looked like midi data. Cool idea! (I was going to get exotic and save to CSV…) :wink:

Hey @iainmccurdy, I was able to test the Slide issue with your above code. (Apart from some strangeness on Linux Csound that insisted on having sample rate in CsInstruments otherwise would spit out a wav file full of zeros)

Aftertouch

I also tested the aftouch, but in Linux that looks like some sporadic issue, as its working as expected now?! :confused: I will look into this more when I have time. (maybe its a MacOS specific issue? I don’t know.) Aftouch does have that 127 init value behaviour- see below.

Slide/Y

Below is the graph of the slide value issue, resetting to note-on value at note-off. I am accessing the Slide value by doing:

kslide init 0
midicontrolchange 74, kslide, 0,1
chnset a(kslide), "slide"

I performed 4 slides: Top->Bottom; Bottom->Top; Middle->Bottom; Middle->Top

I really do wish the Slide/Y of the Roli Blocks looked like your nice Rise Slide! :smiley:

Obviously the main issue with the above graph is that if one were to program a sound to change depending on Slide/Y- then the sound would snap back to the original value very fast. I think the correct behaviour is on the Rise- so that the value stays at last value.

##Lineto
I have played with lineto opcode but I can still hear a slight stepping sound when changing pressure. Is there a audio rate version of lineto? This really would be good for such an expressive instrument. As opposed to having to resort to using ksmps=1.

##aftouch 127 value
I can also hear the issue with after-touch being init to 127, (as I wasn’t using aftouch before). This is in the code of Csound for some reason, it would be good to change this to init 0. I have to press down on notes until all the channels are cleared of 127 before I can play without this problem. I have cloned the Csound git, changed 127->0 - and built Csound - but for some reason can’t get ALSA MIDI working… (this is on Arch Linux)

Roli just published an update to Seaboard Blocks: v 0.4.2
I actually can’t get stuck notes now… all sound made the test patch above with a bit of freeverb in Cabbage v2.0.27a on MacOS Sierra. (would have liked to make this in Linux but Dashboard isn’t available yet for that platform!)

There is still the Slide/Y issue, but for me there are no more stuck notes.

@alcomposer I think that a large part of the problem with smoothing low resolution contiguous data is that if you apply heavy smoothing (filtering) so that small changes are smoothed, then response when large changes are made become sluggish. I’m not sure that running at audio-rate or ksmps=1 can do much about this as the quantisation is vertical and not so much time-related. One approach I have taken is an adaptive filter that adjusts the amount of smoothing applied according to the size of the change from data point to data point. Try the example below, I think it works quite well at masking the limitations of a 7-bit controller, you can adjust it for pressure on the Roli Block. The crucial value - the time value that is given to the UDO ‘Smoother’ - is slightly dimensionless in that it will need to be adjusted according to the range covered by the controller. Perhaps insisting on a normalised controller (0 to 1) would allow this to be standardised. It’s a work in progress…

opcode	Smoother, k, kk
 kinput,ktime	xin
 kPrevVal init   0 
 kRamp    linseg   0, 0.01, 1
 ktime = kRamp * divz:k(ktime,abs(kinput-kPrevVal),0.000001)
 ktrig	changed	kinput, ktime	
 if ktrig==1 then
  reinit RESTART
 endif
 RESTART:
 if i(ktime)==0 then
  koutput	=	i(kinput)
 else
  koutput	linseg	i(koutput),i(ktime),i(kinput)
 endif
 rireturn
 		xout	koutput
 kPrevVal =      koutput
endop


alwayson 1
instr		1
 kOct     ctrl7     1, 1, 6, 12
 
 ;                        time
 kOct     Smoother  kOct, 0.005
 
 asig      vco2      0.1, cpsoct(kOct), 4, 0.5
 	   out       asig
endin 

Interesting to learn that the initial 127 value from aftouch is a Csound quirk. I would like to think that it could be changed in GIT but perhaps some might consider this to a compatibility breakage.

@iainmccurdy I’m not 100% certain its a Csound quirk, or why it is exactly. My guess is that its the init of aftouch to 127, (not sure why its 127- as opposed to 0). If I had more time to spend on this I would get my system in order and test my fork of Csound, but a few deadlines are upon me! :open_mouth: Thanks for the smoothing UDO, will take a look soon.

Re: compatibility, it would be very easy to make a Seaboard version of Csound with this one change, if it is just changing FL(127.0) to FL(0.0) :slight_smile:

@rorywalsh have you noticed the strange aftouch init 127 bug?

@alcomposer, I don’t really use midi much these days, and never actually owned a keyboard with aftertouch. So I’m at a loss here.

I still haven’t got around to testing the midi track Iain sent but it’s on my list of things to do. But you guys will probably have everything figured out by the time that happens :joy:

Well I have to work out how to build csound & cabbage on Arch first… If there are any Arch guides let me know.

I think we had this aftertouch discussion a while ago on this very forum.
Somehow, we all agreed that this was a csound weird behaviour.
The aftertouch is implemented with a workaround (always 0 at start) in the morpheur synth: not using the aftertouch opcode but the raw midiin one, and any time a note off is received, then the variable storing the aftertouch is set to zero.