adding installation audio player and putting lock on public gui
parent
fc32faba51
commit
32b4768ca6
@ -0,0 +1,44 @@
|
||||
(
|
||||
SynthDef(\hdpPlayer, {arg playDurBus = 5, playBuf = 0;
|
||||
var startTrig, playDur, fadeTime, changeTrig, playSig, fade;
|
||||
startTrig = InTrig.kr(playDurBus);
|
||||
playDur = In.kr(playDurBus);
|
||||
fadeTime = 30;
|
||||
playSig = PlayBuf.ar(2, playBuf, BufRateScale.kr(playBuf), startTrig, 0);
|
||||
fade = EnvGen.kr(Env.asr(fadeTime, 1, fadeTime), Stepper.kr(startTrig + TDelay.kr(startTrig, playDur - fadeTime), 0, 0, 1));
|
||||
Out.ar(0, playSig * fade);
|
||||
Out.ar([0, 1], BrownNoise.ar * 0.05 * (fade - 1).abs);
|
||||
SendReply.kr(TDelay.kr(startTrig, playDur), '/unlock');
|
||||
}).add;
|
||||
|
||||
);
|
||||
|
||||
(
|
||||
var recDir, recPaths, recInfo, playBuf, playDurBus, lock;
|
||||
recDir = "/home/mwinter/a_history_of_the_domino_problem/recs/";
|
||||
recPaths = ["berger_knuth.wav", "robinson.wav", "penrose.wav", "ammann.wav", "kari_culik.wav", "jaendel_rao.wav"].collect({arg file; recDir +/+ file});
|
||||
recInfo = recPaths.collect({arg path; var sndFile; sndFile = SoundFile.openRead(path); [sndFile.numFrames, sndFile.sampleRate]});
|
||||
playBuf = Buffer.read(s, recPaths[0]);
|
||||
playDurBus = Bus.control(s,1);
|
||||
lock = false;
|
||||
|
||||
OSCFunc({ arg msg, time;
|
||||
var numPlayFrames, startFrame;
|
||||
[time, msg].postln;
|
||||
lock.postln;
|
||||
if(lock.not, {
|
||||
numPlayFrames = (5.rand + 5) * 60 * recInfo[msg[1]][1];
|
||||
startFrame = (recInfo[msg[1]][0] - numPlayFrames).rand;
|
||||
playBuf.free;
|
||||
playBuf = Buffer.read(s, recPaths[msg[1]], startFrame, numPlayFrames, action: {arg buf;
|
||||
playDurBus.set(numPlayFrames / recInfo[msg[1]][1])
|
||||
});
|
||||
lock = true;
|
||||
Routine({10.wait; lock = false; lock.postln}).play
|
||||
});
|
||||
},'/playTiling', n);
|
||||
Synth(\hdpPlayer, [\playDurBus, playDurBus, \playBuf, playBuf]);
|
||||
)
|
||||
|
||||
n = NetAddr("127.0.0.1", 57120)
|
||||
n.sendMsg('/playTiling', 5)
|
@ -0,0 +1,181 @@
|
||||
// main controller for the installation
|
||||
// TODO: playback of the recordings, automation, switch from open-loop to closed-loop with the openCV tracker
|
||||
(
|
||||
var imgPositions, imgIndexToAudioIndex, curPos, tarPos,
|
||||
netAddress, localAddress, serialPort, serialListener,
|
||||
moveTo, jogControl, jogHorizontal, jogVertical,
|
||||
imgSelect, imgCalibrate, lastSelect,
|
||||
trackerPos, trackerOffsetBaseDist, trackerOffset;
|
||||
|
||||
// init global vars
|
||||
imgPositions = 9.collect({nil});
|
||||
imgIndexToAudioIndex = [0, 1, nil, 2, nil, 3, nil, 4, 5];
|
||||
curPos = Point.new(0, 0);
|
||||
tarPos = Point.new(0, 0);
|
||||
netAddress = NetAddr.new("127.0.0.1", 8080);
|
||||
localAddress = NetAddr.new("127.0.0.1", 57120);
|
||||
lastSelect = -1;
|
||||
trackerOffsetBaseDist = 16000;
|
||||
trackerOffset = [
|
||||
[trackerOffsetBaseDist * 1, trackerOffsetBaseDist * 1],
|
||||
[trackerOffsetBaseDist * 0, trackerOffsetBaseDist * 1],
|
||||
[trackerOffsetBaseDist * -1, trackerOffsetBaseDist * 1],
|
||||
|
||||
[trackerOffsetBaseDist * 1, trackerOffsetBaseDist * 0],
|
||||
[trackerOffsetBaseDist * 0, trackerOffsetBaseDist * 0],
|
||||
[trackerOffsetBaseDist * -1, trackerOffsetBaseDist * 0],
|
||||
|
||||
[trackerOffsetBaseDist * 1, trackerOffsetBaseDist * -1],
|
||||
[trackerOffsetBaseDist * 0, trackerOffsetBaseDist * -1],
|
||||
[trackerOffsetBaseDist * -1, trackerOffsetBaseDist * -1]
|
||||
];
|
||||
|
||||
|
||||
~serialPort = SerialPort("/dev/ttyACM0", baudrate: 115200, crtscts: true);
|
||||
|
||||
// recieve motor feedback
|
||||
~serialListener = Routine({
|
||||
var byte, str, res, valArray,
|
||||
stepper, limitSwitchNeg, limitSwitchPos, safeMode, limitPos;
|
||||
|
||||
safeMode = false;
|
||||
|
||||
loop{
|
||||
byte = ~serialPort.read;
|
||||
if(byte==13, {
|
||||
if(str[1].asString == "[", {
|
||||
valArray = str.asString.interpret.postln;
|
||||
curPos = Point.new(valArray[0], valArray[1]);
|
||||
limitSwitchNeg = valArray[2];
|
||||
limitSwitchPos = valArray[3];
|
||||
if(safeMode && (limitSwitchNeg == limitSwitchPos), {
|
||||
safeMode = false;
|
||||
fork {
|
||||
netAddress.sendMsg("/STATE/SET", "{message: \"all clear\"}");
|
||||
2.wait;
|
||||
netAddress.sendMsg("/STATE/SET", "{message: \"\"}");
|
||||
}
|
||||
});
|
||||
}, {
|
||||
if(str[1..3].asString == "!!!", {
|
||||
netAddress.sendMsg("/STATE/SET", "{message: \"!!! limit switch still on after 1000 steps, this should NEVER happen\"}");
|
||||
}, {
|
||||
safeMode = true;
|
||||
netAddress.sendMsg("/STATE/SET", "{message: \"!! limit hit, move the other direction\"}");
|
||||
});
|
||||
});
|
||||
str = "";
|
||||
}, {str = str++byte.asAscii});
|
||||
};
|
||||
}).play(AppClock);
|
||||
|
||||
// send new coordinates to the arduino / motors
|
||||
moveTo = {arg point;
|
||||
if((point.x.abs < 8000) && (curPos.y.abs < 8000), {
|
||||
"move to".postln;
|
||||
point.postln;
|
||||
~serialPort.putAll(point.x.asInteger.asString ++ " " ++ point.y.asInteger.asString);
|
||||
~serialPort.put(10);
|
||||
});
|
||||
};
|
||||
|
||||
jogControl = {arg axis;
|
||||
var jog, count = 0, jogRate= 0, jogDirection = 1;
|
||||
jog = Task({
|
||||
loop{
|
||||
count = (count + 0.01).clip(0, 1);
|
||||
count.postln;
|
||||
jogRate = pow(count, 2) * 500;
|
||||
if(axis == '/jog_horizontal', {
|
||||
tarPos.x = curPos.x + (jogRate * jogDirection * -1);
|
||||
}, {
|
||||
tarPos.y = curPos.y + (jogRate * jogDirection);
|
||||
});
|
||||
curPos.postln;
|
||||
moveTo.value(tarPos);
|
||||
0.1.wait
|
||||
};
|
||||
});
|
||||
OSCFunc({arg msg;
|
||||
msg.postln;
|
||||
if(msg[1] == 0, {count = 0; jogRate = 0; jog.pause()}, {jogDirection = msg[1]; jog.play(AppClock)});
|
||||
}, axis, netAddress);
|
||||
};
|
||||
|
||||
jogHorizontal = jogControl.value('/jog_horizontal');
|
||||
jogVertical = jogControl.value('/jog_vertical');
|
||||
|
||||
imgSelect = {
|
||||
OSCFunc({arg msg;
|
||||
var imgIndex, audioIndex;
|
||||
msg.postln;
|
||||
if((msg[1] > 0), {
|
||||
imgIndex = msg[1] - 1;
|
||||
imgIndex.postln;
|
||||
if(imgPositions[imgIndex] != nil, {tarPos = imgPositions[imgIndex].deepCopy; moveTo.value(tarPos)});
|
||||
9.do({arg i; if(imgIndex != i, {
|
||||
netAddress.sendMsg("/STATE/SET", "{img_" ++ (i + 1).asString ++ "_select: " ++ (i + 1).neg ++ "}")})});
|
||||
lastSelect = imgIndex;
|
||||
audioIndex = imgIndexToAudioIndex[imgIndex];
|
||||
if(audioIndex != nil, {localAddress.sendMsg('/playTiling', audioIndex)});
|
||||
}, {
|
||||
lastSelect.postln;
|
||||
if(msg[1] == ((lastSelect + 1) * -1), {"here".postln; lastSelect = -1})
|
||||
});
|
||||
}, '/img_select', netAddress)
|
||||
}.value;
|
||||
|
||||
imgCalibrate = {
|
||||
var calibrateHold, imgIndex, setPos;
|
||||
calibrateHold = Routine({
|
||||
var imageCalibrationIndex = 0;
|
||||
20.do({0.1.wait});
|
||||
[-1, 0, 1].do({arg row;
|
||||
[-1, 0, 1].do({arg col;
|
||||
imgPositions[imageCalibrationIndex] = setPos.deepCopy + Point.new(6550 * col, 6550 * row);
|
||||
imgPositions[imageCalibrationIndex].postln;
|
||||
imageCalibrationIndex = imageCalibrationIndex + 1;
|
||||
});
|
||||
});
|
||||
|
||||
imgPositions.postln;
|
||||
netAddress.sendMsg("/STATE/SET", "{message: \"image calibrated\"}");
|
||||
});
|
||||
|
||||
OSCFunc({ arg msg;
|
||||
imgIndex = msg[1] - 1;
|
||||
if(imgIndex >= 0, {
|
||||
setPos = curPos.deepCopy;
|
||||
calibrateHold.play(AppClock);
|
||||
}, {
|
||||
calibrateHold.stop; calibrateHold.reset; netAddress.sendMsg("/STATE/SET", "{message: \"\"}");
|
||||
});
|
||||
}, '/img_calibrate', netAddress);
|
||||
}.value;
|
||||
|
||||
trackerPos = OSCFunc({arg msg;
|
||||
if(lastSelect.postln > -1, {
|
||||
var distX, distY, isFocusing;
|
||||
distX = curPos.x - imgPositions[lastSelect].x;
|
||||
distY = curPos.y - imgPositions[lastSelect].y;
|
||||
isFocusing = false;
|
||||
if((imgPositions[lastSelect] != nil) && (distX.abs < 300) && ((msg[1] - trackerOffset[lastSelect][0]).abs > 3000), {
|
||||
tarPos.x = curPos.x + (10 * (msg[1] - trackerOffset[lastSelect][0]).sign);// * -1);
|
||||
isFocusing = true;
|
||||
});
|
||||
if((imgPositions[lastSelect] != nil) && (distY.abs < 300) && ((msg[2] - trackerOffset[lastSelect][1]).abs > 3000), {
|
||||
tarPos.y = curPos.y + (10 * (msg[2] - trackerOffset[lastSelect][1]).sign);// * -1);
|
||||
isFocusing = true;
|
||||
});
|
||||
if(isFocusing, {moveTo.value(tarPos)});
|
||||
})
|
||||
}, '/trackerpos');
|
||||
)
|
||||
|
||||
//in case of emergency
|
||||
~serialPort.close
|
||||
~serialPort = SerialPort.new("/dev/ttyACM0", baudrate: 115200, crtscts: true);
|
||||
~serialListener.reset
|
||||
~serialListener.play(AppClock);
|
||||
|
||||
|
Loading…
Reference in New Issue