summaryrefslogtreecommitdiffstats
path: root/Processing/Synthe3000/Synth.pde
blob: ec310bb376e473acd193a5f0f1c5ee60122051c0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
void initSynth() // Initialisation du synthétiseur
{
  Synthesizer synth = null;
  
  try { synth = MidiSystem.getSynthesizer(); }
  catch (MidiUnavailableException e) { exit(); }
  
  try { synth.open(); }
  catch (MidiUnavailableException e) { exit(); }
  
  channel = synth.getChannels()[midiChannelNumber];
}

int processNote(int activatedKey, boolean white, boolean on, boolean autoplay) // Détection de la note cliquée (activatedKey : code de la touche, white : touche blanche ou touche noire, on : activer ou désactiver, autoplay : jouée par l'utilisateur ou par l'ordinateur)
{  
  int keyNumber;
  int octave;
  
  if(autoplay)
  {
    if(on)
      keysPressed[white ? 1 : 0][activatedKey-1] = -1;
    else
      keysPressed[white ? 1 : 0][activatedKey-1] = 0;
  }
  else if(on && keysPressed[white ? 1 : 0][activatedKey-1] > 0) // Si déjà activée
      return -1;
  
  if (white)
  {
    keyNumber = (activatedKey-1)%7; // Calcul du numéro de touche dans l'octave
    octave = (activatedKey-1-keyNumber)/7; // Calcul de l'octave
    if (keyNumber < 3)
      keyNumber *= 2;
    else 
      keyNumber = (keyNumber*2)-1;
  }
  else
  {
    keyNumber = (activatedKey-1)%5;
    octave = (activatedKey-1-keyNumber)/5;
    if (keyNumber < 2)
      keyNumber = (keyNumber*2)+1;
    else
      keyNumber = (keyNumber*2)+2;
  }
  octave -= (numOctaves-numOctaves%2)/2; // Ajustement de l'octave
  keyNumber = octave*12+baseNote+keyNumber; // Calcul du code MIDI de la note à jouer
  if(on)
  {
     channel.noteOn(keyNumber, midiVelocity); // Joue la note
     keysPressed[white ? 1 : 0][activatedKey-1] = 1; // La place dans le tableau des notes activées pour la colorer et ne pas la rejouer
  }
  else
  {
    channel.noteOff(keyNumber, midiVelocity);
    keysPressed[white ? 1 : 0][activatedKey-1] = 0;
  }

  if (on && events[RECORDINGSTARTED])
  {
    if(numnote >= notePressed.length) // Arrête l'enregistrement si le nombre de note dépasse la longueur du tableau
      events[RECORDINGSTOPPED] = true;
    else
    {
      notePressed[numnote][0] = keyNumber; // Enregistre le code de la note
      if (numnote != 0) notePressed[numnote][1] = millis() - notePressed[0][1]; // Enregistre la durée de la note
      else notePressed[numnote][1] = millis();
      numnote++;
    }
  }
  return keyNumber;
}

void playNotes() // Joue les notes de notes[][], appelé lors du clic sur le bouton lecture et jusqu'à la fin du tableau
{

  if (timer == 0) // Si le chronomètre n'est pas lancé
  { 
    if (events[PLAYPRESSED]) // Et que la touche lecture est cliquée
    {
      timer = millis(); // Lancer le chronomètre
      events[MUSICSTARTED] = true;
      if(!events[MUSICPLAYED]) events[MUSICPLAYED] = true;
    }
  }
  else if (numnote < notes.length) // Si la note suivante existe 
  {
    if ( numnote == 0 || timer + notes[numnote-1][2]*(60000/bpm) < millis() ) // et que c'est la première note ou la durée de la note précédente est écoulée
    {
      if(numnote > 0) processNote(notes[numnote-1][0], notes[numnote-1][1]%2!=0, false, true);
      int keyNumber = processNote(notes[numnote][0], notes[numnote][1]%2!=0, true, true);
      /* Remplit un tableau temporaire comportant le timestamp de chaque note. */
      tmpNotes[numnote][0] = keyNumber;
      if (numnote != 0) tmpNotes[numnote][1] = millis()-tmpNotes[0][1];
      else tmpNotes[0][1] = millis();
      
      //channel.noteOn(notes[numnote][0], midiVelocity); // Jouer la note
      numnote++; // Passer à la note suivante
      timer = millis(); // Réinitialiser le chronomètre
    }
  }
  else // Si la lecture est terminée
  {
    if ( numnote == 0 || timer + notes[numnote-1][2]*(60000/bpm) < millis() ) // et que c'est la première note ou la durée de la note précédente est écoulée
    {
      processNote(notes[numnote-1][0], notes[numnote-1][1]%2!=0, false, true);
      tmpNotes[0][1] = 0; // Le timestamp de la première note est 0.
      timer = 0;
      numnote = 0;
      events[MUSICFINISHED] = true;
    }
  }
}