From 7022c4009fafa72fffa0fcf45aac9919557a280f Mon Sep 17 00:00:00 2001 From: Burt Sloane Date: Thu, 15 Jun 2017 15:18:06 -0700 Subject: [PATCH 01/21] midi in and out --- includes/BuildInfo.h | 29 +++ interface/CMakeLists.txt | 2 +- interface/src/Application.cpp | 14 +- libraries/midi/CMakeLists.txt | 3 + libraries/midi/src/Midi.cpp | 223 ++++++++++++++++++ libraries/midi/src/Midi.h | 68 ++++++ libraries/script-engine/src/ScriptEngine.cpp | 3 + libraries/shared/src/USBEventListener.cpp | 48 ++++ libraries/shared/src/USBEventListener.h | 28 +++ scripts/tutorials/createMidiSphere.js | 49 ++++ .../tutorials/entity_scripts/midiSphere.js | 52 ++++ 11 files changed, 514 insertions(+), 5 deletions(-) create mode 100644 includes/BuildInfo.h create mode 100644 libraries/midi/CMakeLists.txt create mode 100644 libraries/midi/src/Midi.cpp create mode 100644 libraries/midi/src/Midi.h create mode 100644 libraries/shared/src/USBEventListener.cpp create mode 100644 libraries/shared/src/USBEventListener.h create mode 100644 scripts/tutorials/createMidiSphere.js create mode 100644 scripts/tutorials/entity_scripts/midiSphere.js diff --git a/includes/BuildInfo.h b/includes/BuildInfo.h new file mode 100644 index 0000000000..76faf1fe84 --- /dev/null +++ b/includes/BuildInfo.h @@ -0,0 +1,29 @@ +// +// BuildInfo.h.in +// cmake/templates +// +// Created by Stephen Birarda on 1/14/16. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#define USE_STABLE_GLOBAL_SERVICES 0 + +#include + +namespace BuildInfo { + // WARNING: This file has been auto-generated. + // Check cmake/templates/BuildInfo.h.in if you want to modify it. + + const QString INTERFACE_NAME = "Interface"; + const QString ASSIGNMENT_CLIENT_NAME = "assignment-client"; + const QString DOMAIN_SERVER_NAME = "domain-server"; + const QString AC_CLIENT_SERVER_NAME = "ac-client"; + const QString MODIFIED_ORGANIZATION = "High Fidelity - dev"; + const QString ORGANIZATION_DOMAIN = "highfidelity.io"; + const QString VERSION = "dev"; + const QString BUILD_BRANCH = ""; + const QString BUILD_GLOBAL_SERVICES = "DEVELOPMENT"; +} diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 71341f3f11..79758c625b 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -193,7 +193,7 @@ link_hifi_libraries( shared octree ktx gpu gl gpu-gl procedural model render recording fbx networking model-networking entities avatars trackers audio audio-client animation script-engine physics - render-utils entities-renderer avatars-renderer ui auto-updater + render-utils entities-renderer avatars-renderer ui auto-updater midi controllers plugins image trackers ui-plugins display-plugins input-plugins ${NON_ANDROID_LIBRARIES} diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 890b5cb455..d54c0da371 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -61,6 +61,7 @@ #include #include #include +#include #include #include #include @@ -395,7 +396,11 @@ public: return true; } } - } + + if (message->message == WM_DEVICECHANGE) { + Midi::USBchanged(); // re-scan the MIDI bus + } + } return false; } }; @@ -518,8 +523,9 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); - DependencyManager::set(); - DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); @@ -640,7 +646,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo _entityClipboard->createRootElement(); #ifdef Q_OS_WIN - installNativeEventFilter(&MyNativeEventFilter::getInstance()); + installNativeEventFilter(&MyNativeEventFilter::getInstance()); #endif _logger = new FileLogger(this); // After setting organization name in order to get correct directory diff --git a/libraries/midi/CMakeLists.txt b/libraries/midi/CMakeLists.txt new file mode 100644 index 0000000000..dc54819c2b --- /dev/null +++ b/libraries/midi/CMakeLists.txt @@ -0,0 +1,3 @@ +set(TARGET_NAME midi) +setup_hifi_library(Network) +link_hifi_libraries(shared networking) diff --git a/libraries/midi/src/Midi.cpp b/libraries/midi/src/Midi.cpp new file mode 100644 index 0000000000..5f5b4fa2f3 --- /dev/null +++ b/libraries/midi/src/Midi.cpp @@ -0,0 +1,223 @@ +// +// Midi.cpp +// libraries/midi/src +// +// Created by Burt Sloane +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "Midi.h" + + +#include + + +#if defined Q_OS_WIN32 +#include "Windows.h" +#endif + + +static Midi* instance = NULL; // communicate this to non-class callbacks + + +#if defined Q_OS_WIN32 + +#pragma comment(lib, "Winmm.lib") + +// +std::vector midihin; +std::vector midihout; + +std::vector Midi::midiinexclude; +std::vector Midi::midioutexclude; + + +void CALLBACK MidiInProc( + HMIDIIN hMidiIn, + UINT wMsg, + DWORD_PTR dwInstance, + DWORD_PTR dwParam1, + DWORD_PTR dwParam2 +) { + if (wMsg == MIM_OPEN) { + } + else if (wMsg == MIM_CLOSE) { + for (int i = 0; i < midihin.size(); i++) if (midihin[i] == hMidiIn) { + midihin[i] = NULL; + instance->sendNote(0xb0, 0x7b, 0); // all notes off + } + } + else if (wMsg == MIM_DATA) { + int status = 0x0ff & dwParam1; + int note = 0x0ff & (dwParam1 >> 8); + int vel = 0x0ff & (dwParam1 >> 16); +//sendNote(status, note, vel); // NOTE: relay the note on to all other midi devices + instance->Midi::noteReceived(status, note, vel); + } +} + + +void CALLBACK MidiOutProc( + HMIDIOUT hmo, + UINT wMsg, + DWORD_PTR dwInstance, + DWORD_PTR dwParam1, + DWORD_PTR dwParam2 + ) { + if (wMsg == MOM_CLOSE) { + for (int i = 0; i < midihout.size(); i++) if (midihout[i] == hmo) { + midihout[i] = NULL; + instance->sendNote(0xb0, 0x7b, 0); // all notes off + } + } +} + + +void Midi::sendNote(int status, int note, int vel) { + for (int i = 0; i < midihout.size(); i++) if (midihout[i] != NULL) { + midiOutShortMsg(midihout[i], status + (note << 8) + (vel << 16)); + } +} + +void Midi::noteReceived(int status, int note, int velocity) { + if (status >= 0x0a0) return; // NOTE: only sending note-on and note-off to Javascript + + QVariantMap eventData; + eventData["status"] = status; + eventData["note"] = note; + eventData["velocity"] = velocity; + emit midiNote(eventData); +} + + +void Midi::MidiSetup() { + midihin.clear(); + midihout.clear(); + + MIDIINCAPS incaps; + for (unsigned int i = 0; i < midiInGetNumDevs(); i++) { + midiInGetDevCaps(i, &incaps, sizeof(MIDIINCAPS)); + + bool found = false; + for (int j = 0; j < midiinexclude.size(); j++) { + if (lstrcmp(midiinexclude[j].toStdString().c_str(), incaps.szPname) == 0) found = true; + } + if (!found) // EXCLUDE AN INPUT BY NAME + { + HMIDIIN tmphin; + midiInOpen(&tmphin, i, (DWORD_PTR)MidiInProc, NULL, CALLBACK_FUNCTION); + midiInStart(tmphin); + midihin.push_back(tmphin); + } + + } + + MIDIOUTCAPS outcaps; + for (unsigned int i = 0; i < midiOutGetNumDevs(); i++) { + midiOutGetDevCaps(i, &outcaps, sizeof(MIDIINCAPS)); + + bool found = false; + for (int j = 0; j < midioutexclude.size(); j++) { + if (lstrcmp(midioutexclude[j].toStdString().c_str(), outcaps.szPname) == 0) found = true; + } + if (!found) // EXCLUDE AN OUTPUT BY NAME + { + HMIDIOUT tmphout; + midiOutOpen(&tmphout, i, (DWORD_PTR)MidiOutProc, NULL, CALLBACK_FUNCTION); + midihout.push_back(tmphout); + } + } + + sendNote(0xb0, 0x7b, 0); // all notes off +} + +void Midi::MidiCleanup() { + sendNote(0xb0, 0x7b, 0); // all notes off + + for (int i = 0; i < midihin.size(); i++) if (midihin[i] != NULL) { + midiInStop(midihin[i]); + midiInClose(midihin[i]); + } + for (int i = 0; i < midihout.size(); i++) if (midihout[i] != NULL) { + midiOutClose(midihout[i]); + } + midihin.clear(); + midihout.clear(); +} +#endif + +// + +Midi::Midi() { + instance = this; + midioutexclude.push_back("Microsoft GS Wavetable Synth"); // we don't want to hear this thing + MidiSetup(); +} + +void Midi::playMidiNote(int status, int note, int velocity) { + sendNote(status, note, velocity); +} + +void Midi::allNotesOff() { + sendNote(0xb0, 0x7b, 0); // all notes off +} + +void Midi::resetDevices() { + MidiCleanup(); + MidiSetup(); +} + +void Midi::USBchanged() { + instance->MidiCleanup(); + instance->MidiSetup(); +} + +// + +QStringList Midi::listMidiDevices(bool output) { + QStringList rv; + if (output) { + MIDIOUTCAPS outcaps; + for (unsigned int i = 0; i < midiOutGetNumDevs(); i++) { + midiOutGetDevCaps(i, &outcaps, sizeof(MIDIINCAPS)); + rv.append(outcaps.szPname); + } + } + else { + MIDIINCAPS incaps; + for (unsigned int i = 0; i < midiInGetNumDevs(); i++) { + midiInGetDevCaps(i, &incaps, sizeof(MIDIINCAPS)); + rv.append(incaps.szPname); + } + } + return rv; +} + +void Midi::unblockMidiDevice(QString name, bool output) { + if (output) { + for (int i = 0; i < midioutexclude.size(); i++) if (midioutexclude[i].toStdString().compare(name.toStdString()) == 0) { + midioutexclude.erase(midioutexclude.begin() + i); + break; + } + } + else { + for (int i = 0; i < midiinexclude.size(); i++) if (midiinexclude[i].toStdString().compare(name.toStdString()) == 0) { + midiinexclude.erase(midiinexclude.begin() + i); + break; + } + } +} + +void Midi::blockMidiDevice(QString name, bool output) { + unblockMidiDevice(name, output); // make sure it's only in there once + if (output) { + midioutexclude.push_back(name); + } + else { + midiinexclude.push_back(name); + } +} + diff --git a/libraries/midi/src/Midi.h b/libraries/midi/src/Midi.h new file mode 100644 index 0000000000..66e45f0a53 --- /dev/null +++ b/libraries/midi/src/Midi.h @@ -0,0 +1,68 @@ +// +// Midi.h +// libraries/midi/src +// +// Created by Burt Sloane +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_Midi_h +#define hifi_Midi_h + +#include +#include +#include + +#include +#include + +class Midi : public QObject, public Dependency { + Q_OBJECT + SINGLETON_DEPENDENCY + +public: + Midi(); + +public: + void noteReceived(int status, int note, int velocity); // relay a note to Javascript + void sendNote(int status, int note, int vel); // relay a note to MIDI outputs + static void USBchanged(); + +private: + static std::vector midiinexclude; + static std::vector midioutexclude; + +private: + void MidiSetup(); + void MidiCleanup(); + +signals: + void midiNote(QVariantMap eventData); + +public slots: +/// play a note on all connected devices +/// @param {int} status: 0x80 is noteoff, 0x90 is noteon (if velocity=0, noteoff), etc +/// @param {int} note: midi note number +/// @param {int} velocity: note velocity (0 means noteoff) +Q_INVOKABLE void playMidiNote(int status, int note, int velocity); + +/// turn off all notes on all connected devices +Q_INVOKABLE void allNotesOff(); + +/// clean up and re-discover attached devices +Q_INVOKABLE void resetDevices(); + +/// ask for a list of inputs/outputs +Q_INVOKABLE QStringList listMidiDevices(bool output); + +/// block an input/output by name +Q_INVOKABLE void blockMidiDevice(QString name, bool output); + +/// unblock an input/output by name +Q_INVOKABLE void unblockMidiDevice(QString name, bool output); +}; + +#endif // hifi_Midi_h diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 61bf601019..ba162ba502 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -76,6 +76,7 @@ #include +#include "../../midi/src/Midi.h" // FIXME why won't a simpler include work? #include "MIDIEvent.h" const QString ScriptEngine::_SETTINGS_ENABLE_EXTENDED_EXCEPTIONS { @@ -662,6 +663,8 @@ void ScriptEngine::init() { registerGlobalObject("Audio", DependencyManager::get().data()); + registerGlobalObject("Midi", DependencyManager::get().data()); + registerGlobalObject("Entities", entityScriptingInterface.data()); registerGlobalObject("Quat", &_quatLibrary); registerGlobalObject("Vec3", &_vec3Library); diff --git a/libraries/shared/src/USBEventListener.cpp b/libraries/shared/src/USBEventListener.cpp new file mode 100644 index 0000000000..c71277dfed --- /dev/null +++ b/libraries/shared/src/USBEventListener.cpp @@ -0,0 +1,48 @@ +// +// USBEventListener.cpp +// libraries/shared/src +// +// Created by Ryan Huffman on 09/03/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "USBEventListener.h" + +#ifdef Q_OS_WIN +#include +#else +#include +#endif + +#include +#include + +USBEventListener& USBEventListener::getInstance() { + static USBEventListener staticInstance; + return staticInstance; +} + +void signalHandler(int param) { + // tell the qApp it should quit + QMetaObject::invokeMethod(qApp, "quit"); +} + +USBEventListener::USBEventListener(QObject* parent) : QObject(parent) { +#ifndef Q_OS_WIN +#endif +} + + +bool USBEventListener::nativeEventFilter(const QByteArray &eventType, void* msg, long* result) { +#ifdef Q_OS_WIN + if (eventType == "windows_generic_MSG") { + MSG* message = (MSG*)msg; + if (message->message == WM_DEVICECHANGE) { + } + } +#endif + return false; +} diff --git a/libraries/shared/src/USBEventListener.h b/libraries/shared/src/USBEventListener.h new file mode 100644 index 0000000000..9ab008256e --- /dev/null +++ b/libraries/shared/src/USBEventListener.h @@ -0,0 +1,28 @@ +// +// USBEventListener.h +// libraries/midi +// +// Created by Burt Sloane +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_USBEventListener_h +#define hifi_USBEventListener_h + +#include +#include + +class USBEventListener : public QObject, public QAbstractNativeEventFilter { + Q_OBJECT +public: + static USBEventListener& getInstance(); + + virtual bool nativeEventFilter(const QByteArray& eventType, void* message, long* result) override; +private: + USBEventListener(QObject* parent = 0); +}; + +#endif // hifi_USBEventListener_h diff --git a/scripts/tutorials/createMidiSphere.js b/scripts/tutorials/createMidiSphere.js new file mode 100644 index 0000000000..705acac9de --- /dev/null +++ b/scripts/tutorials/createMidiSphere.js @@ -0,0 +1,49 @@ +// +// Created by James B. Pollack @imgntn on April 18, 2016. +// Adapted by Burt +// Copyright 2016 High Fidelity, Inc. +// +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +var SCRIPT_URL = "file:///e:/hifi/scripts/tutorials/entity_scripts/midiSphere.js"; +var center = Vec3.sum(MyAvatar.position, Vec3.multiply(0.5, Quat.getForward(Camera.getOrientation()))); + +var BALL_GRAVITY = { + x: 0, + y: 0, + z: 0 +}; + +var BALL_DIMENSIONS = { + x: 0.4, + y: 0.4, + z: 0.4 +}; + + +var BALL_COLOR = { + red: 255, + green: 0, + blue: 0 +}; + +var midiSphereProperties = { + name: 'MIDI Sphere', + shapeType: 'sphere', + type: 'Sphere', + script: SCRIPT_URL, + color: BALL_COLOR, + dimensions: BALL_DIMENSIONS, + gravity: BALL_GRAVITY, + dynamic: false, + position: center, + collisionless: false, + ignoreForCollisions: true +}; + +var midiSphere = Entities.addEntity(midiSphereProperties); + +Script.stop(); diff --git a/scripts/tutorials/entity_scripts/midiSphere.js b/scripts/tutorials/entity_scripts/midiSphere.js new file mode 100644 index 0000000000..5ed29a330f --- /dev/null +++ b/scripts/tutorials/entity_scripts/midiSphere.js @@ -0,0 +1,52 @@ +// midiSphere.js +// +// Script Type: Entity +// Created by James B. Pollack @imgntn on 9/21/2015 +// Adapted by Burt +// Copyright 2015 High Fidelity, Inc. +// +// This script listens to MIDI and makes the ball change color. +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +(function() { + var _this; + + function MidiSphere() { + _this = this; + this.clicked = false; + return; + } + + MidiSphere.prototype = { + preload: function(entityID) { + this.entityID = entityID; + Midi.midiNote.connect(function(eventData) { + print("MidiSphere.noteReceived: "+JSON.stringify(eventData)); + Entities.editEntity(entityID, { color: { red: 2*eventData.note, green: 2*eventData.note, blue: 2*eventData.note} }); + }); + print("MidiSphere.preload"); + }, + unload: function(entityID) { + print("MidiSphere.unload"); + }, + + clickDownOnEntity: function(entityID, mouseEvent) { + print("MidiSphere.clickDownOnEntity"); + if (this.clicked) { + Entities.editEntity(entityID, { color: { red: 0, green: 255, blue: 255} }); + this.clicked = false; + Midi.playMidiNote(144, 64, 0); + } else { + Entities.editEntity(entityID, { color: { red: 255, green: 255, blue: 0} }); + this.clicked = true; + Midi.playMidiNote(144, 64, 100); + } + } + + }; + + // entity scripts should return a newly constructed object of our type + return new MidiSphere(); +}); \ No newline at end of file From ade017fab043898108866262cedb798a8a30e192 Mon Sep 17 00:00:00 2001 From: burtsloane Date: Thu, 15 Jun 2017 15:21:36 -0700 Subject: [PATCH 02/21] Delete BuildInfo.h --- includes/BuildInfo.h | 29 ----------------------------- 1 file changed, 29 deletions(-) delete mode 100644 includes/BuildInfo.h diff --git a/includes/BuildInfo.h b/includes/BuildInfo.h deleted file mode 100644 index 76faf1fe84..0000000000 --- a/includes/BuildInfo.h +++ /dev/null @@ -1,29 +0,0 @@ -// -// BuildInfo.h.in -// cmake/templates -// -// Created by Stephen Birarda on 1/14/16. -// Copyright 2015 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#define USE_STABLE_GLOBAL_SERVICES 0 - -#include - -namespace BuildInfo { - // WARNING: This file has been auto-generated. - // Check cmake/templates/BuildInfo.h.in if you want to modify it. - - const QString INTERFACE_NAME = "Interface"; - const QString ASSIGNMENT_CLIENT_NAME = "assignment-client"; - const QString DOMAIN_SERVER_NAME = "domain-server"; - const QString AC_CLIENT_SERVER_NAME = "ac-client"; - const QString MODIFIED_ORGANIZATION = "High Fidelity - dev"; - const QString ORGANIZATION_DOMAIN = "highfidelity.io"; - const QString VERSION = "dev"; - const QString BUILD_BRANCH = ""; - const QString BUILD_GLOBAL_SERVICES = "DEVELOPMENT"; -} From 19e35e1cd005590571a4c13d39abd5f036bae388 Mon Sep 17 00:00:00 2001 From: burtsloane Date: Thu, 15 Jun 2017 15:22:40 -0700 Subject: [PATCH 03/21] Delete USBEventListener.h --- libraries/shared/src/USBEventListener.h | 28 ------------------------- 1 file changed, 28 deletions(-) delete mode 100644 libraries/shared/src/USBEventListener.h diff --git a/libraries/shared/src/USBEventListener.h b/libraries/shared/src/USBEventListener.h deleted file mode 100644 index 9ab008256e..0000000000 --- a/libraries/shared/src/USBEventListener.h +++ /dev/null @@ -1,28 +0,0 @@ -// -// USBEventListener.h -// libraries/midi -// -// Created by Burt Sloane -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_USBEventListener_h -#define hifi_USBEventListener_h - -#include -#include - -class USBEventListener : public QObject, public QAbstractNativeEventFilter { - Q_OBJECT -public: - static USBEventListener& getInstance(); - - virtual bool nativeEventFilter(const QByteArray& eventType, void* message, long* result) override; -private: - USBEventListener(QObject* parent = 0); -}; - -#endif // hifi_USBEventListener_h From 2358d51ef14bd94dfe41356e194f9945b9da4bb4 Mon Sep 17 00:00:00 2001 From: burtsloane Date: Thu, 15 Jun 2017 15:22:51 -0700 Subject: [PATCH 04/21] Delete USBEventListener.cpp --- libraries/shared/src/USBEventListener.cpp | 48 ----------------------- 1 file changed, 48 deletions(-) delete mode 100644 libraries/shared/src/USBEventListener.cpp diff --git a/libraries/shared/src/USBEventListener.cpp b/libraries/shared/src/USBEventListener.cpp deleted file mode 100644 index c71277dfed..0000000000 --- a/libraries/shared/src/USBEventListener.cpp +++ /dev/null @@ -1,48 +0,0 @@ -// -// USBEventListener.cpp -// libraries/shared/src -// -// Created by Ryan Huffman on 09/03/14. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include "USBEventListener.h" - -#ifdef Q_OS_WIN -#include -#else -#include -#endif - -#include -#include - -USBEventListener& USBEventListener::getInstance() { - static USBEventListener staticInstance; - return staticInstance; -} - -void signalHandler(int param) { - // tell the qApp it should quit - QMetaObject::invokeMethod(qApp, "quit"); -} - -USBEventListener::USBEventListener(QObject* parent) : QObject(parent) { -#ifndef Q_OS_WIN -#endif -} - - -bool USBEventListener::nativeEventFilter(const QByteArray &eventType, void* msg, long* result) { -#ifdef Q_OS_WIN - if (eventType == "windows_generic_MSG") { - MSG* message = (MSG*)msg; - if (message->message == WM_DEVICECHANGE) { - } - } -#endif - return false; -} From af5e812f00affc5d59cb01140895612e937d5452 Mon Sep 17 00:00:00 2001 From: Burt Sloane Date: Thu, 15 Jun 2017 15:56:49 -0700 Subject: [PATCH 05/21] neutralized for non-windows compile --- libraries/midi/src/Midi.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/libraries/midi/src/Midi.cpp b/libraries/midi/src/Midi.cpp index 5f5b4fa2f3..8ae6c085bb 100644 --- a/libraries/midi/src/Midi.cpp +++ b/libraries/midi/src/Midi.cpp @@ -22,6 +22,9 @@ static Midi* instance = NULL; // communicate this to non-class callbacks +std::vector Midi::midiinexclude; +std::vector Midi::midioutexclude; + #if defined Q_OS_WIN32 @@ -31,9 +34,6 @@ static Midi* instance = NULL; // communicate this to non-class callbacks std::vector midihin; std::vector midihout; -std::vector Midi::midiinexclude; -std::vector Midi::midioutexclude; - void CALLBACK MidiInProc( HMIDIIN hMidiIn, @@ -147,6 +147,17 @@ void Midi::MidiCleanup() { midihin.clear(); midihout.clear(); } +#else +void Midi::sendNote(int status, int note, int vel) { +} + +void Midi::MidiSetup() { + sendNote(0xb0, 0x7b, 0); // all notes off +} + +void Midi::MidiCleanup() { + sendNote(0xb0, 0x7b, 0); // all notes off +} #endif // @@ -179,6 +190,7 @@ void Midi::USBchanged() { QStringList Midi::listMidiDevices(bool output) { QStringList rv; +#if defined Q_OS_WIN32 if (output) { MIDIOUTCAPS outcaps; for (unsigned int i = 0; i < midiOutGetNumDevs(); i++) { @@ -193,6 +205,7 @@ QStringList Midi::listMidiDevices(bool output) { rv.append(incaps.szPname); } } +#endif return rv; } From a73281b827e1aec988ab05cc2b540e10779bd793 Mon Sep 17 00:00:00 2001 From: Burt Sloane Date: Thu, 15 Jun 2017 16:10:08 -0700 Subject: [PATCH 06/21] fix PR issues --- interface/src/Application.cpp | 2 +- libraries/midi/src/Midi.cpp | 50 +++++++++++++++-------------------- 2 files changed, 23 insertions(+), 29 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index d54c0da371..9d11c6f2be 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -646,7 +646,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo _entityClipboard->createRootElement(); #ifdef Q_OS_WIN - installNativeEventFilter(&MyNativeEventFilter::getInstance()); + installNativeEventFilter(&MyNativeEventFilter::getInstance()); #endif _logger = new FileLogger(this); // After setting organization name in order to get correct directory diff --git a/libraries/midi/src/Midi.cpp b/libraries/midi/src/Midi.cpp index 8ae6c085bb..6e76565bed 100644 --- a/libraries/midi/src/Midi.cpp +++ b/libraries/midi/src/Midi.cpp @@ -20,6 +20,13 @@ #endif +const int MIDI_STATUS_MASK = 0x0F0; +const int MIDI_NOTE_OFF = 0x080; +const int MIDI_NOTE_ON = 0x090; +const int MIDI_CONTROL_CHANGE = 0x0b0; +const int MIDI_CHANNEL_MODE_ALL_NOTES_OFF = 0x07b; + + static Midi* instance = NULL; // communicate this to non-class callbacks std::vector Midi::midiinexclude; @@ -35,22 +42,14 @@ std::vector midihin; std::vector midihout; -void CALLBACK MidiInProc( - HMIDIIN hMidiIn, - UINT wMsg, - DWORD_PTR dwInstance, - DWORD_PTR dwParam1, - DWORD_PTR dwParam2 -) { +void CALLBACK MidiInProc(HMIDIIN hMidiIn, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) { if (wMsg == MIM_OPEN) { - } - else if (wMsg == MIM_CLOSE) { + } else if (wMsg == MIM_CLOSE) { for (int i = 0; i < midihin.size(); i++) if (midihin[i] == hMidiIn) { midihin[i] = NULL; - instance->sendNote(0xb0, 0x7b, 0); // all notes off + instance->allNotesOff(); } - } - else if (wMsg == MIM_DATA) { + } else if (wMsg == MIM_DATA) { int status = 0x0ff & dwParam1; int note = 0x0ff & (dwParam1 >> 8); int vel = 0x0ff & (dwParam1 >> 16); @@ -60,17 +59,11 @@ void CALLBACK MidiInProc( } -void CALLBACK MidiOutProc( - HMIDIOUT hmo, - UINT wMsg, - DWORD_PTR dwInstance, - DWORD_PTR dwParam1, - DWORD_PTR dwParam2 - ) { +void CALLBACK MidiOutProc(HMIDIOUT hmo, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) { if (wMsg == MOM_CLOSE) { for (int i = 0; i < midihout.size(); i++) if (midihout[i] == hmo) { midihout[i] = NULL; - instance->sendNote(0xb0, 0x7b, 0); // all notes off + instance->allNotesOff(); } } } @@ -83,7 +76,8 @@ void Midi::sendNote(int status, int note, int vel) { } void Midi::noteReceived(int status, int note, int velocity) { - if (status >= 0x0a0) return; // NOTE: only sending note-on and note-off to Javascript + if (((status & MIDI_STATUS_MASK) != MIDI_NOTE_OFF) && + ((status & MIDI_STATUS_MASK) != MIDI_NOTE_ON)) return; // NOTE: only sending note-on and note-off to Javascript QVariantMap eventData; eventData["status"] = status; @@ -103,7 +97,7 @@ void Midi::MidiSetup() { bool found = false; for (int j = 0; j < midiinexclude.size(); j++) { - if (lstrcmp(midiinexclude[j].toStdString().c_str(), incaps.szPname) == 0) found = true; + if (midiinexclude[j].toStdString().compare(incaps.szPname) == 0) found = true; } if (!found) // EXCLUDE AN INPUT BY NAME { @@ -121,7 +115,7 @@ void Midi::MidiSetup() { bool found = false; for (int j = 0; j < midioutexclude.size(); j++) { - if (lstrcmp(midioutexclude[j].toStdString().c_str(), outcaps.szPname) == 0) found = true; + if (midioutexclude[j].toStdString().compare(outcaps.szPname) == 0) found = true; } if (!found) // EXCLUDE AN OUTPUT BY NAME { @@ -131,11 +125,11 @@ void Midi::MidiSetup() { } } - sendNote(0xb0, 0x7b, 0); // all notes off + allNotesOff(); } void Midi::MidiCleanup() { - sendNote(0xb0, 0x7b, 0); // all notes off + allNotesOff(); for (int i = 0; i < midihin.size(); i++) if (midihin[i] != NULL) { midiInStop(midihin[i]); @@ -152,11 +146,11 @@ void Midi::sendNote(int status, int note, int vel) { } void Midi::MidiSetup() { - sendNote(0xb0, 0x7b, 0); // all notes off + allNotesOff(); } void Midi::MidiCleanup() { - sendNote(0xb0, 0x7b, 0); // all notes off + allNotesOff(); } #endif @@ -173,7 +167,7 @@ void Midi::playMidiNote(int status, int note, int velocity) { } void Midi::allNotesOff() { - sendNote(0xb0, 0x7b, 0); // all notes off + sendNote(MIDI_CONTROL_CHANGE, MIDI_CHANNEL_MODE_ALL_NOTES_OFF, 0); // all notes off } void Midi::resetDevices() { From 7d92ef9f2589cd48d1e35e50340d5db5064d4391 Mon Sep 17 00:00:00 2001 From: Burt Sloane Date: Thu, 15 Jun 2017 16:12:16 -0700 Subject: [PATCH 07/21] more PR fixes --- interface/src/Application.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9d11c6f2be..4f645eb1d2 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -523,9 +523,9 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); - DependencyManager::set(); - DependencyManager::set(); - DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); + DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); From fbc28c0e2fd70ce7de726f7726ed8852fb4bc927 Mon Sep 17 00:00:00 2001 From: Burt Sloane Date: Thu, 15 Jun 2017 16:16:29 -0700 Subject: [PATCH 08/21] pedantic PR --- libraries/script-engine/src/ScriptEngine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index ba162ba502..3a846d3026 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -663,7 +663,7 @@ void ScriptEngine::init() { registerGlobalObject("Audio", DependencyManager::get().data()); - registerGlobalObject("Midi", DependencyManager::get().data()); + registerGlobalObject("Midi", DependencyManager::get().data()); registerGlobalObject("Entities", entityScriptingInterface.data()); registerGlobalObject("Quat", &_quatLibrary); From c35020eb5a4552f31956a3a5a18e7846c20e6bfd Mon Sep 17 00:00:00 2001 From: Burt Sloane Date: Thu, 15 Jun 2017 16:24:12 -0700 Subject: [PATCH 09/21] last of the PR changes --- libraries/midi/src/Midi.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libraries/midi/src/Midi.cpp b/libraries/midi/src/Midi.cpp index 6e76565bed..60e4b61cbd 100644 --- a/libraries/midi/src/Midi.cpp +++ b/libraries/midi/src/Midi.cpp @@ -99,8 +99,7 @@ void Midi::MidiSetup() { for (int j = 0; j < midiinexclude.size(); j++) { if (midiinexclude[j].toStdString().compare(incaps.szPname) == 0) found = true; } - if (!found) // EXCLUDE AN INPUT BY NAME - { + if (!found) { // EXCLUDE AN INPUT BY NAME HMIDIIN tmphin; midiInOpen(&tmphin, i, (DWORD_PTR)MidiInProc, NULL, CALLBACK_FUNCTION); midiInStart(tmphin); @@ -117,8 +116,7 @@ void Midi::MidiSetup() { for (int j = 0; j < midioutexclude.size(); j++) { if (midioutexclude[j].toStdString().compare(outcaps.szPname) == 0) found = true; } - if (!found) // EXCLUDE AN OUTPUT BY NAME - { + if (!found) { // EXCLUDE AN OUTPUT BY NAME HMIDIOUT tmphout; midiOutOpen(&tmphout, i, (DWORD_PTR)MidiOutProc, NULL, CALLBACK_FUNCTION); midihout.push_back(tmphout); From 4f7a1a6e2ef932ff14dff794a32cd458fa92c64a Mon Sep 17 00:00:00 2001 From: Burt Sloane Date: Thu, 15 Jun 2017 16:35:53 -0700 Subject: [PATCH 10/21] got rid of tabs --- interface/src/Application.cpp | 8 +- libraries/midi/src/Midi.cpp | 245 +++++++++--------- libraries/midi/src/Midi.h | 18 +- libraries/script-engine/src/ScriptEngine.cpp | 2 +- scripts/tutorials/createMidiSphere.js | 8 +- .../tutorials/entity_scripts/midiSphere.js | 42 +-- 6 files changed, 168 insertions(+), 155 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 4f645eb1d2..ffd37bb813 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -397,10 +397,10 @@ public: } } - if (message->message == WM_DEVICECHANGE) { - Midi::USBchanged(); // re-scan the MIDI bus - } - } + if (message->message == WM_DEVICECHANGE) { + Midi::USBchanged(); // re-scan the MIDI bus + } + } return false; } }; diff --git a/libraries/midi/src/Midi.cpp b/libraries/midi/src/Midi.cpp index 60e4b61cbd..a3d4db0c88 100644 --- a/libraries/midi/src/Midi.cpp +++ b/libraries/midi/src/Midi.cpp @@ -27,7 +27,7 @@ const int MIDI_CONTROL_CHANGE = 0x0b0; const int MIDI_CHANNEL_MODE_ALL_NOTES_OFF = 0x07b; -static Midi* instance = NULL; // communicate this to non-class callbacks +static Midi* instance = NULL; // communicate this to non-class callbacks std::vector Midi::midiinexclude; std::vector Midi::midioutexclude; @@ -43,186 +43,199 @@ std::vector midihout; void CALLBACK MidiInProc(HMIDIIN hMidiIn, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) { - if (wMsg == MIM_OPEN) { - } else if (wMsg == MIM_CLOSE) { - for (int i = 0; i < midihin.size(); i++) if (midihin[i] == hMidiIn) { - midihin[i] = NULL; - instance->allNotesOff(); - } - } else if (wMsg == MIM_DATA) { - int status = 0x0ff & dwParam1; - int note = 0x0ff & (dwParam1 >> 8); - int vel = 0x0ff & (dwParam1 >> 16); -//sendNote(status, note, vel); // NOTE: relay the note on to all other midi devices - instance->Midi::noteReceived(status, note, vel); - } + if (wMsg == MIM_OPEN) { + } else if (wMsg == MIM_CLOSE) { + for (int i = 0; i < midihin.size(); i++) { + if (midihin[i] == hMidiIn) { + midihin[i] = NULL; + instance->allNotesOff(); + } + } + } else if (wMsg == MIM_DATA) { + int status = 0x0ff & dwParam1; + int note = 0x0ff & (dwParam1 >> 8); + int vel = 0x0ff & (dwParam1 >> 16); +//sendNote(status, note, vel); // NOTE: relay the note on to all other midi devices + instance->Midi::noteReceived(status, note, vel); + } } void CALLBACK MidiOutProc(HMIDIOUT hmo, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) { - if (wMsg == MOM_CLOSE) { - for (int i = 0; i < midihout.size(); i++) if (midihout[i] == hmo) { - midihout[i] = NULL; - instance->allNotesOff(); - } - } + if (wMsg == MOM_CLOSE) { + for (int i = 0; i < midihout.size(); i++) { + if (midihout[i] == hmo) { + midihout[i] = NULL; + instance->allNotesOff(); + } + } + } } void Midi::sendNote(int status, int note, int vel) { - for (int i = 0; i < midihout.size(); i++) if (midihout[i] != NULL) { - midiOutShortMsg(midihout[i], status + (note << 8) + (vel << 16)); - } + for (int i = 0; i < midihout.size(); i++) if (midihout[i] != NULL) { + midiOutShortMsg(midihout[i], status + (note << 8) + (vel << 16)); + } } void Midi::noteReceived(int status, int note, int velocity) { - if (((status & MIDI_STATUS_MASK) != MIDI_NOTE_OFF) && - ((status & MIDI_STATUS_MASK) != MIDI_NOTE_ON)) return; // NOTE: only sending note-on and note-off to Javascript + if (((status & MIDI_STATUS_MASK) != MIDI_NOTE_OFF) && + ((status & MIDI_STATUS_MASK) != MIDI_NOTE_ON)) return; // NOTE: only sending note-on and note-off to Javascript - QVariantMap eventData; - eventData["status"] = status; - eventData["note"] = note; - eventData["velocity"] = velocity; - emit midiNote(eventData); + QVariantMap eventData; + eventData["status"] = status; + eventData["note"] = note; + eventData["velocity"] = velocity; + emit midiNote(eventData); } void Midi::MidiSetup() { - midihin.clear(); - midihout.clear(); + midihin.clear(); + midihout.clear(); - MIDIINCAPS incaps; - for (unsigned int i = 0; i < midiInGetNumDevs(); i++) { - midiInGetDevCaps(i, &incaps, sizeof(MIDIINCAPS)); + MIDIINCAPS incaps; + for (unsigned int i = 0; i < midiInGetNumDevs(); i++) { + midiInGetDevCaps(i, &incaps, sizeof(MIDIINCAPS)); - bool found = false; - for (int j = 0; j < midiinexclude.size(); j++) { - if (midiinexclude[j].toStdString().compare(incaps.szPname) == 0) found = true; - } - if (!found) { // EXCLUDE AN INPUT BY NAME - HMIDIIN tmphin; - midiInOpen(&tmphin, i, (DWORD_PTR)MidiInProc, NULL, CALLBACK_FUNCTION); - midiInStart(tmphin); - midihin.push_back(tmphin); - } + bool found = false; + for (int j = 0; j < midiinexclude.size(); j++) { + if (midiinexclude[j].toStdString().compare(incaps.szPname) == 0) { + found = true; + } + } + if (!found) { // EXCLUDE AN INPUT BY NAME + HMIDIIN tmphin; + midiInOpen(&tmphin, i, (DWORD_PTR)MidiInProc, NULL, CALLBACK_FUNCTION); + midiInStart(tmphin); + midihin.push_back(tmphin); + } - } + } - MIDIOUTCAPS outcaps; - for (unsigned int i = 0; i < midiOutGetNumDevs(); i++) { - midiOutGetDevCaps(i, &outcaps, sizeof(MIDIINCAPS)); + MIDIOUTCAPS outcaps; + for (unsigned int i = 0; i < midiOutGetNumDevs(); i++) { + midiOutGetDevCaps(i, &outcaps, sizeof(MIDIINCAPS)); - bool found = false; - for (int j = 0; j < midioutexclude.size(); j++) { - if (midioutexclude[j].toStdString().compare(outcaps.szPname) == 0) found = true; - } - if (!found) { // EXCLUDE AN OUTPUT BY NAME - HMIDIOUT tmphout; - midiOutOpen(&tmphout, i, (DWORD_PTR)MidiOutProc, NULL, CALLBACK_FUNCTION); - midihout.push_back(tmphout); - } - } + bool found = false; + for (int j = 0; j < midioutexclude.size(); j++) { + if (midioutexclude[j].toStdString().compare(outcaps.szPname) == 0) { + found = true; + } + } + if (!found) { // EXCLUDE AN OUTPUT BY NAME + HMIDIOUT tmphout; + midiOutOpen(&tmphout, i, (DWORD_PTR)MidiOutProc, NULL, CALLBACK_FUNCTION); + midihout.push_back(tmphout); + } + } - allNotesOff(); + allNotesOff(); } void Midi::MidiCleanup() { - allNotesOff(); + allNotesOff(); - for (int i = 0; i < midihin.size(); i++) if (midihin[i] != NULL) { - midiInStop(midihin[i]); - midiInClose(midihin[i]); - } - for (int i = 0; i < midihout.size(); i++) if (midihout[i] != NULL) { - midiOutClose(midihout[i]); - } - midihin.clear(); - midihout.clear(); + for (int i = 0; i < midihin.size(); i++) { + if (midihin[i] != NULL) { + midiInStop(midihin[i]); + midiInClose(midihin[i]); + } + } + for (int i = 0; i < midihout.size(); i++) { + if (midihout[i] != NULL) { + midiOutClose(midihout[i]); + } + } + midihin.clear(); + midihout.clear(); } #else void Midi::sendNote(int status, int note, int vel) { } void Midi::MidiSetup() { - allNotesOff(); + allNotesOff(); } void Midi::MidiCleanup() { - allNotesOff(); + allNotesOff(); } #endif // Midi::Midi() { - instance = this; - midioutexclude.push_back("Microsoft GS Wavetable Synth"); // we don't want to hear this thing - MidiSetup(); + instance = this; + midioutexclude.push_back("Microsoft GS Wavetable Synth"); // we don't want to hear this thing + MidiSetup(); } void Midi::playMidiNote(int status, int note, int velocity) { - sendNote(status, note, velocity); + sendNote(status, note, velocity); } void Midi::allNotesOff() { - sendNote(MIDI_CONTROL_CHANGE, MIDI_CHANNEL_MODE_ALL_NOTES_OFF, 0); // all notes off + sendNote(MIDI_CONTROL_CHANGE, MIDI_CHANNEL_MODE_ALL_NOTES_OFF, 0); // all notes off } void Midi::resetDevices() { - MidiCleanup(); - MidiSetup(); + MidiCleanup(); + MidiSetup(); } void Midi::USBchanged() { - instance->MidiCleanup(); - instance->MidiSetup(); + instance->MidiCleanup(); + instance->MidiSetup(); } // QStringList Midi::listMidiDevices(bool output) { - QStringList rv; + QStringList rv; #if defined Q_OS_WIN32 - if (output) { - MIDIOUTCAPS outcaps; - for (unsigned int i = 0; i < midiOutGetNumDevs(); i++) { - midiOutGetDevCaps(i, &outcaps, sizeof(MIDIINCAPS)); - rv.append(outcaps.szPname); - } - } - else { - MIDIINCAPS incaps; - for (unsigned int i = 0; i < midiInGetNumDevs(); i++) { - midiInGetDevCaps(i, &incaps, sizeof(MIDIINCAPS)); - rv.append(incaps.szPname); - } - } + if (output) { + MIDIOUTCAPS outcaps; + for (unsigned int i = 0; i < midiOutGetNumDevs(); i++) { + midiOutGetDevCaps(i, &outcaps, sizeof(MIDIINCAPS)); + rv.append(outcaps.szPname); + } + } else { + MIDIINCAPS incaps; + for (unsigned int i = 0; i < midiInGetNumDevs(); i++) { + midiInGetDevCaps(i, &incaps, sizeof(MIDIINCAPS)); + rv.append(incaps.szPname); + } + } #endif - return rv; + return rv; } void Midi::unblockMidiDevice(QString name, bool output) { - if (output) { - for (int i = 0; i < midioutexclude.size(); i++) if (midioutexclude[i].toStdString().compare(name.toStdString()) == 0) { - midioutexclude.erase(midioutexclude.begin() + i); - break; - } - } - else { - for (int i = 0; i < midiinexclude.size(); i++) if (midiinexclude[i].toStdString().compare(name.toStdString()) == 0) { - midiinexclude.erase(midiinexclude.begin() + i); - break; - } - } + if (output) { + for (int i = 0; i < midioutexclude.size(); i++) { + if (midioutexclude[i].toStdString().compare(name.toStdString()) == 0) { + midioutexclude.erase(midioutexclude.begin() + i); + break; + } + } + } else { + for (int i = 0; i < midiinexclude.size(); i++) { + if (midiinexclude[i].toStdString().compare(name.toStdString()) == 0) { + midiinexclude.erase(midiinexclude.begin() + i); + break; + } + } + } } void Midi::blockMidiDevice(QString name, bool output) { - unblockMidiDevice(name, output); // make sure it's only in there once - if (output) { - midioutexclude.push_back(name); - } - else { - midiinexclude.push_back(name); - } + unblockMidiDevice(name, output); // make sure it's only in there once + if (output) { + midioutexclude.push_back(name); + } else { + midiinexclude.push_back(name); + } } diff --git a/libraries/midi/src/Midi.h b/libraries/midi/src/Midi.h index 66e45f0a53..90ce9f8a37 100644 --- a/libraries/midi/src/Midi.h +++ b/libraries/midi/src/Midi.h @@ -24,23 +24,23 @@ class Midi : public QObject, public Dependency { SINGLETON_DEPENDENCY public: - Midi(); + Midi(); public: - void noteReceived(int status, int note, int velocity); // relay a note to Javascript - void sendNote(int status, int note, int vel); // relay a note to MIDI outputs - static void USBchanged(); + void noteReceived(int status, int note, int velocity); // relay a note to Javascript + void sendNote(int status, int note, int vel); // relay a note to MIDI outputs + static void USBchanged(); private: - static std::vector midiinexclude; - static std::vector midioutexclude; + static std::vector midiinexclude; + static std::vector midioutexclude; private: - void MidiSetup(); - void MidiCleanup(); + void MidiSetup(); + void MidiCleanup(); signals: - void midiNote(QVariantMap eventData); + void midiNote(QVariantMap eventData); public slots: /// play a note on all connected devices diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 3a846d3026..568260d6e3 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -76,7 +76,7 @@ #include -#include "../../midi/src/Midi.h" // FIXME why won't a simpler include work? +#include "../../midi/src/Midi.h" // FIXME why won't a simpler include work? #include "MIDIEvent.h" const QString ScriptEngine::_SETTINGS_ENABLE_EXTENDED_EXCEPTIONS { diff --git a/scripts/tutorials/createMidiSphere.js b/scripts/tutorials/createMidiSphere.js index 705acac9de..a36d4bf608 100644 --- a/scripts/tutorials/createMidiSphere.js +++ b/scripts/tutorials/createMidiSphere.js @@ -16,7 +16,7 @@ var BALL_GRAVITY = { y: 0, z: 0 }; - + var BALL_DIMENSIONS = { x: 0.4, y: 0.4, @@ -34,14 +34,14 @@ var midiSphereProperties = { name: 'MIDI Sphere', shapeType: 'sphere', type: 'Sphere', - script: SCRIPT_URL, + script: SCRIPT_URL, color: BALL_COLOR, dimensions: BALL_DIMENSIONS, gravity: BALL_GRAVITY, dynamic: false, position: center, - collisionless: false, - ignoreForCollisions: true + collisionless: false, + ignoreForCollisions: true }; var midiSphere = Entities.addEntity(midiSphereProperties); diff --git a/scripts/tutorials/entity_scripts/midiSphere.js b/scripts/tutorials/entity_scripts/midiSphere.js index 5ed29a330f..980f8f834e 100644 --- a/scripts/tutorials/entity_scripts/midiSphere.js +++ b/scripts/tutorials/entity_scripts/midiSphere.js @@ -15,35 +15,35 @@ function MidiSphere() { _this = this; - this.clicked = false; - return; + this.clicked = false; + return; } - + MidiSphere.prototype = { preload: function(entityID) { this.entityID = entityID; - Midi.midiNote.connect(function(eventData) { - print("MidiSphere.noteReceived: "+JSON.stringify(eventData)); - Entities.editEntity(entityID, { color: { red: 2*eventData.note, green: 2*eventData.note, blue: 2*eventData.note} }); - }); - print("MidiSphere.preload"); + Midi.midiNote.connect(function(eventData) { + print("MidiSphere.noteReceived: "+JSON.stringify(eventData)); + Entities.editEntity(entityID, { color: { red: 2*eventData.note, green: 2*eventData.note, blue: 2*eventData.note} }); + }); + print("MidiSphere.preload"); }, unload: function(entityID) { - print("MidiSphere.unload"); + print("MidiSphere.unload"); }, - clickDownOnEntity: function(entityID, mouseEvent) { - print("MidiSphere.clickDownOnEntity"); - if (this.clicked) { - Entities.editEntity(entityID, { color: { red: 0, green: 255, blue: 255} }); - this.clicked = false; - Midi.playMidiNote(144, 64, 0); - } else { - Entities.editEntity(entityID, { color: { red: 255, green: 255, blue: 0} }); - this.clicked = true; - Midi.playMidiNote(144, 64, 100); - } - } + clickDownOnEntity: function(entityID, mouseEvent) { + print("MidiSphere.clickDownOnEntity"); + if (this.clicked) { + Entities.editEntity(entityID, { color: { red: 0, green: 255, blue: 255} }); + this.clicked = false; + Midi.playMidiNote(144, 64, 0); + } else { + Entities.editEntity(entityID, { color: { red: 255, green: 255, blue: 0} }); + this.clicked = true; + Midi.playMidiNote(144, 64, 100); + } + } }; From a29f07aef50f96ebe9278f3e2cf0eebe6d80dcdc Mon Sep 17 00:00:00 2001 From: Burt Sloane Date: Thu, 15 Jun 2017 17:32:59 -0700 Subject: [PATCH 11/21] one more --- libraries/midi/src/Midi.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libraries/midi/src/Midi.cpp b/libraries/midi/src/Midi.cpp index a3d4db0c88..2d2d08440e 100644 --- a/libraries/midi/src/Midi.cpp +++ b/libraries/midi/src/Midi.cpp @@ -74,8 +74,10 @@ void CALLBACK MidiOutProc(HMIDIOUT hmo, UINT wMsg, DWORD_PTR dwInstance, DWORD_P void Midi::sendNote(int status, int note, int vel) { - for (int i = 0; i < midihout.size(); i++) if (midihout[i] != NULL) { - midiOutShortMsg(midihout[i], status + (note << 8) + (vel << 16)); + for (int i = 0; i < midihout.size(); i++) { + if (midihout[i] != NULL) { + midiOutShortMsg(midihout[i], status + (note << 8) + (vel << 16)); + } } } From 6f842dc204aa1abdf5e4aa2240018c8b63650771 Mon Sep 17 00:00:00 2001 From: Burt Sloane Date: Fri, 16 Jun 2017 14:30:20 -0700 Subject: [PATCH 12/21] requested changes --- libraries/midi/src/Midi.cpp | 67 +++++++++++++++++++++++++------------ libraries/midi/src/Midi.h | 3 ++ 2 files changed, 49 insertions(+), 21 deletions(-) diff --git a/libraries/midi/src/Midi.cpp b/libraries/midi/src/Midi.cpp index 2d2d08440e..5b5376c6d3 100644 --- a/libraries/midi/src/Midi.cpp +++ b/libraries/midi/src/Midi.cpp @@ -20,6 +20,9 @@ #endif +const int MIDI_BYTE_MASK = 0x0FF; +const int MIDI_SHIFT_NOTE = 8; +const int MIDI_SHIFT_VELOCITY = 16; const int MIDI_STATUS_MASK = 0x0F0; const int MIDI_NOTE_OFF = 0x080; const int MIDI_NOTE_ON = 0x090; @@ -28,6 +31,7 @@ const int MIDI_CHANNEL_MODE_ALL_NOTES_OFF = 0x07b; static Midi* instance = NULL; // communicate this to non-class callbacks +static bool thruModeEnabled = false; std::vector Midi::midiinexclude; std::vector Midi::midioutexclude; @@ -43,32 +47,45 @@ std::vector midihout; void CALLBACK MidiInProc(HMIDIIN hMidiIn, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) { - if (wMsg == MIM_OPEN) { - } else if (wMsg == MIM_CLOSE) { - for (int i = 0; i < midihin.size(); i++) { - if (midihin[i] == hMidiIn) { - midihin[i] = NULL; - instance->allNotesOff(); + switch (wMsg) { + case MIM_OPEN: + // message not used + break; + case MIM_CLOSE: + for (int i = 0; i < midihin.size(); i++) { + if (midihin[i] == hMidiIn) { + midihin[i] = NULL; + instance->allNotesOff(); + } } + break; + case MIM_DATA: { + int status = MIDI_BYTE_MASK & dwParam1; + int note = MIDI_BYTE_MASK & (dwParam1 >> MIDI_SHIFT_NOTE); + int vel = MIDI_BYTE_MASK & (dwParam1 >> MIDI_SHIFT_VELOCITY); + if (thruModeEnabled) { + instance->sendNote(status, note, vel); // relay the note on to all other midi devices + } + instance->noteReceived(status, note, vel); // notify the javascript + break; } - } else if (wMsg == MIM_DATA) { - int status = 0x0ff & dwParam1; - int note = 0x0ff & (dwParam1 >> 8); - int vel = 0x0ff & (dwParam1 >> 16); -//sendNote(status, note, vel); // NOTE: relay the note on to all other midi devices - instance->Midi::noteReceived(status, note, vel); } } void CALLBACK MidiOutProc(HMIDIOUT hmo, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) { - if (wMsg == MOM_CLOSE) { - for (int i = 0; i < midihout.size(); i++) { - if (midihout[i] == hmo) { - midihout[i] = NULL; - instance->allNotesOff(); + switch (wMsg) { + case MOM_OPEN: + // message not used + break; + case MOM_CLOSE: + for (int i = 0; i < midihout.size(); i++) { + if (midihout[i] == hmo) { + midihout[i] = NULL; + instance->allNotesOff(); + } } - } + break; } } @@ -76,14 +93,16 @@ void CALLBACK MidiOutProc(HMIDIOUT hmo, UINT wMsg, DWORD_PTR dwInstance, DWORD_P void Midi::sendNote(int status, int note, int vel) { for (int i = 0; i < midihout.size(); i++) { if (midihout[i] != NULL) { - midiOutShortMsg(midihout[i], status + (note << 8) + (vel << 16)); + midiOutShortMsg(midihout[i], status + (note << MIDI_SHIFT_NOTE) + (vel << MIDI_SHIFT_VELOCITY)); } } } void Midi::noteReceived(int status, int note, int velocity) { if (((status & MIDI_STATUS_MASK) != MIDI_NOTE_OFF) && - ((status & MIDI_STATUS_MASK) != MIDI_NOTE_ON)) return; // NOTE: only sending note-on and note-off to Javascript + ((status & MIDI_STATUS_MASK) != MIDI_NOTE_ON)) { + return; // NOTE: only sending note-on and note-off to Javascript + } QVariantMap eventData; eventData["status"] = status; @@ -105,9 +124,10 @@ void Midi::MidiSetup() { for (int j = 0; j < midiinexclude.size(); j++) { if (midiinexclude[j].toStdString().compare(incaps.szPname) == 0) { found = true; + break; } } - if (!found) { // EXCLUDE AN INPUT BY NAME + if (!found) { // EXCLUDE AN INPUT BY NAME HMIDIIN tmphin; midiInOpen(&tmphin, i, (DWORD_PTR)MidiInProc, NULL, CALLBACK_FUNCTION); midiInStart(tmphin); @@ -124,6 +144,7 @@ void Midi::MidiSetup() { for (int j = 0; j < midioutexclude.size(); j++) { if (midioutexclude[j].toStdString().compare(outcaps.szPname) == 0) { found = true; + break; } } if (!found) { // EXCLUDE AN OUTPUT BY NAME @@ -241,3 +262,7 @@ void Midi::blockMidiDevice(QString name, bool output) { } } +void Midi::thruModeEnable(bool enable) { + thruModeEnabled = enable; +} + diff --git a/libraries/midi/src/Midi.h b/libraries/midi/src/Midi.h index 90ce9f8a37..e8ba803ad4 100644 --- a/libraries/midi/src/Midi.h +++ b/libraries/midi/src/Midi.h @@ -63,6 +63,9 @@ Q_INVOKABLE void blockMidiDevice(QString name, bool output); /// unblock an input/output by name Q_INVOKABLE void unblockMidiDevice(QString name, bool output); + +/// repeat all incoming notes to all outputs (default disabled) +Q_INVOKABLE void thruModeEnable(bool enable); }; #endif // hifi_Midi_h From f1485afccc80585499dd0d6b9ab4691f74f85853 Mon Sep 17 00:00:00 2001 From: Burt Sloane Date: Thu, 22 Jun 2017 13:01:11 -0700 Subject: [PATCH 13/21] public script --- scripts/tutorials/createMidiSphere.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/tutorials/createMidiSphere.js b/scripts/tutorials/createMidiSphere.js index a36d4bf608..cfec8b59dc 100644 --- a/scripts/tutorials/createMidiSphere.js +++ b/scripts/tutorials/createMidiSphere.js @@ -8,7 +8,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var SCRIPT_URL = "file:///e:/hifi/scripts/tutorials/entity_scripts/midiSphere.js"; +//var SCRIPT_URL = "file:///e:/hifi/scripts/tutorials/entity_scripts/midiSphere.js"; +var SCRIPT_URL = "http://hifi-files.s3-website-us-west-2.amazonaws.com/midiSphere.js";" var center = Vec3.sum(MyAvatar.position, Vec3.multiply(0.5, Quat.getForward(Camera.getOrientation()))); var BALL_GRAVITY = { From 2b111358e1cb445d14128c00c7e1712986c5b0b2 Mon Sep 17 00:00:00 2001 From: Burt Sloane Date: Thu, 29 Jun 2017 16:49:00 -0700 Subject: [PATCH 14/21] extra quote --- scripts/tutorials/createMidiSphere.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/tutorials/createMidiSphere.js b/scripts/tutorials/createMidiSphere.js index cfec8b59dc..56eae98585 100644 --- a/scripts/tutorials/createMidiSphere.js +++ b/scripts/tutorials/createMidiSphere.js @@ -9,7 +9,7 @@ // //var SCRIPT_URL = "file:///e:/hifi/scripts/tutorials/entity_scripts/midiSphere.js"; -var SCRIPT_URL = "http://hifi-files.s3-website-us-west-2.amazonaws.com/midiSphere.js";" +var SCRIPT_URL = "http://hifi-files.s3-website-us-west-2.amazonaws.com/midiSphere.js"; var center = Vec3.sum(MyAvatar.position, Vec3.multiply(0.5, Quat.getForward(Camera.getOrientation()))); var BALL_GRAVITY = { From 88838da6e584dd2375909173dd3da250c494e932 Mon Sep 17 00:00:00 2001 From: Burt Sloane Date: Tue, 25 Jul 2017 17:46:08 -0700 Subject: [PATCH 15/21] cleaning up for mac and linux --- libraries/midi/src/Midi.cpp | 112 +++++++++++++++++++++++++++++++----- libraries/midi/src/Midi.h | 11 ++-- 2 files changed, 103 insertions(+), 20 deletions(-) diff --git a/libraries/midi/src/Midi.cpp b/libraries/midi/src/Midi.cpp index 5b5376c6d3..ca6c67ad81 100644 --- a/libraries/midi/src/Midi.cpp +++ b/libraries/midi/src/Midi.cpp @@ -98,19 +98,6 @@ void Midi::sendNote(int status, int note, int vel) { } } -void Midi::noteReceived(int status, int note, int velocity) { - if (((status & MIDI_STATUS_MASK) != MIDI_NOTE_OFF) && - ((status & MIDI_STATUS_MASK) != MIDI_NOTE_ON)) { - return; // NOTE: only sending note-on and note-off to Javascript - } - - QVariantMap eventData; - eventData["status"] = status; - eventData["note"] = note; - eventData["velocity"] = velocity; - emit midiNote(eventData); -} - void Midi::MidiSetup() { midihin.clear(); @@ -187,14 +174,32 @@ void Midi::MidiCleanup() { } #endif +void Midi::noteReceived(int status, int note, int velocity) { + if (((status & MIDI_STATUS_MASK) != MIDI_NOTE_OFF) && + ((status & MIDI_STATUS_MASK) != MIDI_NOTE_ON)) { + return; // NOTE: only sending note-on and note-off to Javascript + } + + QVariantMap eventData; + eventData["status"] = status; + eventData["note"] = note; + eventData["velocity"] = velocity; +// emit midiNote(eventData); +} + // Midi::Midi() { instance = this; +#if defined Q_OS_WIN32 midioutexclude.push_back("Microsoft GS Wavetable Synth"); // we don't want to hear this thing +#endif MidiSetup(); } +Midi::~Midi() { +} + void Midi::playMidiNote(int status, int note, int velocity) { sendNote(status, note, velocity); } @@ -237,14 +242,14 @@ QStringList Midi::listMidiDevices(bool output) { void Midi::unblockMidiDevice(QString name, bool output) { if (output) { - for (int i = 0; i < midioutexclude.size(); i++) { + for (unsigned long i = 0; i < midioutexclude.size(); i++) { if (midioutexclude[i].toStdString().compare(name.toStdString()) == 0) { midioutexclude.erase(midioutexclude.begin() + i); break; } } } else { - for (int i = 0; i < midiinexclude.size(); i++) { + for (unsigned long i = 0; i < midiinexclude.size(); i++) { if (midiinexclude[i].toStdString().compare(name.toStdString()) == 0) { midiinexclude.erase(midiinexclude.begin() + i); break; @@ -266,3 +271,80 @@ void Midi::thruModeEnable(bool enable) { thruModeEnabled = enable; } +/* +/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -arch x86_64 -isysroot +/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk -L/Users/burt/hifi/assignment-client/Debug -F/Users/burt/hifi/assignment-client/Debug -F/Users/burt/Qt5.6.2/5.6/clang_64/lib -filelist +/Users/burt/hifi/assignment-client/hifi.build/Debug/assignment-client.build/Objects-normal/x86_64/assignment-client.LinkFileList -Xlinker -rpath -Xlinker +/Users/burt/Qt5.6.2/5.6/clang_64/lib -mmacosx-version-min=10.8 -Xlinker -object_path_lto -Xlinker +/Users/burt/hifi/assignment-client/hifi.build/Debug/assignment-client.build/Objects-normal/x86_64/assignment-client_lto.o -Xlinker -no_deduplicate -stdlib=libc++ -Wl,-search_paths_first -Wl,-headerpad_max_install_names +/Users/burt/hifi/libraries/audio/Debug/libaudio.a +/Users/burt/hifi/libraries/avatars/Debug/libavatars.a +/Users/burt/hifi/libraries/octree/Debug/liboctree.a +/Users/burt/hifi/libraries/gpu/Debug/libgpu.a +/Users/burt/hifi/libraries/model/Debug/libmodel.a +/Users/burt/hifi/libraries/fbx/Debug/libfbx.a +/Users/burt/hifi/libraries/entities/Debug/libentities.a +/Users/burt/hifi/libraries/networking/Debug/libnetworking.a +/Users/burt/hifi/libraries/animation/Debug/libanimation.a +/Users/burt/hifi/libraries/recording/Debug/librecording.a +/Users/burt/hifi/libraries/shared/Debug/libshared.a +/Users/burt/hifi/libraries/script-engine/Debug/libscript-engine.a +/Users/burt/hifi/libraries/embedded-webserver/Debug/libembedded-webserver.a +/Users/burt/hifi/libraries/controllers/Debug/libcontrollers.a +/Users/burt/hifi/libraries/physics/Debug/libphysics.a +/Users/burt/hifi/libraries/plugins/Debug/libplugins.a +/Users/burt/hifi/libraries/ui/Debug/libui.a +/Users/burt/hifi/libraries/script-engine/Debug/libscript-engine.a +/Users/burt/hifi/libraries/ui/Debug/libui.a +/Users/burt/hifi/libraries/recording/Debug/librecording.a +/Users/burt/hifi/libraries/controllers/Debug/libcontrollers.a +/Users/burt/hifi/libraries/physics/Debug/libphysics.a +/Users/burt/hifi/libraries/entities/Debug/libentities.a +/Users/burt/hifi/libraries/audio/Debug/libaudio.a +/Users/burt/hifi/libraries/plugins/Debug/libplugins.a +/Users/burt/hifi/libraries/avatars/Debug/libavatars.a +/Users/burt/hifi/libraries/octree/Debug/liboctree.a +/Users/burt/hifi/libraries/animation/Debug/libanimation.a +/Users/burt/hifi/ext/Xcode/bullet/project/lib/libBulletDynamics.dylib +/Users/burt/hifi/ext/Xcode/bullet/project/lib/libBulletCollision.dylib +/Users/burt/hifi/ext/Xcode/bullet/project/lib/libLinearMath.dylib +/Users/burt/hifi/ext/Xcode/bullet/project/lib/libBulletSoftBody.dylib +/Users/burt/Qt5.6.2/5.6/clang_64/lib/QtScriptTools.framework/QtScriptTools +/Users/burt/hifi/ext/Xcode/quazip/project/lib/libquazip5d.1.0.0.dylib +/Users/burt/hifi/libraries/procedural/Debug/libprocedural.a +/Users/burt/hifi/libraries/model-networking/Debug/libmodel-networking.a +/Users/burt/hifi/libraries/fbx/Debug/libfbx.a +/Users/burt/hifi/libraries/model/Debug/libmodel.a +/Users/burt/hifi/libraries/image/Debug/libimage.a +/Users/burt/hifi/ext/Xcode/nvtt/project/lib/libnvtt.dylib +/Users/burt/hifi/libraries/gpu-gl/Debug/libgpu-gl.a +/Users/burt/hifi/libraries/gpu/Debug/libgpu.a +/Users/burt/hifi/libraries/ktx/Debug/libktx.a +/Users/burt/Qt5.6.2/5.6/clang_64/lib/QtConcurrent.framework/QtConcurrent -lpthread +/Users/burt/Qt5.6.2/5.6/clang_64/lib/QtWebSockets.framework/QtWebSockets +/Users/burt/Qt5.6.2/5.6/clang_64/lib/QtXmlPatterns.framework/QtXmlPatterns +/Users/burt/hifi/libraries/gl/Debug/libgl.a +/Users/burt/hifi/libraries/networking/Debug/libnetworking.a +/Users/burt/Qt5.6.2/5.6/clang_64/lib/QtWebEngine.framework/QtWebEngine +/Users/burt/Qt5.6.2/5.6/clang_64/lib/QtWebEngineCore.framework/QtWebEngineCore +/Users/burt/Qt5.6.2/5.6/clang_64/lib/QtQuick.framework/QtQuick +/Users/burt/Qt5.6.2/5.6/clang_64/lib/QtWebChannel.framework/QtWebChannel +/Users/burt/Qt5.6.2/5.6/clang_64/lib/QtPositioning.framework/QtPositioning +/usr/local/Cellar/openssl/1.0.2k/lib/libssl.dylib +/usr/local/Cellar/openssl/1.0.2k/lib/libcrypto.dylib +/Users/burt/hifi/ext/Xcode/tbb/project/src/tbb/lib/libtbb_debug.dylib +/Users/burt/hifi/ext/Xcode/tbb/project/src/tbb/lib/libtbbmalloc_debug.dylib -framework IOKit -framework CoreFoundation +/Users/burt/hifi/libraries/shared/Debug/libshared.a +/Users/burt/Qt5.6.2/5.6/clang_64/lib/QtScript.framework/QtScript +/usr/local/lib/libz.a +/Users/burt/Qt5.6.2/5.6/clang_64/lib/QtQml.framework/QtQml +/Users/burt/Qt5.6.2/5.6/clang_64/lib/QtOpenGL.framework/QtOpenGL +/Users/burt/Qt5.6.2/5.6/clang_64/lib/QtWidgets.framework/QtWidgets +/Users/burt/Qt5.6.2/5.6/clang_64/lib/QtGui.framework/QtGui -framework OpenGL +/Users/burt/hifi/ext/Xcode/glew/project/lib/libglew_d.a +/Users/burt/Qt5.6.2/5.6/clang_64/lib/QtNetwork.framework/QtNetwork +/Users/burt/Qt5.6.2/5.6/clang_64/lib/QtCore.framework/QtCore -Xlinker -dependency_info -Xlinker +/Users/burt/hifi/assignment-client/hifi.build/Debug/assignment-client.build/Objects-normal/x86_64/assignment-client_dependency_info.dat -o +/Users/burt/hifi/assignment-client/Debug/assignment-client +*/ + diff --git a/libraries/midi/src/Midi.h b/libraries/midi/src/Midi.h index e8ba803ad4..54ffdb58e8 100644 --- a/libraries/midi/src/Midi.h +++ b/libraries/midi/src/Midi.h @@ -22,9 +22,6 @@ class Midi : public QObject, public Dependency { Q_OBJECT SINGLETON_DEPENDENCY - -public: - Midi(); public: void noteReceived(int status, int note, int velocity); // relay a note to Javascript @@ -39,8 +36,8 @@ private: void MidiSetup(); void MidiCleanup(); -signals: - void midiNote(QVariantMap eventData); +//signals: +// void midiNote(QVariantMap eventData); public slots: /// play a note on all connected devices @@ -66,6 +63,10 @@ Q_INVOKABLE void unblockMidiDevice(QString name, bool output); /// repeat all incoming notes to all outputs (default disabled) Q_INVOKABLE void thruModeEnable(bool enable); + +public: + Midi(); + virtual ~Midi(); }; #endif // hifi_Midi_h From d2975c79c9b5f495e365a03fcfedd6f1ed37c308 Mon Sep 17 00:00:00 2001 From: Burt Sloane Date: Wed, 26 Jul 2017 08:41:26 -0700 Subject: [PATCH 16/21] add midi to 3 CMakeLists.txt for linking --- assignment-client/CMakeLists.txt | 2 +- plugins/oculusLegacy/CMakeLists.txt | 2 +- tests/controllers/CMakeLists.txt | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/assignment-client/CMakeLists.txt b/assignment-client/CMakeLists.txt index 54afabfd21..f891afdbfb 100644 --- a/assignment-client/CMakeLists.txt +++ b/assignment-client/CMakeLists.txt @@ -11,7 +11,7 @@ endif () link_hifi_libraries( audio avatars octree gpu model fbx entities networking animation recording shared script-engine embedded-webserver - controllers physics plugins + controllers physics plugins midi ) if (WIN32) diff --git a/plugins/oculusLegacy/CMakeLists.txt b/plugins/oculusLegacy/CMakeLists.txt index f4e1bb76a2..12d0236cc2 100644 --- a/plugins/oculusLegacy/CMakeLists.txt +++ b/plugins/oculusLegacy/CMakeLists.txt @@ -13,7 +13,7 @@ if (APPLE) set(TARGET_NAME oculusLegacy) setup_hifi_plugin() - link_hifi_libraries(shared gl gpu gpu-gl plugins ui ui-plugins display-plugins input-plugins) + link_hifi_libraries(shared gl gpu gpu-gl plugins ui ui-plugins display-plugins input-plugins midi) include_hifi_library_headers(octree) diff --git a/tests/controllers/CMakeLists.txt b/tests/controllers/CMakeLists.txt index 3aac4db0a8..7be71928be 100644 --- a/tests/controllers/CMakeLists.txt +++ b/tests/controllers/CMakeLists.txt @@ -6,7 +6,7 @@ setup_hifi_project(Script Qml) set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/") # link in the shared libraries -link_hifi_libraries(shared gl script-engine plugins render-utils ui-plugins input-plugins display-plugins controllers) +link_hifi_libraries(shared gl script-engine plugins render-utils ui-plugins input-plugins display-plugins controllers midi) if (WIN32) @@ -16,4 +16,4 @@ if (WIN32) target_link_libraries(${TARGET_NAME} ${OPENVR_LIBRARIES}) endif() -package_libraries_for_deployment() \ No newline at end of file +package_libraries_for_deployment() From 246a5c9fa4ca91cfa76c7bbaa7fb093395c1031c Mon Sep 17 00:00:00 2001 From: Burt Sloane Date: Wed, 26 Jul 2017 08:59:48 -0700 Subject: [PATCH 17/21] 1 more --- tests/render-perf/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/render-perf/CMakeLists.txt b/tests/render-perf/CMakeLists.txt index 553e7c06e7..a1ecb7df2a 100644 --- a/tests/render-perf/CMakeLists.txt +++ b/tests/render-perf/CMakeLists.txt @@ -10,7 +10,7 @@ setup_hifi_project(Quick Gui OpenGL) set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/") # link in the shared libraries -link_hifi_libraries(shared octree ktx gl gpu gpu-gl render model model-networking networking render-utils fbx entities entities-renderer animation audio avatars script-engine physics image procedural) +link_hifi_libraries(shared octree ktx gl gpu gpu-gl render model model-networking networking render-utils fbx entities entities-renderer animation audio avatars script-engine physics image procedural midi) package_libraries_for_deployment() From 215fa7b816c943b656f7033eaf7183feb8f64fcb Mon Sep 17 00:00:00 2001 From: Burt Sloane Date: Wed, 26 Jul 2017 09:34:46 -0700 Subject: [PATCH 18/21] removed extra comments --- libraries/midi/src/Midi.cpp | 79 +------------------------------------ 1 file changed, 1 insertion(+), 78 deletions(-) diff --git a/libraries/midi/src/Midi.cpp b/libraries/midi/src/Midi.cpp index ca6c67ad81..7716602144 100644 --- a/libraries/midi/src/Midi.cpp +++ b/libraries/midi/src/Midi.cpp @@ -184,7 +184,7 @@ void Midi::noteReceived(int status, int note, int velocity) { eventData["status"] = status; eventData["note"] = note; eventData["velocity"] = velocity; -// emit midiNote(eventData); + emit midiNote(eventData); } // @@ -271,80 +271,3 @@ void Midi::thruModeEnable(bool enable) { thruModeEnabled = enable; } -/* -/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -arch x86_64 -isysroot -/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk -L/Users/burt/hifi/assignment-client/Debug -F/Users/burt/hifi/assignment-client/Debug -F/Users/burt/Qt5.6.2/5.6/clang_64/lib -filelist -/Users/burt/hifi/assignment-client/hifi.build/Debug/assignment-client.build/Objects-normal/x86_64/assignment-client.LinkFileList -Xlinker -rpath -Xlinker -/Users/burt/Qt5.6.2/5.6/clang_64/lib -mmacosx-version-min=10.8 -Xlinker -object_path_lto -Xlinker -/Users/burt/hifi/assignment-client/hifi.build/Debug/assignment-client.build/Objects-normal/x86_64/assignment-client_lto.o -Xlinker -no_deduplicate -stdlib=libc++ -Wl,-search_paths_first -Wl,-headerpad_max_install_names -/Users/burt/hifi/libraries/audio/Debug/libaudio.a -/Users/burt/hifi/libraries/avatars/Debug/libavatars.a -/Users/burt/hifi/libraries/octree/Debug/liboctree.a -/Users/burt/hifi/libraries/gpu/Debug/libgpu.a -/Users/burt/hifi/libraries/model/Debug/libmodel.a -/Users/burt/hifi/libraries/fbx/Debug/libfbx.a -/Users/burt/hifi/libraries/entities/Debug/libentities.a -/Users/burt/hifi/libraries/networking/Debug/libnetworking.a -/Users/burt/hifi/libraries/animation/Debug/libanimation.a -/Users/burt/hifi/libraries/recording/Debug/librecording.a -/Users/burt/hifi/libraries/shared/Debug/libshared.a -/Users/burt/hifi/libraries/script-engine/Debug/libscript-engine.a -/Users/burt/hifi/libraries/embedded-webserver/Debug/libembedded-webserver.a -/Users/burt/hifi/libraries/controllers/Debug/libcontrollers.a -/Users/burt/hifi/libraries/physics/Debug/libphysics.a -/Users/burt/hifi/libraries/plugins/Debug/libplugins.a -/Users/burt/hifi/libraries/ui/Debug/libui.a -/Users/burt/hifi/libraries/script-engine/Debug/libscript-engine.a -/Users/burt/hifi/libraries/ui/Debug/libui.a -/Users/burt/hifi/libraries/recording/Debug/librecording.a -/Users/burt/hifi/libraries/controllers/Debug/libcontrollers.a -/Users/burt/hifi/libraries/physics/Debug/libphysics.a -/Users/burt/hifi/libraries/entities/Debug/libentities.a -/Users/burt/hifi/libraries/audio/Debug/libaudio.a -/Users/burt/hifi/libraries/plugins/Debug/libplugins.a -/Users/burt/hifi/libraries/avatars/Debug/libavatars.a -/Users/burt/hifi/libraries/octree/Debug/liboctree.a -/Users/burt/hifi/libraries/animation/Debug/libanimation.a -/Users/burt/hifi/ext/Xcode/bullet/project/lib/libBulletDynamics.dylib -/Users/burt/hifi/ext/Xcode/bullet/project/lib/libBulletCollision.dylib -/Users/burt/hifi/ext/Xcode/bullet/project/lib/libLinearMath.dylib -/Users/burt/hifi/ext/Xcode/bullet/project/lib/libBulletSoftBody.dylib -/Users/burt/Qt5.6.2/5.6/clang_64/lib/QtScriptTools.framework/QtScriptTools -/Users/burt/hifi/ext/Xcode/quazip/project/lib/libquazip5d.1.0.0.dylib -/Users/burt/hifi/libraries/procedural/Debug/libprocedural.a -/Users/burt/hifi/libraries/model-networking/Debug/libmodel-networking.a -/Users/burt/hifi/libraries/fbx/Debug/libfbx.a -/Users/burt/hifi/libraries/model/Debug/libmodel.a -/Users/burt/hifi/libraries/image/Debug/libimage.a -/Users/burt/hifi/ext/Xcode/nvtt/project/lib/libnvtt.dylib -/Users/burt/hifi/libraries/gpu-gl/Debug/libgpu-gl.a -/Users/burt/hifi/libraries/gpu/Debug/libgpu.a -/Users/burt/hifi/libraries/ktx/Debug/libktx.a -/Users/burt/Qt5.6.2/5.6/clang_64/lib/QtConcurrent.framework/QtConcurrent -lpthread -/Users/burt/Qt5.6.2/5.6/clang_64/lib/QtWebSockets.framework/QtWebSockets -/Users/burt/Qt5.6.2/5.6/clang_64/lib/QtXmlPatterns.framework/QtXmlPatterns -/Users/burt/hifi/libraries/gl/Debug/libgl.a -/Users/burt/hifi/libraries/networking/Debug/libnetworking.a -/Users/burt/Qt5.6.2/5.6/clang_64/lib/QtWebEngine.framework/QtWebEngine -/Users/burt/Qt5.6.2/5.6/clang_64/lib/QtWebEngineCore.framework/QtWebEngineCore -/Users/burt/Qt5.6.2/5.6/clang_64/lib/QtQuick.framework/QtQuick -/Users/burt/Qt5.6.2/5.6/clang_64/lib/QtWebChannel.framework/QtWebChannel -/Users/burt/Qt5.6.2/5.6/clang_64/lib/QtPositioning.framework/QtPositioning -/usr/local/Cellar/openssl/1.0.2k/lib/libssl.dylib -/usr/local/Cellar/openssl/1.0.2k/lib/libcrypto.dylib -/Users/burt/hifi/ext/Xcode/tbb/project/src/tbb/lib/libtbb_debug.dylib -/Users/burt/hifi/ext/Xcode/tbb/project/src/tbb/lib/libtbbmalloc_debug.dylib -framework IOKit -framework CoreFoundation -/Users/burt/hifi/libraries/shared/Debug/libshared.a -/Users/burt/Qt5.6.2/5.6/clang_64/lib/QtScript.framework/QtScript -/usr/local/lib/libz.a -/Users/burt/Qt5.6.2/5.6/clang_64/lib/QtQml.framework/QtQml -/Users/burt/Qt5.6.2/5.6/clang_64/lib/QtOpenGL.framework/QtOpenGL -/Users/burt/Qt5.6.2/5.6/clang_64/lib/QtWidgets.framework/QtWidgets -/Users/burt/Qt5.6.2/5.6/clang_64/lib/QtGui.framework/QtGui -framework OpenGL -/Users/burt/hifi/ext/Xcode/glew/project/lib/libglew_d.a -/Users/burt/Qt5.6.2/5.6/clang_64/lib/QtNetwork.framework/QtNetwork -/Users/burt/Qt5.6.2/5.6/clang_64/lib/QtCore.framework/QtCore -Xlinker -dependency_info -Xlinker -/Users/burt/hifi/assignment-client/hifi.build/Debug/assignment-client.build/Objects-normal/x86_64/assignment-client_dependency_info.dat -o -/Users/burt/hifi/assignment-client/Debug/assignment-client -*/ - From c777384d939ce8c43a67dfd1473f11ef95d6850b Mon Sep 17 00:00:00 2001 From: Burt Sloane Date: Wed, 26 Jul 2017 10:00:19 -0700 Subject: [PATCH 19/21] another comment removal --- libraries/midi/src/Midi.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/midi/src/Midi.h b/libraries/midi/src/Midi.h index 54ffdb58e8..0ffa27986d 100644 --- a/libraries/midi/src/Midi.h +++ b/libraries/midi/src/Midi.h @@ -36,8 +36,8 @@ private: void MidiSetup(); void MidiCleanup(); -//signals: -// void midiNote(QVariantMap eventData); +signals: + void midiNote(QVariantMap eventData); public slots: /// play a note on all connected devices From a960ea5ccbba13fbeba68c55fcbd3de43bcb46c0 Mon Sep 17 00:00:00 2001 From: Burt Sloane Date: Wed, 26 Jul 2017 13:32:23 -0700 Subject: [PATCH 20/21] Linux build --- libraries/script-engine/CMakeLists.txt | 2 +- tests/controllers/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/script-engine/CMakeLists.txt b/libraries/script-engine/CMakeLists.txt index 39338fd767..42b2d51417 100644 --- a/libraries/script-engine/CMakeLists.txt +++ b/libraries/script-engine/CMakeLists.txt @@ -16,6 +16,6 @@ if (NOT ANDROID) endif () -link_hifi_libraries(shared networking octree gpu ui procedural model model-networking ktx recording avatars fbx entities controllers animation audio physics image) +link_hifi_libraries(shared networking octree gpu ui procedural model model-networking ktx recording avatars fbx entities controllers animation audio physics image midi) # ui includes gl, but link_hifi_libraries does not use transitive includes, so gl must be explicit include_hifi_library_headers(gl) diff --git a/tests/controllers/CMakeLists.txt b/tests/controllers/CMakeLists.txt index 7be71928be..5757a3ad4b 100644 --- a/tests/controllers/CMakeLists.txt +++ b/tests/controllers/CMakeLists.txt @@ -6,7 +6,7 @@ setup_hifi_project(Script Qml) set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/") # link in the shared libraries -link_hifi_libraries(shared gl script-engine plugins render-utils ui-plugins input-plugins display-plugins controllers midi) +link_hifi_libraries(shared gl script-engine plugins render-utils ui-plugins input-plugins display-plugins controllers) if (WIN32) From e557f759b592468320db14231953c88c47baf5d7 Mon Sep 17 00:00:00 2001 From: burtsloane Date: Thu, 27 Jul 2017 16:17:23 -0700 Subject: [PATCH 21/21] Update Midi.cpp --- libraries/midi/src/Midi.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/midi/src/Midi.cpp b/libraries/midi/src/Midi.cpp index 7716602144..ad650cf067 100644 --- a/libraries/midi/src/Midi.cpp +++ b/libraries/midi/src/Midi.cpp @@ -20,9 +20,11 @@ #endif +#if defined Q_OS_WIN32 const int MIDI_BYTE_MASK = 0x0FF; const int MIDI_SHIFT_NOTE = 8; const int MIDI_SHIFT_VELOCITY = 16; +#endif const int MIDI_STATUS_MASK = 0x0F0; const int MIDI_NOTE_OFF = 0x080; const int MIDI_NOTE_ON = 0x090;