CNMAT / Music-and-Computing

Materials built for MUS158A, MUS158B (B is only io area of patchers)
Other
6 stars 3 forks source link

QuNeo, interacting with the cnmat.o. -objects #99

Open Pulmunen11 opened 5 years ago

Pulmunen11 commented 5 years ago

Hi,

We're now off the ground with the QuNeo and the students are pretty excited to work with it!

However, this poses yet another challenge for the sound engines. Problems occur when QuNeo is feeding too much data to the sound engines and this creates a lot of audio clicks. What I see is that f.ex. the cnmat.o.sinusoids~ gives an error message of 'jit.buffer~ input matrix too wide', which I think is related to it getting too much data. Putting o.speedlim of 100ms between the codebox and cnmat.o.sinusoids~ helps a little, but does not clean all of the audio clicks from the output sound.

I have now tested with the sinusoids~ and fed it the same data at the same rate. No problems there. Output is very smooth.

There are also no problems, when using the QuNeo simulation, since it's not feeding data in such a fast rate as the device itself. Well, naturally, since only a little movement of finger on the QuNeo will cause change to the output value.

Unfortunately I'm not skilled enough to fine tune cnmat.o.sinusoids~ to meet the demands of QuNeo dataflow. With my 158A section, we can continue by using the sinusoids~, but wouldn't that be a little bit disappointing to our cnmat.o. quest?

I can imagine it will be hard without the QuNeo device at hand to verify this problem. It is a real problem and affects how the students interact with the device as well as odot. Please find attached a patch where you can compare the two sound engines (cnmat.o.sinusoids~ and sinusoids~).

Best wishes, ~ Maija


----------begin_max5_patcher----------
1279.3ocwXszaiaCD9r8uBBcxt0QVTurcARA5g1iscOzSaBBnkns4VIRshTN
OVr6u8xGRV1wODar1rAHRlCGNy7Myvgi3WFNvYI6IL2A7KfOBFL3KCGLPSRQ
XP83AN4nmRxPbMaN4XNGsF6LwLm.+jPSmKXEMDKPhjMD55GJwIBivC8b8l.V
rXg5UPf5ouuqG395kPqxIzLrPqD+VhrJQCUXMURpVgrke5lEMZzvl34BrQcN
Nf6Uy70gCUOlb0fCUJdjPSYO1MFmoeMKrmv37dFiT7iRwdDDSQIe6BXCFoib
POSrKX1aAcdGiNem2.DxHawtqQD5NKdKpjhxwmY1Sgmv4JDLOVCKy.XP74vC
7j3I7X7.a0YozfD3xGvTzxL79R4nHImrlhxblHiox+WkwPB0OxHbo41XPIaP
TJN6.6Q5RD0zSXUTw9dYNZKN8AjPTRVVIvs+hW6Zq8sJuWVElspgbC88AQtz
Ynl+Fc18wymwnqOeD3UhBoCtwmTPDJQPj9BsiwqMdb.S7MrRgkpqwMeJkUIU
FW7rI5DZlWmK175+YhYUNlV0cV2LOS9lm2k2EsqZf.mWWj1gsZkJ0Xh5QBMG
Ib4DZEmQR46n2RYe4tWhavwItAytTlq24xbITQSZauVNhiyjdMV42.9VrK1W
WrEFGcY+Yfs0bChc5XqZuh0lv0kJXErPW3c1L8q341k4zMRidOQJysTpFLX5
lWlhxKr.tP8AMKBeKv0+DvM37mlJSg+iprr+Fk7uXQOC60HwFbo83NNzjQ6A
6Kf6+iF3fNPtuO7.j2Wgbn2OBjaJMybsZucMzq2aCg8FzgNVzwwaB1LW7SEk
tIrTrhwWC+oEnTo4AtU1T0j6nSKYLAkI24eKHT1lrjjj3RLMURfmfxviTqXJ
LX5SS.Jef+rIfa709AWuwJQv1hKELJlezRdtcIP4gAGx8TouWtBDG+4QxYam
XrwHjIl2BF0Zf+LvXW+DHZr7wgBRI4srL4w7GYDuzZDR7IsZsYn4I82xKTJA
5BltuAnDuQZJVQZlnqHYYiZYRZw6jw3V1Hq.6z7VbFKgHdF7qJKPwfzD1gt5
EjiJFIoH.x+xP4KSQi93lI.z8R9Tz.lQ0CF2PUJ.iHuiN9NZSXNiPw6Z2Dtn
yDa+vXcW1KLmOuvqqL6ULpXEJ4fVO5Na+7k31aS9q2xumF4jWLsoKS45yZfn
jjp7t29Ciztmn3d5n8YuOe3nrFmtWMPc9X2.02SWmaQTeUlK56ZEdlaJgWjg
d9RGaOOduN5gQ5WAgWed9IhqgWJt9NjNSXtethhYfO7O+4u+Wc6Tpu4ftNUy
Z7GXy17ChzZEpqZ8pq5RazJ5G5G3rpxjFgVeOSfVyNEyEDJRPXz83w2vyI8z
1pm4uS5YlE5Qsq5pUTfMZR80VWulhsAS8ghhrER96XJmjVvjepLu4hB8cijc
p3YtMTY4vlQWqsEXis0KAVeazTPenIKTzgYYuxaGHOnQ5eWXtrk.ulA63mUl
hK0Ea9tangGvyNE6cUJFZSFIrOpa.sJp6eonQc.HZt9z+5cB5Q8tawFiU80g
VYrQSNXTem7.g1VUAdswPOabK8QkRn8ml0yNSKUL7xobl1FPEExOFiWuZsNk
MJ8Ill84SzCITyPcOLNk3sjF9MTPkxdiDxFipJMWY8Swlt3bxke.cIshTCZI
ZkpT2Dl55s4E0MGp6Ua3WG9e.dlGjmB
-----------end_max5_patcher-----------
equilet commented 5 years ago

This is easy to fix with interpolation methods. @Pulmunen11 please email me privately about this.

Pulmunen11 commented 5 years ago

@equilet, actually Ed has advised me to create an issue here if there's one. I'm puzzled.

@kulpajj had some other cnmat.o. objects that have similar problems.

~ Maija

~ Maija

ramagottfried commented 5 years ago

hello! yes -- the issue has to do with the fact that we're leveraging jit.fill to dump lists into a jit.matrix and then send them into a buffer~ object. Using jitter makes that really fast, but also sometimes I've noticed this error also.

Possibly adding an o.deferlow after the codebox patch might help, I noticed that actually jit.fill/matrix always output on the main thread, so the bang might be coming at the wrong time if the input is on the timer thread. But I'm not sure that's the problem you're seeing.

Or another possibility is that the matrix takes a millisecond to resize, so we could try adding a micro delay between resizing the matrix and sending the list into it (via jit.fill)... Would be nice to fix this, I can try to take a look at it (I wonder if a o.bufferfill~ object might be needed/useful).

There are two main pedagogy points for using cnmat.o.sinusoids~.

The first is that unlike sinusoids~, cnmat.o.sinusoids~ uses separate /amplitude and /frequency lists, this makes it much easier to apply functions to the values, without having to interleave and de-interleave, and encourages students to use the codebox to manipulate the data (since it's all packaged and ready to go). ... I see in your patch that you're doing this already, looks good! possibly we could make a new sinusoids~ wrapper that uses the old sinusoids~ inside, and interleaves the addresses.

But also, the second point of cnmat.o.sinusoids~, is that unlike sinusoids~, the patched version is not an external object, it uses a clean gen~ codebox to show you exactly how it works, and allows you to adapt it to your own uses, to make new fancy sounds!

But yeah, it's also possible that for some situations you might still need sinusoids~, for example with SDIF-tuples/threefates ... it would be nice if cnmat.o.sinusoids~ could handle that also, but I think we might be up against a jitter issues here... so maybe an object that takes a list and puts it into a buffer as fast as possible might be useful.

best, rama

p.s. If you haven't already, I think it's worth spending a little time to study the patch so you know how it works! cnmat.o.sinusoids~ is probably a good one to start with. in the gen.codebox, basically it's using gen~ versions of peek~ and poke~ to store the wave phases into an internal buffer~ (aka Data), and then uses the phase ramps to spin the sinusoids.