/******************************************************************************************************************************************************* Projekt: Konzept eines möglichen Processing-MP3-Players mit Spektrumsanalyse und Visualisierung derselben mittels eines Feldes von 3-Dimensionalen Kuben Beteiligte: Marc Haemmerle u. Thomas Goethe Bemerkung: Die Methoden zur Anzeige der Gesamtdauer und der bereits gespielten Dauer eines Musikstückes sind vorhanden, aber durch die jetzige Version von ESS noch nicht anwendbar =/ Verbesserungs- möglichkeiten: * Komplette gewohnte Playersteuerung andenken * Titel aus den ID3-Tags auslesen * Menue zur Ansicht der verfügbaren Steuerungsmöglichkeiten * Alben abspielen / unterschiedliche Playlisten -> neuer Navigations"ring" mit offenen "Enden" *******************************************************************************************************************************************************/ // Benoetigte Bibliotheken importieren import processing.opengl.*; import krister.Ess.*; import proxml.*; import gestalt.p5.Ge; import gestalt.shape.Cube; import java.util.Iterator; import java.util.LinkedList; /*****************************************************************************************************************************************/ // Globale Variablen fuer das Interface int play = -1; int songToPlay = -1; //startmarkierung float dauer=3.30,gelaufen=0.00; PlayerInterface myInterface; int outerRadius = 60; //Aussmass des Interface int innerRadius = 30; //Inneregrenze des Interface /*****************************************************************************************************************************************/ // Arrayposition des gerade abgespielten MP3s int currentPlaylistPosition; int playlistLength; // ++++++++++++++++ boolean isStarted = false; // ++++++++++++++++ // XML-Dokument XMLInOut xmlIO; // Positionsvariablen fuer die 3D-Navigation float xmag, ymag = 0; float newXmag, newYmag = 0; /*****************************************************************************************************************************************/ // ESS Variable - Stream AudioStream myStream; // ESS Variable - Datei, die *gerade* gestreamt wird AudioFile myFile; // Globale Lautstaerkeeinstellung float myVolume = 1.0; // ESS Variable - Objekt fuer FFT-Berechnungen FFT myFFT; /*****************************************************************************************************************************************/ // Fontvariable der Menueueberschriften PFont menuHeaderFont; // Anzahl angezeigter Frequenzbaender int xCount = 50; // Breite der Frequenzbaender int yCount = 32; // Array zur Speicherung des Visualisierungsrasters float[][] stageArray = new float[xCount][yCount]; float x,y; // Array zur Verwaltung der Cube-Geometrien Cube[] myCube = new Cube[xCount*yCount]; // Serveradresse auf der die MP3's und die Playlist liegen String serverAdress = "http://www.no7hing.com/dev/processing/p5mp3/"; //String serverAdress = "http://localhost/gc/"; // Playliste fuer ausgelesene MP3's LinkedList mp3Playlist = new LinkedList(); // Instanzvariable fuer Visualizer Visualizer viz; // Horizontale Korrekturdistanz zum Ausgleich des POI float horizontalCorrection; /*****************************************************************************************************************************************/ void setup() { // Sketchgroesse einstellen und OPENGL verwenden size(1200,780,OPENGL); frameRate(24); background(30); // Wir fangen bei der ersten Position an currentPlaylistPosition = 0; // Schriftart Menueueberschrift menuHeaderFont = loadFont("CenturyGothic-Italic-11.vlw"); // Visualisierungsarray mit 0-en fuellen for(int x=0;x 0.01){ xmag -= diff/4.0; } // Faktor schrittweise bis zum Erreichen der ausgerechneten Position erhoehen diff = ymag - newYmag; if (abs(diff) > 0.01){ ymag -= diff / 4.0; } // Kameraposition wird mit obigen Faktoren eingestellt Ge.camera().position().set((width / 2 - horizontalCorrection)*xmag, height * 1.5, height * 0.5 * ymag); // simple Zaehlvariable für den Array mit den Kuben int countCube = 0; // Rekursiver Array zum Positionieren, Skalieren und einfaerben der Spektrumskuben for(int x=0;x= 0.2){ myVolume -= 0.2; Ess.masterVolume(myVolume); } } // Auswahl durch Enter if (keyCode == ENTER){ play = songToPlay; currentPlaylistPosition = play; myFile.close(); myFile.open(mp3Playlist.get(currentPlaylistPosition).toString(),0,Ess.READ); } //println(keyCode); } /*****************************************************************************************************************************************/ // temporaeres Zeuchs fuer das skippen von Liedern void keyPressed() { // Steuerung des Interfaces mit Cursortasten und Enter if (keyCode == RIGHT) { if(songToPlay == (playlistLength-1)){ songToPlay = 0; } else { songToPlay++; } } else if (keyCode == LEFT){ if(songToPlay == 0){ songToPlay = playlistLength-1; } else { songToPlay--; } } } /*****************************************************************************************************************************************/ // wird anscheinend aus der ESS Klasse heraus aufgerufen ... void audioStreamWrite(AudioStream theStream) { // ... und wenns folgendes weg ist gibt's keine Musik - aus dem ESS Tutorial entnommen int samplesRead=myFile.read(myStream); if (samplesRead==0) { isStarted = false; if(currentPlaylistPosition == (playlistLength-1)){ currentPlaylistPosition = 0; } else { currentPlaylistPosition++; } play = songToPlay = currentPlaylistPosition; myFile.close(); myFile.open(mp3Playlist.get(currentPlaylistPosition).toString(),0,Ess.READ); samplesRead = myFile.read(myStream); isStarted = true; } } /*****************************************************************************************************************************************/ // Listener fuer Events der XML-Klasse void xmlEvent(XMLElement element){ XMLElement mp3Node; playlistLength = element.countChildren(); for(int i=0; i < element.countChildren(); i++){ mp3Node = element.getChild(i); String[] testAttr = mp3Node.getAttributes(); String mp3FullPath = serverAdress + mp3Node.getAttribute(testAttr[2]) + mp3Node.getAttribute(testAttr[0]); mp3Playlist.add(mp3FullPath); } myInterface = new PlayerInterface(playlistLength, 60, 30, width-60-20, height-60-20); startSound(); } /*****************************************************************************************************************************************/ // we are done, clean up Ess public void stop() { Ess.stop(); super.stop(); } /*****************************************************************************************************************************************/ // Zeichenklasse fuer Kreissegmente class PlayerInterface { // Variablen int r; //aeusserer Radius int r2; //innerer Radius int anzK; //segmentanzahl int posX; //XPosition int posY; //YPosition int faktor = 2; //Teilung des einzelnen Segmentes in X elemente (so wirkt es runder) float a,winkel,num; //uebergabevariablen // Konstruktor PlayerInterface (int mp3, int radius1, int radius2, int positionX, int positionY){ anzK = mp3; r = radius1; r2 = radius2; posX = positionX; posY = positionY; PFont font; //Schrift font = loadFont("ArialMT-16.vlw"); textFont(font, 16); } // Methoden //Punkte fuer die Segmente float pointX(float winkelM){ return cos(radians(winkelM))*r; } float pointY(float winkelM){ return sin(radians(winkelM))*r; } float pointX1(float winkelM){ return cos(radians(winkelM))*(r-r2); } float pointY1(float winkelM){ return sin(radians(winkelM))*(r-r2); } //Segment wird erstellt void zeichneSegment(int segmentNum){ // winkelausmass des elements winkel = 360.0 / anzK; // abstand der segmente im element a = winkel / faktor; num = winkel * segmentNum; beginShape(); vertex(pointX(num)+posX,pointY(num)+posY); vertex(pointX(num+a)+posX,pointY(num+a)+posY); for(int i=1;i<=faktor;i++){ vertex(pointX(num+a*i)+posX,pointY(num+a*i)+posY); } for(int i=faktor;i>0;i--){ vertex(pointX1(num+a*i)+posX,pointY1(num+a*i)+posY); } vertex(pointX1(num+a)+posX,pointY1(num+a)+posY); vertex(pointX1(num)+posX,pointY1(num)+posY); endShape(CLOSE); } void zeichnen(int auswahlId){ textAlign(RIGHT); for (int i=0;i