La Transformée de Fourier et la Musique

Programme en C++ Qt6 basé directement sur la transformée de Fourier rapide. Retrouve les notes de musique (et leur code midi) à partir d'un fichier audio (fichier.wav)
Ce fichier source doit être stéréo échantillonné à 48kb/s, ce qui peut être facilement obtenu avec le soft avidemux (par exemple), éventuellement après extraction de la piste audio d'une vidéo .mp4.

1 Vue d'ensemble



Les notes obtenues peuvent être rejouées, les durées et le rythme sont pris en compte

2 Scan en cours (Transformée de fourier d'un échantillon de signal)

3 Aperçu en vidéo


A voir directement sur Youtube en 1080p pour voir les détails !!!

4 Le code source 'wav to midi' en C++ Qt6: fichier mainwindow.cpp



CODE SOURCE en C++
  1. /* top
  2.   Calcul de la transformée de Fourier rapide d'un signal audio au format PCM enregistré dans un fichier .wav
  3.   Format WAVE, RIFF, fmt échantilloné à 48000Hz
  4.  
  5.   Format : Wave
  6.   File size : 2.39 MiB
  7.   Duration : 13 s 54 ms
  8.   Overall bit rate mode : Constant
  9.   Overall bit rate : 1 536 kb/s
  10.  
  11.   Audio
  12.   Format : PCM
  13.   Format settings : Little / Signed
  14.   Codec ID : 1
  15.   Duration : 13 s 54 ms
  16.   Bit rate mode : Constant
  17.   Bit rate : 1 536 kb/s
  18.   Channel(s) : 2 channels
  19.   Sampling rate : 48.0 kHz
  20.   Bit depth : 16 bits
  21.   Stream size : 2.39 MiB (100%)
  22.  
  23.   Programme écrit par Silicium628
  24.   ce logiciel est libre et open source
  25. */
  26. /*
  27. ***** RAPPEL**** (source: https://helpx.adobe.com/fr/audition/using/digitizing-audio.html) **
  28. Taux d’échantillonnage Niveau de qualité Plage de fréquences
  29.  
  30. 11,025 Hz Faible qualité radio AM (multimédia bas de gamme) 0- 5 512 Hz
  31. 22,050 Hz Comparable à la qualité radio FM (multimédia haut de gamme) 0-11 025 Hz
  32. 32 000 Hz Meilleur que la qualité radio FM (taux de diffusion standard) 0-16 000 Hz
  33. 44 100 Hz CD 0-22 050 Hz
  34. 48 000 Hz DVD standard 0-24 000 Hz
  35. 96 000 Hz DVD Blu-ray 0-48 000 Hz
  36. *********************************************************************************************/
  37. /*
  38. Le présent logiciel est paramétré pour traiter les fichiers audio ECHANTILLONES à 48000Hz (qualité DVD)
  39. ET PAS 44.1 !!
  40. Je le rendrai compatible avec les autres taux, mais pour l'instant il faut enregistrer
  41. au préalable l'audio à traiter avec un taux de 48kHz
  42. (par exemple avec Audacity, c'est facile voir en bas à gauche de sa fenêtre).
  43. */
  44.  
  45.  
  46. #include "mainwindow.h"
  47. #include "ui_mainwindow.h"
  48. #include "math.h"
  49. #include "complexe.cpp"
  50.  
  51. #include <QMessageBox>
  52. #include <QFileDialog>
  53. #include <QFile>
  54. //#include <QImage>
  55.  
  56. #include <QtMultimedia/QMediaPlayer>
  57. #include <QAudioOutput>
  58.  
  59. #include <QMouseEvent>
  60. #include <QDate>
  61. #include <QDateTime>
  62. #include <QScrollBar>
  63.  
  64. /* FFT_wav */
  65. //=============================================================================================
  66. // nouvelle numérotation par (date de compilation + 1 lettre si plusieurs compils le même jour)
  67. // toute version antérieure à la plus récente doit être jetée dans la poubelle jaune.
  68. QString version = "2025-04-19 a";
  69. //=============================================================================================
  70.  
  71. int write_mode =0;
  72.  
  73. QString couleur_ecran = "#141414";
  74. QString couleur_ligne = "#878787";
  75. QString couleur_trace1 = "#0EA004";
  76. QString couleur_trace2 = "#00FFFF";
  77. QString couleur_curseur = "#FFFF00";
  78. QString couleur_texte = "#FFFF00"; // JAUNE
  79. QString couleur_encadrement = "#FF0000"; // ROUGE
  80.  
  81. QPen pen_ligne(QColor(couleur_ligne), 1, Qt::SolidLine);
  82. QPen pen_trace1(QColor(couleur_trace1), 1, Qt::SolidLine);
  83. QPen pen_trace2(QColor(couleur_trace2), 1, Qt::SolidLine);
  84. QPen pen_curseur(QColor(couleur_curseur), 1, Qt::SolidLine);
  85. QPen pen_reticule(QColor(couleur_ligne), 1, Qt::SolidLine);
  86. QPen pen_encadrement(QColor(couleur_encadrement), 1, Qt::SolidLine);
  87.  
  88. char temp_entete[100]; // signal entete lu dans le fichier .wav
  89. char temp_data[2000000]; // signal audio lu dans le fichier .wav (max 2MB)
  90. int pas_echantillonage = 24;
  91.  
  92. Complexe ech[2048]; // nb_ech echantillons
  93. Complexe tab_X[2048]; // nb_ech valeurs traitées
  94. Complexe tab_W[2048];
  95. bool tableau_w_plein = false;
  96.  
  97. uint8_t table_FREQ_midi[2000][1]; // [t][num_raie]
  98. double table_integration_amplitudes[83];// [code midi]
  99.  
  100. uint16_t table_histogramme_durees[35]; // [valeur_duree] = nb d'occurences
  101. uint16_t table_histogramme_midi[42]; // [num_midi] = nb d'occurences
  102. uint16_t table_histogramme_degre[12]; //[n°degre = 1..12] = nb d'occurences
  103.  
  104. double facteur_compression=1.0;
  105.  
  106. //double frequence1=400; // Hz
  107. //double frequence2=400; // Hz
  108. //double frequence3=100; // Hz
  109.  
  110. uint nb_etapes=10; // 10
  111. uint nb_ech = pow (2, nb_etapes); // nombre d'échantillons = 2 puissance(nb_etapes) ->2^10 = 1024
  112.  
  113. double table_modules_FFT[1024]; // = 2^10
  114.  
  115. double x_clic_ecran, y_clic_ecran;
  116.  
  117. int nb_tics;
  118. int nb_tics2=0;
  119. int d_barre2=1;
  120. int num_barre_en_cours=0; // permet de tracer l'avancement de l'exécution des notes du morceau
  121. long T_i=0; // variable GLOBALE
  122. int n_player=1;
  123. double seuil;
  124. double gain =1.0;
  125. int num_note_depart;
  126. int num_note_cliquee=0;
  127. int num_note_jouee=0;
  128. int nb_acc=0;
  129. int num_note_max=0;
  130. double memo_scroll_x=0;
  131. QDateTime temps_0; // départ du jeu des notes
  132. bool hamming = true;
  133. bool bourrage_de_zeros = true;
  134. bool second_Frq = false;
  135. bool bz = true;
  136. bool modul = false;
  137.  
  138. // type de mesure noté Ta/Tb (4/4, 3/2 ...)
  139. int8_t Ta = 4;
  140. int8_t Tb = 4;
  141.  
  142.  
  143. //QList<int> index_midi; // position x des notes midi sur le graphe FFT (à partir de midi=40)
  144. QList<QString> liste_couleurs;
  145. QList<ENR_FFT> liste_ENR_FFT; // liste de "notes" détectées (maximums de FFT)
  146. QList<NOTE> liste_NOTES;
  147. //QList<QString> noms_notes;
  148. QList<QString> gamme_chromatique;
  149. QList<QString> gamme_chromatique_GB;
  150.  
  151.  
  152. QFile file_wav; // fichier à analyser
  153. QFile file_dat; // datas du TAB_FRQ
  154.  
  155. QDir currentDir;
  156. QString base_Dir;
  157. QString default_Dir = "/home/";
  158. QString string_currentDir = default_Dir; // à priori; sera mis à jour lors de la lecture du fichier 'params.ini'
  159. QString string_currentFile;
  160. QString nom_fichier_in="";
  161.  
  162. QDataStream binStream1;
  163.  
  164. double duree_totale; // calculée dans la fonction 'decode_entete'
  165. double data_size; // calculée dans la fonction 'decode_entete'
  166.  
  167. bool wav_ok = false;
  168. bool dossier_de_travail_ok = false;
  169. bool data_nts_ok = false;
  170. bool rapide = false;
  171. bool etendre = true;
  172.  
  173. //bool visu_T = true;
  174. //bool visu_notesM = false;
  175. //bool visu_M; // echelle temporelle sous forme de mesures (temps forts, temps faibles)
  176. //bool visu_T; // echelle temporelle simple en 1/40s
  177.  
  178. char mode = 'T'; // T ou M
  179.  
  180. bool visu_freq = true;
  181. bool visu_ech_tps;
  182. //bool mode_select = false;
  183.  
  184. bool visu_duree_notes = true;
  185. bool visu_notes = true;
  186. bool visu_notes_auto = true;
  187. bool lecture_en_cours = false;
  188.  
  189. uint32_t offset_t;
  190. double zoom_x =1.0;
  191.  
  192.  
  193. MainWindow::MainWindow(QWidget *parent) :
  194. QMainWindow(parent)
  195. {
  196. setupUi(this);
  197. setWindowTitle("Transformée de Fourier Rapide FFT - version " + version);
  198.  
  199. //this->setGeometry(0,0, 1900, 1000);
  200. setWindowState(Qt::WindowMaximized);
  201. tabWidget_Global->setGeometry(0,0, 1920, 1280);
  202. tabWidget_Global->setCurrentIndex(0);
  203.  
  204. //-----------------------------------------------------
  205. // SCENE 1 - celle du haut ('Transformée de Fourier' ET 'partie échantillonée du signal')
  206.  
  207. scene1 = new QGraphicsScene(this);
  208. scene1->setBackgroundBrush(QColor(couleur_ecran));
  209. graphicsView1->setScene(scene1);
  210. graphicsView1->setGeometry(0, 0, 1900, 655); //( 0, 0, 1900, 700)
  211. graphicsView1->verticalScrollBar()->setValue(0);
  212.  
  213. calque_lignes_F_zero = new QGraphicsItemGroup();
  214. scene1->addItem(calque_lignes_F_zero);
  215.  
  216. calque_reticule1 = new QGraphicsItemGroup();
  217. scene1->addItem(calque_reticule1);
  218. afficher_titre_calque("Transformée de Fourier", 0, 0, calque_reticule1);
  219.  
  220. calque_trace_FFT = new QGraphicsItemGroup();
  221. scene1->addItem(calque_trace_FFT);
  222.  
  223. calque_trace_signal1 = new QGraphicsItemGroup();
  224. scene1->addItem(calque_trace_signal1);
  225.  
  226. calque_curseur = new QGraphicsItemGroup();
  227. scene1->addItem(calque_curseur);
  228.  
  229.  
  230. //-----------------------------------------------------
  231. // SCENE 2 - celle du bas ('Fichier Audio .wav')
  232.  
  233. scene2 = new QGraphicsScene(this);
  234. QBrush QB1("#222222");
  235. scene2->setBackgroundBrush(QB1); // couleur_ecran
  236.  
  237. graphicsView2->setScene(scene2);
  238. graphicsView2->setGeometry(0, 660, 1900, 200); // (0, 660, 1900, 200)
  239.  
  240. calque_trace_signal2 = new QGraphicsItemGroup();
  241. scene2->addItem(calque_trace_signal2);
  242.  
  243.  
  244. calque_reticule2 = new QGraphicsItemGroup();
  245. scene2->addItem(calque_reticule2);
  246. afficher_titre_calque("Fichier Audio .wav", 0, -80, calque_reticule2);
  247.  
  248. calque_encadrement1 = new QGraphicsItemGroup();
  249. scene2->addItem(calque_encadrement1);
  250.  
  251. calque_encadrement2 = new QGraphicsItemGroup();
  252. scene2->addItem(calque_encadrement2);
  253.  
  254. //-----------------------------------------------------
  255. // SCENE 3 - LISTE verticale NOTES sur l'onglet NOTES
  256. scene3 = new QGraphicsScene(this);
  257. scene3->setBackgroundBrush(QColor(couleur_ecran));
  258. graphicsView3->setScene(scene3);
  259.  
  260. calque_gradu_TAB_FRQ = new QGraphicsItemGroup();
  261. scene3->addItem(calque_gradu_TAB_FRQ);
  262.  
  263. //-----------------------------------------------------
  264. // SCENE 4 - ANALYSE sur l'onglet NOTES
  265.  
  266. scene4 = new QGraphicsScene(this);
  267. scene4->setBackgroundBrush(QColor(couleur_ecran));
  268. graphicsView4->setScene(scene4);
  269.  
  270. calque_grille_M = new QGraphicsItemGroup();
  271. scene4->addItem(calque_grille_M);
  272.  
  273. calque_grille_T = new QGraphicsItemGroup();
  274. scene4->addItem(calque_grille_T);
  275.  
  276. calque_TAB_FRQ = new QGraphicsItemGroup();
  277. scene4->addItem(calque_TAB_FRQ);
  278. afficher_titre_calque("Table Fréquences & notes", 200, 0, calque_TAB_FRQ);
  279.  
  280. calque_notes_manuelles = new QGraphicsItemGroup();
  281. scene4->addItem(calque_notes_manuelles);
  282.  
  283. calque_notes_auto = new QGraphicsItemGroup();
  284. scene4->addItem(calque_notes_auto);
  285.  
  286. calque_notes_jouee = new QGraphicsItemGroup();
  287. scene4->addItem(calque_notes_jouee);
  288.  
  289. calque_echelle_temporelle_T = new QGraphicsItemGroup();
  290. scene4->addItem(calque_echelle_temporelle_T);
  291.  
  292. calque_echelle_temporelle_M = new QGraphicsItemGroup();
  293. scene4->addItem(calque_echelle_temporelle_M);
  294.  
  295. //-----------------------------------------------------
  296. // SCENE 5 - Histogramme sur l'onglet NOTES
  297.  
  298. scene5 = new QGraphicsScene(this);
  299. scene5->setBackgroundBrush(QColor(couleur_ecran));
  300. graphicsView5->setScene(scene5);
  301. calque_histogramme = new QGraphicsItemGroup();
  302. scene5->addItem(calque_histogramme);
  303. //-----------------------------------------------------
  304.  
  305. Timer1 = new QTimer(this);
  306. connect(Timer1, SIGNAL(timeout()), this, SLOT(Tic1()));
  307.  
  308. Timer2 = new QTimer(this);
  309. connect(Timer2, SIGNAL(timeout()), this, SLOT(Tic2()));
  310.  
  311.  
  312. //noms_notes<<"La"<<"Si"<<"Do"<<"Ré"<<"Mi" <<"Fa"<<"Sol"<<"--"<<"--"; // <- A B C D E F G
  313. gamme_chromatique<<"Do"<<"Do#"<<"Ré"<<"Ré#"<<"Mi"<<"Fa"<<"Fa#"<<"Sol"<<"Sol#"<<"La"<<"La#"<<"Si";
  314.  
  315. //la gamme GB commence en principe par la lettre A (=La) mais pour simplifier ce programme
  316. //on la fait partir de C (=Do) comme la gamme FR...
  317. gamme_chromatique_GB<<"C"<<"C#"<<"D"<<"Eb"<<"E"<<"F"<<"F#"<<"G"<<"G#"<<"A"<<"A#"<<"B";
  318.  
  319. // dans la liste suivante, la première couleur (#0)->"#EF2929" est le rouge pour la note DO
  320. liste_couleurs <<"#EF2929"<<"#FF5C00"<<"#FCAF3E"<<"#FFE300"<<"#BFFF00"<<"#07F64F"
  321. <<"#16D298"<<"#16D2C4"<<"#00AEFF"<<"#1667D2"<<"#7C00FF"<<"#FF67EF"<<"#EEEEEC";
  322.  
  323. player1 = new QMediaPlayer;
  324. audioOutput1 = new QAudioOutput(this);
  325. player1->setAudioOutput(audioOutput1);
  326.  
  327. player2 = new QMediaPlayer;
  328. audioOutput2 = new QAudioOutput(this);
  329. player2->setAudioOutput(audioOutput2);
  330.  
  331. player3 = new QMediaPlayer;
  332. audioOutput3 = new QAudioOutput(this);
  333. player3->setAudioOutput(audioOutput3);
  334.  
  335. player4 = new QMediaPlayer;
  336. audioOutput4 = new QAudioOutput(this);
  337. player4->setAudioOutput(audioOutput4);
  338.  
  339. parametrages();
  340.  
  341. if(0)
  342. {
  343. //pour la phase de developpement
  344. afficher_titre_calque("Scene1", 100, 200, calque_trace_FFT);
  345. afficher_titre_calque("Scene2", 20, 20, calque_trace_signal2);
  346. afficher_titre_calque("Scene3", 10, 10, calque_gradu_TAB_FRQ);
  347. afficher_titre_calque("Scene4", 100, 100, calque_grille_T);
  348. afficher_titre_calque("Scene5", 20, 20, calque_histogramme);
  349. }
  350.  
  351. }
  352.  
  353.  
  354. void MainWindow::parametrages()
  355. {
  356. load_fichier_ini();
  357.  
  358. calcul_tableau_W();
  359. tracer_graduations_signal();
  360. tracer_graduations_FFT();
  361.  
  362. init_TW_1();
  363. init_TAB_FRQ();
  364. init_TAB_lst_notes();
  365. init_TW_type_M();
  366. init_Autres();
  367.  
  368. seuil = doubleSpinBox_seuil->value();
  369.  
  370. spinBox_offset->setValue(-2124); // 2124; +/- 22 pour un décalage de +/-1/4 de ton
  371. spinBox_echx->setValue(499);
  372. write_mode=0;
  373. on_Bt_mode_R_clicked();
  374.  
  375. visu_notes_auto = false;
  376. on_Bt_toggle_visu_notes_auto_clicked();
  377.  
  378. visu_notes = false;
  379. on_Bt_toggle_visu_notes_clicked();
  380.  
  381. on_tableWidget_type_M_cellClicked(2, 0);
  382.  
  383. spinBox_zoom_2->setValue(2);
  384. // Bt_jouer_tout->setStyleSheet("background-color: rgb(200, 200, 200);");
  385.  
  386. progressBar_1->setValue(0);
  387.  
  388. effacer_calque(scene1,calque_trace_FFT );
  389.  
  390. effacer_calque(scene1,calque_lignes_F_zero );
  391. effacer_calque(scene1,calque_encadrement1 );
  392. effacer_calque(scene1,calque_trace_signal1 );
  393. effacer_calque(scene1,calque_trace_FFT );
  394. effacer_calque(scene1,calque_curseur );
  395.  
  396. effacer_calque(scene2,calque_encadrement2 );
  397. effacer_calque(scene2, calque_trace_signal2 );
  398.  
  399. effacer_calque(scene4,calque_TAB_FRQ );
  400. effacer_calque(scene4, calque_notes_manuelles );
  401. effacer_calque(scene4, calque_notes_auto );
  402. effacer_calque(scene4, calque_notes_jouee );
  403. effacer_calque(scene4, calque_echelle_temporelle_T);
  404.  
  405. for(int i=0; i<35; i++) { table_histogramme_durees[i]=0; }
  406. effacer_calque(scene5, calque_histogramme );
  407.  
  408. on_Bt_RAZ_clicked();
  409.  
  410. T_i=0; // T_i : variable GLOBALE
  411. doubleSpinBox_dxb->setValue(2.5);
  412.  
  413. mode='M';
  414. on_Bt_toggle_grille_T_clicked();
  415. mode_grille_T();
  416. spinBox_nb_barres->setValue(40);
  417. effacer_calque(scene4, calque_grille_T);
  418. tracer_grille_T();
  419. checkBox_scrolling->setChecked(true);
  420.  
  421. }
  422.  
  423.  
  424. void MainWindow::init_TAB_FRQ()
  425. {
  426. frame_notes->setGeometry(0,0,1920,720);
  427.  
  428. graphicsView3->setGeometry(0, 30, 100, 730);
  429.  
  430. graphicsView4->setGeometry(100, 30, 2000, 730);
  431. graphicsView4->setEnabled(false); // empêche le recadrage auto par le contenu, mais disable le scroll manuel !
  432.  
  433. rectangle1 = new QGraphicsRectItem(0, 0, 2000, 670);
  434.  
  435. rectangle1->setPen(QColor(couleur_ligne));
  436. calque_TAB_FRQ->addToGroup(rectangle1);
  437. tracer_graduation_TAB_NOTES();
  438. tracer_grille_M();
  439. }
  440.  
  441.  
  442. void MainWindow::init_TAB_lst_notes()
  443. {
  444. tableWidget_lst_notes->setGeometry(1000, 30, 320, 201);
  445. QStringList liste_entetes1;
  446. liste_entetes1<<"num"<<"midi"<<"note"<<"n° barT"<< "n° barM)";
  447. tableWidget_lst_notes->setHorizontalHeaderLabels (liste_entetes1);
  448. tableWidget_lst_notes->setEditTriggers(QAbstractItemView::NoEditTriggers);
  449. }
  450.  
  451.  
  452.  
  453. void MainWindow::init_Autres()
  454. {
  455. // frame_1->setGeometry(1250, 865, 410, 131);
  456. // frame_1->setVisible(true);
  457. frame_2->setGeometry(10, 865, 970, 75);
  458. frame_3->setGeometry(1000, 865, 665, 121);
  459. frame_5->setGeometry(0, 760, 1920, 260);
  460. frame_6->setGeometry(10, 950, 901, 40);
  461.  
  462. graphicsView5->setGeometry(1460, 15, 440, 235); //225 histogrammes
  463. graphicsView5->setScene(scene5);
  464.  
  465. Bt_efface->setGeometry(915, 950, 60, 21);
  466. Bt_efface_2->setGeometry(1165, 0, 81, 26);
  467. pushButton_9->setGeometry(1290, 10, 31, 20);
  468. Bt_open_DIR_2->setGeometry(912, 40, 70, 26);
  469.  
  470. frame_8->setGeometry(1500, 740, 400, 30); // boutons "debut , < , > , fin"
  471. frame_9->setGeometry(1360, 789, 100, 70);
  472.  
  473. Bt_save_notes->setGeometry(831, 5, 151, 31);
  474. Bt_RAZ_general->setGeometry(1700, 900, 150, 50);
  475.  
  476. lineEdit_fichier_FREQ->setGeometry(1250, 0, 700, 22);
  477. progressBar_1->setGeometry(98, 4, 101, 18); //(1085, 3, 78, 18);
  478. lineEdit_fichier->setGeometry(380, 40, 530, 26);
  479. groupBox_2->setGeometry(380, 70, 241, 161);
  480. groupBox_3->setGeometry(630, 70, 351, 161);
  481.  
  482. Bt_dedoubleM->setGeometry(110, 5, 92, 26);
  483.  
  484. tracer_gradu_temporelle_signal_entree();
  485. tracer_graduations_signal();
  486. }
  487.  
  488.  
  489. void MainWindow::init_TW_type_M()
  490. {
  491. frame_4->setGeometry(210, 5, 140, 90);
  492. frame_7->setGeometry(210, 100, 140, 50);
  493.  
  494. tableWidget_type_M->setGeometry(5, 20, 40, 62);
  495. lineEdit_10->setGeometry(55, 30, 51, 26);
  496. lineEdit_11->setGeometry(55, 60, 51, 26);
  497. label_8->setGeometry(2, 2, 111, 20);
  498. label_39->setGeometry(108, 63, 40, 20);
  499.  
  500. //spinBox_barre_zero->setGeometry(5, 110, 61, 21);
  501. //spinBox_nb_barres->setGeometry(5, 130, 61, 21);
  502.  
  503.  
  504. QStringList liste_labels; // pour mettre directement dans la 1ere colonne (et pas en entêtes)
  505. liste_labels << "2/4" << "3/4" << "4/4";
  506. for(int n=0; n<3; n++) { tableWidget_type_M->setItem(0, n, new QTableWidgetItem (liste_labels[n])); }
  507. }
  508.  
  509.  
  510. void MainWindow::init_TW_1() // affi entete du fichier wav
  511. {
  512. tableWidget_1->setGeometry(700, 200, 600, 300);
  513. Bt_close_entete->setGeometry(1280, 200, 20, 20);
  514. tableWidget_1->setColumnCount(6);
  515. tableWidget_1->setColumnWidth(4, 120);
  516. tableWidget_1->setColumnWidth(5, 130);
  517.  
  518. tableWidget_1->setVisible(false);
  519. Bt_close_entete->setVisible(false);
  520.  
  521. QStringList liste_entetes;
  522. liste_entetes <<"FileTypeBlocID"
  523. <<"FileSize"
  524. <<"FileFormatID"
  525. <<"FormatBlocID"
  526. <<"BlocSize"
  527. <<"AudioFormat"
  528. <<"NbrCanaux"
  529. <<"Frequence"
  530. <<"ECH (BytePerSec)"
  531. <<"BytePerBloc"
  532. <<"BitsPerSample"
  533. <<"DataBlocID"
  534. <<"DataSize"
  535. <<"durée calculée";
  536.  
  537. tableWidget_1->setVerticalHeaderLabels(liste_entetes);
  538. }
  539.  
  540.  
  541. void MainWindow::load_fichier_ini()
  542. {
  543. QString line;
  544. int p1, p2, p3;
  545.  
  546. dossier_de_travail_ok = false; // à priori
  547. QFile file1(QDir::currentPath() + "/" + "params_FFT.ini"); // dans le dossier de l'exécutable (= QDir::currentPath() )
  548. if (file1.open(QIODevice::ReadOnly | QIODevice::Text))
  549. {
  550. QTextStream in(&file1);
  551. in.reset();
  552. while ( !in.atEnd() )
  553. {
  554. line = in.readLine();
  555. if (line.at(0) !='#')
  556. {
  557. if ((p1 = line.indexOf("<currentDir>")) != -1)
  558. {
  559. p2 = line.indexOf('>',p1);
  560. p3 = line.indexOf("</",p2);
  561. QString s1 = line.mid(p2+1, p3-p2-1);
  562. string_currentDir = s1;
  563. dossier_de_travail_ok = true;
  564. }
  565.  
  566. if ((p1 = line.indexOf("<currentFile>")) != -1)
  567. {
  568. p2 = line.indexOf('>',p1);
  569. p3 = line.indexOf("</",p2);
  570. QString s1 = line.mid(p2+1, p3-p2-1);
  571. string_currentFile = s1;
  572. }
  573. }
  574. }
  575. file1.close();
  576. }
  577. else
  578. {
  579. QString s1 = "fichier .ini non trouvé, je le crée (dans le dossier de l'executable)";
  580. QMessageBox msgBox; msgBox.setText(s1); msgBox.exec();
  581. base_Dir=QDir::currentPath() + "/";
  582. save_fichier_ini();
  583. dossier_de_travail_ok = false;
  584. }
  585. lineEdit_current_dir->setText(string_currentDir);
  586. lineEdit_fichier->setText(string_currentDir);
  587. }
  588.  
  589.  
  590.  
  591. QString calcul_couleur(double x) // x = 0.0 à 1.0 ; return: rouge->jaune->vert
  592. {
  593. QString coul_str ="#000000";
  594. QString coul_R_str="#000000";
  595. QString coul_V_str="#000000";
  596. int R, V; // rouge, vert
  597.  
  598. V= x * 255;
  599. R= 300 - (1.2 * V);
  600.  
  601. double coxh;
  602. // la formule suivante met le jaune en valeur (avec un cosinus hyperbolique)
  603. 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) )
  604.  
  605. R *= coxh/1.2;
  606. V *= coxh/1.2;
  607.  
  608. coul_R_str.setNum(R, 16); coul_R_str = "0" + coul_R_str; coul_R_str = coul_R_str.right(2);
  609. coul_V_str.setNum(V, 16); coul_V_str = "0" + coul_V_str; coul_V_str = coul_V_str.right(2);
  610. coul_str = coul_R_str + coul_V_str;
  611. coul_str = "#" + coul_str + "00";
  612. return coul_str; // de la forme "#AABB00" (rouge & vert en exa, (bleu à zéro, à traiter))
  613. }
  614.  
  615.  
  616.  
  617. int MainWindow::calcul_y_note(int midi) // en pixels sur la grille
  618. {
  619. int y =700 - ((midi-40) * 16); // voir 'tracer_graduation_TAB_NOTES()' pour l'espacement vertical
  620. return y;
  621. }
  622.  
  623.  
  624.  
  625. int MainWindow::calcul_hauteur_note(int mid) //'hauteur' au sens musical, gamme chromatique de 0 à 11
  626. {
  627. int h1 = mid;
  628.  
  629. while(h1>=12) {h1-=12;}
  630. while(h1<0) {h1+=12;}
  631. if (h1==12) {h1=0;}
  632. if ((h1<0) || (h1>(liste_couleurs.length()-1))) {h1 = 0;}
  633.  
  634. return h1; // h1 = 0..11
  635. }
  636.  
  637.  
  638.  
  639. QString MainWindow::nom_note(int mid)
  640. {
  641. QString s1;
  642.  
  643. int h1 = calcul_hauteur_note(mid);
  644. s1 = gamme_chromatique[h1];
  645. return s1;
  646. }
  647.  
  648.  
  649. QString MainWindow::nom_note_GB(int mid)
  650. {
  651. QString s1;
  652.  
  653. int h1 = calcul_hauteur_note(mid);
  654. s1 = gamme_chromatique_GB[h1];
  655. return s1;
  656. }
  657.  
  658.  
  659. QString MainWindow::nom_octave_GB(int mid)
  660. {
  661. QString octave;
  662. if((mid>=40)&&(mid < 48)) {octave = "2";}
  663. if((mid>=48)&&(mid < 60)) {octave = "3";}
  664. if((mid>=60)&&(mid < 72)) {octave = "4";}
  665. if((mid>=72)&&(mid < 90)) {octave = "5";}
  666. return octave;
  667. }
  668.  
  669.  
  670.  
  671. double freq_mid(int midi_i) // calcule la fréquence (en Hertz) d'une note à partir de son numéro midi
  672. {
  673. // https://fr.wikipedia.org/wiki/MIDI_Tuning_Standard
  674. double F, A;
  675. A=((double)midi_i-69.0)/12.0;
  676. F= 440 * powf(2,A);
  677. return F;
  678. }
  679.  
  680.  
  681. double calcul_id_midi(double freq_i) // complément de la fonction précédente ( double freq_mid(int midi_i) )
  682. {
  683. double id;
  684. id = 69.0 + 12.0 * log2(freq_i / 440.0);
  685. return id;
  686. }
  687.  
  688.  
  689. int MainWindow::calcul_num_midi(double x) // en fonction de la position horizontale dans le tableau d'affichage de la FFT
  690. {
  691. // on va détecter la note la plus proche de la position donnée
  692. // rappel : x=92 +(m-40) * 40.9 (voir la fonction : 'tracer_graduations_FFT()')
  693.  
  694. double dx;
  695. double xm;
  696.  
  697. for (int m=40; m<83; m++)
  698. {
  699. xm= 92.0 +(m-40) * 40.9;
  700. dx = xm-x;
  701. if (dx<0){dx=-dx;}
  702. if (dx < (40.9/2) )
  703. {
  704. encadrement_note(m);
  705. return m;
  706. }
  707. }
  708. return 0;
  709. }
  710.  
  711.  
  712. void MainWindow::play_note(int midi, int duree_i) // sortie audio; duree en nb de barres
  713. {
  714. QString s1, freq_txt;
  715.  
  716. calcul_hauteur_note(midi);
  717. s1.setNum(midi);
  718.  
  719. // fichiers audio comprenant une seule note chacun, voir dans le dossier "notes" sur le HDD
  720.  
  721.  
  722. int D;
  723. if (mode == 'M') {D = 20;} else {D = 40;}
  724.  
  725. // (duree_i < D) { s1="notes2/"+s1+".wav"; } // (notes2 = notes +10dB)
  726. if (checkBox_long->isChecked()) { s1="notes_longues/"+s1+".wav"; } // (notes2 = notes +10dB)
  727. else { s1="notes2/"+s1+".wav"; }
  728.  
  729.  
  730. if (n_player == 1) {player1->stop(); player1->setSource(QUrl::fromLocalFile(s1)); player1->play();}
  731. if (n_player == 2) {player2->stop(); player2->setSource(QUrl::fromLocalFile(s1)); player2->play();}
  732. if (n_player == 3) {player3->stop(); player3->setSource(QUrl::fromLocalFile(s1)); player3->play();}
  733. if (n_player == 4) {player4->stop(); player4->setSource(QUrl::fromLocalFile(s1)); player4->play();}
  734. if (n_player == 5) {player5->stop(); player5->setSource(QUrl::fromLocalFile(s1)); player5->play();}
  735. n_player++;
  736. if (n_player >= 4) {n_player = 1;} // voir ligne 4013 RAZ du n° player, à voir
  737. }
  738.  
  739.  
  740.  
  741.  
  742. void MainWindow::effacer_calque(QGraphicsScene *scene_i, QGraphicsItemGroup *calque_i)
  743. {
  744. foreach( QGraphicsItem *item, scene_i->items( calque_i->boundingRect() ) )
  745. {if( item->group() == calque_i ) { delete item; }}
  746. }
  747.  
  748.  
  749. MainWindow::~MainWindow()
  750. {
  751.  
  752. }
  753.  
  754.  
  755.  
  756. void MainWindow::Etiquette(int x, int y, int dx, QString s, QString coul_txt, QString coul_fond, QString coul_bord, QGraphicsItemGroup *calque_i )
  757. {
  758. // si dx = 0 -> la largeur sera fonction du nb de caractères
  759.  
  760. if (dx==0)
  761. {
  762. dx = 8 * (s.length()+1 );
  763. }
  764. rect1 = new QGraphicsRectItem(x, y+4, dx, 18);
  765. rect1->setPen(QColor(coul_bord)); // bordure
  766. rect1->setBrush(QColor(coul_fond)); // fond
  767. calque_i->addToGroup(rect1);
  768.  
  769. //texte
  770. GraphicsTextItem = new QGraphicsTextItem(s);
  771. GraphicsTextItem->setPos(x, y);
  772. GraphicsTextItem->setDefaultTextColor(coul_txt);
  773. calque_i->addToGroup(GraphicsTextItem);
  774. }
  775.  
  776.  
  777.  
  778. void MainWindow::tracer_graduations_FFT() // sur onglet 'Source wav'
  779. {
  780. double x=0;
  781. QString s1;
  782. int y_bas =450; // 350
  783.  
  784. // cadre
  785. rectangle1 = new QGraphicsRectItem(0, 0, 1900, y_bas);
  786. QPen pen1("#12FF00");
  787. rectangle1->setPen(pen1);
  788.  
  789. calque_reticule1->addToGroup(rectangle1);
  790.  
  791. s1 = "midi :"; // numéro midi
  792. GraphicsTextItem = new QGraphicsTextItem(s1);
  793. GraphicsTextItem->setDefaultTextColor("#FFFFFF");
  794. GraphicsTextItem->setPos(30, 20);
  795. // if(x<1900)
  796. {
  797. calque_reticule1->addToGroup(GraphicsTextItem);
  798. }
  799.  
  800. // positions des notes midi
  801. x= 96;
  802. for(int m=40; m<=83; m++)
  803. {
  804. ligne1 = new QGraphicsLineItem(x, 70, x, y_bas);
  805. ligne1->setPen(pen_reticule);
  806. calque_reticule1->addToGroup(ligne1);
  807.  
  808. s1.setNum(m); // numéro midi
  809. GraphicsTextItem = new QGraphicsTextItem(s1);
  810. GraphicsTextItem->setDefaultTextColor("#D3D7CF");
  811. GraphicsTextItem->setPos(x-15, 20);
  812. if(x<1900) {calque_reticule1->addToGroup(GraphicsTextItem); }
  813.  
  814. int h1 = calcul_hauteur_note(m);
  815.  
  816. s1 = " " + gamme_chromatique[h1]; // nom de la note
  817. GraphicsTextItem = new QGraphicsTextItem(s1);
  818. GraphicsTextItem->setDefaultTextColor(liste_couleurs[h1]);
  819. GraphicsTextItem->setPos(x-18, 40);
  820. if(x<1900) {calque_reticule1->addToGroup(GraphicsTextItem); }
  821.  
  822. x+=40.9; // espacement des graduation
  823. }
  824. }
  825.  
  826.  
  827. // voir fonction "void MainWindow::tracer_echelle_temps_TAB_NOTES()"
  828. // dx = 1000.0 * pas_echantillonage/256.0; // = 1000 * 24 /256 = 93.75
  829.  
  830.  
  831. double MainWindow:: calcul_pas_grille()
  832. {
  833. double pas = 0;
  834. if (mode == 'T')
  835. {
  836. pas = 1000.0 * pas_echantillonage/256.0 / 40.0 * zoom_x; // 1 barre toutes les 1/40 seconde
  837. }
  838. if (mode == 'M')
  839. {
  840. pas = (doubleSpinBox_dxb->value()) * 1000.0 * pas_echantillonage/256.0 / 40.0 * zoom_x;
  841. }
  842.  
  843. return pas;
  844. }
  845.  
  846. /*
  847. double MainWindow::calcul_pas_grille_M()
  848. {
  849.   double pas_grille_M = (spinBox_dxa->value()+doubleSpinBox_dxb->value()) * 1000.0 * pas_echantillonage/256.0 / 40.0 * zoom_x;
  850.   return pas_grille_M;
  851. }
  852. */
  853.  
  854. int MainWindow::calcul_tempo()
  855. {
  856. double dbar = doubleSpinBox_dxb->value(); // nb de barres de 1/40s séparant 2 barres de mesure
  857. double dt = (8.0/40.0) * dbar; // en s
  858. double nb_bpm = 60.0 / dt; // nb de barres / mn
  859. //double Tp = nb_bpm / 8.0;
  860. return int(nb_bpm);
  861. }
  862.  
  863.  
  864.  
  865. double MainWindow::calcul_x_barre(int n_barre)
  866. {
  867. // calcul de l'abscisse (en pixel) d'une barre de mesure
  868. double x =0;
  869. double x0;
  870.  
  871. int x0a = spinBox_x0a->value();
  872. double x0b = 80.0 + 10.0 * doubleSpinBox_x0b->value();
  873. x0b += 20.0 * x0a;
  874.  
  875. if (mode == 'T')
  876. {
  877. x0 = 80.0; // 100 à voir !
  878. x = x0 + double(n_barre) * calcul_pas_grille();
  879. }
  880. if (mode == 'M')
  881. {
  882. x = x0b + double(n_barre) * calcul_pas_grille();
  883. }
  884.  
  885. return x;
  886. }
  887.  
  888. /*
  889. double MainWindow::calcul_x_barre_M(int n_barre)
  890. {
  891.   double x = double(n_barre) * calcul_pas_grille_M();
  892.   return x;
  893. }
  894. */
  895.  
  896. void MainWindow::trace_1_barre_M(double x_i, QString couleur_i)
  897. {
  898. if(x_i<0) {return;} // pour ne pas décaler tout l'affichage
  899. QPen pen_i;
  900. pen_i.setColor(couleur_i);
  901. ligne1 = new QGraphicsLineItem(x_i, 0.0, x_i, 700.0);
  902. ligne1->setPen(pen_i);
  903. calque_grille_M->addToGroup(ligne1);
  904. }
  905.  
  906.  
  907. void MainWindow::tracer_grille_M()
  908. {
  909. effacer_calque(scene4, calque_echelle_temporelle_T);
  910. double x1;
  911. //int i;
  912. QString s1;
  913. // int nb = spinBox_nb_barres->value();
  914. // int n_zero = spinBox_barre_zero->value();
  915.  
  916. //int x0a = spinBox_x0a->value();
  917. //double x0b = 80.0 + 10.0 * doubleSpinBox_x0b->value();
  918. //x0b += 20.0 * x0a;
  919.  
  920. QString couleur1;
  921.  
  922. QString gris_clair = "#888888";
  923. QString gris_fonce = "#444444";
  924. QString gris_tres_fonce = "#222222";
  925. QString jaune = "#FFFF00";
  926. QString cyan = "#00FFFF";
  927.  
  928. int num_mesure=0;
  929. int us2=0; // une sur 2
  930. for(int n=-500; n<=500; n++)
  931. {
  932. // rappel : mesures type Ta/Tb dans le petit tableau 'Type Mesures'
  933. // 3/4 -> Ta=3 & Tb=4
  934. // 4/4 -> Ta=4 & Tb=4
  935.  
  936. x1 = calcul_x_barre(n);
  937.  
  938. couleur1 = gris_clair; // à priori
  939. if (n%(4*Ta) == 0)
  940. {
  941. if(x1<0){num_mesure=-1;}
  942. num_mesure++;
  943. if(num_mesure>0)
  944. {
  945. couleur1 = cyan; us2 =0;
  946.  
  947. s1.setNum(num_mesure);
  948. Etiquette(x1, 10, 0, s1, "#FFFFFF", "#000000", "#00FFFF", calque_echelle_temporelle_M ); // en haut
  949. }
  950. }
  951. us2++;
  952. if ((us2 %2)==0) { couleur1 = gris_fonce; }
  953. if(n==0){couleur1 = jaune;}
  954. trace_1_barre_M(x1, couleur1); // principale
  955. }
  956.  
  957. double Tempo = calcul_tempo();
  958. s1.setNum(Tempo);
  959. lineEdit_11->setText(s1); // BPM
  960.  
  961. // Etiquette(0, 0, 0, s1, "#FFFFFF", "#000000", "#FF00FF", calque_echelle_temporelle_T );
  962. // s1 = "BPM";
  963.  
  964. /*
  965.   GraphicsTextItem = new QGraphicsTextItem(s1);
  966.   GraphicsTextItem->setPos(45, 0);
  967.   GraphicsTextItem->setDefaultTextColor("#FF00FF");
  968.   calque_echelle_temporelle_T->addToGroup(GraphicsTextItem);
  969. */
  970.  
  971. }
  972.  
  973.  
  974. void MainWindow::tracer_grille_T()
  975. {
  976. //grille T sur l'onglet NOTES (barres verticales)
  977. QString s1;
  978. // QString bleu_clair = "#00AAFF";
  979. // QString jaune = "#FFFF00";
  980. QString gris_clair = "#CCCCCC";
  981. QString gris_fonce = "#777777";
  982. QString gris_tres_fonce = "#444444";
  983. QString couleur_i;
  984. QPen pen_i;
  985. double x_i1;
  986. //int num_mesure;
  987. int nb = spinBox_nb_barres->value();
  988. int n_zero = spinBox_barre_zero->value();
  989.  
  990. for(int n=0; n<=120*16; n++)
  991. {
  992. if (Ta<2) {Ta=2;}
  993. x_i1 = calcul_x_barre(n);
  994.  
  995. couleur_i = gris_tres_fonce; // à priori
  996.  
  997. if (((n-n_zero)%nb) == 0) { couleur_i ="#00AAAA"; } //couleur_i = gris_fonce;
  998. /*
  999.   if ( n%(4*Ta) == 0) // 1er temps fort de la mmesure
  1000.   {
  1001. // numérotation des mesures, en bas, chiffres jaunes
  1002.   num_mesure = n /Ta/4;
  1003.   s1.setNum(num_mesure);
  1004.   Etiquette(x_i1-0, 0, 650, s1, "#FFFF00", "#000000", "#0000FF", calque_grille_T);
  1005.   }
  1006. */
  1007. //if ( n%(4*m)== 0) {couleur_i = jaune;}
  1008.  
  1009. pen_i.setColor(couleur_i);
  1010. ligne1 = new QGraphicsLineItem(x_i1, 0.0, x_i1, 700.0); //100.0 pour test des 2 grilles ensemble
  1011. ligne1->setPen(pen_i);
  1012. calque_grille_T->addToGroup(ligne1);
  1013. }
  1014. }
  1015.  
  1016.  
  1017. void MainWindow::afficher_titre_calque(QString titre, int x, int y, QGraphicsItemGroup *calque_i)
  1018. {
  1019. GraphicsTextItem = new QGraphicsTextItem(titre);
  1020. GraphicsTextItem->setDefaultTextColor("#FFFFFF");
  1021. GraphicsTextItem->setPos(x, y);
  1022. calque_i->addToGroup(GraphicsTextItem);
  1023. }
  1024.  
  1025.  
  1026.  
  1027. void MainWindow::tracer_graduation_TAB_NOTES() // midi ; en colonne à gauche + noms des notes
  1028. {
  1029. // positions des notes midi
  1030. QString s1;
  1031. int y= 640; //640
  1032. for(int m=40; m<=82; m++)
  1033. {
  1034. //ligne1 = new QGraphicsLineItem(100, 0, 100, 350);
  1035. //ligne1->setPen(pen_reticule);
  1036. //calque_reticule1->addToGroup(ligne1);
  1037.  
  1038. s1.setNum(m); // numéro midi
  1039. GraphicsTextItem = new QGraphicsTextItem(s1);
  1040. GraphicsTextItem->setDefaultTextColor("#D3D7CF");
  1041. GraphicsTextItem->setPos(0, y);
  1042. if(y> -50) {calque_gradu_TAB_FRQ->addToGroup(GraphicsTextItem); }
  1043.  
  1044. int h1 = calcul_hauteur_note(m);
  1045. s1 = " " + gamme_chromatique[h1]; // nom de la note
  1046. GraphicsTextItem = new QGraphicsTextItem(s1);
  1047. GraphicsTextItem->setDefaultTextColor(liste_couleurs[h1]);
  1048. // GraphicsTextItem->setHtml("<div style='background-color:#666666;'>" + s1 + "</div>");
  1049.  
  1050. if (m==69) // La 440
  1051. {
  1052. rect3 = new QGraphicsRectItem(30, y+6, 40, 15);
  1053. QBrush br2;
  1054. QPen pen_i;
  1055. pen_i.setColor("#AAAAAA");
  1056. rect3->setPen(pen_i);
  1057. calque_gradu_TAB_FRQ->addToGroup(rect3);
  1058.  
  1059. }
  1060.  
  1061. GraphicsTextItem->setPos(30, y);
  1062. if(y > -50) {calque_gradu_TAB_FRQ->addToGroup(GraphicsTextItem); }
  1063.  
  1064. y-=16; // espacement des graduations
  1065. }
  1066. }
  1067.  
  1068.  
  1069.  
  1070. void MainWindow::tracer_graduations_signal() // sur le 1er onglet (Source.wav)
  1071. {
  1072. /*
  1073.   midi57 = 110Hz
  1074.   1/110Hz = 9ms -> delta x = 142-46 = 96px
  1075.   echelle x = 96/9 = 10.6 px/ms
  1076.   soit:
  1077.   10ms -> 106px
  1078. */
  1079. double x;
  1080. double nb_grad_max;
  1081. double intervalle; // séparant les graduations
  1082. QPen pen1;
  1083. // int num_x;
  1084. //QString sti;
  1085. // uint decal = 3; // leger decallage vertical pour ne pas masquer la trace
  1086.  
  1087. /*
  1088.   rectangle1 = new QGraphicsRectItem(5, 452, 1900, 200);
  1089.   pen1.setColor("#0073FF");
  1090.   rectangle1->setPen(pen1);
  1091.   calque_reticule1->addToGroup(rectangle1);
  1092.  
  1093.   ligne1 = new QGraphicsLineItem(10, 475, 1900, 475); // ligne horizontale
  1094.   pen1.setColor("#0073FF");
  1095.   ligne1->setPen(pen1);
  1096.   calque_reticule1->addToGroup(ligne1);
  1097. */
  1098. afficher_titre_calque("Partie échantillonée du signal", 0, 452, calque_reticule1);
  1099.  
  1100. // lignes verticales
  1101.  
  1102. intervalle = 106;
  1103. nb_grad_max = 18;
  1104.  
  1105. for (int i=0; i<=nb_grad_max; i++)
  1106. {
  1107. x = intervalle * i;
  1108.  
  1109. ligne1 = new QGraphicsLineItem(x, 452, x, 780);
  1110. ligne1->setPen(pen_reticule);
  1111. }
  1112.  
  1113. /*
  1114. // lignes horizontales
  1115.   intervalle = 55;
  1116.   nb_grad_max = 3;
  1117.   for (i=0; i<=nb_grad_max; i++)
  1118.   {
  1119.   y = 300 - intervalle * i;
  1120.  
  1121.   ligne1 = new QGraphicsLineItem(0, y, 1350, y);
  1122.   ligne1->setPen(pen_reticule);
  1123.   calque_reticule1->addToGroup(ligne1);
  1124.   }
  1125.   texte_mid = new QGraphicsTextItem("Silicium628");
  1126.   texte_mid->setDefaultTextColor(couleur_signature);
  1127.   texte_mid->setPos(5,5);
  1128.   calque_reticule1->addToGroup(texte_mid);
  1129.  */
  1130.  
  1131. scene1->addItem(calque_reticule1);
  1132. }
  1133.  
  1134.  
  1135.  
  1136. void MainWindow::tracer_gradu_temporelle_signal_entree()
  1137. {
  1138. // GRADUATION TEMPORELLE sur le signal d'entrée, en secondes; (scene2 sur onglet 'Source wav')
  1139.  
  1140. QString s1, s2;
  1141. int x=0;
  1142. int dy = 75;
  1143. int nb_s, nb_mn;
  1144. double pas =8;
  1145.  
  1146. for(int n=0; n<2400; n++) // 1200
  1147. {
  1148.  
  1149. if (n%10 == 0) { dy = 75; }
  1150. else if (n%5 == 0) {dy = 20; }
  1151. else {dy = 10;}
  1152.  
  1153. x = n *pas;
  1154. ligne1 = new QGraphicsLineItem(x, -dy, x, dy);
  1155. QPen P1("#AAAAAA");
  1156. ligne1->setPen(P1);
  1157. calque_reticule2->addToGroup(ligne1);
  1158.  
  1159. if (n%10 == 0)
  1160. {
  1161. nb_s = n/10;
  1162. s1.setNum(nb_s);
  1163. s1+="s";
  1164.  
  1165. if (nb_s>60)
  1166. {
  1167. nb_mn = nb_s/60;
  1168. nb_s -= nb_mn * 60;
  1169. s1.setNum(nb_s);
  1170. if (nb_s<10) {s1 = "0" +s1;}
  1171. s2.setNum(nb_mn);
  1172. s1 = s2 + ":" + s1;
  1173. }
  1174. GraphicsTextItem = new QGraphicsTextItem(s1);
  1175. GraphicsTextItem->setDefaultTextColor(couleur_texte);
  1176. GraphicsTextItem->setPos(x,55);
  1177. if(x<20000) {calque_reticule2->addToGroup(GraphicsTextItem); }//6000
  1178. }
  1179. }
  1180. }
  1181.  
  1182.  
  1183.  
  1184. void MainWindow::tracer_signal_complet() // totalité du fichier wav (dans le cadre du bas du 1er onglet)
  1185. {
  1186. uint8_t octet_n;
  1187. double R;
  1188.  
  1189. double offset_y = 0.0;
  1190. double echelle_y =doubleSpinBox_gain->value();
  1191. double echelle_x =0.2;
  1192.  
  1193. int x, y, memo_x, memo_y;
  1194. double min= 1000000.0;
  1195. double max=-1000000.0;
  1196.  
  1197. int pas = 10 * pas_echantillonage; // 240;
  1198.  
  1199. //rappel : duree_totale = data_size / 96000;
  1200.  
  1201. // le signal wav est échantillonné à l'origine à 96000 Bps (séréo 2*fois 48000 Bps)
  1202. // en ne prenant qu'un octet sur 24 on obtient 4000 Bps.
  1203. QString s1;
  1204.  
  1205. effacer_calque(scene2, calque_trace_signal2 );
  1206. segment_trace = new QGraphicsLineItem(0, offset_y, 512, offset_y);
  1207. QPen P1("#0000FF");
  1208. segment_trace->setPen(P1); //couleur_ligne
  1209. calque_trace_signal2->addToGroup(segment_trace);
  1210.  
  1211. x=0;
  1212. y=offset_y;
  1213.  
  1214. double n_max = data_size / pas;
  1215.  
  1216. long n;
  1217. long i=0;
  1218. // int j=0;
  1219.  
  1220. for(n=0; n<n_max; n+=10)
  1221. {
  1222. memo_x = x;
  1223. memo_y = y;
  1224. x = echelle_x * n;
  1225.  
  1226. octet_n = temp_data[i]; // canal 1
  1227. R = octet_n - 128; // pour ôter la composante continue propre au codage par des octets non signés
  1228. R *= echelle_y;
  1229. R *= doubleSpinBox_gain->value();
  1230. y=offset_y + R;
  1231.  
  1232. // recherche du mini-maxi:
  1233. if (y < min) {min = y;}
  1234. if (y > max) {max = y;}
  1235.  
  1236. //if (x<3000) //3000
  1237. {
  1238. segment_trace = new QGraphicsLineItem(memo_x ,memo_y, x, y);
  1239. QPen P1("#0055FF");
  1240. segment_trace->setPen(P1);
  1241. calque_trace_signal2->addToGroup(segment_trace);
  1242. }
  1243.  
  1244. i+= pas; // le nb de pas étant pair, on retombe toujours sur le même canal (droite ou gauche)
  1245. }
  1246. //scene1->addItem(calque_trace_signal);
  1247. s1.setNum(min);
  1248. //lineEdit_4->setText(s1);
  1249. s1.setNum(max);
  1250. // lineEdit_5->setText(s1);
  1251. }
  1252.  
  1253.  
  1254.  
  1255. void MainWindow::encadrement_signal(int x, int dx)
  1256. {
  1257. ligne1 = new QGraphicsLineItem(x, -80, x, 80);
  1258. ligne1->setPen(pen_encadrement);
  1259. calque_encadrement2->addToGroup(ligne1);
  1260.  
  1261. ligne1 = new QGraphicsLineItem(x+dx, -80, x+dx, 80);
  1262. ligne1->setPen(pen_encadrement);
  1263. calque_encadrement2->addToGroup(ligne1);
  1264.  
  1265. ligne1 = new QGraphicsLineItem(x, -80, x+dx, -80);
  1266. ligne1->setPen(pen_encadrement);
  1267. calque_encadrement2->addToGroup(ligne1);
  1268.  
  1269. ligne1 = new QGraphicsLineItem(x, 80, x+dx, 80);
  1270. ligne1->setPen(pen_encadrement);
  1271. calque_encadrement2->addToGroup(ligne1);
  1272. }
  1273.  
  1274.  
  1275.  
  1276. void MainWindow::encadrement_note(int n_midi) // par un rectangle
  1277. {
  1278. double x, dx, y, dy;
  1279.  
  1280. x=92 - 13 + ((double)n_midi-40.0) * 40.9;
  1281. dx=35;
  1282. y=16;
  1283. dy=50;
  1284.  
  1285. rectangle1 = new QGraphicsRectItem(x, y, dx, dy);
  1286. rectangle1->setPen(pen_encadrement);
  1287. calque_trace_FFT->addToGroup(rectangle1);
  1288. }
  1289.  
  1290.  
  1291.  
  1292. void MainWindow::tracer_signal_a_convertir() //partie à analyser s=f(t) (signal incident, pas le FFT); dans le cadre du haut
  1293. {
  1294. double offset_y = 575.0;
  1295. double echelle =5.0;
  1296. uint8_t octet_n;
  1297. double R;
  1298. double x, y, memo_x, memo_y;
  1299. double min= 1000000.0;
  1300. double max=-1000000.0;
  1301. QString s1;
  1302.  
  1303. effacer_calque(scene1,calque_trace_signal1 );
  1304. segment_trace = new QGraphicsLineItem(0, offset_y, 512, offset_y);
  1305. segment_trace->setPen(QColor(couleur_ligne));
  1306. calque_trace_signal1->addToGroup(segment_trace);
  1307.  
  1308. long n;
  1309. long i=0;
  1310. x=0;
  1311. y=offset_y;
  1312. int pas = 64;
  1313. for(n=0; n<nb_ech/2; n++)
  1314. {
  1315. memo_x = x;
  1316. memo_y = y;
  1317. x = echelle * n;
  1318.  
  1319. octet_n = temp_data[i]; // canal 1
  1320. R = octet_n - 128; // pour oter la composante continue propre au codage par des octets non signés
  1321. // R /= 10.0;
  1322. y=offset_y + R;
  1323.  
  1324. if (y < min) {min = y;}
  1325. if (y > max) {max = y;}
  1326.  
  1327. if (x<1800)
  1328. {
  1329. segment_trace = new QGraphicsLineItem(memo_x ,memo_y, x, y);
  1330. segment_trace->setPen(pen_trace1);
  1331. calque_trace_signal1->addToGroup(segment_trace);
  1332. }
  1333.  
  1334. i++; // pour sauter le canal B (le signal dans le fichier .wav est stéréo)
  1335. i+= pas;
  1336. }
  1337. //scene1->addItem(calque_trace_signal);
  1338. s1.setNum(min);
  1339. //lineEdit_4->setText(s1);
  1340. s1.setNum(max);
  1341. // lineEdit_5->setText(s1);
  1342. }
  1343.  
  1344.  
  1345.  
  1346.  
  1347. void MainWindow::tracer_segments_FFT() //scene1 sur le 1er onglet (Source wav)
  1348. {
  1349. double offset_x= spinBox_offset->value(); // ref -2146 ; +/- 22 pour un décalage de +/-1/4 de ton
  1350. double echelle_x =spinBox_echx->value(); // 498
  1351. double offset_y = 350.0;
  1352.  
  1353. uint n;
  1354. double module_FFT;
  1355. double x, y;
  1356. double memo_x[5]={0,0,0,0,0};
  1357. double memo_y[5]={0,0,0,0,0};
  1358. double x0, y0; // fréquence centrale trouvée comme résultat (points d'inflexions de la courbe)
  1359.  
  1360. double z=1.6;
  1361. //int x1=0;
  1362. //int x2=0;
  1363. int num_raie=0;
  1364. //bool note_validee = false;
  1365.  
  1366. QPen pen1("#12FF00");
  1367.  
  1368. if(!rapide)
  1369. {
  1370. effacer_calque(scene1,calque_trace_FFT );
  1371. effacer_calque(scene1,calque_lignes_F_zero );
  1372. }
  1373.  
  1374. x=0;
  1375. y = offset_y;
  1376. ENR_FFT enr_i;
  1377. for(n=0; n<nb_ech; n++)
  1378. {
  1379. //note_validee = false;
  1380. memo_x[0] = x;
  1381. memo_y[0] = y;
  1382. // x = offset_x + echelle_x * n; // echelle linéaire -> pas top
  1383. x = offset_x + echelle_x * log2((double)(n+1)); // échelle logarithmique afin que les tons soient équi-espacés
  1384.  
  1385. // ci-dessous 'a' est la partie réelle du complexe, et 'b' la partie imaginaire
  1386. // on calcule le module :
  1387. module_FFT = z * sqrt( tab_X[n].a * tab_X[n].a + tab_X[n].b * tab_X[n].b ); // z * racine(a²+b²)
  1388.  
  1389. y = module_FFT*10.0; // amplitude
  1390. y = offset_y - y; // offset et inversion du sens d'affichage because à l'écran les y croissent de haut en bas
  1391.  
  1392.  
  1393. // décale la pile memo_x
  1394. // puis mise en mémoire (empile) le dernier point
  1395. memo_x[4] = memo_x[3]; memo_y[4] = memo_y[3];
  1396. memo_x[3] = memo_x[2]; memo_y[3] = memo_y[2];
  1397. memo_x[2] = memo_x[1]; memo_y[2] = memo_y[1];
  1398. memo_x[1] = memo_x[0]; memo_y[1] = memo_y[0];
  1399. memo_x[0] = x;
  1400. memo_y[0] = y;
  1401.  
  1402. if((x>20) && (x<1900))
  1403. {
  1404. //y *=1.0;
  1405. if (x > -100)
  1406. {
  1407. if (!rapide)
  1408. {
  1409. segment_trace = new QGraphicsLineItem(memo_x[1] ,memo_y[1], x, y);
  1410. segment_trace->setPen(pen_trace2);
  1411. calque_trace_FFT->addToGroup(segment_trace);
  1412. }
  1413. }
  1414.  
  1415. // DETECTION DES NOTES primaires
  1416.  
  1417. //----------------------------------------------------------------------------------
  1418. // détection direct des points hauts (points d'inflexion de la courbe)
  1419. // on pourrait calculer la dérivée de la courbe, et détecter les valeurs pour lesquelles elle s'annule
  1420. // problème : peut ne pas détecter si le sommet est un pic (discontinuité)
  1421. //----------------------------------------------------------------------------------
  1422.  
  1423. // Autre méthode :
  1424. // détection de 2 doublets de points de part et d'autre, montants puis descendant
  1425. // le sommet se situe donc entre les 2 doublets
  1426.  
  1427. // la DETECTION s'effectue ICI
  1428.  
  1429. // ATTENTION : la ligne qui suit détermine la stratégie utilisée et son paramétrage influe grandement
  1430. // sur la qualité du résultat.
  1431. // on doit pouvoir l'améliorer mais attention : toujours expérimenter sur des données réelles (air de musique)
  1432. // avant de valider la moindre "améloration".
  1433.  
  1434. //if ( (memo_y[3] - memo_y[2]) >0.5 && (memo_y[1] - memo_y[2]) >0.5 )
  1435. if ( (memo_y[3] - memo_y[2]) > 1.1 && (memo_y[1] - memo_y[2]) > 1.1 )
  1436. {
  1437. x0 = memo_x[2]; // point d'inflexion probable
  1438. y0 = memo_y[2];
  1439.  
  1440. if( !rapide) // donc pas d'affichage en mode rapide
  1441. {
  1442. ligne1 = new QGraphicsLineItem(x0, 60, x0, 350);
  1443. ligne1->setPen(pen1); // BLEU
  1444. calque_lignes_F_zero->addToGroup(ligne1);
  1445. ligne1 = new QGraphicsLineItem(x0, T_i-1, x0, T_i+1); // T_i : variable GLOBALE
  1446. ligne1->setPen(pen1);
  1447. }
  1448.  
  1449. int m0 = 0;
  1450. m0 = calcul_num_midi(x0);
  1451. enr_i.t = T_i; // T_i : variable GLOBALE
  1452. enr_i.num = num_raie;
  1453. enr_i.midi = m0;
  1454. enr_i.amplitude = y0;
  1455.  
  1456. // tracer sur tableau fréquences
  1457. if(num_raie<10) // 6
  1458. {
  1459. liste_ENR_FFT << enr_i; // memorisation ; donc 5 notes max pour un temps (T_i) donné
  1460. // les notes ayant même T_i seront considérées comme simultanées (accord)
  1461. tracer_1enr(enr_i); // sur le 2eme onglet (NOTES)
  1462. }
  1463.  
  1464. num_raie++;
  1465. }
  1466. }
  1467. }
  1468. T_i++; // variable GLOBALE
  1469.  
  1470.  
  1471.  
  1472. // T_i est ici incrémenté à chaque appel de la fonction
  1473. // sachant que chaque appel de cette fonction analyse 1024 échantillons du signal.
  1474. // et que chaque échantillon représente une durée = 0.5ms du signal d'origine
  1475. // donc T_i est (virtuellement) incrémenté toutes les 1024*0.5ms = 512ms;
  1476. // pourquoi 'virtuellement' ? parce que chaque échantillon "REPRESENTE" une durée de 0.5 ms
  1477. // mais ne "DURE PAS" 0.5ms; L'analyse s'effectue à très haute vitesse sur un signal pré-échantilloné.
  1478. // de quel chapeau sort ce 0.5ms? Voir la fontion 'void MainWindow::remplir_tableau_echantillons_signal()'
  1479.  
  1480. num_raie=0;
  1481. //affi_notes();
  1482.  
  1483. }
  1484.  
  1485.  
  1486. void MainWindow::tracer_echelle_temps_TAB_NOTES() //en secondes (scene4 sur l'onglet NOTES)
  1487. {
  1488.  
  1489. QString s1;
  1490. double x, x0, dx;
  1491. int offset_x = 80;
  1492. int y0 = 620;
  1493. double nbs;
  1494.  
  1495. //effacer_calque(scene4, calque_echelle_temporelle_T);
  1496.  
  1497. if (visu_ech_tps == true) {y0 = 0;} // grandes lignes
  1498. for(int n=0; n<=120; n++)
  1499. {
  1500. x0 = 10.0 * doubleSpinBox_T0->value();
  1501. dx = 1000.0 * pas_echantillonage/256.0; // = 1000 * 24 /256 = 93.75
  1502.  
  1503. x = x0 + dx * zoom_x * (double)n;
  1504.  
  1505. ligne1 = new QGraphicsLineItem(offset_x + x, y0-5, offset_x + x, 650);
  1506. QPen pen1;
  1507. pen1.setColor("#00FF00"); //
  1508. ligne1->setPen(pen1);
  1509. calque_echelle_temporelle_T->addToGroup(ligne1);
  1510.  
  1511. nbs = (double) n;
  1512. s1.setNum(nbs, 10, 0); // base 10, 0 décimale
  1513. s1 += "s";
  1514.  
  1515. Etiquette(offset_x + x, 630, 0, s1, "#FFFFFF", "#000000", "#00FF00", calque_echelle_temporelle_T); // en bas
  1516. }
  1517. }
  1518.  
  1519.  
  1520.  
  1521. void MainWindow::tracer_1enr(ENR_FFT enr_i) // c.a.d. ayant la durée élémentaire T_i = 256 ms
  1522. {
  1523. // "notes" primaires -> calque 'calque_TAB_FRQ' sur le 2eme onglet (NOTES)
  1524.  
  1525. int T2;
  1526. //uint8_t num_raie;
  1527. uint8_t m0;
  1528. double yH, yL;
  1529. double y0, y2, dy, dy2;
  1530. uint16_t v; // v comme 'vertical'
  1531. double offset_y = 350.0;
  1532. QString couleur1;
  1533.  
  1534. T2 = zoom_x * enr_i.t;
  1535.  
  1536. m0 = enr_i.midi;
  1537. y0 = enr_i.amplitude;
  1538.  
  1539. if (checkBox_flitrer->isChecked() && (m0 != spinBox_filtre->value())) {return;}
  1540.  
  1541. v= 700 - (16 * (m0-40) );
  1542. y2 = -y0 + offset_y;
  1543. dy = y2/30.0; // 40
  1544. //dy = y2/10;
  1545. //dy=dy*dy; // pour un meilleur affichage ; A VOIR !!!!
  1546. //dy /=5.0;
  1547. dy *= gain;
  1548.  
  1549. if (dy > 200) {dy = 200;} // bridage amplitude max
  1550.  
  1551. if(v > 730) {return;}
  1552.  
  1553. if (dy > seuil)
  1554. {
  1555. dy2 = dy;
  1556. if (checkBox_norm->isChecked()) {dy2=5; } // bride la hauteur des tirets
  1557. double x = 80.0 + T2;
  1558. yH = v+dy2/2;
  1559. yL = v-dy2/2;
  1560. // rabotage pour éviter le scrolling de l'affichage:
  1561. if(yH > 730) {yH = 730;}
  1562. if(yL <0) {yH = 0;}
  1563.  
  1564. //ligne1 = new QGraphicsLineItem(x, yL, x, yH);
  1565.  
  1566. rectangle1 = new QGraphicsRectItem(x, v-dy2/2, zoom_x-2, dy2);
  1567. int h1 = calcul_hauteur_note(m0);
  1568.  
  1569. if (checkBox_norm->isChecked()) // utilise une couleur en fonction de l'amplitude du signal
  1570. {
  1571. double dy3 = dy/ 20;
  1572. if (dy3 > 0.8) {dy3 = 0.8;}
  1573. couleur1 = calcul_couleur(dy3);
  1574. }
  1575. else
  1576. {
  1577. // utilise une couleur en fonction de la fréquence ('hauteur') de la note
  1578. couleur1 = liste_couleurs[h1];
  1579. }
  1580.  
  1581. QPen pen1;
  1582. pen1.setColor(couleur1);
  1583.  
  1584. rectangle1->setPen(pen1);
  1585. rectangle1->setBrush(QColor(couleur1));
  1586.  
  1587. QBrush br1;
  1588. br1.setStyle(Qt::SolidPattern);
  1589. br1.setColor(couleur1);
  1590. rectangle1->setBrush(br1);
  1591. calque_TAB_FRQ->addToGroup(rectangle1); // lent !
  1592.  
  1593. graphicsView1->verticalScrollBar()->setValue(0);
  1594. }
  1595. }
  1596.  
  1597.  
  1598. void MainWindow::detection_notes_auto() // notes secondaires (affi par petits cercles colorés)
  1599. {
  1600. ENR_FFT enr_i;
  1601.  
  1602. int T2;
  1603. uint32_t n_max;
  1604. uint8_t m0;
  1605. double A1;
  1606. double x, y, y0, y2;
  1607. double memo_x = 0;
  1608. double offset_y = 350.0;
  1609. //double decalage;
  1610. QString couleur1;
  1611. QPen pen1;
  1612. pen1.setWidth(1);
  1613.  
  1614. double pas_grille = doubleSpinBox_dxb->value()/2.0 * zoom_x;
  1615. double offset_x = 10 * doubleSpinBox_x0b->value() + spinBox_d_barres->value() * pas_grille;
  1616.  
  1617. n_max = liste_ENR_FFT.size();
  1618.  
  1619. if (n_max == 0) return;
  1620.  
  1621. tableWidget_type_M->setCurrentCell(2, 0);
  1622. on_tableWidget_type_M_cellClicked(2, 0);
  1623.  
  1624. liste_NOTES.clear();
  1625.  
  1626. for(int n=0; n<83; n++)
  1627. {
  1628. table_integration_amplitudes[n] =0; // RAZ
  1629. }
  1630. calque_notes_auto->setPos(0, 0);
  1631.  
  1632. for(uint32_t n=0; n<n_max-1; n++)
  1633. {
  1634. enr_i = liste_ENR_FFT[n];
  1635. T2 = zoom_x * enr_i.t;
  1636.  
  1637. m0 = enr_i.midi;
  1638.  
  1639. y0 = enr_i.amplitude;
  1640. y2 = -y0 + offset_y;
  1641.  
  1642. y = 700 - (16 * (m0-40) );
  1643. A1 = y2/10.0; // 40
  1644. A1 *= gain;
  1645.  
  1646. // table_integration_amplitudes[m0] /= 2.0; // usure volontaire
  1647. if(A1<20)
  1648. {
  1649. table_integration_amplitudes[m0] = 0; // ce qui est débloquant
  1650. }
  1651.  
  1652. if (A1 > 20) // 30
  1653. {
  1654. x = 80.0 + T2 -8; // le -8 pour décaler dans le temps (de la durée de l'intégration)
  1655.  
  1656. //intégration temporelle des amplitudes en vue de valider en tant que note
  1657. if(table_integration_amplitudes[m0] >=0) // si pas de blocage en cours
  1658. {
  1659. table_integration_amplitudes[m0] += A1;
  1660. }
  1661.  
  1662. if (table_integration_amplitudes[m0] > 200.0)
  1663. {
  1664. // la NOTE est comfirmée, on va l'ajouter à la fin de la liste des notes
  1665. // Mais il faut aussi empêcher des re-détections multiples lorsque l'amplitute du signal ne décroit
  1666. // que progressivement. Pour cela on attribue la valeur -1 dans la table d'intégration
  1667. // pour le n° midi de la note, ce qui sera bloquant.
  1668. // Le déblocage se produira lorsque l'amplitude du signal concernant cette note
  1669. // sera descendu en dessous d'un certain niveau.
  1670.  
  1671. table_integration_amplitudes[m0] = -1; //ce qui est bloquant (voir 10 lignes +haut)
  1672.  
  1673. int h1 = calcul_hauteur_note(m0); //'hauteur' au sens musical, gamme chromatique
  1674. couleur1 = liste_couleurs[h1];
  1675. pen1.setColor(couleur1);
  1676.  
  1677. // int delta_x = int(x - memo_x);
  1678. memo_x = x ;
  1679.  
  1680. ellipse1 = new QGraphicsEllipseItem(x-A1/2, y-A1/2, A1, A1);
  1681. ellipse1->setPen(pen1);
  1682. calque_notes_auto->addToGroup(ellipse1); // cercle coloré
  1683. //on va ajouter la note à la liste des notes
  1684.  
  1685. int n_barre = num_barre(x);
  1686.  
  1687. if (n_barre != -1000) {ajout_note(m0, n_barre, 0);}
  1688.  
  1689. // ellipse1 = new QGraphicsEllipseItem(x, v-1, 2, 2);
  1690. // pen1.setColor("#FFFFFF");
  1691. // ellipse1->setPen(pen1);
  1692. // calque_notes_auto->addToGroup(ellipse1); // point blanc
  1693. }
  1694. }
  1695. // voir la fonction -> 'tracer_1enr(ENR_FFT enr_i)' pour le cadrage
  1696.  
  1697. }
  1698. calque_notes_auto->setPos(offset_x, 0);
  1699. mode='M';
  1700. on_Bt_toggle_grille_T_clicked(); // basculera à T;
  1701. doubleSpinBox_vitesse->setValue(30);
  1702. }
  1703.  
  1704.  
  1705. void MainWindow::retracer_TAB_FRQ()
  1706. {
  1707. ENR_FFT enr_i;
  1708. uint16_t n_max = liste_ENR_FFT.length();
  1709. if (n_max == 0) return;
  1710. //effacer_calque(scene1,calque_trace_FFT );
  1711. tracer_graduation_TAB_NOTES();
  1712.  
  1713. calque_TAB_FRQ->setPos(0, 0);
  1714. for(uint16_t n=0; n<n_max-1; n++)
  1715. {
  1716. enr_i = liste_ENR_FFT[n];
  1717. tracer_1enr(enr_i);
  1718. }
  1719.  
  1720. double pas_grille = doubleSpinBox_dxb->value()/2.0 * zoom_x;
  1721. double offset_x = 10 * doubleSpinBox_x0b->value() + spinBox_d_barres->value() * pas_grille;
  1722. calque_TAB_FRQ->setPos(offset_x, 0);
  1723. }
  1724.  
  1725.  
  1726.  
  1727. void RAZ_tableau_echantillons()
  1728. {
  1729. uint n;
  1730. for(n=0; n < nb_ech; n++)
  1731. {
  1732. ech[n].a = 0; // partie reelle
  1733. ech[n].b = 0; // partie imaginaire
  1734. }
  1735. }
  1736.  
  1737.  
  1738.  
  1739. uint bit_reversal(uint num, uint nb_bits)
  1740. {
  1741. uint r = 0, i, s;
  1742. if ( num > (1<< nb_bits)) { return 0; }
  1743.  
  1744. for (i=0; i<nb_bits; i++)
  1745. {
  1746. s = (num & (1 << i));
  1747. if(s) { r |= (1 << ((nb_bits - 1) - i)); }
  1748. }
  1749. return r;
  1750. }
  1751.  
  1752.  
  1753.  
  1754. void MainWindow::bit_reverse_tableau_X()
  1755. {
  1756. // recopie les échantillons en les classant dans l'ordre 'bit reverse'
  1757. uint n,r;
  1758.  
  1759. for(n=0; n < nb_ech; n++) // nb d'échantillons
  1760. {
  1761. r=bit_reversal(n,nb_etapes);
  1762. tab_X[n] = ech[r];
  1763. }
  1764. }
  1765.  
  1766. void MainWindow::calcul_tableau_W()
  1767. {
  1768. if (tableau_w_plein == true) {return;}
  1769. // calcul et memorisation dans un tableau des twiddle factors (facteurs de rotation)
  1770. uint n;
  1771. double x;
  1772. for(n=0; n<(nb_ech/2-1); n++)
  1773. {
  1774. x=2.0*M_PI * n / nb_ech;
  1775.  
  1776. tab_W[n].a = cos(x); // partie reelle
  1777. tab_W[n].b = -sin(x); // partie imaginaire
  1778. }
  1779. tableau_w_plein = true;
  1780. }
  1781.  
  1782.  
  1783. void MainWindow::calcul_FFT()
  1784. {
  1785. Complexe produit; // voir la classe "Complexe" : complexe.h et complexe.ccp
  1786.  
  1787. uint etape, e1, e2, li, w, ci;
  1788. uint li_max=nb_ech;
  1789. e2=1;
  1790.  
  1791. for (etape=1; etape<=nb_etapes; etape++)
  1792. {
  1793. e1=e2; //(e1 évite d'effectuer des divisions e2/2 plus bas)
  1794. e2=e2+e2; // plus rapide que *=2
  1795.  
  1796. for (li=0; li<li_max; li+=1)
  1797. {
  1798. ci=li & (e2-1); // ET bit à bit
  1799. if (ci>(e1-1))
  1800. {
  1801. w=li_max/e2*(li & (e1 -1)); // ET bit à bit calcul du numéro du facteur de rotation W
  1802. 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"
  1803. tab_X[li]=tab_X[li-e1] - produit; // concerne la ligne basse du croisillon; soustraction complexe; Voir "complexe.cpp"
  1804. tab_X[li-e1]=tab_X[li-e1] + produit; // concerne la ligne haute du croisillon; addition complexe; Voir "complexe.cpp"
  1805. }
  1806. }
  1807. }
  1808. }
  1809.  
  1810.  
  1811. void MainWindow::Tic1() // pour l'analyse de Fourier en vitesse lente
  1812. {
  1813.  
  1814. nb_tics++;
  1815. if(nb_tics > 4000)
  1816. {
  1817. Timer1->stop();
  1818. nb_tics=0;
  1819. }
  1820. else
  1821. {
  1822. spinBox_4->setValue( spinBox_4->value() +1); //voir la fonction 'on_spinBox_4_valueChanged()'
  1823. Timer1->setInterval(2); // à voir
  1824. }
  1825. }
  1826.  
  1827.  
  1828. void MainWindow::trace_time_line()
  1829. {
  1830. double x_note, x, dx;
  1831.  
  1832. if (num_note_jouee < 1) {return;}
  1833. if(mode=='T') { x_note = calcul_x_barre(liste_NOTES[num_note_jouee-1].n_barreT); }
  1834. if(mode=='M') { x_note = calcul_x_barre(liste_NOTES[num_note_jouee-1].n_barreM); }
  1835. dx = calcul_pas_grille();
  1836. x = x_note + double(num_barre_en_cours) * dx;
  1837.  
  1838.  
  1839. int midi_i = liste_NOTES[num_note_jouee-1].midi;
  1840. int y = calcul_y_note(midi_i) ;
  1841.  
  1842. int h1 = calcul_hauteur_note(midi_i);
  1843. QString couleur1 = liste_couleurs[h1];
  1844.  
  1845. QPen pen1;
  1846. pen1.setColor(couleur1);
  1847. pen1.setWidth(2);
  1848.  
  1849. //ellipse1 = new QGraphicsEllipseItem(x, y, 2, 2) ;
  1850. //ellipse1->setPen(pen1);
  1851. //ellipse1->setBrush(blanc);
  1852. //calque_notes_jouee->addToGroup(ellipse1);
  1853.  
  1854. rectangle1 = new QGraphicsRectItem(x, y, dx, 2) ;
  1855. rectangle1->setPen(pen1);
  1856. calque_notes_jouee->addToGroup(rectangle1);
  1857. }
  1858.  
  1859.  
  1860.  
  1861. void MainWindow::Tic2() // pour jouer le morceau (la liste des notes détectées)
  1862. {
  1863. double dt, vts;
  1864. int deltaT;
  1865.  
  1866. num_barre_en_cours++;
  1867.  
  1868. trace_time_line();
  1869.  
  1870. nb_tics2++;
  1871. if(nb_tics2 >= d_barre2) // d_barre2 variable globale
  1872. {
  1873. nb_tics2=0;
  1874. num_barre_en_cours=-1;
  1875. d_barre2 = joue_1_note_de_la_liste(); // nb de barres temporelles séparant la note avec celle qui suit
  1876. }
  1877.  
  1878. vts = 2.0 * doubleSpinBox_vitesse->value();
  1879. dt = 20.0; // * (double)d_barre;
  1880. dt *= (100.0 / vts);
  1881. if(mode == 'M') {dt *= 4.0;}
  1882. deltaT = (int) dt;
  1883.  
  1884. if (d_barre2>0) {Timer2->setInterval(deltaT);} else {Timer2->setInterval(0);}
  1885.  
  1886. }
  1887.  
  1888.  
  1889. void clear_temp_data()
  1890. {
  1891. for(int i=0; i<2000000; i++)
  1892. {
  1893. temp_data[i]=0;
  1894. }
  1895.  
  1896. }
  1897.  
  1898.  
  1899. void MainWindow::on_Bt_load_wav_clicked()
  1900. {
  1901. open_fichier_wav(); // associe le binStream1 au fichier wav
  1902. decode_entete();
  1903.  
  1904. MainWindow::setCursor(Qt::WaitCursor);
  1905. liste_ENR_FFT.clear();
  1906. effacer_calque(scene1,calque_trace_signal1 );
  1907.  
  1908. effacer_calque(scene1, calque_trace_FFT);
  1909. clear_temp_data();
  1910. garnis_temp_data(0);
  1911.  
  1912. ajustement_gain();
  1913. // donne accès à la totalité (2MB) du fichier wav (dans le 'temp_data')
  1914. tracer_signal_complet();
  1915. MainWindow::setCursor(Qt::ArrowCursor);
  1916. tracer_gradu_temporelle_signal_entree();
  1917.  
  1918. frame_3->setVisible(true);
  1919. Bt_scan_auto->setVisible(true);
  1920. checkBox_rapide->setVisible(true);
  1921. }
  1922.  
  1923.  
  1924.  
  1925. /*
  1926.   char RIFF[4]; (4 bytes)
  1927.   unsigned long ChunkSize; (4 bytes)
  1928.   char WAVE[4]; (4 bytes)
  1929.   char fmt[4]; (4 bytes)
  1930.   unsigned long Subchunk1Size; (4 bytes)
  1931.   unsigned short AudioFormat; (2 octets)
  1932.   unsigned short NumOfChan; (2 octets)
  1933.   unsigned long SamplesPerSec; (4 bytes)
  1934.   unsigned long bytesPerSec; (4 bytes)
  1935.   unsigned short blockAlign; (2 octets)
  1936.   unsigned short bitsPerSample; (2 octets)
  1937.   char Subchunk2ID[4]; (4 bytes)
  1938.   unsigned long Subchunk2Size; (4 bytes)
  1939.  
  1940.   TOTAL 44 octets
  1941. */
  1942.  
  1943.  
  1944. QString separ_milliers(uint n) // séparation des miliers par des espaces
  1945. {
  1946. QString s1, s1a, s1b, s1c;
  1947. s1.setNum(n);
  1948. int L= s1.length(); s1a = s1.right(3); s1b = s1.mid(L-6, 3); s1c = s1.mid(L-9, 3);
  1949. return (s1c+" "+s1b+" "+s1a);
  1950. }
  1951.  
  1952.  
  1953.  
  1954. void MainWindow::save_fichier_ini()
  1955. {
  1956. QFile file1(QDir::currentPath() + "/" + "params_FFT.ini"); // dans le dossier de l'exécutable
  1957. if (file1.open(QIODevice::WriteOnly | QIODevice::Text))
  1958. {
  1959. //int p1= string_currentFile.lastIndexOf('/');
  1960. //string_currentDir = string_currentFile.left(p1);
  1961.  
  1962. QTextStream out(&file1);
  1963.  
  1964. out << "# Ce fichier est crée automatiquement par le programme";
  1965. out << '\n';
  1966. out << "#";
  1967. out << '\n';
  1968. out << "# chemins:";
  1969. out << '\n';
  1970. out << "<currentDir>" << string_currentDir << "</currentDir>";
  1971. out << '\n';
  1972. out << "<currentFile>" << string_currentFile << "</currentFile>";
  1973. }
  1974. file1.close();
  1975. }
  1976.  
  1977.  
  1978.  
  1979. void MainWindow::open_fichier_wav()
  1980. {
  1981. // Le fichier .wav comprend un signal audio stéréo échantilloné à 48 000 octets/seconde pour chaque canal
  1982. // ce qui fait 96000 octets/s pour l'ensemble du signal stéréo
  1983.  
  1984. string_currentFile = QFileDialog::getOpenFileName(this, tr("Ouvrir Fichier wav..."), string_currentDir,
  1985. tr("Fichiers wav (*.wav);;All Files (*)"));
  1986. if (string_currentFile != "")
  1987. {
  1988. save_fichier_ini();
  1989. }
  1990. lineEdit_1->setText(string_currentFile);
  1991.  
  1992. int p1= string_currentFile.lastIndexOf('/');
  1993. string_currentDir = string_currentFile.left(p1);
  1994. lineEdit_current_dir->setText(string_currentDir);
  1995.  
  1996. save_fichier_ini();
  1997.  
  1998. file_wav.setFileName(string_currentFile);
  1999. if (!file_wav.open(QIODevice::ReadOnly))
  2000. {
  2001. wav_ok = false;
  2002. Bt_scan_auto->setStyleSheet("background-color: rgb(200, 200, 200);");
  2003. return ;
  2004. }
  2005. else
  2006. {
  2007. binStream1.setDevice(&file_wav); // accès à la totalité du fichier wav
  2008. wav_ok = true;
  2009. Bt_scan_auto->setStyleSheet("background-color: rgb(0, 255, 0);"); // vert
  2010.  
  2011. }
  2012. // le fichier reste ouvert pour toute la session
  2013. }
  2014.  
  2015.  
  2016.  
  2017.  
  2018. void MainWindow::decode_entete()
  2019. {
  2020. // ============ [Bloc de déclaration d'un fichier au format WAVE] ============
  2021.  
  2022. if (! wav_ok) {return;}
  2023. QString s3, s4, s5, fileSize1;
  2024. uint8_t x, nb_canaux;
  2025. double tot1, tot2, tot3, tot4;
  2026.  
  2027.  
  2028. binStream1.device()->seek(0); // retour de la lecture au début du fichier
  2029. binStream1.readRawData (temp_entete, 100); // lecture entete du fichier
  2030. //FileTypeBlocID
  2031. x=(uint8_t)temp_entete[0]; if ((x>64) && (x<127)) { s3 = char(x); }
  2032. x=(uint8_t)temp_entete[1]; if ((x>64) && (x<127)) { s3 += char(x); }
  2033. x=(uint8_t)temp_entete[2]; if ((x>64) && (x<127)) { s3 += char(x); }
  2034. x=(uint8_t)temp_entete[3]; if ((x>64) && (x<127)) { s3 += char(x); }
  2035. tableWidget_1->setItem(0, 0, new QTableWidgetItem (s3) ); //FileTypeBlocID
  2036.  
  2037. // FileSize
  2038. x=(uint8_t)temp_entete[4]; s3.setNum(x); tableWidget_1->setItem(1, 0, new QTableWidgetItem (s3) );
  2039. x=(uint8_t)temp_entete[5]; s3.setNum(x); tableWidget_1->setItem(1, 1, new QTableWidgetItem (s3) );
  2040. x=(uint8_t)temp_entete[6]; s3.setNum(x); tableWidget_1->setItem(1, 2, new QTableWidgetItem (s3) );
  2041. x=(uint8_t)temp_entete[7]; s3.setNum(x); tableWidget_1->setItem(1, 3, new QTableWidgetItem (s3) );
  2042.  
  2043. tot1 = temp_entete[4] + (2<<7) * temp_entete[5] + (2<<15) * temp_entete[6] + (2<23)* temp_entete[7];
  2044. fileSize1 = separ_milliers(tot1);
  2045. tableWidget_1->setItem(1, 4, new QTableWidgetItem ("= " + fileSize1) );
  2046.  
  2047. // FileFormatID
  2048. x=(uint8_t)temp_entete[8]; if ((x>64) && (x<127)) { s3 = char(x); }
  2049. x=(uint8_t)temp_entete[9]; if ((x>64) && (x<127)) { s3 += char(x); }
  2050. x=(uint8_t)temp_entete[10]; if ((x>64) && (x<127)) { s3 += char(x); }
  2051. x=(uint8_t)temp_entete[11]; if ((x>64) && (x<127)) { s3 += char(x); }
  2052. tableWidget_1->setItem(2, 0, new QTableWidgetItem (s3) );
  2053.  
  2054. // ============ [Bloc décrivant le format audio] ==============
  2055.  
  2056. // FormatBlocID
  2057. x=(uint8_t)temp_entete[12]; if ((x>64) && (x<127)) { s3 = char(x); }
  2058. x=(uint8_t)temp_entete[13]; if ((x>64) && (x<127)) { s3 += char(x); }
  2059. x=(uint8_t)temp_entete[14]; if ((x>64) && (x<127)) { s3 += char(x); }
  2060. x=(uint8_t)temp_entete[15]; if ((x>64) && (x<127)) { s3 += char(x); }
  2061. tableWidget_1->setItem(3, 0, new QTableWidgetItem (s3) );
  2062.  
  2063. //BlocSize
  2064. x=(uint8_t)temp_entete[16]; s3.setNum(x); tableWidget_1->setItem(4, 0, new QTableWidgetItem (s3) );
  2065. x=(uint8_t)temp_entete[17]; s3.setNum(x); tableWidget_1->setItem(4, 1, new QTableWidgetItem (s3) );
  2066. x=(uint8_t)temp_entete[18]; s3.setNum(x); tableWidget_1->setItem(4, 2, new QTableWidgetItem (s3) );
  2067. x=(uint8_t)temp_entete[19]; s3.setNum(x); tableWidget_1->setItem(4, 3, new QTableWidgetItem (s3) );
  2068.  
  2069. 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];
  2070. tableWidget_1->setItem(4, 4, new QTableWidgetItem ("= " + separ_milliers(tot2)) );
  2071.  
  2072. //AudioFormat
  2073. x=(uint8_t)temp_entete[20]; s3.setNum(x); tableWidget_1->setItem(5, 0, new QTableWidgetItem (s3) );
  2074. x=(uint8_t)temp_entete[21]; s3.setNum(x); tableWidget_1->setItem(5, 1, new QTableWidgetItem (s3) );
  2075.  
  2076. if ((uint8_t)temp_entete[20]==1){tableWidget_1->setItem(5, 4, new QTableWidgetItem ("PCM") );}
  2077.  
  2078. //NbrCanaux
  2079. nb_canaux=(uint8_t)temp_entete[22]; s3.setNum(nb_canaux); tableWidget_1->setItem(6, 0, new QTableWidgetItem (s3) );
  2080. x=(uint8_t)temp_entete[23]; s3.setNum(x); tableWidget_1->setItem(6, 1, new QTableWidgetItem (s3) );
  2081.  
  2082. //Fréquence d'échantillonage en Hz
  2083. x=(uint8_t)temp_entete[24]; s3.setNum(x); tableWidget_1->setItem(7, 0, new QTableWidgetItem (s3) );
  2084. x=(uint8_t)temp_entete[25]; s3.setNum(x); tableWidget_1->setItem(7, 1, new QTableWidgetItem (s3) );
  2085. x=(uint8_t)temp_entete[26]; s3.setNum(x); tableWidget_1->setItem(7, 2, new QTableWidgetItem (s3) );
  2086. x=(uint8_t)temp_entete[27]; s3.setNum(x); tableWidget_1->setItem(7, 3, new QTableWidgetItem (s3) );
  2087.  
  2088. 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];
  2089. tableWidget_1->setItem(7, 4, new QTableWidgetItem ("= " + separ_milliers(tot3)) );
  2090.  
  2091. //BytePerSec
  2092. x=temp_entete[28]; s3.setNum(x); tableWidget_1->setItem(8, 0, new QTableWidgetItem (s3) );
  2093. x=temp_entete[29]; s3.setNum(x); tableWidget_1->setItem(8, 1, new QTableWidgetItem (s3) );
  2094. x=temp_entete[30]; s3.setNum(x); tableWidget_1->setItem(8, 2, new QTableWidgetItem (s3) );
  2095. x=temp_entete[31]; s3.setNum(x); tableWidget_1->setItem(8, 3, new QTableWidgetItem (s3) );
  2096.  
  2097. 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];
  2098. s3.setNum(tot4); // 96000
  2099.  
  2100. tableWidget_1->setItem(8, 4, new QTableWidgetItem (s3));
  2101. //tableWidget_1->setItem(8, 4, new QTableWidgetItem ("= " + separ_milliers(tot4)) );
  2102.  
  2103. //BytePerBloc
  2104. x=(uint8_t)temp_entete[32]; s3.setNum(x); tableWidget_1->setItem(9, 0, new QTableWidgetItem (s3) );
  2105. x=(uint8_t)temp_entete[33]; s3.setNum(x); tableWidget_1->setItem(9, 1, new QTableWidgetItem (s3) );
  2106.  
  2107. //BitsPerSample
  2108. x=(uint8_t)temp_entete[34]; s3.setNum(x); tableWidget_1->setItem(10, 0, new QTableWidgetItem (s3) );
  2109. x=(uint8_t)temp_entete[35]; s3.setNum(x); tableWidget_1->setItem(10, 1, new QTableWidgetItem (s3) );
  2110.  
  2111. x=(uint8_t)temp_entete[36]; if ((x>64) && (x<127)) { s3 = char(x); }
  2112. x=(uint8_t)temp_entete[37]; if ((x>64) && (x<127)) { s3 += char(x); }
  2113. x=(uint8_t)temp_entete[38]; if ((x>64) && (x<127)) { s3 += char(x); }
  2114. x=(uint8_t)temp_entete[39]; if ((x>64) && (x<127)) { s3 += char(x); }
  2115. tableWidget_1->setItem(11, 0, new QTableWidgetItem (s3) );
  2116.  
  2117. // DataSize
  2118. x=(uint8_t)temp_entete[40]; s3.setNum(x); tableWidget_1->setItem(12, 0, new QTableWidgetItem (s3) );
  2119. x=(uint8_t)temp_entete[41]; s3.setNum(x); tableWidget_1->setItem(12, 1, new QTableWidgetItem (s3) );
  2120. x=(uint8_t)temp_entete[42]; s3.setNum(x); tableWidget_1->setItem(12, 2, new QTableWidgetItem (s3) );
  2121. x=(uint8_t)temp_entete[43]; s3.setNum(x); tableWidget_1->setItem(12, 3, new QTableWidgetItem (s3) );
  2122.  
  2123. int tot5a = 1 * (uint8_t) temp_entete[40]; //because le temp_entête de type 'char' code avec entiers signés
  2124. int tot5b = (1<<8) * (uint8_t)temp_entete[41]; // remarque: (1<<8) = 2^8 = 256 // ne pas écrire (2<<8) !!
  2125. int tot5c = (1<<16) * (uint8_t)temp_entete[42];
  2126. int tot5d = (1<<24) * (uint8_t)temp_entete[43];
  2127.  
  2128. data_size = tot5a + tot5b + tot5c + tot5d;
  2129.  
  2130. // 21248 + 458752 = 480000
  2131. // pour le .wav LA 440 (48000, durée 10s) ->14x(2^16) + 166 * (2^8) = 960000
  2132. // 960 000 kb (stéréo) / 96 000 kb/s (stéréo)= 10s
  2133.  
  2134. tableWidget_1->setItem(12, 4, new QTableWidgetItem ("= " + separ_milliers(data_size)) ); // DataSize
  2135.  
  2136. // durée calculée
  2137. duree_totale = data_size / tot4;
  2138. s3.setNum(duree_totale, 'f', 3);// double n, char format = 'g', int precision = 6
  2139. tableWidget_1->setItem(13, 4, new QTableWidgetItem (s3 + " s") );
  2140.  
  2141. s4.setNum(tot4);
  2142. s4 = "ech : " + s3;
  2143. s4 += " Bps / 2 voies (stéréo) = ";
  2144.  
  2145. s5.setNum(tot4/2000);
  2146. s5 +=" kBps";
  2147.  
  2148. tableWidget_1->setItem(8, 5, new QTableWidgetItem (s5) );
  2149. lineEdit_6->setText("File size = " + fileSize1 + " bytes ; " + s4 + s5 + " ; durée calculée = " +s3 + "s");
  2150.  
  2151. if ((nb_canaux == 2) && (tot4 != 96000))
  2152. {
  2153. QMessageBox msgBox;
  2154. QString s1;
  2155. s1 = "Attention: Le taux d'échentillonage n'est pas 48 kb/s";
  2156. msgBox.setText(s1);
  2157. msgBox.exec();
  2158. }
  2159. if (nb_canaux != 2)
  2160. {
  2161. QMessageBox msgBox;
  2162. QString s1;
  2163. s1 = "Attention: Signal mono (doit être STEREO !)";
  2164. msgBox.setText(s1);
  2165. msgBox.exec();
  2166. }
  2167. }
  2168.  
  2169.  
  2170.  
  2171.  
  2172.  
  2173. // voir la page : https://fr.wikipedia.org/wiki/Waveform_Audio_File_Format
  2174. void MainWindow::garnis_temp_data(qint32 offset_i)
  2175. {
  2176. if (! wav_ok) {return;}
  2177.  
  2178. binStream1.device()->seek(0); // retour de la lecture au début du fichier
  2179. binStream1.skipRawData(44+offset_i); // saut bien plus loin dans le fichier
  2180. binStream1.readRawData (temp_data, 2000000); //lecture des données audio
  2181.  
  2182. //file_wav.close();
  2183. }
  2184.  
  2185.  
  2186. void MainWindow::calcul_compression()
  2187. {
  2188. double R;
  2189. double R_max=0;
  2190.  
  2191. for(uint n =0; n<nb_ech/4; n++)
  2192. {
  2193. R=ech[n].a;
  2194. if (R>R_max) {R_max=R;}
  2195. }
  2196. }
  2197.  
  2198.  
  2199. void MainWindow::remplir_tableau_echantillons_signal() // lecture du signal à analyser dans le 'temp_data' -> ech[n]
  2200. {
  2201.  
  2202. /*
  2203. Le fichier .wav doit avoir les caractéristiques suivantes :
  2204. - RIFF PCM WAVE fmt
  2205. - stéréo deux voies
  2206. - 96000 octets/s c'est à dire acqui avec 48000 octets/s x 2 voies
  2207. La FTT sera effectuée en 10 passes, sur un nb_ech = 2^10 = 1024 échantillons
  2208. */
  2209.  
  2210. uint n, n_max, i, offset_x;
  2211. double R;
  2212.  
  2213. offset_x = 40; // ou plus, si lecture plus loin dans le temps, à voir
  2214.  
  2215. uint8_t octet_n; // octet_B;
  2216. /*
  2217.   pour un codage 8 bits/sample = 2 * 1 octet/sample (stéréo)
  2218.   [Octet du Sample1 Canal1 ] (octet_A, octet_B)
  2219.   [Octet du Sample1 Canal2 ]
  2220.   ...
  2221. */
  2222. i=0;
  2223. n=0;
  2224. // on ne prend pas en compte tous les échantillons dispo dans le .wav (inutile ici)
  2225. // mais 1 sur 40 (la fréquence de la note la plus aigue (midi94) est = 932Hz)
  2226. // et seul le fondamental est pertinant pour reconnaitre la note, les harmoniques (timbre) sont ignorées
  2227. // il faut donc échantilloner à 932*2 = 1864 Hz au minimum
  2228. // Le fichier .wav d'origine est échantilloné à 48kHz
  2229. // 48000 / 1864 = 25.75
  2230. // On va prendre 1 échantillon sur 24 , ce qui donne un échantillonage à 48000/24 = 2000Hz
  2231. // attention : tout changement de cette valeur (pas = 24) change l'échelle de représentation de la FFT
  2232. // et fout le bocson dans tout le programme !!!
  2233. // chaque échantillon représente donc une durée = 1/2000 seconde = 0.5ms = 500us
  2234. // voir la suite des explications vers la fin de la fonction 'void MainWindow::tracer_segments_FFT()'
  2235.  
  2236. n_max = nb_ech /2; // = 1024/2 = 512
  2237. // 512*0.5ms = 256 ms
  2238.  
  2239. while (n < n_max)
  2240. {
  2241. octet_n = temp_data[offset_x + i]; // canal A
  2242. // i++; // pour sauter (et ignorer) le canal B (le signal dans le fichier .wav est stéréo)
  2243. i+= pas_echantillonage;
  2244.  
  2245. // x= 256 * octet_A + octet_B;
  2246. R = octet_n - 128; // pour oter la composante continue propre au codage par des octets non signés
  2247. R /= 10.0;
  2248. R *= doubleSpinBox_gain->value();
  2249.  
  2250. if (hamming) { R = R * (1- cos (2* M_PI * n / nb_ech/2 ));}
  2251.  
  2252. if (bourrage_de_zeros)
  2253. {
  2254. if (n<=nb_ech/4) // /4 -> signal
  2255. {
  2256. ech[n].a = R; // partie reelle
  2257. ech[n].b = 0; // partie imaginaire
  2258. }
  2259. else // -> Bourage de zéros
  2260. {
  2261. ech[n].a = 0; // partie reelle
  2262. ech[n].b = 0; // partie imaginaire
  2263. }
  2264. }
  2265. else
  2266. {
  2267. ech[n].a = R; // partie reelle
  2268. ech[n].b = 0; // partie imaginaire
  2269. }
  2270.  
  2271. n++; // n atteindra la valeur max = 512 ech représentant une durée totale de 256 ms
  2272. }
  2273.  
  2274. //calcul_compression();
  2275. }
  2276.  
  2277. /*
  2278. void MainWindow::on_toolButton_2_clicked() // recup signal
  2279. {
  2280.   RAZ_tableau_echantillons();
  2281.   remplir_tableau_echantillons_signal();
  2282.   tracer_signal_a_convertir();
  2283. }
  2284. */
  2285.  
  2286. void MainWindow::calcul_ofsset()
  2287. {
  2288. if(!wav_ok) return;
  2289. offset_t = spinBox_1->value() + 10 * spinBox_2->value() + 100 * spinBox_3->value() + 1000 * spinBox_4->value()
  2290. + 10000 * spinBox_5->value() + 100000 * spinBox_6->value();
  2291. QString s1;
  2292. s1 = separ_milliers(offset_t) ;
  2293. lineEdit_3->setText(s1);
  2294. effacer_calque(scene2, calque_encadrement2);
  2295. encadrement_signal(offset_t/1200, 25);
  2296. }
  2297.  
  2298.  
  2299. void MainWindow::traitement_signal() // lance les Transformées de Fourier du signal
  2300. {
  2301. if (! wav_ok) {return;}
  2302.  
  2303. garnis_temp_data(offset_t);
  2304. remplir_tableau_echantillons_signal();
  2305.  
  2306. calcul_tableau_W();
  2307. //RAZ_tableau_echantillons();
  2308.  
  2309. if(!rapide) { tracer_signal_a_convertir();}
  2310. bit_reverse_tableau_X();
  2311.  
  2312. calcul_FFT(); // 1 FFT s'effectue sur 1 cluster de 1024 échantillons.
  2313. //Le résultat représente un spectre élémentaire correspondant au cluster, c.a.d à une durée = 1024 x 0.5ms = 512 ms
  2314. // ce résultat est retourné dans le tableau 'Complexe tab_X[2048]'
  2315.  
  2316. //if (radioButton_notes->isChecked()) { tracer_segments_FFT(); }
  2317. //else { tracer_modules_FFT(); }
  2318.  
  2319. tracer_segments_FFT();
  2320. }
  2321.  
  2322.  
  2323.  
  2324. void MainWindow::analyse_tout() // FFT de tous les clusters, c.a.d. sur la totalité du signal
  2325. {
  2326.  
  2327. progressBar_1->setVisible(true);
  2328. /*
  2329.   if (wav_ok == false)
  2330.   {
  2331.   QMessageBox msgBox;
  2332.   msgBox.setText("file 'wav' not open");
  2333.   int ret = msgBox.exec();
  2334.   return;
  2335.   }
  2336. */
  2337. /*
  2338.   if (data_nts_ok == false)
  2339.   {
  2340.   QMessageBox msgBox;
  2341.   msgBox.setText("file 'nts' not open");
  2342.   int ret = msgBox.exec();
  2343.   return;
  2344.   }
  2345. */
  2346.  
  2347. QString s1;
  2348. offset_t=0;
  2349. T_i=0; // variable GLOBALE
  2350.  
  2351. uint16_t i_max = data_size / 1024; // = environ 6000
  2352.  
  2353. if (checkBox_debut_seul->isChecked()) {i_max=2000;} // pour gagner du temps lors de la phase de test
  2354.  
  2355.  
  2356. // data_size est affiché par le visualisateur d'entête
  2357. // et aussi dans le LineEdit en bas de l'onglet FFT
  2358. // data_size = de l'ordre de 7MB, ce qui nous donne un i_max d'environ 6900
  2359.  
  2360. effacer_calque(scene4, calque_TAB_FRQ);
  2361. liste_ENR_FFT.clear();
  2362. //clear_temp_data();
  2363. //garnis_temp_data(0);
  2364.  
  2365. // effacer_calque(scene4, calque_gradu_TAB_FRQ);
  2366. // effacer_calque(scene4, calque_notes_manuelles);
  2367. // effacer_calque(scene4, calque_notes_jouee);
  2368. // effacer_calque(scene4, calque_grille_mesures);
  2369. // effacer_calque(scene4, calque_echelle_temporelle_T);
  2370.  
  2371. for(uint16_t i=0 ; i<i_max ; i++) // cette boucle sera donc parcourue environ 6000 fois...
  2372. {
  2373. if ((i % 200) == 0)
  2374. {
  2375. uint16_t pc = 100 * i / i_max;
  2376. pc+=2;
  2377. progressBar_1->setValue(pc);
  2378. // la ligne suivante permet l'affichage de la progression
  2379. QCoreApplication::processEvents(QEventLoop::AllEvents, 1);
  2380. }
  2381. //s1.setNum(i); lineEdit_compteur->setText(s1);
  2382.  
  2383. traitement_signal(); // traitement d'un cluster de 1024 échantillons
  2384. offset_t += 1024; // on passera au cluster de 1024 échantillons suivant c.a.d à un temps + 0.5ms
  2385.  
  2386. }
  2387. progressBar_1->setVisible(false);
  2388.  
  2389. tracer_echelle_temps_TAB_NOTES();
  2390. }
  2391.  
  2392.  
  2393.  
  2394.  
  2395. void MainWindow::on_spinBox_1_valueChanged(int arg1)
  2396. {
  2397. if (arg1==10) { spinBox_1->setValue(0); spinBox_2->stepUp();}
  2398. calcul_ofsset();
  2399. traitement_signal();
  2400. }
  2401.  
  2402.  
  2403. void MainWindow::on_spinBox_2_valueChanged(int arg1)
  2404. {
  2405. if (arg1==-1) {spinBox_2->setValue(9); spinBox_3->stepDown();}
  2406. if (arg1==10) { spinBox_2->setValue(0); spinBox_3->stepUp();}
  2407. calcul_ofsset();
  2408. traitement_signal();
  2409. }
  2410.  
  2411.  
  2412. void MainWindow::on_spinBox_3_valueChanged(int arg1)
  2413. {
  2414. if (arg1==-1) {spinBox_3->setValue(9); spinBox_4->stepDown();}
  2415. if (arg1==10) { spinBox_3->setValue(0); spinBox_4->stepUp();}
  2416. calcul_ofsset();
  2417. traitement_signal();
  2418. }
  2419.  
  2420.  
  2421. void MainWindow::on_spinBox_4_valueChanged(int arg1)
  2422. {
  2423. if (arg1==-1) {spinBox_4->setValue(9); spinBox_5->stepDown();}
  2424. if (arg1==10) { spinBox_4->setValue(0); spinBox_5->stepUp();}
  2425. calcul_ofsset();
  2426. traitement_signal();
  2427. }
  2428.  
  2429.  
  2430. void MainWindow::on_spinBox_5_valueChanged(int arg1)
  2431. {
  2432. if (arg1==-1) {spinBox_5->setValue(9); spinBox_6->stepDown();}
  2433. if (arg1==10) { spinBox_5->setValue(0); spinBox_6->stepUp();}
  2434. calcul_ofsset();
  2435. traitement_signal();
  2436. }
  2437.  
  2438.  
  2439. void MainWindow::on_spinBox_6_valueChanged()
  2440. {
  2441. //if (arg1==-1) {spinBox_6->setValue(9);} //spinBox_6->stepDown();}
  2442. calcul_ofsset();
  2443. traitement_signal();
  2444. }
  2445.  
  2446.  
  2447. void MainWindow::on_doubleSpinBox_1_valueChanged()
  2448. {
  2449. calcul_ofsset();
  2450. traitement_signal();
  2451. }
  2452.  
  2453.  
  2454. void MainWindow::on_pushButton_8_clicked()
  2455. {
  2456. QMessageBox msgBox;
  2457. QString s1;
  2458. s1 = "Le fichier audio à analyser doit être au format unsigned 8 bits PCM";
  2459. s1 += " (généré par exemple avec Audacity)";
  2460. s1 += "\n";
  2461. s1 += "Attention: ce n'est pas le format PCM par défaut, il faut aller dans les sous-menus :";
  2462. s1 += "\n";
  2463. s1 += "Fichier/Exporter/Exporter en WAV / encodage : Unsigned 8-bit PCM";
  2464. s1 += "\n";
  2465. s1 += "Ce n'est pas 'top WiFi', mais largement suffisant pour en faire la FFT et retrouver les notes.";
  2466. s1 += "\n";
  2467. s1 += "Ce qui est le but ici.";
  2468. s1 += "\n";
  2469. s1 += "D'autre part il est vivement conseillé de compresser la dynamique de l'audio (ce qui est simple avec Audacity)";
  2470. s1 += "\n";
  2471. s1 += "ce qui facilite grandement la détection des notes.";
  2472.  
  2473. msgBox.setText(s1);
  2474. msgBox.exec();
  2475. }
  2476.  
  2477.  
  2478. void MainWindow::on_Bt_RAZ_clicked()
  2479. {
  2480. spinBox_1->setValue(0);
  2481. spinBox_2->setValue(0);
  2482. spinBox_3->setValue(0);
  2483. spinBox_4->setValue(0);
  2484. spinBox_5->setValue(0);
  2485. spinBox_6->setValue(0);
  2486. offset_t=0;
  2487. num_barre_en_cours=0;
  2488. }
  2489.  
  2490.  
  2491. void MainWindow::on_spinBox_7_valueChanged(int arg1)
  2492. {
  2493. // ligne verticale
  2494. effacer_calque(scene1,calque_curseur);
  2495. int x = arg1;
  2496. ligne1 = new QGraphicsLineItem(x, 10, x, 500);
  2497. ligne1->setPen(pen_curseur);
  2498. calque_curseur->addToGroup(ligne1);
  2499.  
  2500. }
  2501.  
  2502.  
  2503.  
  2504.  
  2505. void MainWindow::on_pushButton_2_clicked()
  2506. {
  2507. Timer1->stop();
  2508. nb_tics=0;
  2509. }
  2510.  
  2511.  
  2512. void MainWindow::on_Btn_52_clicked()
  2513. {
  2514. //spinBox_n_midi->setValue(52);
  2515.  
  2516. file_wav.setFileName(nom_fichier_in);
  2517. if (!file_wav.open(QIODevice::ReadOnly))
  2518. {
  2519. wav_ok = false;
  2520. return ;
  2521. }
  2522.  
  2523. wav_ok = true;
  2524.  
  2525. on_Bt_RAZ_clicked();
  2526.  
  2527. binStream1.setDevice(&file_wav);
  2528. calcul_ofsset();
  2529. traitement_signal();
  2530. }
  2531.  
  2532.  
  2533. void MainWindow::on_Btn_94_clicked()
  2534. {
  2535.  
  2536. file_wav.setFileName(nom_fichier_in);
  2537. if (!file_wav.open(QIODevice::ReadOnly))
  2538. {
  2539. wav_ok = false;
  2540. return ;
  2541. }
  2542.  
  2543. wav_ok = true;
  2544.  
  2545. on_Bt_RAZ_clicked();
  2546.  
  2547. binStream1.setDevice(&file_wav);
  2548. calcul_ofsset();
  2549. traitement_signal();
  2550. }
  2551.  
  2552.  
  2553. void MainWindow::on_Bt_efface_clicked()
  2554. {
  2555. QMessageBox msgBox;
  2556. msgBox.setText("Erase Frequences");
  2557. msgBox.setInformativeText("Effacer toutes les FFT ?");
  2558. msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
  2559. msgBox.setDefaultButton(QMessageBox::Cancel);
  2560. int ret = msgBox.exec();
  2561.  
  2562. if (ret == QMessageBox::Ok )
  2563. {
  2564. effacer_calque(scene1,calque_trace_signal1 );
  2565. effacer_calque(scene1,calque_trace_FFT );
  2566. effacer_calque(scene1,calque_lignes_F_zero );
  2567. effacer_calque(scene1,calque_encadrement1 );
  2568. effacer_calque(scene2,calque_encadrement2 );
  2569.  
  2570. effacer_calque(scene4,calque_TAB_FRQ );
  2571. on_Bt_RAZ_clicked();
  2572. T_i=0; // T_i : variable GLOBALE
  2573. }
  2574.  
  2575. }
  2576.  
  2577.  
  2578.  
  2579. void MainWindow::on_pushButton_3_clicked()
  2580. {
  2581.  
  2582. tableWidget_1->setVisible(true);
  2583. Bt_close_entete->setVisible(true);
  2584. }
  2585.  
  2586.  
  2587. void MainWindow::on_Bt_close_entete_clicked()
  2588. {
  2589. tableWidget_1->setVisible(false);
  2590. Bt_close_entete->setVisible(false);
  2591. }
  2592.  
  2593. /*
  2594. void MainWindow::on_Bt_close_frame1_clicked()
  2595. {
  2596.   frame_1->setVisible(false);
  2597.   frame_3->setVisible(true);
  2598. }
  2599.  
  2600.  
  2601. void MainWindow::on_pushButton_4_clicked()
  2602. {
  2603.   frame_3->setVisible(false);
  2604.   frame_1->setVisible(true);
  2605. }
  2606. */
  2607.  
  2608.  
  2609. void MainWindow::on_pushButton_6_clicked()
  2610. {
  2611. frame_notes->setVisible(false);
  2612. }
  2613.  
  2614.  
  2615.  
  2616. void MainWindow::on_pushButton_5_clicked()
  2617. {
  2618. spinBox_offset->setValue(-2124); // 2154 ; ref -2210 ; +/- 22 pour un décalage de +/-1/4 de ton
  2619. spinBox_echx->setValue(499); // 498
  2620. }
  2621.  
  2622.  
  2623.  
  2624. int MainWindow::save_fichier_FRQ(QString date_i)
  2625. {
  2626. // enregisterment incrémentiel sur le disque (nom de fichier = 1..2...3...)
  2627. ENR_FFT enr_i;
  2628. QString s1;
  2629.  
  2630. uint8_t x0a = spinBox_x0a->value();
  2631. double x0b = doubleSpinBox_x0b->value();
  2632.  
  2633. //uint8_t dxa = spinBox_dxa->value();
  2634. double dxb = doubleSpinBox_dxb->value();
  2635.  
  2636. long n_max = liste_ENR_FFT.length();
  2637. if (n_max == 0)
  2638. {
  2639. QMessageBox msgBox; msgBox.setText("liste FRQ vide !"); msgBox.exec();
  2640. return 1;
  2641. }
  2642. //int numero=0;
  2643. QString s2 = date_i;
  2644. Timer1->stop();
  2645.  
  2646. QFile file1(string_currentDir + "/" + s2 + ".FRQ");
  2647. if (file1.open(QIODevice::WriteOnly | QIODevice::Text))
  2648. {
  2649. QByteArray byteArray1;
  2650. QDataStream stream1(&byteArray1, QIODevice::WriteOnly);
  2651. stream1.setDevice(&file1);
  2652. stream1.setVersion(QDataStream::Qt_6_8);
  2653.  
  2654. // entête 64 octets------------------
  2655. double vts = doubleSpinBox_vitesse->value(); // 8 octets
  2656. stream1 << x0b << dxb << vts << Ta << Tb << x0a; //8+8+8+1+1+1+1 =27 octets au début du fichier
  2657.  
  2658. for (int i=0; i<(64-27); i++) {stream1 << 'x';} // complète à 64 octet
  2659. // ----------------------------------
  2660.  
  2661. for(int n=0; n<n_max; n++)
  2662. {
  2663. enr_i = liste_ENR_FFT[n];
  2664. stream1 << enr_i.amplitude << enr_i.midi << enr_i.num << enr_i.t; // sérialisation des data
  2665. }
  2666. }
  2667. file1.close();
  2668.  
  2669. return 0;
  2670.  
  2671. }
  2672.  
  2673.  
  2674. void MainWindow::choix_dossier_de_travail()
  2675. {
  2676.  
  2677. QString actuel = string_currentDir;
  2678. string_currentDir = QFileDialog::getExistingDirectory
  2679. (this, tr("Open Directory"), actuel, QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
  2680.  
  2681. if (string_currentDir != "")
  2682. {
  2683. dossier_de_travail_ok = true;
  2684. save_fichier_ini();
  2685. lineEdit_current_dir->setText(string_currentDir);
  2686. }
  2687. else { dossier_de_travail_ok = false; } // -> si on clique sur le bouton 'cancel'
  2688.  
  2689. }
  2690.  
  2691.  
  2692. void MainWindow::on_Bt_choix_current_dir_clicked()
  2693. {
  2694. choix_dossier_de_travail();
  2695. }
  2696.  
  2697.  
  2698. void MainWindow::ajustement_gain()
  2699. {
  2700. double somme;
  2701. double moyenne;
  2702. double R;
  2703. double gain;
  2704. uint8_t octet_n;
  2705. long i, j;
  2706.  
  2707. double pas = 10.0 * pas_echantillonage; // 240
  2708. double n_max = 2000000 / pas;
  2709.  
  2710. i=0;
  2711. j=0;
  2712. somme =0;
  2713. for(long n=0; n<n_max; n++)
  2714. {
  2715. octet_n = temp_data[i]; // canal 1
  2716. if (octet_n !=0)
  2717. {
  2718. R = octet_n - 128;// pour ôter la composante continue (octets non signés)
  2719. if (R<0) {R= -R;}
  2720. somme += R;
  2721. j++; // nb de notes effectivement prises en compte
  2722. }
  2723. i+= pas;
  2724. }
  2725. moyenne = somme / j;
  2726.  
  2727. gain = 20.0/moyenne;
  2728. doubleSpinBox_gain->setValue(gain);
  2729. }
  2730.  
  2731.  
  2732. void MainWindow::load_fichier_FRQ()
  2733. {
  2734. QString filename1;
  2735. QString s1;
  2736.  
  2737. MainWindow::setCursor(Qt::WaitCursor);
  2738.  
  2739. if(dossier_de_travail_ok == false)
  2740. {
  2741. choix_dossier_de_travail();
  2742. if (dossier_de_travail_ok == false)
  2743. {
  2744. QMessageBox msgBox;
  2745. s1="Le dossier de travail n'est pas spécifié";
  2746. msgBox.setText(s1); msgBox.exec();
  2747. return ;
  2748. }
  2749. }
  2750.  
  2751. filename1 = QFileDialog::getOpenFileName(this,
  2752. tr("Ouvrir Fichier FRQ"), string_currentDir + "/", tr("Fichiers FRQ (*.FRQ)"));
  2753.  
  2754.  
  2755. lineEdit_fichier_FREQ->setText(filename1);
  2756.  
  2757. file_dat.setFileName(filename1);
  2758. if (!file_dat.open(QIODevice::ReadOnly))
  2759. {
  2760. data_nts_ok = false;
  2761. return ;
  2762. }
  2763. else
  2764. {
  2765. binStream1.setDevice(&file_dat); // accès à la totalité du fichier dat
  2766. binStream1.setVersion(QDataStream::Qt_6_8);
  2767. data_nts_ok = true;
  2768. liste_ENR_FFT.clear();
  2769. }
  2770.  
  2771. //int z = sizeof(ENR_FFT); // ATTENTION ! ne PAS utiliser cette valeur qui tient en compte l'alignement en RAM
  2772. long n_max = file_dat.bytesAvailable() / 14; // 14 bits par enr; voir la def de 'ENR_FFT' dans le .h
  2773.  
  2774. uint8_t x0a;
  2775. double x0b;
  2776. uint8_t dxa;
  2777. double dxb;
  2778.  
  2779. double vts;
  2780.  
  2781. // lecture entête -----------------
  2782.  
  2783. binStream1 >> x0b >> dxb >> vts >> Ta >> Tb >> x0a >> dxa; // 8+8+8+1+1+1+1=28 octets au début du fichiers
  2784.  
  2785. uint8_t xx;
  2786. for (int i=0; i<(64-28); i++) {binStream1 >> xx;} // lit en tout à 64 octets
  2787. //---------------------------------
  2788.  
  2789. spinBox_x0a->setValue(x0a);
  2790. doubleSpinBox_x0b->setValue(x0b);
  2791. // spinBox_dxa->setValue(dxa);
  2792. doubleSpinBox_dxb->setValue(dxb);
  2793. doubleSpinBox_vitesse->setValue(vts);
  2794.  
  2795. //---------------------------------
  2796.  
  2797. ENR_FFT enr_i;
  2798. for(int n=0; n<n_max; n++)
  2799. {
  2800. binStream1 >> enr_i.amplitude >> enr_i.midi >> enr_i.num >> enr_i.t;
  2801. liste_ENR_FFT << enr_i;
  2802. }
  2803. file_dat.close();
  2804.  
  2805. retracer_TAB_FRQ();
  2806. MainWindow::setCursor(Qt::ArrowCursor);
  2807. }
  2808.  
  2809.  
  2810. int MainWindow::save_fichier_NOTES(QString date_i)
  2811. {
  2812. // enregisterment incrémentiel sur le disque (nom de fichier = 1..2...3...)
  2813. NOTE note_i;
  2814. QString s1;
  2815.  
  2816. uint8_t x0a = spinBox_x0a->value();
  2817. double x0b = doubleSpinBox_x0b->value();
  2818.  
  2819. //uint8_t dxa = spinBox_dxa->value();
  2820. double dxb = doubleSpinBox_dxb->value();
  2821.  
  2822. uint16_t n_max = liste_NOTES.length();
  2823. if (n_max == 0)
  2824. {
  2825. QMessageBox msgBox; msgBox.setText("liste NOTES vide !"); msgBox.exec();
  2826. return 1;
  2827. }
  2828.  
  2829. if (date_i == "BAK")
  2830. {
  2831. QMessageBox msgBox;
  2832. QString s1="Fichier BAK.NTS enregistré";
  2833. msgBox.setText(s1); msgBox.exec();
  2834. }
  2835.  
  2836.  
  2837. //int numero=0;
  2838. QString s2;
  2839.  
  2840. Timer1->stop();
  2841.  
  2842. s2 = date_i;
  2843.  
  2844. //QFile file1(string_currentDir + "/" + "NOTES_" + s2 + ".nts");
  2845. QFile file1(string_currentDir + "/" + s2 + ".NTS");
  2846. if (file1.open(QIODevice::WriteOnly | QIODevice::Text))
  2847. {
  2848. QByteArray byteArray1;
  2849. QDataStream stream1(&byteArray1, QIODevice::WriteOnly);
  2850. stream1.setDevice(&file1);
  2851. stream1.setVersion(QDataStream::Qt_6_8);
  2852.  
  2853. // entête 64 octets --------------
  2854. double vts = doubleSpinBox_vitesse->value(); // 8 octets
  2855. stream1 << x0b << dxb << vts << Ta << Tb << x0a; //8+8+8+1+1+1 =27 octets au début du fichier
  2856.  
  2857. for (int i=0; i<(64-27); i++) {stream1 << 'x';} // complète à 64 octets
  2858. //--------------------------------
  2859. for(uint16_t n=0; n<n_max; n++)
  2860. {
  2861. note_i = liste_NOTES[n];
  2862. // sérialisation des data
  2863. stream1 << note_i.numero << note_i.midi << note_i.n_barreT << note_i.n_barreM;
  2864. }
  2865. }
  2866. file1.close();
  2867.  
  2868. return 0;
  2869. }
  2870.  
  2871.  
  2872.  
  2873. void MainWindow::load_fichier_NOTES(QString s0)
  2874. {
  2875. QString filename1;
  2876. QString s1;
  2877.  
  2878. MainWindow::setCursor(Qt::WaitCursor);
  2879.  
  2880. if (s0 == "BAK")
  2881. {
  2882. filename1 = string_currentDir+ "/BAK.NTS";
  2883. }
  2884. else
  2885. {
  2886. if(dossier_de_travail_ok == false)
  2887. {
  2888. choix_dossier_de_travail();
  2889. if (dossier_de_travail_ok == false)
  2890. {
  2891. QMessageBox msgBox;
  2892. s1="Le dossier de travail n'est pas spécifié";
  2893. msgBox.setText(s1); msgBox.exec();
  2894. return ;
  2895. }
  2896. }
  2897. filename1 = QFileDialog::getOpenFileName(this,
  2898. tr("Ouvrir Fichier NTS"), string_currentDir+"/", tr("Fichiers nts (*.NTS)"));
  2899.  
  2900.  
  2901. }
  2902.  
  2903. lineEdit_fichier->setText(filename1);
  2904. file_dat.setFileName(filename1);
  2905. if (!file_dat.open(QIODevice::ReadOnly))
  2906. {
  2907. data_nts_ok = false;
  2908. return ;
  2909. }
  2910. else
  2911. {
  2912. binStream1.setDevice(&file_dat); // accès à la totalité du fichier dat
  2913. binStream1.setVersion(QDataStream::Qt_6_8);
  2914. data_nts_ok = true;
  2915. }
  2916.  
  2917. //int z = sizeof(NOTE); // ATTENTION ! ne PAS utiliser cette valeur qui tient en compte l'alignement en RAM
  2918. uint16_t n_max = file_dat.bytesAvailable() / 7; // 7 bits par enr; voir la def de 'NOTE' dans le .h
  2919.  
  2920. uint8_t x0a;
  2921. double x0b;
  2922. uint8_t dxa;
  2923. double dxb;
  2924.  
  2925. double vts;
  2926.  
  2927. // lecture entête -----------------
  2928. binStream1 >> x0b >> dxb >> vts >> Ta >> Tb >> x0a >> dxa; // 8+8+8+1+1+1+1=28 octets au début du fichiers
  2929.  
  2930. uint8_t xx;
  2931. for (int i=0; i<(64-28); i++) {binStream1 >> xx;} // lit en tout à 64 octets
  2932. //---------------------------------
  2933. spinBox_x0a->setValue(x0a);
  2934. doubleSpinBox_x0b->setValue(x0b);
  2935. //spinBox_dxa->setValue(dxa);
  2936. doubleSpinBox_dxb->setValue(dxb);
  2937. doubleSpinBox_vitesse->setValue(vts);
  2938.  
  2939. switch (Ta)
  2940. {
  2941. case 2: {lineEdit_10->setText("2/4"); Ta=2; Tb=4;} break; // Ta et Tb variables globales
  2942. case 3: {lineEdit_10->setText("3/4"); Ta=3; Tb=4;} break;
  2943. case 4: {lineEdit_10->setText("4/4"); Ta=4; Tb=4;} break;
  2944. default: break;
  2945. }
  2946.  
  2947. for(int n=0; n<n_max; n++)
  2948. {
  2949. NOTE note_i;
  2950. binStream1 >> note_i.numero >> note_i.midi >> note_i.n_barreT >> note_i.n_barreM;
  2951. note_i.midi += spinBox_transposition->value();
  2952. liste_NOTES << note_i;
  2953. }
  2954.  
  2955. file_dat.close();
  2956. mode = 'M';
  2957.  
  2958. affiche_liste_notes();
  2959. //on_Bt_toggle_grille_T_clicked();
  2960. Bt_jouer_tout->setStyleSheet("background-color: rgb(0, 255, 0);"); // vert
  2961.  
  2962. MainWindow::setCursor(Qt::ArrowCursor);
  2963. }
  2964.  
  2965.  
  2966. void decalle_notes(int d)
  2967. {
  2968. int nb;
  2969. uint16_t i_max = liste_NOTES.length();
  2970. for( int i =0; i<i_max; i++)
  2971. {
  2972. nb = liste_NOTES[i].n_barreT;
  2973. nb += d;
  2974. liste_NOTES[i].n_barreT = nb;
  2975. }
  2976.  
  2977. }
  2978.  
  2979.  
  2980. void MainWindow::on_Bt_load_FREQ_clicked()
  2981. {
  2982. load_fichier_FRQ();
  2983. on_Bt_toggle_grille_T_clicked();
  2984. // effacer_calque(scene4, );
  2985. effacer_calque(scene5, calque_histogramme );
  2986. // tracer_echelle_temps_TAB_NOTES();
  2987. }
  2988.  
  2989.  
  2990. void MainWindow::on_checkBox_rapide_stateChanged(int arg1)
  2991. {
  2992. rapide=arg1;
  2993. init_TAB_FRQ();
  2994. }
  2995.  
  2996.  
  2997. void MainWindow::on_doubleSpinBox_seuil_valueChanged(double arg1)
  2998. {
  2999. seuil = arg1;
  3000. effacer_calque(scene4, calque_TAB_FRQ);
  3001. retracer_TAB_FRQ();
  3002. }
  3003.  
  3004.  
  3005. void MainWindow::on_checkBox_norm_clicked()
  3006. {
  3007. /*
  3008.   if (checkBox_norm->isChecked())
  3009.   {
  3010.   textEdit_ETAT->setText("Mode Normalisé : \n Les couleurs représentent l'amplitude du signal");
  3011.   }
  3012.   else
  3013.   {
  3014.   textEdit_ETAT->setText(
  3015. "Mode Fréquences : \n"
  3016.  "Les couleurs représentent la valeur (fréquence) de la note (Do, RE, MI...) \n"
  3017.  "La taille de chaque tiret représente (abusivement sur l'axe fréquenciel) l'amplitude du signal \n"
  3018.  "cette taille ne signifie donc pas un étalement en fréquence du signal, c'est juste une astuce de représentation."
  3019.   );
  3020.   }
  3021. */
  3022. effacer_calque(scene4, calque_TAB_FRQ);
  3023. retracer_TAB_FRQ();
  3024. }
  3025.  
  3026.  
  3027.  
  3028. void MainWindow::surbrille_note(uint16_t n, bool HRM)
  3029. {
  3030. // HRM true -> visu harmoniques x2 et x3
  3031. double x_note;
  3032.  
  3033. NOTE note_i;
  3034. uint16_t n_max = liste_NOTES.length();
  3035. if ( n>= n_max) {return;}
  3036.  
  3037. note_i = liste_NOTES[n];
  3038. if(mode=='T') { x_note = calcul_x_barre(note_i.n_barreT); }
  3039. if(mode=='M') { x_note = calcul_x_barre(note_i.n_barreM); }
  3040.  
  3041. if (checkBox_scrolling->isChecked())
  3042. {
  3043. //int n =0;
  3044. double diff1 =0;
  3045.  
  3046. double xb = graphicsView4->horizontalScrollBar()->value();
  3047. diff1= x_note - xb;
  3048.  
  3049. if(diff1 >1700)
  3050. {
  3051. on_Bt_next_clicked();
  3052. on_Bt_next_clicked();
  3053. }
  3054. }
  3055.  
  3056. int y1, y2, y3; // y1=F0; y2 = 2xF0; y3 = 3xF0
  3057. int midi_i;
  3058. QString blanc = "#FFFFFF";
  3059.  
  3060. midi_i = note_i.midi;
  3061. y1 = calcul_y_note(midi_i) ;
  3062. y2 = calcul_y_note(midi_i+12);
  3063. y3 = calcul_y_note(midi_i+17);
  3064. //if (effacer) {effacer_calque(scene4, calque_notes_jouee);}
  3065.  
  3066. QPen pen1;
  3067. pen1.setColor(blanc);
  3068. pen1.setWidth(2);
  3069. ellipse1 = new QGraphicsEllipseItem(x_note-15, y1-15, 30, 30) ;
  3070. ellipse1->setPen(pen1);
  3071. //ellipse1->setBrush(blanc);
  3072. calque_notes_jouee->addToGroup(ellipse1);
  3073.  
  3074. if (HRM== true)
  3075. {
  3076. rectangle1= new QGraphicsRectItem(x_note-20, y2-1, 40, 2) ;
  3077. rectangle1->setPen(pen1);
  3078. calque_notes_jouee->addToGroup(rectangle1);
  3079.  
  3080. rectangle1= new QGraphicsRectItem(x_note-20, y3-1, 40, 2) ;
  3081. rectangle1->setPen(pen1);
  3082. calque_notes_jouee->addToGroup(rectangle1);
  3083. }
  3084.  
  3085. }
  3086.  
  3087.  
  3088. void MainWindow::complete_case(int row, int column, QString s1, QString c1, QString c2, bool bold1, QTableWidget *QTI)
  3089. {
  3090. QTableWidgetItem *Item1 = new QTableWidgetItem();
  3091. Item1->QTableWidgetItem::setForeground(QColor(c1));
  3092. Item1->QTableWidgetItem::setBackground(QColor(c2));
  3093.  
  3094. QFont font1;
  3095. font1.setBold(bold1);
  3096. Item1->setFont(font1);
  3097. Item1->setTextAlignment(Qt::AlignCenter);
  3098.  
  3099. Item1->setText(s1);
  3100. QTI->setItem(row, column, Item1);
  3101. }
  3102.  
  3103.  
  3104. void MainWindow::affiche_liste_notes() // en TEXTE dans le petit tableau
  3105. {
  3106. NOTE note_i;
  3107. QString s1;
  3108.  
  3109. QString blanc = "#FFFFFF";
  3110. QString jaune = "#FFFF00";
  3111. QString cyan = "#00FFFF";
  3112.  
  3113. tableWidget_lst_notes->clear();
  3114. tableWidget_lst_notes->setRowCount(0);
  3115. init_TAB_lst_notes();
  3116.  
  3117. uint16_t n_max = liste_NOTES.length();
  3118. if (n_max == 0) {return;}
  3119.  
  3120. for(int n=0; n<n_max; n++) //n_max
  3121. {
  3122. note_i=liste_NOTES[n];
  3123.  
  3124. int numero = note_i.numero;
  3125. int midi = note_i.midi;
  3126. int n_barreT = note_i.n_barreT;
  3127. int n_barreM = note_i.n_barreM;
  3128.  
  3129. int num_ligne = tableWidget_lst_notes->rowCount();
  3130. tableWidget_lst_notes->setRowCount(num_ligne+1); // ajout une ligne au tableau
  3131.  
  3132. s1.setNum(numero);
  3133.  
  3134. complete_case(n, 0, s1, "000000", "#FFFFFF", false, tableWidget_lst_notes);
  3135.  
  3136. s1.setNum(midi);
  3137. int h1 = calcul_hauteur_note(midi);
  3138.  
  3139.  
  3140. QString couleur1 = liste_couleurs[h1];
  3141. complete_case(n, 1, s1, "#000000", couleur1, true, tableWidget_lst_notes);
  3142.  
  3143. s1 = nom_note(midi);
  3144. complete_case(n, 2, s1, "#000000", "#FFFFFF", false, tableWidget_lst_notes);
  3145.  
  3146. s1.setNum(n_barreT);
  3147. complete_case(n, 3, s1, jaune, "#555555", true, tableWidget_lst_notes);
  3148.  
  3149. s1.setNum(n_barreM);
  3150.  
  3151. complete_case(n, 4, s1, "#000000", "#FFFFFF", false, tableWidget_lst_notes);
  3152.  
  3153. }
  3154.  
  3155. tableWidget_lst_notes->AdjustToContents;
  3156. affiche_histogramme();
  3157.  
  3158. }
  3159.  
  3160.  
  3161. void MainWindow::affiche_histogramme_durees()
  3162. {
  3163. int x;
  3164. double dy;
  3165. double echelle;
  3166. QBrush br1;
  3167. QString couleur1;
  3168. QString s1;
  3169.  
  3170. effacer_calque(scene5, calque_histogramme);
  3171.  
  3172. GraphicsTextItem = new QGraphicsTextItem("Histogramme des durées \n en nb de barres 1/40s");
  3173. GraphicsTextItem->setFont(QFont("Arial", 12));
  3174. GraphicsTextItem->setDefaultTextColor("#FFFFFF");
  3175. GraphicsTextItem->setPos(220, -160);
  3176. calque_histogramme->addToGroup(GraphicsTextItem);
  3177.  
  3178. //calcul de la valeur la plus grande
  3179. int total=0;
  3180. for(int n=0; n<=20; n++) // attention à ne pas dépasser la taille de la table...
  3181. {
  3182. dy = table_histogramme_durees[n];
  3183. if (dy > total ) {total = dy;}
  3184. }
  3185. //calcul échelle y
  3186. if (total == 0) {total = 1;}
  3187. echelle = 150.0 / total;
  3188.  
  3189. for(int n=0; n<=30; n++) // attention à ne pas dépasser la taille de la table...
  3190. {
  3191. x = 10*n;
  3192. dy = echelle * table_histogramme_durees[n];
  3193. dy = -dy;
  3194. rect1 = new QGraphicsRectItem(x, 0, 2, dy);
  3195.  
  3196. couleur1="#AAFFFF";
  3197. br1.setStyle(Qt::SolidPattern);
  3198. br1.setColor(QColor(couleur1));
  3199.  
  3200. rect1->setPen(QColor(couleur1));
  3201. rect1->setBrush(br1);
  3202. calque_histogramme->addToGroup(rect1);
  3203.  
  3204. if (n%2 == 0)
  3205. {
  3206. x = -5 + 20*n;
  3207. s1.setNum(n);
  3208. GraphicsTextItem = new QGraphicsTextItem(s1);
  3209. GraphicsTextItem->setFont(QFont("Arial", 10));
  3210. GraphicsTextItem->setDefaultTextColor("#FFFFFF");
  3211. GraphicsTextItem->setPos(x, 0);
  3212. calque_histogramme->addToGroup(GraphicsTextItem);
  3213. }
  3214. }
  3215. }
  3216.  
  3217.  
  3218.  
  3219. void MainWindow::calcul_histogramme_durees()
  3220. {
  3221. uint16_t n_max = liste_NOTES.length();
  3222. if (n_max == 0) {return;}
  3223.  
  3224. for(int i=0; i<35; i++) { table_histogramme_durees[i]=0; } // RAZ
  3225.  
  3226. for(int n=1; n<n_max; n++) // attention: =1 et pas =0 because 'liste_NOTES[n-1]' ci-dessous !
  3227. {
  3228. int duree = liste_NOTES[n].n_barreT - liste_NOTES[n-1].n_barreT;
  3229. table_histogramme_durees[duree]++;
  3230. }
  3231. }
  3232.  
  3233.  
  3234. void MainWindow::affiche_histogramme_midi()
  3235. {
  3236.  
  3237. int x;
  3238. double dy;
  3239. double echelle;
  3240. QBrush br1;
  3241. QString couleur1;
  3242. QString s1;
  3243.  
  3244. effacer_calque(scene5, calque_histogramme);
  3245.  
  3246. GraphicsTextItem = new QGraphicsTextItem("Histogramme des notes midi");
  3247. GraphicsTextItem->setFont(QFont("Arial", 12));
  3248. GraphicsTextItem->setDefaultTextColor("#FFFFFF");
  3249. GraphicsTextItem->setPos(150, -160);
  3250. calque_histogramme->addToGroup(GraphicsTextItem);
  3251.  
  3252. //calcul de la valeur la plus grande
  3253. int total=0;
  3254. for(int n=0; n<=42; n++) // attention à ne pas dépasser la taille de la table...
  3255. {
  3256. dy = table_histogramme_midi[n];
  3257. if (dy > total ) {total = dy;}
  3258. }
  3259. //calcul échelle y
  3260. if (total == 0) {total = 1;}
  3261. echelle = 150.0 / total;
  3262.  
  3263. for(int n=0; n<=40; n++) // 42 attention à ne pas dépasser la taille de la table...
  3264. {
  3265. x = 10*n;
  3266. dy = echelle * table_histogramme_midi[n];
  3267. dy = -dy;
  3268. rect1 = new QGraphicsRectItem(x, 0, 5, dy);
  3269.  
  3270. couleur1="#AAFFFF";
  3271. int h1 = calcul_hauteur_note(n+40);
  3272. QString couleur1 = liste_couleurs[h1];
  3273. br1.setStyle(Qt::SolidPattern);
  3274. br1.setColor(QColor(couleur1));
  3275.  
  3276. rect1->setPen(QColor(couleur1));
  3277. rect1->setBrush(br1);
  3278. calque_histogramme->addToGroup(rect1);
  3279.  
  3280. if (n%2== 0)
  3281. {
  3282. x = -5 + 10*n;
  3283. s1.setNum(n+40);
  3284. GraphicsTextItem = new QGraphicsTextItem(s1);
  3285. GraphicsTextItem->setFont(QFont("Arial", 10));
  3286. GraphicsTextItem->setDefaultTextColor("#FFFFFF");
  3287. GraphicsTextItem->setPos(x, 0);
  3288. calque_histogramme->addToGroup(GraphicsTextItem);
  3289. }
  3290. }
  3291.  
  3292. }
  3293.  
  3294.  
  3295. void MainWindow::calcul_histogramme_midi()
  3296. {
  3297. for(int i=0; i<42; i++)
  3298. {
  3299. table_histogramme_midi[i]=0; // RAZ
  3300. }
  3301.  
  3302. uint16_t n_max = liste_NOTES.length();
  3303.  
  3304. for(int n=0; n<n_max; n++)
  3305. {
  3306. int M=liste_NOTES[n].midi;
  3307. if ((M>=40)&&(M<=82)) { table_histogramme_midi[M-40]++;}
  3308. }
  3309. }
  3310.  
  3311. /*
  3312. Liste des correspondances en fonction des dièses présents à la clef :
  3313. Pas d'altération : Do Majeur
  3314.  Fa# : Sol Majeur
  3315.  Fa#, Do# -> gamme de Ré Majeur
  3316.  Fa#, Do#, Sol# -> gamme de La Majeur
  3317.  Fa#, Do#, Sol#, Ré# -> gamme de Mi Majeur
  3318.  Fa#, Do#, Sol#, Ré#, La# -> gamme de Si Majeur
  3319.  Fa#, Do#, Sol#, Ré#, La#, Mi# -> gamme de Fa dièse Majeur
  3320.  Fa#, Do#, Sol#, Ré#, La#, Mi#, Si# -> gamme de Do dièse Majeur
  3321. */
  3322.  
  3323.  
  3324. QString MainWindow::denombre_diezes_a_la_cle()
  3325. {
  3326. // FA♯ DO♯ SOL♯ RÉ♯ LA♯ MI♯ SI♯
  3327. // 42 49 56 51 46 53 48 // midi
  3328. // 6 1 8 3 10 5 0 (reportées dans la première octave)
  3329.  
  3330. QString s1, s2;
  3331. int N;
  3332. int FA=0, DO=0, SOL=0, RE=0, LA=0, MI=0, SI=0;
  3333. s1="";
  3334. if (table_histogramme_degre[6] > 0) {FA=1; s1+=" FA#";}
  3335. if ((table_histogramme_degre[1] > 0)&&(FA==1)) {DO=1; s1+= " DO#";}
  3336. if ((table_histogramme_degre[8] > 0)&&(DO==1)) {SOL=1; s1+= " SOL#";}
  3337. if ((table_histogramme_degre[3] > 0)&&(SOL==1)) {RE=1; s1+= " RE#";}
  3338. if ((table_histogramme_degre[10] > 0)&&(RE==1)) {LA=1; s1+= " LA#";}
  3339. if ((table_histogramme_degre[5] > 0)&&(LA==1)) {MI=1; s1+= " MI#";}
  3340. if ((table_histogramme_degre[0] > 0)&&(MI==1)) {SI=1; s1+= " SI#";}
  3341.  
  3342. N = FA+DO+SOL+RE+LA;
  3343. s2.setNum(N);
  3344. s2+=" dièse";
  3345. if (N>1) {s2+="s";}
  3346. s2+=" à la clé " ;
  3347. s2 += s1;
  3348. return s2;
  3349. }
  3350.  
  3351.  
  3352. void MainWindow::affiche_histogramme_degre()
  3353. {
  3354.  
  3355. int y1, y2;
  3356. double dx;
  3357. double echelle;
  3358. QBrush br1;
  3359. QString couleur1;
  3360. QString s1;
  3361.  
  3362. effacer_calque(scene5, calque_histogramme);
  3363.  
  3364. GraphicsTextItem = new QGraphicsTextItem("Histogramme des degrés (gamme chromatique)");
  3365. GraphicsTextItem->setFont(QFont("Arial", 12));
  3366. GraphicsTextItem->setDefaultTextColor("#FFFFFF");
  3367. GraphicsTextItem->setPos(80, -170);
  3368. calque_histogramme->addToGroup(GraphicsTextItem);
  3369.  
  3370. //calcul de la valeur la plus grande
  3371. int total=0;
  3372. for(int n=0; n<12; n++) // attention à ne pas dépasser la taille de la table...
  3373. {
  3374. dx = table_histogramme_degre[n];
  3375. if (dx > total ) {total = dx;}
  3376. }
  3377. //calcul échelle y
  3378. if (total == 0) {total = 1;}
  3379. echelle = 150.0 / total;
  3380.  
  3381. for(int n=0; n<12; n++)
  3382. {
  3383. y1 = 20 - 10*n;
  3384. dx = echelle * table_histogramme_degre[n];
  3385. if (dx>0)
  3386. {
  3387. rect1 = new QGraphicsRectItem(40, y1, dx, 4);
  3388.  
  3389. couleur1="#AAFFFF";
  3390. int h1 = n;
  3391. QString couleur1 = liste_couleurs[h1];
  3392. br1.setStyle(Qt::SolidPattern);
  3393. br1.setColor(QColor(couleur1));
  3394.  
  3395. rect1->setPen(QColor(couleur1));
  3396. rect1->setBrush(br1);
  3397. calque_histogramme->addToGroup(rect1);
  3398. }
  3399.  
  3400. y2 = 12 - 10*n;
  3401. //s1.setNum(n+1);
  3402. s1=gamme_chromatique[n];
  3403. GraphicsTextItem = new QGraphicsTextItem(s1);
  3404. GraphicsTextItem->setFont(QFont("Arial", 8));
  3405. GraphicsTextItem->setDefaultTextColor(couleur1);
  3406. GraphicsTextItem->setPos(0, y2);
  3407. calque_histogramme->addToGroup(GraphicsTextItem);
  3408.  
  3409. }
  3410.  
  3411. s1 = denombre_diezes_a_la_cle();
  3412. Etiquette(10, -140, 0, s1, "#FFFF00", "#000000", "#FFFFFF", calque_histogramme );
  3413.  
  3414.  
  3415. }
  3416.  
  3417.  
  3418.  
  3419. void MainWindow::calcul_histogramme_degre() // degres de la gamme chromatique (= 1..12 )
  3420. {
  3421. for(int n=0; n<12; n++)
  3422. {
  3423. table_histogramme_degre[n]=0; // RAZ
  3424. }
  3425.  
  3426. uint16_t n_max = liste_NOTES.length();
  3427.  
  3428. for(int n=0; n<n_max; n++)
  3429. {
  3430. int M=liste_NOTES[n].midi;
  3431. if ((M>=40)&&(M<=82))
  3432. {
  3433. //int midi = M-40;
  3434. int H = calcul_hauteur_note(M);
  3435. table_histogramme_degre[H]++;
  3436. }
  3437. }
  3438. }
  3439.  
  3440.  
  3441. void MainWindow::affiche_histogramme()
  3442. {
  3443.  
  3444.  
  3445. //la suite fait planter !
  3446.  
  3447. if(radioButton_D->isChecked())
  3448. {
  3449. calcul_histogramme_durees();
  3450. affiche_histogramme_durees();
  3451. }
  3452. if(radioButton_M->isChecked())
  3453. {
  3454. calcul_histogramme_midi();
  3455. affiche_histogramme_midi();
  3456. }
  3457. if(radioButton_H->isChecked())
  3458. {
  3459. calcul_histogramme_degre();
  3460. affiche_histogramme_degre();
  3461. }
  3462. }
  3463.  
  3464.  
  3465.  
  3466. void MainWindow::trace_liste_notes() //dessine des cercles colorés (couleur midi) sur la grille
  3467. {
  3468. tri_liste_notes_par_num_barre(); //les notes seront triées par temps croissant
  3469. numerotation_liste_notes();
  3470.  
  3471. effacer_calque(scene4,calque_notes_manuelles);
  3472. effacer_calque(scene4,calque_notes_jouee);
  3473.  
  3474.  
  3475. QString s1;
  3476. int midi_i;
  3477. double x, y; //,dx, dbx, dy;
  3478. int numero;
  3479. uint16_t n_max = liste_NOTES.length();
  3480. int n_barre_1;
  3481. int x0a = spinBox_x0a->value();
  3482. double x0b = 10.0 * doubleSpinBox_x0b->value();
  3483. x0b += 20.0 * x0a;
  3484. QString blanc = "#FFFFFF";
  3485. QString jaune = "#FFFF00";
  3486. QString cyan = "#00FFFF";
  3487.  
  3488. for(int n=0; n<n_max; n++)
  3489. {
  3490. n_barre_1=0;
  3491. if (mode=='T') {n_barre_1 = liste_NOTES[n].n_barreT; }
  3492. if (mode=='M') {n_barre_1 = liste_NOTES[n].n_barreM; }
  3493. x = calcul_x_barre(n_barre_1);
  3494. midi_i = liste_NOTES[n].midi;
  3495.  
  3496. if ((midi_i >=40) && (midi_i <=83) )
  3497. {
  3498. y = calcul_y_note(midi_i);
  3499. int h1 = calcul_hauteur_note(midi_i);
  3500. QString couleur1 = liste_couleurs[h1];
  3501. ellipse1 = new QGraphicsEllipseItem(x-10, y-10, 20, 20);
  3502. if (mode=='T') {ellipse1->setPen(QColor(jaune));}
  3503. if (mode=='M') {ellipse1->setPen(QColor(blanc));}
  3504. ellipse1->setBrush(QColor(couleur1));
  3505. calque_notes_manuelles->addToGroup(ellipse1);
  3506.  
  3507. // inscrit le numéro de la note au centre de la note
  3508. numero = liste_NOTES[n].numero;
  3509. s1.setNum(numero);
  3510. GraphicsTextItem = new QGraphicsTextItem(s1);
  3511. GraphicsTextItem->setFont(QFont("Arial", 8));
  3512. GraphicsTextItem->setDefaultTextColor("#000000");
  3513. int x2 = x-12; if(numero<10){x2+=4;}
  3514. GraphicsTextItem->setPos(x2, y-10);
  3515. calque_notes_manuelles->addToGroup(GraphicsTextItem);
  3516. }
  3517. }
  3518. tracer_echelle_temps_TAB_NOTES();
  3519. }
  3520.  
  3521.  
  3522. void MainWindow::numerotation_liste_notes()
  3523. {
  3524. uint16_t i_max = liste_NOTES.length();
  3525.  
  3526. for(uint16_t n=0; n<i_max; n++)
  3527. {
  3528. liste_NOTES[n].numero = n;
  3529. }
  3530. }
  3531.  
  3532.  
  3533. void MainWindow::suppression_notes_invalides()
  3534. {
  3535. int midi;
  3536. int nb = 0;
  3537. uint16_t n_max = liste_NOTES.length();
  3538. if (n_max == 0) {return;}
  3539. bool boucler=true;
  3540. do
  3541. {
  3542. nb=0;
  3543. for(uint16_t n=0; n<n_max; n++)
  3544. {
  3545. midi = liste_NOTES[n].midi;
  3546. if ((midi <40) || (midi>82))
  3547. {
  3548. supprime_note(n);
  3549. if (n_max == 0) {return;}
  3550. n_max --;
  3551. nb++;
  3552. }
  3553. }
  3554. if (nb==0) {boucler=false;}
  3555. }
  3556. while (boucler == true);
  3557. }
  3558.  
  3559.  
  3560. void MainWindow::suppression_mesures()
  3561. {
  3562. //int midi;
  3563. uint16_t n_max = liste_NOTES.length();
  3564. int nb = 0;
  3565.  
  3566. bool boucler=true;
  3567. do
  3568. {
  3569. nb=0;
  3570. for(int n=0; n<n_max; n++)
  3571. {
  3572. //midi = liste_NOTES[n].midi;
  3573. /*
  3574.   if (midi == 100) // midi=100 codera pour les barres de mesures
  3575.   {
  3576.   supprime_note(n);
  3577.   n_max --;
  3578.   nb++;
  3579.   }
  3580. */
  3581. }
  3582. if (nb==0) {boucler=false;}
  3583. }
  3584. while (boucler == true);
  3585.  
  3586. }
  3587.  
  3588.  
  3589.  
  3590. void MainWindow::tri_liste_notes_par_num_barre()
  3591. {
  3592.  
  3593. // tri par bulles
  3594.  
  3595. int ba1, ba2; // barres
  3596. NOTE note_i;
  3597. uint16_t i_max = liste_NOTES.length();
  3598. if (i_max==0){return;}
  3599.  
  3600. for(int p=0; p<i_max; p++)
  3601. {
  3602. for(int n=0; n<i_max-1; n++)
  3603. {
  3604. if(mode=='T')
  3605. {
  3606. ba1=liste_NOTES[n].n_barreT;
  3607. ba2=liste_NOTES[n+1].n_barreT;
  3608. }
  3609. if(mode=='M')
  3610. {
  3611. ba1=liste_NOTES[n].n_barreM;
  3612. ba2=liste_NOTES[n+1].n_barreM;
  3613. }
  3614.  
  3615. if(ba1 > ba2)
  3616. {
  3617. //permutter les notes
  3618. note_i = liste_NOTES[n];
  3619. liste_NOTES[n] = liste_NOTES[n+1];
  3620. liste_NOTES[n+1] = note_i;
  3621. }
  3622. }
  3623. }
  3624. }
  3625.  
  3626.  
  3627.  
  3628. void MainWindow::ajout_note(int midi, int n_barreT, int n_barreM)
  3629. {
  3630. // ajout d'une note à la fin de la liste 'liste_NOTES[]'
  3631. NOTE note_i;
  3632. note_i.midi = midi;
  3633. note_i.n_barreT = n_barreT; // valeur discrète, entière : numéro de la barre de la grille temporelle
  3634. note_i.n_barreM = n_barreM;
  3635. liste_NOTES << note_i;
  3636. tri_liste_notes_par_num_barre();
  3637. }
  3638.  
  3639.  
  3640. void MainWindow::deplace_note(int n, int d)
  3641. {
  3642. //if (n<=0) {return;}
  3643. if (n >= liste_NOTES.length()) {return;}
  3644. NOTE note_i;
  3645. note_i = liste_NOTES[n];
  3646. if (mode == 'T') { note_i.n_barreT = note_i.n_barreT+d; }
  3647. if (mode == 'M') { note_i.n_barreM = note_i.n_barreM+d; }
  3648. liste_NOTES[n] = note_i;
  3649. surbrille_note(n, true);
  3650. }
  3651.  
  3652.  
  3653.  
  3654. void MainWindow::supprime_note(int16_t n)
  3655. {
  3656. int L = liste_NOTES.length();
  3657. if (L==0) {return;}
  3658.  
  3659. if (n<L)
  3660. {
  3661. liste_NOTES.remove(n);
  3662. effacer_calque(scene4, calque_notes_manuelles);
  3663. tri_liste_notes_par_num_barre(); //les notes seront triées par temps croissant
  3664. numerotation_liste_notes(); //les notes seront numérotées par temps croissant
  3665. trace_liste_notes();
  3666. }
  3667. }
  3668.  
  3669.  
  3670.  
  3671. int MainWindow::test_if_note_in_liste(int16_t n_barre, int midi)
  3672. {
  3673. // retourne la position dans la liste, sinon zéro;
  3674. int16_t barre_i=0; // accepte nb négatifs
  3675. int midi_i;
  3676. int i_max = liste_NOTES.length();
  3677. for(int n=0; n<i_max; n++)
  3678. {
  3679. if(mode=='T') {barre_i = liste_NOTES[n].n_barreT;}
  3680. if(mode=='M') {barre_i = liste_NOTES[n].n_barreM;}
  3681.  
  3682. midi_i = liste_NOTES[n].midi;
  3683.  
  3684. // int diff_n = abs(barre_i-n_barre);
  3685. //if ((diff_n ==0) && (midi_i == midi))
  3686.  
  3687. if ((barre_i == n_barre) && (midi_i == midi))
  3688. {
  3689. return n;
  3690. }
  3691. }
  3692. return -1000;
  3693. }
  3694.  
  3695.  
  3696. uint16_t MainWindow::calcul_n_barreM_note(uint16_t n)
  3697. //numero de la barre M la plus proche de la note posée sur une barre T
  3698. {
  3699. uint16_t nT = liste_NOTES[n].n_barreT;
  3700. mode='T';
  3701. int xT = calcul_x_barre(nT);
  3702.  
  3703. int trouve = 0;
  3704. int16_t i =-250;
  3705.  
  3706. mode='M';
  3707.  
  3708. // int x0a = spinBox_x0a->value();
  3709. // double x0b = 10.0 * doubleSpinBox_x0b->value();
  3710. // x0b += 20.0 * x0a;
  3711.  
  3712. while ((trouve == 0) && (i<250))
  3713. {
  3714. double xi = calcul_x_barre(i);
  3715. double diff = xT - xi;
  3716. if(diff<0)diff = -diff;
  3717.  
  3718. if(diff < calcul_pas_grille() /2 )
  3719. {
  3720. trouve = 1;
  3721. }
  3722. i++;
  3723. }
  3724. if (trouve == 0) {i=1;}
  3725. mode='T';
  3726. return i-1;
  3727. }
  3728.  
  3729.  
  3730. uint16_t MainWindow::calcul_n_barreT_note(uint16_t n)
  3731. {
  3732. //numero de la barre T la plus proche de la note posée sur une barre M
  3733. //toutefois cette fonction est à revoir, HS telle-quelle !
  3734.  
  3735. int16_t nM = liste_NOTES[n].n_barreM;
  3736. mode='M';
  3737. int xM = calcul_x_barre(nM);
  3738.  
  3739.  
  3740. int trouve = 0;
  3741. int16_t i = -500;
  3742. //spinBox_x0a->setValue(0);
  3743.  
  3744. mode='T';
  3745. double pas_T = calcul_pas_grille();
  3746. while ((trouve == 0) && (i<2000))
  3747. {
  3748. double xi = calcul_x_barre(i);
  3749. if (xi>0)
  3750. {
  3751. double diff = xM - xi;
  3752. if(diff<0)
  3753. {
  3754. diff = -diff;
  3755. }
  3756. if(diff < (pas_T /1.5) )
  3757. {
  3758. trouve = 1;
  3759. }
  3760. }
  3761. i++;
  3762. }
  3763. if (trouve == 0) {i=1;}
  3764. mode='M';
  3765. return i-1;
  3766. }
  3767.  
  3768.  
  3769.  
  3770. void MainWindow::affi_txt_en_couleur(int midi_i, QLineEdit *lineEdit_i)
  3771. {
  3772. int h1 = calcul_hauteur_note(midi_i);
  3773.  
  3774. QString c1 = liste_couleurs[h1];
  3775. QString c2 = "#000000";
  3776. lineEdit_i->setStyleSheet("color: " + c1 + "; background-color: " + c2 + "; font: 700 14pt 'Ubuntu';");
  3777. }
  3778.  
  3779.  
  3780.  
  3781. void MainWindow::encadre_midi(int n_midi) // dans la liste des notes à gauche
  3782. {
  3783. if (n_midi>82) {return;}
  3784.  
  3785. effacer_calque(scene3, calque_gradu_TAB_FRQ);
  3786. tracer_graduation_TAB_NOTES();
  3787. double x, dx, y, dy;
  3788.  
  3789. int dm = n_midi -40;
  3790. y = 645 - (dm * 16);
  3791.  
  3792. dy=16;
  3793. x=0;
  3794. dx=85;
  3795.  
  3796. rectangle1 = new QGraphicsRectItem(x, y, dx, dy);
  3797. QPen pen1;
  3798. pen1.setColor("#FFFFFF");
  3799. pen1.setWidth(2);
  3800. rectangle1->setPen(pen1);
  3801. calque_gradu_TAB_FRQ->addToGroup(rectangle1);
  3802. }
  3803.  
  3804.  
  3805. int MainWindow::num_barre(double xi) // en fonction de la position x
  3806. {
  3807. //double pas_grille = spinBox_dxa->value()/2.0 * zoom_x; // pas de la grille
  3808. //double offset_grille = 0; //75;
  3809. //double x_barre = offset_grille; //0
  3810.  
  3811. int n_barre=0; // numero de la barre verticale de la grille T temporelle (depuis le départ)
  3812. double x_barre=0;
  3813. bool trouve = false; // à priori
  3814. int n =-100; // nb négatif pour prendre en compte les notes situées en amont (à gauche) de la barre zéro
  3815. while ((n<2000) && (trouve == false))
  3816. {
  3817. double dx2 = xi- x_barre;
  3818. if (dx2<0) {dx2 = -dx2;}
  3819.  
  3820. if (dx2 < calcul_pas_grille()/2.0)
  3821. {
  3822. trouve = true;
  3823. n_barre = n; // numero de la barre verticale de la grille temporelle
  3824. }
  3825. x_barre = calcul_x_barre(n+1);
  3826. n++;
  3827. }
  3828.  
  3829. if (trouve == false) {return -1000;}
  3830. //if (n==0) {return -1000;}
  3831.  
  3832. return n_barre;
  3833. }
  3834.  
  3835.  
  3836.  
  3837. void MainWindow::mousePressEvent(QMouseEvent *event)
  3838. {
  3839. if(event->button() == Qt::RightButton) {return;}
  3840.  
  3841. qDebug() << "clic de gauche";
  3842.  
  3843. if (tabWidget_Global->currentIndex() != 1) {return;}
  3844.  
  3845. QString s1;
  3846. double x0, y0; // position cliquée
  3847.  
  3848. int n_barre=0; // numero de la barre verticale de la grille temporelle (depuis le départ)
  3849. int n2=0;
  3850.  
  3851. //double x_barre=0;
  3852. double x_min, x_max;
  3853. double y_min, y_max;
  3854.  
  3855. int midi=0; // midi
  3856.  
  3857. double scroll_x = graphicsView4->horizontalScrollBar()->value();
  3858. double scroll_y = graphicsView4->verticalScrollBar()->value();
  3859.  
  3860. graphicsView4->verticalScrollBar()->setValue(0);
  3861.  
  3862. s1.setNum(scroll_x); lineEdit_8->setText(s1);
  3863. s1.setNum(scroll_y); lineEdit_9->setText(s1);
  3864.  
  3865. x_min = graphicsView4->x();
  3866. x_max = x_min + graphicsView4->width();
  3867.  
  3868. y_min = graphicsView4->y()+60;
  3869. y_max = y_min + graphicsView4->height() + 32; // +32 sinon rate le mi grave (midi 40)
  3870.  
  3871. x_clic_ecran = event->position().x();
  3872. y_clic_ecran = event->position().y();
  3873.  
  3874. x0 = x_clic_ecran-102 + scroll_x; // position cliquée
  3875. y0 = y_clic_ecran-78 + scroll_y;
  3876.  
  3877.  
  3878. // ----------------------
  3879.  
  3880. if (x_clic_ecran > x_min && x_clic_ecran < x_max && y_clic_ecran > y_min && y_clic_ecran < y_max)
  3881. {
  3882. s1.setNum(x0); lineEdit_4->setText(s1);
  3883. s1.setNum(y0); lineEdit_5->setText(s1); // =481 foire !
  3884.  
  3885. // recherche (verticale) de la note midi la plus proche du point cliqué
  3886. int dm =0;
  3887. for(int n=0; n<=43; n++)
  3888. {
  3889. int d1= (700-y0) - 16*n; // 704
  3890. //d1=abs(d1);
  3891. if(d1<0){d1= -d1;}
  3892.  
  3893. if(d1 <= 8) // 8 sachant que l'espacement (vertical) de niveaux est = 16
  3894. {
  3895. dm = n;
  3896. }
  3897. }
  3898.  
  3899. // calcul de la valeur midi de la note
  3900. midi = 40 + dm;
  3901. encadre_midi(midi);
  3902.  
  3903. n_barre = num_barre(x0);
  3904.  
  3905. if (n_barre == -1000) {return;}
  3906.  
  3907. s1.setNum(midi);
  3908. lineEdit_7->setText(s1);
  3909.  
  3910. affi_txt_en_couleur(midi, lineEdit_7b);
  3911. lineEdit_7b->setText(nom_note(midi));
  3912.  
  3913. affi_txt_en_couleur(midi, lineEdit_7e);
  3914. QString s1;
  3915.  
  3916. s1=nom_note_GB(midi);
  3917. s1+=nom_octave_GB(midi);
  3918. lineEdit_7e->setText(s1);
  3919.  
  3920. double F = freq_mid(midi);
  3921. s1.setNum(F);
  3922. s1.replace('.',','); // ce qui permet un copié-collé direct dans 'Adacity'
  3923. lineEdit_7d->setText(s1);
  3924.  
  3925. n2 = test_if_note_in_liste(n_barre, midi); // si note in liste, -> n2 = num de la note
  3926.  
  3927. if (n2 != -1000) { QString s1; s1.setNum(n2); lineEdit_7c->setText(s1); }
  3928.  
  3929.  
  3930. // if (write_mode == 3) // SELECT
  3931. {
  3932. n2 = test_if_note_in_liste(n_barre, midi);
  3933. if (n2 != -1000) // si la note figure dans la liste...
  3934. {
  3935. effacer_calque(scene4, calque_notes_jouee);
  3936. num_note_cliquee = n2;
  3937.  
  3938. }
  3939. }
  3940.  
  3941. play_note(midi, 1);
  3942. surbrille_note(n2, true);
  3943.  
  3944. if (write_mode == 1) // WRITE (ajout d'une note)
  3945. {
  3946. n2 = test_if_note_in_liste(n_barre, midi);
  3947. if (n2 == -1000) // si la note ne figure pas déjà dans la liste...
  3948. {
  3949. // enregistre la note dans la liste (à la fin)
  3950. if(mode=='T') {ajout_note(midi, n_barre, 0);}
  3951. if(mode=='M') {ajout_note(midi, 0, n_barre);}
  3952. }
  3953. }
  3954.  
  3955. if (write_mode == 2) // EFFACE
  3956. {
  3957. n2 = test_if_note_in_liste(n_barre, midi);
  3958. if (n2 != -1000) // si la note figure dans la liste...
  3959. {
  3960. supprime_note(n2);
  3961. on_Bt_mode_R_clicked(); // repasse en mode LECTURE pour éviter d'effacer d'autres notes par erreur
  3962. }
  3963. }
  3964.  
  3965. /*
  3966.   if (mode_select == true)
  3967.   {
  3968.   n2 = test_if_note_in_liste(n_barre, midi);
  3969.   if (n2 != -1) // si la note figure dans la liste...
  3970.   {
  3971.   effacer_calque(scene4, calque_notes_jouee);
  3972.   num_note_cliquee = n2;
  3973.   surbrille_note(n2);
  3974.   }
  3975.   }
  3976. */
  3977. }
  3978. //int h1 = calcul_hauteur_note(midi);
  3979. //QColor couleur1 = liste_couleurs[h1];
  3980.  
  3981. effacer_calque(scene4,calque_notes_manuelles);
  3982. //effacer_calque(scene4,calque_notes_jouee);
  3983. tri_liste_notes_par_num_barre(); // les notes seront triées par num_barre croissant
  3984. numerotation_liste_notes(); // les notes seront numérotées par num_barre croissant
  3985. affiche_liste_notes();
  3986. trace_liste_notes();
  3987. surbrille_note(n2, true);
  3988.  
  3989. if (0) // 1 pour test (affiche une petite croix)
  3990. {
  3991. int d=10; // taille
  3992. QPen pen1; pen1.setColor("#FFFF00");
  3993. ligne1 = new QGraphicsLineItem(x0-d, y0-d, x0+d, y0+d);
  3994. ligne1->setPen(pen1);
  3995. calque_notes_manuelles->addToGroup(ligne1);
  3996. ligne1 = new QGraphicsLineItem(x0-d, y0+d, x0+d, y0-d);
  3997. ligne1->setPen(pen1);
  3998. calque_notes_manuelles->addToGroup(ligne1);
  3999. }
  4000.  
  4001. }
  4002.  
  4003.  
  4004. void MainWindow::contextMenuEvent(QContextMenuEvent *event)
  4005. //declenche le menu contextuel lors du clic de droite
  4006. {
  4007. qDebug() << "clic de droite";
  4008. return;
  4009.  
  4010. }
  4011.  
  4012.  
  4013. int MainWindow::joue_1_note_de_la_liste()
  4014. {
  4015. NOTE note_i1, note_i2;
  4016. int midi_i;
  4017. int barre1=0;
  4018. int barre2=0;
  4019. int d_barre;
  4020. QString s1;
  4021.  
  4022. QDateTime tpi;
  4023. tpi = QDateTime::currentDateTime();
  4024. qint64 tp_relatif = temps_0.msecsTo(tpi); // en ms
  4025. s1.setNum(tp_relatif);
  4026.  
  4027. uint16_t num_max = liste_NOTES.length();
  4028. if (num_max == 0) {return 0;}
  4029. if (num_max < 3) {return 0;}
  4030.  
  4031.  
  4032. if (num_note_jouee >= num_max-1) // -1 because 'liste_NOTES[num_note_jouee+1]' ci-dessous
  4033. {
  4034. return 0;
  4035. }
  4036. note_i1 = liste_NOTES[num_note_jouee];
  4037. note_i2 = liste_NOTES[num_note_jouee+1];
  4038.  
  4039. midi_i=note_i1.midi;
  4040.  
  4041. if(mode == 'T')
  4042. {
  4043. barre1 = note_i1.n_barreT;
  4044. barre2 = note_i2.n_barreT;
  4045. }
  4046. if(mode == 'M')
  4047. {
  4048. barre1 = note_i1.n_barreM;
  4049. barre2 = note_i2.n_barreM;
  4050. }
  4051.  
  4052. d_barre = barre2 - barre1;
  4053. if (d_barre < 0){d_barre = -d_barre;}
  4054.  
  4055. if (barre1 == barre2) // detection d'un accord (notes simultanées)
  4056. {
  4057. surbrille_note(num_note_jouee, false);
  4058. surbrille_note(num_note_jouee+1, false);
  4059. nb_acc++;
  4060. }
  4061. else
  4062. {
  4063. if (nb_acc == 0) {effacer_calque(scene4, calque_notes_jouee);}
  4064. surbrille_note(num_note_jouee, false);
  4065. if (midi_i >45) // on laisse résonner les basses
  4066. {
  4067. //player1->stop();
  4068. //player2->stop();
  4069. //player3->stop();
  4070. }
  4071. nb_acc--; if (nb_acc<0) {nb_acc=0;}
  4072. }
  4073.  
  4074. s1.setNum(num_note_jouee); lineEdit_7c->setText(s1);
  4075. lineEdit_7->setText("");
  4076. lineEdit_7b->setText("");
  4077.  
  4078. s1.setNum(midi_i) ;
  4079.  
  4080. if ( ! (checkBox_basses->isChecked() && midi_i > spinBox_filtre_2->value() ))
  4081. {
  4082. play_note(midi_i, d_barre);
  4083. encadre_midi(midi_i);
  4084. }
  4085.  
  4086. num_note_jouee++;
  4087. if(num_note_jouee > num_note_max)
  4088. {
  4089. Timer2->stop();
  4090. //num_note_jouee=0;
  4091. }
  4092.  
  4093. return d_barre; // permet de retrouver l'espacement temporel entre la note et celle qui suit.
  4094. }
  4095.  
  4096.  
  4097.  
  4098.  
  4099. void MainWindow::on_Bt_toggle_grille_T_clicked()
  4100. {
  4101. Bt_toggle_grille_T->setStyleSheet("background-color: rgb(0, 255, 0);"); // vert
  4102. Bt_toggle_grille_M->setStyleSheet("background-color: rgb(200, 200, 200);");
  4103.  
  4104. mode = 'T';
  4105. mode_grille_T();
  4106.  
  4107. // tri_liste_notes_par_num_barre(); //les notes seront triées par temps croissant
  4108. // numerotation_liste_notes(); //les notes seront numérotées par temps croissant
  4109. // affiche_liste_notes();
  4110. trace_liste_notes();
  4111. //effacer_calque(scene4, calque_echelle_temporelle_T);
  4112.  
  4113. }
  4114.  
  4115.  
  4116. void MainWindow::on_Bt_toggle_visu_notes_clicked()
  4117. {
  4118. if(visu_notes == true)
  4119. {
  4120. visu_notes = false;
  4121. Bt_toggle_visu_notes->setStyleSheet("background-color: rgb(200, 200, 200);");
  4122. effacer_calque(scene4, calque_notes_manuelles);
  4123. }
  4124. else
  4125. {
  4126. visu_notes = true;
  4127. Bt_toggle_visu_notes->setStyleSheet("background-color: rgb(0, 255, 0);"); // vert
  4128. trace_liste_notes();
  4129. }
  4130. }
  4131.  
  4132.  
  4133.  
  4134.  
  4135. void MainWindow::on_Bt_toggle_grille_M_clicked()
  4136. {
  4137. Bt_toggle_grille_M->setStyleSheet("background-color: rgb(0, 255, 0);"); // vert
  4138. Bt_toggle_grille_T->setStyleSheet("background-color: rgb(200, 200, 200);");
  4139.  
  4140. mode = 'M';
  4141. mode_grille_M();
  4142.  
  4143. //tri_liste_notes_par_num_barre(); //les notes seront triées par temps croissant
  4144. // numerotation_liste_notes(); //les notes seront numérotées par temps croissant
  4145. // affiche_liste_notes();
  4146. trace_liste_notes();
  4147. }
  4148.  
  4149.  
  4150.  
  4151.  
  4152.  
  4153. void MainWindow::mode_grille_T()
  4154. {
  4155. effacer_calque(scene4, calque_grille_T);
  4156. effacer_calque(scene4, calque_grille_M);
  4157. effacer_calque(scene4, calque_echelle_temporelle_T);
  4158. effacer_calque(scene4, calque_echelle_temporelle_M);
  4159.  
  4160. frame_7->setVisible(true);
  4161. //spinBox_dxa->setVisible(false);
  4162. doubleSpinBox_dxb->setVisible(false);
  4163. spinBox_x0a->setVisible(false);
  4164. doubleSpinBox_x0b->setVisible(false);
  4165.  
  4166. tracer_grille_T();
  4167. }
  4168.  
  4169.  
  4170.  
  4171. void MainWindow::mode_grille_M()
  4172. {
  4173. effacer_calque(scene4, calque_grille_T);
  4174. effacer_calque(scene4, calque_grille_M);
  4175. effacer_calque(scene4, calque_echelle_temporelle_T);
  4176. effacer_calque(scene4, calque_echelle_temporelle_M);
  4177.  
  4178. frame_7->setVisible(false);
  4179.  
  4180. //spinBox_dxa->setVisible(true);
  4181. doubleSpinBox_dxb->setVisible(true);
  4182. spinBox_x0a->setVisible(true);
  4183. doubleSpinBox_x0b->setVisible(true);
  4184.  
  4185. tracer_grille_M();
  4186. }
  4187.  
  4188.  
  4189.  
  4190. void MainWindow::on_Bt_save_notes_clicked()
  4191. {
  4192. int r1, r2;
  4193.  
  4194. QDate date_systeme = QDate::currentDate();
  4195. QTime heure_systeme = QTime::currentTime();
  4196.  
  4197. QString date1 = date_systeme.toString("yyyyMMdd");
  4198. QString heure1 = heure_systeme.toString();
  4199. QString date_out = date1 + "_" + heure1;
  4200.  
  4201. r1 = save_fichier_NOTES(date_out);
  4202. r2 = save_fichier_FRQ(date_out);
  4203.  
  4204. if ((r1 + r2) != 2) // si = 2 -> aucun fichier enregistré, alors on n'affiche pas le message
  4205. {
  4206. QMessageBox msgBox;
  4207. QString s1="Fichiers enregistrés dans : \n" + string_currentDir + "/";
  4208. msgBox.setText(s1); msgBox.exec();
  4209. }
  4210. }
  4211.  
  4212.  
  4213.  
  4214. void MainWindow::on_Bt_load_notes_clicked()
  4215. {
  4216. uint16_t n_max = liste_NOTES.length();
  4217.  
  4218. if (n_max != 0) // pour éviter d'enregistrer un fichier vide lors du 1er chargement des notes
  4219. {
  4220. QMessageBox msgBox;
  4221.  
  4222. msgBox.setText("Confirmation de chargement");
  4223. msgBox.setInformativeText("Un enregistrement des notes va être effectué au préalable.\n \n"
  4224. "Si clic sur No, les notes actuelles seront perdues.\n \n"
  4225. "Si clic sur Cancel, opération annulée");
  4226.  
  4227. msgBox.setStandardButtons(QMessageBox::No | QMessageBox::Ok | QMessageBox::Cancel);
  4228. msgBox.setDefaultButton(QMessageBox::Cancel);
  4229. int ret = msgBox.exec();
  4230. if (ret == QMessageBox::Cancel ) { return; }
  4231. if (ret == QMessageBox::Ok ) { on_Bt_save_notes_clicked(); }
  4232. }
  4233.  
  4234.  
  4235. liste_NOTES.clear();
  4236. effacer_calque(scene4,calque_notes_manuelles);
  4237. effacer_calque(scene4,calque_notes_auto);
  4238. effacer_calque(scene4,calque_notes_jouee);
  4239. effacer_calque(scene5, calque_histogramme );
  4240. effacer_calque(scene4, calque_echelle_temporelle_T);
  4241. effacer_calque(scene4, calque_echelle_temporelle_M);
  4242.  
  4243. load_fichier_NOTES("");
  4244.  
  4245. suppression_notes_invalides();
  4246.  
  4247. tri_liste_notes_par_num_barre(); //les notes seront triées par temps croissant
  4248. numerotation_liste_notes();
  4249.  
  4250. calcul_histogramme_durees();
  4251. affiche_histogramme_durees();
  4252. on_Bt_toggle_grille_M_clicked();
  4253. }
  4254.  
  4255.  
  4256. void MainWindow::on_Bt_joue_passage_clicked()
  4257. {
  4258. if (liste_NOTES.length() == 0) {return;}
  4259.  
  4260. if (lecture_en_cours == true)
  4261. {
  4262. Timer2->stop();
  4263. Bt_joue_passage->setText(">");
  4264. Timer2->setInterval(0);
  4265. lecture_en_cours = false;
  4266. }
  4267. else
  4268. {
  4269. Bt_joue_passage->setText("[]");
  4270.  
  4271. Timer2->start(500);
  4272.  
  4273. int note_de_depart = spinBox_10->value();
  4274. int nb_notes_a_jouer = spinBox_11->value()-1;
  4275.  
  4276. num_note_jouee = note_de_depart;
  4277. num_note_max = note_de_depart + nb_notes_a_jouer;
  4278. if (num_note_max > liste_NOTES.length()-1) { num_note_max = liste_NOTES.length()-1;}
  4279.  
  4280. NOTE note_i = liste_NOTES[note_de_depart];
  4281. //double x_note = 80 + note_i.n_barreT * spinBox_dxa->value()/2.0 * zoom_x;
  4282. // graphicsView4->horizontalScrollBar()->setValue(x_note - 100);
  4283.  
  4284. Timer2->start(500);
  4285. lecture_en_cours = true;
  4286. }
  4287.  
  4288. }
  4289.  
  4290.  
  4291. void MainWindow::on_Bt_joue_wav_clicked()
  4292. {
  4293. QStringList arguments;
  4294. arguments << string_currentFile;
  4295. QString program = "audacity"; //"audacious"
  4296. QProcess *myProcess = new QProcess();
  4297. myProcess->start(program, arguments);
  4298. }
  4299.  
  4300.  
  4301.  
  4302. void MainWindow::on_Bt_joue_wav_2_clicked()
  4303. {
  4304. on_Bt_joue_wav_clicked();
  4305. }
  4306.  
  4307.  
  4308. void MainWindow::on_Btn_RAZ_notes_clicked()
  4309. {
  4310. QMessageBox msgBox;
  4311. msgBox.setText("Erase notes");
  4312. msgBox.setInformativeText("Effacer toutes les notes ?");
  4313. msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
  4314. msgBox.setDefaultButton(QMessageBox::Cancel);
  4315. int ret = msgBox.exec();
  4316.  
  4317. if (ret == QMessageBox::Ok )
  4318. {
  4319. liste_NOTES.clear();
  4320. effacer_calque(scene4,calque_notes_manuelles);
  4321. effacer_calque(scene4, calque_notes_auto);
  4322. affiche_liste_notes();
  4323. }
  4324. }
  4325.  
  4326.  
  4327. void MainWindow::on_Btn_RAZ_notes_2_clicked()
  4328. {
  4329. QMessageBox msgBox;
  4330. msgBox.setText("Erase certaines notes");
  4331. msgBox.setInformativeText("Effacer des notes ?");
  4332. msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
  4333. msgBox.setDefaultButton(QMessageBox::Cancel);
  4334. int ret = msgBox.exec();
  4335.  
  4336. if (ret == QMessageBox::Ok )
  4337. {
  4338. int n = spinBox_n_raz->value();
  4339. //int n_max = liste_NOTES.length();
  4340.  
  4341. int n_max = liste_NOTES.length();
  4342. if (n<n_max)
  4343. {
  4344. liste_NOTES.remove(n, n_max-n);
  4345. }
  4346.  
  4347. int n_max2 = liste_ENR_FFT.length();
  4348. int n2= 300*n;
  4349. if (n2<n_max2)
  4350. {
  4351. liste_ENR_FFT.remove(n2, n_max2-n2);
  4352. }
  4353.  
  4354. effacer_calque(scene4, calque_notes_manuelles);
  4355. trace_liste_notes();
  4356.  
  4357. effacer_calque(scene4, calque_TAB_FRQ);
  4358. retracer_TAB_FRQ();
  4359.  
  4360. //effacer_calque(scene4,calque_notes_manuelles);
  4361. //effacer_calque(scene4, calque_notes_auto);
  4362. //affiche_liste_notes();
  4363. }
  4364. }
  4365.  
  4366.  
  4367.  
  4368. void MainWindow::on_spinBox_8_textChanged()
  4369. {
  4370. effacer_calque(scene4, calque_echelle_temporelle_T);
  4371. effacer_calque(scene4, calque_echelle_temporelle_M);
  4372. tracer_echelle_temps_TAB_NOTES();
  4373. }
  4374.  
  4375.  
  4376. void MainWindow::on_doubleSpinBox_x0_valueChanged(double arg1)
  4377. {
  4378.  
  4379. //double pas_grille = spinBox_dt->value()/2.0 * zoom_x;
  4380. //double offset_x = 10 * arg1 + spinBox_d_barres->value() * pas_grille;
  4381. // calque_TAB_FRQ->setPos(offset_x, 0);
  4382. // calque_notes_auto->setPos(offset_x, 0);
  4383.  
  4384. effacer_calque(scene4, calque_grille_M);
  4385. tracer_grille_M();
  4386. // effacer_calque(scene4, calque_notes_manuelles);
  4387. // affiche_liste_notes();
  4388. // trace_liste_notes();
  4389. // effacer_calque(scene4, calque_echelle_temporelle_T);
  4390. // tracer_echelle_temps_TAB_NOTES();
  4391. }
  4392.  
  4393.  
  4394. void MainWindow::on_spinBox_dxa_valueChanged(int arg1)
  4395. {
  4396.  
  4397. //doubleSpinBox_dxb->setValue(0);
  4398. effacer_calque(scene4, calque_echelle_temporelle_T);
  4399. effacer_calque(scene4, calque_grille_M);
  4400. tracer_grille_M();
  4401. effacer_calque(scene4, calque_notes_manuelles);
  4402. affiche_liste_notes();
  4403. //trace_liste_notes();
  4404.  
  4405. tracer_echelle_temps_TAB_NOTES();
  4406. if (visu_notes == true) {trace_liste_notes();}
  4407.  
  4408. // on_Bt_copy_nt_T_to_M_clicked();
  4409. }
  4410.  
  4411.  
  4412. void MainWindow::on_doubleSpinBox_dxb_valueChanged(double arg1)
  4413. {
  4414. effacer_calque(scene4, calque_grille_M);
  4415. effacer_calque(scene4, calque_echelle_temporelle_T);
  4416. effacer_calque(scene4, calque_echelle_temporelle_M);
  4417. effacer_calque(scene4, calque_notes_manuelles);
  4418.  
  4419. on_Bt_copy_nt_T_to_M_clicked();
  4420.  
  4421. affiche_liste_notes();
  4422. trace_liste_notes();
  4423. tracer_grille_M();
  4424. tracer_echelle_temps_TAB_NOTES();
  4425.  
  4426. //if (visu_notes == true) {trace_liste_notes();}
  4427.  
  4428. // on_Bt_copy_nt_T_to_M_clicked();
  4429.  
  4430. }
  4431.  
  4432.  
  4433. void MainWindow::on_Bt_mode_R_clicked() // LECTURE
  4434. {
  4435. write_mode=0;
  4436. //mode_select=false;
  4437. MainWindow::setCursor(Qt::ArrowCursor);
  4438. Bt_mode_R->setStyleSheet("background-color: rgb(0, 255, 0);"); // vert
  4439. Bt_mode_W->setStyleSheet("background-color: rgb(200, 200, 200);");
  4440. Bt_mode_E->setStyleSheet("background-color: rgb(200, 200, 200);");
  4441.  
  4442. }
  4443.  
  4444.  
  4445. void MainWindow::on_Bt_mode_W_clicked() // AJOUT
  4446. {
  4447. write_mode=1;
  4448. //mode_select=false;
  4449. //MainWindow::setCursor(Qt::SplitHCursor);
  4450. effacer_calque(scene4, calque_notes_jouee);
  4451. Bt_mode_W->setStyleSheet("background-color: rgb(255, 0, 0);"); // rouge
  4452. Bt_mode_R->setStyleSheet("background-color: rgb(200, 200, 200);");
  4453. Bt_mode_E->setStyleSheet("background-color: rgb(200, 200, 200);");
  4454.  
  4455. }
  4456.  
  4457.  
  4458. void MainWindow::on_Bt_mode_E_clicked() // EFFACE
  4459. {
  4460. write_mode=2;
  4461. //mode_select=false;
  4462. //MainWindow::setCursor(Qt::SplitHCursor);
  4463. Bt_mode_E->setStyleSheet("background-color: rgb(0, 200, 200);"); // cyan
  4464. Bt_mode_W->setStyleSheet("background-color: rgb(200, 200, 200);");
  4465. Bt_mode_R->setStyleSheet("background-color: rgb(200, 200, 200);");
  4466.  
  4467. }
  4468.  
  4469.  
  4470.  
  4471. void MainWindow::on_Bt_deplace_L_clicked()
  4472. {
  4473. write_mode=3;
  4474.  
  4475. Bt_mode_E->setStyleSheet("background-color: rgb(200, 200, 200);");
  4476. Bt_mode_W->setStyleSheet("background-color: rgb(200, 200, 200);");
  4477. Bt_mode_R->setStyleSheet("background-color: rgb(200, 200, 200);");
  4478.  
  4479. effacer_calque(scene4, calque_notes_manuelles);
  4480. effacer_calque(scene4, calque_notes_jouee);
  4481. deplace_note(num_note_cliquee, -1);
  4482. affiche_liste_notes();
  4483. trace_liste_notes();
  4484. }
  4485.  
  4486.  
  4487. void MainWindow::on_Bt_deplace_R_clicked()
  4488. {
  4489. write_mode=3;
  4490. Bt_mode_E->setStyleSheet("background-color: rgb(200, 200, 200);");
  4491. Bt_mode_W->setStyleSheet("background-color: rgb(200, 200, 200);");
  4492. Bt_mode_R->setStyleSheet("background-color: rgb(200, 200, 200);");
  4493.  
  4494. effacer_calque(scene4, calque_notes_manuelles);
  4495. effacer_calque(scene4, calque_notes_jouee);
  4496.  
  4497. deplace_note(num_note_cliquee, 1);
  4498. affiche_liste_notes();
  4499. trace_liste_notes();
  4500. }
  4501.  
  4502.  
  4503. void MainWindow::on_Bt_scan_auto_clicked()
  4504. {
  4505. if (! wav_ok) {return;}
  4506. if ( ! liste_ENR_FFT.isEmpty()) {on_Bt_efface_clicked();}
  4507.  
  4508. on_Bt_toggle_visu_notes_clicked();
  4509.  
  4510. if (rapide)
  4511. {
  4512. tabWidget_Global->setCurrentIndex(1);
  4513.  
  4514. on_Bt_RAZ_clicked();
  4515.  
  4516. MainWindow::setCursor(Qt::WaitCursor);
  4517. effacer_calque(scene4, calque_TAB_FRQ );
  4518. effacer_calque(scene4, calque_echelle_temporelle_T);
  4519.  
  4520. mode_grille_T();
  4521. analyse_tout();
  4522. MainWindow::setCursor(Qt::ArrowCursor);
  4523. }
  4524. else {Timer1->start(10);}
  4525.  
  4526. }
  4527.  
  4528.  
  4529.  
  4530. void MainWindow::on_Bt_jouer_tout_clicked()
  4531. {
  4532. if (liste_NOTES.length() == 0) {return;}
  4533.  
  4534. if (lecture_en_cours == true)
  4535. {
  4536. lecture_en_cours = false;
  4537. Timer2->stop();
  4538. Bt_jouer_tout->setText(">");
  4539. }
  4540. else
  4541. {
  4542. Bt_jouer_tout->setText("[]");
  4543.  
  4544. graphicsView4->horizontalScrollBar()->setValue(0);
  4545. memo_scroll_x = 0;
  4546.  
  4547. Timer2->stop();
  4548. num_note_depart = 0;
  4549. num_note_max = liste_NOTES.length();//-1;
  4550. if (num_note_max < 1) {return;}
  4551. num_note_jouee = 0;
  4552. num_barre_en_cours=0;
  4553.  
  4554. temps_0 = QDateTime::currentDateTime();
  4555. Timer2->start(100); //voir la fonction 'Tic2()' qui va jouer les notes
  4556. lecture_en_cours = true;
  4557. }
  4558. }
  4559.  
  4560.  
  4561.  
  4562. void MainWindow::on_Bt_toggle_visu_freq_clicked()
  4563. {
  4564. if(visu_freq == 0)
  4565. {
  4566. visu_freq = 1;
  4567. Bt_toggle_visu_freq->setStyleSheet("background-color: rgb(0, 255, 0);"); // vert
  4568. calque_TAB_FRQ->setVisible(true);
  4569. }
  4570. else
  4571. {
  4572. visu_freq = 0;
  4573. Bt_toggle_visu_freq->setStyleSheet("background-color: rgb(200, 200, 200);");
  4574. calque_TAB_FRQ->setVisible(false);
  4575. }
  4576. }
  4577.  
  4578.  
  4579. void MainWindow::on_Bt_efface_2_clicked() // sur tab FREQ-NOTES
  4580. {
  4581. on_Bt_efface_clicked(); // (celui de l'autre tab FFT)
  4582. }
  4583.  
  4584.  
  4585.  
  4586.  
  4587.  
  4588. void MainWindow::on_doubleSpinBox_t0_valueChanged()
  4589. {
  4590. effacer_calque(scene4, calque_grille_M);
  4591. effacer_calque(scene4, calque_echelle_temporelle_T);
  4592. effacer_calque(scene4, calque_notes_manuelles);
  4593.  
  4594. affiche_liste_notes();
  4595. trace_liste_notes();
  4596.  
  4597. tracer_echelle_temps_TAB_NOTES();
  4598. tracer_grille_M();
  4599. }
  4600.  
  4601.  
  4602.  
  4603. void MainWindow::maj_TAB_NOTES()
  4604. {
  4605. effacer_calque(scene4, calque_grille_M);
  4606. effacer_calque(scene4, calque_notes_manuelles);
  4607. effacer_calque(scene4, calque_notes_auto);
  4608. effacer_calque(scene4, calque_echelle_temporelle_T);
  4609. effacer_calque(scene4, calque_TAB_FRQ);
  4610.  
  4611. retracer_TAB_FRQ();
  4612. trace_liste_notes();
  4613. tracer_echelle_temps_TAB_NOTES();
  4614. tracer_grille_M();
  4615. }
  4616.  
  4617.  
  4618.  
  4619. void MainWindow::on_spinBox_zoom_2_valueChanged(int arg1)
  4620. {
  4621. zoom_x = arg1;
  4622. MainWindow::setCursor(Qt::WaitCursor);
  4623. effacer_calque(scene4, calque_grille_T);
  4624. maj_TAB_NOTES();
  4625. MainWindow::setCursor(Qt::ArrowCursor);
  4626. }
  4627.  
  4628.  
  4629.  
  4630. void MainWindow::on_pushButton_9_clicked()
  4631. {
  4632. QMessageBox msgBox;
  4633. QString s1;
  4634. s1 = "Le n° barre est compté depuis le début.";
  4635. s1 += "\n";
  4636.  
  4637. msgBox.setText(s1);
  4638. msgBox.exec();
  4639. }
  4640.  
  4641.  
  4642. void MainWindow::on_spinBox_offset_valueChanged()
  4643. {
  4644. //do_FFT_freq_midi();
  4645. }
  4646.  
  4647.  
  4648.  
  4649. void MainWindow::on_spinBox_d_barres_valueChanged()
  4650. {
  4651. double pas_grille = doubleSpinBox_dxb->value()/2.0 * zoom_x;
  4652. double offset_x = 10 * doubleSpinBox_x0b->value() + spinBox_d_barres->value() * pas_grille;
  4653. calque_TAB_FRQ->setPos(offset_x, 0);
  4654. }
  4655.  
  4656.  
  4657. void MainWindow::on_Bt_decale_notes_L_clicked()
  4658. {
  4659. decalle_notes(-1);
  4660. effacer_calque(scene4,calque_notes_manuelles);
  4661. affiche_liste_notes(); // en texte
  4662. trace_liste_notes(); // ellipses
  4663. }
  4664.  
  4665.  
  4666. void MainWindow::on_Bt_decale_notes_R_clicked()
  4667. {
  4668. decalle_notes(1);
  4669. effacer_calque(scene4,calque_notes_manuelles);
  4670. affiche_liste_notes(); // en texte
  4671. trace_liste_notes(); // ellipses
  4672. }
  4673.  
  4674.  
  4675.  
  4676. void MainWindow::on_tableWidget_type_M_cellClicked(int row, int column)
  4677. {
  4678. switch (row)
  4679. {
  4680. case 0: {lineEdit_10->setText("2/4"); Ta=2; Tb=4;} break; // Ta et Tb variables globales
  4681. case 1: {lineEdit_10->setText("3/4"); Ta=3; Tb=4;} break;
  4682. case 2: {lineEdit_10->setText("4/4"); Ta=4; Tb=4;} break;
  4683. default: break;
  4684. }
  4685. tracer_grille_M();
  4686. }
  4687.  
  4688.  
  4689.  
  4690. void MainWindow::on_checkBox_flitrer_clicked()
  4691. {
  4692. /*
  4693.   if (checkBox_flitrer->isChecked())
  4694.   {
  4695.   textEdit_ETAT->setText("Mode Filtré : \n Ne sont représentés que les signaux dont l'amplitude est supérieure au seuil choisi");
  4696.   }
  4697.   else
  4698.   {
  4699.   textEdit_ETAT->setText("Mode non-filtré : \n Tous les signaux issus de la FFT sont représentés");
  4700.   }
  4701. */
  4702.  
  4703. MainWindow::setCursor(Qt::WaitCursor);
  4704. maj_TAB_NOTES();
  4705. MainWindow::setCursor(Qt::ArrowCursor);
  4706. }
  4707.  
  4708. /*
  4709. void MainWindow::on_spinBox_filtre_valueChanged()
  4710. {
  4711.   if (checkBox_flitrer->isChecked())
  4712.   {
  4713.   MainWindow::setCursor(Qt::WaitCursor);
  4714.   maj_TAB_NOTES();
  4715.   MainWindow::setCursor(Qt::ArrowCursor);
  4716.   }
  4717. }
  4718. */
  4719. /*
  4720. void MainWindow::on_doubleSpinBox_gain_valueChanged()
  4721. {
  4722.   MainWindow::setCursor(Qt::WaitCursor);
  4723.   effacer_calque(scene4, calque_TAB_FRQ);
  4724.   retracer_TAB_FRQ();
  4725.   MainWindow::setCursor(Qt::ArrowCursor);
  4726. }
  4727. */
  4728.  
  4729. void MainWindow::on_Bt_open_DIR_clicked()
  4730. {
  4731. QString s1, path1;
  4732.  
  4733. path1 = string_currentDir;
  4734.  
  4735. QProcess process1;
  4736. process1.setProgram("caja");
  4737. process1.setArguments({path1});
  4738. process1.startDetached();
  4739. }
  4740.  
  4741.  
  4742.  
  4743. void MainWindow::on_Bt_goto_clicked()
  4744. {
  4745.  
  4746. QString s1;
  4747. int n = lineEdit_7c->text().toInt();
  4748. if ((n<0) || (n>=liste_NOTES.length())) {return;}
  4749.  
  4750. spinBox_10->setValue(n);
  4751. NOTE note_i = liste_NOTES[n];
  4752.  
  4753. //double x_note = 80 + note_i.n_barreT * spinBox_dxa->value()/2.0 * zoom_x;
  4754.  
  4755. num_note_jouee = n;
  4756. surbrille_note(n, false);
  4757.  
  4758. int midi = note_i.midi;
  4759. s1.setNum(midi);
  4760.  
  4761. lineEdit_7->setText(s1);
  4762. affi_txt_en_couleur(midi, lineEdit_7b); // nom de la note
  4763. //affi_txt_en_couleur(midi, lineEdit_7e);
  4764.  
  4765. // graphicsView4->horizontalScrollBar()->setValue(x_note - 200);
  4766.  
  4767. }
  4768.  
  4769.  
  4770. void MainWindow::on_doubleSpinBox_T0_valueChanged(double arg1)
  4771. {
  4772. tracer_echelle_temps_TAB_NOTES();
  4773. }
  4774.  
  4775.  
  4776. void MainWindow::on_Bt_test1_clicked()
  4777. {
  4778. QString s1;
  4779. double valeur;
  4780.  
  4781. for (int n = 0; n <= 255; n+=1)
  4782. {
  4783. valeur = (double )n / 255;
  4784. s1 = calcul_couleur(valeur);
  4785.  
  4786. rectangle1 = new QGraphicsRectItem(n, 200, 2, 5);
  4787. QPen pen1;
  4788. pen1.setColor(s1);
  4789. pen1.setWidth(2);
  4790. rectangle1->setPen(pen1);
  4791. calque_grille_M->addToGroup(rectangle1);
  4792. }
  4793. }
  4794.  
  4795.  
  4796. void MainWindow::on_Bt_durees_div2_clicked()
  4797. {
  4798.  
  4799.  
  4800. uint16_t n_max = liste_NOTES.length();
  4801. if (n_max == 0) {return;}
  4802.  
  4803. NOTE note_i;
  4804. for(int n=0; n<n_max; n++) //n_max
  4805. {
  4806. note_i=liste_NOTES[n];
  4807.  
  4808. int n_barre =note_i.n_barreT;
  4809. n_barre /=2;
  4810. note_i.n_barreT = n_barre;
  4811.  
  4812. liste_NOTES[n] = note_i;
  4813. }
  4814.  
  4815. effacer_calque(scene4,calque_notes_manuelles);
  4816. affiche_liste_notes(); // en texte
  4817. trace_liste_notes(); // ellipses
  4818. }
  4819.  
  4820.  
  4821. void MainWindow::on_Bt_durees_mult2_clicked()
  4822. {
  4823.  
  4824. uint16_t n_max = liste_NOTES.length();
  4825. if (n_max == 0) {return;}
  4826.  
  4827. NOTE note_i;
  4828. for(int n=0; n<n_max; n++) //n_max
  4829. {
  4830. note_i=liste_NOTES[n];
  4831.  
  4832. int n_barre =note_i.n_barreT;
  4833. n_barre *=2;
  4834. note_i.n_barreT = n_barre;
  4835.  
  4836. liste_NOTES[n] = note_i;
  4837. }
  4838.  
  4839. effacer_calque(scene4,calque_notes_manuelles);
  4840. affiche_liste_notes(); // en texte
  4841. trace_liste_notes(); // ellipses
  4842.  
  4843. }
  4844.  
  4845.  
  4846.  
  4847. void MainWindow::on_Bt_div2_clicked()
  4848. {
  4849. gain /=sqrt(2); // en fait / par racine carrée de deux pour plus de finesse
  4850. MainWindow::setCursor(Qt::WaitCursor);
  4851. effacer_calque(scene4, calque_TAB_FRQ);
  4852. retracer_TAB_FRQ();
  4853. MainWindow::setCursor(Qt::ArrowCursor);
  4854. }
  4855.  
  4856.  
  4857. void MainWindow::on_pushButton_clicked()
  4858. {
  4859. gain *=sqrt(2);
  4860. MainWindow::setCursor(Qt::WaitCursor);
  4861. effacer_calque(scene4, calque_TAB_FRQ);
  4862. retracer_TAB_FRQ();
  4863. MainWindow::setCursor(Qt::ArrowCursor);
  4864. }
  4865.  
  4866.  
  4867. void MainWindow::on_Bt_next_clicked()
  4868. {
  4869. double scroll_x = graphicsView4->horizontalScrollBar()->value();
  4870. graphicsView4->horizontalScrollBar()->setValue(scroll_x + 800);
  4871.  
  4872. }
  4873.  
  4874.  
  4875. void MainWindow::on_Bt_prev_clicked()
  4876. {
  4877. double scroll_x = graphicsView4->horizontalScrollBar()->value();
  4878. graphicsView4->horizontalScrollBar()->setValue(scroll_x - 800);
  4879. }
  4880.  
  4881.  
  4882. void MainWindow::on_Bt_debut_clicked()
  4883. {
  4884. graphicsView4->horizontalScrollBar()->setValue(0);
  4885. }
  4886.  
  4887.  
  4888. void MainWindow::on_Bt_fin_clicked()
  4889. {
  4890. graphicsView4->horizontalScrollBar()->setValue(10000);
  4891. }
  4892.  
  4893.  
  4894.  
  4895. void MainWindow::on_bt_test_clicked()
  4896. {
  4897.  
  4898.  
  4899. }
  4900.  
  4901.  
  4902. void MainWindow::on_Bt_detection_notes_clicked()
  4903. {
  4904. effacer_calque(scene4,calque_notes_manuelles);
  4905. effacer_calque(scene4,calque_notes_auto);
  4906. detection_notes_auto();
  4907. on_Bt_toggle_visu_notes_clicked();
  4908.  
  4909. }
  4910.  
  4911.  
  4912. void MainWindow::on_Bt_toggle_visu_notes_auto_clicked()
  4913. {
  4914. if(visu_notes_auto == 0)
  4915. {
  4916. visu_notes_auto = 1;
  4917. Bt_toggle_visu_notes_auto->setStyleSheet("background-color: rgb(0, 255, 0);"); // vert
  4918. calque_notes_auto->setVisible(true);
  4919. //detection_notes_auto();
  4920. // tri_liste_notes_par_num_barre(); //les notes seront triées par temps croissant
  4921. //numerotation_liste_notes(); //les notes seront numérotées par temps croissant
  4922. // affiche_liste_notes();
  4923. // trace_liste_notes();
  4924. }
  4925. else
  4926. {
  4927. Bt_toggle_visu_notes_auto->setStyleSheet("background-color: rgb(200, 200, 200);");
  4928. visu_notes_auto = 0;
  4929. //effacer_calque(scene4,calque_notes_auto);
  4930. calque_notes_auto->setVisible(false);
  4931. }
  4932. }
  4933.  
  4934.  
  4935. void MainWindow::on_Bt_m10_clicked()
  4936. {
  4937. doubleSpinBox_vitesse->setValue(doubleSpinBox_vitesse->value()-10);
  4938. }
  4939.  
  4940.  
  4941. void MainWindow::on_Bt_p10_clicked()
  4942. {
  4943. doubleSpinBox_vitesse->setValue(doubleSpinBox_vitesse->value()+10);
  4944. }
  4945.  
  4946.  
  4947. void MainWindow::on_doubleSpinBox_gain_valueChanged(double arg1)
  4948. {
  4949. tracer_signal_complet();
  4950. }
  4951.  
  4952.  
  4953. void MainWindow::on_Bt_test2_clicked()
  4954. {
  4955. //calcul_histogramme_durees();
  4956. //affiche_histogramme_durees();
  4957. //tracer_grille_libre();
  4958.  
  4959. //QDate date_systeme;
  4960. //QTime heure_systeme;
  4961. QDate date_systeme = QDate::currentDate();
  4962. //QTime heure_systeme = QTime::currentTime();
  4963.  
  4964. //qDebug() << "date_systeme" << date_systeme;
  4965. //qDebug() << "heure_systeme" << heure_systeme;
  4966. }
  4967.  
  4968.  
  4969. void MainWindow::on_Bt_open_DIR_2_clicked()
  4970. {
  4971. on_Bt_open_DIR_clicked();
  4972. }
  4973.  
  4974.  
  4975. void MainWindow::on_spinBox_nb_barres_valueChanged(int arg1)
  4976. {
  4977. effacer_calque(scene4, calque_grille_T);
  4978. tracer_grille_T();
  4979. }
  4980.  
  4981.  
  4982. void MainWindow::on_spinBox_barre_zero_valueChanged(int arg1)
  4983. {
  4984. effacer_calque(scene4, calque_grille_T);
  4985. tracer_grille_T();
  4986. }
  4987.  
  4988.  
  4989. void MainWindow::on_pushButton_10_clicked()
  4990. {
  4991. QMessageBox msgBox;
  4992. QString s1;
  4993. s1 = "Les notes sont dans une premier temps attachées à la grille T (Temporelle, fixe, 1/40s)"; s1 += "\n";
  4994. s1 += "Ensuite la grille M (Mesures) permet"; s1 += "\n";
  4995. s1 += "de placer leur double au plus près du tempo théorique"; s1 += "\n";
  4996. s1 += "La grille M (Mesures) doit être configurée manuellement"; s1 += "\n";
  4997. s1 += "(par 'x0' et 'dt' en haut)"; s1 += "\n";
  4998. s1 += "Le bouton 'Place T->M' sert à créer ces doubles"; s1 += "\n";
  4999. s1 += "et les place automatiquement sur la barre de mesure la plus proche"; s1 += "\n";
  5000.  
  5001. s1 += ""; s1 += "\n";
  5002.  
  5003. msgBox.setText(s1);
  5004. msgBox.exec();
  5005. }
  5006.  
  5007.  
  5008. void MainWindow::on_pushButton_11_clicked()
  5009. {
  5010. QMessageBox msgBox;
  5011. QString s1;
  5012.  
  5013. s1 += "Pour déplacer une note horizontalement :"; s1 += "\n";
  5014. s1 += "1) cliquez sur la note pour la sélectionner"; s1 += "\n";
  5015. s1 += "2) cliquez sur les boutons '<' et '>' qui sont apparus à la place du bouton 'Select'"; s1 += "\n";
  5016. s1 += "\n";
  5017. s1 += "Les petits tirets blancs indiquent les harmoniques x2 et x3";
  5018.  
  5019. s1 += ""; s1 += "\n";
  5020.  
  5021. msgBox.setText(s1);
  5022. msgBox.exec();
  5023. }
  5024.  
  5025.  
  5026.  
  5027. void MainWindow::on_Bt_RAZ_general_clicked()
  5028. {
  5029. liste_NOTES.clear();
  5030. liste_ENR_FFT.clear();
  5031. parametrages();
  5032. graphicsView4->horizontalScrollBar()->setValue(0);
  5033. }
  5034.  
  5035.  
  5036.  
  5037. void MainWindow::on_spinBox_x0a_valueChanged(int arg1)
  5038. {
  5039. effacer_calque(scene4, calque_echelle_temporelle_T);
  5040. effacer_calque(scene4, calque_echelle_temporelle_M);
  5041. effacer_calque(scene4, calque_grille_M);
  5042.  
  5043. on_Bt_copy_nt_T_to_M_clicked();
  5044.  
  5045. trace_liste_notes();
  5046. tracer_grille_M();
  5047. tracer_echelle_temps_TAB_NOTES();
  5048. }
  5049.  
  5050.  
  5051. void MainWindow::on_doubleSpinBox_x0b_valueChanged(double arg1)
  5052. {
  5053. effacer_calque(scene4, calque_echelle_temporelle_T);
  5054. effacer_calque(scene4, calque_echelle_temporelle_M);
  5055. effacer_calque(scene4, calque_grille_M);
  5056.  
  5057. on_Bt_copy_nt_T_to_M_clicked();
  5058.  
  5059. trace_liste_notes();
  5060. tracer_grille_M();
  5061. tracer_echelle_temps_TAB_NOTES();
  5062. }
  5063.  
  5064.  
  5065.  
  5066. void MainWindow::on_Bt_copy_nt_T_to_M_clicked()
  5067. {
  5068. //uint16_t n;
  5069.  
  5070. //save_fichier_NOTES("BAK"); // par sécurité !!!
  5071.  
  5072. uint16_t n_max = liste_NOTES.length();
  5073. uint16_t nb_M;
  5074.  
  5075. for(int n=0; n<n_max; n++)
  5076. {
  5077. nb_M = calcul_n_barreM_note(n);
  5078. liste_NOTES[n].n_barreM = nb_M;
  5079. }
  5080. mode='M';
  5081. affiche_liste_notes();
  5082. trace_liste_notes();
  5083. }
  5084.  
  5085.  
  5086. void efface_notes_T()
  5087. {
  5088. int16_t n_max = liste_NOTES.length();
  5089. for(int n=0; n<n_max; n++)
  5090. {
  5091. liste_NOTES[n].n_barreT = 0;
  5092. }
  5093. }
  5094.  
  5095.  
  5096.  
  5097. void MainWindow::on_Bt_copy_nt_M_to_T_clicked()
  5098. {
  5099. //int n;
  5100. int n_max = liste_NOTES.length();
  5101. int nb_T;
  5102.  
  5103. efface_notes_T();
  5104.  
  5105. for(int n=0; n<n_max; n++)
  5106. {
  5107. nb_T = calcul_n_barreT_note(n);
  5108. //nb_T = liste_NOTES[n].n_barreM * 14 ; //8.5; // méthode directe. à voir...
  5109. if (nb_T < 5000) {liste_NOTES[n].n_barreT = nb_T;}
  5110. }
  5111. mode='T';
  5112. mode_grille_T();
  5113. affiche_liste_notes();
  5114. trace_liste_notes();
  5115. }
  5116.  
  5117.  
  5118.  
  5119. void MainWindow::on_radioButton_D_clicked()
  5120. {
  5121. affiche_histogramme();
  5122. }
  5123.  
  5124.  
  5125. void MainWindow::on_radioButton_M_clicked()
  5126. {
  5127. affiche_histogramme();
  5128. }
  5129.  
  5130.  
  5131. void MainWindow::on_radioButton_H_clicked()
  5132. {
  5133. affiche_histogramme();
  5134. }
  5135.  
  5136.  
  5137. void MainWindow::on_Bt_dedoubleM_clicked()
  5138. {
  5139. int n_max = liste_NOTES.length();
  5140. for(int n=0; n<n_max; n++)
  5141. {
  5142. liste_NOTES[n].n_barreM = liste_NOTES[n].n_barreM *2;
  5143. }
  5144. tracer_grille_M();
  5145. trace_liste_notes();
  5146.  
  5147. }
  5148.  
  5149.  
  5150. void MainWindow::on_Bt_bak1_clicked()
  5151. {
  5152.  
  5153. QString filename1 = string_currentDir+ "/BAK.NTS";
  5154. QFile file1(filename1);
  5155. if (file1.exists())
  5156. {
  5157. liste_NOTES.clear();
  5158. effacer_calque(scene4,calque_notes_manuelles);
  5159. effacer_calque(scene4,calque_notes_auto);
  5160. effacer_calque(scene4,calque_notes_jouee);
  5161. effacer_calque(scene5, calque_histogramme );
  5162. effacer_calque(scene4, calque_echelle_temporelle_T);
  5163. effacer_calque(scene4, calque_echelle_temporelle_M);
  5164.  
  5165. load_fichier_NOTES("BAK");
  5166. on_Bt_toggle_grille_M_clicked();
  5167. }
  5168. else
  5169. {
  5170. QMessageBox msgBox;
  5171. QString s1="pas de Fichier BAK.NTS !";
  5172. msgBox.setText(s1); msgBox.exec();
  5173. }
  5174. }
  5175.  
  5176.  

Mais où se cache cette fameuse transformée de Fourier rapide dans ce programme ?

Cherchez la fonction :

void MainWindow::calcul_FFT()

ainsi que les fonctions :

void MainWindow::calcul_tableau_W()
void MainWindow::bit_reverse_tableau_X()
uint bit_reversal(uint num, uint nb_bits)


Voir aussi les fichiers complexe.cpp et complexe.h

Et pour les explications et les démonstrations mathématiques vior les liens au bas de cet article.

5 'wav to midi' : fichier mainwindow.h

CODE SOURCE en C++
  1.  
  2. #ifndef MAINWINDOW_H
  3. #define MAINWINDOW_H
  4.  
  5. #include <QMainWindow>
  6. #include "ui_mainwindow.h"
  7.  
  8. #include <QGraphicsView>
  9. #include <QGraphicsSceneMouseEvent>
  10. #include <QGraphicsTextItem>
  11. #include <QGraphicsLineItem>
  12. #include <QGraphicsRectItem>
  13. #include <QGraphicsItemGroup>
  14. //#include <QImage>
  15. #include <QProcess>
  16. #include <QtMultimedia/QMediaPlayer>
  17. #include <QAudioOutput>
  18. #include <QTimer>
  19.  
  20. #include "complexe.h"
  21.  
  22.  
  23. struct ENR_FFT
  24. {
  25. double amplitude; // 8 octets
  26. uint32_t t; // 4 octets
  27. uint8_t num; // 1 octet
  28. uint8_t midi; //1 octet
  29. // total 4+1+1+8 = 14 octets
  30. };
  31.  
  32.  
  33. // à propos des notes : PRINCIPE
  34. // les notes ont une fréquence qui n'est pas directement enregistrée ici mais est représenté par le numéro MIDI.
  35. // elles ont un emplacement qui est enregistré et qui permet de connaitre l'instant de son jeu, connaissant la grille.
  36. // pour la grille temporelle, voir 'tracer_grille_MESURES()'
  37. // la variable 'duree' pourrait être calculée en fonction des précédentes, mais le fait de l'avoir ici
  38. // permet de visualiser une toute partie de la partition, voir une note unique, en dehors du contexte
  39. struct NOTE
  40. {
  41. uint16_t numero; // 2 octets
  42. uint8_t midi; // 1 octet
  43. int16_t n_barreT; // 2 octets; numéro de la barre temporelle (T, 1/20s)sur laquelle est posée la note
  44. int16_t n_barreM; // 2 octets; num de barre M sur laquelle.. (accepte les valeurs négatives)
  45. // total 7 octets
  46. };
  47.  
  48.  
  49.  
  50. /* FFT */
  51.  
  52. class MainWindow : public QMainWindow, public Ui::MainWindow
  53. {
  54. Q_OBJECT
  55.  
  56. public:
  57. explicit MainWindow(QWidget *parent = 0);
  58. ~MainWindow();
  59.  
  60. protected:
  61.  
  62. void mousePressEvent(QMouseEvent *event);
  63. void contextMenuEvent(QContextMenuEvent *event); // clic de droite
  64.  
  65.  
  66. private slots:
  67. void Tic1();
  68. void Tic2();
  69. void save_fichier_ini();
  70. void load_fichier_ini();
  71. void choix_dossier_de_travail();
  72. void open_fichier_wav();
  73.  
  74. void on_Bt_load_wav_clicked();
  75. void ajustement_gain();
  76. void load_fichier_FRQ();
  77. int save_fichier_FRQ(QString date_i);
  78. void load_fichier_NOTES(QString s0);
  79. int save_fichier_NOTES(QString date_i);
  80.  
  81. void decode_entete();
  82. void garnis_temp_data(qint32 offset);
  83.  
  84. void parametrages();
  85. void init_TW_1();
  86. void init_TAB_FRQ();
  87. void init_TAB_lst_notes();
  88. void init_TW_type_M();
  89. void init_Autres();
  90.  
  91. void Etiquette(int x, int dx, int y, QString s, QString coul_txt, QString coul_fond, QString coul_cadre , QGraphicsItemGroup *calque_i);
  92.  
  93. void afficher_titre_calque(QString titre, int x, int y, QGraphicsItemGroup *calque_i);
  94. void tracer_graduations_signal();
  95. void tracer_graduations_FFT(); // sur onglet 'Source wav'
  96. void tracer_signal_complet(); // sur onglet 'Source wav'
  97. void tracer_gradu_temporelle_signal_entree(); // sur onglet 'Source wav'
  98. void tracer_signal_a_convertir(); // sur onglet 'Source wav'
  99. void tracer_graduation_TAB_NOTES(); // midi ; en colonne à gauche + noms des notes
  100. void tracer_echelle_temps_TAB_NOTES(); //en secondes (scene4 sur l'onglet NOTES)
  101. void tracer_grille_M();
  102. void tracer_grille_T();
  103. double calcul_pas_grille();
  104. //double calcul_pas_grille_M();
  105. double calcul_x_barre(int n_barre);
  106. int calcul_tempo();
  107. //double calcul_x_barre_M(int n_barre);
  108. void trace_1_barre_M(double xi, QString couleur_i);
  109. void tracer_1enr(ENR_FFT enr_i);
  110. void detection_notes_auto(); // notes secondaires (affi par petits cercles colorés)
  111. void retracer_TAB_FRQ();
  112. void maj_TAB_NOTES();
  113.  
  114. void encadrement_signal(int x, int dx);
  115. void encadrement_note(int n_midi);
  116. void encadre_midi(int n_midi);
  117. int calcul_num_midi(double x);
  118. void tracer_segments_FFT();
  119.  
  120. void complete_case(int row, int column, QString s1, QString c1, QString c2, bool bold1, QTableWidget *QTI);
  121. void affiche_liste_notes();
  122. void trace_liste_notes(); //dessine des cercles colorés (couleur midi) sur la grille
  123.  
  124. void calcul_histogramme_durees();
  125. void affiche_histogramme_durees();
  126.  
  127. void calcul_histogramme_midi();
  128. void affiche_histogramme_midi();
  129.  
  130. void calcul_histogramme_degre(); // degrés de la gamme chromatique = 1..12
  131. void affiche_histogramme_degre();
  132.  
  133. void affiche_histogramme();
  134.  
  135. QString denombre_diezes_a_la_cle();
  136. int test_if_note_in_liste(int16_t n_barre, int midi);
  137. void affi_txt_en_couleur(int midi_i, QLineEdit *lineEdit_i);
  138.  
  139. int num_barre(double xi);
  140. void ajout_note(int midi, int n_barreT, int n_barreM);
  141. void deplace_note(int n, int d);
  142. void supprime_note(int16_t n);
  143. uint16_t calcul_n_barreM_note(uint16_t n); // barre M la plus proche de la note posée sur une barre T
  144. uint16_t calcul_n_barreT_note(uint16_t n); // barre T la plus proche de la note posée sur une barre M
  145.  
  146. void remplir_tableau_echantillons_signal();
  147. void calcul_compression();
  148. void bit_reverse_tableau_X();
  149.  
  150. int calcul_y_note(int midi); // en pixels sur la grille
  151. int calcul_hauteur_note(int mid);
  152. void calcul_tableau_W();
  153. void calcul_FFT();
  154. void calcul_ofsset();
  155. void traitement_signal();
  156. void analyse_tout();
  157. QString nom_note(int mid);
  158. QString nom_note_GB(int mid);
  159. QString nom_octave_GB(int mid);
  160.  
  161. void numerotation_liste_notes();
  162. void tri_liste_notes_par_num_barre();
  163. void suppression_notes_invalides();
  164. void suppression_mesures();
  165.  
  166. void play_note(int midi, int duree_i);// sortie audio
  167. int joue_1_note_de_la_liste();
  168. void surbrille_note(uint16_t n, bool HRM);
  169. void trace_time_line();
  170.  
  171. void effacer_calque(QGraphicsScene *scene_i, QGraphicsItemGroup *calque_i);
  172.  
  173. void on_spinBox_1_valueChanged(int arg1);
  174. void on_spinBox_2_valueChanged(int arg1);
  175. void on_spinBox_3_valueChanged(int arg1);
  176. void on_spinBox_4_valueChanged(int arg1);
  177. void on_spinBox_5_valueChanged(int arg1);
  178. void on_spinBox_6_valueChanged();
  179. void on_spinBox_7_valueChanged(int arg1);
  180. void on_pushButton_8_clicked();
  181. void on_doubleSpinBox_1_valueChanged();
  182. void on_Bt_RAZ_clicked();
  183. void on_Bt_scan_auto_clicked();
  184. void on_pushButton_2_clicked();
  185. void on_Btn_52_clicked();
  186. void on_Btn_94_clicked();
  187. void on_pushButton_3_clicked();
  188. void on_Bt_close_entete_clicked();
  189. void on_pushButton_6_clicked();
  190. void on_Bt_efface_clicked();
  191. void on_pushButton_5_clicked();
  192. void on_checkBox_rapide_stateChanged(int arg1);
  193. void on_doubleSpinBox_seuil_valueChanged(double arg1);
  194. void on_checkBox_norm_clicked();
  195. void on_Bt_jouer_tout_clicked();
  196.  
  197. void mode_grille_T();
  198. void mode_grille_M();
  199.  
  200. void on_Bt_toggle_grille_T_clicked();
  201. void on_Bt_toggle_grille_M_clicked();
  202.  
  203. void on_Bt_toggle_visu_notes_clicked();
  204.  
  205. void on_Bt_save_notes_clicked();
  206. void on_Bt_load_notes_clicked();
  207. void on_Bt_joue_passage_clicked();
  208. void on_Bt_joue_wav_clicked();
  209. void on_Btn_RAZ_notes_clicked();
  210.  
  211. void on_Bt_mode_R_clicked();
  212. void on_Bt_mode_W_clicked();
  213. void on_Bt_toggle_visu_freq_clicked();
  214. void on_Bt_efface_2_clicked();
  215. void on_Bt_copy_nt_T_to_M_clicked();
  216. void on_Bt_copy_nt_M_to_T_clicked();
  217. void on_Bt_joue_wav_2_clicked();
  218. void on_Bt_choix_current_dir_clicked();
  219. void on_pushButton_9_clicked();
  220. void on_spinBox_8_textChanged();
  221. void on_doubleSpinBox_t0_valueChanged();
  222. void on_spinBox_offset_valueChanged();
  223. void on_spinBox_zoom_2_valueChanged(int arg1);
  224. void on_spinBox_d_barres_valueChanged();
  225. void on_Bt_load_FREQ_clicked();
  226. void on_Bt_decale_notes_L_clicked();
  227. void on_Bt_decale_notes_R_clicked();
  228. void on_tableWidget_type_M_cellClicked(int row, int column);
  229. void on_checkBox_flitrer_clicked();
  230. void on_Bt_open_DIR_clicked();
  231. void on_Bt_goto_clicked();
  232. void on_doubleSpinBox_x0_valueChanged(double arg1);
  233. void on_doubleSpinBox_T0_valueChanged(double arg1);
  234. void on_Bt_test1_clicked();
  235. void on_Bt_div2_clicked();
  236. void on_pushButton_clicked();
  237. void on_Bt_next_clicked();
  238. void on_Bt_prev_clicked();
  239. void on_Bt_debut_clicked();
  240. void on_Bt_fin_clicked();
  241. void on_Bt_durees_div2_clicked();
  242. void on_Bt_durees_mult2_clicked();
  243. void on_bt_test_clicked();
  244. void on_Bt_detection_notes_clicked();
  245. void on_Bt_toggle_visu_notes_auto_clicked();
  246. void on_Bt_m10_clicked();
  247. void on_Bt_p10_clicked();
  248. void on_doubleSpinBox_gain_valueChanged(double arg1);
  249. void on_Bt_test2_clicked();
  250. void on_Bt_open_DIR_2_clicked();
  251. void on_spinBox_nb_barres_valueChanged(int arg1);
  252. void on_spinBox_barre_zero_valueChanged(int arg1);
  253. void on_pushButton_10_clicked();
  254. void on_Bt_mode_E_clicked();
  255. void on_Bt_RAZ_general_clicked();
  256. void on_spinBox_x0a_valueChanged(int arg1);
  257. void on_doubleSpinBox_x0b_valueChanged(double arg1);
  258.  
  259. void on_spinBox_dxa_valueChanged(int arg1);
  260.  
  261. void on_Bt_deplace_L_clicked();
  262. void on_Bt_deplace_R_clicked();
  263.  
  264. void on_doubleSpinBox_dxb_valueChanged(double arg1);
  265.  
  266. void on_pushButton_11_clicked();
  267.  
  268. void on_radioButton_D_clicked();
  269. void on_radioButton_M_clicked();
  270. void on_radioButton_H_clicked();
  271.  
  272.  
  273. void on_Btn_RAZ_notes_2_clicked();
  274.  
  275.  
  276. void on_Bt_dedoubleM_clicked();
  277.  
  278. void on_Bt_bak1_clicked();
  279.  
  280. private:
  281.  
  282. QPoint Zoom_point2_;
  283.  
  284. // QImage image1;
  285.  
  286. QGraphicsScene *scene1; // sur l'onglet 'Source' - Trace FFT
  287. QGraphicsItemGroup *calque_reticule1;
  288. QGraphicsItemGroup *calque_trace_signal1;
  289. QGraphicsItemGroup *calque_trace_FFT;
  290. QGraphicsItemGroup *calque_curseur;
  291. QGraphicsItemGroup *calque_encadrement1;
  292. QGraphicsItemGroup *calque_lignes_F_zero;
  293.  
  294. QGraphicsScene *scene2; // sur l'onglet 'Source' - Signal d'entrée
  295. QGraphicsItemGroup *calque_reticule2;
  296. QGraphicsItemGroup *calque_encadrement2;
  297. QGraphicsItemGroup *calque_trace_signal2;
  298.  
  299. QGraphicsScene *scene3;
  300. QGraphicsItemGroup *calque_gradu_TAB_FRQ;
  301.  
  302. QGraphicsScene *scene4; // sur l'onglet 'NOTES'
  303. QGraphicsItemGroup *calque_TAB_FRQ;
  304.  
  305. QGraphicsScene *scene5; // sur l'onglet 'NOTES'
  306. QGraphicsItemGroup *calque_histogramme;
  307.  
  308. QGraphicsItemGroup *calque_grille_T;
  309. QGraphicsItemGroup *calque_grille_M;
  310. QGraphicsItemGroup *calque_echelle_temporelle_T; // pour grille T
  311. QGraphicsItemGroup *calque_echelle_temporelle_M; // pour grille M
  312. QGraphicsItemGroup *calque_notes_manuelles;
  313. QGraphicsItemGroup *calque_notes_auto;
  314. QGraphicsItemGroup *calque_notes_jouee;
  315.  
  316. QGraphicsLineItem *ligne1;
  317. QGraphicsLineItem *segment_trace;
  318. QGraphicsLineItem *segment_trace2;
  319. QGraphicsRectItem *rectangle1;
  320. QGraphicsRectItem *rectangle2;
  321. QGraphicsEllipseItem *ellipse1;
  322. QGraphicsRectItem *rect1;
  323. QGraphicsRectItem *rect2;
  324. QGraphicsRectItem *rect3;
  325.  
  326. QGraphicsTextItem *GraphicsTextItem;
  327.  
  328. QMediaPlayer *player1;
  329. QMediaPlayer *player2;
  330. QMediaPlayer *player3;
  331. QMediaPlayer *player4;
  332. QMediaPlayer *player5;
  333.  
  334. QAudioOutput *audioOutput1;
  335. QAudioOutput *audioOutput2;
  336. QAudioOutput *audioOutput3;
  337. QAudioOutput *audioOutput4;
  338. QAudioOutput *audioOutput5;
  339.  
  340. QTimer *Timer1; // pour analyse auto à faible vitesse
  341. QTimer *Timer2; // pour rejouer les notes détectées
  342.  
  343. };
  344.  
  345.  
  346.  
  347. #endif // MAINWINDOW_H
  348.  

6 'wav to midi' : fichier complexe.cpp

CODE SOURCE en C++
  1.  
  2. #include "complexe.h"
  3. //
  4.  
  5. void Complexe::multi_lambda(float lambda)
  6. {
  7. a *= lambda;
  8. b *= lambda;
  9. }
  10.  
  11.  
  12. Complexe Complexe::operator+ (Complexe c)
  13. {
  14. Complexe r;
  15. r.a=this->a+c.a;
  16. r.b=this->b+c.b;
  17. return r;
  18. }
  19.  
  20.  
  21. Complexe Complexe::operator- (Complexe c)
  22. {
  23. Complexe r;
  24. r.a=this->a-c.a;
  25. r.b=this->b-c.b;
  26. return r;
  27. }
  28.  
  29.  
  30. Complexe Complexe::operator* (Complexe c)
  31. {
  32. Complexe r;
  33. r.a=this->a * c.a - this->b * c.b;
  34. r.b=this->a * c.b + this->b * c.a;
  35. return r;
  36. }
  37.  
  38.  
  39.  
  40. /* rappel: fonction en pascal
  41. function produit_cplx(c1,c2:complexe):complexe;
  42.  begin
  43.   produit_cplx[1]:=c1[1]*c2[1]-c1[2]*c2[2];
  44.   produit_cplx[2]:=c1[1]*c2[2]+c1[2]*c2[1];
  45.  end;
  46. */
  47.  
  48.  

7 'wav to midi' : fichier complexe.h

CODE SOURCE en C++
  1.  
  2. #ifndef COMPLEXE_H
  3. #define COMPLEXE_H
  4. // Nombres complexes de la forme a+ib
  5.  
  6. //
  7. class Complexe
  8. {
  9.  
  10. public:
  11.  
  12. float a; // partie reelle
  13. float b; // partie imaginaire
  14. void multi_lambda(float lambda);
  15. Complexe operator+ (Complexe c);
  16. Complexe operator- (Complexe c);
  17. Complexe operator* (Complexe c); //equivaut a une rotation dans le plan (produit des modules, somme des arguments)
  18.  
  19. };
  20.  
  21.  
  22.  
  23.  
  24. #endif
  25.  

8 Autre programme : 'Guitare' - Présentation en vidéo


Ce nouveau programme constitue la suite logique du programme 'wav to midi'.
Il peut traiter la liste de notes générée par 'wav to midi'.
On part donc d'un fichier audio et on arrive à une sorte de suite de tablatures représentées sur la manche de la guitare avec position de chaque doigt de la main. Le tout ré-jouable avec respect du tempo.

Il fera l'objet d'un prochain article sur ce site. Je vous donne juste un aperçu en vidéo en attendant.
A suivre...

9 programme : 'Guitare' - video2


Vous aurez reconnu le court extrait de "Hotel California" à titre d'exemple.

10 programme : 'Guitare' - video 3


Vous aurez reconnu le court extrait de "Hotel California" à titre d'exemple.

11 Le code source 'Guitare' en C++ Qt6: fichier mainwindow.cpp

CODE SOURCE en C++
  1. #include "MainWindow.h"
  2. #include "ui_MainWindow.h"
  3.  
  4. #include "math.h"
  5. #include <QFile>
  6. #include <QFileDialog>
  7. #include <QTextStream>
  8. #include <QGraphicsView>
  9. #include <QPixmap>
  10. #include <QGraphicsPixmapItem>
  11. #include <QGraphicsEllipseItem>
  12. #include <QList>
  13. #include <QTimer>
  14. #include <QLine>
  15. #include <QProcess>
  16. #include <QDebug>
  17. #include <QMessageBox>
  18.  
  19. //#include <QSound>
  20. #include <QtMultimedia/QMediaPlayer>
  21. #include <QAudioOutput>
  22.  
  23. #include <QMouseEvent>
  24. #include <QScrollBar>
  25.  
  26.  
  27. QString version_i = "2025-04-24 a";
  28.  
  29. QFile file_dat;
  30.  
  31. uint16_t largeur_image = 1216; // image du manche de la guitare
  32. uint16_t hauteur_image = 180;
  33.  
  34. QDir currentDir;
  35. QString base_Dir;
  36. QString default_Dir = "/home/";
  37. QString string_currentDir = default_Dir; // à priori; sera mis à jour lors de la lecture du fichier 'params.ini'
  38. QString string_currentFile;
  39.  
  40. QString repertoire_images;
  41. QString nom_fichier_in="";
  42. QStringList liste_str_in;
  43. //QList<NOTE> liste_NOTES;
  44. QStringList liste_accords;
  45.  
  46. QDataStream binStream1;
  47.  
  48. //QList<NOTE> liste_notes;
  49. //QList<MESURE> liste_mesures;
  50.  
  51. QList<uint16_t> positionsX;
  52. QList<QString> noms_notes;
  53. QList<QString> gamme_chromatique;
  54. QList<QString> gamme_chromatique_GB;
  55. //QList<QColor> liste_couleurs;
  56. QList<QString> liste_couleurs;
  57. QList<NOTE_importee> liste_NOTES_importees;
  58.  
  59. int type_accords=0; // 1=MAJ; 2=min; 3=7e dom
  60.  
  61. uint16_t x_clic_ecran, y_clic_ecran;
  62.  
  63. int nb_lignes;
  64. int L_save_min=0;
  65. int L_save_max=0;
  66. int numero_note=0; // dans la liste totale de la partition (ne compte QUE les notes)
  67. int num_ligne_en_cours=0; // lignes du tableWidget_3
  68. int num_note_A=0;
  69. int num_note_max=0;
  70. int num_note_stop=10000;
  71. int nb_notes_jouees_max;
  72. int nb_notes_jouees=0;
  73. int accord_en_cours=0;
  74. int num_note_jouee=0;
  75. int corde_jouee;
  76. int case_jouee;
  77. int n_midi_jouee;
  78. int ligne_TW3;
  79. int memo_corde_i;
  80. int memo_case_i;
  81. QString acc1="";
  82. QString memo_acc1="";
  83. char gamme;
  84.  
  85. int case_min=0;
  86. int case_max=0;
  87.  
  88. int mesure_a_encadrer=0;
  89. int memo_mesure_a_encadrer=0;
  90. int num_colonne_a_encadrer=0;
  91. int nb_colonnes_a_encadrer=1;
  92. int zoom=1;
  93.  
  94. int num_mesure_en_cours=0;
  95.  
  96. int Tp1;
  97. int temps1;
  98.  
  99. // type de mesure noté Ta/Tb (4/4, 3/2 ...)
  100. int8_t Ta = 4;
  101. int8_t Tb = 4;
  102.  
  103. float duree=30;
  104. int boucler=0;
  105. int lecture_pause=1; // fonction du bouton lecture / pause
  106. int n_player=1;
  107.  
  108. double grille_t0;
  109. double grille_dt;
  110.  
  111. bool notes_pleines; // concerne le graphique : ellipse pleine ou bien juste un cercle
  112. bool notes_silencieuses; // pour représenter les positions d'accords, sans les jouer
  113. bool mode_depot_note=false; // pour écrire la valeur midi d'une note dans TW3 suite à clic de droite le manche
  114. bool data_ok = false;
  115. bool dossier_de_travail_ok = false;
  116.  
  117.  
  118.  
  119. MainWindow::MainWindow(QWidget *parent) :
  120. QMainWindow(parent)
  121. {
  122. setupUi(this);
  123. setWindowTitle("Guitare " + version_i);
  124.  
  125. //this->setGeometry(0,0, 1900, 1000);
  126. setWindowState(Qt::WindowMaximized);
  127.  
  128. //statusbar->showMessage("Position des doigts...");
  129.  
  130. frame_back->setGeometry(0, 0, 1900, 1050);
  131.  
  132. scene1 = new QGraphicsScene(this);
  133.  
  134. graphicsView1->setScene(scene1);
  135. graphicsView1->setGeometry(10,100, largeur_image+20, hauteur_image+5);
  136. pushButton_8->setGeometry(10, 100, 26, 26); // bouton aide1 (sur le manche)
  137. pushButton_9->setGeometry(38, 100, 26, 26); // bouton aide2 (sur le manche)
  138.  
  139. Timer2 = new QTimer(this);
  140.  
  141. connect(Timer2, SIGNAL(timeout()), this, SLOT(Tic2()));
  142. connect(tableWidget_T->horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(TW_T_scroll(int)));
  143. connect(tableWidget_3->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(TW_3_scroll(int)));
  144.  
  145. repertoire_images = "./images/"; // chemin relatif / dossier de l'exécutable
  146. charger_image_manche();
  147.  
  148. calque_notes = new QGraphicsItemGroup();
  149. scene1->addItem(calque_notes);
  150.  
  151. calque_encadrement = new QGraphicsItemGroup();
  152. scene1->addItem(calque_encadrement);
  153.  
  154. Frame_wWidget1 = new QFrame();
  155.  
  156. positionsX << 5 << 55 << 140 <<225 << 305 << 385 << 459 << 528 << 595 << 650 << 714 << 765
  157. << 820 << 864 << 910 << 960 << 1000 << 1035 << 1072 << 1111 << 1145;
  158. // 21 valeurs en comptant les cordes à vide
  159. // indice max = 21-1 = 20
  160.  
  161. player1 = new QMediaPlayer;
  162. audioOutput1 = new QAudioOutput(this);
  163. player1->setAudioOutput(audioOutput1);
  164.  
  165. player2 = new QMediaPlayer;
  166. audioOutput2 = new QAudioOutput(this);
  167. player2->setAudioOutput(audioOutput2);
  168.  
  169. player3 = new QMediaPlayer;
  170. audioOutput3 = new QAudioOutput(this);
  171. player3->setAudioOutput(audioOutput3);
  172.  
  173. player4 = new QMediaPlayer;
  174. audioOutput4 = new QAudioOutput(this);
  175. player4->setAudioOutput(audioOutput4);
  176.  
  177. player5 = new QMediaPlayer;
  178. audioOutput5 = new QAudioOutput(this);
  179. player5->setAudioOutput(audioOutput5);
  180.  
  181. player6 = new QMediaPlayer;
  182. audioOutput6 = new QAudioOutput(this);
  183. player6->setAudioOutput(audioOutput6);
  184.  
  185. player7 = new QMediaPlayer;
  186. audioOutput7 = new QAudioOutput(this);
  187. player7->setAudioOutput(audioOutput7);
  188.  
  189. player8 = new QMediaPlayer;
  190. audioOutput8 = new QAudioOutput(this);
  191. player8->setAudioOutput(audioOutput8);
  192.  
  193. noms_notes<<"La"<<"Si"<<"Do"<<"Ré"<<"Mi" <<"Fa"<<"Sol"; // <- A B C D E F G
  194. gamme_chromatique<<"Do"<<"Do#"<<"Ré"<<"Mib"<<"Mi"<<"Fa"<<"Fa#"<<"Sol"<<"Sol#"<<"La"<<"Sib"<<"Si";
  195. gamme_chromatique_GB<<"C"<<"C#"<<"D"<<"Eb"<<"E"<<"F"<<"F#"<<"G"<<"G#"<<"A"<<"A#"<<"B";
  196.  
  197. liste_couleurs <<"#EF2929"<<"#FF5C00"<<"#FCAF3E"<<"#FFE300"<<"#BFFF00"<<"#07F64F"
  198. <<"#16D298"<<"#16D2C4"<<"#00AEFF"<<"#1667D2"<<"#7C00FF"<<"#FF67EF"<<"#EEEEEC"; //(la dernière = GRIS)
  199.  
  200. lecture_fichier_ini();
  201.  
  202. //init_TW_1();
  203. init_TW_3();
  204. init_TW_T();
  205. init_TAB_lst_notes();
  206. init_tableWidget_doigts();
  207. init_autres();
  208.  
  209. on_spinBox_2_valueChanged(0);
  210.  
  211. doubleSpinBox_vitesse->setValue(25.0);
  212. //on_doubleSpinBox_vitesse_valueChanged(30);
  213.  
  214. radioButton_Z1->setChecked(true); // set zomm 1
  215. set_zoom1();
  216.  
  217. Bt_lecture_2->setText("joue > debut");
  218. notes_pleines = true;
  219. notes_silencieuses = false;
  220.  
  221. on_pushButton_3_clicked();
  222. effacer_calque(scene1, calque_encadrement);
  223. label_43->clear();
  224. label_44->clear();
  225. label_45->clear();
  226. //line1 = new QFrame(this);
  227. Frame_wWidget1->setVisible(false);
  228.  
  229. }
  230.  
  231. MainWindow::~MainWindow()
  232. {
  233. delete ui;
  234. }
  235.  
  236.  
  237. void MainWindow::save_fichier_ini()
  238. {
  239. QFile file1(QDir::currentPath() + "/" + "params_Guitare.ini"); // dans le dossier de l'exécutable
  240. if (file1.open(QIODevice::WriteOnly | QIODevice::Text))
  241. {
  242. //int p1= string_currentFile.lastIndexOf('/');
  243. // string_currentDir = string_currentFile.left(p1);
  244.  
  245. QTextStream out(&file1);
  246.  
  247. out << "# Ce fichier est cree automatiquement par le programme";
  248. out << '\n';
  249. out << "#";
  250. out << '\n';
  251. out << "# chemins:";
  252. out << '\n';
  253. out << "<currentDir>" << string_currentDir << "</currentDir>";
  254. out << '\n';
  255. out << "<currentFile>" << string_currentFile << "</currentFile>";
  256. }
  257. file1.close();
  258. }
  259.  
  260.  
  261. void MainWindow::lecture_fichier_ini()
  262. {
  263. //QMessageBox msgBox;
  264. QString line;
  265. int p1, p2, p3;
  266.  
  267. dossier_de_travail_ok = false; // à priori
  268. QFile file1(QDir::currentPath() + "/" + "params_Guitare.ini"); // dans le dossier de l'exécutable (= QDir::currentPath() )
  269. if (file1.open(QIODevice::ReadOnly | QIODevice::Text))
  270. {
  271. QTextStream in(&file1);
  272. in.reset();
  273. while ( !in.atEnd() )
  274. {
  275. line = in.readLine();
  276. if (line.at(0) !='#')
  277. {
  278. if ((p1 = line.indexOf("<currentDir>")) != -1)
  279. {
  280. p2 = line.indexOf('>',p1);
  281. p3 = line.indexOf("</",p2);
  282. QString s1 = line.mid(p2+1, p3-p2-1);
  283. string_currentDir = s1;
  284.  
  285. dossier_de_travail_ok = true;
  286. }
  287.  
  288.  
  289. if ((p1 = line.indexOf("<currentFile>")) != -1)
  290. {
  291. p2 = line.indexOf('>',p1);
  292. p3 = line.indexOf("</",p2);
  293. QString s1 = line.mid(p2+1, p3-p2-1);
  294. string_currentFile = s1;
  295. }
  296. }
  297. }
  298. file1.close();
  299. }
  300. else
  301. {
  302. QString s1 = "fichier .ini non trouvé, je le crée (dans le dossier de l'executable)";
  303. QMessageBox msgBox; msgBox.setText(s1); msgBox.exec();
  304. base_Dir=QDir::currentPath() + "/";
  305. save_fichier_ini();
  306. dossier_de_travail_ok = false;
  307. }
  308.  
  309. lineEdit_current_dir->setText(string_currentDir);
  310. }
  311.  
  312.  
  313. float freq_mid(int midi_i) // calcule la fréquence (en Hertz) d'une note à partir de son numéro midi
  314. {
  315. // https://fr.wikipedia.org/wiki/MIDI_Tuning_Standard
  316. float F, A;
  317. A=((float)midi_i-69.0)/12.0;
  318. F= 440 * powf(2,A);
  319. return F;
  320. }
  321.  
  322.  
  323. void MainWindow::init_TW_3() // affi grande liste verticale
  324. {
  325.  
  326. label_TW3->setGeometry(1205, 10, 50, 18);
  327. tableWidget_3->setGeometry(1250, 10, 640, 836); // la valeur 836 est critique pour l'encadrement ok
  328. tableWidget_3->clear();
  329. tableWidget_3->setRowCount(1);
  330. tableWidget_3->setColumnCount(13);
  331. QStringList liste_entetes;
  332. liste_entetes << "num" <<"note1"<<"note2"<<"note3"<<"Cmt"<<">"<<"dur"<<"M"<<"tps"<< "n°b"<<"ACC"<<"cases"<<"doigts";
  333. tableWidget_3->setHorizontalHeaderLabels (liste_entetes );
  334. tableWidget_3->resizeColumnsToContents();
  335. //for(int n=0; n<=2; n++)
  336. {
  337. tableWidget_3->setItem(0, 0, new QTableWidgetItem (" ") ); tableWidget_3->setColumnWidth(0,65);
  338. tableWidget_3->setItem(0, 1, new QTableWidgetItem (" ") ); tableWidget_3->setColumnWidth(1,65);
  339. tableWidget_3->setItem(0, 2, new QTableWidgetItem (" ") ); tableWidget_3->setColumnWidth(2,65);
  340.  
  341. tableWidget_3->setItem(0, 3, new QTableWidgetItem (" ") ); tableWidget_3->setColumnWidth(3,100); // commentaire
  342. // tableWidget_3->setColumnWidth(3, 80);
  343.  
  344. QTableWidgetItem *Item1 = new QTableWidgetItem();
  345. Item1->setIcon(QIcon("../images/03.png" ));
  346. tableWidget_3->setItem(0, 4, Item1 );
  347. tableWidget_3->setColumnWidth(4, 80);
  348.  
  349. tableWidget_3->setItem(0, 5, new QTableWidgetItem ("0") ); // durée
  350.  
  351. tableWidget_3->setColumnWidth(5, 20);
  352.  
  353. tableWidget_3->setItem(0, 6, new QTableWidgetItem ("0") ); // MESURE
  354. tableWidget_3->setColumnWidth(6, 40);
  355.  
  356. tableWidget_3->setItem(0, 7, new QTableWidgetItem (" ") ); // tps
  357. tableWidget_3->setColumnWidth(7, 40);
  358.  
  359. tableWidget_3->setItem(0, 8, new QTableWidgetItem (" ") ); // tot
  360. tableWidget_3->setColumnWidth(8, 40);
  361.  
  362. tableWidget_3->setItem(0, 9, new QTableWidgetItem (" ") ); // ACC
  363. tableWidget_3->setColumnWidth(9, 40);
  364.  
  365. tableWidget_3->setItem(0, 10, new QTableWidgetItem (" ") ); // cases
  366. tableWidget_3->setColumnWidth(10, 54);
  367.  
  368. tableWidget_3->setItem(0, 11, new QTableWidgetItem (" ") ); // doigts
  369. tableWidget_3->setColumnWidth(11, 52);
  370.  
  371. tableWidget_3->setItem(0, 12, new QTableWidgetItem (" ") ); // doigts
  372. tableWidget_3->setColumnWidth(11, 60);
  373.  
  374. }
  375. }
  376.  
  377. void MainWindow::init_tableWidget_doigts()
  378. {
  379. tableWidget_doigts->setGeometry(5, 20, 200, 200);
  380.  
  381. tableWidget_doigts->clear();
  382. tableWidget_doigts->setRowCount(5);
  383. tableWidget_doigts->setColumnCount(3);
  384. QStringList liste_entetesH;
  385. liste_entetesH <<"corde"<<"case"<<"DOIGT";
  386. tableWidget_doigts->setHorizontalHeaderLabels (liste_entetesH );
  387.  
  388. QStringList liste_entetesV;
  389. liste_entetesV <<"0"<<"1"<<"2"<<"3"<<"4";
  390. tableWidget_doigts->setVerticalHeaderLabels(liste_entetesV );
  391.  
  392. for(int n=0; n<5; n++)
  393. {
  394. QTableWidgetItem *Item1 = new QTableWidgetItem();
  395. Item1->setIcon(QIcon("../images/02.png" ));
  396. tableWidget_doigts->setItem(n, 2, Item1 );
  397. }
  398. tableWidget_doigts->resizeColumnsToContents();
  399. tableWidget_doigts->setColumnWidth(2, 20);
  400.  
  401. pushButton_6->setGeometry(189, 0, 22, 21); // bouton aide position des doigts
  402.  
  403. Bt_copie_doigts_to_TW3->setGeometry(50, 147, 150, 26);
  404. Bt_RAZ_doigts->setGeometry(10, 147, 31, 26);
  405.  
  406.  
  407. int R, C;
  408. for (R=0; R<5; R++)
  409. {
  410. for (C=0; C<2; C++)
  411. {
  412. tableWidget_doigts->setItem(R, C, new QTableWidgetItem ("-") );
  413. tableWidget_doigts->item(R,C)->setTextAlignment(Qt::AlignCenter);
  414. }
  415. }
  416. }
  417.  
  418.  
  419.  
  420. void MainWindow::init_TW_T()
  421. {
  422. tableWidget_T->setGeometry(10, 880, 1870, 135);
  423. tableWidget_T->setColumnCount(300);
  424. label_timeline->setGeometry(10, 850, 100, 30);
  425.  
  426. tableWidget_T->clear();
  427. for(int n=0; n< tableWidget_T->columnCount(); n++)
  428. {
  429. complete_case(0, n, "-", "#000000", "#FFFFFF", false, tableWidget_T);
  430. //complete_case(5, n, "-", "#000000", "#FFFFFF", tableWidget_T);
  431. }
  432. }
  433.  
  434.  
  435. void MainWindow::init_TAB_lst_notes()
  436. {
  437. tableWidget_lst_notes->setGeometry(330, 640, 260, 231);
  438. QStringList liste_entetes1;
  439. liste_entetes1<<"num"<<"midi"<<"note"<<"n°barM";
  440. tableWidget_lst_notes->setHorizontalHeaderLabels (liste_entetes1);
  441. tableWidget_lst_notes->setEditTriggers(QAbstractItemView::NoEditTriggers);
  442. pushButton_11->setGeometry(570, 640, 20, 20);
  443. }
  444.  
  445.  
  446.  
  447.  
  448. void MainWindow::init_autres()
  449. {
  450. groupBox_1->setGeometry(20, 450, 350, 181); // Configurateur d'Accords
  451. groupBox_2->setGeometry(900, 490, 311, 370);
  452. groupBox_3->setGeometry(670, 450, 200, 180); // Général
  453. groupBox_4->setGeometry(380, 450, 210, 180); // Position des doigts
  454.  
  455. groupBox_ZOOM->setGeometry(20, 760, 50, 70);
  456.  
  457. H_line_1->setVisible(false);
  458. V_line_1->setVisible(false);
  459. H_line_2->setVisible(false);
  460. V_line_2->setVisible(false);
  461. H_line_1b->setVisible(false);
  462. V_line_1b->setVisible(false);
  463. H_line_2b->setVisible(false);
  464. V_line_2b->setVisible(false);
  465.  
  466. label_44->setGeometry(900, 430, 111, 31);
  467. label_45->setGeometry(900, 450, 111, 31);
  468.  
  469. groupBox_Import->setGeometry(600, 640, 270, 100);
  470.  
  471. groupBox_sigles->setGeometry(600, 750, 270, 121);
  472.  
  473. Bt_save_ACD->setGeometry(1000, 50, 92, 26);
  474. Bt_load_ACD->setGeometry(1100, 50, 92, 26);
  475.  
  476.  
  477. create_100_lignes_V();
  478. }
  479.  
  480.  
  481. void MainWindow::effacer_calque(QGraphicsScene *scene_i, QGraphicsItemGroup *calque_i)
  482. {
  483. foreach( QGraphicsItem *item, scene_i->items( calque_i->boundingRect() ) )
  484. {if( item->group() == calque_i ) { delete item; }}
  485. }
  486.  
  487.  
  488.  
  489. void MainWindow::charger_image_manche()
  490. {
  491. QString fileName1;
  492. fileName1 = repertoire_images + "manche2.jpg";
  493.  
  494. QFile file1(fileName1);
  495. if (file1.exists() )
  496. {
  497. QImage image1(fileName1);
  498. image1 = image1.scaledToWidth(largeur_image);
  499. image1.load(fileName1);
  500. //imageLabel1->setPixmap(QPixmap::fromImage(image1));
  501. QGraphicsPixmapItem* item1 = new QGraphicsPixmapItem(QPixmap::fromImage(image1));
  502. scene1->addItem(item1);
  503. //calque_notes->addToGroup(item1);
  504. }
  505. }
  506.  
  507.  
  508. void MainWindow::affi_txt_en_couleur(int midi_i, QLineEdit *lineEdit_i)
  509. {
  510. int h1 = calcul_hauteur_note(midi_i); h1-=3; if(h1<0){h1+=12;} if(h1>11){h1-=12;}
  511. if ((h1<0) || (h1>(liste_couleurs.length()-1))) {h1 = 0;}
  512. QString c1 = liste_couleurs[h1];
  513. QString c2 = "#000000";
  514. lineEdit_i->setStyleSheet("color: " + c1 + "; background-color: " + c2 + "; font: 700 14pt 'Ubuntu';");
  515. }
  516.  
  517.  
  518. QString MainWindow::nom_note_FR(int mid)
  519. {
  520. QString s1;
  521.  
  522. int h1 = calcul_hauteur_note(mid);
  523. h1-=3;
  524. if(h1<0){h1+=12;}
  525. if(h1>11){h1-=12;}
  526.  
  527. if((h1<0) || ( h1>= gamme_chromatique.length())) {return "-";}
  528. s1 = gamme_chromatique[h1];
  529. return s1;
  530. }
  531.  
  532.  
  533. QString MainWindow::nom_note_GB(int mid)
  534. {
  535. QString s1;
  536.  
  537. int h1 = calcul_hauteur_note(mid);
  538. h1-=3;
  539. if(h1<0){h1+=12;}
  540. if(h1>11){h1-=12;}
  541.  
  542. if((h1<0) || ( h1>= gamme_chromatique_GB.length())) {return "-";}
  543. s1 = gamme_chromatique_GB[h1];
  544. return s1;
  545. }
  546.  
  547.  
  548. QString MainWindow::nom_octave_GB(int mid)
  549. {
  550. QString octave;
  551. if((mid>=40)&&(mid < 48)) {octave = "2";}
  552. if((mid>=48)&&(mid < 60)) {octave = "3";}
  553. if((mid>=60)&&(mid < 72)) {octave = "4";}
  554. if((mid>=72)&&(mid < 90)) {octave = "5";}
  555. return octave;
  556. }
  557.  
  558. int MainWindow::calcul_hauteur_note(int mid) //'hauteur' au sens musical, gamme chromatique de 0 à 11
  559. {
  560. int h1 = mid;
  561.  
  562. while(h1>=12) {h1-=12;}
  563. while(h1<0) {h1+=12;}
  564. if (h1==12) {h1=0;}
  565. if ((h1<0) || (h1>(liste_couleurs.length()-1))) {h1 = 0;}
  566.  
  567. return h1; // h1 = 0..11
  568. }
  569.  
  570.  
  571. int MainWindow::calcul_midi(int corde_i, int case_i)
  572. {
  573. // 40 -> Mi octave 2 (corde 6 à vide)
  574. int n;
  575. n = 40 + case_i; // corde6 de Mi grave
  576. if (corde_i == 5){n+=5;}
  577. if (corde_i == 4){n+=10;}
  578. if (corde_i == 3){n+=15;}
  579. if (corde_i == 2){n+=19;}
  580. if (corde_i == 1){n+=24;} // corde1 de Mi aigu (+2 octaves)
  581.  
  582. //*n_midi = n;
  583. return n;
  584.  
  585. }
  586.  
  587.  
  588. void MainWindow::calcul_xy_note(int corde_i, int case_i, int *x_i, int *y_i)
  589. {
  590. float x;
  591. float y;
  592. float dy;
  593. float y0;
  594. float ech;
  595.  
  596. if (case_i >= positionsX.length())
  597. {
  598. *x_i=1;
  599. *y_i=1;
  600. return;
  601. }
  602. x=positionsX[case_i];
  603.  
  604. y0=102;
  605. ech=1+case_i/90.0;
  606. dy=-20.0*((7-corde_i)-3.2);
  607.  
  608. dy *= ech;
  609. y=y0+dy;
  610.  
  611. *x_i=int(x);
  612. *y_i=int(y);
  613. }
  614.  
  615.  
  616.  
  617. void MainWindow::detecte_note_xy(int x_i, int y_i, int *corde_i, int *case_i)
  618. {
  619. // suite à un clic directement sur le manche
  620. // voir la fonction "mousePressEvent()"
  621. float y;
  622. float dy;
  623. float y0;
  624. float ech;
  625.  
  626. // détection du numéro de la case jouée
  627. *case_i=-1;
  628. for (int i=0; i<21; i++)
  629. {
  630. int x= positionsX[i] +30;
  631. if ((abs(x_i - x))<30) {*case_i = i;}
  632. }
  633. if (*case_i == -1)
  634. {
  635. *corde_i=0;
  636. *case_i=0;
  637. return;
  638. }
  639.  
  640. // détection du numéro de la corde jouée
  641. *corde_i=0;
  642. y0=220;
  643.  
  644. for (int i=1; i<=6; i++)
  645. {
  646. ech=1+ *case_i/90.0;
  647. dy=-20.0*((7-i)-3.2);
  648. dy *= ech;
  649. y=y0+dy;
  650.  
  651. if ((abs(y_i - y))<20) {*corde_i = i;}
  652. }
  653. }
  654.  
  655.  
  656. void MainWindow::numerote_1_note(int corde_i, int case_i, int num_i)
  657. {
  658. QString s1;
  659. int x, y;
  660.  
  661. s1.setNum(num_i);
  662.  
  663. calcul_xy_note(corde_i, case_i, &x, &y);
  664. textItem1 = new QGraphicsSimpleTextItem(s1);
  665. QBrush brush1;
  666. brush1.setStyle(Qt::SolidPattern);
  667. brush1.setColor("#000000");
  668. textItem1->setBrush(brush1);
  669. textItem1->setPos(x+2, y -1);
  670. calque_notes->addToGroup(textItem1);
  671. }
  672.  
  673.  
  674.  
  675. void MainWindow::dessine_1_note(int corde_i, int case_i, QColor couleur_i)
  676. {
  677. int x, y;
  678. // case_i = 0..20 (0 -> corde à vide)
  679.  
  680. if ( (case_i < case_min) || (case_i > case_max) ) {return;}
  681.  
  682. uint midi = calcul_midi(corde_i, case_i);
  683. affiche_details_note(midi);
  684.  
  685. QPen pen_note(couleur_i, 1, Qt::SolidLine);
  686.  
  687. if ((case_i>=0) && (case_i<=20))
  688. {
  689. calcul_xy_note(corde_i, case_i, &x, &y);
  690. ellipse1 = new QGraphicsEllipseItem(x, y, 15, 15);
  691. ellipse1->setPen(pen_note);
  692. if (notes_pleines == true) {ellipse1->setBrush(couleur_i);}
  693. calque_notes->addToGroup(ellipse1);
  694.  
  695. memo_case_i=case_i;
  696. memo_corde_i=corde_i;
  697. }
  698. }
  699.  
  700.  
  701. void MainWindow::encadre_accord(int case1, int case2)
  702. {
  703. int x0, y0, x1, y1, dx, dy;
  704.  
  705. effacer_calque(scene1, calque_encadrement);
  706.  
  707. if (case1>19) {return;}
  708. if (case2>20) {return;}
  709.  
  710. if (case1>case2) {return;}
  711.  
  712. //qDebug() << "case1" << case1;
  713. //qDebug() << "case2" << case2;
  714. //qDebug() << "______________";
  715.  
  716. calcul_xy_note(1, case1, &x0, &y0);
  717. calcul_xy_note(6, case2, &x1, &y1);
  718. dx= x1-x0;
  719. dy=y1-y0;
  720.  
  721. Frame_wWidget1->setGeometry(QRect(x0-4, y0-2, dx+24, dy +14));
  722. Frame_wWidget1->setStyleSheet( "background: transparent;" "border: 1px solid yellow;" "border-radius: 15px;" );
  723. QGraphicsProxyWidget *proxy = scene1->addWidget(Frame_wWidget1);
  724. Frame_wWidget1->setVisible(true);
  725. }
  726.  
  727.  
  728. void MainWindow::dessine_accord(int corde_i1, int case_i1, int corde_i2, int case_i2)
  729. {
  730. //QGraphicsLineItem *QGraphicsScene::addLine(qreal x1, qreal y1, qreal x2, qreal y2, const QPen &pen = QPen())
  731. int x1, y1;
  732. int x2, y2;
  733. QString couleur1;
  734. calcul_xy_note(corde_i1, case_i1, &x1, &y1);
  735. calcul_xy_note(corde_i2, case_i2, &x2, &y2);
  736. couleur1 = liste_couleurs[4];
  737. QPen pen_ligne; //(liste_couleurs[4], 1, Qt::SolidLine);
  738. pen_ligne.setColor(couleur1);
  739. scene1->addLine(x1+8, y1+8, x2+8, y2+8, pen_ligne);
  740. }
  741.  
  742.  
  743.  
  744.  
  745.  
  746. /**
  747. REMARQUES:
  748.  
  749. pour la guitare :
  750. E2 = le Mi2 grave (corde 6 à vide)
  751. E3 = le Mi3 corde 4 case 2
  752. E4 = le Mi4 corde 1 à vide
  753. E5 = le Mi5 corde 1 case 12
  754. D6 = le Ré6 corde 1 case 22 (la note la plus aigüe de la guitare électrique)
  755.  
  756. donc au total (presque) 4 octaves (manque juste 2 notes, Mib6 et Mi6)
  757. **/
  758.  
  759.  
  760. void MainWindow::execute_note_midi(uint midi)
  761. {
  762. calcul_hauteur_note(midi);
  763. //if (checkBox1->isChecked()) {on_Bt_RAZ_clicked();} // efface tout avant de ne dessiner qu'une seule note
  764. //QString s1;
  765. //s1.setNum(i);
  766. //lineEdit_7->setText(s1);
  767. num_note_jouee++;
  768. switch(midi)
  769. {
  770. case 40: on_Bt_E3_clicked(); break; // mi octave 3
  771. case 41: on_Bt_F3_clicked(); break; // fa octave 3
  772. case 42: on_Bt_Fd3_clicked(); break; // fa# octave 3
  773. case 43: on_Bt_G3_clicked(); break; //sol
  774. case 44: on_Bt_Gd3_clicked(); break; //sol#
  775. case 45: on_Bt_A3_clicked(); break; //la
  776. case 46: on_Bt_Bb3_clicked(); break; //sib
  777. case 47: on_BT_B3_clicked(); break; //si
  778. case 48: on_Bt_C4_clicked(); break; //do
  779. case 49: on_Bt_Cd4_clicked(); break; //do#
  780. case 50: on_Bt_D4_clicked(); break; //re
  781. case 51: on_Bt_Eb4_clicked(); break; //mib
  782. case 52: on_Bt_E4_clicked(); break; //mi
  783. case 53: on_Bt_F4_clicked(); break; //fa
  784. case 54: on_Bt_Fd4_clicked(); break; //fa#
  785. case 55: on_Bt_G4_clicked(); break; //sol
  786. case 56: on_Bt_Gd4_clicked(); break; //sol#
  787. case 57: on_Bt_A4_clicked(); break; //la
  788. case 58: on_Bt_Bb4_clicked(); break; //sib
  789. case 59: on_Bt_B4_clicked(); break; //si
  790. case 60: on_Bt_C5_clicked(); break; //do
  791. case 61: on_Bt_Cd5_clicked(); break; //do#
  792. case 62: on_Bt_D5_clicked(); break; //re
  793. case 63: on_Bt_Eb5_clicked(); break; //mib
  794. case 64: on_Bt_E5_clicked(); break; //mi
  795. case 65: on_Bt_F5_clicked(); break; //fa
  796. case 66: on_Bt_Fd5_clicked(); break; //fa#
  797. case 67: on_Bt_G5_clicked(); break; //sol
  798. case 68: on_Bt_Gd5_clicked(); break; //sol#
  799. case 69: on_Bt_A5_clicked(); break; //la
  800. case 70: on_Bt_Bb5_clicked(); break; //sib
  801. case 71: on_Bt_B5_clicked(); break; //si
  802. case 72: on_Bt_C6_clicked(); break; //do
  803. case 73: on_Bt_Cd6_clicked(); break; //do#
  804. case 74: on_Bt_D6_clicked(); break; //re
  805. case 75: on_Bt_Eb6_clicked(); break; //mib
  806. case 76: on_Bt_E6_clicked(); break; //mi
  807. case 77: on_Bt_F6_clicked(); break; //fa
  808. case 78: on_Bt_Fd6_clicked(); break; //fa#
  809. case 79: on_Bt_G6_clicked(); break; //sol
  810. case 80: on_Bt_Gd6_clicked(); break; //sol#
  811. case 81: on_Bt_A6_clicked(); break; //la
  812. case 82: on_Bt_Bb6_clicked(); break; //sib
  813.  
  814. default: { ; } break;
  815. }
  816. }
  817.  
  818. /*
  819. A TRAITER: silences (rest)
  820.  
  821. voir fichier xml ligne 535
  822.   *
  823. <note>
  824.   <rest/>
  825.   <duration>12</duration>
  826.   <voice>1</voice>
  827.   <type>eighth</type>
  828.   <staff>1</staff>
  829. </note>
  830. */
  831.  
  832.  
  833. void MainWindow::effacer_touches()
  834. {
  835. QColor c = "#505050";
  836. set_couleur_label(c, label5);
  837. set_couleur_label(c, label6);
  838. set_couleur_label(c, label7);
  839. set_couleur_label(c, label8);
  840. set_couleur_label(c, label9);
  841. set_couleur_label(c, label10);
  842. set_couleur_label(c, label11);
  843. set_couleur_label(c, label12);
  844.  
  845. set_couleur_label(c, label1_2);
  846. set_couleur_label(c, label2_2);
  847. set_couleur_label(c, label3_2);
  848. set_couleur_label(c, label4_2);
  849. set_couleur_label(c, label5_2);
  850. set_couleur_label(c, label6_2);
  851. set_couleur_label(c, label7_2);
  852. set_couleur_label(c, label8_2);
  853. set_couleur_label(c, label9_2);
  854. set_couleur_label(c, label10_2);
  855. set_couleur_label(c, label11_2);
  856. set_couleur_label(c, label12_2);
  857.  
  858. set_couleur_label(c, label1_3);
  859. set_couleur_label(c, label2_3);
  860. set_couleur_label(c, label3_3);
  861. set_couleur_label(c, label4_3);
  862. set_couleur_label(c, label5_3);
  863. set_couleur_label(c, label6_3);
  864. set_couleur_label(c, label7_3);
  865. set_couleur_label(c, label8_3);
  866. set_couleur_label(c, label9_3);
  867. set_couleur_label(c, label10_3);
  868. set_couleur_label(c, label11_3);
  869. set_couleur_label(c, label12_3);
  870.  
  871. set_couleur_label(c, label1_4);
  872. set_couleur_label(c, label2_4);
  873. set_couleur_label(c, label3_4);
  874. set_couleur_label(c, label4_4);
  875. set_couleur_label(c, label5_4);
  876. set_couleur_label(c, label6_4);
  877. set_couleur_label(c, label7_4);
  878. set_couleur_label(c, label8_4);
  879. set_couleur_label(c, label9_4);
  880. set_couleur_label(c, label10_4);
  881. set_couleur_label(c, label11_4);
  882. set_couleur_label(c, label12_4);
  883.  
  884. }
  885.  
  886.  
  887. void MainWindow::on_Bt_RAZ_clicked()
  888. {
  889. // sur le manche
  890. effacer_calque(scene1, calque_notes);
  891. effacer_calque(scene1, calque_encadrement);
  892. Frame_wWidget1->setVisible(false);
  893.  
  894. // la suite sur les touches
  895. effacer_touches();
  896.  
  897. // label_44->setText("-");
  898. // label_45->setText("-");
  899.  
  900. }
  901.  
  902.  
  903. void MainWindow::set_couleur_bouton(QColor c1, QPushButton *Bt_i)
  904. {
  905. QPalette pal1 = Bt_i->palette();
  906. pal1.setColor(QPalette::Button, c1);
  907. Bt_i->setPalette(pal1);
  908. }
  909.  
  910.  
  911. void MainWindow::set_couleur_label(QColor c1, QLabel *Lb_i)
  912. {
  913. QPalette pal1 = Lb_i->palette();
  914. pal1.setColor(Lb_i->backgroundRole(), c1);
  915. Lb_i->setAutoFillBackground(true);
  916. Lb_i->setPalette(pal1);
  917. }
  918.  
  919.  
  920. void MainWindow::set_couleur_case(QColor couleur_i, QTableWidget *Tb_i, int L, int C)
  921. {
  922. QTableWidgetItem *Item1 = new QTableWidgetItem();
  923. Item1->setTextAlignment(Qt::AlignCenter);
  924. Item1->setFlags(Qt::ItemIsSelectable);
  925. Item1->QTableWidgetItem::setBackground(couleur_i);
  926. Tb_i->setItem(L,C,Item1);
  927. }
  928.  
  929.  
  930.  
  931. void MainWindow::Tic2()
  932. {
  933.  
  934. // à voir : ne lit pas les positions des doigts !!!
  935.  
  936. //int i_max = liste_notes.count();
  937. int i_max=tableWidget_3->rowCount();
  938. QString s1, s2, s3;
  939. QString duree_txt;
  940. int di=0;
  941.  
  942. int d_barre;
  943. float dt, vts;
  944. int itrv;
  945.  
  946. vts = doubleSpinBox_vitesse->value();
  947.  
  948. if ((num_ligne_en_cours >= 0) && (num_ligne_en_cours < i_max) )
  949. {
  950. s1 = tableWidget_3->item(num_ligne_en_cours, 7)->text();
  951. //s2 = s1.mid(1); // partie numérique de "*2"
  952. duree_txt = tableWidget_3->item(num_ligne_en_cours, 6)->text();
  953. d_barre = duree_txt.toInt();
  954. nb_colonnes_a_encadrer = d_barre;
  955. num_colonne_a_encadrer=Tp1;
  956.  
  957. write_Time_line();
  958. encadrement_colonne();
  959.  
  960. // memo_mesure_a_encadrer = mesure_a_encadrer;
  961. mesure_a_encadrer = s1.toInt(); // numero de la mesure
  962.  
  963. tableWidget_3->selectRow(num_ligne_en_cours);
  964.  
  965. //diF = duree_txt.toFloat();
  966. di = duree_txt.toInt();
  967.  
  968. s1 = tableWidget_3->item(num_ligne_en_cours, 10)->text();
  969. s2 = tableWidget_3->item(num_ligne_en_cours, 11)->text();
  970. notes_silencieuses = true;
  971. joue_accord_complet(s1, s2); // représentation graphique de la position avant de jouer la note
  972. notes_silencieuses = false;
  973.  
  974. s1 = tableWidget_3->item(num_ligne_en_cours, 7)->text();
  975. // if (s1 !=" ") {play_toc();}
  976.  
  977. effacer_touches();
  978.  
  979. joue_1_ligne(num_ligne_en_cours);
  980.  
  981. s1 = tableWidget_3->item(num_ligne_en_cours, 12)->text();
  982. affi_positions_doigts_dans_status(s1);
  983.  
  984. dt = 20.0 * (float)d_barre;
  985. dt *= (150.0 / vts);
  986. itrv = (int) dt;
  987.  
  988. //dt = 40.0 * d_barre;
  989. //dt *= (10.0 - vts);
  990. //itrv = (int) dt;
  991.  
  992. Timer2->setInterval(itrv);
  993. }
  994. num_ligne_en_cours++;
  995. if (num_ligne_en_cours >= i_max)
  996. {
  997. Bt_lecture_2->setText("joue > debut");
  998. Bt_lecture_2->setStyleSheet("QPushButton{background-color:#50FF1B;}");
  999. lecture_pause =0;
  1000. QString s1;
  1001. s1.setNum(num_ligne_en_cours);// conversion num -> txt
  1002. Timer2->stop();
  1003. }
  1004.  
  1005.  
  1006. encadrement_ligne();
  1007. Tp1 += di;
  1008.  
  1009. nb_notes_jouees++;
  1010.  
  1011. if (nb_notes_jouees>nb_notes_jouees_max)
  1012. {
  1013. nb_notes_jouees=0;
  1014. lecture_pause =0;
  1015. Timer2->stop();
  1016. }
  1017. }
  1018.  
  1019.  
  1020. void MainWindow::play_toc()
  1021. {
  1022. QString s1;
  1023. s1="notes/bip.wav";
  1024. if (n_player == 1)
  1025. {
  1026. player1->setSource(QUrl::fromLocalFile(s1));
  1027. player1->play();
  1028. }
  1029. if (n_player == 2)
  1030. {
  1031. player2->setSource(QUrl::fromLocalFile(s1));
  1032. player2->play();
  1033. }
  1034. if (n_player == 3)
  1035. {
  1036. player3->setSource(QUrl::fromLocalFile(s1));
  1037. player3->play();
  1038. }
  1039. if (n_player == 4)
  1040. {
  1041. player4->setSource(QUrl::fromLocalFile(s1));
  1042. player4->play();
  1043. }
  1044.  
  1045. if (n_player == 5)
  1046. {
  1047. player5->setSource(QUrl::fromLocalFile(s1));
  1048. player5->play();
  1049. }
  1050. if (n_player == 6)
  1051. {
  1052. player6->setSource(QUrl::fromLocalFile(s1));
  1053. player6->play();
  1054. }
  1055. if (n_player == 7)
  1056. {
  1057. player7->setSource(QUrl::fromLocalFile(s1));
  1058. player7->play();
  1059. }
  1060. if (n_player == 8)
  1061. {
  1062. player8->setSource(QUrl::fromLocalFile(s1));
  1063. player8->play();
  1064. }
  1065.  
  1066. n_player++;
  1067. if (n_player >= 9) {n_player = 1;}
  1068.  
  1069. }
  1070.  
  1071.  
  1072. void MainWindow::play_note(int midi) // sortie audio
  1073. {
  1074. if (notes_silencieuses == true) {return ;}
  1075.  
  1076. if (!checkBox_not_erase->isChecked()) {on_Bt_RAZ_clicked();}
  1077.  
  1078. QString s1, freq_txt;
  1079.  
  1080. calcul_hauteur_note(midi);
  1081. s1.setNum(midi);
  1082.  
  1083. lineEdit_6->setText(s1);
  1084. lineEdit_n_midi->setText(s1);
  1085.  
  1086. float freq = freq_mid(midi-12);
  1087. freq_txt.setNum(freq,'f', 2);
  1088. lineEdit_freq->setText(freq_txt+" Hz");
  1089.  
  1090.  
  1091. s1="notes2/"+s1+".wav"; // fichiers audio comprenant une seule note chacun, voir dans le dossier "notes" sur le HDD
  1092.  
  1093. if (n_player == 1)
  1094. {
  1095. player1->setSource(QUrl::fromLocalFile(s1));
  1096. player1->play();
  1097. }
  1098. if (n_player == 2)
  1099. {
  1100. player2->setSource(QUrl::fromLocalFile(s1));
  1101. player2->play();
  1102. }
  1103. if (n_player == 3)
  1104. {
  1105. player3->setSource(QUrl::fromLocalFile(s1));
  1106. player3->play();
  1107. }
  1108. if (n_player == 4)
  1109. {
  1110. player4->setSource(QUrl::fromLocalFile(s1));
  1111. player4->play();
  1112. }
  1113.  
  1114. if (n_player == 5)
  1115. {
  1116. player5->setSource(QUrl::fromLocalFile(s1));
  1117. player5->play();
  1118. }
  1119. if (n_player == 6)
  1120. {
  1121. player6->setSource(QUrl::fromLocalFile(s1));
  1122. player6->play();
  1123. }
  1124. if (n_player == 7)
  1125. {
  1126. player7->setSource(QUrl::fromLocalFile(s1));
  1127. player7->play();
  1128. }
  1129. if (n_player == 8)
  1130. {
  1131. player8->setSource(QUrl::fromLocalFile(s1));
  1132. player8->play();
  1133. }
  1134.  
  1135. n_player++;
  1136. if (n_player >= 9) {n_player = 1;}
  1137. }
  1138.  
  1139.  
  1140. void MainWindow::on_Bt_E3_clicked()
  1141. {
  1142. int n_midi=40;
  1143. play_note(n_midi); // numérotation MIDI
  1144. QColor c=liste_couleurs[4];
  1145. dessine_1_note(6, 0, c); // sur le manche
  1146. set_couleur_label(c, label5); // près de la touche piano
  1147. }
  1148.  
  1149. void MainWindow::on_Bt_F3_clicked()
  1150. {
  1151. int n_midi=41;
  1152. play_note(n_midi);
  1153. QColor c=liste_couleurs[5];
  1154. dessine_1_note(6, 1, c); // sur le manche
  1155. set_couleur_label(c, label6); // près de la touche piano
  1156. }
  1157.  
  1158. void MainWindow::on_Bt_Fd3_clicked()
  1159. {
  1160. int n_midi=42;
  1161. play_note(n_midi);
  1162. QColor c=liste_couleurs[6];
  1163. dessine_1_note(6, 2, c); // sur le manche
  1164. set_couleur_label(c, label7); // près de la touche piano
  1165. }
  1166.  
  1167. void MainWindow::on_Bt_G3_clicked()
  1168. {
  1169. int n_midi=43;
  1170. play_note(n_midi);
  1171. QColor c=liste_couleurs[7];
  1172. dessine_1_note(6, 3, c); // sur le manche
  1173. set_couleur_label(c, label8); // près de la touche piano
  1174. }
  1175.  
  1176. void MainWindow::on_Bt_Gd3_clicked()
  1177. {
  1178. int n_midi=44;
  1179. play_note(n_midi);
  1180. QColor c=liste_couleurs[8];
  1181. dessine_1_note(6, 4, c); // sur le manche
  1182. set_couleur_label(c, label9); // près de la touche piano
  1183. }
  1184.  
  1185. void MainWindow::on_Bt_A3_clicked()
  1186. {
  1187. int n_midi=45;
  1188. play_note(n_midi);
  1189. QColor c=liste_couleurs[9];
  1190. dessine_1_note(6, 5, c); dessine_1_note(5, 0, c); // sur le manche
  1191. set_couleur_label(c, label10); // près de la touche piano
  1192. }
  1193.  
  1194. void MainWindow::on_Bt_Bb3_clicked()
  1195. {
  1196. int n_midi=46;
  1197. play_note(n_midi);
  1198. QColor c=liste_couleurs[10];
  1199. dessine_1_note(6, 6, c); dessine_1_note(5, 1, c);
  1200. set_couleur_label(c, label11); // près de la touche piano
  1201. }
  1202.  
  1203. void MainWindow::on_BT_B3_clicked()
  1204. {
  1205. int n_midi=47;
  1206. play_note(n_midi);
  1207. QColor c=liste_couleurs[11];
  1208. dessine_1_note(6, 7, c); dessine_1_note(5, 2, c);
  1209. set_couleur_label(c, label12); // près de la touche piano
  1210. }
  1211.  
  1212. void MainWindow::on_Bt_C4_clicked()
  1213. {
  1214. int n_midi=48;
  1215. play_note(n_midi);
  1216. QColor c=liste_couleurs[0];
  1217. dessine_1_note(6, 8, c); dessine_1_note(5, 3, c);
  1218. set_couleur_label(c, label1_2);
  1219. }
  1220.  
  1221. void MainWindow::on_Bt_Cd4_clicked()
  1222. {
  1223. int n_midi=49;
  1224. play_note(n_midi);
  1225. QColor c=liste_couleurs[1];
  1226. dessine_1_note(6, 9, c); dessine_1_note(5, 4, c);
  1227. set_couleur_label(c, label2_2);
  1228. }
  1229.  
  1230. void MainWindow::on_Bt_D4_clicked()
  1231. {
  1232. int n_midi=50;
  1233. play_note(n_midi);
  1234. QColor c=liste_couleurs[2];
  1235. dessine_1_note(6, 10, c); dessine_1_note(5, 5, c); dessine_1_note(4, 0, c);
  1236. set_couleur_label(c, label3_2);
  1237. }
  1238.  
  1239. void MainWindow::on_Bt_Eb4_clicked()
  1240. {
  1241. int n_midi=51;
  1242. play_note(n_midi);
  1243. QColor c=liste_couleurs[3];
  1244. dessine_1_note(6, 11, c); dessine_1_note(5, 6, c); dessine_1_note(4, 1, c);
  1245. set_couleur_label(c, label4_2);
  1246. }
  1247.  
  1248. void MainWindow::on_Bt_E4_clicked()
  1249. {
  1250. int n_midi=52;
  1251. play_note(n_midi);
  1252. QColor c=liste_couleurs[4];
  1253. dessine_1_note(6, 12, c); dessine_1_note(5, 7, c); dessine_1_note(4, 2, c);
  1254. set_couleur_label(c, label5_2);
  1255. }
  1256.  
  1257. void MainWindow::on_Bt_F4_clicked()
  1258. {
  1259. int n_midi=53;
  1260. play_note(n_midi);
  1261. QColor c=liste_couleurs[5];
  1262. dessine_1_note(6, 13, c); dessine_1_note(5, 8, c); dessine_1_note(4, 3, c);
  1263. set_couleur_label(c, label6_2);
  1264. }
  1265.  
  1266. void MainWindow::on_Bt_Fd4_clicked()
  1267. {
  1268. int n_midi=54;
  1269. play_note(n_midi);
  1270. QColor c=liste_couleurs[6];
  1271. dessine_1_note(6, 14, c); dessine_1_note(5, 9, c); dessine_1_note(4, 4, c);
  1272. set_couleur_label(c, label7_2);
  1273. }
  1274.  
  1275. void MainWindow::on_Bt_G4_clicked()
  1276. {
  1277. int n_midi=55;
  1278. play_note(n_midi);
  1279. QColor c=liste_couleurs[7];
  1280. dessine_1_note(6, 15, c); dessine_1_note(5, 10, c); dessine_1_note(4, 5, c); dessine_1_note(3, 0, c);
  1281. set_couleur_label(c, label8_2);
  1282. }
  1283.  
  1284. void MainWindow::on_Bt_Gd4_clicked()
  1285. {
  1286. int n_midi=56;
  1287. play_note(n_midi);
  1288. QColor c=liste_couleurs[8];
  1289. dessine_1_note(6, 16, c); dessine_1_note(5, 11, c); dessine_1_note(4, 6, c); dessine_1_note(3, 1, c);
  1290. set_couleur_label(c, label9_2);
  1291. }
  1292.  
  1293. void MainWindow::on_Bt_A4_clicked()
  1294. {
  1295. int n_midi=57;
  1296. play_note(n_midi);
  1297. QColor c=liste_couleurs[9];
  1298. dessine_1_note(6, 17, c); dessine_1_note(5, 12, c); dessine_1_note(4, 7, c); dessine_1_note(3, 2, c);
  1299. set_couleur_label(c, label10_2);
  1300. }
  1301.  
  1302. void MainWindow::on_Bt_Bb4_clicked()
  1303. { int n_midi=58;
  1304. play_note(n_midi);
  1305. QColor c=liste_couleurs[10];
  1306. dessine_1_note(6, 18, c); dessine_1_note(5, 13, c); dessine_1_note(4, 8, c); dessine_1_note(3, 3, c);
  1307. set_couleur_label(c, label11_2);
  1308. }
  1309.  
  1310. void MainWindow::on_Bt_B4_clicked()
  1311. {
  1312. int n_midi=59;
  1313. play_note(n_midi);
  1314. QColor c=liste_couleurs[11];
  1315. dessine_1_note(2, 0, c); dessine_1_note(3, 4, c); dessine_1_note(4, 9, c); dessine_1_note(5, 14, c);
  1316. set_couleur_label(c, label12_2);
  1317. }
  1318.  
  1319. void MainWindow::on_Bt_C5_clicked()
  1320. {
  1321. int n_midi=60;
  1322. play_note(n_midi);
  1323. QColor c=liste_couleurs[0];
  1324. dessine_1_note(2, 1, c); dessine_1_note(3, 5, c); dessine_1_note(4, 10, c); dessine_1_note(5, 15, c);
  1325. set_couleur_label(c, label1_3);
  1326. }
  1327.  
  1328. void MainWindow::on_Bt_Cd5_clicked()
  1329. {
  1330. int n_midi=61;
  1331. play_note(n_midi);
  1332. QColor c=liste_couleurs[1];
  1333. dessine_1_note(2, 2, c); dessine_1_note(3, 6, c); dessine_1_note(4, 11, c); dessine_1_note(5, 16, c);
  1334. set_couleur_label(c, label2_3);
  1335. }
  1336.  
  1337. void MainWindow::on_Bt_D5_clicked()
  1338. {
  1339. int n_midi=62;
  1340. play_note(n_midi);
  1341. QColor c=liste_couleurs[2];
  1342. dessine_1_note(2, 3, c); dessine_1_note(3, 7, c); dessine_1_note(4, 12, c); dessine_1_note(5, 17, c);
  1343. set_couleur_label(c, label3_3);
  1344. }
  1345.  
  1346. void MainWindow::on_Bt_Eb5_clicked()
  1347. {
  1348. int n_midi=63;
  1349. play_note(n_midi);
  1350. QColor c=liste_couleurs[3];
  1351. dessine_1_note(2, 4, c); dessine_1_note(3, 8, c); dessine_1_note(4, 13, c); dessine_1_note(5, 18, c);
  1352. set_couleur_label(c, label4_3);
  1353. }
  1354.  
  1355. void MainWindow::on_Bt_E5_clicked()
  1356. {
  1357. int n_midi=64;
  1358. play_note(n_midi);
  1359. QColor c=liste_couleurs[4];
  1360. dessine_1_note(1, 0, c); dessine_1_note(2, 5, c); dessine_1_note(3, 9, c); dessine_1_note(4, 14, c);
  1361. set_couleur_label(c, label5_3);
  1362.  
  1363. }
  1364.  
  1365. void MainWindow::on_Bt_F5_clicked()
  1366. {
  1367. int n_midi=65;
  1368. play_note(n_midi);
  1369. QColor c=liste_couleurs[5];
  1370. dessine_1_note(1, 1, c); dessine_1_note(2, 6, c); dessine_1_note(3, 10, c); dessine_1_note(4, 15, c);
  1371. set_couleur_label(c, label6_3);
  1372. }
  1373.  
  1374. void MainWindow::on_Bt_Fd5_clicked()
  1375. {
  1376. int n_midi=66;
  1377. play_note(n_midi);
  1378. QColor c=liste_couleurs[6];
  1379. dessine_1_note(1, 2, c); dessine_1_note(2, 7, c); dessine_1_note(3, 11, c); dessine_1_note(4, 16, c);
  1380. set_couleur_label(c, label7_3);
  1381. }
  1382.  
  1383. void MainWindow::on_Bt_G5_clicked()
  1384. {
  1385. int n_midi=67;
  1386. play_note(n_midi);
  1387. QColor c=liste_couleurs[7];
  1388. dessine_1_note(1, 3, c); dessine_1_note(2, 8, c); dessine_1_note(3, 12, c); dessine_1_note(4, 17, c);
  1389. set_couleur_label(c, label8_3);
  1390. }
  1391.  
  1392. void MainWindow::on_Bt_Gd5_clicked()
  1393. {
  1394. int n_midi=68;
  1395. play_note(n_midi);
  1396. QColor c=liste_couleurs[8];
  1397. dessine_1_note(1, 4, c); dessine_1_note(2, 9, c); dessine_1_note(3, 13, c); dessine_1_note(4, 18, c);
  1398. set_couleur_label(c, label9_3);
  1399. }
  1400.  
  1401. void MainWindow::on_Bt_A5_clicked()
  1402. {
  1403. int n_midi=69;
  1404. play_note(n_midi);
  1405. QColor c=liste_couleurs[9];
  1406. dessine_1_note(1, 5, c); dessine_1_note(2, 10, c); dessine_1_note(3, 14, c);
  1407. set_couleur_label(c, label10_3);
  1408. }
  1409.  
  1410. void MainWindow::on_Bt_Bb5_clicked()
  1411. {
  1412. int n_midi=70;
  1413. play_note(n_midi);
  1414. QColor c=liste_couleurs[10];
  1415. dessine_1_note(1, 6, c); dessine_1_note(2, 11, c); dessine_1_note(3, 15, c);
  1416. set_couleur_label(c, label11_3);
  1417. }
  1418.  
  1419. void MainWindow::on_Bt_B5_clicked()
  1420. {
  1421. int n_midi=71;
  1422. play_note(n_midi);
  1423. QColor c=liste_couleurs[11];
  1424. dessine_1_note(1, 7, c); dessine_1_note(2, 12, c); dessine_1_note(3, 16, c);
  1425. set_couleur_label(c, label12_3);
  1426. }
  1427.  
  1428.  
  1429. void MainWindow::on_Bt_C6_clicked()
  1430. {
  1431. int n_midi=72;
  1432. play_note(n_midi);
  1433. QColor c=liste_couleurs[0];
  1434. dessine_1_note(1, 8, c); dessine_1_note(2, 13, c); dessine_1_note(3, 17, c);
  1435. set_couleur_label(c, label1_4);
  1436. }
  1437.  
  1438. void MainWindow::on_Bt_Cd6_clicked()
  1439. {
  1440. int n_midi=73;
  1441. play_note(n_midi);
  1442. QColor c=liste_couleurs[1];
  1443. dessine_1_note(1, 9, c); dessine_1_note(2, 14, c); dessine_1_note(3, 18, c);
  1444. set_couleur_label(c, label2_4);
  1445. }
  1446.  
  1447.  
  1448. void MainWindow::on_Bt_D6_clicked()
  1449. {
  1450. int n_midi=74;
  1451. play_note(n_midi);
  1452. QColor c=liste_couleurs[2];
  1453. dessine_1_note(1, 10, c); dessine_1_note(2, 15, c);
  1454. set_couleur_label(c, label3_4);
  1455. }
  1456.  
  1457. void MainWindow::on_Bt_Eb6_clicked()
  1458. {
  1459. int n_midi=75;
  1460. play_note(n_midi);
  1461. QColor c=liste_couleurs[3];
  1462. dessine_1_note(1, 11, c); dessine_1_note(2, 16, c);
  1463. set_couleur_label(c, label4_4);
  1464. }
  1465.  
  1466. void MainWindow::on_Bt_E6_clicked()
  1467. {
  1468. int n_midi=76;
  1469. play_note(n_midi);
  1470. QColor c=liste_couleurs[4];
  1471. dessine_1_note(1, 12, c); dessine_1_note(2, 17, c);
  1472. set_couleur_label(c, label5_4);
  1473. }
  1474.  
  1475. void MainWindow::on_Bt_F6_clicked()
  1476. {
  1477. int n_midi=77;
  1478. play_note(n_midi);
  1479. QColor c=liste_couleurs[5];
  1480. dessine_1_note(1, 13, c); dessine_1_note(2, 18, c);
  1481. set_couleur_label(c, label6_4);
  1482. }
  1483.  
  1484. void MainWindow::on_Bt_Fd6_clicked()
  1485. {
  1486. int n_midi=78;
  1487. play_note(n_midi);
  1488. QColor c=liste_couleurs[6];
  1489. dessine_1_note(1, 14, c); dessine_1_note(2, 19, c);
  1490. set_couleur_label(c, label7_4);
  1491. }
  1492.  
  1493. void MainWindow::on_Bt_G6_clicked()
  1494. {
  1495. int n_midi=79;
  1496. play_note(n_midi);
  1497. QColor c=liste_couleurs[7];
  1498. dessine_1_note(1, 15, c); dessine_1_note(2, 20, c);
  1499. set_couleur_label(c, label8_4);
  1500. }
  1501.  
  1502. void MainWindow::on_Bt_Gd6_clicked()
  1503. {
  1504. int n_midi=80;
  1505. play_note(n_midi);
  1506. QColor c=liste_couleurs[8];
  1507. dessine_1_note(1, 16, c);
  1508. set_couleur_label(c, label9_4);
  1509. }
  1510.  
  1511. void MainWindow::on_Bt_A6_clicked()
  1512. {
  1513. int n_midi=81;
  1514. play_note(n_midi);
  1515. QColor c=liste_couleurs[9];
  1516. dessine_1_note(1, 17, c);
  1517. set_couleur_label(c, label10_4);
  1518. }
  1519.  
  1520. void MainWindow::on_Bt_Bb6_clicked()
  1521. {
  1522. int n_midi=82;
  1523. play_note(n_midi);
  1524. QColor c=liste_couleurs[10];
  1525. dessine_1_note(1, 18, c);
  1526. set_couleur_label(c, label11_4);
  1527. }
  1528.  
  1529.  
  1530. void MainWindow::on_Bt_B6_clicked()
  1531. {
  1532. int n_midi=83;
  1533. play_note(n_midi);
  1534. QColor c=liste_couleurs[11];
  1535. dessine_1_note(1, 19, c);
  1536. set_couleur_label(c, label12_4);
  1537. }
  1538.  
  1539. void MainWindow::on_Bt_C7_clicked()
  1540. {
  1541. int n_midi=84;
  1542. play_note(n_midi);
  1543. QColor c=liste_couleurs[0];
  1544. dessine_1_note(1, 20, c);
  1545. //set_couleur_label(c, label13_4);
  1546. }
  1547.  
  1548.  
  1549.  
  1550. void MainWindow::joue_1_ligne(int ligne_i)
  1551. {
  1552. QString s1;
  1553.  
  1554. for(int C=1; C<5; C++)
  1555. {
  1556. //on_Bt_RAZ_clicked();
  1557. s1 = tableWidget_3->item(ligne_i, C)->text();
  1558. s1 = s1.left(3);
  1559. int m1 = s1.toInt();
  1560. execute_note_midi(m1);
  1561. }
  1562. }
  1563.  
  1564.  
  1565. void MainWindow::complete_case(int row, int column, QString s1, QColor c1, QColor c2, bool bold1, QTableWidget *QTI)
  1566. {
  1567. int R = QTI->rowCount();
  1568. int C = QTI->columnCount();
  1569.  
  1570. if ((row<0) || (column<0) || (row > R) || (column > C ) ) {return;}
  1571.  
  1572. QTableWidgetItem *Item1 = new QTableWidgetItem();
  1573. Item1->QTableWidgetItem::setForeground(c1);
  1574. Item1->QTableWidgetItem::setBackground(c2);
  1575.  
  1576. QFont font1;
  1577. font1.setBold(bold1);
  1578. Item1->setFont(font1);
  1579. Item1->setTextAlignment(Qt::AlignCenter);
  1580.  
  1581. Item1->setText(s1);
  1582. QTI->setItem(row,column,Item1);
  1583. }
  1584.  
  1585.  
  1586. void MainWindow::affi_positions_doigts_dans_status(QString s_i)
  1587. {
  1588. // et dans le cadre 'Position de doigts' (tableWidget_doigts)
  1589. // et numérote les notes jouées sur le manche
  1590.  
  1591. QString s2, s3;
  1592. int corde1, case1, num1;
  1593. init_tableWidget_doigts();
  1594.  
  1595. s3="";
  1596. //---------------------------------------------------------------------------------------
  1597. s2=extraction_data(s_i, "D0v=");
  1598. if((s2 != "") && (s2 != "-"))
  1599. {
  1600. num1=0;
  1601. tableWidget_doigts->setItem(0, 0, new QTableWidgetItem (s2) ); // corde
  1602. tableWidget_doigts->item(0, 0)->setTextAlignment(Qt::AlignCenter);
  1603. s3 += "( DOIGT 1 corde " + s2;
  1604. corde1 = s2.toInt();
  1605. label_44->setText("corde " + s2);
  1606.  
  1607. s2=extraction_data(s_i, "D0h=");
  1608. case1 = s2.toInt();
  1609. s3 += " case " + s2 + " ) ";
  1610. tableWidget_doigts->setItem(0, 1, new QTableWidgetItem (s2) ); // case
  1611. tableWidget_doigts->item(0, 1)->setTextAlignment(Qt::AlignCenter);
  1612. numerote_1_note(corde1, case1, num1);
  1613. label_45->setText("case " + s2);
  1614. }
  1615. //---------------------------------------------------------------------------------------
  1616. s2=extraction_data(s_i, "D1v=");
  1617. if((s2 != "") && (s2 != "-"))
  1618. {
  1619. num1=1;
  1620. tableWidget_doigts->setItem(1, 0, new QTableWidgetItem (s2) ); // corde
  1621. tableWidget_doigts->item(1, 0)->setTextAlignment(Qt::AlignCenter);
  1622. s3 += "( DOIGT 1 corde " + s2;
  1623. corde1 = s2.toInt();
  1624. label_44->setText("corde " + s2);
  1625.  
  1626. s2=extraction_data(s_i, "D1h=");
  1627. case1 = s2.toInt();
  1628. s3 += " case " + s2 + " ) ";
  1629. tableWidget_doigts->setItem(1, 1, new QTableWidgetItem (s2) ); // case
  1630. tableWidget_doigts->item(1, 1)->setTextAlignment(Qt::AlignCenter);
  1631. numerote_1_note(corde1, case1, num1);
  1632. label_45->setText("case " + s2);
  1633. }
  1634. //---------------------------------------------------------------------------------------
  1635. s2=extraction_data(s_i, "D2v=");
  1636. if((s2 != "") && (s2 != "-"))
  1637. {
  1638. bool ok; int dec = s2.toInt(&ok, 10);
  1639. if (ok==true)
  1640. {
  1641. num1=2;
  1642. tableWidget_doigts->setItem(2, 0, new QTableWidgetItem (s2) ); // corde
  1643. tableWidget_doigts->item(2, 0)->setTextAlignment(Qt::AlignCenter);
  1644. s3 += "( DOIGT 2 corde " + s2;
  1645. corde1 = s2.toInt();
  1646. label_44->setText("corde " + s2);
  1647.  
  1648.  
  1649. s2=extraction_data(s_i, "D2h=");
  1650. case1 = s2.toInt();
  1651. label_45->setText("case " + s2);
  1652.  
  1653. s3 += " case " + s2 + " ) ";
  1654. tableWidget_doigts->setItem(2, 1, new QTableWidgetItem (s2) ); // case
  1655. tableWidget_doigts->item(2, 1)->setTextAlignment(Qt::AlignCenter);
  1656. numerote_1_note(corde1, case1, num1);
  1657. }
  1658. }
  1659. //---------------------------------------------------------------------------------------
  1660.  
  1661. s2=extraction_data(s_i, "D3v=");
  1662. if((s2 != "") && (s2 != "-"))
  1663. {
  1664. bool ok; int dec = s2.toInt(&ok, 10);
  1665. if (ok==true)
  1666. {
  1667. num1=3;
  1668. tableWidget_doigts->setItem(3, 0, new QTableWidgetItem (s2) ); // corde
  1669. tableWidget_doigts->item(3, 0)->setTextAlignment(Qt::AlignCenter);
  1670. s3 += "( DOIGT 3 corde " + s2;
  1671. corde1 = s2.toInt();
  1672. label_44->setText("corde " + s2);
  1673.  
  1674.  
  1675. s2=extraction_data(s_i, "D3h=");
  1676. case1 = s2.toInt();
  1677. s3 += " case " + s2 + " ) ";
  1678. label_45->setText("case " + s2);
  1679. tableWidget_doigts->setItem(3, 1, new QTableWidgetItem (s2) ); // case
  1680. tableWidget_doigts->item(3, 1)->setTextAlignment(Qt::AlignCenter);
  1681. numerote_1_note(corde1, case1, num1);
  1682. }
  1683. }
  1684. //---------------------------------------------------------------------------------------
  1685. s2=extraction_data(s_i, "D4v=");
  1686. if((s2 != "") && (s2 != "-"))
  1687. {
  1688. bool ok; int dec = s2.toInt(&ok, 10);
  1689. if (ok==true)
  1690. {
  1691. num1=4;
  1692. tableWidget_doigts->setItem(4, 0, new QTableWidgetItem (s2) ); // corde
  1693. tableWidget_doigts->item(4, 0)->setTextAlignment(Qt::AlignCenter);
  1694. s3 += "( DOIGT 4 corde " + s2;
  1695. corde1 = s2.toInt();
  1696. label_44->setText("corde " + s2);
  1697.  
  1698.  
  1699. s2=extraction_data(s_i, "D4h=");
  1700. case1 = s2.toInt();
  1701. s3 += " case " + s2 + " ) ";
  1702. label_45->setText("case " + s2);
  1703. tableWidget_doigts->setItem(4, 1, new QTableWidgetItem (s2) ); // case
  1704. tableWidget_doigts->item(4, 1)->setTextAlignment(Qt::AlignCenter);
  1705. numerote_1_note(corde1, case1, num1);
  1706. }
  1707. }
  1708. //---------------------------------------------------------------------------------------
  1709.  
  1710. statusbar->showMessage(s3);
  1711. }
  1712.  
  1713. /*
  1714. QString MainWindow::nom_note(int mid)
  1715. {
  1716.   QString s1;
  1717.  
  1718.   int h1 = calcul_hauteur_note(mid);
  1719.   h1-=3;
  1720.   if(h1<0){h1+=12;}
  1721.   if(h1>11){h1-=12;}
  1722.   s1 = gamme_chromatique[h1];
  1723.   return s1;
  1724. }
  1725. */
  1726.  
  1727. void MainWindow::affiche_liste_notes() // en TEXTE dans le petit tableau
  1728. {
  1729. NOTE_importee note_i;
  1730. QString s1;
  1731.  
  1732. // QString blanc = "#FFFFFF";
  1733. // QString jaune = "#FFFF00";
  1734. // QString cyan = "#00FFFF";
  1735.  
  1736. tableWidget_lst_notes->clear();
  1737. tableWidget_lst_notes->setRowCount(0);
  1738. init_TAB_lst_notes();
  1739.  
  1740. uint16_t n_max = liste_NOTES_importees.length();
  1741. if (n_max == 0) {return;}
  1742.  
  1743. for(int n=0; n<n_max; n++) //n_max
  1744. {
  1745. note_i=liste_NOTES_importees[n];
  1746.  
  1747. int numero = note_i.numero;
  1748. int midi = note_i.midi;
  1749. int n_barreT = note_i.n_barreT;
  1750. int n_barreM = note_i.n_barreM;
  1751.  
  1752. int num_ligne = tableWidget_lst_notes->rowCount();
  1753. tableWidget_lst_notes->setRowCount(num_ligne+1); // ajout une ligne au tableau
  1754.  
  1755. s1.setNum(numero);
  1756.  
  1757. complete_case(n, 0, s1, "000000", "#FFFFFF", false, tableWidget_lst_notes);
  1758.  
  1759. s1.setNum(midi);
  1760. int h1 = calcul_hauteur_note(midi);
  1761.  
  1762.  
  1763. QString couleur1 = liste_couleurs[h1];
  1764. complete_case(n, 1, s1, "#000000", couleur1, true, tableWidget_lst_notes);
  1765.  
  1766. s1 = nom_note_FR(midi);
  1767. complete_case(n, 2, s1, "#000000", "#FFFFFF", false, tableWidget_lst_notes);
  1768.  
  1769. s1.setNum(n_barreM);
  1770. complete_case(n, 3, s1, "#000000", "#FFFFFF", false, tableWidget_lst_notes);
  1771.  
  1772. }
  1773.  
  1774. tableWidget_lst_notes->AdjustToContents;
  1775. // affiche_histogramme();
  1776. }
  1777.  
  1778.  
  1779. void MainWindow::on_tableWidget_3_cellClicked(int row, int column)
  1780. {
  1781. ligne_TW3 = row;
  1782. QString s1, s2, s3, ACC, cases;
  1783. QString duree_txt;
  1784. int di=0;
  1785. int R;
  1786.  
  1787. //checkBox_not_erase->setChecked(true);
  1788.  
  1789. R = tableWidget_3->currentRow();
  1790. num_ligne_en_cours = row;
  1791. s1.setNum(R+1);
  1792. lineEdit_9->setText(s1);
  1793.  
  1794. encadrement_ligne();
  1795.  
  1796. s2 = tableWidget_3->item(row, column)->text(); // actuellement dans la case cible
  1797.  
  1798. s1 = lineEdit_n_midi->text();
  1799.  
  1800. int m1 = s1.toInt();
  1801.  
  1802. if ((column<4) && mode_depot_note == true)
  1803. {
  1804. mode_depot_note = false;
  1805. statusbar->showMessage("");
  1806. MainWindow::setCursor(Qt::ArrowCursor);
  1807. if(s1 != s2) // alors on inscrit la nouvelle valeur dans la case
  1808. {
  1809. int h1 = calcul_hauteur_note(m1); // h1 = 0..11
  1810. h1-=3;
  1811. if(h1<0){h1+=12;}
  1812. if(h1>11){h1-=12;}
  1813.  
  1814. s3 = " " + gamme_chromatique[h1];
  1815. s1 += s3;
  1816.  
  1817. QColor couleur_case = liste_couleurs[h1];
  1818.  
  1819. complete_case(row, column, s1, "#000000", couleur_case, false, tableWidget_3);
  1820.  
  1821. tableWidget_3->resizeColumnsToContents();
  1822. }
  1823. else // on efface la valeur
  1824. {
  1825. tableWidget_3->setItem(row, column, new QTableWidgetItem ("--") );
  1826. }
  1827. init_TW_T();
  1828. }
  1829.  
  1830. if (column==5) // celle qui contient les petits boutons ( triangles '>' verts)
  1831. {
  1832. //effacer_calque(scene1, calque_notes);
  1833.  
  1834. ACC = tableWidget_3->item(row, 10)->text();
  1835. cases = tableWidget_3->item(row, 11)->text();
  1836.  
  1837. notes_silencieuses = true;
  1838. joue_accord_complet(ACC, cases); // représentation graphique de la position avant de jouer la note
  1839. notes_silencieuses = false;
  1840.  
  1841. joue_1_ligne(row);
  1842.  
  1843. s1 = tableWidget_3->item(row, 12)->text();
  1844. affi_positions_doigts_dans_status(s1);
  1845. }
  1846.  
  1847.  
  1848. if (column==6) { write_Time_line(); }
  1849.  
  1850. if (column==9) // ACC
  1851. {
  1852. s1 = tableWidget_3->item(row, 10)->text();
  1853. s2 = tableWidget_3->item(row, 11)->text();
  1854.  
  1855.  
  1856. if (s1 !=" ")
  1857. {
  1858. notes_silencieuses = true;
  1859. joue_accord_complet(s1, s2);
  1860. notes_silencieuses = false;
  1861. }
  1862. }
  1863.  
  1864. if (column==11)
  1865. {
  1866. QMessageBox msgBox;
  1867. QString s1;
  1868. s1 = "Colonne read only";
  1869. s1 += "\n";
  1870. s1 += "Utiliser le cadre 'de saisie 'Position des doigts'";
  1871. s1 += "\n";
  1872. s1 += "pour saisir les positions.";
  1873. msgBox.setText(s1);
  1874. msgBox.exec();
  1875. }
  1876.  
  1877. s2 = tableWidget_3->item(row, 7)->text();
  1878. s2 = s2.mid(1);
  1879. mesure_a_encadrer = s2.toInt();
  1880.  
  1881. write_Time_line();
  1882.  
  1883. duree_txt = tableWidget_3->item(R, 6)->text();
  1884.  
  1885. di = duree_txt.toInt();
  1886. nb_colonnes_a_encadrer = di;
  1887.  
  1888. int T_note;
  1889. T_note = calcul_T_note(row);
  1890. num_colonne_a_encadrer = T_note;
  1891.  
  1892. encadrement_colonne();
  1893. }
  1894.  
  1895.  
  1896. void MainWindow::on_Bt_ACCORD_1_clicked()
  1897. {
  1898. // accord majeur
  1899. //effacer_calque(scene1, calque_notes);
  1900. on_Bt_RAZ_clicked();
  1901. label_44->setText("-");
  1902. label_45->setText("-");
  1903.  
  1904. checkBox_not_erase->setChecked(true);
  1905.  
  1906. QString s1, s2, s3, s4;
  1907. int d = spinBox_2->value();
  1908.  
  1909. s1 = gamme_chromatique[d];
  1910. s2="M";
  1911. s1+=s2;
  1912. lineEdit_10->setText(s1);
  1913.  
  1914. case_min = spinBox_4->value(); s3.setNum(case_min);
  1915. case_max = spinBox_5->value(); s4.setNum(case_max);
  1916. lineEdit_14->setText(s3 + "a" +s4);
  1917.  
  1918. label_43->clear();
  1919. encadre_accord(case_min, case_max);
  1920.  
  1921. //on_Bt_RAZ_clicked();
  1922. execute_note_midi(28 + spinBox_2->value());
  1923. execute_note_midi(31 + spinBox_2->value());
  1924. execute_note_midi(36 + spinBox_2->value());
  1925.  
  1926. execute_note_midi(28+12 + spinBox_2->value());
  1927. execute_note_midi(31+12 + spinBox_2->value());
  1928. execute_note_midi(36+12 + spinBox_2->value());
  1929.  
  1930. execute_note_midi(28+12+12 + spinBox_2->value());
  1931. execute_note_midi(31+12+12 + spinBox_2->value());
  1932. execute_note_midi(36+12+12 + spinBox_2->value());
  1933.  
  1934. execute_note_midi(28+12+12+12 + spinBox_2->value());
  1935. execute_note_midi(31+12+12+12 + spinBox_2->value());
  1936. execute_note_midi(36+12+12+12 + spinBox_2->value());
  1937.  
  1938. type_accords = 1;
  1939. }
  1940.  
  1941.  
  1942.  
  1943. void MainWindow::on_Bt_ACCORD_2_clicked()
  1944. {
  1945. // accord mineur
  1946.  
  1947. effacer_calque(scene1, calque_notes);
  1948. label_44->setText("-");
  1949. label_45->setText("-");
  1950.  
  1951. checkBox_not_erase->setChecked(true);
  1952.  
  1953. QString s1, s2, s3, s4;
  1954. int d = spinBox_2->value();
  1955.  
  1956. s1 = gamme_chromatique[d];
  1957. s2="m";
  1958. s1+=s2;
  1959. lineEdit_10->setText(s1);
  1960.  
  1961. case_min = spinBox_4->value(); s3.setNum(case_min);
  1962. case_max = spinBox_5->value(); s4.setNum(case_max);
  1963. lineEdit_14->setText(s3 + "a" +s4);
  1964.  
  1965.  
  1966. label_43->clear();
  1967. encadre_accord(case_min, case_max);
  1968.  
  1969. //on_Bt_RAZ_clicked();
  1970.  
  1971.  
  1972. execute_note_midi( 31 + spinBox_2->value());
  1973. execute_note_midi( 36 + spinBox_2->value());
  1974. execute_note_midi( 39 + spinBox_2->value());
  1975.  
  1976. execute_note_midi( 31+12 + spinBox_2->value());
  1977. execute_note_midi( 36+12 + spinBox_2->value());
  1978. execute_note_midi( 39+12 + spinBox_2->value());
  1979.  
  1980. execute_note_midi( 31+12+12 + spinBox_2->value());
  1981. execute_note_midi( 36+12+12 + spinBox_2->value());
  1982. execute_note_midi( 39+12+12 + spinBox_2->value());
  1983.  
  1984. execute_note_midi( 31+12+12+12 + spinBox_2->value());
  1985. execute_note_midi( 36+12+12+12 + spinBox_2->value());
  1986. execute_note_midi( 39+12+12+12 + spinBox_2->value());
  1987.  
  1988. type_accords = 2;
  1989. }
  1990.  
  1991.  
  1992. void MainWindow::on_Bt_ACCORD_3_clicked()
  1993. {
  1994. // accord 7eme de dominante
  1995.  
  1996. effacer_calque(scene1, calque_notes);
  1997. label_44->setText("-");
  1998. label_45->setText("-");
  1999. checkBox_not_erase->setChecked(true);
  2000.  
  2001. QString s1, s2, s3, s4;
  2002. int d = spinBox_2->value();
  2003.  
  2004. s1 = gamme_chromatique[d];
  2005. s2="7";
  2006. s1+=s2;
  2007. lineEdit_10->setText(s1);
  2008.  
  2009. case_min = spinBox_4->value(); s3.setNum(case_min);
  2010. case_max = spinBox_5->value(); s4.setNum(case_max);
  2011. lineEdit_14->setText(s3 + "a" +s4);
  2012.  
  2013. label_43->clear();
  2014. encadre_accord(case_min, case_max);
  2015.  
  2016. //on_Bt_RAZ_clicked();
  2017. execute_note_midi( 36 + spinBox_2->value());
  2018. execute_note_midi( 40 + spinBox_2->value());
  2019. execute_note_midi( 43 + spinBox_2->value());
  2020. execute_note_midi( 58 + spinBox_2->value());
  2021.  
  2022. execute_note_midi( 36+12 + spinBox_2->value());
  2023. execute_note_midi( 40+12 + spinBox_2->value());
  2024. execute_note_midi( 43+12 + spinBox_2->value());
  2025. execute_note_midi( 58+12 + spinBox_2->value());
  2026.  
  2027. execute_note_midi( 36+12+12 + spinBox_2->value());
  2028. execute_note_midi( 40+12+12 + spinBox_2->value());
  2029. execute_note_midi( 43+12+12 + spinBox_2->value());
  2030. execute_note_midi( 58+12+12 + spinBox_2->value());
  2031.  
  2032. type_accords = 3;
  2033. }
  2034.  
  2035.  
  2036. void MainWindow::on_Bt_NO_ACCORD_clicked() // note seule
  2037. {
  2038. QString s3, s4;
  2039.  
  2040. effacer_calque(scene1, calque_notes);
  2041.  
  2042. lineEdit_10->clear();
  2043. lineEdit_10->setText("-");
  2044. label_43->clear();
  2045.  
  2046. case_min = spinBox_4->value();
  2047. s3.setNum(case_min);
  2048.  
  2049. case_max = case_min;
  2050.  
  2051. spinBox_5->setValue(case_max);
  2052. s4.setNum(case_max);
  2053.  
  2054. lineEdit_14->setText(s3 + "a" +s4);
  2055.  
  2056. type_accords = 0;
  2057. }
  2058.  
  2059.  
  2060.  
  2061. void MainWindow::joue_accord_complet(QString ACC, QString cases)
  2062. {
  2063. // exemple: (Sol, 3a5) -> c.a.d case 3 à case 5
  2064. QString s1, s2b, s2c, s3, s4;
  2065. //QString degré_txt;
  2066. QString type;
  2067. int p1, p2;
  2068. s1 = ACC; // exemples : Sim, Sibm, Do, Dom, La, Lam, Sol, Solm, Mi7
  2069.  
  2070. // if (!checkBox_not_erase->isChecked()) {on_Bt_RAZ_clicked();}
  2071.  
  2072. if ((ACC == "") || (ACC == " ") ) { return; }
  2073.  
  2074. /*
  2075. s1 "La"
  2076. s1 "Fa#"
  2077. s1 "Mi7"
  2078. s1 "Sim"
  2079. s1 "Sibm"
  2080. s1 "Do"
  2081. */
  2082. // détection du degré (0 pour Do , à 11 pour Si)
  2083. // rappel : gamme_chromatique<<"Do"<<"Do#"<<"Ré"<<"Mib"<<"Mi"<<"Fa"<<"Fa#"<<"Sol"<<"Sol#"<<"La"<<"Sib"<<"Si";
  2084.  
  2085. int n=11;
  2086. int deg = -1;
  2087. bool ok = false;
  2088. while ((n>0) && (ok == false))
  2089. {
  2090. QString s2a = gamme_chromatique[n];
  2091. p1 = s1.indexOf(s2a);
  2092. if (p1 != -1) {ok = true;}
  2093. n--;
  2094. }
  2095. if (ok == true) {deg = n+1; }
  2096.  
  2097. p1 = s1.indexOf("b");
  2098. if (p1 != -1) {deg --;} // bémol
  2099.  
  2100. s2b = ACC.right(1); // m, 7, mais aussi # ou la dernière lettre du nom de la note !
  2101.  
  2102. type = "MAJ"; // à priori
  2103. if (s2b == "m") {type = "min";}
  2104. if (s2b == "7") {type = "dom";}
  2105. if (s2b == "-") {type = "-";} // note seule
  2106.  
  2107. // intervalle de cases à jouer :
  2108.  
  2109. s2c = cases; // "0a3" ou "12a14" ...
  2110. p2=s2c.indexOf("a");
  2111.  
  2112. if (p2 != -1)
  2113. {
  2114. s3=s2c.left(p2);
  2115. case_min = s3.toInt();
  2116. spinBox_4->setValue(case_min);
  2117.  
  2118. s4 = s2c.mid(p2+1, 255);
  2119. int v4 = s4.toInt();
  2120.  
  2121. if (v4 >= case_min) // on accepte une case unique (genre "7a7") pour forcer une note unique à sa place
  2122. {
  2123. case_max = v4; // ici on enregistre le numero de la case max
  2124. spinBox_5->setValue(case_max);
  2125. }
  2126. }
  2127.  
  2128. else
  2129. {
  2130. case_min = 0;
  2131. spinBox_4->setValue(case_min);
  2132. case_max = 20; // numéro de la case
  2133. spinBox_5->setValue(case_max); // nombre de cases
  2134. }
  2135.  
  2136. notes_pleines = false; // ne représentera qu'un cercle
  2137.  
  2138. if (type=="MAJ") // accord majeur
  2139. {
  2140. spinBox_2->setValue(deg); // spinBox dans le cadre 'Configurateur d'Accords'
  2141. on_Bt_ACCORD_1_clicked();
  2142. }
  2143.  
  2144.  
  2145.  
  2146. if (type=="min") // accord mineur
  2147. {
  2148. spinBox_2->setValue(deg);
  2149. on_Bt_ACCORD_2_clicked();
  2150. }
  2151.  
  2152.  
  2153. if (type=="dom") // 7eme de dominante
  2154. {
  2155. spinBox_2->setValue(deg);
  2156. on_Bt_ACCORD_3_clicked();
  2157. }
  2158.  
  2159.  
  2160. if (type=="-") // note seule
  2161. {
  2162. // spinBox_2->setValue(D);
  2163. // on_Bt_ACCORD_3_clicked();
  2164.  
  2165. on_Bt_RAZ_clicked();
  2166. }
  2167.  
  2168. /*
  2169.   case_min = 0;
  2170.   spinBox_4->setValue(case_min);
  2171.   case_max = 20;
  2172.   spinBox_5->setValue(case_max);
  2173. */
  2174. notes_pleines = true;
  2175.  
  2176. s1 = type;
  2177. if (s1 == "dom") {s1 = "7e dom";}
  2178. label_43->setText(lineEdit_8->text() + " " +s1);
  2179.  
  2180.  
  2181. }
  2182.  
  2183.  
  2184. void MainWindow::affiche_details_note(uint midi)
  2185. {
  2186. QString s1;
  2187. s1.setNum(midi);
  2188. s1 = "m" + s1;
  2189. lineEdit_7->setText(s1);
  2190.  
  2191. affi_txt_en_couleur(midi, lineEdit_7b);
  2192. lineEdit_7b->setText(nom_note_FR(midi));
  2193.  
  2194. affi_txt_en_couleur(midi, lineEdit_7e);
  2195.  
  2196. s1=nom_note_GB(midi);
  2197. s1+=nom_octave_GB(midi);
  2198. lineEdit_7e->setText(s1);
  2199. }
  2200.  
  2201.  
  2202. void MainWindow::mousePressEvent(QMouseEvent *event)
  2203. {
  2204. QString s1, s2, s3;
  2205. int x_min, x_max, y_min, y_max;
  2206.  
  2207. x_min = graphicsView1->x();
  2208. x_max = x_min + graphicsView1->width();
  2209. y_min = graphicsView1->y();
  2210. y_max = y_min + graphicsView1->height();
  2211.  
  2212. x_clic_ecran = event->position().x();
  2213. y_clic_ecran = event->position().y();
  2214.  
  2215. if (x_clic_ecran > x_min && x_clic_ecran < x_max && y_clic_ecran > y_min && y_clic_ecran < y_max)
  2216. {
  2217.  
  2218. // suite à un clic sur le manche :
  2219. detecte_note_xy(x_clic_ecran, y_clic_ecran, &corde_jouee, &case_jouee); // actualise les variables globales
  2220.  
  2221. s1.setNum(case_jouee); lineEdit_case_i->setText(s1);
  2222. s1.setNum(corde_jouee); lineEdit_corde_i->setText(s1);
  2223.  
  2224. if (corde_jouee>0)
  2225. {
  2226. case_min = 0;
  2227. case_max = 20;
  2228. // checkBox_not_erase->setChecked(false);
  2229.  
  2230. if (!checkBox_not_erase->isChecked()) {on_Bt_RAZ_clicked();}
  2231.  
  2232. s2.setNum(corde_jouee);
  2233. label_44->setText("corde " + s2);
  2234. s3.setNum(case_jouee);
  2235. label_45->setText("case " + s3);
  2236.  
  2237. n_midi_jouee = calcul_midi(corde_jouee, case_jouee);
  2238.  
  2239. //affiche_details_note(n_midi_jouee);
  2240.  
  2241. calcul_hauteur_note(n_midi_jouee);
  2242. execute_note_midi( n_midi_jouee);
  2243. }
  2244. }
  2245. else
  2246. {
  2247. mode_depot_note = false;
  2248. statusbar->showMessage("");
  2249. MainWindow::setCursor(Qt::ArrowCursor);
  2250. }
  2251. }
  2252.  
  2253.  
  2254. void MainWindow::on_spinBox_2_valueChanged(int arg1)
  2255. {
  2256. int n=arg1;
  2257. lineEdit_8->setText(gamme_chromatique[n]);
  2258.  
  2259. lineEdit_10->clear();
  2260. lineEdit_14->clear();
  2261.  
  2262. }
  2263.  
  2264.  
  2265.  
  2266. void MainWindow::save_fichier_lst()
  2267. {
  2268. // enregisterment incrémentiel sur HDD (nom de fichier = 1..2...3...)
  2269.  
  2270. QString s1;
  2271. //QString ligne_i;
  2272. int numero=0;
  2273. QString s2;
  2274. QString chemin_out;
  2275.  
  2276. lecture_pause = 1;
  2277. Bt_lecture_2->setText(">");
  2278. Bt_lecture_2->setStyleSheet("QPushButton{background-color:#50FF1B;}");
  2279. lecture_pause =0;
  2280. s1.setNum(num_ligne_en_cours);// conversion num -> txt
  2281. Timer2->stop();
  2282.  
  2283. chemin_out = string_currentDir; //QDir::homePath() + "/GUITARE/ACCORDS/";
  2284.  
  2285.  
  2286. /*
  2287.   if (!dossier_out.exists())
  2288.   {
  2289.   QMessageBox msgBox;
  2290.   msgBox.setText("Le dossier : " + dossier_out.dirName() + " n'éxiste pas, je le crée");
  2291.   msgBox.exec();
  2292.   }
  2293. */
  2294. bool existe =1;
  2295. while(existe)
  2296. {
  2297. numero++;
  2298. s2.setNum(numero);
  2299. existe = QFile::exists(chemin_out + s2 + ".lst");
  2300.  
  2301.  
  2302. /*
  2303.   QMessageBox msgBox;
  2304.   QString s1;
  2305.   s1 = "Le fichier de destination (" + chemin_out + s2 + ".lst ) existe déjà";
  2306.   msgBox.setText(s1);
  2307.   msgBox.exec();
  2308. */
  2309. }
  2310.  
  2311. s2.setNum(numero);
  2312. int nb_lignes;
  2313.  
  2314. QFile file1(chemin_out + s2 + ".lst");
  2315. //file1.remove();
  2316.  
  2317. if (file1.open(QIODevice::WriteOnly | QIODevice::Text))
  2318. {
  2319. QTextStream file_out(&file1);
  2320.  
  2321. int vitesse = doubleSpinBox_vitesse->value();
  2322. QString s1;
  2323. s1.setNum(vitesse);
  2324. file_out << "v=" + s1 + ";";
  2325. file_out << char(10);
  2326. nb_lignes = liste_accords.length();
  2327. for (int i=0; i<nb_lignes; i++)
  2328. {
  2329. file_out << liste_accords[i]; // << char(10);
  2330. }
  2331. }
  2332. file1.close();
  2333.  
  2334. QMessageBox msgBox;
  2335. s1="Fichier enregistré: " + chemin_out + s2 + ".lst";
  2336. msgBox.setText(s1);
  2337. msgBox.exec();
  2338. }
  2339.  
  2340.  
  2341. int MainWindow::constitue_liste_accords() // en vue de l'enregistrement sur le HDD (par la fonction 'save_fichier_lst()' ci-dessus)
  2342. {
  2343. // remarque: les codes midi sont 40..84 qui correspondent à des caractères ASCII classiques.
  2344. // la valeur 100 est utilisée (ici) pour coder les barres de mesure
  2345. // plus exactement, les codes ascii 32..126 codents poue des caratères classiques.
  2346. // on peut donc les encoder dans des QString qui eux sont facilement recordables...
  2347. QString s1, s2, s3, s4; // les 4 valeurs midi d'un accord sous forme de texte
  2348. QString ligne_i;
  2349. int m1, p1;
  2350.  
  2351. liste_accords.clear();
  2352. int RC=tableWidget_3->rowCount();
  2353.  
  2354. int L_save_min = lineEdit_12->text().toInt() -1;
  2355. int L_save_max = lineEdit_13->text().toInt();
  2356.  
  2357. if (L_save_min < 0) {L_save_min = 0;}
  2358. if (L_save_max > RC) {L_save_max = RC;}
  2359.  
  2360. if ((L_save_max-L_save_min) < 2)
  2361. {
  2362. QMessageBox msgBox;
  2363. msgBox.setText("Le tableau doit contenir au minimum 2 lignes !");
  2364. msgBox.exec();
  2365. return 1;
  2366. }
  2367.  
  2368. for(int L=L_save_min; L<L_save_max; L++)
  2369. {
  2370. ligne_i.clear();
  2371. s1 = tableWidget_3->item(L, 1)->text(); s1 = s1.left(2);
  2372. m1 = s1.toInt(); if ((m1<40)||(m1>84)) {s1="";} // code midi de la note
  2373.  
  2374. s1 = "m1=" +s1 + ";";
  2375. ligne_i += s1;
  2376.  
  2377. s1 = tableWidget_3->item(L, 3)->text(); s1 = s1.left(2);
  2378. m1 = s1.toInt(); if ((m1<40)||(m1>84)) {s1="";}
  2379. s1 = "m2=" +s1 + ";";
  2380. ligne_i += s1;
  2381.  
  2382. s1 = tableWidget_3->item(L, 4)->text(); s1 = s1.left(2);
  2383. m1 = s1.toInt(); if ((m1<40)||(m1>84)) {s1="";}
  2384. s1 = "m3=" +s1 + ";";
  2385. ligne_i += s1;
  2386.  
  2387. s1 = tableWidget_3->item(L, 5)->text(); // commentaire
  2388. s1 = "cmt=" +s1 + ";";
  2389. ligne_i += s1;
  2390.  
  2391. s1 = tableWidget_3->item(L, 7)->text(); // DUREE
  2392. s1 = " " + s1; s1=s1.right(2); // ajoute 1 espace si nombre<10
  2393.  
  2394. s1 = "d=" +s1 + ";"; // durée
  2395. ligne_i += s1;
  2396.  
  2397. s1 = tableWidget_3->item(L, 8)->text(); // MESURE
  2398. s1 = "M=" +s1 + ";";
  2399. ligne_i += s1;
  2400.  
  2401. s1 = tableWidget_3->item(L, 9)->text(); // tps
  2402. s1 = "T=" +s1 + ";";
  2403. ligne_i += s1;
  2404.  
  2405. //s1 = tableWidget_3->item(L, 8)->text(); // disponible
  2406. //s1 = "x=" +s1 + ";";
  2407. //ligne_x += s1;
  2408.  
  2409. s1 = tableWidget_3->item(L, 11)->text(); // ACC // "11min
  2410. s1 = "a=" + s1 + ";";
  2411. ligne_i += s1;
  2412.  
  2413. s1 = tableWidget_3->item(L, 12)->text(); ; // "7a9"
  2414. s1 = "cases=" + s1 + ";";
  2415. ligne_i += s1;
  2416.  
  2417. s1 = tableWidget_3->item(L, 13)->text(); // doigts (la case contient toute le string en question),
  2418. // voir la fonction : 'on_Bt_copie_doigts_to_TW3_clicked()' qui constitue ce string à partir du 'tableWidget_doigts.'
  2419.  
  2420. //qDebug() << "" << s1;
  2421. //qDebug() << "______________";
  2422.  
  2423. ligne_i += s1;
  2424.  
  2425. ligne_i += '\n';
  2426.  
  2427. liste_accords << ligne_i;
  2428. }
  2429. return 0;
  2430. }
  2431.  
  2432.  
  2433.  
  2434. void MainWindow::on_Bt_save_clicked()
  2435. {
  2436. int R = constitue_liste_accords();
  2437. if (R == 0) { save_fichier_lst(); }
  2438.  
  2439. }
  2440.  
  2441.  
  2442. int MainWindow::dechiffre_note(QString label_i, int L, int c)
  2443. {
  2444.  
  2445. int p1a, p1b, m1, h1;
  2446. QString ligne_i=liste_accords[L];
  2447. QString s1, s2;
  2448. QColor couleur1;
  2449.  
  2450. p1a=ligne_i.indexOf(label_i);
  2451. p1b=ligne_i.indexOf(";",p1a);
  2452. s1 = ligne_i.mid(p1a+3, p1b-(p1a+3));
  2453.  
  2454. if (s1=="") { return 0; }
  2455.  
  2456. m1 = s1.toInt();
  2457.  
  2458. if (m1==0) {return 0;}
  2459.  
  2460. h1 = calcul_hauteur_note(m1); // h1 = 0..11
  2461. couleur1 = liste_couleurs[h1];
  2462. s2 = " " + gamme_chromatique[h1];
  2463. s1 += s2;
  2464.  
  2465. complete_case(L, c, s1, "#000000", couleur1, false, tableWidget_3);
  2466. return 1; // Une note est présente en L, C
  2467. }
  2468.  
  2469.  
  2470.  
  2471. int MainWindow::open_fichier_lst() // cette fonction est appelée par la fonction 'write_Tableau_vertical()'
  2472. {
  2473. QString ligne_i, str1;
  2474. QString s1;
  2475. int p1a, p1b;
  2476.  
  2477. // stop execution en cours
  2478. lecture_pause = 1;
  2479. Bt_lecture_2->setText("joue > debut");
  2480. Bt_lecture_2->setStyleSheet("QPushButton{background-color:#50FF1B;}");
  2481. lecture_pause =0;
  2482.  
  2483. s1.setNum(num_ligne_en_cours);// conversion num -> txt
  2484. Timer2->stop();
  2485.  
  2486. string_currentFile = QFileDialog::getOpenFileName(this, tr("Ouvrir Fichier accords..."), string_currentDir,
  2487. tr("Fichiers lst (*.lst);;All Files (*)"));
  2488.  
  2489. // qDebug() << "string_currentFile" << string_currentFile;
  2490.  
  2491. if (string_currentFile != "")
  2492. {
  2493. save_fichier_ini();
  2494. liste_str_in.clear();
  2495. liste_accords.clear();
  2496. }
  2497. else {return 0;}
  2498.  
  2499. int p1 = string_currentFile.lastIndexOf("/");
  2500.  
  2501. string_currentDir =string_currentFile.left(p1+1);
  2502.  
  2503. if (!string_currentFile.isEmpty())
  2504. {
  2505. lineEdit_1->setText(string_currentFile);
  2506. }
  2507. else {return 0;}
  2508.  
  2509. QFile file1(string_currentFile);
  2510. if (!file1.open(QIODevice::ReadOnly | QIODevice::Text)) return 1;
  2511. QTextStream TextStream1(&file1);
  2512.  
  2513. int num_ligne = 0;
  2514. ligne_i = TextStream1.readLine(); // vitesse
  2515.  
  2516. p1a=ligne_i.indexOf("v="); // duree
  2517. p1b=ligne_i.indexOf(";",p1a);
  2518. s1 = ligne_i.mid(p1a+2, p1b-(p1a+2));
  2519.  
  2520. int v1;
  2521. v1 = s1.toFloat();
  2522. doubleSpinBox_vitesse->setValue(v1);
  2523.  
  2524. while ( !TextStream1.atEnd() )
  2525. {
  2526. ligne_i = TextStream1.readLine();
  2527. liste_accords += ligne_i;
  2528. num_ligne++;
  2529. }
  2530.  
  2531. file1.close();
  2532.  
  2533. str1.setNum(num_ligne);
  2534. lineEdit_2->setText(str1 + " lignes");
  2535.  
  2536. int nb_de_lignes = num_ligne;
  2537.  
  2538. L_save_max = nb_de_lignes;
  2539.  
  2540. s1.setNum(0);
  2541. lineEdit_12->setText(s1);
  2542.  
  2543. s1.setNum(nb_de_lignes);
  2544. lineEdit_13->setText(s1);
  2545.  
  2546. return nb_de_lignes;
  2547. }
  2548.  
  2549.  
  2550. //---------------------------------------------------------------------------------------
  2551.  
  2552.  
  2553. void MainWindow::write_Time_line()
  2554. {
  2555.  
  2556. int m1;
  2557. int R;
  2558. QColor couleur1;
  2559. int duree_note, intervalle_t, Ti1, Ti2, numero_mesure;
  2560. QString s1, s2, s3, sm;
  2561. intervalle_t=0;
  2562. Ti1=0;
  2563.  
  2564. int Rmax= tableWidget_3->rowCount();
  2565. if (Rmax > 1000) {Rmax =1000;} // évite de saturer sur des morceaux trops longs !
  2566.  
  2567. // ------------- colorie les cases horizontales (notes) ---------------------------
  2568. Ti2=0;
  2569.  
  2570. R=0;
  2571. while ((R < Rmax) && Ti2 < 300)
  2572. {
  2573. s1 = tableWidget_3->item(R, 6)->text();
  2574. duree_note = s1.toInt();
  2575.  
  2576. for (int dt=0; dt<duree_note; dt++)
  2577. {
  2578. s1 = tableWidget_3->item(R, 1)->text();
  2579. s1 = s1.left(2);
  2580. m1 = s1.toInt();
  2581. if ((m1 >= 40) && (m1 <= 82)) // si présence d'un code midi
  2582. {
  2583. couleur1 = tableWidget_3->item(R, 1)->background().color();
  2584. if(couleur1 != "#000000") { complete_case(1, Ti2, " ", "#CECECE", couleur1, false, tableWidget_T);}
  2585. }
  2586.  
  2587. s1 = tableWidget_3->item(R, 2)->text();
  2588. s1 = s1.left(2);
  2589. m1 = s1.toInt();
  2590.  
  2591. if ((m1 >= 40) && (m1 <= 82))
  2592. {
  2593. couleur1 = tableWidget_3->item(R, 2)->background().color();
  2594. if(couleur1 != "#000000") { complete_case(2, Ti2, " ", "#CECECE", couleur1, false, tableWidget_T);}
  2595. }
  2596.  
  2597. s1 = tableWidget_3->item(R, 3)->text();
  2598. s1 = s1.left(2);
  2599. m1 = s1.toInt();
  2600. if ((m1 >= 40) && (m1 <= 82))
  2601. {
  2602. couleur1 = tableWidget_3->item(R, 3)->background().color();
  2603. if(couleur1 != "#000000") { complete_case(3, Ti2, " ", "#CECECE", couleur1, false, tableWidget_T);}
  2604. }
  2605.  
  2606. s1 = tableWidget_3->item(R, 4)->text();
  2607. s1 = s1.left(2);
  2608. m1 = s1.toInt();
  2609. if ((m1 >= 40) && (m1 <= 82))
  2610. {
  2611. couleur1 = tableWidget_3->item(R, 4)->background().color();
  2612. if(couleur1 != "#000000") {complete_case(4, Ti2, " ", "#CECECE", couleur1, false, tableWidget_T);}
  2613. }
  2614. Ti2 ++;
  2615. }
  2616. R++;
  2617. }
  2618. // ----------------------------------------
  2619. numero_mesure =1; // DEPART
  2620.  
  2621. R=0;
  2622. while ((R < Rmax) && Ti1 < 300)
  2623. {
  2624. sm =tableWidget_3->item(R, 7)->text();
  2625.  
  2626. couleur1 = tableWidget_3->item(R, 8)->background().color();
  2627. if(couleur1 == "#888888")
  2628. {
  2629. s2.setNum(intervalle_t);
  2630.  
  2631. complete_case(0, Ti1-1, s2, "#000000", "#FFFFFF", false, tableWidget_T);
  2632. intervalle_t=0;
  2633.  
  2634. s3.setNum(numero_mesure);
  2635. complete_case(0, Ti1, s3, "#FFFFFF", "#555555", false, tableWidget_T);
  2636.  
  2637. trace_ligne_V(Ti1, numero_mesure);
  2638. s1 = tableWidget_3->item(R, 6)->text();
  2639. duree_note = s1.toInt();
  2640. intervalle_t += duree_note;
  2641. Ti1 += duree_note;
  2642. numero_mesure++;
  2643. }
  2644. else
  2645. {
  2646. s1 = tableWidget_3->item(R, 6)->text(); // durée de la note
  2647. duree_note = s1.toInt();
  2648. intervalle_t += duree_note;
  2649. Ti1 += duree_note;
  2650. }
  2651. R++;
  2652. }
  2653. }
  2654.  
  2655.  
  2656. //---------------------------------------------------------------------------------------
  2657. /*
  2658. void MainWindow::gestion_mesures()
  2659. {
  2660.  
  2661. // sur le tableau vertical
  2662.   QString s1, s2;
  2663.   int numero_mesure=0;
  2664.   int memo_numero_mesure=0;
  2665.   int temps=0;
  2666.   int duree_i=0;
  2667.   int total=0;
  2668.  
  2669.   for (int L=0; L<tableWidget_3->rowCount(); L++)
  2670.   {
  2671.   s1=tableWidget_3->item(L,5)->text();
  2672.   duree_i = s1.toInt();
  2673.  
  2674.   if (numero_mesure == memo_numero_mesure)
  2675.   {
  2676.   s2.setNum(total);
  2677.   complete_case(L-1, 7, s2, "#000000", "#C4F6FC", false, tableWidget_3); // BLEU CLAIR
  2678.   total += duree_i;
  2679.   }
  2680.  
  2681.  
  2682.   s1=tableWidget_3->item(L,6)->text();
  2683.   numero_mesure = s1.toInt();
  2684.   if ( (numero_mesure % 2) == 0)
  2685.   { complete_case(L, 6, s1, "#000000", "#C4F6FC", false, tableWidget_3); }// BLEU CLAIR
  2686.   else { complete_case(L, 6, s1, "#000000", "#3AE0F5", false, tableWidget_3); } //BLEU FONCE
  2687.  
  2688.  
  2689.   if (numero_mesure != memo_numero_mesure)
  2690.   {
  2691.   memo_numero_mesure = numero_mesure;
  2692.   complete_case(L, 6, s1, "#000000", "#F57900", true, tableWidget_3); // ORANGE
  2693.   complete_case(L-1, 7, s2, "#000000", "#C4F6FC", true, tableWidget_3); // BLEU CLAIR
  2694.   total = duree_i;
  2695.   }
  2696.   }
  2697. }
  2698. */
  2699.  
  2700. int MainWindow::calcul_T_note(int R)
  2701. {
  2702. // temps du début de la note en fonction du num de ligne (row) de la cellule cliquée dans le tableau3
  2703. int i, di, dT;
  2704. QString s1, duree_txt;
  2705.  
  2706. dT=0;
  2707. for(i=0 ; i<R ; i++)
  2708. {
  2709. duree_txt = tableWidget_3->item(i, 6)->text();
  2710. di = duree_txt.toInt();
  2711. dT += di;
  2712. }
  2713. return dT;
  2714. }
  2715.  
  2716.  
  2717. QString MainWindow::extraction_data(QString ligne_i, QString label)
  2718. {
  2719. int p1, p2, nb;
  2720. QString s1;
  2721.  
  2722. p1=ligne_i.indexOf(label);
  2723. if(p1 == -1) {return "";} // (pas trouvé)
  2724.  
  2725. p2=ligne_i.indexOf(";",p1);
  2726. nb = label.length();
  2727. s1 = ligne_i.mid(p1+nb, p2-(p1+nb));
  2728.  
  2729. return s1;
  2730. }
  2731.  
  2732.  
  2733. void MainWindow::calcul_tps()
  2734. {
  2735.  
  2736. int duree;
  2737. int total=0;
  2738. QString s1;
  2739.  
  2740. int nb_de_lignes=tableWidget_3->rowCount();
  2741. for (int L=0; L<nb_de_lignes-1; L++)
  2742. {
  2743. duree = tableWidget_3->item(L, 6)->text().toInt();
  2744.  
  2745. s1.setNum(total);
  2746.  
  2747. tableWidget_3->setItem(L, 9, new QTableWidgetItem (s1) );
  2748. total += duree;
  2749. //if (total == 32) {total=0;}
  2750. }
  2751. }
  2752.  
  2753.  
  2754.  
  2755. int MainWindow::write_Tableau_vertical() // décrypte la 'liste_accords[]'
  2756. {
  2757. QString s1, s2;
  2758. int dt;
  2759. int temps=0;
  2760. int total =0;
  2761. int z;
  2762.  
  2763. //liste_accords.clear();
  2764. int nb_de_lignes = open_fichier_lst(); // appel de la fonction qui peuple la variable (QString) 'liste_accords'
  2765. if (nb_de_lignes == 0) {return 1;}
  2766.  
  2767. init_TW_3();
  2768. tableWidget_3->setRowCount(0);
  2769.  
  2770. mode_depot_note = false;
  2771.  
  2772. // -------------------------------------------------------------------------------
  2773. // on va transcrire ce contenu du String "liste_accords" dans le tableWidget_3
  2774.  
  2775. QString ligne_i;
  2776. for (int L=0; L<nb_de_lignes; L++)
  2777. {
  2778. on_Bt_AddLine_clicked();
  2779.  
  2780. ligne_i=liste_accords[L];
  2781.  
  2782. z = dechiffre_note("m1=", L, 1);
  2783. z += dechiffre_note("m2=", L, 2);
  2784. z += dechiffre_note("m3=", L, 3);
  2785.  
  2786. total = L+z;
  2787. s1.setNum(total); complete_case(L, 0, s1, "#000000", "#DDDDDD", false, tableWidget_3);
  2788. //dechiffre_note("m4=", L, 3);
  2789.  
  2790. s1= extraction_data(ligne_i, "cmt=");
  2791.  
  2792. complete_case(L, 4, s1, "#000000", "#FFFCDD", false, tableWidget_3);
  2793.  
  2794. // la colonne 4 est un bouton
  2795.  
  2796. s1= extraction_data(ligne_i, "d="); // durée
  2797. tableWidget_3->setItem(L, 6, new QTableWidgetItem (s1) ); // dt
  2798. dt = s1.toInt();
  2799.  
  2800.  
  2801. s1= extraction_data(ligne_i, "M="); // mesure
  2802. if (s1 != " ")
  2803. {
  2804. complete_case(L, 7, s1, "#FFFFFF", "#888888", false, tableWidget_3); // 'M' (mesure)
  2805.  
  2806. s1.setNum(temps);
  2807. complete_case(L, 8, s1, "#000000", "#FFFCDD", false, tableWidget_3); // tps
  2808. temps =0;
  2809. }
  2810. else
  2811. {
  2812. s1.setNum(temps);
  2813. complete_case(L, 8, s1, "#000000", "#CECECE", false, tableWidget_3); // 'M' (mesure)
  2814. }
  2815. temps += dt;
  2816.  
  2817. tableWidget_3->setItem(L, 9, new QTableWidgetItem (" "));
  2818.  
  2819.  
  2820. s1= extraction_data(ligne_i, "a="); // ACC
  2821. tableWidget_3->setItem(L, 10, new QTableWidgetItem (s1));
  2822.  
  2823. s1= extraction_data(ligne_i, "cases=");
  2824. complete_case(L, 11, s1, "#000000", "#FFFFFF", false, tableWidget_3);
  2825.  
  2826. s2="";
  2827. bool ok = false;
  2828.  
  2829. s1= extraction_data(ligne_i, "D0v="); // corde à vide
  2830. if ((s1 != "") && (s1 != "-")) { s2 += "D0v=" + s1 + ";"; ok = true; }
  2831.  
  2832. s1= extraction_data(ligne_i, "D0h="); // corde à vide
  2833. if ((s1 != "") && (s1 != "-")) { s2 += "D0h=" + s1 + ";"; ok = true; }
  2834.  
  2835. s1= extraction_data(ligne_i, "D1v="); // posiion "verticale" (c.d corde) du doigt 1 (index)
  2836. if ((s1 != "") && (s1 != "-")) { s2 += "D1v=" + s1 + ";"; ok = true; }
  2837.  
  2838. s1= extraction_data(ligne_i, "D1h="); // posiion "horizontale" (case) du doigt 1 (index)
  2839. if ((s1 != "") && (s1 != "-")) { s2 += "D1h=" + s1 + ";"; ok = true; }
  2840.  
  2841. s1= extraction_data(ligne_i, "D2v=");
  2842. if ((s1 != "") && (s1 != "-")) { s2 += "D2v=" + s1 + ";"; ok = true; }
  2843.  
  2844. s1= extraction_data(ligne_i, "D2h=");
  2845. if ((s1 != "") && (s1 != "-")) { s2 += "D2h=" + s1 + ";"; ok = true; }
  2846.  
  2847. s1= extraction_data(ligne_i, "D3v=");
  2848. if ((s1 != "") && (s1 != "-")) { s2 += "D3v=" + s1 + ";"; ok = true; }
  2849.  
  2850. s1= extraction_data(ligne_i, "D3h=");
  2851. if ((s1 != "") && (s1 != "-")) { s2 += "D3h=" + s1 + ";"; ok = true; }
  2852.  
  2853. s1= extraction_data(ligne_i, "D4v=");
  2854. if ((s1 != "") && (s1 != "-")) { s2 += "D4v=" + s1 + ";"; ok = true; }
  2855.  
  2856. s1= extraction_data(ligne_i, "D4h=");
  2857. if ((s1 != "") && (s1 != "-")) { s2 += "D4h=" + s1 + ";"; ok = true; }
  2858.  
  2859. if (ok != true) {s2=" ";}
  2860. QTableWidgetItem *item1 = new QTableWidgetItem();
  2861. item1->setText(s2);
  2862. item1->setFlags(item1->flags() & ~Qt::ItemIsEditable); // passe en read only
  2863. tableWidget_3->setItem(L, 12, item1);
  2864. }
  2865. tableWidget_3->resizeColumnsToContents();
  2866. return 0;
  2867. }
  2868.  
  2869.  
  2870. void MainWindow::on_Bt_Load_lst_clicked()
  2871. {
  2872. set_zoom2();
  2873. int w = write_Tableau_vertical();
  2874. // if (w==0)
  2875. {
  2876. //checkBox_not_erase->setChecked(true);
  2877. //gestion_mesures();
  2878. write_Time_line();
  2879. }
  2880. }
  2881.  
  2882.  
  2883. void MainWindow::on_Bt_Supp_line_clicked()
  2884. {
  2885. int R= tableWidget_3->currentRow();
  2886. tableWidget_3->removeRow(R);
  2887. }
  2888.  
  2889.  
  2890.  
  2891. void MainWindow::complete_ligne(int R)
  2892. {
  2893. tableWidget_3->setItem(R, 1, new QTableWidgetItem (" ") ); // note1
  2894. tableWidget_3->setItem(R, 2, new QTableWidgetItem (" ") ); // note2
  2895. tableWidget_3->setItem(R, 3, new QTableWidgetItem (" ") ); // note3
  2896.  
  2897. tableWidget_3->setItem(R, 4, new QTableWidgetItem (" ") ); // cmt
  2898.  
  2899. QTableWidgetItem *Item1 = new QTableWidgetItem();
  2900. Item1->setIcon(QIcon("../images/01.png" ));
  2901. tableWidget_3->setItem(R, 5, Item1 ); // bouton
  2902.  
  2903. tableWidget_3->setItem(R, 6, new QTableWidgetItem (" ") ); // dt
  2904. tableWidget_3->setItem(R, 7, new QTableWidgetItem (" ") ); // M
  2905. tableWidget_3->setItem(R, 8, new QTableWidgetItem (" ") ); // tps
  2906. tableWidget_3->setItem(R, 9, new QTableWidgetItem (" ") ); // tot
  2907. tableWidget_3->setItem(R, 10, new QTableWidgetItem (" ") ); // ACC (accord type)
  2908. tableWidget_3->setItem(R, 11, new QTableWidgetItem (" ") ); // intervalle de cases (sur le manche) à jouer
  2909. tableWidget_3->setItem(R, 12, new QTableWidgetItem (" ") ); // doigts
  2910. }
  2911.  
  2912.  
  2913.  
  2914. void MainWindow::on_Bt_AddLine_clicked() // à la fin
  2915. {
  2916. int R=tableWidget_3->rowCount();
  2917.  
  2918. tableWidget_3->setRowCount(R+1);
  2919. complete_ligne(R);
  2920. }
  2921.  
  2922.  
  2923. void MainWindow::on_Bt_AddLine_ici_clicked() // ici
  2924. {
  2925. int R= tableWidget_3->currentRow();
  2926. tableWidget_3->insertRow(R);
  2927. complete_ligne(R);
  2928. }
  2929.  
  2930.  
  2931.  
  2932.  
  2933. void MainWindow::on_pushButton_2_clicked()
  2934. {
  2935. on_Bt_save_clicked();
  2936. init_TW_3();
  2937. lineEdit_2->clear();
  2938. lineEdit_12->clear();
  2939. lineEdit_13->clear();
  2940. }
  2941.  
  2942.  
  2943. void MainWindow::joue_morceau_debut()
  2944. {
  2945. //if(nb_lignes ==0){return;}
  2946. if (lecture_pause == 1)
  2947. {
  2948. Bt_lecture_2->setText("joue > debut");
  2949. //Bt_lecture_2->setStyleSheet("QPushButton{background-color:#50FF1B;}");
  2950. lecture_pause =0;
  2951. QString s1;
  2952. s1.setNum(num_ligne_en_cours);// conversion num -> txt
  2953. Timer2->stop();
  2954. }
  2955. else
  2956. {
  2957. nb_notes_jouees_max = 10000;
  2958. // Bt_lecture_2->setText("[]");
  2959. //Bt_lecture_2->setStyleSheet("QPushButton{background-color:yellow;}");
  2960. lecture_pause = 1;
  2961. //num_note_stop=10000;
  2962. Tp1=0;
  2963. temps1=0;
  2964. Timer2->start(10);
  2965. }
  2966. }
  2967.  
  2968.  
  2969. void MainWindow::joue_morceau_ici(int R, int nb_notes)
  2970. {
  2971. //if(nb_lignes ==0){return;}
  2972.  
  2973.  
  2974. num_ligne_en_cours = R-1;
  2975. //num_colonne_a_encadrer = R;
  2976. nb_notes_jouees_max = nb_notes-1;
  2977. nb_notes_jouees = 0;
  2978.  
  2979. //tableWidget_3->selectRow(lineEdit_7->text().toInt());
  2980. //R = tableWidget_3->currentRow();
  2981. R = lineEdit_9->text().toInt();
  2982. int T1 = calcul_T_note(R-1);
  2983. // num_colonne_a_encadrer = 3; //T1;
  2984. Tp1=T1;
  2985. temps1=T1;
  2986.  
  2987.  
  2988. if (lecture_pause == 1)
  2989. {
  2990. //Bt_lecture_1->setText("joue > ici");
  2991. //Bt_lecture_1->setStyleSheet("QPushButton{background-color:#50FF1B;}");
  2992. lecture_pause =0;
  2993. // QString s1;
  2994. // s1.setNum(num_ligne_en_cours);// conversion num -> txt
  2995. Timer2->stop();
  2996. //Edit_1->setText(s1);
  2997. }
  2998. else
  2999. {
  3000. //Bt_lecture_1->setText("[]");
  3001. //Bt_lecture_1->setStyleSheet("QPushButton{background-color:yellow;}");
  3002. lecture_pause = 1;
  3003. //num_note_stop=10000;
  3004. Timer2->start(300);
  3005. }
  3006. }
  3007.  
  3008.  
  3009. void MainWindow::on_Bt_lecture_1_clicked() // joue ici
  3010. {
  3011. int R=lineEdit_9->text().toInt();
  3012. nb_notes_jouees_max = spinBox_nb_notes->value();
  3013. joue_morceau_ici(R, nb_notes_jouees_max);
  3014. }
  3015.  
  3016.  
  3017.  
  3018. void MainWindow::on_Bt_lecture_2_clicked() // joue depuis le début
  3019. {
  3020. num_ligne_en_cours =0;
  3021. // num_note_max = liste_NOTES_importees.length()-1;
  3022.  
  3023. num_note_max = tableWidget_3->rowCount();
  3024. if (num_note_max < 1) {return;}
  3025. joue_morceau_debut();
  3026. }
  3027.  
  3028.  
  3029. void MainWindow::on_Bt_lecture_3_clicked() // joue 1 note
  3030. {
  3031. int n0 = num_ligne_en_cours;
  3032. //QString s1;
  3033. //s1.setNum(n0);
  3034. //lineEdit_9->setText(s1);
  3035. //int R=lineEdit_9->text().toInt();
  3036. joue_morceau_ici(n0, 1);
  3037. num_ligne_en_cours ++;
  3038. }
  3039.  
  3040.  
  3041. void MainWindow::on_Bt_STOP_clicked()
  3042. {
  3043. Bt_lecture_2->setText("joue > debut");
  3044. lecture_pause =0;
  3045. QString s1;
  3046. s1.setNum(num_ligne_en_cours);
  3047. Timer2->stop();
  3048. }
  3049.  
  3050.  
  3051.  
  3052. void MainWindow::create_100_lignes_V()
  3053. {
  3054. for (int n=0; n<100; n++)
  3055. {
  3056. lst_frames.append(new QFrame(this));
  3057. lst_frames[n]->setGeometry(0, 0, 1, 1);
  3058. //lst_frames[n]->setStyleSheet(QString::fromUtf8("background-color: rgb(0, 0, 0);"));
  3059. lst_frames[n]->setStyleSheet("background-color: blue");
  3060. lst_frames[n]->hide();
  3061. }
  3062. }
  3063.  
  3064.  
  3065. void MainWindow::trace_ligne_V(int num_colonne, int num_mesure)
  3066. {
  3067. //sur le tableau horizontal (TimeLine)
  3068.  
  3069. if (num_mesure >=100) {return;} // nb max de lignes instanciées, voir fonction ci-dessus
  3070.  
  3071. int x;
  3072. int dy=140;
  3073. int LC=10; // largeur colonnes
  3074. int H_diff;
  3075. int x0=tableWidget_T->x();
  3076. int y0=tableWidget_T->y();
  3077.  
  3078. if (zoom==1) {LC=10;}
  3079. if (zoom==2) {LC=20;}
  3080.  
  3081. QScrollBar *H_Scroll = tableWidget_T->horizontalScrollBar();
  3082.  
  3083. H_diff = num_colonne - H_Scroll->value();
  3084. x = x0 + LC * H_diff;
  3085.  
  3086. if (H_diff>=0)
  3087. {
  3088. lst_frames[num_mesure+8]->setGeometry(QRect(x, y0, 2, dy));
  3089. lst_frames[num_mesure+8]->setStyleSheet("background-color: gray");
  3090. lst_frames[num_mesure+8]->show();
  3091. }
  3092. }
  3093.  
  3094.  
  3095.  
  3096. void MainWindow::trace_rectangle1(int x, int y, int dx, int dy)
  3097. {
  3098. lst_frames[1]->setGeometry(QRect(x, y, dx, 2)); lst_frames[1]->show();
  3099. lst_frames[2]->setGeometry(QRect(x, y+dy, dx, 2)); lst_frames[2]->show();
  3100.  
  3101. lst_frames[3]->setGeometry(QRect(x, y, 2, dy)); lst_frames[3]->show();
  3102. lst_frames[4]->setGeometry(QRect(x+dx, y, 2, dy)); lst_frames[4]->show();
  3103. }
  3104.  
  3105.  
  3106.  
  3107. void MainWindow::trace_rectangle2(int x, int y, int dx, int dy)
  3108. {
  3109. // l'objet QRect doit s'utiliser sur un QPainter
  3110. // d'où cette fonction qui trace directement sur le mainwindow
  3111. // sans masquage du fond (ne confisque pas les clics souris sur les widgets en particulier !!!)
  3112. lst_frames[5]->setGeometry(QRect(x, y, dx, 2)); lst_frames[5]->show();
  3113. lst_frames[6]->setGeometry(QRect(x, y+dy, dx, 2)); lst_frames[6]->show();
  3114.  
  3115. lst_frames[7]->setGeometry(QRect(x, y, 2, dy)); lst_frames[7]->show();
  3116. lst_frames[8]->setGeometry(QRect(x+dx, y, 2, dy)); lst_frames[8]->show();
  3117. }
  3118.  
  3119.  
  3120.  
  3121.  
  3122. void MainWindow::encadrement_colonne() // de la timeline en bas (tableWidget_T)
  3123. {
  3124. // rappel : label_timeline->setGeometry(10, 830, 100, 30);
  3125.  
  3126. int x0=tableWidget_T->x();
  3127. int y0=tableWidget_T->y();
  3128. int x;
  3129. int dx;
  3130. int dy=120; //tableWidget_T->height();
  3131. int LC=10; // largeur colonnes, doit coincider avec la valeur inscrite dans l'ui
  3132. int HSB;
  3133. int H_diff;
  3134.  
  3135. //num_colonne_a_encadrer=5;
  3136. //nb_colonnes_a_encadrer=3;
  3137.  
  3138. if (zoom==1) {LC=10;}
  3139. if (zoom==2) {LC=20;}
  3140. // nb_colonnes_a_encadrer -> variable globale
  3141.  
  3142. QScrollBar *H_Scroll = tableWidget_T->horizontalScrollBar();
  3143.  
  3144. HSB = H_Scroll->value();
  3145. H_diff = num_colonne_a_encadrer - HSB;
  3146.  
  3147. x = x0 + LC * H_diff;
  3148. dx = LC * nb_colonnes_a_encadrer;
  3149.  
  3150. if (H_diff>=0)
  3151. {
  3152. trace_rectangle2(x, y0, dx, dy);
  3153. }
  3154. else
  3155. {
  3156. ;
  3157. }
  3158. }
  3159.  
  3160.  
  3161.  
  3162. void MainWindow::encadrement_ligne() // du tableWidget_3
  3163. {
  3164. int x0=tableWidget_3->x();
  3165. int y0=tableWidget_3->y() + 22;
  3166. int y_max = y0 + tableWidget_3->height();
  3167.  
  3168. int x, y;
  3169. int largeur = tableWidget_3->width()-18;
  3170. int HL = tableWidget_3->verticalHeader()->defaultSectionSize();
  3171. int V_SB;
  3172. int V_diff;
  3173.  
  3174. // encadrement de la ligne sélectionnée
  3175. int num_ligne = tableWidget_3->currentRow();
  3176. QScrollBar *V_Scroll = tableWidget_3->verticalScrollBar();
  3177.  
  3178. V_SB = V_Scroll->value();
  3179. V_diff = num_ligne - V_SB;
  3180.  
  3181. x = x0;
  3182. y = y0 + HL * V_diff;
  3183.  
  3184. if ((V_diff>=0) && (y < y_max - HL))
  3185. {
  3186. trace_rectangle1(x, y, largeur, HL);
  3187. }
  3188. else { trace_rectangle1(x,y, 1, 1); }
  3189. }
  3190.  
  3191.  
  3192. void MainWindow::TW_T_scroll(int H)
  3193. {
  3194.  
  3195. write_Time_line();
  3196. encadrement_colonne();
  3197.  
  3198. }
  3199.  
  3200. void MainWindow::TW_3_scroll(int H)
  3201. {
  3202.  
  3203. //write_Time_line();
  3204. encadrement_ligne();
  3205.  
  3206. }
  3207.  
  3208.  
  3209.  
  3210. void MainWindow::on_Bt_refresh_clicked()
  3211. {
  3212. init_TW_T();
  3213. create_100_lignes_V();
  3214. }
  3215.  
  3216.  
  3217. void MainWindow::set_zoom1()
  3218. {
  3219. zoom=1;
  3220.  
  3221. QFont fnt;
  3222. fnt.setFamily("Ubuntu");
  3223. fnt.setPointSize(6);
  3224. tableWidget_T->setFont(fnt);
  3225.  
  3226. for(int n=0; n<100; n++)
  3227. {
  3228. tableWidget_T->setColumnWidth(n, 10);
  3229. }
  3230. }
  3231.  
  3232.  
  3233. void MainWindow::set_zoom2()
  3234. {
  3235. zoom=2;
  3236.  
  3237. QFont fnt;
  3238. int n_max = tableWidget_T->columnCount();
  3239.  
  3240. fnt.setFamily("Ubuntu");
  3241. fnt.setPointSize(8);
  3242. tableWidget_T->setFont(fnt);
  3243.  
  3244. for(int n=0; n<n_max; n++)
  3245. {
  3246. tableWidget_T->setColumnWidth(n, 20);
  3247. }
  3248.  
  3249. }
  3250.  
  3251. void MainWindow::on_radioButton_Z1_clicked()
  3252. {
  3253. set_zoom1();
  3254. }
  3255.  
  3256.  
  3257. void MainWindow::on_radioButton_Z2_clicked()
  3258. {
  3259. set_zoom2();
  3260. }
  3261.  
  3262.  
  3263.  
  3264.  
  3265. void MainWindow::on_Bt_open_dossier_clicked()
  3266. {
  3267. QString s1, path1;
  3268. int p1;
  3269. /*
  3270.   s1 = lineEdit_1->text();
  3271.   p1 = s1.lastIndexOf("/");
  3272.   s1.remove(p1, 255);
  3273.   path1 = s1;
  3274. */
  3275. path1 = string_currentDir;
  3276.  
  3277. QProcess process1;
  3278. process1.setProgram("caja");
  3279. process1.setArguments({path1});
  3280. process1.startDetached();
  3281. }
  3282.  
  3283.  
  3284.  
  3285.  
  3286.  
  3287. void MainWindow::on_spinBox_4_valueChanged(int arg1)
  3288. {
  3289. QString s3, s4;
  3290. case_min = arg1;
  3291.  
  3292. if (arg1 > case_max) {spinBox_5->setValue(arg1);}
  3293. s3.setNum(case_min);
  3294.  
  3295. case_max = spinBox_5->value();
  3296. s4.setNum(case_max);
  3297. lineEdit_14->setText(s3 + "a" +s4);
  3298.  
  3299. encadre_accord(case_min, case_max);
  3300.  
  3301. //complete_accord(case_min, case_max); // NON !! pas ici !!!!
  3302.  
  3303. }
  3304.  
  3305.  
  3306. void MainWindow::on_spinBox_5_valueChanged(int arg1)
  3307. {
  3308. QString s3, s4;
  3309.  
  3310. case_min = spinBox_4->value();
  3311.  
  3312. if (arg1 < case_min) {spinBox_5->setValue(case_min);}
  3313.  
  3314. s3.setNum(case_min);
  3315.  
  3316. case_max = arg1;
  3317. s4.setNum(case_max);
  3318.  
  3319. lineEdit_14->setText(s3 + "a" +s4);
  3320.  
  3321. encadre_accord(case_min, case_max);
  3322.  
  3323. //complete_accord(case_min, case_max); // NON !! pas ici !!!!
  3324. }
  3325.  
  3326.  
  3327. void MainWindow::on_pushButton_4_clicked()
  3328. {
  3329. QString s1;
  3330.  
  3331. int R = tableWidget_3->currentRow();
  3332.  
  3333.  
  3334. s1=lineEdit_10->text();
  3335. if (s1 != "")
  3336. {
  3337. tableWidget_3->setItem(R, 10, new QTableWidgetItem (s1) );
  3338.  
  3339. s1=lineEdit_14->text();
  3340. tableWidget_3->setItem(R, 11, new QTableWidgetItem (s1) );
  3341. }
  3342. else
  3343. {
  3344. QMessageBox msgBox;
  3345. msgBox.setText("Choisir le type (Maj, Min, 7e de dom... au préalable)");
  3346. msgBox.exec();
  3347. }
  3348. }
  3349.  
  3350.  
  3351. /* RAPPEL :
  3352. struct NOTE_importee
  3353. {
  3354.   uint16_t numero; // 2 octets
  3355.   uint8_t midi; // 1 octet
  3356.   int16_t n_barreT; // 2 octets; numéro de la barre temporelle (T, 1/20s)sur laquelle est posée la note
  3357.   int16_t n_barreM; // 2 octets; num de barre M sur laquelle.. (accepte les valeurs négatives)
  3358.   // total 7 octets
  3359. };
  3360. */
  3361.  
  3362. void MainWindow::analyse_notes_importees() // (depuis le prog FFT) et garnit le TW3
  3363. {
  3364. NOTE_importee note1, note2;
  3365.  
  3366. int n_barre1, n_barre2;
  3367. int duree;
  3368. int midi_i;
  3369. int num_case=1;
  3370. int num_ligne=0;
  3371.  
  3372. QString s1;
  3373. QString nom_note;
  3374. QString duree_txt;
  3375. uint32_t t=0;
  3376.  
  3377. int n_max = liste_NOTES_importees.length();
  3378. init_TW_3();
  3379. tableWidget_3->setRowCount(0);
  3380.  
  3381. for(int n=0; n<n_max; n++)
  3382. {
  3383. int RC = tableWidget_3->rowCount();
  3384. tableWidget_3->setRowCount(RC+1); // ajout une ligne au tableau
  3385. for (int c=0; c<=13; c++)
  3386. {
  3387. complete_case(RC, c, "", "#000000", "#FFFFFF", false, tableWidget_3);
  3388. }
  3389. }
  3390.  
  3391.  
  3392. for(int n=0; n<n_max; n++)
  3393. {
  3394. note1 = liste_NOTES_importees[n-1];
  3395. note2 = liste_NOTES_importees[n];
  3396.  
  3397. n_barre1 = note1.n_barreM;
  3398. n_barre2 = note2.n_barreM;
  3399.  
  3400. midi_i = note2.midi;
  3401.  
  3402. // num_ligne++;
  3403. if (n_barre2 != n_barre1) { num_ligne++; }
  3404.  
  3405. nom_note="";
  3406. if ((midi_i >=40) && (midi_i <=83) )
  3407. {
  3408. nom_note.setNum(midi_i);
  3409. int h1 = calcul_hauteur_note(midi_i);
  3410. QColor couleur1 = liste_couleurs[h1];
  3411. nom_note+=" ";
  3412. nom_note += nom_note_FR(midi_i);
  3413.  
  3414. //num_case=0;
  3415. int RC = tableWidget_3->rowCount();
  3416.  
  3417. QString s0="";
  3418. if (num_ligne >1) {s0 = tableWidget_3->item(num_ligne-1, 0)->text(); }
  3419. s1.setNum(n);
  3420. s1 = s0 + " " + s1;
  3421.  
  3422. complete_case(num_ligne-1, 0, s1, "#000000", "#DDDDDD", false, tableWidget_3);
  3423. for (int c=0; c<=13; c++)
  3424. {
  3425. complete_case(RC, c, "-", "#000000", "#FFFFFF", false, tableWidget_3);
  3426. }
  3427.  
  3428. QTableWidgetItem *Item1 = new QTableWidgetItem();
  3429. Item1->setIcon(QIcon("../images/01.png" ));
  3430. tableWidget_3->setItem(num_ligne-1, 5, Item1 );
  3431. //complete_case(num_ligne-1, 5, ">", "#00FF00", "#000000", false, tableWidget_3);
  3432.  
  3433. duree = n_barre2 - n_barre1;
  3434. if (duree <0) {duree = 0;}
  3435. if (duree > 0)
  3436. {
  3437. //c'est ici que la durée de la note jouée est définie :
  3438. duree_txt.setNum(duree);
  3439. complete_case(num_ligne-2, 6, duree_txt, "#000000", "#FFFFFF", false, tableWidget_3);
  3440. }
  3441.  
  3442. if (n_barre2 == n_barre1)
  3443. {
  3444. num_case++;
  3445. if (num_case>3) {num_case=3;}
  3446. }
  3447. else {num_case=1;}
  3448.  
  3449. // écriture du nom des notes sur fond coloré :
  3450. complete_case(num_ligne-1, num_case, nom_note, "#000000", couleur1, false, tableWidget_3);
  3451. }
  3452. }
  3453.  
  3454. tableWidget_3->resizeColumnsToContents();
  3455. // tableWidget_3->setColumnWidth(0, 100);
  3456.  
  3457. s1.setNum(0);
  3458. lineEdit_12->setText(s1);
  3459.  
  3460. s1.setNum(num_ligne);
  3461. lineEdit_13->setText(s1);
  3462. }
  3463.  
  3464.  
  3465. void MainWindow::supprime_note(int n)
  3466. {
  3467. //int z1= liste_NOTES.length();
  3468.  
  3469. liste_NOTES_importees.remove(n);
  3470. //effacer_calque(scene4,calque_notes);
  3471. //tri_liste_notes_par_num_barre(); //les notes seront triées par temps croissant
  3472. // numerotation_liste_notes(); //les notes seront numérotées par temps croissant
  3473. //affiche_liste_notes();
  3474. //trace_liste_notes();
  3475.  
  3476. //int z2= liste_NOTES_importees.length();
  3477. }
  3478.  
  3479. /*
  3480. uint16_t numero;
  3481. uint8_t midi;
  3482. int16_t n_barreT;
  3483. int16_t n_barreM;
  3484. */
  3485.  
  3486. void MainWindow::suppression_notes_invalides()
  3487. {
  3488. int numero, midi, n_barreT, n_barreM;
  3489. int n_max = liste_NOTES_importees.length();
  3490. int nb = 0;
  3491.  
  3492. bool boucler=true;
  3493. do
  3494. {
  3495. nb=0;
  3496. for(int n=0; n<n_max; n++)
  3497. {
  3498. numero = liste_NOTES_importees[n].numero;
  3499. midi = liste_NOTES_importees[n].midi;
  3500. n_barreT = liste_NOTES_importees[n].n_barreT;
  3501. n_barreM = liste_NOTES_importees[n].n_barreM;
  3502.  
  3503. if ((midi <40) || (midi>82)) // midi=100 code pour les barres de mesures
  3504. {
  3505. supprime_note(n);
  3506. n_max --;
  3507. nb++;
  3508. }
  3509. }
  3510. if (nb==0) {boucler=false;}
  3511. }
  3512. while (boucler == true);
  3513. }
  3514.  
  3515.  
  3516.  
  3517. void MainWindow::import_fichier_NOTES() // généré par le programme FFT
  3518. {
  3519. QString filename1;
  3520. QString s1;
  3521.  
  3522. filename1 = QFileDialog::getOpenFileName(this,
  3523. tr("Ouvrir Fichier NTS"), string_currentDir+"/", tr("Fichiers NTS (*.NTS)"));
  3524.  
  3525. file_dat.setFileName(filename1);
  3526. if (!file_dat.open(QIODevice::ReadOnly))
  3527. {
  3528. data_ok = false;
  3529. return ;
  3530. }
  3531. else
  3532. {
  3533. binStream1.setDevice(&file_dat); // accès à la totalité du fichier dat
  3534. binStream1.setVersion(QDataStream::Qt_6_8);
  3535. data_ok = true;
  3536. }
  3537.  
  3538. // int z = sizeof(NOTE); // ATTENTION ! ne PAS utiliser cette valeur qui tient en compte l'alignement en RAM
  3539. long n_max = file_dat.bytesAvailable() / 7; // 7 bits par enr; voir la def de 'NOTE' dans le .h
  3540.  
  3541. uint8_t x0a;
  3542. double x0b;
  3543. uint8_t dxa;
  3544. double dxb;
  3545. double vts;
  3546.  
  3547. // lecture entête -----------------
  3548. // binStream1 >> x >> dx >> vts; // 8+8+8=24 octets au début du fichiers
  3549. binStream1 >> x0b >> dxb >> vts >> Ta >> Tb >> x0a >> dxa; // 8+8+8+1+1+1+1=28 octets au début du fichiers
  3550.  
  3551. uint8_t xx;
  3552. for (int i=0; i<(64-28); i++) {binStream1 >> xx;} // lit en tout à 64 octets
  3553. //---------------------------------
  3554.  
  3555. doubleSpinBox_vitesse->setValue(vts);
  3556.  
  3557. NOTE_importee note_i;
  3558. for(int n=0; n<n_max; n++)
  3559. {
  3560. //NOTE_importee note_i;
  3561. binStream1 >> note_i.numero >> note_i.midi >> note_i.n_barreT >> note_i.n_barreM;
  3562. note_i.midi += spinBox_transposition->value();
  3563. liste_NOTES_importees << note_i;
  3564.  
  3565. }
  3566. file_dat.close();
  3567.  
  3568. suppression_notes_invalides();
  3569. }
  3570.  
  3571.  
  3572.  
  3573.  
  3574. void MainWindow::on_Bt_copie_doigts_to_TW3_clicked()
  3575. {
  3576. // le 'tableWidget_doigts' c'est le tableau de saisie dans le cadre 'Position des doigts'
  3577.  
  3578. QString s1, s_out;;
  3579. s1 = tableWidget_doigts->item(0,0) ->text();
  3580. if (s1 != "-") {s_out += "D0v=" + s1 + ";";}
  3581. s1 = tableWidget_doigts->item(0,1) ->text();
  3582. if (s1 != "-") {s_out += "D0h=" + s1 + ";";}
  3583.  
  3584. s1 = tableWidget_doigts->item(1,0) ->text();
  3585. if (s1 != "-") {s_out += "D1v=" + s1 + ";";}
  3586. s1 = tableWidget_doigts->item(1,1) ->text();
  3587. if (s1 != "-") {s_out += "D1h=" + s1 + ";";}
  3588.  
  3589. s1 = tableWidget_doigts->item(2,0) ->text();
  3590. if (s1 != "-") {s_out += "D2v=" + s1 + ";";}
  3591. s1 = tableWidget_doigts->item(2,1) ->text();
  3592. if (s1 != "-") {s_out += "D2h=" + s1 + ";";}
  3593.  
  3594. s1 = tableWidget_doigts->item(3,0) ->text();
  3595. if (s1 != "-") {s_out += "D3v=" + s1 + ";";}
  3596. s1 = tableWidget_doigts->item(3,1) ->text();
  3597. if (s1 != "-") {s_out += "D3h=" + s1 + ";";}
  3598.  
  3599. s1 = tableWidget_doigts->item(4,0) ->text();
  3600. if (s1 != "-") {s_out += "D4v=" + s1 + ";";}
  3601. s1 = tableWidget_doigts->item(4,1) ->text();
  3602. if (s1 != "-") {s_out += "D4h=" + s1 + ";";}
  3603.  
  3604. QTableWidgetItem *item1 = new QTableWidgetItem();
  3605. item1->setText(s_out);
  3606. item1->setFlags(item1->flags() & ~Qt::ItemIsEditable);
  3607. tableWidget_3->setItem(ligne_TW3, 11, item1); // recopie le résultat dans le grand tableau TW3 de droite
  3608.  
  3609. affi_positions_doigts_dans_status(s_out);
  3610. }
  3611.  
  3612.  
  3613. void MainWindow::on_pushButton_6_clicked()
  3614. {
  3615. QMessageBox msgBox;
  3616. QString s1;
  3617.  
  3618. s1 = "POSITION DES DOIGTS main gauche (sur le manche)";
  3619. s1 += "\n";
  3620. s1 += "\n";
  3621. s1 += "La première ligne (0) désigne la corde à vide";
  3622. s1 += "\n";
  3623.  
  3624. s1 += "Chacune des 4 lignes suivantes (1 à 4) représente un doigt :";
  3625. s1 += "\n";
  3626. s1 += "le numéro de la ligne désigne le doigt :";
  3627. s1 += "\n";
  3628. s1 += "doigt 1 = index, 2 = majeur...";
  3629. s1 += "\n";
  3630. s1 += "Pour écrire dans le tableau cliquer au préalable sur une note (sur le manche)";
  3631. s1 += "\n";
  3632. s1 += "... puis ici sur une ligne (sur une des 4 petites flèches vertes)";
  3633. s1 += "\n";
  3634. s1 += "( corde 1 = mi aigü...)";
  3635. s1 += "\n";
  3636. s1 += "\n";
  3637. s1 += "Le tableau s'actualise également lorsqu'une note est jouée depuis la liste TW3";
  3638. s1 += "\n";
  3639. s1 += "\n";
  3640. s1 += "Dès lors, sur le manche, les numéros des doigts s'afficheront au centre des notes "
  3641. "pressées dans les cases (et pas forcément jouées, on peut très bien plaquer tout un "
  3642. "accord et ne jouer qu'une note à la fois, en arpège )";
  3643.  
  3644. msgBox.setText(s1);
  3645. msgBox.exec();
  3646.  
  3647.  
  3648. }
  3649.  
  3650.  
  3651. void MainWindow::on_tableWidget_doigts_cellClicked(int row, int column)
  3652. {
  3653. QString s1, s2;
  3654.  
  3655. if(case_jouee == 0)
  3656. {
  3657. s1.setNum(corde_jouee);
  3658. tableWidget_doigts->item(0, 0)->setText(s1);
  3659. return ;
  3660. }
  3661.  
  3662. if (column==2)
  3663. {
  3664. s1.setNum(corde_jouee);
  3665. tableWidget_doigts->item(row, 0)->setText(s1);
  3666. s2.setNum(case_jouee);
  3667. tableWidget_doigts->item(row, 1)->setText(s2);
  3668.  
  3669. }
  3670. }
  3671.  
  3672.  
  3673. void MainWindow::on_Bt_RAZ_doigts_clicked()
  3674. {
  3675. //tableWidget_doigts->clear();
  3676. init_tableWidget_doigts();
  3677. }
  3678.  
  3679.  
  3680. void MainWindow::on_pushButton_7_clicked()
  3681. {
  3682. QMessageBox msgBox;
  3683. QString s1;
  3684. s1 = "AIDE GENERALE";
  3685. s1 += "\n";
  3686. s1 += "\n";
  3687. s1 += "1- Ouvrir un 'fichier accords' préalablement sauvegardé avec ce logiciel 'Guitare'";
  3688. s1 += "\n";
  3689. s1 += "Variante : Importer la liste des notes créée avec le logiciel 'FFT'";
  3690. s1 += "\n";
  3691. s1 += "2- vérifier la durée (calculée) des mesures et modifier la durée des notes si nécessaire";
  3692. s1 += "\n";
  3693. s1 += "3- Pour chaque ligne, configurer un accord type ou une 'note seule'";
  3694. s1 += "(utiliser pour cela le 'Configurateur d'accords')";
  3695. s1 += " puis envoyer la configuration obtenue vers le tableau TW3, avec le bouton 'to TW3 -->' du 'configurateur d'Accords'";
  3696. s1 += "\n";
  3697. s1 += "4- Reste à choisir les doigts pour chaque note. Voir l'aide du cadre 'Position des doigts'";
  3698. s1 += "\n";
  3699. s1 += "\n";
  3700. s1 += "VARIANTE :";
  3701. s1 += "\n";
  3702. s1 += "\n";
  3703. s1 += "On peut aussi partir de zéro et entrer les notes une à une manuellement dans TW3 (TableWidget 3)";
  3704. s1 += "\n";
  3705. s1 += "Il est fortement conseillé de cliquer les notes sur le manche au préalable (voir l'aide du manche) ";
  3706. s1 += "plutôt que de saisir les libellés au clavier, afin d'éviter les saisies incorrectes";
  3707. msgBox.setText(s1);
  3708. msgBox.exec();
  3709. }
  3710.  
  3711.  
  3712.  
  3713.  
  3714.  
  3715. void MainWindow::contextMenuEvent(QContextMenuEvent *event) // menu contextuel (c.a.d déclenché par le clic de droite)
  3716. {
  3717. // statusbar->showMessage("clic de droite");
  3718. int x_min, x_max;
  3719. int y_min, y_max;
  3720.  
  3721. x_min = graphicsView1->x();
  3722. x_max = x_min + graphicsView1->width();
  3723.  
  3724. y_min = graphicsView1->y();
  3725. y_max = y_min + graphicsView1->height();
  3726.  
  3727. if (x_clic_ecran > x_min && x_clic_ecran < x_max && y_clic_ecran > y_min && y_clic_ecran < y_max)
  3728. {
  3729. QString s1, s2;
  3730. s1.setNum(n_midi_jouee);
  3731.  
  3732. s2 = "mode: DEPOT NOTE ("+ s1 + ") -> ";
  3733. s2 += lineEdit_note->text();
  3734. s2 += " cliquez maintenant dans une case de TW3 pour placer la note";
  3735.  
  3736. mode_depot_note = true;
  3737. statusbar->showMessage(s2);
  3738. MainWindow::setCursor(Qt::CrossCursor);
  3739. }
  3740. }
  3741.  
  3742.  
  3743. void MainWindow::on_pushButton_8_clicked()
  3744. {
  3745. QMessageBox msgBox;
  3746. QString s1;
  3747. s1 = "COPIE d'une note vers le tableau TW3 -->";
  3748. s1 += "\n";
  3749. s1 += "\n";
  3750. s1 += "1- clic-droit sur une note (sur le manche)";
  3751. s1 += "\n";
  3752. s1 += "Le curseur de la souris devient une croix";
  3753. s1 += "\n";
  3754. s1 += "2- cliquer_gauche alors dans une case de TW3 (colonnes 1 à 3)";
  3755. s1 += "\n";
  3756. s1 += "La note est alors collée dans le tableau";
  3757. s1 += "\n";
  3758. s1 += "\n";
  3759. s1 += "Si clic en dehors du tableau, l'opéraion est annulée";
  3760. s1 += "\n";
  3761.  
  3762. msgBox.setText(s1);
  3763. msgBox.exec();
  3764. }
  3765.  
  3766. void MainWindow::on_pushButton_9_clicked()
  3767. {
  3768. QMessageBox msgBox;
  3769. QString s1;
  3770. s1 = "Les numéros qui s'affichent au centre des notes jouées sont ceux des doigts de la main gauche";
  3771. s1 += "\n";
  3772. s1 += "1=index, 2=majeur, 3=annulaire, 4=auriculaire";
  3773.  
  3774.  
  3775. msgBox.setText(s1);
  3776. msgBox.exec();
  3777. }
  3778.  
  3779.  
  3780.  
  3781.  
  3782. void MainWindow::on_pushButton_10_clicked()
  3783. {
  3784. QMessageBox msgBox;
  3785. QString s1;
  3786. s1 = "Les fichiers sont enregistrés au format texte";
  3787. s1 += "\n";
  3788. s1 += "Il peuvent être facilement concaténés avec un éditeur de texte";
  3789. s1 += "\n";
  3790. s1 += "pour obtenir un morceau complet à partir de petites séquences.";
  3791.  
  3792. msgBox.setText(s1);
  3793. msgBox.exec();
  3794. }
  3795.  
  3796.  
  3797. void MainWindow::on_Bt_import_notes_clicked()
  3798. {
  3799. init_TW_3();
  3800. liste_NOTES_importees.clear();
  3801. import_fichier_NOTES();
  3802. // suppression_notes_invalides();
  3803. affiche_liste_notes();
  3804. analyse_notes_importees(); // et garnit le TW3
  3805. write_Time_line();
  3806. }
  3807.  
  3808.  
  3809. void MainWindow::complete_accord(int c_min, int c_max)
  3810. {
  3811. spinBox_4->setValue(c_min);
  3812. case_min = c_min;
  3813.  
  3814. spinBox_5->setValue(c_max);
  3815. case_max = c_max;
  3816.  
  3817. if (type_accords == 1) {on_Bt_ACCORD_1_clicked();}
  3818. if (type_accords == 2) {on_Bt_ACCORD_2_clicked();}
  3819. if (type_accords == 3) {on_Bt_ACCORD_3_clicked();}
  3820. }
  3821.  
  3822.  
  3823.  
  3824. void MainWindow::on_pushButton_3_clicked()
  3825. {
  3826. complete_accord(0, 20);
  3827. }
  3828.  
  3829.  
  3830.  
  3831. void MainWindow::on_pushButton_3a_clicked()
  3832. {
  3833. complete_accord(9, 12);
  3834. }
  3835.  
  3836.  
  3837. void MainWindow::on_pushButton_3b_clicked()
  3838. {
  3839. complete_accord(7, 10);
  3840. }
  3841.  
  3842.  
  3843. void MainWindow::on_pushButton_3c_clicked()
  3844. {
  3845. complete_accord(5, 8);
  3846. }
  3847.  
  3848.  
  3849. void MainWindow::on_pushButton_3d_clicked()
  3850. {
  3851. complete_accord(3, 6);
  3852. }
  3853.  
  3854.  
  3855. void MainWindow::on_pushButton_3e_clicked()
  3856. {
  3857. complete_accord(0, 3);
  3858. }
  3859.  
  3860.  
  3861. void MainWindow::on_pushButton_11_clicked()
  3862. {
  3863. QMessageBox msgBox;
  3864. QString s1;
  3865. s1 = "Cliquer sur bouton vert 'Import notes' pour remplir le tableau";
  3866. s1 += "\n";
  3867.  
  3868. msgBox.setText(s1);
  3869. msgBox.exec();
  3870. }
  3871.  
  3872.  
  3873. void MainWindow::on_tableWidget_3_cellChanged(int row, int column)
  3874. {
  3875. // if (column==5) {calcul_tps();}
  3876. }
  3877.  
  3878.  
  3879. void MainWindow::choix_dossier_de_travail()
  3880. {
  3881.  
  3882. QString currentDir_actuel = string_currentDir;
  3883. string_currentDir = QFileDialog::getExistingDirectory
  3884. (this, tr("Open Directory"), currentDir_actuel, QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
  3885.  
  3886. if (string_currentDir != "")
  3887. {
  3888. string_currentDir += "/";
  3889. dossier_de_travail_ok = true;
  3890. save_fichier_ini();
  3891. lineEdit_current_dir->setText(string_currentDir);
  3892. }
  3893. else
  3894. {
  3895. string_currentDir = currentDir_actuel;
  3896. dossier_de_travail_ok = false;
  3897. } // -> si on clique sur le bouton 'cancel'
  3898. }
  3899.  
  3900.  
  3901.  
  3902. void MainWindow::on_Bt_choix_current_dir_clicked()
  3903. {
  3904. choix_dossier_de_travail();
  3905. }
  3906.  
  3907.  
  3908.  
  3909.  
  3910. void MainWindow::on_Bt_save_ACD_clicked()
  3911. {
  3912. QString chemin_out;
  3913. chemin_out = string_currentDir;
  3914. QFile file1(chemin_out + "ACD" + ".txt");
  3915. QString sA, sC, sD;
  3916. int n_max = tableWidget_3->rowCount();
  3917.  
  3918. if (file1.open(QIODevice::WriteOnly | QIODevice::Text))
  3919. {
  3920. QTextStream file_out(&file1);
  3921.  
  3922. for (int n=0; n<n_max; n++)
  3923. {
  3924. sA = tableWidget_3->item(n, 9)->text(); // accords
  3925. sC = tableWidget_3->item(n, 10)->text(); // cases
  3926. sD = tableWidget_3->item(n, 11)->text(); // doigts
  3927.  
  3928. file_out << "A=" + sA + ";" + "C=" + sC + ";" + "D=" + sD + ";";
  3929. file_out << char(10);
  3930. }
  3931.  
  3932. }
  3933. file1.close();
  3934.  
  3935. QMessageBox msgBox;
  3936. QString s1="Fichier enregistré: " + chemin_out + "ACD" + ".txt";
  3937. msgBox.setText(s1);
  3938. msgBox.exec();
  3939. }
  3940.  
  3941.  
  3942. int MainWindow::on_Bt_load_ACD_clicked()
  3943. {
  3944. QString chemin_in;
  3945. chemin_in = string_currentDir;
  3946. QFile file1(chemin_in + "ACD" + ".txt");
  3947. QString sA, sC, sD;
  3948. QString ligne_i;
  3949. int num_ligne=0;
  3950.  
  3951. if (!file1.open(QIODevice::ReadOnly | QIODevice::Text)) return 1;
  3952. QTextStream TextStream1(&file1);
  3953.  
  3954. while ( !TextStream1.atEnd() )
  3955. {
  3956. ligne_i = TextStream1.readLine();
  3957. tableWidget_3->item(num_ligne, 8)->setText(" ");
  3958. sA= extraction_data(ligne_i, "A="); tableWidget_3->item(num_ligne, 9)->setText(sA);
  3959. sC= extraction_data(ligne_i, "C="); tableWidget_3->item(num_ligne, 10)->setText(sC);
  3960. sD= extraction_data(ligne_i, "D="); tableWidget_3->item(num_ligne, 11)->setText(sD);
  3961. num_ligne++;
  3962. }
  3963. file1.close();
  3964.  
  3965. return 0;
  3966. }
  3967.  
  3968.  
  3969. void MainWindow::on_Bt_calcul_tps_clicked()
  3970. {
  3971. calcul_tps();
  3972. }
  3973.  
  3974.  
  3975. void MainWindow::on_pushButton_12_clicked()
  3976. {
  3977. QMessageBox msgBox;
  3978. QString s1;
  3979. s1 = "ABBREVIATIONS, sigles utilisés"; s1 += "\n";
  3980. s1 += "dans la colonne Cmt ->"; s1 += "\n";
  3981. s1 += "\n";
  3982. s1 += "(GL = début glissendo"; s1 += "\n";
  3983. s1 += "GL) = fin glissendo"; s1 += "\n";
  3984. s1 += "HO = Hammer-On"; s1 += "\n";
  3985. s1 += "PO = Pull-Off"; s1 += "\n";
  3986. s1 += "pB = petit Barré (cordes 1-2-3)"; s1 += "\n";
  3987. msgBox.setText(s1);
  3988. msgBox.exec();
  3989. }
  3990.  
  3991.  
  3992. void MainWindow::on_Bt_sigle_1_clicked()
  3993. {
  3994. complete_case(num_ligne_en_cours, 3, "(GL", "#000000","#FFFCDD", false, tableWidget_3);
  3995. }
  3996.  
  3997.  
  3998. void MainWindow::on_Bt_sigle_2_clicked()
  3999. {
  4000. complete_case(num_ligne_en_cours, 3, "GL)", "#000000","#FFFCDD", false, tableWidget_3);
  4001. }
  4002.  
  4003.  
  4004. void MainWindow::on_Bt_sigle_3_clicked()
  4005. {
  4006. complete_case(num_ligne_en_cours, 3, "(HO", "#000000","#FFFCDD", false, tableWidget_3);
  4007. }
  4008.  
  4009.  
  4010. void MainWindow::on_Bt_sigle_4_clicked()
  4011. {
  4012. complete_case(num_ligne_en_cours, 3, "HO)", "#000000","#FFFCDD", false, tableWidget_3);
  4013. }
  4014.  
  4015.  
  4016. void MainWindow::on_Bt_sigle_5_clicked()
  4017. {
  4018. complete_case(num_ligne_en_cours, 3, "Ba", "#000000","#FFFCDD", false, tableWidget_3);
  4019. }
  4020.  
  4021.  
  4022. void MainWindow::on_Bt_sigle_9_clicked()
  4023. {
  4024. complete_case(num_ligne_en_cours, 3, "PO", "#000000","#FFFCDD", false, tableWidget_3);
  4025. }
  4026.  
  4027.  
  4028. void MainWindow::on_Bt_sigle_10_clicked()
  4029. {
  4030. complete_case(num_ligne_en_cours, 3, "Ba", "#000000","#FFFCDD", false, tableWidget_3);
  4031. }
  4032.  
  4033.  
  4034. void MainWindow::on_pushButton_clicked()
  4035. {
  4036. encadre_accord(spinBox_4->value(), spinBox_5->value());
  4037. }
  4038.  
  4039.  

12 Documents

Important : Le dossier 'notes2' contenant les échantillons audios des notes midi (midi 52 à 94) doit être placé dans le dossier de l’exécutable. (Ce dossier de l’exécutable (= Répertoire de compilation) étant choisi lors de la configuration du projet sous Qt Creator). Ces notes servent à rejouer la musique à partir des codes midi fournis par la transformée de Fourier.

13 -

Liens...

646