Browse Source

Codes for Flakes

master
markvandenheuvel 3 months ago
parent
commit
121e8465e8
3 changed files with 2282 additions and 0 deletions
  1. 180
    0
      INPUT_OUTPUT/Flakes/chaos_on_trigger.ino
  2. 143
    0
      INPUT_OUTPUT/Flakes/deep_flakes.ino
  3. 1959
    0
      INPUT_OUTPUT/Flakes/sample.h

+ 180
- 0
INPUT_OUTPUT/Flakes/chaos_on_trigger.ino View File

@@ -0,0 +1,180 @@
1
+// Chaos on Trigger 
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 INPUT3_PIN A3   // gate trigger
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
+volatile boolean is_playing;
27
+
28
+volatile uint16_t time_since_gate;
29
+
30
+bool triggered;
31
+
32
+int i=0;
33
+
34
+byte lastSample;
35
+
36
+void startPlayback()
37
+
38
+{
39
+    pinMode(SPEAKER_PIN, OUTPUT);
40
+
41
+    // Set up Timer 2 to do pulse width modulation on the speaker pin.
42
+    // Use internal clock (datasheet p.160)
43
+    ASSR &= ~(_BV(EXCLK) | _BV(AS2));
44
+
45
+    // Set fast PWM mode  (p.157)
46
+    TCCR2A |= _BV(WGM21) | _BV(WGM20);
47
+    TCCR2B &= ~_BV(WGM22);
48
+
49
+    // Do non-inverting PWM on pin OC2A (p.155)
50
+    // On the Arduino this is pin 11.
51
+    TCCR2A = (TCCR2A | _BV(COM2A1)) & ~_BV(COM2A0);
52
+    TCCR2A &= ~(_BV(COM2B1) | _BV(COM2B0));
53
+    // No prescaler (p.158)
54
+    TCCR2B = (TCCR2B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
55
+
56
+    // Set initial pulse width to the first sample.
57
+    OCR2A = pgm_read_byte(&sound_data[0]);
58
+
59
+    // Set up Timer 1 to send a sample every interrupt.
60
+    cli();
61
+
62
+    // Set CTC mode (Clear Timer on Compare Match) (p.133)
63
+    // Have to set OCR1A *after*, otherwise it gets reset to 0!
64
+    TCCR1B = (TCCR1B & ~_BV(WGM13)) | _BV(WGM12);
65
+    TCCR1A = TCCR1A & ~(_BV(WGM11) | _BV(WGM10));
66
+
67
+    // No prescaler (p.134)
68
+    TCCR1B = (TCCR1B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
69
+
70
+    // Set the compare register (OCR1A).
71
+    // OCR1A is a 16-bit register, so we have to do this with
72
+    // interrupts disabled to be safe.
73
+    OCR1A = F_CPU / SAMPLE_RATE; // 16e6 / 8000 = 2000
74
+
75
+    // Enable interrupt when TCNT1 == OCR1A (p.136)
76
+    TIMSK1 |= _BV(OCIE1A);
77
+
78
+    lastSample = pgm_read_byte(&sound_data[sound_length - 1]);
79
+    sample = 0;
80
+    sei();
81
+}
82
+
83
+void stopPlayback()
84
+{
85
+    TIMSK1 &= ~_BV(OCIE1A); // Disable playback per-sample interrupt.
86
+    TCCR1B &= ~_BV(CS10);   // Disable the per-sample timer completely.
87
+    TCCR2B &= ~_BV(CS10);   // Disable the PWM timer.
88
+    digitalWrite(SPEAKER_PIN, LOW);
89
+}
90
+
91
+void setup()
92
+{
93
+    pinMode(LED_PIN, OUTPUT);
94
+    digitalWrite(LED_PIN, HIGH);
95
+
96
+    startPlayback();
97
+
98
+    loop_start = 0; 
99
+    loop_length = sound_length;
100
+    gate = false;
101
+    gate_prev = false;
102
+    is_playing = false;
103
+    time_since_gate = 0;
104
+}
105
+
106
+// This is called at 8000 Hz to load the next sample.
107
+ISR(TIMER1_COMPA_vect)
108
+{
109
+
110
+	if (gate == true && gate_prev == false)
111
+	
112
+	  {
113
+		time_since_gate = 0;
114
+		sample = loop_start;
115
+		is_playing = true;
116
+  	}
117
+
118
+	gate_prev = gate;
119
+	time_since_gate++;
120
+
121
+	if (time_since_gate >= 8000 * 20)
122
+	{
123
+
124
+		is_playing = false;
125
+	}
126
+
127
+	if (is_playing)
128
+	{
129
+
130
+	    OCR2A = pgm_read_byte(&sound_data[sample % sound_length]);
131
+	    sample++;
132
+
133
+	    if(sample >= index_bounds)
134
+	    {
135
+	        sample = loop_start;
136
+	    }
137
+	    else if((sample < loop_start) &&
138
+	            (sample >= loop_overflow))
139
+	    {
140
+	        sample = loop_start;}
141
+	} 
142
+	
143
+	else 
144
+	{
145
+  OCR2A = pgm_read_byte(&sound_data[0]);
146
+	}
147
+}
148
+
149
+void loop()
150
+
151
+{  
152
+  gate = analogRead(A3) << 9;
153
+  if (gate && !triggered)
154
+  {
155
+    loop_start = random(0,1023) / 1024.0 * random(100,11461);  
156
+  delay(500); 
157
+  loop_length = (analogRead(KNOB_2) + 1) / 1024.0 * sound_length;
158
+  OCR1A = (512.0 / (analogRead(KNOB_3) + 1)) * (F_CPU / SAMPLE_RATE);
159
+	gate = analogRead(3) ;
160
+
161
+	triggered=true;
162
+  }
163
+
164
+  else if(!gate && triggered)
165
+  {triggered=false;}
166
+
167
+  
168
+//  can be up to 2x sound length. the more you know.
169
+    index_bounds = loop_start + loop_length;
170
+    //Serial.println(loop_length);
171
+//  this will set the overflow length. take the loop overflow into account when checking the loop boundaries
172
+    if(index_bounds > sound_length)
173
+    {
174
+        loop_overflow = index_bounds - sound_length;
175
+    }
176
+    else
177
+    {
178
+        loop_overflow = 0;
179
+    }
180
+}

+ 143
- 0
INPUT_OUTPUT/Flakes/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
+}

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


Loading…
Cancel
Save