{"id":98,"date":"2008-05-06T22:24:50","date_gmt":"2008-05-06T20:24:50","guid":{"rendered":"http:\/\/www.berkeleynoise.com\/celesteh\/podcast\/?p=98"},"modified":"2008-05-06T22:24:50","modified_gmt":"2008-05-06T20:24:50","slug":"phreaking","status":"publish","type":"post","link":"https:\/\/www.berkeleynoise.com\/celesteh\/podcast\/2008\/05\/phreaking\/","title":{"rendered":"Phreaking"},"content":{"rendered":"<p><a href=\"http:\/\/www.berkeleynoise.com\/celesteh\/mp3s\/2008\/Phreaking.mp3\"><img decoding=\"async\" src=\"http:\/\/www.berkeleynoise.com\/celesteh\/images\/play.gif\" width = 12 height = 12 alt=\"[play]\"\/>Phreaking<\/a> (2008)<\/p>\n<p>I wrote this piece for BrumCon 07. The con was sponsored by our local 2600 group, so I decided to use telephone in-line signaling codes as source materials.  I spent a lot of time readin up on phone phreaking, which was just so completely cool.  I never did it as a kid because the threats my dad made against me were so dire. But man, it was awesome!<\/p>\n<p>The piece, though, is slightly silly. Well, maybe more than slightly.  I doubt I&#8217;ll play it again, but I think the logic I used around the drum beats will definitely be refined and reused.<\/p>\n<p>In the spirit of the con, the fugly, un-clean code is below the cut, along with some explanation of what the heck is going on.  When I say ugly and unclean, I really, really mean it.<\/p>\n<p><!--more-->  <\/p>\n<h4>Code<\/h4>\n<p>The SuperCollider code requires <a href=\"http:\/\/www.berkeleynoise.com\/celesteh\/code\/BBBufferTool.sc\">BBBufferTool.sc<\/a> (which is a very close relative of <a href=\"http:\/\/www.berkeleynoise.com\/celesteh\/code\/BufferTool.sc\">BufferTool.sc<\/a>, so you can use either one). It handles some tricks with Buffers, like granulation.<\/p>\n<p>Some explanation of the code at the bottom . . . <\/p>\n<pre>\r\n(\r\n\r\n\tvar joystick;\r\n\r\n\t\/\/ drums\r\n\ta =  BBBufferTool.open(s, \"sounds\/SHARP_SN.wav\");\r\n\tb = \tBBBufferTool.open(s, \"sounds\/kick2.wav\");\r\n\tc = \tBBBufferTool.open(s, \"sounds\/HIHATCLO.wav\");\r\n\td =\tBBBufferTool.open(s, \"sounds\/click.au\");\r\n\te = \tBBBufferTool.open(s, \"sounds\/TOM_HI.wav\");\r\n\ta = [a, b, c, d, e];\r\n\t\r\n\t\/\/ operator\t\r\n\tb = \tBBBufferTool.open(s, \"sounds\/pundits\/telephone\/hangup.aiff\");\r\n\tc =\tBBBufferTool.open(s,\"sounds\/pundits\/telephone\/not_completed.aiff\");\r\n\td =\tBBBufferTool.open(s,\"sounds\/pundits\/telephone\/not_in_service.aiff\");\r\n\tb = [b, c, d];\r\n\r\n\tSynthDef(\"teltone\", {arg out = 0, freq, dur = 0.2, amp = 0.2, pan = -1;\r\n\t\r\n\t\tvar sin, env, panner;\r\n\t\t\r\n\t\tsin = SinOsc.ar(freq, mul: amp);\r\n\t\tenv = EnvGen.kr(Env.linen(0.01, dur - 0.02, 0.01, 1, 'linear'), doneAction: 2);\r\n\t\tpanner = Pan2.ar(sin, pan, env);\r\n\t\tOut.ar(out, panner);\r\n\t}).store;\r\n\t\r\n\tSynthDef(\"gamey\", { arg out, freq, gate = 1, amp, pan;\r\n\r\n\t\tvar osc, env, filter, panner;\r\n\r\n\t\tosc = Pulse.ar(freq, mul:amp);\r\n\t\tenv = amp * EnvGen.kr(Env.asr(0.09, 1, 0.1, 1, 'linear'), gate, doneAction: 2);\r\n\t\tosc = osc * env;\r\n\t\tfilter = MantissaMask.ar(osc, 8\/*, env*\/);\r\n\t\tpanner = Pan2.ar(filter, pan);\r\n\t\tOut.ar(out, panner);\r\n\t}).store;\r\n\r\n\r\n\tSynthDef(\"funky\", { arg out, freq, dur, gate = 1, amp, pan;\r\n\r\n\t\tvar osc, env, filter, panner, widthline, pitchline;\r\n\t\r\n\t\t\/\/ a half step down is 50\/53\r\n\t\t\/\/ and a quarter step is 34\/35\r\n\t\t\/\/ eigth is 68\/ 67\r\n\r\n\t\tpitchline = Line.kr((68 \/ 67), (67 \/ 68), dur * 3 \/ 5);\r\n\t\twidthline = Line.kr(0.25, 0.75, dur);\r\n\r\n\t\tosc = Pulse.ar(freq * pitchline, widthline);\r\n\t\tenv = amp * EnvGen.kr(Env.asr(0.09, 1, 0.1, 1, 'linear'), gate, doneAction: 2);\r\n\t\tosc = osc * env;\r\n\t\tfilter = MantissaMask.ar(osc, 8\/*, env*\/);\r\n\t\tpanner = Pan2.ar(filter, pan);\r\n\t\tOut.ar(out, panner);\r\n\t}).store;\r\n\r\n\t\r\n\tSynthDef(\"plainBuf\", {arg out = 0, bufnum = 0, gate =1, pan = 0, \r\n\t\t\t\t\t\t\t\tamp = 0;\r\n\t\r\n\t\t\/\/ plays a buffer through forwards and at the normal rate\r\n\t\r\n\t\tvar dur, env, buf, outputAudio;\r\n\t\tdur = BufDur.kr(bufnum) + 1;\r\n\t\t\r\n\t\t\/\/ envelope required or the ugens stay around forver\r\n\t\tenv = EnvGen.kr(Env.linen(0.0001, (dur - 0.0002), 0.0001, amp), gate, doneAction:2);\r\n\t\tbuf = PlayBuf.ar(1, bufnum, BufRateScale.kr(bufnum));\r\n\t\t\r\n\t\t\/\/ this Pan2 stuff is a hack because Pan4 is glitchy\r\n\t\t\r\n\t\toutputAudio = Pan2.ar(buf, pan);\r\n\t\t\/\/outputAudio = Pan2.ar(outputAudio.at(0), yPan) ++ Pan2.ar(outputAudio.at(1), yPan);\r\n\t\t\r\n\t\tOut.ar( out, outputAudio * env);\r\n\t\t\t\t\t\r\n\t}).store;\r\n\t\r\n\r\n\tSynthDef( \"grainBuf\", { arg out = 0, bufnum = 0, pan = 0, \r\n \t\t\t\t\t\t\t\t\tamp =1,startFrame = 0, grainDur = 1, rate = 1;\r\n \t\t\t\t\t\t\t\t\t\r\n \t\t\tvar env, speed, player, panner;\r\n \t\t\t\r\n \t\t\tenv = EnvGen.kr(Env.linen(0.001, (grainDur - 0.002), 0.001, amp), doneAction:2);\r\n \t\t\t\/\/env = EnvGen.kr(Env.linen(0.0001, (grainDur - 0.0002), 0.0001, 1), doneAction:2);\r\n\t\t\tspeed = rate *  BufRateScale.kr(bufnum);\r\n\t\t\tplayer = PlayBuf.ar(1, bufnum, speed, startPos: startFrame);\r\n\t\t\tpanner = Pan2.ar(player, pan, env);\r\n\t\t\tOffsetOut.ar(out, panner);\r\n\t}).store;\r\n\t \r\n\t \r\n\t \/\/HIDDeviceServiceExt.buildDeviceList;\r\n\t\/\/HIDDeviceServiceExt.queueDeviceByName('  USB  Joystick  ');\r\n\t\/\/ Look for the devices that are attached:\r\n\tGeneralHID.buildDeviceList;\r\n\t\/\/ Get the list of devices:\r\n\t\/\/g = GeneralHID.deviceList;\r\n\t\/\/ Check which devices have been found:\r\n\tGeneralHID.postDevices;\r\n\t\/\/ Pick the 6th device and open it and create an instance of it:\r\n\t\/\/j = GeneralHID.open( g[6] );\r\n\t\/\/j.info;\r\n\t\r\n\t\/\/j.info.name\r\n\t\r\n\t\r\n\tGeneralHID.deviceList.do({ arg dev, num;\r\n\t\r\n\t\tvar name;\r\n\t\t\r\n\t\tname = dev.info.name;\r\n\t\t(name.contains(\"RumblePad\")).if ({\r\n\t\t\r\n\t\t\tj = GeneralHID.open( dev);\r\n\t\t})\r\n\t\t\r\n\t});\r\n\t\r\n\tj.caps;\r\n\t\r\n\t\r\n\tjoystick = j;\r\n\r\n\t\/\/ get joystick stuff setup while that goes;\r\n\tjoystick.spec = IdentityDictionary[\r\n   \t\t\/\/ buttons\r\n   \t\t\\b1->joystick.slots[1].at(1), \\b2->joystick.slots[1].at(2), \r\n   \t\t\\b3->joystick.slots[1].at(3), \\b4->joystick.slots[1].at(4), \r\n   \t\t\\b5->joystick.slots[1].at(5), \\b6->joystick.slots[1].at(6), \r\n   \t\t\\b7->joystick.slots[1].at(7), \\b8->joystick.slots[1].at(8),\r\n   \t\t\\b9->joystick.slots[1].at(9), \\b10->joystick.slots[1].at(10),    \r\n   \t\t\\hat->joystick.slots[3].at(57),\r\n   \t\t\/\/ sticks\r\n   \t\t\/\/left\r\n   \t\t\\lx->joystick.slots[3].at(48), \\ly->joystick.slots[3].at(49),\r\n   \t\t\/\/right\r\n   \t\t\\rx-> joystick.slots[3].at(50), \\ry->joystick.slots[3].at(53),\r\n  \t]; \r\n\r\n\tj = joystick;\r\n\r\n\r\n\r\n)\t\t\r\n\r\n\r\n\r\n(\r\n\r\n  var coin10p, coin50p, trunk2600, dtmfkey, operator, npa_codes, intl_codes, busy_signal, dial_tone,\r\n  \tpay_tone, confirmation_tone, ringback_tone, joystick, steps, dur, flag, drum_accents, cond;\r\n  \t \r\n  \t \r\n  \t \r\n  \t joystick = j;\r\n\tGeneralHID.startEventLoop(0.005);\r\n\r\n\/\/http:\/\/en.wikipedia.org\/wiki\/Red_box_%28phreaking%29\r\n\/\/ In the UK, a 1000 Hz tone for 200 ms represents a 10p coin, \r\n\/\/ and 1000 Hz for 350 ms represents a 50p coin.\r\n\r\n\tcoin10p = [1000, 0.2];\r\n\tcoin50p = [1000, 0.35];\r\n\ttrunk2600 = [2600, 0.4];\r\n\tpay_tone = [400, 0.125];  \/\/ divided by 10 for artistic reasons\r\n\t\/\/confirmation_tone = [400, ]\r\n\t\r\n\t\r\n\t\/\/ The minimum duration of the tone should be at least 70 msec,\r\n\tdtmfkey = IdentityDictionary[\r\n\t\r\n\t\t\\1-> [697, 1209],\r\n\t\t\\2-> [697, 1336],\r\n\t\t\\3-> [697, 1477],\r\n\t\t\\4-> [770, 1209], \r\n\t\t\\5-> [770, 1336], \r\n\t\t\\6-> [770, 1477], \r\n\t\t\\7-> [852, 1209],\r\n\t\t\\8-> [852, 1336], \r\n\t\t\\9-> [852, 1477], \r\n\t\t\\0-> [941, 1336],\r\n\t\t\\star-> [941, 1209], \r\n\t\t\\pound-> [941, 1477], \r\n\t\t\\a-> [697, 1633],\r\n\t\t\\b-> [770, 1633], \r\n\t\t\\c-> [852, 1633], \r\n\t\t\\d-> [941, 1633]\r\n\t];\r\n\t\r\n\t\/\/Normally, the tone durations are on for 60ms, with 60ms of silence between digits. \r\n\t\/\/The 'KP' and 'KP2' tones are sent for 100ms. \r\n\t\/\/ KP2 (ST2 in the R1 standard) was used for dialing internal Bell System telephone numbers.\r\n\t\r\n\t\/*\r\n\tOnce the far end sends the supervision flash, the user would use the blue box to dial a \"Key Pulse\" or \"KP\", the tone that starts a routing digit sequence, followed by either a telephone number or one of the numerous special codes that were used internally by the telephone company, then finished up with a \"Start\" or \"ST\" tone. At this point, the far end of the connection would route the call the way you told it, while the users end would think you were still ringing at the original number. KP1 is generally used for domestic dialing where KP2 would be for international calls.\r\n\t*\/\r\n\t\r\n\t\r\n\toperator = IdentityDictionary[\r\n\t\t\\1-> [700, 900],\r\n\t\t\\2-> [700, 1100],\r\n\t\t\\3-> [900, 1100],\r\n\t\t\\4-> [700, 1300], \r\n\t\t\\5-> [900, 1300], \r\n\t\t\\6-> [1100, 1300], \r\n\t\t\\7-> [700, 1500],\r\n\t\t\\8-> [900, 1500], \r\n\t\t\\9-> [1100, 1500], \r\n\t\t\\0-> [1300, 1500],\r\n\t\t\\11-> [700, 1700],\r\n\t\t\\12-> [900, 1700],\r\n\t\t\\kp->  [1100, 1700],\r\n\t\t\\kp2-> [1300, 1700],\r\n\t\t\\st->  [1500, 1700]\r\n\t];\r\n\t\r\n\tnpa_codes = [ \r\n\t\t\/\/ a three digit are code (aka a NPA) comes before these codes\r\n\t\t[\\1, \\0, \\0], \r\n\t\t[\\1, \\0, \\1], \r\n\t\t[\\1, \\0, \\2], \r\n\t\t[\\1, \\0, \\3], \r\n\t\t[\\1, \\0, \\4], \r\n\t\t[\\1, \\0, \\5], \r\n\t\t[\\1, \\0, \\6], \r\n\t\t[\\1, \\0, \\7], \r\n\t\t[\\1, \\0, \\8], \r\n\t\t[\\1, \\0, \\9], \r\n\t\t[\\1, \\2, \\1],\r\n\t\t[\\1, \\3, \\1],\r\n\t\t[\\1, \\4, \\1],\r\n\t\t[\\1, \\6, \\1],\r\n\t\t[\\1, \\8, \\1] \/\/ coin refund!\r\n\t];\r\n\t\r\n\tintl_codes = [\r\n\t\r\n\t\t[\\9, \\1, \\4, \\1, \\5, \\1], \/\/incoming\r\n\t\t[\\2, \\1, \\2, \\1, \\5, \\1], \/\/incoming\r\n\t\t\/\/ senders\r\n\t\t[\\9, \\1, \\4, \\1, \\8, \\2],\r\n\t\t[\\2, \\1, \\2, \\1, \\8, \\3],\r\n\t\t[\\4, \\1, \\2, \\1, \\8, \\4],\r\n\t\t[\\4, \\0, \\7, \\1, \\8, \\5],\r\n\t\t[\\5, \\1, \\0, \\1, \\8, \\6], \/\/oakland!\r\n\t\t[\\3, \\0, \\3, \\1, \\8, \\7],\r\n\t\t[\\2, \\1, \\2, \\1, \\8, \\8]\r\n\t];\r\n\t\r\n\t\/\/ The frequencies were initially designed with a ratio of 21\/19,\r\n\tbusy_signal = [ 400, 0.375 ];\r\n\tdial_tone = [ 350, 440];\r\n\t\r\n\tringback_tone = [ [ [400, 450], 0.4 ], [ \\rest, 0.2], [ [400, 450], 0.4 ], [ \\rest, 2.0] ];\r\n\t\r\n\t\/\/In Australia and the UK, the standard ring cadence is 400 ms on, 200 ms off, 400 ms on, 2000 ms off. \r\n\r\n\r\n\t\r\n\t\/\/ prepare some buffers, figure out beat sizes\r\n\r\n\tsteps = 30.rrand(38);\r\n\tdur = 4 \/ steps;\r\n\t\r\n\t{\r\n\t\tb.do({arg bbuf;\r\n\t\t\tbbuf.beatlength = steps;\r\n\t\t\tbbuf.calc_grains_dur(dur\/4);\r\n\t\t});\r\n\t}.fork;\r\n\t\r\n\tflag = true;\r\n\t\r\n\t\/\/ This piece is five minuts long, so let's pull the plug after 5\r\n\t\r\n\tRoutine.new({ (5 * 60).wait; flag = false; \"time's up!\".postln; }).play;\r\n\t\r\n\t\r\n\t\/\/ ok let's make some sound\t\r\n\t\r\n\r\n\tPseq([\r\n\t\r\n\t\t\/\/ dial tone\r\n\t\t\r\n\t\tPbind (\r\n\r\n\t\t\t\\instrument, \t\\teltone,\r\n\t\t\t\\freq,\t\tdial_tone,\r\n\t\t\t\\dur,\t\tPseq([2 + 4.0.rand], 1)\r\n\t\t),\r\n\t\t\r\n\t\t\/\/ coins\r\n\t\t\r\n\t\tPbind (\r\n\t\t\t\\instrument, \t\t\\teltone,\r\n\t\t\t[\\freq, \\dur],\tProut({\r\n\t\t\t\r\n\t\t\t\t\t\t\t\tvar dur;\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t(2 + 3.rand).do ({\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\tdur = 0.2.rrand(0.5);\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t[coin10p, coin50p].choose.yield;\r\n\t\t\t\t\t\t\t\t\t[\\rest, 0.0125].yield;\r\n\t\t\t\t\t\t\t\t\tpay_tone.yield;\r\n\t\t\t\t\t\t\t\t\t[\\rest, 0.0125].yield;\r\n\t\t\t\t\t\t\t\t\t\/\/[400, 0.125].yield; \/\/ pay tone?\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\tdur = 0.18.rrand(0.3);\r\n\t\t\t\t\t\t\t\t\t[\\rest, dur].yield;\r\n\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\tdur = 0.2.rrand(1.1);\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t[dial_tone, dur].yield;\r\n\t\t\t\t\t\t\t})\r\n\t\t\t\r\n\t\t\t\r\n\t\t\t\r\n\t\t\t\t\t\t\/\/\tPrand([coin10p, coin50p, \r\n\t\t\t\t\t\t\/\/\t\t[\\rest, 0.7],\r\n\t\t\t\t\t\t\/\/\t\t[\\rest, 0.5],\r\n\t\t\t\t\t\t\/\/\t\t[\\rest, 0.6]], 7)\r\n\t\t),\r\n\t\t\r\n\t\t\/\/ pause\r\n\t\t\r\n\t\t\/\/Pbind (\r\n\t\t\/\/\r\n\t\t\/\/\t\\freq,\t\\rest,\r\n\t\t\/\/\t\\dur,\tPwhite([0.2, 1], 1)\r\n\t\t\/\/),\r\n\t\t\r\n\t\t\/\/ dial\r\n\t\t\r\n\t\tPbind (\r\n\r\n\t\t\t\\instrument, \t\\teltone,\r\n\t\t\t\/\/\\dur,\t\tPfunc({0.1.rrand(0.3)}),\r\n\t\t\t\/*\\key,\t\tPseq([\\0, \r\n\t\t\t\t\t\t\tPrand([\\0, \\1, \\2, \\3, \\4, \\5, \\6, \\7, \\8, \\9], 7)\r\n\t\t\t\t\t\t\t], 7),\r\n\t\t\t\\freq,\t\tPfunc({ arg evt;\r\n\t\t\t\t\t\t\tdtmfkey.at(evt[\\key]) }),*\/\r\n\t\t\t\t\t\t\t\r\n\t\t\t[\\freq, \\dur],\t\tProut ({ arg evt;\r\n\t\t\t\r\n\t\t\t\t\t\t\tvar keys, dial, button, dur;\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\tkeys = [\\0, \\1, \\2, \\3, \\4, \\5, \\6, \\7, \\8, \\9];\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\tevt.dump; evt.array.postln;\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\tbutton = \\0;\r\n\t\t\t\t\t\t\tdial = dtmfkey.at(button);\r\n\t\t\t\t\t\t\tdur = 0.11.rrand(0.2);\r\n\t\t\t\t\t\t\tbutton.post; dur.post; dial.postln;\r\n\r\n\t\t\t\t\t\t\t[dial, dur].yield;\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\tdur = 0.05.rrand(0.1);\r\n\t\t\t\t\t\t\t[\\rest, dur].yield;\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t7.do({\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\tbutton = keys.choose;\r\n\t\t\t\t\t\t\t\tdial = dtmfkey.at(button);\r\n\t\t\t\t\t\t\t\tdur = 0.07.rrand(0.2);\r\n\t\t\t\t\t\t\t\tbutton.post; dur.post; dial.postln;\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t[dial, dur].yield;\r\n\r\n\t\t\t\t\t\t\t\tdur = 0.05.rrand(0.1);\r\n\t\t\t\t\t\t\t\t[\\rest, dur].yield;\r\n\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t[\\rest, 0.2].yield;\r\n\t\t\t\t\t\t})\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\r\n\t\t),\t\t\r\n\t\t\r\n\t\t\/\/ ring back + 2600\r\n\t\t\r\n\t\tPbind (\r\n\t\t\t\\instrument, \t\t\\teltone,\r\n\t\t\t[\\freq, \\dur],\tPseq([\r\n\t\t\t\t\t\t\t\tPseq(ringback_tone, (2 + 2.rand)),\r\n\t\t\t\t\t\t\t\ttrunk2600,\r\n\t\t\t\t\t\t\t\t[\\rest, 0.2]\r\n\t\t\t\t\t\t\t], 1)\r\n\t\t),\r\n\t\t\r\n\t\t\r\n\t\t\/\/ and now the piece\r\n\t\t\r\n\t\tPtpar([\r\n\t\t\t\/\/ringing\r\n\t\t\t0, \tPbind (\r\n\t\t\t\t\\instrument, \t\t\\teltone,\r\n\t\t\t\t[\\freq, \\dur],\tPseq(ringback_tone, 95)\r\n\t\t\t\t),\r\n\t\t\t\/\/ operator dialing\r\n\t\t\t1, Pbind (\t\t\r\n\t\t\t\t\\instrument, \t\t\\teltone,\r\n\t\t\t\t[\\freq, \\dur],\tProut ({\r\n\t\t\t\t\t\t\t\t\tvar button;\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\/*82.do*\/ {flag}.while ({\r\n\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t[operator.at(\\kp2), 0.1].yield;\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\tintl_codes.choose.do({ arg key;\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t[\\rest, 0.06].yield;\r\n\t\t\t\t\t\t\t\t\t\t[operator.at(key), 0.06].yield;\r\n\t\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t10.do({\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\tbutton = \r\n\t\t\t\t\t\t\t\t\t\t\t[\\0, \\1, \\2, \\3, \\4, \\5, \\6, \\7, \\8, \\9].choose;\r\n\t\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t[\\rest, 0.06].yield;\r\n\t\t\t\t\t\t\t\t\t\t[operator.at(button), 0.06].yield;\r\n\t\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t[\\rest, 0.06].yield;\r\n\t\t\t\t\t\t\t\t\t[operator.at(\\st), 0.1].yield;\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t[\\rest, 1.82].yield;\r\n\r\n\t\t\t\t\t\t\t\t\t})\r\n\t\t\t\t\t\t\t\t})\r\n\t\t\t\t),\r\n\t\t\t\/\/ drum patterns\r\n\t\t\t\r\n\t\t\t8, Pseq([ \/\/ stick something after the drums\r\n\t\t\t\tPbind(\r\n\t\t\t\t\\instrument,\t\t\\plainBuf,\r\n\t\t\t\t\/\/\\amp,\t\t\t0.19,\r\n\t\t\t\t\/\/\\dur,\t\t\tPseq([\r\n\t\t\t\t\/\/\t\t\t\t\tPseq([\r\n\t\t\t\t\/\/\t\t\t\t\t\tPseq([0.2485], 3), \r\n\t\t\t\t\/\/\t\t\t\t\t\t\t0.249], 3),\r\n\t\t\t\t\/\/\t\t\t\t\tPseq([\r\n\t\t\t\t\/\/\t\t\t\t\t\tPseq([0.2485], 3),\r\n\t\t\t\t\/\/\t\t\t\t\t\t0.271], 1)\r\n\t\t\t\t\/\/\t\t\t\t\t], inf),  \/\/ * 16 adds up to 4\r\n\t\t\t\t[\\bufnum, \\amp, \\dur, \\freq],\tProut({\r\n\t\t\t\t\r\n\t\t\tvar kick, hat, snare, click, tom, drumpats, currentpat, drums, result, repeats, rest,\r\n\t\t\t\t\/\/steps, dur, \/\/have moved outside this Prout\r\n\t\t\t\taccents, amp;\r\n\r\n\t\t\tkick = a[1].bufnum;  hat = a[2].bufnum;  snare = a[0].bufnum;  click = a[3].bufnum;  \r\n\t\t\t\ttom = a[4].bufnum;\r\n\t\t\t\r\n\t\t\trepeats = 8.rrand(10);  \/\/ number of times to repeat a pattern before swapping\r\n\t\t\t\r\n\t\t\t\/\/ what we need is the emergency addition of beats in case a loop is too sparse\r\n\t\t\t\r\n\t\t\tjoystick.spec.at(\\b6).action_({ |val|\r\n\t\t\t\tvar value;\r\n\t\t\t\tvalue = val.value;\r\n\t\t\t\r\n\t\t\t\t(value == 1).if ({\r\n\t\t\t\t\r\n\t\t\t\t\t\"adding beats\".postln;\r\n\r\n\t\t\t\t\tdrums = [kick, hat, snare, click, tom].scramble.copyRange(0, 1.rrand(4));\r\n\t\t\t\t\tdrums.do({ arg drum;\r\n\t\t\t\t\r\n\t\t\t\t\t\t4.rrand(steps).do({\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\tresult = steps.rand;\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\tcurrentpat = currentpat.add([result, drum]);\r\n\t\t\t\t\t\t})\r\n\t\t\t\t\t});\r\n\t\t\t\t});\r\n\t\t\t});\r\n\t\t\t\r\n\t\t\t\/\/ too many!  \/\/ drop a beat!\r\n\t\t\tjoystick.spec.at(\\b5).action_({ |val|\r\n\t\t\t\tvar value;\r\n\t\t\t\tvalue = val.value;\r\n\t\t\t\r\n\t\t\t\t(value == 1).if ({\r\n\t\t\t\t\r\n\t\t\t\t\t\"dropping \".post;\r\n\t\t\t\t\tcurrentpat.pop.postln;\r\n\t\t\t\t\r\n\t\t\t\t});\r\n\t\t\t});\r\n\r\n\t\t\r\n\t\t\t\/\/ let's keep the accents around\t\r\n\t\t\t4.rrand(steps \/2 ).do ({\r\n\t\t\t\t\r\n\t\t\t\tdrum_accents = drum_accents.add(steps.rand);\r\n\t\t\t});\r\n\r\n\t\t\t\/\/ do the looping thing\r\n\r\n\t\t\t\r\n\r\n\t\t\t\/*(80 \/ repeats).do*\/ {flag}.while ({\r\n\r\n\t\t\t\t\/\/currentpat = drumpats.choose;\r\n\t\t\t\t\r\n\t\t\t\tdrums = [kick, hat, snare, click, tom].scramble.copyRange(0, 1.rrand(4));\r\n\t\t\t\tcurrentpat = [];\r\n\t\t\t\t\r\n\t\t\t\tdrums.do({ arg drum;\r\n\t\t\t\t\r\n\t\t\t\t\t4.rrand(steps).do({\r\n\t\t\t\t\t\r\n\t\t\t\t\t\tresult = steps.rand;\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\tcurrentpat = currentpat.add([result, drum]);\r\n\t\t\t\t\t})\r\n\t\t\t\t});\r\n\t\t\t\t\r\n\t\t\t\tdrum_accents.do({ arg ac;\r\n\t\t\t\t\r\n\t\t\t\t\tcurrentpat = [[ac, drums.last]] ++ currentpat;\r\n\t\t\t\t});\r\n\t\t\t\t\r\n\t\t\t\t\"new drum pat\".postln;\r\n\t\t\t\trepeats.do({\r\n\t\t\t\t\r\n\t\t\t\t\t\/\/currentpat.postln;\r\n\t\t\t\t\tsteps.do ({ arg index;\r\n\t\r\n\t\t\t\t\t\tamp = 0.15;\r\n\t\t\t\t\t\tresult = [];\r\n\t\t\t\t\t\trest = \\rest;\r\n\t\t\t\t\t\tdrums = [];\r\n\t\t\t\t\t\tcurrentpat.do ({ arg val, num;\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\/\/val.first\r\n\t\t\t\t\t\t\tif (val.first == index, {\r\n\t\t\t\t\t\t\t\t\/\/val.last.postln;\r\n\t\t\t\t\t\t\t\t((drums.includes(val.last)).not). if ({\r\n\t\t\t\t\t\t\t\t\tdrums = drums ++ val.last;\r\n\t\t\t\t\t\t\t\t\trest = 440;\r\n\t\t\t\t\t\t\t\t}, { \/\/ kill the redundancy\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\tcurrentpat.removeAt(num);\t\r\n\t\t\t\t\t\t\t\t})\r\n\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\tif ( drum_accents.includes(index), { amp = amp + 0.09; });\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t[drums, amp, rest].postln;\t\t\r\n\t\t\t\t\t\t[drums, amp, dur, rest].yield;\r\n\t\t\t\t\t});\r\n\t\t\t\t});\r\n\t\t\t});\r\n\t\t\t\/\/ we're done, so set the flag\r\n\t\t\t\r\n\t\t\tflag = false;\r\n\t\t\t\r\n\t\t\t})\r\n\t\t\t\r\n\t\t), \/\/ still in the drum Pseq\r\n\t\tPbind(\r\n\t\t\r\n\t\t\t\\instrument,\t\t\\grainBuf,\r\n\t\t\t\\amp,\t\t\t0.4,\r\n\t\t\t\\rate,\t\t\t1,\r\n\t\t\t[\\bufnum, \\dur, \\grainDur, \\startFrame, \\freq],\r\n\t\t\t\t\t\t\tProut({\r\n\t\t\t\t\t\t\t\tvar activebuf;\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\tactivebuf = b.choose;\r\n\t\t\t\t\t[activebuf.bufnum, activebuf.dur, activebuf.dur, 0, 440].yield;\r\n\t\t\t\t\t\t\t})\r\n\t\t)], 1), \/\/end of drum pseq\r\n\r\n\t\t\r\n\t\t\r\n\t\t\/\/ busy signal\r\n\t\t\r\n\t\t16, Pbind (\r\n\r\n\t\t\t\t\\instrument, \t\t\\teltone,\r\n\t\t\t\t[\\freq, \\dur],\tPseq ([ Pseq([busy_signal, \r\n\t\t\t\t\t\t\t\t\t\t[\\rest, busy_signal.last]],6.rrand(8)),\r\n\t\t\t\t\t\t\t\t\tPrand([[\\rest, 8], [\\rest, 16], [\\rest, 24]], 1)], 8 )\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t),\r\n\t\t\r\n\t\t\r\n\t\t\/\/ telephone operator voice\r\n\t\t\r\n\t\t56, Pbind (\r\n\t\t\r\n\t\t\t\\instrument,\t\t\\grainBuf,\r\n\t\t\t\\amp,\t\t\t0.4,\r\n\t\t\t\\rate,\t\t\t1,\r\n\t\t\t[\\bufnum, \\dur, \\grainDur, \\startFrame, \\freq],\r\n\t\t\t\r\n\t\t\t\tProut({\r\n\t\t\t\t\t\r\n\t\t\t\t\tvar tick, repeats, accents, substeps, subdur, activebuf, stuttered,\r\n\t\t\t\t\t\tstutter_probability, overlap, stut, init_func, stutter_steps;\r\n\t\t\t\t\t\r\n\t\t\t\t\tinit_func = { arg buf;\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t\/\/ number of times to repeat a pattern before swapping\r\n\t\t\t\t\t\trepeats = 2.rrand(4);  \r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\/\/ let's keep the accents around\r\n\t\t\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t4.rrand(steps \/4 ).do ({\r\n\t\t\t\t\r\n\t\t\t\t\t\t\taccents = accents.add(steps.rand);\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t\/\/ ok, now lets' keep the accents off of substeps\r\n\t\t\t\t\t\taccents = accents * 4;\r\n\t\t\t\t\t\t\/\/accents = accents ++ drum_accents;\r\n\t\t\t\t\t\r\n\t\t\t\t\t\tstuttered = 0;\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\tactivebuf = b.wrapAt(buf);\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t};\r\n\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\t\/\/ because there are 4 substeps to a step\r\n\t\t\t\t\tsubsteps = steps * 4;\r\n\t\t\t\t\tsubdur = dur \/4;\r\n\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\t\/\/ init\r\n\t\t\t\t\tstuttered = 0;\r\n\t\t\t\t\ttick = 0;\r\n\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\tstutter_probability = 0.5; \/\/ let's try 50%\r\n\t\t\t\t\toverlap = 1.02;  \/\/ multiply the duration by\r\n\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\t\/\/ this will become a joystick function:\r\n\t\t\t\t\t\r\n\t\t\t\t\tactivebuf = b.choose;\r\n\t\t\t\t\tinit_func.value(3.rand);\r\n\r\n\t\t\t\t\tjoystick.spec.at(\\b1).action_({ |val|\r\n\t\t\t\t\t\tvar value;\r\n\t\t\t\t\t\tvalue = val.value;\r\n\t\t\t\r\n\t\t\t\t\t\t(value == 1).if ({\r\n\t\t\t\t\r\n\t\t\t\t\t\t\tinit_func.value(0)\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t});\r\n\r\n\t\t\t\t\tjoystick.spec.at(\\b2).action_({ |val|\r\n\t\t\t\t\t\tvar value;\r\n\t\t\t\t\t\tvalue = val.value;\r\n\t\t\t\r\n\t\t\t\t\t\t(value == 1).if ({\r\n\t\t\t\t\r\n\t\t\t\t\t\t\tinit_func.value(1)\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t});\r\n\r\n\t\t\t\t\tjoystick.spec.at(\\b3).action_({ |val|\r\n\t\t\t\t\t\tvar value;\r\n\t\t\t\t\t\tvalue = val.value;\r\n\t\t\t\r\n\t\t\t\t\t\t(value == 1).if ({\r\n\t\t\t\t\r\n\t\t\t\t\t\t\tinit_func.value(2)\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t});\r\n\r\n\r\n\t\t\t\t\tjoystick.spec.at(\\lx).action_({ |val|\r\n\t\t\t\t\t\r\n\t\t\t\t\t\tvar value;\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\tvalue = val.value;\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\tstutter_probability = value;\r\n\t\t\t\t\t\tvalue.postln;\r\n\t\t\t\t\t});\r\n\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\tstutter_steps = CV.new.sp(2, 0, 5, 1, 'linear');\r\n\t\t\t\t\t\r\n\t\t\t\t\tjoystick.spec.at(\\rx).action_({ |val|\r\n\t\t\t\t\t\tvar value;\r\n\t\t\t\t\t\tvalue = val.value;\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\tstutter_steps.input = value;\r\n\t\t\t\t\t\tstutter_steps.value.postln;\r\n\t\t\t\t\t});\r\n\t\t\t\t\t\t\r\n\r\n\r\n\t\t\t\t\t{flag}.while({\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t(activebuf.notNil). if ({\r\n\t\t\t\t\t\t\trepeats.do({\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t\t\tactivebuf.grains.do({arg grain, index;\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t(accents.includes(index)).if ({ \/\/ don't stutter\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\tstuttered = index;\r\n\t\t\t\t\t\t\t\t\t\t[grain.bufnum, subdur, subdur * overlap,\r\n\t\t\t\t\t\t\t\t\t\t\tgrain.startFrame, 440].yield;\r\n\t\t\t\t\t\t\t\t\t} , {\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t\/\/ can stutter\r\n\t\t\t\t\t\t\t\t\t\tstutter_probability.coin .if ({\r\n\t\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t\t\/\/ will stutter\r\n\t\t\t\t\t\t\t\t\t\t\tstut = stuttered + stutter_steps.value.rand2;\r\n\t\t\t\t\t\t\t\t\t\t\t[activebuf.grains.wrapAt(stut).bufnum,\r\n\t\t\t\t\t\t\t\t\t\t\t\tsubdur, subdur * overlap,\r\n\t\t\t\t\t\t\t\t\t\t\t\tactivebuf.grains.wrapAt(stut).startFrame,\r\n\t\t\t\t\t\t\t\t\t\t\t\t440].yield;\r\n\t\t\t\t\t\t\t\t\t\t} , {\r\n\t\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t\t\/\/ won't stutter\r\n\t\t\t\t\t\t\t\t\t\t\tstuttered = index;\r\n\t\t\t\t\t\t\t\t\t\t\t[grain.bufnum, subdur, subdur * overlap,\r\n\t\t\t\t\t\t\t\t\t\t\t\tgrain.startFrame, 440].yield;\r\n\t\t\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\t\ttick = tick + 1;\r\n\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t{\/*tick < substeps*\/ (tick % substeps) != 0}.while({\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t[0, subdur, subdur, 0, \\rest].yield;\r\n\t\t\t\t\t\t\t\t\ttick = tick +1\r\n\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\ttick = 0;\r\n\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\tactivebuf = nil;\t\t\t\t\t\t\t\r\n\r\n\t\t\t\t\t\t}, {\r\n\t\t\t\t\t\t\tstuttered = 0;\r\n\t\t\t\t\t\t\t[0, dur, dur, 0, \\rest].yield;\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t});\r\n\t\t\t\t\t\r\n\t\t\t\t\tactivebuf = b.choose;\r\n\t\t\t\t\t\/\/[activebuf.bufnum, activebuf.dur, activebuf.dur, 0, 440].yield;\r\n\t\t\t\t\t\r\n\t\t\t\t})\r\n\t\t),\r\n\t\t\r\n\t\t\/\/ bassline\r\n\t\t\r\n\t\t\t32, Pbind(\t\r\n\t\t\t\t\\instrument, \t\t\\teltone,\r\n\t\t\t\t\\amp,\t\t\t0.18,\r\n\t\t\t\t\\freq, \t\t\tProut({\r\n\t\t\t\t\t\t\t\t\tvar num, repeats;\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\tnum = [\\0, \\0, \\1, \\4, \\0, \\8, \\7, \\2, \\5,\r\n\t\t\t\t\t\t\t\t\t\t\t\\0, \\6, \\4, \\4]; \r\n\t\t\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\trepeats = 8.rrand(10);\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t{flag}.while({\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\tnum = [\r\n\t\t\t\t\t\t\t\t\t\t\t[\\0, \\0, \\1, \\4, \\0, \\8, \\7, \\2, \\5,\r\n\t\t\t\t\t\t\t\t\t\t\t\t\\0, \\6, \\4, \\4], \/\/ my childhood\r\n\t\t\t\t\t\t\t\t\t\t\t\/\/ other numbers redacted because they're still current\r\n\t\t\t\t\t\t\t\t\t\t].choose;\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\trepeats.do({\r\n\t\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t\tnum.do({ arg button;\r\n\t\t\t\t\t\t\t\t\t\t\t\tif (flag, {\r\n\t\t\t\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t\t\t  (dtmfkey.at(button) \/ 8).yield;\r\n\t\t\t\t\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\t}), \r\n\t\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\\dur,\t\t\t0.5\r\n\t\t)\r\n\r\n\t\t], 1 )\r\n\t], 1).play;\r\n\t\t\t\r\n\t\r\n\r\n)\t \r\n\t\t\r\n\t<\/pre>\n<p>The very top part loads drum beat sounds and operator sounds.  Below that are a bunch of SynthDefs. Many of them are not actually used. (I told you it was ugly.) Then some code related to my joystick.  All of that code runs as one block.  The variables whose names are single letters, a, b, c, etc are persistent across blocks, but the rest have a local scope.<\/p>\n<p>The next block contains a whole lot of crap about telephone codes. Then we make some decisions about how many beats are going to be in a loop.  The Buffers are divided into grains the size of 16th notes. (Which is to say, 4 grains to a beat.) Then comes the timing logic. Pbinds, Pseqs, etc, handle timing really well.  So I've got some of them to do the straight telephony-sounding intro. Then, the drums come in. I haphazardly pick some beats which are accented.  Those always have drum sounds on them and are hit harder. Then I randomly pick other beats and stick some drum sounds on them also. The rule of loopy dance music is that if you repeat something enough times, it starts to work by the sheer force of the repetition. That's the logic here. So play that a few times. Then switch it up with new drum sounds, but the same accents.<\/p>\n<p>The next interesting thing is the operator voice. It comes in of it's own accord, but future instances of it are triggered with the joystick.  The grains of the buffer can be shuffled. The parameters for this are controlled by the sticks on my gamepad.  Accented beats are always played at the correct time.  This effect would be more striking if the voice accents were actually in synch with the drum accents, but they're not. So the pattern is the same, but will probably be offset in time.<\/p>\n<p>Finally the bassline (which is low sine tones. You won't hear it on your laptop's built-in speakers) is just phone numbers played at slow speed and shifted down by 3 octaves.  I took some numbers out of the code above because I don't want folks calling up my friends and family.<\/p>\n<p>The other numbers inside the piece were totally random.  This turned out not to be the best idea. To me, it sounded fine, but I'm not a phreaker, so phone number tones are not as meaningful to me. To some folks in the audience, they could totally tell that numbers were not meaningful. Which is really awesome, actually, even though it's not great for this piece.<\/p>\n<div class=\"powerpress_player\" id=\"powerpress_player_4921\"><a href=\"http:\/\/www.berkeleynoise.com\/celesteh\/mp3s\/2008\/Phreaking.mp3\" title=\"Play\" onclick=\"return powerpress_embed_html5a('4921','http:\/\/www.berkeleynoise.com\/celesteh\/mp3s\/2008\/Phreaking.mp3');\" target=\"_blank\"><img decoding=\"async\" src=\"https:\/\/www.berkeleynoise.com\/celesteh\/podcast\/wp-content\/plugins\/powerpress\/play_audio.png\" title=\"Play\" alt=\"Play\" style=\"border:0;\" width=\"23px\" height=\"24px\" \/><\/a><\/div>\n<p class=\"powerpress_links powerpress_links_mp3\" style=\"margin-bottom: 1px !important;\">Podcast: <a href=\"http:\/\/www.berkeleynoise.com\/celesteh\/mp3s\/2008\/Phreaking.mp3\" class=\"powerpress_link_pinw\" target=\"_blank\" title=\"Play in new window\" onclick=\"return powerpress_pinw('https:\/\/www.berkeleynoise.com\/celesteh\/podcast\/?powerpress_pinw=98-podcast');\" rel=\"nofollow\">Play in new window<\/a> | <a href=\"http:\/\/www.berkeleynoise.com\/celesteh\/mp3s\/2008\/Phreaking.mp3\" class=\"powerpress_link_d\" title=\"Download\" rel=\"nofollow\" download=\"Phreaking.mp3\">Download<\/a> (5.9MB)<\/p>","protected":false},"excerpt":{"rendered":"<p>Phreaking (2008) I wrote this piece for BrumCon 07. The con was sponsored by our local 2600 group, so I decided to use telephone in-line signaling codes as source materials. I spent a lot of time readin up on phone phreaking, which was just so completely cool. I never did it as a kid because [&hellip;]<\/p>\n<div class=\"powerpress_player\" id=\"powerpress_player_4922\"><a href=\"http:\/\/www.berkeleynoise.com\/celesteh\/mp3s\/2008\/Phreaking.mp3\" title=\"Play\" onclick=\"return powerpress_embed_html5a('4922','http:\/\/www.berkeleynoise.com\/celesteh\/mp3s\/2008\/Phreaking.mp3');\" target=\"_blank\"><img decoding=\"async\" src=\"https:\/\/www.berkeleynoise.com\/celesteh\/podcast\/wp-content\/plugins\/powerpress\/play_audio.png\" title=\"Play\" alt=\"Play\" style=\"border:0;\" width=\"23px\" height=\"24px\" \/><\/a><\/div>\n<p class=\"powerpress_links powerpress_links_mp3\" style=\"margin-bottom: 1px !important;\">Podcast: <a href=\"http:\/\/www.berkeleynoise.com\/celesteh\/mp3s\/2008\/Phreaking.mp3\" class=\"powerpress_link_pinw\" target=\"_blank\" title=\"Play in new window\" onclick=\"return powerpress_pinw('https:\/\/www.berkeleynoise.com\/celesteh\/podcast\/?powerpress_pinw=98-podcast');\" rel=\"nofollow\">Play in new window<\/a> | <a href=\"http:\/\/www.berkeleynoise.com\/celesteh\/mp3s\/2008\/Phreaking.mp3\" class=\"powerpress_link_d\" title=\"Download\" rel=\"nofollow\" download=\"Phreaking.mp3\">Download<\/a> (5.9MB)<\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":3,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"","footnotes":""},"categories":[54,40,4,8],"tags":[72,71,98],"class_list":["post-98","post","type-post","status-publish","format-standard","hentry","category-54","category-english","category-noise","category-supercollider","tag-brum","tag-brumcon","tag-celesteh"],"_links":{"self":[{"href":"https:\/\/www.berkeleynoise.com\/celesteh\/podcast\/wp-json\/wp\/v2\/posts\/98","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.berkeleynoise.com\/celesteh\/podcast\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.berkeleynoise.com\/celesteh\/podcast\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.berkeleynoise.com\/celesteh\/podcast\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.berkeleynoise.com\/celesteh\/podcast\/wp-json\/wp\/v2\/comments?post=98"}],"version-history":[{"count":0,"href":"https:\/\/www.berkeleynoise.com\/celesteh\/podcast\/wp-json\/wp\/v2\/posts\/98\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.berkeleynoise.com\/celesteh\/podcast\/wp-json\/wp\/v2\/media?parent=98"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.berkeleynoise.com\/celesteh\/podcast\/wp-json\/wp\/v2\/categories?post=98"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.berkeleynoise.com\/celesteh\/podcast\/wp-json\/wp\/v2\/tags?post=98"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}