OpenShot Library | OpenShotAudio  0.2.2
juce_MidiDevices.h
1 
2 /** @weakgroup juce_audio_devices-midi_io
3  * @{
4  */
5 /*
6  ==============================================================================
7 
8  This file is part of the JUCE library.
9  Copyright (c) 2017 - ROLI Ltd.
10 
11  JUCE is an open source library subject to commercial or open-source
12  licensing.
13 
14  The code included in this file is provided under the terms of the ISC license
15  http://www.isc.org/downloads/software-support-policy/isc-license. Permission
16  To use, copy, modify, and/or distribute this software for any purpose with or
17  without fee is hereby granted provided that the above copyright notice and
18  this permission notice appear in all copies.
19 
20  JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
21  EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
22  DISCLAIMED.
23 
24  ==============================================================================
25 */
26 
27 namespace juce
28 {
29 //==============================================================================
30 /**
31  This struct contains information about a MIDI input or output device.
32 
33  You can get one of these structs by calling the static getAvailableDevices() or
34  getDefaultDevice() methods of MidiInput and MidiOutput or by calling getDeviceInfo()
35  on an instance of these classes. Devices can be opened by passing the identifier to
36  the openDevice() method.
37 
38  @tags{Audio}
39 */
41 {
42  MidiDeviceInfo() = default;
43 
44  MidiDeviceInfo (const String& deviceName, const String& deviceIdentifier)
45  : name (deviceName), identifier (deviceIdentifier)
46  {
47  }
48 
49  /** The name of this device.
50 
51  This will be provided by the OS unless the device has been created with the
52  createNewDevice() method.
53 
54  Note that the name is not guaranteed to be unique and two devices with the
55  same name will be indistinguishable. If you want to address a specific device
56  it is better to use the identifier.
57  */
59 
60  /** The identifier for this device.
61 
62  This will be provided by the OS and it's format will differ on different systems
63  e.g. on macOS it will be a number whereas on Windows it will be a long alphanumeric string.
64  */
66 
67  //==============================================================================
68  bool operator== (const MidiDeviceInfo& other) const noexcept { return name == other.name && identifier == other.identifier; }
69  bool operator!= (const MidiDeviceInfo& other) const noexcept { return ! operator== (other); }
70 };
71 
72 class MidiInputCallback;
73 
74 //==============================================================================
75 /**
76  Represents a midi input device.
77 
78  To create one of these, use the static getAvailableDevices() method to find out what
79  inputs are available, and then use the openDevice() method to try to open one.
80 
81  @see MidiOutput
82 
83  @tags{Audio}
84 */
85 class JUCE_API MidiInput final
86 {
87 public:
88  //==============================================================================
89  /** Returns a list of the available midi input devices.
90 
91  You can open one of the devices by passing its identifier into the openDevice() method.
92 
93  @see MidiDeviceInfo, getDevices, getDefaultDeviceIndex, openDevice
94  */
95  static Array<MidiDeviceInfo> getAvailableDevices();
96 
97  /** Returns the MidiDeviceInfo of the default midi input device to use. */
98  static MidiDeviceInfo getDefaultDevice();
99 
100  /** Tries to open one of the midi input devices.
101 
102  This will return a MidiInput object if it manages to open it, you can then
103  call start() and stop() on this device.
104 
105  If the device can't be opened, this will return an empty object.
106 
107  @param deviceIdentifier the ID of the device to open - use the getAvailableDevices() method to
108  find the available devices that can be opened
109  @param callback the object that will receive the midi messages from this device
110 
111  @see MidiInputCallback, getDevices
112  */
113  static std::unique_ptr<MidiInput> openDevice (const String& deviceIdentifier, MidiInputCallback* callback);
114 
115  #if JUCE_LINUX || JUCE_MAC || JUCE_IOS || DOXYGEN
116  /** This will try to create a new midi input device (only available on Linux, macOS and iOS).
117 
118  This will attempt to create a new midi input device with the specified name for other
119  apps to connect to.
120 
121  NB - if you are calling this method on iOS you must have enabled the "Audio Background Capability"
122  setting in the iOS exporter otherwise this method will fail.
123 
124  Returns an empty object if a device can't be created.
125 
126  @param deviceName the name of the device to create
127  @param callback the object that will receive the midi messages from this device
128  */
129  static std::unique_ptr<MidiInput> createNewDevice (const String& deviceName, MidiInputCallback* callback);
130  #endif
131 
132  //==============================================================================
133  /** Destructor. */
134  ~MidiInput();
135 
136  /** Starts the device running.
137 
138  After calling this, the device will start sending midi messages to the MidiInputCallback
139  object that was specified when the openDevice() method was called.
140 
141  @see stop
142  */
143  void start();
144 
145  /** Stops the device running.
146 
147  @see start
148  */
149  void stop();
150 
151  /** Returns the MidiDeviceInfo struct containing some information about this device. */
152  MidiDeviceInfo getDeviceInfo() const noexcept { return deviceInfo; }
153 
154  /** Returns the identifier of this device. */
155  String getIdentifier() const noexcept { return deviceInfo.identifier; }
156 
157  /** Returns the name of this device. */
158  String getName() const noexcept { return deviceInfo.name; }
159 
160  /** Sets a custom name for the device. */
161  void setName (const String& newName) noexcept { deviceInfo.name = newName; }
162 
163  //==============================================================================
164  /** Deprecated. */
165  static StringArray getDevices();
166  /** Deprecated. */
167  static int getDefaultDeviceIndex();
168  /** Deprecated. */
169  static std::unique_ptr<MidiInput> openDevice (int, MidiInputCallback*);
170 
171 private:
172  //==============================================================================
173  explicit MidiInput (const String&, const String&);
174 
175  MidiDeviceInfo deviceInfo;
176  void* internal = nullptr;
177 
178  JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiInput)
179 };
180 
181 //==============================================================================
182 /**
183  Receives incoming messages from a physical MIDI input device.
184 
185  This class is overridden to handle incoming midi messages. See the MidiInput
186  class for more details.
187 
188  @see MidiInput
189 
190  @tags{Audio}
191 */
193 {
194 public:
195  /** Destructor. */
196  virtual ~MidiInputCallback() = default;
197 
198  /** Receives an incoming message.
199 
200  A MidiInput object will call this method when a midi event arrives. It'll be
201  called on a high-priority system thread, so avoid doing anything time-consuming
202  in here, and avoid making any UI calls. You might find the MidiBuffer class helpful
203  for queueing incoming messages for use later.
204 
205  @param source the MidiInput object that generated the message
206  @param message the incoming message. The message's timestamp is set to a value
207  equivalent to (Time::getMillisecondCounter() / 1000.0) to specify the
208  time when the message arrived
209  */
210  virtual void handleIncomingMidiMessage (MidiInput* source,
211  const MidiMessage& message) = 0;
212 
213  /** Notification sent each time a packet of a multi-packet sysex message arrives.
214 
215  If a long sysex message is broken up into multiple packets, this callback is made
216  for each packet that arrives until the message is finished, at which point
217  the normal handleIncomingMidiMessage() callback will be made with the entire
218  message.
219 
220  The message passed in will contain the start of a sysex, but won't be finished
221  with the terminating 0xf7 byte.
222  */
223  virtual void handlePartialSysexMessage (MidiInput* source,
224  const uint8* messageData,
225  int numBytesSoFar,
226  double timestamp)
227  {
228  ignoreUnused (source, messageData, numBytesSoFar, timestamp);
229  }
230 };
231 
232 //==============================================================================
233 /**
234  Represents a midi output device.
235 
236  To create one of these, use the static getAvailableDevices() method to find out what
237  outputs are available, and then use the openDevice() method to try to open one.
238 
239  @see MidiInput
240 
241  @tags{Audio}
242 */
243 class JUCE_API MidiOutput final : private Thread
244 {
245 public:
246  //==============================================================================
247  /** Returns a list of the available midi output devices.
248 
249  You can open one of the devices by passing its identifier into the openDevice() method.
250 
251  @see MidiDeviceInfo, getDevices, getDefaultDeviceIndex, openDevice
252  */
253  static Array<MidiDeviceInfo> getAvailableDevices();
254 
255  /** Returns the MidiDeviceInfo of the default midi output device to use. */
256  static MidiDeviceInfo getDefaultDevice();
257 
258  /** Tries to open one of the midi output devices.
259 
260  This will return a MidiOutput object if it manages to open it, you can then
261  send messages to this device.
262 
263  If the device can't be opened, this will return an empty object.
264 
265  @param deviceIdentifier the ID of the device to open - use the getAvailableDevices() method to
266  find the available devices that can be opened
267  @see getDevices
268  */
269  static std::unique_ptr<MidiOutput> openDevice (const String& deviceIdentifier);
270 
271  #if JUCE_LINUX || JUCE_MAC || JUCE_IOS || DOXYGEN
272  /** This will try to create a new midi output device (only available on Linux, macOS and iOS).
273 
274  This will attempt to create a new midi output device with the specified name that other
275  apps can connect to and use as their midi input.
276 
277  NB - if you are calling this method on iOS you must have enabled the "Audio Background Capability"
278  setting in the iOS exporter otherwise this method will fail.
279 
280  Returns an empty object if a device can't be created.
281 
282  @param deviceName the name of the device to create
283  */
284  static std::unique_ptr<MidiOutput> createNewDevice (const String& deviceName);
285  #endif
286 
287  //==============================================================================
288  /** Destructor. */
289  ~MidiOutput() override;
290 
291  /** Returns the MidiDeviceInfo struct containing some information about this device. */
292  MidiDeviceInfo getDeviceInfo() const noexcept { return deviceInfo; }
293 
294  /** Returns the identifier of this device. */
295  String getIdentifier() const noexcept { return deviceInfo.identifier; }
296 
297  /** Returns the name of this device. */
298  String getName() const noexcept { return deviceInfo.name; }
299 
300  /** Sets a custom name for the device. */
301  void setName (const String& newName) noexcept { deviceInfo.name = newName; }
302 
303  //==============================================================================
304  /** Sends out a MIDI message immediately. */
305  void sendMessageNow (const MidiMessage& message);
306 
307  /** Sends out a sequence of MIDI messages immediately. */
308  void sendBlockOfMessagesNow (const MidiBuffer& buffer);
309 
310  /** This lets you supply a block of messages that will be sent out at some point
311  in the future.
312 
313  The MidiOutput class has an internal thread that can send out timestamped
314  messages - this appends a set of messages to its internal buffer, ready for
315  sending.
316 
317  This will only work if you've already started the thread with startBackgroundThread().
318 
319  A time is specified, at which the block of messages should be sent. This time uses
320  the same time base as Time::getMillisecondCounter(), and must be in the future.
321 
322  The samplesPerSecondForBuffer parameter indicates the number of samples per second
323  used by the MidiBuffer. Each event in a MidiBuffer has a sample position, and the
324  samplesPerSecondForBuffer value is needed to convert this sample position to a
325  real time.
326  */
327  void sendBlockOfMessages (const MidiBuffer& buffer,
328  double millisecondCounterToStartAt,
329  double samplesPerSecondForBuffer);
330 
331  /** Gets rid of any midi messages that had been added by sendBlockOfMessages(). */
332  void clearAllPendingMessages();
333 
334  /** Starts up a background thread so that the device can send blocks of data.
335  Call this to get the device ready, before using sendBlockOfMessages().
336  */
337  void startBackgroundThread();
338 
339  /** Stops the background thread, and clears any pending midi events.
340  @see startBackgroundThread
341  */
342  void stopBackgroundThread();
343 
344  //==============================================================================
345  /** Deprecated. */
346  static StringArray getDevices();
347  /** Deprecated. */
348  static int getDefaultDeviceIndex();
349  /** Deprecated. */
350  static std::unique_ptr<MidiOutput> openDevice (int);
351 
352 private:
353  //==============================================================================
354  struct PendingMessage
355  {
356  PendingMessage (const void* data, int len, double timeStamp)
357  : message (data, len, timeStamp)
358  {
359  }
360 
361  MidiMessage message;
362  PendingMessage* next;
363  };
364 
365  //==============================================================================
366  explicit MidiOutput (const String&, const String&);
367  void run() override;
368 
369  MidiDeviceInfo deviceInfo;
370  void* internal = nullptr;
371  CriticalSection lock;
372  PendingMessage* firstMessage = nullptr;
373 
374  JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiOutput)
375 };
376 
377 } // namespace juce
378 
379 /** @}*/
String getIdentifier() const noexcept
Returns the identifier of this device.
#define JUCE_API
This macro is added to all JUCE public class declarations.
MidiDeviceInfo getDeviceInfo() const noexcept
Returns the MidiDeviceInfo struct containing some information about this device.
Represents a midi input device.
Encapsulates a MIDI message.
String identifier
The identifier for this device.
String getName() const noexcept
Returns the name of this device.
A special array for holding a list of strings.
The JUCE String class!
Definition: juce_String.h:42
String getIdentifier() const noexcept
Returns the identifier of this device.
This struct contains information about a MIDI input or output device.
String getName() const noexcept
Returns the name of this device.
Encapsulates a thread.
Definition: juce_Thread.h:46
void setName(const String &newName) noexcept
Sets a custom name for the device.
Holds a resizable array of primitive or copy-by-value objects.
Definition: juce_Array.h:59
Holds a sequence of time-stamped midi events.
virtual void handlePartialSysexMessage(MidiInput *source, const uint8 *messageData, int numBytesSoFar, double timestamp)
Notification sent each time a packet of a multi-packet sysex message arrives.
Receives incoming messages from a physical MIDI input device.
A re-entrant mutex.
Represents a midi output device.
String name
The name of this device.
MidiDeviceInfo getDeviceInfo() const noexcept
Returns the MidiDeviceInfo struct containing some information about this device.
void setName(const String &newName) noexcept
Sets a custom name for the device.