#include #include #include "pipewire-binding.h" #define SAMPLING_RATE 48000 #define CHANNELS 2 #define VOLUME 0.7 #define NODE_NAME "soundbox" #define STRIDE sizeof(int16_t) * CHANNELS static void on_process(void *userdata) { struct pw_stream *stream = *(struct pw_stream **)userdata; struct pw_buffer *pw_buf; struct spa_buffer *spa_buf; int n_frames; int16_t *src; if ((pw_buf = pw_stream_dequeue_buffer(stream)) == NULL) { return; } spa_buf = pw_buf->buffer; if ((src = spa_buf->datas[0].data) == NULL) { return; } n_frames = spa_buf->datas[0].chunk->size / STRIDE; if (pw_buf->requested) { n_frames = SPA_MIN(pw_buf->requested, n_frames); } size_t len = spa_buf->datas[0].chunk->size; goHandleData(src, len); spa_buf->datas[0].chunk->offset = 0; spa_buf->datas[0].chunk->stride = STRIDE; spa_buf->datas[0].chunk->size = n_frames * STRIDE; pw_stream_queue_buffer(stream, pw_buf); } static const struct pw_stream_events stream_events = { .version = PW_VERSION_STREAM_EVENTS, .process = on_process, }; void pw_stdout(void) { pw_init(NULL, NULL); struct pw_main_loop *loop = pw_main_loop_new(NULL); struct pw_stream *stream = NULL; stream = pw_stream_new_simple( pw_main_loop_get_loop(loop), NODE_NAME, pw_properties_new( PW_KEY_MEDIA_TYPE, "Audio", PW_KEY_CONFIG_NAME, "client-rt.conf", PW_KEY_MEDIA_CATEGORY, "Capture", PW_KEY_MEDIA_ROLE, "Music", NULL ), &stream_events, &stream ); uint8_t buffer[1024]; struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer)); const struct spa_pod *params[] = { spa_format_audio_raw_build( &b, SPA_PARAM_EnumFormat, &SPA_AUDIO_INFO_RAW_INIT( .format = SPA_AUDIO_FORMAT_S16, .channels = CHANNELS, .rate = SAMPLING_RATE ) ) }; pw_stream_connect( stream, PW_DIRECTION_INPUT, PW_ID_ANY, PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_MAP_BUFFERS | PW_STREAM_FLAG_RT_PROCESS, params, sizeof(params) / sizeof(params[0]) ); pw_main_loop_run(loop); pw_stream_destroy(stream); pw_main_loop_destroy(loop); pw_deinit(); }