summaryrefslogtreecommitdiffstats
path: root/Processing-js/Synth.pde
blob: 19d3a651f845c2ca79e521dc1a6813a6dcf7b4b6 (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
void initSynth()
{
//  MIDI.loadPlugin({instrument: "acoustic_grand_piano"});
}

int processNote(int activatedKey, boolean white, boolean on, boolean autoplay) // Détection de la note cliquée
{  
  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)
      return -1;
  
  if (white)
  {
    keyNumber = (activatedKey-1)%7;
    octave = (activatedKey-1-keyNumber)/7;
    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;
  keyNumber = octave*12+baseNote+keyNumber;
  if(on)
  {
     MIDI.noteOn(0, keyNumber, midiVelocity, 0);
     keysPressed[white ? 1 : 0][activatedKey-1] = 1;
  }
  else
  {
    MIDI.noteOff(0, keyNumber, 0);
    keysPressed[white ? 1 : 0][activatedKey-1] = 0;
  }

  if (on && events[RECORDINGSTARTED])
  {
    if(numnote >= notePressed.length)
      events[RECORDINGSTOPPED] = true;
    else
    {
      notePressed[numnote][0] = keyNumber;
      if (numnote != 0) notePressed[numnote][1] = millis() - notePressed[0][1];
      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;
    }
  }
}