dinsdag 24 juli 2012

Lasercutten

Wat een marathon, 84 slices lasercutten. Heeft me meer dan 12 uur gekost, maar ben blij met het resultaat! Ik wil zo snel mogelijk alle slices op elkaar stapelen en vastlijmen. Maar ik moet dan eigenlijk wel alvast de LED-jes in muziekbox gesoldeerd hebben. Dus ik denk dat Mikail en ik binnenkort maar even moeten afspreken om dat te doen.
Zodra de slices allemaal netjes op elkaar gelijmd zijn, ga ik het model 'plamuren' met MDF vuller, schuren, een goede grondlaag geven en verven. Uiteindelijk gaat er ook nog een laag doorzichtige epoxy overheen voor een goede shiny finishing coat!



Vorderingen Virtuoso in Max/MSP

Even kijken of video op blogger ook een beetje lekker werkt, maar de 2 filmpjes demonstreren de max patch in wording van interactieve muziek. [update: nee, de filmpjes zien er dan bagger uit, worden nu geupload op:
http://greencouch.nl/downloads/virtuoso dan is e.e.a. tenminste ook te zien en lezen]

In Filmpje 1 staat de iPod nog uit, in filmpje 2 staat ie aan.
Filmpje legt zichzelf aardig uit (volg de muis) en de bekende 'bugs' komen ook mooi in beeld:
 (volume voor het eerst ingesteld zonder dat er handmatig een preset is 'aangezet' (op 1 minuut), wat normaal natuurlijk door de interactie wordt gestuurd).

Wat er in deze versies dus zit is:
- interactie (met een iPod via mrmr)
- losse midi-blokjes in 'groepen', gedefinieerd in een simpel tekstbestandje
wordt nu door de druk-rustig slider aangestuurd
- hoog / laag (momenteel hoge instrumenten vs. lage instrumenten via channel mixer)
- mogelijkheid om andere muziek (en presets in te laden)
- algehele volumeslider
- temposlider




vrijdag 6 juli 2012

06-07-2012 vorderingen tilt compensated compass

Mikail en ik (Raymond) zijn vandaag weer verder gegaan met het kijken naar de mogelijkheden van de Tilt Compensated Compass (TCC). De TCC heeft twee functies, een functie die kijkt op welke as (XYZ) er wordt geroteerd en een accelerometer. Nu is vandaag gebleken dat de eerste functie werkt als een echt kompas en daarmee door ons niet gebruikt kan worden. Wij moeten namelijk interactie creëren op coördinaten, maar deze zijn verschillend, afhankelijk van de hoek waarin men staat ten opzichte van het Noorden.
De accelerometer kunnen we daarentegen wel gebruiken omdat deze kijkt naar Acceleratie per as, niet ten opzichte van het noorden. Toch moeten we nog goed gaan bedenken hoe we dit goed kunnen programmeren, want de accelerometer is erg nauwkeurig, maar daarmee ook erg gevoelig. Dit wil dus zeggen dat wanneer iemand naar links wijst en daar rondjes draait, de accelerometer gaat denken dat er alweer naar rechts wordt gewezen.

Misschien dat we ergens dit weekend nog tijd zien om verder te werken, maar dit is niet zeker. Volgende kunnen we wel weer aan de bak.

dinsdag 3 juli 2012

02-07-2012 Voortgang en beperkingen muziek-systeem...

Tja, ja, ja, het aanvankelijke enthousiasme (mooi Max-script dat midi omzet in Arduino-array) begint weer wat te dalen nu er toch een aantal beperkingen optreden:
Als de array (een soort lijst) met nootjes te lang is, dan speelt de arduino het niet meer af... Hopelijk bestaat er een simpele oplossing???


Een 'lang zal ie leven' met alléén een instrument (en een paar nootjes minder) geeft nu al:
"Binary sketch size: 6,740 bytes (of a 32,256 byte maximum)"

Verder merk ik dat vanaf 6,800 bytes het script hoe dan ook over zijn nek gaat, ongeacht van de muziek(stijl) of hoeveelheid nootjes : s
Dan krijg je op z'n best (net over de grens van 6,800 bytes) hele rare overstuurde sounds, bij meer bytes hoor je gewoon helemaal niks meer.

Dit is mogelijk dus een veel groter probleem, waar ik op internet ook niet per sé iets over tegenkom. Jullie hier bekend mee?
Heel misschien heeft het er mee te maken dat de Musical Instrument Shield niet helemaal goed gesoldeerd is en dan mogelijk niet het volledige geheugen aangesproken kan worden...?

Tenslotte, maar dat is momenteel het minst belangrijk probeer ik via Max/MSP ook de Serial.read aan de praat te krijgen / aan te spreken, zodat ik wat interactie zou kunnen testen.
Wellicht dat jullie daar een makkelijke oplossing voor kennen? Dat krijg ik in ons script ook niet aan de praat (los in andere scripts wel).


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Afijn, tot dusver dus even mijn Arduino bevindingen, ik kan nu eerlijk gezegd weer even niet verder,
: s
dus actie of feedback is wel gewenst.

29-06-2012 script updates met Raymond, Mikail en Than

We hebben het script voor het muziek-gedeelte aangepast:
samengevat komt het neer op:
- tempo is per heden in bpm in plaats van in millisecondes per tijdseenheid
- delta-t (duratie van events) is nu in 4e, 8e , 16e etc. noten ipv in millisecondes of aantal tijdseenheden
- note velocity is nu vanaf 1 t/m 127 ipv alleen '1' voor noot aan, '0' voor noot uit
- mogelijkheid om na één array een andere array af te spelen, oftewel na een muziekblokje kan er een volgend muziekblokje worden afgespeeld

De bron-code-wijzigingen zullen we de blog besparen ; )
maar hier een Vader Jacob (gevolgd door een los nootje) in het huidige script :


/*********************************************************
v1.0, 20120526
created by Felix (Donkers Creative Technologies)
http://www.donkersct.nl

Derived from original Sparkfun example, see header below.

Optimized for Arduino SDK v1
- uses the "SoftwareSerial" library
and extended code:
- extra function so you can now play simple MIDI sequences
  with multiple MIDI-channels
 
See following some links for details on the MIDI protocol:
http://www.sonicspot.com/guide/midifiles.html
http://www.midi.org/techspecs/gm1sound.php

**********************************************************
version history
1.0, 20120526,  initial version
*********************************************************/


/* This is the original header for "MusicInstrument_Example"
 2-12-2011
 Spark Fun Electronics 2011
 Nathan Seidle

 This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license).

 This code works with the VS1053 Breakout Board and controls the VS1053 in what is called Real Time MIDI mode.
 To get the VS1053 into RT MIDI mode, power up the VS1053 breakout board with GPIO0 tied low, GPIO1 tied high.

 I use the NewSoftSerial library to send out the MIDI serial at 31250bps. This allows me to print regular messages
 for debugging to the terminal window. This helped me out a ton.

 5V : VS1053 VCC
 GND : VS1053 GND
 D3 (SoftSerial TX) : VS1053 RX
 D4 : VS1053 RESET

 Attach a headphone breakout board to the VS1053:
 VS1053 LEFT : TSH
 VS1053 RIGHT : RSH
 VS1053 GBUF : GND

 When in the drum bank (0x78), there are not different instruments, only different notes.
 To play the different sounds, select an instrument # like 5, then play notes 27 to 87.

 To play "Sticks" (31):
 talkMIDI(0xB0, 0, 0x79); //Bank select: drums
 talkMIDI(0xC0, 5, 0); //Set instrument number
 //Play note on channel 1 (0x90), some note value (note), middle velocity (60):
 noteOn(0, 31, 60);

*/
int volCounter = 20;
int chan0 = 80;
int chan1 = 80;
int chan2 = 80;
int chan3 = 80;
int theVariableT = 0;

// enable debugging with the Arduino serial monitor
#define Serial_monitor

#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); //Soft TX on 3, we don't use RX in this code
byte resetMIDI = 4; //Tied to VS1053 Reset line
byte ledPin = 13; //MIDI traffic inidicator

// define MIDI soundbanks
#define SB_GM1         0x00
#define SB_FANCYSOUNDS 0x78
#define SB_MELODIC     0x79

struct t_midiHeader {
  byte soundbank[4];
  byte instrument[4];
  byte volume[4];
  byte pitchShift[4];
  int tempo;
}; // t_midiHeader

// HIER MAAK JE EEN CHANNEL AAN
t_midiHeader JacobHeader = {
 {SB_GM1,SB_GM1,SB_GM1,SB_GM1}, //DIT ZIJN MIDI BOARDS
 {60, 1, 1, 3}, // INSTRUMENT BIJ DESBETREFFENDE CHANNEL
 {chan0, chan1, chan2, chan3}, // VOLUME BIJ CHANNEL
 {0, 0, 0, 0}, // PITCH ? DONT KNOW WTF IT IS
 120 // TEMPO
}; // t_midiHeader

struct t_midiNote {
  int  deltaTime; // deltaTime is in ms wordt berekend aan de hand van de nootduur in beats
  byte channel;   // midi channel for this note
  byte note;      // midi note to be played
  byte noteVelocity;     // 0=off, boven 0=on/velocity
}; // t_midiNote

t_midiNote singleNote;
 
t_midiNote Jacob1[] = {
{ 0, 1, 48, 70},
{ 0, 2, 60, 78},
{ 4, 1, 48, 0},
{ 0, 1, 48, 27},
{ 0, 2, 60, 0},
{ 0, 2, 62, 68},
{ 4, 1, 48, 0},
{ 0, 1, 48, 58},
{ 0, 2, 62, 0},
{ 0, 2, 64, 64},
{ 4, 1, 48, 0},
{ 0, 1, 48, 59},
{ 0, 2, 60, 80},
{ 0, 2, 64, 0},
{ 4, 1, 47, 80},
{ 0, 1, 48, 0},
{ 0, 2, 60, 0},
{ 0, 2, 60, 83},
{ 4, 1, 47, 0},
{ 0, 1, 47, 61},
{ 0, 2, 60, 0},
{ 0, 2, 62, 75},
{ 4, 1, 47, 0},
{ 0, 1, 47, 64},
{ 0, 2, 62, 0},
{ 0, 2, 64, 66},
{ 4, 1, 47, 0},
{ 0, 1, 47, 53},
{ 0, 2, 60, 78},
{ 0, 2, 64, 0},
{ 4, 1, 45, 78},
{ 0, 1, 47, 0},
{ 0, 2, 60, 0},
{ 0, 2, 64, 71},
{ 4, 1, 45, 0},
{ 0, 1, 45, 35},
{ 0, 2, 64, 0},
{ 0, 2, 65, 78},
{ 4, 1, 45, 0},
{ 0, 1, 45, 76},
{ 0, 2, 65, 0},
{ 0, 2, 67, 62},
{ 4, 1, 45, 0},
{ 0, 1, 45, 70},
{ 0, 2, 67, 0},
{ 4, 1, 43, 78},
{ 0, 1, 45, 0},
{ 0, 2, 64, 73},
{ 4, 1, 43, 0},
{ 0, 1, 43, 64},
{ 0, 2, 64, 0},
{ 0, 2, 65, 44},
{ 4, 1, 43, 0},
{ 0, 1, 43, 56},
{ 0, 2, 65, 0},
{ 0, 2, 67, 80},
{ 4, 1, 43, 0},
{ 0, 1, 43, 69},
{ 0, 2, 67, 0},
{ 4, 1, 41, 91},
{ 0, 1, 43, 0},
{ 0, 2, 67, 54},
{ 8, 2, 67, 0},
{ 0, 2, 69, 66},
{ 8, 1, 41, 0},
{ 0, 1, 41, 80},
{ 0, 2, 67, 64},
{ 0, 2, 69, 0},
{ 8, 2, 65, 66},
{ 0, 2, 67, 0},
{ 8, 1, 41, 0},
{ 0, 1, 43, 87},
{ 0, 2, 64, 75},
{ 0, 2, 65, 0},
{ 8, 2, 64, 0},
{ 8, 1, 43, 0},
{ 0, 1, 43, 55},
{ 0, 2, 60, 80},
{ 8, 2, 60, 0},
{ 8, 1, 43, 0},
{ 0, 1, 45, 86},
{ 0, 2, 67, 78},
{ 8, 2, 67, 0},
{ 0, 2, 69, 40},
{ 8, 1, 45, 0},
{ 0, 1, 45, 83},
{ 0, 2, 67, 78},
{ 0, 2, 69, 0},
{ 8, 2, 65, 68},
{ 0, 2, 67, 0},
{ 8, 1, 43, 86},
{ 0, 1, 45, 0},
{ 0, 2, 64, 75},
{ 0, 2, 65, 0},
{ 8, 2, 64, 0},
{ 8, 1, 43, 0},
{ 0, 1, 43, 80},
{ 0, 2, 60, 80},
{ 4, 1, 43, 0},
{ 0, 1, 43, 90},
{ 0, 2, 60, 0},
{ 0, 2, 60, 80},
{ 4, 1, 43, 0},
{ 0, 1, 43, 94},
{ 0, 2, 55, 73},
{ 0, 2, 60, 0},
{ 4, 1, 43, 0},
{ 0, 1, 48, 79},
{ 0, 2, 55, 0},
{ 0, 2, 60, 88},
{ 4, 1, 48, 0},
{ 0, 1, 48, 59},
{ 0, 2, 60, 0},
{ 4, 1, 43, 90},
{ 0, 1, 48, 0},
{ 0, 2, 60, 88},
{ 4, 1, 43, 0},
{ 0, 1, 43, 92},
{ 0, 2, 55, 80},
{ 0, 2, 60, 0},
{ 4, 1, 36, 97},
{ 0, 1, 43, 0},
{ 0, 2, 55, 0},
{ 0, 2, 60, 94},
{ 4, 1, 24, 97},
{ 0, 1, 36, 0},
{ 0, 2, 60, 0},
{ 4, 1, 24, 0},



};

t_midiNote Jacob2[] = {
  // deltatime, channel, note, on/off
  { 1, 0, 48, 40},
  { 1, 0, 48, 0},
};

void setup() {
#ifdef Serial_monitor
  Serial.begin(57600);
#endif

  //Setup soft serial for MIDI control
  mySerial.begin(31250);
 
  //Reset the VS1053
  pinMode(resetMIDI, OUTPUT);
  digitalWrite(resetMIDI, LOW);
  delay(100);
  digitalWrite(resetMIDI, HIGH);
  delay(100);
}



void loop() {
playMidiSequence(&JacobHeader, &Jacob1[0], sizeof(Jacob1) / sizeof(singleNote));
//playMidiSequence(&JacobHeader, &Jacob2[0], sizeof(Jacob2) / sizeof(singleNote));
}

//=================================================================
// demo: playMidiSequence
//=================================================================

void playMidiSequence(struct t_midiHeader *header, struct t_midiNote *sequence, int sequenceSize) {
  int sequencePntr = 0;
  byte pitch = 0;
  byte channel = 0;
  byte noteVelocity = 0;

  // initialize MIDI channels
  for (int i=0; i<16; i++) {
    MIDI_setSoundbank(i, header->soundbank[i]);
    MIDI_setVolume(i, header->volume[i]);
    MIDI_setInstrument(i, header->instrument[i]);
  }

  sequencePntr = 0;
 
  while(sequencePntr < sequenceSize ) {
    pitch = sequence[sequencePntr].note + header->pitchShift[sequence[sequencePntr].channel];
    channel = sequence[sequencePntr].channel;    
    noteVelocity = sequence[sequencePntr].noteVelocity;
   
    if (sequence[sequencePntr].noteVelocity > 0) {
      for (int i=0; i<3; i++) {
        MIDI_setVolume(i,chan0); //(channel, channelVelocity)
      }
      MIDI_noteOn(channel, pitch, noteVelocity);
    }
    else
    MIDI_noteOff(channel, pitch, 60);
    sequencePntr++;
   
    int tempoMs = 60000/header->tempo; // 60 000 = 60sec, headertempo is in ms, uitkomst = bpm
    int wholeNote = tempoMs * 4; // hele noot = 4 * kwart noot
    int delta = sequence[sequencePntr].deltaTime;
   
    if (!delta == 0) { // if delta=0 dan geen delay
      delay(wholeNote/delta); // playbackspeed
    }

  }
} // playMidiSequence

/*********************************************************
Various low level MIDI commands
*********************************************************/

//Send a MIDI note-on message.  Like pressing a piano key
//channel ranges from 0-15
void MIDI_noteOn(byte channel, byte note, byte attack_velocity) {
  talkMIDI( (0x90 | channel), note, attack_velocity);
} // MIDI_noteOn

//Send a MIDI note-off message.  Like releasing a piano key
void MIDI_noteOff(byte channel, byte note, byte release_velocity) {
  talkMIDI( (0x80 | channel), note, release_velocity);
} // MIDI_noteOff

//Send a MIDI set soundbank message
void MIDI_setSoundbank(byte channel, byte soundbank) {
  //0xB0 is channel message, set soundbank
  talkMIDI( (0xb0 | channel), 0x00, soundbank);
} // MIDI_setSoundbank

//Send a MIDI volume message
void MIDI_setVolume(byte channel, byte volume) {
  //0xB0 is channel message, set ch_x volume
  talkMIDI( (0xB0 | channel), 0x07, volume);
} // MIDI_setVolume

//Send a MIDI set instrument message
void MIDI_setInstrument(byte channel, byte instrument) {
  //0xC0 is a 1 data byte command, set ch_x instrument number
  talkMIDI( (0xC0 | channel), instrument, 0);
} // MIDI_setInstrument

//Plays a MIDI note. Doesn't check to see that cmd is greater than 127, or that data values are less than 127
void talkMIDI(byte cmd, byte data1, byte data2) {
  digitalWrite(ledPin, HIGH);
  mySerial.write(cmd);
  mySerial.write(data1);

  //Some commands only have one data byte. All cmds less than 0xBn have 2 data bytes
  //(sort of: http://253.ccarh.org/handout/midiprotocol/)
  if( (cmd & 0xF0) <= 0xB0)
    mySerial.write(data2);

  digitalWrite(ledPin, LOW);
} // talkMIDI