VAE - Virtual Audio Engine 1
Small Data Driven Audio Engine
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
vae::core::DevicePortaudio Class Referencefinal

Portaudio backend implementation. More...

#include <vae_portaudio.hpp>

Inheritance diagram for vae::core::DevicePortaudio:
Collaboration diagram for vae::core::DevicePortaudio:

Public Member Functions

 DevicePortaudio (Backend &backend, const EngineConfig &config)
 
 ~DevicePortaudio ()
 
bool openDevice (DeviceInfo &device) override
 Opens a specific audio device. More...
 
bool closeDevice () override
 Closes the currently open device. More...
 
- Public Member Functions inherited from vae::core::Device
 Device (Backend &backend, const EngineConfig &config)
 Only a Backend can construct a Device. More...
 
virtual ~Device ()
 
void setCallback (Callback callback)
 
virtual bool openDevice (bool input=false)
 Tries to open the default audio device whith desired in out channels. More...
 
Size push (const ScratchBuffer &buffer)
 Push samples to the audio device. More...
 
Size canPush () const
 Return amount of audio frames which can be pushed in buffer ! this is an estimate when resampling ! More...
 
void pop (ScratchBuffer &buffer)
 Get samples form audio device. More...
 
Size canPop () const
 
Size getChannelsOut () const
 
Size getChannelsIn () const
 
Size getSampleRate () const
 Get the sample rate. More...
 
Size getRealSampleRate () const
 Get the Real Sample Rate before resampling. More...
 
size_t getStreamTime () const
 
Size getOverruns () const
 
Size getUnderruns () const
 

Private Member Functions

void cleanUp ()
 

Static Private Member Functions

static int AudioCallback (const void *in, void *out, unsigned long frames, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *data)
 Function called from the PortAudio thread. More...
 
static void StreamFinished (void *data)
 

Private Attributes

PaStream * mStream = nullptr
 
bool mInitialized = false
 

Additional Inherited Members

- Public Types inherited from vae::core::Device
using Resampler = tklb::ResamplerTpl< Sample, ScratchBuffer >
 
- Protected Types inherited from vae::core::Device
using Callback = tklb::Delegate< void(Device *)>
 
- Protected Member Functions inherited from vae::core::Device
void init (Size sampleRate, Uchar channelsIn, Uchar channelsOut, Size bufferSize)
 initializes buffers, queues and resamplers if needed Has to be called in openDevice once the samplerate and channel config is known More...
 
void postInit ()
 
- Protected Attributes inherited from vae::core::Device
BackendmBackend
 
const EngineConfigmConfig
 
Size mSampleRate = 0
 
Size mRealSampleRate = 0
 
Size mOverruns = 0
 
Size mUnderruns = 0
 
Resampler mResamplerToDevice
 
ScratchBuffer mResamplerBufferToDevice
 
AudioThreadWorker mWorker
 
- Static Protected Attributes inherited from vae::core::Device
static constexpr int _VAE_WORKER_SIZE = sizeof(AudioThreadWorker)
 

Detailed Description

Portaudio backend implementation.

Definition at line 15 of file vae_portaudio.hpp.

Constructor & Destructor Documentation

◆ DevicePortaudio()

vae::core::DevicePortaudio::DevicePortaudio ( Backend backend,
const EngineConfig config 
)
inline

Definition at line 62 of file vae_portaudio.hpp.

64 : Device(backend, config) { }
Device(Backend &backend, const EngineConfig &config)
Only a Backend can construct a Device.
Definition: vae_device.hpp:184

◆ ~DevicePortaudio()

vae::core::DevicePortaudio::~DevicePortaudio ( )
inline

Definition at line 66 of file vae_portaudio.hpp.

Here is the call graph for this function:

Member Function Documentation

◆ AudioCallback()

static int vae::core::DevicePortaudio::AudioCallback ( const void *  in,
void *  out,
unsigned long  frames,
const PaStreamCallbackTimeInfo *  timeInfo,
PaStreamCallbackFlags  statusFlags,
void *  data 
)
inlinestaticprivate

Function called from the PortAudio thread.

Definition at line 41 of file vae_portaudio.hpp.

45 {
46 (void) timeInfo; // Prevent unused variable warnings.
47 (void) statusFlags; // Prevent unused variable warnings.
48 auto inFloat = static_cast<const float*>(in);
49 auto outFloat = static_cast<float*>(out);
50 static_cast<AudioThreadWorker*>(data)
51 ->swapBufferInterleaved(inFloat, outFloat, frames);
52 return paContinue;
53 }
Here is the caller graph for this function:

◆ cleanUp()

void vae::core::DevicePortaudio::cleanUp ( )
inlineprivate

Definition at line 19 of file vae_portaudio.hpp.

19 {
20 VAE_PROFILER_SCOPE_NAMED("Cleanup portaudio")
21 if (!mInitialized || mStream == nullptr) {
22 return;
23 }
24
25 {
26 VAE_PROFILER_SCOPE_NAMED("Stop portaudio stream")
27 PaError err = Pa_StopStream(mStream);
28 VAE_ASSERT(err == paNoError)
29 }
30 {
31 VAE_PROFILER_SCOPE_NAMED("Close portaudio stream")
32 PaError err = Pa_CloseStream(mStream);
33 VAE_ASSERT(err == paNoError)
34 }
35 mInitialized = false;
36 }
#define VAE_PROFILER_SCOPE_NAMED(name)
Profiles a scope and names it.
#define VAE_ASSERT(condition)
Definition: vae_util.hpp:11
Here is the caller graph for this function:

◆ closeDevice()

bool vae::core::DevicePortaudio::closeDevice ( )
inlineoverridevirtual

Closes the currently open device.

Otherwise does nothing.

Implements vae::core::Device.

Definition at line 153 of file vae_portaudio.hpp.

153 {
154 cleanUp();
155 return true;
156 }
Here is the call graph for this function:

◆ openDevice()

bool vae::core::DevicePortaudio::openDevice ( DeviceInfo device)
inlineoverridevirtual

Opens a specific audio device.

The device struct may be altered to match the actual hardware. (sampleRate, bufferSize and channel count)

Implements vae::core::Device.

Definition at line 68 of file vae_portaudio.hpp.

68 {
69 const PaDeviceInfo* deviceInfo = Pa_GetDeviceInfo(device.id);
70
71 if (deviceInfo == nullptr) {
72 VAE_ASSERT(false)
73 return false;
74 }
75
76 device.channelsIn = tklb::clamp<int>(device.channelsIn, 0, StaticConfig::MaxChannels);
77 device.channelsOut = tklb::clamp<int>(device.channelsOut, 0, StaticConfig::MaxChannels);
78
79 PaStreamParameters inputParameters;
80 inputParameters.device = device.id;
81 inputParameters.sampleFormat = paFloat32;
82 inputParameters.suggestedLatency = deviceInfo->defaultLowInputLatency;
83 inputParameters.hostApiSpecificStreamInfo = NULL;
84 VAE_ASSERT(device.channelsIn <= Uint(deviceInfo->maxInputChannels))
85 inputParameters.channelCount = device.channelsIn;
86
87 PaStreamParameters outputParameters;
88 outputParameters.device = device.id;
89 outputParameters.sampleFormat = paFloat32;
90 outputParameters.suggestedLatency = deviceInfo->defaultLowOutputLatency;
91 outputParameters.hostApiSpecificStreamInfo = NULL;
92 VAE_ASSERT(device.channelsOut <= Uint(deviceInfo->maxOutputChannels))
93 outputParameters.channelCount = device.channelsOut;
94
95 if (device.bufferSize == 0) {
96 device.bufferSize = mConfig.preferredBufferSize;
97 }
98
99 PaError err;
100 {
101 VAE_PROFILER_SCOPE_NAMED("Open stream portaudio")
102 err = Pa_OpenStream(
103 &mStream,
104 0 < inputParameters.channelCount ? &inputParameters : NULL,
105 0 < outputParameters.channelCount ? &outputParameters : NULL,
106 mConfig.internalSampleRate, // try getting internal samplerate
107 device.bufferSize,
108 paClipOff, // no clipping, device will do that
110 &mWorker
111 );
112
113 }
114
115 if (err != paNoError) {
116 VAE_ASSERT(false)
117 cleanUp();
118 return false;
119 }
120
121 err = Pa_SetStreamFinishedCallback(
123 );
124
125 if (err != paNoError) {
126 VAE_ASSERT(false)
127 cleanUp();
128 return false;
129 }
130
131 // Might have gotten different samplerate
132 const PaStreamInfo* streamInfo = Pa_GetStreamInfo(mStream);
133 init(
134 Uint(streamInfo->sampleRate),
135 device.channelsIn, device.channelsOut,
136 device.bufferSize // Pa doesn't provide any info, so we assume we got what we wanted
137 );
138
139 {
140 VAE_PROFILER_SCOPE_NAMED("Start stream portaudio")
141 err = Pa_StartStream(mStream);
142 }
143
144 if (err != paNoError) {
145 VAE_ASSERT(false)
146 cleanUp();
147 return false;
148 }
149 postInit();
150 return true;
151 }
AudioThreadWorker mWorker
Definition: vae_device.hpp:102
const EngineConfig & mConfig
Definition: vae_device.hpp:24
void init(Size sampleRate, Uchar channelsIn, Uchar channelsOut, Size bufferSize)
initializes buffers, queues and resamplers if needed Has to be called in openDevice once the samplera...
Definition: vae_device.hpp:114
static void StreamFinished(void *data)
static int AudioCallback(const void *in, void *out, unsigned long frames, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *data)
Function called from the PortAudio thread.
Using template interfaces isn't an option so this simply defines a default Convolver type.
Definition: TAllocator.hpp:15
T clamp(const T &v, const T &_min, const T &_max)
Definition: TMath.hpp:26
constexpr unsigned char MaxChannels
Maximum channel count used to pre allocate buffers.
Definition: vae.hpp:268
unsigned int Uint
Definition: vae_types.hpp:46
Size preferredBufferSize
Buffer size that will be requested from device.
Definition: vae.hpp:233
Here is the call graph for this function:

◆ StreamFinished()

static void vae::core::DevicePortaudio::StreamFinished ( void *  data)
inlinestaticprivate

Definition at line 55 of file vae_portaudio.hpp.

55 {
56 (void) data; // Prevent unused variable warnings.
57 }
Here is the caller graph for this function:

Member Data Documentation

◆ mInitialized

bool vae::core::DevicePortaudio::mInitialized = false
private

Definition at line 17 of file vae_portaudio.hpp.

◆ mStream

PaStream* vae::core::DevicePortaudio::mStream = nullptr
private

Definition at line 16 of file vae_portaudio.hpp.


The documentation for this class was generated from the following file: