@@ -1,952 +0,0 @@ | |||
/* | |||
============================================================================== | |||
This file is part of the JUCE library. | |||
Copyright (c) 2017 - ROLI Ltd. | |||
JUCE is an open source library subject to commercial or open-source | |||
licensing. | |||
The code included in this file is provided under the terms of the ISC license | |||
http://www.isc.org/downloads/software-support-policy/isc-license. Permission | |||
To use, copy, modify, and/or distribute this software for any purpose with or | |||
without fee is hereby granted provided that the above copyright notice and | |||
this permission notice appear in all copies. | |||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER | |||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE | |||
DISCLAIMED. | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** | |||
Encapsulates a MIDI message. | |||
@see MidiMessageSequence, MidiOutput, MidiInput | |||
@tags{Audio} | |||
*/ | |||
class JUCE_API MidiMessage | |||
{ | |||
public: | |||
//============================================================================== | |||
/** Creates a 3-byte short midi message. | |||
@param byte1 message byte 1 | |||
@param byte2 message byte 2 | |||
@param byte3 message byte 3 | |||
@param timeStamp the time to give the midi message - this value doesn't | |||
use any particular units, so will be application-specific | |||
*/ | |||
MidiMessage (int byte1, int byte2, int byte3, double timeStamp = 0) noexcept; | |||
/** Creates a 2-byte short midi message. | |||
@param byte1 message byte 1 | |||
@param byte2 message byte 2 | |||
@param timeStamp the time to give the midi message - this value doesn't | |||
use any particular units, so will be application-specific | |||
*/ | |||
MidiMessage (int byte1, int byte2, double timeStamp = 0) noexcept; | |||
/** Creates a 1-byte short midi message. | |||
@param byte1 message byte 1 | |||
@param timeStamp the time to give the midi message - this value doesn't | |||
use any particular units, so will be application-specific | |||
*/ | |||
MidiMessage (int byte1, double timeStamp = 0) noexcept; | |||
/** Creates a midi message from a list of bytes. */ | |||
template <typename... Data> | |||
MidiMessage (int byte1, int byte2, int byte3, Data... otherBytes) : size (3 + sizeof... (otherBytes)) | |||
{ | |||
// this checks that the length matches the data.. | |||
jassert (size > 3 || byte1 >= 0xf0 || getMessageLengthFromFirstByte ((uint8) byte1) == size); | |||
const uint8 data[] = { (uint8) byte1, (uint8) byte2, (uint8) byte3, static_cast<uint8> (otherBytes)... }; | |||
memcpy (allocateSpace (size), data, (size_t) size); | |||
} | |||
/** Creates a midi message from a block of data. */ | |||
MidiMessage (const void* data, int numBytes, double timeStamp = 0); | |||
/** Reads the next midi message from some data. | |||
This will read as many bytes from a data stream as it needs to make a | |||
complete message, and will return the number of bytes it used. This lets | |||
you read a sequence of midi messages from a file or stream. | |||
@param data the data to read from | |||
@param maxBytesToUse the maximum number of bytes it's allowed to read | |||
@param numBytesUsed returns the number of bytes that were actually needed | |||
@param lastStatusByte in a sequence of midi messages, the initial byte | |||
can be dropped from a message if it's the same as the | |||
first byte of the previous message, so this lets you | |||
supply the byte to use if the first byte of the message | |||
has in fact been dropped. | |||
@param timeStamp the time to give the midi message - this value doesn't | |||
use any particular units, so will be application-specific | |||
@param sysexHasEmbeddedLength when reading sysexes, this flag indicates whether | |||
to expect the data to begin with a variable-length | |||
field indicating its size | |||
*/ | |||
MidiMessage (const void* data, int maxBytesToUse, | |||
int& numBytesUsed, uint8 lastStatusByte, | |||
double timeStamp = 0, | |||
bool sysexHasEmbeddedLength = true); | |||
/** Creates an active-sense message. | |||
Since the MidiMessage has to contain a valid message, this default constructor | |||
just initialises it with an empty sysex message. | |||
*/ | |||
MidiMessage() noexcept; | |||
/** Creates a copy of another midi message. */ | |||
MidiMessage (const MidiMessage&); | |||
/** Creates a copy of another midi message, with a different timestamp. */ | |||
MidiMessage (const MidiMessage&, double newTimeStamp); | |||
/** Destructor. */ | |||
~MidiMessage() noexcept; | |||
/** Copies this message from another one. */ | |||
MidiMessage& operator= (const MidiMessage& other); | |||
/** Move constructor */ | |||
MidiMessage (MidiMessage&&) noexcept; | |||
/** Move assignment operator */ | |||
MidiMessage& operator= (MidiMessage&&) noexcept; | |||
//============================================================================== | |||
/** Returns a pointer to the raw midi data. | |||
@see getRawDataSize | |||
*/ | |||
const uint8* getRawData() const noexcept { return getData(); } | |||
/** Returns the number of bytes of data in the message. | |||
@see getRawData | |||
*/ | |||
int getRawDataSize() const noexcept { return size; } | |||
//============================================================================== | |||
/** Returns a human-readable description of the midi message as a string, | |||
for example "Note On C#3 Velocity 120 Channel 1". | |||
*/ | |||
String getDescription() const; | |||
//============================================================================== | |||
/** Returns the timestamp associated with this message. | |||
The exact meaning of this time and its units will vary, as messages are used in | |||
a variety of different contexts. | |||
If you're getting the message from a midi file, this could be a time in seconds, or | |||
a number of ticks - see MidiFile::convertTimestampTicksToSeconds(). | |||
If the message is being used in a MidiBuffer, it might indicate the number of | |||
audio samples from the start of the buffer. | |||
If the message was created by a MidiInput, see MidiInputCallback::handleIncomingMidiMessage() | |||
for details of the way that it initialises this value. | |||
@see setTimeStamp, addToTimeStamp | |||
*/ | |||
double getTimeStamp() const noexcept { return timeStamp; } | |||
/** Changes the message's associated timestamp. | |||
The units for the timestamp will be application-specific - see the notes for getTimeStamp(). | |||
@see addToTimeStamp, getTimeStamp | |||
*/ | |||
void setTimeStamp (double newTimestamp) noexcept { timeStamp = newTimestamp; } | |||
/** Adds a value to the message's timestamp. | |||
The units for the timestamp will be application-specific. | |||
*/ | |||
void addToTimeStamp (double delta) noexcept { timeStamp += delta; } | |||
/** Return a copy of this message with a new timestamp. | |||
The units for the timestamp will be application-specific - see the notes for getTimeStamp(). | |||
*/ | |||
MidiMessage withTimeStamp (double newTimestamp) const; | |||
//============================================================================== | |||
/** Returns the midi channel associated with the message. | |||
@returns a value 1 to 16 if the message has a channel, or 0 if it hasn't (e.g. | |||
if it's a sysex) | |||
@see isForChannel, setChannel | |||
*/ | |||
int getChannel() const noexcept; | |||
/** Returns true if the message applies to the given midi channel. | |||
@param channelNumber the channel number to look for, in the range 1 to 16 | |||
@see getChannel, setChannel | |||
*/ | |||
bool isForChannel (int channelNumber) const noexcept; | |||
/** Changes the message's midi channel. | |||
This won't do anything for non-channel messages like sysexes. | |||
@param newChannelNumber the channel number to change it to, in the range 1 to 16 | |||
*/ | |||
void setChannel (int newChannelNumber) noexcept; | |||
//============================================================================== | |||
/** Returns true if this is a system-exclusive message. | |||
*/ | |||
bool isSysEx() const noexcept; | |||
/** Returns a pointer to the sysex data inside the message. | |||
If this event isn't a sysex event, it'll return 0. | |||
@see getSysExDataSize | |||
*/ | |||
const uint8* getSysExData() const noexcept; | |||
/** Returns the size of the sysex data. | |||
This value excludes the 0xf0 header byte and the 0xf7 at the end. | |||
@see getSysExData | |||
*/ | |||
int getSysExDataSize() const noexcept; | |||
//============================================================================== | |||
/** Returns true if this message is a 'key-down' event. | |||
@param returnTrueForVelocity0 if true, then if this event is a note-on with | |||
velocity 0, it will still be considered to be a note-on and the | |||
method will return true. If returnTrueForVelocity0 is false, then | |||
if this is a note-on event with velocity 0, it'll be regarded as | |||
a note-off, and the method will return false | |||
@see isNoteOff, getNoteNumber, getVelocity, noteOn | |||
*/ | |||
bool isNoteOn (bool returnTrueForVelocity0 = false) const noexcept; | |||
/** Creates a key-down message (using a floating-point velocity). | |||
@param channel the midi channel, in the range 1 to 16 | |||
@param noteNumber the key number, 0 to 127 | |||
@param velocity in the range 0 to 1.0 | |||
@see isNoteOn | |||
*/ | |||
static MidiMessage noteOn (int channel, int noteNumber, float velocity) noexcept; | |||
/** Creates a key-down message (using an integer velocity). | |||
@param channel the midi channel, in the range 1 to 16 | |||
@param noteNumber the key number, 0 to 127 | |||
@param velocity in the range 0 to 127 | |||
@see isNoteOn | |||
*/ | |||
static MidiMessage noteOn (int channel, int noteNumber, uint8 velocity) noexcept; | |||
/** Returns true if this message is a 'key-up' event. | |||
If returnTrueForNoteOnVelocity0 is true, then his will also return true | |||
for a note-on event with a velocity of 0. | |||
@see isNoteOn, getNoteNumber, getVelocity, noteOff | |||
*/ | |||
bool isNoteOff (bool returnTrueForNoteOnVelocity0 = true) const noexcept; | |||
/** Creates a key-up message. | |||
@param channel the midi channel, in the range 1 to 16 | |||
@param noteNumber the key number, 0 to 127 | |||
@param velocity in the range 0 to 1.0 | |||
@see isNoteOff | |||
*/ | |||
static MidiMessage noteOff (int channel, int noteNumber, float velocity) noexcept; | |||
/** Creates a key-up message. | |||
@param channel the midi channel, in the range 1 to 16 | |||
@param noteNumber the key number, 0 to 127 | |||
@param velocity in the range 0 to 127 | |||
@see isNoteOff | |||
*/ | |||
static MidiMessage noteOff (int channel, int noteNumber, uint8 velocity) noexcept; | |||
/** Creates a key-up message. | |||
@param channel the midi channel, in the range 1 to 16 | |||
@param noteNumber the key number, 0 to 127 | |||
@see isNoteOff | |||
*/ | |||
static MidiMessage noteOff (int channel, int noteNumber) noexcept; | |||
/** Returns true if this message is a 'key-down' or 'key-up' event. | |||
@see isNoteOn, isNoteOff | |||
*/ | |||
bool isNoteOnOrOff() const noexcept; | |||
/** Returns the midi note number for note-on and note-off messages. | |||
If the message isn't a note-on or off, the value returned is undefined. | |||
@see isNoteOff, getMidiNoteName, getMidiNoteInHertz, setNoteNumber | |||
*/ | |||
int getNoteNumber() const noexcept; | |||
/** Changes the midi note number of a note-on or note-off message. | |||
If the message isn't a note on or off, this will do nothing. | |||
*/ | |||
void setNoteNumber (int newNoteNumber) noexcept; | |||
//============================================================================== | |||
/** Returns the velocity of a note-on or note-off message. | |||
The value returned will be in the range 0 to 127. | |||
If the message isn't a note-on or off event, it will return 0. | |||
@see getFloatVelocity | |||
*/ | |||
uint8 getVelocity() const noexcept; | |||
/** Returns the velocity of a note-on or note-off message. | |||
The value returned will be in the range 0 to 1.0 | |||
If the message isn't a note-on or off event, it will return 0. | |||
@see getVelocity, setVelocity | |||
*/ | |||
float getFloatVelocity() const noexcept; | |||
/** Changes the velocity of a note-on or note-off message. | |||
If the message isn't a note on or off, this will do nothing. | |||
@param newVelocity the new velocity, in the range 0 to 1.0 | |||
@see getFloatVelocity, multiplyVelocity | |||
*/ | |||
void setVelocity (float newVelocity) noexcept; | |||
/** Multiplies the velocity of a note-on or note-off message by a given amount. | |||
If the message isn't a note on or off, this will do nothing. | |||
@param scaleFactor the value by which to multiply the velocity | |||
@see setVelocity | |||
*/ | |||
void multiplyVelocity (float scaleFactor) noexcept; | |||
//============================================================================== | |||
/** Returns true if this message is a 'sustain pedal down' controller message. */ | |||
bool isSustainPedalOn() const noexcept; | |||
/** Returns true if this message is a 'sustain pedal up' controller message. */ | |||
bool isSustainPedalOff() const noexcept; | |||
/** Returns true if this message is a 'sostenuto pedal down' controller message. */ | |||
bool isSostenutoPedalOn() const noexcept; | |||
/** Returns true if this message is a 'sostenuto pedal up' controller message. */ | |||
bool isSostenutoPedalOff() const noexcept; | |||
/** Returns true if this message is a 'soft pedal down' controller message. */ | |||
bool isSoftPedalOn() const noexcept; | |||
/** Returns true if this message is a 'soft pedal up' controller message. */ | |||
bool isSoftPedalOff() const noexcept; | |||
//============================================================================== | |||
/** Returns true if the message is a program (patch) change message. | |||
@see getProgramChangeNumber, getGMInstrumentName | |||
*/ | |||
bool isProgramChange() const noexcept; | |||
/** Returns the new program number of a program change message. | |||
If the message isn't a program change, the value returned is undefined. | |||
@see isProgramChange, getGMInstrumentName | |||
*/ | |||
int getProgramChangeNumber() const noexcept; | |||
/** Creates a program-change message. | |||
@param channel the midi channel, in the range 1 to 16 | |||
@param programNumber the midi program number, 0 to 127 | |||
@see isProgramChange, getGMInstrumentName | |||
*/ | |||
static MidiMessage programChange (int channel, int programNumber) noexcept; | |||
//============================================================================== | |||
/** Returns true if the message is a pitch-wheel move. | |||
@see getPitchWheelValue, pitchWheel | |||
*/ | |||
bool isPitchWheel() const noexcept; | |||
/** Returns the pitch wheel position from a pitch-wheel move message. | |||
The value returned is a 14-bit number from 0 to 0x3fff, indicating the wheel position. | |||
If called for messages which aren't pitch wheel events, the number returned will be | |||
nonsense. | |||
@see isPitchWheel | |||
*/ | |||
int getPitchWheelValue() const noexcept; | |||
/** Creates a pitch-wheel move message. | |||
@param channel the midi channel, in the range 1 to 16 | |||
@param position the wheel position, in the range 0 to 16383 | |||
@see isPitchWheel | |||
*/ | |||
static MidiMessage pitchWheel (int channel, int position) noexcept; | |||
//============================================================================== | |||
/** Returns true if the message is an aftertouch event. | |||
For aftertouch events, use the getNoteNumber() method to find out the key | |||
that it applies to, and getAftertouchValue() to find out the amount. Use | |||
getChannel() to find out the channel. | |||
@see getAftertouchValue, getNoteNumber | |||
*/ | |||
bool isAftertouch() const noexcept; | |||
/** Returns the amount of aftertouch from an aftertouch messages. | |||
The value returned is in the range 0 to 127, and will be nonsense for messages | |||
other than aftertouch messages. | |||
@see isAftertouch | |||
*/ | |||
int getAfterTouchValue() const noexcept; | |||
/** Creates an aftertouch message. | |||
@param channel the midi channel, in the range 1 to 16 | |||
@param noteNumber the key number, 0 to 127 | |||
@param aftertouchAmount the amount of aftertouch, 0 to 127 | |||
@see isAftertouch | |||
*/ | |||
static MidiMessage aftertouchChange (int channel, | |||
int noteNumber, | |||
int aftertouchAmount) noexcept; | |||
/** Returns true if the message is a channel-pressure change event. | |||
This is like aftertouch, but common to the whole channel rather than a specific | |||
note. Use getChannelPressureValue() to find out the pressure, and getChannel() | |||
to find out the channel. | |||
@see channelPressureChange | |||
*/ | |||
bool isChannelPressure() const noexcept; | |||
/** Returns the pressure from a channel pressure change message. | |||
@returns the pressure, in the range 0 to 127 | |||
@see isChannelPressure, channelPressureChange | |||
*/ | |||
int getChannelPressureValue() const noexcept; | |||
/** Creates a channel-pressure change event. | |||
@param channel the midi channel: 1 to 16 | |||
@param pressure the pressure, 0 to 127 | |||
@see isChannelPressure | |||
*/ | |||
static MidiMessage channelPressureChange (int channel, int pressure) noexcept; | |||
//============================================================================== | |||
/** Returns true if this is a midi controller message. | |||
@see getControllerNumber, getControllerValue, controllerEvent | |||
*/ | |||
bool isController() const noexcept; | |||
/** Returns the controller number of a controller message. | |||
The name of the controller can be looked up using the getControllerName() method. | |||
Note that the value returned is invalid for messages that aren't controller changes. | |||
@see isController, getControllerName, getControllerValue | |||
*/ | |||
int getControllerNumber() const noexcept; | |||
/** Returns the controller value from a controller message. | |||
A value 0 to 127 is returned to indicate the new controller position. | |||
Note that the value returned is invalid for messages that aren't controller changes. | |||
@see isController, getControllerNumber | |||
*/ | |||
int getControllerValue() const noexcept; | |||
/** Returns true if this message is a controller message and if it has the specified | |||
controller type. | |||
*/ | |||
bool isControllerOfType (int controllerType) const noexcept; | |||
/** Creates a controller message. | |||
@param channel the midi channel, in the range 1 to 16 | |||
@param controllerType the type of controller | |||
@param value the controller value | |||
@see isController | |||
*/ | |||
static MidiMessage controllerEvent (int channel, | |||
int controllerType, | |||
int value) noexcept; | |||
/** Checks whether this message is an all-notes-off message. | |||
@see allNotesOff | |||
*/ | |||
bool isAllNotesOff() const noexcept; | |||
/** Checks whether this message is an all-sound-off message. | |||
@see allSoundOff | |||
*/ | |||
bool isAllSoundOff() const noexcept; | |||
/** Checks whether this message is a reset all controllers message. | |||
@see allControllerOff | |||
*/ | |||
bool isResetAllControllers() const noexcept; | |||
/** Creates an all-notes-off message. | |||
@param channel the midi channel, in the range 1 to 16 | |||
@see isAllNotesOff | |||
*/ | |||
static MidiMessage allNotesOff (int channel) noexcept; | |||
/** Creates an all-sound-off message. | |||
@param channel the midi channel, in the range 1 to 16 | |||
@see isAllSoundOff | |||
*/ | |||
static MidiMessage allSoundOff (int channel) noexcept; | |||
/** Creates an all-controllers-off message. | |||
@param channel the midi channel, in the range 1 to 16 | |||
*/ | |||
static MidiMessage allControllersOff (int channel) noexcept; | |||
//============================================================================== | |||
/** Returns true if this event is a meta-event. | |||
Meta-events are things like tempo changes, track names, etc. | |||
@see getMetaEventType, isTrackMetaEvent, isEndOfTrackMetaEvent, | |||
isTextMetaEvent, isTrackNameEvent, isTempoMetaEvent, isTimeSignatureMetaEvent, | |||
isKeySignatureMetaEvent, isMidiChannelMetaEvent | |||
*/ | |||
bool isMetaEvent() const noexcept; | |||
/** Returns a meta-event's type number. | |||
If the message isn't a meta-event, this will return -1. | |||
@see isMetaEvent, isTrackMetaEvent, isEndOfTrackMetaEvent, | |||
isTextMetaEvent, isTrackNameEvent, isTempoMetaEvent, isTimeSignatureMetaEvent, | |||
isKeySignatureMetaEvent, isMidiChannelMetaEvent | |||
*/ | |||
int getMetaEventType() const noexcept; | |||
/** Returns a pointer to the data in a meta-event. | |||
@see isMetaEvent, getMetaEventLength | |||
*/ | |||
const uint8* getMetaEventData() const noexcept; | |||
/** Returns the length of the data for a meta-event. | |||
@see isMetaEvent, getMetaEventData | |||
*/ | |||
int getMetaEventLength() const noexcept; | |||
//============================================================================== | |||
/** Returns true if this is a 'track' meta-event. */ | |||
bool isTrackMetaEvent() const noexcept; | |||
/** Returns true if this is an 'end-of-track' meta-event. */ | |||
bool isEndOfTrackMetaEvent() const noexcept; | |||
/** Creates an end-of-track meta-event. | |||
@see isEndOfTrackMetaEvent | |||
*/ | |||
static MidiMessage endOfTrack() noexcept; | |||
/** Returns true if this is an 'track name' meta-event. | |||
You can use the getTextFromTextMetaEvent() method to get the track's name. | |||
*/ | |||
bool isTrackNameEvent() const noexcept; | |||
/** Returns true if this is a 'text' meta-event. | |||
@see getTextFromTextMetaEvent | |||
*/ | |||
bool isTextMetaEvent() const noexcept; | |||
/** Returns the text from a text meta-event. | |||
@see isTextMetaEvent | |||
*/ | |||
String getTextFromTextMetaEvent() const; | |||
/** Creates a text meta-event. */ | |||
static MidiMessage textMetaEvent (int type, StringRef text); | |||
//============================================================================== | |||
/** Returns true if this is a 'tempo' meta-event. | |||
@see getTempoMetaEventTickLength, getTempoSecondsPerQuarterNote | |||
*/ | |||
bool isTempoMetaEvent() const noexcept; | |||
/** Returns the tick length from a tempo meta-event. | |||
@param timeFormat the 16-bit time format value from the midi file's header. | |||
@returns the tick length (in seconds). | |||
@see isTempoMetaEvent | |||
*/ | |||
double getTempoMetaEventTickLength (short timeFormat) const noexcept; | |||
/** Calculates the seconds-per-quarter-note from a tempo meta-event. | |||
@see isTempoMetaEvent, getTempoMetaEventTickLength | |||
*/ | |||
double getTempoSecondsPerQuarterNote() const noexcept; | |||
/** Creates a tempo meta-event. | |||
@see isTempoMetaEvent | |||
*/ | |||
static MidiMessage tempoMetaEvent (int microsecondsPerQuarterNote) noexcept; | |||
//============================================================================== | |||
/** Returns true if this is a 'time-signature' meta-event. | |||
@see getTimeSignatureInfo | |||
*/ | |||
bool isTimeSignatureMetaEvent() const noexcept; | |||
/** Returns the time-signature values from a time-signature meta-event. | |||
@see isTimeSignatureMetaEvent | |||
*/ | |||
void getTimeSignatureInfo (int& numerator, int& denominator) const noexcept; | |||
/** Creates a time-signature meta-event. | |||
@see isTimeSignatureMetaEvent | |||
*/ | |||
static MidiMessage timeSignatureMetaEvent (int numerator, int denominator); | |||
//============================================================================== | |||
/** Returns true if this is a 'key-signature' meta-event. | |||
@see getKeySignatureNumberOfSharpsOrFlats, isKeySignatureMajorKey | |||
*/ | |||
bool isKeySignatureMetaEvent() const noexcept; | |||
/** Returns the key from a key-signature meta-event. | |||
This method must only be called if isKeySignatureMetaEvent() is true. | |||
A positive number here indicates the number of sharps in the key signature, | |||
and a negative number indicates a number of flats. So e.g. 3 = F# + C# + G#, | |||
-2 = Bb + Eb | |||
@see isKeySignatureMetaEvent, isKeySignatureMajorKey | |||
*/ | |||
int getKeySignatureNumberOfSharpsOrFlats() const noexcept; | |||
/** Returns true if this key-signature event is major, or false if it's minor. | |||
This method must only be called if isKeySignatureMetaEvent() is true. | |||
*/ | |||
bool isKeySignatureMajorKey() const noexcept; | |||
/** Creates a key-signature meta-event. | |||
@param numberOfSharpsOrFlats if positive, this indicates the number of sharps | |||
in the key; if negative, the number of flats | |||
@param isMinorKey if true, the key is minor; if false, it is major | |||
@see isKeySignatureMetaEvent | |||
*/ | |||
static MidiMessage keySignatureMetaEvent (int numberOfSharpsOrFlats, bool isMinorKey); | |||
//============================================================================== | |||
/** Returns true if this is a 'channel' meta-event. | |||
A channel meta-event specifies the midi channel that should be used | |||
for subsequent meta-events. | |||
@see getMidiChannelMetaEventChannel | |||
*/ | |||
bool isMidiChannelMetaEvent() const noexcept; | |||
/** Returns the channel number from a channel meta-event. | |||
@returns the channel, in the range 1 to 16. | |||
@see isMidiChannelMetaEvent | |||
*/ | |||
int getMidiChannelMetaEventChannel() const noexcept; | |||
/** Creates a midi channel meta-event. | |||
@param channel the midi channel, in the range 1 to 16 | |||
@see isMidiChannelMetaEvent | |||
*/ | |||
static MidiMessage midiChannelMetaEvent (int channel) noexcept; | |||
//============================================================================== | |||
/** Returns true if this is an active-sense message. */ | |||
bool isActiveSense() const noexcept; | |||
//============================================================================== | |||
/** Returns true if this is a midi start event. | |||
@see midiStart | |||
*/ | |||
bool isMidiStart() const noexcept; | |||
/** Creates a midi start event. */ | |||
static MidiMessage midiStart() noexcept; | |||
/** Returns true if this is a midi continue event. | |||
@see midiContinue | |||
*/ | |||
bool isMidiContinue() const noexcept; | |||
/** Creates a midi continue event. */ | |||
static MidiMessage midiContinue() noexcept; | |||
/** Returns true if this is a midi stop event. | |||
@see midiStop | |||
*/ | |||
bool isMidiStop() const noexcept; | |||
/** Creates a midi stop event. */ | |||
static MidiMessage midiStop() noexcept; | |||
/** Returns true if this is a midi clock event. | |||
@see midiClock, songPositionPointer | |||
*/ | |||
bool isMidiClock() const noexcept; | |||
/** Creates a midi clock event. */ | |||
static MidiMessage midiClock() noexcept; | |||
/** Returns true if this is a song-position-pointer message. | |||
@see getSongPositionPointerMidiBeat, songPositionPointer | |||
*/ | |||
bool isSongPositionPointer() const noexcept; | |||
/** Returns the midi beat-number of a song-position-pointer message. | |||
@see isSongPositionPointer, songPositionPointer | |||
*/ | |||
int getSongPositionPointerMidiBeat() const noexcept; | |||
/** Creates a song-position-pointer message. | |||
The position is a number of midi beats from the start of the song, where 1 midi | |||
beat is 6 midi clocks, and there are 24 midi clocks in a quarter-note. So there | |||
are 4 midi beats in a quarter-note. | |||
@see isSongPositionPointer, getSongPositionPointerMidiBeat | |||
*/ | |||
static MidiMessage songPositionPointer (int positionInMidiBeats) noexcept; | |||
//============================================================================== | |||
/** Returns true if this is a quarter-frame midi timecode message. | |||
@see quarterFrame, getQuarterFrameSequenceNumber, getQuarterFrameValue | |||
*/ | |||
bool isQuarterFrame() const noexcept; | |||
/** Returns the sequence number of a quarter-frame midi timecode message. | |||
This will be a value between 0 and 7. | |||
@see isQuarterFrame, getQuarterFrameValue, quarterFrame | |||
*/ | |||
int getQuarterFrameSequenceNumber() const noexcept; | |||
/** Returns the value from a quarter-frame message. | |||
This will be the lower nybble of the message's data-byte, a value between 0 and 15 | |||
*/ | |||
int getQuarterFrameValue() const noexcept; | |||
/** Creates a quarter-frame MTC message. | |||
@param sequenceNumber a value 0 to 7 for the upper nybble of the message's data byte | |||
@param value a value 0 to 15 for the lower nybble of the message's data byte | |||
*/ | |||
static MidiMessage quarterFrame (int sequenceNumber, int value) noexcept; | |||
/** SMPTE timecode types. | |||
Used by the getFullFrameParameters() and fullFrame() methods. | |||
*/ | |||
enum SmpteTimecodeType | |||
{ | |||
fps24 = 0, | |||
fps25 = 1, | |||
fps30drop = 2, | |||
fps30 = 3 | |||
}; | |||
/** Returns true if this is a full-frame midi timecode message. */ | |||
bool isFullFrame() const noexcept; | |||
/** Extracts the timecode information from a full-frame midi timecode message. | |||
You should only call this on messages where you've used isFullFrame() to | |||
check that they're the right kind. | |||
*/ | |||
void getFullFrameParameters (int& hours, | |||
int& minutes, | |||
int& seconds, | |||
int& frames, | |||
SmpteTimecodeType& timecodeType) const noexcept; | |||
/** Creates a full-frame MTC message. */ | |||
static MidiMessage fullFrame (int hours, | |||
int minutes, | |||
int seconds, | |||
int frames, | |||
SmpteTimecodeType timecodeType); | |||
//============================================================================== | |||
/** Types of MMC command. | |||
@see isMidiMachineControlMessage, getMidiMachineControlCommand, midiMachineControlCommand | |||
*/ | |||
enum MidiMachineControlCommand | |||
{ | |||
mmc_stop = 1, | |||
mmc_play = 2, | |||
mmc_deferredplay = 3, | |||
mmc_fastforward = 4, | |||
mmc_rewind = 5, | |||
mmc_recordStart = 6, | |||
mmc_recordStop = 7, | |||
mmc_pause = 9 | |||
}; | |||
/** Checks whether this is an MMC message. | |||
If it is, you can use the getMidiMachineControlCommand() to find out its type. | |||
*/ | |||
bool isMidiMachineControlMessage() const noexcept; | |||
/** For an MMC message, this returns its type. | |||
Make sure it's actually an MMC message with isMidiMachineControlMessage() before | |||
calling this method. | |||
*/ | |||
MidiMachineControlCommand getMidiMachineControlCommand() const noexcept; | |||
/** Creates an MMC message. */ | |||
static MidiMessage midiMachineControlCommand (MidiMachineControlCommand command); | |||
/** Checks whether this is an MMC "goto" message. | |||
If it is, the parameters passed-in are set to the time that the message contains. | |||
@see midiMachineControlGoto | |||
*/ | |||
bool isMidiMachineControlGoto (int& hours, | |||
int& minutes, | |||
int& seconds, | |||
int& frames) const noexcept; | |||
/** Creates an MMC "goto" message. | |||
This messages tells the device to go to a specific frame. | |||
@see isMidiMachineControlGoto | |||
*/ | |||
static MidiMessage midiMachineControlGoto (int hours, | |||
int minutes, | |||
int seconds, | |||
int frames); | |||
//============================================================================== | |||
/** Creates a master-volume change message. | |||
@param volume the volume, 0 to 1.0 | |||
*/ | |||
static MidiMessage masterVolume (float volume); | |||
//============================================================================== | |||
/** Creates a system-exclusive message. | |||
The data passed in is wrapped with header and tail bytes of 0xf0 and 0xf7. | |||
*/ | |||
static MidiMessage createSysExMessage (const void* sysexData, | |||
int dataSize); | |||
//============================================================================== | |||
/** Reads a midi variable-length integer. | |||
@param data the data to read the number from | |||
@param numBytesUsed on return, this will be set to the number of bytes that were read | |||
*/ | |||
static int readVariableLengthVal (const uint8* data, | |||
int& numBytesUsed) noexcept; | |||
/** Based on the first byte of a short midi message, this uses a lookup table | |||
to return the message length (either 1, 2, or 3 bytes). | |||
The value passed in must be 0x80 or higher. | |||
*/ | |||
static int getMessageLengthFromFirstByte (uint8 firstByte) noexcept; | |||
//============================================================================== | |||
/** Returns the name of a midi note number. | |||
E.g "C", "D#", etc. | |||
@param noteNumber the midi note number, 0 to 127 | |||
@param useSharps if true, sharpened notes are used, e.g. "C#", otherwise | |||
they'll be flattened, e.g. "Db" | |||
@param includeOctaveNumber if true, the octave number will be appended to the string, | |||
e.g. "C#4" | |||
@param octaveNumForMiddleC if an octave number is being appended, this indicates the | |||
number that will be used for middle C's octave | |||
@see getMidiNoteInHertz | |||
*/ | |||
static String getMidiNoteName (int noteNumber, | |||
bool useSharps, | |||
bool includeOctaveNumber, | |||
int octaveNumForMiddleC); | |||
/** Returns the frequency of a midi note number. | |||
The frequencyOfA parameter is an optional frequency for 'A', normally 440-444Hz for concert pitch. | |||
@see getMidiNoteName | |||
*/ | |||
static double getMidiNoteInHertz (int noteNumber, double frequencyOfA = 440.0) noexcept; | |||
/** Returns true if the given midi note number is a black key. */ | |||
static bool isMidiNoteBlack (int noteNumber) noexcept; | |||
/** Returns the standard name of a GM instrument, or nullptr if unknown for this index. | |||
@param midiInstrumentNumber the program number 0 to 127 | |||
@see getProgramChangeNumber | |||
*/ | |||
static const char* getGMInstrumentName (int midiInstrumentNumber); | |||
/** Returns the name of a bank of GM instruments, or nullptr if unknown for this bank number. | |||
@param midiBankNumber the bank, 0 to 15 | |||
*/ | |||
static const char* getGMInstrumentBankName (int midiBankNumber); | |||
/** Returns the standard name of a channel 10 percussion sound, or nullptr if unknown for this note number. | |||
@param midiNoteNumber the key number, 35 to 81 | |||
*/ | |||
static const char* getRhythmInstrumentName (int midiNoteNumber); | |||
/** Returns the name of a controller type number, or nullptr if unknown for this controller number. | |||
@see getControllerNumber | |||
*/ | |||
static const char* getControllerName (int controllerNumber); | |||
/** Converts a floating-point value between 0 and 1 to a MIDI 7-bit value between 0 and 127. */ | |||
static uint8 floatValueToMidiByte (float valueBetween0and1) noexcept; | |||
/** Converts a pitchbend value in semitones to a MIDI 14-bit pitchwheel position value. */ | |||
static uint16 pitchbendToPitchwheelPos (float pitchbendInSemitones, | |||
float pitchbendRangeInSemitones) noexcept; | |||
private: | |||
//============================================================================== | |||
#ifndef DOXYGEN | |||
union PackedData | |||
{ | |||
uint8* allocatedData; | |||
uint8 asBytes[sizeof (uint8*)]; | |||
}; | |||
PackedData packedData; | |||
double timeStamp = 0; | |||
int size; | |||
#endif | |||
inline bool isHeapAllocated() const noexcept { return size > (int) sizeof (packedData); } | |||
inline uint8* getData() const noexcept { return isHeapAllocated() ? packedData.allocatedData : (uint8*) packedData.asBytes; } | |||
uint8* allocateSpace (int); | |||
}; | |||
} // namespace juce |
@@ -1,11 +0,0 @@ | |||
--- modules/juce_audio_basics/midi/juce_MidiMessage.h | |||
+++ modules/juce_audio_basics/midi/juce_MidiMessage.h | |||
@@ -945,7 +945,7 @@ private: | |||
#endif | |||
inline bool isHeapAllocated() const noexcept { return size > (int) sizeof (packedData); } | |||
- inline uint8* getData() const noexcept { return isHeapAllocated() ? packedData.allocatedData : (uint8*) packedData.asBytes; } | |||
+ inline uint8* getData() const noexcept { return isHeapAllocated() ? packedData.allocatedData : const_cast<uint8*>(packedData.asBytes); } | |||
uint8* allocateSpace (int); | |||
}; | |||
@@ -1,58 +0,0 @@ | |||
--- modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp | |||
+++ modules/juce_audio_plugin_client/VST/juce_VST_Wrapper.cpp | |||
@@ -1295,7 +1295,7 @@ public: | |||
bounds.bottom = (int16) b.getHeight(); | |||
bounds.right = (int16) b.getWidth(); | |||
- #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE | |||
+ #if JUCE_LINUX || (JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE) | |||
bounds.bottom = (int16) roundToInt (bounds.bottom * wrapper.editorScaleFactor); | |||
bounds.right = (int16) roundToInt (bounds.right * wrapper.editorScaleFactor); | |||
#endif | |||
@@ -1321,6 +1321,10 @@ public: | |||
addToDesktop (0, args.ptr); | |||
hostWindow = (Window) args.ptr; | |||
XReparentWindow (display.display, (Window) getWindowHandle(), hostWindow, 0, 0); | |||
+ | |||
+ if (auto* ed = getEditorComp()) | |||
+ if (auto* peer = ed->getPeer()) | |||
+ wrapper.editorScaleFactor = (float) peer->getPlatformScaleFactor(); | |||
#else | |||
hostWindow = attachComponentToWindowRefVST (this, args.ptr, wrapper.useNSView); | |||
#endif | |||
@@ -1356,7 +1360,7 @@ public: | |||
return dynamic_cast<AudioProcessorEditor*> (getChildComponent(0)); | |||
} | |||
- #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE | |||
+ #if JUCE_LINUX || (JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE) | |||
void checkScaleFactorIsCorrect() | |||
{ | |||
if (auto* peer = getEditorComp()->getPeer()) | |||
@@ -1373,7 +1377,7 @@ public: | |||
{ | |||
if (auto* ed = getEditorComp()) | |||
{ | |||
- #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE | |||
+ #if JUCE_LINUX || (JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE) | |||
checkScaleFactorIsCorrect(); | |||
#endif | |||
@@ -1451,7 +1455,7 @@ public: | |||
if (status == (pointer_sized_int) 1 || getHostType().isAbletonLive()) | |||
{ | |||
- #if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE | |||
+ #if JUCE_LINUX || (JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE) | |||
newWidth = roundToInt (newWidth * wrapper.editorScaleFactor); | |||
newHeight = roundToInt (newHeight * wrapper.editorScaleFactor); | |||
#endif | |||
@@ -2205,7 +2209,7 @@ private: | |||
editorScaleFactor = scale; | |||
if (editorComp != nullptr) | |||
- #if JUCE_WINDOWS && ! JUCE_WIN_PER_MONITOR_DPI_AWARE | |||
+ #if JUCE_LINUX || (JUCE_WINDOWS && ! JUCE_WIN_PER_MONITOR_DPI_AWARE) | |||
if (auto* ed = editorComp->getEditorComp()) | |||
ed->setScaleFactor (scale); | |||
#else |
@@ -1,335 +0,0 @@ | |||
/* | |||
============================================================================== | |||
This file is part of the JUCE 6 technical preview. | |||
Copyright (c) 2017 - ROLI Ltd. | |||
You may use this code under the terms of the GPL v3 | |||
(see www.gnu.org/licenses). | |||
For this technical preview, this file is not subject to commercial licensing. | |||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER | |||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE | |||
DISCLAIMED. | |||
============================================================================== | |||
*/ | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
#if JUCE_BIG_ENDIAN | |||
#define JUCE_MULTICHAR_CONSTANT(a, b, c, d) (a | (((uint32) b) << 8) | (((uint32) c) << 16) | (((uint32) d) << 24)) | |||
#else | |||
#define JUCE_MULTICHAR_CONSTANT(a, b, c, d) (d | (((uint32) c) << 8) | (((uint32) b) << 16) | (((uint32) a) << 24)) | |||
#endif | |||
//============================================================================== | |||
/** Structure for VST speaker mappings | |||
@tags{Audio} | |||
*/ | |||
struct SpeakerMappings : private AudioChannelSet // (inheritance only to give easier access to items in the namespace) | |||
{ | |||
/** Structure describing a mapping */ | |||
struct Mapping | |||
{ | |||
int32 vst2; | |||
ChannelType channels[13]; | |||
bool matches (const Array<ChannelType>& chans) const noexcept | |||
{ | |||
auto n = static_cast<int> (sizeof (channels) / sizeof (ChannelType)); | |||
for (int i = 0; i < n; ++i) | |||
{ | |||
if (channels[i] == unknown) return (i == chans.size()); | |||
if (i == chans.size()) return (channels[i] == unknown); | |||
if (channels[i] != chans.getUnchecked (i)) | |||
return false; | |||
} | |||
return true; | |||
} | |||
}; | |||
static AudioChannelSet vstArrangementTypeToChannelSet (int32 arr, int fallbackNumChannels) | |||
{ | |||
if (arr == Vst2::kSpeakerArrEmpty) return AudioChannelSet::disabled(); | |||
else if (arr == Vst2::kSpeakerArrMono) return AudioChannelSet::mono(); | |||
else if (arr == Vst2::kSpeakerArrStereo) return AudioChannelSet::stereo(); | |||
else if (arr == Vst2::kSpeakerArr30Cine) return AudioChannelSet::createLCR(); | |||
else if (arr == Vst2::kSpeakerArr30Music) return AudioChannelSet::createLRS(); | |||
else if (arr == Vst2::kSpeakerArr40Cine) return AudioChannelSet::createLCRS(); | |||
else if (arr == Vst2::kSpeakerArr50) return AudioChannelSet::create5point0(); | |||
else if (arr == Vst2::kSpeakerArr51) return AudioChannelSet::create5point1(); | |||
else if (arr == Vst2::kSpeakerArr60Cine) return AudioChannelSet::create6point0(); | |||
else if (arr == Vst2::kSpeakerArr61Cine) return AudioChannelSet::create6point1(); | |||
else if (arr == Vst2::kSpeakerArr60Music) return AudioChannelSet::create6point0Music(); | |||
else if (arr == Vst2::kSpeakerArr61Music) return AudioChannelSet::create6point1Music(); | |||
else if (arr == Vst2::kSpeakerArr70Music) return AudioChannelSet::create7point0(); | |||
else if (arr == Vst2::kSpeakerArr70Cine) return AudioChannelSet::create7point0SDDS(); | |||
else if (arr == Vst2::kSpeakerArr71Music) return AudioChannelSet::create7point1(); | |||
else if (arr == Vst2::kSpeakerArr71Cine) return AudioChannelSet::create7point1SDDS(); | |||
else if (arr == Vst2::kSpeakerArr40Music) return AudioChannelSet::quadraphonic(); | |||
for (const Mapping* m = getMappings(); m->vst2 != Vst2::kSpeakerArrEmpty; ++m) | |||
{ | |||
if (m->vst2 == arr) | |||
{ | |||
AudioChannelSet s; | |||
for (int i = 0; m->channels[i] != 0; ++i) | |||
s.addChannel (m->channels[i]); | |||
return s; | |||
} | |||
} | |||
return AudioChannelSet::discreteChannels (fallbackNumChannels); | |||
} | |||
static AudioChannelSet vstArrangementTypeToChannelSet (const Vst2::VstSpeakerArrangement& arr) | |||
{ | |||
return vstArrangementTypeToChannelSet (arr.type, arr.numChannels); | |||
} | |||
static int32 channelSetToVstArrangementType (AudioChannelSet channels) | |||
{ | |||
if (channels == AudioChannelSet::disabled()) return Vst2::kSpeakerArrEmpty; | |||
else if (channels == AudioChannelSet::mono()) return Vst2::kSpeakerArrMono; | |||
else if (channels == AudioChannelSet::stereo()) return Vst2::kSpeakerArrStereo; | |||
else if (channels == AudioChannelSet::createLCR()) return Vst2::kSpeakerArr30Cine; | |||
else if (channels == AudioChannelSet::createLRS()) return Vst2::kSpeakerArr30Music; | |||
else if (channels == AudioChannelSet::createLCRS()) return Vst2::kSpeakerArr40Cine; | |||
else if (channels == AudioChannelSet::create5point0()) return Vst2::kSpeakerArr50; | |||
else if (channels == AudioChannelSet::create5point1()) return Vst2::kSpeakerArr51; | |||
else if (channels == AudioChannelSet::create6point0()) return Vst2::kSpeakerArr60Cine; | |||
else if (channels == AudioChannelSet::create6point1()) return Vst2::kSpeakerArr61Cine; | |||
else if (channels == AudioChannelSet::create6point0Music()) return Vst2::kSpeakerArr60Music; | |||
else if (channels == AudioChannelSet::create6point1Music()) return Vst2::kSpeakerArr61Music; | |||
else if (channels == AudioChannelSet::create7point0()) return Vst2::kSpeakerArr70Music; | |||
else if (channels == AudioChannelSet::create7point0SDDS()) return Vst2::kSpeakerArr70Cine; | |||
else if (channels == AudioChannelSet::create7point1()) return Vst2::kSpeakerArr71Music; | |||
else if (channels == AudioChannelSet::create7point1SDDS()) return Vst2::kSpeakerArr71Cine; | |||
else if (channels == AudioChannelSet::quadraphonic()) return Vst2::kSpeakerArr40Music; | |||
if (channels == AudioChannelSet::disabled()) | |||
return Vst2::kSpeakerArrEmpty; | |||
auto chans = channels.getChannelTypes(); | |||
for (auto* m = getMappings(); m->vst2 != Vst2::kSpeakerArrEmpty; ++m) | |||
if (m->matches (chans)) | |||
return m->vst2; | |||
return Vst2::kSpeakerArrUserDefined; | |||
} | |||
static void channelSetToVstArrangement (const AudioChannelSet& channels, Vst2::VstSpeakerArrangement& result) | |||
{ | |||
result.type = channelSetToVstArrangementType (channels); | |||
result.numChannels = channels.size(); | |||
for (int i = 0; i < result.numChannels; ++i) | |||
{ | |||
auto& speaker = result.speakers[i]; | |||
zeromem (&speaker, sizeof (Vst2::VstSpeakerProperties)); | |||
speaker.type = getSpeakerType (channels.getTypeOfChannel (i)); | |||
} | |||
} | |||
/** Class to hold a speaker configuration */ | |||
class VstSpeakerConfigurationHolder | |||
{ | |||
public: | |||
VstSpeakerConfigurationHolder() | |||
{ | |||
clear(); | |||
} | |||
VstSpeakerConfigurationHolder (const Vst2::VstSpeakerArrangement& vstConfig) | |||
{ | |||
operator= (vstConfig); | |||
} | |||
VstSpeakerConfigurationHolder (const VstSpeakerConfigurationHolder& other) | |||
{ | |||
operator= (other.get()); | |||
} | |||
VstSpeakerConfigurationHolder (VstSpeakerConfigurationHolder&& other) | |||
: storage (std::move (other.storage)) | |||
{ | |||
other.clear(); | |||
} | |||
VstSpeakerConfigurationHolder (const AudioChannelSet& channels) | |||
{ | |||
auto numberOfChannels = channels.size(); | |||
Vst2::VstSpeakerArrangement& dst = *allocate (numberOfChannels); | |||
dst.type = channelSetToVstArrangementType (channels); | |||
dst.numChannels = numberOfChannels; | |||
for (int i = 0; i < dst.numChannels; ++i) | |||
{ | |||
Vst2::VstSpeakerProperties& speaker = dst.speakers[i]; | |||
zeromem (&speaker, sizeof (Vst2::VstSpeakerProperties)); | |||
speaker.type = getSpeakerType (channels.getTypeOfChannel (i)); | |||
} | |||
} | |||
VstSpeakerConfigurationHolder& operator= (const VstSpeakerConfigurationHolder& vstConfig) { return operator=(vstConfig.get()); } | |||
VstSpeakerConfigurationHolder& operator= (const Vst2::VstSpeakerArrangement& vstConfig) | |||
{ | |||
Vst2::VstSpeakerArrangement& dst = *allocate (vstConfig.numChannels); | |||
dst.type = vstConfig.type; | |||
dst.numChannels = vstConfig.numChannels; | |||
for (int i = 0; i < dst.numChannels; ++i) | |||
dst.speakers[i] = vstConfig.speakers[i]; | |||
return *this; | |||
} | |||
VstSpeakerConfigurationHolder& operator= (VstSpeakerConfigurationHolder && vstConfig) | |||
{ | |||
storage = std::move (vstConfig.storage); | |||
vstConfig.clear(); | |||
return *this; | |||
} | |||
const Vst2::VstSpeakerArrangement& get() const { return *storage.get(); } | |||
private: | |||
JUCE_LEAK_DETECTOR (VstSpeakerConfigurationHolder) | |||
HeapBlock<Vst2::VstSpeakerArrangement> storage; | |||
Vst2::VstSpeakerArrangement* allocate (int numChannels) | |||
{ | |||
auto arrangementSize = (size_t) (jmax (8, numChannels) - 8) * sizeof (Vst2::VstSpeakerProperties) | |||
+ sizeof (Vst2::VstSpeakerArrangement); | |||
storage.malloc (1, arrangementSize); | |||
return storage.get(); | |||
} | |||
void clear() | |||
{ | |||
Vst2::VstSpeakerArrangement& dst = *allocate (0); | |||
dst.type = Vst2::kSpeakerArrEmpty; | |||
dst.numChannels = 0; | |||
} | |||
}; | |||
static const Mapping* getMappings() noexcept | |||
{ | |||
static const Mapping mappings[] = | |||
{ | |||
{ Vst2::kSpeakerArrMono, { centre, unknown } }, | |||
{ Vst2::kSpeakerArrStereo, { left, right, unknown } }, | |||
{ Vst2::kSpeakerArrStereoSurround, { leftSurround, rightSurround, unknown } }, | |||
{ Vst2::kSpeakerArrStereoCenter, { leftCentre, rightCentre, unknown } }, | |||
{ Vst2::kSpeakerArrStereoSide, { leftSurroundRear, rightSurroundRear, unknown } }, | |||
{ Vst2::kSpeakerArrStereoCLfe, { centre, LFE, unknown } }, | |||
{ Vst2::kSpeakerArr30Cine, { left, right, centre, unknown } }, | |||
{ Vst2::kSpeakerArr30Music, { left, right, surround, unknown } }, | |||
{ Vst2::kSpeakerArr31Cine, { left, right, centre, LFE, unknown } }, | |||
{ Vst2::kSpeakerArr31Music, { left, right, LFE, surround, unknown } }, | |||
{ Vst2::kSpeakerArr40Cine, { left, right, centre, surround, unknown } }, | |||
{ Vst2::kSpeakerArr40Music, { left, right, leftSurround, rightSurround, unknown } }, | |||
{ Vst2::kSpeakerArr41Cine, { left, right, centre, LFE, surround, unknown } }, | |||
{ Vst2::kSpeakerArr41Music, { left, right, LFE, leftSurround, rightSurround, unknown } }, | |||
{ Vst2::kSpeakerArr50, { left, right, centre, leftSurround, rightSurround, unknown } }, | |||
{ Vst2::kSpeakerArr51, { left, right, centre, LFE, leftSurround, rightSurround, unknown } }, | |||
{ Vst2::kSpeakerArr60Cine, { left, right, centre, leftSurround, rightSurround, surround, unknown } }, | |||
{ Vst2::kSpeakerArr60Music, { left, right, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear, unknown } }, | |||
{ Vst2::kSpeakerArr61Cine, { left, right, centre, LFE, leftSurround, rightSurround, surround, unknown } }, | |||
{ Vst2::kSpeakerArr61Music, { left, right, LFE, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear, unknown } }, | |||
{ Vst2::kSpeakerArr70Cine, { left, right, centre, leftSurround, rightSurround, topFrontLeft, topFrontRight, unknown } }, | |||
{ Vst2::kSpeakerArr70Music, { left, right, centre, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear, unknown } }, | |||
{ Vst2::kSpeakerArr71Cine, { left, right, centre, LFE, leftSurround, rightSurround, topFrontLeft, topFrontRight, unknown } }, | |||
{ Vst2::kSpeakerArr71Music, { left, right, centre, LFE, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear, unknown } }, | |||
{ Vst2::kSpeakerArr80Cine, { left, right, centre, leftSurround, rightSurround, topFrontLeft, topFrontRight, surround, unknown } }, | |||
{ Vst2::kSpeakerArr80Music, { left, right, centre, leftSurround, rightSurround, surround, leftSurroundRear, rightSurroundRear, unknown } }, | |||
{ Vst2::kSpeakerArr81Cine, { left, right, centre, LFE, leftSurround, rightSurround, topFrontLeft, topFrontRight, surround, unknown } }, | |||
{ Vst2::kSpeakerArr81Music, { left, right, centre, LFE, leftSurround, rightSurround, surround, leftSurroundRear, rightSurroundRear, unknown } }, | |||
{ Vst2::kSpeakerArr102, { left, right, centre, LFE, leftSurround, rightSurround, topFrontLeft, topFrontCentre, topFrontRight, topRearLeft, topRearRight, LFE2, unknown } }, | |||
{ Vst2::kSpeakerArrEmpty, { unknown } } | |||
}; | |||
return mappings; | |||
} | |||
static inline int32 getSpeakerType (AudioChannelSet::ChannelType type) noexcept | |||
{ | |||
static const std::map<AudioChannelSet::ChannelType, int32> speakerTypeMap = | |||
{ | |||
{ AudioChannelSet::left, Vst2::kSpeakerL }, | |||
{ AudioChannelSet::right, Vst2::kSpeakerR }, | |||
{ AudioChannelSet::centre, Vst2::kSpeakerC }, | |||
{ AudioChannelSet::LFE, Vst2::kSpeakerLfe }, | |||
{ AudioChannelSet::leftSurround, Vst2::kSpeakerLs }, | |||
{ AudioChannelSet::rightSurround, Vst2::kSpeakerRs }, | |||
{ AudioChannelSet::leftCentre, Vst2::kSpeakerLc }, | |||
{ AudioChannelSet::rightCentre, Vst2::kSpeakerRc }, | |||
{ AudioChannelSet::surround, Vst2::kSpeakerS }, | |||
{ AudioChannelSet::leftSurroundRear, Vst2::kSpeakerSl }, | |||
{ AudioChannelSet::rightSurroundRear, Vst2::kSpeakerSr }, | |||
{ AudioChannelSet::topMiddle, Vst2::kSpeakerTm }, | |||
{ AudioChannelSet::topFrontLeft, Vst2::kSpeakerTfl }, | |||
{ AudioChannelSet::topFrontCentre, Vst2::kSpeakerTfc }, | |||
{ AudioChannelSet::topFrontRight, Vst2::kSpeakerTfr }, | |||
{ AudioChannelSet::topRearLeft, Vst2::kSpeakerTrl }, | |||
{ AudioChannelSet::topRearCentre, Vst2::kSpeakerTrc }, | |||
{ AudioChannelSet::topRearRight, Vst2::kSpeakerTrr }, | |||
{ AudioChannelSet::LFE2, Vst2::kSpeakerLfe2 } | |||
}; | |||
if (speakerTypeMap.find (type) == speakerTypeMap.end()) | |||
return 0; | |||
return speakerTypeMap.at (type); | |||
} | |||
static inline AudioChannelSet::ChannelType getChannelType (int32 type) noexcept | |||
{ | |||
switch (type) | |||
{ | |||
case Vst2::kSpeakerL: return AudioChannelSet::left; | |||
case Vst2::kSpeakerR: return AudioChannelSet::right; | |||
case Vst2::kSpeakerC: return AudioChannelSet::centre; | |||
case Vst2::kSpeakerLfe: return AudioChannelSet::LFE; | |||
case Vst2::kSpeakerLs: return AudioChannelSet::leftSurround; | |||
case Vst2::kSpeakerRs: return AudioChannelSet::rightSurround; | |||
case Vst2::kSpeakerLc: return AudioChannelSet::leftCentre; | |||
case Vst2::kSpeakerRc: return AudioChannelSet::rightCentre; | |||
case Vst2::kSpeakerS: return AudioChannelSet::surround; | |||
case Vst2::kSpeakerSl: return AudioChannelSet::leftSurroundRear; | |||
case Vst2::kSpeakerSr: return AudioChannelSet::rightSurroundRear; | |||
case Vst2::kSpeakerTm: return AudioChannelSet::topMiddle; | |||
case Vst2::kSpeakerTfl: return AudioChannelSet::topFrontLeft; | |||
case Vst2::kSpeakerTfc: return AudioChannelSet::topFrontCentre; | |||
case Vst2::kSpeakerTfr: return AudioChannelSet::topFrontRight; | |||
case Vst2::kSpeakerTrl: return AudioChannelSet::topRearLeft; | |||
case Vst2::kSpeakerTrc: return AudioChannelSet::topRearCentre; | |||
case Vst2::kSpeakerTrr: return AudioChannelSet::topRearRight; | |||
case Vst2::kSpeakerLfe2: return AudioChannelSet::LFE2; | |||
default: break; | |||
} | |||
return AudioChannelSet::unknown; | |||
} | |||
}; | |||
} // namespace juce |
@@ -1,187 +0,0 @@ | |||
--- modules/juce_audio_processors/format_types/juce_VSTCommon.h | |||
+++ modules/juce_audio_processors/format_types/juce_VSTCommon.h | |||
@@ -100,41 +100,41 @@ struct SpeakerMappings : private AudioChannelSet // (inheritance only to give e | |||
return AudioChannelSet::discreteChannels (fallbackNumChannels); | |||
} | |||
- static AudioChannelSet vstArrangementTypeToChannelSet (const Vst2::VstSpeakerArrangement& arr) | |||
+ static AudioChannelSet vstArrangementTypeToChannelSet (const Vst2::VstSpeakerConfiguration& arr) | |||
{ | |||
- return vstArrangementTypeToChannelSet (arr.type, arr.numChannels); | |||
+ return vstArrangementTypeToChannelSet (arr.type, arr.numberOfChannels); | |||
} | |||
static int32 channelSetToVstArrangementType (AudioChannelSet channels) | |||
{ | |||
- if (channels == AudioChannelSet::disabled()) return Vst2::kSpeakerArrEmpty; | |||
- else if (channels == AudioChannelSet::mono()) return Vst2::kSpeakerArrMono; | |||
- else if (channels == AudioChannelSet::stereo()) return Vst2::kSpeakerArrStereo; | |||
- else if (channels == AudioChannelSet::createLCR()) return Vst2::kSpeakerArr30Cine; | |||
- else if (channels == AudioChannelSet::createLRS()) return Vst2::kSpeakerArr30Music; | |||
- else if (channels == AudioChannelSet::createLCRS()) return Vst2::kSpeakerArr40Cine; | |||
- else if (channels == AudioChannelSet::create5point0()) return Vst2::kSpeakerArr50; | |||
- else if (channels == AudioChannelSet::create5point1()) return Vst2::kSpeakerArr51; | |||
- else if (channels == AudioChannelSet::create6point0()) return Vst2::kSpeakerArr60Cine; | |||
- else if (channels == AudioChannelSet::create6point1()) return Vst2::kSpeakerArr61Cine; | |||
- else if (channels == AudioChannelSet::create6point0Music()) return Vst2::kSpeakerArr60Music; | |||
- else if (channels == AudioChannelSet::create6point1Music()) return Vst2::kSpeakerArr61Music; | |||
- else if (channels == AudioChannelSet::create7point0()) return Vst2::kSpeakerArr70Music; | |||
- else if (channels == AudioChannelSet::create7point0SDDS()) return Vst2::kSpeakerArr70Cine; | |||
- else if (channels == AudioChannelSet::create7point1()) return Vst2::kSpeakerArr71Music; | |||
- else if (channels == AudioChannelSet::create7point1SDDS()) return Vst2::kSpeakerArr71Cine; | |||
- else if (channels == AudioChannelSet::quadraphonic()) return Vst2::kSpeakerArr40Music; | |||
+ if (channels == AudioChannelSet::disabled()) return Vst2::vstSpeakerConfigTypeEmpty; | |||
+ else if (channels == AudioChannelSet::mono()) return Vst2::vstSpeakerConfigTypeMono; | |||
+ else if (channels == AudioChannelSet::stereo()) return Vst2::vstSpeakerConfigTypeLR; | |||
+ else if (channels == AudioChannelSet::createLCR()) return Vst2::vstSpeakerConfigTypeLRC; | |||
+ else if (channels == AudioChannelSet::createLRS()) return Vst2::vstSpeakerConfigTypeLRS; | |||
+ else if (channels == AudioChannelSet::createLCRS()) return Vst2::vstSpeakerConfigTypeLRCS; | |||
+ else if (channels == AudioChannelSet::create5point0()) return Vst2::vstSpeakerConfigTypeLRCLsRs; | |||
+ else if (channels == AudioChannelSet::create5point1()) return Vst2::vstSpeakerConfigTypeLRCLfeLsRs; | |||
+ else if (channels == AudioChannelSet::create6point0()) return Vst2::vstSpeakerConfigTypeLRCLsRsCs; | |||
+ else if (channels == AudioChannelSet::create6point1()) return Vst2::vstSpeakerConfigTypeLRCLfeLsRsCs; | |||
+ else if (channels == AudioChannelSet::create6point0Music()) return Vst2::vstSpeakerConfigTypeLRLsRsSlSr; | |||
+ else if (channels == AudioChannelSet::create6point1Music()) return Vst2::vstSpeakerConfigTypeLRLfeLsRsSlSr; | |||
+ else if (channels == AudioChannelSet::create7point0()) return Vst2::vstSpeakerConfigTypeLRCLsRsSlSr; | |||
+ else if (channels == AudioChannelSet::create7point0SDDS()) return Vst2::vstSpeakerConfigTypeLRCLsRsLcRc; | |||
+ else if (channels == AudioChannelSet::create7point1()) return Vst2::vstSpeakerConfigTypeLRCLfeLsRsSlSr; | |||
+ else if (channels == AudioChannelSet::create7point1SDDS()) return Vst2::vstSpeakerConfigTypeLRCLfeLsRsLcRc; | |||
+ else if (channels == AudioChannelSet::quadraphonic()) return Vst2::vstSpeakerConfigTypeLRLsRs; | |||
Array<AudioChannelSet::ChannelType> chans (channels.getChannelTypes()); | |||
if (channels == AudioChannelSet::disabled()) | |||
- return Vst2::kSpeakerArrEmpty; | |||
+ return Vst2::vstSpeakerConfigTypeEmpty; | |||
- for (const Mapping* m = getMappings(); m->vst2 != Vst2::kSpeakerArrEmpty; ++m) | |||
+ for (const Mapping* m = getMappings(); m->vst2 != Vst2::vstSpeakerConfigTypeEmpty; ++m) | |||
if (m->matches (chans)) | |||
return m->vst2; | |||
- return Vst2::kSpeakerArrUserDefined; | |||
+ return Vst2::vstSpeakerConfigTypeUser; | |||
} | |||
/** Class to hold a speaker configuration */ | |||
@@ -142,7 +142,7 @@ struct SpeakerMappings : private AudioChannelSet // (inheritance only to give e | |||
{ | |||
public: | |||
VstSpeakerConfigurationHolder() { clear(); } | |||
- VstSpeakerConfigurationHolder (const Vst2::VstSpeakerArrangement& vstConfig) { operator= (vstConfig); } | |||
+ VstSpeakerConfigurationHolder (const Vst2::VstSpeakerConfiguration& vstConfig) { operator= (vstConfig); } | |||
VstSpeakerConfigurationHolder (const VstSpeakerConfigurationHolder& other) { operator= (other.get()); } | |||
VstSpeakerConfigurationHolder (VstSpeakerConfigurationHolder&& other) | |||
: storage (std::move (other.storage)) { other.clear(); } | |||
@@ -215,36 +215,36 @@ struct SpeakerMappings : private AudioChannelSet // (inheritance only to give e | |||
{ | |||
static const Mapping mappings[] = | |||
{ | |||
- { Vst2::kSpeakerArrMono, { centre, unknown } }, | |||
- { Vst2::kSpeakerArrStereo, { left, right, unknown } }, | |||
- { Vst2::kSpeakerArrStereoSurround, { leftSurround, rightSurround, unknown } }, | |||
- { Vst2::kSpeakerArrStereoCenter, { leftCentre, rightCentre, unknown } }, | |||
- { Vst2::kSpeakerArrStereoSide, { leftSurroundRear, rightSurroundRear, unknown } }, | |||
- { Vst2::kSpeakerArrStereoCLfe, { centre, LFE, unknown } }, | |||
- { Vst2::kSpeakerArr30Cine, { left, right, centre, unknown } }, | |||
- { Vst2::kSpeakerArr30Music, { left, right, surround, unknown } }, | |||
- { Vst2::kSpeakerArr31Cine, { left, right, centre, LFE, unknown } }, | |||
- { Vst2::kSpeakerArr31Music, { left, right, LFE, surround, unknown } }, | |||
- { Vst2::kSpeakerArr40Cine, { left, right, centre, surround, unknown } }, | |||
- { Vst2::kSpeakerArr40Music, { left, right, leftSurround, rightSurround, unknown } }, | |||
- { Vst2::kSpeakerArr41Cine, { left, right, centre, LFE, surround, unknown } }, | |||
- { Vst2::kSpeakerArr41Music, { left, right, LFE, leftSurround, rightSurround, unknown } }, | |||
- { Vst2::kSpeakerArr50, { left, right, centre, leftSurround, rightSurround, unknown } }, | |||
- { Vst2::kSpeakerArr51, { left, right, centre, LFE, leftSurround, rightSurround, unknown } }, | |||
- { Vst2::kSpeakerArr60Cine, { left, right, centre, leftSurround, rightSurround, surround, unknown } }, | |||
- { Vst2::kSpeakerArr60Music, { left, right, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear, unknown } }, | |||
- { Vst2::kSpeakerArr61Cine, { left, right, centre, LFE, leftSurround, rightSurround, surround, unknown } }, | |||
- { Vst2::kSpeakerArr61Music, { left, right, LFE, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear, unknown } }, | |||
- { Vst2::kSpeakerArr70Cine, { left, right, centre, leftSurround, rightSurround, topFrontLeft, topFrontRight, unknown } }, | |||
- { Vst2::kSpeakerArr70Music, { left, right, centre, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear, unknown } }, | |||
- { Vst2::kSpeakerArr71Cine, { left, right, centre, LFE, leftSurround, rightSurround, topFrontLeft, topFrontRight, unknown } }, | |||
- { Vst2::kSpeakerArr71Music, { left, right, centre, LFE, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear, unknown } }, | |||
- { Vst2::kSpeakerArr80Cine, { left, right, centre, leftSurround, rightSurround, topFrontLeft, topFrontRight, surround, unknown } }, | |||
- { Vst2::kSpeakerArr80Music, { left, right, centre, leftSurround, rightSurround, surround, leftSurroundRear, rightSurroundRear, unknown } }, | |||
- { Vst2::kSpeakerArr81Cine, { left, right, centre, LFE, leftSurround, rightSurround, topFrontLeft, topFrontRight, surround, unknown } }, | |||
- { Vst2::kSpeakerArr81Music, { left, right, centre, LFE, leftSurround, rightSurround, surround, leftSurroundRear, rightSurroundRear, unknown } }, | |||
- { Vst2::kSpeakerArr102, { left, right, centre, LFE, leftSurround, rightSurround, topFrontLeft, topFrontCentre, topFrontRight, topRearLeft, topRearRight, LFE2, unknown } }, | |||
- { Vst2::kSpeakerArrEmpty, { unknown } } | |||
+ { Vst2::vstSpeakerConfigTypeMono, { centre, unknown } }, | |||
+ { Vst2::vstSpeakerConfigTypeLR, { left, right, unknown } }, | |||
+ { Vst2::vstSpeakerConfigTypeLsRs, { leftSurround, rightSurround, unknown } }, | |||
+ { Vst2::vstSpeakerConfigTypeLcRc, { leftCentre, rightCentre, unknown } }, | |||
+ { Vst2::vstSpeakerConfigTypeSlSr, { leftSurroundRear, rightSurroundRear, unknown } }, | |||
+ { Vst2::vstSpeakerConfigTypeCLfe, { centre, LFE, unknown } }, | |||
+ { Vst2::vstSpeakerConfigTypeLRC, { left, right, centre, unknown } }, | |||
+ { Vst2::vstSpeakerConfigTypeLRS, { left, right, surround, unknown } }, | |||
+ { Vst2::vstSpeakerConfigTypeLRCLfe, { left, right, centre, LFE, unknown } }, | |||
+ { Vst2::vstSpeakerConfigTypeLRLfeS, { left, right, LFE, surround, unknown } }, | |||
+ { Vst2::vstSpeakerConfigTypeLRCS, { left, right, centre, surround, unknown } }, | |||
+ { Vst2::vstSpeakerConfigTypeLRLsRs, { left, right, leftSurround, rightSurround, unknown } }, | |||
+ { Vst2::vstSpeakerConfigTypeLRCLfeS, { left, right, centre, LFE, surround, unknown } }, | |||
+ { Vst2::vstSpeakerConfigTypeLRLfeLsRs, { left, right, LFE, leftSurround, rightSurround, unknown } }, | |||
+ { Vst2::vstSpeakerConfigTypeLRCLsRs, { left, right, centre, leftSurround, rightSurround, unknown } }, | |||
+ { Vst2::vstSpeakerConfigTypeLRCLfeLsRs, { left, right, centre, LFE, leftSurround, rightSurround, unknown } }, | |||
+ { Vst2::vstSpeakerConfigTypeLRCLsRsCs, { left, right, centre, leftSurround, rightSurround, surround, unknown } }, | |||
+ { Vst2::vstSpeakerConfigTypeLRLsRsSlSr, { left, right, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear, unknown } }, | |||
+ { Vst2::vstSpeakerConfigTypeLRCLfeLsRsCs, { left, right, centre, LFE, leftSurround, rightSurround, surround, unknown } }, | |||
+ { Vst2::vstSpeakerConfigTypeLRLfeLsRsSlSr, { left, right, LFE, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear, unknown } }, | |||
+ { Vst2::vstSpeakerConfigTypeLRCLsRsLcRc, { left, right, centre, leftSurround, rightSurround, topFrontLeft, topFrontRight, unknown } }, | |||
+ { Vst2::vstSpeakerConfigTypeLRCLsRsSlSr, { left, right, centre, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear, unknown } }, | |||
+ { Vst2::vstSpeakerConfigTypeLRCLfeLsRsLcRc, { left, right, centre, LFE, leftSurround, rightSurround, topFrontLeft, topFrontRight, unknown } }, | |||
+ { Vst2::vstSpeakerConfigTypeLRCLfeLsRsSlSr, { left, right, centre, LFE, leftSurround, rightSurround, leftSurroundRear, rightSurroundRear, unknown } }, | |||
+ { Vst2::vstSpeakerConfigTypeLRCLsRsLcRcCs, { left, right, centre, leftSurround, rightSurround, topFrontLeft, topFrontRight, surround, unknown } }, | |||
+ { Vst2::vstSpeakerConfigTypeLRCLsRsCsSlSr, { left, right, centre, leftSurround, rightSurround, surround, leftSurroundRear, rightSurroundRear, unknown } }, | |||
+ { Vst2::vstSpeakerConfigTypeLRCLfeLsRsLcRcCs, { left, right, centre, LFE, leftSurround, rightSurround, topFrontLeft, topFrontRight, surround, unknown } }, | |||
+ { Vst2::vstSpeakerConfigTypeLRCLfeLsRsCsSlSr, { left, right, centre, LFE, leftSurround, rightSurround, surround, leftSurroundRear, rightSurroundRear, unknown } }, | |||
+ { Vst2::vstSpeakerConfigTypeLRCLfeLsRsTflTfcTfrTrlTrrLfe2, { left, right, centre, LFE, leftSurround, rightSurround, topFrontLeft, topFrontCentre, topFrontRight, topRearLeft, topRearRight, LFE2, unknown } }, | |||
+ { Vst2::vstSpeakerConfigTypeEmpty, { unknown } } | |||
}; | |||
return mappings; | |||
@@ -254,25 +254,25 @@ struct SpeakerMappings : private AudioChannelSet // (inheritance only to give e | |||
{ | |||
switch (type) | |||
{ | |||
- case AudioChannelSet::left: return Vst2::kSpeakerL; | |||
- case AudioChannelSet::right: return Vst2::kSpeakerR; | |||
- case AudioChannelSet::centre: return Vst2::kSpeakerC; | |||
- case AudioChannelSet::LFE: return Vst2::kSpeakerLfe; | |||
- case AudioChannelSet::leftSurround: return Vst2::kSpeakerLs; | |||
- case AudioChannelSet::rightSurround: return Vst2::kSpeakerRs; | |||
- case AudioChannelSet::leftCentre: return Vst2::kSpeakerLc; | |||
- case AudioChannelSet::rightCentre: return Vst2::kSpeakerRc; | |||
- case AudioChannelSet::surround: return Vst2::kSpeakerS; | |||
- case AudioChannelSet::leftSurroundRear: return Vst2::kSpeakerSl; | |||
- case AudioChannelSet::rightSurroundRear: return Vst2::kSpeakerSr; | |||
- case AudioChannelSet::topMiddle: return Vst2::kSpeakerTm; | |||
- case AudioChannelSet::topFrontLeft: return Vst2::kSpeakerTfl; | |||
- case AudioChannelSet::topFrontCentre: return Vst2::kSpeakerTfc; | |||
- case AudioChannelSet::topFrontRight: return Vst2::kSpeakerTfr; | |||
- case AudioChannelSet::topRearLeft: return Vst2::kSpeakerTrl; | |||
- case AudioChannelSet::topRearCentre: return Vst2::kSpeakerTrc; | |||
- case AudioChannelSet::topRearRight: return Vst2::kSpeakerTrr; | |||
- case AudioChannelSet::LFE2: return Vst2::kSpeakerLfe2; | |||
+ case AudioChannelSet::left: return Vst2::vstIndividualSpeakerTypeLeft; | |||
+ case AudioChannelSet::right: return Vst2::vstIndividualSpeakerTypeRight; | |||
+ case AudioChannelSet::centre: return Vst2::vstIndividualSpeakerTypeCentre; | |||
+ case AudioChannelSet::LFE: return Vst2::vstIndividualSpeakerTypeLFE; | |||
+ case AudioChannelSet::leftSurround: return Vst2::vstIndividualSpeakerTypeLeftSurround; | |||
+ case AudioChannelSet::rightSurround: return Vst2::vstIndividualSpeakerTypeRightSurround; | |||
+ case AudioChannelSet::leftCentre: return Vst2::vstIndividualSpeakerTypeLeftCentre; | |||
+ case AudioChannelSet::rightCentre: return Vst2::vstIndividualSpeakerTypeRightCentre; | |||
+ case AudioChannelSet::surround: return Vst2::vstIndividualSpeakerTypeSurround; | |||
+ case AudioChannelSet::leftSurroundRear: return Vst2::vstIndividualSpeakerTypeLeftRearSurround; | |||
+ case AudioChannelSet::rightSurroundRear: return Vst2::vstIndividualSpeakerTypeRightRearSurround; | |||
+ case AudioChannelSet::topMiddle: return Vst2::vstIndividualSpeakerTypeTopMiddle; | |||
+ case AudioChannelSet::topFrontLeft: return Vst2::vstIndividualSpeakerTypeTopFrontLeft; | |||
+ case AudioChannelSet::topFrontCentre: return Vst2::vstIndividualSpeakerTypeTopFrontCentre; | |||
+ case AudioChannelSet::topFrontRight: return Vst2::vstIndividualSpeakerTypeTopFrontRight; | |||
+ case AudioChannelSet::topRearLeft: return Vst2::vstIndividualSpeakerTypeTopRearLeft; | |||
+ case AudioChannelSet::topRearCentre: return Vst2::vstIndividualSpeakerTypeTopRearCentre; | |||
+ case AudioChannelSet::topRearRight: return Vst2::vstIndividualSpeakerTypeTopRearRight; | |||
+ case AudioChannelSet::LFE2: return Vst2::vstIndividualSpeakerTypeLFE2; | |||
default: break; | |||
} | |||
@@ -1,191 +0,0 @@ | |||
/* | |||
============================================================================== | |||
This file is part of the JUCE 6 technical preview. | |||
Copyright (c) 2017 - ROLI Ltd. | |||
You may use this code under the terms of the GPL v3 | |||
(see www.gnu.org/licenses). | |||
For this technical preview, this file is not subject to commercial licensing. | |||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER | |||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE | |||
DISCLAIMED. | |||
============================================================================== | |||
*/ | |||
// NB: this must come first, *before* the header-guard. | |||
#ifdef JUCE_VSTINTERFACE_H_INCLUDED | |||
namespace juce | |||
{ | |||
//============================================================================== | |||
/** Holds a set of VSTMidiEvent objects and makes it easy to add | |||
events to the list. | |||
This is used by both the VST hosting code and the plugin wrapper. | |||
@tags{Audio} | |||
*/ | |||
class VSTMidiEventList | |||
{ | |||
public: | |||
//============================================================================== | |||
VSTMidiEventList() | |||
: numEventsUsed (0), numEventsAllocated (0) | |||
{ | |||
} | |||
~VSTMidiEventList() | |||
{ | |||
freeEvents(); | |||
} | |||
//============================================================================== | |||
void clear() | |||
{ | |||
numEventsUsed = 0; | |||
if (events != nullptr) | |||
events->numEvents = 0; | |||
} | |||
void addEvent (const void* const midiData, int numBytes, int frameOffset) | |||
{ | |||
ensureSize (numEventsUsed + 1); | |||
void* const ptr = (Vst2::VstMidiEvent*) (events->events [numEventsUsed]); | |||
auto* const e = (Vst2::VstMidiEvent*) ptr; | |||
events->numEvents = ++numEventsUsed; | |||
if (numBytes <= 4) | |||
{ | |||
if (e->type == Vst2::kVstSysExType) | |||
{ | |||
delete[] (((Vst2::VstMidiSysexEvent*) ptr)->sysexDump); | |||
e->type = Vst2::kVstMidiType; | |||
e->byteSize = sizeof (Vst2::VstMidiEvent); | |||
e->noteLength = 0; | |||
e->noteOffset = 0; | |||
e->detune = 0; | |||
e->noteOffVelocity = 0; | |||
} | |||
e->deltaFrames = frameOffset; | |||
memcpy (e->midiData, midiData, (size_t) numBytes); | |||
} | |||
else | |||
{ | |||
auto* const se = (Vst2::VstMidiSysexEvent*) ptr; | |||
if (se->type == Vst2::kVstSysExType) | |||
delete[] se->sysexDump; | |||
se->sysexDump = new char [(size_t) numBytes]; | |||
memcpy (se->sysexDump, midiData, (size_t) numBytes); | |||
se->type = Vst2::kVstSysExType; | |||
se->byteSize = sizeof (Vst2::VstMidiSysexEvent); | |||
se->deltaFrames = frameOffset; | |||
se->flags = 0; | |||
se->dumpBytes = numBytes; | |||
se->resvd1 = 0; | |||
se->resvd2 = 0; | |||
} | |||
} | |||
//============================================================================== | |||
// Handy method to pull the events out of an event buffer supplied by the host | |||
// or plugin. | |||
static void addEventsToMidiBuffer (const Vst2::VstEvents* events, MidiBuffer& dest) | |||
{ | |||
for (int i = 0; i < events->numEvents; ++i) | |||
{ | |||
const Vst2::VstEvent* const e = events->events[i]; | |||
if (e != nullptr) | |||
{ | |||
const void* const ptr = events->events[i]; | |||
if (e->type == Vst2::kVstMidiType) | |||
{ | |||
dest.addEvent ((const juce::uint8*) ((const Vst2::VstMidiEvent*) ptr)->midiData, | |||
4, e->deltaFrames); | |||
} | |||
else if (e->type == Vst2::kVstSysExType) | |||
{ | |||
const auto* se = (const Vst2::VstMidiSysexEvent*) ptr; | |||
dest.addEvent ((const juce::uint8*) se->sysexDump, | |||
(int) se->dumpBytes, | |||
e->deltaFrames); | |||
} | |||
} | |||
} | |||
} | |||
//============================================================================== | |||
void ensureSize (int numEventsNeeded) | |||
{ | |||
if (numEventsNeeded > numEventsAllocated) | |||
{ | |||
numEventsNeeded = (numEventsNeeded + 32) & ~31; | |||
const size_t size = 20 + (size_t) numEventsNeeded * sizeof (Vst2::VstEvent*); | |||
if (events == nullptr) | |||
events.calloc (size, 1); | |||
else | |||
events.realloc (size, 1); | |||
for (int i = numEventsAllocated; i < numEventsNeeded; ++i) | |||
events->events[i] = allocateVSTEvent(); | |||
numEventsAllocated = numEventsNeeded; | |||
} | |||
} | |||
void freeEvents() | |||
{ | |||
if (events != nullptr) | |||
{ | |||
for (int i = numEventsAllocated; --i >= 0;) | |||
freeVSTEvent (events->events[i]); | |||
events.free(); | |||
numEventsUsed = 0; | |||
numEventsAllocated = 0; | |||
} | |||
} | |||
//============================================================================== | |||
HeapBlock<Vst2::VstEvents> events; | |||
private: | |||
int numEventsUsed, numEventsAllocated; | |||
static Vst2::VstEvent* allocateVSTEvent() | |||
{ | |||
auto e = (Vst2::VstEvent*) std::calloc (1, sizeof (Vst2::VstMidiEvent) > sizeof (Vst2::VstMidiSysexEvent) ? sizeof (Vst2::VstMidiEvent) | |||
: sizeof (Vst2::VstMidiSysexEvent)); | |||
e->type = Vst2::kVstMidiType; | |||
e->byteSize = sizeof (Vst2::VstMidiEvent); | |||
return e; | |||
} | |||
static void freeVSTEvent (Vst2::VstEvent* e) | |||
{ | |||
if (e->type == Vst2::kVstSysExType) | |||
{ | |||
delete[] (reinterpret_cast<Vst2::VstMidiSysexEvent*> (e)->sysexDump); | |||
} | |||
std::free (e); | |||
} | |||
}; | |||
} // namespace juce | |||
#endif // JUCE_VSTINTERFACE_H_INCLUDED |
@@ -1,193 +0,0 @@ | |||
--- modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp | |||
+++ modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp | |||
@@ -2358,56 +2356,56 @@ private: | |||
if (currentPlayHead->getCurrentPosition (position)) | |||
{ | |||
- vstHostTime.samplePos = (double) position.timeInSamples; | |||
- vstHostTime.tempo = position.bpm; | |||
- vstHostTime.timeSigNumerator = position.timeSigNumerator; | |||
- vstHostTime.timeSigDenominator = position.timeSigDenominator; | |||
- vstHostTime.ppqPos = position.ppqPosition; | |||
- vstHostTime.barStartPos = position.ppqPositionOfLastBarStart; | |||
- vstHostTime.flags |= Vst2::kVstTempoValid | |||
- | Vst2::kVstTimeSigValid | |||
- | Vst2::kVstPpqPosValid | |||
- | Vst2::kVstBarsValid; | |||
+ vstHostTime.samplePosition = (double) position.timeInSamples; | |||
+ vstHostTime.tempoBPM = position.bpm; | |||
+ vstHostTime.timeSignatureNumerator = position.timeSigNumerator; | |||
+ vstHostTime.timeSignatureDenominator = position.timeSigDenominator; | |||
+ vstHostTime.musicalPosition = position.ppqPosition; | |||
+ vstHostTime.lastBarPosition = position.ppqPositionOfLastBarStart; | |||
+ vstHostTime.flags |= Vst2::vstTimingInfoFlagTempoValid | |||
+ | Vst2::vstTimingInfoFlagTimeSignatureValid | |||
+ | Vst2::vstTimingInfoFlagMusicalPositionValid | |||
+ | Vst2::vstTimingInfoFlagLastBarPositionValid; | |||
int32 newTransportFlags = 0; | |||
- if (position.isPlaying) newTransportFlags |= Vst2::kVstTransportPlaying; | |||
- if (position.isRecording) newTransportFlags |= Vst2::kVstTransportRecording; | |||
+ if (position.isPlaying) newTransportFlags |= Vst2::vstTimingInfoFlagCurrentlyPlaying; | |||
+ if (position.isRecording) newTransportFlags |= Vst2::vstTimingInfoFlagCurrentlyRecording; | |||
- if (newTransportFlags != (vstHostTime.flags & (Vst2::kVstTransportPlaying | |||
- | Vst2::kVstTransportRecording))) | |||
- vstHostTime.flags = (vstHostTime.flags & ~(Vst2::kVstTransportPlaying | Vst2::kVstTransportRecording)) | newTransportFlags | Vst2::kVstTransportChanged; | |||
+ if (newTransportFlags != (vstHostTime.flags & (Vst2::vstTimingInfoFlagCurrentlyPlaying | |||
+ | Vst2::vstTimingInfoFlagCurrentlyRecording))) | |||
+ vstHostTime.flags = (vstHostTime.flags & ~(Vst2::vstTimingInfoFlagCurrentlyPlaying | Vst2::vstTimingInfoFlagCurrentlyRecording)) | newTransportFlags | Vst2::vstTimingInfoFlagTransportChanged; | |||
else | |||
- vstHostTime.flags &= ~Vst2::kVstTransportChanged; | |||
+ vstHostTime.flags &= ~Vst2::vstTimingInfoFlagTransportChanged; | |||
switch (position.frameRate) | |||
{ | |||
- case AudioPlayHead::fps24: setHostTimeFrameRate (Vst2::kVstSmpte24fps, 24.0, position.timeInSeconds); break; | |||
- case AudioPlayHead::fps25: setHostTimeFrameRate (Vst2::kVstSmpte25fps, 25.0, position.timeInSeconds); break; | |||
- case AudioPlayHead::fps30: setHostTimeFrameRate (Vst2::kVstSmpte30fps, 30.0, position.timeInSeconds); break; | |||
- case AudioPlayHead::fps60: setHostTimeFrameRate (Vst2::kVstSmpte60fps, 60.0, position.timeInSeconds); break; | |||
- | |||
- case AudioPlayHead::fps23976: setHostTimeFrameRateDrop (Vst2::kVstSmpte239fps, 24.0, position.timeInSeconds); break; | |||
- case AudioPlayHead::fps2997: setHostTimeFrameRateDrop (Vst2::kVstSmpte2997fps, 30.0, position.timeInSeconds); break; | |||
- case AudioPlayHead::fps2997drop: setHostTimeFrameRateDrop (Vst2::kVstSmpte2997dfps, 30.0, position.timeInSeconds); break; | |||
- case AudioPlayHead::fps30drop: setHostTimeFrameRateDrop (Vst2::kVstSmpte30dfps, 30.0, position.timeInSeconds); break; | |||
- case AudioPlayHead::fps60drop: setHostTimeFrameRateDrop (Vst2::kVstSmpte599fps, 60.0, position.timeInSeconds); break; | |||
+ case AudioPlayHead::fps24: setHostTimeFrameRate (Vst2::vstSmpteRateFps24, 24.0, position.timeInSeconds); break; | |||
+ case AudioPlayHead::fps25: setHostTimeFrameRate (Vst2::vstSmpteRateFps25, 25.0, position.timeInSeconds); break; | |||
+ case AudioPlayHead::fps30: setHostTimeFrameRate (Vst2::vstSmpteRateFps30, 30.0, position.timeInSeconds); break; | |||
+ case AudioPlayHead::fps60: setHostTimeFrameRate (Vst2::vstSmpteRateFps60, 60.0, position.timeInSeconds); break; | |||
+ | |||
+ case AudioPlayHead::fps23976: setHostTimeFrameRateDrop (Vst2::vstSmpteRateFps239, 24.0, position.timeInSeconds); break; | |||
+ case AudioPlayHead::fps2997: setHostTimeFrameRateDrop (Vst2::vstSmpteRateFps2997, 30.0, position.timeInSeconds); break; | |||
+ case AudioPlayHead::fps2997drop: setHostTimeFrameRateDrop (Vst2::vstSmpteRateFps2997drop, 30.0, position.timeInSeconds); break; | |||
+ case AudioPlayHead::fps30drop: setHostTimeFrameRateDrop (Vst2::vstSmpteRateFps30drop, 30.0, position.timeInSeconds); break; | |||
+ case AudioPlayHead::fps60drop: setHostTimeFrameRateDrop (Vst2::vstSmpteRateFps599, 60.0, position.timeInSeconds); break; | |||
default: break; | |||
} | |||
if (position.isLooping) | |||
{ | |||
- vstHostTime.cycleStartPos = position.ppqLoopStart; | |||
- vstHostTime.cycleEndPos = position.ppqLoopEnd; | |||
- vstHostTime.flags |= (Vst2::kVstCyclePosValid | Vst2::kVstTransportCycleActive); | |||
+ vstHostTime.loopStartPosition = position.ppqLoopStart; | |||
+ vstHostTime.loopEndPosition = position.ppqLoopEnd; | |||
+ vstHostTime.flags |= (Vst2::vstTimingInfoFlagLoopPositionValid | Vst2::vstTimingInfoFlagLoopActive); | |||
} | |||
else | |||
{ | |||
- vstHostTime.flags &= ~(Vst2::kVstCyclePosValid | Vst2::kVstTransportCycleActive); | |||
+ vstHostTime.flags &= ~(Vst2::vstTimingInfoFlagLoopPositionValid | Vst2::vstTimingInfoFlagLoopActive); | |||
} | |||
} | |||
} | |||
- vstHostTime.nanoSeconds = getVSTHostTimeNanoseconds(); | |||
+ vstHostTime.systemTimeNanoseconds = getVSTHostTimeNanoseconds(); | |||
if (wantsMidiMessages) | |||
{ | |||
@@ -2950,11 +2948,11 @@ public: | |||
setScaleFactorAndDispatchMessage (newScaleFactor); | |||
#if JUCE_WINDOWS | |||
- Vst2::ERect* rect = nullptr; | |||
- dispatch (Vst2::effEditGetRect, 0, 0, &rect, 0); | |||
+ Vst2::VstEditorBounds* rect = nullptr; | |||
+ dispatch (Vst2::plugInOpcodeGetEditorBounds, 0, 0, &rect, 0); | |||
- if (! isWindowSizeCorrectForPlugin (roundToInt ((rect->right - rect->left) / nativeScaleFactor), | |||
- roundToInt ((rect->bottom - rect->top) / nativeScaleFactor))) | |||
+ if (! isWindowSizeCorrectForPlugin (roundToInt ((rect->rightmost - rect->leftmost) / nativeScaleFactor), | |||
+ roundToInt ((rect->lower - rect->upper) / nativeScaleFactor))) | |||
return; | |||
#endif | |||
@@ -3134,15 +3132,15 @@ private: | |||
dpiDisabler.reset (new ScopedDPIAwarenessDisabler()); | |||
#endif | |||
- Vst2::ERect* rect = nullptr; | |||
- dispatch (Vst2::effEditGetRect, 0, 0, &rect, 0); | |||
+ Vst2::VstEditorBounds* rect = nullptr; | |||
+ dispatch (Vst2::plugInOpcodeGetEditorBounds, 0, 0, &rect, 0); | |||
#if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE | |||
// some plug-ins are fussy about this | |||
dpiDisabler.reset (nullptr); | |||
#endif | |||
- dispatch (Vst2::effEditOpen, 0, 0, getWindowHandle(), 0); | |||
+ dispatch (Vst2::plugInOpcodeOpenEditor, 0, 0, getWindowHandle(), 0); | |||
#if JUCE_WINDOWS && JUCE_WIN_PER_MONITOR_DPI_AWARE | |||
if (! pluginRespondsToDPIChanges) | |||
@@ -3150,11 +3148,11 @@ private: | |||
#endif | |||
// do this before and after like in the steinberg example | |||
- dispatch (Vst2::effEditGetRect, 0, 0, &rect, 0); | |||
- dispatch (Vst2::effGetProgram, 0, 0, nullptr, 0); // also in steinberg code | |||
+ dispatch (Vst2::plugInOpcodeGetEditorBounds, 0, 0, &rect, 0); | |||
+ dispatch (Vst2::plugInOpcodeGetCurrentProgram, 0, 0, nullptr, 0); // also in steinberg code | |||
// Install keyboard hooks | |||
- pluginWantsKeys = (dispatch (Vst2::effKeysRequired, 0, 0, nullptr, 0) == 0); | |||
+ pluginWantsKeys = (dispatch (Vst2::plugInOpcodeKeyboardFocusRequired, 0, 0, nullptr, 0) == 0); | |||
#if JUCE_WINDOWS | |||
originalWndProc = 0; | |||
@@ -3410,17 +3408,17 @@ private: | |||
if (owner.isOpen) | |||
{ | |||
owner.isOpen = false; | |||
- owner.dispatch (Vst2::effEditClose, 0, 0, 0, 0); | |||
- owner.dispatch (Vst2::effEditSleep, 0, 0, 0, 0); | |||
+ owner.dispatch (Vst2::plugInOpcodeCloseEditor, 0, 0, 0, 0); | |||
+ owner.dispatch (Vst2::plugInOpcodeSleepEditor, 0, 0, 0, 0); | |||
} | |||
} | |||
bool getEmbeddedViewSize (int& w, int& h) override | |||
{ | |||
- Vst2::ERect* rect = nullptr; | |||
- owner.dispatch (Vst2::effEditGetRect, 0, 0, &rect, 0); | |||
- w = rect->right - rect->left; | |||
- h = rect->bottom - rect->top; | |||
+ Vst2::VstEditorBounds* rect = nullptr; | |||
+ owner.dispatch (Vst2::plugInOpcodeGetEditorBounds, 0, 0, &rect, 0); | |||
+ w = rect->rightmost - rect->leftmost; | |||
+ h = rect->lower - rect->upper; | |||
return true; | |||
} | |||
@@ -3430,7 +3428,7 @@ private: | |||
{ | |||
alreadyInside = true; | |||
getTopLevelComponent()->toFront (true); | |||
- owner.dispatch (Vst2::effEditMouse, x, y, 0, 0); | |||
+ owner.dispatch (Vst2::plugInOpcodeGetMouse, x, y, 0, 0); | |||
alreadyInside = false; | |||
} | |||
else | |||
@@ -3444,13 +3442,13 @@ private: | |||
if (auto* peer = getPeer()) | |||
{ | |||
auto pos = peer->globalToLocal (getScreenPosition()); | |||
- Vst2::ERect r; | |||
- r.left = (int16) pos.getX(); | |||
- r.top = (int16) pos.getY(); | |||
- r.right = (int16) (r.left + getWidth()); | |||
- r.bottom = (int16) (r.top + getHeight()); | |||
+ Vst2::VstEditorBounds r; | |||
+ r.leftmost = (int16) pos.getX(); | |||
+ r.upper = (int16) pos.getY(); | |||
+ r.rightmost = (int16) (r.leftmost + getWidth()); | |||
+ r.lower = (int16) (r.upper + getHeight()); | |||
- owner.dispatch (Vst2::effEditDraw, 0, 0, &r, 0); | |||
+ owner.dispatch (Vst2::plugInOpcodeDrawEditor, 0, 0, &r, 0); | |||
} | |||
} | |||