summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/portaudio/src/hostapi/pulseaudio/pa_linux_pulseaudio_internal.h
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/portaudio/src/hostapi/pulseaudio/pa_linux_pulseaudio_internal.h')
-rw-r--r--3rdparty/portaudio/src/hostapi/pulseaudio/pa_linux_pulseaudio_internal.h273
1 files changed, 273 insertions, 0 deletions
diff --git a/3rdparty/portaudio/src/hostapi/pulseaudio/pa_linux_pulseaudio_internal.h b/3rdparty/portaudio/src/hostapi/pulseaudio/pa_linux_pulseaudio_internal.h
new file mode 100644
index 00000000000..84bff257993
--- /dev/null
+++ b/3rdparty/portaudio/src/hostapi/pulseaudio/pa_linux_pulseaudio_internal.h
@@ -0,0 +1,273 @@
+
+/*
+ * PulseAudio host to play natively in Linux based systems without
+ * ALSA emulation
+ *
+ * Copyright (c) 2014-2023 Tuukka Pasanen <tuukka.pasanen@ilmi.fi>
+ * Copyright (c) 2016 Sqweek
+ *
+ * Based on the Open Source API proposed by Ross Bencina
+ * Copyright (c) 1999-2002 Ross Bencina, Phil Burk
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * The text above constitutes the entire PortAudio license; however,
+ * the PortAudio community also makes the following non-binding requests:
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version. It is also
+ * requested that these non-binding requests be included along with the
+ * license above.
+ */
+
+#ifndef _PA_HOSTAPI_PULSEAUDIO_H_
+#define _PA_HOSTAPI_PULSEAUDIO_H_
+
+#include "pa_util.h"
+#include "pa_allocation.h"
+#include "pa_hostapi.h"
+#include "pa_stream.h"
+#include "pa_cpuload.h"
+#include "pa_process.h"
+
+#include "pa_unix_util.h"
+#include "pa_ringbuffer.h"
+#include "pa_debugprint.h"
+
+/* PulseAudio headers */
+#include <stdio.h>
+#include <string.h>
+#include <pulse/pulseaudio.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/* prototypes for functions declared in this file */
+
+#define PA_PULSEAUDIO_SET_LAST_HOST_ERROR(errorCode, errorText) \
+ PaUtil_SetLastHostErrorInfo(paInDevelopment, errorCode, errorText)
+
+#define PAPULSEAUDIO_MAX_DEVICECOUNT 1024
+#define PAPULSEAUDIO_MAX_DEVICENAME 1024
+
+/* Default latency values to expose. Chosen by trial and error to be reasonable. */
+#define PA_PULSEAUDIO_DEFAULT_MIN_LATENCY 0.010
+#define PA_PULSEAUDIO_DEFAULT_MAX_LATENCY 0.080
+
+/* Just some value that Pulseaudio can handle */
+#define PAPULSEAUDIO_FRAMESPERBUFFERUNSPEC 32
+
+/* Assuming of 2 seconds of 44100 Hz sample rate with FLOAT (4 bytes) and stereo channels (2 channels).
+ You should have pretty good size buffer with this. If output/intput doesn't happens in 2 second we
+ have more trouble than this buffer.
+ @todo change this to something more sophisticated */
+#define PULSEAUDIO_BUFFER_SIZE (96100 * 4 * 2)
+
+typedef struct
+{
+ PaUtilHostApiRepresentation inheritedHostApiRep;
+ PaUtilStreamInterface callbackStreamInterface;
+ PaUtilStreamInterface blockingStreamInterface;
+
+ PaUtilAllocationGroup *allocations;
+
+ PaHostApiIndex hostApiIndex;
+ PaDeviceInfo deviceInfoArray[PAPULSEAUDIO_MAX_DEVICECOUNT];
+ char *pulseaudioDeviceNames[PAPULSEAUDIO_MAX_DEVICECOUNT];
+ pa_sample_spec pulseaudioDefaultSampleSpec;
+
+ /* PulseAudio stuff goes here */
+ pa_threaded_mainloop *mainloop;
+ pa_mainloop_api *mainloopApi;
+ pa_context *context;
+ int deviceCount;
+ pa_time_event *timeEvent;
+}
+PaPulseAudio_HostApiRepresentation;
+
+/* PaPulseAudio_Stream - a stream data structure specifically for this implementation */
+
+typedef struct PaPulseAudio_Stream
+{
+ PaUtilStreamRepresentation streamRepresentation;
+ PaUtilCpuLoadMeasurer cpuLoadMeasurer;
+ PaUtilBufferProcessor bufferProcessor;
+ PaPulseAudio_HostApiRepresentation *hostapi;
+
+ unsigned long framesPerHostCallback;
+ pa_threaded_mainloop *mainloop;
+ pa_context *context;
+ pa_sample_spec outputSampleSpec;
+ pa_sample_spec inputSampleSpec;
+ pa_stream *outputStream;
+ pa_stream *inputStream;
+ pa_buffer_attr outputBufferAttr;
+ pa_buffer_attr inputBufferAttr;
+ int outputUnderflows;
+ int outputChannelCount;
+ int inputChannelCount;
+
+ size_t maxFramesPerBuffer;
+ size_t maxFramesHostPerBuffer;
+ int outputFrameSize;
+ int inputFrameSize;
+
+ PaDeviceIndex inputDevice;
+ PaDeviceIndex outputDevice;
+
+ char *outputStreamName;
+ char *inputStreamName;
+
+ PaUtilRingBuffer inputRing;
+
+ size_t missedBytes;
+
+ /* Used in communication between threads
+ *
+ * State machine works like this:
+ * When stream is wanted to start with Pa_StartStream
+ * then isActive is 1 if opening of devices goes well
+ * and isStopped is then 0.
+ *
+ * When requested to stop isStopped is 1 on isActive is 0
+ * and nothing should be written to ouput or read from input
+ * anymore
+ *
+ * Pulseaudio does not like this as it creates streams and they
+ * start when they are ready and it can be after we have
+ * exited Pa_StartStream or before if get's kicked up very fast
+ *
+ * pulseaudioIsActive and pulseaudioIsStopped are used to find if
+ * there is stream active or stopped in pulseaudio side. They
+ * live their own life besides isActive and isStopped to make sure
+ * that portaudio will have input and output available before
+ * reading or writing to stream.
+ */
+ volatile sig_atomic_t isActive;
+ volatile sig_atomic_t isStopped;
+ volatile sig_atomic_t pulseaudioIsActive;
+ volatile sig_atomic_t pulseaudioIsStopped;
+
+}
+PaPulseAudio_Stream;
+
+/* PulseAudio Error checking macro */
+#define PA_PULSEAUDIO_IS_ERROR(pastream, errorCode) \
+ if( !(pastream) || \
+ !(pastream)->context || \
+ !PA_CONTEXT_IS_GOOD( pa_context_get_state( (pastream)->context ) ) || \
+ ( (pastream)->outputStream && \
+ !PA_STREAM_IS_GOOD( pa_stream_get_state( (pastream)->outputStream ) ) ) || \
+ ( (pastream)->inputStream && \
+ !PA_STREAM_IS_GOOD( pa_stream_get_state( (pastream)->inputStream ) ) ) ) \
+ { \
+ if( !(pastream) || \
+ ( (pastream)->context && \
+ pa_context_get_state( (pastream)->context ) == PA_CONTEXT_FAILED ) || \
+ ( (pastream)->outputStream && \
+ pa_stream_get_state( (pastream)->outputStream ) == PA_STREAM_FAILED ) || \
+ ( (pastream)->inputStream && \
+ pa_stream_get_state( (pastream)->inputStream ) == PA_STREAM_FAILED ) ) \
+ { \
+ return errorCode; \
+ } \
+ } \
+ if( !pastream->isActive || pastream->isStopped ) \
+ { \
+ return paStreamIsStopped; \
+ }
+
+void PaPulseAudio_Lock( pa_threaded_mainloop *mainloop );
+
+void PaPulseAudio_UnLock( pa_threaded_mainloop *mainloop );
+
+PaError PaPulseAudio_Initialize( PaUtilHostApiRepresentation ** hostApi,
+ PaHostApiIndex index );
+
+void Terminate( struct PaUtilHostApiRepresentation *hostApi );
+
+
+PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
+ const PaStreamParameters * inputParameters,
+ const PaStreamParameters * outputParameters,
+ double sampleRate );
+
+PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
+ PaStream ** s,
+ const PaStreamParameters * inputParameters,
+ const PaStreamParameters * outputParameters,
+ double sampleRate,
+ unsigned long framesPerBuffer,
+ PaStreamFlags streamFlags,
+ PaStreamCallback * streamCallback,
+ void *userData );
+
+
+PaError IsStreamStopped( PaStream * s );
+PaError IsStreamActive( PaStream * stream );
+
+PaTime GetStreamTime( PaStream * stream );
+double GetStreamCpuLoad( PaStream * stream );
+
+PaPulseAudio_HostApiRepresentation *PaPulseAudio_New( void );
+void PaPulseAudio_Free( PaPulseAudio_HostApiRepresentation * ptr );
+
+int PaPulseAudio_CheckConnection( PaPulseAudio_HostApiRepresentation * ptr );
+
+void PaPulseAudio_CheckContextStateCb( pa_context * c,
+ void *userdata );
+void PaPulseAudio_ServerInfoCb( pa_context *c,
+ const pa_server_info *i,
+ void *userdata );
+
+void PaPulseAudio_SinkListCb( pa_context * c,
+ const pa_sink_info * l,
+ int eol,
+ void *userdata );
+
+void PaPulseAudio_SourceListCb( pa_context * c,
+ const pa_source_info * l,
+ int eol,
+ void *userdata );
+
+void PaPulseAudio_StreamStateCb( pa_stream * s,
+ void *userdata );
+
+void PaPulseAudio_StreamStartedCb( pa_stream * s,
+ void *userdata );
+
+void PaPulseAudio_StreamUnderflowCb( pa_stream * s,
+ void *userdata );
+
+PaError PaPulseAudio_ConvertPortaudioFormatToPaPulseAudio_( PaSampleFormat portaudiosf,
+ pa_sample_spec * pulseaudiosf
+);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif