// Gerard Paresys
// 18 06 2012
// Le dossier data doit comporter:
// lesmaries_mme.wav
// lesmaries_mme_Pitch_listing.txt
// lesmaries_mme_Intensity_listing.txt
// lesmaries_mme.TextGrid.xml (format Praat TextGrid)
// Helvetica-50.vlw
// Touche S Sauve l'ecran (format png)
// Annuler Commentaire sur les 3 lignes qui commencent par: // NomFichier
// pour ouvrir n'importe quel fichier
/**
* 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 et joue le fichier Audio lesmaries_mme.wav
* Ouvre le fichier texte lesmaries_mme_Pitch_listing.txt généré par Praat
* Ouvre le fichier texte lesmaries_mme_Intensity_listing.txt généré par Praat
* Dessine les courbes Pitch et Intensity synchronisées avec l'Audio
* La courbe Pitch n'est pas dessinée quand pitch est "undefined"
* Chronomètre...
*
*/
// * Taper: P Phonème - Y Syllabe - M Mot - H Phonétique - O Orthographique
// * Affiche au choix 5 segmentations différentes du texte faites par Olivier Baude:
import ddf.minim.*; // pour AudioPlayer
PFont maFonte;
String NomFichierAudio = "lesmaries_mme.mp3";
String NomFichierPitch = "lesmaries_mme_Pitch_listing.txt";
String NomFichierIntensity = "lesmaries_mme_Intensity_listing.txt";
String NomFichierXML = "lesmaries_mme.TextGrid.xml";
float FacteurX = 32;
int Couche = 2; //Mot
boolean Alea = true;
String[] LignesPitch;
String[] LignesIntensity;
int IndexPitch = 0;
int IndexIntensity = 0;
float xAvantPitch, xApresPitch, yAvantPitch, yApresPitch;
float xAvantIntensity, xApresIntensity, yAvantIntensity, yApresIntensity;
int LigneText, x;
AudioPlayer player;
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 IndexXML = 0, IndexXMLCouche4 = 0, n;
float xmin, xmax;
String s1, s2, Content1, Content2;
void setup() {
size(800, 600); // "The size() function must be the first line in setup()"
maFonte = loadFont("Helvetica-50.vlw");
smooth();
background(255);
stroke(160);
textAlign(LEFT, TOP);
textFont(maFonte, 16);
fill(0, 0, 0); // Texte noir
// NomFichierPitch = selectInput("select a Pitch File");
if (loadStrings(NomFichierPitch) == null) {
println("Le fichier " + NomFichierPitch + " n'existe pas");
Probleme = true;
}
else {
LignesPitch = loadStrings(NomFichierPitch);
println("Ouverture de: " + NomFichierPitch +" " + LignesPitch.length + " lignes" );
text(NomFichierPitch, 10, 5);
}
// NomFichierIntensity = selectInput("select an Intensity File");
if (loadStrings(NomFichierIntensity) == null) {
println("Le fichier " + NomFichierIntensity + " n'existe pas");
Probleme = true;
}
else {
LignesIntensity = loadStrings(NomFichierIntensity);
println("Ouverture de: " + NomFichierIntensity +" " + LignesIntensity.length + " lignes" );
text(NomFichierIntensity, 10, 25);
}
// NomFichierAudio = selectInput("select an Audio File (wav, aiff, mp3...");
if (loadStrings(NomFichierAudio) == null) {
println("Le fichier " + NomFichierAudio + " n'existe pas");
Probleme = true;
}
else {
println("Ouverture de: " + NomFichierAudio);
text(NomFichierAudio, 10, 45);
minim = new Minim(this);
player = minim.loadFile(NomFichierAudio, 2048);
}
// NomFichierXML = selectInput("select an XML File (format Praat textGrid)");
if (loadStrings(NomFichierXML) == null) {
println("Le fichier " + NomFichierXML + " n'existe pas");
Probleme = true;
}
else {
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);
text(NomFichierXML, 10, 65);
// AfficheCouche(Couche);
}
if (! Probleme) {
player.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");
EffaceEcran();
TempsPause = millis();
}
else exit();
}
void draw() {
temps = millis() - TempsPause;
if ((! Pause) && (! Fin)) AfficheTemps(temps);
temps = temps / 1000;
if (IndexPitch < LignesPitch.length) {
LignePitch = float(split(LignesPitch[IndexPitch], " "));
if (Float.isNaN(LignePitch[0])) {
IndexPitch = IndexPitch + 1;
}
if (IndexPitch < 0) { //Astuce IndexPitch est > 0
LigneText = (IndexPitch * 14) + 20;
fill(0, 0, 255);
text(LignePitch[0], 50, LigneText);
fill(255, 0, 0);
text(LignePitch[1], 100, LigneText);
}
// println("temps = " + temps + " LignePitch[0] = " + LignePitch[0]);
if ((temps > LignePitch[0]) && ! Pause) {
xApresPitch = FacteurX * (width) * LignePitch[0] / DureeFichier;
if (((xAvantPitch % width) > (xApresPitch % width)) && (IndexPitch < LignesPitch.length - 10) ) EffaceEcran();
if (Float.isNaN(LignePitch[1])) {
IndexPitch = IndexPitch + 1;
Trace = false;
xAvantPitch = xApresPitch;
// println("NaN IndexPitch = " + IndexPitch);
}
else {
yApresPitch = YPitch(LignePitch[1]) ;
if (Trace) {
stroke(100, 100, 100); // Ligne noire
line(xAvantPitch % width, yAvantPitch, xApresPitch % width, yApresPitch);
}
xAvantPitch = xApresPitch;
yAvantPitch = yApresPitch;
Trace = true;
IndexPitch = IndexPitch + 1;
}
}
}
else Fin = true;
if (IndexIntensity < LignesIntensity.length) {
LigneIntensity = float(split(LignesIntensity[IndexIntensity], " "));
if (Float.isNaN(LigneIntensity[0])) {
IndexIntensity = IndexIntensity + 1;
}
if (IndexIntensity < 0) { //Astuce IndexIntensity est > 0
LigneText = (IndexIntensity * 14) + 20;
fill(0, 0, 255);
text(LigneIntensity[0], 50, LigneText);
fill(255, 0, 0);
text(LigneIntensity[1], 100, LigneText);
}
// println("temps = " + temps + " LigneIntensity[0] = " + LigneIntensity[0]);
if ((temps > LigneIntensity[0]) && ! Pause) {
xApresIntensity = FacteurX * (width) * LigneIntensity[0] / DureeFichier;
if (((xAvantIntensity % width) > (xApresIntensity % width)) && (IndexIntensity < LignesIntensity.length - 10)) {
EffaceEcran();
}
if (Float.isNaN(LigneIntensity[1])) {
IndexIntensity = IndexIntensity + 1;
// Trace = false;
xAvantIntensity = xApresIntensity;
// println("NaN IndexIntensity = " + IndexIntensity);
}
else {
yApresIntensity = YIntensity(LigneIntensity[1]) ;
//if (Trace) {
stroke(255, 100, 100); // Ligne rouge
line(xAvantIntensity % width, yAvantIntensity, xApresIntensity % width, yApresIntensity);
//}
xAvantIntensity = xApresIntensity;
yAvantIntensity = yApresIntensity;
Trace = true;
//IndexIntensity = IndexIntensity + 1;
IndexIntensity = IndexIntensity + 5;
}
}
}
else Fin = true;
NombreDeChild2 = kidkid1Data[Couche].getChildCount();
if (IndexXML < NombreDeChild2) {
kid1 = kidkid1Data[Couche].getChild(IndexXML);
n = kid1.getInt("n");
xmin = kid1.getFloat("xmin");
xmax = kid1.getFloat("xmax");
Content1 = kid1.getContent();
// println("Child(" + IndexXML + "): n = " + n + " xmin = " + xmin + " xmax = " + xmax + " " + Content1);
if (Content1 == null) IndexXML = IndexXML + 1;
else if (Content1.equals("_") == true) IndexXML = IndexXML + 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
textFont(maFonte, LignePitch[1] / 10);
// yApresPitch = YPitch(LignePitch[1]) ;
// text(Content1, xApresPitch % width, yApresPitch - 20);
text(Content1, xApresPitch % width, YPitch(LignePitch[1]) - 20);
fill(255, 0, 0); // Texte rouge
// textFont(maFonte, (LigneIntensity[1] - 20) / 2);
textFont(maFonte, (LigneIntensity[1] - 40) / 2);
//yApresIntensity = YIntensity(LigneIntensity[1]) ;
//text(Content1, xApresIntensity % width, yApresIntensity - 20);
text(Content1, xApresIntensity % width, YIntensity(LigneIntensity[1]) - 20);
// println("Child(" + IndexXML + "): n=" + n + " xmin=" + xmin + " xmax = " + xmax + " " + Content1 + " temps = " + temps);
IndexXML = IndexXML + 1;
}
}
}
NombreDeChild2 = kidkid1Data[4].getChildCount(); // 4 = Couche orthographique
if (IndexXMLCouche4 < NombreDeChild2) {
kid2 = kidkid1Data[4].getChild(IndexXMLCouche4); // 4 = Couche orthographique
n = kid2.getInt("n");
xmin = kid2.getFloat("xmin");
xmax = kid2.getFloat("xmax");
Content2 = kid2.getContent();
// println("Child(" + IndexXML + "): n = " + n + " xmin = " + xmin + " xmax = " + xmax + " " + Content1);
if (Content2 == null) IndexXMLCouche4 = IndexXMLCouche4 + 1;
else if (Content2.equals("_") == true) IndexXMLCouche4 = IndexXMLCouche4 + 1;//Elimination des caracteres _ qui separe les segments
else {
if ((temps > xmin) && ! Pause) {
// if ((temps > xmax) && ! Pause) {
// if ((temps > (xmin + xmax) / 2) && ! Pause) {
noStroke(); // pas de contour
fill(255); // Rect blanc
rect(0, YIntensity(40) + 1, width, 60);
fill(0); // Texte noir
textFont(maFonte, 20);
text(Content2, 10, YIntensity(40) + 5, width-20, 60 );
// println("Child(" + IndexXMLCouche4 + "): n=" + n + " xmin=" + xmin + " xmax = " + xmax + " " + Content2 + " temps = " + temps);
IndexXMLCouche4 = IndexXMLCouche4 + 1;
}
}
}
}
float YPitch(float w) {
return ((500 - w) / 2) + 100;
}
float YIntensity(float w) {
if (w < 40) w= 40;
return ((100 - w) * 3) + 312;
}
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 AfficheCouche(int Couche) {
NombreDeChild2 = kidkid1Data[Couche].getChildCount();
println(" " + s2 +" : NombreDeChild2 = " + NombreDeChild2 + " child(s)" );
// println();
// background(255);
// textFont(maFonte, 24);
textFont(maFonte, 16);
fill(255, 0, 0, 100);
for (int i = 0; i < NombreDeChild2; i++) {
XMLElement kid1 = kidkid1Data[Couche].getChild(i);
int n = kid1.getInt("n");
float xmin = kid1.getFloat("xmin");
float xmax = kid1.getFloat("xmax");
String Content1 = kid1.getContent();
println("Child(" + i + "): n = " + n + " xmin = " + xmin + " xmax = " + xmax + " " + Content1);
if (Content1 == null) {
}
else if (Content1.equals("_") == true) //Elimination des caracteres _ qui separe les segments
{
}
else {
if (Alea) {
text(Content1, random(1, 790), random(1, 590));
}
else {
text(Content1, 5, i * 16);
}
}
}
}
void EffaceEcran() {
// background(255); // Fond blanc
noStroke(); // pas de contour
fill(200); // Blanc
rect(0, YPitch(500), width, YIntensity(40) - YPitch(500));
// AfficheCouche(Couche);
// textFont(maFonte, 16);
//text("Fichier: " + NomFichierPitch + " ("+ LignesPitch.length + " LignesPitch)", 5, 10);
textFont(maFonte, 12);
stroke(0, 0, 0); // Ligne noire
fill(0, 0, 0); // Texte noir
line(0, YPitch(75), width, YPitch(75));
text("75Hz", width - 40, YPitch(75) - 10);
line(0, YPitch(500), width, YPitch(500));
text("500Hz", width - 40, YPitch(500) + 2);
text("Pause : Espace", width - 85, 575);
fill(255, 0, 0); // Texte rouge
stroke(255, 0, 0); // Ligne rouge
text("100dB", width - 40, YPitch(75) + 2);
text("40dB", width - 40, YIntensity(40) - 10);
line(0, YIntensity(40), width, YIntensity(40));
// line(0, YIntensity(40), width, YIntensity(100));
xAvantPitch = 0;
yAvantPitch = YPitch(75) ;
xAvantIntensity = 0;
yAvantIntensity = YIntensity(40) ;
}
void Debut() {
TempsPause = millis();
IndexPitch = 0;
IndexIntensity = 0;
IndexXML = 0;
IndexXMLCouche4 = 0;
EffaceEcran();
PlayerAudioDebut();
}
void PlayerAudioDebut() {
player.close();
player = minim.loadFile(NomFichierAudio, 2048);
player.play();
}
void keyPressed() {
// println("key = " + key);
if (key == ' ') { // barre d'espace
ToucheEspace = ! ToucheEspace;
Pause = ToucheEspace;
if (Pause) {
player.pause();
TempsDebutPause = millis();
}
else {
player.play();
TempsPause = TempsPause + millis() - TempsDebutPause;
}
}
else if ( key == 'p' || key == 'P' )
{
Couche = 0; // P Phonème
Debut();
}
else if (key == 'y' || key == 'Y')
{
Couche = 1; // Y Syllabe
Debut();
}
else if (key == 'm' || key == 'M')
{
Couche = 2; // M Mot
Debut();
}
else if (key == 'h' || key == 'H')
{
Couche = 3; // H Phonétique
Debut();
}
else if (key == 'o' || key == 'O')
{
Couche = 4; // O Orthographique
Debut();
}
// else if (key == 'a' || key == 'A')
// {
// Alea = !Alea;
// EffaceEcran();
// }
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
player.close();
minim.stop();
super.stop();
}