mirror of https://github.com/AxioDL/boo.git
Allocate submixes and voices using boo::ObjToken
This commit is contained in:
parent
135f504899
commit
489e7e671b
|
@ -13,7 +13,7 @@ class IObj
|
||||||
protected:
|
protected:
|
||||||
virtual ~IObj() = default;
|
virtual ~IObj() = default;
|
||||||
public:
|
public:
|
||||||
virtual std::unique_lock<std::recursive_mutex> destructorLock() { return {}; }
|
virtual std::unique_lock<std::recursive_mutex> destructorLock()=0;
|
||||||
void increment() { m_refCount++; }
|
void increment() { m_refCount++; }
|
||||||
void decrement()
|
void decrement()
|
||||||
{
|
{
|
||||||
|
|
|
@ -241,7 +241,7 @@ struct DeferredWindowEvents : public IWindowCallback
|
||||||
m_cmds.back().m_mods = mod;
|
m_cmds.back().m_mods = mod;
|
||||||
}
|
}
|
||||||
|
|
||||||
ITextInputCallback* getTextInputCallback() {return m_rec.getTextInputCallback();}
|
ITextInputCallback* getTextInputCallback() { return m_rec.getTextInputCallback(); }
|
||||||
|
|
||||||
void dispatchEvents()
|
void dispatchEvents()
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,7 +27,7 @@ class IApplication
|
||||||
friend class WindowWin32;
|
friend class WindowWin32;
|
||||||
virtual void _deletedWindow(IWindow* window)=0;
|
virtual void _deletedWindow(IWindow* window)=0;
|
||||||
public:
|
public:
|
||||||
virtual ~IApplication() {}
|
virtual ~IApplication() = default;
|
||||||
|
|
||||||
enum class EPlatformType
|
enum class EPlatformType
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include "boo/BooObject.hpp"
|
||||||
|
|
||||||
namespace boo
|
namespace boo
|
||||||
{
|
{
|
||||||
|
@ -19,10 +20,8 @@ enum class SubmixFormat
|
||||||
Float
|
Float
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IAudioSubmix
|
struct IAudioSubmix : IObj
|
||||||
{
|
{
|
||||||
virtual ~IAudioSubmix() = default;
|
|
||||||
|
|
||||||
/** Reset channel-levels to silence; unbind all submixes */
|
/** Reset channel-levels to silence; unbind all submixes */
|
||||||
virtual void resetSendLevels()=0;
|
virtual void resetSendLevels()=0;
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "boo/BooObject.hpp"
|
||||||
|
|
||||||
namespace boo
|
namespace boo
|
||||||
{
|
{
|
||||||
|
@ -54,10 +55,8 @@ static inline unsigned ChannelCount(AudioChannelSet layout)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct IAudioVoice
|
struct IAudioVoice : IObj
|
||||||
{
|
{
|
||||||
virtual ~IAudioVoice() = default;
|
|
||||||
|
|
||||||
/** Set sample rate into voice (may result in audio discontinuities) */
|
/** Set sample rate into voice (may result in audio discontinuities) */
|
||||||
virtual void resetSampleRate(double sampleRate)=0;
|
virtual void resetSampleRate(double sampleRate)=0;
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "IAudioVoice.hpp"
|
#include "IAudioVoice.hpp"
|
||||||
#include "IAudioSubmix.hpp"
|
#include "IAudioSubmix.hpp"
|
||||||
#include "IMIDIPort.hpp"
|
#include "IMIDIPort.hpp"
|
||||||
|
#include "boo/BooObject.hpp"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -36,17 +37,17 @@ struct IAudioVoiceEngine
|
||||||
* Client must be prepared to supply audio frames via the callback when this is called;
|
* 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
|
* the backing audio-buffers are primed with initial data for low-latency playback start
|
||||||
*/
|
*/
|
||||||
virtual std::unique_ptr<IAudioVoice> allocateNewMonoVoice(double sampleRate,
|
virtual ObjToken<IAudioVoice> allocateNewMonoVoice(double sampleRate,
|
||||||
IAudioVoiceCallback* cb,
|
IAudioVoiceCallback* cb,
|
||||||
bool dynamicPitch=false)=0;
|
bool dynamicPitch=false)=0;
|
||||||
|
|
||||||
/** Same as allocateNewMonoVoice, but source audio is stereo-interleaved */
|
/** Same as allocateNewMonoVoice, but source audio is stereo-interleaved */
|
||||||
virtual std::unique_ptr<IAudioVoice> allocateNewStereoVoice(double sampleRate,
|
virtual ObjToken<IAudioVoice> allocateNewStereoVoice(double sampleRate,
|
||||||
IAudioVoiceCallback* cb,
|
IAudioVoiceCallback* cb,
|
||||||
bool dynamicPitch=false)=0;
|
bool dynamicPitch=false)=0;
|
||||||
|
|
||||||
/** Client calls this to allocate a Submix for gathering audio together for effects processing */
|
/** 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 */
|
/** Client can register for key callback events from the mixing engine this way */
|
||||||
virtual void setCallbackInterface(IAudioVoiceEngineCallback* cb)=0;
|
virtual void setCallbackInterface(IAudioVoiceEngineCallback* cb)=0;
|
||||||
|
|
|
@ -7,27 +7,27 @@
|
||||||
namespace boo
|
namespace boo
|
||||||
{
|
{
|
||||||
|
|
||||||
/** Linked-list iterator shareable by data container types */
|
/** Linked-list iterator shareable by ListNode types. */
|
||||||
template<class T>
|
template <class T>
|
||||||
class DataIterator : public std::iterator<std::bidirectional_iterator_tag, T>
|
class ListIterator : public std::iterator<std::bidirectional_iterator_tag, T>
|
||||||
{
|
{
|
||||||
T* m_node;
|
T* m_node;
|
||||||
public:
|
public:
|
||||||
explicit DataIterator(T* node) : m_node(node) {}
|
explicit ListIterator(T* node) : m_node(node) {}
|
||||||
T& operator*() const { return *m_node; }
|
T& operator*() const { return *m_node; }
|
||||||
bool operator!=(const DataIterator& other) const { return m_node != other.m_node; }
|
bool operator!=(const ListIterator& other) const { return m_node != other.m_node; }
|
||||||
DataIterator& operator++() { m_node = m_node->m_next; return *this; }
|
ListIterator& operator++() { m_node = m_node->m_next; return *this; }
|
||||||
DataIterator& operator--() { m_node = m_node->m_prev; 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()
|
* Subclasses must implement static methods _getHeadPtr() and _getHeadLock()
|
||||||
* to support the common list-management functionality.
|
* to support the common list-management functionality.
|
||||||
*/
|
*/
|
||||||
template <class N, class H, class P = IObj>
|
template <class N, class H, class P = IObj>
|
||||||
struct ListNode : P
|
struct ListNode : P
|
||||||
{
|
{
|
||||||
using iterator = DataIterator<N>;
|
using iterator = ListIterator<N>;
|
||||||
iterator begin() { return iterator(static_cast<N*>(this)); }
|
iterator begin() { return iterator(static_cast<N*>(this)); }
|
||||||
iterator end() { return iterator(nullptr); }
|
iterator end() { return iterator(nullptr); }
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,8 @@ AudioSubmix::~AudioSubmix()
|
||||||
AudioSubmix*& AudioSubmix::_getHeadPtr(BaseAudioVoiceEngine* head) { return head->m_submixHead; }
|
AudioSubmix*& AudioSubmix::_getHeadPtr(BaseAudioVoiceEngine* head) { return head->m_submixHead; }
|
||||||
std::unique_lock<std::recursive_mutex> AudioSubmix::_getHeadLock(BaseAudioVoiceEngine* head)
|
std::unique_lock<std::recursive_mutex> AudioSubmix::_getHeadLock(BaseAudioVoiceEngine* head)
|
||||||
{ return std::unique_lock<std::recursive_mutex>{head->m_dataMutex}; }
|
{ 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)
|
bool AudioSubmix::_isDirectDependencyOf(AudioSubmix* send)
|
||||||
{
|
{
|
||||||
|
|
|
@ -79,6 +79,7 @@ class AudioSubmix : public ListNode<AudioSubmix, BaseAudioVoiceEngine*, IAudioSu
|
||||||
public:
|
public:
|
||||||
static AudioSubmix*& _getHeadPtr(BaseAudioVoiceEngine* head);
|
static AudioSubmix*& _getHeadPtr(BaseAudioVoiceEngine* head);
|
||||||
static std::unique_lock<std::recursive_mutex> _getHeadLock(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(BaseAudioVoiceEngine& root, IAudioSubmixCallback* cb, int busId, bool mainOut);
|
||||||
~AudioSubmix();
|
~AudioSubmix();
|
||||||
|
|
|
@ -22,6 +22,8 @@ AudioVoice::~AudioVoice()
|
||||||
AudioVoice*& AudioVoice::_getHeadPtr(BaseAudioVoiceEngine* head) { return head->m_voiceHead; }
|
AudioVoice*& AudioVoice::_getHeadPtr(BaseAudioVoiceEngine* head) { return head->m_voiceHead; }
|
||||||
std::unique_lock<std::recursive_mutex> AudioVoice::_getHeadLock(BaseAudioVoiceEngine* head)
|
std::unique_lock<std::recursive_mutex> AudioVoice::_getHeadLock(BaseAudioVoiceEngine* head)
|
||||||
{ return std::unique_lock<std::recursive_mutex>{head->m_dataMutex}; }
|
{ 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)
|
void AudioVoice::_setPitchRatio(double ratio, bool slew)
|
||||||
{
|
{
|
||||||
|
|
|
@ -65,6 +65,7 @@ protected:
|
||||||
public:
|
public:
|
||||||
static AudioVoice*& _getHeadPtr(BaseAudioVoiceEngine* head);
|
static AudioVoice*& _getHeadPtr(BaseAudioVoiceEngine* head);
|
||||||
static std::unique_lock<std::recursive_mutex> _getHeadLock(BaseAudioVoiceEngine* head);
|
static std::unique_lock<std::recursive_mutex> _getHeadLock(BaseAudioVoiceEngine* head);
|
||||||
|
std::unique_lock<std::recursive_mutex> destructorLock();
|
||||||
|
|
||||||
~AudioVoice();
|
~AudioVoice();
|
||||||
void resetSampleRate(double sampleRate);
|
void resetSampleRate(double sampleRate);
|
||||||
|
|
|
@ -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<int32_t>(size_t frames, int32_t* dataOut);
|
||||||
template void BaseAudioVoiceEngine::_pumpAndMixVoices<float>(size_t frames, float* dataOut);
|
template void BaseAudioVoiceEngine::_pumpAndMixVoices<float>(size_t frames, float* dataOut);
|
||||||
|
|
||||||
std::unique_ptr<IAudioVoice>
|
ObjToken<IAudioVoice>
|
||||||
BaseAudioVoiceEngine::allocateNewMonoVoice(double sampleRate,
|
BaseAudioVoiceEngine::allocateNewMonoVoice(double sampleRate,
|
||||||
IAudioVoiceCallback* cb,
|
IAudioVoiceCallback* cb,
|
||||||
bool dynamicPitch)
|
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,
|
BaseAudioVoiceEngine::allocateNewStereoVoice(double sampleRate,
|
||||||
IAudioVoiceCallback* cb,
|
IAudioVoiceCallback* cb,
|
||||||
bool dynamicPitch)
|
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)
|
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)
|
void BaseAudioVoiceEngine::setCallbackInterface(IAudioVoiceEngineCallback* cb)
|
||||||
|
|
|
@ -56,15 +56,15 @@ protected:
|
||||||
public:
|
public:
|
||||||
BaseAudioVoiceEngine() : m_mainSubmix(std::make_unique<AudioSubmix>(*this, nullptr, -1, false)) {}
|
BaseAudioVoiceEngine() : m_mainSubmix(std::make_unique<AudioSubmix>(*this, nullptr, -1, false)) {}
|
||||||
~BaseAudioVoiceEngine();
|
~BaseAudioVoiceEngine();
|
||||||
std::unique_ptr<IAudioVoice> allocateNewMonoVoice(double sampleRate,
|
ObjToken<IAudioVoice> allocateNewMonoVoice(double sampleRate,
|
||||||
IAudioVoiceCallback* cb,
|
IAudioVoiceCallback* cb,
|
||||||
bool dynamicPitch=false);
|
bool dynamicPitch=false);
|
||||||
|
|
||||||
std::unique_ptr<IAudioVoice> allocateNewStereoVoice(double sampleRate,
|
ObjToken<IAudioVoice> allocateNewStereoVoice(double sampleRate,
|
||||||
IAudioVoiceCallback* cb,
|
IAudioVoiceCallback* cb,
|
||||||
bool dynamicPitch=false);
|
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);
|
void setCallbackInterface(IAudioVoiceEngineCallback* cb);
|
||||||
|
|
||||||
|
|
|
@ -108,9 +108,9 @@ WindowedHilbert::~WindowedHilbert()
|
||||||
{
|
{
|
||||||
ippFree(m_spec);
|
ippFree(m_spec);
|
||||||
ippFree(m_buffer);
|
ippFree(m_buffer);
|
||||||
ippFree(m_inputBuf);
|
ippsFree(m_inputBuf);
|
||||||
ippFree(m_outputBuf);
|
ippsFree(m_outputBuf);
|
||||||
ippFree(m_hammingTable);
|
ippsFree(m_hammingTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowedHilbert::_AddWindow()
|
void WindowedHilbert::_AddWindow()
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#ifndef APPLICATION_UNIX_CPP
|
#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
|
#endif
|
||||||
|
|
||||||
#include "boo/IApplication.hpp"
|
#include "boo/IApplication.hpp"
|
||||||
|
|
Loading…
Reference in New Issue