Nekobee
[mirrors/Programs.git] / arduino / Nekobee_test_blemidi / Nekobee_test_blemidi.ino
1 #include <nekobee.h>
2 #include <nekobee_voice.h>
3 //#include <nekobee_voice_render.h>
4 #include <nekobee_synth.h>
5 #include <nekobee_types.h>
6 #include <esp_task_wdt.h>
7 #include "driver/i2s.h"
8 #include "freertos/queue.h"
9
10
11 #include <BLEMidi.h>
12 //void connected();
13 //void disconnected();
14
15
16 nekobee_synth_t fSynth;
17
18 #define SAMPLE_RATE 30000
19 #define BUF_LEN XSYNTH_NUGGET_SIZE //512
20
21 void nekobee_handle_raw_event(nekobee_synth_t* const synth, const uint8_t size, const uint8_t* const data)
22 {
23 if (size != 3)
24 return;
25
26 switch (data[0] & 0xf0)
27 {
28 case 0x80:
29 nekobee_synth_note_off(synth, data[1], data[2]);
30 break;
31 case 0x90:
32 if (data[2] > 0)
33 nekobee_synth_note_on(synth, data[1], data[2]);
34 else
35 nekobee_synth_note_off(synth, data[1], 64); /* shouldn't happen, but... */
36 break;
37 case 0xB0:
38 nekobee_synth_control_change(synth, data[1], data[2]);
39 break;
40 default:
41 break;
42 }
43 }
44
45
46 static const i2s_port_t i2s_num = I2S_NUM_0; // i2s port number
47
48
49 static const i2s_config_t i2s_config = {
50 .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX /*| I2S_MODE_DAC_BUILT_IN*/ ),
51 .sample_rate = SAMPLE_RATE,
52 .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT, // only the top 8 bits will actually be used by the internal DAC, but using 8 bits stra>
53 .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, // always use stereo output. mono seems to be buggy, and the overhead is insignifcant o>
54 .communication_format = (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_LSB), // this appears to be the correct setting>
55 .intr_alloc_flags = 0, // default interrupt priority
56 .dma_buf_count = 4, // 8*128 bytes of buffer corresponds to 256 samples (2 channels, see above, 2 bytes per sample per channel)
57 .dma_buf_len = BUF_LEN,
58 .use_apll = false
59 };
60
61 static const i2s_pin_config_t pin_config = {
62 .bck_io_num = 26,
63 .ws_io_num = 25,
64 .data_out_num = 17,
65 .data_in_num = I2S_PIN_NO_CHANGE
66 };
67
68 uint8_t midii=0, midichar, mididata[8];
69
70
71 void synth_task( void * pvParameters ) {
72
73
74
75 i2s_driver_install(i2s_num, &i2s_config, 0, NULL); //install and start i2s driver
76
77 //i2s_set_pin(i2s_num, NULL); //for internal DAC, this will enable both of the internal channels
78 i2s_set_pin(i2s_num, &pin_config);
79
80 //You can call i2s_set_dac_mode to set built-in DAC output mode.
81 //i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN);
82
83 //i2s_set_sample_rates(i2s_num, SAMPLE_RATE); //set sample rates
84
85 //i2s_driver_uninstall(i2s_num); //stop & destroy i2s driver
86
87 //i2s_adc_disable(i2s_num);
88
89
90
91
92
93
94 float *out;
95 out = (float*)malloc(sizeof(float)*BUF_LEN);
96 int32_t *outdma;
97 outdma = (int32_t*)malloc(sizeof(int32_t)*BUF_LEN*8);
98
99 int i = 0, n=60, v=60;
100 //nekobee_synth_note_on(&fSynth, n , v);
101 while(1) {
102 if(i==0) {
103 esp_task_wdt_reset();
104 //nekobee_synth_note_off(&fSynth, n , v);
105 n = 16+rand()%63;
106 v = 16+rand()%63;
107 n = rand()%127;
108 v = rand()%127;
109 //nekobee_synth_note_on(&fSynth, n , v);
110 }
111
112
113
114
115 while(Serial.available()) {
116
117 midichar = Serial.read();
118 if(midichar & 0b10000000) {
119 midii = 0;
120 } else if(midii == 0) continue;
121 mididata[midii] = midichar;
122 midii++;
123
124 if(midii >= 3) {
125 nekobee_handle_raw_event(&fSynth, midii, mididata);
126 midii = 0;
127 }
128 }
129
130 nekobee_synth_render_voices(&fSynth, out, BUF_LEN, 1);
131 for(int i = 0; i < BUF_LEN; i++) {
132 outdma[i*2] = outdma[(i*2)+1] = lrintf(out[i] * 2147483647); //((127)+round((out[i]*120.0)))*255;
133 }
134
135 size_t bytes_written;
136 i2s_write(i2s_num, outdma, BUF_LEN*4*2, &bytes_written, portMAX_DELAY);
137
138 //printf("%d\t%f\n", outdma[0], out[0]);
139 //fwrite (out, sizeof(float)*BUF_LEN, 1, stdout);
140 //Serial.println(out[0]);
141 //Serial.println(uxTaskGetStackHighWaterMark(NULL));
142 //Serial.printf("%d\n", outdma[0]);
143 //mgos_msleep(30);
144 //delay(1);
145 i++; if(i>400) i=0;
146 }
147
148 }
149
150
151 uint8_t bn=0, bv=0;
152
153 void onNoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
154 {
155 nekobee_synth_note_off(&fSynth, bn , bv);
156 nekobee_synth_note_on(&fSynth, note , velocity);
157 bn = note, bv = velocity;
158 Serial.print("on");
159 Serial.println(note);
160 }
161
162 void onNoteOff(uint8_t channel, uint8_t note, uint8_t velocity)
163 {
164 nekobee_synth_note_off(&fSynth, note , velocity);
165 Serial.print("off");
166 Serial.println(note);
167 }
168
169
170
171
172 void setup() {
173 Serial.begin(115200);
174
175 nekobee_init_tables();
176
177 // init synth
178 fSynth.sample_rate = SAMPLE_RATE;
179 fSynth.deltat = 1.0f / (float)SAMPLE_RATE;
180 fSynth.nugget_remains = 0;
181
182 fSynth.note_id = 0;
183 fSynth.polyphony = XSYNTH_DEFAULT_POLYPHONY;
184 fSynth.voices = XSYNTH_DEFAULT_POLYPHONY;
185 fSynth.monophonic = XSYNTH_MONO_MODE_ONCE;
186 fSynth.glide = 0;
187 fSynth.last_noteon_pitch = 0.0f;
188 fSynth.vcf_accent = 0.0f;
189 fSynth.vca_accent = 0.0f;
190
191 for (int i=0; i<8; ++i)
192 fSynth.held_keys[i] = -1;
193
194 fSynth.voice = nekobee_voice_new();
195 fSynth.voicelist_mutex_grab_failed = 0;
196 //pthread_mutex_init(&fSynth.voicelist_mutex, nullptr);
197
198 fSynth.channel_pressure = 0;
199 fSynth.pitch_wheel_sensitivity = 0;
200 fSynth.pitch_wheel = 0;
201
202 for (int i=0; i<128; ++i)
203 {
204 fSynth.key_pressure[i] = 0;
205 fSynth.cc[i] = 0;
206 }
207 fSynth.cc[7] = 127; // full volume
208
209 fSynth.mod_wheel = 1.0f;
210 fSynth.pitch_bend = 1.0f;
211 fSynth.cc_volume = 1.0f;
212
213 // Default values
214 /*
215 fParams.waveform = 0.0f;
216 fParams.tuning = 0.0f;
217 fParams.cutoff = 25.0f;
218 fParams.resonance = 25.0f;
219 fParams.envMod = 50.0f;
220 fParams.decay = 75.0f;
221 fParams.accent = 25.0f;
222 fParams.volume = 75.0f;
223 fParams.bypass = false;
224 */
225
226 // Internal stuff
227 fSynth.waveform = 0.0f;
228 fSynth.tuning = 1.0f;
229 fSynth.cutoff = 5.0f;
230 fSynth.resonance = 0.8f;
231 fSynth.envmod = 0.3f;
232 fSynth.decay = 0.0002f;
233 fSynth.accent = 0.3f;
234 fSynth.volume = 0.75f;
235
236 //nekobee_synth_render_voices(&fSynth, NULL, 0, 1); //Update controls
237 nekobee_synth_init_controls(&fSynth);
238 //nekobee_synth_note_on(&fSynth, 80, 128);
239
240 Serial.println("READY");
241
242 xTaskCreate(&synth_task, "blinking_led", 5*configMINIMAL_STACK_SIZE, NULL, 0, NULL);
243
244
245
246 BLEMidiServer.begin("NekoMIDI");
247 BLEMidiServer.setOnConnectCallback([](){ // To show how to make a callback with a lambda function
248 Serial.println("Connected");
249 });
250 BLEMidiServer.setOnDisconnectCallback([](){ // To show how to make a callback with a lambda function
251 Serial.println("Disconnected");
252 });
253 BLEMidiServer.setNoteOnCallback(onNoteOn);
254 BLEMidiServer.setNoteOffCallback(onNoteOff);
255 //BLEMidiServer.setControlChangeCallback(onControlChange);
256 //BLEMidiServer.enableDebugging();
257
258 }
259
260
261
262 int i=0;
263 void loop() {
264 /*
265 void
266 nekobee_voice_render(nekobee_synth_t *synth, nekobee_voice_t *voice,
267 float *out, unsigned long sample_count,
268 int do_control_update)
269
270 void nekobee_synth_render_voices(nekobee_synth_t *synth, float *out,
271 unsigned long sample_count,
272 int do_control_update);
273 */
274
275 //nekobee_synth_render_voices(&fSynth, outbuffer, len, update_controls);
276
277 //float out;
278
279 //nekobee_synth_render_voices(&fSynth, &out, 1, 0);
280
281 //Serial.println(out);
282 //Serial.println(i++);
283 delay(30);
284
285
286
287 //fSynth.waveform = 0.0f;
288 //fSynth.tuning = 1.0f;
289
290 int adc2 = 0;
291 if(adc2_get_raw(ADC2_CHANNEL_2, ADC_WIDTH_12Bit, &adc2) == ESP_OK)
292 fSynth.cutoff = ((float)adc2)/(4095.0f/40.0f);
293 if(adc2_get_raw(ADC2_CHANNEL_0, ADC_WIDTH_12Bit, &adc2) == ESP_OK)
294 fSynth.resonance = ((float)adc2)/(4095.0f);
295
296 fSynth.envmod = ((float)analogRead(35))/4095.0f;
297
298 //fSynth.decay = 0.0002f;
299 fSynth.decay = ((float)analogRead(34))/(4095.0f/0.0004f);
300 fSynth.accent = ((float)analogRead(36))/4095.0f;
301 fSynth.volume = ((float)analogRead(39))/4095.0f;
302
303 /*
304 Serial.print("SYNTH:");
305 Serial.print("\tCUT:"); Serial.print(fSynth.cutoff);
306 Serial.print("\tRES:"); Serial.print(fSynth.resonance);
307 Serial.print("\tENV:"); Serial.print(fSynth.envmod);
308 Serial.print("\tDEC:"); Serial.printf("%.7f", fSynth.decay);
309 Serial.print("\tACC:"); Serial.print(fSynth.accent);
310 Serial.print("\tVOL:"); Serial.print(fSynth.volume);
311 Serial.println();
312 */
313
314 }
This page took 0.385495 seconds and 4 git commands to generate.