Allocate submixes and voices using boo::ObjToken

This commit is contained in:
Jack Andersen 2017-12-03 16:50:33 -10:00
parent 135f504899
commit 489e7e671b
15 changed files with 47 additions and 42 deletions

View File

@ -13,7 +13,7 @@ class IObj
protected:
virtual ~IObj() = default;
public:
virtual std::unique_lock<std::recursive_mutex> destructorLock() { return {}; }
virtual std::unique_lock<std::recursive_mutex> destructorLock()=0;
void increment() { m_refCount++; }
void decrement()
{

View File

@ -241,7 +241,7 @@ struct DeferredWindowEvents : public IWindowCallback
m_cmds.back().m_mods = mod;
}
ITextInputCallback* getTextInputCallback() {return m_rec.getTextInputCallback();}
ITextInputCallback* getTextInputCallback() { return m_rec.getTextInputCallback(); }
void dispatchEvents()
{

View File

@ -27,7 +27,7 @@ class IApplication
friend class WindowWin32;
virtual void _deletedWindow(IWindow* window)=0;
public:
virtual ~IApplication() {}
virtual ~IApplication() = default;
enum class EPlatformType
{

View File

@ -4,6 +4,7 @@
#include <stddef.h>
#include <stdint.h>
#include <memory>
#include "boo/BooObject.hpp"
namespace boo
{
@ -19,10 +20,8 @@ enum class SubmixFormat
Float
};
struct IAudioSubmix
struct IAudioSubmix : IObj
{
virtual ~IAudioSubmix() = default;
/** Reset channel-levels to silence; unbind all submixes */
virtual void resetSendLevels()=0;

View File

@ -4,6 +4,7 @@
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "boo/BooObject.hpp"
namespace boo
{
@ -54,10 +55,8 @@ static inline unsigned ChannelCount(AudioChannelSet layout)
return 0;
}
struct IAudioVoice
struct IAudioVoice : IObj
{
virtual ~IAudioVoice() = default;
/** Set sample rate into voice (may result in audio discontinuities) */
virtual void resetSampleRate(double sampleRate)=0;

View File

@ -4,6 +4,7 @@
#include "IAudioVoice.hpp"
#include "IAudioSubmix.hpp"
#include "IMIDIPort.hpp"
#include "boo/BooObject.hpp"
#include <memory>
#include <vector>
@ -36,17 +37,17 @@ struct IAudioVoiceEngine
* Client must be prepared to supply audio frames via the callback when this is called;
* the backing audio-buffers are primed with initial data for low-latency playback start
*/
virtual std::unique_ptr<IAudioVoice> allocateNewMonoVoice(double sampleRate,
IAudioVoiceCallback* cb,
bool dynamicPitch=false)=0;
virtual ObjToken<IAudioVoice> allocateNewMonoVoice(double sampleRate,
IAudioVoiceCallback* cb,
bool dynamicPitch=false)=0;
/** Same as allocateNewMonoVoice, but source audio is stereo-interleaved */
virtual std::unique_ptr<IAudioVoice> allocateNewStereoVoice(double sampleRate,
IAudioVoiceCallback* cb,
bool dynamicPitch=false)=0;
virtual ObjToken<IAudioVoice> allocateNewStereoVoice(double sampleRate,
IAudioVoiceCallback* cb,
bool dynamicPitch=false)=0;
/** Client calls this to allocate a Submix for gathering audio together for effects processing */
virtual std::unique_ptr<IAudioSubmix> allocateNewSubmix(bool mainOut, IAudioSubmixCallback* cb, int busId)=0;
virtual ObjToken<IAudioSubmix> allocateNewSubmix(bool mainOut, IAudioSubmixCallback* cb, int busId)=0;
/** Client can register for key callback events from the mixing engine this way */
virtual void setCallbackInterface(IAudioVoiceEngineCallback* cb)=0;

View File

@ -7,27 +7,27 @@
namespace boo
{
/** Linked-list iterator shareable by data container types */
template<class T>
class DataIterator : public std::iterator<std::bidirectional_iterator_tag, T>
/** Linked-list iterator shareable by ListNode types. */
template <class T>
class ListIterator : public std::iterator<std::bidirectional_iterator_tag, T>
{
T* m_node;
public:
explicit DataIterator(T* node) : m_node(node) {}
explicit ListIterator(T* node) : m_node(node) {}
T& operator*() const { return *m_node; }
bool operator!=(const DataIterator& other) const { return m_node != other.m_node; }
DataIterator& operator++() { m_node = m_node->m_next; return *this; }
DataIterator& operator--() { m_node = m_node->m_prev; return *this; }
bool operator!=(const ListIterator& other) const { return m_node != other.m_node; }
ListIterator& operator++() { m_node = m_node->m_next; return *this; }
ListIterator& operator--() { m_node = m_node->m_prev; return *this; }
};
/** Linked-list IObj node made part of objects participating in list
/** Linked-list IObj node made part of objects participating in list.
* Subclasses must implement static methods _getHeadPtr() and _getHeadLock()
* to support the common list-management functionality.
*/
template <class N, class H, class P = IObj>
struct ListNode : P
{
using iterator = DataIterator<N>;
using iterator = ListIterator<N>;
iterator begin() { return iterator(static_cast<N*>(this)); }
iterator end() { return iterator(nullptr); }

View File

@ -25,6 +25,8 @@ AudioSubmix::~AudioSubmix()
AudioSubmix*& AudioSubmix::_getHeadPtr(BaseAudioVoiceEngine* head) { return head->m_submixHead; }
std::unique_lock<std::recursive_mutex> AudioSubmix::_getHeadLock(BaseAudioVoiceEngine* head)
{ return std::unique_lock<std::recursive_mutex>{head->m_dataMutex}; }
std::unique_lock<std::recursive_mutex> AudioSubmix::destructorLock()
{ return std::unique_lock<std::recursive_mutex>{m_head->m_dataMutex}; }
bool AudioSubmix::_isDirectDependencyOf(AudioSubmix* send)
{

View File

@ -79,6 +79,7 @@ class AudioSubmix : public ListNode<AudioSubmix, BaseAudioVoiceEngine*, IAudioSu
public:
static AudioSubmix*& _getHeadPtr(BaseAudioVoiceEngine* head);
static std::unique_lock<std::recursive_mutex> _getHeadLock(BaseAudioVoiceEngine* head);
std::unique_lock<std::recursive_mutex> destructorLock();
AudioSubmix(BaseAudioVoiceEngine& root, IAudioSubmixCallback* cb, int busId, bool mainOut);
~AudioSubmix();

View File

@ -22,6 +22,8 @@ AudioVoice::~AudioVoice()
AudioVoice*& AudioVoice::_getHeadPtr(BaseAudioVoiceEngine* head) { return head->m_voiceHead; }
std::unique_lock<std::recursive_mutex> AudioVoice::_getHeadLock(BaseAudioVoiceEngine* head)
{ return std::unique_lock<std::recursive_mutex>{head->m_dataMutex}; }
std::unique_lock<std::recursive_mutex> AudioVoice::destructorLock()
{ return std::unique_lock<std::recursive_mutex>{m_head->m_dataMutex}; }
void AudioVoice::_setPitchRatio(double ratio, bool slew)
{

View File

@ -65,6 +65,7 @@ protected:
public:
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);

View File

@ -86,26 +86,26 @@ template void BaseAudioVoiceEngine::_pumpAndMixVoices<int16_t>(size_t frames, in
template void BaseAudioVoiceEngine::_pumpAndMixVoices<int32_t>(size_t frames, int32_t* dataOut);
template void BaseAudioVoiceEngine::_pumpAndMixVoices<float>(size_t frames, float* dataOut);
std::unique_ptr<IAudioVoice>
ObjToken<IAudioVoice>
BaseAudioVoiceEngine::allocateNewMonoVoice(double sampleRate,
IAudioVoiceCallback* cb,
bool dynamicPitch)
{
return std::make_unique<AudioVoiceMono>(*this, cb, sampleRate, dynamicPitch);
return {new AudioVoiceMono(*this, cb, sampleRate, dynamicPitch)};
}
std::unique_ptr<IAudioVoice>
ObjToken<IAudioVoice>
BaseAudioVoiceEngine::allocateNewStereoVoice(double sampleRate,
IAudioVoiceCallback* cb,
bool dynamicPitch)
{
return std::make_unique<AudioVoiceStereo>(*this, cb, sampleRate, dynamicPitch);
return {new AudioVoiceStereo(*this, cb, sampleRate, dynamicPitch)};
}
std::unique_ptr<IAudioSubmix>
ObjToken<IAudioSubmix>
BaseAudioVoiceEngine::allocateNewSubmix(bool mainOut, IAudioSubmixCallback* cb, int busId)
{
return std::make_unique<AudioSubmix>(*this, cb, busId, mainOut);
return {new AudioSubmix(*this, cb, busId, mainOut)};
}
void BaseAudioVoiceEngine::setCallbackInterface(IAudioVoiceEngineCallback* cb)

View File

@ -56,15 +56,15 @@ protected:
public:
BaseAudioVoiceEngine() : m_mainSubmix(std::make_unique<AudioSubmix>(*this, nullptr, -1, false)) {}
~BaseAudioVoiceEngine();
std::unique_ptr<IAudioVoice> allocateNewMonoVoice(double sampleRate,
IAudioVoiceCallback* cb,
bool dynamicPitch=false);
ObjToken<IAudioVoice> allocateNewMonoVoice(double sampleRate,
IAudioVoiceCallback* cb,
bool dynamicPitch=false);
std::unique_ptr<IAudioVoice> allocateNewStereoVoice(double sampleRate,
IAudioVoiceCallback* cb,
bool dynamicPitch=false);
ObjToken<IAudioVoice> allocateNewStereoVoice(double sampleRate,
IAudioVoiceCallback* cb,
bool dynamicPitch=false);
std::unique_ptr<IAudioSubmix> allocateNewSubmix(bool mainOut, IAudioSubmixCallback* cb, int busId);
ObjToken<IAudioSubmix> allocateNewSubmix(bool mainOut, IAudioSubmixCallback* cb, int busId);
void setCallbackInterface(IAudioVoiceEngineCallback* cb);

View File

@ -108,9 +108,9 @@ WindowedHilbert::~WindowedHilbert()
{
ippFree(m_spec);
ippFree(m_buffer);
ippFree(m_inputBuf);
ippFree(m_outputBuf);
ippFree(m_hammingTable);
ippsFree(m_inputBuf);
ippsFree(m_outputBuf);
ippsFree(m_hammingTable);
}
void WindowedHilbert::_AddWindow()

View File

@ -1,5 +1,5 @@
#ifndef APPLICATION_UNIX_CPP
#error This file may only be included from CApplicationUnix.cpp
#error This file may only be included from ApplicationUnix.cpp
#endif
#include "boo/IApplication.hpp"