Raspberry PI Piano

c++, socket, multithread clojure, overtone, raspberry,gpio, touch-sensor, overtone, wiringPi

How It Works

Server

Here we load overtone, and create listen socket. Server side Server reads one int from socket and plays it through overtone piano sintezator. Because of my needs, here is a tricky way for converting int to piano beep. For integers in range [0..6] will played C4 octave, more than 6 will played C3 octave.
  1 
(use 'overtone.live)
  2 
(use 'overtone.inst.sampled-piano)
  3 
(require '[clojure.java.io :as io])
  4 
(import '[java.net ServerSocket])
  5 
 
  6 
(defn chr2int [c]      
  7 
  (-> (char c)
  8 
      (str)
  9 
      (Integer.)))
 10 
 
 11 
(defn beep [index]
 12 
  (let [my-scale (if (> index 6) (scale :C3 :major) (scale :C4 :major))
 13 
        note     (nth my-scale (if (> index 6) (- index 1) index))]
 14 
    (sampled-piano :note note)))
 15 
 
 16 
 
 17 
(defn receive
 18 
  [socket]
 19 
  (.readLine (io/reader socket)))
 20 
 
 21 
(defn serve [port handler]
 22 
  (with-open [server-sock (ServerSocket. port)
 23 
              sock (.accept server-sock)]
 24 
    (let [msg-in (receive sock)]
 25 
      (handler (chr2int (nth (seq msg-in) 0))))))
 26 
 
 27 
 
 28 
(while (pos? 1) (do (serve 12345 #(beep %))))

Client

Client uses wiringPi library for reading from raspberry gpio. Every pin handled in separate thread. For every pin touched opens connection to server and integer with note number send to sever.
  1 
int readPin (int pin) {
  2 
    pinMode (pin, OUTPUT);
  3 
    digitalWrite (pin, LOW);
  4 
    delay(1);
  5 
    int c=0;
  6 
    pinMode (pin, INPUT);
  7 
 
  8 
    while (digitalRead (pin)==LOW) {
  9 
        c++;
 10 
    }
 11 
    return c;
 12 
}
 13 
 
 14 
int beep (int pid) {
 15 
    std::string query = std::to_string (pid);
 16 
    std::string hostname = "your_ip";
 17 
    struct sockaddr_in sin;
 18 
    struct hostent *h;
 19 
    int fd;
 20 
    ssize_t n_written, remaining;
 21 
    char buf[1024];
 22 
 
 23 
    h = gethostbyname(hostname.c_str ());
 24 
    if (!h) {
 25 
        fprintf(stderr, "Couldn't lookup");
 26 
        return 1;
 27 
    }
 28 
 
 29 
    fd = socket(AF_INET, SOCK_STREAM, 0);
 30 
    if (fd < 0) {
 31 
        fprintf(stderr, "socket");
 32 
        return 1;
 33 
    }
 34 
 
 35 
    sin.sin_family = AF_INET;
 36 
    sin.sin_port = htons(12345);
 37 
    sin.sin_addr = *(struct in_addr*)h->h_addr;
 38 
    if (connect(fd, (struct sockaddr*) &sin, sizeof(sin))) {
 39 
        fprintf(stderr, "connect");
 40 
        close(fd);
 41 
        return 1;
 42 
    }
 43 
 
 44 
    send(fd, query.c_str (), query.size (), 0);
 45 
    close(fd);
 46 
}
 47 
 
 48 
void sensorHandler (int pid, int note) {
 49 
    int avg_num = 1;
 50 
    while (1) {
 51 
        int ans = 0;
 52 
        for (int avg = 0; avg < avg_num; avg++)
 53 
            ans += readCapacitivePin (pid);
 54 
        printf ("pid: %d, delay %d\n", pid, ans / avg_num);
 55 
        beep (note);
 56 
        delay (100);
 57 
    }
 58 
}