Commit | Line | Data |
---|---|---|
c2e6b737 TM |
1 | /* |
2 | * MIDIUSB_buzzer.ino | |
3 | * | |
4 | * Author: Paulo Costa | |
5 | */ | |
6 | ||
7 | #include <MozziGuts.h> | |
8 | #include <MIDIUSB.h> | |
9 | #include <pitchToFrequency.h> | |
10 | #include <Oscil.h> // oscillator template | |
11 | #include <tables/sin2048_int8.h> // sine table for oscillator | |
12 | #include <mozzi_midi.h> | |
13 | #include <ADSR.h> | |
14 | ||
15 | // use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above | |
16 | Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin(SIN2048_DATA); | |
17 | ||
18 | ADSR <CONTROL_RATE, AUDIO_RATE> envelope; | |
19 | ||
20 | const char* pitch_name(byte pitch) { | |
21 | static const char* names[] = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"}; | |
22 | return names[pitch % 12]; | |
23 | } | |
24 | ||
25 | int pitch_octave(byte pitch) { | |
26 | return (pitch / 12) - 1; | |
27 | } | |
28 | ||
29 | void noteOn(byte channel, byte pitch, byte velocity) { | |
30 | aSin.setFreq(pitchFrequency[pitch]); | |
31 | envelope.noteOn(); | |
32 | ||
33 | Serial.print("Note On: "); | |
34 | Serial.print(pitch_name(pitch)); | |
35 | Serial.print(pitch_octave(pitch)); | |
36 | Serial.print(", channel="); | |
37 | Serial.print(channel); | |
38 | Serial.print(", velocity="); | |
39 | Serial.println(velocity); | |
40 | } | |
41 | ||
42 | void noteOff(byte channel, byte pitch, byte velocity) { | |
43 | //aSin.setFreq(0); | |
44 | envelope.noteOff(); | |
45 | ||
46 | Serial.print("Note Off: "); | |
47 | Serial.print(pitch_name(pitch)); | |
48 | Serial.print(pitch_octave(pitch)); | |
49 | Serial.print(", channel="); | |
50 | Serial.print(channel); | |
51 | Serial.print(", velocity="); | |
52 | Serial.println(velocity); | |
53 | } | |
54 | ||
55 | void controlChange(byte channel, byte control, byte value) { | |
56 | Serial.print("Control change: control="); | |
57 | Serial.print(control); | |
58 | Serial.print(", value="); | |
59 | Serial.print(value); | |
60 | Serial.print(", channel="); | |
61 | Serial.println(channel); | |
62 | } | |
63 | ||
64 | void setup() { | |
65 | Serial.begin(115200); | |
66 | envelope.setADLevels(255,48); | |
67 | envelope.setTimes(150,200,700,200); // 700 is so the note will sustain 0.7 seconds unless a noteOff comes | |
68 | ||
69 | aSin.setFreq(440); // default frequency | |
70 | startMozzi(CONTROL_RATE); | |
71 | } | |
72 | void updateControl(){ | |
73 | envelope.update(); | |
74 | } | |
75 | ||
76 | ||
77 | AudioOutput_t updateAudio(){ | |
78 | return MonoOutput::from16Bit(envelope.next() * aSin.next()); // return an int signal centred around 0 | |
79 | } | |
80 | ||
81 | void loop() { | |
82 | audioHook(); | |
83 | midiEventPacket_t rx = MidiUSB.read(); | |
84 | switch (rx.header) { | |
85 | case 0: | |
86 | break; //No pending events | |
87 | ||
88 | case 0x9: | |
89 | noteOn( | |
90 | rx.byte1 & 0xF, //channel | |
91 | rx.byte2, //pitch | |
92 | rx.byte3 //velocity | |
93 | ); | |
94 | break; | |
95 | ||
96 | case 0x8: | |
97 | noteOff( | |
98 | rx.byte1 & 0xF, //channel | |
99 | rx.byte2, //pitch | |
100 | rx.byte3 //velocity | |
101 | ); | |
102 | break; | |
103 | ||
104 | case 0xB: | |
105 | controlChange( | |
106 | rx.byte1 & 0xF, //channel | |
107 | rx.byte2, //control | |
108 | rx.byte3 //value | |
109 | ); | |
110 | break; | |
111 | ||
112 | default: | |
113 | Serial.print("Unhandled MIDI message: "); | |
114 | Serial.print(rx.header, HEX); | |
115 | Serial.print("-"); | |
116 | Serial.print(rx.byte1, HEX); | |
117 | Serial.print("-"); | |
118 | Serial.print(rx.byte2, HEX); | |
119 | Serial.print("-"); | |
120 | Serial.println(rx.byte3, HEX); | |
121 | } | |
122 | } |