boo/lib/audiodev/AudioVoice.hpp

136 lines
4.2 KiB
C++
Raw Normal View History

2018-10-07 03:36:44 +00:00
#pragma once
2016-03-23 07:01:25 +00:00
#include <soxr.h>
#include <list>
#include <unordered_map>
#include "boo/audiodev/IAudioVoice.hpp"
#include "AudioMatrix.hpp"
#include "Common.hpp"
#include "AudioVoiceEngine.hpp"
2016-03-23 07:01:25 +00:00
2016-06-08 04:37:21 +00:00
struct AudioUnitVoiceEngine;
struct VSTVoiceEngine;
struct WAVOutVoiceEngine;
2016-06-08 04:37:21 +00:00
2018-12-08 05:17:51 +00:00
namespace boo {
class BaseAudioVoiceEngine;
struct AudioVoiceEngineMixInfo;
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;
protected:
2018-12-08 05:17:51 +00:00
/* Callback (audio source) */
IAudioVoiceCallback* m_cb;
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;
2018-12-08 05:17:51 +00:00
/* Running bool */
bool m_running = false;
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;
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);
2018-12-08 05:17:51 +00:00
/* Mid-pump update */
void _midUpdate();
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);
2018-12-08 05:17:51 +00:00
AudioVoice(BaseAudioVoiceEngine& root, IAudioVoiceCallback* cb, bool dynamicRate);
public:
2018-12-08 05:17:51 +00:00
static AudioVoice*& _getHeadPtr(BaseAudioVoiceEngine* head);
static std::unique_lock<std::recursive_mutex> _getHeadLock(BaseAudioVoiceEngine* head);
std::unique_lock<std::recursive_mutex> destructorLock();
~AudioVoice();
void resetSampleRate(double sampleRate);
void setPitchRatio(double ratio, bool slew);
void start();
void stop();
double getSampleRateIn() const { return m_sampleRateIn; }
double getSampleRateOut() const { return m_sampleRateOut; }
};
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);
}
2018-12-08 05:17:51 +00:00
class AudioVoiceMono : public AudioVoice {
std::unordered_map<IAudioSubmix*, AudioMatrixMono> m_sendMatrices;
bool m_silentOut = false;
void _resetSampleRate(double sampleRate);
2018-12-08 05:17:51 +00:00
static size_t SRCCallback(AudioVoiceMono* ctx, int16_t** data, size_t requestedLen);
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);
size_t pumpAndMix16(size_t frames) { return _pumpAndMix<int16_t>(frames); }
size_t pumpAndMix32(size_t frames) { return _pumpAndMix<int32_t>(frames); }
size_t pumpAndMixFlt(size_t frames) { return _pumpAndMix<float>(frames); }
public:
2018-12-08 05:17:51 +00:00
AudioVoiceMono(BaseAudioVoiceEngine& root, IAudioVoiceCallback* cb, double sampleRate, bool dynamicRate);
void resetChannelLevels();
void setMonoChannelLevels(IAudioSubmix* submix, const float coefs[8], bool slew);
void setStereoChannelLevels(IAudioSubmix* submix, const float coefs[8][2], bool slew);
};
2018-12-08 05:17:51 +00:00
class AudioVoiceStereo : public AudioVoice {
std::unordered_map<IAudioSubmix*, AudioMatrixStereo> m_sendMatrices;
bool m_silentOut = false;
void _resetSampleRate(double sampleRate);
2018-12-08 05:17:51 +00:00
static size_t SRCCallback(AudioVoiceStereo* ctx, int16_t** data, size_t requestedLen);
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);
size_t pumpAndMix16(size_t frames) { return _pumpAndMix<int16_t>(frames); }
size_t pumpAndMix32(size_t frames) { return _pumpAndMix<int32_t>(frames); }
size_t pumpAndMixFlt(size_t frames) { return _pumpAndMix<float>(frames); }
public:
2018-12-08 05:17:51 +00:00
AudioVoiceStereo(BaseAudioVoiceEngine& root, IAudioVoiceCallback* cb, double sampleRate, bool dynamicRate);
void resetChannelLevels();
void setMonoChannelLevels(IAudioSubmix* submix, const float coefs[8], bool slew);
void setStereoChannelLevels(IAudioSubmix* submix, const float coefs[8][2], bool slew);
2016-03-23 07:01:25 +00:00
};
2018-12-08 05:17:51 +00:00
} // namespace boo