#define MY_CODE

// Frequenze delle note per l'intera gamma cromatica
word notes[] = 
{
  16,  // C0
  17,  // C#0
  18,  // D0
  19,  // D#0
  21,  // E0
  22,  // F0
  23,  // F#0
  24,  // G0
  25,  // G#0
  26,  // A0
  28,  // A#0
  29,  // B0
  
  33,  // C1
  35,  // C#1
  37,  // D1
  39,  // D#1
  41,  // E1
  44,  // F1
  46,  // F#1
  49,  // G1
  52,  // G#1
  55,  // A1
  58,  // A#1
  62,  // B1
  
  65,  // C2
  69,  // C#2
  73,  // D2
  78,  // D#2
  82,  // E2
  87,  // F2
  92,  // F#2
  98,  // G2
  103, // G#2
  110, // A2
  116, // A#2
  123, // B2
  
  130, // C3
  138, // C#3
  146, // D3
  155, // D#3
  164, // E3
  174, // F3
  185, // F#3
  196, // G3
  207, // G#3
  220, // A3
  233, // A#3
  246, // B3
  
  261, // C4 (Do centrale)
  277, // C#4
  293, // D4
  311, // D#4
  329, // E4
  349, // F4
  370, // F#4
  392, // G4
  415, // G#4
  440, // A4
  466, // A#4
  493, // B4
  
  523, // C5
  554, // C#5
  587, // D5
  622, // D#5
  659, // E5
  698, // F5
  740, // F#5
  784, // G5
  831, // G#5
  880, // A5
  932, // A#5
  987, // B5
  
  1047, // C6
  1109, // C#6
  1175, // D6
  1245, // D#6
  1319, // E6
  1397, // F6
  1480, // F#6
  1568, // G6
  1661, // G#6
  1760, // A6
  1865, // A#6
  1975, // B6
  
  2093, // C7
  2218, // C#7
  2349, // D7
  2489, // D#7
  2637, // E7
  2794, // F7
  2960, // F#7
  3136, // G7
  3322, // G#7
  3520, // A7
  3729, // A#7
  3951, // B7
  
  4186, // C8
  4435, // C#8
  4699, // D8
  4978, // D#8
  5274, // E8
  5588, // F8
  5920, // F#8
  6272, // G8
  6645, // G#8
  7040, // A8
  7458, // A#8
  7902, // B8
};

void ONDA_QUADRA(byte N, word F, double C)
{
  #ifndef MY_CODE 
  tone(N, F);
  //
  // s.attach(N);
  // s.write(0 + 180 * (C - 0.025) / 0.09);
  //
  // analogWrite(N, C * 255);
  #else

  // CONTROLLO DI VALIDITÀ DELL'INPUT
  // Se l'input non è valido non si effettua nessuna modifica
  if((N == 9 || N == 10)  &&  F > 0   &&  (0 <= C && C <= 1)) 
  { 
    // GESTIONE A PARTE DEI CASI PARTICOLARI:
    if(C == 0 || C == 1)
    {
      // Si "slaccia" il pin N:
      if(N == 9) { TCCR1A &= 0b00111111; } else { TCCR1A &= 0b11001111; }  
      // Si procede con la scrittura digitale:
      digitalWrite(N, C);
    }
    else
    {
       // GENERAZIONE DELL'ONDA QUADRA:
       // Allo scopo, si configura la periferica TC1 come seuge.
       //
       // Si impostano il PRESCALER=8 e la MODALITÀ="Fast PWM to ICR1":
       TCCR1A = TCCR1A & 0b11111100 | 0b00000010;
       TCCR1B = 0b00011010;
       // ATTENZIONE! Non "slacciare" i pin.
       //
       // Si imposta la FREQUENZA e la SOGLIA:
       ICR1 = F_CPU/F/8 - 1;
       if(N == 9) { OCR1A  = ICR1 * C; } else { OCR1B  = ICR1 * C; }
       if(TCNT1 >= ICR1) { TCNT1 = 0; }
       //
       // Si "allaccia" il pin N:
       if(N == 9) { TCCR1A |= 0b10000000; } else { TCCR1A |= 0b00100000; } 
    }
  }

  #endif  
}

byte N;
word F;
void setup() 
{
    N = 9;
    pinMode( 9, OUTPUT);
    pinMode(10, OUTPUT);
}
 
void loop() 
{
  //SCALA(3, 8);  // Funziona ALMENO da 3 a 8
  //ALLARME1();
  //ALLARME2();
  //AMBULANZA_SOCCORSO();
  //AMBULANZA_EMERGENZA();
  ONDA_QUADRA(N, F, 0.5);
  if(N == 9) { N = 10; F = 440; } else { N = 9; F = 880; }
  delay(1000);
}

void SCALA(byte m, byte M)
{
  word i;
  for(i = m * 12;   i < M * 12;   i = i + 1)  
  {
    F = notes[i];
  
    ONDA_QUADRA(N, F, 0.5);
    
    delay(100); // min 100
  }
  for(i = M * 12;   i > m * 12;   i = i - 1)
  {
    F = notes[i];
  
    ONDA_QUADRA(N, F, 0.5);
    
    delay(100); // min 100
  }
}

void ALLARME1() 
{        
  // Whoop up
  for(F = 440; F < 1000; F = F + 25)
  {
    ONDA_QUADRA(N, F, 0.5);
    delay(5); // Buono anche 10
  }
  // Whoop down
  for(F = 1000; F > 440; F = F - 25)
  {
    ONDA_QUADRA(N, F, 0.5);
    delay(5); // Buono anche 10
  }
}

void ALLARME2() 
{              
  ONDA_QUADRA(N,  500, 0.5);  delay(300);
  ONDA_QUADRA(N, 1500, 0.5);  delay(300);
}

// Fonte: https://ilsicilia.it/le-sirene-tra-mito-e-ambulanze/
void AMBULANZA_SOCCORSO() 
{              
  ONDA_QUADRA(N, 392, 0.5);  delay(1000);
  ONDA_QUADRA(N, 660, 0.5);  delay(167);
  ONDA_QUADRA(N, 392, 0.5);  delay(167);
  ONDA_QUADRA(N, 660, 0.5);  delay(167);
}

// Fonte: https://ilsicilia.it/le-sirene-tra-mito-e-ambulanze/
void AMBULANZA_EMERGENZA() 
{              
  ONDA_QUADRA(N, 446, 0.5);  delay(750);
  ONDA_QUADRA(N, 622, 0.5);  delay(750);
}