├── .DS_Store
├── .gitattributes
├── .gitignore
├── Icon
├── midi-osc-midi.icns
├── midi-osc-midi.png
└── midi-port.psd
├── README.md
├── addons.make
├── bin
└── data
│ ├── .gitkeep
│ └── MIDI_OSC_SETTINGS.json
├── screenshots
├── Conversion.jpg
├── MidiIn.jpg
├── MidiOut.jpg
├── OSCIn.jpg
└── OSCOut.jpg
└── src
├── .DS_Store
├── MidiConstants.h
├── MidiManager.cpp
├── MidiManager.h
├── OcsManager.cpp
├── OscManager.h
├── SettingsManager.cpp
├── SettingsManager.h
├── colours.h
├── main.cpp
├── modes
├── ConversionMode.cpp
├── ConversionMode.h
├── MidiInSetupMode.cpp
├── MidiInSetupMode.h
├── MidiOutSetupMode.cpp
├── MidiOutSetupMode.h
├── Mode.cpp
├── Mode.h
├── ModeManager.cpp
├── ModeManager.h
├── OscInSetupMode.cpp
├── OscInSetupMode.h
├── OscOutSetupMode.cpp
└── OscOutSetupMode.h
├── ofApp.cpp
├── ofApp.h
└── simpleButton.h
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fred-dev/OSC_MIDI_OSC/a4d127eb9653ef357f936bfab3f7f5b52667bb38/.DS_Store
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 | *.sln merge=union
7 | *.csproj merge=union
8 | *.vbproj merge=union
9 | *.fsproj merge=union
10 | *.dbproj merge=union
11 |
12 | # Standard to msysgit
13 | *.doc diff=astextplain
14 | *.DOC diff=astextplain
15 | *.docx diff=astextplain
16 | *.DOCX diff=astextplain
17 | *.dot diff=astextplain
18 | *.DOT diff=astextplain
19 | *.pdf diff=astextplain
20 | *.PDF diff=astextplain
21 | *.rtf diff=astextplain
22 | *.RTF diff=astextplain
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Ignore all files by default
2 | *
3 |
4 | # Allow directories and files
5 | !/src/
6 | !/addons.make
7 | !/README.md
8 | !/bin/data/
9 | !/Icon/
10 | !/screenshots/
11 |
12 | # Exclude all .DS_Store files
13 | .DS_Store
--------------------------------------------------------------------------------
/Icon/midi-osc-midi.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fred-dev/OSC_MIDI_OSC/a4d127eb9653ef357f936bfab3f7f5b52667bb38/Icon/midi-osc-midi.icns
--------------------------------------------------------------------------------
/Icon/midi-osc-midi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fred-dev/OSC_MIDI_OSC/a4d127eb9653ef357f936bfab3f7f5b52667bb38/Icon/midi-osc-midi.png
--------------------------------------------------------------------------------
/Icon/midi-port.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fred-dev/OSC_MIDI_OSC/a4d127eb9653ef357f936bfab3f7f5b52667bb38/Icon/midi-port.psd
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # OSC_MIDI_OSC
2 |
3 |
4 |
5 | A straightforward cross-platform converter for OSC to MIDI and MIDI to OSC. Designed for zero-configuration, simply set your MIDI and OSC ports, and the software will handle the translation between MIDI and OSC seamlessly. It operates bidirectionally, performing both functions simultaneously.
6 |
7 | You will have to structure the OSC messages in the format described below.
8 |
9 | This tool is practical but also serves as a learning journey for me in software design.
10 | If you have any tips, suggestions, or feature requests, please don't hesitate to reach out.
11 |
12 | - **Made with**: [openframeworks](https://github.com/openframeworks/openFrameworks)
13 |
14 | ## Downloads - if you want to just use the app
15 |
16 | - **MAC OS 10.15+ (ish) 64 bit**: Available on the release tab.
17 | - **Windows 10+ 64 bit**: Available on the release tab.
18 |
19 | > **Note**: Linux has many requirements. If you're looking for a fast and light solution for Linux, this may not be for you due to the heavy dependencies of openframeworks.
20 |
21 | ## Setup - if you want to play with the code
22 |
23 | 1. Download [openframeworks](https://openframeworks.cc/download/) and set it up for your platform.
24 | 2. Navigate to `openframeworksRoot/myApps/` and clone this repository.
25 | 3. Navigate to `openframeworksRoot/addons/` and clone the following repositories:
26 | - [ofxMidi](https://github.com/danomatika/ofxMidi)
27 | - [ofxTextInputField](https://github.com/Flightphase/ofxTextInputField)
28 | - [ofxMSAInteractiveObject](https://github.com/memo/ofxMSAInteractiveObject)
29 | 4. Use the project generator for your platform to generate a project.
30 | 5. Compile for your platform.
31 |
32 | ### Configuration - running the software
33 |
34 | To configure the app, go to the `data` folder and edit the `MIDI_OSC_SETTINGS.json` file, or change the settings from the GUI! You can set the incoming and outgoing midi and OSC ports and the destination IP.
35 |
36 | ## Updates
37 |
38 | - Now includes Midi Machine control.
39 | - Basic interactive GUI for on-the-go settings adjustments.
40 | - Midi Show Control is now included (beta version).
41 |
42 | ## Windows Users
43 |
44 | To use this with Windows, ensure you install a virtual midi port. We recommend [Loopmidi from Tobias Erichsen](http://www.tobias-erichsen.de/software/loopmidi.html).
45 |
46 | ## To-Do
47 |
48 | - More detailed MSC and MTC.
49 |
50 | ## OSC Format
51 |
52 | The OSC format is consistent for both sending and receiving. Here are the detailed descriptions of the address formats:
53 |
54 | - **/cc**: For controller values with two int arguments: the controller number and the value.
55 | - **/noteOn**: For note on messages with two int arguments: note value and velocity.
56 | - **/noteOff**: For note off messages with one int argument: note value.
57 | - **/Aftertouch**: For mono aftertouch off messages with one int argument: value.
58 | - **/PolyAftertouch**: For polyphonic aftertouch messages with two int arguments: pitch and value.
59 | - **/Pitchbend**: For pitch bend messages with one int argument: value.
60 | - **/ProgramChange**: For program change messages with one int argument: program value.
61 |
62 | The software receives OSC messages in these formats and will automatically send the corresponding MIDI signals. Incoming MIDI signals will trigger OSC messages in the same formats.
63 |
64 | The app wll output MMC commands from the following OSC inputs, add an int argument for the device ID and a string argument for the command
65 |
66 | Address: "/MMCCommand"
67 | Commands are:
68 |
69 | - `stop`
70 | - `play`
71 | - `deferred_play`
72 | - `fast_forward`
73 | - `rewind`
74 | - `record_strobe`
75 | - `record_exit`
76 | - `record_pause`
77 | - `pause`
78 | - `eject`
79 | - `chase`
80 | - `command_error_reset`
81 | - `mmc_reset`
82 |
83 |
84 | The app wll output Midi Show Control commands from the following OSC inputs, add an int argument for the device ID, a string argument
85 | for the command target and another string argument for the command type, lastly add extra integer arguments for the command payload (up to 3)
86 |
87 | ### Here are the command targets:
88 | - `lighting`
89 | - `moving_lights`
90 | - `colour_changers`
91 | - `strobes`
92 | - `lasers`
93 | - `chasers`
94 | - `sound`
95 | - `music`
96 | - `cd_players`
97 | - `eprom_playback`
98 | - `audio_tape_machines`
99 | - `intercoms`
100 | - `amplifiers`
101 | - `audio_effects_devices`
102 | - `equalisers`
103 | - `machinery`
104 | - `rigging`
105 | - `flys`
106 | - `lifts`
107 | - `turntables`
108 | - `trusses`
109 | - `robots`
110 | - `animation`
111 | - `floats`
112 | - `breakaways`
113 | - `barges`
114 | - `video`
115 | - `video_tape_machines`
116 | - `video_cassette_machines`
117 | - `video_disc_players`
118 | - `video_switchers`
119 | - `video_effects`
120 | - `video_character_generators`
121 | - `video_still_stores`
122 | - `video_monitors`
123 | - `projection`
124 | - `film_projectors`
125 | - `slide_projectors`
126 | - `video_projectors`
127 | - `dissolvers`
128 | - `shutter_controls`
129 | - `process_control`
130 | - `hydraulic_oil`
131 | - `h20`
132 | - `co2`
133 | - `compressed_air`
134 | - `natural_gas`
135 | - `fog`
136 | - `smoke`
137 | - `cracked_haze`
138 | - `pyro`
139 | - `fireworks`
140 | - `explosions`
141 | - `flame`
142 | - `smoke_pots`
143 | - `all_types`
144 |
145 | ### And here are the command types:
146 |
147 | - `go`
148 | - `stop`
149 | - `resume`
150 | - `timed_go`
151 | - `load`
152 | - `set`
153 | - `fire`
154 | - `all_off`
155 | - `restore`
156 | - `reset`
157 | - `go_off`
158 | - `go_jam_clock`
159 | - `standby+`
160 | - `standby-`
161 | - `sequence+`
162 | - `sequence-`
163 | - `start_clock`
164 | - `stop_clock`
165 | - `zero_clock`
166 | - `set_clock`
167 | - `mtc_chase_on`
168 | - `mtc_chase_off`
169 | - `open_cue_list`
170 | - `close_cue_list`
171 | - `open_cue_path`
172 |
--------------------------------------------------------------------------------
/addons.make:
--------------------------------------------------------------------------------
1 | ofxMSAInteractiveObject
2 | ofxMidi
3 | ofxOsc
4 | ofxTextInputField
5 |
--------------------------------------------------------------------------------
/bin/data/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fred-dev/OSC_MIDI_OSC/a4d127eb9653ef357f936bfab3f7f5b52667bb38/bin/data/.gitkeep
--------------------------------------------------------------------------------
/bin/data/MIDI_OSC_SETTINGS.json:
--------------------------------------------------------------------------------
1 | {
2 | "Log_level": 0,
3 | "allInPorts": [
4 | "Euphonix EuMidi1 0",
5 | "Euphonix EuMidi2 1",
6 | "Euphonix EuMidi3 2",
7 | "Euphonix EuMidi4 3",
8 | "Euphonix EuMidi5 4",
9 | "Euphonix EuMidi6 5",
10 | "Euphonix EuMidi7 6",
11 | "Euphonix EuMidi8 7",
12 | "loopMIDI Port 8"
13 | ],
14 | "allOutPorts": [
15 | "Microsoft GS Wavetable Synth 0",
16 | "Euphonix EuMidi1 1",
17 | "Euphonix EuMidi2 2",
18 | "Euphonix EuMidi3 3",
19 | "Euphonix EuMidi4 4",
20 | "Euphonix EuMidi5 5",
21 | "Euphonix EuMidi6 6",
22 | "Euphonix EuMidi7 7",
23 | "Euphonix EuMidi8 8",
24 | "loopMIDI Port 9"
25 | ],
26 | "frameRate": 25,
27 | "inPortLabel": "Euphonix EuMidi1 0",
28 | "incomingPortOsc": 1233,
29 | "midiInChannel": 1,
30 | "midiInDevice": "IAC Driver Bus 1",
31 | "midiInDeviceByString": true,
32 | "midiInDeviceName": null,
33 | "midiInDeviceNum": 0,
34 | "midiOuDeviceByString": false,
35 | "midiOutChannel": 1,
36 | "midiOutDevice": "Isadora Virtual In",
37 | "midiOutDeviceByString": true,
38 | "midiOutDeviceName": null,
39 | "midiOutDeviceNum": 0,
40 | "outGoingPortOsc": 1234,
41 | "outPortLabel": "Microsoft GS Wavetable Synth 0",
42 | "outgoingIpOSC": "127.0.0.1",
43 | "useVirtualPort": false
44 | }
--------------------------------------------------------------------------------
/screenshots/Conversion.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fred-dev/OSC_MIDI_OSC/a4d127eb9653ef357f936bfab3f7f5b52667bb38/screenshots/Conversion.jpg
--------------------------------------------------------------------------------
/screenshots/MidiIn.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fred-dev/OSC_MIDI_OSC/a4d127eb9653ef357f936bfab3f7f5b52667bb38/screenshots/MidiIn.jpg
--------------------------------------------------------------------------------
/screenshots/MidiOut.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fred-dev/OSC_MIDI_OSC/a4d127eb9653ef357f936bfab3f7f5b52667bb38/screenshots/MidiOut.jpg
--------------------------------------------------------------------------------
/screenshots/OSCIn.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fred-dev/OSC_MIDI_OSC/a4d127eb9653ef357f936bfab3f7f5b52667bb38/screenshots/OSCIn.jpg
--------------------------------------------------------------------------------
/screenshots/OSCOut.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fred-dev/OSC_MIDI_OSC/a4d127eb9653ef357f936bfab3f7f5b52667bb38/screenshots/OSCOut.jpg
--------------------------------------------------------------------------------
/src/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fred-dev/OSC_MIDI_OSC/a4d127eb9653ef357f936bfab3f7f5b52667bb38/src/.DS_Store
--------------------------------------------------------------------------------
/src/MidiConstants.h:
--------------------------------------------------------------------------------
1 | //
2 | // MSCConstants.h
3 | // OSC_MIDI_OSC
4 | //
5 | // Created by Fred Rodrigues on 29/09/2023.
6 | //
7 |
8 | #pragma once
9 |
10 | #include
11 | #include
12 |
13 | // Define the Midi Show Control Target Type map
14 | const std::unordered_map MIDI_SHOW_CONTROL_TARGET_TYPE = {
15 | {0x01, "lighting"},
16 | {0x02, "moving_lights"},
17 | {0x03, "colour_changers"},
18 | {0x04, "strobes"},
19 | {0x05, "lasers"},
20 | {0x06, "chasers"},
21 | {0x10, "sound"},
22 | {0x11, "music"},
23 | {0x12, "cd_players"},
24 | {0x13, "eprom_playback"},
25 | {0x14, "audio_tape_machines"},
26 | {0x15, "intercoms"},
27 | {0x16, "amplifiers"},
28 | {0x17, "audio_effects_devices"},
29 | {0x18, "equalisers"},
30 | {0x20, "machinery"},
31 | {0x21, "rigging"},
32 | {0x22, "flys"},
33 | {0x23, "lifts"},
34 | {0x24, "turntables"},
35 | {0x25, "trusses"},
36 | {0x26, "robots"},
37 | {0x27, "animation"},
38 | {0x28, "floats"},
39 | {0x29, "breakaways"},
40 | {0x2a, "barges"},
41 | {0x30, "video"},
42 | {0x31, "video_tape_machines"},
43 | {0x32, "video_cassette_machines"},
44 | {0x33, "video_disc_players"},
45 | {0x34, "video_switchers"},
46 | {0x35, "video_effects"},
47 | {0x36, "video_character_generators"},
48 | {0x37, "video_still_stores"},
49 | {0x38, "video_monitors"},
50 | {0x40, "projection"},
51 | {0x41, "film_projectors"},
52 | {0x42, "slide_projectors"},
53 | {0x43, "video_projectors"},
54 | {0x44, "dissolvers"},
55 | {0x45, "shutter_controls"},
56 | {0x50, "process_control"},
57 | {0x51, "hydraulic_oil"},
58 | {0x52, "h20"},
59 | {0x53, "co2"},
60 | {0x54, "compressed_air"},
61 | {0x55, "natural_gas"},
62 | {0x56, "fog"},
63 | {0x57, "smoke"},
64 | {0x58, "cracked_haze"},
65 | {0x60, "pyro"},
66 | {0x61, "fireworks"},
67 | {0x62, "explosions"},
68 | {0x63, "flame"},
69 | {0x64, "smoke_pots"},
70 | {0x7f, "all_types"}
71 | };
72 |
73 | const std::unordered_map MIDI_SHOW_CONTROL_COMMAND_TYPE = {
74 | {0x01, "go"},
75 | {0x02, "stop"},
76 | {0x03, "resume"},
77 | {0x04, "timed_go"},
78 | {0x05, "load"},
79 | {0x06, "set"},
80 | {0x07, "fire"},
81 | {0x08, "all_off"},
82 | {0x09, "restore"},
83 | {0x0a, "reset"},
84 | {0x0b, "go_off"},
85 | {0x10, "go_jam_clock"},
86 | {0x11, "standby+"},
87 | {0x12, "standby-"},
88 | {0x13, "sequence+"},
89 | {0x14, "sequence-"},
90 | {0x15, "start_clock"},
91 | {0x16, "stop_clock"},
92 | {0x17, "zero_clock"},
93 | {0x18, "set_clock"},
94 | {0x19, "mtc_chase_on"},
95 | {0x1a, "mtc_chase_off"},
96 | {0x1b, "open_cue_list"},
97 | {0x1c, "close_cue_list"},
98 | {0x1d, "open_cue_path"}
99 | };
100 |
101 | const std::unordered_map MIDI_MACHINE_CONTROL_COMMAND_TYPE = {
102 | {0x01, "stop"},
103 | {0x02, "play"},
104 | {0x03, "deferred_play"},
105 | {0x04, "fast_forward"},
106 | {0x05, "rewind"},
107 | {0x06, "record_strobe"},
108 | {0x07, "record_exit"},
109 | {0x08, "record_pause"},
110 | {0x09, "pause"},
111 | {0x0a, "eject"},
112 | {0x0b, "chase"},
113 | {0x0c, "command_error_reset"},
114 | {0x0d, "mmc_reset"}
115 | };
116 |
117 |
--------------------------------------------------------------------------------
/src/MidiManager.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // MidiManager.cpp
3 | // OSC_MIDI_OSC
4 | //
5 | // Created by Fred Rodrigues on 02/10/2023.
6 | //
7 |
8 | #include "MidiManager.h"
9 |
10 | MidiManager::MidiManager() {
11 |
12 | }
13 | void MidiManager::setup(){
14 | ofLogNotice("MidiManager") << "MidiManager setup";
15 | // Get the instance of SettingsManager
16 | SettingsManager & settingsManager = SettingsManager::getInstance();
17 |
18 | // Access the settings
19 | midiManagerSettings = settingsManager.getSettings();
20 |
21 | midiManagerSettings["allOutPorts"] = midiOut.getOutPortList();
22 | midiManagerSettings["allInPorts"] = midiIn.getInPortList();
23 |
24 | if (midiManagerSettings["useVirtualPort"]) {
25 | midiOut.openVirtualPort("OSC_MIDI_OSC_OUT");
26 | midiIn.openVirtualPort("OSC_MIDI_OSC_IN");
27 | } else {
28 | if (midiManagerSettings["midiOutDevice"].is_string()) {
29 |
30 | //Check if the port from the settings exists
31 | if (midiOut.getOutPortList().size() > 0) {
32 | for (int i = 0; i < midiOut.getOutPortList().size(); i++) {
33 | if (midiOut.getOutPortList()[i] == midiManagerSettings["midiOutDevice"]) {
34 | midiOut.openPort(string(midiManagerSettings["midiOutDevice"]));
35 | break;
36 | }
37 | //else set the port to the first available port
38 | else {
39 | midiOut.openPort(0);
40 | }
41 | }
42 | }
43 |
44 | } else if (midiManagerSettings["midiOutDevice"].is_number()) {
45 |
46 | //check if the port from the settings exists (is the number lower than the number of ports)
47 | if (midiManagerSettings["midiOutDevice"] < midiOut.getNumOutPorts()) {
48 | midiOut.openPort(int(midiManagerSettings["midiOutDevice"]));
49 | } else {
50 | midiOut.openPort(0);
51 | }
52 | }
53 |
54 | if (midiManagerSettings["midiInDevice"].is_string()) {
55 | //Check if the port from the settings exists
56 | if (midiIn.getInPortList().size() > 0) {
57 | for (int i = 0; i < midiIn.getInPortList().size(); i++) {
58 | if (midiIn.getInPortList()[i] == midiManagerSettings["midiInDevice"]) {
59 | midiIn.openPort(string(midiManagerSettings["midiInDevice"]));
60 | break;
61 | }
62 | //else set the port to the first available port
63 | else {
64 | midiIn.openPort(0);
65 | }
66 | }
67 | }
68 |
69 | } else if (midiManagerSettings["midiInDevice"].is_number()) {
70 | //check if the port from the settings exists (is the number lower than the number of ports)
71 | if (midiManagerSettings["midiInDevice"] < midiIn.getNumInPorts()) {
72 | midiIn.openPort(int(midiManagerSettings["midiInDevice"]));
73 | } else {
74 | midiIn.openPort(0);
75 | }
76 | }
77 | }
78 | midiManagerSettings["outPortLabel"] = midiOut.getName();
79 | midiManagerSettings["inPortLabel"] = midiIn.getName();
80 |
81 | settingsManager.saveSettings("MIDI_OSC_SETTINGS.json", midiManagerSettings);
82 |
83 |
84 | ofLogVerbose("MidiManager") << "MidiManager constructor called, midi out port: " + midiOut.getName() + " midi in port: " + midiIn.getName() << endl;
85 | midiIn.ignoreTypes(false, false, false);
86 | midiIn.addListener(this);
87 |
88 |
89 | }
90 | void MidiManager::close(){
91 | midiIn.closePort();
92 | midiIn.removeListener(this);
93 | midiOut.closePort();
94 | }
95 | void MidiManager::newMidiMessage(ofxMidiMessage& msg) {
96 |
97 | midiMessage = msg;
98 |
99 | SettingsManager& settingsManager = SettingsManager::getInstance();
100 |
101 | OscManager& oscManager = OscManager::getInstance();
102 | ofxOscSender& oscSend = oscManager.getOSCSender();
103 | ofxOscMessage m;
104 |
105 |
106 | if (midiMessage.status == MIDI_SYSEX) {
107 | ofLogVerbose("MidiManager::newMidiMessage") << "Sysex Message" << endl;
108 | ofLogVerbose("MidiManager::newMidiMessage") << "Message Size " + ofToString(midiMessage.bytes.size()) << endl;
109 |
110 | int deviceId = static_cast(midiMessage.bytes[2]);
111 |
112 | //Handle midi machine control messages
113 | if (midiMessage.bytes[3] == 0x06) {
114 | ofLogVerbose("MidiManager::newMidiMessage") << "Midi Machine Control Message" << endl;
115 |
116 | m.setAddress("/MMCCommand");
117 | m.addIntArg(deviceId);
118 |
119 | std::string command = getMidiMachineControlCommand(midiMessage.bytes[4]);
120 | m.addStringArg(command);
121 |
122 | message = "Received Midi Machine Control message: Command: " + command + " DeviceID: " + ofToString(deviceId);
123 |
124 | }
125 |
126 | //Handle midi show control messages
127 | if (midiMessage.bytes[3] == 0x02) {
128 | ofLogVerbose("MidiManager::newMidiMessage") << "Midi Show Control Message" << endl;
129 |
130 | m.setAddress("/MidiShowControl");
131 | m.addIntArg(deviceId);
132 |
133 |
134 | m.addStringArg(getMidiShowControTargetType(midiMessage.bytes[4]));
135 | m.addStringArg(getMidiShowControlCommandType(midiMessage.bytes[5]));
136 |
137 | for (int i = 0; i < getMidiShowControlCommandData(midiMessage).size(); i++) {
138 | m.addIntArg(getMidiShowControlCommandData(midiMessage)[i]);
139 | }
140 |
141 |
142 | string dataByteString;
143 |
144 | for (int i = 0; i < getMidiShowControlCommandData(midiMessage).size(); i++) {
145 | dataByteString += ofToString(i) + ": ";
146 | }
147 |
148 | message = "Midi Show Control Message: Command: " + ofToString(getMidiShowControlCommandType(midiMessage.bytes[5])) + " Target: " +ofToString(getMidiShowControTargetType(midiMessage.bytes[4])) + " Device ID: " + ofToString(deviceId) + " Command Data: " + dataByteString;
149 | }
150 |
151 |
152 | }
153 |
154 | if (midiMessage.channel == midiManagerSettings["midiInChannel"] ) {
155 | if (midiMessage.status == MIDI_NOTE_ON) {
156 | m.setAddress("/noteOn");
157 | m.addIntArg(midiMessage.pitch);
158 | m.addIntArg(midiMessage.velocity);
159 | message = "Received Note on Note ID: " + ofToString(midiMessage.pitch) + " With Velocity " + ofToString(midiMessage.velocity);
160 |
161 | }
162 |
163 | if (midiMessage.status == MIDI_NOTE_OFF) {
164 | m.setAddress("/noteOff");
165 | m.addIntArg(midiMessage.pitch);
166 |
167 | message = "Received Note off Note ID: " + ofToString(midiMessage.pitch);
168 | }
169 |
170 | if (midiMessage.status == MIDI_CONTROL_CHANGE) {
171 | if (midiMessage.control == 0) { // Bank Select MSB
172 | m.setAddress("/bankSelectMSB");
173 | m.addIntArg(midiMessage.value);
174 | message = "Received Bank Select MSB: " + ofToString(midiMessage.value);
175 |
176 | } else if (midiMessage.control == 32) { // Bank Select LSB
177 | m.setAddress("/bankSelectLSB");
178 | m.addIntArg(midiMessage.value);
179 | message = "Received Bank Select LSB: " + ofToString(midiMessage.value);
180 |
181 | } else {
182 | m.setAddress("/cc");
183 | m.addIntArg(midiMessage.control);
184 | m.addIntArg(midiMessage.value);
185 | message = "Received Controller ID: " + ofToString(midiMessage.control) + " Value: " + ofToString(midiMessage.value);
186 | }
187 | }
188 |
189 | if (midiMessage.status == MIDI_TIME_CODE) {
190 | m.setAddress("/MTC");
191 | m.addIntArg(midiMessage.deltatime);
192 | message = "Received MTC: " + ofToString(midiMessage.value);
193 | }
194 |
195 | if (midiMessage.status == MIDI_PROGRAM_CHANGE) {
196 | m.setAddress("/ProgramChange");
197 | m.addIntArg(midiMessage.value);
198 | message = "Received Program Change ID: " + ofToString(midiMessage.value);
199 | }
200 |
201 | if (midiMessage.status == MIDI_PITCH_BEND) {
202 | m.setAddress("/PitchBend");
203 | m.addIntArg(midiMessage.value);
204 | message = "Received pitch bend Value: " + ofToString(midiMessage.value);
205 | }
206 |
207 | if (midiMessage.status == MIDI_AFTERTOUCH) {
208 | m.setAddress("/Aftertouch");
209 | m.addIntArg(midiMessage.value);
210 | message = "Received Aftertouch Value: " + ofToString(midiMessage.value);
211 | }
212 |
213 | if (midiMessage.status == MIDI_POLY_AFTERTOUCH) {
214 | m.setAddress("/PolyAftertouch");
215 | m.addIntArg(midiMessage.value);
216 | m.addIntArg(midiMessage.pitch);
217 | message = "Received Poly Aftertouch Pitch: " + ofToString(midiMessage.pitch) + " Value: " + ofToString(midiMessage.value);
218 | }
219 | }
220 | oscSend.sendMessage(m);
221 | ofLogVerbose("MidiManager::newMidiMessage'") << message << endl;
222 | ofSendMessage(message);
223 | }
224 |
225 | std::string MidiManager::getMidiShowControTargetType(uint8_t byte) {
226 | auto it = MIDI_SHOW_CONTROL_TARGET_TYPE.find(byte);
227 |
228 | if (it != MIDI_SHOW_CONTROL_TARGET_TYPE.end()) {
229 | return it->second;
230 | } else {
231 | return "unknown";
232 | }
233 | }
234 |
235 | std::string MidiManager::getMidiShowControlCommandType(uint8_t byte) {
236 | auto it = MIDI_SHOW_CONTROL_COMMAND_TYPE.find(byte);
237 |
238 | if (it != MIDI_SHOW_CONTROL_COMMAND_TYPE.end()) {
239 | return it->second;
240 | } else {
241 | return "unknown";
242 | }
243 | }
244 |
245 | std::vector MidiManager::getMidiShowControlCommandData(ofxMidiMessage midiMessage) {
246 | // Calculate the command data length (excluding the start byte, manufacturer ID, device ID, Sub-IDs, command format, and end byte)
247 | int commandDataLength = midiMessage.bytes.size() - 7;
248 |
249 | // Create a vector to store the command data
250 | std::vector commandData;
251 | // Create a string to accumulate digits
252 | std::string numberStr;
253 |
254 | // Loop through the command data
255 | for (int i = 6; i < 6 + commandDataLength; i++) {
256 | // Check if the byte is not 0x00 (separator) and not 0xF7 (end byte)
257 | if (midiMessage.bytes[i] != 0x00 && midiMessage.bytes[i] != 0xF7) {
258 | // Accumulate digits
259 | numberStr += static_cast(midiMessage.bytes[i]);
260 | } else if (!numberStr.empty()) {
261 | // Convert the accumulated string to an integer and add to the vector
262 | commandData.push_back(std::stoi(numberStr));
263 | // Clear the accumulated string for the next number
264 | numberStr.clear();
265 | }
266 | }
267 |
268 | if (!numberStr.empty()) {
269 | commandData.push_back(std::stoi(numberStr));
270 | }
271 |
272 | return commandData;
273 | }
274 |
275 |
276 | std::string MidiManager::getMidiMachineControlCommand(uint8_t byte) {
277 | auto it = MIDI_MACHINE_CONTROL_COMMAND_TYPE.find(byte);
278 |
279 | if (it != MIDI_MACHINE_CONTROL_COMMAND_TYPE.end()) {
280 | return it->second;
281 | } else {
282 | return "unknown";
283 | }
284 | }
285 |
286 | vector MidiManager::buildMMCMessaage(int deviceID, const std::string& command) {
287 | sysexMMCMsg.clear();
288 | sysexMMCMsg.push_back(MIDI_SYSEX);
289 | sysexMMCMsg.push_back(0x7F); // Real Time Universal SysEx ID
290 | sysexMMCMsg.push_back(deviceID & 0x7F); // Device ID (limited to 7 bits)
291 | sysexMMCMsg.push_back(0x06); // MMC Command
292 |
293 | // Find the command byte from the map
294 | for (const auto& pair : MIDI_MACHINE_CONTROL_COMMAND_TYPE) {
295 | if (pair.second == command) {
296 | sysexMMCMsg.push_back(pair.first);
297 | break;
298 | }
299 | }
300 |
301 | sysexMMCMsg.push_back(MIDI_SYSEX_END);
302 |
303 | return sysexMMCMsg;
304 | }
305 |
306 | std::vector MidiManager::buildMidiShowControlMessage(int deviceID, const std::string& targetType, const std::string& commandType, const std::vector& commandData) {
307 | std::vector sysexMSCMsg;
308 |
309 | sysexMSCMsg.push_back(MIDI_SYSEX);
310 | sysexMSCMsg.push_back(0x7F); // Real Time Universal SysEx ID
311 | sysexMSCMsg.push_back(deviceID); // Device ID (limited to 7 bits)
312 | sysexMSCMsg.push_back(0x02); // Midi Show Control Command
313 |
314 | // Find the target type byte from the map
315 | for (const auto& pair : MIDI_SHOW_CONTROL_TARGET_TYPE) {
316 | if (pair.second == targetType) {
317 | sysexMSCMsg.push_back(pair.first);
318 | break;
319 | }
320 | }
321 |
322 | // Find the command type byte from the map
323 | for (const auto& pair : MIDI_SHOW_CONTROL_COMMAND_TYPE) {
324 | if (pair.second == commandType) {
325 | sysexMSCMsg.push_back(pair.first);
326 | break;
327 | }
328 | }
329 |
330 |
331 | // Add command data bytes with 0x00 separator
332 | for (int dataByte : commandData) {
333 | sysexMSCMsg.push_back('0' + dataByte); // Convert to ASCII representation
334 | sysexMSCMsg.push_back(0x00); // Separator
335 | }
336 | //remove the last separator
337 | sysexMSCMsg.pop_back();
338 |
339 | sysexMSCMsg.push_back(MIDI_SYSEX_END);
340 |
341 | return sysexMSCMsg;
342 | }
343 | //destructors
344 | MidiManager::~MidiManager() {
345 | midiIn.closePort();
346 | midiIn.removeListener(this);
347 | midiOut.closePort();
348 | ofLogVerbose("MidiManager") << "Destructor called" << endl;
349 | }
350 |
351 | void MidiManager::updateSettings(){
352 | SettingsManager & settingsManager = SettingsManager::getInstance();
353 | midiManagerSettings = settingsManager.getSettings();
354 | }
355 |
--------------------------------------------------------------------------------
/src/MidiManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // MidiManager.h
3 | // OSC_MIDI_OSC
4 | //
5 | // Created by Fred Rodrigues on 02/10/2023.
6 | //
7 |
8 |
9 | #pragma once
10 | #include
11 |
12 | #include "ofMain.h"
13 | #include "ofxMidi.h"
14 | #include "SettingsManager.h" // Include the SettingsManager header
15 | #include "OscManager.h"
16 | #include "MidiConstants.h"
17 |
18 | class MidiManager: public ofxMidiListener {
19 | public:
20 | static MidiManager& getInstance() {
21 | static MidiManager instance; // Guaranteed to be destroyed, instantiated on first use.
22 | return instance;
23 | }
24 |
25 | // Delete copy constructor and assignment operator
26 | MidiManager(MidiManager const&) = delete;
27 | void operator=(MidiManager const&) = delete;
28 | void setup();
29 | void close();
30 | ofxMidiOut& getMidiOut() { return midiOut; }
31 | ofxMidiIn& getMidiIn() { return midiIn; }
32 |
33 | // Send MIDI message
34 | void newMidiMessage(ofxMidiMessage& msg);
35 | vector sysexMMCMsg;
36 | vector buildMMCMessaage(int deviceID, const std::string& command);
37 | std::vector buildMidiShowControlMessage(int deviceID, const std::string& targetType, const std::string& commandType, const std::vector& commandData);
38 |
39 | //public destructor
40 | ~MidiManager();
41 |
42 | void updateSettings();
43 |
44 | private:
45 | MidiManager();
46 | ofxMidiOut midiOut;
47 | ofxMidiIn midiIn;
48 | ofxMidiMessage midiMessage;
49 |
50 | ofJson midiManagerSettings;
51 |
52 | string message;
53 | stringstream text;
54 | // Additional private members for MIDI management
55 |
56 | std::string getMidiMachineControlCommand(uint8_t byte);
57 |
58 | std::string getMidiShowControlCommandType(uint8_t byte);
59 | std::string getMidiShowControTargetType(uint8_t byte);
60 | uint8_t getDeviceIdByte(ofxMidiMessage midiMessage);
61 | int getMidiShowControldeviceId(uint8_t byte);
62 | std::vector getMidiShowControlCommandData(ofxMidiMessage midiMessage);
63 |
64 |
65 |
66 | };
67 |
68 |
--------------------------------------------------------------------------------
/src/OcsManager.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // OSCManager.cpp
3 | // OSC_MIDI_OSC
4 | //
5 | // Created by Fred Rodrigues on 02/10/2023.
6 | //
7 |
8 | #include "OscManager.h"
9 |
10 | OscManager::OscManager() {
11 |
12 | }
13 |
14 | void OscManager::setup() {
15 | ofLogVerbose() << "OSC Manager setup" << endl;
16 | SettingsManager & settingsManager = SettingsManager::getInstance();
17 | // Access the settings
18 | oscManagerSettings = settingsManager.getSettings();
19 |
20 | oscSender.setup(oscManagerSettings["outgoingIpOSC"], oscManagerSettings["outGoingPortOsc"]);
21 | ofLogVerbose() << "OSC Sender initialised and set to port: " << oscSender.getPort() << " With host: " << oscSender.getHost() << endl;
22 | oscReceiver.setup(oscManagerSettings["incomingPortOsc"]);
23 | ofLogVerbose() << "OSC Receiver initialised and set to port: " << oscReceiver.getPort() << endl;
24 | }
25 | void OscManager::closeReceiver(){
26 | ///oscReceiver.stop();
27 | }
28 | void OscManager::setupReceiver(){
29 | SettingsManager & settingsManager = SettingsManager::getInstance();
30 | oscManagerSettings = settingsManager.getSettings();
31 | oscReceiver.setup(oscManagerSettings["incomingPortOsc"]);
32 | ofLogVerbose() << "OSC Receiver initialised and set to port: " << oscReceiver.getPort() << endl;
33 | oscReceiver.start();
34 |
35 | }
36 | void OscManager::closeSender(){
37 | //oscSender.clear();
38 |
39 | }
40 | void OscManager::setupSender(){
41 | SettingsManager & settingsManager = SettingsManager::getInstance();
42 | oscManagerSettings = settingsManager.getSettings();
43 | oscSender.setup(oscManagerSettings["outgoingIpOSC"], oscManagerSettings["outGoingPortOsc"]);
44 | ofLogVerbose() << "OSC Sender initialised and set to port: " << oscSender.getPort() << " With host: " << oscSender.getHost() << endl;
45 |
46 | }
47 | void OscManager::handleIncomingMessages() {
48 | MidiManager& midiManager = MidiManager::getInstance();
49 | ofxMidiOut& midiOut = midiManager.getMidiOut();
50 |
51 | while (oscReceiver.hasWaitingMessages()) {
52 | ofxOscMessage m;
53 | oscReceiver.getNextMessage(m);
54 |
55 | if (m.getAddress() == "/noteOn") {
56 | if (m.getNumArgs() > 1) {
57 | midiOut.sendNoteOn(oscManagerSettings["midiOutChannel"], m.getArgAsInt32(0), m.getArgAsInt32(1));
58 | message = "Sending note on: Note ID " + ofToString(m.getArgAsInt32(0)) + " With Velocity " + ofToString(m.getArgAsInt32(1));
59 | }
60 |
61 | if (m.getNumArgs() == 1) {
62 | midiOut.sendNoteOn(oscManagerSettings["midiOutChannel"], m.getArgAsInt32(0));
63 | message = "Sending note on: Note ID " + ofToString(m.getArgAsInt32(0)) + " With Velocity " + ofToString(64);
64 | }
65 | }
66 |
67 | if (m.getAddress() == "/noteOff") {
68 | midiOut.sendNoteOff(oscManagerSettings["midiOutChannel"], m.getArgAsInt32(0));
69 | message = "Sending note off Note ID " + ofToString(m.getArgAsInt32(0));
70 | }
71 |
72 | if (m.getAddress() == "/cc") {
73 | midiOut.sendControlChange(oscManagerSettings["midiOutChannel"], m.getArgAsInt32(0), m.getArgAsInt32(1));
74 | message = "Sending cc Controller ID " + ofToString(m.getArgAsInt32(0)) + " Controller value " + ofToString(m.getArgAsInt32(1));
75 | }
76 |
77 | if (m.getAddress() == "/ProgramChange") {
78 | midiOut.sendProgramChange(oscManagerSettings["midiOutChannel"], m.getArgAsInt32(0));
79 | message = "Sending program change ID: " + ofToString(m.getArgAsInt32(0));
80 | }
81 |
82 | if (m.getAddress() == "/PitchBend") {
83 | midiOut.sendPitchBend(oscManagerSettings["midiOutChannel"], m.getArgAsInt32(0));
84 | message = "Sending pitch bend value: " + ofToString(m.getArgAsInt32(0));
85 | }
86 |
87 | if (m.getAddress() == "/Aftertouch") {
88 | midiOut.sendAftertouch(oscManagerSettings["midiOutChannel"], m.getArgAsInt32(0));
89 | message = "Sending aftertouch Value: " + ofToString(m.getArgAsInt32(0));
90 | }
91 |
92 | if (m.getAddress() == "/PolyAftertouch") {
93 | midiOut.sendPolyAftertouch(oscManagerSettings["midiOutChannel"], m.getArgAsInt32(0), m.getArgAsInt32(1));
94 | message = "Sending poly aftertouch Note: " + ofToString(m.getArgAsInt32(0)) + " value " + ofToString(m.getArgAsInt32(1));
95 | }
96 |
97 | if (m.getAddress() == "/MMCCommand") {
98 | int deviceId = m.getArgAsInt32(0);
99 | std::string command = m.getArgAsString(1);
100 |
101 | // Convert the command string back to its corresponding MMC byte
102 | uint8_t commandByte = 0x00;
103 | for (const auto& pair : MIDI_MACHINE_CONTROL_COMMAND_TYPE) {
104 | if (pair.second == command) {
105 | commandByte = pair.first;
106 | break;
107 | }
108 | }
109 | std::vector midiBytes = midiManager.buildMMCMessaage(deviceId, command);
110 | midiOut.sendMidiBytes(midiBytes);
111 | message = "Sending MMC Command: " + command + " DeviceID: " + ofToString(deviceId);
112 | }
113 | if(m.getAddress() == "/MidiShowControl"){
114 |
115 | //iterate through the arguments
116 | //first int argument is device id
117 | //first string argument is command
118 | //second string argument is command format
119 | //remaining int arguments are command data
120 | std::vector integerPositions;
121 | std::vector stringPositions;
122 | for (int i = 0; i commandData;
135 | for (int i = 2; i < integerPositions.size(); i++) {
136 | commandData.push_back(m.getArgAsInt32(integerPositions[i]));
137 | }
138 |
139 |
140 | std::vector midiBytes = midiManager.buildMidiShowControlMessage(deviceId, command, commandFormat, commandData);
141 | midiOut.sendMidiBytes(midiBytes);
142 | message = "Sending MSC Command: " + command + " DeviceID: " + ofToString(deviceId);
143 |
144 | }
145 |
146 |
147 | ofSendMessage(message);
148 | }
149 | }
150 |
151 | //destructor
152 | OscManager::~OscManager() {
153 | oscSender.clear();
154 |
155 |
156 |
157 | ofLogVerbose() << "OSC Manager destructor called" << endl;
158 | }
159 | void OscManager::updateSettings(){
160 | SettingsManager & settingsManager = SettingsManager::getInstance();
161 | oscManagerSettings = settingsManager.getSettings();
162 | }
163 |
--------------------------------------------------------------------------------
/src/OscManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // OSCManager.h
3 | // OSC_MIDI_OSC
4 | //
5 | // Created by Fred Rodrigues on 02/10/2023.
6 | //
7 |
8 | #pragma once
9 | #include "ofMain.h"
10 | #include "ofxOsc.h"
11 | #include "MidiManager.h"
12 | #include "SettingsManager.h" // Include the SettingsManager header
13 |
14 | class OscManager {
15 | public:
16 | static OscManager& getInstance() {
17 | static OscManager instance; // Guaranteed to be destroyed, instantiated on first use.
18 | return instance;
19 | }
20 |
21 | // Delete copy and move constructors and assignment operators
22 | OscManager(OscManager const&) = delete;
23 | OscManager(OscManager&&) = delete;
24 | void operator=(OscManager const&) = delete;
25 | void operator=(OscManager&&) = delete;
26 |
27 | void setup();
28 | void closeReceiver();
29 | void setupReceiver();
30 | void closeSender();
31 | void setupSender();
32 |
33 | ofxOscSender& getOSCSender() { return oscSender; }
34 | ofxOscReceiver& getOscReciever() { return oscReceiver; }
35 |
36 | void handleIncomingMessages();
37 |
38 | //public destructor
39 | ~OscManager();
40 | void updateSettings();
41 |
42 | private:
43 | OscManager(); // Constructor is private now
44 |
45 | ofJson oscManagerSettings;
46 | string message;
47 | ofxOscSender oscSender;
48 | ofxOscReceiver oscReceiver;
49 | };
50 |
--------------------------------------------------------------------------------
/src/SettingsManager.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // SettingsManager.cpp
3 | // OSC_MIDI_OSC
4 | //
5 | // Created by Fred Rodrigues on 02/10/2023.
6 | //
7 |
8 | #include "SettingsManager.h"
9 |
10 | SettingsManager::SettingsManager() {
11 | // Constructor code
12 | setDefaultSettings();
13 | }
14 |
15 |
16 | void SettingsManager::loadSettings(const std::string& filename) {
17 | if (ofFile::doesFileExist(filename)) {
18 | settings = ofLoadJson(filename);
19 |
20 | if (!settings["Log_level"].is_null()) {
21 | ofLogVerbose("loadSettings") << "Log level set to " << settings["Log_level"] << endl;
22 | ofSetLogLevel(settings["Log_level"]);
23 | } else {
24 | settings["Log_level"] = OF_LOG_VERBOSE;
25 | ofLogVerbose("loadSettings fallback") << "Log level set to " << settings["Log_level"] << endl;
26 | }
27 |
28 | #ifdef TARGET_OSX
29 |
30 | if (!settings["useVirtualPort"].is_null()) {
31 | ofLogVerbose("loadSettings") << "useVirtualPort set to " << settings["useVirtualPort"] << endl;
32 | } else {
33 | settings["useVirtualPort"] = true;
34 | ofLogVerbose("loadSettings fallback") << "useVirtualPort set to " << settings["useVirtualPort"] << endl;
35 | }
36 |
37 | #else
38 | settings["useVirtualPort"] = false;
39 | ofLogVerbose("loadSettings") << "useVirtualPort, unavailable on windows, now set to " << settings["useVirtualPort"] << endl;
40 | #endif
41 |
42 | if (!settings["midiInDevice"].is_null()) {
43 | if (settings["midiInDevice"].is_number()) {
44 | settings["midiInDeviceByString"] = false;
45 | ofLogVerbose("loadSettings") << "midiInDevice set to number: " << settings["midiInDeviceNum"] << endl;
46 | } else if (settings["midiInDevice"].is_string()) {
47 | settings["midiInDeviceByString"] = true;
48 | ofLogVerbose("loadSettings") << "midiInDevice set to string: " << settings["midiInDeviceName"] << endl;
49 | }
50 | } else {
51 | settings["midiInDeviceByString"] = false;
52 | settings["midiInDevice"] = 0;
53 | ofLogVerbose("loadSettings") << "midiInDevice set to number" << settings["midiInDevice"] << endl;
54 | }
55 |
56 | if (!settings["midiOutDevice"].is_null()) {
57 | if (settings["midiOutDevice"].is_number()) {
58 | settings["midiOutDeviceByString"] = false;
59 | ofLogVerbose("loadSettings") << "midiOutDevice set to number: " << settings["midiOutDeviceNum"] << endl;
60 | } else if (settings["midiOutDevice"].is_string()) {
61 | settings["midiOutDeviceByString"] = true;
62 | ofLogVerbose("loadSettings") << "midiOutDevice set to string: " << settings["midiOutDeviceName"] << endl;
63 | }
64 | } else {
65 | settings["midiOutDeviceByString"] = false;
66 | settings["midiOutDevice"] = 0;
67 | ofLogVerbose("loadSettings") << "midiOutDevice set to " << settings["midiOutDevice"] << endl;
68 | }
69 |
70 | if (!settings["midiOutChannel"].is_null()) {
71 | ofLogVerbose("loadSettings") << "midiOutChannel set to " << settings["midiOutChannel"] << endl;
72 | } else {
73 | settings["midiOutChannel"] = 1;
74 | ofLogVerbose("loadSettings fallback") << "midiOutChannel set to " << settings["midiOutChannel"] << endl;
75 | }
76 |
77 | if (!settings["midiInChannel"].is_null()) {
78 | ofLogVerbose("loadSettings") << "midiInChannel set to " << settings["midiInChannel"] << endl;
79 | } else {
80 | settings["midiInChannel"] = 1;
81 | ofLogVerbose("loadSettings fallback") << "midiInChannel set to " << settings["midiInChannel"] << endl;
82 | }
83 |
84 | //set the incomingPortOsc from the settings
85 | if (!settings["incomingPortOsc"].is_null()) {
86 | ofLogVerbose("loadSettings") << "incomingPortOsc set to " << settings["incomingPortOsc"] << endl;
87 | } else {
88 | settings["incomingPortOsc"] = 12345;
89 | ofLogVerbose("loadSettings fallback") << "incomingPortOsc set to " << settings["incomingPortOsc"] << endl;
90 | }
91 |
92 | if (!settings["outGoingPortOsc"].is_null()) {
93 | ofLogVerbose("loadSettings") << "outGoingPortOsc set to " << settings["outGoingPortOsc"] << endl;
94 | } else {
95 | settings["outGoingPortOsc"] = 1234;
96 | ofLogVerbose("loadSettings fallback") << "outGoingPortOsc set to " << settings["outGoingPortOsc"] << endl;
97 | }
98 |
99 | if (!settings["outgoingIpOSC"].is_null()) {
100 | ofLogVerbose("loadSettings") << "outgoingIpOSC set to " << settings["outgoingIpOSC"] << endl;
101 | } else {
102 | settings["outgoingIpOSC"] = "127.0.0.1";
103 | ofLogVerbose("loadSettings fallback") << "outgoingIpOSC set to " << settings["outgoingIpOSC"] << endl;
104 | }
105 |
106 | if (!settings["frameRate"].is_null()) {
107 | ofLogVerbose("loadSettings") << "frameRate set to " << settings["frameRate"] << endl;
108 | } else {
109 | settings["frameRate"] = 25;
110 | }
111 | } else {
112 | ofLogError("SettingsManager::LoadSettings") << "Settings file not found: " << filename;
113 | setDefaultSettings();
114 | }
115 | }
116 |
117 | ofJson SettingsManager::getSettings() const {
118 | return settings;
119 | }
120 |
121 | void SettingsManager::setDefaultSettings() {
122 | ofLogVerbose("SettingsManager::setDefaultSettings") << "Loading defualt settings" << endl;
123 |
124 | settings["Log_level"] = OF_LOG_VERBOSE;
125 | ofLogVerbose("SettingsManager::setDefaultSettings") << "Log level set to " << settings["Log_level"] << endl;
126 |
127 | #ifdef TARGET_OSX
128 | settings["useVirtualPort"] = true;
129 | #else
130 | settings["useVirtualPort"] = false;
131 | #endif
132 | ofLogVerbose("SettingsManager::setDefaultSettings") << "useVirtualPort set to " << settings["useVirtualPort"] << endl;
133 |
134 | settings["incomingPortOsc"] = 12345;
135 | ofLogVerbose("SettingsManager::setDefaultSettings") << "incomingPortOsc set to " << settings["incomingPortOsc"] << endl;
136 |
137 | settings["outGoingPortOsc"] = 1234;
138 | ofLogVerbose("SettingsManager::setDefaultSettings") << "outGoingPortOsc set to " << settings["outGoingPortOsc"] << endl;
139 |
140 | settings["outgoingIpOSC"] = "127.0.0.1";
141 | ofLogVerbose("SettingsManager::setDefaultSettings") << "outgoingIpOSC set to " << settings["outgoingIpOSC"] << endl;
142 |
143 | settings["midiInDevice"] = 0;
144 | ofLogVerbose("SettingsManager::setDefaultSettings") << "midiInDevice set to " << settings["midiInDevice"] << endl;
145 |
146 | settings["midiOutDevice"] = 0;
147 | ofLogVerbose("SettingsManager::setDefaultSettings") << "midiOutDevice set to " << settings["midiOutDevice"] << endl;
148 |
149 | settings["midiOutChannel"] = 1;
150 | ofLogVerbose("SettingsManager::setDefaultSettings") << "midiOutChannel set to " << settings["midiOutChannel"] << endl;
151 |
152 |
153 | settings["midiInChannel"] = 1;
154 | ofLogVerbose("SettingsManager::setDefaultSettings") << "midiInChannel set to " << settings["midiInChannel"] << endl;
155 |
156 | settings["frameRate"] = 25;
157 | ofLogVerbose("SettingsManager::setDefaultSettings") << "frameRate set to " << settings["frameRate"] << endl;
158 | }
159 |
160 | void SettingsManager::saveSettings(const std::string& filename, ofJson remoteSettings){
161 | settings = remoteSettings;
162 |
163 | ofLogVerbose("SettingsManager::saveSettings") << "Saving settings to " << filename << endl;
164 | ofSavePrettyJson(filename, settings);
165 | }
166 |
167 | void SettingsManager::updateSettings(ofJson remoteSettings){
168 | settings = remoteSettings;
169 | ofLogVerbose("SettingsManager::updateSettings") << "Settings updated" << endl;
170 | }
171 | //public destructor
172 | SettingsManager::~SettingsManager() {
173 | // Destructor code
174 | }
175 |
--------------------------------------------------------------------------------
/src/SettingsManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // SettingsManager.h
3 | // OSC_MIDI_OSC
4 | //
5 | // Created by Fred Rodrigues on 02/10/2023.
6 | //
7 |
8 | #pragma once
9 | #include
10 | #include "ofMain.h"
11 |
12 | class SettingsManager {
13 | public:
14 | static SettingsManager& getInstance() {
15 | static SettingsManager instance; // Guaranteed to be destroyed, instantiated on first use.
16 | return instance;
17 | }
18 |
19 | ~SettingsManager(); // Private destructor
20 |
21 | void loadSettings(const std::string& filename);
22 | ofJson getSettings() const;
23 |
24 | // Delete copy constructor and assignment operator
25 | SettingsManager(SettingsManager const&) = delete;
26 | void operator=(SettingsManager const&) = delete;
27 |
28 | void saveSettings(const std::string& filename, ofJson remoteSettings);
29 | void updateSettings(ofJson remoteSettings);
30 |
31 | private:
32 | SettingsManager(); // Private constructor
33 |
34 | ofJson settings;
35 |
36 | void setDefaultSettings();
37 | };
38 |
39 |
--------------------------------------------------------------------------------
/src/colours.h:
--------------------------------------------------------------------------------
1 | //
2 | // colours.h
3 | // OSC_MIDI_OSC
4 | //
5 | // Created by Fred Rodrigues on 03/10/2023.
6 | //
7 |
8 | #pragma once
9 |
10 | #include "ofMain.h"
11 |
12 | class Colours {
13 | public:
14 |
15 | ofColor background = ofColor::fromHex(0xEBEDFF);
16 | ofColor text = ofColor::fromHex(0x1B2CC1);
17 | ofColor button = ofColor::fromHex(0x1B2CC1);
18 | ofColor buttonActive = ofColor::fromHex(0xFF499E);
19 | ofColor buttonHover = ofColor::fromHex(0xFF499E);
20 | ofColor buttonOutline = ofColor::fromHex(0x1B2CC1);
21 | ofColor buttonOutlineHover = ofColor::fromHex(0xFF499E);
22 | ofColor buttonOutlineActive = ofColor::fromHex(0xFF499E);
23 |
24 | };
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/src/main.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include "ofMain.h"
3 | #include "ofApp.h"
4 |
5 |
6 | #ifdef TARGET_WIN32
7 |
8 | #define IDI_ICON1 101
9 |
10 | #endif
11 |
12 | //========================================================================
13 | int main( ){
14 |
15 | //Use ofGLFWWindowSettings for more options like multi-monitor fullscreen
16 | ofGLWindowSettings settings;
17 | settings.setSize(750, 210);
18 | settings.windowMode = OF_WINDOW; //can also be OF_FULLSCREEN
19 |
20 | auto window = ofCreateWindow(settings);
21 |
22 | #ifdef TARGET_WIN32
23 | HWND hwnd = ofGetWin32Window();
24 | // Load and set the application icon
25 | HICON hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1));
26 | SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon); // Set the large icon
27 | SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon); // Set the small icon
28 | #endif
29 | ofRunApp(window, std::make_shared());
30 | ofRunMainLoop();
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/modes/ConversionMode.cpp:
--------------------------------------------------------------------------------
1 |
2 | //
3 | // ConversionMode.cpp
4 | // OSC_MIDI_OSC
5 | //
6 | // Created by Fred Rodrigues on 02/10/2023.
7 | //
8 |
9 | #include "ConversionMode.h"
10 |
11 | ConversionMode::ConversionMode(ofTrueTypeFont & fontRef, ofJson & settingsRef, Colours & coloursRef)
12 | : Mode(fontRef, settingsRef, coloursRef) {
13 | goToMidiOutSetMode.setup("Midi out setup", "BTN_MSG_GOTOMODE_MODE_SETTING_MIDI_OUT");
14 | goToMidiOutSetMode.set(30, 175, 140, 20);
15 | goToMidiOutSetMode.disableAllEvents();
16 |
17 | goToMidiInSetMode.setup("Midi in setup", "BTN_MSG_GOTOMODE_MODE_SETTING_MIDI_IN");
18 | goToMidiInSetMode.set(200, 175, 140, 20);
19 | goToMidiInSetMode.disableAllEvents();
20 |
21 | gotToOSCOutSetMode.setup("OSC out setup", "BTN_MSG_GOTOMODE_MODE_SETTING_OSC_OUT");
22 | gotToOSCOutSetMode.set(370, 175, 140, 20);
23 | gotToOSCOutSetMode.disableAllEvents();
24 |
25 | goToOSCInSetMode.setup("OSC in setup", "BTN_MSG_GOTOMODE_MODE_SETTING_OSC_IN");
26 | goToOSCInSetMode.set(540, 175, 140, 20);
27 | goToOSCInSetMode.disableAllEvents();
28 | ofLogVerbose("ConversionMode::ConversionMode");
29 | }
30 |
31 | ConversionMode::~ConversionMode() { }
32 |
33 | void ConversionMode::setup() {
34 | ofLogVerbose("ConversionMode::setup");
35 |
36 | goToMidiOutSetMode.enableAllEvents();
37 | goToMidiInSetMode.enableAllEvents();
38 | gotToOSCOutSetMode.enableAllEvents();
39 | goToOSCInSetMode.enableAllEvents();
40 |
41 | ofAddListener(ofEvents().keyPressed, this, &ConversionMode::_keyPressed);
42 | ofRegisterGetMessages(this);
43 | }
44 |
45 | void ConversionMode::draw() {
46 |
47 | ofSetColor(colours.text);
48 | font.drawString("Conversion active", 10, 15);
49 | font.drawString(activityMessage, 10, 35);
50 | font.drawString("Midi input on port " + settings["inPortLabel"].get() + " Channel: " + ofToString(settings["midiInChannel"]), 10, 55);
51 | font.drawString("Midi output on port " + settings["outPortLabel"].get() + " Channel: " + ofToString(settings["midiOutChannel"]), 10, 75);
52 | font.drawString("Osc input on port " + ofToString(settings["incomingPortOsc"]), 10, 95);
53 | font.drawString("Osc output on port " + ofToString(settings["outGoingPortOsc"]), 10, 115);
54 | font.drawString("Osc output to host " + settings["outgoingIpOSC"].get(), 10, 135);
55 | }
56 |
57 | void ConversionMode::update() {
58 | // oscManager.handleIncomingMessages();
59 |
60 | }
61 |
62 | void ConversionMode::exit() {
63 | goToMidiOutSetMode.disableAllEvents();
64 | goToMidiInSetMode.disableAllEvents();
65 | gotToOSCOutSetMode.disableAllEvents();
66 | goToOSCInSetMode.disableAllEvents();
67 | ofRemoveListener(ofEvents().keyPressed, this, &ConversionMode::_keyPressed);
68 | ofUnregisterGetMessages(this);
69 | }
70 |
71 |
72 | void ConversionMode::_keyPressed(ofKeyEventArgs & e) {
73 | int key = e.key;
74 | keyPressed(key);
75 | }
76 |
77 | void ConversionMode::gotMessage(ofMessage & msg) {
78 | ofLogVerbose("ConversionMode::ofGetMessage");
79 |
80 | if (msg.message.substr(0, 3) != "BTN") {
81 | activityMessage = msg.message;
82 | }
83 | }
84 |
85 |
--------------------------------------------------------------------------------
/src/modes/ConversionMode.h:
--------------------------------------------------------------------------------
1 |
2 | //
3 | // ConversionMode.h
4 | // OSC_MIDI_OSC
5 | //
6 | // Created by Fred Rodrigues on 02/10/2023.
7 | //
8 | #pragma once
9 |
10 | #include "modes/Mode.h"
11 | #include
12 |
13 | class ConversionMode : public Mode {
14 | private:
15 | std::string title;
16 | std::string activityMessage = "Waiting for input......";
17 |
18 | public:
19 | ConversionMode(ofTrueTypeFont & fontRef, ofJson & settingsRef, Colours & coloursRef);
20 | ~ConversionMode();
21 |
22 | void setup() override;
23 | void draw() override;
24 | void update() override;
25 | void exit() override;
26 | void keyPressed(int key) override{ }
27 | void gotMessage(ofMessage & msg);
28 |
29 | void _keyPressed(ofKeyEventArgs & e);
30 |
31 | simpleButton goToMidiOutSetMode;
32 | simpleButton goToMidiInSetMode;
33 | simpleButton gotToOSCOutSetMode;
34 | simpleButton goToOSCInSetMode;
35 |
36 | };
37 |
--------------------------------------------------------------------------------
/src/modes/MidiInSetupMode.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // MidiInSetupMode.cpp
3 | // OSC_MIDI_OSC
4 | //
5 | // Created by Fred Rodrigues on 02/10/2023.
6 | //
7 |
8 | #include "MidiInSetupMode.h"
9 |
10 |
11 | MidiInSetupMode::MidiInSetupMode(ofTrueTypeFont & fontRef, ofJson & settingsRef, Colours & coloursRef)
12 | : Mode(fontRef, settingsRef, coloursRef) {
13 | saveMidiInPortSettings.setup("Set midi in port", "BTN_MSG_MIDI_IN_PORT_SET");
14 | saveMidiInPortSettings.set(30, 175, 140, 20);
15 | saveMidiInPortSettings.disableAllEvents();
16 |
17 | saveMidiInChannelSettings.setup("Set midi in channel", "BTN_MSG_MIDI_IN_CHANNEL_SET");
18 | saveMidiInChannelSettings.set(200, 175, 140, 20);
19 | saveMidiInChannelSettings.disableAllEvents();
20 |
21 | GoToConversionMode.setup("Exit settings", "BTN_MSG_GOTOMODE_MODE_CONVERSION");
22 | GoToConversionMode.set(370, 175, 135, 20);
23 | GoToConversionMode.disableAllEvents();
24 | }
25 |
26 | MidiInSetupMode::~MidiInSetupMode() {}
27 |
28 | void MidiInSetupMode::setup() {
29 |
30 | saveMidiInPortSettings.enableAllEvents();
31 | saveMidiInChannelSettings.enableAllEvents();
32 | GoToConversionMode.enableAllEvents();
33 | ofAddListener(ofEvents().keyPressed, this, &MidiInSetupMode::_keyPressed);
34 | }
35 |
36 | void MidiInSetupMode::draw() {
37 | ofSetColor(colours.text);
38 |
39 | font.drawString(title, 10, 15);
40 | font.drawString("Use the up & down keys to set the port and the < and > to set the channel", 10, 35);
41 |
42 | // Draw the list of ports and highlight the selected one
43 | for (int i = 0; i < settings["allInPorts"].size(); i++) {
44 | ofPushStyle();
45 |
46 | if (settings["allInPorts"][i] == settings["inPortLabel"]) {
47 | ofSetColor(colours.buttonActive);
48 | } else {
49 | ofSetColor(colours.text);
50 | }
51 |
52 | font.drawString(settings["allInPorts"][i], 10, 55 + (i * 20));
53 | ofPopStyle();
54 | }
55 |
56 | // Draw the midi channel to the right of these messages
57 | ofSetColor(colours.text);
58 | font.drawString("Midi channel set to: ", 320, 55);
59 | ofSetColor(colours.buttonActive);
60 | int xPos = font.getStringBoundingBox("Midi channel set to: ", 320, 55).x + font.getStringBoundingBox("Midi channel set to: ", 320, 55).width;
61 | font.drawString( ofToString(settings["midiInChannel"]), xPos, 55);
62 | }
63 |
64 | void MidiInSetupMode::update() {
65 | // Implementation
66 | }
67 |
68 | void MidiInSetupMode::exit() {
69 | saveMidiInPortSettings.disableAllEvents();
70 | saveMidiInChannelSettings.disableAllEvents();
71 | GoToConversionMode.disableAllEvents();
72 | ofRemoveListener(ofEvents().keyPressed, this, &MidiInSetupMode::_keyPressed);
73 | }
74 |
75 | void MidiInSetupMode::_keyPressed(ofKeyEventArgs & e) {
76 | int key = e.key;
77 |
78 | if (key == OF_KEY_DOWN) {
79 | selectPort(settings["allInPorts"], settings["inPortLabel"], 1);
80 | }
81 |
82 | if (key == OF_KEY_UP) {
83 | selectPort(settings["allInPorts"], settings["inPortLabel"], -1);
84 | }
85 |
86 | if (key == OF_KEY_LEFT) {
87 | selectChannel(settings["midiInChannel"], -1);
88 | }
89 |
90 | if (key == OF_KEY_RIGHT) {
91 | selectChannel(settings["midiInChannel"], 1);
92 | }
93 | }
94 |
95 | void MidiInSetupMode::selectPort(ofJson & ports, ofJson & currentPort, int direction) {
96 | for (int i = 0; i < ports.size(); i++) {
97 | if (ports[i] == currentPort) {
98 | int newIndex = ofClamp(i + direction, 0, ports.size() - 1);
99 | currentPort = ports[newIndex];
100 | break;
101 | }
102 | }
103 | }
104 |
105 | void MidiInSetupMode::selectChannel(ofJson & channel, int direction) {
106 | int newChannel = ofClamp(channel.get() + direction, 1, 16);
107 |
108 | channel = newChannel;
109 | }
110 | void MidiInSetupMode::saveMidiInPort(){
111 | settings["midiInDeviceName"] = settings["inPortLabel"];
112 | settings["midiInDevice"] = settings["inPortLabel"];
113 | settings["midiInDeviceByString"] = true;
114 |
115 |
116 | }
117 |
118 | void MidiInSetupMode::saveMidiInChannel(){
119 | settings["midiInChannel"];
120 | }
121 |
--------------------------------------------------------------------------------
/src/modes/MidiInSetupMode.h:
--------------------------------------------------------------------------------
1 | //
2 | // MidiInSetupMode.h
3 | // OSC_MIDI_OSC
4 | //
5 | // Created by Fred Rodrigues on 02/10/2023.
6 | //
7 |
8 |
9 | #pragma once
10 |
11 | #include
12 | #include "modes/Mode.h"
13 |
14 | class MidiInSetupMode : public Mode {
15 | private:
16 | std::string title = "MIDI in setup";
17 |
18 |
19 | public:
20 | MidiInSetupMode(ofTrueTypeFont & fontRef, ofJson & settingsRef, Colours & coloursRef);
21 | ~MidiInSetupMode();
22 |
23 | void setup() override;
24 | void draw() override;
25 | void update() override;
26 | void exit() override;
27 | void keyPressed(int key)override { }
28 |
29 | void _keyPressed(ofKeyEventArgs & e);
30 | simpleButton saveMidiInPortSettings;
31 | simpleButton saveMidiInChannelSettings;
32 | simpleButton GoToConversionMode;
33 | void selectPort(ofJson & ports, ofJson & currentPort, int direction);
34 | void selectChannel(ofJson & channel, int direction);
35 | void saveMidiInPort();
36 | void saveMidiInChannel();
37 |
38 | };
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/src/modes/MidiOutSetupMode.cpp:
--------------------------------------------------------------------------------
1 |
2 | //
3 | // MidiOutSetupMode.cpp
4 | // OSC_MIDI_OSC
5 | //
6 | // Created by Fred Rodrigues on 02/10/2023.
7 | //
8 |
9 | #include "MidiOutSetupMode.h"
10 |
11 | MidiOutSetupMode::MidiOutSetupMode(ofTrueTypeFont & fontRef, ofJson & settingsRef, Colours & coloursRef)
12 | : Mode(fontRef, settingsRef, coloursRef) {
13 | saveMidiOutPortSettings.setup("Set midi out port", "BTN_MSG_MIDI_OUT_PORT_SET");
14 | saveMidiOutPortSettings.set(30, 175, 140, 20);
15 | saveMidiOutPortSettings.disableAllEvents();
16 |
17 | saveMidiOutChannelSettings.setup("Set midi out channel", "BTN_MSG_MIDI_OUT_CHANNEL_SET");
18 | saveMidiOutChannelSettings.set(200, 175, 140, 20);
19 | saveMidiOutChannelSettings.disableAllEvents();
20 |
21 | GoToConversionMode.setup("Exit settings", "BTN_MSG_GOTOMODE_MODE_CONVERSION");
22 | GoToConversionMode.set(370, 175, 140, 20);
23 | GoToConversionMode.disableAllEvents();
24 | }
25 |
26 | MidiOutSetupMode::~MidiOutSetupMode() { }
27 |
28 | void MidiOutSetupMode::setup() {
29 |
30 | saveMidiOutPortSettings.enableAllEvents();
31 | saveMidiOutChannelSettings.enableAllEvents();
32 | GoToConversionMode.enableAllEvents();
33 | ofAddListener(ofEvents().keyPressed, this, &MidiOutSetupMode::_keyPressed);
34 | }
35 |
36 | void MidiOutSetupMode::draw() {
37 | ofSetColor(colours.text);
38 |
39 | font.drawString(title, 10, 15);
40 | font.drawString("Use the up & down keys to set the port and the < and > to set the channel", 10, 35);
41 |
42 | // Draw the list of ports and highlight the selected one
43 | for (int i = 0; i < settings["allOutPorts"].size(); i++) {
44 | ofPushStyle();
45 |
46 | if (settings["allOutPorts"][i] == settings["outPortLabel"]) {
47 | ofSetColor(colours.buttonActive);
48 | } else {
49 | ofSetColor(colours.text);
50 |
51 | }
52 |
53 | font.drawString(settings["allOutPorts"][i], 10, 55 + (i * 15));
54 | ofPopStyle();
55 | }
56 |
57 | // Draw the midi channel to the right of these messages
58 | ofSetColor(colours.text);
59 | // we want to draw this string font.drawString("Midi channel set to: " + ofToString(settings["midiOutChannel"]), 320, 55) but the ofToString(settings["midiOutChannel"]) part should be a different colour
60 | font.drawString("Midi channel set to: ", 320, 55);
61 | ofSetColor(colours.buttonActive);
62 | int xPos = font.getStringBoundingBox("Midi channel set to: ", 320, 55).x + font.getStringBoundingBox("Midi channel set to: ", 320, 55).width;
63 | font.drawString( ofToString(settings["midiOutChannel"]), xPos, 55);
64 |
65 |
66 |
67 |
68 |
69 |
70 | //font.drawString("Midi channel set to: " + ofToString(settings["midiOutChannel"]), 320, 55);
71 | }
72 |
73 | void MidiOutSetupMode::update() {
74 | // Implementation
75 | }
76 |
77 | void MidiOutSetupMode::exit() {
78 | saveMidiOutPortSettings.disableAllEvents();
79 | saveMidiOutChannelSettings.disableAllEvents();
80 | GoToConversionMode.disableAllEvents();
81 | ofRemoveListener(ofEvents().keyPressed, this, &MidiOutSetupMode::_keyPressed);
82 | }
83 |
84 | void MidiOutSetupMode::_keyPressed(ofKeyEventArgs & e) {
85 | int key = e.key;
86 |
87 | if (key == OF_KEY_DOWN) {
88 | selectPort(settings["allOutPorts"], settings["outPortLabel"], 1);
89 | }
90 |
91 | if (key == OF_KEY_UP) {
92 | selectPort(settings["allOutPorts"], settings["outPortLabel"], -1);
93 | }
94 |
95 | if (key == OF_KEY_LEFT) {
96 | selectChannel(settings["midiOutChannel"], -1);
97 | }
98 |
99 | if (key == OF_KEY_RIGHT) {
100 | selectChannel(settings["midiOutChannel"], 1);
101 | }
102 | }
103 |
104 | void MidiOutSetupMode::selectPort(ofJson & ports, ofJson & currentPort, int direction) {
105 | for (int i = 0; i < ports.size(); i++) {
106 | if (ports[i] == currentPort) {
107 | int newIndex = ofClamp(i + direction, 0, ports.size() - 1);
108 | currentPort = ports[newIndex];
109 | break;
110 | }
111 | }
112 | }
113 |
114 | // Helper function to handle channel selection
115 | void MidiOutSetupMode::selectChannel(ofJson & channel, int direction) {
116 | int newChannel = ofClamp(channel.get() + direction, 1, 16);
117 |
118 | channel = newChannel;
119 | }
120 |
--------------------------------------------------------------------------------
/src/modes/MidiOutSetupMode.h:
--------------------------------------------------------------------------------
1 | //
2 | // MidiOutSetupMode.h
3 | // OSC_MIDI_OSC
4 | //
5 | // Created by Fred Rodrigues on 02/10/2023.
6 | //
7 |
8 | #include "modes/Mode.h"
9 | #include
10 |
11 | class MidiOutSetupMode : public Mode {
12 | private:
13 | std::string title = "MIDI out setup";;
14 |
15 | public:
16 | MidiOutSetupMode(ofTrueTypeFont & fontRef, ofJson & settingsRef, Colours & coloursRef);
17 | ~MidiOutSetupMode();
18 |
19 | void setup() override;
20 | void draw() override;
21 | void update() override;
22 | void exit() override;
23 | void keyPressed(int key) override{ }
24 |
25 | void _keyPressed(ofKeyEventArgs & e);
26 | simpleButton saveMidiOutPortSettings;
27 | simpleButton saveMidiOutChannelSettings;
28 | simpleButton GoToConversionMode;
29 |
30 | void selectPort(ofJson & ports, ofJson & currentPort, int direction);
31 | void selectChannel(ofJson & channel, int direction);
32 | };
33 |
--------------------------------------------------------------------------------
/src/modes/Mode.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Mode.cpp
3 | // OSC_MIDI_OSC
4 | //
5 | // Created by Fred Rodrigues on 02/10/2023.
6 | //
7 |
8 | #include "Mode.h"
9 |
10 | Mode::Mode(ofTrueTypeFont & fontRef, ofJson & settingsRef, Colours & coloursRef)
11 | : font(fontRef)
12 | , settings(settingsRef)
13 | , colours(coloursRef) {
14 | }
15 |
16 | Mode::~Mode() {
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/src/modes/Mode.h:
--------------------------------------------------------------------------------
1 | //
2 | // Mode.h
3 | // OSC_MIDI_OSC
4 | //
5 | // Created by Fred Rodrigues on 02/10/2023.
6 | //
7 |
8 | #pragma once
9 |
10 | #include "ofMain.h"
11 | #include "stdio.h"
12 | #include "simpleButton.h"
13 | #include "colours.h"
14 |
15 | class Mode {
16 | protected:
17 | ofTrueTypeFont & font;
18 | ofJson & settings;
19 | std::string title;
20 | Colours & colours;
21 |
22 |
23 | public:
24 | Mode(ofTrueTypeFont & fontRef, ofJson & settingsRef, Colours & coloursRef);
25 | virtual ~Mode();
26 |
27 | virtual void setup() = 0;
28 | virtual void draw() = 0;
29 | virtual void update() = 0;
30 | virtual void exit() = 0;
31 | virtual void keyPressed(int key) = 0;
32 |
33 | };
34 |
--------------------------------------------------------------------------------
/src/modes/ModeManager.cpp:
--------------------------------------------------------------------------------
1 |
2 | //
3 | // ModeManager.cpp
4 | // OSC_MIDI_OSC
5 | //
6 | // Created by Fred Rodrigues on 02/10/2023.
7 | //
8 |
9 | #include "ModeManager.h"
10 |
11 | ModeManager::ModeManager() {
12 | // Constructor implementation (if needed)
13 | }
14 |
15 | ModeManager::~ModeManager() {
16 | // Destructor implementation (if needed)
17 | }
18 |
19 | void ModeManager::setMode(std::shared_ptr newMode) {
20 | if (currentMode) {
21 | currentMode->exit();
22 | }
23 |
24 | currentMode = newMode;
25 | currentMode->setup();
26 | }
27 |
28 | void ModeManager::update() {
29 | if (currentMode) {
30 | currentMode->update();
31 | }
32 | }
33 |
34 | void ModeManager::draw() {
35 | if (currentMode) {
36 | currentMode->draw();
37 | }
38 | }
39 |
40 | void ModeManager::keyPressed(int key) {
41 | if (currentMode) {
42 | currentMode->keyPressed(key);
43 | }
44 | }
45 |
46 | void ModeManager::exit() {
47 | if (currentMode) {
48 | currentMode->exit();
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/modes/ModeManager.h:
--------------------------------------------------------------------------------
1 |
2 | //
3 | // ModeManager.h
4 | // OSC_MIDI_OSC
5 | //
6 | // Created by Fred Rodrigues on 02/10/2023.
7 | //
8 |
9 | #pragma once
10 |
11 | #include "modes/Mode.h"
12 | #include
13 |
14 | class ModeManager {
15 | public:
16 | ModeManager();
17 | ~ModeManager();
18 |
19 | void setMode(std::shared_ptr newMode);
20 | void update();
21 | void draw();
22 | void keyPressed(int key);
23 | void exit();
24 |
25 | private:
26 | std::shared_ptr currentMode;
27 | };
28 |
--------------------------------------------------------------------------------
/src/modes/OscInSetupMode.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // MidiInSetupMode.cpp
3 | // OSC_MIDI_OSC
4 | //
5 | // Created by Fred Rodrigues on 02/10/2023.
6 | //
7 |
8 | #include "OscInSetupMode.h"
9 |
10 | OscInSetupMode::OscInSetupMode(ofTrueTypeFont & fontRef, ofJson & settingsRef, Colours & coloursRef)
11 | : Mode(fontRef, settingsRef, coloursRef) {
12 | oscInPortField.setup();
13 | oscInPortField.text = ofToString(settings["incomingPortOsc"]);
14 | oscInPortField.bounds.x = 10;
15 | oscInPortField.bounds.y = 35;
16 | oscInPortField.bounds.height = font.getStringBoundingBox("1", 0, 0).height + 5;
17 | oscInPortField.bounds.width = font.getStringBoundingBox(ofToString(settings["incomingPortOsc"]), 0, 0).width + 30;
18 | oscInPortField.setFont(font);
19 |
20 | saveOSCInPortSettings.setup("Set OSC in port", "BTN_MSG_OSC_IN_PORT_SET");
21 | saveOSCInPortSettings.set(30, 175, 140, 20);
22 | saveOSCInPortSettings.disableAllEvents();
23 |
24 | GoToConversionMode.setup("Exit settings", "BTN_MSG_GOTOMODE_MODE_CONVERSION");
25 | GoToConversionMode.set(200, 175, 140, 20);
26 | GoToConversionMode.disableAllEvents();
27 | }
28 |
29 | OscInSetupMode::~OscInSetupMode() {}
30 |
31 | void OscInSetupMode::setup() {
32 | oscInPortField.enable();
33 | saveOSCInPortSettings.enableAllEvents();
34 | GoToConversionMode.enableAllEvents();
35 | ofAddListener(oscInPortField.onTextChange, this, &OscInSetupMode::onOSCInputPortEditied);
36 |
37 | ofAddListener(ofEvents().keyPressed, this, &OscInSetupMode::_keyPressed);
38 | }
39 |
40 | void OscInSetupMode::draw() {
41 | ofSetColor(colours.text);
42 | font.drawString("OSC in settings", 10, 15);
43 | ofPushStyle();
44 | ofSetColor(colours.buttonActive);
45 | ofFill();
46 | ofDrawRectRounded(oscInPortField.bounds.x, oscInPortField.bounds.y + 8, oscInPortField.bounds.width, oscInPortField.bounds.height, 3);
47 | ofPopStyle();
48 | oscInPortField.draw();
49 | }
50 |
51 | void OscInSetupMode::update() {
52 | // Implementation
53 | }
54 |
55 | void OscInSetupMode::exit() {
56 | oscInPortField.disable();
57 | saveOSCInPortSettings.disableAllEvents();
58 | GoToConversionMode.disableAllEvents();
59 | ofRemoveListener(oscInPortField.onTextChange, this, &OscInSetupMode::onOSCInputPortEditied);
60 | ofRemoveListener(ofEvents().keyPressed, this, &OscInSetupMode::_keyPressed);
61 | }
62 |
63 |
64 | void OscInSetupMode::_keyPressed(ofKeyEventArgs & e) {
65 |
66 | }
67 |
68 | void OscInSetupMode::onOSCInputPortEditied(string & message) {
69 | settings["incomingPortOsc"] = ofToInt(message);
70 |
71 | }
72 |
--------------------------------------------------------------------------------
/src/modes/OscInSetupMode.h:
--------------------------------------------------------------------------------
1 | //
2 | // OscInSetupMode.h
3 | // OSC_MIDI_OSC
4 | //
5 | // Created by Fred Rodrigues on 02/10/2023.
6 | //
7 |
8 | #pragma once
9 |
10 |
11 | #include
12 |
13 | #include "modes/Mode.h"
14 | #include "ofxTextInputField.h"
15 |
16 | class OscInSetupMode : public Mode {
17 | private:
18 | std::string title;
19 |
20 | public:
21 | OscInSetupMode(ofTrueTypeFont & fontRef, ofJson & settingsRef, Colours & coloursRef);
22 | ~OscInSetupMode();
23 |
24 | void setup() override;
25 | void draw() override;
26 | void update() override;
27 | void exit() override;
28 | void keyPressed(int key) override{ }
29 |
30 | void _keyPressed(ofKeyEventArgs & e);
31 | simpleButton saveMidiInPortSettings;
32 | simpleButton saveMidiInChannelSettings;
33 |
34 | ofxTextInputField oscInPortField;
35 |
36 | void onOSCInputPortEditied(string & message);
37 |
38 | simpleButton saveOSCInPortSettings;
39 | simpleButton GoToConversionMode;
40 |
41 | };
42 |
--------------------------------------------------------------------------------
/src/modes/OscOutSetupMode.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // OscOutSetupMode.cpp
3 | // OSC_MIDI_OSC
4 | //
5 | // Created by Fred Rodrigues on 02/10/2023.
6 | //
7 |
8 | #include "OscOutSetupMode.h"
9 |
10 | OscOutSetupMode::OscOutSetupMode(ofTrueTypeFont & fontRef, ofJson & settingsRef, Colours & coloursRef)
11 | : Mode(fontRef, settingsRef, coloursRef) {
12 | oscOutPortField.setup();
13 | oscOutPortField.text = ofToString(settings["outGoingPortOsc"]);
14 | oscOutPortField.bounds.x = 10;
15 | oscOutPortField.bounds.y = 35;
16 | oscOutPortField.bounds.height = font.getStringBoundingBox("1", 0, 0).height + 5;
17 | oscOutPortField.bounds.width = font.getStringBoundingBox(ofToString(settings["outGoingPortOsc"]), 0, 0).width + 30;
18 | oscOutPortField.setFont(font);
19 |
20 | oscOutIPField.setup();
21 | oscOutIPField.text = settings["outgoingIpOSC"];
22 | oscOutIPField.bounds.x = 10;
23 | oscOutIPField.bounds.y = 60;
24 | oscOutIPField.bounds.height = font.getStringBoundingBox("1", 0, 0).height + 5;
25 | oscOutIPField.bounds.width = font.getStringBoundingBox(ofToString(settings["outgoingIpOSC"]), 0, 0).width + 30;;
26 | oscOutIPField.setFont(font);
27 |
28 | saveOSCOutPortSettings.setup("Set OSC out port", "BTN_MSG_OST_OUT_PORT_SET");
29 | saveOSCOutPortSettings.set(30, 175, 140, 20);
30 | saveOSCOutPortSettings.disableAllEvents();
31 |
32 | saveOSCOutIptSettings.setup("Set OSC IP port", "BTN_MSG_OST_OUT_IP_SET");
33 | saveOSCOutIptSettings.set(200, 175, 140, 20);
34 | saveOSCOutIptSettings.disableAllEvents();
35 |
36 | GoToConversionMode.setup("Exit settings", "BTN_MSG_GOTOMODE_MODE_CONVERSION");
37 | GoToConversionMode.set(370, 175, 140, 20);
38 | GoToConversionMode.disableAllEvents();
39 | }
40 |
41 | OscOutSetupMode::~OscOutSetupMode() { }
42 |
43 | void OscOutSetupMode::setup() {
44 | oscOutPortField.enable();
45 | oscOutIPField.enable();
46 | saveOSCOutPortSettings.enableAllEvents();
47 | saveOSCOutIptSettings.enableAllEvents();
48 | GoToConversionMode.enableAllEvents();
49 | ofAddListener(oscOutPortField.onTextChange, this, &OscOutSetupMode::onOSCOutputPortEditied);
50 | ofAddListener(oscOutIPField.onTextChange, this, &OscOutSetupMode::onOSCOutputIPEditied);
51 | ofAddListener(ofEvents().keyPressed, this, &OscOutSetupMode::_keyPressed);
52 | }
53 |
54 | void OscOutSetupMode::draw() {
55 | ofSetColor(colours.text);
56 | font.drawString("OSC out settings", 10, 15);
57 | ofPushStyle();
58 | ofFill();
59 | ofSetColor(colours.buttonActive);
60 | ofDrawRectRounded(oscOutPortField.bounds.x, oscOutPortField.bounds.y + 8, oscOutPortField.bounds.width, oscOutPortField.bounds.height, 3);
61 | ofDrawRectRounded(oscOutIPField.bounds.x, oscOutIPField.bounds.y + 8, oscOutIPField.bounds.width, oscOutIPField.bounds.height, 3);
62 | ofPopStyle();
63 | oscOutIPField.draw();
64 | oscOutPortField.draw();
65 |
66 | }
67 |
68 | void OscOutSetupMode::update() {
69 | // Implementation
70 | }
71 |
72 | void OscOutSetupMode::exit() {
73 | oscOutPortField.disable();
74 | oscOutIPField.disable();
75 | saveOSCOutPortSettings.disableAllEvents();
76 | saveOSCOutIptSettings.disableAllEvents();
77 | GoToConversionMode.disableAllEvents();
78 | ofRemoveListener(oscOutPortField.onTextChange, this, &OscOutSetupMode::onOSCOutputPortEditied);
79 | ofRemoveListener(oscOutIPField.onTextChange, this, &OscOutSetupMode::onOSCOutputIPEditied);
80 | }
81 |
82 |
83 | void OscOutSetupMode::_keyPressed(ofKeyEventArgs & e) {
84 | int key = e.key;
85 | }
86 |
87 | void OscOutSetupMode::onOSCOutputIPEditied(string& message) {
88 | settings["outgoingIpOSC"] = message;
89 | }
90 |
91 | void OscOutSetupMode::onOSCOutputPortEditied(string& message) {
92 | settings["outGoingPortOsc"] = ofToInt(message);
93 | }
94 |
--------------------------------------------------------------------------------
/src/modes/OscOutSetupMode.h:
--------------------------------------------------------------------------------
1 | //
2 | // OscOutSetupMode.h
3 | // OSC_MIDI_OSC
4 | //
5 | // Created by Fred Rodrigues on 02/10/2023.
6 | //
7 |
8 | #pragma once
9 |
10 | #include
11 |
12 | #include "modes/Mode.h"
13 | #include "ofxTextInputField.h"
14 |
15 | class OscOutSetupMode : public Mode {
16 | private:
17 | std::string title;
18 |
19 | public:
20 | OscOutSetupMode(ofTrueTypeFont & fontRef, ofJson & settingsRef, Colours & coloursRef);
21 | ~OscOutSetupMode();
22 |
23 | void setup() override;
24 | void draw() override;
25 | void update() override;
26 | void exit() override;
27 | void keyPressed(int key) override { }
28 |
29 | void _keyPressed(ofKeyEventArgs & e);
30 | simpleButton saveMidiInPortSettings;
31 | simpleButton saveMidiInChannelSettings;
32 |
33 | ofxTextInputField oscOutPortField, oscOutIPField;
34 |
35 | void onOSCOutputIPEditied(string & message);
36 | void onOSCOutputPortEditied(string & message);
37 |
38 | simpleButton saveOSCOutPortSettings;
39 | simpleButton saveOSCOutIptSettings;
40 | simpleButton GoToConversionMode;
41 | };
42 |
--------------------------------------------------------------------------------
/src/ofApp.cpp:
--------------------------------------------------------------------------------
1 | #include "ofApp.h"
2 |
3 | //--------------------------------------------------------------
4 | void ofApp::setup() {
5 | ofSetLogLevel(OF_LOG_VERBOSE);
6 | font.load("frabk.ttf", 14);
7 | settingsManager.loadSettings("MIDI_OSC_SETTINGS.json");
8 | appSettings = settingsManager.getSettings();
9 | midiManager.setup();
10 | oscManager.setup();
11 | ofBackground(255);
12 |
13 | activityMessage = "No messages received";
14 |
15 | midiInSetupMode = std::make_shared(font, appSettings, colours);
16 | midiOutSetupMode = std::make_shared(font, appSettings, colours);
17 | oscInSetupMode = std::make_shared(font, appSettings, colours);
18 | oscOutSetupMode = std::make_shared(font, appSettings, colours);
19 | conversionMode = std::make_shared(font, appSettings, colours);
20 |
21 | modeManager.setMode(conversionMode);
22 | }
23 |
24 | //--------------------------------------------------------------
25 | void ofApp::update() {
26 | modeManager.update();
27 | oscManager.handleIncomingMessages();
28 | }
29 |
30 | //--------------------------------------------------------------
31 | void ofApp::draw() {
32 | ofSetBackgroundColor(colours.background);
33 | modeManager.draw();
34 | }
35 |
36 | //--------------------------------------------------------------
37 | void ofApp::keyPressed(int key) {
38 |
39 | }
40 |
41 | //--------------------------------------------------------------
42 | void ofApp::keyReleased(int key) {
43 | }
44 |
45 | //--------------------------------------------------------------
46 | void ofApp::mouseMoved(int x, int y) {
47 | }
48 |
49 | //--------------------------------------------------------------
50 | void ofApp::mouseDragged(int x, int y, int button) {
51 | }
52 |
53 | //--------------------------------------------------------------
54 | void ofApp::mousePressed(int x, int y, int button) {
55 | }
56 |
57 | //--------------------------------------------------------------
58 | void ofApp::mouseReleased(int x, int y, int button) {
59 | }
60 |
61 | //--------------------------------------------------------------
62 | void ofApp::windowResized(int w, int h) {
63 | }
64 |
65 | //--------------------------------------------------------------
66 | void ofApp::gotMessage(ofMessage msg) {
67 | if (msg.message.substr(0, 3) == "BTN" && buttonMessagesMap.find(msg.message) != buttonMessagesMap.end()) {
68 |
69 | ofLogVerbose() << "Button message received: " << msg.message;
70 |
71 | // Get the corresponding enum value from the map
72 | int buttonValue = buttonMessagesMap[msg.message];
73 | // Use a switch statement on the enum value
74 | switch (buttonValue) {
75 | case BTN_MSG_GOTOMODE_MODE_SETTING_MIDI_IN:
76 | modeManager.setMode(midiInSetupMode);
77 | break;
78 |
79 | case BTN_MSG_GOTOMODE_MODE_SETTING_MIDI_OUT:
80 | modeManager.setMode(midiOutSetupMode);
81 | break;
82 |
83 | case BTN_MSG_GOTOMODE_MODE_SETTING_OSC_IN:
84 | modeManager.setMode(oscInSetupMode);
85 | break;
86 |
87 | case BTN_MSG_GOTOMODE_MODE_SETTING_OSC_OUT:
88 | modeManager.setMode(oscOutSetupMode);
89 | break;
90 |
91 | case BTN_MSG_GOTOMODE_MODE_CONVERSION:
92 | modeManager.setMode(conversionMode);
93 | break;
94 |
95 | case BTN_MSG_MIDI_IN_PORT_SET:
96 | appSettings["midiInDevice"] = appSettings["inPortLabel"].get();
97 | appSettings["midiInDeviceByString"] = true;
98 | settingsManager.saveSettings("MIDI_OSC_SETTINGS.json", appSettings);
99 | midiManager.close();
100 | midiManager.updateSettings();
101 | midiManager.setup();
102 | break;
103 |
104 | case BTN_MSG_MIDI_IN_CHANNEL_SET:
105 | settingsManager.saveSettings("MIDI_OSC_SETTINGS.json", appSettings);
106 | midiManager.updateSettings();
107 | break;
108 |
109 | case BTN_MSG_MIDI_OUT_PORT_SET:
110 | appSettings["midiOutDevice"] = appSettings["outPortLabel"].get();
111 | appSettings["midiOutDeviceByString"] = true;
112 | settingsManager.saveSettings("MIDI_OSC_SETTINGS.json", appSettings);
113 | midiManager.close();
114 | midiManager.updateSettings();
115 | midiManager.setup();
116 |
117 | break;
118 |
119 | case BTN_MSG_MIDI_OUT_CHANNEL_SET:
120 | settingsManager.saveSettings("MIDI_OSC_SETTINGS.json", appSettings);
121 | midiManager.updateSettings();
122 | break;
123 |
124 | case BTN_MSG_OSC_IN_PORT_SET:
125 | oscManager.closeReceiver();
126 | settingsManager.saveSettings("MIDI_OSC_SETTINGS.json", appSettings);
127 | oscManager.updateSettings();
128 | oscManager.setupReceiver();
129 |
130 | break;
131 |
132 | case BTN_MSG_OST_OUT_PORT_SET:
133 | oscManager.closeSender();
134 | settingsManager.saveSettings("MIDI_OSC_SETTINGS.json", appSettings);
135 | oscManager.updateSettings();
136 | oscManager.setupSender();
137 |
138 | break;
139 |
140 | case BTN_MSG_OST_OUT_IP_SET:
141 | oscManager.closeSender();
142 | settingsManager.saveSettings("MIDI_OSC_SETTINGS.json", appSettings);
143 | oscManager.setupSender();
144 | break;
145 |
146 |
147 | }
148 | } else if (msg.message.substr(0, 3) != "BTN") {
149 | activityMessage = msg.message;
150 | }
151 | }
152 |
153 | //--------------------------------------------------------------
154 |
--------------------------------------------------------------------------------
/src/ofApp.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "ofMain.h"
4 | #include "SettingsManager.h"
5 | #include "MidiManager.h"
6 | #include "OscManager.h"
7 | #include "ofxTextInputField.h"
8 | #include "simpleButton.h"
9 | #include "Mode.h"
10 | #include "modes/ModeManager.h"
11 | #include "modes/MidiInSetupMode.h"
12 | #include "modes/MidiOutSetupMode.h"
13 | #include "modes/OscInSetupMode.h"
14 | #include "modes/OscOutSetupMode.h"
15 | #include "modes/ConversionMode.h"
16 | #include "colours.h"
17 |
18 |
19 |
20 | enum OperationMode {
21 | MODE_SETTING_MIDI_IN,
22 | MODE_SETTING_MIDI_OUT,
23 | MODE_SETTING_OSC_IN,
24 | MODE_SETTING_OSC_OUT,
25 | MODE_CONVERSION
26 | };
27 |
28 | enum buttonMesssages {
29 | BTN_MSG_MIDI_IN_PORT_SET,
30 | BTN_MSG_MIDI_IN_CHANNEL_SET,
31 | BTN_MSG_MIDI_OUT_PORT_SET,
32 | BTN_MSG_MIDI_OUT_CHANNEL_SET,
33 | BTN_MSG_OSC_IN_PORT_SET,
34 | BTN_MSG_OST_OUT_PORT_SET,
35 | BTN_MSG_OST_OUT_IP_SET,
36 | BTN_MSG_GOTOMODE_MODE_SETTING_MIDI_IN,
37 | BTN_MSG_GOTOMODE_MODE_SETTING_MIDI_OUT,
38 | BTN_MSG_GOTOMODE_MODE_SETTING_OSC_IN,
39 | BTN_MSG_GOTOMODE_MODE_SETTING_OSC_OUT,
40 | BTN_MSG_GOTOMODE_MODE_CONVERSION
41 | };
42 |
43 |
44 | const int MAX_MIDI_CHANNEL = 16;
45 |
46 | class ofApp : public ofBaseApp {
47 |
48 | public:
49 | void setup();
50 | void update();
51 | void draw();
52 |
53 | void keyPressed(int key);
54 | void keyReleased(int key);
55 | void mouseMoved(int x, int y );
56 | void mouseDragged(int x, int y, int button);
57 | void mousePressed(int x, int y, int button);
58 | void mouseReleased(int x, int y, int button);
59 | void windowResized(int w, int h);
60 | void gotMessage(ofMessage msg);
61 |
62 | SettingsManager& settingsManager = SettingsManager::getInstance();
63 | MidiManager& midiManager = MidiManager::getInstance();
64 | OscManager& oscManager = OscManager::getInstance();
65 | ofJson appSettings;
66 |
67 | std::string activityMessage;
68 |
69 |
70 | std::vector midiInPortList;
71 | std::vector midiOutPortList;
72 | int selectedInPort, selectedOutPort;
73 |
74 | ofTrueTypeFont font;
75 | // Helper function to handle port selection
76 |
77 | ModeManager modeManager; // If you have a separate class for ModeManager
78 |
79 | std::shared_ptr midiInSetupMode;
80 | std::shared_ptr midiOutSetupMode;
81 | std::shared_ptr oscInSetupMode;
82 | std::shared_ptr oscOutSetupMode;
83 | std::shared_ptr conversionMode;
84 |
85 |
86 |
87 |
88 | std::unordered_map buttonMessagesMap = {
89 | {"BTN_MSG_MIDI_IN_PORT_SET", 0},
90 | {"BTN_MSG_MIDI_IN_CHANNEL_SET", 1},
91 | {"BTN_MSG_MIDI_OUT_PORT_SET", 2},
92 | {"BTN_MSG_MIDI_OUT_CHANNEL_SET", 3},
93 | {"BTN_MSG_OSC_IN_PORT_SET", 4},
94 | {"BTN_MSG_OST_OUT_PORT_SET", 5},
95 | {"BTN_MSG_OST_OUT_IP_SET", 6},
96 | {"BTN_MSG_GOTOMODE_MODE_SETTING_MIDI_IN", 7},
97 | {"BTN_MSG_GOTOMODE_MODE_SETTING_MIDI_OUT", 8},
98 | {"BTN_MSG_GOTOMODE_MODE_SETTING_OSC_IN", 9},
99 | {"BTN_MSG_GOTOMODE_MODE_SETTING_OSC_OUT", 10},
100 | {"BTN_MSG_GOTOMODE_MODE_CONVERSION", 11}
101 | };
102 |
103 | Colours colours;
104 |
105 | };
106 |
107 |
--------------------------------------------------------------------------------
/src/simpleButton.h:
--------------------------------------------------------------------------------
1 | //
2 | // simpleButton.h
3 | // OSC_MIDI_OSC
4 | //
5 | // Created by Fred Rodrigues on 02/10/2023.
6 | //
7 |
8 | #pragma once
9 | #include "ofxMSAInteractiveObject.h"
10 | #include "colours.h"
11 |
12 | #define IDLE_COLOR 0x2860bd
13 | #define OVER_COLOR 0xbd5928
14 | #define DOWN_COLOR 0xbd5928
15 |
16 | class simpleButton : public ofxMSAInteractiveObject {
17 | public:
18 | string buttonLabel;
19 | string buttonMessage;
20 | ofTrueTypeFont drawFont;
21 | Colours colours;
22 | void setup(string label, string message) {
23 | enableMouseEvents();
24 | enableKeyEvents();
25 |
26 | buttonLabel = label;
27 | buttonMessage = message;
28 | drawFont.load("frabk.ttf", 12);
29 | }
30 |
31 | void exit() {
32 | }
33 |
34 | void update() {
35 | }
36 |
37 | void draw() {
38 | ofPushStyle();
39 |
40 | if (isMousePressed()) {
41 | ofSetColor(colours.buttonActive);
42 | } else if (isMouseOver()) {
43 | ofSetColor(colours.buttonActive);
44 | } else {
45 | ofSetColor(colours.button);
46 | }
47 |
48 | ofNoFill();
49 | ofDrawRectRounded(x, y, width, height, 12 / 2);
50 | drawFont.drawString(buttonLabel, x + ((width - drawFont.getStringBoundingBox(buttonLabel, 0, 0).getWidth()) / 2), y + ((height - drawFont.getStringBoundingBox(buttonLabel, 0, 0).getHeight()) / 2) + drawFont.getStringBoundingBox(buttonLabel, 0, 0).getHeight());
51 |
52 | ofPopStyle();
53 | }
54 |
55 | virtual void onRollOver(int x, int y) {
56 | }
57 |
58 | virtual void onRollOut() {
59 | }
60 |
61 | virtual void onMouseMove(int x, int y) {
62 | }
63 |
64 | virtual void onDragOver(int x, int y, int button) {
65 | }
66 |
67 | virtual void onDragOutside(int x, int y, int button) {
68 | }
69 |
70 | virtual void onPress(int x, int y, int button) {
71 | ofSendMessage(buttonMessage);
72 | }
73 |
74 | virtual void onRelease(int x, int y, int button) {
75 | }
76 |
77 | virtual void onReleaseOutside(int x, int y, int button) {
78 | }
79 |
80 | virtual void keyPressed(int key) {
81 | }
82 |
83 | virtual void keyReleased(int key) {
84 | }
85 | };
86 |
--------------------------------------------------------------------------------