paper speakers

here's some technical information on a collaboration with visual artist Jenny Michel. it's an sounding art installation that has previously been shown at galerie feldbuschwiesner and städtische galerie wolfsburg, and is now (sept2016) up and running at smac project space in berlin.

'traps', as the piece is called, consists of speakers made out of paper and enameled copper wire. the wire is embedded into the paper in the shape of a coil and two strong magnets are situated on the back. the paper is manually layered and filled with prints and later perforated with cutouts. behind the paper is also a small circuit with a microcontroller, an amplifier and an antenna - all hand soldered dead-bug style. power comes from a shared 5v wall adapter.

traps consists of around 30 individual speakers and they all react on each other via their antennas. they also pick up different electromagnetic fields - but we can't say in exactly which frequency range they are sensitive as the antennas are made with arbitrary lengths and shapes (they're also copper wire).

the sound is synthesized with the microcontroller (attiny45). loudness and quality varies depending on the shape of the speakers - they're all individual - but in general the resulting sounds are quite noisy and piercing. the code was written to create a lot of variation and not just sonify the raw antenna input. so it's more of an interpretation than a direct translation of trapped radio frequency signals to sound as we first had planned. we also wanted harsher electronic sounds as it both fits better with the visual impression and that that type of square wave audio work very well in these non-linear lo-fi speakers.

there are also two modes: if one quickly turn the power on-off-on, the installation will start in 'vernissage mode' and play more sound than if one just turn the power on as normal (look for the eeprom part in the code below to see how it works more in detail).

in total we built 50 circuits and many more paper speakers. though ~30 are enough to fill medium sized gallery.





here's the code...

//f.olofsson 2015-2016
//select ATtiny, 1MHz (internal)
//decreased durMax in two places from 80000 to 8000

#include <EEPROM.h>

int durPause;
unsigned long durMax;
byte pausePer;
void setup() {
  randomSeed(analogRead(3));
  pinMode(4, OUTPUT);
  byte magic = EEPROM.read(0);
  if (magic == 123) { //lots of sound - chaotic opening mode
    durPause = 15000;
    durMax = 8000;
    pausePer = 67;  //percentage
    for (byte i = 0; i < 3; i++) {  //beep three times at startup
      prgStatic(100);
      prgPause(100);
    }
  } else {  //default - soft gallery mode
    durPause = 30000;
    durMax = 8000;
    pausePer = 75;  //percentage
    EEPROM.write(0, 123);
    delay(3000);  //power on for <3sec & then next time mode 1
    prgStatic(1500);  //make a tone at startup to know all working
  }
  EEPROM.write(0, 255);
}
void loop() {
  prgNoise(analogRead(3));
  if (random(100) < pausePer) {
    prgPause(durPause);
  } else {
    unsigned long dur = random(durMax);
    switch (analogRead(3) % 7) {
      case 0:
        prgPause(dur);
        break;
      case 1:
        prgNoise(dur);
        break;
      case 2:
        prgNoise(dur);
        break;
      case 3:
        prgChunks(dur);
        break;
      case 4:
        prgChunks(dur);
        break;
      case 5:
        prgBitbang(dur);
        break;
      case 6:
        prgImpulses(dur);
        break;
    }
  }
}
void prgPause(unsigned long dur) {
  analogWrite(4, 0);
  pinMode(0, OUTPUT);
  digitalWrite(0, 0);
  delay(dur);
  pinMode(0, INPUT);
}
void prgStatic(int dur) {
  analogWrite(4, 127);
  delay(dur);
}
void prgNoise(unsigned long dur) {
  unsigned long stamp = millis();
  while (millis() - stamp < dur) {
    analogWrite(4, analogRead(3) >> 2);
  }
}
void prgNoise2(unsigned long dur) {
  unsigned long stamp = millis();
  while (millis() - stamp < dur) {
    analogWrite(4, analogRead(3) >> 2);
    delay(1);
  }
}
void prgChunks(unsigned long dur) {
  unsigned long stamp = millis();
  byte base = (analogRead(3) >> 10) * 255; //either 0 or 255
  while (millis() - stamp < dur) {
    int val = analogRead(3);
    analogWrite(4, val >> 2);
    delay(val);
  }
}
void prgChunks2(unsigned long dur) {
  unsigned long stamp = millis();
  byte base = (analogRead(3) >> 10) * 255; //either 0 or 255
  while (millis() - stamp < dur) {
    int val = analogRead(3);
    analogWrite(4, val >> 2);
    delay(val / 2);
    analogWrite(4, base);
    delay(val / 2);
  }
}
void prgBitbang(unsigned long dur) {
  unsigned long stamp = millis();
  while (millis() - stamp < dur) {
    int val = analogRead(3 >> 2);
    for (byte i = 0; i < 8; i++) {
      digitalWrite(4, val >> i & 1);
    }
  }
}
void prgImpulses(unsigned long dur) {
  unsigned long stamp = millis();
  while (millis() - stamp < dur) {
    int val = analogRead(3);
    digitalWrite(4, 1);
    digitalWrite(4, 0);
    delay(val);
  }
}

note the use of the lm386 n-4. it is more powerful than the n1, n3 variants.