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 "AudioDevice.h"
37#include "LmmsTypes.h"
38#include "SampleFrame.h"
39#include "LocklessList.h"
40#include "FifoBuffer.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 _needs_fifo, 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
174
175 // methods providing information for other classes
177 {
178 return m_framesPerPeriod;
179 }
180
181
183 {
184 return m_profiler;
185 }
186
187 int cpuLoad() const
188 {
189 return m_profiler.cpuLoad();
190 }
191
193 {
194 return m_profiler.detailLoad(type);
195 }
196
198
199
201 {
202 return m_audioDev != nullptr ? m_audioDev->sampleRate() : m_baseSampleRate;
203 }
204
205
207 {
208 return m_audioDev != nullptr ? m_audioDev->sampleRate() : m_baseSampleRate;
209 }
210
211
212 inline float masterGain() const
213 {
214 return m_masterGain;
215 }
216
217 inline void setMasterGain(const float mo)
218 {
220 }
221
222
223 static inline sample_t clip(const sample_t s)
224 {
225 if (s > 1.0f)
226 {
227 return 1.0f;
228 }
229 else if (s < -1.0f)
230 {
231 return -1.0f;
232 }
233 return s;
234 }
235
236
237 bool criticalXRuns() const;
238
239 inline bool hasFifoWriter() const
240 {
241 return m_fifoWriter != nullptr;
242 }
243
244 void pushInputFrames( SampleFrame* _ab, const f_cnt_t _frames );
245
246 inline const SampleFrame* inputBuffer()
247 {
249 }
250
252 {
254 }
255
256 inline const SampleFrame* nextBuffer()
257 {
258 return hasFifoWriter() ? m_fifo->read() : renderNextBuffer();
259 }
260
262 void requestChangeInModel();
263 void doneChangeInModel();
264
269
270 static bool isAudioDevNameValid(QString name);
271 static bool isMidiDevNameValid(QString name);
272
273
274signals:
278
279
280private:
282
283 class fifoWriter : public QThread
284 {
285 public:
286 fifoWriter( AudioEngine * audioEngine, Fifo * fifo );
287
288 void finish();
289
290
291 private:
294 volatile bool m_writing;
295
296 void run() override;
297
298 void write(SampleFrame* buffer);
299 } ;
300
301
302 AudioEngine( bool renderOnly );
303 ~AudioEngine() override;
304
305 void startProcessing(bool needsFifo = true);
306 void stopProcessing();
307
308
311
314 void renderStageEffects();
315 void renderStageMix();
316
318
319 void swapBuffers();
320
321 void clearInternal();
322
324
325 std::vector<AudioBusHandle*> m_audioBusHandles;
326
328
335
336 std::unique_ptr<SampleFrame[]> m_outputBufferRead;
337 std::unique_ptr<SampleFrame[]> m_outputBufferWrite;
338
339 // worker thread stuff
340 std::vector<AudioEngineWorkerThread *> m_workers;
342
343 // playhandle stuff
345 // place where new playhandles are added temporarily
348
350
351 // audio device stuff
352 void doSetAudioDevice( AudioDevice *_dev );
357
358 // MIDI device stuff
361
362 // FIFO stuff
365
367
369
370 std::recursive_mutex m_changeMutex;
371
372 friend class Engine;
374 friend class ProjectRenderer;
375} ;
376
377} // namespace lmms
378
379#endif // LMMS_AUDIO_ENGINE_H
#define nullptr
Definition DistrhoDefines.h:75
CAdPlugDatabase::CRecord::RecordType type
Definition adplugdb.cpp:93
static void run(LV2_Handle instance, uint32_t n_samples)
Definition bindings_test_plugin.c:112
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:284
volatile bool m_writing
Definition AudioEngine.h:294
void write(SampleFrame *buffer)
void finish()
Definition AudioEngine.cpp:1067
Fifo * m_fifo
Definition AudioEngine.h:293
fifoWriter(AudioEngine *audioEngine, Fifo *fifo)
Definition AudioEngine.cpp:1056
AudioEngine * m_audioEngine
Definition AudioEngine.h:292
std::unique_ptr< SampleFrame[]> m_outputBufferRead
Definition AudioEngine.h:336
int m_inputBufferWrite
Definition AudioEngine.h:334
bool m_clearSignal
Definition AudioEngine.h:368
sample_rate_t m_baseSampleRate
Definition AudioEngine.h:332
Fifo * m_fifo
Definition AudioEngine.h:363
int m_inputBufferRead
Definition AudioEngine.h:333
LocklessList< PlayHandle * > m_newPlayHandles
Definition AudioEngine.h:346
QString m_midiClientName
Definition AudioEngine.h:360
std::vector< AudioEngineWorkerThread * > m_workers
Definition AudioEngine.h:340
bool audioDevStartFailed() const
Definition AudioEngine.h:123
int m_numWorkers
Definition AudioEngine.h:341
f_cnt_t inputBufferFrames() const
Definition AudioEngine.h:251
void clearNewPlayHandles()
Definition AudioEngine.cpp:439
bool renderOnly() const
Definition AudioEngine.h:116
friend class Engine
Definition AudioEngine.h:372
ConstPlayHandleList m_playHandlesToRemove
Definition AudioEngine.h:347
void sampleRateChanged()
f_cnt_t m_framesPerPeriod
Definition AudioEngine.h:327
void startProcessing(bool needsFifo=true)
Definition AudioEngine.cpp:207
void addAudioBusHandle(AudioBusHandle *busHandle)
Definition AudioEngine.h:140
PlayHandleList m_playHandles
Definition AudioEngine.h:344
AudioEngineProfiler & profiler()
Definition AudioEngine.h:182
MidiClient * midiClient()
Definition AudioEngine.h:156
void initDevices()
Definition AudioEngine.cpp:188
void renderStageNoteSetup()
Definition AudioEngine.cpp:281
sample_rate_t baseSampleRate() const
Definition AudioEngine.h:197
QString m_audioDevName
Definition AudioEngine.h:355
MidiClient * tryMidiClients()
Definition AudioEngine.cpp:934
std::unique_ptr< SampleFrame[]> m_outputBufferWrite
Definition AudioEngine.h:337
std::recursive_mutex m_changeMutex
Definition AudioEngine.h:370
int cpuLoad() const
Definition AudioEngine.h:187
bool m_audioDevStartFailed
Definition AudioEngine.h:356
float m_masterGain
Definition AudioEngine.h:349
void renderStageEffects()
Definition AudioEngine.cpp:344
const SampleFrame * renderNextBuffer()
Definition AudioEngine.cpp:400
void doneChangeInModel()
Definition AudioEngine.cpp:657
AudioEngine(bool renderOnly)
Definition AudioEngine.cpp:74
FifoBuffer< SampleFrame * > Fifo
Definition AudioEngine.h:281
void doSetAudioDevice(AudioDevice *_dev)
Definition AudioEngine.cpp:467
void renderStageInstruments()
Definition AudioEngine.cpp:334
float masterGain() const
Definition AudioEngine.h:212
bool m_renderOnly
Definition AudioEngine.h:323
void swapBuffers()
Definition AudioEngine.cpp:421
bool hasFifoWriter() const
Definition AudioEngine.h:239
void stopProcessing()
Definition AudioEngine.cpp:225
void renderStageMix()
Definition AudioEngine.cpp:381
void qualitySettingsChanged()
int detailLoad(const AudioEngineProfiler::DetailType type) const
Definition AudioEngine.h:192
AudioDevice * audioDev()
Definition AudioEngine.h:133
AudioDevice * m_oldAudioDev
Definition AudioEngine.h:354
void nextAudioBuffer(const lmms::SampleFrame *buffer)
std::vector< AudioBusHandle * > m_audioBusHandles
Definition AudioEngine.h:325
f_cnt_t framesPerPeriod() const
Definition AudioEngine.h:176
fifoWriter * m_fifoWriter
Definition AudioEngine.h:364
sample_rate_t inputSampleRate() const
Definition AudioEngine.h:206
const SampleFrame * nextBuffer()
Definition AudioEngine.h:256
void clearInternal()
Definition AudioEngine.cpp:455
AudioDevice * tryAudioDevices()
Definition AudioEngine.cpp:786
f_cnt_t m_inputBufferFrames[2]
Definition AudioEngine.h:330
static sample_t clip(const sample_t s)
Definition AudioEngine.h:223
void setMasterGain(const float mo)
Definition AudioEngine.h:217
AudioDevice * m_audioDev
Definition AudioEngine.h:353
MidiClient * m_midiClient
Definition AudioEngine.h:359
SampleFrame * m_inputBuffer[2]
Definition AudioEngine.h:329
PlayHandleList & playHandles()
Definition AudioEngine.h:167
void clear()
Definition AudioEngine.cpp:431
const QString & audioDevName() const
Definition AudioEngine.h:119
sample_rate_t outputSampleRate() const
Definition AudioEngine.h:200
void requestChangeInModel()
Block until a change in model can be done (i.e. wait for audio thread).
Definition AudioEngine.cpp:651
f_cnt_t m_inputBufferSize[2]
Definition AudioEngine.h:331
RequestChangesGuard requestChangesGuard()
Definition AudioEngine.h:265
const QString & midiClientName() const
Definition AudioEngine.h:151
AudioEngineProfiler m_profiler
Definition AudioEngine.h:366
const SampleFrame * inputBuffer()
Definition AudioEngine.h:246
friend class ProjectRenderer
Definition AudioEngine.h:374
friend class AudioEngineWorkerThread
Definition AudioEngine.h:373
Definition AudioEngineProfiler.h:39
DetailType
Definition AudioEngineProfiler.h:58
Definition AudioEngineWorkerThread.h:41
Definition FifoBuffer.h:37
Definition LocklessList.h:37
Definition MidiClient.h:46
Definition PlayHandle.h:47
Flags< Type > Types
Definition PlayHandle.h:56
Definition SampleFrame.h:41
Base-class for all tracks.
Definition Track.h:68
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