Made 0.4.12 release
[lmms/mlankhorst.git] / include / mixer.h
blob40a8c33f0b28e1473059f4169898fac1a04eba17
1 /*
2 * mixer.h - audio-device-independent mixer for LMMS
4 * Copyright (c) 2004-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
6 * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
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.
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.
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.
25 #ifndef _MIXER_H
26 #define _MIXER_H
28 #include "lmmsconfig.h"
30 #ifndef LMMS_USE_3RDPARTY_LIBSRC
31 #include <samplerate.h>
32 #else
33 #ifndef OUT_OF_TREE_BUILD
34 #include "src/3rdparty/samplerate/samplerate.h"
35 #else
36 #include <samplerate.h>
37 #endif
38 #endif
41 #include <QtCore/QMutex>
42 #include <QtCore/QThread>
43 #include <QtCore/QVector>
44 #include <QtCore/QWaitCondition>
47 #include "lmms_basics.h"
48 #include "note.h"
49 #include "fifo_buffer.h"
52 class AudioDevice;
53 class MidiClient;
54 class AudioPort;
57 const fpp_t DEFAULT_BUFFER_SIZE = 256;
59 const int BYTES_PER_SAMPLE = sizeof( sample_t );
60 const int BYTES_PER_INT_SAMPLE = sizeof( int_sample_t );
61 const int BYTES_PER_FRAME = sizeof( sampleFrame );
62 const int BYTES_PER_SURROUND_FRAME = sizeof( surroundSampleFrame );
64 const float OUTPUT_SAMPLE_MULTIPLIER = 32767.0f;
67 const float BaseFreq = 440.0f;
68 const Keys BaseKey = Key_A;
69 const Octaves BaseOctave = DefaultOctave;
72 #include "play_handle.h"
75 class MixerWorkerThread;
78 class EXPORT mixer : public QObject
80 Q_OBJECT
81 public:
82 struct qualitySettings
84 enum Mode
86 Mode_Draft,
87 Mode_HighQuality,
88 Mode_FinalMix
89 } ;
91 enum Interpolation
93 Interpolation_Linear,
94 Interpolation_SincFastest,
95 Interpolation_SincMedium,
96 Interpolation_SincBest
97 } ;
99 enum Oversampling
101 Oversampling_None,
102 Oversampling_2x,
103 Oversampling_4x,
104 Oversampling_8x
107 Interpolation interpolation;
108 Oversampling oversampling;
109 bool sampleExactControllers;
110 bool aliasFreeOscillators;
112 qualitySettings( Mode _m )
114 switch( _m )
116 case Mode_Draft:
117 interpolation = Interpolation_Linear;
118 oversampling = Oversampling_None;
119 sampleExactControllers = false;
120 aliasFreeOscillators = false;
121 break;
122 case Mode_HighQuality:
123 interpolation =
124 Interpolation_SincFastest;
125 oversampling = Oversampling_2x;
126 sampleExactControllers = true;
127 aliasFreeOscillators = false;
128 break;
129 case Mode_FinalMix:
130 interpolation = Interpolation_SincBest;
131 oversampling = Oversampling_8x;
132 sampleExactControllers = true;
133 aliasFreeOscillators = true;
134 break;
138 qualitySettings( Interpolation _i, Oversampling _o, bool _sec,
139 bool _afo ) :
140 interpolation( _i ),
141 oversampling( _o ),
142 sampleExactControllers( _sec ),
143 aliasFreeOscillators( _afo )
147 int sampleRateMultiplier() const
149 switch( oversampling )
151 case Oversampling_None: return 1;
152 case Oversampling_2x: return 2;
153 case Oversampling_4x: return 4;
154 case Oversampling_8x: return 8;
156 return 1;
159 int libsrcInterpolation() const
161 switch( interpolation )
163 case Interpolation_Linear:
164 return SRC_ZERO_ORDER_HOLD;
165 case Interpolation_SincFastest:
166 return SRC_SINC_FASTEST;
167 case Interpolation_SincMedium:
168 return SRC_SINC_MEDIUM_QUALITY;
169 case Interpolation_SincBest:
170 return SRC_SINC_BEST_QUALITY;
172 return SRC_LINEAR;
176 void initDevices();
177 void clear();
180 // audio-device-stuff
181 inline const QString & audioDevName() const
183 return m_audioDevName;
186 void setAudioDevice( AudioDevice * _dev );
187 void setAudioDevice( AudioDevice * _dev,
188 const struct qualitySettings & _qs,
189 bool _needs_fifo );
190 void restoreAudioDevice();
191 inline AudioDevice * audioDev()
193 return m_audioDev;
197 // audio-port-stuff
198 inline void addAudioPort( AudioPort * _port )
200 lock();
201 m_audioPorts.push_back( _port );
202 unlock();
205 void removeAudioPort( AudioPort * _port );
208 // MIDI-client-stuff
209 inline const QString & midiClientName() const
211 return m_midiClientName;
214 inline MidiClient * midiClient()
216 return m_midiClient;
220 // play-handle stuff
221 inline bool addPlayHandle( playHandle * _ph )
223 if( criticalXRuns() == false )
225 lock();
226 m_playHandles.push_back( _ph );
227 unlock();
228 return true;
230 delete _ph;
231 return false;
234 void removePlayHandle( playHandle * _ph );
236 inline PlayHandleList & playHandles()
238 return m_playHandles;
241 void removePlayHandles( track * _track );
243 inline bool hasPlayHandles() const
245 return !m_playHandles.empty();
249 // methods providing information for other classes
250 inline fpp_t framesPerPeriod() const
252 return m_framesPerPeriod;
255 inline const surroundSampleFrame * currentReadBuffer() const
257 return m_readBuf;
261 inline int cpuLoad() const
263 return m_cpuLoad;
266 const qualitySettings & currentQualitySettings() const
268 return m_qualitySettings;
272 sample_rate_t baseSampleRate() const;
273 sample_rate_t outputSampleRate() const;
274 sample_rate_t inputSampleRate() const;
275 sample_rate_t processingSampleRate() const;
278 inline float masterGain() const
280 return m_masterGain;
283 inline void setMasterGain( const float _mo )
285 m_masterGain = _mo;
289 static inline sample_t clip( const sample_t _s )
291 if( _s > 1.0f )
293 return 1.0f;
295 else if( _s < -1.0f )
297 return -1.0f;
299 return _s;
303 // methods needed by other threads to alter knob values, waveforms, etc
304 void lock()
306 m_globalMutex.lock();
309 void unlock()
311 m_globalMutex.unlock();
314 void lockInputFrames()
316 m_inputFramesMutex.lock();
319 void unlockInputFrames()
321 m_inputFramesMutex.unlock();
324 // audio-buffer-mgm
325 void bufferToPort( const sampleFrame * _buf,
326 const fpp_t _frames,
327 const f_cnt_t _offset,
328 stereoVolumeVector _volume_vector,
329 AudioPort * _port );
331 static void clearAudioBuffer( sampleFrame * _ab,
332 const f_cnt_t _frames,
333 const f_cnt_t _offset = 0 );
334 #ifndef LMMS_DISABLE_SURROUND
335 static void clearAudioBuffer( surroundSampleFrame * _ab,
336 const f_cnt_t _frames,
337 const f_cnt_t _offset = 0 );
338 #endif
340 static float peakValueLeft( sampleFrame * _ab, const f_cnt_t _frames );
341 static float peakValueRight( sampleFrame * _ab, const f_cnt_t _frames );
344 bool criticalXRuns() const;
346 inline bool hasFifoWriter() const
348 return m_fifoWriter != NULL;
351 void pushInputFrames( sampleFrame * _ab, const f_cnt_t _frames );
353 inline const sampleFrame * inputBuffer()
355 return m_inputBuffer[ m_inputBufferRead ];
358 inline f_cnt_t inputBufferFrames() const
360 return m_inputBufferFrames[ m_inputBufferRead ];
363 inline const surroundSampleFrame * nextBuffer()
365 return hasFifoWriter() ? m_fifo->read() : renderNextBuffer();
368 void changeQuality( const struct qualitySettings & _qs );
371 signals:
372 void qualitySettingsChanged();
373 void sampleRateChanged();
374 void nextAudioBuffer();
377 private:
378 typedef fifoBuffer<surroundSampleFrame *> fifo;
380 class fifoWriter : public QThread
382 public:
383 fifoWriter( mixer * _mixer, fifo * _fifo );
385 void finish();
388 private:
389 mixer * m_mixer;
390 fifo * m_fifo;
391 volatile bool m_writing;
393 virtual void run();
398 mixer();
399 virtual ~mixer();
401 void startProcessing( bool _needs_fifo = true );
402 void stopProcessing();
405 AudioDevice * tryAudioDevices();
406 MidiClient * tryMidiClients();
409 const surroundSampleFrame * renderNextBuffer();
413 QVector<AudioPort *> m_audioPorts;
415 fpp_t m_framesPerPeriod;
417 sampleFrame * m_workingBuf;
419 sampleFrame * m_inputBuffer[2];
420 f_cnt_t m_inputBufferFrames[2];
421 f_cnt_t m_inputBufferSize[2];
422 int m_inputBufferRead;
423 int m_inputBufferWrite;
425 surroundSampleFrame * m_readBuf;
426 surroundSampleFrame * m_writeBuf;
428 QVector<surroundSampleFrame *> m_bufferPool;
429 int m_readBuffer;
430 int m_writeBuffer;
431 int m_poolDepth;
433 surroundSampleFrame m_maxClip;
434 surroundSampleFrame m_previousSample;
435 fpp_t m_halfStart[SURROUND_CHANNELS];
436 bool m_oldBuffer[SURROUND_CHANNELS];
437 bool m_newBuffer[SURROUND_CHANNELS];
439 int m_cpuLoad;
440 QVector<MixerWorkerThread *> m_workers;
441 int m_numWorkers;
442 QWaitCondition m_queueReadyWaitCond;
445 PlayHandleList m_playHandles;
446 ConstPlayHandleList m_playHandlesToRemove;
448 struct qualitySettings m_qualitySettings;
449 float m_masterGain;
452 AudioDevice * m_audioDev;
453 AudioDevice * m_oldAudioDev;
454 QString m_audioDevName;
457 MidiClient * m_midiClient;
458 QString m_midiClientName;
461 QMutex m_globalMutex;
462 QMutex m_inputFramesMutex;
465 fifo * m_fifo;
466 fifoWriter * m_fifoWriter;
469 friend class engine;
470 friend class MixerWorkerThread;
475 #endif