OpenShot Audio Library | OpenShotAudio  0.6.0
juce_MidiDevices.h
1 /*
2  ==============================================================================
3 
4  This file is part of the JUCE library.
5  Copyright (c) 2022 - Raw Material Software Limited
6 
7  JUCE is an open source library subject to commercial or open-source
8  licensing.
9 
10  The code included in this file is provided under the terms of the ISC license
11  http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12  To use, copy, modify, and/or distribute this software for any purpose with or
13  without fee is hereby granted provided that the above copyright notice and
14  this permission notice appear in all copies.
15 
16  JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17  EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18  DISCLAIMED.
19 
20  ==============================================================================
21 */
22 
23 namespace juce
24 {
25 
26 class MidiDeviceListConnectionBroadcaster;
27 
50 {
51 public:
52  using Key = uint64_t;
53 
57 
60  : broadcaster (std::exchange (other.broadcaster, nullptr)),
61  key (std::exchange (other.key, Key{}))
62  {
63  }
64 
65  MidiDeviceListConnection& operator= (const MidiDeviceListConnection&) = delete;
66  MidiDeviceListConnection& operator= (MidiDeviceListConnection&& other) noexcept
67  {
68  MidiDeviceListConnection (std::move (other)).swap (*this);
69  return *this;
70  }
71 
72  ~MidiDeviceListConnection() noexcept;
73 
79  void reset() noexcept
80  {
81  MidiDeviceListConnection().swap (*this);
82  }
83 
90  static MidiDeviceListConnection make (std::function<void()>);
91 
92 private:
93  MidiDeviceListConnection (MidiDeviceListConnectionBroadcaster* b, const Key k)
94  : broadcaster (b), key (k) {}
95 
96  void swap (MidiDeviceListConnection& other) noexcept
97  {
98  std::swap (other.broadcaster, broadcaster);
99  std::swap (other.key, key);
100  }
101 
102  MidiDeviceListConnectionBroadcaster* broadcaster = nullptr;
103  Key key = {};
104 };
105 
106 //==============================================================================
118 {
119  MidiDeviceInfo() = default;
120 
121  MidiDeviceInfo (const String& deviceName, const String& deviceIdentifier)
122  : name (deviceName), identifier (deviceIdentifier)
123  {
124  }
125 
136 
143 
144  //==============================================================================
145  auto tie() const { return std::tie (name, identifier); }
146  bool operator== (const MidiDeviceInfo& other) const noexcept { return tie() == other.tie(); }
147  bool operator!= (const MidiDeviceInfo& other) const noexcept { return tie() != other.tie(); }
148 };
149 
150 class MidiInputCallback;
151 
152 //==============================================================================
163 class JUCE_API MidiInput final
164 {
165 public:
166  //==============================================================================
174 
177 
191  static std::unique_ptr<MidiInput> openDevice (const String& deviceIdentifier, MidiInputCallback* callback);
192 
193  #if JUCE_LINUX || JUCE_BSD || JUCE_MAC || JUCE_IOS || DOXYGEN
207  static std::unique_ptr<MidiInput> createNewDevice (const String& deviceName, MidiInputCallback* callback);
208  #endif
209 
210  //==============================================================================
213 
221  void start();
222 
227  void stop();
228 
230  MidiDeviceInfo getDeviceInfo() const noexcept { return deviceInfo; }
231 
233  String getIdentifier() const noexcept { return deviceInfo.identifier; }
234 
236  String getName() const noexcept { return deviceInfo.name; }
237 
239  void setName (const String& newName) noexcept { deviceInfo.name = newName; }
240 
241  //==============================================================================
242  #ifndef DOXYGEN
243  [[deprecated ("Use getAvailableDevices instead.")]]
244  static StringArray getDevices();
245  [[deprecated ("Use getDefaultDevice instead.")]]
246  static int getDefaultDeviceIndex();
247  [[deprecated ("Use openDevice that takes a device identifier instead.")]]
248  static std::unique_ptr<MidiInput> openDevice (int, MidiInputCallback*);
249  #endif
250 
252  class Pimpl;
253 
254 private:
255  //==============================================================================
256  explicit MidiInput (const String&, const String&);
257 
258  MidiDeviceInfo deviceInfo;
259 
260  std::unique_ptr<Pimpl> internal;
261 
262  JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiInput)
263 };
264 
265 //==============================================================================
276 class JUCE_API MidiInputCallback
277 {
278 public:
280  virtual ~MidiInputCallback() = default;
281 
294  virtual void handleIncomingMidiMessage (MidiInput* source,
295  const MidiMessage& message) = 0;
296 
307  virtual void handlePartialSysexMessage (MidiInput* source,
308  const uint8* messageData,
309  int numBytesSoFar,
310  double timestamp);
311 };
312 
313 //==============================================================================
324 class JUCE_API MidiOutput final : private Thread
325 {
326 public:
327  //==============================================================================
335 
338 
350  static std::unique_ptr<MidiOutput> openDevice (const String& deviceIdentifier);
351 
352  #if JUCE_LINUX || JUCE_BSD || JUCE_MAC || JUCE_IOS || DOXYGEN
365  static std::unique_ptr<MidiOutput> createNewDevice (const String& deviceName);
366  #endif
367 
368  //==============================================================================
370  ~MidiOutput() override;
371 
373  MidiDeviceInfo getDeviceInfo() const noexcept { return deviceInfo; }
374 
376  String getIdentifier() const noexcept { return deviceInfo.identifier; }
377 
379  String getName() const noexcept { return deviceInfo.name; }
380 
382  void setName (const String& newName) noexcept { deviceInfo.name = newName; }
383 
384  //==============================================================================
386  void sendMessageNow (const MidiMessage& message);
387 
389  void sendBlockOfMessagesNow (const MidiBuffer& buffer);
390 
408  void sendBlockOfMessages (const MidiBuffer& buffer,
409  double millisecondCounterToStartAt,
410  double samplesPerSecondForBuffer);
411 
413  void clearAllPendingMessages();
414 
418  void startBackgroundThread();
419 
423  void stopBackgroundThread();
424 
428  bool isBackgroundThreadRunning() const noexcept { return isThreadRunning(); }
429 
430  //==============================================================================
431  #ifndef DOXYGEN
432  [[deprecated ("Use getAvailableDevices instead.")]]
433  static StringArray getDevices();
434  [[deprecated ("Use getDefaultDevice instead.")]]
435  static int getDefaultDeviceIndex();
436  [[deprecated ("Use openDevice that takes a device identifier instead.")]]
437  static std::unique_ptr<MidiOutput> openDevice (int);
438  #endif
439 
441  class Pimpl;
442 
443 private:
444  //==============================================================================
445  struct PendingMessage
446  {
447  PendingMessage (const void* data, int len, double timeStamp)
448  : message (data, len, timeStamp)
449  {
450  }
451 
452  MidiMessage message;
453  PendingMessage* next;
454  };
455 
456  //==============================================================================
457  explicit MidiOutput (const String&, const String&);
458  void run() override;
459 
460  MidiDeviceInfo deviceInfo;
461 
462  std::unique_ptr<Pimpl> internal;
463 
464  CriticalSection lock;
465  PendingMessage* firstMessage = nullptr;
466 
467  JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiOutput)
468 };
469 
470 } // namespace juce
static MidiDeviceListConnection make(std::function< void()>)
virtual ~MidiInputCallback()=default
virtual void handleIncomingMidiMessage(MidiInput *source, const MidiMessage &message)=0
void setName(const String &newName) noexcept
static std::unique_ptr< MidiInput > openDevice(const String &deviceIdentifier, MidiInputCallback *callback)
String getName() const noexcept
MidiDeviceInfo getDeviceInfo() const noexcept
static MidiDeviceInfo getDefaultDevice()
static Array< MidiDeviceInfo > getAvailableDevices()
String getIdentifier() const noexcept
static MidiDeviceInfo getDefaultDevice()
static Array< MidiDeviceInfo > getAvailableDevices()
String getName() const noexcept
static std::unique_ptr< MidiOutput > openDevice(const String &deviceIdentifier)
void setName(const String &newName) noexcept
String getIdentifier() const noexcept
MidiDeviceInfo getDeviceInfo() const noexcept
bool isBackgroundThreadRunning() const noexcept
void sendMessageNow(const MidiMessage &message)
~MidiOutput() override