Mercurial > hg > touchkeys
view Source/Mappings/MRPMapping.h @ 20:dfff66c07936
Lots of minor changes to support building on Visual Studio. A few MSVC-specific #ifdefs to eliminate things Visual Studio doesn't like. This version now compiles on Windows (provided liblo, Juce and pthread are present) but the TouchKeys device support is not yet enabled. Also, the code now needs to be re-checked on Mac and Linux.
author | Andrew McPherson <andrewm@eecs.qmul.ac.uk> |
---|---|
date | Sun, 09 Feb 2014 18:40:51 +0000 |
parents | 3580ffe87dc8 |
children |
line wrap: on
line source
/* TouchKeys: multi-touch musical keyboard control software Copyright (c) 2013 Andrew McPherson This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. ===================================================================== MRPMapping.h: mapping class for magnetic resonator piano using continuous key position. */ #ifndef __touchkeys__MRPMapping__ #define __touchkeys__MRPMapping__ #include <map> #include <boost/bind.hpp> #include "../TouchKeys/KeyTouchFrame.h" #include "../TouchKeys/KeyPositionTracker.h" #include "../TouchKeys/PianoKeyboard.h" #include "Mapping.h" #include "../Utility/IIRFilter.h" // How many velocity samples to save in the buffer. Make sure this is // enough to cover the frequency of updates. const int kMRPMappingVelocityBufferLength = 30; // This class handles the mapping from key position and, optionally, // touch information to OSC messages which control the magnetic resonator // piano. One copy of the object is created for each active note, and // all objects use the PianoKeyboard Scheduler facility to request timed // updates. class MRPMapping : public Mapping { private: /*// Useful constants for mapping MRP messages const int kMIDINoteOnMessage = 0x90; const int kDefaultMIDIChannel = 15; const float kDefaultAftertouchScaler = 100.0; // Parameters for vibrato detection and mapping const key_velocity kVibratoVelocityThreshold = scale_key_velocity(2.0); const timestamp_diff_type kVibratoMinimumPeakSpacing = microseconds_to_timestamp(60000); const timestamp_diff_type kVibratoTimeout = microseconds_to_timestamp(500000); const int kVibratoMinimumOscillations = 4; const float kVibratoRateScaler = 0.005;*/ // Useful constants for mapping MRP messages static const int kMIDINoteOnMessage; static const int kDefaultMIDIChannel; static const float kDefaultAftertouchScaler; // Parameters for vibrato detection and mapping static const key_velocity kVibratoVelocityThreshold; static const timestamp_diff_type kVibratoMinimumPeakSpacing; static const timestamp_diff_type kVibratoTimeout; static const int kVibratoMinimumOscillations; static const float kVibratoRateScaler; struct PitchBend { int note; // Note number of the bending key bool isControllingBend; // True if the note in this structure // is the one controlling bend (false if it's us) bool isFinished; // True if the bend should finish after this cycle Node<key_position>* positionBuffer; // Key position for bending key KeyPositionTracker* positionTracker; // Key states for bending key }; public: // ***** Constructors ***** // Default constructor, passing the buffer on which to trigger MRPMapping(PianoKeyboard &keyboard, MappingFactory *factory, int noteNumber, Node<KeyTouchFrame>* touchBuffer, Node<key_position>* positionBuffer, KeyPositionTracker* positionTracker); // Copy constructor //MRPMapping(MRPMapping const& obj); // ***** Destructor ***** ~MRPMapping(); // ***** Modifiers ***** // Disable mappings from being sent void disengage(); // Reset the state back initial values void reset(); // Set the aftertouch sensitivity on continuous key position // 0 means no aftertouch, 1 means default sensitivity, upward // from there void setAftertouchSensitivity(float sensitivity); // Engage a pitch bend from a different key, based on its position and state void enablePitchBend(int toNote, Node<key_position>* toPositionBuffer, KeyPositionTracker *toPositionTracker); // ***** Evaluators ***** // This method receives triggers whenever events occur in the touch data or the // continuous key position (state changes only). It alters the behavior and scheduling // of the mapping but does not itself send OSC messages void triggerReceived(TriggerSource* who, timestamp_type timestamp); // This method handles the OSC message transmission. It should be run in the Scheduler // thread provided by PianoKeyboard. timestamp_type performMapping(); private: // ***** Private Methods ***** // Bring velocity calculations up to date key_velocity updateVelocityMeasurements(); // Find the timestamp of the first transition into a PartialPress state timestamp_type findTimestampOfPartialPress(); // ***** Member Variables ***** bool noteIsOn_; // Whether the MIDI note is active or not float aftertouchScaler_; // Scaler which affects aftertouch sensitivity float lastIntensity_, lastBrightness_; // Cached values for mapping qualities float lastPitch_, lastHarmonic_; bool shouldLookForPitchBends_; // Whether to search for adjacent keys to start a pitch bend std::vector<PitchBend> activePitchBends_; // Which keys are involved in a pitch bend Node<key_velocity> rawVelocity_; // History of key velocity measurements IIRFilterNode<key_velocity> filteredVelocity_; // Filtered key velocity information Node<key_position>::size_type lastCalculatedVelocityIndex_; // Keep track of how many velocity samples we've calculated bool vibratoActive_; // Whether a vibrato gesture is currently detected int vibratoVelocityPeakCount_; // Counter for tracking velocity oscillations timestamp_type vibratoLastPeakTimestamp_; // When the last velocity peak took place JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MRPMapping) }; #endif /* defined(__touchkeys__MRPMapping__) */