Showing posts with label Programming. Show all posts
Showing posts with label Programming. Show all posts

Friday, 29 January 2010

Hero Code

After creating my program, I encountered some small problems regarding refreshing web feeds. I posted the problem & my code on the Processing forum & one of the other members made me a completely new program that works better than I could ever imagine! After tinkering with the code to work seamlessly with Arduino, I have got my finished code:

import processing.video.*; // import theProcessing video library
import processing.serial.*; // import the Processing serial library

static final boolean USE_ARDUINO = true;

static final boolean USE_WEBCAM = false;
static final String WEBCAM_STRING = "USB PC Camera-WDM";

static final int MAX_LOAD_ATTEMPTS = 15; // Number of times to try loading a web image

static final String[] feedSetup = new String[] {
"Adelaide Market Observer", "http://www.adelaidecitycouncil.com/netcatapps/webcam/images/centralMkt.jpg", // Adelaide Market
"Vancouver Observer", "http://www.cbc.ca/bc/webcam/images/webcam.jpg", // Vancouver Building Site
"Adelaide Lantern Observer", "http://www.adelaidecitycouncil.com/netcatapps/webcam/images/rundleEast.jpg", // Rundle Mall East & Lantern
"Colony Observer", "http://www.draperbee.com/webcam/pic/image.jpg?1262444320177", // Beehive
"Adelaide 3 Observer", "http://www.adelaidecitycouncil.com/NetcatApps/webcam/images/bellsth.jpg", // Adelaide Bell Street South
"Aruba Observer", "http://www.bucuticam.com/arubacam.jpg", //Aruba, Netherlands Antilles
"Turtle Dome Observer", "http://www.yosemite.org/DSN/wwwyosemiteassociationorg/Content/Webcam/turtleback.jpg", //Yosemite, Turtle Dome
"Brooklyn Bridge Observer", "http://brooklyn-bridge.mobotixcam.de/record/current.jpg?rand=380424", //Brooklyn Bridge
"Bass Rock Observer", "http://www.outercam.co.uk/ssc/camera3.jpg?1260446915311", // Bass Rock, North Berwick
"Bar Observer", "http://ecoast.vs.oiccam.com:443/ftp/capcom/jackalope/image.jpg?rand=14:52:10", //Jackalope Jacks Bar, North Carolina
"Panama Canal Observer", "http://webcams.pancanal.com/webcam/miraflores.jpg", // Panama Canal
"Dundee Satellite Observer", "http://www.sat.dundee.ac.uk/webcam/cam0.jpg", //Dundee Tower Building
"Living Room Observer", "http://www.xs4all.nl/~twocats/cam/Cam-A.jpg", //Amsterdam House
"Ablerta University Observer", "http://www.cs.ualberta.ca/~lake/cam/jpg/large/201.jpg", //Alberta University
"Drama Observer", "http://facweb.furman.edu/~rbryson/dramadept/TheatreCamPic.jpg", //Student Theatre
};

Serial Arduino; // The serial port

//boolean onoff = true; // Display the local webcam?

PFont font; // Description text font

// Feeds, current feed index and reference for current feed (from the ArrayList)
private ArrayList feeds;
int feedIndex; // Current feed index
int camIndex = -1; // Index of cam (if available)
Feed currentFeed;

float xpos, ypos, onoff; // Starting position of the webcam feed
float specialWidth = 1450.0;

float scrollOffset = 0; // Text scrolling offset
float scrollSpeed = 3; // Text scrolling speed

int scrolltext;

long clock; // Realtime clock in milliseconds, based on millis(), updated in ticktock()

void setup()
{
ticktock();

size(1050,760,P3D);

font = loadFont("Consolas-36.vlw");
textFont(font, 36);

if (USE_ARDUINO && !online)
{
// List all the available serial ports
println(Serial.list());

Arduino = new Serial(this, Serial.list()[1], 9600);

// read bytes into a buffer until you get a linefeed (ASCII 10):
Arduino.bufferUntil('\n');
}

feeds = new ArrayList();

if (USE_WEBCAM && !online) try
{
// List all the available cameras
println(Capture.list());
CaptureFeed captureFeed = new CaptureFeed(this, "Camera One", WEBCAM_STRING, width/2, height/2, 30);
camIndex = feeds.size();
feeds.add(captureFeed);
}
catch (Exception e)
{
println("Error initialising webcam (" + WEBCAM_STRING + "): " + e.getMessage());
}

// Set up web feeds
for (int i = 0; i <>
{
Feed feed = new WebFeed(feedSetup[i], feedSetup[i+1]);
feeds.add(feed);
}

selectFeed(0); // Maybe webcam
}

void draw()
{
ticktock();

background(0);
rotate(-PI/2);

scrollOffset += scrollSpeed;
if (scrollOffset > width + specialWidth)
{
scrollOffset = 0;
}

currentFeed.update();
currentFeed.display();

if(onoff == 0){
background(0);
}
}

public void ticktock()
{
clock = millis();
}

void serialEvent(Serial Arduino)
{
// Read the serial buffer:
String myString = Arduino.readStringUntil('\n');
// if you got any bytes other than the linefeed:
if (myString != null){

myString = trim(myString);

// split the string at the commas
// and convert the sections into integers:
int sensor[] = int(split(myString, ','));

// print out the values you got:
for (int sensorNum = 0; sensorNum <>
print("sensor " + sensorNum + ": " + sensor[sensorNum] + "\t");
}
// add a linefeed after all the sensor values are printed:
println();
if (sensor.length > 1){
xpos = map(sensor[0], 0, 1023, -width/2, -(width/4)*3);
ypos = map(sensor[1], 0, 1023, 0, (height- 150 - height/2));
int feedSelection = constrain((int)map(sensor[2], 0, 1023, 0, feeds.size() - 1), 0, feeds.size() - 1);
selectFeed(feedSelection);
onoff = map(sensor[3], 0, 1, 0, 1);

if (onoff == 1)
{
selectFeed(camIndex);
}

scrolltext = (int)map(sensor[4], 0, 1023, 0, currentFeed.description.length() - 1);
}
}
}


void displayScrollText(String displayText)
{
text(displayText, width - scrollOffset, height + 200);
}

public void selectFeed(int feedSelection)
{
if (feedSelection <>= feeds.size())
{
println("Cannot select feedIndex " + feedSelection);
return;
}

feedIndex = feedSelection;
currentFeed = (Feed)feeds.get(feedIndex);
}

//============================================================

/**
* Feed class
* Contains feed metadata (description and locator) and
* proscription for update() and display() methods in subclasses
*/

abstract class Feed
{
public String description;
public String locator;

public Feed(String description, String locator)
{
this.description = description;
this.locator = locator;
}

public abstract void update(); // Must be implemented in subclasses
public abstract void display(); // Must be implemented in subclasses
}

//============================================================

/**
* WebFeed class
* Access periodically-updated image from the web
* Load image in separate thread so as not to block main thread
* Delayed refresh (after error or sucessful load)
*/

class WebFeed extends Feed
{
public int refreshDelay = 2000; // Number of milliseconds to wait between refresh() calls
public PImage loadedImage; // Last loaded image

private PImage loadingImage; // Used for requestImage()
private boolean loading; // Waiting for result from requestImage()?
private boolean requestRefresh; // Set true when a refresh() is wanted
private long refreshAt; // Time (based on millis()) at which to refresh() if requestRefresh true
private int loadFailures; // Number of times the load has failed (since last successful load)

public WebFeed(String description, String locator)
{
super(description, locator);
println("new WebFeed(" + description + ", " + locator + ")");
loadedImage = null;
refresh();
}

public void update()
{
if (loading)
{
if (loadingImage.width == 0)
{
// Image is not yet loaded
}
else if (loadingImage.width == -1)
{
// This means an error occurred during image loading
println("requestImage() failed for " + description + " [" + locator + "]");
loading = false;
loadFailures++;
if (loadFailures <>
{
requestRefresh();
}
}
else
{
// Image is loaded; save a copy and request a fresh copy
println("Loaded: " + description);
loadedImage = loadingImage;
loading = false;
loadFailures = 0;

requestRefresh();
}
}

if (requestRefresh && clock >= refreshAt)
{
refresh();
}
}

public void requestRefresh()
{
requestRefresh = true;
refreshAt = clock + refreshDelay;
println("refreshAt: " + refreshAt + " (now: " + clock + ")");
}

public void refresh()
{
println("Refresh " + description + " [" + locator + "]");
loadingImage = requestImage(locator);
loading = true;
requestRefresh = false;
}

public void display()
{
if (loadedImage == null)
{
displayScrollText(description + " LOADING...");
}
else
{
image(loadedImage, xpos, ypos, width/2, height/2);
displayScrollText(description + " ONLINE");
}
}
}

//============================================================

class CaptureFeed extends Feed
{
public Capture capture; // A local webcam

public CaptureFeed(PApplet p5, String description, String locator, int feedWidth, int feedHeight, int fps)
{
super(description, locator);
capture = new Capture(p5, feedWidth, feedHeight, locator, fps);
}

public void update()
{
if (capture.available())
{
capture.read();
}
}

public void display()
{
image(capture, xpos, ypos);
displayScrollText(description + " LIVE");
}
}

Wednesday, 27 January 2010

Code Development

To tie in with my revised rational, I have changed my Processing code, so you can turn on the system, change between manually placed webcams & cameras on the internet, select a certain feed & move the image about on the screen all through inputs from Arduino.

import processing.video.*; // import theProcessing video library
import processing.serial.*; // import the Processing serial library
Serial Arduino; // The serial port
Capture webCamOne; // The webcam feed
Capture webCamTwo;
PFont font;

float xpos, ypos, manualauto, x; // Starting position of the webcam feed
int autoselect, manualselect;
float size = 700.0;

String[] feed = new String[] {
"http://www.adelaidecitycouncil.com/netcatapps/webcam/images/centralMkt.jpg", //Adelaide Market
"http://www.cbc.ca/bc/webcam/images/webcam.jpg", // Vancouver Building Site
"http://www.adelaidecitycouncil.com/netcatapps/webcam/images/rundleEast.jpg", //Rundle Mall East & Lantern
"http://www.draperbee.com/webcam/pic/image.jpg?1262444320177", //beehive
"http://www.adelaidecitycouncil.com//NetcatApps/webcam/images/bellsth.jpg" //Adelaide Bell Street South
};

String[] description = new String[]{
"Adelaide 1 Observer ONLINE",
"Vancouver Observer ONLINE",
"Adelaide 2 Observer ONLINE",
"Colony Observer ONLINE",
"Adelaide 3 Observer ONLINE",
};
PImage[] images;

void setup() {
size(678,510,P3D);

font = loadFont("01_Digit-23.vlw");
textFont(font, 23);
// List all the available serial ports & cameras
//println(Serial.list());
println(Capture.list());

webCamOne = new Capture(this, width/2, height/2, "USB PC Camera-WDM", 30);
webCamTwo = new Capture(this, width/2, height/2, "PC Camer@-WDM", 30);

Arduino = new Serial(this, Serial.list()[1], 9600);

// read bytes into a buffer until you get a linefeed (ASCII 10):
Arduino.bufferUntil('\n');

/ need as many images as we have feeds
images = new PImage[feed.length];
// initial load of images (slow);
for (int i = 0 ; i <>
images[i] = loadImage(feed[i]);
}
}

void draw() {
background(0);
if (manualauto == 1){
if (manualselect == 0){
if (webCamOne.available()){
webCamOne.read();
}
image(webCamOne, xpos, ypos);
translate(-x, 0, 0);
text("OBSERVER 1 ONLINE", 0, 494);
}
if (manualselect == 1){
if (webCamTwo.available()){
webCamTwo.read();
}
image(webCamTwo, xpos, ypos);
translate(-x, 0, 0);
text("OBSERVER 2 ONLINE", 0, 494);
}
if (manualselect == 2){
translate(-x, 0, 0);
text("OBSERVER 3 OFFLINE", 0, 494);
}
}
else{
loadImage(feed[autoselect]);
image(images[autoselect], xpos, ypos, width/2, height/2);
translate(-x, 0, 0);
text(description[autoselect], 0, 494);
}

x = x +3;
if (x > width + size){
x = -size;
}
}


void serialEvent(Serial Arduino) {
// read the serial buffer:
String myString = Arduino.readStringUntil('\n');
// if you got any bytes other than the linefeed:
if (myString != null) {

myString = trim(myString);

// split the string at the commas
// and convert the sections into integers:
int sensor[] = int(split(myString, ','));

// print out the values you got:
for (int sensorNum = 0; sensorNum <>
print("sensor " + sensorNum + ": " + sensor[sensorNum] + "\t");
}
// add a linefeed after all the sensor values are printed:
println();
if (sensor.length > 1) {
xpos = map(sensor[0], 0, 1023, 0, width/2);
ypos = map(sensor[1], 0, 1023, 0, (height/2 - 50));
autoselect = (int)map(sensor[2], 0, 1023, 0, images.length - 1);
manualauto = map(sensor[3], 0, 1, 0, 1);
manualselect = (int)map(sensor[4], 0, 1023, 0, 2);
}
}
}

Wednesday, 20 January 2010

Directives

The whole point of the Mass Observation is to respond to "directives" - a series of questions or topics for the observers to record. I have created a small code that scrolls this information across the screen to constantly remind the observer of what their objective is:

PFont font;
float x;
float size = 430.0;
// The font must be located in the sketch's
// "data" directory to load successfully
void setup(){
size(600, 100, P3D);

font = loadFont("SubwayTicker-32.vlw");
textFont(font, 23);
}

void draw(){
background(0);
x = x +3;
if (x > width + size){
x = -size;
}

translate(x, 0, 12);
text("Directive 1: Mid-life transitions", 0, 44);

}

The only problem with the Mass Observation is that the topics are very broad & not a lot of deliberate observation is needed, mostly past experiences. I want the user to interact with the object as if it is necessary for the completion of the "mission". Maybe the content of the directives need to be customised...

The code so far...

Here is the Arduino & Processing code for the system below:

Arduino:

int potpinx = 0; //analog input
int potpiny = 1; //analog input
int potpinzoom = 2; //analog input
int onoff = 3; //digital input
int scroll = 5; //analog input
int onoffled = 13; // digital output

int sensorValue = 0; //analog value
int onoffvalue = 0; //digital value

void setup() {
// configure the serial connection:
Serial.begin(9600);
// configure the digital input
pinMode(onoff, INPUT);
// configure the digital output
pinMode(onoffled, OUTPUT);
}

void loop() {
// read the sensor:
sensorValue = analogRead(potpinx);
// print the results:
Serial.print(sensorValue, DEC);
Serial.print(",");

// read the sensor:
sensorValue = analogRead(potpiny);
// print the results:
Serial.print(sensorValue, DEC);
Serial.print(",");

// read the sensor:
sensorValue = analogRead(potpinzoom);
// print the results:
Serial.print(sensorValue, DEC);
Serial.print(",");

// read the sensor:
sensorValue = digitalRead(onoff);
Serial.print(sensorValue, DEC);
Serial.print(",");

//read the sensor:
sensorValue = analogRead(scroll);
Serial.println(sensorValue/255, DEC);

delay(90);

//read the onoff switch again & assign the output as a different name
onoffvalue = digitalRead(onoff);

//if the digital switch is in the on position, turn on the led
if (onoffvalue == HIGH){
digitalWrite(onoffled, HIGH);
}
else{
digitalWrite(onoffled, LOW);
}
}


Processing:

import processing.video.*; // import theProcessing video library
import processing.serial.*; // import the Processing serial library
Serial Arduino; // The serial port
Capture webCam; // The webcam feed
PImage hide; //Declare variable "hide" of type PImage

float xpos, ypos, zoom, onoff; // Starting position of the webcam feed

void setup() {
size(640,480,P3D);

// List all the available serial ports & cameras
//println(Serial.list());
//println(Capture.list());

webCam = new Capture(this, width/2, height/2, "USB PC Camera-WDM", 30);
Arduino = new Serial(this, Serial.list()[1], 9600);

// read bytes into a buffer until you get a linefeed (ASCII 10):
Arduino.bufferUntil('\n');

}

void draw() {
background(153, 153, 0);
scale(zoom/100);
if (webCam.available()){
webCam.read();
}
if (onoff == 1){
image(webCam, xpos, ypos);
}
}

void serialEvent(Serial Arduino) {
// read the serial buffer:
String myString = Arduino.readStringUntil('\n');
// if you got any bytes other than the linefeed:
if (myString != null) {

myString = trim(myString);

// split the string at the commas
// and convert the sections into integers:
int sensor[] = int(split(myString, ','));

// print out the values you got:
for (int sensorNum = 0; sensorNum <>
print("sensor " + sensorNum + ": " + sensor[sensorNum] + "\t");
}
// add a linefeed after all the sensor values are printed:
println();
if (sensor.length > 1) {
xpos = map(sensor[0], 0,width,0,width);
ypos = map(sensor[1], 0,height,0,height);
zoom = map(sensor[2], 1, 1023, 1, 1023);
onoff = map(sensor[3], 0, 1, 0, 1);
}
}
}


New Interactions



As I want some of the interactions of my product to be microscope-ish, I wanted to use potentiometers to control some aspects of the image on screen - such as moving the feed on the x & y axis, & changing the scale of the picture (as well as turning the feed on & off).

Instead of using Pure Data as I originally thought, I have managed to use an Arduino board & Processing. The video of the system working is below:


Wednesday, 6 January 2010

New Interaction Screen Shots

The first set of "generic" camera feeds.

When the button is pressed the second set of webcamera feeds appear.

New Interaction

To coincide with the revelation of using fewer cameras, I have created a simple interaction for people who don't want their content to be discovered - through using a simple switch.

The idea is:
there are a set of generic images (say beach views) being displayed constantly on the screen, but when you want to begin spying on who/whatever, you press a hidden button somewhere on the device to activate those feeds. This should keep your secret a secret (at least for a while...).

So far I have made a code that does such a thing, using some feeds from the other programs:

public static final int NROWS = 1;
public static final int NCOLS = 3;

//List of cameras
String[] goodfeed = new String[3];{
goodfeed[0] = "http://www.coast.ag/webcam/cruise.jpg";
goodfeed[1] = "http://www.st-barths.com/a_cam/view1.jpg";
goodfeed[2] = "http://webcam.raservice.com/cam.jpg";
};

String[] badfeed = new String[3];{
badfeed[0] = "http://brooklyn-bridge.mobotixcam.de/record/current.jpg?rand=380424";
badfeed[1] = "http://stjohnspice.com/spicecam1.jpg";
badfeed[2] = "http://abclocal.go.com/three/kabc/webcam/web1-1.jpg";
};

PImage[] images;

void setup(){
size(1200, 440);
images = new PImage[goodfeed.length];
for (int i = 0 ; i <>
images[i] = loadImage(goodfeed[i]);
}

images = new PImage[badfeed.length];
for (int i = 0 ; i <>
images[i] = loadImage(badfeed[i]);
}
}

void draw(){
int index = 0;
for (int y = 0 ; y <>
for (int x = 0 ; x <>
image(images[index], x * (width / NCOLS), y * (height / NROWS), (width / NCOLS), (height / NROWS));
index++;
}
}

if(keyPressed) {
if (key == 'b' || key == 'B') {
for (int i = 0 ; i <>
images[i] = loadImage(goodfeed[i]);
}

delay(1000);
}
} else {
for (int i = 0 ; i <>
images[i] = loadImage(badfeed[i]);
}
}

}


Sunday, 3 January 2010

A Quick Look


Here's what 30 feeds looks like.

The Extreme Limits!

For the past couple of weeks I have been continuously working on the code & hassling people on the Processing website to allow the number of webcam feeds & the speed of refreshing increases.
Behold! 30 different feeds with a refresh rate of one random feed every two seconds. This modified code allows more efficient loading of feeds without frying the program:

public static final int NROWS = 5;
public static final int NCOLS = 6;

// list of cameras
String[] feeds = {
"http://www.adelaidecitycouncil.com/netcatapps/webcam/images/centralMkt.jpg", //Adelaide Market
"http://www.cbc.ca/bc/webcam/images/webcam.jpg", // Vancouver Building Site
"http://www.adelaidecitycouncil.com/netcatapps/webcam/images/rundleEast.jpg", //Rundle Mall East & Lantern
"http://www.draperbee.com/webcam/pic/image.jpg?1262444320177", //beehive
//"http://www.aad.gov.au/asset/webcams/casey/small/C0912121710s.jpg", //Antarctica Davis Station
"http://www.adelaidecitycouncil.com//NetcatApps/webcam/images/bellsth.jpg", //Adelaide Bell Street South
"http://www.abbeyroad.com/webcam/crossing.jpg?cacheKiller=362683", //Abbey Road
"http://server.fishycam.com/fishycam.jpg?time=1260184950863", //Fish Tank Goldfish
"http://www.cph.dk/CPHdata/webcam/CPH_spot1.jpg?1260188477647", //Copenhagen Airport
"http://www.adelaidecitycouncil.com/netcatapps/webcam/images/rundle.jpg", //Rundle Mall Balls
"http://images.ibsys.com/sea/images/weather/auto/queenannecam_640x480.jpg?", //Seattle Skyline
"http://www.pani.com/webcam/airport_tower.jpg?", //German Airport Tower
"http://www.rrtearoom.com/live.jpg",// Psychic Tearoom Massachusetts
"http://www.camchickens.com/webcam.jpg", // Amsterdam Chickens
"http://www.terrapin-gardens.net/images/webcam.jpg",// House Vermont
"http://stream.fisheyeview.com/FVCam.jpg",// Coral Reef
"http://www.cs.ualberta.ca/~lake/cam/jpg/large/201.jpg",//Alberta University
"http://webcams.pancanal.com/webcam/miraflores.jpg", // Panama Canal
"http://www.oceanvillageholidays.co.uk/webcam/ov1.jpg", //Ferry
"http://brooklyn-bridge.mobotixcam.de/record/current.jpg?rand=380424",//Brooklyn Bridge
"http://www.outercam.co.uk/ssc/camera3.jpg?1260446915311",//Bass Rock
"http://www.xs4all.nl/~twocats/cam/Cam-A.jpg",// Cats
"http://www.sat.dundee.ac.uk/webcam/cam0.jpg",//Dundee Uni Tower Building
"http://facweb.furman.edu/~rbryson/dramadept/TheatreCamPic.jpg", // Student Theatre
"http://www.adelaidecitycouncil.com//NetcatApps/webcam/images/bellnth.jpg",// Adelaide King William Street
"http://www.outercam.co.uk/ssc/camera2.jpg?1260455145216",// North Berwick Bird Feeder
"http://www.jb.man.ac.uk/common/camera30sec.jpg?dummy=1260456117729",//Lovell Telescope
"http://ecoast.vs.oiccam.com:443/ftp/capcom/jackalope/image.jpg?rand=14:52:10",//Jackalope Jacks Bar North Carolina
"http://www.yosemite.org/DSN/wwwyosemiteassociationorg/Content/Webcam/turtleback.jpg",//Yosemite Turtle Dome
"http://www.ek.fi/kamera/tn_palace00.jpg", //Helsinki Market Place
"http://www.electricearl.com/LAcam-2009c.jpg" // Downtown LA
// more here...
};
PImage[] images;

void setup(){
size(1280, 800);
// need as many images as we have feeds
images = new PImage[feeds.length];
// initial load of images (slow)
for (int i = 0 ; i <>
images[i] = loadImage(feeds[i]);
}
}

void draw(){
// draw grid
int index = 0;
for (int y = 0 ; y <>
for (int x = 0 ; x <>
image(images[index], x * (width / NCOLS), y * (height / NROWS), (width / NCOLS), (height / NROWS));
index++;
}
}

// update a random image
int i = (int)random(feeds.length);
images[i] = loadImage(feeds[i]);

// sleep
delay(2000);
}

Wednesday, 9 December 2009

The Limits...


I have found the limits of how many feeds you can clearly see on my screen & the answer is...
20! I can get a 5x4 grid of feeds on my computer screen which are big enough to understand what is being seen. I just need to find 8 extra feeds now!

Monday, 7 December 2009

Button Test

A cheeky little vid to show the system working.

Everywhere

I've managed to combine 8 web feeds with my 3 webcams to get a grid of 11 showing different place around the world - from Adelaide to Copenhagen! Here's a screenshot:


The only problem with this is that the whole programme slows down, including my webcams, to around 1 frame every 3 seconds...

Around the world!

After speaking to some people on the Processing website, asking if I could stream live feeds from the internet, they said no - but only to movie files, not jpegs that refresh every couple of seconds on the web page. I just had to write a simple programme that tells processing to look for the exact picture - simple! It's not the smoothest thing in the world, but it works. The best feed I could find so far is from the Brooklyn Bridge that refreshes the picture every second. To view it just copy & paste this code into a processing application:

PImage a; // Declare variable "a" of type PImage

void setup() {
frameRate(1);
size(1024, 768);
}

void draw() {
// Displays the image at its actual size at point (0,0)
a = loadImage("http://brooklyn-bridge.mobotixcam.de/record/current.jpg?rand=380424");
image(a, 0, 0);


}

Making Noise

After talking to Jon about my progress, he thought that I should explore the receiving end of the system - the people who are being looked at & ways they could become aware of someone watching them. So to do this, I am playing around with sounds - when an individual peephole is activated, the corresponding webcam makes a sound.

Currently the sounds are limited to being played off my computer (each alert is controlled from a different mouse button) & the sounds are from Metal Gear Solid, but hopefully I'll be able to play them in separate speakers.

"Hears" the code:

import ddf.minim.*;

AudioPlayer leave;
AudioPlayer codeccall;
AudioPlayer alert;
Minim minim;

void setup()
{
size(200, 200);

minim = new Minim(this);

// load a file, give the AudioPlayer buffers that are 1024 samples long
// player = minim.loadFile("found.wav");

// load a file, give the AudioPlayer buffers that are 2048 samples long
alert = minim.loadFile("found.wav", 2048);
codeccall = minim.loadFile("codeccall.wav", 2048);
leave = minim.loadFile("leave.wav", 2048);
// play the file

}

void draw()
{
background(0);

if((mousePressed)&& (mouseButton == RIGHT)){
alert.play();
alert.rewind();
delay (1000);
}

if((mousePressed)&& (mouseButton == LEFT)){
codeccall.play();
codeccall.rewind();
delay (1000);
}

if((mousePressed)&& (mouseButton == CENTER)){
leave.play();
leave.rewind();
delay (1000);
}
}

Sunday, 29 November 2009

The System Works!

After playing around with Processing for a few days with no success - trying to make webcam feeds appear when a certain switch is activated - I finally got my eureka moment! Instead of making a singular feed appear on the screen when a button is pressed, I could have all three feeds on at the same time, making two disappear (covering them with squares that are the same colour as the background) leaving a certain one on the screen - simple! The code for this program is below:

import processing.video.*;

Capture camera;
Capture camera2;
Capture camera3;

void setup()
{
size(1010, 730);
int value = 0;
// List all available capture devices to the console
// Use the information printed to the text area to
// correctly set the variable "s" below
println(Capture.list());

// Specify your own device by the name of the capture
// device returned from the Capture.list() function
camera = new Capture(this, width/3, height/3, "USB PC Camera-WDM");
camera2 = new Capture(this, width/3, height/3, "PC Camer@-WDM");
camera3 = new Capture(this, width/3, height/3, "Labtec WebCam-WDM");
// If no device is specified, will just use the default
//camera = new Capture(this, 320, 240, 12);

// Opens the settings page for this capture device
//camera.settings();
}


void captureEvent(Capture camera)
{
camera.read();
}

void draw()
{
image(camera, width/3, height/3);
image(camera2, 0, height/3);
image(camera3, 671, height/3);


if (keyPressed){
if (key == 'b' || key == 'B'){
rect(0, 0, width/3, height);
fill(0);
rect(width/3, 0, width/3, height);
fill(0);
}
}
if (keyPressed){
if (key =='t' || key == 'T'){
rect(width/3, 0, width/3, height);
fill(0);
rect(671, 0, width/3, height);
fill(0);
}
}
if (keyPressed){
{if (key == 'g' || key == 'G'){
rect(671, 0, width/3, height);
fill(0);
rect(0, 0, width/3, height);
fill(0);
}
}


}
}

The code is still a work in progress - trying to make it more slimline & efficient, but it works!
The screen shots are below.