mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-24 01:04:02 +02:00
PipeWire: Finish work on removing the SPA dependency.
This commit is contained in:
@@ -3,6 +3,119 @@
|
|||||||
|
|
||||||
#include "miniaudio_pipewire.h"
|
#include "miniaudio_pipewire.h"
|
||||||
|
|
||||||
|
/* This is temporary until this is merged into miniaudio proper. */
|
||||||
|
MA_API MA_NO_INLINE int ma_pipewire_itoa_s(int value, char* dst, size_t dstSizeInBytes, int radix)
|
||||||
|
{
|
||||||
|
int sign;
|
||||||
|
unsigned int valueU;
|
||||||
|
char* dstEnd;
|
||||||
|
|
||||||
|
if (dst == NULL || dstSizeInBytes == 0) {
|
||||||
|
return 22;
|
||||||
|
}
|
||||||
|
if (radix < 2 || radix > 36) {
|
||||||
|
dst[0] = '\0';
|
||||||
|
return 22;
|
||||||
|
}
|
||||||
|
|
||||||
|
sign = (value < 0 && radix == 10) ? -1 : 1; /* The negative sign is only used when the base is 10. */
|
||||||
|
|
||||||
|
if (value < 0) {
|
||||||
|
valueU = -value;
|
||||||
|
} else {
|
||||||
|
valueU = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
dstEnd = dst;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
int remainder = valueU % radix;
|
||||||
|
if (remainder > 9) {
|
||||||
|
*dstEnd = (char)((remainder - 10) + 'a');
|
||||||
|
} else {
|
||||||
|
*dstEnd = (char)(remainder + '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
dstEnd += 1;
|
||||||
|
dstSizeInBytes -= 1;
|
||||||
|
valueU /= radix;
|
||||||
|
} while (dstSizeInBytes > 0 && valueU > 0);
|
||||||
|
|
||||||
|
if (dstSizeInBytes == 0) {
|
||||||
|
dst[0] = '\0';
|
||||||
|
return 22; /* Ran out of room in the output buffer. */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sign < 0) {
|
||||||
|
*dstEnd++ = '-';
|
||||||
|
dstSizeInBytes -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dstSizeInBytes == 0) {
|
||||||
|
dst[0] = '\0';
|
||||||
|
return 22; /* Ran out of room in the output buffer. */
|
||||||
|
}
|
||||||
|
|
||||||
|
*dstEnd = '\0';
|
||||||
|
|
||||||
|
|
||||||
|
/* At this point the string will be reversed. */
|
||||||
|
dstEnd -= 1;
|
||||||
|
while (dst < dstEnd) {
|
||||||
|
char temp = *dst;
|
||||||
|
*dst = *dstEnd;
|
||||||
|
*dstEnd = temp;
|
||||||
|
|
||||||
|
dst += 1;
|
||||||
|
dstEnd -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MA_API MA_NO_INLINE int ma_pipewire_strcat_s(char* dst, size_t dstSizeInBytes, const char* src)
|
||||||
|
{
|
||||||
|
char* dstorig;
|
||||||
|
|
||||||
|
if (dst == 0) {
|
||||||
|
return 22;
|
||||||
|
}
|
||||||
|
if (dstSizeInBytes == 0) {
|
||||||
|
return 34;
|
||||||
|
}
|
||||||
|
if (src == 0) {
|
||||||
|
dst[0] = '\0';
|
||||||
|
return 22;
|
||||||
|
}
|
||||||
|
|
||||||
|
dstorig = dst;
|
||||||
|
|
||||||
|
while (dstSizeInBytes > 0 && dst[0] != '\0') {
|
||||||
|
dst += 1;
|
||||||
|
dstSizeInBytes -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dstSizeInBytes == 0) {
|
||||||
|
return 22; /* Unterminated. */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
while (dstSizeInBytes > 0 && src[0] != '\0') {
|
||||||
|
*dst++ = *src++;
|
||||||
|
dstSizeInBytes -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dstSizeInBytes > 0) {
|
||||||
|
dst[0] = '\0';
|
||||||
|
} else {
|
||||||
|
dstorig[0] = '\0';
|
||||||
|
return 34;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#include <string.h> /* memset() */
|
#include <string.h> /* memset() */
|
||||||
#include <assert.h> /* assert() */
|
#include <assert.h> /* assert() */
|
||||||
|
|
||||||
@@ -34,6 +147,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MA_HAS_PIPEWIRE)
|
#if defined(MA_HAS_PIPEWIRE)
|
||||||
|
#if 0
|
||||||
#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
|
#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic ignored "-Wpedantic"
|
#pragma GCC diagnostic ignored "-Wpedantic"
|
||||||
@@ -43,9 +157,10 @@
|
|||||||
#pragma GCC diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
|
#pragma GCC diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
/*#include <pipewire/pipewire.h>*/
|
/*#include <pipewire/pipewire.h>*/
|
||||||
|
|
||||||
#include <spa/param/audio/format-utils.h> /* For spa_format_audio_raw_build() */
|
/*#include <spa/param/audio/format-utils.h>*/
|
||||||
/*#include <spa/param/audio/raw.h>*/
|
/*#include <spa/param/audio/raw.h>*/
|
||||||
/*#include <spa/utils/dict.h>*/
|
/*#include <spa/utils/dict.h>*/
|
||||||
/*#include <spa/pod/command.h>*/
|
/*#include <spa/pod/command.h>*/
|
||||||
@@ -395,6 +510,36 @@ struct ma_spa_hook
|
|||||||
|
|
||||||
|
|
||||||
/* spa_pod is the most complicated part of SPA that we use. We're only implementing specifically what we need. */
|
/* spa_pod is the most complicated part of SPA that we use. We're only implementing specifically what we need. */
|
||||||
|
#define MA_SPA_TYPE_Id 3
|
||||||
|
#define MA_SPA_TYPE_Int 4
|
||||||
|
#define MA_SPA_TYPE_Array 13
|
||||||
|
#define MA_SPA_TYPE_Object 15
|
||||||
|
#define MA_SPA_TYPE_Choice 19
|
||||||
|
|
||||||
|
#define MA_SPA_TYPE_OBJECT_Format 262147
|
||||||
|
#define MA_SPA_TYPE_OBJECT_ParamBuffers 262148
|
||||||
|
|
||||||
|
#define MA_SPA_PARAM_EnumFormat 3
|
||||||
|
#define MA_SPA_PARAM_Format 4
|
||||||
|
#define MA_SPA_PARAM_Buffers 5
|
||||||
|
|
||||||
|
#define MA_SPA_PARAM_BUFFERS_buffers 1
|
||||||
|
#define MA_SPA_PARAM_BUFFERS_blocks 2
|
||||||
|
#define MA_SPA_PARAM_BUFFERS_size 3
|
||||||
|
#define MA_SPA_PARAM_BUFFERS_stride 4
|
||||||
|
|
||||||
|
#define MA_SPA_FORMAT_mediaType 1
|
||||||
|
#define MA_SPA_FORMAT_mediaSubtype 2
|
||||||
|
|
||||||
|
#define MA_SPA_MEDIA_TYPE_audio 1
|
||||||
|
#define MA_SPA_MEDIA_SUBTYPE_raw 1
|
||||||
|
|
||||||
|
#define MA_SPA_FORMAT_AUDIO_format 65537
|
||||||
|
#define MA_SPA_FORMAT_AUDIO_rate 65539
|
||||||
|
#define MA_SPA_FORMAT_AUDIO_channels 65540
|
||||||
|
#define MA_SPA_FORMAT_AUDIO_position 65541
|
||||||
|
|
||||||
|
|
||||||
struct ma_spa_pod
|
struct ma_spa_pod
|
||||||
{
|
{
|
||||||
ma_uint32 size;
|
ma_uint32 size;
|
||||||
@@ -415,7 +560,7 @@ static MA_INLINE struct ma_spa_pod_id ma_spa_pod_id_init(ma_uint32 value)
|
|||||||
|
|
||||||
MA_PIPEWIRE_ZERO_OBJECT(&pod);
|
MA_PIPEWIRE_ZERO_OBJECT(&pod);
|
||||||
pod.pod.size = 4; /* Does not include the header or padding. */
|
pod.pod.size = 4; /* Does not include the header or padding. */
|
||||||
pod.pod.type = SPA_TYPE_Id;
|
pod.pod.type = MA_SPA_TYPE_Id;
|
||||||
pod.value = value;
|
pod.value = value;
|
||||||
|
|
||||||
return pod;
|
return pod;
|
||||||
@@ -435,7 +580,7 @@ static MA_INLINE struct ma_spa_pod_int ma_spa_pod_int_init(ma_int32 value)
|
|||||||
|
|
||||||
MA_PIPEWIRE_ZERO_OBJECT(&pod);
|
MA_PIPEWIRE_ZERO_OBJECT(&pod);
|
||||||
pod.pod.size = 4; /* Does not include the header or padding. */
|
pod.pod.size = 4; /* Does not include the header or padding. */
|
||||||
pod.pod.type = SPA_TYPE_Int;
|
pod.pod.type = MA_SPA_TYPE_Int;
|
||||||
pod.value = value;
|
pod.value = value;
|
||||||
|
|
||||||
return pod;
|
return pod;
|
||||||
@@ -578,14 +723,14 @@ static MA_INLINE struct ma_spa_pod_buffer_params ma_spa_pod_buffer_params_init(m
|
|||||||
MA_PIPEWIRE_ZERO_OBJECT(&pod);
|
MA_PIPEWIRE_ZERO_OBJECT(&pod);
|
||||||
|
|
||||||
pod.object.pod.size = sizeof(struct ma_spa_pod_buffer_params) - sizeof(struct ma_spa_pod); /* Don't include the header in the size. */
|
pod.object.pod.size = sizeof(struct ma_spa_pod_buffer_params) - sizeof(struct ma_spa_pod); /* Don't include the header in the size. */
|
||||||
pod.object.pod.type = SPA_TYPE_Object;
|
pod.object.pod.type = MA_SPA_TYPE_Object;
|
||||||
pod.object.body.type = SPA_TYPE_OBJECT_ParamBuffers;
|
pod.object.body.type = MA_SPA_TYPE_OBJECT_ParamBuffers;
|
||||||
pod.object.body.id = SPA_PARAM_Buffers;
|
pod.object.body.id = MA_SPA_PARAM_Buffers;
|
||||||
|
|
||||||
pod.buffers = ma_spa_pod_prop_int_init(SPA_PARAM_BUFFERS_buffers, 2);
|
pod.buffers = ma_spa_pod_prop_int_init(MA_SPA_PARAM_BUFFERS_buffers, 2);
|
||||||
pod.blocks = ma_spa_pod_prop_int_init(SPA_PARAM_BUFFERS_blocks, 1);
|
pod.blocks = ma_spa_pod_prop_int_init(MA_SPA_PARAM_BUFFERS_blocks, 1);
|
||||||
pod.stride = ma_spa_pod_prop_int_init(SPA_PARAM_BUFFERS_stride, (ma_int32)strideInBytes);
|
pod.stride = ma_spa_pod_prop_int_init(MA_SPA_PARAM_BUFFERS_stride, (ma_int32)strideInBytes);
|
||||||
pod.size = ma_spa_pod_prop_int_init(SPA_PARAM_BUFFERS_size, (ma_int32)(strideInBytes * bufferSizeInFrames));
|
pod.size = ma_spa_pod_prop_int_init(MA_SPA_PARAM_BUFFERS_size, (ma_int32)(strideInBytes * bufferSizeInFrames));
|
||||||
|
|
||||||
return pod;
|
return pod;
|
||||||
}
|
}
|
||||||
@@ -625,27 +770,27 @@ static MA_INLINE struct ma_spa_pod_audio_info_raw ma_spa_pod_audio_info_raw_init
|
|||||||
MA_PIPEWIRE_ZERO_OBJECT(&pod);
|
MA_PIPEWIRE_ZERO_OBJECT(&pod);
|
||||||
|
|
||||||
pod.object.pod.size = sizeof(struct ma_spa_pod_object) - sizeof(struct ma_spa_pod); /* Don't include the header in the size. */
|
pod.object.pod.size = sizeof(struct ma_spa_pod_object) - sizeof(struct ma_spa_pod); /* Don't include the header in the size. */
|
||||||
pod.object.pod.type = SPA_TYPE_Object;
|
pod.object.pod.type = MA_SPA_TYPE_Object;
|
||||||
pod.object.body.type = SPA_TYPE_OBJECT_Format;
|
pod.object.body.type = MA_SPA_TYPE_OBJECT_Format;
|
||||||
pod.object.body.id = SPA_PARAM_EnumFormat;
|
pod.object.body.id = MA_SPA_PARAM_EnumFormat;
|
||||||
|
|
||||||
pod.mediaType = ma_spa_pod_prop_id_init(SPA_FORMAT_mediaType, SPA_MEDIA_TYPE_audio);
|
pod.mediaType = ma_spa_pod_prop_id_init(MA_SPA_FORMAT_mediaType, MA_SPA_MEDIA_TYPE_audio);
|
||||||
pod.object.pod.size += sizeof(struct ma_spa_pod_prop_id);
|
pod.object.pod.size += sizeof(struct ma_spa_pod_prop_id);
|
||||||
|
|
||||||
pod.mediaSubtype = ma_spa_pod_prop_id_init(SPA_FORMAT_mediaSubtype, SPA_MEDIA_SUBTYPE_raw);
|
pod.mediaSubtype = ma_spa_pod_prop_id_init(MA_SPA_FORMAT_mediaSubtype, MA_SPA_MEDIA_SUBTYPE_raw);
|
||||||
pod.object.pod.size += sizeof(struct ma_spa_pod_prop_id);
|
pod.object.pod.size += sizeof(struct ma_spa_pod_prop_id);
|
||||||
|
|
||||||
pod.format = ma_spa_pod_prop_id_init(SPA_FORMAT_AUDIO_format, (ma_uint32)format);
|
pod.format = ma_spa_pod_prop_id_init(MA_SPA_FORMAT_AUDIO_format, (ma_uint32)format);
|
||||||
pod.object.pod.size += sizeof(struct ma_spa_pod_prop_id);
|
pod.object.pod.size += sizeof(struct ma_spa_pod_prop_id);
|
||||||
|
|
||||||
if (channels > 0) {
|
if (channels > 0) {
|
||||||
pod.extra[extraIndex] = ma_spa_pod_prop_int_init(SPA_FORMAT_AUDIO_channels, (ma_int32)channels);
|
pod.extra[extraIndex] = ma_spa_pod_prop_int_init(MA_SPA_FORMAT_AUDIO_channels, (ma_int32)channels);
|
||||||
pod.object.pod.size += sizeof(struct ma_spa_pod_prop_int);
|
pod.object.pod.size += sizeof(struct ma_spa_pod_prop_int);
|
||||||
extraIndex += 1;
|
extraIndex += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sampleRate > 0) {
|
if (sampleRate > 0) {
|
||||||
pod.extra[extraIndex] = ma_spa_pod_prop_int_init(SPA_FORMAT_AUDIO_rate, (ma_int32)sampleRate);
|
pod.extra[extraIndex] = ma_spa_pod_prop_int_init(MA_SPA_FORMAT_AUDIO_rate, (ma_int32)sampleRate);
|
||||||
pod.object.pod.size += sizeof(struct ma_spa_pod_prop_int);
|
pod.object.pod.size += sizeof(struct ma_spa_pod_prop_int);
|
||||||
extraIndex += 1;
|
extraIndex += 1;
|
||||||
}
|
}
|
||||||
@@ -663,13 +808,13 @@ static MA_INLINE ma_uint32 ma_spa_pod_get_id_value(const struct ma_spa_pod* pod)
|
|||||||
|
|
||||||
switch (pod->type)
|
switch (pod->type)
|
||||||
{
|
{
|
||||||
case SPA_TYPE_Id:
|
case MA_SPA_TYPE_Id:
|
||||||
{
|
{
|
||||||
const struct ma_spa_pod_id* pPodID = (const struct ma_spa_pod_id*)pod;
|
const struct ma_spa_pod_id* pPodID = (const struct ma_spa_pod_id*)pod;
|
||||||
return pPodID->value;
|
return pPodID->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SPA_TYPE_Choice:
|
case MA_SPA_TYPE_Choice:
|
||||||
{
|
{
|
||||||
const struct ma_spa_pod_choice* pPodChoice = (const struct ma_spa_pod_choice*)pod;
|
const struct ma_spa_pod_choice* pPodChoice = (const struct ma_spa_pod_choice*)pod;
|
||||||
const void* pValues = ma_spa_pod_choice_get_values(pPodChoice);
|
const void* pValues = ma_spa_pod_choice_get_values(pPodChoice);
|
||||||
@@ -692,13 +837,13 @@ static MA_INLINE ma_int32 ma_spa_pod_get_int_value(const struct ma_spa_pod* pod)
|
|||||||
|
|
||||||
switch (pod->type)
|
switch (pod->type)
|
||||||
{
|
{
|
||||||
case SPA_TYPE_Id:
|
case MA_SPA_TYPE_Id:
|
||||||
{
|
{
|
||||||
const struct ma_spa_pod_int* pPodInt = (const struct ma_spa_pod_int*)pod;
|
const struct ma_spa_pod_int* pPodInt = (const struct ma_spa_pod_int*)pod;
|
||||||
return pPodInt->value;
|
return pPodInt->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SPA_TYPE_Choice:
|
case MA_SPA_TYPE_Choice:
|
||||||
{
|
{
|
||||||
const struct ma_spa_pod_choice* pPodChoice = (const struct ma_spa_pod_choice*)pod;
|
const struct ma_spa_pod_choice* pPodChoice = (const struct ma_spa_pod_choice*)pod;
|
||||||
const void* pValues = ma_spa_pod_choice_get_values(pPodChoice);
|
const void* pValues = ma_spa_pod_choice_get_values(pPodChoice);
|
||||||
@@ -854,7 +999,7 @@ struct ma_pw_stream_events
|
|||||||
void (* state_changed)(void* data, enum ma_pw_stream_state oldState, enum ma_pw_stream_state newState, const char* error);
|
void (* state_changed)(void* data, enum ma_pw_stream_state oldState, enum ma_pw_stream_state newState, const char* error);
|
||||||
void (* control_info )(void* data, ma_uint32 id, const struct ma_pw_stream_control* control);
|
void (* control_info )(void* data, ma_uint32 id, const struct ma_pw_stream_control* control);
|
||||||
void (* io_changed )(void* data, ma_uint32 id, void* area, ma_uint32 size);
|
void (* io_changed )(void* data, ma_uint32 id, void* area, ma_uint32 size);
|
||||||
void (* param_changed)(void* data, ma_uint32 id, const struct spa_pod* param);
|
void (* param_changed)(void* data, ma_uint32 id, const struct ma_spa_pod* param);
|
||||||
void (* add_buffer )(void* data, struct ma_pw_buffer* buffer);
|
void (* add_buffer )(void* data, struct ma_pw_buffer* buffer);
|
||||||
void (* remove_buffer)(void* data, struct ma_pw_buffer* buffer);
|
void (* remove_buffer)(void* data, struct ma_pw_buffer* buffer);
|
||||||
void (* process )(void* data);
|
void (* process )(void* data);
|
||||||
@@ -1316,7 +1461,7 @@ typedef struct
|
|||||||
} ma_enumerate_devices_data_pipewire;
|
} ma_enumerate_devices_data_pipewire;
|
||||||
|
|
||||||
|
|
||||||
static void ma_on_core_done__pipewire(void* pUserData, uint32_t id, int seq)
|
static void ma_on_core_done__pipewire(void* pUserData, ma_uint32 id, int seq)
|
||||||
{
|
{
|
||||||
ma_enumerate_devices_data_pipewire* pEnumData = (ma_enumerate_devices_data_pipewire*)pUserData;
|
ma_enumerate_devices_data_pipewire* pEnumData = (ma_enumerate_devices_data_pipewire*)pUserData;
|
||||||
|
|
||||||
@@ -1454,7 +1599,7 @@ static struct ma_pw_metadata_events ma_gMetadataEventsPipeWire =
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static void ma_registry_event_global_add_enumeration_by_type__pipewire(ma_enumerate_devices_data_pipewire* pEnumData, uint32_t id, uint32_t permissions, const char* type, uint32_t version, const struct ma_spa_dict* props, ma_device_type deviceType)
|
static void ma_registry_event_global_add_enumeration_by_type__pipewire(ma_enumerate_devices_data_pipewire* pEnumData, ma_uint32 id, ma_uint32 permissions, const char* type, ma_uint32 version, const struct ma_spa_dict* props, ma_device_type deviceType)
|
||||||
{
|
{
|
||||||
ma_device_info deviceInfo;
|
ma_device_info deviceInfo;
|
||||||
const char* pNodeName; /* <-- This is the ID. */
|
const char* pNodeName; /* <-- This is the ID. */
|
||||||
@@ -1498,7 +1643,7 @@ static void ma_registry_event_global_add_enumeration_by_type__pipewire(ma_enumer
|
|||||||
/*printf("Registry Global Added By Type: ID=%u, Type=%s, DeviceType=%d, NiceName=%s\n", id, type, deviceType, pNiceName);*/
|
/*printf("Registry Global Added By Type: ID=%u, Type=%s, DeviceType=%d, NiceName=%s\n", id, type, deviceType, pNiceName);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ma_registry_event_global_add_enumeration__pipewire(void* pUserData, uint32_t id, uint32_t permissions, const char* type, uint32_t version, const struct ma_spa_dict* props)
|
static void ma_registry_event_global_add_enumeration__pipewire(void* pUserData, ma_uint32 id, ma_uint32 permissions, const char* type, ma_uint32 version, const struct ma_spa_dict* props)
|
||||||
{
|
{
|
||||||
ma_enumerate_devices_data_pipewire* pEnumData = (ma_enumerate_devices_data_pipewire*)pUserData;
|
ma_enumerate_devices_data_pipewire* pEnumData = (ma_enumerate_devices_data_pipewire*)pUserData;
|
||||||
const char* pMediaClass;
|
const char* pMediaClass;
|
||||||
@@ -1516,7 +1661,7 @@ static void ma_registry_event_global_add_enumeration__pipewire(void* pUserData,
|
|||||||
if (pName != NULL && strcmp(pName, "default") == 0) {
|
if (pName != NULL && strcmp(pName, "default") == 0) {
|
||||||
pEnumData->pMetadata = (struct ma_pw_metadata*)pEnumData->pContextStatePipeWire->pw_registry_bind(pEnumData->pRegistry, id, MA_PW_TYPE_INTERFACE_Metadata, MA_PW_VERSION_METADATA, 0);
|
pEnumData->pMetadata = (struct ma_pw_metadata*)pEnumData->pContextStatePipeWire->pw_registry_bind(pEnumData->pRegistry, id, MA_PW_TYPE_INTERFACE_Metadata, MA_PW_VERSION_METADATA, 0);
|
||||||
if (pEnumData->pMetadata != NULL) {
|
if (pEnumData->pMetadata != NULL) {
|
||||||
spa_zero(pEnumData->metadataListener);
|
MA_PIPEWIRE_ZERO_OBJECT(&pEnumData->metadataListener);
|
||||||
|
|
||||||
/* Not using pw_metadata_add_listener() because it appears to be an inline function and thus not exported by libpipewire. */
|
/* Not using pw_metadata_add_listener() because it appears to be an inline function and thus not exported by libpipewire. */
|
||||||
((struct ma_pw_metadata_methods*)((struct ma_spa_interface*)pEnumData->pMetadata)->cb.funcs)->add_listener(pEnumData->pMetadata, &pEnumData->metadataListener, &ma_gMetadataEventsPipeWire, pEnumData);
|
((struct ma_pw_metadata_methods*)((struct ma_spa_interface*)pEnumData->pMetadata)->cb.funcs)->add_listener(pEnumData->pMetadata, &pEnumData->metadataListener, &ma_gMetadataEventsPipeWire, pEnumData);
|
||||||
@@ -1604,7 +1749,7 @@ static ma_result ma_context_enumerate_devices__pipewire(ma_context* pContext, ma
|
|||||||
|
|
||||||
ma_enumerate_devices_data_pipewire_init(&enumData, pContextStatePipeWire, pLoop, pCore, pRegistry, ma_context_get_allocation_callbacks(pContext));
|
ma_enumerate_devices_data_pipewire_init(&enumData, pContextStatePipeWire, pLoop, pCore, pRegistry, ma_context_get_allocation_callbacks(pContext));
|
||||||
|
|
||||||
spa_zero(registeryListener);
|
MA_PIPEWIRE_ZERO_OBJECT(®isteryListener);
|
||||||
pContextStatePipeWire->pw_registry_add_listener(pRegistry, ®isteryListener, &ma_gRegistryEventsPipeWire_Enumeration, &enumData);
|
pContextStatePipeWire->pw_registry_add_listener(pRegistry, ®isteryListener, &ma_gRegistryEventsPipeWire_Enumeration, &enumData);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1689,12 +1834,12 @@ static ma_result ma_context_enumerate_devices__pipewire(ma_context* pContext, ma
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void ma_stream_event_param_changed__pipewire(void* pUserData, ma_uint32 id, const struct spa_pod* pParam, ma_device_type deviceType)
|
static void ma_stream_event_param_changed__pipewire(void* pUserData, ma_uint32 id, const struct ma_spa_pod* pParam, ma_device_type deviceType)
|
||||||
{
|
{
|
||||||
ma_device_state_pipewire* pDeviceStatePipeWire = (ma_device_state_pipewire*)pUserData;
|
ma_device_state_pipewire* pDeviceStatePipeWire = (ma_device_state_pipewire*)pUserData;
|
||||||
ma_context_state_pipewire* pContextStatePipeWire = pDeviceStatePipeWire->pContextStatePipeWire;
|
ma_context_state_pipewire* pContextStatePipeWire = pDeviceStatePipeWire->pContextStatePipeWire;
|
||||||
|
|
||||||
if (id == SPA_PARAM_Format) {
|
if (id == MA_SPA_PARAM_Format) {
|
||||||
ma_pipewire_stream_state* pStreamState;
|
ma_pipewire_stream_state* pStreamState;
|
||||||
struct ma_spa_pod_buffer_params bufferParams;
|
struct ma_spa_pod_buffer_params bufferParams;
|
||||||
const struct ma_spa_pod* pBufferParameters[1];
|
const struct ma_spa_pod* pBufferParameters[1];
|
||||||
@@ -1738,7 +1883,7 @@ static void ma_stream_event_param_changed__pipewire(void* pUserData, ma_uint32 i
|
|||||||
ma_uint32 cursor = 0;
|
ma_uint32 cursor = 0;
|
||||||
ma_uint32 size;
|
ma_uint32 size;
|
||||||
|
|
||||||
if (pParam->type != SPA_TYPE_Object || pParam->size < sizeof(struct ma_spa_pod_object_body)) {
|
if (pParam->type != MA_SPA_TYPE_Object || pParam->size < sizeof(struct ma_spa_pod_object_body)) {
|
||||||
ma_log_postf(pContextStatePipeWire->pLog, MA_LOG_LEVEL_ERROR, "Failed to parse PipeWire format parameter (invalid pod type).");
|
ma_log_postf(pContextStatePipeWire->pLog, MA_LOG_LEVEL_ERROR, "Failed to parse PipeWire format parameter (invalid pod type).");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1749,7 +1894,7 @@ static void ma_stream_event_param_changed__pipewire(void* pUserData, ma_uint32 i
|
|||||||
size = pParam->size + sizeof(struct ma_spa_pod);
|
size = pParam->size + sizeof(struct ma_spa_pod);
|
||||||
cursor += sizeof(struct ma_spa_pod);
|
cursor += sizeof(struct ma_spa_pod);
|
||||||
|
|
||||||
if (pObject->body.type != SPA_TYPE_OBJECT_Format) {
|
if (pObject->body.type != MA_SPA_TYPE_OBJECT_Format) {
|
||||||
ma_log_postf(pContextStatePipeWire->pLog, MA_LOG_LEVEL_ERROR, "Failed to parse PipeWire format parameter (invalid body type).");
|
ma_log_postf(pContextStatePipeWire->pLog, MA_LOG_LEVEL_ERROR, "Failed to parse PipeWire format parameter (invalid body type).");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1772,27 +1917,27 @@ static void ma_stream_event_param_changed__pipewire(void* pUserData, ma_uint32 i
|
|||||||
|
|
||||||
switch (pNextProp->key)
|
switch (pNextProp->key)
|
||||||
{
|
{
|
||||||
case SPA_FORMAT_AUDIO_format:
|
case MA_SPA_FORMAT_AUDIO_format:
|
||||||
{
|
{
|
||||||
formatPA = (enum ma_spa_audio_format)ma_spa_pod_get_id_value(pPropValue);
|
formatPA = (enum ma_spa_audio_format)ma_spa_pod_get_id_value(pPropValue);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case SPA_FORMAT_AUDIO_channels:
|
case MA_SPA_FORMAT_AUDIO_channels:
|
||||||
{
|
{
|
||||||
channels = ma_spa_pod_get_int_value(pPropValue);
|
channels = ma_spa_pod_get_int_value(pPropValue);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case SPA_FORMAT_AUDIO_rate:
|
case MA_SPA_FORMAT_AUDIO_rate:
|
||||||
{
|
{
|
||||||
sampleRate = ma_spa_pod_get_int_value(pPropValue);
|
sampleRate = ma_spa_pod_get_int_value(pPropValue);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case SPA_FORMAT_AUDIO_position:
|
case MA_SPA_FORMAT_AUDIO_position:
|
||||||
{
|
{
|
||||||
ma_uint32 positionCount;
|
ma_uint32 positionCount;
|
||||||
|
|
||||||
/* I'm assuming we can only get an array back for this. */
|
/* I'm assuming we can only get an array back for this. */
|
||||||
if (pPropValue->type != SPA_TYPE_Array) {
|
if (pPropValue->type != MA_SPA_TYPE_Array) {
|
||||||
ma_log_postf(pContextStatePipeWire->pLog, MA_LOG_LEVEL_ERROR, "Failed to parse PipeWire format parameter (invalid type for position property).");
|
ma_log_postf(pContextStatePipeWire->pLog, MA_LOG_LEVEL_ERROR, "Failed to parse PipeWire format parameter (invalid type for position property).");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1830,9 +1975,18 @@ static void ma_stream_event_param_changed__pipewire(void* pUserData, ma_uint32 i
|
|||||||
{
|
{
|
||||||
struct ma_spa_dict_item items[1];
|
struct ma_spa_dict_item items[1];
|
||||||
struct ma_spa_dict dict;
|
struct ma_spa_dict dict;
|
||||||
|
char bufferSizeInFramesStr[32];
|
||||||
|
char sampleRateStr[32];
|
||||||
char latencyStr[32];
|
char latencyStr[32];
|
||||||
|
|
||||||
snprintf(latencyStr, sizeof(latencyStr), "%u/%u", (unsigned int)pStreamState->bufferSizeInFrames, pStreamState->sampleRate);
|
ma_pipewire_itoa_s(pStreamState->bufferSizeInFrames, bufferSizeInFramesStr, sizeof(bufferSizeInFramesStr), 10);
|
||||||
|
ma_pipewire_itoa_s(pStreamState->sampleRate, sampleRateStr, sizeof(sampleRateStr), 10);
|
||||||
|
|
||||||
|
latencyStr[0] = '\0';
|
||||||
|
ma_pipewire_strcat_s(latencyStr, sizeof(latencyStr), bufferSizeInFramesStr);
|
||||||
|
ma_pipewire_strcat_s(latencyStr, sizeof(latencyStr), "/");
|
||||||
|
ma_pipewire_strcat_s(latencyStr, sizeof(latencyStr), sampleRateStr);
|
||||||
|
|
||||||
items[0] = MA_SPA_DICT_ITEM_INIT(MA_PW_KEY_NODE_LATENCY, latencyStr);
|
items[0] = MA_SPA_DICT_ITEM_INIT(MA_PW_KEY_NODE_LATENCY, latencyStr);
|
||||||
|
|
||||||
dict = MA_SPA_DICT_INIT(items, 1);
|
dict = MA_SPA_DICT_INIT(items, 1);
|
||||||
@@ -2010,12 +2164,12 @@ static void ma_stream_event_process__pipewire(void* pUserData, ma_device_type de
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void ma_stream_event_param_changed_playback__pipewire(void* pUserData, ma_uint32 id, const struct spa_pod* pParam)
|
static void ma_stream_event_param_changed_playback__pipewire(void* pUserData, ma_uint32 id, const struct ma_spa_pod* pParam)
|
||||||
{
|
{
|
||||||
ma_stream_event_param_changed__pipewire(pUserData, id, pParam, ma_device_type_playback);
|
ma_stream_event_param_changed__pipewire(pUserData, id, pParam, ma_device_type_playback);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ma_stream_event_param_changed_capture__pipewire(void* pUserData, ma_uint32 id, const struct spa_pod* pParam)
|
static void ma_stream_event_param_changed_capture__pipewire(void* pUserData, ma_uint32 id, const struct ma_spa_pod* pParam)
|
||||||
{
|
{
|
||||||
ma_stream_event_param_changed__pipewire(pUserData, id, pParam, ma_device_type_capture);
|
ma_stream_event_param_changed__pipewire(pUserData, id, pParam, ma_device_type_capture);
|
||||||
}
|
}
|
||||||
@@ -2436,9 +2590,11 @@ static ma_device_backend_vtable ma_gDeviceBackendVTable_PipeWire =
|
|||||||
|
|
||||||
ma_device_backend_vtable* ma_device_backend_pipewire = &ma_gDeviceBackendVTable_PipeWire;
|
ma_device_backend_vtable* ma_device_backend_pipewire = &ma_gDeviceBackendVTable_PipeWire;
|
||||||
|
|
||||||
|
#if 0
|
||||||
#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
|
#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
ma_device_backend_vtable* ma_device_backend_pipewire = NULL;
|
ma_device_backend_vtable* ma_device_backend_pipewire = NULL;
|
||||||
#endif /* MA_HAS_PIPEWIRE */
|
#endif /* MA_HAS_PIPEWIRE */
|
||||||
|
|||||||
@@ -1,23 +1,3 @@
|
|||||||
/*
|
|
||||||
The PipeWire backend depends on the libspa development packages. On Debian-based distributions,
|
|
||||||
this can be installed with:
|
|
||||||
|
|
||||||
sudo apt install libspa-0.2-dev
|
|
||||||
|
|
||||||
If using Ubuntu, this may install it in a "spa-0.2" subfolder. In this case, you might need
|
|
||||||
to add the following to your build command:
|
|
||||||
|
|
||||||
-I/usr/include/spa-0.2
|
|
||||||
|
|
||||||
Unfortunately PipeWire has a hard dependency on the above package, and because it's made up
|
|
||||||
entirely of non-trivial inlined code, it's not practical to avoid this dependency. It's for
|
|
||||||
this reason the PipeWire backend cannot be included in miniaudio.h since it has a requirement
|
|
||||||
that it does not depend on external development packages. To use the PipeWire backend, you
|
|
||||||
need to plug it in as a custom backend. See the custom_backend example for how to do this.
|
|
||||||
|
|
||||||
The PipeWire backend cannot be used with `-std=c89`. This is because the SPA headers do not
|
|
||||||
support it.
|
|
||||||
*/
|
|
||||||
#ifndef miniaudio_backend_pipewire_h
|
#ifndef miniaudio_backend_pipewire_h
|
||||||
#define miniaudio_backend_pipewire_h
|
#define miniaudio_backend_pipewire_h
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user