LMMS
Loading...
Searching...
No Matches
AudioEngine.h
Go to the documentation of this file.
1/*
2 * AudioEngine.h - device-independent audio engine for LMMS
3 *
4 * Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
5 *
6 * This file is part of LMMS - https://lmms.io
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program (see COPYING); if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301 USA.
22 *
23 */
24
25#ifndef LMMS_AUDIO_ENGINE_H
26#define LMMS_AUDIO_ENGINE_H
27
28#include <mutex>
29
30#include <QThread>
31#include <samplerate.h>
32
33#include <memory>
34#include <vector>
35
36#include "AudioBufferView.h"
37#include "AudioDevice.h"
38#include "LmmsTypes.h"
39#include "SampleFrame.h"
40#include "LocklessList.h"
41#include "AudioEngineProfiler.h"
42#include "PlayHandle.h"
43
44
45namespace lmms
46{
47
48class MidiClient;
49class AudioBusHandle; // IWYU pragma: keep
51
55
56constexpr int BYTES_PER_SAMPLE = sizeof(sample_t);
57constexpr int BYTES_PER_INT_SAMPLE = sizeof(int_sample_t);
58constexpr int BYTES_PER_FRAME = sizeof(SampleFrame);
59
60constexpr float OUTPUT_SAMPLE_MULTIPLIER = 32767.0f;
61
62constexpr auto SUPPORTED_SAMPLERATES = std::array{44100, 48000, 88200, 96000, 192000};
63constexpr auto SUPPORTED_BITRATES = std::array{64, 128, 160, 192, 256, 320};
64
65class LMMS_EXPORT AudioEngine : public QObject
66{
67 Q_OBJECT
68public:
74 friend class AudioEngine;
75
76 private:
78 : m_audioEngine{audioEngine}
79 {
80 m_audioEngine->requestChangeInModel();
81 }
82 public:
83
88
91 {
92 std::swap(other.m_audioEngine, m_audioEngine);
93 }
94
95 // Disallow copy.
98
100 if (m_audioEngine) {
101 m_audioEngine->doneChangeInModel();
102 }
103 }
104
105 private:
107 };
108
109 void initDevices();
110 void clear();
111 void clearNewPlayHandles();
112
113
114 // audio-device-stuff
115
116 bool renderOnly() const { return m_renderOnly; }
117 // Returns the current audio device's name. This is not necessarily
118 // the user's preferred audio device, in case you were thinking that.
119 inline const QString & audioDevName() const
120 {
121 return m_audioDevName;
122 }
123 inline bool audioDevStartFailed() const
124 {
126 }
127
130 void setAudioDevice(AudioDevice* _dev, bool startNow);
131 void storeAudioDevice();
132 void restoreAudioDevice();
134 {
135 return m_audioDev;
136 }
137
138
139 // audio-bus-handle-stuff
140 inline void addAudioBusHandle(AudioBusHandle* busHandle)
141 {
143 m_audioBusHandles.push_back(busHandle);
145 }
146
147 void removeAudioBusHandle(AudioBusHandle* busHandle);
148
149
150 // MIDI-client-stuff
151 inline const QString & midiClientName() const
152 {
153 return m_midiClientName;
154 }
155
157 {
158 return m_midiClient;
159 }
160
161
162 // play-handle stuff
163 bool addPlayHandle( PlayHandle* handle );
164
165 void removePlayHandle( PlayHandle* handle );
166
168 {
169 return m_playHandles;
170 }
171
172 void removePlayHandlesOfTypes(Track * track, PlayHandle::Types types);
173
175 {
176 return m_profiler;
177 }
178
179 int cpuLoad() const
180 {
181 return m_profiler.cpuLoad();
182 }
183
185 {
186 return m_profiler.detailLoad(type);
187 }
188
190
191
193 {
194 return m_audioDev != nullptr ? m_audioDev->sampleRate() : m_baseSampleRate;
195 }
196
197
199 {
200 return m_audioDev != nullptr ? m_audioDev->sampleRate() : m_baseSampleRate;
201 }
202
203
204 inline float masterGain() const
205 {
206 return m_masterGain;
207 }
208
209 inline void setMasterGain(const float mo)
210 {
212 }
213
214
215 static inline sample_t clip(const sample_t s)
216 {
217 if (s > 1.0f)
218 {
219 return 1.0f;
220 }
221 else if (s < -1.0f)
222 {
223 return -1.0f;
224 }
225 return s;
226 }
227
228
229 bool criticalXRuns() const;
230
231 void pushInputFrames( SampleFrame* _ab, const f_cnt_t _frames );
232
233 inline const SampleFrame* inputBuffer()
234 {
236 }
237
239 {
241 }
242
249
257
272 std::span<const SampleFrame> renderNextPeriod();
273
288
291
293 void requestChangeInModel();
294 void doneChangeInModel();
295
300
301 static bool isAudioDevNameValid(QString name);
302 static bool isMidiDevNameValid(QString name);
303
304
305signals:
309
310
311private:
313 {
314 for (auto frame = f_cnt_t{0}; frame < dst.frames(); ++frame)
315 {
318
319 switch (dst.channels())
320 {
321 case 0:
322 assert(false);
323 break;
324 case 1:
325 dst.sample(0, frame) = m_outputBufferRead[m_outputBufferReadIndex].average();
326 break;
327 case 2:
328 dst.sample(0, frame) = m_outputBufferRead[m_outputBufferReadIndex][0];
329 dst.sample(1, frame) = m_outputBufferRead[m_outputBufferReadIndex][1];
330 break;
331 default:
332 dst.sample(0, frame) = m_outputBufferRead[m_outputBufferReadIndex][0];
333 dst.sample(1, frame) = m_outputBufferRead[m_outputBufferReadIndex][1];
334 for (auto channel = 2; channel < dst.channels(); ++channel)
335 {
336 dst.sample(channel, frame) = 0.f;
337 }
338 break;
339 }
340
342 }
343 }
344
345 AudioEngine( bool renderOnly );
346 ~AudioEngine() override;
347
348 void startProcessing() { m_audioDev->startProcessing(); }
349 void stopProcessing() { m_audioDev->stopProcessing(); }
350
351
352 AudioDevice * tryAudioDevices();
353 MidiClient * tryMidiClients();
354
355 void renderStageNoteSetup();
356 void renderStageInstruments();
357 void renderStageEffects();
358 void renderStageMix();
359
360
361 void swapBuffers();
362
363 void clearInternal();
364
366
367 std::vector<AudioBusHandle*> m_audioBusHandles;
368
372
378
379 std::unique_ptr<SampleFrame[]> m_outputBufferRead;
380 std::unique_ptr<SampleFrame[]> m_outputBufferWrite;
382
383 // worker thread stuff
384 std::vector<AudioEngineWorkerThread *> m_workers;
386
387 // playhandle stuff
389 // place where new playhandles are added temporarily
392
394
395 // audio device stuff
396 void doSetAudioDevice( AudioDevice *_dev );
401
402 // MIDI device stuff
405
407
409
410 std::recursive_mutex m_changeMutex;
411
412 friend class Engine;
414 friend class ProjectRenderer;
415} ;
416
417} // namespace lmms
418
419#endif // LMMS_AUDIO_ENGINE_H
#define nullptr
Definition DistrhoDefines.h:75
assert(0)
CAdPlugDatabase::CRecord::RecordType type
Definition adplugdb.cpp:93
Job between PlayHandle and MixerChannel.
Definition AudioBusHandle.h:55
Definition AudioDevice.h:44
RAII helper for requestChangesInModel. Used by AudioEngine::requestChangesGuard.
Definition AudioEngine.h:73
friend class AudioEngine
Definition AudioEngine.h:74
RequestChangesGuard(const RequestChangesGuard &)=delete
RequestChangesGuard(RequestChangesGuard &&other)
Definition AudioEngine.h:89
~RequestChangesGuard()
Definition AudioEngine.h:99
RequestChangesGuard(AudioEngine *audioEngine)
Definition AudioEngine.h:77
RequestChangesGuard & operator=(const RequestChangesGuard &)=delete
RequestChangesGuard()
Definition AudioEngine.h:84
AudioEngine * m_audioEngine
Definition AudioEngine.h:106
Definition AudioEngine.h:66
std::unique_ptr< SampleFrame[]> m_outputBufferRead
Definition AudioEngine.h:379
int m_inputBufferWrite
Definition AudioEngine.h:377
bool m_clearSignal
Definition AudioEngine.h:408
sample_rate_t m_baseSampleRate
Definition AudioEngine.h:371
int m_inputBufferRead
Definition AudioEngine.h:376
LocklessList< PlayHandle * > m_newPlayHandles
Definition AudioEngine.h:390
QString m_midiClientName
Definition AudioEngine.h:404
std::vector< AudioEngineWorkerThread * > m_workers
Definition AudioEngine.h:384
bool audioDevStartFailed() const
Definition AudioEngine.h:123
int m_numWorkers
Definition AudioEngine.h:385
void renderNextBuffer(InterleavedBufferView< float > dst)
Renders an audio buffer into dst.
Definition AudioEngine.h:287
f_cnt_t inputBufferFrames() const
Definition AudioEngine.h:238
void clearNewPlayHandles()
Definition AudioEngine.cpp:356
bool renderOnly() const
Definition AudioEngine.h:116
friend class Engine
Definition AudioEngine.h:412
ConstPlayHandleList m_playHandlesToRemove
Definition AudioEngine.h:391
std::span< const SampleFrame > renderNextPeriod()
Renders the next audio period.
Definition AudioEngine.cpp:319
void sampleRateChanged()
void renderNextBuffer(AudioBufferView< float > auto dst)
Definition AudioEngine.h:312
f_cnt_t m_framesPerPeriod
Definition AudioEngine.h:370
void addAudioBusHandle(AudioBusHandle *busHandle)
Definition AudioEngine.h:140
PlayHandleList m_playHandles
Definition AudioEngine.h:388
AudioEngineProfiler & profiler()
Definition AudioEngine.h:174
MidiClient * midiClient()
Definition AudioEngine.h:156
void startProcessing()
Definition AudioEngine.h:348
void initDevices()
Definition AudioEngine.cpp:147
sample_rate_t baseSampleRate() const
Definition AudioEngine.h:189
QString m_audioDevName
Definition AudioEngine.h:399
std::unique_ptr< SampleFrame[]> m_outputBufferWrite
Definition AudioEngine.h:380
std::recursive_mutex m_changeMutex
Definition AudioEngine.h:410
int cpuLoad() const
Definition AudioEngine.h:179
bool m_audioDevStartFailed
Definition AudioEngine.h:400
float m_masterGain
Definition AudioEngine.h:393
void doneChangeInModel()
Definition AudioEngine.cpp:574
AudioEngine(bool renderOnly)
Definition AudioEngine.cpp:70
void doSetAudioDevice(AudioDevice *_dev)
Definition AudioEngine.cpp:384
float masterGain() const
Definition AudioEngine.h:204
bool m_renderOnly
Definition AudioEngine.h:365
void stopProcessing()
Definition AudioEngine.h:349
f_cnt_t m_outputBufferReadIndex
Definition AudioEngine.h:381
void qualitySettingsChanged()
int detailLoad(const AudioEngineProfiler::DetailType type) const
Definition AudioEngine.h:184
AudioDevice * audioDev()
Definition AudioEngine.h:133
AudioDevice * m_oldAudioDev
Definition AudioEngine.h:398
void nextAudioBuffer(const lmms::SampleFrame *buffer)
std::vector< AudioBusHandle * > m_audioBusHandles
Definition AudioEngine.h:367
f_cnt_t framesPerPeriod() const
Definition AudioEngine.h:248
sample_rate_t inputSampleRate() const
Definition AudioEngine.h:198
f_cnt_t m_inputBufferFrames[2]
Definition AudioEngine.h:374
void renderNextBuffer(PlanarBufferView< float > dst)
Renders an audio buffer into dst.
Definition AudioEngine.h:290
static sample_t clip(const sample_t s)
Definition AudioEngine.h:215
void setMasterGain(const float mo)
Definition AudioEngine.h:209
AudioDevice * m_audioDev
Definition AudioEngine.h:397
MidiClient * m_midiClient
Definition AudioEngine.h:403
SampleFrame * m_inputBuffer[2]
Definition AudioEngine.h:373
PlayHandleList & playHandles()
Definition AudioEngine.h:167
f_cnt_t framesPerAudioBuffer() const
Definition AudioEngine.h:256
void clear()
Definition AudioEngine.cpp:348
const QString & audioDevName() const
Definition AudioEngine.h:119
sample_rate_t outputSampleRate() const
Definition AudioEngine.h:192
void requestChangeInModel()
Block until a change in model can be done (i.e. wait for audio thread).
Definition AudioEngine.cpp:568
f_cnt_t m_framesPerAudioBuffer
Definition AudioEngine.h:369
f_cnt_t m_inputBufferSize[2]
Definition AudioEngine.h:375
RequestChangesGuard requestChangesGuard()
Definition AudioEngine.h:296
const QString & midiClientName() const
Definition AudioEngine.h:151
AudioEngineProfiler m_profiler
Definition AudioEngine.h:406
const SampleFrame * inputBuffer()
Definition AudioEngine.h:233
friend class ProjectRenderer
Definition AudioEngine.h:414
friend class AudioEngineWorkerThread
Definition AudioEngine.h:413
Definition AudioEngineProfiler.h:39
DetailType
Definition AudioEngineProfiler.h:58
Definition AudioEngineWorkerThread.h:41
Definition AudioBufferView.h:291
Definition LocklessList.h:37
Definition MidiClient.h:46
Definition AudioBufferView.h:481
Definition PlayHandle.h:47
Flags< Type > Types
Definition PlayHandle.h:56
Definition SampleFrame.h:41
Base-class for all tracks.
Definition Track.h:68
Concept for any audio buffer view, interleaved or planar.
Definition AudioBufferView.h:576
unsigned s
Definition inflate.c:1555
static const char * name
Definition pugl.h:1582
Definition AudioAlsa.cpp:35
constexpr int BYTES_PER_FRAME
Definition AudioEngine.h:58
QList< PlayHandle * > PlayHandleList
Definition PlayHandle.h:162
constexpr f_cnt_t MAXIMUM_BUFFER_SIZE
Definition AudioEngine.h:54
std::uint32_t sample_rate_t
Definition LmmsTypes.h:42
float sample_t
Definition LmmsTypes.h:39
constexpr auto SUPPORTED_SAMPLERATES
Definition AudioEngine.h:62
constexpr int BYTES_PER_SAMPLE
Definition AudioEngine.h:56
constexpr int BYTES_PER_INT_SAMPLE
Definition AudioEngine.h:57
std::int16_t int_sample_t
Definition LmmsTypes.h:40
constexpr f_cnt_t DEFAULT_BUFFER_SIZE
Definition AudioEngine.h:53
QList< const PlayHandle * > ConstPlayHandleList
Definition PlayHandle.h:163
std::uint64_t f_cnt_t
Definition LmmsTypes.h:43
constexpr auto SUPPORTED_BITRATES
Definition AudioEngine.h:63
constexpr float OUTPUT_SAMPLE_MULTIPLIER
Definition AudioEngine.h:60
constexpr f_cnt_t MINIMUM_BUFFER_SIZE
Definition AudioEngine.h:52
mo
Definition zipinfo.c:2287