reflexion 0.3.8.1 → 0.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/src/event.cpp CHANGED
@@ -5,6 +5,7 @@
5
5
  #include "reflex/device.h"
6
6
  #include "reflex/timer.h"
7
7
  #include "reflex/shape.h"
8
+ #include "reflex/midi.h"
8
9
  #include "reflex/exception.h"
9
10
  #include "view.h"
10
11
  #include "pointer.h"
@@ -868,6 +869,124 @@ namespace Reflex
868
869
  }
869
870
 
870
871
 
872
+ struct MIDIEvent::Data
873
+ {
874
+
875
+ MIDI::Ref midi;
876
+
877
+ uchar bytes[3] = {0};
878
+
879
+ bool captured = false;
880
+
881
+ };// MIDIEvent
882
+
883
+
884
+ bool
885
+ MIDIEvent_to_note_event (NoteEvent* result, const MIDIEvent& event)
886
+ {
887
+ auto a = event.action();
888
+ if (a != MIDIEvent::NOTE_ON && a != MIDIEvent::NOTE_OFF)
889
+ return false;
890
+
891
+ *result = NoteEvent(
892
+ a == MIDIEvent::NOTE_ON ? NoteEvent::ON : NoteEvent::OFF,
893
+ event.channel(), event.data1(), event.data2() / 127.f, event.time());
894
+ return true;
895
+ }
896
+
897
+ bool
898
+ MIDIEvent_to_control_change_event (
899
+ ControlChangeEvent* result, const MIDIEvent& event)
900
+ {
901
+ if (event.action() != MIDIEvent::CONTROL_CHANGE)
902
+ return false;
903
+
904
+ *result = ControlChangeEvent(
905
+ event.channel(), event.data1(), event.data2() / 127.f, event.time());
906
+ return true;
907
+ }
908
+
909
+ void
910
+ MIDIEvent_set_captured (MIDIEvent* pthis, bool captured)
911
+ {
912
+ pthis->self->captured = captured;
913
+ }
914
+
915
+
916
+ MIDIEvent::MIDIEvent ()
917
+ {
918
+ }
919
+
920
+ MIDIEvent::MIDIEvent (MIDI* midi, const uchar* bytes, double time)
921
+ : Event(time)
922
+ {
923
+ self->midi = midi;
924
+ memcpy(self->bytes, bytes, sizeof(uchar) * 3);
925
+ }
926
+
927
+ MIDIEvent::MIDIEvent (const MIDIEvent* src)
928
+ : Event(src), self(new Data(*src->self))
929
+ {
930
+ }
931
+
932
+ MIDIEvent
933
+ MIDIEvent::dup () const
934
+ {
935
+ return MIDIEvent(this);
936
+ }
937
+
938
+ MIDI*
939
+ MIDIEvent::midi () const
940
+ {
941
+ return self->midi;
942
+ }
943
+
944
+ MIDIEvent::Action
945
+ MIDIEvent::action () const
946
+ {
947
+ switch (self->bytes[0] >> 4)
948
+ {
949
+ case 0x9: return NOTE_ON;
950
+ case 0x8: return NOTE_OFF;
951
+ case 0xA: return KEY_PRESSURE;
952
+ case 0xB: return CONTROL_CHANGE;
953
+ case 0xC: return PROGRAM_CHANGE;
954
+ case 0xD: return CHANNEL_PRESSURE;
955
+ case 0xE: return PITCH_BEND_CHANGE;
956
+ case 0xF: return SYSTEM;
957
+ default: return ACTION_NONE;
958
+ }
959
+ }
960
+
961
+ int
962
+ MIDIEvent::channel () const
963
+ {
964
+ auto a = action();
965
+ if (a == ACTION_NONE || a == SYSTEM)
966
+ return -1;
967
+
968
+ return self->bytes[0] & 0xF;
969
+ }
970
+
971
+ uchar
972
+ MIDIEvent::data1 () const
973
+ {
974
+ return self->bytes[1];
975
+ }
976
+
977
+ uchar
978
+ MIDIEvent::data2 () const
979
+ {
980
+ return self->bytes[2];
981
+ }
982
+
983
+ bool
984
+ MIDIEvent::is_captured () const
985
+ {
986
+ return self->captured;
987
+ }
988
+
989
+
871
990
  struct NoteEvent::Data
872
991
  {
873
992
 
@@ -954,6 +1073,76 @@ namespace Reflex
954
1073
  }
955
1074
 
956
1075
 
1076
+ struct ControlChangeEvent::Data
1077
+ {
1078
+
1079
+ int channel = 0;
1080
+
1081
+ int controller = 0;
1082
+
1083
+ float value = 0;
1084
+
1085
+ bool captured = false;
1086
+
1087
+ };// ControlChangeEvent::Data
1088
+
1089
+
1090
+ void
1091
+ ControlChangeEvent_set_captured (ControlChangeEvent* pthis, bool captured)
1092
+ {
1093
+ pthis->self->captured = captured;
1094
+ }
1095
+
1096
+
1097
+ ControlChangeEvent::ControlChangeEvent ()
1098
+ {
1099
+ }
1100
+
1101
+ ControlChangeEvent::ControlChangeEvent (
1102
+ int channel, int controller, float value, double time)
1103
+ : Event(time)
1104
+ {
1105
+ self->channel = channel;
1106
+ self->controller = controller;
1107
+ self->value = value;
1108
+ }
1109
+
1110
+ ControlChangeEvent::ControlChangeEvent (const ControlChangeEvent* src)
1111
+ : Event(src), self(new Data(*src->self))
1112
+ {
1113
+ }
1114
+
1115
+ ControlChangeEvent
1116
+ ControlChangeEvent::dup () const
1117
+ {
1118
+ return ControlChangeEvent(this);
1119
+ }
1120
+
1121
+ int
1122
+ ControlChangeEvent::channel () const
1123
+ {
1124
+ return self->channel;
1125
+ }
1126
+
1127
+ int
1128
+ ControlChangeEvent::controller () const
1129
+ {
1130
+ return self->controller;
1131
+ }
1132
+
1133
+ float
1134
+ ControlChangeEvent::value () const
1135
+ {
1136
+ return self->value;
1137
+ }
1138
+
1139
+ bool
1140
+ ControlChangeEvent::is_captured () const
1141
+ {
1142
+ return self->captured;
1143
+ }
1144
+
1145
+
957
1146
  struct CaptureEvent::Data
958
1147
  {
959
1148
 
data/src/event.h CHANGED
@@ -49,9 +49,20 @@ namespace Reflex
49
49
  void WheelEvent_set_position (WheelEvent* pthis, const Point& position);
50
50
 
51
51
 
52
+ bool MIDIEvent_to_note_event (NoteEvent* result, const MIDIEvent& event);
53
+
54
+ bool MIDIEvent_to_control_change_event (
55
+ ControlChangeEvent* result, const MIDIEvent& event);
56
+
57
+ void MIDIEvent_set_captured (MIDIEvent* pthis, bool captured);
58
+
59
+
52
60
  void NoteEvent_set_captured (NoteEvent* pthis, bool captured);
53
61
 
54
62
 
63
+ void ControlChangeEvent_set_captured (ControlChangeEvent* pthis, bool captured);
64
+
65
+
55
66
  }// Reflex
56
67
 
57
68
 
data/src/midi.cpp CHANGED
@@ -33,33 +33,7 @@ namespace Reflex
33
33
  };// MIDI::Data
34
34
 
35
35
 
36
- static void
37
- call_note_event (
38
- MIDI* midi, bool on,
39
- int channel, int note, float velocity, double time)
40
- {
41
- NoteEvent e(
42
- on ? NoteEvent::ON : NoteEvent::OFF,
43
- channel, note, velocity, time);
44
-
45
- midi->on_note(&e);
46
- if (e.is_blocked()) return;
47
-
48
- switch ((int) e.action())
49
- {
50
- case NoteEvent::ON: midi->on_note_on(&e); break;
51
- case NoteEvent::OFF: midi->on_note_off(&e); break;
52
- }
53
- if (e.is_blocked()) return;
54
-
55
- Window* win = Window_get_active();
56
- if (!win) return;
57
-
58
- Window_call_note_event(win, &e);
59
- }
60
-
61
-
62
- struct MIDIEvent
36
+ struct RtMidiEvent
63
37
  {
64
38
 
65
39
  typedef std::vector<unsigned char> Message;
@@ -76,60 +50,84 @@ namespace Reflex
76
50
 
77
51
  double time = 0;
78
52
 
79
- MIDIEvent ()
53
+ RtMidiEvent ()
80
54
  : error("")
81
55
  {
82
56
  }
83
57
 
84
- MIDIEvent (MIDI* midi, const Message& message, double time)
58
+ RtMidiEvent (MIDI* midi, const Message& message, double time)
85
59
  : type(MESSAGE), midi(midi), message(message), error(""), time(time)
86
60
  {
87
61
  }
88
62
 
89
- MIDIEvent (MIDI* midi, const RtMidiError& error)
63
+ RtMidiEvent (MIDI* midi, const RtMidiError& error)
90
64
  : type(ERROR), midi(midi), error(error)
91
65
  {
92
66
  }
93
67
 
94
- };// MIDIEvent
68
+ };// RtMidiEvent
69
+
70
+
71
+ static void
72
+ call_midi_note_event (MIDI* midi, NoteEvent* event)
73
+ {
74
+ midi->on_note(event);
75
+ if (event->is_blocked())
76
+ return;
77
+
78
+ switch ((int) event->action())
79
+ {
80
+ case NoteEvent::ON: midi->on_note_on(event); break;
81
+ case NoteEvent::OFF: midi->on_note_off(event); break;
82
+ }
83
+ }
95
84
 
85
+ static void
86
+ call_midi_event (MIDI* midi, const MIDIEvent& event)
87
+ {
88
+ NoteEvent note_e;
89
+ if (MIDIEvent_to_note_event(&note_e, event))
90
+ call_midi_note_event(midi, &note_e);
96
91
 
97
- static Queue<MIDIEvent> queue;
92
+ ControlChangeEvent cc_e;
93
+ if (MIDIEvent_to_control_change_event(&cc_e, event))
94
+ midi->on_control_change(&cc_e);
95
+ }
98
96
 
99
97
  static void
100
- dispatch_midi_event (MIDIEvent* event)
98
+ call_events (MIDI* midi, const uchar* bytes, double time)
99
+ {
100
+ MIDIEvent event(midi, bytes, time);
101
+
102
+ midi->on_midi(&event);
103
+ if (event.is_blocked()) return;
104
+
105
+ call_midi_event(midi, event);
106
+
107
+ Window* win = Window_get_active();
108
+ if (!win) return;
109
+
110
+ Window_call_midi_event(win, &event);
111
+ }
112
+
113
+ static Queue<RtMidiEvent> queue;
114
+
115
+ static void
116
+ dispatch_midi_event (RtMidiEvent* event)
101
117
  {
102
118
  switch (event->type)
103
119
  {
104
- case MIDIEvent::MESSAGE:
105
- {
106
- auto& bytes = event->message;
107
- switch (bytes[0] >> 4)
108
- {
109
- case 0x9:
110
- call_note_event(
111
- event->midi, true,
112
- bytes[0] & 0xf, bytes[1], bytes[2] / 127.f, event->time);
113
- break;
114
-
115
- case 0x8:
116
- call_note_event(
117
- event->midi, false,
118
- bytes[0] & 0xf, bytes[1], bytes[2] / 127.f, event->time);
119
- break;
120
- }
120
+ case RtMidiEvent::MESSAGE:
121
+ call_events(event->midi, &event->message[0], event->time);
121
122
  break;
122
- }
123
123
 
124
- case MIDIEvent::ERROR:
125
- {
124
+ case RtMidiEvent::ERROR:
126
125
  system_error(
127
126
  __FILE__, __LINE__,
128
127
  Xot::stringf("MIDI: %s", event->error.what()).c_str());
129
128
  break;
130
- }
131
129
 
132
- case MIDIEvent::UNKNOWN:
130
+ case RtMidiEvent::UNKNOWN:
133
131
  invalid_state_error(__FILE__, __LINE__);
134
132
  }
135
133
  }
@@ -137,13 +135,13 @@ namespace Reflex
137
135
  static void
138
136
  process_midi_events ()
139
137
  {
140
- MIDIEvent event;
138
+ RtMidiEvent event;
141
139
  while (queue.try_pop(&event))
142
140
  dispatch_midi_event(&event);
143
141
  }
144
142
 
145
143
  static void
146
- event_callback (double dt, MIDIEvent::Message* message, void* data)
144
+ event_callback (double dt, RtMidiEvent::Message* message, void* data)
147
145
  {
148
146
  MIDI* midi = (MIDI*) data;
149
147
  MIDI::Data* self = midi->self.get();
@@ -153,7 +151,7 @@ namespace Reflex
153
151
  else
154
152
  self->time += dt;
155
153
 
156
- queue.push(MIDIEvent(midi, *message, self->time));
154
+ queue.push(RtMidiEvent(midi, *message, self->time));
157
155
  }
158
156
 
159
157
  static void
@@ -161,7 +159,7 @@ namespace Reflex
161
159
  {
162
160
  MIDI* midi = (MIDI*) data;
163
161
 
164
- queue.push(MIDIEvent(midi, RtMidiError(message, type)));
162
+ queue.push(RtMidiEvent(midi, RtMidiError(message, type)));
165
163
  }
166
164
 
167
165
  static MIDI_CreateFun midi_create_fun = NULL;
@@ -349,6 +347,11 @@ namespace Reflex
349
347
  return self->name;
350
348
  }
351
349
 
350
+ void
351
+ MIDI::on_midi (MIDIEvent* e)
352
+ {
353
+ }
354
+
352
355
  void
353
356
  MIDI::on_note (NoteEvent* e)
354
357
  {
@@ -364,6 +367,11 @@ namespace Reflex
364
367
  {
365
368
  }
366
369
 
370
+ void
371
+ MIDI::on_control_change (ControlChangeEvent* e)
372
+ {
373
+ }
374
+
367
375
  MIDI::operator bool () const
368
376
  {
369
377
  return self->input.isPortOpen();
data/src/view.cpp CHANGED
@@ -1508,6 +1508,20 @@ namespace Reflex
1508
1508
  view->on_wheel(&e);
1509
1509
  }
1510
1510
 
1511
+ void
1512
+ View_call_midi_event (View* view, MIDIEvent* event)
1513
+ {
1514
+ if (!view)
1515
+ argument_error(__FILE__, __LINE__);
1516
+ if (!event)
1517
+ argument_error(__FILE__, __LINE__);
1518
+
1519
+ if (view->hidden()) return;
1520
+
1521
+ MIDIEvent e = event->dup();
1522
+ view->on_midi(&e);
1523
+ }
1524
+
1511
1525
  void
1512
1526
  View_call_note_event (View* view, NoteEvent* event)
1513
1527
  {
@@ -1530,6 +1544,20 @@ namespace Reflex
1530
1544
  }
1531
1545
  }
1532
1546
 
1547
+ void
1548
+ View_call_control_change_event (View* view, ControlChangeEvent* event)
1549
+ {
1550
+ if (!view)
1551
+ argument_error(__FILE__, __LINE__);
1552
+ if (!event)
1553
+ argument_error(__FILE__, __LINE__);
1554
+
1555
+ if (view->hidden()) return;
1556
+
1557
+ ControlChangeEvent e = event->dup();
1558
+ view->on_control_change(&e);
1559
+ }
1560
+
1533
1561
  void
1534
1562
  View_call_contact_event (View* view, ContactEvent* event)
1535
1563
  {
@@ -2805,6 +2833,11 @@ namespace Reflex
2805
2833
  //scroll_by(e->dx, e->dy, e->dz);
2806
2834
  }
2807
2835
 
2836
+ void
2837
+ View::on_midi (MIDIEvent* e)
2838
+ {
2839
+ }
2840
+
2808
2841
  void
2809
2842
  View::on_note (NoteEvent* e)
2810
2843
  {
@@ -2820,6 +2853,11 @@ namespace Reflex
2820
2853
  {
2821
2854
  }
2822
2855
 
2856
+ void
2857
+ View::on_control_change (ControlChangeEvent* e)
2858
+ {
2859
+ }
2860
+
2823
2861
  void
2824
2862
  View::on_capture (CaptureEvent* e)
2825
2863
  {
data/src/view.h CHANGED
@@ -36,15 +36,19 @@ namespace Reflex
36
36
 
37
37
  void View_update_shapes (View* view);
38
38
 
39
- void View_call_key_event (View* view, KeyEvent* event);
39
+ void View_call_key_event (View* view, KeyEvent* event);
40
40
 
41
- void View_call_pointer_event (View* view, PointerEvent* event);
41
+ void View_call_pointer_event (View* view, PointerEvent* event);
42
42
 
43
- void View_call_wheel_event (View* view, WheelEvent* event);
43
+ void View_call_wheel_event (View* view, WheelEvent* event);
44
44
 
45
- void View_call_note_event (View* view, NoteEvent* event);
45
+ void View_call_midi_event (View* view, MIDIEvent* event);
46
46
 
47
- void View_call_contact_event (View* view, ContactEvent* event);
47
+ void View_call_note_event (View* view, NoteEvent* event);
48
+
49
+ void View_call_control_change_event (View* view, ControlChangeEvent* event);
50
+
51
+ void View_call_contact_event (View* view, ContactEvent* event);
48
52
 
49
53
 
50
54
  }// Reflex
data/src/window.cpp CHANGED
@@ -262,8 +262,6 @@ namespace Reflex
262
262
  KeyEvent e = event->dup();
263
263
  KeyEvent_set_captured(&e, true);
264
264
  View_call_key_event(const_cast<View*>(view.get()), &e);
265
-
266
- if (e.is_blocked()) event->block();
267
265
  }
268
266
 
269
267
  if (!event->is_blocked())
@@ -607,7 +605,7 @@ namespace Reflex
607
605
  View_call_wheel_event(window->root(), event);
608
606
  }
609
607
 
610
- void
608
+ static void
611
609
  Window_call_note_event (Window* window, NoteEvent* event)
612
610
  {
613
611
  assert(window);
@@ -619,7 +617,7 @@ namespace Reflex
619
617
  {
620
618
  if (
621
619
  !view->window() ||
622
- !is_capturing(view.get(), targets, View::CAPTURE_NOTE))
620
+ !is_capturing(view.get(), targets, View::CAPTURE_MIDI))
623
621
  {
624
622
  continue;
625
623
  }
@@ -627,8 +625,6 @@ namespace Reflex
627
625
  NoteEvent e = event->dup();
628
626
  NoteEvent_set_captured(&e, true);
629
627
  View_call_note_event(const_cast<View*>(view.get()), &e);
630
-
631
- if (e.is_blocked()) event->block();
632
628
  }
633
629
 
634
630
  if (!event->is_blocked())
@@ -646,6 +642,75 @@ namespace Reflex
646
642
 
647
643
  if (!event->is_blocked() && window->self->focus)
648
644
  View_call_note_event(window->self->focus.get(), event);
645
+ }
646
+
647
+ static void
648
+ Window_call_control_change_event (Window* window, ControlChangeEvent* event)
649
+ {
650
+ assert(window);
651
+
652
+ if (!event)
653
+ argument_error(__FILE__, __LINE__);
654
+
655
+ for (auto& [view, targets] : window->self->captures)
656
+ {
657
+ if (
658
+ !view->window() ||
659
+ !is_capturing(view.get(), targets, View::CAPTURE_MIDI))
660
+ {
661
+ continue;
662
+ }
663
+
664
+ ControlChangeEvent e = event->dup();
665
+ ControlChangeEvent_set_captured(&e, true);
666
+ View_call_control_change_event(const_cast<View*>(view.get()), &e);
667
+ }
668
+
669
+ if (!event->is_blocked())
670
+ window->on_control_change(event);
671
+
672
+ if (!event->is_blocked() && window->self->focus)
673
+ View_call_control_change_event(window->self->focus.get(), event);
674
+ }
675
+
676
+ void
677
+ Window_call_midi_event (Window* window, MIDIEvent* event)
678
+ {
679
+ if (!window) return;
680
+
681
+ if (!event)
682
+ argument_error(__FILE__, __LINE__);
683
+
684
+ for (auto& [view, targets] : window->self->captures)
685
+ {
686
+ if (
687
+ !view->window() ||
688
+ !is_capturing(view.get(), targets, View::CAPTURE_MIDI))
689
+ {
690
+ continue;
691
+ }
692
+
693
+ MIDIEvent e = event->dup();
694
+ MIDIEvent_set_captured(&e, true);
695
+ View_call_midi_event(const_cast<View*>(view.get()), &e);
696
+ }
697
+
698
+ if (!event->is_blocked())
699
+ window->on_midi(event);
700
+
701
+ if (!event->is_blocked() && window->self->focus)
702
+ View_call_midi_event(window->self->focus.get(), event);
703
+
704
+ if (!event->is_blocked())
705
+ {
706
+ NoteEvent note_e;
707
+ if (MIDIEvent_to_note_event(&note_e, *event))
708
+ Window_call_note_event(window, &note_e);
709
+
710
+ ControlChangeEvent cc_e;
711
+ if (MIDIEvent_to_control_change_event(&cc_e, *event))
712
+ Window_call_control_change_event(window, &cc_e);
713
+ }
649
714
 
650
715
  cleanup_captures(window);
651
716
  }
@@ -941,6 +1006,11 @@ namespace Reflex
941
1006
  {
942
1007
  }
943
1008
 
1009
+ void
1010
+ Window::on_midi (MIDIEvent* e)
1011
+ {
1012
+ }
1013
+
944
1014
  void
945
1015
  Window::on_note (NoteEvent* e)
946
1016
  {
@@ -956,6 +1026,11 @@ namespace Reflex
956
1026
  {
957
1027
  }
958
1028
 
1029
+ void
1030
+ Window::on_control_change (ControlChangeEvent* e)
1031
+ {
1032
+ }
1033
+
959
1034
  Window::operator bool () const
960
1035
  {
961
1036
  return self && *self;
data/src/window.h CHANGED
@@ -139,7 +139,7 @@ namespace Reflex
139
139
 
140
140
  void Window_call_wheel_event (Window* window, WheelEvent* event);
141
141
 
142
- void Window_call_note_event (Window* window, NoteEvent* event);
142
+ void Window_call_midi_event (Window* window, MIDIEvent* event);
143
143
 
144
144
 
145
145
  typedef View* (*Window_CreateRootViewFun) ();
@@ -26,34 +26,34 @@ class TestCaptureEvent < Test::Unit::TestCase
26
26
  end
27
27
 
28
28
  def test_begin()
29
- c = event [:key, :pointer, :note], []
30
- assert_equal [:key, :pointer, :note], c.begin
29
+ c = event [:key, :pointer, :midi], []
30
+ assert_equal [:key, :pointer, :midi], c.begin
31
31
  assert_equal true, c.begin?(:key)
32
32
  assert_equal true, c.begin?(:pointer)
33
- assert_equal true, c.begin?(:note)
33
+ assert_equal true, c.begin?(:midi)
34
34
  assert_equal true, c.begin?(:all)
35
35
 
36
36
  c = event [:key], []
37
37
  assert_equal [:key], c.begin
38
38
  assert_equal true, c.begin?(:key)
39
39
  assert_equal false, c.begin?(:pointer)
40
- assert_equal false, c.begin?(:note)
40
+ assert_equal false, c.begin?(:midi)
41
41
  assert_equal false, c.begin?(:all)
42
42
  end
43
43
 
44
44
  def test_end()
45
- c = event [], [:key, :pointer, :note]
46
- assert_equal [:key, :pointer, :note], c.end
45
+ c = event [], [:key, :pointer, :midi]
46
+ assert_equal [:key, :pointer, :midi], c.end
47
47
  assert_equal true, c.end?(:key)
48
48
  assert_equal true, c.end?(:pointer)
49
- assert_equal true, c.end?(:note)
49
+ assert_equal true, c.end?(:midi)
50
50
  assert_equal true, c.end?(:all)
51
51
 
52
52
  c = event [], [:key]
53
53
  assert_equal [:key], c.end
54
54
  assert_equal true, c.end?(:key)
55
55
  assert_equal false, c.end?(:pointer)
56
- assert_equal false, c.end?(:note)
56
+ assert_equal false, c.end?(:midi)
57
57
  assert_equal false, c.end?(:all)
58
58
  end
59
59