Inserting an image into a PDF and/or converting multiple images to pdf

I needed to insert an image (a photo of a signature) into an existing PDF. There are tons of tools that cost something, crippled 2-page converters or online web services that will make you tear your hair out. So here’s how to do this for free. I must warn that it takes some command line and open source hacking around.

Step 1) Convert the pages in the PDF to separate TIFF files. I did this with the free GIMP program. It runs on just about any operating system, so that shouldn’t be a problem. GIMP gives you several options for importing the PDF pages. Be sure to adjust the resolution and Open pages as images. Unless of course you love layers and know exactly what you’re doing. If you go for a default resolution of 100 dpi, you might lose some quality. Don’t worry if you get gigantic TIFF files. They’ll be compressed back later.

Screen Shot 2014-07-28 at 15.24.09

 

 

 

 

 

 

 

 

 

Step 2) Within GIMP edit the page you want to insert something into. If you can’t work with GIMP, export all the pages to TIFF and edit them in your favorite image editing program. Either way, you should end up with a separate TIFF for every page in your PDF. Exporting to TIFF in GIMP is easy if you know how. File – Export As… and then Select File Type (TIFF Image). Check if your TIFFs are all beautiful. They should have increasing names, like page01.tif, page02.tif, etc.

Screen Shot 2014-07-28 at 15.29.15

 

 

 

 

 

 

 

 

 

 

Step 3) Move all the TIFFs to a single temporary directory which you can access from your command line. Now we can do this in OSX or Linux. I happen to have both on my Macbook Pro. If you don’t have at least one Linux distribution at your disposal, it is time to change this. In this day and age one meddling with computers should at least know some basic Linux. The command we need is convert and it is part of a wonderful open source program called imagemagick. To install imagemagick in OSX I highly recommend homebrew. First we run of course:

osx_prompt$ brew update

 

Then followed by:

osx_prompt$ brew install imagemagick

 

Of course osx_prompt$ is the name of your OSX Terminal prompt.

In Linux (Debian in my case) it is (as a super user):

root@debian:/home/your_name# apt-get install imagemagick

 

3) We now cd to the directory where all the TIFFs are and execute the command:

root@debian:/home/your_name# convert -compress LZW *.tif new.pdf

 

Or you may choose to run this as a normal Terminal, because your Desktop probably is not “root@debian” so you might find that your pdf is now not owned by you. Also in OSX you can now simply run:

osx_prompt$ convert -compress LZW *.tif new.pdf

 

There it is, a beautiful PDF to mail to the eagerly waiting other party! Two things to note:

- We do an LZW compress because else the PDF would be of a monster size. Especially for b&w page scans you can compress a lot using a simple LZW.
- If all your TIFFs end with .tiff, you can say convert -compress LZW *.tiff new.pdf of course.

Automatic backups via the internet

I looked at all the options, but CrashPlan by Code 42 is hands down the winner. I’ve been using it for some years now and it has never failed on me. When you start hunting for a backup solution, you’ll quickly find that several of them are interesting but do not allow you to backup external harddrives. Not so with CrashPlan. It’s exactly what it is: unlimited storage for a good price. They do version backups, have an awesome application that runs in the background, have an iPad app and restoring is just plain easy.

Screen Shot 2014-07-27 at 13.30.20

 

 

 

 

 

 

 

 

 

Equal gain versus equal power crossfades

In Pro Tools you always have the option to use an equal power or an equal gain crossfade:

equal power

 

 

 

 

 

 

 

 

 

 

 

equal gain

 

 

 

 

 

 

 

 

 

 

 

From experience you will quickly learn that coherent (the same source) and/or time continuous material requires an equal gain crossfade, because an equal power crossfade will result in an unwanted rise in level in that situation. Incoherent (different sources) and/or time discontinuous material on the other hand requires an equal power crossfade, because an equal gain crossfade would result in an unwanted drop in level in that situation. In post production, dialog noise that is time discontinuous needs an equal power crossfade, else you will hear a small but certain drop in level.

So why is this?

For coherent material (i.e. the same or pretty much the same waveforms, in phase) it is a simple matter of arithmetic. 1 + 1 = 2. The instantaneous level at any point doubles, so we get a 6 dB rise, because 20 log(2) ≈ 6.02 dB. For incoherent material (noise from different sources) we immediately meet the central limit theorem and this only yields a 3 dB rise.

I made a max/msp patch to see how this could be implemented. The equal gain is a pretty simple afair i.e. a linear fade. The equal power uses cos(x) and sin(x) because of the trig identity cos^2 u + sin^2 u = 1.

Screen Shot 2014-07-25 at 22.54.34

 

 

 

 

 

 

You can download the patch here:

 

----------begin_max5_patcher----------
4699.3oc6cszbiabD97t+JPzoDasxy6GopbvoJWIop7zoRkC1t1hhDqV5PQp
hjZ8Z6x5GVNleYAXlAjCzRLnADa.IQ4CZUKSBLe8zcOc2SO87yu9Umc4pOlu
4rrea12j8pW8yu9Uux8mJ+CuJP+pytdxGmtXxF2G6rKuc61UKO6b++qk2d87
kKx259+QC+wU2ts3Os8GuI2+fO6xIKu5rrua+2w+Ip8klOy83Wc42+FJ2T87
uYx1oue9xqd657oa8OMI6Bx4YRR4OY69Y12U9E9kW+5xebNPrLc00Wmuba0K
aa9Gcuiy9huHa4proKleSRbVGHjve8cqu5RG8EU+kKuZ5pEqV6G9zxQr6GD+
Onhcbl2sZ41My+IGaix188qwZTIXMTlgdg77Ltz8Bjp8bmn2vxIW6dCm8kqm
OYwY8fusL+GJFLeBa6ytq.N5CxxXMIZrY9UKKFDsHb.gwnSxX3wLFACIFy04
a1L4p7OgyL62m80+k+YRNyMqy2THKNY67BsqHnW9LhDeH0EenQP3S3sswUqI
WRhel0evMv8iGwQ7ZEi63tFsSFT5dZlnGWsYMVxYMha.IMxFdTGmYs2sXUAC
JopdSyN2LYcwqea952lubxkKxiMD7.l4JFQSJLKk1xYkjy1Bbu7p5uabmZ0N
8G9mZdoX.NKe57qmr3lESll2rAddpocpelNLsyAYEqB2qVOKecKX+EE6dM6y
0hNnXSSLCKLunW+XRutZl8gqWSRMqyezoV2jCfduRxlM+cu6hucY1ulj86x1
TLx9MUexEyWlOc0sK21jl9aO3mnSxfGG2KaUlnDze+sa1N+cymtaLvZYg.uN
Ki6LEn8Sn7FLEvR5YFm6j8DR+ih8IOpijmY2tX67MKlWHFczMHLcxxYE7tk4
pJgSMu7+bretjYEk+l1XXbYaV1OuYq6UyISKXHylrcR7va2PfWMDXVB0pJew
BJUqjtgPgWxLU8gPCVT9DaY6dClceTlVHot2fPSj1xeSV9Ro0+lax2VvnKlM
7ew2Pa9YKqd1RifScrMy92BuX3yq+MaP9TR3d4Hui9Lm.pMVYvKJbPy3zFGd
rpOJUHIVS4fhQ3VFq723RkQwa3apq9lFcIxbeSGdNO5ocOl1ls+nWNSTA17I
+mZiXg0T75O+f+1AGFhceyhQM0IcnJlvHNnPJlDM2aXDoGm1UcJwTx1TBOez
5rtaY8ztbCAXtY4ja179UauKa+BMvByzuv6CNJSADdfj5.ugOrQeOY6pYW1s
7xbDB6lIgvQDNNhfNvbjOjutvo86xnDR15q2zMlyQKyDLE.Vjv3XQAJD3QOA
y0EUjJMfJGC6DLUW1TNYWZ7YDSzkPPy9i+TR9xi23dik8H1jNspL9XXbhcJK
RAv1jcsatIe4rl3yXZsmRfvUXh8bkWj85grWJ6dJA2ofepI5Q3.XJiljWGcG
8HrHfHoln2+aleWxJhBRNjBIqyd6aWbXWQIXJgvfvRnBTcE8wjHRRMFeJXOo
jPLV.LDjkOlEkUyCm.pDIZpsvZKdbtG0NveXN0NtDgPHGhQoSt8LLosTZgoz
k+iOfeQe2B9mD7izAhHDGO1QSlOFbiGlTIs0PXQAqdhX7vzNCwaBYvWaY3EN
R57AQb5IbnZmgbpHbnSmQPke8U6IjvAE.CgQOQjNRY5P3EKD7SGgCkrc9AUN
FYOeSy7iVRJb6fNo+ktMB1Z1KILbXtv8wYtRy3nWdqsyTjpVYJdiDJx.ajX5
h7IqGZCELKfcMIDsluLDFNSEaytbLjPRVVzUrDJ0myewvp474YztIgLe4QX+
X4V.KsF3H90SFNNxUS1lmw6nZy4oKADN7cpl.gyH7VYUigAkh2XFIiV7SZWk
cNBajeRexXZZj0EKVVWZg8PbrG5XvdjBPtr5YOXsEDamj1Jaw++vIW4rquca
dodyxUy239kMyWle1AqRndmaoRCVOL0yFKVIuxnRFUrR0zFimYfDcUHUljSB
GEnoVCfa4CgeBuTGo8qNREDUGpizTKoon1gnLRSTEMyxuJa6pr0Sl83qPZRo
hv7gZw79BXYCb8G8U+i+0W9my9Ce4e5ud13Ib2D6zjV5lByvNulgccCh2zjI
XVY1G.H0eDHq8jFhIo+9e6e+Ue8ytYIV37m.bVJYwrqTwyRTjlkJ3lWlu9tj
KzVrxScVaSSMMUlZm2RQyV8htd0r7X5NdhxzAeTzMTEe01feI.m1Cq.LzED3
atajN2qDEDlhWpFuPf6iD4.I4UiYoS68r8BsbG2BOQnmJbKH4aBcl0g02l9i
EAabWVmKqlildGkB47lGJHMrJp6qmrc87ONc65iXMTrX9FWftt+sEgpMSmbu
iB0pE2d8xZACud0OT66TiIxfjmgPkU32xP4w8Hk34f2kwyXGjExaW8a+ukhk
w6fnEGfdG238xPLvo0zkhk6FoiRAUBw9cPqSLvljFWNCjCYxHwXFosKgRnsm
YnSpsKgRH.1s4SwsKwZAvXPd2RdFEVmfQAGVmMYydx+cOwBpypAvRdIjNGqJ
05dBo3k.5h3Ux1WODaV0i2sD1xZWo6zcGgsz1WfD6MD9QZp.LR.mG2WRDPpD
AX3.jtNwRCfg0t0ZzSBvoRMXTsIPfpACCfnnFqRvfbgx7z+HPqSENlw3CP02
lUj7gsLw+Uuo.KiRymQmJPIqj5y8kmqLzQu+EkcWowgqjJVIaHCxgJKQL3Ji
b1y.kwzGtIB8BlDe0wE4eHegagh65UIHzmLpkt6hEZWhThOhoBMtCsXgv1t7
oT4yEIKzCsNt917Y20YKVGKWikoVozJbgQI7+Ce36fOiFWg1dk9fMWoYSVxh
+S+z2pkjAfI6Uc8AVLfgyStvvohmCLYN.WRvlK+3ZWmjI8GwWtSzvw4Zn8GY
y5oYOUcHIYo8Ey+Msy+8AmwG5r3YG7SaqzBPXbbZALij5ohz9xBio5I8Yt5o
BfuOij54fqcp.3hxHoc94izNepRcvyL91YovhaAJj+SylL8tdcmNb35bugvH
CANZs9FChr5mGJJRkpc9hjqt+C5n23+9e+2gtw+oR5OEmGc9gjlSh5ZRkzCG
1n5g4zB4770O2WCy19DPna+HF30vXlKLMoj9zJoiI8SqvjobWZcQKkiM1KGk
CdWygBPkGYOEZuS8cL1gOP6JPS4k0Dt7AX6OMo53ETcO7hm2M2t8P8+O6gaF
hL.7dey9+g17+d4NJ4D5NJgIEubGkbjuiRDIqiDhaUim4WQIbY6rfSoanjjW
XpU7iS46mjjWbpAFD52NIOh1c2fcYX6tax61Llh8rd2cSdw1vDgCS6I216l9
JQx2h.Fus2UI4BN8oe.hLA.t7ns+tZoxtuo.+DlKygnhONav6l4c7Zn+H4gE
iAfmDteVXCuBtQZTlmA0.JilroEw7UcV3ZGbfE89rRTQKB5iOJ93mrSXUIAF
xNlm07rOo3I6vUi+159bupKn514+mLUcQxN4EaT2W2w5n32tuZuTzE3ocxZm
8exTyE.jDGGUyoq1LJtyltyg3ycQk2r1AtKYLVMUsjQvG1kmmIUgh.dQnjtu
D4YKOOKBkj8opxd80IWQnjr8mwnlWJBEr83lz9DvHUDJEAfxdVTDJI6+gFyI
VMn.Pg+juDT390BNxkfhD.q+nTAJOB6rcB.82mSvF9GGPyg.YtRSMK7uc42t
7Q+8aP2WWnIMd8A1t3FuCC3h1cg1DZpGAio7Wl3PYhSw3cYhCPHgFNoeSbtO
likGZlJUyit20BWeTId1bypaWOsxhRU6KLis6sMKuv+wk632ey9FbU19gz6m
OaV9xXN+0ymcyp4K2FFDBizGaK0WEC6o1+hluob4TGehbPIwNg.ZaHf1QDnC
2lEgNCuAcDPZAATaGQPzXtbccFpHPC.AksqwtfffbSnfGhov.AB.Hn71MuKH
fVt+1NW88p2bZ3hcnNo+R4fxT1cjXfPNDoLQ2PnxXi.nzJhvWEkGdRo.Uzw.
fNCuWRfADToQgEBnHffpwruA1DSgABHPP.q1BNsOG3KDBt2fbLEFH.hJRGMi
wz9RLf6SuWDEB.v.AAVd+Tx4gNQnESgHiAhPjtaHvPcWpBThSHJlBCD.YwPE
qeHvuXnIHEgzhgk0eV6yAcboBJkGMGDSgABjPzCHcb4ffwGgL1TTs873Hh.H
Njn52TfWHhpknJDwgtZP2WOi66iVhP7R0oppfSmGuNJLPGD+MrczLUXLKnww
M4nvBATHHf1ADnDtpqqBBZ+cq3nBgNpjrCBdCU0HGMAIY+DjBPHhZrlEX8cV
vKHwY5cBR6oDgPJr9OpPLdyPL4CQUOE7BloQCcPB6PK65BMZ2JMhvZ86ov.A
PB6vcktziUZBtqH7Evx8oLQpWNpwCdjGD7hnP.BZH9zqscaoFqJz9P80Mh0+
O2ixeizXY6oFK3U15F6E770WSEfpQI727nVp7.TdqGFq.SqGZHw5n6XDyVu4
Bl+xRnhQ3HGMHn53rWMHPIEAIL5Xnrkp1CLToC4uCipSI7G70vmzQgA5fDLm
rmKQorwKQURgABfDLmoelvU7HK3JNNieP4Nl1wkXqx3Mm3mCXdoIG43ABxCC
DbepYPCDPbFU2w3Nsr3r3WY6RSFODn5IB7onzFtUKPJEkZPtLy5EBn9C4QLE
FH.hA0NllalNZ7GSgv3WAIM2JSulA7WBQQDXL9A4PLseRP7ZRPHsQCJPdM0U
ONB5s9JgN3j68nB1n3BLsQof3wgVzubWphVuliS1IUfRdbGSIiQR8s.FmCGw
TiJBncGALVzln3nFKDHr8aNvifvJ0iJBnL0CABThMraJ0HElvcrK0e0cYPRJ
igvJ4UaNmuF5qrCaPxREDeQTjdg.+JgQDXL9IXrYo01xcCta4t536KU0NyEt
JvXZLkfjVL7lUaGNc.In7uo6EBBdCpwzaPIH2ws8aFH3MnFUuAkPTBTcrrSX
p8agv9eGiQODu8319keoc06fF0Bd.FFLOPLH3Q6BxdRS7Z0XsOHRPdiPY8Ch
gLGTiDCP.Z4ZQuVtSn0QNl6nv.ADnHnKA9IUwHveWZhFBfrctjdk8iPzoU6H
MVgmJA4Wd+PP3pNTPvTMPv.gfNmReuEHYnYTDShAHnnXPhYHQEc7NCRHU0wB
Bfh2P14R8yniN9D6v.Rm9.GFZ6LrH57lS3afoUXnZZASLzpUod5Cxt4ApFUL
.sf+5QAkEJ5xZjH.ANjfgDjd5FEutqfbbTo4FnXf1caqzPQIEzNnHUWAbHgD
w6ZMW46M6RRnXq1SgABfDRjf2ODnpg.0Hh.JmzOH3uJtKqKEYfBCH.JpHU+P
.u1j.RNYfRQTGJM5fI0HJD..yhSXagkxFFujXfTEjcyj5t5V0G0SngYgUTOL
ITHz8DUVg.gEyHOYfpCWUOmD74zfI1c3AhnBs2esJTmwzQDe79gOt2ibdwpc
5JRLv.H2X6ZnoUgS6qltZjiFFn8bdf32FaiuZ5tGku6aHIgOJe7vGU0u4Htz
Gpg1unhDIUEHHnWlx746Oh.gQO0hwI8MbB+GjypL0fPADUaaSQdSunfZXA8B
.dIHFp6ZJUA8HozkP7B5r9UJp5EI0npNRJVFlEUNLzIdHni46vQXsLHETbG5
t1MIrQENQ.H0oBkMQHlDrpZBPni8fPGSSwrxV.g.JueHvWeTwTiJBn8cNHrH
HZyAfRWXGWDIzkQBEic0QzFoZwFDBnD9CABJIGUH.JYgccm6UNkWiX+N2aPZ
kBP4Ij5zCXcI2+gShPnCeEShAJ.kdAQOSQRHcm0HQADfVyqufPUGDpwDDTNu
mnvDxVkB0rdRA0Kj5X7qgMDNzjpC6RbcpvleGZr4Hs22TPdGRo8bJJjTzZjn
fBIXTzocoQai2tr5znfCNzy9ZOlLBmGdJgYiNd76HCmv0P0ufUvH2aNHwYqj
ziIJPPrp7XPEhs6HiomyhUkKVD4nMQQI59NSsqP9rn1PPfNandX5Tg5Y.qVy
BzYCUOMvsCF9lLHdvfgypMgyVMguyg.xmRVc+FEVKBoVYz8O2tM4zSWUbp7Z
NrTTLIJn.VexnicYhcmmWkumcJX6IQAEPJF+9cxL40NYlHUI322tTSSCx9UU
bglAaMRTPALavcLGjUAy62oWMYOEJX.TmkRzyVZandoiIQADPTHrcTotpi83
8tJzspwpTlteq4IAD5Q+6gWq+8fTEkAyzJsWlkBaWBC0sKAgVoX3HZ4MpFS0
5322y1mbyMeHe8lvfvMzO65IeuuY0qN2QNeomz016Oac9GlW840t+xj0Se+7
s4S2d6Ze+g+iF0Yut787Ku9+Cy8Uz3.
-----------end_max5_patcher-----------

I also made a YouTube about it for this coursera class I’m taking:

Copy icons in OSX

Sometimes I just want to change a default icon (e.g. for a folder) in OSX. So where to do this? First you need a source image to copy. These days (OSX 10.9.4 when I write this) just about every image you can preview can be used, as well as other Application or Document icons. It wasn’t always so.

Say for instance we want to use the Blender icon for the folder it occupies in our Applications folder. The default is the boring blue folder:

Screen Shot 2014-07-13 at 14.00.50

 

 

 

 

 

 

I enter the Blender folder, select the actual Application and choose Command – I to get the Info window:

Screen Shot 2014-07-13 at 14.02.22

 

 

 

 

 

 

 

 

 

 

 

The trick is now to select the small upper icon and Command – C it:

Screen Shot 2014-07-13 at 14.03.27

 

 

 

 

 

 

You can then do the same for the Folder where all the Blender files live in…

Screen Shot 2014-07-13 at 14.04.27

 

 

 

 

 

 

….except this time Command – V the copied image into it:

Screen Shot 2014-07-13 at 14.05.50

 

 

 

 

 

 

 

Voila:

Screen Shot 2014-07-13 at 14.06.52

 

 

 

 

 

 

 

 

Routing audio in max/msp

In something I’m making in max/msp I want to switch the order of a filter and a saturation stage. This seemed easy enough with a a few gate~ objects, but the output was muted all the time when I connected the (inactive) outlet of the gate~ back to the inlet of an object. This is counter intuitive. To explain, this of course works (noise output):

Screen Shot 2014-07-07 at 20.02.18

 

 

 

 

 

 

 

 

But this next situation mutes the instant you connect the closed gate~ outlet back to the dummy +~ object (which is there because max 6 refused to connect that gate~ outlet to a gate~ inlet):

Screen Shot 2014-07-07 at 20.03.18

 

 

 

 

 

 

 

 

 

I guess it all makes sense from a max/msp implementation standpoint and protects us users from stack overflows and such, but how then do we route audio? Using send~ and receive~ it is easy to deceive max/msp, and this works just fine:

Screen Shot 2014-07-07 at 19.55.34

 

 

 

 

 

 

 

 

 

 

 

This way the noise~ output can be routed p gain -> p level -> easydac or p level -> p gain -> easydac. Awesome! Here’s the code:

 

 

----------begin_max5_patcher----------
1447.3oc6Z0sjhpCD9Z8ofhaOytEI.pL2cdN1yTSEgnlcwfUH33rSsyy9I+.
XPIXbKWFOmZpoDgjNjt+R2ecm371zI9KKNfK88dz6adSl71zISTMIaXR8yS7
2hNjliJUh4mVrcKlx8eP2GGefqZeMhP8Pq3Xl2Vr3Zi.qJn7RxOwRg.vuFT2
LsZKgli4pWJnQV15kxmCLEqnh2HWSqKWmVjWvzpMPHrXDIfP.LRdWXRHHLQd
Gbg2S0CYGhmtgPW+LCmx0CbVfZnIgxqfvH4WPwT2NFRlxxJV98uDBLsGJZqx
d7+aFAk6K63WSmJu7vs.EWhWUvv+WAFiiRjCMdtKvXvsEF2hKKQqwmAio4XD
Sn5d.0eP0GwSMBpAC9q6vZav2uUacAng8Bq.6XTTrxIKYlBifJ.CrneLBlLx
XTCJIwH3GHFodShnRWvnE2VLhheQ7ZOChDJGlrG+tWAzJpTRVSES5UgMfqEa
lCTdNvHkaz7vghw.fQAaJwzLSf422tCFfaIQ4SDlX3ZX0tCFYeBvGqOwLXny
9DIioKA3OqKQXfytDKFmj1GdziP2Uw+G5qO5IrBwsMxjSn3zhJJ2jR7NNWtF
bAyhNBtgg8CtyuwooPbF4PJmkaMrJmTJ.15uaUIGbmZ.dADUskpZJrtIVwKc
d1dhoZPA.TekjzOpD429hXHUEbOionk4JaH31Eqogq28B8BuDMzC8eWWTzEe
xvdA2nKGqFUWTX7f0FNJbT67jkXeevbmnPmnAYtgCkM2bJvrZvnFMDCfji2i
YkjBpgBMwGsamQySLFhDB+tlDY1CsMQn5l.sMwv6IMi+nfHlvP4BqrhoUxCK
l4q6TrrMsYnMn.T4TDuPY8yz02jXv0H4zxKR+ANyfmSrjsCSErsLrHaCGwq0
h1tyvqPU47m6egqa+qPoXqCtWndh+ZFIqfJUhNiT1byzI3eUN5xqGMFkDTzt
dFbovNpJWhXRTslp.1zIunHuaWsKjh..DkHXBvbhVYgAsuTx1cLhNuSaaZln
Mkorh77NuJcO66omLwZcJ9ERFeSm7PxdDhS10rD32hQYj03Rd213n0kcaoyI
OX5DZFY2o8Shv0AaMuOagk1yYZeyZJeQ8V1fwMWaWJsvaUmgQWhfxRaZVwbU
GF7aZqJyxbhtDy043QfU7.3Dd.bCNfiAbjKp.+qRh72Mms8HVaTa+R3TJR4m
U4Enyq0v5tb6ATicATmqOzjXMeQ3b6vJvuy667ZKLWDKQ6wYOi3hRDVVwwGu
qz.aM.WIzkWgKVY1sY+lSYdAc8vvbGwK2Tv3Wg7MKNAV5eq.8k8+k4GohNWF
jxKZlUIHTBWRqqVKB5B6cDrRHXI+UMFGcTlVmXyaM7rOR7K2BfEdNkegr+9c
4KKpXoMdp0NAdc8PDbvbBsMM32ZojNQtMjrrtYczD0kR2mr1ZSuX340pwPG0
XvMRi8dZpY8F0QBhYPD30SXva2npBtbUGWQpxdUhAlbaSpn5okn75hCaGaOY
jmdDDuUEYKq7L+93Lypqxdv8d.R9+ZU1gyzVux7CiAsPxmkY+YY128kdVWzI
zsROiGiRO6P40k16udWrtc0HkkPnqnTSm.QflNLbwo7f1NAqgNKlaDV9mZGb
0tMZtu6jcvoxHppob3cjnHSd55gjK3DrPgEI5ivDpbBjmmo8cwMV0zF6XEhQ
2M0z5pFCuaz3nQdeCeVE98PU3zBRI98O1hvq+E.ZJBe1fG08s8G..+yLTZq4
6v+aBC7iNNSW+bzb3w8RDEaYuDlJqRftzkZc+zP3ZK3rPWYHIrcZru4YPqLm
Exdd35YH4sVaBFEsIoyLYgDd7TmHGTmvQSaBcPaVLpZC3RNNAil5.cw0IZ7T
mE2WpCvQO4wgzAdWEWARbTcfii53xZ0I5r65iN80IGkkTUN4HrN43qN+nqrc
rUh44WS+WQk32T.
-----------end_max5_patcher-----------

Controlling TouchOsc via Python and maxmsp

Controlling an OSC client via Python is super easy thanks to the python-osc module. You install it via pip:

 

thingthohmmmmmm:~ henszimmerman$ pip3 install python-osc
Downloading/unpacking python-osc
  Downloading python-osc-1.4.1.tar.gz
  Running setup.py (path:/private/var/folders/wz/7t75jnps3m5dvmrqd4kwpglh0000gn/T/pip_build_henszimmerman/python-osc/setup.py) egg_info for package python-osc
    
Installing collected packages: python-osc
  Running setup.py install for python-osc
    
Successfully installed python-osc
Cleaning up...

With that out of the way, it takes just a few lines of python to control the super great fun TouchOsc iPad app (in this case its monome128 template):

# Python3 on OSX controls OSC UDP iPad client TouchOSC
# with the monome128 template.
# H.Zimmerman, July 4, 2014.

from pythonosc import osc_message_builder
from pythonosc import udp_client

import random
import time

# Hardcoded IP of TouchOSC on my iPad and port 9000.
# TouchOSC has monome 128 template loaded.

client = udp_client.UDPClient('192.168.178.31', 9000)

# Turn on and off 100 times.
# We start with 1, else the TouchOSC LEDs are turned off first
# which suscipiciously looks like it isn't working.

for counter in range(1, 100):

    # Monome128 template has (duh) 128 buttons.

    for buttonIndex in range(128):
        # Build the OSC address of the pushbutton we want to control.
        buttonAdr = '/1/push' + str(buttonIndex)

        # Some console output for our nerdy debugging fun.
        print(buttonAdr)

        # Now construct an OSC message.
        msg = osc_message_builder.OscMessageBuilder(address=buttonAdr)
        msg.add_arg(int(counter % 2))

        # Send it to the iPad.
        client.send(msg.build())

        # Slow down, OSX, else it's over before we know it.
        time.sleep(.1)

I was already having a lot of fun controlling TouchOsc via UDP using max/msp.

Screen Shot 2014-07-04 at 21.34.24

 
 
 
 
 
 
 
 
 
 
 
 
 
 

In case you want this max patch for experimentation fun, here’s the code:

----------begin_max5_patcher----------
1653.3oc4a0saaaCF8ZmmBBgMf01DW9qnztYXXO.6hc4ZQgrEiiZkkDjjyRa
We2GEoUhaijEcMImRZBjULMk8QG+8c99gLe9hEAqJuSzD.9UveCVr3yWrXgZ
ntAVr+4KB1lb257jF0zBVWtcqnnM3R8q0JtqUMdSaYU+fE61lUjKZUWA5gAK
201OJb+nYopqtb06uhh6u9qKKZKR1JTuzuWmkje+qTuYk5xWBOXtMYeRMWD9
9gqRZWeSVwl2UKV2pu+XQQxWFfwpSD7Rl7Ix2Hva6tjubwEcOb4YRCU4Ie77
nAB2wz.jqtysBMrUzzjrQ7HZ.NHGfGjC5YF8PserRnAZP.3sCPOgFPOFSFgx
67ukLPQVlLPtiLn1jLXT3ibP9tIiBw+HQ3i3hZ4Ml.fBoxCl7HTdvkGQxiX.
hOrgSzfbUznb0kG4XPdDYUipX7RbG2wzBNPj9jkYRwFwcUfWWsq4le4MxeRe
0KV9xSP6gYL8MDkgsqeXnhpPXr5DJ7rXrbQ5Q4gpjZIdaE0uSTjrJWbnRrgt
iYRs+gnkPRv32kbl1AiC6u8ruYwU.qH2L18GypJNzH022TB+IYrHFwljAGQT
r.h5N42ceJShhnSfQHiwHqRJ1zoNzedTKFnUsXXZKFnRgfFeVtPikD25bQRM
PphzblYzF61T43jXc1KJxficgdRKX0IPBniZsLj4Ak6.en8LBl5BF4O+q+3J
cZLcgdeoMXmgYFpChvFoTZQPmXqrqnJY8G.YfqOARAerPPRckqyKSFVYgZU4
WDDxTbSj5T34wPiELpQzB9I2UP.0pIxRBoc5KgHlNJslddhwH1M7S7SeFgD6
fJnsCiLhtxlDoXK6DHjyqzFRjc0UzAiHDcsMj3mARuDKK8x2msqMjdmnd45x
1j5OpqX9EcO17KKe4K7VcyDnSBZsuvYBysY7nIueyY47fwtfc5S5I1sjyqQ1
v2a7NtfbA2vTMmJB8TLaGjUijwYpxEbar8Wi1K.wbJwD5.hgyUtQ7nyhXRO.
B2+w+PsucQbj2iU6Z+FWGmzEuwCvgdnrzMqKyKq0WgpkcJek9+59Kd0ilGbv
40AhrBgYStPHRyMbtGwjlROP.TcxMF0TmZTScPdq+XYTydNXT2WwguLpwN0n
1Ekm9ikQM94fQceiEbuQcWSK6V+U3R20gA6JTyWxY8IpRHPWzggcoUxOQQ1s
B.CBgNq9FmjBud0RiicRJ7H3RBeIBGuDeT6ktKXP2Ozi7TNG9y.BzT26uhno
Gkn4GzXXr9YNp8DR8lVUSIdUWWIz+kbnsIMevasnvts+RycTsY.2IaEhlp5r
h1qA6U294zwhXakVTD6fVryP6aiCzINw8x9XtKykAa0kxCGqRyiEpz0hcRik
qSJRK2dhqH9IumIvLGXwPiTlJ7yqgeska1jK9+ZyxfoCpYiNoLmH5xAHLc7u
n9Gsoch79utDfrxNIYzUBGa0zl1SK62nD86DsmllIvfokIfbK70+j0Bhbo9o
KBr7CUofOK5YW+htaoJAGufmFQQJ.EiWhBiVhjVHDDH9zJ9Yf87DyA4.Dg0Y
OFQbQ1iRyoT8lXygayIDwAIUqj1CcSJiYWutr35rMf+EroVTAdSPWoIxS8Cb
0sRPJwg7W2IIFZeVSuABw80zY4JQtQjmaqUAb78Lm8YkX5wpsUAhfNIvu4+U
H06W23eMU0Ttqdc+sx9PafGT8REMsYEIsYkEGLG1WMmaxRSEEGJxjl0zEwPQ
CvA+JyTzHy1Gfl.MccZ3fI4R3vMfbh8F4DZ.ZndCMLpAvA6O1oaKeOMdnyL7
.8Gd59nvS4oS8Kdlje3dCOTSb1CIyK7vla3we1yTizeB8GdHFD6hD4sXWca3
3I4GO5dYh6d2JF5K7X.bh7FZHljFFxe4gQhLIWCjewyTNWTnewCYJm8X+hG5
T1OdDOgyqjwHzYFdLI4PhG0eLIXAk6W7LUxpjP+hmICt6Q6GnI5gj4EdH9CO
3XSKtvOIig4yp1rnRKdxut7W3cLad0KArQgK7n4rQ8RfMyvi+RGCiMIbpGwi
QgSoyK7f8WwW3YVuePFU9kGwiIgKP9K8GT3rJ7ExjvEH+4dgnyK5wD0YOZ7X
h3LxehyH375aKSBc4sDUMJPw2ahg5EqLop5VQcy92SERB1l7d8dxH7R0SyJz
OUs1rA0hay5mudBI0quIqUrtcWsdIVuKJL3htOmubw+AEYN1b
-----------end_max5_patcher-----------

Through the wonders of UDP networking, TouchOsc can easily be bombarded with osc messages from both max/msp and python. Here you can see a silly demonstration of just that:

wxWidgets: drag a file in Windows

sfx

 

 

 

 

 

Disgruntled by the slow and bloated commercial sound effects program we used at work, I decided to write my own blazing fast free light weight version. It is much simpler and uses a flat textfile “database” that’s read straight into RAM. Combined with ISIS network storage, the result is considerably faster and we now solely rely on my program for day to day post production sound effects in every studio and for every audio engineer in our company!

I wrote the program with the fantastic free Code::Blocks C++ IDE and used wxWidgets all the way. You can of course download the full source code and executable on sourceforge.

One thing that took me a while was figuring out how to drag a file from a scrolling list box straight into the Pro Tools timeline (because that’s what we wanna do when we select a sound effect from a list and use it in our sessions).

Let me rephrase that: I have a filename and want the pointed-to file be created in a drag and drop fashion. I’m not coming from an actual file, I’m coming from a filename.

Needless to say, this is just a Windows drag-and-drop, and works just as well for copying a file to a Windows Explorer window or an Avid Media Composer bin. It turns out that you just need a wxFileDataObject object and populate it with the filename via its method AddFile(). Then you create a wxDropSource and populate that with a pointer to the wxFileDataObject using its SetData() method. With the wxDropSource you then do a DoDragDrop():


wxFileDataObject* data = new wxFileDataObject();

wxString fileName = whatever_you_have_to_do_to_get_that_full_filename;

data->AddFile(fileName);

wxDropSource dragSource(this);
dragSource.SetData(*data);

wxDragResult dragResult = dragSource.DoDragDrop();

wxDELETE(data);

// ... assess dragResult, etc.

A good use for Pro Tools’ relative grid option

One of those things in Pro Tools I ignored for years until it dawned on me how handy this could be.

rel

 

 

 

 

 

 

 

Scenario: In a post production timeline (so to be clear: this is not a song) where you work on a timecode grid with frames, some event needs sound effects. This effect happens to be a graphic that ticks away the seconds. You want a beep on every second. Now simply switching to grid mode will not necessarily align the events on the seconds. Place and align the first beep in slip mode, then switch to rel. grid with a seconds grid (see below). You can now alt-drag every next event to the next second. It’s super easy and fast!

rel grid