2016-03-24 00:01:57 +00:00
|
|
|
#ifndef BOO_AUDIOVOICEENGINE_HPP
|
|
|
|
#define BOO_AUDIOVOICEENGINE_HPP
|
|
|
|
|
|
|
|
#include "boo/audiodev/IAudioVoiceEngine.hpp"
|
|
|
|
#include "AudioVoice.hpp"
|
2016-05-07 04:28:32 +00:00
|
|
|
#include "AudioSubmix.hpp"
|
2016-05-19 10:14:21 +00:00
|
|
|
#include <functional>
|
2016-03-24 00:01:57 +00:00
|
|
|
|
|
|
|
namespace boo
|
|
|
|
{
|
|
|
|
|
|
|
|
/** Pertinent information from audio backend about optimal mixed-audio representation */
|
|
|
|
struct AudioVoiceEngineMixInfo
|
|
|
|
{
|
|
|
|
double m_sampleRate;
|
|
|
|
soxr_datatype_t m_sampleFormat;
|
|
|
|
unsigned m_bitsPerSample;
|
|
|
|
AudioChannelSet m_channels;
|
|
|
|
ChannelMap m_channelMap;
|
|
|
|
size_t m_periodFrames;
|
|
|
|
};
|
|
|
|
|
|
|
|
/** Base class for managing mixing and sample-rate-conversion amongst active voices */
|
2016-07-13 03:03:52 +00:00
|
|
|
class BaseAudioVoiceEngine : public IAudioVoiceEngine
|
2016-03-24 00:01:57 +00:00
|
|
|
{
|
|
|
|
protected:
|
|
|
|
friend class AudioVoice;
|
2016-05-07 04:28:32 +00:00
|
|
|
friend class AudioSubmix;
|
2016-05-07 22:11:45 +00:00
|
|
|
friend class AudioVoiceMono;
|
|
|
|
friend class AudioVoiceStereo;
|
2016-07-14 06:16:40 +00:00
|
|
|
float m_totalVol = 1.f;
|
2016-03-24 00:01:57 +00:00
|
|
|
AudioVoiceEngineMixInfo m_mixInfo;
|
|
|
|
std::list<AudioVoice*> m_activeVoices;
|
2016-05-07 04:28:32 +00:00
|
|
|
std::list<AudioSubmix*> m_activeSubmixes;
|
2016-05-19 10:14:21 +00:00
|
|
|
size_t m_5msFrames = 0;
|
|
|
|
std::function<void(double dt)> m_5msCallback;
|
2016-03-24 00:01:57 +00:00
|
|
|
|
2016-05-07 22:11:45 +00:00
|
|
|
/* Shared scratch buffers for accumulating audio data for resampling */
|
|
|
|
std::vector<int16_t> m_scratchIn;
|
2016-07-14 04:59:41 +00:00
|
|
|
std::vector<int16_t> m_scratch16Pre;
|
|
|
|
std::vector<int32_t> m_scratch32Pre;
|
|
|
|
std::vector<float> m_scratchFltPre;
|
|
|
|
std::vector<int16_t> m_scratch16Post;
|
|
|
|
std::vector<int32_t> m_scratch32Post;
|
|
|
|
std::vector<float> m_scratchFltPost;
|
2016-05-07 22:11:45 +00:00
|
|
|
|
2016-07-13 03:03:52 +00:00
|
|
|
AudioSubmix m_mainSubmix;
|
|
|
|
std::list<AudioSubmix*> m_linearizedSubmixes;
|
|
|
|
bool m_submixesDirty = true;
|
|
|
|
|
2016-03-24 00:01:57 +00:00
|
|
|
void _pumpAndMixVoices(size_t frames, int16_t* dataOut);
|
|
|
|
void _pumpAndMixVoices(size_t frames, int32_t* dataOut);
|
|
|
|
void _pumpAndMixVoices(size_t frames, float* dataOut);
|
|
|
|
|
2016-05-07 04:28:32 +00:00
|
|
|
void _unbindFrom(std::list<AudioVoice*>::iterator it);
|
|
|
|
void _unbindFrom(std::list<AudioSubmix*>::iterator it);
|
|
|
|
|
2016-03-24 00:01:57 +00:00
|
|
|
public:
|
2016-07-14 04:59:41 +00:00
|
|
|
BaseAudioVoiceEngine() : m_mainSubmix(*this, nullptr, -1, false) {}
|
2016-05-16 22:14:07 +00:00
|
|
|
~BaseAudioVoiceEngine();
|
2016-03-24 00:01:57 +00:00
|
|
|
std::unique_ptr<IAudioVoice> allocateNewMonoVoice(double sampleRate,
|
|
|
|
IAudioVoiceCallback* cb,
|
|
|
|
bool dynamicPitch=false);
|
|
|
|
|
|
|
|
std::unique_ptr<IAudioVoice> allocateNewStereoVoice(double sampleRate,
|
|
|
|
IAudioVoiceCallback* cb,
|
|
|
|
bool dynamicPitch=false);
|
|
|
|
|
2016-07-14 04:59:41 +00:00
|
|
|
std::unique_ptr<IAudioSubmix> allocateNewSubmix(bool mainOut, IAudioSubmixCallback* cb, int busId);
|
2016-05-07 04:28:32 +00:00
|
|
|
|
2016-05-19 10:14:21 +00:00
|
|
|
void register5MsCallback(std::function<void(double dt)>&& callback);
|
|
|
|
|
2016-07-14 06:16:40 +00:00
|
|
|
void setVolume(float vol);
|
2016-05-07 04:28:32 +00:00
|
|
|
const AudioVoiceEngineMixInfo& mixInfo() const;
|
2016-03-24 00:01:57 +00:00
|
|
|
AudioChannelSet getAvailableSet() {return m_mixInfo.m_channels;}
|
|
|
|
void pumpAndMixVoices() {}
|
2016-07-06 21:29:06 +00:00
|
|
|
size_t get5MsFrames() const {return m_5msFrames;}
|
2016-03-24 00:01:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // BOO_AUDIOVOICEENGINE_HPP
|