aboutsummaryrefslogtreecommitdiffstats
path: root/src/jingle_bells/jingle_bells.pde
blob: d4d49bf23c7ae386e8018964f6626a6470a02b40 (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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
 * Arduino Jingle Bells.  Reconstructed from code snippets here: 
 *  http://www.uchobby.com/index.php/2007/11/22/arduino-sound-part-3-playing-a-melody/
 */

#define LEDPIN 13
#define OUTPIN 9

#define FREQ_A3 220.00
#define FREQ_AS3 233.08
#define FREQ_BF3 233.08
#define FREQ_B3 246.94
#define FREQ_C4 261.63 //Middle C
#define FREQ_CS4 277.18
#define FREQ_DF4 277.18
#define FREQ_D4 293.66
#define FREQ_DS4 311.13
#define FREQ_E4 329.63
#define FREQ_F4 349.23
#define FREQ_G4 392.00
#define FREQ_A4 440.00
#define FREQ_B4 493.88
#define FREQ_C5 523.25
#define FREQ_D5 587.33

#define WHOLE_NOTE_TIME 2000

void Sound(float freq, int durationMS, int outputPin) {
  int halfPeriod;
  float period;
  int durationCycles;
  //Check for rest, 0 frequency is a rest for durationMS.
  if(freq==0.0) {
    //0 frequency so we stay quiet for duration
    delay (durationMS);
  }
  else { //Frequency is not zero so we have work to do
    // turn on output pin
    pinMode(outputPin, OUTPUT);
    //calculate the period or cycle time for the given frequency
    period=1/freq; //Take the reciprocal to get time in seconds
    period=period*1.0E6; //to covert seconds to uS.
    //divide that by 2 to get the 1/2 cycle time. convert to int at the same time
    halfPeriod = (int)(period/2.0) - 7; // subtract 7 us to make up for digitalWrite overhead

    // calculate cycles for duration.
    durationCycles = (int)(((float)durationMS*1000.0)/period); // play note for duration ms
    for (int i=0; i<durationCycles; i++){
      digitalWrite(outputPin, HIGH);
      delayMicroseconds(halfPeriod);
      digitalWrite(outputPin, LOW);
      delayMicroseconds(halfPeriod - 1); // - 1 to make up for fractional microsecond                                              in digitaWrite overhead
    }
    // shut off pin to avoid noise from other operations
    pinMode(outputPin, INPUT);
  }
}

void PlayMusicString(char* music, int outputPin){
  int noteCount=strlen(music);
  float freq;
  int duration;

  for (int i=0;i<noteCount;i+=2) {
    switch(music[i]){
      case ' ' :
        freq=0;
        break;
      case 'D' :
        freq=FREQ_D4;
        break;
      case 'e' :
        freq=FREQ_E4;
        break;
      case 'f' :
        freq=FREQ_F4;
        break;
      case 'g' :
        freq=FREQ_G4;
        break;
      case 'a' :
        freq=FREQ_A4;
        break;
      case 'b' :
        freq=FREQ_B4;
        break;
      case 'c' :
        freq=FREQ_C5;
        break;
      case 'd' :
        freq=FREQ_D5;
        break;
    }
    //Note Timing
    switch(music[i+1]){
      case '1' :
        duration=WHOLE_NOTE_TIME;
        break;
      case '2' :
        duration=WHOLE_NOTE_TIME/2;
        break;
      case '4' :
        duration=WHOLE_NOTE_TIME/4;
        break;
      case '8' :
        duration=WHOLE_NOTE_TIME/8;
        break;
    }
    Sound(freq,duration,outputPin);
    delay(WHOLE_NOTE_TIME/32);
  }
}


void setup() {
}
void loop() {
  //Jingle Bells translated from sheet music at
  char music[] = {
    "D1e1f1g1a1b1c1d1"
    "D4"             "D4b4a4g4"    "D2 4D4"    "D4b4a4g4" 
    "e2 4e4"        "e4c4b4a4"    "f2 4d4"     "d4d4c4a4"
    "b2g4D4"       "D4b4a4g4"    "D2 4D4"    "D4b4a4g4"
    "e2 4e4"        "e4c4b4a4"    "d4d4d4d4" "e4d4c4a4"
    "g2g4 4"        "b4b4b2"       "b4b4b2"    "b4d4g4a8" "b2"
    "c4c4c4c8"    "c4b4b4b8b8" "b4a4a4b4" "a2d2"
    "b4b4b2"       "b4b4b2"       "b4d4g4a8" "b2 4"       "c4c4"
    "c4b4b4b8b8" "d4d4c4a4"    "g2"};

  delay(1000);
  PlayMusicString(music,OUTPIN);
}