tracktion-engine 3.0-10-g034fdde4aa5
Tracktion Engine — High level data model for audio applications

« « « Anklang Documentation
Loading...
Searching...
No Matches
tracktion_DeviceManager.h
Go to the documentation of this file.
1 /*
2 ,--. ,--. ,--. ,--.
3 ,-' '-.,--.--.,--,--.,---.| |,-.,-' '-.`--' ,---. ,--,--, Copyright 2024
4 '-. .-'| .--' ,-. | .--'| /'-. .-',--.| .-. || \ Tracktion Software
5 | | | | \ '-' \ `--.| \ \ | | | |' '-' '| || | Corporation
6 `---' `--' `--`--'`---'`--'`--' `---' `--' `---' `--''--' www.tracktion.com
7
8 Tracktion Engine uses a GPL/commercial licence - see LICENCE.md for details.
9*/
10
11namespace tracktion { inline namespace engine
12{
13
14class HostedAudioDeviceInterface;
15
16
17//==============================================================================
23 private juce::AsyncUpdater,
24 private juce::Timer
25{
26 friend class Engine;
28
29public:
30 //==============================================================================
31 ~DeviceManager() override;
32
33 void initialise (int defaultNumInputChannelsToOpen = 512,
34 int defaultNumOutputChannelsToOpen = 512);
35 void closeDevices();
36 void saveSettings();
37
38 void resetToDefaults (bool deviceSettings,
39 bool resetInputDevices,
40 bool resetOutputDevices,
41 bool latencySettings,
42 bool mixSettings);
43
44 void rescanMidiDeviceList();
45 void rescanWaveDeviceList();
46
47 int getMidiDeviceScanIntervalSeconds() const { return midiRescanIntervalSeconds; }
48 void setMidiDeviceScanIntervalSeconds (int intervalSeconds);
49
50 //==============================================================================
51 double getSampleRate() const;
52 int getBitDepth() const;
53 int getBlockSize() const;
54 TimeDuration getBlockLength() const;
55 double getBlockSizeMs() const;
56 double getOutputLatencySeconds() const;
57
58 // get a time by which recordings should be shifted to sync up with active output channels
59 double getRecordAdjustmentMs();
60 int getRecordAdjustmentSamples();
61
62 //==============================================================================
63 float getCpuUsage() const noexcept { return (float) currentCpuUsage; }
64
65 // Sets an upper limit on the proportion of CPU time being used - if getCpuUsage() exceeds this,
66 // the processing will be muted to keep the system running. Defaults to 0.98
67 void setCpuLimitBeforeMuting (double newLimit) { jassert (newLimit > 0); cpuLimitBeforeMuting = newLimit; }
68
69 PerformanceMeasurement::Statistics getCPUStatistics() const;
70 void restCPUStatistics();
71
72 void updateNumCPUs(); // should be called when active num CPUs is changed
73
74 //==============================================================================
76 void enableOutputClipping (bool clipOutput);
77
81 bool hasOutputClipped (bool reset);
82
83
84 //==============================================================================
90
93
99
100 //==============================================================================
101 // list of all input devices..
102 int getNumInputDevices() const;
103 InputDevice* getInputDevice (int index) const;
104
105 int getNumOutputDevices() const;
106 OutputDevice* getOutputDeviceAt (int index) const;
107
108 InputDevice* findInputDeviceForID (const juce::String& id) const;
109 InputDevice* findInputDeviceWithName (const juce::String& name) const;
110 std::shared_ptr<MidiInputDevice> findMidiInputDeviceForID (const juce::String& id) const;
111
112 OutputDevice* findOutputDeviceForID (const juce::String& id) const;
113 OutputDevice* findOutputDeviceWithName (const juce::String& name) const;
114
115 //==============================================================================
116 int getNumWaveOutDevices() const { return waveOutputs.size(); }
117 WaveOutputDevice* getWaveOutDevice (int index) const { return waveOutputs[index]; }
118
119 void setDefaultWaveOutDevice (juce::String deviceID);
120 WaveOutputDevice* getDefaultWaveOutDevice() const;
121 juce::String getDefaultWaveOutDeviceID() const { return defaultWaveOutID; }
122
123 int getNumWaveInDevices() const { return waveInputs.size(); }
124 WaveInputDevice* getWaveInDevice (int index) const { return waveInputs[index]; }
125
126 void setDefaultWaveInDevice (juce::String deviceID);
127 WaveInputDevice* getDefaultWaveInDevice() const;
128 juce::String getDefaultWaveInDeviceID() const { return defaultWaveInID; }
129
130 void setWaveOutChannelsEnabled (const std::vector<ChannelIndex>&, bool);
131 void setDeviceOutChannelStereo (int channelNum, bool isStereoPair);
132 bool isDeviceOutChannelStereo (int chan) const { return ! outMonoChans[chan / 2]; }
133 bool isDeviceOutEnabled (int chanNum) { return outEnabled[chanNum]; }
134
135 void setWaveInChannelsEnabled (const std::vector<ChannelIndex>&, bool);
136 void setDeviceInChannelStereo (int channelNum, bool isStereoPair);
137 bool isDeviceInChannelStereo (int chan) const { return inStereoChans[chan / 2]; }
138 bool isDeviceInEnabled (int chanNum) { return inEnabled[chanNum]; }
139
140 //==============================================================================
141 int getNumMidiOutDevices() const { return (int) midiOutputs.size(); }
142 MidiOutputDevice* getMidiOutDevice (int index) const { return index >= 0 && index < (int) midiOutputs.size() ? midiOutputs[(size_t) index].get() : nullptr; }
143
144 void setDefaultMidiOutDevice (juce::String deviceID);
145 MidiOutputDevice* getDefaultMidiOutDevice() const;
146 juce::String getDefaultMidiOutDeviceID() const { return defaultMidiOutID; }
147
148 int getNumMidiInDevices() const;
149 std::shared_ptr<MidiInputDevice> getMidiInDevice (int index) const;
150
151 std::vector<std::shared_ptr<MidiInputDevice>> getMidiInDevices() const;
152
153 void setDefaultMidiInDevice (juce::String deviceID);
154 MidiInputDevice* getDefaultMidiInDevice() const;
155 juce::String getDefaultMidiInDeviceID() const { return defaultMidiInID; }
156
157 void injectMIDIMessageToDefaultDevice (const juce::MidiMessage&);
158 void broadcastMessageToAllVirtualDevices (MidiInputDevice&, const juce::MidiMessage&);
159
160 void broadcastStreamTimeToMidiDevices (double streamTime);
161 bool shouldSendMidiTimecode() const noexcept { return sendMidiTimecode; }
162
166 double getCurrentStreamTime() const noexcept { return streamTime; }
167
168 bool isMSWavetableSynthPresent() const;
169
172
173 //==============================================================================
174 void checkDefaultDevicesAreValid();
175
176 static juce::String getDefaultAudioOutDeviceName (bool translated);
177 static juce::String getDefaultMidiOutDeviceName (bool translated);
178
179 static juce::String getDefaultAudioInDeviceName (bool translated);
180 static juce::String getDefaultMidiInDeviceName (bool translated);
181
182 juce::Result createVirtualMidiDevice (const juce::String& name);
183 void deleteVirtualMidiDevice (VirtualMidiInputDevice&);
184
185 Engine& engine;
186
187 //==============================================================================
194 {
196 void createAudioDeviceTypes (juce::OwnedArray<juce::AudioIODeviceType>&) override;
197
198 Engine& engine;
199 };
200
201 TracktionEngineAudioDeviceManager deviceManager { engine };
202
203 //==============================================================================
204 std::unique_ptr<HostedAudioDeviceInterface> hostedAudioDeviceInterface;
205
206 std::vector<std::shared_ptr<MidiInputDevice>> midiInputs; // Only thread-safe from the message thread
208
211
212 //==============================================================================
213 void addContext (EditPlaybackContext*);
214 void removeContext (EditPlaybackContext*);
215
216 //==============================================================================
222
224 juce::AudioProcessor* getGlobalOutputAudioProcessor() const { return globalOutputAudioProcessor.get(); }
225
230
231
232private:
233 //==============================================================================
234 bool finishedInitialising = false;
235 bool sendMidiTimecode = false;
236
237 std::atomic<double> currentCpuUsage { 0 }, streamTime { 0 }, cpuLimitBeforeMuting { 0.98 };
238 std::atomic<bool> isSuspended { true }, outputHasClipped { false }, outputClippingEnabled { false };
239 double currentLatencyMs = 0, outputLatencyTime = 0, currentSampleRate = 0;
240 int maxBlockSize = 0;
241
242 int defaultNumInputChannelsToOpen = 512, defaultNumOutputChannelsToOpen = 512;
243 juce::BigInteger outEnabled, inEnabled, activeOutChannels, outMonoChans, inStereoChans;
244 juce::String defaultWaveOutID, defaultMidiOutID, defaultWaveInID, defaultMidiInID;
245
246 int midiRescanIntervalSeconds = 4;
247 bool onlyRescanMidiOnHardwareChange = true;
248
249 struct MIDIDeviceList;
250 std::unique_ptr<MIDIDeviceList> lastMIDIDeviceList;
251
252 struct AvailableWaveDeviceList;
253 std::unique_ptr<AvailableWaveDeviceList> lastAvailableWaveDeviceList;
254
255 struct PrepareToStartCaller;
256 std::unique_ptr<PrepareToStartCaller> prepareToStartCaller;
257
258 std::shared_mutex contextLock;
260 std::unique_ptr<juce::AudioProcessor> globalOutputAudioProcessor;
261 juce::HeapBlock<const float*> inputChannelsScratch;
262 juce::HeapBlock<float*> outputChannelsScratch;
263
264 mutable std::shared_mutex midiInputsMutex;
265
266 #if JUCE_ANDROID
267 ScopedSteadyLoad::Context steadyLoadContext;
268 #endif
269
270 PerformanceMeasurement performanceMeasurement { "tracktion_engine::DeviceManager", -1, false };
271 crill::seqlock_object<PerformanceMeasurement::Statistics> performanceStats;
272 std::atomic<bool> clearStatsFlag { false };
273
274 void applyNewMidiDeviceList();
275 void restartMidiCheckTimer();
276
277 void clearAllContextDevices();
278 void reloadAllContextDevices();
279
280 void loadSettings();
281 void sanityCheckEnabledChannels();
282
283 bool usesHardwareMidiDevices();
284 void timerCallback() override;
285
286 void handleAsyncUpdate() override;
287 void changeListenerCallback (juce::ChangeBroadcaster*) override;
288
289 void audioDeviceIOCallbackWithContext (const float* const* inputChannelData, int totalNumInputChannels,
290 float* const* outputChannelData, int totalNumOutputChannels, int numSamples,
291 const juce::AudioIODeviceCallbackContext&) override;
292 void audioDeviceAboutToStart (juce::AudioIODevice*) override;
293 void audioDeviceStopped() override;
294 void prepareToStart();
295
296 void audioDeviceIOCallbackInternal (const float* const* inputChannelData, int numInputChannels,
297 float* const* outputChannelData, int totalNumOutputChannels,
298 int numSamples);
299
301};
302
303}} // namespace tracktion { inline namespace engine
void handleUpdateNowIfNeeded()
void enableOutputClipping(bool clipOutput)
If set to true, clips the output at 0.0.
bool hasOutputClipped(bool reset)
Checks if the output has clipped.
void removeHostedAudioDeviceInterface()
Removes the hosted audio device.
void dispatchPendingUpdates()
Changes to the devices get applied asyncronously so this function can be called to trigger any pendin...
bool isHostedAudioDeviceInterfaceInUse() const
Returns true if the hosted interface is available and in use.
double getCurrentStreamTime() const noexcept
Returns the current block's stream time.
void setGlobalOutputAudioProcessor(std::unique_ptr< juce::AudioProcessor >)
Sets a global processor to be applied to the output.
juce::AudioProcessor * getGlobalOutputAudioProcessor() const
Returns a previously set globalOutputAudioProcessor.
std::function< void(InputDevice *)> warnOfWastedMidiMessagesFunction
If this is set, it will get called (possibly on the midi thread) when incoming messages seem to be un...
HostedAudioDeviceInterface & getHostedAudioDeviceInterface()
If you are using the engine in a plugin or an application that accesses the audio device directly,...
The Engine is the central class for all tracktion sessions.
The HostedAudioDeviceInterface allows an application or plugin to pass audio and midi buffers to the ...
Represents an input device.
Base class for audio or midi output devices, to which a track's output can be sent.
A (virtual) audio input device.
A (virtual) audio output device.
T get(T... args)
#define jassert(expression)
#define JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(className)
typedef int
Represents a duration in real-life time.
Subclass of an AudioDeviceManager which can be used to avoid adding the system audio devices in plugi...
typedef size_t