summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/midi.c227
-rw-r--r--src/synth_engine.h2
2 files changed, 129 insertions, 100 deletions
diff --git a/src/midi.c b/src/midi.c
index 2ba97d6..8597100 100644
--- a/src/midi.c
+++ b/src/midi.c
@@ -6,99 +6,132 @@
#include <stdlib.h>
#include <string.h>
+void midi_pitch_bend(synth_t *synth, int channel, int value) {
+ (void)channel;
+
+ float pitch;
+ float semitones = 2;
+ if (value == 0) {
+ pitch = 1;
+ } else if (value > 0) {
+ pitch = 1 + ((float)value / 8191) * semitones * pow(2.0, 1.0 / 12.0) / 12;
+ } else {
+ pitch = 1 + ((float)value / 8192) * semitones * pow(2.0, 1.0 / 12.0) / 12;
+ }
+ synth->cc_pitch.target = pitch;
+ /* cc_step(synth->cc_pitch, 1); */
+}
+
+void midi_cc(synth_t *synth, int channel, int controller, int value) {
+ (void)channel;
+
+ int x = value < 64 ? 1 : -1;
+ switch (controller) {
+ case 0:
+ cc_step(&synth->cc_adsr_a, x);
+ //synth->adsr.a = synth->adsr.a + (x * 0.01);
+ //synth->freq_offset = synth->freq_offset + (x*5);
+ //cc_step(&synth->cc_cutoff, x);
+ break;
+ case 1:
+ cc_step(&synth->cc_adsr_d, x);
+ //synth->adsr.d = synth->adsr.d + (x * 0.01);
+ break;
+ case 2:
+ cc_step(&synth->cc_adsr_s, x);
+ //synth->adsr.s = synth->adsr.s + (x * 0.01);
+ break;
+ case 3:
+ cc_step(&synth->cc_adsr_r, x);
+ //synth->adsr.r = synth->adsr.r + (x * 0.01);
+ break;
+ case 4:
+ cc_step(&synth->cc_cutoff, x);
+ //synth->cutoff = synth->cutoff + (x * (10 * log10(synth->cutoff)));
+ break;
+ case 5:
+ cc_step(&synth->cc_resonance, x);
+ break;
+ case 6:
+ //cc_step(&synth->cc_pitch, x);
+ cc_step(&synth->cc_lfo_freq, x);
+ //synth->lfo.freq = synth->lfo.freq + (x * 0.1);
+ break;
+ case 7:
+ //cc_reset(&synth->cc_pitch);
+ cc_step(&synth->cc_lfo_amp, x);
+ //synth->lfo.amp = synth->lfo.amp + (x * 0.002);
+ break;
+ case 8:
+ //cc_reset(&synth->cc_pitch);
+ synth->wvt_pos = value;
+ //synth->lfo.amp = synth->lfo.amp + (x * 0.002);
+ break;
+ case 28:
+ if (synth->geni > 0) synth->geni--;
+ break;
+ case 29:
+ if (synth->geni < 6) synth->geni++;
+ break;
+ default:
+ break;
+ }
+}
+
+void midi_note_off(synth_t *synth, int channel, int note, int velocity) {
+ (void)channel;
+ (void)velocity;
+
+ synth->midi_note[note].noteOff = Pa_GetStreamTime(synth->stream);
+ synth->midi_note[note].noteOffSample = synth->midi_note[note].elapsed;
+}
+
+void midi_note_on(synth_t *synth, int channel, int note, int velocity) {
+ int flag = 1;
+
+ synth->midi_note[note].freq = notes[note % 12][(note / 12) % 8];
+ synth->midi_note[note].channel = channel;
+ synth->midi_note[note].noteOn = Pa_GetStreamTime(synth->stream);
+ synth->midi_note[note].noteOff = 0;
+ synth->midi_note[note].velocity = (float)velocity / 127.0;
+ synth->midi_note[note].elapsed = 0;
+ synth->midi_note[note].active = 1;
+ for (int i = 0; i < synth->midi_active_n; i++) {
+ if (synth->midi_active[i] == &synth->midi_note[note]) {
+ flag = 0;
+ }
+ }
+ if (flag) {
+ synth->midi_active[synth->midi_active_n++] = &synth->midi_note[note];
+ }
+ synth->active = 1;
+
+}
+
void midi_decode(uint32_t msg, synth_t * synth) {
- // printf("MIDI message: 0x%X\n", msg);
+ //printf("MIDI message: 0x%X\n", msg);
uint8_t status = msg;
uint8_t data1 = (msg >> 8) & 0xFF;
uint8_t data2 = (msg >> 16) & 0xFF;
uint8_t channel = (status & 0x0F) + 1; // convert to human
uint8_t message = status >> 4;
- int flag = 1;
-
switch (message) {
case 0x08:
printf("Note Off: channel=%d, note=%d, velocity=%d\n", channel, data1, data2);
- synth->midi_note[data1].noteOff = Pa_GetStreamTime(synth->stream);
- synth->midi_note[data1].noteOffSample = synth->midi_note[data1].elapsed;
+ midi_note_off(synth, channel, data1, data2);
break;
case 0x09:
printf("Note On: channel=%d, note=%d, velocity=%d\n", channel, data1, data2);
- //synth->midi_note[i].n = -1;
- synth->midi_note[data1].freq = notes[data1 % 12][(data1 / 12) % 8];
- synth->midi_note[data1].channel = channel;
- synth->midi_note[data1].noteOn = Pa_GetStreamTime(synth->stream);
- synth->midi_note[data1].noteOff = 0;
- synth->midi_note[data1].velocity = (float)data2 / 127.0;
- synth->midi_note[data1].elapsed = 0;
- synth->midi_note[data1].active = 1;
- for (int i = 0; i < synth->midi_active_n; i++) {
- if (synth->midi_active[i] == &synth->midi_note[data1]) {
- flag = 0;
- }
- }
- if (flag) {
- synth->midi_active[synth->midi_active_n++] = &synth->midi_note[data1];
- }
- synth->active = 1;
+ midi_note_on(synth, channel, data1, data2);
break;
case 0x0A:
printf("Aftertouch: channel=%d, note=%d, pressure=%d\n", channel, data1, data2);
break;
case 0x0B:
- printf("Control Change: channel=%d, controller=%d, value=%d\n", channel, data1, data2);
- int x = data2 < 64 ? 1 : -1;
- int val;
- switch (data1) {
- case 0:
- cc_step(&synth->cc_adsr_a, x);
- //synth->adsr.a = synth->adsr.a + (x * 0.01);
- //synth->freq_offset = synth->freq_offset + (x*5);
- //cc_step(&synth->cc_cutoff, x);
- break;
- case 1:
- cc_step(&synth->cc_adsr_d, x);
- //synth->adsr.d = synth->adsr.d + (x * 0.01);
- break;
- case 2:
- cc_step(&synth->cc_adsr_s, x);
- //synth->adsr.s = synth->adsr.s + (x * 0.01);
- break;
- case 3:
- cc_step(&synth->cc_adsr_r, x);
- //synth->adsr.r = synth->adsr.r + (x * 0.01);
- break;
- case 4:
- cc_step(&synth->cc_cutoff, x);
- //synth->cutoff = synth->cutoff + (x * (10 * log10(synth->cutoff)));
- break;
- case 5:
- cc_step(&synth->cc_resonance, x);
- break;
- case 6:
- //cc_step(&synth->cc_pitch, x);
- cc_step(&synth->cc_lfo_freq, x);
- //synth->lfo.freq = synth->lfo.freq + (x * 0.1);
- break;
- case 7:
- //cc_reset(&synth->cc_pitch);
- cc_step(&synth->cc_lfo_amp, x);
- //synth->lfo.amp = synth->lfo.amp + (x * 0.002);
- break;
- case 8:
- //cc_reset(&synth->cc_pitch);
- synth->wvt_pos = data2;
- //synth->lfo.amp = synth->lfo.amp + (x * 0.002);
- break;
- case 28:
- if (synth->geni > 0) synth->geni--;
- break;
- case 29:
- if (synth->geni < 6) synth->geni++;
- break;
- default:
- break;
- }
+ printf("Control Change: channel=%d, controller=%d, value=%d\n", channel,
+ data1, data2);
+ midi_cc(synth, channel, data1, data2);
break;
case 0x0C:
printf("Program Change: channel=%d, program=%d\n", channel, data1);
@@ -107,19 +140,8 @@ void midi_decode(uint32_t msg, synth_t * synth) {
printf("Channel Pressure: channel=%d, pressure=%d\n", channel, data1);
break;
case 0x0E:
- val = ((data2 << 7) | data1) - 8192;
- printf("Pitch Bend: channel=%d, value=%d\n", channel, val);
- float pitch;
- float semitones = 2;
- if (val == 0) {
- pitch = 1;
- } else if (val > 0) {
- pitch = 1 + ((float)val / 8191) * semitones * pow(2.0, 1.0 / 12.0) / 12;
- } else {
- pitch = 1 + ((float)val / 8192) * semitones * pow(2.0, 1.0 / 12.0) / 12;
- }
- synth->cc_pitch.target = pitch;
- /* cc_step(synth->cc_pitch, 1); */
+ printf("Pitch Bend: channel=%d, value=%d\n", channel, ((data2 << 7) | data1) - 8192);
+ midi_pitch_bend(synth, channel, ((data2 << 7) | data1) - 8192);
break;
default:
printf("Unknown MIDI message\n");
@@ -136,7 +158,7 @@ midiCallback(PtTimestamp timestamp, void *userData) {
if (!m->stream) return;
if (!enable) return;
- // if (!Pm_Poll(m->stream)) return;
+ //if (!Pm_Poll(m->stream)) return;
PmEvent buf;
int e = Pm_Read(m->stream, &buf, 1);
@@ -157,7 +179,10 @@ init_midi(midi_t *m, synth_t *synth)
m->stream = NULL;
m->synth = synth;
- Pm_Initialize();
+ PmError err = Pm_Initialize();
+ if (err != pmNoError) {
+ fprintf(stdout, "Pm Error: %s\n", Pm_GetErrorText(err));
+ }
//printf("midi devs: %d\n", Pm_CountDevices());
const PmDeviceInfo *info;
@@ -167,20 +192,24 @@ init_midi(midi_t *m, synth_t *synth)
if (!info->input) {
continue;
}
- //printf("%d: %s [input: %d output: %d opened: %d is_virt:%d] (interf: %s) -- %d\n", i, info->name, info->input, info->output, info->opened, info->is_virtual, info->interf, Pm_GetDefaultInputDeviceID());
- if (!strcmp(synth->midi_device.name, info->name) && !info->input) break;
+ printf("%d: %s [input: %d output: %d opened: %d is_virt:%d] (interface: %s)\n", i, info->name, info->input, info->output, info->opened, info->is_virtual, info->interf);
+ if (0 == strcmp(synth->midi_device.name, info->name))
+ break;
}
printf("Selected device: %s [input: %d output: %d opened: %d is_virt:%d] (interf: %s)\n", info->name, info->input, info->output, info->opened, info->is_virtual, info->interf);
Pt_Start(1, midiCallback, m);
- Pm_OpenInput(&(m->stream),
- i, //Pm_GetDefaultInputDeviceID(),
- NULL,
- 128,
- NULL,
- NULL);
+ err = Pm_OpenInput(&(m->stream),
+ i, //Pm_GetDefaultInputDeviceID(),
+ NULL,
+ 128,
+ NULL,
+ NULL);
+ if (err != pmNoError) {
+ fprintf(stdout, "Pm Error: %s\n", Pm_GetErrorText(err));
+ }
enable = 1;
}
@@ -219,7 +248,7 @@ get_midi_devices()
strcat(ret, ";");
}
ret[strlen(ret) - 1] = '\0';
-
+
return ret;
}
diff --git a/src/synth_engine.h b/src/synth_engine.h
index f771073..e198c22 100644
--- a/src/synth_engine.h
+++ b/src/synth_engine.h
@@ -47,7 +47,7 @@ typedef struct midi_note_t {
int active;
} midi_note_t;
-typedef struct {
+typedef struct synth_viz {
int spectrum_enabled;
int wave_enabled;
int adsr_enabled;