From 73228f5e5d1d4cd31a46e5e93aa893a8f727e3b9 Mon Sep 17 00:00:00 2001
From: Jack Humbert <jack.humb@gmail.com>
Date: Thu, 21 Apr 2016 00:37:45 -0400
Subject: [PATCH] restructures audio, begins voicing

---
 quantum/{ => audio}/audio.c         | 29 ++++----------
 quantum/{ => audio}/audio.h         |  1 +
 quantum/{ => audio}/musical_notes.h |  0
 quantum/{ => audio}/song_list.h     |  0
 quantum/{ => audio}/vibrato_lut.h   |  0
 quantum/audio/voices.c              | 60 +++++++++++++++++++++++++++++
 quantum/audio/voices.h              | 21 ++++++++++
 quantum/{ => audio}/wave.h          |  0
 quantum/quantum.mk                  |  3 +-
 9 files changed, 91 insertions(+), 23 deletions(-)
 rename quantum/{ => audio}/audio.c (96%)
 rename quantum/{ => audio}/audio.h (99%)
 rename quantum/{ => audio}/musical_notes.h (100%)
 rename quantum/{ => audio}/song_list.h (100%)
 rename quantum/{ => audio}/vibrato_lut.h (100%)
 create mode 100644 quantum/audio/voices.c
 create mode 100644 quantum/audio/voices.h
 rename quantum/{ => audio}/wave.h (100%)

diff --git a/quantum/audio.c b/quantum/audio/audio.c
similarity index 96%
rename from quantum/audio.c
rename to quantum/audio/audio.c
index df421ef99..3225557ba 100644
--- a/quantum/audio.c
+++ b/quantum/audio/audio.c
@@ -299,27 +299,6 @@ float vibrato(float average_freq) {
 
 #endif
 
-float envelope(float f) {
-    uint16_t compensated_index = (uint16_t)((float)envelope_index * (880.0 / f));
-    switch (compensated_index) {
-        case 0 ... 9:
-            f = f / 4;
-            note_timbre = TIMBRE_12;
-        break;
-        case 10 ... 19:
-            f = f / 2;
-            note_timbre = TIMBRE_12;
-        break;
-        case 20 ... 200:
-            note_timbre = .125 - pow(((float)compensated_index - 20) / (200 - 20), 2)*.125;
-        break;
-        default:
-            note_timbre = 0;
-        break;
-    }
-    return f;
-}
-
 ISR(TIMER3_COMPA_vect) {
     if (note) {
         #ifdef PWM_AUDIO
@@ -413,7 +392,7 @@ ISR(TIMER3_COMPA_vect) {
                 if (envelope_index < 65535) {
                     envelope_index++;
                 }
-                freq = envelope(freq);
+                freq = voice_envelope(freq);
 
                 if (freq < 30.517578125)
                     freq = 30.52;
@@ -456,6 +435,11 @@ ISR(TIMER3_COMPA_vect) {
                     freq = note_frequency;
                 }
 
+                if (envelope_index < 65535) {
+                    envelope_index++;
+                }
+                freq = voice_envelope(freq);
+
                 ICR3 = (int)(((double)F_CPU) / (freq * CPU_PRESCALER)); // Set max to the period
                 OCR3A = (int)((((double)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); // Set compare to half the period
             } else {
@@ -498,6 +482,7 @@ ISR(TIMER3_COMPA_vect) {
                     note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE;
                     note_length = (*notes_pointer)[current_note][1] * (note_tempo / 100);
                 #else
+                    envelope_index = 0;
                     note_frequency = (*notes_pointer)[current_note][0];
                     note_length = ((*notes_pointer)[current_note][1] / 4) * (note_tempo / 100);
                 #endif
diff --git a/quantum/audio.h b/quantum/audio/audio.h
similarity index 99%
rename from quantum/audio.h
rename to quantum/audio/audio.h
index 2d4d303ce..d1ccfdb82 100644
--- a/quantum/audio.h
+++ b/quantum/audio/audio.h
@@ -4,6 +4,7 @@
 #include <util/delay.h>
 #include "musical_notes.h"
 #include "song_list.h"
+#include "voices.h"
 
 #ifndef AUDIO_H
 #define AUDIO_H
diff --git a/quantum/musical_notes.h b/quantum/audio/musical_notes.h
similarity index 100%
rename from quantum/musical_notes.h
rename to quantum/audio/musical_notes.h
diff --git a/quantum/song_list.h b/quantum/audio/song_list.h
similarity index 100%
rename from quantum/song_list.h
rename to quantum/audio/song_list.h
diff --git a/quantum/vibrato_lut.h b/quantum/audio/vibrato_lut.h
similarity index 100%
rename from quantum/vibrato_lut.h
rename to quantum/audio/vibrato_lut.h
diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c
new file mode 100644
index 000000000..30e8be641
--- /dev/null
+++ b/quantum/audio/voices.c
@@ -0,0 +1,60 @@
+#include "voices.h"
+
+extern uint16_t envelope_index;
+extern float note_timbre;
+
+voice_type voice = default_voice;
+
+void set_voice(voice_type v) {
+	voice = v;
+}
+
+float voice_envelope(float frequency) {
+	// envelope_index ranges from 0 to 0xFFFF, which is preserved at 880.0 Hz
+    uint16_t compensated_index = (uint16_t)((float)envelope_index * (880.0 / frequency));
+
+    switch (voice) {
+    	case default_voice:
+    		// nothing here on purpose
+    	break;
+    	case butts_fader:
+		    switch (compensated_index) {
+		        case 0 ... 9:
+		            frequency = frequency / 4;
+		            note_timbre = TIMBRE_12;
+		        break;
+		        case 10 ... 19:
+		            frequency = frequency / 2;
+		            note_timbre = TIMBRE_12;
+		        break;
+		        case 20 ... 200:
+		            note_timbre = .125 - pow(((float)compensated_index - 20) / (200 - 20), 2)*.125;
+		        break;
+		        default:
+		            note_timbre = 0;
+		        break;
+		    }
+	    break;
+    	case octave_crunch:
+		    switch (compensated_index) {
+		        case 0 ... 9:
+		        case 20 ... 24:
+		        case 30 ... 32:
+		            frequency = frequency / 2;
+		            note_timbre = TIMBRE_12;
+		        break;
+		        case 10 ... 19:
+		        case 25 ... 29:
+		        case 33 ... 35:
+		            frequency = frequency * 2;
+		            note_timbre = TIMBRE_12;
+		        break;
+		        default:
+		            note_timbre = TIMBRE_12;
+		        break;
+		    }
+	    break;
+	}
+
+	return frequency;
+}
\ No newline at end of file
diff --git a/quantum/audio/voices.h b/quantum/audio/voices.h
new file mode 100644
index 000000000..32135dac7
--- /dev/null
+++ b/quantum/audio/voices.h
@@ -0,0 +1,21 @@
+#include <stdint.h>
+#include <stdbool.h>
+#include <avr/io.h>
+#include <util/delay.h>
+#include "musical_notes.h"
+#include "song_list.h"
+
+#ifndef VOICES_H
+#define VOICES_H
+
+float voice_envelope(float frequency);
+
+typedef enum {
+	default_voice,
+	butts_fader,
+	octave_crunch
+} voice_type;
+
+void set_voice(voice_type v);
+
+#endif
\ No newline at end of file
diff --git a/quantum/wave.h b/quantum/audio/wave.h
similarity index 100%
rename from quantum/wave.h
rename to quantum/audio/wave.h
diff --git a/quantum/quantum.mk b/quantum/quantum.mk
index 1fe7390eb..83c4f1d1d 100644
--- a/quantum/quantum.mk
+++ b/quantum/quantum.mk
@@ -28,7 +28,7 @@ ifeq ($(strip $(MIDI_ENABLE)), yes)
 endif
 
 ifeq ($(strip $(AUDIO_ENABLE)), yes)
-	SRC += $(QUANTUM_DIR)/audio.c
+	SRC += $(QUANTUM_DIR)/audio/audio.c $(QUANTUM_DIR)/audio/voices.c
 endif
 
 ifeq ($(strip $(UNICODE_ENABLE)), yes)
@@ -47,6 +47,7 @@ endif
 # Search Path
 VPATH += $(TOP_DIR)/$(QUANTUM_DIR)
 VPATH += $(TOP_DIR)/$(QUANTUM_DIR)/keymap_extras
+VPATH += $(TOP_DIR)/$(QUANTUM_DIR)/audio
 
 include $(TMK_DIR)/protocol/lufa.mk