36#include <libFreeWRL.h>
38#include "../vrml_parser/Structs.h"
39#include "../main/headers.h"
41#include "LinearAlgebra.h"
43#include "../../libmidi/libmidi.h"
45typedef struct icset {
int p;
int d;
int ld;
int n;
int s;
int ls; }
icset;
49 Stack* midi_context_stack;
50 Stack* midi_parent_stack;
52void* Component_MIDI_constructor() {
57void Component_MIDI_init(
struct tComponent_MIDI* t) {
62 t->prv = Component_MIDI_constructor();
64 ppComponent_MIDI p = (ppComponent_MIDI)t->prv;
65 p->midi_context_stack = newStack(
int);
66 stack_push(
int, p->midi_context_stack, 0);
67 p->midi_parent_stack = newStack(
icset);
68 icset aps = { 0, 0, 0, 0, 0, 0 };
69 stack_push(
icset, p->midi_parent_stack, aps);
73void Component_MIDI_clear(
struct tComponent_MIDI* t) {
74 ppComponent_MIDI p = (ppComponent_MIDI)t->prv;
113void register_visit_check(
struct X3D_Node* node);
114void visit_check_midi(
struct X3D_Node* node,
unsigned int iframe) {
116 if (srep->icontext) {
117 if (iframe == srep->iframe) {
118 libmidi_resumeContext0(srep->icontext);
124 libmidi_pauseContext0(srep->icontext);
130void push_midi_context(
int midi_context) {
131 ppComponent_MIDI p = (ppComponent_MIDI)gglobal()->Component_MIDI.prv;
132 stack_push(
int, p->midi_context_stack, midi_context);
134void create_and_push_midi_context(
struct X3D_Node* node) {
139 if (!srep->icontext) {
140 int jcontext = peek_midi_context();
142 jcontext = libmidi_createContext0();
144 srep->icontext = jcontext;
145 register_visit_check(node);
147 push_midi_context(srep->icontext);
149void pop_midi_context() {
150 ppComponent_MIDI p = (ppComponent_MIDI)gglobal()->Component_MIDI.prv;
151 stack_pop(
int, p->midi_context_stack);
153int peek_midi_context() {
154 ppComponent_MIDI p = (ppComponent_MIDI)gglobal()->Component_MIDI.prv;
155 return stack_top(
int, p->midi_context_stack);
157void push_midi_parent(
int inode) {
158 ppComponent_MIDI p = (ppComponent_MIDI)gglobal()->Component_MIDI.prv;
159 icset aps = { 0, 0, 0, 0, 0, 0 };
163 stack_push(
icset, p->midi_parent_stack, aps);
165void pop_midi_parent() {
166 ppComponent_MIDI p = (ppComponent_MIDI)gglobal()->Component_MIDI.prv;
167 stack_pop(
icset, p->midi_parent_stack);
169icset peek_midi_parent() {
170 ppComponent_MIDI p = (ppComponent_MIDI)gglobal()->Component_MIDI.prv;
171 return stack_top(
icset, p->midi_parent_stack);
175 if (!srep->connections) srep->connections = newStack(
ivec3);
177 for (
int i = 0; i < vectorSize(srep->connections); i++) {
178 icset conn = vector_get(
icset, srep->connections, i);
179 if (conn.p == iparent.p && conn.n == iparent.n && conn.d == iparent.d && conn.s == iparent.s)
183 stack_push(
icset, srep->connections, iparent);
185 return 1 - duplicate;
188 if (iparent.d == iparent.ld && iparent.s == iparent.ls)
return 0;
189 if (!srep->connections)
return 0;
191 for (
int i = 0; i < vectorSize(srep->connections); i++) {
192 icset conn = vector_get(
icset, srep->connections, i);
194 if (conn.p == iparent.p && conn.n == iparent.n) {
195 if (iparent.d != iparent.ld && conn.d == iparent.ld)
196 if (conn.s == iparent.s || conn.s == iparent.ls) found_old = i;
197 if (iparent.s != iparent.ls && conn.s == iparent.ls)
198 if (conn.d == iparent.d || conn.d == iparent.ld) found_old = i;
201 if (found_old > -1) {
202 vector_remove_elem(
icset, srep->connections, found_old);
204 return found_old > -1 ? 1 : 0;
208 if (midinewconnect(srep, iparent)) {
209 libmidi_connect(srep->icontext, iparent);
210 libmidi_print_connections();
212 if (mididisconnect(srep, iparent)) {
213 libmidi_disconnect(srep->icontext, iparent);
214 libmidi_print_connections();
219 struct X3D_MidiRep* srep = getMidiRep(X3D_NODE(node));
220 srep->iframe = gglobal()->Mainloop.iframe;
222 icset iparent = peek_midi_parent();
227 int icontext = peek_midi_context();
228 libmidi_updateNode3(icontext, iparent, anode);
230 node->_ichange = node->_change;
234 iparent.n = srep->inode;
236 update_midi_connections(srep, iparent);
240 LOADER_INITIAL_STATE = 0,
241 LOADER_REQUEST_RESOURCE,
242 LOADER_FETCHING_RESOURCE,
249 resource_item_t* res;
252 switch (node->__loadstatus) {
253 case LOADER_INITIAL_STATE:
255 if (node->url.n == 0) {
256 node->__loadstatus = LOADER_STABLE;
259 res = resource_create_multi(&(node->url));
260 res->media_type = resm_midi;
261 node->__loadstatus = LOADER_REQUEST_RESOURCE;
262 node->__loadResource = res;
266 case LOADER_REQUEST_RESOURCE:
267 res = node->__loadResource;
268 resource_identify(node->_parentResource, res);
271 res->actions = resa_download | resa_load;
272 resitem_enqueue(ml_new(res));
274 node->__loadstatus = LOADER_FETCHING_RESOURCE;
277 case LOADER_FETCHING_RESOURCE:
278 res = node->__loadResource;
283 if (res->status == ress_loaded) {
284 node->__loadstatus = LOADER_STABLE;
286 of = res->openned_files;
291 node->__loadstatus = LOADER_LOADED;
292 node->__blob.p = (
int*)of->fileData;
293 node->__blob.n = of->fileDataSize;
295 else if ((res->status == ress_failed) || (res->status == ress_invalid)) {
297 printf(
"resource failed to load\n");
298 node->__loadstatus = LOADER_STABLE;
303 case LOADER_PROCESSING:
304 res = node->__loadResource;
307 printf(
"res complete %d\n", res->complete);
309 if (res->status == ress_parsed) {
310 node->__loadstatus = LOADER_LOADED;
313 node->__loadstatus = LOADER_STABLE;
321 case LOADER_COMPILED:
324 if (node->__loadstatus == LOADER_STABLE || node->__loadstatus == LOADER_LOADED)
331 if (node->__loadstatus != LOADER_LOADED)
return;
333 struct X3D_MidiRep* srep = getMidiRep(X3D_NODE(node));
334 srep->iframe = gglobal()->Mainloop.iframe;
336 icset iparent = peek_midi_parent();
337 if (!srep->ibuffer) {
339 printf(
"loaded .mid file size = %d\n", node->__blob.n);
340 srep->ibuffer = node->__blob.n;
341 int icontext = peek_midi_context();
342 libmidi_updateNode3(icontext, iparent, anode);
348 int icontext = peek_midi_context();
349 libmidi_updateNode3(icontext, iparent, anode);
351 node->_ichange = node->_change;
355 iparent.n = srep->inode;
357 update_midi_connections(srep, iparent);
362 icset have_parent = peek_midi_parent();
363 create_and_push_midi_context(anode);
364 struct X3D_MidiRep* srep = getMidiRep(X3D_NODE(node));
365 libmidi_updateNode3(peek_midi_context(), have_parent, anode);
366 if (!have_parent.p) {
367 push_midi_parent(srep->inode);
368 icset junk = peek_midi_parent();
370 srep->iframe = gglobal()->Mainloop.iframe;
371 if (node->children.n) {
372 for (
int i = 0; i < node->children.n; i++)
373 render_node(X3D_NODE(node->children.p[i]));
383 icset have_parent = peek_midi_parent();
384 create_and_push_midi_context(anode);
385 struct X3D_MidiRep* srep = getMidiRep(X3D_NODE(node));
386 libmidi_updateNode3(peek_midi_context(), have_parent, anode);
387 if (!have_parent.p) {
388 push_midi_parent(srep->inode);
390 srep->iframe = gglobal()->Mainloop.iframe;
391 if (node->children.n) {
392 for (
int i = 0; i < node->children.n; i++)
393 render_node(X3D_NODE(node->children.p[i]));
402 if (node->children.n) {
403 for (
int i = 0; i < node->children.n; i++)
404 render_node(X3D_NODE(node->children.p[i]));
410 icset have_parent = peek_midi_parent();
411 create_and_push_midi_context(anode);
412 struct X3D_MidiRep* srep = getMidiRep(X3D_NODE(node));
413 libmidi_updateNode3(peek_midi_context(), have_parent, anode);
414 if (!have_parent.p) {
415 push_midi_parent(srep->inode);
417 srep->iframe = gglobal()->Mainloop.iframe;
418 if (node->children.n) {
419 for (
int i = 0; i < node->children.n; i++)
420 render_node(X3D_NODE(node->children.p[i]));
427 struct X3D_MidiRep* srep = getMidiRep(X3D_NODE(node));
428 srep->iframe = gglobal()->Mainloop.iframe;
430 icset iparent = peek_midi_parent();
432 if (node->_ichange != node->_change) {
434 int icontext = peek_midi_context();
435 libmidi_updateNode3(icontext, iparent, anode);
438 iparent.n = srep->inode;
440 update_midi_connections(srep, iparent);
444 icset iparent = peek_midi_parent();
445 create_and_push_midi_context(anode);
446 struct X3D_MidiRep* srep = getMidiRep(X3D_NODE(node));
447 libmidi_updateNode3(peek_midi_context(), iparent, anode);
449 push_midi_parent(srep->inode);
451 srep->iframe = gglobal()->Mainloop.iframe;
452 if (node->children.n) {
453 push_midi_parent(srep->inode);
454 for (
int i = 0; i < node->children.n; i++)
455 render_node(X3D_NODE(node->children.p[i]));
458 iparent.n = srep->inode;
460 update_midi_connections(srep, iparent);
468 icset iparent = peek_midi_parent();
469 create_and_push_midi_context(anode);
470 struct X3D_MidiRep* srep = getMidiRep(X3D_NODE(node));
471 libmidi_updateNode3(peek_midi_context(), iparent, anode);
473 push_midi_parent(srep->inode);
475 srep->iframe = gglobal()->Mainloop.iframe;
476 if (node->children.n) {
477 push_midi_parent(srep->inode);
478 for (
int i = 0; i < node->children.n; i++)
479 render_node(X3D_NODE(node->children.p[i]));
482 iparent.n = srep->inode;
484 update_midi_connections(srep, iparent);
526void midimsg_uint2values(
unsigned int msg, ubyte* channel, ubyte*
command, ubyte* note, ubyte* velocity) {
529 ubyte* bytes = (ubyte*)&msg;
530 *channel = (bytes[0] & 0xF) + 1;
531 *
command = bytes[0] - (*channel - 1);
533 *velocity = bytes[2];
535unsigned int midimsg_values2uint(ubyte channel, ubyte
command, ubyte note, ubyte velocity) {
537 ubyte* bytes = (ubyte*)&msg;
538 bytes[0] = (channel - 1) |
command;
545void midiump_packet2values(
double packet, ubyte* channel, ubyte*
command, ubyte* note, ushort* velocity) {
549 *channel = (ump.bytes[1] & 0xF) + 1;
550 *
command = ump.bytes[1] - (*channel - 1);
551 *note = ump.bytes[2];
552 *velocity= ump.u16[2];
554double midiump_values2packet(ubyte channel, ubyte
command, ubyte note, ushort velocity) {
556 ump.bytes[1] = (channel - 1) |
command;
558 ump.u16[2] = velocity;
563void render_MIDIConverterIn(
struct MIDIConverterIn* node) {}
564void offset_notefields_MidiToneSplitter(
size_t* cfield) {
581 static size_t cfields[13] = { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0 };
582 if (cfields[0] == 0) offset_notefields_MidiToneSplitter(cfields);
584 struct X3D_Node* anode = X3D_NODE(node);
585 if (node->_ichange != node->_change) {
586 if (MIDITransport() == MIDI_MSG) {
587 for (
int i = 0; i < node->midiMsg.n; i++)
589 ubyte note, channel,
command, velocity;
590 unsigned int msg = (
unsigned int)node->midiMsg.p[i];
591 midimsg_uint2values(msg, &channel, &
command, ¬e, &velocity);
592 int status =
command == NOTE_ON && velocity > 0 ? TRUE : FALSE;
593 int octave = note / 12;
594 int inote = note % 12;
595 if (channel == node->channelFilter || node->channelFilter == -1) {
597 if (octave == node->octaveFilter || node->octaveFilter == -1)
600 int* field = (
int*)(cfields[inote] + (
unsigned char*)node);
602 MARK_EVENT(anode, cfields[inote]);
605 else if (
command == CONTROL_CHANGE && note == 64) {
606 node->pedal = velocity == 0 ? FALSE : TRUE;
612 else if (MIDITransport() == MIDI_UMP) {
613 for (
int i = 0; i < node->midiUmp.n; i++)
618 ump.packet = node->midiUmp.p[i];
619 midiump_packet2values(ump.packet, &channel, &
command, ¬e, &velocity);
620 int status =
command == NOTE_ON && velocity > 0 ? TRUE : FALSE;
621 int octave = note / 12;
622 int inote = note % 12;
623 if (channel == node->channelFilter || node->channelFilter == -1) {
625 if (octave == node->octaveFilter || node->octaveFilter == -1)
628 int* field = (
int*)(cfields[inote] + (
unsigned char*)node);
630 MARK_EVENT(anode, cfields[inote]);
633 else if (
command == CONTROL_CHANGE && note == 64) {
634 node->pedal = velocity == 0 ? FALSE : TRUE;
662void offset_notefields_MidiToneMerger(
size_t * cfield) {
678 struct X3D_Node* anode = X3D_NODE(node);
680 static size_t cfields[13];
681 if (node->_lastnote.n == 0)
684 node->_lastnote.p = malloc(13 *
sizeof(
int));
685 node->_lastnote.n = 13;
686 for (
int i = 0; i < 13; i++) node->_lastnote.p[i] = FALSE;
687 offset_notefields_MidiToneMerger(cfields);
689 if (node->_ichange != node->_change) {
690 int n, mark, mnote[12];
694 for(
int i=0;i<node->_lastnote.n;i++)
696 int lastval = node->_lastnote.p[i];
697 int octave = node->octave;
698 int channel = node->channel;
700 int note = i + 12 * octave;
701 int *field = (
int*)(cfields[i] + (
unsigned char*)node);
703 if(curval != lastval) {
706 command = curval ? NOTE_ON : NOTE_OFF;
712 if (MIDITransport() == MIDI_MSG){
713 ubyte velocity = curval ? 127 : 0;
714 mnote[n] = midimsg_values2uint(channel,
command, note, velocity);
716 if (MIDITransport() == MIDI_UMP) {
717 ushort velocity = curval ? 65535 : 0;
718 dnote[n] = midiump_values2packet(channel,
command, note, velocity);
724 node->_lastnote.p[i] = curval;
747 if (MIDITransport() == MIDI_MSG) {
749 node->midiMsg.p = realloc(node->midiMsg.p, n *
sizeof(
int));
750 memcpy(node->midiMsg.p, mnote, n *
sizeof(
int));
754 if (MIDITransport() == MIDI_UMP) {
756 node->midiUmp.p = realloc(node->midiUmp.p, n *
sizeof(
double));
757 memcpy(node->midiUmp.p, dnote, n *
sizeof(
double));
767void render_MIDIAudioSynth(
struct MIDIAudioSynth* node) {}
769static midi_transport_method = MIDI_UMP;
770void set_MIDITransport(
int method) {
771 midi_transport_method = method == 1 || method == 2 ? method : midi_transport_method;
774 return midi_transport_method;
790void render_MIDIConverterIn(
struct MIDIConverterIn* node) {}
791void render_MIDIToneSplitter(
struct MIDIToneSplitter* node) {}
792void render_MIDIToneMerger(
struct MIDIToneMerger* node) {}
793void render_MIDIAudioSynth(
struct MIDIAudioSynth* node) {}