-
Notifications
You must be signed in to change notification settings - Fork 1
/
opm_voice_collector.c
93 lines (85 loc) · 2.49 KB
/
opm_voice_collector.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "opm_voice_collector.h"
void opm_voice_collector_init(struct opm_voice_collector *collector) {
memset(collector, 0, sizeof(*collector));
}
void opm_voice_collector_push_voice(struct opm_voice_collector *collector, struct opm_voice_collector_voice *voice, int chan, int midi_note) {
opm_voice_normalize(&voice->voice);
int existing_voice = -1;
for(int i = 0; i < collector->num_voices; i++) {
struct opm_voice_collector_voice *v = collector->voices + i;
if(!opm_voice_compare(&voice->voice, &v->voice)) {
existing_voice = i;
break;
}
}
if(existing_voice >= 0) {
struct opm_voice_collector_voice *v = &collector->voices[existing_voice];
if(chan >= 0) v->chan_used_mask |= 1 << chan;
if(midi_note >= 0) v->note_usage[midi_note & 0x7f]++;
return;
}
collector->num_voices++;
collector->voices = realloc(collector->voices, collector->num_voices * sizeof(struct opm_voice_collector_voice));
if(!collector->voices) {
fprintf(stderr, "Could not reallocate %d OPM voices\n", collector->num_voices);
return;
}
if(chan >= 0) voice->chan_used_mask |= 1 << chan;
if(midi_note >= 0) voice->note_usage[midi_note & 0x7f]++;
memcpy(&collector->voices[collector->num_voices - 1], voice, sizeof(*voice));
}
void opm_voice_collector_voice_dump(struct opm_voice_collector_voice *v) {
printf(
"fb=%d connect=%d chan_used_mask=%c%c%c%c%c%c%c%c\n",
v->voice.rl_fb_con >> 3 & 0x07,
v->voice.rl_fb_con & 0x07,
v->chan_used_mask & 1 ? '1' : '0',
v->chan_used_mask & 2 ? '1' : '0',
v->chan_used_mask & 4 ? '1' : '0',
v->chan_used_mask & 8 ? '1' : '0',
v->chan_used_mask & 16 ? '1' : '0',
v->chan_used_mask & 32 ? '1' : '0',
v->chan_used_mask & 64 ? '1' : '0',
v->chan_used_mask & 128 ? '1' : '0'
);
printf("OP AR D1R D2R RR D1L TL MUL DT1 DT2 KS AME\n");
for(int j = 0; j < 4; j++) {
struct opm_voice_operator *o = v->voice.operators + j;
printf(
" %d"
" %2d"
" %2d"
" %2d"
" %2d"
" %2d"
" %3d"
" %2d"
" %2d"
" %d"
" %d"
" %d"
"\n",
j,
o->ks_ar & 0x1f,
o->ams_d1r & 0x1f,
o->dt2_d2r & 0x1f,
o->d1l_rr & 0x0f,
o->d1l_rr >> 4,
o->tl,
o->dt1_mul & 0x0f,
o->dt1_mul >> 4 & 0x07,
o->dt2_d2r >> 6,
o->ks_ar >> 6,
o->ams_d1r >> 7
);
}
}
void opm_voice_collector_dump_voices(struct opm_voice_collector *collector) {
for(int i = 0; i < collector->num_voices; i++) {
printf("Voice %d\n", i);
opm_voice_collector_voice_dump(collector->voices + i);
}
}