this repo has no description
1#ifndef AUDIOUNITPA_H
2#define AUDIOUNITPA_H
3#include "AudioOutputUnitComponent.h"
4#include <pulse/pulseaudio.h>
5#include <thread>
6
7#ifndef kOutputBus
8# define kOutputBus 0 // playback
9# define kInputBus 1 // recording
10#endif
11
12class AudioUnitPA : public AudioOutputUnitComponent
13{
14public:
15 AudioUnitPA();
16 virtual ~AudioUnitPA();
17
18 OSStatus init() override;
19 OSStatus deinit() override;
20
21 OSStatus start() override;
22 OSStatus stop() override;
23
24 OSStatus reset(AudioUnitScope inScope, AudioUnitElement inElement) override;
25
26 OSStatus render(AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) override;
27
28 int cardIndex() const override;
29private:
30 OSStatus initOutput();
31private:
32 static void initializePA();
33 static void deinitializePA();
34 static void paContextStateCB(pa_context* c, void*);
35 static void paStreamStateCB(pa_stream* s, void*);
36 static void paStreamWriteCB(pa_stream* s, size_t length, void*);
37 static std::string getAppName();
38 pa_sample_spec paSampleSpecForASBD(const AudioStreamBasicDescription& asbd);
39
40 void requestDataForPlayback(size_t length);
41
42 inline bool isOutputPlanar() const { return m_config[kOutputBus].second.mFormatFlags & kAudioFormatFlagIsNonInterleaved; }
43 inline bool isInputPlanar() const { return m_config[kInputBus].first.mFormatFlags & kAudioFormatFlagIsNonInterleaved; }
44
45 OSStatus renderOutput(AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inNumberFrames, AudioBufferList *ioData);
46 OSStatus renderInterleavedOutput(AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inNumberFrames, AudioBufferList *ioData);
47 OSStatus renderPlanarOutput(AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inNumberFrames, AudioBufferList *ioData);
48
49 OSStatus renderInput(AudioUnitRenderActionFlags *ioActionFlags,const AudioTimeStamp *inTimeStamp, UInt32 inNumberFrames, AudioBufferList *ioData);
50 OSStatus renderInterleavedInput(AudioUnitRenderActionFlags *ioActionFlags,const AudioTimeStamp *inTimeStamp, UInt32 inNumberFrames, AudioBufferList *ioData);
51 OSStatus renderPlanarInput(AudioUnitRenderActionFlags *ioActionFlags,const AudioTimeStamp *inTimeStamp, UInt32 inNumberFrames, AudioBufferList *ioData);
52private:
53 static pa_mainloop* m_mainloop;
54 static pa_context* m_context;
55 static std::thread* m_mainloopThread;
56private:
57 pa_stream* m_stream;
58
59 // PulseAudio supports only unsigned 8-bit PCM and only signed >8-bit PCM.
60 // We need to perform conversion of samples if input/output differs.
61 bool m_convertUnsignedSigned = false;
62 bool m_started = false;
63};
64
65#endif /* AUDIOUNITPA_H */
66