Commit bc9c0c91 authored by ludi's avatar ludi
Browse files

Finally Bits and sound joining the relearn package

parent 8bb1df4c
This diff is collapsed.
Bits and sound - 06.07-11.07.2014
======
### File formats
We can think of sound as series of air pressures; a wave (WAV) file
is sort of like a series of numerirc air pressure values.
We can think of image as a grid of lights; a netbpm (PPM, for example)
file is pretty much just a cartesian grid of colored pixels, where
each pixel's color is specified as a triplet of red, green, and blue values.
In an eight-bit wave file, each byte is the air pressure value for
a frame of audio. In a binary PPM file, each byte is the intensity
value for a particular color (red, green or blue) within a particular
pixel of the image.
### Color versus oscillation
I ran [this](http://small.dada.pink/netwaves/drums.py) to
produce a [file](http://small.dada.pink/netwaves/drums.ppm)
that looks like this when interpreted as ppm
XXX
and sounds like this when interpreted as an 8-bit wave file
played at 8000 hz.
XXX
Sound is expressed as oscillations in value, whereas perceived color
is expressed the average value in a particular region of the image.
A series of pixels of the same value is heard as silence, and the
same series of pixels is viewed as a solid color. The file above sounds
like a series of beeps, and the changes in visual color aren't really
noticable when the file is played as audio.
#http://source.thomaslevine.branchable.com/?p=source.git;a=blob_plain;f=dada/relearn/index.mdwn;hb=HEAD
Thomas Levine
XXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXX
XXXXXXX
XXXX
## documentation
On Tuesday evening, Yves Poliart was invited to present a playlist in echo to the worksession.
He spoke from a text file containing small text entries shortly describing the musicians accompanied by urls, leading to youtube more often than not.
It was quite exciting to quickly go through works by Luigi Russolo, Walter Rutmann, Daphné Oram and Delia Derbyshire, Coil, and quite a few others.
##documentation
## loops
You'll find here a set of python script to write ppm patterns pixels by pixels.
exemple:
`
# Generates a gradient image in the ppm format
# Usage:
# python gradient.py > myimage.ppm
print('P3')
print('51 5')
print('255')
for value in range(255):
print('0 0 ' + str(value))
`
looks like
<img src="/loops/gradiant.ppm" alt="a blue gradiant"/>
## sheetmusic
Sheetmusic is a plugin of Gnumeric providing musical functions inside the spreadsheet.
https://pypi.python.org/pypi/sheetmusic?
— The spreadsheet 'rgbvaluestochords.gnumeric' uses the following formula to map rgb values (decimals from 0 to 255) on a base 7 corresponding to 7 notes (from A to G) and 7 octaves.
=concatenate(if(roundup(mod(A2/256*49,7))<2,"A",if(roundup(mod(A2/256*49,7))<3,"B",if(roundup(mod(A2/256*49,7))<4,"C",if(roundup(mod(A2/256*49,7))<5,"D",if(roundup(mod(A2/256*49,7))<6,"E",if(roundup(mod(A2/256*49,7))<7,"F","G")))))),if(roundup(A2/256*49/7)=0,1,roundup(A2/256*49/7)))
This means with this spreadsheet you can convert a pixel into a chord.
— 'rgbvaluestochords.gnumeric' convert decimals to notes. Play Fibonacci !
## pd
Pure data patches.
binaryseqauencer: play sound from picture with a binary sequencer
play sound from a text and/or with the keyboard
pixel-player: play sound from rgb pixel datas
asciify: turns characters (symbols) into ascii values (floats)
list-find: Find positions of a value (symbol or float) in a list
rawreader
open textfile
textfileludipaul
=====================================================================================================
Digital Drawdio --> connecting pencil drawings to all kinds of programmes and networks by dy-wen
==============================================================================
Arduino takes the resistive qualities of the black crayons and it can send it as serial data to
- pure data
- the terminal
- python
- the network
- chatbots?
- somewhere in space??
Setting up the Arduino in physical space
==================================
- take a 800KOhm resistor and make a voltage divider with the A0 as Arduino input (change the resistor value if necessary)
- put a pin in the graphite of the pencil & connect it to the Arduino with a aligator clip (this is one leg of your variable resistor in your voltage divider)
- connect a aligator clip to the drawing (onto the graphite) -> it is your ground
--> start drawing between the ground and further on the paper
Arduino & Pure Data-extended
==========================
- on Arduino, upload the StandardFirmata_slower sketch
- to connect with the Arduino in Pure Data --> put the Pduino_arduino_test.pd patch in the folder where your music patch is
- open it and follow these instructions
- Instructions to connect the Arduino data to your Pure Data Patch with Pduino
------------------------------------------------------------------------------------------------------------
- Choose the right serial port, for the usb to connect to the Arduino (little blocks in the top left of this patch)
- Open the connections to the Arduino (analog --> 14 & 15) in the top right box (configure mode for each pin)
- you should see values changing at the bottom left - there are two send objects: s arduino_analo0 & s arduino_analog1
- put two receive patches in your own pd patch to receive these data (r arduino_analo0 & r arduino_analog1)
arduino & the terminal::
============================
Put a sketch on your Arduino that sends serial data to the serial monitor
In a terminal -> run:
stty -F /dev/ttyACM0 9600
stty -F /dev/ttyACM0 raw
cat < /dev/ttyACM0
(potentially interesting: https://github.com/todbot/arduino-serial/)
Arduino & Python
========================
http://playground.arduino.cc/interfacing/python
Arduino and Python
Talking to Arduino over a serial interface is pretty trivial in Python. On Unix-like systems you can read and write to the serial device as if it were a file, but there is also a wrapper library called pySerial that works well across all operating systems.
After installing pySerial, reading data from Arduino is straightforward:
>>> import serial
>>> ser = serial.Serial('/dev/ttyNameOfYourSerialForArduino', 9600)
>>> while True:
... print ser.readline()
=============================================================================
Commenting on bits-and-sound :: a partial account of the week through day 1
:: beware, *syntactic sugar* only :: by madeleine
=============================================================================
==the endless translation workshop==
During this week we have been switching formats and interfaces treating data versatility to its limits / bringing out its potential. We have been producing data then working it into different formats and so into different lectures and devices. (Earphoned) ears, (concentrated) eyes, (busy) hands and (mostly sitting) bodies have been playfully manipulating the protean lives of 0s and 1s in the name of sound.
Here, what-you-see-is-what-you-hear-is-what-is-transformable-is-what-keeps-rewriting-itself.
During this first day some people within the group were experimenting with glitching for the first time, some others were using the terminal instead of a custom software to produce them for the first time while others were already beyond simple glitching and into DIY experiments for instance (hi Wendy!).
Some collections of glitched images ended up as animated gifs produced in the commandline : the "broken down" images came alive like golums of code through a simple suite of words : convert abcd.jpg abcd.gif
## monday-morning-glitches==>>
This folder has gathered our first experiments editing pictures while playing with software, be it Vim or convert, nano and gimp in the terminal, etc.
This session helped us come a bit closer to the basic structure of several picture formats. We started by identifying headers, content and other parts of the data contained within images by opening them into "foreign" software.
Opening data (i.e. an image file) "where it does not belong" (i.e. a text editor)
(((but, from the PoV of data,
are there really such places given its inherent versatility?)))
is like forcing a "breakdown" = "force quit" but stay put.
Through this artificially provoked malfunction what actually happens is that some things do break down. And they break down in many ways :
On the one hand,
the image file is no longer a meaningful, more or less homogeneous surface you can have a quick look at, it not longer "works" for your (codewise illiterate) senses, it has become a broken (down) image.
On the other hand,
this image is literally broken down as it is now in pieces, reduced to its bits and pieces. It has become (un)readable textual material and, though visually rich, unable to be perceived as a traditional image, at least not by human eyes.
This discontinuous writing is the image as it is (now) : broken down to the pieces that tell the computer how to show it to human users. To human eyes many characters are familiar while some look definitely strange and some are more like new combinations of known elements. This state of the file is an open door that leads to a further (third) breaking down also known as glitching.
Why did glitching come up so quickly in the bits-and-sound room? And, how come there is so much glitszching going on nowadays on the web for instance? What do you do when you glitch? To glitzch is to intentionnaly provoke a breakdown, isn't it. You start experimenting with formats and files, you start gliTching. When you turn for instance an image into text by choosing to open it in a text editor rather than in a dedicated image editor, what you make happen is not only transforming the perception of the file, but also stripping the body of a contemporary digital file "naked".
Images in text editors become as many half-readable half-unreadable chunks of text (letters, symbols, numbers) as you can mistreat, bend, erase, tweak, transfer -up to the point when (if you distort the header for instance) the file really breaks down and can be opened nowhere no more.
But before it becomes a lonely dead piece of text, it will have become a variation of itself.
And also a variation of possible relations to the computer (that can thus become a start for the way to *companionship* ((cf. D. Haraway)), to the way it computes and how it uses us/we use it or make things with each other. By treating files "deviantly" (yet harmlessly?), we get to strip the user interface down to a first layer of code. We get to know tech-logic a bit better, we meet the noise. Provoking a system's breakdown makes the system visible ((the idea is several decades old, comes from ambiguous Heidegger)).
Picture for instance electricity going down while you're in a museum or some other windowless place. You suddenly remember it's so useful and fragile. You realise how electric current makes som any modern things work : the museum as a space, your activities there, the way you see art, the way you talk about it online. Rathen than banal and everywhere (it's not everywhere, except in its bio-electrical form), electricity appears for what it is = a reality-forging technology (to go very very fast). So, forcing a file into a "foreign" environment (=the wrong software) exposes the fact that what we recognise as sound, image and text through our different (often codewise illiterate) senses are code and layers of translations that go as far down as on/off == true/false == 0/1.
In an apple/google/samsung/facebook/etc. world, this realisation can amount to important and even dangerous data. Not because the above-mentioned superpowers are afraid of glitched files and animated gifs of course, but because code literacy (which can start with glitching and experimenting bits and sounds in unsound ways), combined with critical thinking, can become a way to destabilise apple/google/samsung/facebook/etc.'s current and coming kingdoms. But glitzching in this political sense is also important on a more humble mundane level opening up possible companionships that do much more than simply allow apple/google/samsung/facebook/etc. to augment their gains and power, which seems to be the dominant reason software is created these days... let's glitzsch the landlord, let's lyntzch the landlord yeah
P.S. twitter says On Kawara died today, 11.07.2014, age 81.
======= =============== ======================================== ==== ====
=== ========================================= ============== ======= =====
\ No newline at end of file
P3
# The P3 means colors are in ASCII, then 3 columns and 2 rows,
# then 255 for max color, then RGB triplets
51 5
255
0 0 0
0 0 1
0 0 2
0 0 3
0 0 4
0 0 5
0 0 6
0 0 7
0 0 8
0 0 9
0 0 10
0 0 11
0 0 12
0 0 13
0 0 14
0 0 15
0 0 16
0 0 17
0 0 18
0 0 19
0 0 20
0 0 21
0 0 22
0 0 23
0 0 24
0 0 25
0 0 26
0 0 27
0 0 28
0 0 29
0 0 30
0 0 31
0 0 32
0 0 33
0 0 34
0 0 35
0 0 36
0 0 37
0 0 38
0 0 39
0 0 40
0 0 41
0 0 42
0 0 43
0 0 44
0 0 45
0 0 46
0 0 47
0 0 48
0 0 49
0 0 50
0 0 51
0 0 52
0 0 53
0 0 54
0 0 55
0 0 56
0 0 57
0 0 58
0 0 59
0 0 60
0 0 61
0 0 62
0 0 63
0 0 64
0 0 65
0 0 66
0 0 67
0 0 68
0 0 69
0 0 70
0 0 71
0 0 72
0 0 73
0 0 74
0 0 75
0 0 76
0 0 77
0 0 78
0 0 79
0 0 80
0 0 81
0 0 82
0 0 83
0 0 84
0 0 85
0 0 86
0 0 87
0 0 88
0 0 89
0 0 90
0 0 91
0 0 92
0 0 93
0 0 94
0 0 95
0 0 96
0 0 97
0 0 98
0 0 99
0 0 100
0 0 101
0 0 102
0 0 103
0 0 104
0 0 105
0 0 106
0 0 107
0 0 108
0 0 109
0 0 110
0 0 111
0 0 112
0 0 113
0 0 114
0 0 115
0 0 116
0 0 117
0 0 118
0 0 119
0 0 120
0 0 121
0 0 122
0 0 123
0 0 124
0 0 125
0 0 126
0 0 127
0 0 128
0 0 129
0 0 130
0 0 131
0 0 132
0 0 133
0 0 134
0 0 135
0 0 136
0 0 137
0 0 138
0 0 139
0 0 140
0 0 141
0 0 142
0 0 143
0 0 144
0 0 145
0 0 146
0 0 147
0 0 148
0 0 149
0 0 150
0 0 151
0 0 152
0 0 153
0 0 154
0 0 155
0 0 156
0 0 157
0 0 158
0 0 159
0 0 160
0 0 161
0 0 162
0 0 163
0 0 164
0 0 165
0 0 166
0 0 167
0 0 168
0 0 169
0 0 170
0 0 171
0 0 172
0 0 173
0 0 174
0 0 175
0 0 176
0 0 177
0 0 178
0 0 179
0 0 180
0 0 181
0 0 182
0 0 183
0 0 184
0 0 185
0 0 186
0 0 187
0 0 188
0 0 189
0 0 190
0 0 191
0 0 192
0 0 193
0 0 194
0 0 195
0 0 196
0 0 197
0 0 198
0 0 199
0 0 200
0 0 201
0 0 202
0 0 203
0 0 204
0 0 205
0 0 206
0 0 207
0 0 208
0 0 209
0 0 210
0 0 211
0 0 212
0 0 213
0 0 214
0 0 215
0 0 216
0 0 217
0 0 218
0 0 219
0 0 220
0 0 221
0 0 222
0 0 223
0 0 224
0 0 225
0 0 226
0 0 227
0 0 228
0 0 229
0 0 230
0 0 231
0 0 232
0 0 233
0 0 234
0 0 235
0 0 236
0 0 237
0 0 238
0 0 239
0 0 240
0 0 241
0 0 242
0 0 243
0 0 244
0 0 245
0 0 246
0 0 247
0 0 248
0 0 249
0 0 250
0 0 251
0 0 252
0 0 253
0 0 254
for value in range(255):
print('0 0 ' + str(value))
This diff is collapsed.
P3
# The P3 means colors are in ASCII, then 3 columns and 2 rows,
# then 255 for max color, then RGB triplets
3 2
255
255 0 0 0 255 0 0 0 255
255 255 0 255 255 255 0 0 0
xgCVx
\ No newline at end of file
/*
Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
See file LICENSE.txt for further informations on licensing terms.
formatted using the GNU C formatting and indenting
*/
/*
* TODO: use Program Control to load stored profiles from EEPROM
*/
#include <Servo.h>
#include <Firmata.h>
/*==============================================================================
* GLOBAL VARIABLES
*============================================================================*/
/* analog inputs */
int analogInputsToReport = 0; // bitwise array to store pin reporting
/* digital input ports */
byte reportPINs[TOTAL_PORTS]; // 1 = report this port, 0 = silence
byte previousPINs[TOTAL_PORTS]; // previous 8 bits sent
/* pins configuration */
byte pinConfig[TOTAL_PINS]; // configuration of every pin
byte portConfigInputs[TOTAL_PORTS]; // each bit: 1 = pin in INPUT, 0 = anything else
int pinState[TOTAL_PINS]; // any value that has been written
/* timer variables */
unsigned long currentMillis; // store the current value from millis()
unsigned long previousMillis; // for comparison with currentMillis
int samplingInterval = 100; // how often to run the main loop (in ms)
Servo servos[MAX_SERVOS];
/*==============================================================================
* FUNCTIONS
*============================================================================*/
void outputPort(byte portNumber, byte portValue, byte forceSend)
{
// pins not configured as INPUT are cleared to zeros
portValue = portValue & portConfigInputs[portNumber];
// only send if the value is different than previously sent
if(forceSend || previousPINs[portNumber] != portValue) {
Firmata.sendDigitalPort(portNumber, portValue);
previousPINs[portNumber] = portValue;
}
}
/* -----------------------------------------------------------------------------
* check all the active digital inputs for change of state, then add any events
* to the Serial output queue using Serial.print() */
void checkDigitalInputs(void)
{
/* Using non-looping code allows constants to be given to readPort().
* The compiler will apply substantial optimizations if the inputs
* to readPort() are compile-time constants. */
if (TOTAL_PORTS > 0 && reportPINs[0]) outputPort(0, readPort(0, portConfigInputs[0]), false);
if (TOTAL_PORTS > 1 && reportPINs[1]) outputPort(1, readPort(1, portConfigInputs[1]), false);
if (TOTAL_PORTS > 2 && reportPINs[2]) outputPort(2, readPort(2, portConfigInputs[2]), false);
if (TOTAL_PORTS > 3 && reportPINs[3]) outputPort(3, readPort(3, portConfigInputs[3]), false);
if (TOTAL_PORTS > 4 && reportPINs[4]) outputPort(4, readPort(4, portConfigInputs[4]), false);
if (TOTAL_PORTS > 5 && reportPINs[5]) outputPort(5, readPort(5, portConfigInputs[5]), false);
if (TOTAL_PORTS > 6 && reportPINs[6]) outputPort(6, readPort(6, portConfigInputs[6]), false);
if (TOTAL_PORTS > 7 && reportPINs[7]) outputPort(7, readPort(7, portConfigInputs[7]), false);
if (TOTAL_PORTS > 8 && reportPINs[8]) outputPort(8, readPort(8, portConfigInputs[8]), false);
if (TOTAL_PORTS > 9 && reportPINs[9]) outputPort(9, readPort(9, portConfigInputs[9]), false);
if (TOTAL_PORTS > 10 && reportPINs[10]) outputPort(10, readPort(10, portConfigInputs[10]), false);
if (TOTAL_PORTS > 11 && reportPINs[11]) outputPort(11, readPort(11, portConfigInputs[11]), false);
if (TOTAL_PORTS > 12 && reportPINs[12]) outputPort(12, readPort(12, portConfigInputs[12]), false);
if (TOTAL_PORTS > 13 && reportPINs[13]) outputPort(13, readPort(13, portConfigInputs[13]), false);
if (TOTAL_PORTS > 14 && reportPINs[14]) outputPort(14, readPort(14, portConfigInputs[14]), false);
if (TOTAL_PORTS > 15 && reportPINs[15]) outputPort(15, readPort(15, portConfigInputs[15]), false);
}
// -----------------------------------------------------------------------------
/* sets the pin mode to the correct state and sets the relevant bits in the
* two bit-arrays that track Digital I/O and PWM status
*/
void setPinModeCallback(byte pin, int mode)
{
if (IS_PIN_SERVO(pin) && mode != SERVO && servos[PIN_TO_SERVO(pin)].attached()) {
servos[PIN_TO_SERVO(pin)].detach();
}
if (IS_PIN_ANALOG(pin)) {
reportAnalogCallback(PIN_TO_ANALOG(pin), mode == ANALOG ? 1 : 0); // turn on/off reporting
}
if (IS_PIN_DIGITAL(pin)) {
if (mode == INPUT) {
portConfigInputs[pin/8] |= (1 << (pin & 7));
} else {
portConfigInputs[pin/8] &= ~(1 << (pin & 7));
}
}
pinState[pin] = 0;
switch(mode) {
case ANALOG:
if (IS_PIN_ANALOG(pin)) {
if (IS_PIN_DIGITAL(pin)) {
pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver
digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
}
pinConfig[pin] = ANALOG;
}
break;
case INPUT:
if (IS_PIN_DIGITAL(pin)) {
pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver
digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
pinConfig[pin] = INPUT;
}
break;
case OUTPUT:
if (IS_PIN_DIGITAL(pin)) {
digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable PWM
pinMode(PIN_TO_DIGITAL(pin), OUTPUT);
pinConfig[pin] = OUTPUT;
}
break;
case PWM:
if (IS_PIN_PWM(pin)) {
pinMode(PIN_TO_PWM(pin), OUTPUT);
analogWrite(PIN_TO_PWM(pin), 0);
pinConfig[pin] = PWM;
}
break;
case SERVO:
if (IS_PIN_SERVO(pin)) {
pinConfig[pin] = SERVO;
if (!servos[PIN_TO_SERVO(pin)].attached()) {
servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin));
} else {
Firmata.sendString("Servo only on pins from 2 to 13");
}
}
break;