mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2024-12-04 01:51:06 +00:00
commit
e63ea6698e
7 changed files with 351 additions and 0 deletions
|
@ -88,6 +88,7 @@ option ( enable-winmidi "compile Windows MIDI support (if it is available)" on )
|
||||||
option ( enable-sdl2 "compile SDL2 audio support (if it is available)" on )
|
option ( enable-sdl2 "compile SDL2 audio support (if it is available)" on )
|
||||||
option ( enable-pkgconfig "use pkg-config to locate fluidsynth's (mostly optional) dependencies" on )
|
option ( enable-pkgconfig "use pkg-config to locate fluidsynth's (mostly optional) dependencies" on )
|
||||||
option ( enable-pulseaudio "compile PulseAudio support (if it is available)" on )
|
option ( enable-pulseaudio "compile PulseAudio support (if it is available)" on )
|
||||||
|
option ( enable-pipewire "compile PipeWire support (if it is available)" on )
|
||||||
option ( enable-readline "compile readline lib line editing (if it is available)" on )
|
option ( enable-readline "compile readline lib line editing (if it is available)" on )
|
||||||
option ( enable-threads "enable multi-threading support (such as parallel voice synthesis)" on )
|
option ( enable-threads "enable multi-threading support (such as parallel voice synthesis)" on )
|
||||||
option ( enable-openmp "enable OpenMP support (parallelization of soundfont decoding, vectorization of voice mixing, etc.)" on )
|
option ( enable-openmp "enable OpenMP support (parallelization of soundfont decoding, vectorization of voice mixing, etc.)" on )
|
||||||
|
@ -595,6 +596,14 @@ else(NOT enable-pkgconfig)
|
||||||
unset_pkg_config ( JACK )
|
unset_pkg_config ( JACK )
|
||||||
endif ( enable-jack )
|
endif ( enable-jack )
|
||||||
|
|
||||||
|
unset ( PIPEWIRE_SUPPORT CACHE )
|
||||||
|
if ( enable-pipewire )
|
||||||
|
pkg_check_modules ( PIPEWIRE libpipewire-0.3 )
|
||||||
|
set ( PIPEWIRE_SUPPORT ${PIPEWIRE_FOUND} )
|
||||||
|
else ( enable-pipewire )
|
||||||
|
unset_pkg_config ( PIPEWIRE )
|
||||||
|
endif ( enable-pipewire )
|
||||||
|
|
||||||
unset ( LASH_SUPPORT CACHE )
|
unset ( LASH_SUPPORT CACHE )
|
||||||
if ( enable-lash )
|
if ( enable-lash )
|
||||||
pkg_check_modules ( LASH lash-1.0>=0.3 )
|
pkg_check_modules ( LASH lash-1.0>=0.3 )
|
||||||
|
@ -830,6 +839,7 @@ link_directories (
|
||||||
${GLIB_LIBRARY_DIRS}
|
${GLIB_LIBRARY_DIRS}
|
||||||
${LASH_LIBRARY_DIRS}
|
${LASH_LIBRARY_DIRS}
|
||||||
${JACK_LIBRARY_DIRS}
|
${JACK_LIBRARY_DIRS}
|
||||||
|
${PIPEWIRE_LIBRARY_DIRS}
|
||||||
${ALSA_LIBRARY_DIRS}
|
${ALSA_LIBRARY_DIRS}
|
||||||
${PULSE_LIBRARY_DIRS}
|
${PULSE_LIBRARY_DIRS}
|
||||||
${PORTAUDIO_LIBRARY_DIRS}
|
${PORTAUDIO_LIBRARY_DIRS}
|
||||||
|
|
|
@ -31,6 +31,12 @@ else ( JACK_SUPPORT )
|
||||||
set ( AUDIO_MIDI_REPORT "${AUDIO_MIDI_REPORT} JACK: no\n" )
|
set ( AUDIO_MIDI_REPORT "${AUDIO_MIDI_REPORT} JACK: no\n" )
|
||||||
endif ( JACK_SUPPORT )
|
endif ( JACK_SUPPORT )
|
||||||
|
|
||||||
|
if ( PIPEWIRE_SUPPORT )
|
||||||
|
set ( AUDIO_MIDI_REPORT "${AUDIO_MIDI_REPORT} PipeWire: yes\n" )
|
||||||
|
else ( PIPEWIRE_SUPPORT )
|
||||||
|
set ( AUDIO_MIDI_REPORT "${AUDIO_MIDI_REPORT} PipeWire: no\n" )
|
||||||
|
endif ( PIPEWIRE_SUPPORT )
|
||||||
|
|
||||||
if ( MIDISHARE_SUPPORT )
|
if ( MIDISHARE_SUPPORT )
|
||||||
set ( AUDIO_MIDI_REPORT "${AUDIO_MIDI_REPORT} MidiShare: yes\n" )
|
set ( AUDIO_MIDI_REPORT "${AUDIO_MIDI_REPORT} MidiShare: yes\n" )
|
||||||
else ( MIDISHARE_SUPPORT )
|
else ( MIDISHARE_SUPPORT )
|
||||||
|
|
|
@ -75,6 +75,11 @@ if ( JACK_SUPPORT )
|
||||||
include_directories ( ${JACK_INCLUDE_DIRS} )
|
include_directories ( ${JACK_INCLUDE_DIRS} )
|
||||||
endif ( JACK_SUPPORT )
|
endif ( JACK_SUPPORT )
|
||||||
|
|
||||||
|
if ( PIPEWIRE_SUPPORT )
|
||||||
|
set ( fluid_pipewire_SOURCES drivers/fluid_pipewire.c )
|
||||||
|
include_directories ( SYSTEM ${PIPEWIRE_INCLUDE_DIRS} )
|
||||||
|
endif ( PIPEWIRE_SUPPORT )
|
||||||
|
|
||||||
if ( PORTAUDIO_SUPPORT )
|
if ( PORTAUDIO_SUPPORT )
|
||||||
set ( fluid_portaudio_SOURCES drivers/fluid_portaudio.c )
|
set ( fluid_portaudio_SOURCES drivers/fluid_portaudio.c )
|
||||||
include_directories ( ${PORTAUDIO_INCLUDE_DIRS} )
|
include_directories ( ${PORTAUDIO_INCLUDE_DIRS} )
|
||||||
|
@ -277,6 +282,7 @@ add_library ( libfluidsynth-OBJ OBJECT
|
||||||
${fluid_dart_SOURCES}
|
${fluid_dart_SOURCES}
|
||||||
${fluid_dbus_SOURCES}
|
${fluid_dbus_SOURCES}
|
||||||
${fluid_jack_SOURCES}
|
${fluid_jack_SOURCES}
|
||||||
|
${fluid_pipewire_SOURCES}
|
||||||
${fluid_lash_SOURCES}
|
${fluid_lash_SOURCES}
|
||||||
${fluid_midishare_SOURCES}
|
${fluid_midishare_SOURCES}
|
||||||
${fluid_opensles_SOURCES}
|
${fluid_opensles_SOURCES}
|
||||||
|
@ -353,6 +359,7 @@ target_link_libraries ( libfluidsynth
|
||||||
${GMODULE_LIBRARIES}
|
${GMODULE_LIBRARIES}
|
||||||
${LASH_LIBRARIES}
|
${LASH_LIBRARIES}
|
||||||
${JACK_LIBRARIES}
|
${JACK_LIBRARIES}
|
||||||
|
${PIPEWIRE_LIBRARIES}
|
||||||
${ALSA_LIBRARIES}
|
${ALSA_LIBRARIES}
|
||||||
${PULSE_LIBRARIES}
|
${PULSE_LIBRARIES}
|
||||||
${PORTAUDIO_LIBRARIES}
|
${PORTAUDIO_LIBRARIES}
|
||||||
|
|
|
@ -130,6 +130,9 @@
|
||||||
/* Define to enable JACK driver */
|
/* Define to enable JACK driver */
|
||||||
#cmakedefine JACK_SUPPORT @JACK_SUPPORT@
|
#cmakedefine JACK_SUPPORT @JACK_SUPPORT@
|
||||||
|
|
||||||
|
/* Define to enable PipeWire driver */
|
||||||
|
#cmakedefine PIPEWIRE_SUPPORT @PIPEWIRE_SUPPORT@
|
||||||
|
|
||||||
/* Include the LADSPA Fx unit */
|
/* Include the LADSPA Fx unit */
|
||||||
#cmakedefine LADSPA @LADSPA_SUPPORT@
|
#cmakedefine LADSPA @LADSPA_SUPPORT@
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,16 @@ static const fluid_audriver_definition_t fluid_audio_drivers[] =
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if PIPEWIRE_SUPPORT
|
||||||
|
{
|
||||||
|
"pipewire",
|
||||||
|
new_fluid_pipewire_audio_driver,
|
||||||
|
new_fluid_pipewire_audio_driver2,
|
||||||
|
delete_fluid_pipewire_audio_driver,
|
||||||
|
fluid_pipewire_audio_driver_settings
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
|
||||||
#if OSS_SUPPORT
|
#if OSS_SUPPORT
|
||||||
{
|
{
|
||||||
"oss",
|
"oss",
|
||||||
|
|
|
@ -138,6 +138,14 @@ void fluid_jack_audio_driver_settings(fluid_settings_t *settings);
|
||||||
int fluid_jack_obtain_synth(fluid_settings_t *settings, fluid_synth_t **synth);
|
int fluid_jack_obtain_synth(fluid_settings_t *settings, fluid_synth_t **synth);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if PIPEWIRE_SUPPORT
|
||||||
|
fluid_audio_driver_t *new_fluid_pipewire_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth);
|
||||||
|
fluid_audio_driver_t *new_fluid_pipewire_audio_driver2(fluid_settings_t *settings,
|
||||||
|
fluid_audio_func_t func, void *data);
|
||||||
|
void delete_fluid_pipewire_audio_driver(fluid_audio_driver_t *p);
|
||||||
|
void fluid_pipewire_audio_driver_settings(fluid_settings_t *settings);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if SNDMAN_SUPPORT
|
#if SNDMAN_SUPPORT
|
||||||
fluid_audio_driver_t *new_fluid_sndmgr_audio_driver(fluid_settings_t *settings,
|
fluid_audio_driver_t *new_fluid_sndmgr_audio_driver(fluid_settings_t *settings,
|
||||||
fluid_synth_t *synth);
|
fluid_synth_t *synth);
|
||||||
|
|
307
src/drivers/fluid_pipewire.c
Normal file
307
src/drivers/fluid_pipewire.c
Normal file
|
@ -0,0 +1,307 @@
|
||||||
|
/* FluidSynth - A Software Synthesizer
|
||||||
|
*
|
||||||
|
* Copyright (C) 2003 Peter Hanappe and others.
|
||||||
|
* Copyright (C) 2021 E. "sykhro" Melucci
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free
|
||||||
|
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* fluid_pipewire.c
|
||||||
|
*
|
||||||
|
* Audio driver for PipeWire.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "fluid_synth.h"
|
||||||
|
#include "fluid_adriver.h"
|
||||||
|
#include "fluid_settings.h"
|
||||||
|
|
||||||
|
#if PIPEWIRE_SUPPORT
|
||||||
|
|
||||||
|
#include <pipewire/pipewire.h>
|
||||||
|
#include <spa/param/audio/format-utils.h>
|
||||||
|
|
||||||
|
/* At the moment, only stereo is supported */
|
||||||
|
#define NUM_CHANNELS 2
|
||||||
|
static const int stride = sizeof(float) * NUM_CHANNELS;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
fluid_audio_driver_t driver;
|
||||||
|
fluid_audio_func_t user_callback;
|
||||||
|
void *data;
|
||||||
|
|
||||||
|
/* Used only with the user-provided callback */
|
||||||
|
float *lbuf, *rbuf;
|
||||||
|
|
||||||
|
int buffer_period;
|
||||||
|
struct spa_pod_builder *builder;
|
||||||
|
|
||||||
|
struct pw_thread_loop *pw_loop;
|
||||||
|
struct pw_stream *pw_stream;
|
||||||
|
struct pw_stream_events *events;
|
||||||
|
|
||||||
|
} fluid_pipewire_audio_driver_t;
|
||||||
|
|
||||||
|
|
||||||
|
/* Fast-path rendering routine with no user processing callbacks */
|
||||||
|
static void fluid_pipewire_event_process(void *data)
|
||||||
|
{
|
||||||
|
fluid_pipewire_audio_driver_t *drv = data;
|
||||||
|
struct pw_buffer *pwb;
|
||||||
|
struct spa_buffer *buf;
|
||||||
|
float *dest;
|
||||||
|
|
||||||
|
pwb = pw_stream_dequeue_buffer(drv->pw_stream);
|
||||||
|
if (!pwb)
|
||||||
|
{
|
||||||
|
FLUID_LOG(FLUID_WARN, "No buffers!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = pwb->buffer;
|
||||||
|
dest = buf->datas[0].data;
|
||||||
|
if (!dest)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fluid_synth_write_float(drv->data, drv->buffer_period, dest, 0, 2, dest, 1, 2);
|
||||||
|
buf->datas[0].chunk->offset = 0;
|
||||||
|
buf->datas[0].chunk->stride = stride;
|
||||||
|
buf->datas[0].chunk->size = drv->buffer_period * stride;
|
||||||
|
|
||||||
|
pw_stream_queue_buffer(drv->pw_stream, pwb);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Rendering routine with support for user-defined audio manipulation */
|
||||||
|
static void fluid_pipewire_event_process2(void *data)
|
||||||
|
{
|
||||||
|
fluid_pipewire_audio_driver_t *drv = data;
|
||||||
|
struct pw_buffer *pwb;
|
||||||
|
struct spa_buffer *buf;
|
||||||
|
float *dest;
|
||||||
|
float *channels[NUM_CHANNELS] = { drv->lbuf, drv->rbuf };
|
||||||
|
int i;
|
||||||
|
|
||||||
|
pwb = pw_stream_dequeue_buffer(drv->pw_stream);
|
||||||
|
if (!pwb)
|
||||||
|
{
|
||||||
|
FLUID_LOG(FLUID_WARN, "No buffers!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = pwb->buffer;
|
||||||
|
dest = buf->datas[0].data;
|
||||||
|
if (!dest)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FLUID_MEMSET(drv->lbuf, 0, drv->buffer_period * sizeof(float));
|
||||||
|
FLUID_MEMSET(drv->rbuf, 0, drv->buffer_period * sizeof(float));
|
||||||
|
|
||||||
|
(*drv->user_callback)(drv->data, drv->buffer_period, 0, NULL, NUM_CHANNELS, channels);
|
||||||
|
|
||||||
|
/* Interleave the floating point data */
|
||||||
|
for (i = 0; i < drv->buffer_period; i++)
|
||||||
|
{
|
||||||
|
dest[i * 2] = drv->lbuf[i];
|
||||||
|
dest[i * 2 + 1] = drv->rbuf[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
buf->datas[0].chunk->offset = 0;
|
||||||
|
buf->datas[0].chunk->stride = stride;
|
||||||
|
buf->datas[0].chunk->size = drv->buffer_period * stride;
|
||||||
|
|
||||||
|
pw_stream_queue_buffer(drv->pw_stream, pwb);
|
||||||
|
}
|
||||||
|
|
||||||
|
fluid_audio_driver_t *new_fluid_pipewire_audio_driver(fluid_settings_t *settings, fluid_synth_t *synth)
|
||||||
|
{
|
||||||
|
return new_fluid_pipewire_audio_driver2(settings, NULL, synth);
|
||||||
|
}
|
||||||
|
|
||||||
|
fluid_audio_driver_t *
|
||||||
|
new_fluid_pipewire_audio_driver2(fluid_settings_t *settings, fluid_audio_func_t func, void *data)
|
||||||
|
{
|
||||||
|
fluid_pipewire_audio_driver_t *drv;
|
||||||
|
int period_size;
|
||||||
|
int buffer_length;
|
||||||
|
int res;
|
||||||
|
int pw_flags;
|
||||||
|
int realtime_prio = 0;
|
||||||
|
double sample_rate;
|
||||||
|
char *media_role = NULL;
|
||||||
|
char *media_type = NULL;
|
||||||
|
char *media_category = NULL;
|
||||||
|
float *buffer = NULL;
|
||||||
|
const struct spa_pod *params[1];
|
||||||
|
|
||||||
|
drv = FLUID_NEW(fluid_pipewire_audio_driver_t);
|
||||||
|
if (!drv)
|
||||||
|
{
|
||||||
|
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
FLUID_MEMSET(drv, 0, sizeof(*drv));
|
||||||
|
|
||||||
|
fluid_settings_getint(settings, "audio.period-size", &period_size);
|
||||||
|
fluid_settings_getint(settings, "audio.realtime-prio", &realtime_prio);
|
||||||
|
fluid_settings_getnum(settings, "synth.sample-rate", &sample_rate);
|
||||||
|
fluid_settings_dupstr(settings, "audio.pipewire.media-role", &media_role);
|
||||||
|
fluid_settings_dupstr(settings, "audio.pipewire.media-type", &media_type);
|
||||||
|
fluid_settings_dupstr(settings, "audio.pipewire.media-category", &media_category);
|
||||||
|
|
||||||
|
drv->data = data;
|
||||||
|
drv->user_callback = func;
|
||||||
|
drv->buffer_period = period_size;
|
||||||
|
|
||||||
|
drv->events = FLUID_NEW(struct pw_stream_events);
|
||||||
|
if (!drv->events)
|
||||||
|
{
|
||||||
|
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||||
|
goto driver cleanup;
|
||||||
|
}
|
||||||
|
FLUID_MEMSET(drv->events, 0, sizeof(*drv->events));
|
||||||
|
drv->events->version = PW_VERSION_STREAM_EVENTS;
|
||||||
|
drv->events->process = func ? fluid_pipewire_event_process2 : fluid_pipewire_event_process;
|
||||||
|
|
||||||
|
drv->pw_loop = pw_thread_loop_new("fluid_pipewire", NULL);
|
||||||
|
if (!drv->pw_loop)
|
||||||
|
{
|
||||||
|
FLUID_LOG(FLUID_ERR, "Failed to allocate PipeWire loop");
|
||||||
|
goto driver_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
drv->pw_stream = pw_stream_new_simple(
|
||||||
|
pw_thread_loop_get_loop(drv->pw_loop),
|
||||||
|
"FluidSynth",
|
||||||
|
pw_properties_new(PW_KEY_MEDIA_TYPE, media_type, PW_KEY_MEDIA_CATEGORY, media_category, PW_KEY_MEDIA_ROLE, media_role, NULL),
|
||||||
|
drv->events,
|
||||||
|
drv);
|
||||||
|
if (!drv->pw_stream)
|
||||||
|
{
|
||||||
|
FLUID_LOG(FLUID_ERR, "Failed to allocate PipeWire stream");
|
||||||
|
goto driver_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = FLUID_ARRAY(float, NUM_CHANNELS *period_size);
|
||||||
|
if (!buffer)
|
||||||
|
{
|
||||||
|
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||||
|
goto driver_cleanup;
|
||||||
|
}
|
||||||
|
buffer_length = period_size * sizeof(float) * NUM_CHANNELS;
|
||||||
|
|
||||||
|
drv->builder = FLUID_NEW(struct spa_pod_builder);
|
||||||
|
if (!drv->builder)
|
||||||
|
{
|
||||||
|
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||||
|
goto driver_cleanup;
|
||||||
|
}
|
||||||
|
FLUID_MEMSET(drv->builder, 0, sizeof(*drv->builder));
|
||||||
|
drv->builder->data = buffer;
|
||||||
|
drv->builder->size = buffer_length;
|
||||||
|
|
||||||
|
if (func)
|
||||||
|
{
|
||||||
|
drv->lbuf = FLUID_ARRAY(float, period_size);
|
||||||
|
drv->rbuf = FLUID_ARRAY(float, period_size);
|
||||||
|
|
||||||
|
if (!drv->lbuf || !drv->rbuf)
|
||||||
|
{
|
||||||
|
FLUID_LOG(FLUID_ERR, "Out of memory");
|
||||||
|
goto driver_cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
params[0] = spa_format_audio_raw_build(drv->builder,
|
||||||
|
SPA_PARAM_EnumFormat,
|
||||||
|
&SPA_AUDIO_INFO_RAW_INIT(.format = SPA_AUDIO_FORMAT_F32,
|
||||||
|
.channels = 2,
|
||||||
|
.rate = sample_rate));
|
||||||
|
|
||||||
|
pw_flags = PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_MAP_BUFFERS;
|
||||||
|
pw_flags |= realtime_prio ? PW_STREAM_FLAG_RT_PROCESS : 0;
|
||||||
|
res = pw_stream_connect(drv->pw_stream, PW_DIRECTION_OUTPUT, PW_ID_ANY, pw_flags, params, 1);
|
||||||
|
if (res < 0)
|
||||||
|
{
|
||||||
|
FLUID_LOG(FLUID_ERR, "PipeWire stream connection failed");
|
||||||
|
goto driver_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = pw_thread_loop_start(drv->pw_loop);
|
||||||
|
if (res != 0)
|
||||||
|
{
|
||||||
|
FLUID_LOG(FLUID_ERR, "Failed starting PipeWire loop");
|
||||||
|
goto driver_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
FLUID_LOG(FLUID_INFO, "Using PipeWire audio driver");
|
||||||
|
|
||||||
|
free(media_role);
|
||||||
|
free(media_type);
|
||||||
|
free(media_category);
|
||||||
|
|
||||||
|
return (fluid_audio_driver_t *)drv;
|
||||||
|
|
||||||
|
driver_cleanup:
|
||||||
|
free(media_role);
|
||||||
|
free(media_type);
|
||||||
|
free(media_category);
|
||||||
|
|
||||||
|
delete_fluid_pipewire_audio_driver((fluid_audio_driver_t *)drv);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void delete_fluid_pipewire_audio_driver(fluid_audio_driver_t *p)
|
||||||
|
{
|
||||||
|
fluid_pipewire_audio_driver_t *drv = (fluid_pipewire_audio_driver_t *)p;
|
||||||
|
fluid_return_if_fail(drv);
|
||||||
|
|
||||||
|
if (drv->pw_stream)
|
||||||
|
{
|
||||||
|
pw_stream_destroy(drv->pw_stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (drv->pw_loop)
|
||||||
|
{
|
||||||
|
pw_thread_loop_destroy(drv->pw_loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
FLUID_FREE(drv->lbuf);
|
||||||
|
FLUID_FREE(drv->rbuf);
|
||||||
|
|
||||||
|
if (drv->builder)
|
||||||
|
{
|
||||||
|
FLUID_FREE(drv->builder->data);
|
||||||
|
}
|
||||||
|
FLUID_FREE(drv->builder);
|
||||||
|
|
||||||
|
FLUID_FREE(drv->events);
|
||||||
|
|
||||||
|
FLUID_FREE(drv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fluid_pipewire_audio_driver_settings(fluid_settings_t *settings)
|
||||||
|
{
|
||||||
|
fluid_settings_register_str(settings, "audio.pipewire.media-role", "Music", 0);
|
||||||
|
fluid_settings_register_str(settings, "audio.pipewire.media-type", "Audio", 0);
|
||||||
|
fluid_settings_register_str(settings, "audio.pipewire.media-category", "Playback", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue