LMMS
Loading...
Searching...
No Matches
juce_MidiDevices.cpp
Go to the documentation of this file.
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
23namespace juce
24{
25
26MidiOutput::MidiOutput (const String& deviceName, const String& deviceIdentifier)
27 : Thread ("midi out"), deviceInfo (deviceName, deviceIdentifier)
28{
29}
30
32{
33 for (const auto metadata : buffer)
34 sendMessageNow (metadata.getMessage());
35}
36
38 double millisecondCounterToStartAt,
39 double samplesPerSecondForBuffer)
40{
41 // You've got to call startBackgroundThread() for this to actually work..
43
44 // this needs to be a value in the future - RTFM for this method!
45 jassert (millisecondCounterToStartAt > 0);
46
47 auto timeScaleFactor = 1000.0 / samplesPerSecondForBuffer;
48
49 for (const auto metadata : buffer)
50 {
51 auto eventTime = millisecondCounterToStartAt + timeScaleFactor * metadata.samplePosition;
52 auto* m = new PendingMessage (metadata.data, metadata.numBytes, eventTime);
53
54 const ScopedLock sl (lock);
55
56 if (firstMessage == nullptr || firstMessage->message.getTimeStamp() > eventTime)
57 {
58 m->next = firstMessage;
60 }
61 else
62 {
63 auto* mm = firstMessage;
64
65 while (mm->next != nullptr && mm->next->message.getTimeStamp() <= eventTime)
66 mm = mm->next;
67
68 m->next = mm->next;
69 mm->next = m;
70 }
71 }
72
73 notify();
74}
75
77{
78 const ScopedLock sl (lock);
79
80 while (firstMessage != nullptr)
81 {
82 auto* m = firstMessage;
84 delete m;
85 }
86}
87
92
97
99{
100 while (! threadShouldExit())
101 {
102 auto now = Time::getMillisecondCounter();
103 uint32 eventTime = 0;
104 uint32 timeToWait = 500;
105
107
108 {
109 const ScopedLock sl (lock);
111
112 if (message != nullptr)
113 {
114 eventTime = (uint32) roundToInt (message->message.getTimeStamp());
115
116 if (eventTime > now + 20)
117 {
118 timeToWait = eventTime - (now + 20);
119 message = nullptr;
120 }
121 else
122 {
123 firstMessage = message->next;
124 }
125 }
126 }
127
128 if (message != nullptr)
129 {
130 std::unique_ptr<PendingMessage> messageDeleter (message);
131
132 if (eventTime > now)
133 {
135
136 if (threadShouldExit())
137 break;
138 }
139
140 if (eventTime > now - 200)
141 sendMessageNow (message->message);
142 }
143 else
144 {
145 jassert (timeToWait < 1000 * 30);
146 wait ((int) timeToWait);
147 }
148 }
149
151}
152
153} // namespace juce
static void message(int level, const char *fmt,...)
Definition adplugdb.cpp:120
Definition juce_MidiBuffer.h:145
void sendBlockOfMessagesNow(const MidiBuffer &buffer)
Definition juce_MidiDevices.cpp:31
void stopBackgroundThread()
Definition juce_MidiDevices.cpp:93
void run() override
Definition juce_MidiDevices.cpp:98
CriticalSection lock
Definition juce_MidiDevices.h:385
PendingMessage * firstMessage
Definition juce_MidiDevices.h:386
void clearAllPendingMessages()
Definition juce_MidiDevices.cpp:76
void startBackgroundThread()
Definition juce_MidiDevices.cpp:88
MidiOutput(const String &, const String &)
Definition juce_MidiDevices.cpp:26
void sendMessageNow(const MidiMessage &message)
Definition juce_linux_Bela.cpp:591
void sendBlockOfMessages(const MidiBuffer &buffer, double millisecondCounterToStartAt, double samplesPerSecondForBuffer)
Definition juce_MidiDevices.cpp:37
MidiDeviceInfo deviceInfo
Definition juce_MidiDevices.h:381
Definition juce_String.h:53
void startThread()
Definition juce_Thread.cpp:122
bool wait(int timeOutMilliseconds) const
Definition juce_Thread.cpp:299
Thread(const String &threadName, size_t threadStackSize=0)
Definition juce_Thread.cpp:26
bool threadShouldExit() const
Definition juce_Thread.cpp:177
bool stopThread(int timeOutMilliseconds)
Definition juce_Thread.cpp:208
void notify() const
Definition juce_Thread.cpp:304
bool isThreadRunning() const
Definition juce_Thread.cpp:155
static void waitForMillisecondCounter(uint32 targetTime) noexcept
Definition juce_Time.cpp:267
static uint32 getMillisecondCounter() noexcept
Definition juce_Time.cpp:241
unsigned * m
Definition inflate.c:1559
#define jassert(expression)
Definition carla_juce.cpp:31
CriticalSection::ScopedLockType ScopedLock
Definition juce_CriticalSection.h:186
unsigned int uint32
Definition juce_MathsFunctions.h:45
int roundToInt(const FloatType value) noexcept
Definition juce_MathsFunctions.h:465
Definition juce_MidiDevices.h:367
mm
Definition zipinfo.c:2291