/* top
Calcul de la transformée de Fourier rapide d'un signal audio au format PCM enregistré dans un fichier .wav
Format WAVE, RIFF, fmt échantilloné à 48000Hz
Format : Wave
File size : 2.39 MiB
Duration : 13 s 54 ms
Overall bit rate mode : Constant
Overall bit rate : 1 536 kb/s
Audio
Format : PCM
Format settings : Little / Signed
Codec ID : 1
Duration : 13 s 54 ms
Bit rate mode : Constant
Bit rate : 1 536 kb/s
Channel(s) : 2 channels
Sampling rate : 48.0 kHz
Bit depth : 16 bits
Stream size : 2.39 MiB (100%)
Programme écrit par Silicium628
ce logiciel est libre et open source
*/
/*
***** RAPPEL**** (source: https://helpx.adobe.com/fr/audition/using/digitizing-audio.html) **
Taux d’échantillonnage Niveau de qualité Plage de fréquences
11,025 Hz Faible qualité radio AM (multimédia bas de gamme) 0- 5 512 Hz
22,050 Hz Comparable à la qualité radio FM (multimédia haut de gamme) 0-11 025 Hz
32 000 Hz Meilleur que la qualité radio FM (taux de diffusion standard) 0-16 000 Hz
44 100 Hz CD 0-22 050 Hz
48 000 Hz DVD standard 0-24 000 Hz
96 000 Hz DVD Blu-ray 0-48 000 Hz
*********************************************************************************************/
/*
Le présent logiciel est paramétré pour traiter les fichiers audio ECHANTILLONES à 48000Hz (qualité DVD)
ET PAS 44.1 !!
Je le rendrai compatible avec les autres taux, mais pour l'instant il faut enregistrer
au préalable l'audio à traiter avec un taux de 48kHz
(par exemple avec Audacity, c'est facile voir en bas à gauche de sa fenêtre).
*/
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "math.h"
#include "complexe.cpp"
#include <QMessageBox>
#include <QFileDialog>
#include <QFile>
//#include <QImage>
#include <QtMultimedia/QMediaPlayer>
#include <QAudioOutput>
#include <QMouseEvent>
#include <QDate>
#include <QDateTime>
#include <QScrollBar>
/*
#include "var_generales.h"
#include "instruments.h"
*/
/* FFT_wav */
//=============================================================================================
// nouvelle numérotation par (date de compilation + 1 lettre si plusieurs compils le même jour)
// toute version antérieure à la plus récente doit être jetée dans la poubelle jaune.
QString version = "2025-06-23 a";
//=============================================================================================
int write_mode =0;
QString couleur_ecran = "#141414";
QString couleur_ligne = "#878787";
QString couleur_trace1 = "#0EA004";
QString couleur_trace2 = "#00FFFF";
QString couleur_curseur = "#FFFF00";
QString couleur_texte = "#FFFF00"; // JAUNE
QString couleur_encadrement = "#FF0000"; // ROUGE
QPen pen_ligne(QColor(couleur_ligne), 1, Qt::SolidLine);
QPen pen_trace1(QColor(couleur_trace1), 1, Qt::SolidLine);
QPen pen_trace2(QColor(couleur_trace2), 1, Qt::SolidLine);
QPen pen_curseur(QColor(couleur_curseur), 1, Qt::SolidLine);
QPen pen_reticule(QColor(couleur_ligne), 1, Qt::SolidLine);
QPen pen_encadrement(QColor(couleur_encadrement), 1, Qt::SolidLine);
char temp_entete[100]; // signal entete lu dans le fichier .wav
char temp_data[2000000]; // signal audio lu dans le fichier .wav (max 2MB)
int pas_echantillonage = 24;
const int _nb_ech = 2048;
Complexe ech[_nb_ech]; // nb_ech echantillons
Complexe tab_X[_nb_ech]; // nb_ech valeurs traitées
Complexe tab_W[_nb_ech];
bool tableau_w_plein = false;
uint8_t table_FREQ_midi[2000][1]; // [t][num_raie]
double table_integration_amplitudes[83];// [code midi]
uint16_t table_histogramme_durees[35]; // [valeur_duree] = nb d'occurences
const uint16_t _Hmax =42;
uint16_t table_histogramme_midi[_Hmax]; // [num_midi] = nb d'occurences
uint16_t table_histogramme_degre[12]; //[n°degre = 1..12] = nb d'occurences
double facteur_compression=1.0;
//double frequence1=400; // Hz
//double frequence2=400; // Hz
//double frequence3=100; // Hz
uint nb_etapes=10; // 10
uint nb_ech = pow (2, nb_etapes); // nombre d'échantillons = 2 puissance(nb_etapes) ->2^10 = 1024
double table_modules_FFT[_nb_ech /2]; // = 2^10
double x_clic_ecran, y_clic_ecran;
double x_clic_GRV4, y_clic_GRV4; // relatif à graphicsView4
double x0_boite, x1_boite, y0_boite, y1_boite;
int type_accords=0; // 1=MAJ; 2=min; 3=7e dom
int nb_tics;
int nb_tics2=0;
int delta_barre=0;
int num_barre_en_cours=0; // permet de tracer l'avancement de l'exécution des notes du morceau
int num_barre_saisie=0; // pour le composeur manuel
long T_i=0; // variable GLOBALE
int n_player=1;
double seuil;
double gain =1.0;
int num_note_depart;
int num_note_cliquee=0;
int num_note_jouee=0;
int num_ligne_en_cours=0; // lignes du tableWidget_3
int n_midi_jouee;
int ligne_TW3;
int nb_acc=0;
int num_note_max=0;
double memo_scroll_x=0;
QDateTime temps_0; // départ du jeu des notes
bool hamming = true;
bool bourrage_de_zeros = true;
// type de mesure noté Ta/Tb (4/4, 3/2 ...)
int8_t Ta = 4;
int8_t Tb = 4;
int n_barre_copie;
//QList<int> index_midi; // position x des notes midi sur le graphe FFT (à partir de midi=40)
//QList<QString> liste_couleurs;
QList<ENR_FFT> liste_ENR_FFT; // liste de "notes" détectées (maximums de FFT)
QList<NOTE> liste_NOTES;
//QList<QString> noms_notes;
QList<QString> gamme_chromatique;
QList<QString> gamme_chromatique_GB;
QList<QString> types_note;
QList<QString> types_silence;
QFile file_wav; // fichier à analyser
QFile file_dat; // datas du TAB_FRQ
QDir currentDir;
QString base_Dir;
QString default_Dir = "/home/";
QString string_currentDir = default_Dir; // à priori; sera mis à jour lors de la lecture du fichier 'params.ini'
QString string_currentFile;
QString nom_fichier_in="";
QDataStream binStream1;
double duree_totale; // calculée dans la fonction 'decode_entete'
double data_size; // calculée dans la fonction 'decode_entete'
bool wav_ok = false;
//bool dossier_de_travail_ok = false;
bool data_nts_ok = false;
bool rapide = false;
bool etendre = true;
bool mode_composition = false;
//bool visu_T = true;
//bool visu_notesM = false;
//bool visu_M; // echelle temporelle sous forme de mesures (temps forts, temps faibles)
//bool visu_T; // echelle temporelle simple en 1/40s
char mode = 'T'; // T ou M
bool visu_freq = true;
bool visu_ech_tps;
//bool mode_select = false;
bool visu_duree_notes = true;
int duree_int = 4;
bool visu_notes = true;
bool visu_notes_auto = true;
bool lecture_en_cours = false;
uint32_t offset_t;
double zoom_x =1.0;
QString repertoire_images= "./images/";
int case_min=0;
int case_max=20;
uint16_t largeur_image = 1216; // image du manche de la guitare
uint16_t hauteur_image = 180;
QList<uint16_t> positionsX;
bool notes_pleines = true; // concerne le graphique : ellipse pleine ou bien juste un cercle
bool notes_silencieuses; // pour représenter les positions d'accords, sans les jouer
bool mode_depot_note=false; // pour écrire la valeur midi d'une note dans TW3 suite à clic de droite le manche
//bool data_ok = false;
bool dossier_de_travail_ok = false;
int memo_corde_i;
int memo_case_i;
int corde_jouee;
int case_jouee;
int Tp1;
int temps1;
int nb_notes_jouees=0;
int nb_notes_jouees_max;
int lecture_pause=1; // fonction du bouton lecture / pause
QStringList liste_str_in;
QStringList liste_accords;
int nb_lignes;
int L_save_min=0;
int L_save_max=0;
int mesure_a_encadrer=0;
int memo_mesure_a_encadrer=0;
int num_colonne_a_encadrer=0;
int nb_colonnes_a_encadrer=1;
int zoom=1;
QList<QString> liste_couleurs;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
setupUi(this);
setWindowTitle("MUSIQUE - version " + version);
//this->setGeometry(0,0, 1900, 1000);
setWindowState(Qt::WindowMaximized);
Boite_Onglets_Global->setGeometry(0,0, 1920, 1280);
Boite_Onglets_Global->setCurrentIndex(0);
// frame_back->setGeometry(0, 0, 1900, 1050);
// ============================== ONGLET 0 (le plus à gauche) ============================================
// SCENE 1 - celle du haut ('Transformée de Fourier' ET 'partie échantillonée du signal')
scene1 = new QGraphicsScene(this);
scene1->setBackgroundBrush(QColor(couleur_ecran));
graphicsView1->setScene(scene1);
graphicsView1->setGeometry(0, 0, 1900, 655); //( 0, 0, 1900, 700)
graphicsView1->verticalScrollBar()->setValue(0);
calque_notes = new QGraphicsItemGroup();
scene1->addItem(calque_notes);
calque_reticule1 = new QGraphicsItemGroup();
scene1->addItem(calque_reticule1);
afficher_titre_calque("Transformée de Fourier", 0, 0, calque_reticule1);
calque_trace_signal1 = new QGraphicsItemGroup();
scene1->addItem(calque_trace_signal1);
calque_trace_FFT = new QGraphicsItemGroup();
scene1->addItem(calque_trace_FFT);
calque_curseur = new QGraphicsItemGroup();
scene1->addItem(calque_curseur);
calque_lignes_F_zero = new QGraphicsItemGroup();
scene1->addItem(calque_lignes_F_zero);
//-----------------------------------------------------
// SCENE 2 - celle du bas ('Fichier Audio .wav')
scene2 = new QGraphicsScene(this);
QBrush QB1("#222222");
scene2->setBackgroundBrush(QB1); // couleur_ecran
graphicsView2->setScene(scene2);
graphicsView2->setGeometry(0, 660, 1900, 200); // (0, 660, 1900, 200)
calque_trace_signal2 = new QGraphicsItemGroup();
scene2->addItem(calque_trace_signal2);
calque_reticule2 = new QGraphicsItemGroup();
scene2->addItem(calque_reticule2);
afficher_titre_calque("Fichier Audio .wav", 0, -80, calque_reticule2);
calque_encadrement1 = new QGraphicsItemGroup();
scene2->addItem(calque_encadrement1);
calque_encadrement2 = new QGraphicsItemGroup();
scene2->addItem(calque_encadrement2);
// =============== ONGLET 1 (le deuxième onglet, la numérotation débute à 0)- NOTES ===================================
// SCENE 3 - LISTE verticale NOTES
scene3 = new QGraphicsScene(this);
scene3->setBackgroundBrush(QColor(couleur_ecran));
graphicsView3->setScene(scene3);
calque_gradu_TAB_FRQ = new QGraphicsItemGroup();
scene3->addItem(calque_gradu_TAB_FRQ);
//-----------------------------------------------------
// SCENE 4 (grilles T et/ou M) (T comme temporelle, M comme mesures)
scene4 = new QGraphicsScene(this);
scene4->setBackgroundBrush(QColor(couleur_ecran));
GV_grillesTM->setScene(scene4);
calque_grille_M = new QGraphicsItemGroup();
scene4->addItem(calque_grille_M);
calque_grille_T = new QGraphicsItemGroup();
scene4->addItem(calque_grille_T);
calque_TAB_FRQ = new QGraphicsItemGroup();
scene4->addItem(calque_TAB_FRQ);
afficher_titre_calque("Table Fréquences & notes", 200, 0, calque_TAB_FRQ);
calque_notes_manuelles = new QGraphicsItemGroup();
scene4->addItem(calque_notes_manuelles);
calque_notes_auto = new QGraphicsItemGroup();
scene4->addItem(calque_notes_auto);
calque_notes_jouee = new QGraphicsItemGroup();
scene4->addItem(calque_notes_jouee);
calque_echelle_temporelle_T = new QGraphicsItemGroup();
scene4->addItem(calque_echelle_temporelle_T);
calque_echelle_temporelle_M = new QGraphicsItemGroup();
scene4->addItem(calque_echelle_temporelle_M);
calque_surbrillance= new QGraphicsItemGroup();
scene4->addItem(calque_surbrillance);
calque_rect_select= new QGraphicsItemGroup();
scene4->addItem(calque_rect_select);
//-----------------------------------------------------
// SCENE 5 - Histogramme
scene5 = new QGraphicsScene(this);
scene5->setBackgroundBrush(QColor(couleur_ecran));
graphicsView5->setScene(scene5);
calque_histogramme = new QGraphicsItemGroup();
scene5->addItem(calque_histogramme);
// ============================== ONGLET 2 - INSTRUMENTS ===============================================
// SCENE MANCHE (manche de la guitare)
scene_manche = new QGraphicsScene(this);
GRW_manche->setScene(scene_manche);
GRW_manche->setGeometry(10,100, largeur_image+20, hauteur_image+5);
Frame_wWidget1 = new QFrame();
charger_image_manche();
calque_notes_manche = new QGraphicsItemGroup();
scene_manche->addItem(calque_notes_manche);
calque_encadrement3 = new QGraphicsItemGroup();
scene_manche->addItem(calque_encadrement3);
case_min = 0;
case_max = 20;
//=========================================================================================================
Timer1 = new QTimer(this);
connect(Timer1, SIGNAL(timeout()), this, SLOT(Tic1()));
Timer2 = new QTimer(this);
connect(Timer2, SIGNAL(timeout()), this, SLOT(Tic2()));
Timer3 = new QTimer(this);
connect(Timer3, SIGNAL(timeout()), this, SLOT(Tic3()));
connect(TW_3->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(TW_3_scroll(int)));
//noms_notes<<"La"<<"Si"<<"Do"<<"Ré"<<"Mi" <<"Fa"<<"Sol"<<"--"<<"--"; // <- A B C D E F G
gamme_chromatique<<"Do"<<"Do#"<<"Ré"<<"Ré#"<<"Mi"<<"Fa"<<"Fa#"<<"Sol"<<"Sol#"<<"La"<<"La#"<<"Si";
//la gamme GB commence en principe par la lettre A (=La) mais pour simplifier ce programme
//on la fait partir de C (=Do) comme la gamme FR...
gamme_chromatique_GB<<"C"<<"C#"<<"D"<<"Eb"<<"E"<<"F"<<"F#"<<"G"<<"G#"<<"A"<<"A#"<<"B";
types_note <<"ronde"<<"blanche"<<"noire"<<"croche"<<"double croche"<<"triple croche"<<""<<"";
types_silence << "pause" << "demi-pause" << "soupir" << "demi-soupir" << "quart de soupir" << "";
// dans la liste suivante, la première couleur (#0)->"#EF2929" est le rouge pour la note DO
liste_couleurs <<"#EF2929"<<"#FF5C00"<<"#FCAF3E"<<"#FFE300"<<"#BFFF00"<<"#07F64F"
<<"#16D298"<<"#16D2C4"<<"#00AEFF"<<"#1667D2"<<"#7C00FF"<<"#FF67EF"<<"#EEEEEC"; //(la dernière = GRIS)
positionsX << 5 << 55 << 140 <<225 << 305 << 385 << 459 << 528 << 595 << 650 << 714 << 765
<< 820 << 864 << 910 << 960 << 1000 << 1035 << 1072 << 1111 << 1145;
// 21 valeurs en comptant les cordes à vide
player1 = new QMediaPlayer;
audioOutput1 = new QAudioOutput(this);
player1->setAudioOutput(audioOutput1);
player2 = new QMediaPlayer;
audioOutput2 = new QAudioOutput(this);
player2->setAudioOutput(audioOutput2);
player3 = new QMediaPlayer;
audioOutput3 = new QAudioOutput(this);
player3->setAudioOutput(audioOutput3);
player4 = new QMediaPlayer;
audioOutput4 = new QAudioOutput(this);
player4->setAudioOutput(audioOutput4);
player5 = new QMediaPlayer;
audioOutput5 = new QAudioOutput(this);
player5->setAudioOutput(audioOutput5);
parametrages();
if(1)
{
//pour la phase de developpement
afficher_titre_calque("Scene1", 100, 200, calque_trace_FFT);
afficher_titre_calque("Scene2", 20, 20, calque_trace_signal2);
afficher_titre_calque("Scene3", 10, 10, calque_gradu_TAB_FRQ);
afficher_titre_calque("Scene4", 100, 100, calque_grille_T);
afficher_titre_calque("Scene5", 20, 20, calque_histogramme);
}
init_TW_3();
on_Bt_AddLine_clicked();
}
void MainWindow::parametrages()
{
load_fichier_ini();
calcul_tableau_W();
tracer_graduations_signal();
tracer_graduations_FFT();
init_TW_1();
init_TAB_FRQ();
init_TAB_lst_notes();
init_TW_type_M();
init_Autres();
init_onglet_instruments();
init_TW_T();
init_TW_doigts();
seuil = doubleSpinBox_seuil->value();
on_Bt_par_defaut_clicked();// valeurs FFT par défaut
write_mode=0;
on_Bt_mode_R_clicked();
visu_notes_auto = false;
on_Bt_toggle_visu_notes_auto_clicked();
visu_notes = false;
on_Bt_toggle_visu_notes_clicked();
on_tableWidget_type_M_cellClicked(2, 0);
spinBox_zoom_2->setValue(2);
// Bt_jouer_tout->setStyleSheet("background-color: rgb(200, 200, 200);");
progressBar_1->setValue(0);
effacer_calque(scene1,calque_lignes_F_zero );
effacer_calque(scene1,calque_encadrement1 );
effacer_calque(scene1,calque_trace_signal1 );
effacer_calque(scene1,calque_trace_FFT );
effacer_calque(scene1,calque_curseur );
effacer_calque(scene2,calque_encadrement2 );
effacer_calque(scene2, calque_trace_signal2 );
effacer_calque(scene4,calque_TAB_FRQ );
effacer_calque(scene4, calque_notes_manuelles );
effacer_calque(scene4, calque_notes_auto );
effacer_calque(scene4, calque_notes_jouee );
effacer_calque(scene4, calque_echelle_temporelle_T);
for(int i=0; i<35; i++) { table_histogramme_durees[i]=0; }
effacer_calque(scene5, calque_histogramme );
on_Bt_RAZ_clicked();
T_i=0; // T_i : variable GLOBALE
doubleSpinBox_dxb->setValue(2.5);
mode='M';
on_Bt_toggle_grille_T_clicked();
mode_grille_T();
spinBox_nb_barres->setValue(40);
effacer_calque(scene4, calque_grille_T);
tracer_grille_T();
checkBox_scrolling->setChecked(true);
SBX_de->setValue(0); case_min = 0;
SBX_a->setValue(20); case_max = 20;
}
void MainWindow::init_TAB_FRQ()
{
frame_notes->setGeometry(0,0,1920,720);
graphicsView3->setGeometry(0, 30, 100, 730);
GV_grillesTM->setGeometry(100, 30, 2000, 730);
GV_grillesTM->setEnabled(false); // empêche le recadrage auto par le contenu, mais disable le scroll manuel !
rectangle1 = new QGraphicsRectItem(0, 0, 2000, 670);
rectangle1->setPen(QColor(couleur_ligne));
calque_TAB_FRQ->addToGroup(rectangle1);
tracer_graduation_TAB_NOTES();
tracer_grille_M();
}
void MainWindow::init_TAB_lst_notes()
{
TW_lst_notes->setGeometry(1105, 30, 350, 201);
QStringList liste_entetes1;
liste_entetes1<<"num"<<"midi"<<"note"<<"n° barT"<< "n° barM)" << "durée";
TW_lst_notes->setColumnWidth(1, 40);
TW_lst_notes->setColumnWidth(5, 50);
TW_lst_notes->setHorizontalHeaderLabels (liste_entetes1);
TW_lst_notes->setEditTriggers(QAbstractItemView::NoEditTriggers);
}
void MainWindow::init_TW_T() // TimeLine sur onglet 'INSTRUMENTS'
{
TW_TimeLine->setGeometry(10, 860, 1880, 135);
TW_TimeLine->setColumnCount(300);
label_timeline->setGeometry(10, 830, 100, 30);
TW_TimeLine->clear();
for(int n=0; n< TW_TimeLine->columnCount(); n++)
{
complete_case(0, n, "-", "#000000", "#FFFFFF", false, TW_TimeLine);
//complete_case(5, n, "-", "#000000", "#FFFFFF", tableWidget_T);
}
}
void MainWindow::init_TW_doigts()
{
TW_doigts->setGeometry(5, 20, 200, 200);
TW_doigts->clear();
TW_doigts->setRowCount(5);
TW_doigts->setColumnCount(3);
QStringList liste_entetesH;
liste_entetesH <<"corde"<<"case"<<"DOIGT";
TW_doigts->setHorizontalHeaderLabels (liste_entetesH );
QStringList liste_entetesV;
liste_entetesV <<"0"<<"1"<<"2"<<"3"<<"4";
TW_doigts->setVerticalHeaderLabels(liste_entetesV );
for(int n=0; n<5; n++)
{
QTableWidgetItem *Item1 = new QTableWidgetItem();
Item1->setIcon(QIcon("../images/02.png" ));
TW_doigts->setItem(n, 2, Item1 );
}
TW_doigts->resizeColumnsToContents();
TW_doigts->setColumnWidth(2, 20);
// pushButton_6->setGeometry(189, 0, 22, 21); // bouton aide position des doigts
Bt_copie_doigts_to_TW3->setGeometry(50, 147, 150, 26);
Bt_RAZ_doigts->setGeometry(10, 147, 31, 26);
int R, C;
for (R=0; R<5; R++)
{
for (C=0; C<2; C++)
{
TW_doigts->setItem(R, C, new QTableWidgetItem ("-") );
TW_doigts->item(R,C)->setTextAlignment(Qt::AlignCenter);
}
}
}
void MainWindow::init_Autres()
{
// frame_1->setGeometry(1250, 865, 410, 131);
// frame_1->setVisible(true);
frame_2->setGeometry(10, 865, 970, 75);
frame_3->setGeometry(1000, 865, 665, 121);
frame_5->setGeometry(0, 760, 1920, 260); // 0, 760, 1920, 260
frame_6->setGeometry(10, 950, 901, 40);
graphicsView5->setGeometry(1460, 15, 440, 235); //225 histogrammes
graphicsView5->setScene(scene5);
// voir le fichier de ressources
// Le fichier image est incorporé sous forme de ressource, il sera compilé et fera partie du programme
// l'image sera dispo quelle que soit l'emplacement de l'executable,
// et en particulier si celui-ci est appellé via un lien.
Bt_deplace_H->setIcon(QIcon(":/images/01.png" )); // Le fichier image est incorporé sous forme de ressource
Bt_deplace_B->setIcon(QIcon(":/images/02.png" ));
Bt_deplace_R->setIcon(QIcon(":/images/03.png" ));
Bt_deplace_L->setIcon(QIcon(":/images/04.png" ));
Bt_efface->setGeometry(915, 950, 60, 21);
Bt_efface_2->setGeometry(1165, 0, 81, 26);
Bt_9->setGeometry(1290, 10, 31, 20);
Bt_open_DIR_2->setGeometry(912, 40, 70, 26);
Bt_choix_current_dir_3->setGeometry(985, 40, 90, 26);
frame_8->setGeometry(1500, 740, 400, 30); // boutons "debut , < , > , fin"
frame_9->setGeometry(1760, 850, 100, 70);
frame_11->setGeometry(200, 152, 145, 21); // copie groupe de notes
Bt_save_notes->setGeometry(930, 5, 151, 31);
Bt_RAZ_general->setGeometry(1700, 900, 150, 50);
lineEdit_fichier_FREQ->setGeometry(1250, 0, 700, 22);
progressBar_1->setGeometry(98, 4, 101, 18); //(1085, 3, 78, 18);
lineEdit_fichier->setGeometry(380, 40, 530, 26);
groupBox_2->setGeometry(380, 70, 350, 161);
groupBox_3->setGeometry(750, 70, 351, 161);
Bt_dedoubleM->setGeometry(110, 5, 92, 26);
// Bt_copie_depuis_TW3->setGeometry(200, 700, 200, 26);
// Bt_copie_depuis_Instruments->setGeometry(200, 700, 251, 26);
// label_image1->setGeometry(1800, 780, 10, 10);
frame_cle_de_sol->setGeometry(1700, 10, 200, 340); //1800, 805, 100, 170
frame_cle_de_sol->setVisible(false);
Bt_composition->setGeometry(1800, 10, 100, 30); // bouton 'Composition'
frame_composeur->setGeometry(1435, 80, 260, 181);
frame_composeur->setVisible(false);
label_SEL_P_BOITE->setGeometry(120, 40, 260, 20);
label_SEL_P_BOITE->setVisible(false);
GRBX_conf_accords->setGeometry(20, 450, 350, 181); // Configurateur d'Accords
GRBX_pos_doigts->setGeometry(380, 450, 210, 180); // Position des doigts
GRB_gestion_TW3->setGeometry(900, 490, 311, 351);
GRBX_sigles->setGeometry(670, 640, 150, 121);
GBX_general->setGeometry(670, 450, 200, 180);
LBL_corde->setGeometry(900, 435, 111, 25);
LBL_case->setGeometry(900, 460, 111, 25);
create_100_lignes_V();
tracer_gradu_temporelle_signal_entree();
tracer_graduations_signal();
label_MESSAGE->setVisible(false);
}
void MainWindow::init_TW_type_M()
{
frame_4->setGeometry(210, 5, 140, 90);
frame_7->setGeometry(210, 100, 140, 50);
frame_10->setGeometry(185, 100, 185, 50);
tableWidget_type_M->setGeometry(5, 20, 40, 62);
lineEdit_10->setGeometry(55, 30, 51, 26);
lineEdit_11->setGeometry(55, 60, 51, 26);
label_8->setGeometry(2, 2, 111, 20);
label_39->setGeometry(108, 63, 40, 20);
QStringList liste_labels; // pour mettre directement dans la 1ere colonne (et pas en entêtes)
liste_labels << "2/4" << "3/4" << "4/4";
for(int n=0; n<3; n++) { tableWidget_type_M->setItem(0, n, new QTableWidgetItem (liste_labels[n])); }
}
void MainWindow::init_TW_1() // affi entete du fichier wav
{
TW_entete_wav->setGeometry(700, 200, 600, 300);
Bt_close_entete->setGeometry(1280, 200, 20, 20);
TW_entete_wav->setColumnCount(6);
TW_entete_wav->setColumnWidth(4, 120);
TW_entete_wav->setColumnWidth(5, 130);
TW_entete_wav->setVisible(false);
Bt_close_entete->setVisible(false);
QStringList liste_entetes;
liste_entetes <<"FileTypeBlocID"
<<"FileSize"
<<"FileFormatID"
<<"FormatBlocID"
<<"BlocSize"
<<"AudioFormat"
<<"NbrCanaux"
<<"Frequence"
<<"ECH (BytePerSec)"
<<"BytePerBloc"
<<"BitsPerSample"
<<"DataBlocID"
<<"DataSize"
<<"durée calculée";
TW_entete_wav->setVerticalHeaderLabels(liste_entetes);
}
void MainWindow::init_TW_3() // affi liste verticale sur ongler 'INSTRUMENTS'
{
label_TW3->setGeometry(1205, 10, 50, 18);
TW_3->setGeometry(1250, 10, 640, 836); //(1250, 10, 640, 836) la valeur 836 est critique pour l'encadrement ok
TW_3->clear();
TW_3->setRowCount(0);
TW_3->setColumnCount(13);
QStringList liste_entetes;
liste_entetes << "num" <<"note1"<<"note2"<<"note3"<<"Cmt"<<">"<<"dur"<<"M"<<"tps"<< "n°b"<<"ACC"<<"cases"<<"doigts";
TW_3->setHorizontalHeaderLabels (liste_entetes );
TW_3->resizeColumnsToContents();
for(int n=0; n<=5; n++)
{
on_Bt_AddLine_clicked();
}
}
void MainWindow::load_fichier_ini()
{
QString line;
int p1, p2, p3;
dossier_de_travail_ok = false; // à priori
QFile file1(QDir::currentPath() + "/" + "params_FFT.ini"); // dans le dossier de l'exécutable (= QDir::currentPath() )
if (file1.open(QIODevice::ReadOnly | QIODevice::Text))
{
QTextStream in(&file1);
in.reset();
while ( !in.atEnd() )
{
line = in.readLine();
if (line.at(0) !='#')
{
if ((p1 = line.indexOf("<currentDir>")) != -1)
{
p2 = line.indexOf('>',p1);
p3 = line.indexOf("</",p2);
QString s1 = line.mid(p2+1, p3-p2-1);
string_currentDir = s1;
dossier_de_travail_ok = true;
}
if ((p1 = line.indexOf("<currentFile>")) != -1)
{
p2 = line.indexOf('>',p1);
p3 = line.indexOf("</",p2);
QString s1 = line.mid(p2+1, p3-p2-1);
string_currentFile = s1;
}
}
}
file1.close();
}
else
{
QString s1 = "fichier .ini non trouvé, je le crée (dans le dossier de l'executable)";
QMessageBox msgBox; msgBox.setText(s1); msgBox.exec();
base_Dir=QDir::currentPath() + "/";
save_fichier_ini();
dossier_de_travail_ok = false;
}
lineEdit_current_dir->setText(string_currentDir); // sur l'onglet 'source wav'
lineEdit_fichier->setText(string_currentDir); // sur l'onglet 'NOTES'
lineEdit_current_dir_2->setText(string_currentDir); // sur l'onglet 'INSTRUMENTS'
}
QString calcul_couleur(double x) // x = 0.0 à 1.0 ; return: rouge->jaune->vert
{
QString coul_str ="#000000";
QString coul_R_str="#000000";
QString coul_V_str="#000000";
int R, V; // rouge, vert
V= x * 255;
R= 300 - (1.2 * V);
double coxh;
// la formule suivante met le jaune en valeur (avec un cosinus hyperbolique)
coxh = 3.2 - 1.5 * cosh(2.6*x - 1.5); // merci kmplot (testez la courbe f(x) = 3.2 −1.5 * cosh(2.6x − 1.5) )
R *= coxh/1.2;
V *= coxh/1.2;
coul_R_str.setNum(R, 16); coul_R_str = "0" + coul_R_str; coul_R_str = coul_R_str.right(2);
coul_V_str.setNum(V, 16); coul_V_str = "0" + coul_V_str; coul_V_str = coul_V_str.right(2);
coul_str = coul_R_str + coul_V_str;
coul_str = "#" + coul_str + "00";
return coul_str; // de la forme "#AABB00" (rouge & vert en exa, (bleu à zéro, à traiter))
}
int MainWindow::calcul_y_note(int midi) // en pixels sur la grille
{
int y =690 - ((midi-28) * 12); // voir 'tracer_graduation_TAB_NOTES()' pour l'espacement vertical
return y;
}
int MainWindow::calcul_hauteur_note(int mid) //'hauteur' au sens musical, gamme chromatique de 0 à 11
{
int h1 = mid;
while(h1>=12) {h1-=12;}
while(h1<0) {h1+=12;}
if (h1==12) {h1=0;}
if ((h1<0) || (h1>(liste_couleurs.length()-1))) {h1 = 0;}
return h1; // h1 = 0..11
}
QString MainWindow::nom_note(int mid)
{
QString s1;
int h1 = calcul_hauteur_note(mid);
s1 = gamme_chromatique[h1];
return s1;
}
QString MainWindow::nom_note_GB(int mid)
{
QString s1;
int h1 = calcul_hauteur_note(mid);
s1 = gamme_chromatique_GB[h1];
return s1;
}
QString MainWindow::nom_octave_GB(int mid)
{
QString octave;
if((mid>=40)&&(mid < 48)) {octave = "2";}
if((mid>=48)&&(mid < 60)) {octave = "3";}
if((mid>=60)&&(mid < 72)) {octave = "4";}
if((mid>=72)&&(mid < 90)) {octave = "5";}
return octave;
}
double freq_mid(int midi_i) // calcule la fréquence (en Hertz) d'une note à partir de son numéro midi
{
// https://fr.wikipedia.org/wiki/MIDI_Tuning_Standard
double F, A;
A=((double)midi_i-69.0)/12.0;
F= 440 * powf(2,A);
return F;
}
double calcul_id_midi(double freq_i) // complément de la fonction précédente ( double freq_mid(int midi_i) )
{
double id;
id = 69.0 + 12.0 * log2(freq_i / 440.0);
return id;
}
/*
int MainWindow::calcul_num_midi(double x) // en fonction de la position horizontale dans le tableau d'affichage de la FFT
{
// on va détecter la note la plus proche de la position donnée
// rappel : x=96 +(m-28) * 32 (voir la fonction : 'tracer_graduations_FFT()')
double dx;
double xm;
for (int m=28; m<83; m++)
{
xm= 96.0 +(m-28) * 32.0;
dx = xm-x;
if (dx<0){dx=-dx;}
if (dx < (32.0/2) )
{
// encadrement_note(m);
return m;
}
}
return 0;
}
*/
int MainWindow::calcul_num_midi(double x) // en fonction de la position horizontale dans le tableau d'affichage de la FFT
{
// on va détecter la note la plus proche de la position donnée
// rappel : x=92 +(m-40) * 40.9 (voir la fonction : 'tracer_graduations_FFT()')
double dx;
double xm;
for (int m=40; m<83; m++)
{
xm= 92.0 +(m-40) * 40.9;
dx = xm-x;
if (dx<0){dx=-dx;}
if (dx < (40.9/2) )
{
encadrement_note(m);
return m;
}
}
return 0;
}
void MainWindow::play_note(int midi) // sortie audio; duree en nb de barres
{
if (notes_silencieuses == true) {return ;}
QString s1, freq_txt;
calcul_hauteur_note(midi);
s1.setNum(midi);
lineEdit_6->setText(s1);
lineEdit_n_midi->setText(s1);
float freq = freq_mid(midi-12);
freq_txt.setNum(freq,'f', 2);
lineEdit_freq->setText(freq_txt+" Hz");
// fichiers audio comprenant une seule note chacun, voir dans le dossier "notes" sur le HDD
//int D;
//if (mode == 'M') {D = 20;} else {D = 40;}
// (duree_i < D) { s1="notes2/"+s1+".wav"; } // (notes2 = notes +10dB)
if (checkBox_long->isChecked()) { s1="notes_longues/"+s1+".wav"; } // (notes2 = notes +10dB)
else { s1="notes2/"+s1+".wav"; }
if (n_player == 1) {player1->stop(); player1->setSource(QUrl::fromLocalFile(s1)); player1->play();}
if (n_player == 2) {player2->stop(); player2->setSource(QUrl::fromLocalFile(s1)); player2->play();}
if (n_player == 3) {player3->stop(); player3->setSource(QUrl::fromLocalFile(s1)); player3->play();}
if (n_player == 4) {player4->stop(); player4->setSource(QUrl::fromLocalFile(s1)); player4->play();}
if (n_player == 5) {player5->stop(); player5->setSource(QUrl::fromLocalFile(s1)); player5->play();}
n_player++;
if (n_player > 5) {n_player = 1;} // voir ligne 4013 RAZ du n° player, à voir
}
void MainWindow::effacer_calque(QGraphicsScene *scene_i, QGraphicsItemGroup *calque_i)
{
foreach( QGraphicsItem *item, scene_i->items( calque_i->boundingRect() ) )
{if( item->group() == calque_i ) { delete item; }}
}
MainWindow::~MainWindow()
{
}
void MainWindow::Etiquette(int x, int y, int dx, QString s, QString coul_txt, QString coul_fond, QString coul_bord, QGraphicsItemGroup *calque_i )
{
// si dx = 0 -> la largeur sera fonction du nb de caractères
if (dx==0)
{
dx = 8 * (s.length()+1 );
}
rect1 = new QGraphicsRectItem(x, y+4, dx, 18);
rect1->setPen(QColor(coul_bord)); // bordure
rect1->setBrush(QColor(coul_fond)); // fond
calque_i->addToGroup(rect1);
//texte
GraphicsTextItem = new QGraphicsTextItem(s);
GraphicsTextItem->setPos(x, y);
GraphicsTextItem->setDefaultTextColor(coul_txt);
calque_i->addToGroup(GraphicsTextItem);
}
void MainWindow::tracer_graduations_FFT() // sur onglet 'Source wav'
{
double x=0;
QString s1;
int y_bas =450; // 350
// cadre
rectangle1 = new QGraphicsRectItem(0, 0, 1900, y_bas);
QPen pen1("#12FF00");
rectangle1->setPen(pen1);
calque_reticule1->addToGroup(rectangle1);
s1 = "midi :"; // numéro midi
GraphicsTextItem = new QGraphicsTextItem(s1);
GraphicsTextItem->setDefaultTextColor("#FFFFFF");
GraphicsTextItem->setPos(30, 20);
// if(x<1900)
{
calque_reticule1->addToGroup(GraphicsTextItem);
}
// positions des notes midi
x= 96;
// for(int m=28; m<=83; m++)
for(int m=40; m<=83; m++)
{
ligne1 = new QGraphicsLineItem(x, 70, x, y_bas);
ligne1->setPen(pen_reticule);
calque_reticule1->addToGroup(ligne1);
s1.setNum(m); // numéro midi
GraphicsTextItem = new QGraphicsTextItem(s1);
GraphicsTextItem->setDefaultTextColor("#D3D7CF");
GraphicsTextItem->setPos(x-15, 20);
if(x<1900) {calque_reticule1->addToGroup(GraphicsTextItem); }
int h1 = calcul_hauteur_note(m);
s1 = " " + gamme_chromatique[h1]; // nom de la note
GraphicsTextItem = new QGraphicsTextItem(s1);
GraphicsTextItem->setDefaultTextColor(liste_couleurs[h1]);
GraphicsTextItem->setPos(x-18, 40);
if(x<1900) {calque_reticule1->addToGroup(GraphicsTextItem); }
//x+=32.0; // espacement des graduation
x+=40.9; // espacement des graduation
}
}
// voir fonction "void MainWindow::tracer_echelle_temps_TAB_NOTES()"
// dx = 1000.0 * pas_echantillonage/256.0; // = 1000 * 24 /256 = 93.75
double MainWindow:: calcul_pas_grille()
{
double pas = 0;
if (mode == 'T')
{
pas = 1000.0 * pas_echantillonage/256.0 / 40.0 * zoom_x; // 1 barre toutes les 1/40 seconde
}
if (mode == 'M')
{
pas = (doubleSpinBox_dxb->value()) * 1000.0 * pas_echantillonage/256.0 / 40.0 * zoom_x;
}
return pas;
}
/*
double MainWindow::calcul_pas_grille_M()
{
double pas_grille_M = (spinBox_dxa->value()+doubleSpinBox_dxb->value()) * 1000.0 * pas_echantillonage/256.0 / 40.0 * zoom_x;
return pas_grille_M;
}
*/
int MainWindow::calcul_tempo()
{
double dbar = doubleSpinBox_dxb->value(); // nb de barres de 1/40s séparant 2 barres de mesure
double dt = (8.0/40.0) * dbar; // en s
double nb_bpm = 60.0 / dt; // nb de barres / mn
//double Tp = nb_bpm / 8.0;
return int(nb_bpm);
}
double MainWindow::calcul_x_barre(int n_barre)
{
// calcul de l'abscisse (en pixel) d'une barre de mesure
double x =0;
double x0;
int x0a = spinBox_x0a->value();
double x0b = 80.0 + 10.0 * doubleSpinBox_x0b->value();
x0b += 20.0 * x0a;
if (mode == 'T')
{
x0 = 80.0; // 100 à voir !
x = x0 + double(n_barre) * calcul_pas_grille();
}
if (mode == 'M')
{
x = x0b + double(n_barre) * calcul_pas_grille();
}
return x;
}
/*
double MainWindow::calcul_x_barre_M(int n_barre)
{
double x = double(n_barre) * calcul_pas_grille_M();
return x;
}
*/
void MainWindow::trace_1_barre_M(double x_i, QString couleur_i)
{
if(x_i<0) {return;} // pour ne pas décaler tout l'affichage
QPen pen_i;
pen_i.setColor(couleur_i);
ligne1 = new QGraphicsLineItem(x_i, 0.0, x_i, 700.0);
ligne1->setPen(pen_i);
calque_grille_M->addToGroup(ligne1);
}
void MainWindow::tracer_grille_M()
{
effacer_calque(scene4, calque_echelle_temporelle_M);
double x1;
int num_temps=0;
QString s1;
QPen pen1;
QString couleur1;
QString gris_clair = "#888888";
QString gris_fonce = "#444444";
QString gris_tres_fonce = "#222222";
QString jaune = "#FFFF00";
QString cyan = "#00FFFF";
int num_mesure=0;
int us2=0; // une sur 2
for(int n=-500; n<=1000; n++)
{
// rappel : mesures type Ta/Tb dans le petit tableau 'Type Mesures'
// 3/4 -> Ta=3 & Tb=4
// 4/4 -> Ta=4 & Tb=4
x1 = calcul_x_barre(n);
couleur1 = gris_clair; // à priori
if (n%(4*Ta) == 0)
{
if(x1<0){num_mesure= -1;}
num_mesure++;
if(num_mesure>0)
{
couleur1 = cyan; us2 =0;
s1.setNum(num_mesure);
Etiquette(x1, 10, 0, s1, "#FFFFFF", "#000000", "#00FFFF", calque_echelle_temporelle_M ); // en haut
}
}
if ((Ta==4) && (1) && (num_mesure<10) && (n%(Ta/2) == 0) && (checkBox_numerotation->isChecked()))
{
// numérotation des temps au sein de chaque mesure
num_temps = n/(Ta/2);
if ((num_temps>=0) && (num_temps<80)) // <8
{
int dy =0;
int nt2 =num_temps/2;
nt2 = nt2 %4;
s1.setNum(nt2 + 1);
if(num_temps%2 == 1)
{
s1 = "&";
dy = 10;
}
Etiquette(x1, 400-dy, 0, s1, "#FFFFFF", "#000000", "#444444", calque_echelle_temporelle_M );// au milieu
}
}
us2++;
if ((us2 %2)==0) { couleur1 = gris_fonce; }
if(n==0){couleur1 = jaune;}
trace_1_barre_M(x1, couleur1); // principale
}
for(int n=0; n<55; n++)
{
int y = 40 + 12*n;
ligne1 = new QGraphicsLineItem(0, y, 12000, y);
pen1.setColor("#555555");
ligne1->setPen(pen1);
calque_grille_T->addToGroup(ligne1);
}
double Tempo = calcul_tempo();
s1.setNum(Tempo);
lineEdit_11->setText(s1); // BPM
// Etiquette(0, 0, 0, s1, "#FFFFFF", "#000000", "#FF00FF", calque_echelle_temporelle_T );
// s1 = "BPM";
/*
GraphicsTextItem = new QGraphicsTextItem(s1);
GraphicsTextItem->setPos(45, 0);
GraphicsTextItem->setDefaultTextColor("#FF00FF");
calque_echelle_temporelle_T->addToGroup(GraphicsTextItem);
*/
}
void MainWindow::tracer_grille_T()
{
//grille T sur l'onglet NOTES (barres verticales)
QString s1;
// QString bleu_clair = "#00AAFF";
// QString jaune = "#FFFF00";
QString gris_clair = "#CCCCCC";
QString gris_fonce = "#777777";
QString gris_tres_fonce = "#444444";
QString couleur_i;
QPen pen_i;
double x_i1;
//int num_mesure;
int nb = spinBox_nb_barres->value();
int n_zero = spinBox_barre_zero->value();
for(int n=0; n<=120*16; n++)
{
if (Ta<2) {Ta=2;}
x_i1 = calcul_x_barre(n);
couleur_i = gris_tres_fonce; // à priori
if (((n-n_zero)%nb) == 0) { couleur_i ="#00AAAA"; } //couleur_i = gris_fonce;
/*
if ( n%(4*Ta) == 0) // 1er temps fort de la mmesure
{
// numérotation des mesures, en bas, chiffres jaunes
num_mesure = n /Ta/4;
s1.setNum(num_mesure);
Etiquette(x_i1-0, 0, 650, s1, "#FFFF00", "#000000", "#0000FF", calque_grille_T);
}
*/
//if ( n%(4*m)== 0) {couleur_i = jaune;}
pen_i.setColor(couleur_i);
ligne1 = new QGraphicsLineItem(x_i1, 0.0, x_i1, 700.0); //100.0 pour test des 2 grilles ensemble
ligne1->setPen(pen_i);
calque_grille_T->addToGroup(ligne1);
}
for(int n=0; n<55; n++)
{
int y =40 + 12*n;
ligne1 = new QGraphicsLineItem(0, y, 12000, y);
pen_i.setColor("#555555");
ligne1->setPen(pen_i);
calque_grille_T->addToGroup(ligne1);
}
}
void MainWindow::afficher_titre_calque(QString titre, int x, int y, QGraphicsItemGroup *calque_i)
{
GraphicsTextItem = new QGraphicsTextItem(titre);
GraphicsTextItem->setDefaultTextColor("#FFFFFF");
GraphicsTextItem->setPos(x, y);
calque_i->addToGroup(GraphicsTextItem);
}
void MainWindow::tracer_graduation_TAB_NOTES() // midi ; en colonne à gauche + noms des notes
{
// positions des notes midi
QString s1;
int y= 640; //640
for(int m=28; m<=82; m++)
{
//ligne1 = new QGraphicsLineItem(100, 0, 100, 350);
//ligne1->setPen(pen_reticule);
//calque_reticule1->addToGroup(ligne1);
s1.setNum(m); // numéro midi
GraphicsTextItem = new QGraphicsTextItem(s1);
GraphicsTextItem->setDefaultTextColor("#D3D7CF");
GraphicsTextItem->setFont(QFont("Arial", 8));
GraphicsTextItem->setPos(0, y);
if(y> -50) {calque_gradu_TAB_FRQ->addToGroup(GraphicsTextItem); }
int h1 = calcul_hauteur_note(m);
s1 = " " + gamme_chromatique[h1]; // nom de la note
GraphicsTextItem = new QGraphicsTextItem(s1);
GraphicsTextItem->setDefaultTextColor(liste_couleurs[h1]);
GraphicsTextItem->setFont(QFont("Arial", 8));
// GraphicsTextItem->setHtml("<div style='background-color:#666666;'>" + s1 + "</div>");
if (m==69) // La 440
{
rect3 = new QGraphicsRectItem(30, y+6, 40, 10);
QBrush br2;
QPen pen_i;
pen_i.setColor("#AAAAAA");
rect3->setPen(pen_i);
calque_gradu_TAB_FRQ->addToGroup(rect3);
}
GraphicsTextItem->setPos(30, y);
if(y > -50) {calque_gradu_TAB_FRQ->addToGroup(GraphicsTextItem); }
y-=12; //16 espacement des graduations
}
GV_grillesTM->verticalScrollBar()->setValue(0);
}
void MainWindow::tracer_graduations_signal() // sur le 1er onglet (Source.wav)
{
/*
midi57 = 110Hz
1/110Hz = 9ms -> delta x = 142-46 = 96px
echelle x = 96/9 = 10.6 px/ms
soit:
10ms -> 106px
*/
double x;
double nb_grad_max;
double intervalle; // séparant les graduations
QPen pen1;
// int num_x;
//QString sti;
// uint decal = 3; // leger decallage vertical pour ne pas masquer la trace
/*
rectangle1 = new QGraphicsRectItem(5, 452, 1900, 200);
pen1.setColor("#0073FF");
rectangle1->setPen(pen1);
calque_reticule1->addToGroup(rectangle1);
ligne1 = new QGraphicsLineItem(10, 475, 1900, 475); // ligne horizontale
pen1.setColor("#0073FF");
ligne1->setPen(pen1);
calque_reticule1->addToGroup(ligne1);
*/
afficher_titre_calque("Partie échantillonée du signal", 0, 452, calque_reticule1);
// lignes verticales
intervalle = 106;
nb_grad_max = 18;
for (int i=0; i<=nb_grad_max; i++)
{
x = intervalle * i;
ligne1 = new QGraphicsLineItem(x, 452, x, 780);
ligne1->setPen(pen_reticule);
}
/*
// lignes horizontales
intervalle = 55;
nb_grad_max = 3;
for (i=0; i<=nb_grad_max; i++)
{
y = 300 - intervalle * i;
ligne1 = new QGraphicsLineItem(0, y, 1350, y);
ligne1->setPen(pen_reticule);
calque_reticule1->addToGroup(ligne1);
}
texte_mid = new QGraphicsTextItem("Silicium628");
texte_mid->setDefaultTextColor(couleur_signature);
texte_mid->setPos(5,5);
calque_reticule1->addToGroup(texte_mid);
*/
scene1->addItem(calque_reticule1);
}
void MainWindow::tracer_gradu_temporelle_signal_entree()
{
// GRADUATION TEMPORELLE sur le signal d'entrée, en secondes; (scene2 sur onglet 'Source wav')
QString s1, s2;
int x=0;
int dy = 75;
int nb_s, nb_mn;
double pas =8;
for(int n=0; n<2400; n++) // 1200
{
if (n%10 == 0) { dy = 75; }
else if (n%5 == 0) {dy = 20; }
else {dy = 10;}
x = n *pas;
ligne1 = new QGraphicsLineItem(x, -dy, x, dy);
QPen P1("#AAAAAA");
ligne1->setPen(P1);
calque_reticule2->addToGroup(ligne1);
if (n%10 == 0)
{
nb_s = n/10;
s1.setNum(nb_s);
s1+="s";
if (nb_s>60)
{
nb_mn = nb_s/60;
nb_s -= nb_mn * 60;
s1.setNum(nb_s);
if (nb_s<10) {s1 = "0" +s1;}
s2.setNum(nb_mn);
s1 = s2 + ":" + s1;
}
GraphicsTextItem = new QGraphicsTextItem(s1);
GraphicsTextItem->setDefaultTextColor(couleur_texte);
GraphicsTextItem->setPos(x,55);
if(x<20000) {calque_reticule2->addToGroup(GraphicsTextItem); }//6000
}
}
}
void MainWindow::tracer_signal_complet() // totalité du fichier wav (dans le cadre du bas du 1er onglet)
{
uint8_t octet_n=0;
double R;
double offset_y = 0.0;
double echelle_y =doubleSpinBox_gain->value();
double echelle_x =0.2;
int x, y, memo_x, memo_y;
double min= 1000000.0;
double max=-1000000.0;
int pas = 10 * pas_echantillonage; // 240;
//rappel : duree_totale = data_size / 96000;
// le signal wav est échantillonné à l'origine à 96000 Bps (séréo 2*fois 48000 Bps)
// en ne prenant qu'un octet sur 24 on obtient 4000 Bps.
QString s1;
effacer_calque(scene2, calque_trace_signal2 );
segment_trace = new QGraphicsLineItem(0, offset_y, 512, offset_y);
QPen P1("#0000FF");
segment_trace->setPen(P1); //couleur_ligne
calque_trace_signal2->addToGroup(segment_trace);
x=0;
y=offset_y;
double n_max=1;
if (pas !=0) {n_max = data_size / pas;}
long n;
long i=0;
// int j=0;
for(n=0; n<n_max; n+=10)
{
memo_x = x;
memo_y = y;
x = echelle_x * n;
if (i < 2000000)
{
octet_n = temp_data[i]; // canal 1}
}
R = octet_n - 128; // pour ôter la composante continue propre au codage par des octets non signés
R *= echelle_y;
R *= doubleSpinBox_gain->value();
y=offset_y + R;
// recherche du mini-maxi:
if (y < min) {min = y;}
if (y > max) {max = y;}
//if (x<3000) //3000
{
segment_trace = new QGraphicsLineItem(memo_x ,memo_y, x, y);
QPen P1("#0055FF");
segment_trace->setPen(P1);
calque_trace_signal2->addToGroup(segment_trace);
}
i+= pas; // le nb de pas étant pair, on retombe toujours sur le même canal (droite ou gauche)
}
//scene1->addItem(calque_trace_signal);
s1.setNum(min);
//lineEdit_4->setText(s1);
s1.setNum(max);
// lineEdit_5->setText(s1);
}
void MainWindow::encadrement_signal(int x, int dx)
{
ligne1 = new QGraphicsLineItem(x, -80, x, 80);
ligne1->setPen(pen_encadrement);
calque_encadrement2->addToGroup(ligne1);
ligne1 = new QGraphicsLineItem(x+dx, -80, x+dx, 80);
ligne1->setPen(pen_encadrement);
calque_encadrement2->addToGroup(ligne1);
ligne1 = new QGraphicsLineItem(x, -80, x+dx, -80);
ligne1->setPen(pen_encadrement);
calque_encadrement2->addToGroup(ligne1);
ligne1 = new QGraphicsLineItem(x, 80, x+dx, 80);
ligne1->setPen(pen_encadrement);
calque_encadrement2->addToGroup(ligne1);
}
void MainWindow::encadrement_note(int n_midi) // par un rectangle sur l'onglet 'Source wav'
{
double x, dx, y, dy;
x=92 - 13 + ((double)n_midi-40.0) * 40.9;
dx=35;
y=16;
dy=50;
rectangle1 = new QGraphicsRectItem(x, y, dx, dy);
rectangle1->setPen(pen_encadrement);
calque_trace_FFT->addToGroup(rectangle1);
}
void MainWindow::tracer_signal_a_convertir() //partie à analyser s=f(t) (signal incident, pas le FFT); dans le cadre du haut
{
double offset_y = 575.0;
double echelle =5.0;
uint8_t octet_n;
double R;
double x, y, memo_x, memo_y;
double min= 1000000.0;
double max=-1000000.0;
QString s1;
effacer_calque(scene1,calque_trace_signal1 );
segment_trace = new QGraphicsLineItem(0, offset_y, 512, offset_y);
segment_trace->setPen(QColor(couleur_ligne));
calque_trace_signal1->addToGroup(segment_trace);
long n;
long i=0;
x=0;
y=offset_y;
int pas = 64;
for(n=0; n<nb_ech/2; n++)
{
memo_x = x;
memo_y = y;
x = echelle * n;
octet_n = temp_data[i]; // canal 1
R = octet_n - 128; // pour oter la composante continue propre au codage par des octets non signés
// R /= 10.0;
y=offset_y + R;
if (y < min) {min = y;}
if (y > max) {max = y;}
if (x<1800)
{
segment_trace = new QGraphicsLineItem(memo_x ,memo_y, x, y);
segment_trace->setPen(pen_trace1);
calque_trace_signal1->addToGroup(segment_trace);
}
i++; // pour sauter le canal B (le signal dans le fichier .wav est stéréo)
i+= pas;
}
//scene1->addItem(calque_trace_signal);
s1.setNum(min);
//lineEdit_4->setText(s1);
s1.setNum(max);
// lineEdit_5->setText(s1);
}
void MainWindow::tracer_segments_FFT() //scene1 sur le 1er onglet (Source wav)
{
double offset_x= spinBox_offset->value(); // ref -2146 ; +/- 22 pour un décalage de +/-1/4 de ton
double echelle_x =doubleSpinBox_echx->value(); // 498
double offset_y = 350.0;
uint n;
double module_FFT;
double x=0, y=0;
// double dx;
double memo_x[5]={0,0,0,0,0};
double memo_y[5]={0,0,0,0,0};
double x0, y0; // fréquence centrale trouvée comme résultat (points d'inflexions de la courbe)
double z=1.6;
//int x1=0;
//int x2=0;
int num_raie=0;
//bool note_validee = false;
QPen pen1("#12FF00");
if(!rapide)
{
effacer_calque(scene1, calque_trace_FFT );
// effacer_calque(scene1,calque_lignes_F_zero );
}
y = offset_y;
ENR_FFT enr_i;
//qDebug() << "nb_ech" << nb_ech; // 1024
//x=0.0;
//dx = 30.0;
for(n=0; n<nb_ech; n++)
{
//note_validee = false;
memo_x[0] = x;
memo_y[0] = y;
//x = 100 + 6.0 * n; // echelle linéaire -> pas top
x = offset_x + echelle_x * log2((double)(n+1)); // échelle logarithmique afin que les tons soient graphiquement équi-espacés
// x += dx;
// ci-dessous 'a' est la partie réelle du complexe, et 'b' la partie imaginaire
// on calcule le module :
module_FFT = z * sqrt( tab_X[n].a * tab_X[n].a + tab_X[n].b * tab_X[n].b ); // z * racine(a²+b²)
y = module_FFT*10.0; // amplitude
y = offset_y - y; // offset et inversion du sens d'affichage because à l'écran les y croissent de haut en bas
// décale la pile memo_x
// puis mise en mémoire (empile) le dernier point
memo_x[4] = memo_x[3]; memo_y[4] = memo_y[3];
memo_x[3] = memo_x[2]; memo_y[3] = memo_y[2];
memo_x[2] = memo_x[1]; memo_y[2] = memo_y[1];
memo_x[1] = memo_x[0]; memo_y[1] = memo_y[0];
memo_x[0] = x;
memo_y[0] = y;
if((x>20) && (x<1900))
{
//y *=1.0;
if (x > -100)
{
if (!rapide)
{
segment_trace = new QGraphicsLineItem(memo_x[1], memo_y[1], x, y);
segment_trace->setPen(pen_trace2);
calque_trace_FFT->addToGroup(segment_trace);
}
}
// DETECTION DES NOTES primaires
//----------------------------------------------------------------------------------
// détection direct des points hauts (points d'inflexion de la courbe)
// on pourrait calculer la dérivée de la courbe, et détecter les valeurs pour lesquelles elle s'annule
// problème : peut ne pas détecter si le sommet est un pic (discontinuité)
//----------------------------------------------------------------------------------
// Autre méthode :
// détection de 2 doublets de points de part et d'autre, montants puis descendant
// le sommet se situe donc entre les 2 doublets
// la DETECTION s'effectue ICI
// ATTENTION : la ligne qui suit détermine la stratégie utilisée et son paramétrage influe grandement
// sur la qualité du résultat.
// on doit pouvoir l'améliorer mais attention : toujours expérimenter sur des données réelles (air de musique)
// avant de valider la moindre "amélioration".
//if ( (memo_y[3] - memo_y[2]) >0.5 && (memo_y[1] - memo_y[2]) >0.5 )
if ( (memo_y[3] - memo_y[2]) > 1.1 && (memo_y[1] - memo_y[2]) > 1.1 )
{
x0 = memo_x[2]; // point d'inflexion probable
y0 = memo_y[2];
// x0 = (memo_x[0]+ memo_x[1]+ memo_x[2]+ memo_x[3] + memo_x[4]) / 5.0;
if( !rapide) // donc pas d'affichage en mode rapide
{
ligne1 = new QGraphicsLineItem(x0, 60, x0, 350);
ligne1->setPen(pen1);
calque_lignes_F_zero->addToGroup(ligne1);
// ligne1 = new QGraphicsLineItem(x0+1, 60, x0+1, 350); // pour épaissir le trait
// ligne1->setPen(pen1);
// calque_lignes_F_zero->addToGroup(ligne1);
ligne1 = new QGraphicsLineItem(x0, T_i-1, x0, T_i+1); // T_i : variable GLOBALE
ligne1->setPen(pen1);
}
int m0 = 0;
m0 = calcul_num_midi(x0);
enr_i.t = T_i; // T_i : variable GLOBALE
enr_i.num = num_raie;
enr_i.midi = m0;
enr_i.amplitude = y0;
// tracer sur tableau fréquences
if(num_raie<10) // 6
{
liste_ENR_FFT << enr_i; // memorisation ; donc 5 notes max pour un temps (T_i) donné
// les notes ayant même T_i seront considérées comme simultanées (accord)
tracer_1enr(enr_i); // sur le 2eme onglet (NOTES)
}
num_raie++;
}
}
//dx /= 1.059463;
}
T_i++; // variable GLOBALE
// T_i est ici incrémenté à chaque appel de la fonction
// sachant que chaque appel de cette fonction analyse 1024 échantillons du signal.
// et que chaque échantillon représente une durée = 0.5ms du signal d'origine
// donc T_i est (virtuellement) incrémenté toutes les 1024*0.5ms = 512ms;
// pourquoi 'virtuellement' ? parce que chaque échantillon "REPRESENTE" une durée de 0.5 ms
// mais ne "DURE PAS" 0.5ms; L'analyse s'effectue à très haute vitesse sur un signal pré-échantilloné.
// de quel chapeau sort ce 0.5ms? Voir la fontion 'void MainWindow::remplir_tableau_echantillons_signal()'
num_raie=0;
//affi_notes();
}
void MainWindow::tracer_echelle_temps_TAB_NOTES() //en secondes (scene4 sur l'onglet NOTES)
{
QString s1;
double x, x0, dx;
int offset_x = 80;
int y0 = 620;
double nbs;
//effacer_calque(scene4, calque_echelle_temporelle_T);
if (visu_ech_tps == true) {y0 = 0;} // grandes lignes
for(int n=0; n<=120; n++)
{
x0 = 10.0 * doubleSpinBox_T0->value();
dx = 1000.0 * pas_echantillonage/256.0; // = 1000 * 24 /256 = 93.75
x = x0 + dx * zoom_x * (double)n;
ligne1 = new QGraphicsLineItem(offset_x + x, y0-5, offset_x + x, 650);
QPen pen1;
pen1.setColor("#00FF00"); //
ligne1->setPen(pen1);
calque_echelle_temporelle_T->addToGroup(ligne1);
nbs = (double) n;
s1.setNum(nbs, 10, 0); // base 10, 0 décimale
s1 += "s";
Etiquette(offset_x + x, 630, 0, s1, "#FFFFFF", "#000000", "#00FF00", calque_echelle_temporelle_T); // en bas
}
}
void MainWindow::tracer_1enr(ENR_FFT enr_i) // c.a.d. ayant la durée élémentaire T_i = 256 ms
{
// "notes" primaires -> calque 'calque_TAB_FRQ' sur le 2eme onglet (NOTES)
int T2;
//uint8_t num_raie;
uint8_t m0;
double yH, yL;
double y0, y2, dy, dy2;
uint16_t v; // v comme 'vertical'
double offset_y = 350.0;
QString couleur1;
T2 = zoom_x * enr_i.t;
m0 = enr_i.midi;
y0 = enr_i.amplitude;
if (checkBox_flitrer->isChecked() && (m0 != spinBox_filtre->value())) {return;}
v= 689 - (12 * (m0-28) );
y2 = -y0 + offset_y;
dy = y2/30.0; // 40
//dy = y2/10;
//dy=dy*dy; // pour un meilleur affichage ; A VOIR !!!!
//dy /=5.0;
dy *= gain;
if (dy > 200) {dy = 200;} // bridage amplitude max
if(v > 730) {return;}
if (dy > seuil)
{
dy2 = dy;
if (checkBox_norm->isChecked()) {dy2=5; } // bride la hauteur des tirets
double x = 80.0 + T2;
yH = v+dy2/2;
yL = v-dy2/2;
// rabotage pour éviter le scrolling de l'affichage:
if(yH > 730) {yH = 730;}
if(yL <0) {yH = 0;}
//ligne1 = new QGraphicsLineItem(x, yL, x, yH);
rectangle1 = new QGraphicsRectItem(x, v-dy2/2, zoom_x-2, dy2);
int h1 = calcul_hauteur_note(m0);
if (checkBox_norm->isChecked()) // utilise une couleur en fonction de l'amplitude du signal
{
double dy3 = dy/ 20;
if (dy3 > 0.8) {dy3 = 0.8;}
couleur1 = calcul_couleur(dy3);
}
else
{
// utilise une couleur en fonction de la fréquence ('hauteur') de la note
couleur1 = liste_couleurs[h1];
}
QPen pen1;
pen1.setColor(couleur1);
rectangle1->setPen(pen1);
rectangle1->setBrush(QColor(couleur1));
QBrush br1;
br1.setStyle(Qt::SolidPattern);
br1.setColor(couleur1);
rectangle1->setBrush(br1);
calque_TAB_FRQ->addToGroup(rectangle1); // lent !
graphicsView1->verticalScrollBar()->setValue(0);
}
}
void MainWindow::detection_notes_auto() // notes secondaires (affi par petits cercles colorés)
{
ENR_FFT enr_i;
int T2;
uint32_t n_max;
uint8_t m0;
double A1;
double x, y, y0, y2;
// double memo_x = 0;
double offset_y = 350.0;
//double decalage;
QString couleur1;
QPen pen1;
pen1.setWidth(1);
double pas_grille = doubleSpinBox_dxb->value()/2.0 * zoom_x;
double offset_x = 10 * doubleSpinBox_x0b->value() + spinBox_d_barres->value() * pas_grille;
n_max = liste_ENR_FFT.size();
if (n_max == 0) return;
tableWidget_type_M->setCurrentCell(2, 0);
on_tableWidget_type_M_cellClicked(2, 0);
liste_NOTES.clear();
for(int n=0; n<83; n++)
{
table_integration_amplitudes[n] =0; // RAZ
}
calque_notes_auto->setPos(0, 0);
for(uint32_t n=0; n<n_max-1; n++)
{
enr_i = liste_ENR_FFT[n];
T2 = zoom_x * enr_i.t;
m0 = enr_i.midi;
y0 = enr_i.amplitude;
y2 = -y0 + offset_y;
// y = 700 - (16 * (m0-40) );
y = 689 - (12 * (m0-28) );
A1 = y2/10.0; // 40
A1 *= gain;
// table_integration_amplitudes[m0] /= 2.0; // usure volontaire
if(A1<20)
{
table_integration_amplitudes[m0] = 0; // ce qui est débloquant
}
if (A1 > 20) // 30
{
x = 80.0 + T2 -8; // le -8 pour décaler dans le temps (de la durée de l'intégration)
//intégration temporelle des amplitudes en vue de valider en tant que note
if(table_integration_amplitudes[m0] >=0) // si pas de blocage en cours
{
table_integration_amplitudes[m0] += A1;
}
if (table_integration_amplitudes[m0] > 200.0)
{
// la NOTE est comfirmée, on va l'ajouter à la fin de la liste des notes
// Mais il faut aussi empêcher des re-détections multiples lorsque l'amplitute du signal ne décroit
// que progressivement. Pour cela on attribue la valeur -1 dans la table d'intégration
// pour le n° midi de la note, ce qui sera bloquant.
// Le déblocage se produira lorsque l'amplitude du signal concernant cette note
// sera descendu en dessous d'un certain niveau.
table_integration_amplitudes[m0] = -1; //ce qui est bloquant (voir 10 lignes +haut)
int h1 = calcul_hauteur_note(m0); //'hauteur' au sens musical, gamme chromatique
couleur1 = liste_couleurs[h1];
pen1.setColor(couleur1);
// int delta_x = int(x - memo_x);
// memo_x = x ;
ellipse1 = new QGraphicsEllipseItem(x-A1/2, y-A1/2, A1, A1);
ellipse1->setPen(pen1);
calque_notes_auto->addToGroup(ellipse1); // grands cercles colorés fin
//on va ajouter la note à la liste des notes
int n_barre = num_barre(x);
if (n_barre != -1000) {ajout_note(m0, n_barre, 0);}
// ellipse1 = new QGraphicsEllipseItem(x, v-1, 2, 2);
// pen1.setColor("#FFFFFF");
// ellipse1->setPen(pen1);
// calque_notes_auto->addToGroup(ellipse1); // point blanc
}
}
// voir la fonction -> 'tracer_1enr(ENR_FFT enr_i)' pour le cadrage
}
calque_notes_auto->setPos(offset_x, 0);
mode='M';
on_Bt_toggle_grille_T_clicked(); // basculera à T;
doubleSpinBox_vitesse->setValue(30);
}
void MainWindow::retracer_TAB_FRQ()
{
ENR_FFT enr_i;
uint16_t n_max = liste_ENR_FFT.length();
if (n_max == 0) return;
//effacer_calque(scene1,calque_trace_FFT );
tracer_graduation_TAB_NOTES();
calque_TAB_FRQ->setPos(0, 0);
for(uint16_t n=0; n<n_max-1; n++)
{
enr_i = liste_ENR_FFT[n];
tracer_1enr(enr_i);
}
double pas_grille = doubleSpinBox_dxb->value()/2.0 * zoom_x;
double offset_x = 10 * doubleSpinBox_x0b->value() + spinBox_d_barres->value() * pas_grille;
calque_TAB_FRQ->setPos(offset_x, 0);
}
void RAZ_tableau_echantillons()
{
uint n;
for(n=0; n < nb_ech; n++)
{
ech[n].a = 0; // partie reelle
ech[n].b = 0; // partie imaginaire
}
}
uint bit_reversal(uint num, uint nb_bits)
{
uint r = 0, i, s;
if ( num > (1<< nb_bits)) { return 0; }
for (i=0; i<nb_bits; i++)
{
s = (num & (1 << i));
if(s) { r |= (1 << ((nb_bits - 1) - i)); }
}
return r;
}
void MainWindow::bit_reverse_tableau_X()
{
// recopie les échantillons en les classant dans l'ordre 'bit reverse'
uint n,r;
for(n=0; n < nb_ech; n++) // nb d'échantillons
{
r=bit_reversal(n,nb_etapes);
tab_X[n] = ech[r];
}
}
void MainWindow::calcul_tableau_W()
{
if (tableau_w_plein == true) {return;}
// calcul et memorisation dans un tableau des twiddle factors (facteurs de rotation)
uint n;
double x;
for(n=0; n<(nb_ech/2-1); n++)
{
x=2.0*M_PI * n / nb_ech;
tab_W[n].a = cos(x); // partie reelle
tab_W[n].b = -sin(x); // partie imaginaire
}
tableau_w_plein = true;
}
void MainWindow::calcul_FFT()
{
Complexe produit; // voir la classe "Complexe" : complexe.h et complexe.ccp
uint etape, e1, e2, li, w, ci;
uint li_max=nb_ech;
e2=1;
for (etape=1; etape<=nb_etapes; etape++)
{
e1=e2; //(e1 évite d'effectuer des divisions e2/2 plus bas)
e2=e2+e2; // plus rapide que *=2
for (li=0; li<li_max; li+=1)
{
ci=li & (e2-1); // ET bit à bit
if (ci>(e1-1))
{
w=li_max/e2*(li & (e1 -1)); // ET bit à bit calcul du numéro du facteur de rotation W
produit = tab_W[w] * tab_X[li]; // le twiddle factor est lu en memoire; le produit est une mutiplication de nb complexes. Voir "complexe.cpp"
tab_X[li]=tab_X[li-e1] - produit; // concerne la ligne basse du croisillon; soustraction complexe; Voir "complexe.cpp"
tab_X[li-e1]=tab_X[li-e1] + produit; // concerne la ligne haute du croisillon; addition complexe; Voir "complexe.cpp"
}
}
}
}
void MainWindow::Tic1() // pour l'analyse de Fourier en vitesse lente
{
nb_tics++;
if(nb_tics > 4000)
{
Timer1->stop();
nb_tics=0;
}
else
{
SBX_de->setValue( SBX_de->value() +1); //voir la fonction 'on_SBX_de_valueChanged()'
Timer1->setInterval(2); // à voir
}
}
void MainWindow::trace_time_line()
{
double x_note=0, x, dx;
if (num_note_jouee < 1) {return;}
if(mode=='T') { x_note = calcul_x_barre(liste_NOTES[num_note_jouee-1].n_barreT); }
if(mode=='M') { x_note = calcul_x_barre(liste_NOTES[num_note_jouee-1].n_barreM); }
dx = calcul_pas_grille();
x = x_note + double(num_barre_en_cours) * dx;
int midi_i = liste_NOTES[num_note_jouee-1].midi;
int y = calcul_y_note(midi_i) ;
int h1 = calcul_hauteur_note(midi_i);
QString couleur1 = liste_couleurs[h1];
QPen pen1;
pen1.setColor(couleur1);
pen1.setWidth(2);
//ellipse1 = new QGraphicsEllipseItem(x, y, 2, 2) ;
//ellipse1->setPen(pen1);
//ellipse1->setBrush(blanc);
//calque_notes_jouee->addToGroup(ellipse1);
rectangle1 = new QGraphicsRectItem(x, y, dx, 2) ;
rectangle1->setPen(pen1);
calque_notes_jouee->addToGroup(rectangle1);
}
void MainWindow::Tic2()
{
int d_barre;
float dt, vts;
int itrv;
// ---------- pour l'onglet 'NOTES' -----------------------------------------------------------------
if (Boite_Onglets_Global->currentIndex() == 1)
{
vts = doubleSpinBox_vitesse->value();
d_barre = joue_1_note_de_la_liste(); // nb de barres temporelles séparant la note avec celle qui suit
dt = 20.0 * d_barre;
dt *= (200.0 / vts);
itrv = (int) dt;
Timer2->setInterval(itrv);
}
// ---------- pour l'onglet 'INSTRUMENTS' ------------------------------------------------------------
if (Boite_Onglets_Global->currentIndex() == 2)
{
// à voir : ne lit pas les positions des doigts !!!
//int i_max = liste_notes.count();
int i_max=TW_3->rowCount();
QString s1, s2, s3;
QString duree_txt;
int di=0;
int d_barre;
float dt, vts;
int itrv;
vts = 2.0 * doubleSpinBox_vitesse->value();
if ((num_ligne_en_cours >= 0) && (num_ligne_en_cours < i_max) )
{
s1 = TW_3->item(num_ligne_en_cours, 7)->text();
//s2 = s1.mid(1); // partie numérique de "*2"
duree_txt = TW_3->item(num_ligne_en_cours, 6)->text();
d_barre = duree_txt.toInt();
nb_colonnes_a_encadrer = d_barre;
num_colonne_a_encadrer=Tp1;
write_Time_line();
encadrement_colonne();
// memo_mesure_a_encadrer = mesure_a_encadrer;
mesure_a_encadrer = s1.toInt(); // numero de la mesure
TW_3->selectRow(num_ligne_en_cours);
//diF = duree_txt.toFloat();
di = duree_txt.toInt();
s1 = TW_3->item(num_ligne_en_cours, 10)->text();
s2 = TW_3->item(num_ligne_en_cours, 11)->text();
notes_silencieuses = true;
joue_accord_complet(s1, s2); // représentation graphique de la position avant de jouer la note
notes_silencieuses = false;
s1 = TW_3->item(num_ligne_en_cours, 7)->text();
// if (s1 !=" ") {play_toc();}
effacer_touches();
joue_1_ligne(num_ligne_en_cours);
s1 = TW_3->item(num_ligne_en_cours, 12)->text();
// affi_positions_doigts_dans_status(s1);
dt = 20.0 * (float)d_barre;
dt *= (100.0 / vts);
dt *= 4.0;
itrv = (int) dt;
Timer2->setInterval(itrv);
}
num_ligne_en_cours++;
if (num_ligne_en_cours >= i_max)
{
Bt_lecture_2->setText("Jouer tout");
//Bt_lecture_2->setStyleSheet("QBt{background-color:#50FF1B;}");
lecture_pause =0;
QString s1;
s1.setNum(num_ligne_en_cours);// conversion num -> txt
Timer2->stop();
}
encadrement_ligne();
Tp1 += di;
nb_notes_jouees++;
if (nb_notes_jouees>nb_notes_jouees_max)
{
nb_notes_jouees=0;
lecture_pause =0;
Timer2->stop();
}
}
}
void MainWindow::Tic3()
{
if(spinBox_6->value()>52)
{
Timer3->stop();
return;
}
spinBox_6->setValue( spinBox_6->value() +1);
Timer3->setInterval(5);
}
void clear_temp_data()
{
for(int i=0; i<2000000; i++)
{
temp_data[i]=0;
}
}
void MainWindow::on_Bt_load_wav_clicked()
{
open_fichier_wav(); // associe le binStream1 au fichier wav
decode_entete();
MainWindow::setCursor(Qt::WaitCursor);
liste_ENR_FFT.clear();
effacer_calque(scene1,calque_trace_signal1 );
effacer_calque(scene1, calque_trace_FFT);
clear_temp_data();
garnis_temp_data(0);
ajustement_gain();
// donne accès à la totalité (2MB) du fichier wav (dans le 'temp_data')
tracer_signal_complet();
MainWindow::setCursor(Qt::ArrowCursor);
tracer_gradu_temporelle_signal_entree();
frame_3->setVisible(true);
Bt_scan_auto->setVisible(true);
checkBox_rapide->setVisible(true);
}
/*
char RIFF[4]; (4 bytes)
unsigned long ChunkSize; (4 bytes)
char WAVE[4]; (4 bytes)
char fmt[4]; (4 bytes)
unsigned long Subchunk1Size; (4 bytes)
unsigned short AudioFormat; (2 octets)
unsigned short NumOfChan; (2 octets)
unsigned long SamplesPerSec; (4 bytes)
unsigned long bytesPerSec; (4 bytes)
unsigned short blockAlign; (2 octets)
unsigned short bitsPerSample; (2 octets)
char Subchunk2ID[4]; (4 bytes)
unsigned long Subchunk2Size; (4 bytes)
TOTAL 44 octets
*/
QString separ_milliers(uint n) // séparation des miliers par des espaces
{
QString s1, s1a, s1b, s1c;
s1.setNum(n);
int L= s1.length(); s1a = s1.right(3); s1b = s1.mid(L-6, 3); s1c = s1.mid(L-9, 3);
return (s1c+" "+s1b+" "+s1a);
}
void MainWindow::save_fichier_ini()
{
QFile file1(QDir::currentPath() + "/" + "params_FFT.ini"); // dans le dossier de l'exécutable
if (file1.open(QIODevice::WriteOnly | QIODevice::Text))
{
//int p1= string_currentFile.lastIndexOf('/');
//string_currentDir = string_currentFile.left(p1);
QTextStream out(&file1);
out << "# Ce fichier est crée automatiquement par le programme";
out << '\n';
out << "#";
out << '\n';
out << "# chemins:";
out << '\n';
out << "<currentDir>" << string_currentDir << "</currentDir>";
out << '\n';
out << "<currentFile>" << string_currentFile << "</currentFile>";
}
file1.close();
}
void MainWindow::open_fichier_wav()
{
// Le fichier .wav comprend un signal audio stéréo échantilloné à 48 000 octets/seconde pour chaque canal
// ce qui fait 96000 octets/s pour l'ensemble du signal stéréo
string_currentFile = QFileDialog::getOpenFileName(this, tr("Ouvrir Fichier wav..."), string_currentDir,
tr("Fichiers wav (*.wav);;All Files (*)"));
if (string_currentFile != "")
{
save_fichier_ini();
}
lineEdit_1->setText(string_currentFile);
int p1= string_currentFile.lastIndexOf('/');
string_currentDir = string_currentFile.left(p1);
lineEdit_current_dir->setText(string_currentDir); // sur l'onglet 'source wav'
lineEdit_fichier->setText(string_currentDir); // sur l'onglet 'NOTES'
lineEdit_current_dir_2->setText(string_currentDir); // sur l'onglet 'INSTRUMENTS'
save_fichier_ini();
file_wav.setFileName(string_currentFile);
if (!file_wav.open(QIODevice::ReadOnly))
{
wav_ok = false;
Bt_scan_auto->setStyleSheet("background-color: rgb(200, 200, 200);");
return ;
}
else
{
binStream1.setDevice(&file_wav); // accès à la totalité du fichier wav
wav_ok = true;
Bt_scan_auto->setStyleSheet("background-color: rgb(0, 255, 0);"); // vert
}
// le fichier reste ouvert pour toute la session
}
void MainWindow::decode_entete()
{
// ============ [Bloc de déclaration d'un fichier au format WAVE] ============
if (! wav_ok) {return;}
QString s3, s4, s5, fileSize1;
uint8_t x, nb_canaux;
double tot1, tot2, tot3, tot4;
binStream1.device()->seek(0); // retour de la lecture au début du fichier
binStream1.readRawData (temp_entete, 100); // lecture entete du fichier
//FileTypeBlocID
x=(uint8_t)temp_entete[0]; if ((x>64) && (x<127)) { s3 = char(x); }
x=(uint8_t)temp_entete[1]; if ((x>64) && (x<127)) { s3 += char(x); }
x=(uint8_t)temp_entete[2]; if ((x>64) && (x<127)) { s3 += char(x); }
x=(uint8_t)temp_entete[3]; if ((x>64) && (x<127)) { s3 += char(x); }
TW_entete_wav->setItem(0, 0, new QTableWidgetItem (s3) ); //FileTypeBlocID
// FileSize
x=(uint8_t)temp_entete[4]; s3.setNum(x); TW_entete_wav->setItem(1, 0, new QTableWidgetItem (s3) );
x=(uint8_t)temp_entete[5]; s3.setNum(x); TW_entete_wav->setItem(1, 1, new QTableWidgetItem (s3) );
x=(uint8_t)temp_entete[6]; s3.setNum(x); TW_entete_wav->setItem(1, 2, new QTableWidgetItem (s3) );
x=(uint8_t)temp_entete[7]; s3.setNum(x); TW_entete_wav->setItem(1, 3, new QTableWidgetItem (s3) );
tot1 = temp_entete[4] + (2<<7) * temp_entete[5] + (2<<15) * temp_entete[6] + (2<23)* temp_entete[7];
fileSize1 = separ_milliers(tot1);
TW_entete_wav->setItem(1, 4, new QTableWidgetItem ("= " + fileSize1) );
// FileFormatID
x=(uint8_t)temp_entete[8]; if ((x>64) && (x<127)) { s3 = char(x); }
x=(uint8_t)temp_entete[9]; if ((x>64) && (x<127)) { s3 += char(x); }
x=(uint8_t)temp_entete[10]; if ((x>64) && (x<127)) { s3 += char(x); }
x=(uint8_t)temp_entete[11]; if ((x>64) && (x<127)) { s3 += char(x); }
TW_entete_wav->setItem(2, 0, new QTableWidgetItem (s3) );
// ============ [Bloc décrivant le format audio] ==============
// FormatBlocID
x=(uint8_t)temp_entete[12]; if ((x>64) && (x<127)) { s3 = char(x); }
x=(uint8_t)temp_entete[13]; if ((x>64) && (x<127)) { s3 += char(x); }
x=(uint8_t)temp_entete[14]; if ((x>64) && (x<127)) { s3 += char(x); }
x=(uint8_t)temp_entete[15]; if ((x>64) && (x<127)) { s3 += char(x); }
TW_entete_wav->setItem(3, 0, new QTableWidgetItem (s3) );
//BlocSize
x=(uint8_t)temp_entete[16]; s3.setNum(x); TW_entete_wav->setItem(4, 0, new QTableWidgetItem (s3) );
x=(uint8_t)temp_entete[17]; s3.setNum(x); TW_entete_wav->setItem(4, 1, new QTableWidgetItem (s3) );
x=(uint8_t)temp_entete[18]; s3.setNum(x); TW_entete_wav->setItem(4, 2, new QTableWidgetItem (s3) );
x=(uint8_t)temp_entete[19]; s3.setNum(x); TW_entete_wav->setItem(4, 3, new QTableWidgetItem (s3) );
tot2 = (uint8_t)temp_entete[16] + (2<<7) * (uint8_t)temp_entete[17] + (2<<15) * (uint8_t)temp_entete[18] + (2<23)* (uint8_t)temp_entete[19];
TW_entete_wav->setItem(4, 4, new QTableWidgetItem ("= " + separ_milliers(tot2)) );
//AudioFormat
x=(uint8_t)temp_entete[20]; s3.setNum(x); TW_entete_wav->setItem(5, 0, new QTableWidgetItem (s3) );
x=(uint8_t)temp_entete[21]; s3.setNum(x); TW_entete_wav->setItem(5, 1, new QTableWidgetItem (s3) );
if ((uint8_t)temp_entete[20]==1){TW_entete_wav->setItem(5, 4, new QTableWidgetItem ("PCM") );}
//NbrCanaux
nb_canaux=(uint8_t)temp_entete[22]; s3.setNum(nb_canaux); TW_entete_wav->setItem(6, 0, new QTableWidgetItem (s3) );
x=(uint8_t)temp_entete[23]; s3.setNum(x); TW_entete_wav->setItem(6, 1, new QTableWidgetItem (s3) );
//Fréquence d'échantillonage en Hz
x=(uint8_t)temp_entete[24]; s3.setNum(x); TW_entete_wav->setItem(7, 0, new QTableWidgetItem (s3) );
x=(uint8_t)temp_entete[25]; s3.setNum(x); TW_entete_wav->setItem(7, 1, new QTableWidgetItem (s3) );
x=(uint8_t)temp_entete[26]; s3.setNum(x); TW_entete_wav->setItem(7, 2, new QTableWidgetItem (s3) );
x=(uint8_t)temp_entete[27]; s3.setNum(x); TW_entete_wav->setItem(7, 3, new QTableWidgetItem (s3) );
tot3 = (uint8_t)temp_entete[24] + (2<<7) * (uint8_t)temp_entete[25] + (2<<15) * (uint8_t)temp_entete[26] + (2<23)* (uint8_t)temp_entete[27];
TW_entete_wav->setItem(7, 4, new QTableWidgetItem ("= " + separ_milliers(tot3)) );
//BytePerSec
x=temp_entete[28]; s3.setNum(x); TW_entete_wav->setItem(8, 0, new QTableWidgetItem (s3) );
x=temp_entete[29]; s3.setNum(x); TW_entete_wav->setItem(8, 1, new QTableWidgetItem (s3) );
x=temp_entete[30]; s3.setNum(x); TW_entete_wav->setItem(8, 2, new QTableWidgetItem (s3) );
x=temp_entete[31]; s3.setNum(x); TW_entete_wav->setItem(8, 3, new QTableWidgetItem (s3) );
tot4 = (uint8_t)temp_entete[28] + (2<<7) * (uint8_t)temp_entete[29] + (2<<15) * (uint8_t)temp_entete[30] + (2<23)* (uint8_t)temp_entete[31];
s3.setNum(tot4); // 96000
TW_entete_wav->setItem(8, 4, new QTableWidgetItem (s3));
//tableWidget_1->setItem(8, 4, new QTableWidgetItem ("= " + separ_milliers(tot4)) );
//BytePerBloc
x=(uint8_t)temp_entete[32]; s3.setNum(x); TW_entete_wav->setItem(9, 0, new QTableWidgetItem (s3) );
x=(uint8_t)temp_entete[33]; s3.setNum(x); TW_entete_wav->setItem(9, 1, new QTableWidgetItem (s3) );
//BitsPerSample
x=(uint8_t)temp_entete[34]; s3.setNum(x); TW_entete_wav->setItem(10, 0, new QTableWidgetItem (s3) );
x=(uint8_t)temp_entete[35]; s3.setNum(x); TW_entete_wav->setItem(10, 1, new QTableWidgetItem (s3) );
x=(uint8_t)temp_entete[36]; if ((x>64) && (x<127)) { s3 = char(x); }
x=(uint8_t)temp_entete[37]; if ((x>64) && (x<127)) { s3 += char(x); }
x=(uint8_t)temp_entete[38]; if ((x>64) && (x<127)) { s3 += char(x); }
x=(uint8_t)temp_entete[39]; if ((x>64) && (x<127)) { s3 += char(x); }
TW_entete_wav->setItem(11, 0, new QTableWidgetItem (s3) );
// DataSize
x=(uint8_t)temp_entete[40]; s3.setNum(x); TW_entete_wav->setItem(12, 0, new QTableWidgetItem (s3) );
x=(uint8_t)temp_entete[41]; s3.setNum(x); TW_entete_wav->setItem(12, 1, new QTableWidgetItem (s3) );
x=(uint8_t)temp_entete[42]; s3.setNum(x); TW_entete_wav->setItem(12, 2, new QTableWidgetItem (s3) );
x=(uint8_t)temp_entete[43]; s3.setNum(x); TW_entete_wav->setItem(12, 3, new QTableWidgetItem (s3) );
int tot5a = 1 * (uint8_t) temp_entete[40]; //because le temp_entête de type 'char' code avec entiers signés
int tot5b = (1<<8) * (uint8_t)temp_entete[41]; // remarque: (1<<8) = 2^8 = 256 // ne pas écrire (2<<8) !!
int tot5c = (1<<16) * (uint8_t)temp_entete[42];
int tot5d = (1<<24) * (uint8_t)temp_entete[43];
data_size = tot5a + tot5b + tot5c + tot5d;
// 21248 + 458752 = 480000
// pour le .wav LA 440 (48000, durée 10s) ->14x(2^16) + 166 * (2^8) = 960000
// 960 000 kb (stéréo) / 96 000 kb/s (stéréo)= 10s
TW_entete_wav->setItem(12, 4, new QTableWidgetItem ("= " + separ_milliers(data_size)) ); // DataSize
// durée calculée
duree_totale = data_size / tot4;
s3.setNum(duree_totale, 'f', 3);// double n, char format = 'g', int precision = 6
TW_entete_wav->setItem(13, 4, new QTableWidgetItem (s3 + " s") );
s4.setNum(tot4);
s4 = "ech : " + s3;
s4 += " Bps / 2 voies (stéréo) = ";
s5.setNum(tot4/2000);
s5 +=" kBps";
TW_entete_wav->setItem(8, 5, new QTableWidgetItem (s5) );
lineEdit_6->setText("File size = " + fileSize1 + " bytes ; " + s4 + s5 + " ; durée calculée = " +s3 + "s");
if ((nb_canaux == 2) && (tot4 != 96000))
{
QMessageBox msgBox;
QString s1;
s1 = "Attention: Le taux d'échentillonage n'est pas 48 kb/s";
msgBox.setText(s1);
msgBox.exec();
}
if (nb_canaux != 2)
{
QMessageBox msgBox;
QString s1;
s1 = "Attention: Signal mono (doit être STEREO !)";
msgBox.setText(s1);
msgBox.exec();
}
}
// voir la page : https://fr.wikipedia.org/wiki/Waveform_Audio_File_Format
void MainWindow::garnis_temp_data(qint32 offset_i)
{
if (! wav_ok) {return;}
binStream1.device()->seek(0); // retour de la lecture au début du fichier
binStream1.skipRawData(44+offset_i); // saut bien plus loin dans le fichier
binStream1.readRawData (temp_data, 2000000); //lecture des données audio
//file_wav.close();
}
void MainWindow::calcul_compression()
{
double R;
double R_max=0;
for(uint n =0; n<nb_ech/4; n++)
{
R=ech[n].a;
if (R>R_max) {R_max=R;}
}
}
void MainWindow::remplir_tableau_echantillons_signal() // lecture du signal à analyser dans le 'temp_data' -> ech[n]
{
/*
Le fichier .wav doit avoir les caractéristiques suivantes :
- RIFF PCM WAVE fmt
- stéréo deux voies
- 96000 octets/s c'est à dire acqui avec 48000 octets/s x 2 voies
La FTT sera effectuée en 10 passes, sur un nb_ech = 2^10 = 1024 échantillons
*/
uint n, n_max, i, offset_x;
double R;
offset_x = 40; // ou plus, si lecture plus loin dans le temps, à voir
uint8_t octet_n; // octet_B;
/*
pour un codage 8 bits/sample = 2 * 1 octet/sample (stéréo)
[Octet du Sample1 Canal1 ] (octet_A, octet_B)
[Octet du Sample1 Canal2 ]
...
*/
i=0;
n=0;
// on ne prend pas en compte tous les échantillons dispo dans le .wav (inutile ici)
// mais 1 sur 40 (la fréquence de la note la plus aigue (midi94) est = 932Hz)
// et seul le fondamental est pertinent pour reconnaitre la note, les harmoniques (timbre) sont ignorées
// il faut donc échantilloner à 932*2 = 1864 Hz au minimum
// Le fichier .wav d'origine est échantilloné à 48kHz
// 48000 / 1864 = 25.75
// On va prendre 1 échantillon sur 24 , ce qui donne un échantillonage à 48000/24 = 2000Hz
// attention : tout changement de cette valeur (pas = 24) change l'échelle de représentation de la FFT
// et fout le bocson dans tout le programme !!!
// chaque échantillon représente donc une durée = 1/2000 seconde = 0.5ms = 500us
// voir la suite des explications vers la fin de la fonction 'void MainWindow::tracer_segments_FFT()'
n_max = nb_ech /2; // = 1024/2 = 512
// 512*0.5ms = 256 ms
while (n < n_max)
{
octet_n = temp_data[offset_x + i]; // canal A
// i++; // pour sauter (et ignorer) le canal B (le signal dans le fichier .wav est stéréo)
i+= pas_echantillonage;
// x= 256 * octet_A + octet_B;
R = octet_n - 128; // pour oter la composante continue propre au codage par des octets non signés
R /= 10.0;
R *= doubleSpinBox_gain->value();
if (hamming) { R = R * (1- cos (2* M_PI * n / nb_ech/2 ));}
if (bourrage_de_zeros)
{
if (n<=nb_ech/4) // /4 -> signal
{
ech[n].a = R; // partie reelle
ech[n].b = 0; // partie imaginaire
}
else // -> Bourage de zéros
{
ech[n].a = 0; // partie reelle
ech[n].b = 0; // partie imaginaire
}
}
else
{
ech[n].a = R; // partie reelle
ech[n].b = 0; // partie imaginaire
}
n++; // n atteindra la valeur max = 512 ech représentant une durée totale de 256 ms
}
//calcul_compression();
}
/*
void MainWindow::on_toolButton_2_clicked() // recup signal
{
RAZ_tableau_echantillons();
remplir_tableau_echantillons_signal();
tracer_signal_a_convertir();
}
*/
void MainWindow::calcul_ofsset()
{
if(!wav_ok) return;
offset_t = spinBox_1->value() + 10 * SBX_tonique->value() + 100 * spinBox_3->value() + 1000 * spinBox_4->value()
+ 10000 * spinBox_5->value() + 100000 * spinBox_6->value();
QString s1;
s1 = separ_milliers(offset_t) ;
lineEdit_3->setText(s1);
effacer_calque(scene2, calque_encadrement2);
encadrement_signal(offset_t/1200, 25);
}
void MainWindow::traitement_signal() // lance les Transformées de Fourier du signal
{
if (! wav_ok) {return;}
garnis_temp_data(offset_t);
remplir_tableau_echantillons_signal();
calcul_tableau_W();
//RAZ_tableau_echantillons();
if(!rapide) { tracer_signal_a_convertir();}
bit_reverse_tableau_X();
calcul_FFT();
// 1 FFT s'effectue sur 1 cluster de 1024 échantillons.
// chaque échantillon représente une durée = 1/2000 seconde = 0.5ms = 500us
// Le résultat représente un spectre élémentaire correspondant au cluster, c.a.d à une durée = 1024 x 0.5ms = 512 ms
// ce résultat est retourné dans le tableau 'Complexe tab_X[2048]'
// La fréquence minimale pouvant être résolue est 1/512ms = 1.953Hz (~2Hz). Toutefois la précision décroit à l'approche
// de cette limite.
// La détection des notes consiste à détecter les maximums de la fonction, il faut donc prendre une marge d'erreur
// On va donc limiter l'analyse à la fréquence du MI garve de la guitare : F_min=82Hz.
// Dans le deuxième onglet du programme (NOTES) il est toutefois possible de saisir de notes une octave en dessous (41Hz)
// Ce qui permet de saisir manuellement la plupart des partitions pour piano.
// ToDo: rajouter des touches au clavier de l'onglet 'INSTRUMENTS'... (et des cordes à la guitare ? ah non !)
tracer_segments_FFT();
}
void MainWindow::analyse_tout() // FFT de tous les clusters, c.a.d. sur la totalité du signal
{
progressBar_1->setVisible(true);
QString s1;
offset_t=0;
T_i=0; // variable GLOBALE
uint16_t i_max = data_size / 1024; // = environ 6000
if (checkBox_debut_seul->isChecked()) {i_max=2000;} // pour gagner du temps lors de la phase de test
// data_size est affiché par le visualisateur d'entête
// et aussi dans le LineEdit en bas de l'onglet FFT
// data_size = de l'ordre de 7MB, ce qui nous donne un i_max d'environ 6900
effacer_calque(scene4, calque_TAB_FRQ);
liste_ENR_FFT.clear();
//clear_temp_data();
//garnis_temp_data(0);
// effacer_calque(scene4, calque_gradu_TAB_FRQ);
// effacer_calque(scene4, calque_notes_manuelles);
// effacer_calque(scene4, calque_notes_jouee);
// effacer_calque(scene4, calque_grille_mesures);
// effacer_calque(scene4, calque_echelle_temporelle_T);
for(uint16_t i=0 ; i<i_max ; i++) // cette boucle sera donc parcourue environ 6000 fois...
{
if ((i % 200) == 0)
{
uint16_t pc = 100 * i / i_max;
pc+=2;
progressBar_1->setValue(pc);
// la ligne suivante permet l'affichage de la progression
QCoreApplication::processEvents(QEventLoop::AllEvents, 1);
}
//s1.setNum(i); lineEdit_compteur->setText(s1);
traitement_signal(); // traitement d'un cluster de 1024 échantillons
offset_t += 1024; // on passera au cluster de 1024 échantillons suivant c.a.d à un temps + 0.5ms
}
progressBar_1->setVisible(false);
tracer_echelle_temps_TAB_NOTES();
}
void MainWindow::on_spinBox_1_valueChanged(int arg1)
{
if (arg1==10) { spinBox_1->setValue(0); SBX_tonique->stepUp();}
calcul_ofsset();
traitement_signal();
}
void MainWindow::on_spinBox_2_valueChanged(int arg1)
{
if (arg1==-1) {SBX_tonique->setValue(9); spinBox_3->stepDown();}
if (arg1==10) { SBX_tonique->setValue(0); spinBox_3->stepUp();}
calcul_ofsset();
traitement_signal();
}
void MainWindow::on_spinBox_3_valueChanged(int arg1)
{
if (arg1==-1) {spinBox_3->setValue(9); SBX_de->stepDown();}
if (arg1==10) { spinBox_3->setValue(0); SBX_de->stepUp();}
calcul_ofsset();
traitement_signal();
}
void MainWindow::on_spinBox_4_valueChanged(int arg1)
{
if (arg1==-1) {spinBox_4->setValue(9); spinBox_5->stepDown();}
if (arg1==10) { spinBox_4->setValue(0); spinBox_5->stepUp();}
calcul_ofsset();
traitement_signal();
}
void MainWindow::on_spinBox_5_valueChanged(int arg1)
{
if (arg1==-1) {spinBox_5->setValue(9); spinBox_6->stepDown();}
if (arg1==10) { spinBox_5->setValue(0); spinBox_6->stepUp();}
calcul_ofsset();
traitement_signal();
}
void MainWindow::on_spinBox_6_valueChanged()
{
//if (arg1==-1) {spinBox_6->setValue(9);} //spinBox_6->stepDown();}
calcul_ofsset();
traitement_signal();
}
void MainWindow::on_doubleSpinBox_1_valueChanged()
{
calcul_ofsset();
traitement_signal();
}
void MainWindow::on_Bt_8_clicked()
{
QMessageBox msgBox;
QString s1;
s1 = "Le fichier audio à analyser doit être au format unsigned 8 bits PCM";
s1 += " (généré par exemple avec Audacity)";
s1 += "\n";
s1 += "Attention: ce n'est pas le format PCM par défaut, il faut aller dans les sous-menus :";
s1 += "\n";
s1 += "Fichier/Exporter/Exporter en WAV / encodage : Unsigned 8-bit PCM";
s1 += "\n";
s1 += "Ce n'est pas 'top WiFi', mais largement suffisant pour en faire la FFT et retrouver les notes.";
s1 += "\n";
s1 += "Ce qui est le but ici.";
s1 += "\n";
s1 += "D'autre part il est vivement conseillé de compresser la dynamique de l'audio (ce qui est simple avec Audacity)";
s1 += "\n";
s1 += "ce qui facilite grandement la détection des notes.";
msgBox.setText(s1);
msgBox.exec();
}
void MainWindow::on_Bt_RAZ_clicked()
{
spinBox_1->setValue(0);
SBX_tonique->setValue(0);
spinBox_3->setValue(0);
SBX_de->setValue(0);
SBX_a->setValue(20);
spinBox_6->setValue(0);
offset_t=0;
num_barre_en_cours=0;
effacer_calque(scene1,calque_trace_FFT );
effacer_calque(scene1,calque_lignes_F_zero );
}
void MainWindow::on_spinBox_7_valueChanged(int arg1)
{
// ligne verticale
effacer_calque(scene1,calque_curseur);
int x = arg1;
ligne1 = new QGraphicsLineItem(x, 10, x, 500);
ligne1->setPen(pen_curseur);
calque_curseur->addToGroup(ligne1);
}
void MainWindow::on_Bt_2_clicked()
{
Timer1->stop();
nb_tics=0;
}
void MainWindow::on_Btn_52_clicked()
{
//spinBox_n_midi->setValue(52);
file_wav.setFileName(nom_fichier_in);
if (!file_wav.open(QIODevice::ReadOnly))
{
wav_ok = false;
return ;
}
wav_ok = true;
on_Bt_RAZ_clicked();
binStream1.setDevice(&file_wav);
calcul_ofsset();
traitement_signal();
}
void MainWindow::on_Btn_94_clicked()
{
file_wav.setFileName(nom_fichier_in);
if (!file_wav.open(QIODevice::ReadOnly))
{
wav_ok = false;
return ;
}
wav_ok = true;
on_Bt_RAZ_clicked();
binStream1.setDevice(&file_wav);
calcul_ofsset();
traitement_signal();
}
void MainWindow::on_Bt_efface_clicked()
{
QMessageBox msgBox;
msgBox.setText("Erase Frequences");
msgBox.setInformativeText("Effacer toutes les FFT ?");
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Cancel);
int ret = msgBox.exec();
if (ret == QMessageBox::Ok )
{
effacer_calque(scene1,calque_trace_signal1 );
effacer_calque(scene1,calque_trace_FFT );
effacer_calque(scene1,calque_lignes_F_zero );
effacer_calque(scene1,calque_encadrement1 );
effacer_calque(scene2,calque_encadrement2 );
effacer_calque(scene4,calque_TAB_FRQ );
on_Bt_RAZ_clicked();
T_i=0; // T_i : variable GLOBALE
}
}
void MainWindow::on_Bt_3_clicked()
{
TW_entete_wav->setVisible(true);
Bt_close_entete->setVisible(true);
}
void MainWindow::on_Bt_close_entete_clicked()
{
TW_entete_wav->setVisible(false);
Bt_close_entete->setVisible(false);
}
/*
void MainWindow::on_Bt_close_frame1_clicked()
{
frame_1->setVisible(false);
frame_3->setVisible(true);
}
void MainWindow::on_Bt_composition_clicked()
{
frame_3->setVisible(false);
frame_1->setVisible(true);
}
*/
void MainWindow::on_Bt_6_clicked()
{
frame_notes->setVisible(false);
}
int MainWindow::save_fichier_FRQ(QString date_i)
{
// enregisterment incrémentiel sur le disque (nom de fichier = 1..2...3...)
ENR_FFT enr_i;
QString s1;
uint8_t x0a = spinBox_x0a->value();
double x0b = doubleSpinBox_x0b->value();
//uint8_t dxa = spinBox_dxa->value();
double dxb = doubleSpinBox_dxb->value();
long n_max = liste_ENR_FFT.length();
if (n_max == 0)
{
QMessageBox msgBox; msgBox.setText("liste FRQ vide !"); msgBox.exec();
return 1;
}
//int numero=0;
QString s2 = date_i;
Timer1->stop();
QFile file1(string_currentDir + "/" + s2 + ".FRQ");
if (file1.open(QIODevice::WriteOnly | QIODevice::Text))
{
QByteArray byteArray1;
QDataStream stream1(&byteArray1, QIODevice::WriteOnly);
stream1.setDevice(&file1);
stream1.setVersion(QDataStream::Qt_6_8);
// entête 64 octets------------------
double vts = doubleSpinBox_vitesse->value(); // 8 octets
stream1 << x0b << dxb << vts << Ta << Tb << x0a; //8+8+8+1+1+1+1 =27 octets au début du fichier
for (int i=0; i<(64-27); i++) {stream1 << 'x';} // complète à 64 octet
// ----------------------------------
for(int n=0; n<n_max; n++)
{
enr_i = liste_ENR_FFT[n];
stream1 << enr_i.amplitude << enr_i.midi << enr_i.num << enr_i.t; // sérialisation des data
}
}
file1.close();
return 0;
}
void MainWindow::choix_dossier_de_travail()
{
QString actuel = string_currentDir;
if (string_currentDir == "") { string_currentDir = QDir::homePath(); }
string_currentDir = QFileDialog::getExistingDirectory
(this, tr("Open Directory"), actuel, QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
if (string_currentDir != "")
{
dossier_de_travail_ok = true;
save_fichier_ini();
lineEdit_current_dir->setText(string_currentDir); // sur l'onglet 'source wav'
lineEdit_fichier->setText(string_currentDir); // sur l'onglet 'NOTES'
lineEdit_current_dir_2->setText(string_currentDir); // sur l'onglet 'INSTRUMENTS'
}
else // -> si on clique sur le bouton 'cancel'
{
string_currentDir = QDir::homePath();
//dossier_de_travail_ok = false;
}
}
void MainWindow::on_Bt_choix_current_dir_clicked()
{
lecture_en_cours = false;
Timer2->stop();
Bt_jouer_tout->setText(">");
choix_dossier_de_travail();
}
void MainWindow::on_Bt_choix_current_dir_2_clicked()
{
lecture_en_cours = false;
Timer2->stop();
Bt_jouer_tout->setText(">");
choix_dossier_de_travail();
}
void MainWindow::on_Bt_choix_current_dir_3_clicked()
{
lecture_en_cours = false;
Timer2->stop();
Bt_jouer_tout->setText(">");
choix_dossier_de_travail();
}
void MainWindow::ajustement_gain()
{
double somme;
double moyenne=0;
double R;
double gain=0.3;
uint8_t octet_n;
long i, j;
double pas = 10.0 * pas_echantillonage; // 240
double n_max=1;
if (pas !=0)
{
n_max = 2000000 / pas;
}
i=0;
j=0;
somme =0;
for(long n=0; n<n_max; n++)
{
octet_n = temp_data[i]; // canal 1
if (octet_n !=0)
{
R = octet_n - 128;// pour ôter la composante continue (octets non signés)
if (R<0) {R= -R;}
somme += R;
j++; // nb de notes effectivement prises en compte
}
i+= pas;
}
if (j !=0) { moyenne = somme / j;}
if (moyenne !=0) { gain = 20.0/moyenne;}
doubleSpinBox_gain->setValue(gain);
}
void MainWindow::load_fichier_FRQ()
{
QString filename1;
QString s1;
MainWindow::setCursor(Qt::WaitCursor);
if(dossier_de_travail_ok == false)
{
choix_dossier_de_travail();
if (dossier_de_travail_ok == false)
{
QMessageBox msgBox;
s1="Le dossier de travail n'est pas spécifié";
msgBox.setText(s1); msgBox.exec();
MainWindow::setCursor(Qt::ArrowCursor);
return ;
}
}
filename1 = QFileDialog::getOpenFileName(this,
tr("Ouvrir Fichier FRQ"), string_currentDir + "/", tr("Fichiers FRQ (*.FRQ)"));
lineEdit_fichier_FREQ->setText(filename1);
file_dat.setFileName(filename1);
if (!file_dat.open(QIODevice::ReadOnly))
{
data_nts_ok = false;
MainWindow::setCursor(Qt::ArrowCursor);
return ;
}
else
{
binStream1.setDevice(&file_dat); // accès à la totalité du fichier dat
binStream1.setVersion(QDataStream::Qt_6_8);
data_nts_ok = true;
liste_ENR_FFT.clear();
}
//int z = sizeof(ENR_FFT); // ATTENTION ! ne PAS utiliser cette valeur qui tient en compte l'alignement en RAM
long n_max = file_dat.bytesAvailable() / 14; // 14 bits par enr; voir la def de 'ENR_FFT' dans le .h
uint8_t x0a;
double x0b;
uint8_t dxa;
double dxb;
double vts;
// lecture entête -----------------
binStream1 >> x0b >> dxb >> vts >> Ta >> Tb >> x0a >> dxa; // 8+8+8+1+1+1+1=28 octets au début du fichiers
uint8_t xx;
for (int i=0; i<(64-28); i++) {binStream1 >> xx;} // lit en tout à 64 octets
//---------------------------------
spinBox_x0a->setValue(x0a);
doubleSpinBox_x0b->setValue(x0b);
// spinBox_dxa->setValue(dxa);
doubleSpinBox_dxb->setValue(dxb);
doubleSpinBox_vitesse->setValue(vts);
//---------------------------------
ENR_FFT enr_i;
for(int n=0; n<n_max; n++)
{
binStream1 >> enr_i.amplitude >> enr_i.midi >> enr_i.num >> enr_i.t;
liste_ENR_FFT << enr_i;
}
file_dat.close();
retracer_TAB_FRQ();
MainWindow::setCursor(Qt::ArrowCursor);
}
int MainWindow::save_fichier_NOTES(QString date_i)
{
// enregisterment incrémentiel sur le disque (nom de fichier = 1..2...3...)
NOTE note_i;
// QString s1;
uint8_t x0a = spinBox_x0a->value();
double x0b = doubleSpinBox_x0b->value();
//uint8_t dxa = spinBox_dxa->value();
double dxb = doubleSpinBox_dxb->value();
uint16_t n_max = liste_NOTES.length();
if (n_max == 0)
{
QMessageBox msgBox; msgBox.setText("liste NOTES vide !"); msgBox.exec();
return 1;
}
if (date_i == "BAK")
{
QMessageBox msgBox;
QString s1="Fichier BAK.NTS enregistré";
msgBox.setText(s1); msgBox.exec();
}
//int numero=0;
QString s2;
Timer1->stop();
s2 = date_i;
//QFile file1(string_currentDir + "/" + "NOTES_" + s2 + ".nts");
QFile file1(string_currentDir + "/" + s2 + ".NTS");
if (file1.open(QIODevice::WriteOnly | QIODevice::Text))
{
QByteArray byteArray1;
QDataStream stream1(&byteArray1, QIODevice::WriteOnly);
stream1.setDevice(&file1);
stream1.setVersion(QDataStream::Qt_6_8);
// entête 64 octets --------------
double vts = doubleSpinBox_vitesse->value(); // 8 octets
stream1 << x0b << dxb << vts << Ta << Tb << x0a; //8+8+8+1+1+1 =27 octets au début du fichier
for (int i=0; i<(64-27); i++) {stream1 << 'x';} // complète à 64 octets
//--------------------------------
for(uint16_t n=0; n<n_max; n++)
{
note_i = liste_NOTES[n];
// sérialisation des data
stream1 << note_i.numero << note_i.midi << note_i.n_barreT << note_i.n_barreM;
}
}
file1.close();
return 0;
}
void MainWindow::load_fichier_NOTES(QString s0)
{
QString filename1;
QString s1;
MainWindow::setCursor(Qt::WaitCursor);
if (s0 == "BAK")
{
filename1 = string_currentDir+ "/BAK.NTS";
}
else
{
if(dossier_de_travail_ok == false)
{
choix_dossier_de_travail();
if (dossier_de_travail_ok == false)
{
QMessageBox msgBox;
s1="Le dossier de travail n'est pas spécifié";
msgBox.setText(s1); msgBox.exec();
MainWindow::setCursor(Qt::ArrowCursor);
return ;
}
}
filename1 = QFileDialog::getOpenFileName(this,
tr("Ouvrir Fichier NTS"), string_currentDir+"/", tr("Fichiers nts (*.NTS)"));
}
lineEdit_fichier->setText(filename1);
file_dat.setFileName(filename1);
if (!file_dat.open(QIODevice::ReadOnly))
{
data_nts_ok = false;
MainWindow::setCursor(Qt::ArrowCursor);
return ;
}
else
{
binStream1.setDevice(&file_dat); // accès à la totalité du fichier dat
binStream1.setVersion(QDataStream::Qt_6_8);
data_nts_ok = true;
}
//int z = sizeof(NOTE); // ATTENTION ! ne PAS utiliser cette valeur qui tient en compte l'alignement en RAM
uint16_t n_max = file_dat.bytesAvailable() / 7; // 7 bits par enr; voir la def de 'NOTE' dans le .h
uint8_t x0a;
double x0b;
uint8_t dxa;
double dxb;
double vts;
// lecture entête -----------------
binStream1 >> x0b >> dxb >> vts >> Ta >> Tb >> x0a >> dxa; // 8+8+8+1+1+1+1=28 octets au début du fichiers
uint8_t xx;
for (int i=0; i<(64-28); i++) {binStream1 >> xx;} // lit en tout à 64 octets
//---------------------------------
spinBox_x0a->setValue(x0a);
doubleSpinBox_x0b->setValue(x0b);
//spinBox_dxa->setValue(dxa);
doubleSpinBox_dxb->setValue(dxb);
doubleSpinBox_vitesse->setValue(vts);
switch (Ta)
{
case 2: {lineEdit_10->setText("2/4"); Ta=2; Tb=4;} break; // Ta et Tb variables globales
case 3: {lineEdit_10->setText("3/4"); Ta=3; Tb=4;} break;
case 4: {lineEdit_10->setText("4/4"); Ta=4; Tb=4;} break;
default: break;
}
for(int n=0; n<n_max; n++)
{
NOTE note_i;
binStream1 >> note_i.numero >> note_i.midi >> note_i.n_barreT >> note_i.n_barreM;
note_i.statut = 0; // n'est pas sauvegardé ni relu
liste_NOTES << note_i;
}
file_dat.close();
mode = 'M';
affiche_liste_notes();
//on_Bt_toggle_grille_T_clicked();
Bt_jouer_tout->setStyleSheet("background-color: rgb(0, 255, 0);"); // vert
MainWindow::setCursor(Qt::ArrowCursor);
}
void decalle_notes(int d)
{
int nb;
uint16_t i_max = liste_NOTES.length();
for( int i =0; i<i_max; i++)
{
nb = liste_NOTES[i].n_barreT;
nb += d;
liste_NOTES[i].n_barreT = nb;
}
}
void MainWindow::on_Bt_load_FREQ_clicked()
{
load_fichier_FRQ();
on_Bt_toggle_grille_T_clicked();
// effacer_calque(scene4, );
effacer_calque(scene5, calque_histogramme );
// tracer_echelle_temps_TAB_NOTES();
}
void MainWindow::on_checkBox_rapide_stateChanged(int arg1)
{
rapide=arg1;
init_TAB_FRQ();
}
void MainWindow::on_doubleSpinBox_seuil_valueChanged(double arg1)
{
seuil = arg1;
effacer_calque(scene4, calque_TAB_FRQ);
retracer_TAB_FRQ();
}
void MainWindow::on_checkBox_norm_clicked()
{
/*
if (checkBox_norm->isChecked())
{
textEdit_ETAT->setText("Mode Normalisé : \n Les couleurs représentent l'amplitude du signal");
}
else
{
textEdit_ETAT->setText(
"Mode Fréquences : \n"
"Les couleurs représentent la valeur (fréquence) de la note (Do, RE, MI...) \n"
"La taille de chaque tiret représente (abusivement sur l'axe fréquenciel) l'amplitude du signal \n"
"cette taille ne signifie donc pas un étalement en fréquence du signal, c'est juste une astuce de représentation."
);
}
*/
effacer_calque(scene4, calque_TAB_FRQ);
retracer_TAB_FRQ();
}
/*
void MainWindow::surbrille_barre(num_barre)
{
}
*/
void MainWindow::surbrille_note(uint16_t n, bool HRM, int type) // HRM = visu harmoniques
{
// HRM true -> visu harmoniques x2 et x3
double x_note=0;
QPen pen1;
//QString couleur1;
QString blanc = "#FFFFFF";
NOTE note_i;
uint16_t n_max = liste_NOTES.length();
if ( n>= n_max) {return;}
note_i = liste_NOTES[n];
if(mode=='T') { x_note = calcul_x_barre(note_i.n_barreT); }
if(mode=='M') { x_note = calcul_x_barre(note_i.n_barreM); }
if (checkBox_scrolling->isChecked())
{
//int n =0;
double diff1 =0;
double xb = GV_grillesTM->horizontalScrollBar()->value();
diff1= x_note - xb;
if(diff1 >1700)
{
on_Bt_next_clicked();
on_Bt_next_clicked();
}
}
int y1, y2, y3; // y1=F0; y2 = 2xF0; y3 = 3xF0
int h1;
int midi_i;
midi_i = note_i.midi;
y1 = calcul_y_note(midi_i);
y2 = calcul_y_note(midi_i+12);
y3 = calcul_y_note(midi_i+17);
if(type == 1)
{
pen1.setColor(blanc);
pen1.setWidth(1);
ellipse1 = new QGraphicsEllipseItem(x_note-12, y1-12, 24, 24) ; // cercle
ellipse1->setPen(pen1);
calque_notes_jouee->addToGroup(ellipse1);
}
if(type == 2)
{
pen1.setColor(blanc);
pen1.setWidth(1);
rectangle1 = new QGraphicsRectItem(x_note-15, y1-15, 30, 30) ; // carré
rectangle1->setPen(pen1);
calque_notes_jouee->addToGroup(rectangle1);
}
if (HRM== true)
{
// visu harmoniques x2 et x3
if (y2 > 4) // afin d'éviter d'afficher trop haut ce qui décalerait tout l'affichage
{
h1 = calcul_hauteur_note(midi_i+12);
pen1.setColor(liste_couleurs[h1]);
rectangle1= new QGraphicsRectItem(x_note-20, y2-1, 40, 2) ;
rectangle1->setPen(pen1);
calque_notes_jouee->addToGroup(rectangle1);
}
if (y3 > 4) // afin d'éviter d'afficher trop haut ce qui décalerait tout l'affichage
{
h1 = calcul_hauteur_note(midi_i+17);
pen1.setColor(liste_couleurs[h1]);
rectangle1= new QGraphicsRectItem(x_note-20, y3-1, 40, 2) ;
rectangle1->setPen(pen1);
calque_notes_jouee->addToGroup(rectangle1);
}
}
}
void MainWindow::surbrille_barre(int n_barre, QString couleur) // par un trait vertical
{
QPen pen1;
pen1.setColor(couleur);
pen1.setWidth(2);
int x= calcul_x_barre(n_barre);
ligne1 = new QGraphicsLineItem(x, 200, x, 500);
ligne1->setPen(pen1);
effacer_calque(scene4, calque_surbrillance);
calque_surbrillance->addToGroup(ligne1);
}
void MainWindow::encadre_groupe_notes(int n_barre_i, int nombre)
{
NOTE note_i;
int midi_i;
double y_i, y_min, y_max;
int x1 = calcul_x_barre(n_barre_i);
int x2 = calcul_x_barre(n_barre_i + nombre);
int n_max = liste_NOTES.length();
y_min = 1000;
y_max = -1;
for(int n_i=0; n_i<nombre; n_i++)
{
for(int n=0; n<n_max; n++)
{
note_i = liste_NOTES[n];
midi_i = note_i.midi;
if(note_i.n_barreM == n_barre_i+n_i)
{
y_i = calcul_y_note(midi_i);
if (y_i > y_max) {y_max=y_i;}
if (y_i < y_min) {y_min=y_i;}
}
}
}
QPen pen1;
pen1.setColor("#00FFFF");
pen1.setWidth(1);
rectangle1= new QGraphicsRectItem(x1-15, y_min-15, x2-x1 +30, y_max-y_min+30) ;
rectangle1->setPen(pen1);
calque_surbrillance->addToGroup(rectangle1);
}
void MainWindow::complete_ligne(int R)
{
TW_3->setItem(R, 0, new QTableWidgetItem (" ") ); // colonne de numerotation
complete_case(R, 0, "0", "#000000", "#FFFCDD", false, TW_3); // attention: 'complete_case' ne crée pas le widget !
TW_3->setItem(R, 1, new QTableWidgetItem (" ") ); // note1
TW_3->setItem(R, 2, new QTableWidgetItem (" ") ); // note2
TW_3->setItem(R, 3, new QTableWidgetItem (" ") ); // note3
TW_3->setItem(R, 4, new QTableWidgetItem (" ") );
complete_case(R, 4, " ", "#000000", "#FFFCDD", false, TW_3); // cmt
QTableWidgetItem *Item1 = new QTableWidgetItem();
Item1->setIcon(QIcon("../images/01.png" ));
TW_3->setItem(R, 5, Item1 ); // bouton
TW_3->setItem(R, 6, new QTableWidgetItem ("0") ); // dt
TW_3->setItem(R, 7, new QTableWidgetItem ("0") ); // M
TW_3->setItem(R, 8, new QTableWidgetItem ("0") ); // tps
TW_3->setItem(R, 9, new QTableWidgetItem ("0") ); // tot
TW_3->setItem(R, 10, new QTableWidgetItem (" ") ); // ACC (accord type)
TW_3->setItem(R, 11, new QTableWidgetItem (" ") ); // intervalle de cases (sur le manche) à jouer
TW_3->setItem(R, 12, new QTableWidgetItem (" ") ); // doigts
}
void MainWindow::on_Bt_AddLine_clicked() // à la fin
{
int R=TW_3->rowCount();
TW_3->setRowCount(R+1);
R=TW_3->rowCount();
complete_ligne(R-1);
}
void MainWindow::on_Bt_AddLine_ici_clicked() // ici
{
int R= TW_3->currentRow();
TW_3->insertRow(R);
complete_ligne(R);
}
void MainWindow::complete_case(int row, int column, QString s1, QColor c1, QColor c2, bool bold1, QTableWidget *QTI)
{
QTableWidgetItem *Item1 = new QTableWidgetItem();
Item1->QTableWidgetItem::setForeground(QColor(c1));
Item1->QTableWidgetItem::setBackground(QColor(c2));
QFont font1;
font1.setBold(bold1);
Item1->setFont(font1);
Item1->setTextAlignment(Qt::AlignCenter);
Item1->setText(s1);
QTI->setItem(row, column, Item1);
}
void MainWindow::affiche_liste_notes() // en TEXTE dans le petit tableau
{
NOTE note_i;
QString s1;
QString blanc = "#FFFFFF";
QString jaune = "#FFFF00";
QString cyan = "#00FFFF";
TW_lst_notes->clear();
TW_lst_notes->setRowCount(0);
init_TAB_lst_notes();
uint16_t n_max = liste_NOTES.length();
if (n_max == 0) {return;}
int memo_n_barreM =0;
for(int n=0; n<n_max; n++) //n_max
{
note_i=liste_NOTES[n];
int numero = note_i.numero;
int midi = note_i.midi;
int n_barreT = note_i.n_barreT;
int n_barreM = note_i.n_barreM;
int duree = n_barreM - memo_n_barreM;
memo_n_barreM = n_barreM;
int num_ligne = TW_lst_notes->rowCount();
TW_lst_notes->setRowCount(num_ligne+1); // ajout une ligne au tableau
s1.setNum(numero);
complete_case(n, 0, s1, "000000", "#FFFFFF", false, TW_lst_notes);
s1.setNum(midi);
int h1 = calcul_hauteur_note(midi);
QString couleur1 = liste_couleurs[h1];
complete_case(n, 1, s1, "#000000", couleur1, true, TW_lst_notes);
s1 = nom_note(midi);
complete_case(n, 2, s1, "#000000", "#FFFFFF", false, TW_lst_notes);
s1.setNum(n_barreT);
complete_case(n, 3, s1, jaune, "#555555", true, TW_lst_notes);
s1.setNum(n_barreM);
complete_case(n, 4, s1, "#000000", "#FFFFFF", false, TW_lst_notes);
s1.setNum(duree);
complete_case(n, 5, s1, "#000000", "#FFFFFF", false, TW_lst_notes);
}
//tableWidget_lst_notes->AdjustToContents;
affiche_histogramme();
}
void MainWindow::affiche_histogramme_durees()
{
int x;
double dy;
double echelle;
QBrush br1;
QString couleur1;
QString s1;
effacer_calque(scene5, calque_histogramme);
GraphicsTextItem = new QGraphicsTextItem("Histogramme des durées \n en nb de barres 1/40s");
GraphicsTextItem->setFont(QFont("Arial", 12));
GraphicsTextItem->setDefaultTextColor("#FFFFFF");
GraphicsTextItem->setPos(100, -160);
calque_histogramme->addToGroup(GraphicsTextItem);
//calcul de la valeur la plus grande
int total=0;
for(int n=0; n<=20; n++) // attention à ne pas dépasser la taille de la table...
{
dy = table_histogramme_durees[n];
if (dy > total ) {total = dy;}
}
//calcul échelle y
if (total == 0) {total = 1;}
echelle = 150.0 / total;
for(int n=0; n<=30; n++) // attention à ne pas dépasser la taille de la table...
{
x = 10*n;
dy = echelle * table_histogramme_durees[n];
dy = -dy;
rect1 = new QGraphicsRectItem(x, 0, 2, dy);
couleur1="#AAFFFF";
br1.setStyle(Qt::SolidPattern);
br1.setColor(QColor(couleur1));
rect1->setPen(QColor(couleur1));
rect1->setBrush(br1);
calque_histogramme->addToGroup(rect1);
if (n%2 == 0)
{
x = -5 + 20*n;
s1.setNum(n);
GraphicsTextItem = new QGraphicsTextItem(s1);
GraphicsTextItem->setFont(QFont("Arial", 10));
GraphicsTextItem->setDefaultTextColor("#FFFFFF");
GraphicsTextItem->setPos(x, 0);
calque_histogramme->addToGroup(GraphicsTextItem);
}
}
}
void MainWindow::calcul_histogramme_durees()
{
uint16_t n_max = liste_NOTES.length();
if (n_max == 0) {return;}
for(int i=0; i<35; i++) { table_histogramme_durees[i]=0; } // RAZ
for(int n=1; n<n_max; n++) // attention: =1 et pas =0 because 'liste_NOTES[n-1]' ci-dessous !
{
int duree = liste_NOTES[n].n_barreT - liste_NOTES[n-1].n_barreT;
table_histogramme_durees[duree]++;
}
}
void MainWindow::affiche_histogramme_midi()
{
int x;
double dy;
double echelle;
QBrush br1;
QString couleur1;
QString s1;
effacer_calque(scene5, calque_histogramme);
GraphicsTextItem = new QGraphicsTextItem("Histogramme des notes midi");
GraphicsTextItem->setFont(QFont("Arial", 12));
GraphicsTextItem->setDefaultTextColor("#FFFFFF");
GraphicsTextItem->setPos(100, -160);
calque_histogramme->addToGroup(GraphicsTextItem);
//calcul de la valeur la plus grande
int total=0;
for(int n=0; n<_Hmax; n++) // 42, attention à ne pas dépasser la taille de la table...
{
dy = table_histogramme_midi[n];
if (dy > total ) {total = dy;}
}
//calcul échelle y
if (total == 0) {total = 1;}
echelle = 150.0 / total;
for(int n=0; n<=40; n++) // 42 attention à ne pas dépasser la taille de la table...
{
x = 10*n;
dy = echelle * table_histogramme_midi[n];
dy = -dy;
rect1 = new QGraphicsRectItem(x, 0, 5, dy);
couleur1="#AAFFFF";
int h1 = calcul_hauteur_note(n+40);
QString couleur1 = liste_couleurs[h1];
br1.setStyle(Qt::SolidPattern);
br1.setColor(QColor(couleur1));
rect1->setPen(QColor(couleur1));
rect1->setBrush(br1);
calque_histogramme->addToGroup(rect1);
if (n%2== 0)
{
x = -5 + 10*n;
s1.setNum(n+40);
GraphicsTextItem = new QGraphicsTextItem(s1);
GraphicsTextItem->setFont(QFont("Arial", 10));
GraphicsTextItem->setDefaultTextColor("#FFFFFF");
GraphicsTextItem->setPos(x, 0);
calque_histogramme->addToGroup(GraphicsTextItem);
}
}
}
void MainWindow::calcul_histogramme_midi()
{
for(int i=0; i<42; i++)
{
table_histogramme_midi[i]=0; // RAZ
}
uint16_t n_max = liste_NOTES.length();
for(int n=0; n<n_max; n++)
{
int M=liste_NOTES[n].midi;
if ((M>=40)&&(M<=82)) { table_histogramme_midi[M-40]++;}
}
}
/*
Liste des correspondances en fonction des dièses présents à la clef :
Pas d'altération : Do Majeur
Fa# : Sol Majeur
Fa#, Do# -> gamme de Ré Majeur
Fa#, Do#, Sol# -> gamme de La Majeur
Fa#, Do#, Sol#, Ré# -> gamme de Mi Majeur
Fa#, Do#, Sol#, Ré#, La# -> gamme de Si Majeur
Fa#, Do#, Sol#, Ré#, La#, Mi# -> gamme de Fa dièse Majeur
Fa#, Do#, Sol#, Ré#, La#, Mi#, Si# -> gamme de Do dièse Majeur
*/
QString MainWindow::denombre_diezes_a_la_cle()
{
// FA♯ DO♯ SOL♯ RÉ♯ LA♯ MI♯ SI♯
// 42 49 56 51 46 53 48 // midi
// 6 1 8 3 10 5 0 (reportées dans la première octave)
QString s1, s2;
int N;
int FA=0, DO=0, SOL=0, RE=0, LA=0; //, MI=0, SI=0;
s1="";
if (table_histogramme_degre[6] > 0) {FA=1; s1+=" FA#";}
if ((table_histogramme_degre[1] > 0)&&(FA==1)) {DO=1; s1+= " DO#";}
if ((table_histogramme_degre[8] > 0)&&(DO==1)) {SOL=1; s1+= " SOL#";}
if ((table_histogramme_degre[3] > 0)&&(SOL==1)) {RE=1; s1+= " RE#";}
if ((table_histogramme_degre[10] > 0)&&(RE==1)) {LA=1; s1+= " LA#";}
if ((table_histogramme_degre[5] > 0)&&(LA==1)) {s1+= " MI#";}
// if ((table_histogramme_degre[0] > 0)&&(MI==1)) {SI=1; s1+= " SI#";}
N = FA+DO+SOL+RE+LA;
s2.setNum(N);
s2+=" dièse";
if (N>1) {s2+="s";}
s2+=" à la clé " ;
s2 += s1;
return s2;
}
void MainWindow::affiche_histogramme_degre()
{
int y1, y2;
double dx;
double echelle;
QBrush br1;
QString couleur1;
QString s1;
effacer_calque(scene5, calque_histogramme);
GraphicsTextItem = new QGraphicsTextItem("Histogramme des degrés (gamme chromatique)");
GraphicsTextItem->setFont(QFont("Arial", 10));
GraphicsTextItem->setDefaultTextColor("#FFFFFF");
GraphicsTextItem->setPos(8, -170);
calque_histogramme->addToGroup(GraphicsTextItem);
//calcul de la valeur la plus grande
int total=0;
for(int n=0; n<12; n++) // attention à ne pas dépasser la taille de la table...
{
dx = table_histogramme_degre[n];
if (dx > total ) {total = dx;}
}
//calcul échelle y
if (total == 0) {total = 1;}
echelle = 150.0 / total;
for(int n=0; n<12; n++)
{
y1 = 20 - 10*n;
dx = echelle * table_histogramme_degre[n];
if (dx>0)
{
rect1 = new QGraphicsRectItem(40, y1, dx, 4);
couleur1="#AAFFFF";
int h1 = n;
QString couleur1 = liste_couleurs[h1];
br1.setStyle(Qt::SolidPattern);
br1.setColor(QColor(couleur1));
rect1->setPen(QColor(couleur1));
rect1->setBrush(br1);
calque_histogramme->addToGroup(rect1);
}
y2 = 12 - 10*n;
//s1.setNum(n+1);
s1=gamme_chromatique[n];
GraphicsTextItem = new QGraphicsTextItem(s1);
GraphicsTextItem->setFont(QFont("Arial", 8));
GraphicsTextItem->setDefaultTextColor(couleur1);
GraphicsTextItem->setPos(0, y2);
calque_histogramme->addToGroup(GraphicsTextItem);
}
s1 = denombre_diezes_a_la_cle();
Etiquette(10, -140, 0, s1, "#FFFF00", "#000000", "#FFFFFF", calque_histogramme );
}
void MainWindow::calcul_histogramme_degre() // degres de la gamme chromatique (= 1..12 )
{
for(int n=0; n<12; n++)
{
table_histogramme_degre[n]=0; // RAZ
}
uint16_t n_max = liste_NOTES.length();
for(int n=0; n<n_max; n++)
{
int M=liste_NOTES[n].midi;
if ((M>=40)&&(M<=82))
{
//int midi = M-40;
int H = calcul_hauteur_note(M);
table_histogramme_degre[H]++;
}
}
}
void MainWindow::affiche_histogramme()
{
//la suite fait planter !
if(radioButton_D->isChecked())
{
calcul_histogramme_durees();
affiche_histogramme_durees();
}
if(radioButton_M->isChecked())
{
calcul_histogramme_midi();
affiche_histogramme_midi();
}
if(radioButton_H->isChecked())
{
calcul_histogramme_degre();
affiche_histogramme_degre();
}
}
void MainWindow::trace_liste_notes() //dessine des cercles colorés (couleur midi) sur la grille
{
tri_liste_notes_par_num_barre(); //les notes seront triées par temps croissant
numerotation_liste_notes();
effacer_calque(scene4,calque_notes_manuelles);
effacer_calque(scene4,calque_notes_jouee);
QString s1;
int midi_i;
double x, dx, y;
double x_suivante;
int numero;
uint16_t n_max = liste_NOTES.length();
int n_barre_1, n_barre_suivante=0;
int x0a = spinBox_x0a->value();
double x0b = 10.0 * doubleSpinBox_x0b->value();
x0b += 20.0 * x0a;
QString blanc = "#FFFFFF";
QString jaune = "#FFFF00";
// QString cyan = "#00FFFF";
for(int n=0; n<n_max; n++)
{
n_barre_1=0;
if (mode=='T') {n_barre_1 = liste_NOTES[n].n_barreT; }
if (mode=='M')
{
n_barre_1 = liste_NOTES[n].n_barreM;
if (n < n_max-1) { n_barre_suivante = liste_NOTES[n+1].n_barreM;}
else {n_barre_suivante = num_barre_saisie;}
}
//memo_x = x;
x = calcul_x_barre(n_barre_1);
x_suivante = calcul_x_barre(n_barre_suivante);
dx = x_suivante -x;
midi_i = liste_NOTES[n].midi;
if ((midi_i >=28) && (midi_i <=83) )
{
y = calcul_y_note(midi_i);
int h1 = calcul_hauteur_note(midi_i);
QString couleur1 = liste_couleurs[h1];
ellipse1 = new QGraphicsEllipseItem(x-8, y-8, 16, 16); // cercle
if (mode=='T') {ellipse1->setPen(QColor(jaune));}
if (mode=='M') {ellipse1->setPen(QColor(blanc));}
ellipse1->setBrush(QColor(couleur1));
calque_notes_manuelles->addToGroup(ellipse1);
// marque la durée des notes par un fin rectangle horizontal
if ( (mode_composition = true) && (mode == 'M') && (visu_freq == 0) && (n<n_max-1) )
{
rectangle1 = new QGraphicsRectItem(x, y-2, dx, 4);
rectangle1->setPen(QColor(couleur1));
calque_notes_manuelles->addToGroup(rectangle1);
}
// inscrit le numéro de la note au centre de la note
numero = liste_NOTES[n].numero;
s1.setNum(numero);
GraphicsTextItem = new QGraphicsTextItem(s1);
GraphicsTextItem->setFont(QFont("Arial", 8));
GraphicsTextItem->setDefaultTextColor("#000000");
int x2 = x-12; if(numero<10){x2+=4;}
GraphicsTextItem->setPos(x2, y-10);
calque_notes_manuelles->addToGroup(GraphicsTextItem);
}
if( liste_NOTES[n].statut & 0b00000001 == 0b00000001) {surbrille_note(n, false, 2);}
}
tracer_echelle_temps_TAB_NOTES();
}
void MainWindow::numerotation_liste_notes()
{
uint16_t i_max = liste_NOTES.length();
for(uint16_t n=0; n<i_max; n++)
{
liste_NOTES[n].numero = n;
}
}
void MainWindow::suppression_notes_invalides()
{
int midi;
int nb = 0;
uint16_t n_max = liste_NOTES.length();
if (n_max == 0) {return;}
bool boucler=true;
do
{
nb=0;
for(uint16_t n=0; n<n_max; n++)
{
midi = liste_NOTES[n].midi;
if ((midi <40) || (midi>82))
{
supprime_note(n);
if (n_max == 0) {return;}
n_max --;
nb++;
}
}
if (nb==0) {boucler=false;}
}
while (boucler == true);
}
void MainWindow::suppression_mesures()
{
//int midi;
uint16_t n_max = liste_NOTES.length();
int nb = 0;
bool boucler=true;
do
{
nb=0;
for(int n=0; n<n_max; n++)
{
//midi = liste_NOTES[n].midi;
/*
if (midi == 100) // midi=100 codera pour les barres de mesures
{
supprime_note(n);
n_max --;
nb++;
}
*/
}
if (nb==0) {boucler=false;}
}
while (boucler == true);
}
void MainWindow::tri_liste_notes_par_num_barre()
{
// tri par bulles
int ba1=0, ba2=0; // barres
NOTE note_i;
uint16_t i_max = liste_NOTES.length();
if (i_max==0){return;}
for(int p=0; p<i_max; p++)
{
for(int n=0; n<i_max-1; n++)
{
if(mode=='T')
{
ba1=liste_NOTES[n].n_barreT;
ba2=liste_NOTES[n+1].n_barreT;
}
if(mode=='M')
{
ba1=liste_NOTES[n].n_barreM;
ba2=liste_NOTES[n+1].n_barreM;
}
if(ba1 > ba2)
{
//permutter les notes
note_i = liste_NOTES[n];
liste_NOTES[n] = liste_NOTES[n+1];
liste_NOTES[n+1] = note_i;
}
}
}
}
void MainWindow::ajout_note(int midi, int n_barreT, int n_barreM)
{
// ajout d'une note à la fin de la liste 'liste_NOTES[]'
NOTE note_i;
note_i.midi = midi;
note_i.n_barreT = n_barreT; // valeur discrète, entière : numéro de la barre de la grille temporelle
note_i.n_barreM = n_barreM;
liste_NOTES << note_i;
tri_liste_notes_par_num_barre();
}
void MainWindow::deplace_note(int num, int DG, int HB)
{
//if (n<=0) {return;}
if (num >= liste_NOTES.length()) {return;}
NOTE note_i;
note_i = liste_NOTES[num];
if (mode == 'T')
{
note_i.n_barreT = note_i.n_barreT+DG;
note_i.midi = note_i.midi+HB;
}
if (mode == 'M')
{
note_i.n_barreM = note_i.n_barreM+DG;
note_i.midi = note_i.midi+HB;
}
liste_NOTES[num] = note_i;
surbrille_note(num, true, 1);
}
void MainWindow::duplique_notes(int n_barreM_1, int n_barreM_2, int nombre)
{
NOTE note_i;
int midi_i;
int n_max = liste_NOTES.length();
for (int n_i = 0; n_i < nombre; n_i ++)
{
for(int n=0; n<n_max; n++)
{
note_i = liste_NOTES[n];
midi_i = note_i.midi;
if(note_i.n_barreM == n_barreM_1+n_i)
{
ajout_note(midi_i, 0, n_barreM_2+n_i);
}
}
}
}
void MainWindow::supprime_note(int16_t n)
{
int n_max = liste_NOTES.length();
if ( (n>=0) && (n<n_max) )
{
liste_NOTES.remove(n);
effacer_calque(scene4, calque_notes_manuelles);
tri_liste_notes_par_num_barre(); //les notes seront triées par temps croissant
numerotation_liste_notes(); //les notes seront numérotées par temps croissant
trace_liste_notes();
}
}
int MainWindow::test_if_note_in_liste(int16_t n_barre, int midi)
{
// retourne la position dans la liste, sinon zéro;
int16_t barre_i=0; // accepte nb négatifs
int midi_i;
int i_max = liste_NOTES.length();
for(int n=0; n<i_max; n++)
{
if(mode=='T') {barre_i = liste_NOTES[n].n_barreT;}
if(mode=='M') {barre_i = liste_NOTES[n].n_barreM;}
midi_i = liste_NOTES[n].midi;
// int diff_n = abs(barre_i-n_barre);
//if ((diff_n ==0) && (midi_i == midi))
if ((barre_i == n_barre) && (midi_i == midi))
{
return n;
}
}
return -1000;
}
uint16_t MainWindow::calcul_n_barreM_note(uint16_t n)
//numero de la barre M la plus proche de la note posée sur une barre T
{
uint16_t nT = liste_NOTES[n].n_barreT;
mode='T';
int xT = calcul_x_barre(nT);
int trouve = 0;
int16_t i =-250;
mode='M';
// int x0a = spinBox_x0a->value();
// double x0b = 10.0 * doubleSpinBox_x0b->value();
// x0b += 20.0 * x0a;
while ((trouve == 0) && (i<600))
{
double xi = calcul_x_barre(i);
double diff = xT - xi;
if(diff<0)diff = -diff;
if(diff < calcul_pas_grille() /2 )
{
trouve = 1;
}
i++;
}
if (trouve == 0) {i=1;}
mode='T';
return i-1;
}
uint16_t MainWindow::calcul_n_barreT_note(uint16_t n)
{
//numero de la barre T la plus proche de la note posée sur une barre M
//toutefois cette fonction est à revoir, HS telle-quelle !
int16_t nM = liste_NOTES[n].n_barreM;
mode='M';
int xM = calcul_x_barre(nM);
int trouve = 0;
int16_t i = -500;
//spinBox_x0a->setValue(0);
mode='T';
double pas_T = calcul_pas_grille();
while ((trouve == 0) && (i<2000))
{
double xi = calcul_x_barre(i);
if (xi>0)
{
double diff = xM - xi;
if(diff<0)
{
diff = -diff;
}
if(diff < (pas_T /1.5) )
{
trouve = 1;
}
}
i++;
}
if (trouve == 0) {i=1;}
mode='M';
return i-1;
}
void MainWindow::affi_txt_en_couleur(int midi_i, QLineEdit *lineEdit_i)
{
int h1 = calcul_hauteur_note(midi_i);
QString c1 = liste_couleurs[h1];
QString c2 = "#000000";
lineEdit_i->setStyleSheet("color: " + c1 + "; background-color: " + c2 + "; font: 700 14pt 'Ubuntu';");
}
void MainWindow::encadre_midi(int n_midi) // sur l'onglet 'NOTES' dans la liste des notes à gauche
{
//n_midi = 82; /// pour test (ok)
if ((n_midi<28) || (n_midi>82)) {return;}
effacer_calque(scene3, calque_gradu_TAB_FRQ);
tracer_graduation_TAB_NOTES();
double x, dx, y1, y2, dy;
int dm = n_midi -28;
y1 = 645 - (dm * 12);
dy=12;
x=0;
dx=85;
rectangle1 = new QGraphicsRectItem(x, y1, dx, dy);
QPen pen1;
pen1.setColor("#FFFFFF");
pen1.setWidth(1);
rectangle1->setPen(pen1);
calque_gradu_TAB_FRQ->addToGroup(rectangle1);
if (! checkBox_sel_boite->isChecked())
{
y2 = y1 + 44;
ligne1 = new QGraphicsLineItem(0, y2, 12000, y2); // ligne horizontale sur toute la largeur du calque
ligne1->setPen(pen1);
calque_surbrillance->addToGroup(ligne1);
}
}
int MainWindow::num_barre(double xi) // en fonction de la position x
{
//double pas_grille = spinBox_dxa->value()/2.0 * zoom_x; // pas de la grille
//double offset_grille = 0; //75;
//double x_barre = offset_grille; //0
int n_barre=0; // numero de la barre verticale de la grille T temporelle (depuis le départ)
double x_barre=0;
bool trouve = false; // à priori
int n =-100; // nb négatif pour prendre en compte les notes situées en amont (à gauche) de la barre zéro
while ((n<2000) && (trouve == false))
{
double dx2 = xi- x_barre;
if (dx2<0) {dx2 = -dx2;}
if (dx2 < calcul_pas_grille()/2.0)
{
trouve = true;
n_barre = n; // numero de la barre verticale de la grille temporelle
}
x_barre = calcul_x_barre(n+1);
n++;
}
if (trouve == false) {return -1000;}
//if (n==0) {return -1000;}
return n_barre;
}
int MainWindow::recherche_note(double y_i)
{
// recherche (verticale) de la note midi la plus proche du point cliqué
int dm =-1;
for(int n=0; n<=54; n++)
{
int d1= (684-y_i) - 12*n; // 704
//d1=abs(d1);
if(d1<0){d1= -d1;}
if(d1 <= 5) { dm = n; } // 5 sachant que l'espacement (vertical) de niveaux est = 10
}
return dm;
}
void MainWindow::recherche_notes_rect()
{
// recherche des notes comprises dans un rectangle
int n_max = liste_NOTES.length();
for (int n=0; n< n_max; n++)
{
int n_barre_i = liste_NOTES[n].n_barreM;
int midi_i = liste_NOTES[n].midi;
double x = calcul_x_barre(n_barre_i);
double y = calcul_y_note(midi_i);
if ((x >= x0_boite) && (x <= x1_boite) && (y >= y0_boite) && (y <= y1_boite) )
{
liste_NOTES[n].statut |= 0b00000001 ;
surbrille_note(n, false, 2);
}
}
}
void MainWindow::mouseMoveEvent(QMouseEvent *event) // actif si le clic de droite reste appuyé
{
double x0, y0; // position cliquée
int midi=0;
int dm =0;
double scroll_x = GV_grillesTM->horizontalScrollBar()->value();
double scroll_y = GV_grillesTM->verticalScrollBar()->value();
x_clic_ecran = event->position().x();
y_clic_ecran = event->position().y();
x0 = x_clic_ecran-102 + scroll_x; // position cliquée
y0 = y_clic_ecran-78 + scroll_y; // 78
// recherche (verticale) de la note midi la plus proche du point cliqué
dm = recherche_note(y0);
if (dm == -1) {return;}
// calcul de la valeur midi de la note
midi = 28 + dm;
effacer_calque(scene4, calque_rect_select);
effacer_calque(scene4, calque_surbrillance);
encadre_midi(midi);
affi_details_note(midi);
// sélection par boite
if (checkBox_sel_boite->isChecked())
{
x0_boite = x_clic_GRV4;
x1_boite = x0;
if(x1_boite <= x0_boite) { x1_boite=x0_boite +1; }
y0_boite = y_clic_GRV4 -8.0;
y1_boite = y0;
if(y1_boite <= y0_boite) { y1_boite=y0_boite +1; }
// rectangle1 = new QGraphicsRectItem(x_clic_GRV4, y_clic_GRV4 -8.0, x0 - x_clic_GRV4, y0 - y_clic_GRV4);
rectangle1 = new QGraphicsRectItem(x0_boite, y0_boite -8.0, x1_boite - x0_boite, y1_boite - y0_boite);
QPen pen1;
pen1.setColor("#F57900");
pen1.setWidth(1);
rectangle1->setPen(pen1);
calque_rect_select->addToGroup(rectangle1);
deselect_notes();
//effacer_calque(scene4, calque_notes_jouee);
recherche_notes_rect();
trace_liste_notes();
}
}
void MainWindow::affi_details_note(int midi)
{
QString s1;
s1.setNum(midi);
lineEdit_7->setText(s1);
affi_txt_en_couleur(midi, lineEdit_7b);
lineEdit_7b->setText(nom_note(midi));
affi_txt_en_couleur(midi, lineEdit_7e);
s1=nom_note_GB(midi);
s1+=nom_octave_GB(midi);
lineEdit_7e->setText(s1);
double F = freq_mid(midi);
s1.setNum(F);
s1.replace('.',','); // ce qui permet un copié-collé direct dans 'Adacity'
lineEdit_7d->setText(s1);
}
void MainWindow::mouseReleaseEvent(QMouseEvent *event)
{
// sert à ajouter une note (en write_mode 1) lorsqu'on relache le clic
// tant que le clic de droite reste enfoncé cela permet de confirmer la note midi qui sera ajoutée
// (mise en surbrillance en temps réel de la valeur midi dans la colonne de gauche)
QString s1;
double x0, y0; // position cliquée
int n_barre=0; // numero de la barre verticale de la grille temporelle (depuis le départ)
int n2=0;
int midi=0;
int dm =0;
double scroll_x = GV_grillesTM->horizontalScrollBar()->value();
double scroll_y = GV_grillesTM->verticalScrollBar()->value();
x_clic_ecran = event->position().x();
y_clic_ecran = event->position().y();
x0 = x_clic_ecran-102 + scroll_x; // position cliquée
y0 = y_clic_ecran-78 + scroll_y;
//qDebug() << "y0" << y0;
dm = recherche_note(y0);
if (dm == -1) {return;}
midi = 28 + dm; // calcul de la valeur midi de la note
n_barre = num_barre(x0);
if (n_barre == -1000) {return;}
affi_details_note(midi);
n2 = test_if_note_in_liste(n_barre, midi); // si note in liste, -> n2 = num de la note
if (n2 != -1000) { QString s1; s1.setNum(n2); lineEdit_7c->setText(s1); }
if (write_mode == 1) // WRITE (ajout d'une note)
{
n2 = test_if_note_in_liste(n_barre, midi);
if (n2 == -1000) // si la note ne figure pas déjà dans la liste...
{
// enregistre la note dans la liste (à la fin)
if(mode=='T') {ajout_note(midi, n_barre, 0);}
if(mode=='M') {ajout_note(midi, 0, n_barre);}
}
effacer_calque(scene4,calque_notes_manuelles);
//effacer_calque(scene4,calque_notes_jouee);
tri_liste_notes_par_num_barre(); // les notes seront triées par num_barre croissant
numerotation_liste_notes(); // les notes seront numérotées par num_barre croissant
affiche_liste_notes();
trace_liste_notes();
surbrille_note(n2, true, 1);
}
}
void MainWindow::deselect_notes()
{
int n_max =liste_NOTES.length();
for (int n =0; n<n_max; n++)
{
liste_NOTES[n].statut &= ~0b00000001;
}
effacer_calque(scene4, calque_surbrillance);
}
void MainWindow::contextMenuEvent(QContextMenuEvent *event) // menu contextuel (c.a.d déclenché par le clic de droite)
{
qDebug() << "clic de droite";
if (Boite_Onglets_Global->currentIndex() == 2)
{
QString s1, s2, s3;
int x_min, x_max, y_min, y_max;
x_min = GRW_manche->x();
x_max = x_min + GRW_manche->width();
y_min = GRW_manche->y();
y_max = y_min + GRW_manche->height();
//x_clic_ecran = event->position().x(); // écriture incompatible pour le clic de gauche...
//y_clic_ecran = event->position().y();
int x_clic_global = event->globalX();
int y_clic_global = event->globalY();
int x_clic_manche = x_clic_global;
int y_clic_manche = y_clic_global-25;
if (x_clic_manche > x_min && x_clic_manche < x_max && y_clic_manche > y_min && y_clic_manche < y_max)
{
// suite à un clic sur le manche :
detecte_note_xy(x_clic_manche, y_clic_manche, &corde_jouee, &case_jouee); // actualise les variables globales
s1.setNum(case_jouee); lineEdit_case_i->setText(s1);
s1.setNum(corde_jouee); lineEdit_corde_i->setText(s1);
}
if (corde_jouee>0)
{
case_min = 0;
case_max = 20;
// checkBox_not_erase->setChecked(false);
if (!checkBox_not_erase->isChecked()) {on_Bt_RAZ_clicked();}
s2.setNum(corde_jouee);
LBL_corde->setText("corde " + s2);
s3.setNum(case_jouee);
LBL_case->setText("case " + s3);
n_midi_jouee = calcul_midi(corde_jouee, case_jouee);
//affiche_details_note(n_midi_jouee);
execute_note_midi(n_midi_jouee);
}
int h = calcul_hauteur_note(n_midi_jouee);
//qDebug() << "h" << h;
QColor c1 = liste_couleurs[h];
s1.setNum(n_midi_jouee);
s2 = "mode: DEPOT NOTE (m"+ s1 + ")\n";
s2 += "clic dans une case de TW3 pour placer la note -->";
label_MESSAGE->setText(s2);
label_MESSAGE->setVisible(true);
set_couleur_label(c1, label_MESSAGE);
mode_depot_note = true;
MainWindow::setCursor(Qt::CrossCursor);
}
}
void MainWindow::detecte_note_xy(int x_i, int y_i, int *corde_i, int *case_i)
{
// suite à un clic directement sur le manche
// voir la fonction "mousePressEvent()"
float y;
float dy;
float y0;
float ech;
// détection du numéro de la case jouée
*case_i=-1;
for (int i=0; i<21; i++)
{
int x= positionsX[i] +30;
if ((abs(x_i - x))<30) {*case_i = i;}
}
if (*case_i == -1)
{
*corde_i=0;
*case_i=0;
return;
}
// détection du numéro de la corde jouée
*corde_i=0;
y0=270; //250
for (int i=1; i<=6; i++)
{
ech=1+ *case_i/90.0;
dy=-20.0*((7-i)-3.2);
dy *= ech;
y=y0+dy;
if ((abs(y_i - y))<20) {*corde_i = i;}
}
}
void MainWindow::execute_note_midi(uint midi)
{
calcul_hauteur_note(midi);
if (checkBox1->isChecked()) {on_Bt_RAZ_clicked();} // efface tout avant de ne dessiner qu'une seule note
//QString s1;
//s1.setNum(i);
//lineEdit_7->setText(s1);
num_note_jouee++;
switch(midi)
{
case 40: on_Bt_E3_clicked(); break; // mi
case 41: on_Bt_F3_clicked(); break; // fa
case 42: on_Bt_Fd3_clicked(); break; // fa#
case 43: on_Bt_G3_clicked(); break; //sol
case 44: on_Bt_Gd3_clicked(); break; //sol#
case 45: on_Bt_A3_clicked(); break; //la
case 46: on_Bt_Bb3_clicked(); break; //sib
case 47: on_BT_B3_clicked(); break; //si
case 48: on_Bt_C4_clicked(); break; //do
case 49: on_Bt_Cd4_clicked(); break; //do#
case 50: on_Bt_D4_clicked(); break; //re
case 51: on_Bt_Eb4_clicked(); break; //mib
case 52: on_Bt_E4_clicked(); break; //mi
case 53: on_Bt_F4_clicked(); break; //fa
case 54: on_Bt_Fd4_clicked(); break; //fa#
case 55: on_Bt_G4_clicked(); break; //sol
case 56: on_Bt_Gd4_clicked(); break; //sol#
case 57: on_Bt_A4_clicked(); break; //la
case 58: on_Bt_Bb4_clicked(); break; //sib
case 59: on_Bt_B4_clicked(); break; //si
case 60: on_Bt_C5_clicked(); break; //do
case 61: on_Bt_Cd5_clicked(); break; //do#
case 62: on_Bt_D5_clicked(); break; //re
case 63: on_Bt_Eb5_clicked(); break; //mib
case 64: on_Bt_E5_clicked(); break; //mi
case 65: on_Bt_F5_clicked(); break; //fa
case 66: on_Bt_Fd5_clicked(); break; //fa#
case 67: on_Bt_G5_clicked(); break; //sol
case 68: on_Bt_Gd5_clicked(); break; //sol#
case 69: on_Bt_A5_clicked(); break; //la
case 70: on_Bt_Bb5_clicked(); break; //sib
case 71: on_Bt_B5_clicked(); break; //si
case 72: on_Bt_C6_clicked(); break; //do
case 73: on_Bt_Cd6_clicked(); break; //do#
case 74: on_Bt_D6_clicked(); break; //re
case 75: on_Bt_Eb6_clicked(); break; //mib
case 76: on_Bt_E6_clicked(); break; //mi
case 77: on_Bt_F6_clicked(); break; //fa
case 78: on_Bt_Fd6_clicked(); break; //fa#
case 79: on_Bt_G6_clicked(); break; //sol
case 80: on_Bt_Gd6_clicked(); break; //sol#
case 81: on_Bt_A6_clicked(); break; //la
case 82: on_Bt_Bb6_clicked(); break; //sib
default: { ; } break;
}
}
void MainWindow::mousePressEvent(QMouseEvent *event) // code provenant du prog 'guitare'
{
if(event->button() == Qt::RightButton) {return;}
qDebug() << "clic de gauche";
//================================================================================================================
if (Boite_Onglets_Global->currentIndex() == 1)
{
QString s1;
//double x0, y0; // position cliquée
int n_barre=0; // numero de la barre verticale de la grille temporelle (depuis le départ)
int n2=0;
//double x_barre=0;
double x_min, x_max;
double y_min, y_max;
int midi=0; // midi
int dm =0;
double scroll_x = GV_grillesTM->horizontalScrollBar()->value();
double scroll_y = GV_grillesTM->verticalScrollBar()->value();
GV_grillesTM->verticalScrollBar()->setValue(0);
//if (checkBox_sel_boite->isChecked()) { deselect_notes();}
effacer_calque(scene4, calque_surbrillance);
s1.setNum(scroll_x); lineEdit_8->setText(s1);
s1.setNum(scroll_y); lineEdit_9->setText(s1);
x_min = GV_grillesTM->x();
x_max = x_min + GV_grillesTM->width();
y_min = GV_grillesTM->y()+60;
y_max = y_min + GV_grillesTM->height() + 32; // +32 sinon rate le mi grave (midi 40)
x_clic_ecran = event->position().x(); // variable globale
y_clic_ecran = event->position().y();
x_clic_GRV4 = x_clic_ecran-102 + scroll_x; // position cliquée // variable globale
y_clic_GRV4 = y_clic_ecran-78 + scroll_y; // 78
// ---------------------- si clic sur la surface de graphicsView4 ----------------------------------------
if (x_clic_ecran > x_min && x_clic_ecran < x_max && y_clic_ecran > y_min && y_clic_ecran < y_max)
{
s1.setNum(x_clic_GRV4); lineEdit_4->setText(s1);
s1.setNum(y_clic_GRV4); lineEdit_5->setText(s1); // =481 foire !
dm = recherche_note(y_clic_GRV4);
if (dm != -1)
{
// calcul de la valeur midi de la note
midi = 28 + dm;
encadre_midi(midi);
n_barre = num_barre(x_clic_GRV4);
num_barre_saisie = n_barre;
spinBox_num_barre->setValue(num_barre_saisie);
surbrille_barre(num_barre_saisie, "#00FF00");
//if (n_barre == -1000) {return;}
affi_details_note(midi);
n2 = test_if_note_in_liste(n_barre, midi); // si note in liste, -> n2 = num de la note
if (n2 != -1000) { QString s1; s1.setNum(n2); lineEdit_7c->setText(s1); }
if (write_mode == 3) // SELECT
{
n2 = test_if_note_in_liste(n_barre, midi);
if (n2 != -1000) // si la note figure dans la liste...
{
effacer_calque(scene4, calque_notes_jouee);
num_note_cliquee = n2;
//liste_NOTES[n2].statut |= 0b00000001;
}
}
if (write_mode < 5) {play_note(midi);}
//effacer_calque(scene4, calque_surbrillance);
// encadre_midi(midi);
// surbrille_note(n2, true);
if (write_mode == 2) // EFFACE une note puis quitte ce mode
{
n2 = test_if_note_in_liste(n_barre, midi);
if (n2 != -1000) // si la note figure dans la liste...
{
supprime_note(n2);
on_Bt_mode_R_clicked(); // repasse en mode LECTURE pour éviter d'effacer d'autres notes par erreur
}
}
if (write_mode == 4) // EFFACE plusieurs notes (c.à.d ne quitte pas le mode)
{
if (checkBox_sel_boite->isChecked())
{
int n_max = liste_NOTES.length();
for(int n=0; n<n_max; n++)
{
if ((liste_NOTES[n].statut & 0b00000001) == 0b00000001) {supprime_note(n);}
}
}
n2 = test_if_note_in_liste(n_barre, midi);
if (n2 != -1000) // si la note figure dans la liste...
{
supprime_note(n2);
}
}
if (write_mode == 5) // COPIER groupe de notes
{
n_barre_copie = n_barre;
MainWindow::setCursor(Qt::PointingHandCursor);
encadre_groupe_notes(n_barre_copie, spinBox_nb_copie->value());
//surbrille_barre(n_barre_copie);
write_mode = 6;
}
else if (write_mode == 6) // COLLER groupe de notes
{
duplique_notes(n_barre_copie, n_barre, spinBox_nb_copie->value());
write_mode = 0;
effacer_calque(scene4, calque_surbrillance);
encadre_groupe_notes(n_barre, spinBox_nb_copie->value());
MainWindow::setCursor(Qt::ArrowCursor);
}
}
else
{
;
//deselect_notes();
//write_mode =0;
}
}
//int h1 = calcul_hauteur_note(midi);
//QColor couleur1 = liste_couleurs[h1];
effacer_calque(scene4,calque_notes_manuelles);
//effacer_calque(scene4,calque_notes_jouee);
tri_liste_notes_par_num_barre(); // les notes seront triées par num_barre croissant
numerotation_liste_notes(); // les notes seront numérotées par num_barre croissant
affiche_liste_notes();
trace_liste_notes();
surbrille_note(n2, true, 1);
encadre_midi(midi);
int octave = (midi-36) /12;
int hauteur = calcul_hauteur_note(midi);
spinBox_octave->setValue(octave);
spinBox_hauteur->setValue(hauteur);
spinBox_num_note->setValue(num_note_cliquee);
spinBox_10->setValue(num_note_cliquee); // 'debut'
if (0) // 1 pour test (affiche une petite croix à la position cliquée)
{
int d=10; // taille
QPen pen1; pen1.setColor("#FFFF00");
ligne1 = new QGraphicsLineItem(x_clic_GRV4-d, y_clic_GRV4-d, x_clic_GRV4+d, y_clic_GRV4+d);
ligne1->setPen(pen1);
calque_notes_manuelles->addToGroup(ligne1);
ligne1 = new QGraphicsLineItem(x_clic_GRV4-d, y_clic_GRV4+d, x_clic_GRV4+d, y_clic_GRV4-d);
ligne1->setPen(pen1);
calque_notes_manuelles->addToGroup(ligne1);
}
}
//=================================== POUR L'ONGLET 2 'INSTRUMENTS' =====================================================
if (Boite_Onglets_Global->currentIndex() == 2)
{
QString s1, s2, s3;
int x_min, x_max, y_min, y_max;
x_min = GRW_manche->x();
x_max = x_min + GRW_manche->width();
y_min = GRW_manche->y();
y_max = y_min + GRW_manche->height()+30;
x_clic_ecran = event->position().x();
y_clic_ecran = event->position().y();
if (x_clic_ecran > x_min && x_clic_ecran < x_max && y_clic_ecran > y_min && y_clic_ecran < y_max)
{
// suite à un clic sur le manche :
detecte_note_xy(x_clic_ecran, y_clic_ecran, &corde_jouee, &case_jouee); // actualise les variables globales
s1.setNum(case_jouee); lineEdit_case_i->setText(s1);
s1.setNum(corde_jouee); lineEdit_corde_i->setText(s1);
if (corde_jouee>=0)
{
case_min = 0;
case_max = 20;
// checkBox_not_erase->setChecked(false);
if (!checkBox_not_erase->isChecked()) {on_Bt_RAZ_clicked();}
s2.setNum(corde_jouee);
LBL_corde->setText("corde " + s2);
s3.setNum(case_jouee);
LBL_case->setText("case " + s3);
n_midi_jouee = calcul_midi(corde_jouee, case_jouee);
//affiche_details_note(n_midi_jouee);
calcul_hauteur_note(n_midi_jouee);
execute_note_midi(n_midi_jouee);
}
}
else
{
mode_depot_note = false;
label_MESSAGE->setVisible(false);
MainWindow::setCursor(Qt::ArrowCursor);
}
/*
if (0) // 1 pour test (affiche une petite croix à la position cliquée)
{
int d=30; // taille
QPen pen1; pen1.setColor("#FFFF00");
ligne1 = new QGraphicsLineItem(x_clic_ecran-d, y_clic_ecran-d, x_clic_ecran+d, y_clic_ecran+d);
ligne1->setPen(pen1);
calque_notes_manche->addToGroup(ligne1);
ligne1 = new QGraphicsLineItem(x_clic_ecran-d, y_clic_ecran+d, x_clic_ecran+d, y_clic_ecran-d);
ligne1->setPen(pen1);
calque_notes_manche->addToGroup(ligne1);
}
*/
}
}
int MainWindow::joue_1_note_de_la_liste()
{
NOTE note_i1, note_i2;
int midi_i;
int barre1=0;
int barre2=0;
int d_barre;
QString s1;
QDateTime tpi;
tpi = QDateTime::currentDateTime();
qint64 tp_relatif = temps_0.msecsTo(tpi); // en ms
s1.setNum(tp_relatif);
uint16_t num_max = liste_NOTES.length();
if (num_max == 0) {return 0;}
if (num_max < 3) {return 0;}
if (num_note_jouee >= num_max-1)
{
// fin du morceau !
lecture_en_cours = false;
Timer2->stop();
Bt_jouer_tout->setText(">");
return 0;
}
note_i1 = liste_NOTES[num_note_jouee];
if(num_note_jouee < num_max)
{
note_i2 = liste_NOTES[num_note_jouee+1];
}
else
{
note_i2 = liste_NOTES[num_note_jouee];
}
midi_i=note_i1.midi;
if(mode == 'T')
{
barre1 = note_i1.n_barreT;
barre2 = note_i2.n_barreT;
}
if(mode == 'M')
{
barre1 = note_i1.n_barreM;
barre2 = note_i2.n_barreM;
}
d_barre = barre2 - barre1;
if (d_barre < 0){d_barre = -d_barre;}
if (barre1 == barre2) // detection d'un accord (notes simultanées)
{
// surbrille_note(num_note_jouee, false);
// surbrille_note(num_note_jouee+1, false);
nb_acc++;
}
else
{
if (nb_acc == 0) {effacer_calque(scene4, calque_notes_jouee);}
surbrille_note(num_note_jouee, false, 1);
surbrille_barre(barre1, "#FFFFFF");
if (midi_i >45) // on laisse résonner les basses
{
//player1->stop();
//player2->stop();
//player3->stop();
}
nb_acc--; if (nb_acc<0) {nb_acc=0;}
}
s1.setNum(num_note_jouee); lineEdit_7c->setText(s1);
lineEdit_7->setText("");
lineEdit_7b->setText("");
s1.setNum(midi_i) ;
if(num_note_jouee == num_max) {d_barre = 2;}
if ( ! (checkBox_basses->isChecked() && midi_i > spinBox_filtre_2->value() ))
{
play_note(midi_i);
// encadre_midi(midi_i);
}
num_note_jouee++;
if(num_note_jouee > num_note_max)
{
Timer2->stop();
effacer_calque(scene4, calque_notes_jouee);
//num_note_jouee=0;
}
return d_barre; // permet de retrouver l'espacement temporel entre la note et celle qui suit.
}
void MainWindow::on_Bt_toggle_grille_T_clicked()
{
Bt_toggle_grille_T->setStyleSheet("background-color: rgb(0, 255, 0);"); // vert
Bt_toggle_grille_M->setStyleSheet("background-color: rgb(200, 200, 200);");
mode = 'T';
mode_grille_T();
// tri_liste_notes_par_num_barre(); //les notes seront triées par temps croissant
// numerotation_liste_notes(); //les notes seront numérotées par temps croissant
// affiche_liste_notes();
trace_liste_notes();
//effacer_calque(scene4, calque_echelle_temporelle_T);
}
void MainWindow::on_Bt_toggle_visu_notes_clicked()
{
if(visu_notes == true)
{
visu_notes = false;
Bt_toggle_visu_notes->setStyleSheet("background-color: rgb(200, 200, 200);");
effacer_calque(scene4, calque_notes_manuelles);
}
else
{
visu_notes = true;
Bt_toggle_visu_notes->setStyleSheet("background-color: rgb(0, 255, 0);"); // vert
trace_liste_notes();
}
}
void MainWindow::on_Bt_toggle_grille_M_clicked()
{
Bt_toggle_grille_M->setStyleSheet("background-color: rgb(0, 255, 0);"); // vert
Bt_toggle_grille_T->setStyleSheet("background-color: rgb(200, 200, 200);");
mode = 'M';
mode_grille_M();
//tri_liste_notes_par_num_barre(); //les notes seront triées par temps croissant
// numerotation_liste_notes(); //les notes seront numérotées par temps croissant
// affiche_liste_notes();
trace_liste_notes();
}
void MainWindow::mode_grille_T()
{
effacer_calque(scene4, calque_grille_T);
effacer_calque(scene4, calque_grille_M);
effacer_calque(scene4, calque_echelle_temporelle_T);
effacer_calque(scene4, calque_echelle_temporelle_M);
frame_7->setVisible(true);
frame_10->setVisible(false);
Bt_copie_notes->setVisible(false);
Bt_12->setVisible(false);
//spinBox_dxa->setVisible(false);
doubleSpinBox_dxb->setVisible(false);
spinBox_x0a->setVisible(false);
doubleSpinBox_x0b->setVisible(false);
Bt_decale_notes_L->setVisible(true);
Bt_decale_notes_R->setVisible(true);
Bt_durees_div2->setVisible(true);
Bt_durees_mult2->setVisible(true);
tracer_grille_T();
}
void MainWindow::mode_grille_M()
{
effacer_calque(scene4, calque_grille_T);
effacer_calque(scene4, calque_grille_M);
effacer_calque(scene4, calque_echelle_temporelle_T);
effacer_calque(scene4, calque_echelle_temporelle_M);
frame_7->setVisible(false);
frame_10->setVisible(true);
Bt_copie_notes->setVisible(true);
Bt_12->setVisible(true);
//spinBox_dxa->setVisible(true);
doubleSpinBox_dxb->setVisible(true);
spinBox_x0a->setVisible(true);
doubleSpinBox_x0b->setVisible(true);
Bt_decale_notes_L->setVisible(false);
Bt_decale_notes_R->setVisible(false);
Bt_durees_div2->setVisible(false);
Bt_durees_mult2->setVisible(false);
tracer_grille_M();
}
void MainWindow::on_Bt_save_notes_clicked()
{
int r1, r2;
QDate date_systeme = QDate::currentDate();
QTime heure_systeme = QTime::currentTime();
QString date1 = date_systeme.toString("yyyyMMdd");
QString heure1 = heure_systeme.toString();
QString date_out = date1 + "_" + heure1;
r1 = save_fichier_NOTES(date_out);
r2 = save_fichier_FRQ(date_out);
if ((r1 + r2) != 2) // si = 2 -> aucun fichier enregistré, alors on n'affiche pas le message
{
QMessageBox msgBox;
QString s1="Fichiers enregistrés dans : \n" + string_currentDir + "/";
msgBox.setText(s1); msgBox.exec();
}
}
void MainWindow::on_Bt_load_notes_clicked()
{
uint16_t n_max = liste_NOTES.length();
if (n_max != 0) // pour éviter d'enregistrer un fichier vide lors du 1er chargement des notes
{
QMessageBox msgBox;
msgBox.setText("Confirmation de chargement");
msgBox.setInformativeText("Un enregistrement des notes va être effectué au préalable.\n \n"
"Si clic sur No, les notes actuelles seront perdues.\n \n"
"Si clic sur Cancel, opération annulée");
msgBox.setStandardButtons(QMessageBox::No | QMessageBox::Ok | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Cancel);
int ret = msgBox.exec();
if (ret == QMessageBox::Cancel ) { return; }
if (ret == QMessageBox::Ok ) { on_Bt_save_notes_clicked(); }
}
liste_NOTES.clear();
effacer_calque(scene4,calque_notes_manuelles);
effacer_calque(scene4,calque_notes_auto);
effacer_calque(scene4,calque_notes_jouee);
effacer_calque(scene5, calque_histogramme );
effacer_calque(scene4, calque_echelle_temporelle_T);
effacer_calque(scene4, calque_echelle_temporelle_M);
load_fichier_NOTES("");
suppression_notes_invalides();
tri_liste_notes_par_num_barre(); //les notes seront triées par temps croissant
numerotation_liste_notes();
calcul_histogramme_durees();
affiche_histogramme_durees();
on_Bt_toggle_grille_M_clicked();
}
void MainWindow::on_Bt_joue_passage_clicked()
{
if (liste_NOTES.length() == 0) {return;}
if (lecture_en_cours == true)
{
Timer2->stop();
Bt_joue_passage->setText(">");
Timer2->setInterval(0);
lecture_en_cours = false;
}
else
{
Bt_joue_passage->setText("[]");
Timer2->start(500);
int note_de_depart = spinBox_10->value();
int nb_notes_a_jouer = spinBox_11->value()-1;
num_note_jouee = note_de_depart;
num_note_max = note_de_depart + nb_notes_a_jouer;
if (num_note_max > liste_NOTES.length()-1) { num_note_max = liste_NOTES.length()-1;}
// NOTE note_i = liste_NOTES[note_de_depart];
//double x_note = 80 + note_i.n_barreT * spinBox_dxa->value()/2.0 * zoom_x;
// graphicsView4->horizontalScrollBar()->setValue(x_note - 100);
Timer2->start(500);
lecture_en_cours = true;
}
}
void MainWindow::on_Bt_joue_wav_clicked()
{
QStringList arguments;
arguments << string_currentFile;
QString program = "audacity"; //"audacious"
QProcess *myProcess = new QProcess();
myProcess->start(program, arguments);
}
void MainWindow::on_Bt_joue_wav_2_clicked()
{
on_Bt_joue_wav_clicked();
}
void MainWindow::on_Btn_RAZ_notes_clicked()
{
QMessageBox msgBox;
msgBox.setText("Erase notes");
msgBox.setInformativeText("Effacer toutes les notes ?");
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Cancel);
int ret = msgBox.exec();
if (ret == QMessageBox::Ok )
{
liste_NOTES.clear();
num_barre_en_cours=0;
effacer_calque(scene4, calque_notes_manuelles);
effacer_calque(scene4, calque_notes_auto);
affiche_liste_notes();
effacer_calque(scene4, calque_surbrillance);
num_barre_saisie=0;
surbrille_barre(num_barre_saisie, "#00FF00");
}
}
void MainWindow::on_Btn_RAZ_notes_2_clicked()
{
QMessageBox msgBox;
msgBox.setText("Erase certaines notes");
msgBox.setInformativeText("Effacer des notes ?");
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Cancel);
int ret = msgBox.exec();
if (ret == QMessageBox::Ok )
{
int n = spinBox_n_raz->value();
//int n_max = liste_NOTES.length();
int n_max = liste_NOTES.length();
if (n<n_max)
{
liste_NOTES.remove(n, n_max-n);
}
int n_max2 = liste_ENR_FFT.length();
int n2= 300*n;
if (n2<n_max2)
{
liste_ENR_FFT.remove(n2, n_max2-n2);
}
effacer_calque(scene4, calque_notes_manuelles);
trace_liste_notes();
effacer_calque(scene4, calque_TAB_FRQ);
retracer_TAB_FRQ();
//effacer_calque(scene4,calque_notes_manuelles);
//effacer_calque(scene4, calque_notes_auto);
//affiche_liste_notes();
}
}
void MainWindow::on_spinBox_8_textChanged()
{
effacer_calque(scene4, calque_echelle_temporelle_T);
effacer_calque(scene4, calque_echelle_temporelle_M);
tracer_echelle_temps_TAB_NOTES();
}
void MainWindow::on_doubleSpinBox_x0_valueChanged(double arg1)
{
//double pas_grille = spinBox_dt->value()/2.0 * zoom_x;
//double offset_x = 10 * arg1 + spinBox_d_barres->value() * pas_grille;
// calque_TAB_FRQ->setPos(offset_x, 0);
// calque_notes_auto->setPos(offset_x, 0);
effacer_calque(scene4, calque_grille_M);
tracer_grille_M();
// effacer_calque(scene4, calque_notes_manuelles);
// affiche_liste_notes();
// trace_liste_notes();
// effacer_calque(scene4, calque_echelle_temporelle_T);
// tracer_echelle_temps_TAB_NOTES();
}
void MainWindow::on_spinBox_dxa_valueChanged(int arg1)
{
//doubleSpinBox_dxb->setValue(0);
effacer_calque(scene4, calque_echelle_temporelle_T);
effacer_calque(scene4, calque_grille_M);
tracer_grille_M();
effacer_calque(scene4, calque_notes_manuelles);
affiche_liste_notes();
//trace_liste_notes();
tracer_echelle_temps_TAB_NOTES();
if (visu_notes == true) {trace_liste_notes();}
// on_Bt_copy_nt_T_to_M_clicked();
}
void MainWindow::on_doubleSpinBox_dxb_valueChanged(double arg1)
{
effacer_calque(scene4, calque_grille_M);
effacer_calque(scene4, calque_echelle_temporelle_T);
effacer_calque(scene4, calque_echelle_temporelle_M);
effacer_calque(scene4, calque_notes_manuelles);
on_Bt_copy_nt_T_to_M_clicked();
affiche_liste_notes();
trace_liste_notes();
tracer_grille_M();
tracer_echelle_temps_TAB_NOTES();
//if (visu_notes == true) {trace_liste_notes();}
// on_Bt_copy_nt_T_to_M_clicked();
}
void MainWindow::on_Bt_mode_R_clicked() // LECTURE
{
write_mode=0;
//mode_select=false;
MainWindow::setCursor(Qt::ArrowCursor);
Bt_mode_R->setStyleSheet("background-color: rgb(0, 255, 0);"); // vert
Bt_mode_W->setStyleSheet("background-color: rgb(200, 200, 200);");
Bt_mode_E->setStyleSheet("background-color: rgb(200, 200, 200);");
Bt_mode_E_2->setStyleSheet("background-color: rgb(200, 200, 200);");
}
void MainWindow::on_Bt_mode_W_clicked() // AJOUT
{
write_mode=1;
//mode_select=false;
//MainWindow::setCursor(Qt::SplitHCursor);
effacer_calque(scene4, calque_notes_jouee);
Bt_mode_W->setStyleSheet("background-color: rgb(255, 0, 0);"); // rouge
Bt_mode_R->setStyleSheet("background-color: rgb(200, 200, 200);");
Bt_mode_E->setStyleSheet("background-color: rgb(200, 200, 200);");
Bt_mode_E_2->setStyleSheet("background-color: rgb(200, 200, 200);");
}
void MainWindow::on_Bt_mode_E_clicked() // EFFACE 1 note puis quitte ce mode
{
write_mode=2;
//mode_select=false;
//MainWindow::setCursor(Qt::SplitHCursor);
Bt_mode_E->setStyleSheet("background-color: rgb(0, 200, 200);"); // cyan
Bt_mode_E_2->setStyleSheet("background-color: rgb(200, 200, 200);");
Bt_mode_W->setStyleSheet("background-color: rgb(200, 200, 200);");
Bt_mode_R->setStyleSheet("background-color: rgb(200, 200, 200);");
}
void MainWindow::on_Bt_mode_E_2_clicked() // efface plusieurs notes (c.a.d reste dans ce mode)
{
if (write_mode == 4)
{
deselect_notes();
effacer_calque(scene4, calque_rect_select);
Bt_mode_E_2->setStyleSheet("background-color: rgb(200, 200, 200);"); // gris
write_mode=0;
}
else
{
Bt_mode_E_2->setStyleSheet("background-color: rgb(200, 0, 0);"); //rouge
if (checkBox_sel_boite->isChecked())
{
int n_max = liste_NOTES.length();
for(int n=0; n<n_max; n++)
{
if (n>=0)
{
if ((liste_NOTES[n].statut & 0b00000001) == 0b00000001)
{
supprime_note(n);
if (n>0) {n--;}
n_max = liste_NOTES.length();
}
}
}
deselect_notes();
effacer_calque(scene4, calque_rect_select);
Bt_mode_E_2->setStyleSheet("background-color: rgb(200, 200, 200);"); // gris
write_mode=0;
}
else
{
write_mode=4; // mode effacement plusieur notes une à la fois par clics successifs
}
Bt_mode_E->setStyleSheet("background-color: rgb(200, 200, 200);"); // gris
Bt_mode_W->setStyleSheet("background-color: rgb(200, 200, 200);"); // gris
Bt_mode_R->setStyleSheet("background-color: rgb(200, 200, 200);"); // gris
}
}
void MainWindow::on_Bt_deplace_L_clicked()
{
write_mode=3;
Bt_mode_E->setStyleSheet("background-color: rgb(200, 200, 200);");
Bt_mode_E_2->setStyleSheet("background-color: rgb(200, 200, 200);");
Bt_mode_W->setStyleSheet("background-color: rgb(200, 200, 200);");
Bt_mode_R->setStyleSheet("background-color: rgb(200, 200, 200);");
effacer_calque(scene4, calque_notes_manuelles);
effacer_calque(scene4, calque_notes_jouee);
int n_max = liste_NOTES.length();
for(int n=0; n<n_max; n++)
{
if ( (liste_NOTES[n].statut & 0b00000001) == 0b00000001) {deplace_note(n, -1, 0);}
}
affiche_liste_notes();
trace_liste_notes();
write_mode=0;
surbrille_note(num_note_cliquee, false, 1);
}
void MainWindow::on_Bt_deplace_R_clicked()
{
write_mode=3;
Bt_mode_E->setStyleSheet("background-color: rgb(200, 200, 200);");
Bt_mode_E_2->setStyleSheet("background-color: rgb(200, 200, 200);");
Bt_mode_W->setStyleSheet("background-color: rgb(200, 200, 200);");
Bt_mode_R->setStyleSheet("background-color: rgb(200, 200, 200);");
effacer_calque(scene4, calque_notes_manuelles);
effacer_calque(scene4, calque_notes_jouee);
int n_max = liste_NOTES.length();
for(int n=0; n<n_max; n++)
{
if ( (liste_NOTES[n].statut & 0b00000001) == 0b00000001) {deplace_note(n, 1, 0);}
}
affiche_liste_notes();
trace_liste_notes();
write_mode=0;
surbrille_note(num_note_cliquee, false, 1);
}
void MainWindow::on_Bt_deplace_H_clicked()
{
write_mode=3;
Bt_mode_E->setStyleSheet("background-color: rgb(200, 200, 200);");
Bt_mode_E_2->setStyleSheet("background-color: rgb(200, 200, 200);");
Bt_mode_W->setStyleSheet("background-color: rgb(200, 200, 200);");
Bt_mode_R->setStyleSheet("background-color: rgb(200, 200, 200);");
effacer_calque(scene4, calque_notes_manuelles);
effacer_calque(scene4, calque_notes_jouee);
int n_max = liste_NOTES.length();
for(int n=0; n<n_max; n++)
{
if ( (liste_NOTES[n].statut & 0b00000001) == 0b00000001)
{
deplace_note(n, 0, 1);
}
}
affiche_liste_notes();
trace_liste_notes();
}
void MainWindow::on_Bt_deplace_B_clicked()
{
write_mode=3;
Bt_mode_E->setStyleSheet("background-color: rgb(200, 200, 200);");
Bt_mode_E_2->setStyleSheet("background-color: rgb(200, 200, 200);");
Bt_mode_W->setStyleSheet("background-color: rgb(200, 200, 200);");
Bt_mode_R->setStyleSheet("background-color: rgb(200, 200, 200);");
effacer_calque(scene4, calque_notes_manuelles);
effacer_calque(scene4, calque_notes_jouee);
int n_max = liste_NOTES.length();
for(int n=0; n<n_max; n++)
{
if ( (liste_NOTES[n].statut & 0b00000001) == 0b00000001) {deplace_note(n, 0, -1);}
}
affiche_liste_notes();
trace_liste_notes();
}
void MainWindow::on_Bt_scan_auto_clicked()
{
if (! wav_ok) {return;}
if ( ! liste_ENR_FFT.isEmpty()) {on_Bt_efface_clicked();}
on_Bt_toggle_visu_notes_clicked();
if (rapide)
{
Boite_Onglets_Global->setCurrentIndex(1);
on_Bt_RAZ_clicked();
MainWindow::setCursor(Qt::WaitCursor);
effacer_calque(scene4, calque_TAB_FRQ );
effacer_calque(scene4, calque_echelle_temporelle_T);
mode_grille_T();
analyse_tout();
MainWindow::setCursor(Qt::ArrowCursor);
}
else {Timer1->start(10);}
}
void MainWindow::on_Bt_jouer_tout_clicked()
{
if (liste_NOTES.length() == 0) {return;}
if (lecture_en_cours == true)
{
lecture_en_cours = false;
Timer2->stop();
Bt_jouer_tout->setText(">");
}
else
{
Bt_jouer_tout->setText("[]");
GV_grillesTM->horizontalScrollBar()->setValue(0);
memo_scroll_x = 0;
Timer2->stop();
num_note_depart = 0;
num_note_max = liste_NOTES.length();//-1;
if (num_note_max < 1) {return;}
num_note_jouee = 0;
num_barre_en_cours=0;
temps_0 = QDateTime::currentDateTime();
Timer2->start(100); //voir la fonction 'Tic2()' qui va jouer les notes
lecture_en_cours = true;
}
}
void MainWindow::on_Bt_toggle_visu_freq_clicked()
{
effacer_calque(scene4, calque_notes_manuelles);
if(visu_freq == 0)
{
visu_freq = 1;
Bt_toggle_visu_freq->setStyleSheet("background-color: rgb(0, 255, 0);"); // vert
calque_TAB_FRQ->setVisible(true);
}
else
{
visu_freq = 0;
Bt_toggle_visu_freq->setStyleSheet("background-color: rgb(200, 200, 200);");
calque_TAB_FRQ->setVisible(false);
on_Bt_toggle_grille_M_clicked();
}
}
void MainWindow::on_Bt_efface_2_clicked() // sur tab FREQ-NOTES
{
on_Bt_efface_clicked(); // (celui de l'autre tab FFT)
}
void MainWindow::on_doubleSpinBox_t0_valueChanged()
{
effacer_calque(scene4, calque_grille_M);
effacer_calque(scene4, calque_echelle_temporelle_T);
effacer_calque(scene4, calque_notes_manuelles);
affiche_liste_notes();
trace_liste_notes();
tracer_echelle_temps_TAB_NOTES();
tracer_grille_M();
}
void MainWindow::maj_TAB_NOTES()
{
effacer_calque(scene4, calque_grille_M);
effacer_calque(scene4, calque_notes_manuelles);
effacer_calque(scene4, calque_notes_auto);
effacer_calque(scene4, calque_echelle_temporelle_T);
effacer_calque(scene4, calque_TAB_FRQ);
retracer_TAB_FRQ();
trace_liste_notes();
tracer_echelle_temps_TAB_NOTES();
tracer_grille_M();
}
void MainWindow::on_spinBox_zoom_2_valueChanged(int arg1)
{
zoom_x = arg1;
MainWindow::setCursor(Qt::WaitCursor);
effacer_calque(scene4, calque_grille_T);
maj_TAB_NOTES();
MainWindow::setCursor(Qt::ArrowCursor);
}
void MainWindow::on_Bt_9_clicked()
{
QMessageBox msgBox;
QString s1;
s1 = "Le n° barre est compté depuis le début.";
s1 += "\n";
s1 += "La durée est exprimée en nombre de barres. Elle est calculée à postériori :"; s1 += "\n";
s1 += "La durée des notes n'est (volontairement) pas enregistrée dans les notes ";
s1 += "ce qui permet de ne PAS affecter l'emplacement de toutes les notes ";
s1 += "dans la trame temporelle lors de la modification, l'ajout ou la suppression d'une note"; s1 += "\n";
s1 += "Le tempo et le rythme sont ainsi conservés."; s1 += "\n";
s1 += "C'est d'ailleurs (me semble-t-il) l'approche retenue dans la norme midi."; s1 += "\n";
msgBox.setText(s1);
msgBox.exec();
}
void MainWindow::on_spinBox_offset_valueChanged()
{
//do_FFT_freq_midi();
}
void MainWindow::on_spinBox_d_barres_valueChanged()
{
double pas_grille = doubleSpinBox_dxb->value()/2.0 * zoom_x;
double offset_x = 10 * doubleSpinBox_x0b->value() + spinBox_d_barres->value() * pas_grille;
calque_TAB_FRQ->setPos(offset_x, 0);
}
void MainWindow::on_Bt_decale_notes_L_clicked()
{
decalle_notes(-1);
effacer_calque(scene4,calque_notes_manuelles);
affiche_liste_notes(); // en texte
trace_liste_notes(); // ellipses
}
void MainWindow::on_Bt_decale_notes_R_clicked()
{
decalle_notes(1);
effacer_calque(scene4,calque_notes_manuelles);
affiche_liste_notes(); // en texte
trace_liste_notes(); // ellipses
}
void MainWindow::on_tableWidget_type_M_cellClicked(int row, int column)
{
switch (row)
{
case 0: {lineEdit_10->setText("2/4"); Ta=2; Tb=4;} break; // Ta et Tb variables globales
case 1: {lineEdit_10->setText("3/4"); Ta=3; Tb=4;} break;
case 2: {lineEdit_10->setText("4/4"); Ta=4; Tb=4;} break;
default: break;
}
effacer_calque(scene4, calque_grille_M);
tracer_grille_M();
}
void MainWindow::on_checkBox_flitrer_clicked()
{
/*
if (checkBox_flitrer->isChecked())
{
textEdit_ETAT->setText("Mode Filtré : \n Ne sont représentés que les signaux dont l'amplitude est supérieure au seuil choisi");
}
else
{
textEdit_ETAT->setText("Mode non-filtré : \n Tous les signaux issus de la FFT sont représentés");
}
*/
MainWindow::setCursor(Qt::WaitCursor);
maj_TAB_NOTES();
MainWindow::setCursor(Qt::ArrowCursor);
}
/*
void MainWindow::on_spinBox_filtre_valueChanged()
{
if (checkBox_flitrer->isChecked())
{
MainWindow::setCursor(Qt::WaitCursor);
maj_TAB_NOTES();
MainWindow::setCursor(Qt::ArrowCursor);
}
}
*/
/*
void MainWindow::on_doubleSpinBox_gain_valueChanged()
{
MainWindow::setCursor(Qt::WaitCursor);
effacer_calque(scene4, calque_TAB_FRQ);
retracer_TAB_FRQ();
MainWindow::setCursor(Qt::ArrowCursor);
}
*/
void MainWindow::on_Bt_open_DIR_clicked()
{
QString s1, path1;
path1 = string_currentDir;
QProcess process1;
process1.setProgram("caja");
process1.setArguments({path1});
process1.startDetached();
}
void MainWindow::on_Bt_goto_clicked()
{
QString s1;
int n = lineEdit_7c->text().toInt();
if ((n<0) || (n>=liste_NOTES.length())) {return;}
spinBox_10->setValue(n);
NOTE note_i = liste_NOTES[n];
//double x_note = 80 + note_i.n_barreT * spinBox_dxa->value()/2.0 * zoom_x;
num_note_jouee = n;
surbrille_note(n, false, 1);
int midi = note_i.midi;
s1.setNum(midi);
lineEdit_7->setText(s1);
affi_txt_en_couleur(midi, lineEdit_7b); // nom de la note
//affi_txt_en_couleur(midi, lineEdit_7e);
// graphicsView4->horizontalScrollBar()->setValue(x_note - 200);
}
void MainWindow::on_doubleSpinBox_T0_valueChanged(double arg1)
{
tracer_echelle_temps_TAB_NOTES();
}
void MainWindow::on_Bt_test1_clicked()
{
QString s1;
double valeur;
for (int n = 0; n <= 255; n+=1)
{
valeur = (double )n / 255;
s1 = calcul_couleur(valeur);
rectangle1 = new QGraphicsRectItem(n, 200, 2, 5);
QPen pen1;
pen1.setColor(s1);
pen1.setWidth(2);
rectangle1->setPen(pen1);
calque_grille_M->addToGroup(rectangle1);
}
}
void MainWindow::on_Bt_durees_div2_clicked()
{
uint16_t n_max = liste_NOTES.length();
if (n_max == 0) {return;}
NOTE note_i;
for(int n=0; n<n_max; n++) //n_max
{
note_i=liste_NOTES[n];
int n_barre =note_i.n_barreT;
n_barre /=2;
note_i.n_barreT = n_barre;
liste_NOTES[n] = note_i;
}
effacer_calque(scene4,calque_notes_manuelles);
affiche_liste_notes(); // en texte
trace_liste_notes(); // ellipses
}
void MainWindow::on_Bt_durees_mult2_clicked()
{
uint16_t n_max = liste_NOTES.length();
if (n_max == 0) {return;}
NOTE note_i;
for(int n=0; n<n_max; n++) //n_max
{
note_i=liste_NOTES[n];
int n_barre =note_i.n_barreT;
n_barre *=2;
note_i.n_barreT = n_barre;
liste_NOTES[n] = note_i;
}
effacer_calque(scene4,calque_notes_manuelles);
affiche_liste_notes(); // en texte
trace_liste_notes(); // ellipses
}
void MainWindow::on_Bt_div2_clicked()
{
gain /=sqrt(2); // en fait / par racine carrée de deux pour plus de finesse
MainWindow::setCursor(Qt::WaitCursor);
effacer_calque(scene4, calque_TAB_FRQ);
retracer_TAB_FRQ();
MainWindow::setCursor(Qt::ArrowCursor);
}
void MainWindow::on_Bt_clicked()
{
gain *=sqrt(2);
MainWindow::setCursor(Qt::WaitCursor);
effacer_calque(scene4, calque_TAB_FRQ);
retracer_TAB_FRQ();
MainWindow::setCursor(Qt::ArrowCursor);
}
void MainWindow::on_Bt_next_clicked()
{
double scroll_x = GV_grillesTM->horizontalScrollBar()->value();
GV_grillesTM->horizontalScrollBar()->setValue(scroll_x + 800);
}
void MainWindow::on_Bt_prev_clicked()
{
double scroll_x = GV_grillesTM->horizontalScrollBar()->value();
GV_grillesTM->horizontalScrollBar()->setValue(scroll_x - 800);
}
void MainWindow::on_Bt_debut_clicked()
{
GV_grillesTM->horizontalScrollBar()->setValue(0);
}
void MainWindow::on_Bt_fin_clicked()
{
GV_grillesTM->horizontalScrollBar()->setValue(10000);
}
void MainWindow::on_bt_test_clicked()
{
}
void MainWindow::on_Bt_detection_notes_clicked()
{
effacer_calque(scene4,calque_notes_manuelles);
effacer_calque(scene4,calque_notes_auto);
detection_notes_auto();
on_Bt_toggle_visu_notes_clicked();
}
void MainWindow::on_Bt_toggle_visu_notes_auto_clicked()
{
if(visu_notes_auto == 0)
{
visu_notes_auto = 1;
Bt_toggle_visu_notes_auto->setStyleSheet("background-color: rgb(0, 255, 0);"); // vert
calque_notes_auto->setVisible(true);
//detection_notes_auto();
// tri_liste_notes_par_num_barre(); //les notes seront triées par temps croissant
//numerotation_liste_notes(); //les notes seront numérotées par temps croissant
// affiche_liste_notes();
// trace_liste_notes();
}
else
{
Bt_toggle_visu_notes_auto->setStyleSheet("background-color: rgb(200, 200, 200);");
visu_notes_auto = 0;
//effacer_calque(scene4,calque_notes_auto);
calque_notes_auto->setVisible(false);
}
}
void MainWindow::on_Bt_m10_clicked()
{
doubleSpinBox_vitesse->setValue(doubleSpinBox_vitesse->value()-10);
}
void MainWindow::on_Bt_p10_clicked()
{
doubleSpinBox_vitesse->setValue(doubleSpinBox_vitesse->value()+10);
}
void MainWindow::on_doubleSpinBox_gain_valueChanged(double arg1)
{
tracer_signal_complet();
}
void MainWindow::on_Bt_test2_clicked()
{
// load fichier wav qui contient les fréquences test
// Le fichier .wav comprend un signal audio stéréo échantilloné à 48 000 octets/seconde pour chaque canal
// ce qui fait 96000 octets/s pour l'ensemble du signal stéréo
effacer_calque(scene1,calque_trace_signal1 );
effacer_calque(scene1,calque_trace_FFT );
effacer_calque(scene1,calque_lignes_F_zero );
effacer_calque(scene1,calque_encadrement1 );
string_currentFile = QDir::homePath() + "/GUITARE/ACCORDS/tonalites_midi/48 kHz/28-82.wav";
save_fichier_ini();
lineEdit_1->setText(string_currentFile);
int p1= string_currentFile.lastIndexOf('/');
string_currentDir = string_currentFile.left(p1);
lineEdit_current_dir->setText(string_currentDir);
save_fichier_ini();
file_wav.setFileName(string_currentFile);
if (!file_wav.open(QIODevice::ReadOnly))
{
wav_ok = false;
Bt_scan_auto->setStyleSheet("background-color: rgb(200, 200, 200);");
return ;
}
else
{
binStream1.setDevice(&file_wav); // accès à la totalité du fichier wav
wav_ok = true;
Bt_scan_auto->setStyleSheet("background-color: rgb(0, 255, 0);"); // vert
}
// le fichier reste ouvert pour toute la session
decode_entete();
MainWindow::setCursor(Qt::WaitCursor);
liste_ENR_FFT.clear();
effacer_calque(scene1,calque_trace_signal1 );
effacer_calque(scene1, calque_trace_FFT);
clear_temp_data();
garnis_temp_data(0);
// ajustement_gain();
// donne accès à la totalité (2MB) du fichier wav (dans le 'temp_data')
tracer_signal_complet();
MainWindow::setCursor(Qt::ArrowCursor);
tracer_gradu_temporelle_signal_entree();
// frame_3->setVisible(true);
// Bt_scan_auto->setVisible(true);
// checkBox_rapide->setVisible(true);
if ( ! liste_ENR_FFT.isEmpty()) {on_Bt_efface_clicked();}
spinBox_6->setValue(0);
Timer3->start(100);
}
void MainWindow::on_Bt_open_DIR_2_clicked()
{
on_Bt_open_DIR_clicked();
}
void MainWindow::on_spinBox_nb_barres_valueChanged(int arg1)
{
effacer_calque(scene4, calque_grille_T);
tracer_grille_T();
}
void MainWindow::on_spinBox_barre_zero_valueChanged(int arg1)
{
effacer_calque(scene4, calque_grille_T);
tracer_grille_T();
}
void MainWindow::on_Bt_10_clicked()
{
QMessageBox msgBox;
QString s1;
s1 = "Les notes sont dans une premier temps attachées à la grille T (Temporelle, fixe, 1/40s)"; s1 += "\n";
s1 += "Ensuite la grille M (Mesures) permet"; s1 += "\n";
s1 += "de placer leur double au plus près du tempo théorique"; s1 += "\n";
s1 += "La grille M (Mesures) doit être configurée manuellement"; s1 += "\n";
s1 += "(par 'x0' et 'dt' en haut)"; s1 += "\n";
s1 += "Le bouton 'Place T->M' sert à créer ces doubles"; s1 += "\n";
s1 += "et les place automatiquement sur la barre de mesure la plus proche"; s1 += "\n";
s1 += ""; s1 += "\n";
msgBox.setText(s1);
msgBox.exec();
}
void MainWindow::on_Bt_11_clicked()
{
QMessageBox msgBox;
QString s1;
s1 += "Pour déplacer une note sur la grille:"; s1 += "\n";
s1 += "1) cliquez sur la note pour la sélectionner"; s1 += "\n";
s1 += "2) cliquez sur les boutons '<' et '>' et '^' et 'v' "; s1 += "\n";
s1 += "\n";
s1 += ""; s1 += "\n";
s1 += "Pour déplacer plusieurs notes sur la grille:"; s1 += "\n";
s1 += "Cochez Sélect/boite" ; s1 += "\n";
s1 += "sélectonnez les notes par un rectangle (en déplaçant la souris avec bouton gauche restant appuyé)"; s1 += "\n";
s1 += "Puis cliquez sur les boutons '<' et '>' et '^' et 'v' "; s1 += "\n";
s1 += "Idem pour supprimer plusieurs notes, sélectionner puis clic sur le bouton 'xx' "; s1 += "\n";
s1 += "\n";
s1 += "Les petits tirets colorés horizontaux indiquent les Harmoniques freq x2(prem. H) et freq x3 (second H)";
msgBox.setText(s1);
msgBox.exec();
}
void MainWindow::on_Bt_RAZ_general_clicked()
{
liste_NOTES.clear();
liste_ENR_FFT.clear();
parametrages();
GV_grillesTM->horizontalScrollBar()->setValue(0);
}
void MainWindow::on_spinBox_x0a_valueChanged(int arg1)
{
effacer_calque(scene4, calque_echelle_temporelle_T);
effacer_calque(scene4, calque_echelle_temporelle_M);
effacer_calque(scene4, calque_grille_M);
on_Bt_copy_nt_T_to_M_clicked();
trace_liste_notes();
tracer_grille_M();
tracer_echelle_temps_TAB_NOTES();
}
void MainWindow::on_doubleSpinBox_x0b_valueChanged(double arg1)
{
effacer_calque(scene4, calque_echelle_temporelle_T);
effacer_calque(scene4, calque_echelle_temporelle_M);
effacer_calque(scene4, calque_grille_M);
on_Bt_copy_nt_T_to_M_clicked();
trace_liste_notes();
tracer_grille_M();
tracer_echelle_temps_TAB_NOTES();
}
void MainWindow::on_Bt_copy_nt_T_to_M_clicked()
{
if(checkBox_GI->isChecked()) {return;}
uint16_t n_max = liste_NOTES.length();
uint16_t nb_M;
for(int n=0; n<n_max; n++)
{
nb_M = calcul_n_barreM_note(n);
liste_NOTES[n].n_barreM = nb_M;
}
mode='M';
affiche_liste_notes();
trace_liste_notes();
}
void efface_notes_T()
{
int16_t n_max = liste_NOTES.length();
for(int n=0; n<n_max; n++)
{
liste_NOTES[n].n_barreT = 0;
}
}
void MainWindow::on_Bt_copy_nt_M_to_T_clicked()
{
if(checkBox_GI->isChecked()) {return;}
int n_max = liste_NOTES.length();
int nb_T;
efface_notes_T();
for(int n=0; n<n_max; n++)
{
nb_T = calcul_n_barreT_note(n);
//nb_T = liste_NOTES[n].n_barreM * 14 ; //8.5; // méthode directe. à voir...
if (nb_T < 5000) {liste_NOTES[n].n_barreT = nb_T;}
}
mode='T';
mode_grille_T();
affiche_liste_notes();
trace_liste_notes();
}
void MainWindow::on_radioButton_D_clicked()
{
affiche_histogramme();
}
void MainWindow::on_radioButton_M_clicked()
{
affiche_histogramme();
}
void MainWindow::on_radioButton_H_clicked()
{
affiche_histogramme();
}
void MainWindow::on_Bt_dedoubleM_clicked()
{
int n_max = liste_NOTES.length();
for(int n=0; n<n_max; n++)
{
liste_NOTES[n].n_barreM = liste_NOTES[n].n_barreM *2;
}
tracer_grille_M();
trace_liste_notes();
}
void MainWindow::on_Bt_bak1_clicked()
{
QString filename1 = string_currentDir+ "/BAK.NTS";
QFile file1(filename1);
if (file1.exists())
{
liste_NOTES.clear();
effacer_calque(scene4,calque_notes_manuelles);
effacer_calque(scene4,calque_notes_auto);
effacer_calque(scene4,calque_notes_jouee);
effacer_calque(scene5, calque_histogramme );
effacer_calque(scene4, calque_echelle_temporelle_T);
effacer_calque(scene4, calque_echelle_temporelle_M);
load_fichier_NOTES("BAK");
on_Bt_toggle_grille_M_clicked();
}
else
{
QMessageBox msgBox;
QString s1="pas de Fichier BAK.NTS !";
msgBox.setText(s1); msgBox.exec();
}
}
void MainWindow::on_checkBox_numerotation_toggled(bool checked)
{
tracer_grille_M();
}
void MainWindow::on_Bt_copie_notes_clicked()
{
write_mode = 5;
MainWindow::setCursor(Qt::CrossCursor);
// voir le write_mode 5 dans la fonction 'mousePressEvent' pour la suite évènementielle..
}
void MainWindow::on_Bt_12_clicked()
{
QMessageBox msgBox;
QString s1;
s1 = "COPIE D'UN ACCORD (=notes alignées verticalement sur la même barre)"; s1 += "\n";
s1 += "1) cliquez sur le bouton jaune pour lancer le mode copie d'accord"; s1 += "\n";
s1 += "2) cliquez sur la barre temporelle contenant les notes de l'accord à copier"; s1 += "\n";
s1 += "3) puis cliquez sur une autre barre (destination)"; s1 += "\n";
msgBox.setText(s1);
msgBox.exec();
}
void MainWindow::on_checkBox_GI_clicked(bool checked)
{
if (checked == true)
{
Bt_copy_nt_M_to_T->setStyleSheet("background-color: rgb(100, 100, 100);");
Bt_copy_nt_T_to_M->setStyleSheet("background-color: rgb(100, 100, 100);");
}
else
{
Bt_copy_nt_M_to_T->setStyleSheet("background-color: rgb(0, 255, 0);");
Bt_copy_nt_T_to_M->setStyleSheet("background-color: rgb(0, 255, 0);");
}
}
void MainWindow::on_Bt_13_clicked()
{
QMessageBox msgBox;
QString s1;
s1 = "Rendre les grilles M et T indépendantes permet de travailler uniquement sur la grille M"; s1 += "\n";
s1 += "par exemple pour composer un morceau ou des accords manuellement"; s1 += "\n";
s1 += "en évitant des surprises lors du changement d'échelle temporelle"; s1 += "\n";
s1 += "(Les notes resteront attachées à la même barre temporelle)"; s1 += "\n";
msgBox.setText(s1);
msgBox.exec();
}
void MainWindow::on_Bt_14_clicked()
{
QMessageBox msgBox;
QString s1;
s1 = "La roulette de la souris permet de modifier la valeur rapidement"; s1 += "\n";
s1 += "CTRL + roulette permet encore + de rapidité"; s1 += "\n";
s1 += ""; s1 += "\n";
s1 += ""; s1 += "\n";
msgBox.setText(s1);
msgBox.exec();
}
void MainWindow::on_Bt_15_clicked()
{
QMessageBox msgBox;
QString s1;
s1 ="Les instruments de musique ne sont pas toujours 'bien' accordés (La=440Hz) involontairement ou volontairement..."; s1 += "\n";
s1 += "Si cette appli détecte mal les frq (hésitation +/-1/2 ton) cette valeur permet d'ajuster la détection."; s1 += "\n";
s1 += "Vous trouverez aussi des notes 'pures' dans le dossier 'tonalites_midi' dans le fichier documents.zip";
msgBox.setText(s1);
msgBox.exec();
}
void MainWindow::on_spinBox_offset_valueChanged(int arg1)
{
calcul_ofsset();
traitement_signal();
}
void MainWindow::on_spinBox_echx_valueChanged(int arg1)
{
calcul_ofsset();
traitement_signal();
}
void MainWindow::on_Bt_par_defaut_clicked()
{
doubleSpinBox_gain->setValue(0.20);
spinBox_offset->setValue(-2124); // -1250 ; +/- 22 pour un décalage de +/-1/4 de ton
doubleSpinBox_echx->setValue(499); // 388
}
void MainWindow::on_Bt_composition_clicked()
{
spinBox_duree->setValue(1);
on_spinBox_duree_valueChanged(2);// noire
visu_freq = true;
on_Bt_toggle_visu_freq_clicked(); // ce qui le repasse à false, avec actions correspondantes
mode_composition = true;
on_Bt_toggle_grille_M_clicked();
frame_cle_de_sol->setVisible(true);
affi_clef();
frame_composeur->setVisible(true);
on_spinBox_hauteur_valueChanged(0);
spinBox_duree->setValue(1);
//on_spinBox_duree_valueChanged(1);
}
void MainWindow::on_Bt_5_clicked()
{
mode_composition = false;
frame_cle_de_sol->setVisible(false);
frame_composeur->setVisible(false);
}
void MainWindow::on_spinBox_hauteur_valueChanged(int arg1)
{
if (arg1==12) { spinBox_hauteur->setValue(0); spinBox_octave->stepUp(); return;}
if (arg1==-1) { spinBox_hauteur->setValue(11); spinBox_octave->stepDown(); return;}
QString s1;
s1 = gamme_chromatique[spinBox_hauteur->value()];
lineEdit_nom->setText(s1);
int midi = 36 + arg1 + 12*spinBox_octave->value();
affi_txt_en_couleur(midi, lineEdit_nom);
s1.setNum(midi);
lineEdit_midi->setText(s1);
effacer_calque(scene4, calque_surbrillance);
surbrille_barre(num_barre_saisie, "#00FF00");
encadre_midi(midi);
}
void MainWindow::on_spinBox_octave_valueChanged(int arg1)
{
QString s1;
s1 = gamme_chromatique[spinBox_hauteur->value()];
lineEdit_nom->setText(s1);
int midi = 36 + spinBox_hauteur->value() + 12*arg1;
s1.setNum(midi);
lineEdit_midi->setText(s1);
effacer_calque(scene4, calque_surbrillance);
surbrille_barre(num_barre_saisie, "#00FF00");
encadre_midi(midi);
}
void MainWindow::on_spinBox_duree_valueChanged(int arg1)
{
QString s1, s2;
duree_int = pow(2, 4-arg1); // variable globale
s1.setNum(duree_int);
lineEdit_duree_int->setText(s1);
if (! checkBox_silence->isChecked()) {s2 = types_note[arg1];}
else
{
s2 = types_silence[arg1];
affi_silence();
}
lineEdit_duree_txt->setText(s2);
surbrille_barre(num_barre_saisie, "#00FF00");
}
void MainWindow::on_Bt_16_clicked()
{
QMessageBox msgBox;
QString s1;
s1 = "Le trait vertical (vert) indique la barre ou se placera la note suivante ";
s1 += "(en fonction de la durée choisie pour la note précédente)"; s1 += "\n";
s1 += "La durée des notes n'est (volontairement) pas enregistrée dans les notes ";
s1 += "ce qui permet de ne PAS affecter l'emplacement de toutes les notes ";
s1 += "dans la trame temporelle lors de la modification, l'ajout ou la suppression d'une note"; s1 += "\n";
s1 += "Le tempo et le rythme sont ainsi conservés."; s1 += "\n";
s1 += "C'est d'ailleurs (me semble-t-il) l'approche retenue dans la norme midi."; s1 += "\n";
s1 += "On peut à tout moment ajouter 'manuellement' une note avec le bouton 'W' du panneau Gestion notes"; s1 += "\n";
s1 += "Ce qui fait basculer dans le mode Write, puis clic sur la grille"; s1 += "\n";
msgBox.setText(s1);
msgBox.exec();
}
void MainWindow::Ajouter_note(int midi)
{
if (checkBox_pause->isChecked()) {midi =0;}
ajout_note(midi, 0, num_barre_saisie);
play_note(midi);
//int d1 = 4 - spinBox_duree->value();
//int d2 = pow(2, d1);
num_barre_saisie += duree_int;
effacer_calque(scene4,calque_notes_manuelles);
//effacer_calque(scene4,calque_notes_jouee);
tri_liste_notes_par_num_barre(); // les notes seront triées par num_barre croissant
numerotation_liste_notes(); // les notes seront numérotées par num_barre croissant
affiche_liste_notes();
trace_liste_notes();
surbrille_barre(num_barre_saisie, "#00FF00");
spinBox_num_barre->setValue(num_barre_saisie);
}
void MainWindow::on_Bt_ajout_clicked()
{
if(!checkBox_silence->isChecked())
{
int midi = 36 + spinBox_hauteur->value() + 12*spinBox_octave->value();
Ajouter_note(midi);
}
else
{
//n'ajoute pas de note, décalle juste la barre de saisie de la note suivante vers la droite
num_barre_saisie += duree_int;
surbrille_barre(num_barre_saisie, "#00FF00");
}
}
void MainWindow::on_Bt_aj_MAJ_clicked()
{
int tonique = 36 + spinBox_hauteur->value() + 12*spinBox_octave->value();
int A = tonique;
int B = tonique +4;
int C = tonique +7;
Ajouter_note(A);
num_barre_saisie -= duree_int; Ajouter_note(B);
num_barre_saisie -= duree_int; Ajouter_note(C);
}
void MainWindow::on_Bt_aj_Min_clicked()
{
int tonique = 36 + spinBox_hauteur->value() + 12*spinBox_octave->value();
int A = tonique;
int B = tonique +3;
int C = tonique +7;
Ajouter_note(A);
num_barre_saisie -= duree_int; Ajouter_note(B);
num_barre_saisie -= duree_int; Ajouter_note(C);
}
void MainWindow::on_Bt_aj_7dom_clicked()
{
int tonique = 36 + spinBox_hauteur->value() + 12*spinBox_octave->value();
int A = tonique;
int B = tonique +4;
int C = tonique +7;
int D = tonique +10;
Ajouter_note(A);
num_barre_saisie -= duree_int; Ajouter_note(B);
num_barre_saisie -= duree_int; Ajouter_note(C);
num_barre_saisie -= duree_int; Ajouter_note(D);
}
void MainWindow::on_Bt_transposer_clicked()
{
int n_max = liste_NOTES.length();
for(int n=0; n<n_max; n++)
{
liste_NOTES[n].midi += spinBox_transposition->value();
}
affiche_liste_notes();
trace_liste_notes();
}
/*
void MainWindow::on_Bt_deselect_clicked()
{
deselect_notes();
effacer_calque(scene4, calque_surbrillance);
effacer_calque(scene4, calque_notes_jouee);
effacer_calque(scene4, calque_rect_select);
}
*/
void MainWindow::on_checkBox_sel_boite_clicked()
{
if(checkBox_sel_boite->isChecked())
{
Bt_mode_E->setVisible(false);
frame_move->setVisible(true);
label_SEL_P_BOITE->setVisible(true);
Bt_mode_E_2->setStyleSheet("background-color: rgb(255, 0, 0);"); // rouge
}
else
{
Bt_mode_E->setVisible(true);
frame_move->setVisible(false);
label_SEL_P_BOITE->setVisible(false);
Bt_mode_E_2->setStyleSheet("background-color: rgb(200, 200, 200);"); // gris
effacer_calque(scene4, calque_rect_select);
deselect_notes();
effacer_calque(scene4, calque_notes_jouee);
}
}
void MainWindow::affi_clef()
{
QString image_filename;
QImage image1;
image_filename = "./cles3r.jpg";
image1.load(image_filename);
label_image1->setGeometry(0, 0, 131, 101);
label_image1->setPixmap(QPixmap::fromImage(image1));
label_image1->adjustSize();
}
void MainWindow::affi_silence()
{
QString image_filename;
QString s1;
int n =spinBox_duree->value();
s1.setNum(n);
QImage image1;
image_filename = "./silence" + s1 + ".jpg";
image1.load(image_filename);
label_image1->setGeometry(20, 100, 131, 101);
label_image1->setPixmap(QPixmap::fromImage(image1));
label_image1->adjustSize();
}
void MainWindow::on_checkBox_silence_clicked()
{
if(checkBox_silence->isChecked()) { affi_silence(); } else { affi_clef(); }
on_spinBox_duree_valueChanged(spinBox_duree->value());
}
void MainWindow::on_spinBox_num_barre_valueChanged(int arg1)
{
num_barre_saisie = arg1;
surbrille_barre(num_barre_saisie, "#00FF00");
}
void MainWindow::on_spinBox_num_note_valueChanged(int arg1)
{
num_note_jouee = arg1;
spinBox_10->setValue(num_note_jouee); // 'debut'
joue_1_note_de_la_liste();
}
// =====================================================================================================
// code ONGLET INSTRUMENTS
// =====================================================================================================
// chemin relatif / dossier de l'exécutable
//uint16_t largeur_image = 1216; // image du manche de la guitare
//uint16_t hauteur_image = 180;
//QList<QString> liste_couleurs;
void MainWindow::init_onglet_instruments()
{
liste_couleurs <<"#EF2929"<<"#FF5C00"<<"#FCAF3E"<<"#FFE300"<<"#BFFF00"<<"#07F64F"
<<"#16D298"<<"#16D2C4"<<"#00AEFF"<<"#1667D2"<<"#7C00FF"<<"#FF67EF"<<"#EEEEEC";
gamme_chromatique<<"Do"<<"Do#"<<"Ré"<<"Mib"<<"Mi"<<"Fa"<<"Fa#"<<"Sol"<<"Sol#"<<"La"<<"Sib"<<"Si";
}
void MainWindow::charger_image_manche()
{
QString fileName1;
// repertoire_images = "./images/";
fileName1 = repertoire_images + "manche3.jpg";
QFile file1(fileName1);
if (file1.exists() )
{
QImage image1(fileName1);
image1 = image1.scaledToWidth(largeur_image);
image1.load(fileName1);
//imageLabel1->setPixmap(QPixmap::fromImage(image1));
QGraphicsPixmapItem* item1 = new QGraphicsPixmapItem(QPixmap::fromImage(image1));
scene_manche->addItem(item1);
// calque_notes_manche->addToGroup(item1);
}
}
int MainWindow::calcul_midi(int corde_i, int case_i)
{
// 40 -> Mi octave 2 (corde 6 à vide)
int n;
n = 40 + case_i; // corde6 de Mi grave
if (corde_i == 5){n+=5;}
if (corde_i == 4){n+=10;}
if (corde_i == 3){n+=15;}
if (corde_i == 2){n+=19;}
if (corde_i == 1){n+=24;} // corde1 de Mi aigu (+2 octaves)
//*n_midi = n;
return n;
}
QString MainWindow::nom_note_FR(int mid)
{
QString s1;
int h1 = calcul_hauteur_note(mid);
//h1-=3;
if(h1<0){h1+=12;}
if(h1>11){h1-=12;}
if((h1<0) || ( h1>= gamme_chromatique.length())) {return "-";}
s1 = gamme_chromatique[h1];
return s1;
}
void MainWindow::affiche_details_note(uint midi)
{
QString s1;
s1.setNum(midi);
s1 = "m" + s1;
LDI_7a->setText(s1);
affi_txt_en_couleur(midi, LDI_7b);
LDI_7b->setText(nom_note_FR(midi));
affi_txt_en_couleur(midi, LDI_7e);
s1=nom_note_GB(midi);
s1+=nom_octave_GB(midi);
LDI_7e->setText(s1);
}
void MainWindow::calcul_xy_note(int corde_i, int case_i, int *x_i, int *y_i)
{
float x;
float y;
float dy;
float y0;
float ech;
if (case_i >= positionsX.length())
{
*x_i=1;
*y_i=1;
return;
}
x=positionsX[case_i];
y0=100; // 72
ech=1+case_i/90.0;
dy=-20.0*((7-corde_i)-3.2);
dy *= ech;
y=y0+dy;
*x_i=int(x);
*y_i=int(y);
}
void MainWindow::dessine_1_note(int corde_i, int case_i, QColor couleur_i)
{
int x, y;
// case_i = 0..20 (0 -> corde à vide)
if ( (case_i < case_min) || (case_i > case_max) ) {return;}
uint midi = calcul_midi(corde_i, case_i);
affiche_details_note(midi);
QPen pen_note(couleur_i, 1, Qt::SolidLine);
if ((case_i>=0) && (case_i<=20))
{
calcul_xy_note(corde_i, case_i, &x, &y);
ellipse1 = new QGraphicsEllipseItem(x, y, 15, 15);
ellipse1->setPen(pen_note);
if (notes_pleines == true) {ellipse1->setBrush(couleur_i);}
calque_notes_manche->addToGroup(ellipse1);
memo_case_i=case_i;
memo_corde_i=corde_i;
}
}
void MainWindow::set_couleur_label(QColor c1, QLabel *Lb_i)
{
QVariant variant1 = c1;
QString couleurCode = variant1.toString();
Lb_i->setStyleSheet("QLabel { background-color :"+couleurCode+" ; color : white; }");
}
void MainWindow::on_Bt_E3_clicked()
{
int n_midi=40;
play_note(n_midi); // numérotation MIDI
QColor c=liste_couleurs[4];
dessine_1_note(6, 0, c); // sur le manche
set_couleur_label(c, label5); // près de la touche piano
}
void MainWindow::on_Bt_F3_clicked()
{
int n_midi=41;
play_note(n_midi);
QColor c=liste_couleurs[5];
dessine_1_note(6, 1, c); // sur le manche
set_couleur_label(c, label6); // près de la touche piano
}
void MainWindow::on_Bt_Fd3_clicked()
{
int n_midi=42;
play_note(n_midi);
QColor c=liste_couleurs[6];
dessine_1_note(6, 2, c); // sur le manche
set_couleur_label(c, label7); // près de la touche piano
}
void MainWindow::on_Bt_G3_clicked()
{
int n_midi=43;
play_note(n_midi);
QColor c=liste_couleurs[7];
dessine_1_note(6, 3, c); // sur le manche
set_couleur_label(c, label8); // près de la touche piano
}
void MainWindow::on_Bt_Gd3_clicked()
{
int n_midi=44;
play_note(n_midi);
QColor c=liste_couleurs[8];
dessine_1_note(6, 4, c); // sur le manche
set_couleur_label(c, label9); // près de la touche piano
}
void MainWindow::on_Bt_A3_clicked()
{
int n_midi=45;
play_note(n_midi);
QColor c=liste_couleurs[9];
dessine_1_note(6, 5, c); dessine_1_note(5, 0, c); // sur le manche
set_couleur_label(c, label10); // près de la touche piano
}
void MainWindow::on_Bt_Bb3_clicked()
{
int n_midi=46;
play_note(n_midi);
QColor c=liste_couleurs[10];
dessine_1_note(6, 6, c); dessine_1_note(5, 1, c);
set_couleur_label(c, label11); // près de la touche piano
}
void MainWindow::on_BT_B3_clicked()
{
int n_midi=47;
play_note(n_midi);
QColor c=liste_couleurs[11];
dessine_1_note(6, 7, c); dessine_1_note(5, 2, c);
set_couleur_label(c, label12); // près de la touche piano
}
void MainWindow::on_Bt_C4_clicked()
{
int n_midi=48;
play_note(n_midi);
QColor c=liste_couleurs[0];
dessine_1_note(6, 8, c); dessine_1_note(5, 3, c);
set_couleur_label(c, label1_2);
}
void MainWindow::on_Bt_Cd4_clicked()
{
int n_midi=49;
play_note(n_midi);
QColor c=liste_couleurs[1];
dessine_1_note(6, 9, c); dessine_1_note(5, 4, c);
set_couleur_label(c, label2_2);
}
void MainWindow::on_Bt_D4_clicked()
{
int n_midi=50;
play_note(n_midi);
QColor c=liste_couleurs[2];
dessine_1_note(6, 10, c); dessine_1_note(5, 5, c); dessine_1_note(4, 0, c);
set_couleur_label(c, label3_2);
}
void MainWindow::on_Bt_Eb4_clicked()
{
int n_midi=51;
play_note(n_midi);
QColor c=liste_couleurs[3];
dessine_1_note(6, 11, c); dessine_1_note(5, 6, c); dessine_1_note(4, 1, c);
set_couleur_label(c, label4_2);
}
void MainWindow::on_Bt_E4_clicked()
{
int n_midi=52;
play_note(n_midi);
QColor c=liste_couleurs[4];
dessine_1_note(6, 12, c); dessine_1_note(5, 7, c); dessine_1_note(4, 2, c);
set_couleur_label(c, label5_2);
}
void MainWindow::on_Bt_F4_clicked()
{
int n_midi=53;
play_note(n_midi);
QColor c=liste_couleurs[5];
dessine_1_note(6, 13, c); dessine_1_note(5, 8, c); dessine_1_note(4, 3, c);
set_couleur_label(c, label6_2);
}
void MainWindow::on_Bt_Fd4_clicked()
{
int n_midi=54;
play_note(n_midi);
QColor c=liste_couleurs[6];
dessine_1_note(6, 14, c); dessine_1_note(5, 9, c); dessine_1_note(4, 4, c);
set_couleur_label(c, label7_2);
}
void MainWindow::on_Bt_G4_clicked()
{
int n_midi=55;
play_note(n_midi);
QColor c=liste_couleurs[7];
dessine_1_note(6, 15, c); dessine_1_note(5, 10, c); dessine_1_note(4, 5, c); dessine_1_note(3, 0, c);
set_couleur_label(c, label8_2);
}
void MainWindow::on_Bt_Gd4_clicked()
{
int n_midi=56;
play_note(n_midi);
QColor c=liste_couleurs[8];
dessine_1_note(6, 16, c); dessine_1_note(5, 11, c); dessine_1_note(4, 6, c); dessine_1_note(3, 1, c);
set_couleur_label(c, label9_2);
}
void MainWindow::on_Bt_A4_clicked()
{
int n_midi=57;
play_note(n_midi);
QColor c=liste_couleurs[9];
dessine_1_note(6, 17, c); dessine_1_note(5, 12, c); dessine_1_note(4, 7, c); dessine_1_note(3, 2, c);
set_couleur_label(c, label10_2);
}
void MainWindow::on_Bt_Bb4_clicked()
{ int n_midi=58;
play_note(n_midi);
QColor c=liste_couleurs[10];
dessine_1_note(6, 18, c); dessine_1_note(5, 13, c); dessine_1_note(4, 8, c); dessine_1_note(3, 3, c);
set_couleur_label(c, label11_2);
}
void MainWindow::on_Bt_B4_clicked()
{
int n_midi=59;
play_note(n_midi);
QColor c=liste_couleurs[11];
dessine_1_note(2, 0, c); dessine_1_note(3, 4, c); dessine_1_note(4, 9, c); dessine_1_note(5, 14, c);
set_couleur_label(c, label12_2);
}
void MainWindow::on_Bt_C5_clicked()
{
int n_midi=60;
play_note(n_midi);
QColor c=liste_couleurs[0];
dessine_1_note(2, 1, c); dessine_1_note(3, 5, c); dessine_1_note(4, 10, c); dessine_1_note(5, 15, c);
set_couleur_label(c, label1_3);
}
void MainWindow::on_Bt_Cd5_clicked()
{
int n_midi=61;
play_note(n_midi);
QColor c=liste_couleurs[1];
dessine_1_note(2, 2, c); dessine_1_note(3, 6, c); dessine_1_note(4, 11, c); dessine_1_note(5, 16, c);
set_couleur_label(c, label2_3);
}
void MainWindow::on_Bt_D5_clicked()
{
int n_midi=62;
play_note(n_midi);
QColor c=liste_couleurs[2];
dessine_1_note(2, 3, c); dessine_1_note(3, 7, c); dessine_1_note(4, 12, c); dessine_1_note(5, 17, c);
set_couleur_label(c, label3_3);
}
void MainWindow::on_Bt_Eb5_clicked()
{
int n_midi=63;
play_note(n_midi);
QColor c=liste_couleurs[3];
dessine_1_note(2, 4, c); dessine_1_note(3, 8, c); dessine_1_note(4, 13, c); dessine_1_note(5, 18, c);
set_couleur_label(c, label4_3);
}
void MainWindow::on_Bt_E5_clicked()
{
int n_midi=64;
play_note(n_midi);
QColor c=liste_couleurs[4];
dessine_1_note(1, 0, c); dessine_1_note(2, 5, c); dessine_1_note(3, 9, c); dessine_1_note(4, 14, c);
set_couleur_label(c, label5_3);
}
void MainWindow::on_Bt_F5_clicked()
{
int n_midi=65;
play_note(n_midi);
QColor c=liste_couleurs[5];
dessine_1_note(1, 1, c); dessine_1_note(2, 6, c); dessine_1_note(3, 10, c); dessine_1_note(4, 15, c);
set_couleur_label(c, label6_3);
}
void MainWindow::on_Bt_Fd5_clicked()
{
int n_midi=66;
play_note(n_midi);
QColor c=liste_couleurs[6];
dessine_1_note(1, 2, c); dessine_1_note(2, 7, c); dessine_1_note(3, 11, c); dessine_1_note(4, 16, c);
set_couleur_label(c, label7_3);
}
void MainWindow::on_Bt_G5_clicked()
{
int n_midi=67;
play_note(n_midi);
QColor c=liste_couleurs[7];
dessine_1_note(1, 3, c); dessine_1_note(2, 8, c); dessine_1_note(3, 12, c); dessine_1_note(4, 17, c);
set_couleur_label(c, label8_3);
}
void MainWindow::on_Bt_Gd5_clicked()
{
int n_midi=68;
play_note(n_midi);
QColor c=liste_couleurs[8];
dessine_1_note(1, 4, c); dessine_1_note(2, 9, c); dessine_1_note(3, 13, c); dessine_1_note(4, 18, c);
set_couleur_label(c, label9_3);
}
void MainWindow::on_Bt_A5_clicked()
{
int n_midi=69;
play_note(n_midi);
QColor c=liste_couleurs[9];
dessine_1_note(1, 5, c); dessine_1_note(2, 10, c); dessine_1_note(3, 14, c);
set_couleur_label(c, label10_3);
}
void MainWindow::on_Bt_Bb5_clicked()
{
int n_midi=70;
play_note(n_midi);
QColor c=liste_couleurs[10];
dessine_1_note(1, 6, c); dessine_1_note(2, 11, c); dessine_1_note(3, 15, c);
set_couleur_label(c, label11_3);
}
void MainWindow::on_Bt_B5_clicked()
{
int n_midi=71;
play_note(n_midi);
QColor c=liste_couleurs[11];
dessine_1_note(1, 7, c); dessine_1_note(2, 12, c); dessine_1_note(3, 16, c);
set_couleur_label(c, label12_3);
}
void MainWindow::on_Bt_C6_clicked()
{
int n_midi=72;
play_note(n_midi);
QColor c=liste_couleurs[0];
dessine_1_note(1, 8, c); dessine_1_note(2, 13, c); dessine_1_note(3, 17, c);
set_couleur_label(c, label1_4);
}
void MainWindow::on_Bt_Cd6_clicked()
{
int n_midi=73;
play_note(n_midi);
QColor c=liste_couleurs[1];
dessine_1_note(1, 9, c); dessine_1_note(2, 14, c); dessine_1_note(3, 18, c);
set_couleur_label(c, label2_4);
}
void MainWindow::on_Bt_D6_clicked()
{
int n_midi=74;
play_note(n_midi);
QColor c=liste_couleurs[2];
dessine_1_note(1, 10, c); dessine_1_note(2, 15, c);
set_couleur_label(c, label3_4);
}
void MainWindow::on_Bt_Eb6_clicked()
{
int n_midi=75;
play_note(n_midi);
QColor c=liste_couleurs[3];
dessine_1_note(1, 11, c); dessine_1_note(2, 16, c);
set_couleur_label(c, label4_4);
}
void MainWindow::on_Bt_E6_clicked()
{
int n_midi=76;
play_note(n_midi);
QColor c=liste_couleurs[4];
dessine_1_note(1, 12, c); dessine_1_note(2, 17, c);
set_couleur_label(c, label5_4);
}
void MainWindow::on_Bt_F6_clicked()
{
int n_midi=77;
play_note(n_midi);
QColor c=liste_couleurs[5];
dessine_1_note(1, 13, c); dessine_1_note(2, 18, c);
set_couleur_label(c, label6_4);
}
void MainWindow::on_Bt_Fd6_clicked()
{
int n_midi=78;
play_note(n_midi);
QColor c=liste_couleurs[6];
dessine_1_note(1, 14, c); dessine_1_note(2, 19, c);
set_couleur_label(c, label7_4);
}
void MainWindow::on_Bt_G6_clicked()
{
int n_midi=79;
play_note(n_midi);
QColor c=liste_couleurs[7];
dessine_1_note(1, 15, c); dessine_1_note(2, 20, c);
set_couleur_label(c, label8_4);
}
void MainWindow::on_Bt_Gd6_clicked()
{
int n_midi=80;
play_note(n_midi);
QColor c=liste_couleurs[8];
dessine_1_note(1, 16, c);
set_couleur_label(c, label9_4);
}
void MainWindow::on_Bt_A6_clicked()
{
int n_midi=81;
play_note(n_midi);
QColor c=liste_couleurs[9];
dessine_1_note(1, 17, c);
set_couleur_label(c, label10_4);
}
void MainWindow::on_Bt_Bb6_clicked()
{
int n_midi=82;
play_note(n_midi);
QColor c=liste_couleurs[10];
dessine_1_note(1, 18, c);
set_couleur_label(c, label11_4);
}
void MainWindow::on_Bt_B6_clicked()
{
int n_midi=83;
play_note(n_midi);
QColor c=liste_couleurs[11];
dessine_1_note(1, 19, c);
set_couleur_label(c, label12_4);
}
void MainWindow::on_Bt_C7_clicked()
{
int n_midi=84;
play_note(n_midi);
QColor c=liste_couleurs[0];
dessine_1_note(1, 20, c);
//set_couleur_label(c, label13_4);
}
void MainWindow::effacer_touches()
{
QColor c = "#505050";
set_couleur_label(c, label5);
set_couleur_label(c, label6);
set_couleur_label(c, label7);
set_couleur_label(c, label8);
set_couleur_label(c, label9);
set_couleur_label(c, label10);
set_couleur_label(c, label11);
set_couleur_label(c, label12);
set_couleur_label(c, label1_2);
set_couleur_label(c, label2_2);
set_couleur_label(c, label3_2);
set_couleur_label(c, label4_2);
set_couleur_label(c, label5_2);
set_couleur_label(c, label6_2);
set_couleur_label(c, label7_2);
set_couleur_label(c, label8_2);
set_couleur_label(c, label9_2);
set_couleur_label(c, label10_2);
set_couleur_label(c, label11_2);
set_couleur_label(c, label12_2);
set_couleur_label(c, label1_3);
set_couleur_label(c, label2_3);
set_couleur_label(c, label3_3);
set_couleur_label(c, label4_3);
set_couleur_label(c, label5_3);
set_couleur_label(c, label6_3);
set_couleur_label(c, label7_3);
set_couleur_label(c, label8_3);
set_couleur_label(c, label9_3);
set_couleur_label(c, label10_3);
set_couleur_label(c, label11_3);
set_couleur_label(c, label12_3);
set_couleur_label(c, label1_4);
set_couleur_label(c, label2_4);
set_couleur_label(c, label3_4);
set_couleur_label(c, label4_4);
set_couleur_label(c, label5_4);
set_couleur_label(c, label6_4);
set_couleur_label(c, label7_4);
set_couleur_label(c, label8_4);
set_couleur_label(c, label9_4);
set_couleur_label(c, label10_4);
set_couleur_label(c, label11_4);
set_couleur_label(c, label12_4);
}
void MainWindow::on_Bt_RAZ_2_clicked()
{
// sur le manche
effacer_calque(scene_manche, calque_notes_manche);
// effacer_calque(scene1, calque_encadrement);
// Frame_wWidget1->setVisible(false);
// la suite sur les touches
effacer_touches();
// LBL_corde->setText("-");
// LBL_case->setText("-");
}
void MainWindow::create_100_lignes_V()
{
for (int n=0; n<100; n++)
{
lst_frames.append(new QFrame(this)); // this
lst_frames[n]->setGeometry(0, 0, 1, 1);
//lst_frames[n]->setStyleSheet(QString::fromUtf8("background-color: rgb(0, 0, 0);"));
lst_frames[n]->setStyleSheet("background-color: blue");
lst_frames[n]->hide();
}
}
void MainWindow::efface_lst_frames()
{
for (int n=0; n<100; n++)
{
lst_frames[n]->hide();
}
}
void MainWindow::trace_rectangle1(int x, int y, int dx, int dy)
{
lst_frames[1]->setGeometry(QRect(x, y, dx, 2)); lst_frames[1]->show();
lst_frames[2]->setGeometry(QRect(x, y+dy, dx, 2)); lst_frames[2]->show();
lst_frames[3]->setGeometry(QRect(x, y, 2, dy)); lst_frames[3]->show();
lst_frames[4]->setGeometry(QRect(x+dx, y, 2, dy)); lst_frames[4]->show();
}
void MainWindow::encadrement_ligne() // du tableWidget_3
{
int x0=TW_3->x();
int y0=TW_3->y() + 70;
int y_max = y0 + TW_3->height();
int x, y;
int largeur = TW_3->width()-10;
int HL = TW_3->verticalHeader()->defaultSectionSize();
int V_SB;
int V_diff;
// encadrement de la ligne sélectionnée
int num_ligne = TW_3->currentRow();
QScrollBar *V_Scroll = TW_3->verticalScrollBar();
V_SB = V_Scroll->value();
V_diff = num_ligne - V_SB;
x = x0;
y = y0 + HL * V_diff;
if ((V_diff>=0) && (y < y_max - HL))
{
trace_rectangle1(x, y, largeur, HL);
}
else { trace_rectangle1(x,y, 1, 1); }
}
void MainWindow::TW_3_scroll(int H)
{
//write_Time_line();
encadrement_ligne();
}
void MainWindow::encadre_accord(int case1, int case2)
{
int x0, y0, x1, y1, dx, dy;
effacer_calque(scene_manche, calque_encadrement3);
if (case1>19) {return;}
if (case2>20) {return;}
if (case1>case2) {return;}
if((case1==0) && (case2==20))
{
Frame_wWidget1->setVisible(false);
return;
}
calcul_xy_note(1, case1, &x0, &y0);
calcul_xy_note(6, case2, &x1, &y1);
dx= x1-x0;
dy=y1-y0;
Frame_wWidget1->setGeometry(QRect(x0-4, y0-2, dx+24, dy +14));
Frame_wWidget1->setStyleSheet( "background: transparent;" "border: 1px solid yellow;" "border-radius: 15px;" );
QGraphicsProxyWidget *proxy = scene_manche->addWidget(Frame_wWidget1);
Frame_wWidget1->setVisible(true);
}
void MainWindow::on_Bt_ACCORD_1_clicked()
{
// accord majeur
//effacer_calque(scene1, calque_notes_manche);
on_Bt_RAZ_2_clicked();
LBL_corde->setText("-");
LBL_case->setText("-");
checkBox_not_erase->setChecked(true);
QString s1, s2, s3, s4;
int d = SBX_tonique->value();
s1 = gamme_chromatique[d];
s2="M";
s1+=s2;
LE_accord_name->setText(s1);
case_min = SBX_de->value(); s3.setNum(case_min);
case_max = SBX_a->value(); s4.setNum(case_max);
LE_de_a->setText(s3 + "a" +s4);
LB_accord_name->clear();
encadre_accord(case_min, case_max);
//on_Bt_RAZ_clicked();
execute_note_midi(28 + SBX_tonique->value());
execute_note_midi(31 + SBX_tonique->value());
execute_note_midi(36 + SBX_tonique->value());
execute_note_midi(28+12 + SBX_tonique->value());
execute_note_midi(31+12 + SBX_tonique->value());
execute_note_midi(36+12 + SBX_tonique->value());
execute_note_midi(28+12+12 + SBX_tonique->value());
execute_note_midi(31+12+12 + SBX_tonique->value());
execute_note_midi(36+12+12 + SBX_tonique->value());
execute_note_midi(28+12+12+12 + SBX_tonique->value());
execute_note_midi(31+12+12+12 + SBX_tonique->value());
execute_note_midi(36+12+12+12 + SBX_tonique->value());
type_accords = 1;
}
void MainWindow::on_Bt_ACCORD_2_clicked()
{
// accord mineur
//effacer_calque(scene1, calque_notes_manche);
on_Bt_RAZ_2_clicked();
LBL_corde->setText("-");
LBL_case->setText("-");
checkBox_not_erase->setChecked(true);
QString s1, s2, s3, s4;
int d = SBX_tonique->value();
s1 = gamme_chromatique[d];
s2="m";
s1+=s2;
LE_accord_name->setText(s1);
case_min = SBX_de->value(); s3.setNum(case_min);
case_max = SBX_a->value(); s4.setNum(case_max);
LE_de_a->setText(s3 + "a" +s4);
LB_accord_name->clear();
encadre_accord(case_min, case_max);
//on_Bt_RAZ_clicked();
execute_note_midi( 31 + SBX_tonique->value());
execute_note_midi( 36 + SBX_tonique->value());
execute_note_midi( 39 + SBX_tonique->value());
execute_note_midi( 31+12 + SBX_tonique->value());
execute_note_midi( 36+12 + SBX_tonique->value());
execute_note_midi( 39+12 + SBX_tonique->value());
execute_note_midi( 31+12+12 + SBX_tonique->value());
execute_note_midi( 36+12+12 + SBX_tonique->value());
execute_note_midi( 39+12+12 + SBX_tonique->value());
execute_note_midi( 31+12+12+12 + SBX_tonique->value());
execute_note_midi( 36+12+12+12 + SBX_tonique->value());
execute_note_midi( 39+12+12+12 + SBX_tonique->value());
type_accords = 2;
}
void MainWindow::on_Bt_ACCORD_3_clicked()
{
// accord 7eme de dominante
//effacer_calque(scene1, calque_notes_manche);
on_Bt_RAZ_2_clicked();
LBL_corde->setText("-");
LBL_case->setText("-");
checkBox_not_erase->setChecked(true);
QString s1, s2, s3, s4;
int d = SBX_tonique->value();
s1 = gamme_chromatique[d];
s2="7";
s1+=s2;
LE_accord_name->setText(s1);
case_min = SBX_de->value(); s3.setNum(case_min);
case_max = SBX_a->value(); s4.setNum(case_max);
LE_de_a->setText(s3 + "a" +s4);
LB_accord_name->clear();
encadre_accord(case_min, case_max);
//on_Bt_RAZ_clicked();
execute_note_midi( 36 + SBX_tonique->value());
execute_note_midi( 40 + SBX_tonique->value());
execute_note_midi( 43 + SBX_tonique->value());
execute_note_midi( 58 + SBX_tonique->value());
execute_note_midi( 36+12 + SBX_tonique->value());
execute_note_midi( 40+12 + SBX_tonique->value());
execute_note_midi( 43+12 + SBX_tonique->value());
execute_note_midi( 58+12 + SBX_tonique->value());
execute_note_midi( 36+12+12 + SBX_tonique->value());
execute_note_midi( 40+12+12 + SBX_tonique->value());
execute_note_midi( 43+12+12 + SBX_tonique->value());
execute_note_midi( 58+12+12 + SBX_tonique->value());
type_accords = 3;
}
void MainWindow::joue_accord_complet(QString ACC, QString cases)
{
// exemple: (Sol, 3a5) -> c.a.d case 3 à case 5
QString s1, s2b, s2c, s3, s4;
//QString degré_txt;
QString type;
int p1, p2;
s1 = ACC; // exemples : Sim, Sibm, Do, Dom, La, Lam, Sol, Solm, Mi7
// if (!checkBox_not_erase->isChecked()) {on_Bt_RAZ_clicked();}
if ((ACC == "") || (ACC == " ") ) { return; }
/*
s1 "La"
s1 "Fa#"
s1 "Mi7"
s1 "Sim"
s1 "Sibm"
s1 "Do"
*/
// détection du degré (0 pour Do , à 11 pour Si)
// rappel : gamme_chromatique<<"Do"<<"Do#"<<"Ré"<<"Mib"<<"Mi"<<"Fa"<<"Fa#"<<"Sol"<<"Sol#"<<"La"<<"Sib"<<"Si";
int n=11;
int deg = -1;
bool ok = false;
while ((n>0) && (ok == false))
{
QString s2a = gamme_chromatique[n];
p1 = s1.indexOf(s2a);
if (p1 != -1) {ok = true;}
n--;
}
if (ok == true) {deg = n+1; }
p1 = s1.indexOf("b");
if (p1 != -1) {deg --;} // bémol
s2b = ACC.right(1); // m, 7, mais aussi # ou la dernière lettre du nom de la note !
type = "MAJ"; // à priori
if (s2b == "m") {type = "min";}
if (s2b == "7") {type = "dom";}
if (s2b == "-") {type = "-";} // note seule
// intervalle de cases à jouer :
s2c = cases; // "0a3" ou "12a14" ...
p2=s2c.indexOf("a");
if (p2 != -1)
{
s3=s2c.left(p2);
case_min = s3.toInt();
SBX_de->setValue(case_min);
s4 = s2c.mid(p2+1, 255);
int v4 = s4.toInt();
if (v4 >= case_min) // on accepte une case unique (genre "7a7") pour forcer une note unique à sa place
{
case_max = v4; // ici on enregistre le numero de la case max
SBX_a->setValue(case_max);
}
}
else
{
case_min = 0;
SBX_de->setValue(case_min);
case_max = 20; // numéro de la case
SBX_a->setValue(case_max); // nombre de cases
}
notes_pleines = false; // ne représentera qu'un cercle
if (type=="MAJ") // accord majeur
{
SBX_tonique->setValue(deg); // spinBox dans le cadre 'Configurateur d'Accords'
on_Bt_ACCORD_1_clicked();
}
if (type=="min") // accord mineur
{
SBX_tonique->setValue(deg);
on_Bt_ACCORD_2_clicked();
}
if (type=="dom") // 7eme de dominante
{
SBX_tonique->setValue(deg);
on_Bt_ACCORD_3_clicked();
}
if (type=="-") // note seule
{
// SB_tonique->setValue(D);
// on_Bt_ACCORD_3_clicked();
on_Bt_RAZ_clicked();
}
/*
case_min = 0;
SBX_de->setValue(case_min);
case_max = 20;
SBX_a->setValue(case_max);
*/
notes_pleines = true;
s1 = type;
if (s1 == "dom") {s1 = "7e dom";}
label_43->setText(LE_tonique->text() + " " +s1);
}
void MainWindow::joue_1_ligne(int ligne_i)
{
QString s1;
for(int C=1; C<5; C++)
{
//on_Bt_RAZ_clicked();
s1 = TW_3->item(ligne_i, C)->text();
s1 = s1.left(3);
int m1 = s1.toInt();
execute_note_midi(m1);
}
}
void MainWindow::trace_ligne_V(int num_colonne, int num_mesure)
{
//sur le tableau horizontal (TimeLine)
if (num_mesure >=100) {return;} // nb max de lignes instanciées, voir fonction ci-dessus
int x;
int dy=140;
int LC=10; // largeur colonnes
int H_diff;
int x0=TW_TimeLine->x();
int y0=TW_TimeLine->y();
if (zoom==1) {LC=10;}
if (zoom==2) {LC=20;}
QScrollBar *H_Scroll = TW_TimeLine->horizontalScrollBar();
H_diff = num_colonne - H_Scroll->value();
x = x0 + LC * H_diff;
if (H_diff>=0)
{
lst_frames[num_mesure+8]->setGeometry(QRect(x, y0, 2, dy));
lst_frames[num_mesure+8]->setStyleSheet("background-color: gray");
lst_frames[num_mesure+8]->show();
}
}
void MainWindow::write_Time_line()
{
int m1;
int R;
QColor couleur1;
int duree_note, intervalle_t, Ti1, Ti2, numero_mesure;
QString s1, s2, s3, sm;
intervalle_t=0;
Ti1=0;
int Rmax= TW_3->rowCount();
if (Rmax > 1000) {Rmax =1000;} // évite de saturer sur des morceaux trops longs !
// ------------- colorie les cases horizontales (notes) ---------------------------
Ti2=0;
R=0;
while ((R < Rmax) && Ti2 < 300)
{
s1 = TW_3->item(R, 6)->text();
duree_note = s1.toInt();
for (int dt=0; dt<duree_note; dt++)
{
s1 = TW_3->item(R, 1)->text();
s1 = s1.left(2);
m1 = s1.toInt();
if ((m1 >= 40) && (m1 <= 82)) // si présence d'un code midi
{
couleur1 = TW_3->item(R, 1)->background().color();
if(couleur1 != "#000000") { complete_case(1, Ti2, " ", "#CECECE", couleur1, false, TW_TimeLine);}
}
s1 = TW_3->item(R, 2)->text();
s1 = s1.left(2);
m1 = s1.toInt();
if ((m1 >= 40) && (m1 <= 82))
{
couleur1 = TW_3->item(R, 2)->background().color();
if(couleur1 != "#000000") { complete_case(2, Ti2, " ", "#CECECE", couleur1, false, TW_TimeLine);}
}
s1 = TW_3->item(R, 3)->text();
s1 = s1.left(2);
m1 = s1.toInt();
if ((m1 >= 40) && (m1 <= 82))
{
couleur1 = TW_3->item(R, 3)->background().color();
if(couleur1 != "#000000") { complete_case(3, Ti2, " ", "#CECECE", couleur1, false, TW_TimeLine);}
}
s1 = TW_3->item(R, 4)->text();
s1 = s1.left(2);
m1 = s1.toInt();
if ((m1 >= 40) && (m1 <= 82))
{
couleur1 = TW_3->item(R, 4)->background().color();
if(couleur1 != "#000000") {complete_case(4, Ti2, " ", "#CECECE", couleur1, false, TW_TimeLine);}
}
Ti2 ++;
}
R++;
}
// ----------------------------------------
numero_mesure =1; // DEPART
R=0;
while ((R < Rmax) && Ti1 < 300)
{
sm =TW_3->item(R, 7)->text();
couleur1 = TW_3->item(R, 8)->background().color();
if(couleur1 == "#888888")
{
s2.setNum(intervalle_t);
complete_case(0, Ti1-1, s2, "#000000", "#FFFFFF", false, TW_TimeLine);
intervalle_t=0;
s3.setNum(numero_mesure);
complete_case(0, Ti1, s3, "#FFFFFF", "#555555", false, TW_TimeLine);
trace_ligne_V(Ti1, numero_mesure);
s1 = TW_3->item(R, 6)->text();
duree_note = s1.toInt();
intervalle_t += duree_note;
Ti1 += duree_note;
numero_mesure++;
}
else
{
s1 = TW_3->item(R, 6)->text(); // durée de la note
duree_note = s1.toInt();
intervalle_t += duree_note;
Ti1 += duree_note;
}
R++;
}
}
int MainWindow::calcul_T_note(int R)
{
// temps du début de la note en fonction du num de ligne (row) de la cellule cliquée dans le tableau3
int i, di, dT;
QString s1, duree_txt;
dT=0;
for(i=0 ; i<R ; i++)
{
duree_txt = TW_3->item(i, 6)->text();
di = duree_txt.toInt();
dT += di;
}
return dT;
}
void MainWindow::trace_rectangle2(int x, int y, int dx, int dy)
{
// l'objet QRect doit s'utiliser sur un QPainter
// d'où cette fonction qui trace directement sur le mainwindow
// sans masquage du fond (ne confisque pas les clics souris sur les widgets en particulier !!!)
lst_frames[5]->setGeometry(QRect(x, y, dx, 2)); lst_frames[5]->show();
lst_frames[6]->setGeometry(QRect(x, y+dy, dx, 2)); lst_frames[6]->show();
lst_frames[7]->setGeometry(QRect(x, y, 2, dy)); lst_frames[7]->show();
lst_frames[8]->setGeometry(QRect(x+dx, y, 2, dy)); lst_frames[8]->show();
}
void MainWindow::encadrement_colonne() // de la timeline en bas (tableWidget_T sur onglet 'INSTRUMENTS')
{
int x0=TW_TimeLine->x();
int y0=TW_TimeLine->y() + 45;
int x;
int dx;
int dy=120; //tableWidget_T->height();
int LC=10; // largeur colonnes, doit coincider avec la valeur inscrite dans l'ui
int HSB;
int H_diff;
//num_colonne_a_encadrer=5;
//nb_colonnes_a_encadrer=3;
if (zoom==1) {LC=10;}
if (zoom==2) {LC=20;}
// nb_colonnes_a_encadrer -> variable globale
QScrollBar *H_Scroll = TW_TimeLine->horizontalScrollBar();
HSB = H_Scroll->value();
H_diff = num_colonne_a_encadrer - HSB;
x = x0 + LC * H_diff;
dx = LC * nb_colonnes_a_encadrer;
if (H_diff>=0)
{
trace_rectangle2(x, y0, dx, dy);
}
else
{
;
}
}
void MainWindow::garnir_TW3()
{
NOTE note1, note2;
int n_barre1, n_barre2;
int duree;
int midi_i;
int num_case=1;
int num_ligne=0;
QString s1;
QString nom_note;
QString duree_txt;
uint32_t t=0;
int n_max = liste_NOTES.length();
if(n_max<2) {return;} // évite d'effacer TW3 intempestivement
init_TW_3();
TW_3->setRowCount(0);
on_Bt_AddLine_clicked();
// premier passage: on remplit le tableau avec des lignes vides
for(int n=0; n<n_max; n++)
{
int RC = TW_3->rowCount();
TW_3->setRowCount(RC+1); // ajout une ligne au tableau
for (int c=0; c<=13; c++)
{
complete_case(RC, c, "", "#000000", "#FFFFFF", false, TW_3);
}
}
// second passage:
for(int n=0; n<n_max; n++)
{
note1 = liste_NOTES[n-1];
note2 = liste_NOTES[n];
n_barre1 = note1.n_barreM;
n_barre2 = note2.n_barreM;
midi_i = note2.midi;
// num_ligne++;
if (n_barre2 != n_barre1) { num_ligne++; }
nom_note="";
if ((midi_i >=40) && (midi_i <=83) )
{
nom_note.setNum(midi_i);
int h1 = calcul_hauteur_note(midi_i);
QColor couleur1 = liste_couleurs[h1];
nom_note+=" ";
nom_note += nom_note_FR(midi_i);
//num_case=0;
int RC = TW_3->rowCount();
QString s0="";
if (num_ligne >1) {s0 = TW_3->item(num_ligne-1, 0)->text(); }
s1.setNum(n);
s1 = s0 + " " + s1;
complete_case(num_ligne-1, 0, s1, "#000000", "#DDDDDD", false, TW_3);
for (int c=0; c<=13; c++)
{
complete_case(RC, c, "-", "#000000", "#FFFFFF", false, TW_3);
}
QTableWidgetItem *Item1 = new QTableWidgetItem();
Item1->setIcon(QIcon("../images/01.png" ));
TW_3->setItem(num_ligne-1, 5, Item1 );
//complete_case(num_ligne-1, 5, ">", "#00FF00", "#000000", false, tableWidget_3);
duree = n_barre2 - n_barre1;
if (duree <0) {duree = 0;}
if (duree > 0)
{
//c'est ici que la durée de la note jouée est définie :
duree_txt.setNum(duree);
complete_case(num_ligne-2, 6, duree_txt, "#000000", "#FFFFFF", false, TW_3);
}
if (n_barre2 == n_barre1)
{
num_case++;
if (num_case>3) {num_case=3;}
}
else {num_case=1;}
// écriture du nom des notes sur fond coloré :
complete_case(num_ligne-1, num_case, nom_note, "#000000", couleur1, false, TW_3);
}
}
TW_3->resizeColumnsToContents();
// tableWidget_3->setColumnWidth(0, 100);
s1.setNum(0);
LE_de->setText(s1);
s1.setNum(num_ligne);
LE_a->setText(s1);
}
void MainWindow::on_Bt_import_notes_clicked()
{
on_Bt_load_notes_clicked();
garnir_TW3();
}
void MainWindow::copie_TW3_to_NOTES()
{
QString s1;
int T=0;
int D=0;
int L_max = TW_3->rowCount();
for(int L=0; L<L_max; L++)
{
s1 = TW_3->item(L, 6)->text(); // durée
D = s1.toInt();
for(int C=1; C<=3; C++)
{
s1 = TW_3->item(L, C)->text();
s1 = s1.left(3);
int m1 = s1.toInt(); //midi
if(m1>0) {ajout_note(m1, 0, T);}
}
T+=D;
}
checkBox_GI->setChecked(true);
on_Bt_copy_nt_M_to_T_clicked();
on_Bt_toggle_grille_M_clicked();
}
void MainWindow::on_Boite_Onglets_Global_tabBarClicked(int index)
{
if(index == 1) // on passe sur l'onglet 'NOTES'
{
copie_TW3_to_NOTES();
}
if(index == 2) // on passe sur l'onglet 'INSTRUMENTS'
{
on_Bt_STOP_clicked();
efface_lst_frames();
garnir_TW3();
}
}
void MainWindow::joue_morceau_debut()
{
//if(nb_lignes ==0){return;}
if (lecture_pause == 1)
{
Bt_lecture_2->setText("Jouer tout");
//Bt_lecture_2->setStyleSheet("QBt{background-color:#50FF1B;}");
lecture_pause =0;
QString s1;
s1.setNum(num_ligne_en_cours);// conversion num -> txt
Timer2->stop();
}
else
{
nb_notes_jouees_max = 10000;
// Bt_lecture_2->setText("[]");
//Bt_lecture_2->setStyleSheet("QBt{background-color:yellow;}");
lecture_pause = 1;
//num_note_stop=10000;
Tp1=0;
temps1=0;
Timer2->start(10);
}
}
void MainWindow::on_Bt_lecture_2_clicked()
{
num_ligne_en_cours =0;
// num_note_max = liste_NOTES_importees.length()-1;
num_note_max = TW_3->rowCount();
if (num_note_max < 1) {return;}
joue_morceau_debut();
}
void MainWindow::set_zoom2()
{
zoom=2;
QFont fnt;
int n_max = TW_TimeLine->columnCount();
fnt.setFamily("Ubuntu");
fnt.setPointSize(8);
TW_TimeLine->setFont(fnt);
for(int n=0; n<n_max; n++)
{
TW_TimeLine->setColumnWidth(n, 20);
}
}
int MainWindow::open_fichier_lst() // cette fonction est appelée par la fonction 'write_Tableau_vertical()'
{
QString ligne_i, str1;
QString s1;
int p1a, p1b;
// stop execution en cours
lecture_pause = 1;
Bt_lecture_2->setText("Jouer tout");
//Bt_lecture_2->setStyleSheet("QBt{background-color:#50FF1B;}");
lecture_pause =0;
s1.setNum(num_ligne_en_cours);// conversion num -> txt
Timer2->stop();
string_currentFile = QFileDialog::getOpenFileName(this, tr("Ouvrir Fichier accords..."), string_currentDir,
tr("Fichiers lst (*.lst);;All Files (*)"));
if (string_currentFile != "")
{
save_fichier_ini();
liste_str_in.clear();
liste_accords.clear();
}
else {return 0;}
int p1 = string_currentFile.lastIndexOf("/");
string_currentDir =string_currentFile.left(p1+1);
if (!string_currentFile.isEmpty())
{
lineEdit_1->setText(string_currentFile);
}
else {return 0;}
QFile file1(string_currentFile);
if (!file1.open(QIODevice::ReadOnly | QIODevice::Text)) return 1;
QTextStream TextStream1(&file1);
int num_ligne = 0;
ligne_i = TextStream1.readLine(); // vitesse
p1a=ligne_i.indexOf("v="); // duree
p1b=ligne_i.indexOf(";",p1a);
s1 = ligne_i.mid(p1a+2, p1b-(p1a+2));
int v1;
v1 = s1.toFloat();
doubleSpinBox_vitesse->setValue(v1);
while ( !TextStream1.atEnd() )
{
ligne_i = TextStream1.readLine();
liste_accords += ligne_i;
num_ligne++;
}
file1.close();
str1.setNum(num_ligne);
lineEdit_2->setText(str1 + " lignes");
int nb_de_lignes = num_ligne;
L_save_max = nb_de_lignes;
s1.setNum(0);
LE_de->setText(s1);
s1.setNum(nb_de_lignes);
LE_a->setText(s1);
return nb_de_lignes;
}
int MainWindow::dechiffre_note(QString label_i, int L, int c) // dans la 'liste_accords[]' et complète case L C de TW3
{
int p1a, p1b, m1, h1;
QString ligne_i=liste_accords[L];
QString s1, s2;
QColor couleur1;
p1a=ligne_i.indexOf(label_i);
p1b=ligne_i.indexOf(";",p1a);
s1 = ligne_i.mid(p1a+3, p1b-(p1a+3));
if (s1=="") { return 0; }
m1 = s1.toInt();
if (m1==0) {return 0;}
h1 = calcul_hauteur_note(m1); // h1 = 0..11
couleur1 = liste_couleurs[h1];
s2 = " " + gamme_chromatique[h1];
s1 += s2;
complete_case(L, c, s1, "#000000", couleur1, false, TW_3);
return 1; // Une note est présente en L, C
}
QString MainWindow::extraction_data(QString ligne_i, QString label)
{
int p1, p2, nb;
QString s1;
p1=ligne_i.indexOf(label);
if(p1 == -1) {return "";} // (pas trouvé)
p2=ligne_i.indexOf(";",p1);
nb = label.length();
s1 = ligne_i.mid(p1+nb, p2-(p1+nb));
return s1;
}
int MainWindow::write_Tableau_vertical() // décrypte la variable globale QStringList 'liste_accords[]'
{
QString s0, s1, s2;
int dt;
int temps=0;
int total =0;
int z;
int num_note=0;
//liste_accords.clear();
int nb_de_lignes = open_fichier_lst(); // appel de la fonction qui peuple la variable (QString) 'liste_accords'
if (nb_de_lignes == 0) {return 1;}
init_TW_3();
TW_3->setRowCount(0);
mode_depot_note = false;
// -------------------------------------------------------------------------------
// on va transcrire ce contenu du String "liste_accords" dans le TW_3
QString ligne_i;
for (int L=0; L<nb_de_lignes; L++)
{
on_Bt_AddLine_clicked();
ligne_i=liste_accords[L];
s1 = "";
z = dechiffre_note("m1=", L, 1); // z=1 si note présente
if (z==1)
{
// en vue de remplir la colonne des n° de notes
total++;
s0.setNum(total);
s1 += " ";
s1 += s0;
}
z = dechiffre_note("m2=", L, 2);
if (z==1)
{
total++;
s0.setNum(total);
s1 += " ";
s1 += s0;
}
z = dechiffre_note("m3=", L, 3);
if (z==1)
{
total++;
s0.setNum(total);
s1 += " ";
s1 += s0;
}
// écriture dans la colonne des n° de notes
complete_case(L, 0, s1, "#000000", "#FFFCDD", false, TW_3);
s1= extraction_data(ligne_i, "cmt="); // commetaire
complete_case(L, 4, s1, "#000000", "#FFFCDD", false, TW_3);
// la colonne 5 est un bouton vert '>'
s1= extraction_data(ligne_i, "d="); // durée
TW_3->setItem(L, 6, new QTableWidgetItem (s1) ); // dt
dt = s1.toInt();
s1= extraction_data(ligne_i, "M="); // mesure
if (s1 != " ")
{
complete_case(L, 7, s1, "#FFFFFF", "#888888", false, TW_3);
s1.setNum(temps);
complete_case(L, 8, s1, "#000000", "#FFFCDD", false, TW_3); // tps
temps =0;
}
else
{
s1.setNum(temps);
complete_case(L, 8, s1, "#000000", "#CECECE", false, TW_3);
}
temps += dt;
TW_3->setItem(L, 9, new QTableWidgetItem (" "));
s1= extraction_data(ligne_i, "a="); // ACC
TW_3->setItem(L, 10, new QTableWidgetItem (s1));
s1= extraction_data(ligne_i, "cases=");
complete_case(L, 11, s1, "#000000", "#FFFFFF", false, TW_3);
s2="";
bool ok = false;
s1= extraction_data(ligne_i, "D0v="); // corde à vide
if ((s1 != "") && (s1 != "-")) { s2 += "D0v=" + s1 + ";"; ok = true; }
s1= extraction_data(ligne_i, "D0h="); // corde à vide
if ((s1 != "") && (s1 != "-")) { s2 += "D0h=" + s1 + ";"; ok = true; }
s1= extraction_data(ligne_i, "D1v="); // posiion "verticale" (c.d corde) du doigt 1 (index)
if ((s1 != "") && (s1 != "-")) { s2 += "D1v=" + s1 + ";"; ok = true; }
s1= extraction_data(ligne_i, "D1h="); // posiion "horizontale" (case) du doigt 1 (index)
if ((s1 != "") && (s1 != "-")) { s2 += "D1h=" + s1 + ";"; ok = true; }
s1= extraction_data(ligne_i, "D2v=");
if ((s1 != "") && (s1 != "-")) { s2 += "D2v=" + s1 + ";"; ok = true; }
s1= extraction_data(ligne_i, "D2h=");
if ((s1 != "") && (s1 != "-")) { s2 += "D2h=" + s1 + ";"; ok = true; }
s1= extraction_data(ligne_i, "D3v=");
if ((s1 != "") && (s1 != "-")) { s2 += "D3v=" + s1 + ";"; ok = true; }
s1= extraction_data(ligne_i, "D3h=");
if ((s1 != "") && (s1 != "-")) { s2 += "D3h=" + s1 + ";"; ok = true; }
s1= extraction_data(ligne_i, "D4v=");
if ((s1 != "") && (s1 != "-")) { s2 += "D4v=" + s1 + ";"; ok = true; }
s1= extraction_data(ligne_i, "D4h=");
if ((s1 != "") && (s1 != "-")) { s2 += "D4h=" + s1 + ";"; ok = true; }
if (ok != true) {s2=" ";}
QTableWidgetItem *item1 = new QTableWidgetItem();
item1->setText(s2);
// item1->setFlags(item1->flags() & ~Qt::ItemIsEditable); // passe en read only
TW_3->setItem(L, 12, item1);
}
TW_3->resizeColumnsToContents();
return 0;
}
void MainWindow::on_Bt_Load_lst_clicked()
{
set_zoom2();
int w = write_Tableau_vertical();
// if (w==0)
{
//checkBox_not_erase->setChecked(true);
//gestion_mesures();
write_Time_line();
}
}
void MainWindow::on_Bt_STOP_clicked()
{
Bt_lecture_2->setText("Jouer tout");
lecture_pause =0;
QString s1;
s1.setNum(num_ligne_en_cours);
Timer2->stop();
}
void MainWindow::on_SB_tonique_valueChanged(int arg1)
{
int n=arg1;
LE_tonique->setText(gamme_chromatique[n]);
lineEdit_10->clear();
LE_de_a->clear();
}
void MainWindow::on_Bt_22_clicked()
{
QMessageBox msgBox;
QString s1;
s1 = "POSITION DES DOIGTS main gauche (sur le manche)";
s1 += "\n";
s1 += "\n";
s1 += "La première ligne (0) désigne la corde à vide";
s1 += "\n";
s1 += "\n";
s1 += "Chacune des 4 lignes suivantes (1 à 4) représente un doigt :";
s1 += "\n";
s1 += "\n";
s1 += "le numéro de la ligne désigne le doigt :";
s1 += "\n";
s1 += "doigt 1 = index, 2 = majeur...";
s1 += "\n";
s1 += "\n";
s1 += "Pour écrire dans le tableau cliquer au préalable sur une note (sur le manche)";
s1 += "\n";
s1 += "... puis ici sur une ligne (sur une des 4 petites flèches vertes)";
s1 += "\n";
s1 += "( corde 1 = mi aigü...)";
s1 += "\n";
s1 += "\n";
s1 += "Le tableau s'actualise également lorsqu'une note est jouée depuis la liste TW3";
s1 += "\n";
s1 += "\n";
s1 += "Dès lors, sur le manche, les numéros des doigts s'afficheront au centre des notes "
"pressées dans les cases (et pas forcément jouées, on peut très bien plaquer tout un "
"accord et ne jouer qu'une note à la fois, en arpège )";
msgBox.setText(s1);
msgBox.exec();
}
void MainWindow::on_Bt_21_clicked()
{
QMessageBox msgBox;
QString s1;
s1 = "AIDE GENERALE";
s1 += "\n";
s1 += "\n";
s1 += "1- Ouvrir un 'fichier accords' préalablement sauvegardé' (comprend notes + positions des doigts)";
s1 += "\n";
s1 += "\n";
s1 += "VARIANTE : Importer la liste des notes.";
s1 += "\n";
s1 += "\n";
s1 += "2- Vérifier la durée (calculée) des mesures et modifier la durée des notes si nécessaire.";
s1 += "\n";
s1 += "3- Pour chaque ligne, configurer un accord type (qui représentera la position des doigts) ou une 'note seule'";
s1 += "(utiliser pour cela le 'Configurateur d'accords')";
s1 += " puis envoyer la configuration obtenue vers le tableau TW3, avec le bouton 'to TW3 -->' du 'configurateur d'Accords'.";
s1 += "\n";
s1 += "4- Reste à choisir les doigts pour chaque note. Voir l'aide du cadre 'Position des doigts'.";
s1 += "\n";
s1 += "\n";
s1 += "VARIANTE :";
s1 += "\n";
s1 += "\n";
s1 += "On peut aussi partir de zéro et entrer les notes une à une manuellement dans TW3 (TableWidget 3).";
s1 += "\n";
s1 += "Il est fortement conseillé de cliquer les notes sur le manche au préalable (voir l'aide du manche) ";
s1 += "plutôt que de saisir les libellés au clavier, afin d'éviter les saisies incorrectes.";
s1 += "On peut aussi créer les notes et les gérer dans l'onglet 'NOTES' qui comprend une aide pour lecture d'une partition musicale.";
s1 += "\n";
msgBox.setText(s1);
msgBox.exec();
}
void MainWindow::on_Bt_18_clicked()
{
QMessageBox msgBox;
QString s1;
s1 = "COPIE d'une note vers le tableau TW3 -->";
s1 += "\n";
s1 += "\n";
s1 += "1- clic-droit sur une note (sur le manche)";
s1 += "\n";
s1 += "Le curseur de la souris devient une croix";
s1 += "\n";
s1 += "2- cliquer_gauche alors dans une case de TW3 (colonnes 1 à 3)";
s1 += "\n";
s1 += "La note est alors collée dans le tableau";
s1 += "\n";
s1 += "\n";
s1 += "Si clic en dehors du tableau, l'opéraion est annulée";
s1 += "\n";
msgBox.setText(s1);
msgBox.exec();
}
void MainWindow::on_Bt_20_clicked()
{
QMessageBox msgBox;
QString s1;
s1 = "Les fichiers sont enregistrés au format texte";
s1 += "\n";
s1 += "Il peuvent être facilement concaténés avec un éditeur de texte";
s1 += "\n";
s1 += "pour obtenir un morceau complet à partir de petites séquences.";
msgBox.setText(s1);
msgBox.exec();
}
void MainWindow::on_Bt_24_clicked()
{
QMessageBox msgBox;
QString s1;
s1 = "Les numéros qui s'affichent au centre des notes jouées sont ceux des doigts de la main gauche";
s1 += "\n";
s1 += "1=index, 2=majeur, 3=annulaire, 4=auriculaire";
msgBox.setText(s1);
msgBox.exec();
}
void MainWindow::on_Bt_17_clicked()
{
QMessageBox msgBox;
QString s1;
s1 = "ABBREVIATIONS, sigles utilisés"; s1 += "\n";
s1 += "dans la colonne Cmt ->"; s1 += "\n";
s1 += "Sélectionner une ligne de TW3 au préalable"; s1 += "\n";
s1 += "\n";
s1 += "(GL = début glissendo"; s1 += "\n";
s1 += "GL) = fin glissendo"; s1 += "\n";
s1 += "HO = Hammer-On"; s1 += "\n";
s1 += "PO = Pull-Off"; s1 += "\n";
s1 += "pB = petit Barré (cordes 1-2-3)"; s1 += "\n";
msgBox.setText(s1);
msgBox.exec();
}
void MainWindow::on_Bt_open_dossier_clicked()
{
QString s1, path1;
int p1;
/*
s1 = lineEdit_1->text();
p1 = s1.lastIndexOf("/");
s1.remove(p1, 255);
path1 = s1;
*/
path1 = string_currentDir;
QProcess process1;
process1.setProgram("caja");
process1.setArguments({path1});
process1.startDetached();
}
void MainWindow::complete_accord(int c_min, int c_max)
{
SBX_de->setValue(c_min);
case_min = c_min;
SBX_a->setValue(c_max);
case_max = c_max;
if (type_accords == 1) {on_Bt_ACCORD_1_clicked();}
if (type_accords == 2) {on_Bt_ACCORD_2_clicked();}
if (type_accords == 3) {on_Bt_ACCORD_3_clicked();}
}
void MainWindow::on_Bt_toutes_clicked()
{
complete_accord(0, 20);
}
void MainWindow::on_Bt_3a_clicked()
{
complete_accord(9, 12);
}
void MainWindow::on_Bt_3b_clicked()
{
complete_accord(7, 10);
}
void MainWindow::on_Bt_3c_clicked()
{
complete_accord(5, 8);
}
void MainWindow::on_Bt_3d_clicked()
{
complete_accord(3, 6);
}
void MainWindow::on_Bt_3e_clicked()
{
complete_accord(0, 3);
}
void MainWindow::on_SB_de_valueChanged(int arg1)
{
QString s3, s4;
case_min = arg1;
if (arg1 > case_max) {SBX_a->setValue(arg1);}
s3.setNum(case_min);
case_max = SBX_a->value();
s4.setNum(case_max);
LE_de_a->setText(s3 + "a" +s4);
encadre_accord(case_min, case_max);
//complete_accord(case_min, case_max); // NON !! pas ici !!!!
}
void MainWindow::on_SB_a_valueChanged(int arg1)
{
QString s3, s4;
case_min = SBX_de->value();
if (arg1 < case_min) {SBX_a->setValue(case_min);}
s3.setNum(case_min);
case_max = arg1;
s4.setNum(case_max);
LE_de_a->setText(s3 + "a" +s4);
encadre_accord(case_min, case_max);
//complete_accord(case_min, case_max); // NON !! pas ici !!!!
}
void MainWindow::on_Bt_25_clicked()
{
QMessageBox msgBox;
QString s1;
s1 = "Sur cet onglet optimisé pour la guitare"; s1 += "\n";
s1 += "les notes < midi40 sont ignorées."; s1 += "\n";
s1 += "De fait le clavier du piano est délesté des touches les plus graves (une octave).\n";
s1 += "Les notes midi28 à midi39 sont toutefois prises en compte dans les onglets précédents."; s1 += "\n";
msgBox.setText(s1);
msgBox.exec();
}
void MainWindow::on_SBX_tonique_valueChanged(int arg1)
{
int n=arg1;
LE_tonique->setText(gamme_chromatique[n]);
LE_accord_name->clear();
LE_de_a->clear();
}
void MainWindow::on_SBX_de_valueChanged(int arg1)
{
QString s3, s4;
case_min = arg1;
if (arg1 > case_max) {SBX_a->setValue(arg1);}
s3.setNum(case_min);
case_max = SBX_a->value();
s4.setNum(case_max);
LE_de_a->setText(s3 + "a" +s4);
encadre_accord(case_min, case_max);
//complete_accord(case_min, case_max); // NON !! pas ici !!!!
}
void MainWindow::on_SBX_a_valueChanged(int arg1)
{
QString s3, s4;
case_min = SBX_de->value();
if (arg1 < case_min) {SBX_a->setValue(case_min);}
s3.setNum(case_min);
case_max = arg1;
s4.setNum(case_max);
LE_de_a->setText(s3 + "a" +s4);
encadre_accord(case_min, case_max);
//complete_accord(case_min, case_max); // NON !! pas ici !!!!
}
void MainWindow::numerote_1_note(int corde_i, int case_i, int num_i)
{
QString s1;
int x, y;
s1.setNum(num_i);
calcul_xy_note(corde_i, case_i, &x, &y);
textItem1 = new QGraphicsSimpleTextItem(s1);
QBrush brush1;
brush1.setStyle(Qt::SolidPattern);
brush1.setColor("#000000");
textItem1->setBrush(brush1);
textItem1->setPos(x+2, y -1);
calque_notes_manche->addToGroup(textItem1);
}
void MainWindow::affi_positions_doigts_dans_status(QString s_i)
{
// et dans le cadre 'Position de doigts' (tableWidget_doigts)
// et numérote les notes jouées sur le manche
QString s2, s3;
int corde1, case1, num1;
init_TW_doigts();
s3="";
//---------------------------------------------------------------------------------------
s2=extraction_data(s_i, "D0v=");
if((s2 != "") && (s2 != "-"))
{
num1=0;
TW_doigts->setItem(0, 0, new QTableWidgetItem (s2) ); // corde
TW_doigts->item(0, 0)->setTextAlignment(Qt::AlignCenter);
s3 += "( DOIGT 1 corde " + s2;
corde1 = s2.toInt();
label_44->setText("corde " + s2);
s2=extraction_data(s_i, "D0h=");
case1 = s2.toInt();
s3 += " case " + s2 + " ) ";
TW_doigts->setItem(0, 1, new QTableWidgetItem (s2) ); // case
TW_doigts->item(0, 1)->setTextAlignment(Qt::AlignCenter);
numerote_1_note(corde1, case1, num1);
label_45->setText("case " + s2);
}
//---------------------------------------------------------------------------------------
s2=extraction_data(s_i, "D1v=");
if((s2 != "") && (s2 != "-"))
{
num1=1;
TW_doigts->setItem(1, 0, new QTableWidgetItem (s2) ); // corde
TW_doigts->item(1, 0)->setTextAlignment(Qt::AlignCenter);
s3 += "( DOIGT 1 corde " + s2;
corde1 = s2.toInt();
label_44->setText("corde " + s2);
s2=extraction_data(s_i, "D1h=");
case1 = s2.toInt();
s3 += " case " + s2 + " ) ";
TW_doigts->setItem(1, 1, new QTableWidgetItem (s2) ); // case
TW_doigts->item(1, 1)->setTextAlignment(Qt::AlignCenter);
numerote_1_note(corde1, case1, num1);
label_45->setText("case " + s2);
}
//---------------------------------------------------------------------------------------
s2=extraction_data(s_i, "D2v=");
if((s2 != "") && (s2 != "-"))
{
bool ok; int dec = s2.toInt(&ok, 10);
if (ok==true)
{
num1=2;
TW_doigts->setItem(2, 0, new QTableWidgetItem (s2) ); // corde
TW_doigts->item(2, 0)->setTextAlignment(Qt::AlignCenter);
s3 += "( DOIGT 2 corde " + s2;
corde1 = s2.toInt();
label_44->setText("corde " + s2);
s2=extraction_data(s_i, "D2h=");
case1 = s2.toInt();
label_45->setText("case " + s2);
s3 += " case " + s2 + " ) ";
TW_doigts->setItem(2, 1, new QTableWidgetItem (s2) ); // case
TW_doigts->item(2, 1)->setTextAlignment(Qt::AlignCenter);
numerote_1_note(corde1, case1, num1);
}
}
//---------------------------------------------------------------------------------------
s2=extraction_data(s_i, "D3v=");
if((s2 != "") && (s2 != "-"))
{
bool ok; int dec = s2.toInt(&ok, 10);
if (ok==true)
{
num1=3;
TW_doigts->setItem(3, 0, new QTableWidgetItem (s2) ); // corde
TW_doigts->item(3, 0)->setTextAlignment(Qt::AlignCenter);
s3 += "( DOIGT 3 corde " + s2;
corde1 = s2.toInt();
label_44->setText("corde " + s2);
s2=extraction_data(s_i, "D3h=");
case1 = s2.toInt();
s3 += " case " + s2 + " ) ";
label_45->setText("case " + s2);
TW_doigts->setItem(3, 1, new QTableWidgetItem (s2) ); // case
TW_doigts->item(3, 1)->setTextAlignment(Qt::AlignCenter);
numerote_1_note(corde1, case1, num1);
}
}
//---------------------------------------------------------------------------------------
s2=extraction_data(s_i, "D4v=");
if((s2 != "") && (s2 != "-"))
{
bool ok;
int dec = s2.toInt(&ok, 10);
if (ok==true)
{
num1=4;
TW_doigts->setItem(4, 0, new QTableWidgetItem (s2) ); // corde
TW_doigts->item(4, 0)->setTextAlignment(Qt::AlignCenter);
s3 += "( DOIGT 4 corde " + s2;
corde1 = s2.toInt();
label_44->setText("corde " + s2);
s2=extraction_data(s_i, "D4h=");
case1 = s2.toInt();
s3 += " case " + s2 + " ) ";
label_45->setText("case " + s2);
TW_doigts->setItem(4, 1, new QTableWidgetItem (s2) ); // case
TW_doigts->item(4, 1)->setTextAlignment(Qt::AlignCenter);
numerote_1_note(corde1, case1, num1);
}
}
//---------------------------------------------------------------------------------------
// statusbar->showMessage(s3);
}
void MainWindow::on_TW_3_cellClicked(int row, int column)
{
ligne_TW3 = row;
QString s1, s2, s3, ACC, cases;
QString duree_txt;
int di=0;
int R;
//checkBox_not_erase->setChecked(true);
R = TW_3->currentRow();
num_ligne_en_cours = row;
s1.setNum(R+1);
lineEdit_9->setText(s1);
encadrement_ligne();
s2 = TW_3->item(row, column)->text(); // actuellement dans la case cible
s1 = lineEdit_n_midi->text();
int m1 = s1.toInt();
if ( (column>0) && (column<4) && mode_depot_note == true) // >0 because la col. 0 ne contient pas de note, mais les n°
{
mode_depot_note = false;
label_MESSAGE->setVisible(false);
// statusbar->showMessage("");
MainWindow::setCursor(Qt::ArrowCursor);
if(s1 != s2) // alors on inscrit la nouvelle valeur dans la case
{
int h1 = calcul_hauteur_note(m1); // h1 = 0..11
if(h1<0){h1+=12;}
if(h1>11){h1-=12;}
s3 = " " + gamme_chromatique[h1];
s1 += s3;
QColor couleur_case = liste_couleurs[h1];
complete_case(row, column, s1, "#000000", couleur_case, false, TW_3);
TW_3->resizeColumnsToContents();
}
else // on efface la valeur
{
TW_3->setItem(row, column, new QTableWidgetItem ("--") );
}
init_TW_T();
}
if (column==5) // celle qui contient les petits boutons ( triangles '>' verts)
{
//effacer_calque(scene1, calque_notes);
ACC = TW_3->item(row, 10)->text();
cases = TW_3->item(row, 11)->text();
notes_silencieuses = true;
joue_accord_complet(ACC, cases); // représentation graphique de la position avant de jouer la note
notes_silencieuses = false;
joue_1_ligne(row);
s1 = TW_3->item(row, 12)->text();
affi_positions_doigts_dans_status(s1);
}
if (column==6) { write_Time_line(); }
if (column==9) // ACC
{
s1 = TW_3->item(row, 10)->text();
s2 = TW_3->item(row, 11)->text();
if (s1 !=" ")
{
notes_silencieuses = true;
joue_accord_complet(s1, s2);
notes_silencieuses = false;
}
}
/*
if (column==11)
{
QMessageBox msgBox;
QString s1;
s1 = "Colonne read only";
s1 += "\n";
s1 += "Utiliser le cadre 'de saisie 'Position des doigts'";
s1 += "\n";
s1 += "pour saisir les positions.";
msgBox.setText(s1);
msgBox.exec();
}
*/
s2 = TW_3->item(row, 7)->text();
s2 = s2.mid(1);
mesure_a_encadrer = s2.toInt();
// write_Time_line();
duree_txt = TW_3->item(R, 6)->text();
di = duree_txt.toInt();
nb_colonnes_a_encadrer = di;
int T_note;
T_note = calcul_T_note(row);
num_colonne_a_encadrer = T_note;
encadrement_colonne();
TW_3->resizeColumnsToContents();
}
void MainWindow::on_Bt_26_clicked()
{
QMessageBox msgBox;
QString s1;
s1 = "Le fichier .LST contient les notes + les positions des doigts, c'est à dire tout le contenu de TW3";
s1 += "\n";
s1 += "";
msgBox.setText(s1);
msgBox.exec();
}
void MainWindow::save_fichier_lst()
{
// enregisterment incrémentiel sur HDD (nom de fichier = 1..2...3...)
QString s1;
//QString ligne_i;
int numero=0;
QString s2;
QString chemin_out;
lecture_pause = 1;
Bt_lecture_2->setText(">");
Bt_lecture_2->setStyleSheet("QPushButton{background-color:#50FF1B;}");
lecture_pause =0;
s1.setNum(num_ligne_en_cours);// conversion num -> txt
Timer2->stop();
chemin_out = string_currentDir; //QDir::homePath() + "/GUITARE/ACCORDS/";
/*
if (!dossier_out.exists())
{
QMessageBox msgBox;
msgBox.setText("Le dossier : " + dossier_out.dirName() + " n'éxiste pas, je le crée");
msgBox.exec();
}
*/
bool existe =1;
while(existe)
{
numero++;
s2.setNum(numero);
existe = QFile::exists(chemin_out + s2 + ".lst");
/*
QMessageBox msgBox;
QString s1;
s1 = "Le fichier de destination (" + chemin_out + s2 + ".lst ) existe déjà";
msgBox.setText(s1);
msgBox.exec();
*/
}
s2.setNum(numero);
int nb_lignes;
QFile file1(chemin_out + s2 + ".lst");
//file1.remove();
if (file1.open(QIODevice::WriteOnly | QIODevice::Text))
{
QTextStream file_out(&file1);
int vitesse = doubleSpinBox_vitesse->value();
QString s1;
s1.setNum(vitesse);
file_out << "v=" + s1 + ";";
file_out << char(10);
nb_lignes = liste_accords.length();
for (int i=0; i<nb_lignes; i++)
{
file_out << liste_accords[i]; // << char(10);
}
}
file1.close();
QMessageBox msgBox;
s1="Fichier enregistré: " + chemin_out + s2 + ".lst";
msgBox.setText(s1);
msgBox.exec();
}
int MainWindow::constitue_liste_accords() // en vue de l'enregistrement sur le HDD (par la fonction 'save_fichier_lst()' ci-dessus)
{
// remarque: les codes midi sont 40..84 qui correspondent à des caractères ASCII classiques.
// la valeur 100 est utilisée (ici) pour coder les barres de mesure
// plus exactement, les codes ascii 32..126 codents poue des caratères classiques.
// on peut donc les encoder dans des QString qui eux sont facilement recordables...
QString s1; // valeurs midi d'un accord sous forme de texte
QString ligne_i;
int m1;
liste_accords.clear();
int RC3=TW_3->rowCount()-1;
int L_min = LE_de->text().toInt() -1;
int L_max = LE_a->text().toInt();
if (L_min < 0) {L_min = 0;}
if (L_max > RC3) {L_save_max = RC3;}
if ((L_max - L_min) < 2)
{
QMessageBox msgBox;
msgBox.setText("Le tableau doit contenir au minimum 2 lignes !");
msgBox.exec();
return 1;
}
for(int L=L_min; L<L_max; L++)
{
ligne_i.clear();
s1 = TW_3->item(L, 1)->text(); s1 = s1.left(2); //note1
m1 = s1.toInt(); if ((m1<40)||(m1>84)) {s1="";} // code midi de la note
s1 = "m1=" +s1 + ";";
ligne_i += s1;
s1 = TW_3->item(L, 2)->text(); s1 = s1.left(2); // note2
m1 = s1.toInt(); if ((m1<40)||(m1>84)) {s1="";}
s1 = "m2=" +s1 + ";";
ligne_i += s1;
s1 = TW_3->item(L, 3)->text(); s1 = s1.left(2); // note3
m1 = s1.toInt(); if ((m1<40)||(m1>84)) {s1="";}
s1 = "m3=" +s1 + ";";
ligne_i += s1;
s1 = TW_3->item(L, 4)->text(); // commentaire
s1 = "cmt=" +s1 + ";";
ligne_i += s1;
s1 = TW_3->item(L, 6)->text(); // DUREE
s1 = " " + s1; s1=s1.right(2); // ajoute 1 espace si nombre<10
s1 = "d=" +s1 + ";"; // durée
ligne_i += s1;
s1 = TW_3->item(L, 7)->text(); // MESURE
s1 = "M=" +s1 + ";";
ligne_i += s1;
s1 = TW_3->item(L, 8)->text(); // tps
s1 = "T=" +s1 + ";";
ligne_i += s1;
//s1 = TW_3->item(L, 8)->text(); // disponible
//s1 = "x=" +s1 + ";";
//ligne_x += s1;
s1 = TW_3->item(L, 10)->text(); // ACC // "11min
s1 = "a=" + s1 + ";";
ligne_i += s1;
s1 = TW_3->item(L, 11)->text(); ; // "7a9"
s1 = "cases=" + s1 + ";";
ligne_i += s1;
s1 = TW_3->item(L, 12)->text(); // doigts (la case contient toute le string en question),
// voir la fonction : 'on_Bt_copie_doigts_to_TW3_clicked()' qui constitue ce string à partir du 'tableWidget_doigts.'
ligne_i += s1;
ligne_i += '\n';
liste_accords << ligne_i;
}
return 0;
}
void MainWindow::on_Bt_save_clicked()
{
int R = constitue_liste_accords();
if (R == 0) { save_fichier_lst(); }
}
void MainWindow::on_Bt_sigle_1_clicked()
{
complete_case(num_ligne_en_cours, 3, "(GL", "#000000","#FFFCDD", false, TW_3);
}
void MainWindow::on_Bt_sigle_2_clicked()
{
complete_case(num_ligne_en_cours, 3, "GL)", "#000000","#FFFCDD", false, TW_3);
}
void MainWindow::on_Bt_sigle_3_clicked()
{
complete_case(num_ligne_en_cours, 3, "(HO", "#000000","#FFFCDD", false, TW_3);
}
void MainWindow::on_Bt_sigle_4_clicked()
{
complete_case(num_ligne_en_cours, 3, "HO)", "#000000","#FFFCDD", false, TW_3);
}
void MainWindow::on_Bt_sigle_5_clicked()
{
complete_case(num_ligne_en_cours, 3, "Ba", "#000000","#FFFCDD", false, TW_3);
}
void MainWindow::on_Bt_sigle_9_clicked()
{
complete_case(num_ligne_en_cours, 3, "PO", "#000000","#FFFCDD", false, TW_3);
}
void MainWindow::on_Bt_sigle_10_clicked()
{
complete_case(num_ligne_en_cours, 3, "pB", "#000000","#FFFCDD", false, TW_3);
}
void MainWindow::on_TW_doigts_cellClicked(int row, int column)
{
QString s1, s2;
if(case_jouee == 0)
{
s1.setNum(corde_jouee);
TW_doigts->item(0, 0)->setText(s1);
return ;
}
if (column==2)
{
s1.setNum(corde_jouee);
TW_doigts->item(row, 0)->setText(s1);
s2.setNum(case_jouee);
TW_doigts->item(row, 1)->setText(s2);
}
}
void MainWindow::on_Bt_RAZ_doigts_clicked()
{
init_TW_doigts();
}
void MainWindow::on_Bt_copie_doigts_to_TW3_clicked()
{
// le 'TW_doigts' c'est le tableau de saisie dans le cadre 'Position des doigts'
QString s1, s_out;;
s1 = TW_doigts->item(0,0) ->text();
if (s1 != "-") {s_out += "D0v=" + s1 + ";";}
s1 = TW_doigts->item(0,1) ->text();
if (s1 != "-") {s_out += "D0h=" + s1 + ";";}
s1 = TW_doigts->item(1,0) ->text();
if (s1 != "-") {s_out += "D1v=" + s1 + ";";}
s1 = TW_doigts->item(1,1) ->text();
if (s1 != "-") {s_out += "D1h=" + s1 + ";";}
s1 = TW_doigts->item(2,0) ->text();
if (s1 != "-") {s_out += "D2v=" + s1 + ";";}
s1 = TW_doigts->item(2,1) ->text();
if (s1 != "-") {s_out += "D2h=" + s1 + ";";}
s1 = TW_doigts->item(3,0) ->text();
if (s1 != "-") {s_out += "D3v=" + s1 + ";";}
s1 = TW_doigts->item(3,1) ->text();
if (s1 != "-") {s_out += "D3h=" + s1 + ";";}
s1 = TW_doigts->item(4,0) ->text();
if (s1 != "-") {s_out += "D4v=" + s1 + ";";}
s1 = TW_doigts->item(4,1) ->text();
if (s1 != "-") {s_out += "D4h=" + s1 + ";";}
QTableWidgetItem *item1 = new QTableWidgetItem();
item1->setText(s_out);
//item1->setFlags(item1->flags() & ~Qt::ItemIsEditable); // read only
TW_3->setItem(ligne_TW3, 12, item1); // recopie le résultat dans TW3
affi_positions_doigts_dans_status(s_out);
}
void MainWindow::on_Bt_23_clicked()
{
on_Bt_save_clicked();
init_TW_3();
efface_lst_frames();
lineEdit_2->clear();
LE_de->clear();
LE_a->clear();
}
void MainWindow::on_Bt_Supp_line_clicked()
{
int R= TW_3->currentRow();
TW_3->removeRow(R);
}