mirror of
https://github.com/godotengine/godot.git
synced 2024-11-27 09:16:35 +08:00
Merge pull request #20154 from marcelofg55/midi_driver
Added a new MIDIDriver class
This commit is contained in:
commit
a501678ba1
@ -221,6 +221,10 @@ String _OS::get_audio_driver_name(int p_driver) const {
|
||||
return OS::get_singleton()->get_audio_driver_name(p_driver);
|
||||
}
|
||||
|
||||
PoolStringArray _OS::get_connected_midi_inputs() {
|
||||
return OS::get_singleton()->get_connected_midi_inputs();
|
||||
}
|
||||
|
||||
void _OS::set_video_mode(const Size2 &p_size, bool p_fullscreen, bool p_resizeable, int p_screen) {
|
||||
|
||||
OS::VideoMode vm;
|
||||
@ -1058,6 +1062,7 @@ void _OS::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_video_driver_name", "driver"), &_OS::get_video_driver_name);
|
||||
ClassDB::bind_method(D_METHOD("get_audio_driver_count"), &_OS::get_audio_driver_count);
|
||||
ClassDB::bind_method(D_METHOD("get_audio_driver_name", "driver"), &_OS::get_audio_driver_name);
|
||||
ClassDB::bind_method(D_METHOD("get_connected_midi_inputs"), &_OS::get_connected_midi_inputs);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_screen_count"), &_OS::get_screen_count);
|
||||
ClassDB::bind_method(D_METHOD("get_current_screen"), &_OS::get_current_screen);
|
||||
|
@ -152,6 +152,8 @@ public:
|
||||
virtual int get_audio_driver_count() const;
|
||||
virtual String get_audio_driver_name(int p_driver) const;
|
||||
|
||||
virtual PoolStringArray get_connected_midi_inputs();
|
||||
|
||||
virtual int get_screen_count() const;
|
||||
virtual int get_current_screen() const;
|
||||
virtual void set_current_screen(int p_screen);
|
||||
|
@ -89,6 +89,7 @@ VARIANT_ENUM_CAST(KeyList);
|
||||
VARIANT_ENUM_CAST(KeyModifierMask);
|
||||
VARIANT_ENUM_CAST(ButtonList);
|
||||
VARIANT_ENUM_CAST(JoystickList);
|
||||
VARIANT_ENUM_CAST(MidiMessageList);
|
||||
|
||||
void register_global_constants() {
|
||||
|
||||
@ -458,6 +459,15 @@ void register_global_constants() {
|
||||
BIND_GLOBAL_ENUM_CONSTANT(JOY_ANALOG_L2);
|
||||
BIND_GLOBAL_ENUM_CONSTANT(JOY_ANALOG_R2);
|
||||
|
||||
// midi
|
||||
BIND_GLOBAL_ENUM_CONSTANT(MIDI_MESSAGE_NOTE_OFF);
|
||||
BIND_GLOBAL_ENUM_CONSTANT(MIDI_MESSAGE_NOTE_ON);
|
||||
BIND_GLOBAL_ENUM_CONSTANT(MIDI_MESSAGE_AFTERTOUCH);
|
||||
BIND_GLOBAL_ENUM_CONSTANT(MIDI_MESSAGE_CONTROL_CHANGE);
|
||||
BIND_GLOBAL_ENUM_CONSTANT(MIDI_MESSAGE_PROGRAM_CHANGE);
|
||||
BIND_GLOBAL_ENUM_CONSTANT(MIDI_MESSAGE_CHANNEL_PRESSURE);
|
||||
BIND_GLOBAL_ENUM_CONSTANT(MIDI_MESSAGE_PITCH_BEND);
|
||||
|
||||
// error list
|
||||
|
||||
BIND_GLOBAL_ENUM_CONSTANT(OK);
|
||||
|
@ -1080,3 +1080,122 @@ InputEventPanGesture::InputEventPanGesture() {
|
||||
|
||||
delta = Vector2(0, 0);
|
||||
}
|
||||
/////////////////////////////
|
||||
|
||||
void InputEventMIDI::set_channel(const int p_channel) {
|
||||
|
||||
channel = p_channel;
|
||||
}
|
||||
|
||||
int InputEventMIDI::get_channel() const {
|
||||
return channel;
|
||||
}
|
||||
|
||||
void InputEventMIDI::set_message(const int p_message) {
|
||||
|
||||
message = p_message;
|
||||
}
|
||||
|
||||
int InputEventMIDI::get_message() const {
|
||||
return message;
|
||||
}
|
||||
|
||||
void InputEventMIDI::set_pitch(const int p_pitch) {
|
||||
|
||||
pitch = p_pitch;
|
||||
}
|
||||
|
||||
int InputEventMIDI::get_pitch() const {
|
||||
return pitch;
|
||||
}
|
||||
|
||||
void InputEventMIDI::set_velocity(const int p_velocity) {
|
||||
|
||||
velocity = p_velocity;
|
||||
}
|
||||
|
||||
int InputEventMIDI::get_velocity() const {
|
||||
return velocity;
|
||||
}
|
||||
|
||||
void InputEventMIDI::set_instrument(const int p_instrument) {
|
||||
|
||||
instrument = p_instrument;
|
||||
}
|
||||
|
||||
int InputEventMIDI::get_instrument() const {
|
||||
return instrument;
|
||||
}
|
||||
|
||||
void InputEventMIDI::set_pressure(const int p_pressure) {
|
||||
|
||||
pressure = p_pressure;
|
||||
}
|
||||
|
||||
int InputEventMIDI::get_pressure() const {
|
||||
return pressure;
|
||||
}
|
||||
|
||||
void InputEventMIDI::set_controller_number(const int p_controller_number) {
|
||||
|
||||
controller_number = p_controller_number;
|
||||
}
|
||||
|
||||
int InputEventMIDI::get_controller_number() const {
|
||||
return controller_number;
|
||||
}
|
||||
|
||||
void InputEventMIDI::set_controller_value(const int p_controller_value) {
|
||||
|
||||
controller_value = p_controller_value;
|
||||
}
|
||||
|
||||
int InputEventMIDI::get_controller_value() const {
|
||||
return controller_value;
|
||||
}
|
||||
|
||||
String InputEventMIDI::as_text() const {
|
||||
|
||||
return "InputEventMIDI : channel=(" + itos(get_channel()) + "), message=(" + itos(get_message()) + ")";
|
||||
}
|
||||
|
||||
void InputEventMIDI::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_channel", "channel"), &InputEventMIDI::set_channel);
|
||||
ClassDB::bind_method(D_METHOD("get_channel"), &InputEventMIDI::get_channel);
|
||||
ClassDB::bind_method(D_METHOD("set_message", "message"), &InputEventMIDI::set_message);
|
||||
ClassDB::bind_method(D_METHOD("get_message"), &InputEventMIDI::get_message);
|
||||
ClassDB::bind_method(D_METHOD("set_pitch", "pitch"), &InputEventMIDI::set_pitch);
|
||||
ClassDB::bind_method(D_METHOD("get_pitch"), &InputEventMIDI::get_pitch);
|
||||
ClassDB::bind_method(D_METHOD("set_velocity", "velocity"), &InputEventMIDI::set_velocity);
|
||||
ClassDB::bind_method(D_METHOD("get_velocity"), &InputEventMIDI::get_velocity);
|
||||
ClassDB::bind_method(D_METHOD("set_instrument", "instrument"), &InputEventMIDI::set_instrument);
|
||||
ClassDB::bind_method(D_METHOD("get_instrument"), &InputEventMIDI::get_instrument);
|
||||
ClassDB::bind_method(D_METHOD("set_pressure", "pressure"), &InputEventMIDI::set_pressure);
|
||||
ClassDB::bind_method(D_METHOD("get_pressure"), &InputEventMIDI::get_pressure);
|
||||
ClassDB::bind_method(D_METHOD("set_controller_number", "controller_number"), &InputEventMIDI::set_controller_number);
|
||||
ClassDB::bind_method(D_METHOD("get_controller_number"), &InputEventMIDI::get_controller_number);
|
||||
ClassDB::bind_method(D_METHOD("set_controller_value", "controller_value"), &InputEventMIDI::set_controller_value);
|
||||
ClassDB::bind_method(D_METHOD("get_controller_value"), &InputEventMIDI::get_controller_value);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "channel"), "set_channel", "get_channel");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "message"), "set_message", "get_message");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "pitch"), "set_pitch", "get_pitch");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "velocity"), "set_velocity", "get_velocity");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "instrument"), "set_instrument", "get_instrument");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "pressure"), "set_pressure", "get_pressure");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "controller_number"), "set_controller_number", "get_controller_number");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "controller_value"), "set_controller_value", "get_controller_value");
|
||||
}
|
||||
|
||||
InputEventMIDI::InputEventMIDI() {
|
||||
|
||||
channel = 0;
|
||||
message = 0;
|
||||
pitch = 0;
|
||||
velocity = 0;
|
||||
instrument = 0;
|
||||
pressure = 0;
|
||||
controller_number = 0;
|
||||
controller_value = 0;
|
||||
}
|
||||
|
@ -140,6 +140,16 @@ enum JoystickList {
|
||||
JOY_ANALOG_R2 = JOY_AXIS_7,
|
||||
};
|
||||
|
||||
enum MidiMessageList {
|
||||
MIDI_MESSAGE_NOTE_OFF = 0x8,
|
||||
MIDI_MESSAGE_NOTE_ON = 0x9,
|
||||
MIDI_MESSAGE_AFTERTOUCH = 0xA,
|
||||
MIDI_MESSAGE_CONTROL_CHANGE = 0xB,
|
||||
MIDI_MESSAGE_PROGRAM_CHANGE = 0xC,
|
||||
MIDI_MESSAGE_CHANNEL_PRESSURE = 0xD,
|
||||
MIDI_MESSAGE_PITCH_BEND = 0xE,
|
||||
};
|
||||
|
||||
/**
|
||||
* Input Modifier Status
|
||||
* for keyboard/mouse events.
|
||||
@ -525,4 +535,50 @@ public:
|
||||
|
||||
InputEventPanGesture();
|
||||
};
|
||||
|
||||
class InputEventMIDI : public InputEvent {
|
||||
GDCLASS(InputEventMIDI, InputEvent)
|
||||
|
||||
int channel;
|
||||
int message;
|
||||
int pitch;
|
||||
int velocity;
|
||||
int instrument;
|
||||
int pressure;
|
||||
int controller_number;
|
||||
int controller_value;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
void set_channel(const int p_channel);
|
||||
int get_channel() const;
|
||||
|
||||
void set_message(const int p_message);
|
||||
int get_message() const;
|
||||
|
||||
void set_pitch(const int p_pitch);
|
||||
int get_pitch() const;
|
||||
|
||||
void set_velocity(const int p_velocity);
|
||||
int get_velocity() const;
|
||||
|
||||
void set_instrument(const int p_instrument);
|
||||
int get_instrument() const;
|
||||
|
||||
void set_pressure(const int p_pressure);
|
||||
int get_pressure() const;
|
||||
|
||||
void set_controller_number(const int p_controller_number);
|
||||
int get_controller_number() const;
|
||||
|
||||
void set_controller_value(const int p_controller_value);
|
||||
int get_controller_value() const;
|
||||
|
||||
virtual String as_text() const;
|
||||
|
||||
InputEventMIDI();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
107
core/os/midi_driver.cpp
Normal file
107
core/os/midi_driver.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
/*************************************************************************/
|
||||
/* midi_driver.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "midi_driver.h"
|
||||
|
||||
#include "main/input_default.h"
|
||||
#include "os/os.h"
|
||||
|
||||
MIDIDriver *MIDIDriver::singleton = NULL;
|
||||
MIDIDriver *MIDIDriver::get_singleton() {
|
||||
|
||||
return singleton;
|
||||
}
|
||||
|
||||
void MIDIDriver::set_singleton() {
|
||||
|
||||
singleton = this;
|
||||
}
|
||||
|
||||
void MIDIDriver::receive_input_packet(uint64_t timestamp, uint8_t *data, uint32_t length) {
|
||||
|
||||
Ref<InputEventMIDI> event;
|
||||
event.instance();
|
||||
|
||||
if (length >= 1) {
|
||||
event->set_channel(data[0] & 0xF);
|
||||
event->set_message(data[0] >> 4);
|
||||
}
|
||||
|
||||
switch (event->get_message()) {
|
||||
case MIDI_MESSAGE_AFTERTOUCH:
|
||||
if (length >= 3) {
|
||||
event->set_pitch(data[1]);
|
||||
event->set_pressure(data[2]);
|
||||
}
|
||||
break;
|
||||
|
||||
case MIDI_MESSAGE_CONTROL_CHANGE:
|
||||
if (length >= 3) {
|
||||
event->set_controller_number(data[1]);
|
||||
event->set_controller_value(data[2]);
|
||||
}
|
||||
break;
|
||||
|
||||
case MIDI_MESSAGE_NOTE_ON:
|
||||
case MIDI_MESSAGE_NOTE_OFF:
|
||||
case MIDI_MESSAGE_PITCH_BEND:
|
||||
if (length >= 3) {
|
||||
event->set_pitch(data[1]);
|
||||
event->set_velocity(data[2]);
|
||||
}
|
||||
break;
|
||||
|
||||
case MIDI_MESSAGE_PROGRAM_CHANGE:
|
||||
if (length >= 2) {
|
||||
event->set_instrument(data[1]);
|
||||
}
|
||||
break;
|
||||
|
||||
case MIDI_MESSAGE_CHANNEL_PRESSURE:
|
||||
if (length >= 2) {
|
||||
event->set_pressure(data[1]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
InputDefault *id = Object::cast_to<InputDefault>(Input::get_singleton());
|
||||
id->parse_input_event(event);
|
||||
}
|
||||
|
||||
PoolStringArray MIDIDriver::get_connected_inputs() {
|
||||
|
||||
PoolStringArray list;
|
||||
return list;
|
||||
}
|
||||
|
||||
MIDIDriver::MIDIDriver() {
|
||||
|
||||
set_singleton();
|
||||
}
|
59
core/os/midi_driver.h
Normal file
59
core/os/midi_driver.h
Normal file
@ -0,0 +1,59 @@
|
||||
/*************************************************************************/
|
||||
/* midi_driver.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef MIDI_DRIVER_H
|
||||
#define MIDI_DRIVER_H
|
||||
|
||||
#include "core/variant.h"
|
||||
#include "typedefs.h"
|
||||
/**
|
||||
* Multi-Platform abstraction for accessing to MIDI.
|
||||
*/
|
||||
|
||||
class MIDIDriver {
|
||||
|
||||
static MIDIDriver *singleton;
|
||||
|
||||
public:
|
||||
static MIDIDriver *get_singleton();
|
||||
void set_singleton();
|
||||
|
||||
virtual Error open() = 0;
|
||||
virtual void close() = 0;
|
||||
|
||||
virtual PoolStringArray get_connected_inputs();
|
||||
|
||||
static void receive_input_packet(uint64_t timestamp, uint8_t *data, uint32_t length);
|
||||
|
||||
MIDIDriver();
|
||||
virtual ~MIDIDriver() {}
|
||||
};
|
||||
|
||||
#endif
|
@ -33,6 +33,7 @@
|
||||
#include "dir_access.h"
|
||||
#include "input.h"
|
||||
#include "os/file_access.h"
|
||||
#include "os/midi_driver.h"
|
||||
#include "project_settings.h"
|
||||
#include "servers/audio_server.h"
|
||||
#include "version_generated.gen.h"
|
||||
@ -672,6 +673,15 @@ List<String> OS::get_restart_on_exit_arguments() const {
|
||||
return restart_commandline;
|
||||
}
|
||||
|
||||
PoolStringArray OS::get_connected_midi_inputs() {
|
||||
|
||||
if (MIDIDriver::get_singleton())
|
||||
return MIDIDriver::get_singleton()->get_connected_inputs();
|
||||
|
||||
PoolStringArray list;
|
||||
return list;
|
||||
}
|
||||
|
||||
OS::OS() {
|
||||
void *volatile stack_bottom;
|
||||
|
||||
|
@ -189,6 +189,8 @@ public:
|
||||
virtual int get_audio_driver_count() const;
|
||||
virtual const char *get_audio_driver_name(int p_driver) const;
|
||||
|
||||
virtual PoolStringArray get_connected_midi_inputs();
|
||||
|
||||
virtual int get_screen_count() const { return 1; }
|
||||
virtual int get_current_screen() const { return 0; }
|
||||
virtual void set_current_screen(int p_screen) {}
|
||||
|
5
drivers/SCsub
vendored
5
drivers/SCsub
vendored
@ -21,6 +21,11 @@ if (env["platform"] == "windows"):
|
||||
if env['xaudio2']:
|
||||
SConscript("xaudio2/SCsub")
|
||||
|
||||
# Midi drivers
|
||||
SConscript('alsamidi/SCsub')
|
||||
SConscript('coremidi/SCsub')
|
||||
SConscript('winmidi/SCsub')
|
||||
|
||||
# Graphics drivers
|
||||
if (env["platform"] != "server"):
|
||||
SConscript('gles3/SCsub')
|
||||
|
8
drivers/alsamidi/SCsub
Normal file
8
drivers/alsamidi/SCsub
Normal file
@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
Import('env')
|
||||
|
||||
# Driver source files
|
||||
env.add_source_files(env.drivers_sources, "*.cpp")
|
||||
|
||||
Export('env')
|
201
drivers/alsamidi/alsa_midi.cpp
Normal file
201
drivers/alsamidi/alsa_midi.cpp
Normal file
@ -0,0 +1,201 @@
|
||||
/*************************************************************************/
|
||||
/* alsa_midi.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifdef ALSAMIDI_ENABLED
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "alsa_midi.h"
|
||||
#include "os/os.h"
|
||||
#include "print_string.h"
|
||||
|
||||
static int get_message_size(uint8_t message) {
|
||||
switch (message & 0xF0) {
|
||||
case 0x80: // note off
|
||||
case 0x90: // note on
|
||||
case 0xA0: // aftertouch
|
||||
case 0xB0: // continuous controller
|
||||
return 3;
|
||||
|
||||
case 0xC0: // patch change
|
||||
case 0xD0: // channel pressure
|
||||
case 0xE0: // pitch bend
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 256;
|
||||
}
|
||||
|
||||
void MIDIDriverALSAMidi::thread_func(void *p_udata) {
|
||||
MIDIDriverALSAMidi *md = (MIDIDriverALSAMidi *)p_udata;
|
||||
uint64_t timestamp = 0;
|
||||
uint8_t buffer[256];
|
||||
int expected_size = 255;
|
||||
int bytes = 0;
|
||||
|
||||
while (!md->exit_thread) {
|
||||
int ret;
|
||||
|
||||
md->lock();
|
||||
|
||||
for (int i = 0; i < md->connected_inputs.size(); i++) {
|
||||
snd_rawmidi_t *midi_in = md->connected_inputs[i];
|
||||
do {
|
||||
uint8_t byte = 0;
|
||||
ret = snd_rawmidi_read(midi_in, &byte, 1);
|
||||
if (ret < 0) {
|
||||
if (ret != -EAGAIN) {
|
||||
ERR_PRINTS("snd_rawmidi_read error: " + String(snd_strerror(ret)));
|
||||
}
|
||||
} else {
|
||||
if (byte & 0x80) {
|
||||
// Flush previous packet if there is any
|
||||
if (bytes) {
|
||||
md->receive_input_packet(timestamp, buffer, bytes);
|
||||
bytes = 0;
|
||||
}
|
||||
expected_size = get_message_size(byte);
|
||||
}
|
||||
|
||||
if (bytes < 256) {
|
||||
buffer[bytes++] = byte;
|
||||
// If we know the size of the current packet receive it if it reached the expected size
|
||||
if (bytes >= expected_size) {
|
||||
md->receive_input_packet(timestamp, buffer, bytes);
|
||||
bytes = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (ret > 0);
|
||||
}
|
||||
|
||||
md->unlock();
|
||||
|
||||
OS::get_singleton()->delay_usec(1000);
|
||||
}
|
||||
}
|
||||
|
||||
Error MIDIDriverALSAMidi::open() {
|
||||
|
||||
void **hints;
|
||||
|
||||
if (snd_device_name_hint(-1, "rawmidi", &hints) < 0)
|
||||
return ERR_CANT_OPEN;
|
||||
|
||||
int i = 0;
|
||||
for (void **n = hints; *n != NULL; n++) {
|
||||
char *name = snd_device_name_get_hint(*n, "NAME");
|
||||
|
||||
if (name != NULL) {
|
||||
snd_rawmidi_t *midi_in;
|
||||
int ret = snd_rawmidi_open(&midi_in, NULL, name, SND_RAWMIDI_NONBLOCK);
|
||||
if (ret >= 0) {
|
||||
connected_inputs.insert(i++, midi_in);
|
||||
}
|
||||
}
|
||||
|
||||
if (name != NULL)
|
||||
free(name);
|
||||
}
|
||||
snd_device_name_free_hint(hints);
|
||||
|
||||
mutex = Mutex::create();
|
||||
thread = Thread::create(MIDIDriverALSAMidi::thread_func, this);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void MIDIDriverALSAMidi::close() {
|
||||
|
||||
if (thread) {
|
||||
exit_thread = true;
|
||||
Thread::wait_to_finish(thread);
|
||||
|
||||
memdelete(thread);
|
||||
thread = NULL;
|
||||
}
|
||||
|
||||
if (mutex) {
|
||||
memdelete(mutex);
|
||||
mutex = NULL;
|
||||
}
|
||||
|
||||
for (int i = 0; i < connected_inputs.size(); i++) {
|
||||
snd_rawmidi_t *midi_in = connected_inputs[i];
|
||||
snd_rawmidi_close(midi_in);
|
||||
}
|
||||
connected_inputs.clear();
|
||||
}
|
||||
|
||||
void MIDIDriverALSAMidi::lock() const {
|
||||
|
||||
if (mutex)
|
||||
mutex->lock();
|
||||
}
|
||||
|
||||
void MIDIDriverALSAMidi::unlock() const {
|
||||
|
||||
if (mutex)
|
||||
mutex->unlock();
|
||||
}
|
||||
|
||||
PoolStringArray MIDIDriverALSAMidi::get_connected_inputs() {
|
||||
|
||||
PoolStringArray list;
|
||||
|
||||
lock();
|
||||
for (int i = 0; i < connected_inputs.size(); i++) {
|
||||
snd_rawmidi_t *midi_in = connected_inputs[i];
|
||||
snd_rawmidi_info_t *info;
|
||||
|
||||
snd_rawmidi_info_malloc(&info);
|
||||
snd_rawmidi_info(midi_in, info);
|
||||
list.push_back(snd_rawmidi_info_get_name(info));
|
||||
snd_rawmidi_info_free(info);
|
||||
}
|
||||
unlock();
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
MIDIDriverALSAMidi::MIDIDriverALSAMidi() {
|
||||
|
||||
mutex = NULL;
|
||||
thread = NULL;
|
||||
|
||||
exit_thread = false;
|
||||
}
|
||||
|
||||
MIDIDriverALSAMidi::~MIDIDriverALSAMidi() {
|
||||
|
||||
close();
|
||||
}
|
||||
|
||||
#endif
|
69
drivers/alsamidi/alsa_midi.h
Normal file
69
drivers/alsamidi/alsa_midi.h
Normal file
@ -0,0 +1,69 @@
|
||||
/*************************************************************************/
|
||||
/* alsa_midi.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifdef ALSAMIDI_ENABLED
|
||||
|
||||
#ifndef ALSA_MIDI_H
|
||||
#define ALSA_MIDI_H
|
||||
|
||||
#include <alsa/asoundlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "core/os/mutex.h"
|
||||
#include "core/os/thread.h"
|
||||
#include "core/vector.h"
|
||||
#include "os/midi_driver.h"
|
||||
|
||||
class MIDIDriverALSAMidi : public MIDIDriver {
|
||||
|
||||
Thread *thread;
|
||||
Mutex *mutex;
|
||||
|
||||
Vector<snd_rawmidi_t *> connected_inputs;
|
||||
|
||||
bool exit_thread;
|
||||
|
||||
static void thread_func(void *p_udata);
|
||||
|
||||
void lock() const;
|
||||
void unlock() const;
|
||||
|
||||
public:
|
||||
virtual Error open();
|
||||
virtual void close();
|
||||
|
||||
virtual PoolStringArray get_connected_inputs();
|
||||
|
||||
MIDIDriverALSAMidi();
|
||||
virtual ~MIDIDriverALSAMidi();
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
8
drivers/coremidi/SCsub
Normal file
8
drivers/coremidi/SCsub
Normal file
@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
Import('env')
|
||||
|
||||
# Driver source files
|
||||
env.add_source_files(env.drivers_sources, "*.cpp")
|
||||
|
||||
Export('env')
|
105
drivers/coremidi/core_midi.cpp
Normal file
105
drivers/coremidi/core_midi.cpp
Normal file
@ -0,0 +1,105 @@
|
||||
/*************************************************************************/
|
||||
/* core_midi.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifdef COREMIDI_ENABLED
|
||||
|
||||
#include "core_midi.h"
|
||||
#include "print_string.h"
|
||||
|
||||
#include <CoreAudio/HostTime.h>
|
||||
#include <CoreServices/CoreServices.h>
|
||||
|
||||
void MIDIDriverCoreMidi::read(const MIDIPacketList *packet_list, void *read_proc_ref_con, void *src_conn_ref_con) {
|
||||
MIDIPacket *packet = const_cast<MIDIPacket *>(packet_list->packet);
|
||||
for (int i = 0; i < packet_list->numPackets; i++) {
|
||||
receive_input_packet(packet->timeStamp, packet->data, packet->length);
|
||||
packet = MIDIPacketNext(packet);
|
||||
}
|
||||
}
|
||||
|
||||
Error MIDIDriverCoreMidi::open() {
|
||||
|
||||
CFStringRef name = CFStringCreateWithCString(NULL, "Godot", kCFStringEncodingASCII);
|
||||
OSStatus result = MIDIClientCreate(name, NULL, NULL, &client);
|
||||
CFRelease(name);
|
||||
if (result != noErr) {
|
||||
ERR_PRINTS("MIDIClientCreate failed: " + String(GetMacOSStatusErrorString(result)));
|
||||
return ERR_CANT_OPEN;
|
||||
}
|
||||
|
||||
result = MIDIInputPortCreate(client, CFSTR("Godot Input"), MIDIDriverCoreMidi::read, (void *)this, &port_in);
|
||||
if (result != noErr) {
|
||||
ERR_PRINTS("MIDIInputPortCreate failed: " + String(GetMacOSStatusErrorString(result)));
|
||||
return ERR_CANT_OPEN;
|
||||
}
|
||||
|
||||
int sources = MIDIGetNumberOfSources();
|
||||
for (int i = 0; i < sources; i++) {
|
||||
|
||||
MIDIEndpointRef source = MIDIGetSource(i);
|
||||
if (source != NULL) {
|
||||
MIDIPortConnectSource(port_in, source, (void *)this);
|
||||
connected_sources.insert(i, source);
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void MIDIDriverCoreMidi::close() {
|
||||
|
||||
for (int i = 0; i < connected_sources.size(); i++) {
|
||||
MIDIEndpointRef source = connected_sources[i];
|
||||
MIDIPortDisconnectSource(port_in, source);
|
||||
}
|
||||
connected_sources.clear();
|
||||
|
||||
if (port_in != 0) {
|
||||
MIDIPortDispose(port_in);
|
||||
port_in = 0;
|
||||
}
|
||||
|
||||
if (client != 0) {
|
||||
MIDIClientDispose(client);
|
||||
client = 0;
|
||||
}
|
||||
}
|
||||
|
||||
MIDIDriverCoreMidi::MIDIDriverCoreMidi() {
|
||||
|
||||
client = 0;
|
||||
}
|
||||
|
||||
MIDIDriverCoreMidi::~MIDIDriverCoreMidi() {
|
||||
|
||||
close();
|
||||
}
|
||||
|
||||
#endif
|
61
drivers/coremidi/core_midi.h
Normal file
61
drivers/coremidi/core_midi.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*************************************************************************/
|
||||
/* core_midi.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifdef COREMIDI_ENABLED
|
||||
|
||||
#ifndef CORE_MIDI_H
|
||||
#define CORE_MIDI_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <CoreMIDI/CoreMIDI.h>
|
||||
|
||||
#include "core/vector.h"
|
||||
#include "os/midi_driver.h"
|
||||
|
||||
class MIDIDriverCoreMidi : public MIDIDriver {
|
||||
|
||||
MIDIClientRef client;
|
||||
MIDIPortRef port_in;
|
||||
|
||||
Vector<MIDIEndpointRef> connected_sources;
|
||||
|
||||
static void read(const MIDIPacketList *packet_list, void *read_proc_ref_con, void *src_conn_ref_con);
|
||||
|
||||
public:
|
||||
virtual Error open();
|
||||
virtual void close();
|
||||
|
||||
MIDIDriverCoreMidi();
|
||||
virtual ~MIDIDriverCoreMidi();
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
8
drivers/winmidi/SCsub
Normal file
8
drivers/winmidi/SCsub
Normal file
@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
Import('env')
|
||||
|
||||
# Driver source files
|
||||
env.add_source_files(env.drivers_sources, "*.cpp")
|
||||
|
||||
Export('env')
|
100
drivers/winmidi/win_midi.cpp
Normal file
100
drivers/winmidi/win_midi.cpp
Normal file
@ -0,0 +1,100 @@
|
||||
/*************************************************************************/
|
||||
/* win_midi.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifdef WINMIDI_ENABLED
|
||||
|
||||
#include "win_midi.h"
|
||||
#include "print_string.h"
|
||||
|
||||
void MIDIDriverWinMidi::read(HMIDIIN hMidiIn, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) {
|
||||
|
||||
if (wMsg == MIM_DATA) {
|
||||
receive_input_packet((uint64_t)dwParam2, (uint8_t *)&dwParam1, 3);
|
||||
}
|
||||
}
|
||||
|
||||
Error MIDIDriverWinMidi::open() {
|
||||
|
||||
for (UINT i = 0; i < midiInGetNumDevs(); i++) {
|
||||
HMIDIIN midi_in;
|
||||
|
||||
MMRESULT res = midiInOpen(&midi_in, i, (DWORD_PTR)read, (DWORD_PTR)this, CALLBACK_FUNCTION);
|
||||
if (res == MMSYSERR_NOERROR) {
|
||||
midiInStart(midi_in);
|
||||
connected_sources.insert(i, midi_in);
|
||||
} else {
|
||||
char err[256];
|
||||
midiInGetErrorText(res, err, 256);
|
||||
ERR_PRINTS("midiInOpen error: " + String(err));
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
PoolStringArray MIDIDriverWinMidi::get_connected_inputs() {
|
||||
|
||||
PoolStringArray list;
|
||||
|
||||
for (int i = 0; i < connected_sources.size(); i++) {
|
||||
HMIDIIN midi_in = connected_sources[i];
|
||||
UINT id = 0;
|
||||
MMRESULT res = midiInGetID(midi_in, &id);
|
||||
if (res == MMSYSERR_NOERROR) {
|
||||
MIDIINCAPS caps;
|
||||
res = midiInGetDevCaps(i, &caps, sizeof(MIDIINCAPS));
|
||||
if (res == MMSYSERR_NOERROR) {
|
||||
list.push_back(caps.szPname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
void MIDIDriverWinMidi::close() {
|
||||
|
||||
for (int i = 0; i < connected_sources.size(); i++) {
|
||||
HMIDIIN midi_in = connected_sources[i];
|
||||
midiInStop(midi_in);
|
||||
midiInClose(midi_in);
|
||||
}
|
||||
connected_sources.clear();
|
||||
}
|
||||
|
||||
MIDIDriverWinMidi::MIDIDriverWinMidi() {
|
||||
}
|
||||
|
||||
MIDIDriverWinMidi::~MIDIDriverWinMidi() {
|
||||
|
||||
close();
|
||||
}
|
||||
|
||||
#endif
|
61
drivers/winmidi/win_midi.h
Normal file
61
drivers/winmidi/win_midi.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*************************************************************************/
|
||||
/* win_midi.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifdef WINMIDI_ENABLED
|
||||
|
||||
#ifndef WIN_MIDI_H
|
||||
#define WIN_MIDI_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include <mmsystem.h>
|
||||
|
||||
#include "core/vector.h"
|
||||
#include "os/midi_driver.h"
|
||||
|
||||
class MIDIDriverWinMidi : public MIDIDriver {
|
||||
|
||||
Vector<HMIDIIN> connected_sources;
|
||||
|
||||
static void CALLBACK read(HMIDIIN hMidiIn, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2);
|
||||
|
||||
public:
|
||||
virtual Error open();
|
||||
virtual void close();
|
||||
|
||||
virtual PoolStringArray get_connected_inputs();
|
||||
|
||||
MIDIDriverWinMidi();
|
||||
virtual ~MIDIDriverWinMidi();
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
@ -115,8 +115,8 @@ def configure(env):
|
||||
## Flags
|
||||
|
||||
env.Append(CPPPATH=['#platform/osx'])
|
||||
env.Append(CPPFLAGS=['-DOSX_ENABLED', '-DUNIX_ENABLED', '-DGLES_ENABLED', '-DAPPLE_STYLE_KEYS', '-DCOREAUDIO_ENABLED'])
|
||||
env.Append(LINKFLAGS=['-framework', 'Cocoa', '-framework', 'Carbon', '-framework', 'OpenGL', '-framework', 'AGL', '-framework', 'AudioUnit', '-framework', 'CoreAudio', '-lz', '-framework', 'IOKit', '-framework', 'ForceFeedback'])
|
||||
env.Append(CPPFLAGS=['-DOSX_ENABLED', '-DUNIX_ENABLED', '-DGLES_ENABLED', '-DAPPLE_STYLE_KEYS', '-DCOREAUDIO_ENABLED', '-DCOREMIDI_ENABLED'])
|
||||
env.Append(LINKFLAGS=['-framework', 'Cocoa', '-framework', 'Carbon', '-framework', 'OpenGL', '-framework', 'AGL', '-framework', 'AudioUnit', '-framework', 'CoreAudio', '-framework', 'CoreMidi', '-lz', '-framework', 'IOKit', '-framework', 'ForceFeedback'])
|
||||
env.Append(LIBS=['pthread'])
|
||||
|
||||
env.Append(CPPFLAGS=['-mmacosx-version-min=10.9'])
|
||||
|
@ -33,6 +33,7 @@
|
||||
|
||||
#include "crash_handler_osx.h"
|
||||
#include "drivers/coreaudio/audio_driver_coreaudio.h"
|
||||
#include "drivers/coremidi/core_midi.h"
|
||||
#include "drivers/unix/os_unix.h"
|
||||
#include "joypad_osx.h"
|
||||
#include "main/input_default.h"
|
||||
@ -74,6 +75,7 @@ public:
|
||||
IP_Unix *ip_unix;
|
||||
|
||||
AudioDriverCoreAudio audio_driver;
|
||||
MIDIDriverCoreMidi midi_driver;
|
||||
|
||||
InputDefault *input;
|
||||
JoypadOSX *joypad_osx;
|
||||
|
@ -1351,6 +1351,8 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
|
||||
|
||||
AudioDriverManager::initialize(p_audio_driver);
|
||||
|
||||
midi_driver.open();
|
||||
|
||||
input = memnew(InputDefault);
|
||||
joypad_osx = memnew(JoypadOSX);
|
||||
|
||||
|
@ -206,7 +206,8 @@ def configure_msvc(env, manual_msvc_config):
|
||||
|
||||
env.AppendUnique(CPPDEFINES = ['WINDOWS_ENABLED', 'OPENGL_ENABLED',
|
||||
'RTAUDIO_ENABLED', 'WASAPI_ENABLED',
|
||||
'TYPED_METHOD_BIND', 'WIN32', 'MSVC',
|
||||
'WINMIDI_ENABLED', 'TYPED_METHOD_BIND',
|
||||
'WIN32', 'MSVC',
|
||||
{'WINVER' : '$target_win_version',
|
||||
'_WIN32_WINNT': '$target_win_version'}])
|
||||
if env["bits"] == "64":
|
||||
|
@ -1219,6 +1219,10 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
|
||||
|
||||
AudioDriverManager::initialize(p_audio_driver);
|
||||
|
||||
#ifdef WINMIDI_ENABLED
|
||||
driver_midi.open();
|
||||
#endif
|
||||
|
||||
TRACKMOUSEEVENT tme;
|
||||
tme.cbSize = sizeof(TRACKMOUSEEVENT);
|
||||
tme.dwFlags = TME_LEAVE;
|
||||
@ -1347,6 +1351,10 @@ void OS_Windows::set_main_loop(MainLoop *p_main_loop) {
|
||||
|
||||
void OS_Windows::finalize() {
|
||||
|
||||
#ifdef WINMIDI_ENABLED
|
||||
driver_midi.close();
|
||||
#endif
|
||||
|
||||
if (main_loop)
|
||||
memdelete(main_loop);
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "crash_handler_win.h"
|
||||
#include "drivers/rtaudio/audio_driver_rtaudio.h"
|
||||
#include "drivers/wasapi/audio_driver_wasapi.h"
|
||||
#include "drivers/winmidi/win_midi.h"
|
||||
#include "os/input.h"
|
||||
#include "os/os.h"
|
||||
#include "power_windows.h"
|
||||
@ -144,6 +145,9 @@ class OS_Windows : public OS {
|
||||
#ifdef XAUDIO2_ENABLED
|
||||
AudioDriverXAudio2 driver_xaudio2;
|
||||
#endif
|
||||
#ifdef WINMIDI_ENABLED
|
||||
MIDIDriverWinMidi driver_midi;
|
||||
#endif
|
||||
|
||||
CrashHandler crash_handler;
|
||||
|
||||
|
@ -249,7 +249,7 @@ def configure(env):
|
||||
|
||||
if (os.system("pkg-config --exists alsa") == 0): # 0 means found
|
||||
print("Enabling ALSA")
|
||||
env.Append(CPPFLAGS=["-DALSA_ENABLED"])
|
||||
env.Append(CPPFLAGS=["-DALSA_ENABLED", "-DALSAMIDI_ENABLED"])
|
||||
env.ParseConfig('pkg-config alsa --cflags --libs')
|
||||
else:
|
||||
print("ALSA libraries not found, disabling driver")
|
||||
|
@ -342,6 +342,10 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
|
||||
|
||||
AudioDriverManager::initialize(p_audio_driver);
|
||||
|
||||
#ifdef ALSAMIDI_ENABLED
|
||||
driver_alsamidi.open();
|
||||
#endif
|
||||
|
||||
ERR_FAIL_COND_V(!visual_server, ERR_UNAVAILABLE);
|
||||
ERR_FAIL_COND_V(x11_window == 0, ERR_UNAVAILABLE);
|
||||
|
||||
@ -606,6 +610,9 @@ void OS_X11::finalize() {
|
||||
memdelete(debugger_connection_console);
|
||||
}
|
||||
*/
|
||||
#ifdef ALSAMIDI_ENABLED
|
||||
driver_alsamidi.close();
|
||||
#endif
|
||||
|
||||
#ifdef JOYDEV_ENABLED
|
||||
memdelete(joypad);
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "servers/visual_server.h"
|
||||
//#include "servers/visual/visual_server_wrap_mt.h"
|
||||
#include "drivers/alsa/audio_driver_alsa.h"
|
||||
#include "drivers/alsamidi/alsa_midi.h"
|
||||
#include "drivers/pulseaudio/audio_driver_pulseaudio.h"
|
||||
#include "joypad_linux.h"
|
||||
#include "main/input_default.h"
|
||||
@ -168,6 +169,10 @@ class OS_X11 : public OS_Unix {
|
||||
AudioDriverALSA driver_alsa;
|
||||
#endif
|
||||
|
||||
#ifdef ALSAMIDI_ENABLED
|
||||
MIDIDriverALSAMidi driver_alsamidi;
|
||||
#endif
|
||||
|
||||
#ifdef PULSEAUDIO_ENABLED
|
||||
AudioDriverPulseAudio driver_pulseaudio;
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user