// TDM28dGGguy2 // Processing 1.5.1 Mac ou Windows // Gerard Paresys - Guy Kayser // 8 2 2014 // // Utilise la library layers de nootropic // http://nootropicdesign.com/processing-layers/ // http://sourceforge.net/projects/layers/files/ // // Taper esc pour quitter // // Le dossier data contient 4 fichiers nommés: // XXX.xml (format Praat TextGrid) // XXX.mp3 // XXX_Pitch.txt // XXX_Intensity.txt // Helvetica-50.vlw // arial.ttf // trousdememoire.jpg // // TDM24 = TDM23a + layers // TDM25 = TDM24b + FlagBlurPitch AdjustBlurPitch FlagBlurIntensity AdjustBlurIntensity // + background(0,0,0,0) pour effacer LineIntensity // TDM26 = TDM25a + background recharge quand spectre a mi-ecran // Spectre ligne212 for (int i = 0; i < (rowmax / 2); i++) { au lieu romax // Mettre rowmax / 3 ou / 4 pour diminuer hauteur Spectre // TDM27 = Largeur Spectre = Duree fichier // TDM27b Ajout if (! FlagBlurPitch) background(0, 0, 0, 0); // TDM27d Ajout FlagSpectreEntier // TDM28c = TDM28b bug corrigé: pas de phoneme a gauche a partir de le 2e tete choisie // TDM28d = TDM28c + 4 Fichiers: BackGround1.jpg BackGround2.jpg BackGround3.jpg BackGround4.jpg // à placer dans le dossier data, s'affichent a 4 temps TempsBackGround1 ... TempsBackGround4 // // Touche S Sauve l'ecran (format png) (Pb seul le 1er layer est sauvé) // Touche Espace Pause // Touche Fleche <- Zoom Out // Touche Fleche -> Zoom In // Touche P Phonème // Touche Y Syllabe // Touche M Mot // Clic souris dans la fenêtre d'abord // Ouvre le fichier XXX.xml // Ouvre et joue le fichier Audio XXX.mp3 // Ouvre le fichier texte XXX_Pitch.txtt généré par Praat // Ouvre le fichier texte XXX_Intensity.txt généré par Praat import ddf.minim.*; // pour AudioPlayer import ddf.minim.analysis.*; // Pour FFT import com.nootropic.processing.layers.*; // Pour layers //import fullscreen.*; //FullScreen fs; PFont maFonte; PFont maFonte1; PFont maFonte2; PFont maFonte3; PImage BackGroundImage, BackGroundImage1, BackGroundImage2, BackGroundImage3, BackGroundImage4; //import geomerative.*; //RFont MaFontOutline40, MaFontOutline60, MaFontOutline80 ; float FacteurX = 16; // Vitessse courbes Pitch et Intensity int CoucheSpectre = 2; //0 Phonème, 1 Syllabe, 2 Mot, 3 Phonétique, 4 Orthographique int CoucheHaut = 1; //0 Phonème, 1 Syllabe, 2 Mot, 3 Phonétique, 4 Orthographique int CoucheBas = 0; //0 Phonème, 1 Syllabe, 2 Mot, 3 Phonétique, 4 Orthographique boolean FlagLigneHaut = true; // true ou false boolean FlagTexteHaut = true; // true ou false boolean FlagLigneBas = false; // true ou false boolean FlagTexteBas = true; // true ou false int PitchMini = 75 ; // 75 Hz int PitchMaxi = 500; // 500 Hz int EpaisseurCourbe = 2; // Courbes Pitch & Intensity int AdjustBlurSpectrum = 5; //+ AdjustBlur est grand, - il y a de blur int AdjustBlurTextSpectrum = 5; //+ AdjustBlur est grand, - il y a de blur boolean FlagSpectreEntier = true; // true ou false boolean FlagBlurPitch = true; // true ou false int AdjustBlurPitch = 4; //+ AdjustBlur est grand, - il y a de blur boolean FlagBlurIntensity = true; // true ou false int AdjustBlurIntensity = 8; //+ AdjustBlur est grand, - il y a de blur String NomFichierBackGround = "trousdememoire.jpg"; int TempsBackGround1 = 0; //Temps en seconde int TempsBackGround2 = 30; //Temps en seconde int TempsBackGround3 = 45; //Temps en seconde int TempsBackGround4 = 400; //Temps en seconde // ATTENTION: mettre les 4 temps dans l'ordre String NomFichierAudio; String NomFichierPitch; String NomFichierIntensity; String NomFichierXML, Nom; float PitchActuel = PitchMini; String[] LignesPitch; String[] LignesIntensity; int IndexPitch = 0; int IndexIntensity = 0; float xAvantPitch, xApresPitch, yAvantPitch, yApresPitch; float xAvantIntensity, xApresIntensity, yAvantIntensity, yApresIntensity; int LigneText, x; AudioPlayer MonPlayer; Minim minim; float temps, DureeFichier; boolean Probleme = false, Fin = false; boolean ToucheEspace = false, Pause = false, Trace = false; float[] LignePitch, LigneIntensity; float TempsPause, TempsDebutPause = 0; XMLElement xml1, kid1, kid2; XMLElement[] kid1Data, kidkid1Data; int NombreDeChild1, NombreDeChild2; int IndexXMLSpectre = 0, IndexXMLCouche4 = 0, IndexXMLHaut = 0, IndexXMLBas = 0; float xmin, xmax; String s1, s2, Content1, Content2; int colmax, colFixe ; // Spectrogram size (pixels) int rowmax ; // Spectrogram size (pixels) FFT Mafft; int col = 0; int Gris; int XSpectre; int Tete; int LargeurEllipse = 34, HauteurEllipse = 53; int[] d = { 46, 250, //1 58, 78, //2 137, 19, //3 134, 146, //4 209, 213, //5 206, 82, //6 335, 88, //7 294, 218, //8 330, 301, //9 378, 231, //10 376, 112, //11 459, 66, //12 475, 193, //13 555, 90, //14 554, 220, //15 601, 30, //16 646, 98, //17 652, 250, //18 722, 78, //19 713, 229 //20 } ; boolean Initialisation = false; int BGI = 0; AppletLayers layers; void setup() { size(800, 600); // "The size() function must be the first line in setup()" // size(800, 600, OPENGL); // "The size() function must be the first line in setup()" // size(800, 600, P3D); // "The size() function must be the first line in setup()" // size(400, 300); // "The size() function must be the first line in setup()" maFonte = loadFont("Helvetica-50.vlw"); maFonte1 = loadFont("ACaslonPro-Semibold-48.vlw"); maFonte2 = loadFont("AmericanTypewriter-48.vlw"); maFonte3 = loadFont("AmericanTypewriter-CondensedBold-48.vlw"); smooth(); stroke(160); textAlign(LEFT, TOP); textFont(maFonte, 16); fill(0, 0, 0); // Texte noir colmax = width; rowmax = height; // RG.init(this); // smooth(); // MaFontOutline40 = new RFont( "arial.ttf", 40, RFont.CENTER); // MaFontOutline60 = new RFont( "Arial Rounded Bold.ttf", 60, RFont.CENTER); // MaFontOutline80 = new RFont( "Georgia.ttf", 80, RFont.CENTER); Tete = 0; BackGroundImage = loadImage(NomFichierBackGround); BackGroundImage1 = loadImage("BackGround1.jpg"); BackGroundImage2 = loadImage("BackGround2.jpg"); BackGroundImage3 = loadImage("BackGround3.jpg"); BackGroundImage4 = loadImage("BackGround4.jpg"); // fs = new FullScreen(this); // fs.enter(); // enter fullscreen mode // TempsPause = millis(); layers = new AppletLayers(this); // layers.addLayer(new TextLayer(this)); layers.addLayer(new PitchLayer(this)); layers.addLayer(new PitchTextLayer(this)); layers.addLayer(new IntensityLayer(this)); } void paint(java.awt.Graphics g) { if (layers != null) layers.paint(this); else super.paint(g); } void draw() { Tete=1; if (Tete == 0) { Initialisation = false; Lancement(); } else { if (! Initialisation) { // NomFichierXML = selectInput("select the XML File (format Praat textGrid)"); // NomFichierXML = "13missmilsaveur_Y/13missmilsaveur_Y.xml"; Nom = ""; if (Tete == 1) Nom = "1jeunessechalette2_Y"; else if (Tete == 2) Nom = "2thomas_gendarme_auxiliaire_X"; else if (Tete == 3) Nom = "3missmontargis_Y"; else if (Tete == 4) Nom = "4DenXiaoPing_X"; else if (Tete == 5) Nom = "5sebastien_petrole_vin_X"; else if (Tete == 6) Nom = "6FAP_Brian_X"; else if (Tete == 7) Nom = "7lesmaries_mr_Y"; else if (Tete == 8) Nom = "8mmeprieux_X"; else if (Tete == 9) Nom = "9millesourires_X"; else if (Tete == 10) Nom = "10mllecentreafrik_Y"; else if (Tete == 11) Nom = "11lesmaries_mme_X"; else if (Tete == 12) Nom = "12domoafrica_X"; else if (Tete == 13) Nom = "13missmilsaveur_Y"; else if (Tete == 14) Nom = "14jouineau_sport_X"; else if (Tete == 15) Nom = "15jeunessechalette1_X"; else if (Tete == 16) Nom = "16rondatipica_X"; else if (Tete == 17) Nom = "17fatidiop_Y"; else if (Tete == 18) Nom = "18ama_pergamano_Y"; else if (Tete == 19) Nom = "19FAP_darfour_Y"; else if (Tete == 20) Nom = "20apageh_X"; //Nom = "../" + "20voix/" + Nom + "/" + Nom; NomFichierXML = Nom + ".xml"; println("NomFichierXML = " + NomFichierXML); if (loadStrings(NomFichierXML) == null) { println("Le fichier " + NomFichierXML + " n'existe pas"); Probleme = true; } else { // String[] list = split(NomFichierXML, '.'); // NomFichierXML = list[0] + ".xml"; xml1 = new XMLElement(this, NomFichierXML); NombreDeChild1 = xml1.getChildCount(); kid1Data = xml1.getChildren(); s1 = kid1Data[0].getName(); // println(s1 + " : " + NombreDeChild1 + " child(s)"); kidkid1Data = kid1Data[0].getChildren(); s2 = kidkid1Data[1].getName(); println("Ouverture de: " + NomFichierXML); NomFichierPitch = Nom + "_Pitch.txt"; if (loadStrings(NomFichierPitch) == null) { println("Le fichier " + NomFichierPitch + " n'existe pas"); Probleme = true; } else { LignesPitch = loadStrings(NomFichierPitch); println("Ouverture de: " + NomFichierPitch +" " + LignesPitch.length + " lignes" ); } NomFichierIntensity = Nom + "_Intensity.txt"; if (loadStrings(NomFichierIntensity) == null) { println("Le fichier " + NomFichierIntensity + " n'existe pas"); Probleme = true; } else { LignesIntensity = loadStrings(NomFichierIntensity); println("Ouverture de: " + NomFichierIntensity +" " + LignesIntensity.length + " lignes" ); } NomFichierAudio = Nom + ".mp3"; if (loadStrings(NomFichierAudio) == null) { println("Le fichier " + NomFichierAudio + " n'existe pas"); Probleme = true; } else { println("Ouverture de: " + NomFichierAudio); minim = new Minim(this); MonPlayer = minim.loadFile(NomFichierAudio, 1024); } } if (! Probleme) { TempsPause = millis(); MonPlayer.play(); LignePitch = float(split(LignesPitch[LignesPitch.length - 1 ], " ")); DureeFichier = LignePitch[0]; println("Duree " + NomFichierPitch + " = " + DureeFichier + " sec"); LigneIntensity = float(split(LignesIntensity[LignesIntensity.length - 1 ], " ")); DureeFichier = LigneIntensity[0]; println("Duree " + NomFichierIntensity + " = " + DureeFichier + " sec"); Mafft = new FFT(MonPlayer.bufferSize(), MonPlayer.sampleRate()); Mafft.window(FFT.HAMMING); // background(0); // Fond noir // The background image must be the same size as the parameters // into the size() method. // BackGroundImage = loadImage("trousdememoire.jpg"); // BackGroundImage = loadImage(NomFichierBackGround); // background(BackGroundImage); Debut(); Initialisation = true; } else { Tete = 0; Initialisation = false; } } if (Initialisation) { temps = millis() - TempsPause; // Spectre Mafft.forward(MonPlayer.mix); if (FlagSpectreEntier) XSpectre = int (height * temps / DureeFichier / 1000); else XSpectre = col; // println("XSpectre = " + XSpectre); // fill in the new column of spectral values // println("rowmax = " + rowmax + " Mafft.specSize() = " + Mafft.specSize()); for (int i = 0; i < (colmax / 2); i++) { Gris = (int)Math.round(Math.max(0, 120*Math.log10(100*Mafft.getBand(i)))); if (Gris > 255) Gris = 255; // stroke(255-Gris); // Inversion Noir <-> Blanc stroke(Gris); // point(col, height - (2 * i) - 1); // point(col, height - (2 * i) - 2); // point(XSpectre, height - (2 * i) - 1); // point(XSpectre, height - (2 * i) - 2); point((2 * i) - 1, height-XSpectre ); point((2 * i) - 2, height-XSpectre ); } col = col + 1; // next time will be the next column if (col == colmax) col = 0; // wrap back to the first column when we get to the end // if (col == width / 2) background(BackGroundImage); if (frameCount % AdjustBlurSpectrum == 0) filter(BLUR, 0.572); // > 0.575 // Temps if ((! Pause) && (! Fin)) AfficheTemps(temps); temps = temps / 1000; if (temps > TempsBackGround4) { if (BGI != 4) { background(BackGroundImage4); BGI = 4; } } else { if (temps > TempsBackGround3) { if (BGI != 3) { background(BackGroundImage3); BGI = 3; } } else { if (temps > TempsBackGround2) { if (BGI != 2) { background(BackGroundImage2); BGI = 2; } } else { if (temps > TempsBackGround1) { if (BGI != 1) { background(BackGroundImage1); BGI = 1; } } } } } if (temps > DureeFichier) { Fini(); } NombreDeChild2 = kidkid1Data[CoucheSpectre].getChildCount(); if (IndexXMLSpectre < NombreDeChild2) { kid1 = kidkid1Data[CoucheSpectre].getChild(IndexXMLSpectre); xmin = kid1.getFloat("xmin"); xmax = kid1.getFloat("xmax"); Content1 = kid1.getContent(); // println("Child(" + IndexXMLSpectre + "): n = " + n + " xmin = " + xmin + " xmax = " + xmax + " " + Content1); if (Content1 == null) IndexXMLSpectre = IndexXMLSpectre + 1; else if (Content1.equals("_") == true) IndexXMLSpectre = IndexXMLSpectre + 1;//Elimination des caracteres _ qui separe les segments else { // if ((temps > xmin) && ! Pause) { // if ((temps > xmax) && ! Pause) { if ((temps > (xmin + xmax) / 2) && ! Pause) { // fill(0, 0, 0); // Texte noir // fill(255); // Texte blanc // textFont(maFonte, LignePitch[1] / 10); textFont(maFonte, PitchActuel / 4+20); // Plantage avec Font autre que Helvetica si Size = NaN //stroke(0); smooth(); // yApresPitch = YPitch(LignePitch[1]) ; // text(Content1, xApresPitch % width, yApresPitch - 20); // text(Content1, xApresPitch % width, YPitch(PitchActuel) - 20); IndexXMLSpectre = IndexXMLSpectre + 1; // colFixe = col; colFixe = XSpectre; // fill(255, 0, 0); // Texte rouge // println("PitchActuel = " + PitchActuel); // fill(PitchActuel/2, 195, YIntensity(LigneIntensity[1]* 3)); //fill(PitchActuel/2, YIntensity( LigneIntensity[1]* 1.9), YIntensity(LigneIntensity[1]* 3)); fill(YIntensity( LigneIntensity[1]* 1.9), YIntensity(LigneIntensity[1]* 3),PitchActuel);//multico2 // text(Content1, colFixe + 10, height / 2); // text(Content1, colFixe + 10, YPitch(LignePitch[1]) - 20); // text(Content1, colFixe - 10, YIntensity(LigneIntensity[1]* 3) + 300); // text(Content1, colFixe - 10, YIntensity(LigneIntensity[1]* 3) + 150); // strokeWeight(1); if (colFixe > 500) { // textAlign(RIGHT); text(Content1, YIntensity(LigneIntensity[1]* 5) + 578, height - colFixe + 50); //translate(YIntensity(LigneIntensity[1]* 5) + 578, height - colFixe + 50); } else { // textAlign(LEFT); text(Content1, YIntensity(LigneIntensity[1]* 5) + 578, height - colFixe -10 + random(-40, +40)); //translate(YIntensity(LigneIntensity[1]* 5) + 578, height - colFixe + 10 + random(-50, +50)); } // if (PitchActuel < 100) MaFontOutline40.draw(Content1); // else if (PitchActuel < 150) MaFontOutline60.draw(Content1); // else MaFontOutline80.draw(Content1); // println(Content1); } } } } } // else exit(); } void Lancement() { BackGroundTrou(); if (mousePressed == true) { for (int i = 0; i < 40; i = i+2) { ellipse(d[i], d[i + 1], LargeurEllipse, HauteurEllipse); if (mouseX >= d[i] && mouseX <= d[i]+LargeurEllipse && mouseY >= d[i + 1] && mouseY <= d[i + 1]+HauteurEllipse) { Tete = i/2 + 1; } } println("Tete = " + Tete ); BackGroundTrou(); // textFont(maFonte, 24); // fill(100, 100, 255); // text("Tete = " + Tete, 300, 570); } } void BackGroundTrou() { background(BackGroundImage); ellipseMode(CORNER); // Set ellipseMode is CORNER noStroke(); fill(255); // Set fill to white for (int i = 0; i < 40; i = i+2) { if (Tete != (i/2 + 1)) { ellipse(d[i], d[i + 1], LargeurEllipse, HauteurEllipse); } } } float YPitch(float w) { return ((500 - w) / 2) + 100; // return ((500 - w) / 2) ; } float YIntensity(float w) { if (w < 40) w= 40; // return ((100 - w) * 3) + 312; return ((100 - w) * 3) + 412; } void AfficheTemps(float T) { T = T / 1000; // x = 728; // fill(0); // rect(x - 3, 587, 100, 15); // fill(255); // textFont(maFonte, 12); // text(T + " sec", x, 590); } void EffaceEcran() { // background(255); // Fond blanc // noStroke(); // pas de contour xAvantPitch = 0; yAvantPitch = YPitch(75) ; xAvantIntensity = 0; yAvantIntensity = YIntensity(40) ; } void Debut() { TempsPause = millis(); IndexPitch = 0; IndexIntensity = 0; IndexXMLSpectre = 0; IndexXMLCouche4 = 0; IndexXMLBas = 0; IndexXMLHaut = 0; EffaceEcran(); PlayerAudioDebut(); BGI = 0; } void Fini() { Fin =true; // background(0, 0, 0); // Tete = 0; // Initialisation = false; } void PlayerAudioDebut() { MonPlayer.close(); MonPlayer = minim.loadFile(NomFichierAudio, 1024); MonPlayer.play(); } void keyPressed() { // println("key = " + key); if (key == ' ') { // barre d'espace ToucheEspace = ! ToucheEspace; Pause = ToucheEspace; if (Pause) { MonPlayer.pause(); TempsDebutPause = millis(); } else { MonPlayer.play(); TempsPause = TempsPause + millis() - TempsDebutPause; } } else if ( key == 'p' || key == 'P' ) { CoucheSpectre = 0; // P Phonème Debut(); } else if (key == 'y' || key == 'Y') { CoucheSpectre = 1; // Y Syllabe Debut(); } else if (key == 'm' || key == 'M') { CoucheSpectre = 2; // M Mot Debut(); } else if (key == 'h' || key == 'H') { CoucheSpectre = 3; // H Phonétique Debut(); } else if (key == 'o' || key == 'O') { CoucheSpectre = 4; // O Orthographique Debut(); } else if (key == 'q' || key == 'Q') { Tete = 0; Initialisation = false; MonPlayer.close(); } else if (key == 's' || key == 'S') saveFrame(timestamp()+"_##.png"); else if (keyPressed && (key == CODED)) { // If it's a coded key if (keyCode == LEFT) { // Left arrow FacteurX = FacteurX / 2; Debut(); } else if (keyCode == RIGHT) { // Right arrow FacteurX = FacteurX * 2; Debut(); } } { // println("key = " + key + " Erreur taper Espace"); } } String timestamp() { Calendar now = Calendar.getInstance(); println("Frame saved"); // return String.format("%1$ty%1$tm%1$td_%1$tH%1$tM%1$tS", now); return String.format("%1$ty%1$tm%1$td_%1$tH%1$tM%1$tS", now); } void stop() { // always close Minim audio classes when you are done with them MonPlayer.close(); minim.stop(); super.stop(); }