2018-10-07 03:36:44 +00:00
|
|
|
#pragma once
|
2016-03-23 07:01:25 +00:00
|
|
|
|
2019-08-17 17:39:39 +00:00
|
|
|
#include <mutex>
|
2016-07-13 03:03:52 +00:00
|
|
|
#include <unordered_map>
|
2019-08-19 23:08:54 +00:00
|
|
|
|
2016-03-24 00:01:57 +00:00
|
|
|
#include "boo/audiodev/IAudioVoice.hpp"
|
2019-08-19 23:08:54 +00:00
|
|
|
#include "lib/audiodev/AudioMatrix.hpp"
|
|
|
|
#include "lib/audiodev/AudioVoiceEngine.hpp"
|
|
|
|
#include "lib/audiodev/Common.hpp"
|
|
|
|
|
|
|
|
#include <soxr.h>
|
2016-03-23 07:01:25 +00:00
|
|
|
|
2016-06-08 04:37:21 +00:00
|
|
|
struct AudioUnitVoiceEngine;
|
2016-06-15 03:53:37 +00:00
|
|
|
struct VSTVoiceEngine;
|
2016-07-06 21:29:06 +00:00
|
|
|
struct WAVOutVoiceEngine;
|
2016-06-08 04:37:21 +00:00
|
|
|
|
2018-12-08 05:17:51 +00:00
|
|
|
namespace boo {
|
2016-03-24 00:01:57 +00:00
|
|
|
class BaseAudioVoiceEngine;
|
|
|
|
struct AudioVoiceEngineMixInfo;
|
2016-07-14 21:29:55 +00:00
|
|
|
struct IAudioSubmix;
|
2016-03-23 07:01:25 +00:00
|
|
|
|
2018-12-08 05:17:51 +00:00
|
|
|
class AudioVoice : public ListNode<AudioVoice, BaseAudioVoiceEngine*, IAudioVoice> {
|
|
|
|
friend class BaseAudioVoiceEngine;
|
|
|
|
friend class AudioSubmix;
|
|
|
|
friend struct WASAPIAudioVoiceEngine;
|
|
|
|
friend struct ::AudioUnitVoiceEngine;
|
|
|
|
friend struct ::VSTVoiceEngine;
|
|
|
|
friend struct ::WAVOutVoiceEngine;
|
2016-03-24 00:01:57 +00:00
|
|
|
|
|
|
|
protected:
|
2018-12-08 05:17:51 +00:00
|
|
|
/* Callback (audio source) */
|
|
|
|
IAudioVoiceCallback* m_cb;
|
2016-03-24 00:01:57 +00:00
|
|
|
|
2018-12-08 05:17:51 +00:00
|
|
|
/* Sample-rate converter */
|
|
|
|
soxr_t m_src = nullptr;
|
|
|
|
double m_sampleRateIn;
|
|
|
|
double m_sampleRateOut;
|
|
|
|
bool m_dynamicRate;
|
2016-03-24 00:01:57 +00:00
|
|
|
|
2018-12-08 05:17:51 +00:00
|
|
|
/* Running bool */
|
|
|
|
bool m_running = false;
|
2016-03-24 00:01:57 +00:00
|
|
|
|
2018-12-08 05:17:51 +00:00
|
|
|
/* Deferred sample-rate reset */
|
|
|
|
bool m_resetSampleRate = false;
|
|
|
|
double m_deferredSampleRate;
|
|
|
|
virtual void _resetSampleRate(double sampleRate) = 0;
|
2016-05-11 21:29:11 +00:00
|
|
|
|
2018-12-08 05:17:51 +00:00
|
|
|
/* Deferred pitch ratio set */
|
|
|
|
bool m_setPitchRatio = false;
|
|
|
|
double m_pitchRatio = 1.0;
|
|
|
|
double m_sampleRatio = 1.0;
|
|
|
|
bool m_slew = false;
|
|
|
|
void _setPitchRatio(double ratio, bool slew);
|
2016-05-11 21:29:11 +00:00
|
|
|
|
2018-12-08 05:17:51 +00:00
|
|
|
/* Mid-pump update */
|
|
|
|
void _midUpdate();
|
2016-05-11 21:29:11 +00:00
|
|
|
|
2018-12-08 05:17:51 +00:00
|
|
|
virtual size_t pumpAndMix16(size_t frames) = 0;
|
|
|
|
virtual size_t pumpAndMix32(size_t frames) = 0;
|
|
|
|
virtual size_t pumpAndMixFlt(size_t frames) = 0;
|
|
|
|
template <typename T>
|
|
|
|
size_t pumpAndMix(size_t frames);
|
2016-07-13 03:03:52 +00:00
|
|
|
|
2018-12-08 05:17:51 +00:00
|
|
|
AudioVoice(BaseAudioVoiceEngine& root, IAudioVoiceCallback* cb, bool dynamicRate);
|
2016-03-24 00:01:57 +00:00
|
|
|
|
|
|
|
public:
|
2018-12-08 05:17:51 +00:00
|
|
|
static AudioVoice*& _getHeadPtr(BaseAudioVoiceEngine* head);
|
|
|
|
static std::unique_lock<std::recursive_mutex> _getHeadLock(BaseAudioVoiceEngine* head);
|
|
|
|
|
2019-08-13 00:52:20 +00:00
|
|
|
~AudioVoice() override;
|
|
|
|
void resetSampleRate(double sampleRate) override;
|
|
|
|
void setPitchRatio(double ratio, bool slew) override;
|
|
|
|
void start() override;
|
|
|
|
void stop() override;
|
2018-12-08 05:17:51 +00:00
|
|
|
double getSampleRateIn() const { return m_sampleRateIn; }
|
|
|
|
double getSampleRateOut() const { return m_sampleRateOut; }
|
2016-03-24 00:01:57 +00:00
|
|
|
};
|
|
|
|
|
2018-12-08 05:17:51 +00:00
|
|
|
template <>
|
|
|
|
inline size_t AudioVoice::pumpAndMix<int16_t>(size_t frames) {
|
|
|
|
return pumpAndMix16(frames);
|
|
|
|
}
|
|
|
|
template <>
|
|
|
|
inline size_t AudioVoice::pumpAndMix<int32_t>(size_t frames) {
|
|
|
|
return pumpAndMix32(frames);
|
|
|
|
}
|
|
|
|
template <>
|
|
|
|
inline size_t AudioVoice::pumpAndMix<float>(size_t frames) {
|
|
|
|
return pumpAndMixFlt(frames);
|
|
|
|
}
|
2017-12-03 06:05:16 +00:00
|
|
|
|
2018-12-08 05:17:51 +00:00
|
|
|
class AudioVoiceMono : public AudioVoice {
|
|
|
|
std::unordered_map<IAudioSubmix*, AudioMatrixMono> m_sendMatrices;
|
|
|
|
bool m_silentOut = false;
|
2019-08-13 00:52:20 +00:00
|
|
|
void _resetSampleRate(double sampleRate) override;
|
2016-03-24 00:01:57 +00:00
|
|
|
|
2018-12-08 05:17:51 +00:00
|
|
|
static size_t SRCCallback(AudioVoiceMono* ctx, int16_t** data, size_t requestedLen);
|
2016-03-24 00:01:57 +00:00
|
|
|
|
2018-12-08 05:17:51 +00:00
|
|
|
bool isSilent() const;
|
2017-11-28 04:09:23 +00:00
|
|
|
|
2018-12-08 05:17:51 +00:00
|
|
|
template <typename T>
|
|
|
|
size_t _pumpAndMix(size_t frames);
|
2019-08-13 00:52:20 +00:00
|
|
|
size_t pumpAndMix16(size_t frames) override { return _pumpAndMix<int16_t>(frames); }
|
|
|
|
size_t pumpAndMix32(size_t frames) override { return _pumpAndMix<int32_t>(frames); }
|
|
|
|
size_t pumpAndMixFlt(size_t frames) override { return _pumpAndMix<float>(frames); }
|
2016-03-24 00:01:57 +00:00
|
|
|
|
|
|
|
public:
|
2018-12-08 05:17:51 +00:00
|
|
|
AudioVoiceMono(BaseAudioVoiceEngine& root, IAudioVoiceCallback* cb, double sampleRate, bool dynamicRate);
|
2019-08-13 00:52:20 +00:00
|
|
|
void resetChannelLevels() override;
|
|
|
|
void setMonoChannelLevels(IAudioSubmix* submix, const float coefs[8], bool slew) override;
|
|
|
|
void setStereoChannelLevels(IAudioSubmix* submix, const float coefs[8][2], bool slew) override;
|
2016-03-24 00:01:57 +00:00
|
|
|
};
|
|
|
|
|
2018-12-08 05:17:51 +00:00
|
|
|
class AudioVoiceStereo : public AudioVoice {
|
|
|
|
std::unordered_map<IAudioSubmix*, AudioMatrixStereo> m_sendMatrices;
|
|
|
|
bool m_silentOut = false;
|
2019-08-13 00:52:20 +00:00
|
|
|
void _resetSampleRate(double sampleRate) override;
|
2016-03-24 00:01:57 +00:00
|
|
|
|
2018-12-08 05:17:51 +00:00
|
|
|
static size_t SRCCallback(AudioVoiceStereo* ctx, int16_t** data, size_t requestedLen);
|
2016-03-24 00:01:57 +00:00
|
|
|
|
2018-12-08 05:17:51 +00:00
|
|
|
bool isSilent() const;
|
2017-11-28 04:09:23 +00:00
|
|
|
|
2018-12-08 05:17:51 +00:00
|
|
|
template <typename T>
|
|
|
|
size_t _pumpAndMix(size_t frames);
|
2019-08-13 00:52:20 +00:00
|
|
|
size_t pumpAndMix16(size_t frames) override { return _pumpAndMix<int16_t>(frames); }
|
|
|
|
size_t pumpAndMix32(size_t frames) override { return _pumpAndMix<int32_t>(frames); }
|
|
|
|
size_t pumpAndMixFlt(size_t frames) override { return _pumpAndMix<float>(frames); }
|
2016-03-24 00:01:57 +00:00
|
|
|
|
|
|
|
public:
|
2018-12-08 05:17:51 +00:00
|
|
|
AudioVoiceStereo(BaseAudioVoiceEngine& root, IAudioVoiceCallback* cb, double sampleRate, bool dynamicRate);
|
2019-08-13 00:52:20 +00:00
|
|
|
void resetChannelLevels() override;
|
|
|
|
void setMonoChannelLevels(IAudioSubmix* submix, const float coefs[8], bool slew) override;
|
|
|
|
void setStereoChannelLevels(IAudioSubmix* submix, const float coefs[8][2], bool slew) override;
|
2016-03-23 07:01:25 +00:00
|
|
|
};
|
|
|
|
|
2018-12-08 05:17:51 +00:00
|
|
|
} // namespace boo
|