Browse Source

Upload files to 'INPUT_OUTPUT/Flakes/Dee'

master
markvandenheuvel 3 months ago
parent
commit
85b2731858
2 changed files with 1217 additions and 0 deletions
  1. 143
    0
      INPUT_OUTPUT/Flakes/Dee/deep_flakes.ino
  2. 1074
    0
      INPUT_OUTPUT/Flakes/Dee/sample.h

+ 143
- 0
INPUT_OUTPUT/Flakes/Dee/deep_flakes.ino View File

@@ -0,0 +1,143 @@
1
+//Deep Flakes
2
+
3
+#include <stdint.h>
4
+#include <avr/interrupt.h>
5
+#include <avr/io.h>
6
+#include <avr/pgmspace.h>
7
+
8
+#include "sample.h"
9
+
10
+#define LED_PIN     13
11
+#define SPEAKER_PIN 11 
12
+
13
+#define KNOB_1  (0)
14
+#define KNOB_2  (1)  
15
+#define KNOB_3  (2)   
16
+#define INPUT_3 (3)   
17
+
18
+volatile uint16_t sample;
19
+volatile uint16_t loop_start;
20
+volatile uint16_t loop_length;
21
+volatile uint16_t index_bounds;
22
+volatile uint16_t loop_overflow;
23
+
24
+volatile boolean gate;
25
+volatile boolean gate_prev;
26
+
27
+byte lastSample;
28
+
29
+void startPlayback()
30
+{
31
+    pinMode(SPEAKER_PIN, OUTPUT);
32
+
33
+    // Set up Timer 2 to do pulse width modulation on the speaker pin.
34
+    // Use internal clock (datasheet p.160)
35
+    ASSR &= ~(_BV(EXCLK) | _BV(AS2));
36
+
37
+    // Set fast PWM mode  (p.157)
38
+    TCCR2A |= _BV(WGM21) | _BV(WGM20);
39
+    TCCR2B &= ~_BV(WGM22);
40
+
41
+    // Do non-inverting PWM on pin OC2A (p.155)
42
+    // On the Arduino this is pin 11.
43
+    TCCR2A = (TCCR2A | _BV(COM2A1)) & ~_BV(COM2A0);
44
+    TCCR2A &= ~(_BV(COM2B1) | _BV(COM2B0));
45
+    // No prescaler (p.158)
46
+    TCCR2B = (TCCR2B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
47
+
48
+    // Set initial pulse width to the first sample.
49
+    OCR2A = pgm_read_byte(&sound_data[0]);
50
+
51
+    // Set up Timer 1 to send a sample every interrupt.
52
+    cli();
53
+
54
+    // Set CTC mode (Clear Timer on Compare Match) (p.133)
55
+    // Have to set OCR1A *after*, otherwise it gets reset to 0!
56
+    TCCR1B = (TCCR1B & ~_BV(WGM13)) | _BV(WGM12);
57
+    TCCR1A = TCCR1A & ~(_BV(WGM11) | _BV(WGM10));
58
+
59
+    // No prescaler (p.134)
60
+    TCCR1B = (TCCR1B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
61
+
62
+    // Set the compare register (OCR1A).
63
+    // OCR1A is a 16-bit register, so we have to do this with
64
+    // interrupts disabled to be safe.
65
+    OCR1A = F_CPU / SAMPLE_RATE; // 16e6 / 8000 = 2000
66
+
67
+    // Enable interrupt when TCNT1 == OCR1A (p.136)
68
+    TIMSK1 |= _BV(OCIE1A);
69
+
70
+    lastSample = pgm_read_byte(&sound_data[sound_length - 1]);
71
+    sample = 0;
72
+    sei();
73
+}
74
+
75
+void stopPlayback()
76
+{
77
+    TIMSK1 &= ~_BV(OCIE1A); // Disable playback per-sample interrupt.
78
+    TCCR1B &= ~_BV(CS10);   // Disable the per-sample timer completely.
79
+    TCCR2B &= ~_BV(CS10);   // Disable the PWM timer.
80
+    digitalWrite(SPEAKER_PIN, LOW);
81
+}
82
+
83
+void setup()
84
+{
85
+    Serial.begin(9600);
86
+    pinMode(LED_PIN, OUTPUT);
87
+    digitalWrite(LED_PIN, HIGH);
88
+
89
+    startPlayback();
90
+
91
+    loop_start  = 0; 
92
+    loop_length = sound_length;
93
+    gate = false;
94
+    gate_prev = false;
95
+}
96
+
97
+// This is called at 8000 Hz to load the next sample.
98
+ISR(TIMER1_COMPA_vect)
99
+{
100
+    if(sample >= index_bounds)
101
+    {
102
+        sample = loop_start;
103
+    }
104
+    else if((sample < loop_start) &&
105
+            (sample >= loop_overflow))
106
+    {
107
+        sample = loop_start;
108
+    }
109
+    else if((gate == true) &&
110
+            (gate_prev == false))
111
+    {
112
+        sample = loop_start;
113
+    }
114
+    else
115
+    {
116
+        OCR2A = pgm_read_byte(&sound_data[sample % sound_length]);
117
+    }
118
+    gate_prev = gate;
119
+    sample++;
120
+
121
+}
122
+
123
+void loop()
124
+{
125
+    loop_start = analogRead(KNOB_1) / 1024.0 * sound_length;
126
+    loop_length = (analogRead(KNOB_2) + 1) / 1024.0 * sound_length;
127
+    OCR1A = (512.0 / (analogRead(KNOB_3) + 1)) * (F_CPU / SAMPLE_RATE);
128
+    gate = analogRead(3) >> 9;  // 10 bits in. gate < 512 == off, gate >= 512 == on 
129
+    // change to gate = analogRead(3) << 9; if trigger doesn't work)
130
+
131
+//  can be up to 2x sound length. the more you know.
132
+    index_bounds = loop_start + loop_length;
133
+    Serial.println(loop_length);
134
+//  this will set the overflow length. take the loop overflow into account when checking the loop boundaries
135
+    if(index_bounds > sound_length)
136
+    {
137
+        loop_overflow = index_bounds - sound_length;
138
+    }
139
+    else
140
+    {
141
+        loop_overflow = 0;
142
+    }
143
+}

+ 1074
- 0
INPUT_OUTPUT/Flakes/Dee/sample.h
File diff suppressed because it is too large
View File


Loading…
Cancel
Save