93 lines
2.1 KiB
C++
93 lines
2.1 KiB
C++
|
#include <random>
|
||
|
#include <cstdio>
|
||
|
#include "pipewire/pipewire.h"
|
||
|
#include "spa/param/audio/format-utils.h"
|
||
|
|
||
|
struct local_data {
|
||
|
pw_main_loop* loop;
|
||
|
pw_stream* stream;
|
||
|
|
||
|
std::mt19937 gen;
|
||
|
std::normal_distribution<float> nd{0, 0.3};
|
||
|
};
|
||
|
|
||
|
void on_process(local_data* ld) {
|
||
|
pw_buffer *b;
|
||
|
spa_buffer *buf;
|
||
|
if((b = pw_stream_dequeue_buffer(ld->stream)) == NULL) {
|
||
|
pw_log_warn("No buffers left!");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
buf = b->buffer;
|
||
|
|
||
|
float* dst;
|
||
|
if((dst = (float*)buf->datas[0].data) == NULL) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
int n_frames = buf->datas[0].maxsize / sizeof(float);
|
||
|
if(b->requested) {
|
||
|
n_frames = SPA_MIN(b->requested, n_frames);
|
||
|
}
|
||
|
|
||
|
for(int i = 0; i < n_frames; ++i) {
|
||
|
*dst++ = ld->nd(ld->gen);
|
||
|
}
|
||
|
|
||
|
buf->datas[0].chunk->offset = 0;
|
||
|
buf->datas[0].chunk->stride = sizeof(float);
|
||
|
buf->datas[0].chunk->size = n_frames * sizeof(float);
|
||
|
|
||
|
pw_stream_queue_buffer(ld->stream, b);
|
||
|
}
|
||
|
|
||
|
const struct pw_stream_events stream_events {
|
||
|
PW_VERSION_STREAM_EVENTS,
|
||
|
.process = (void(*)(void*))on_process,
|
||
|
};
|
||
|
|
||
|
int main(int argc, char** argv) {
|
||
|
// We do NOT seed the MT engine -> the time series will be predictable!
|
||
|
local_data bookkeep{nullptr,nullptr,};
|
||
|
|
||
|
pw_init(&argc, &argv);
|
||
|
bookkeep.loop = pw_main_loop_new(NULL);
|
||
|
|
||
|
bookkeep.stream = pw_stream_new_simple(
|
||
|
pw_main_loop_get_loop(bookkeep.loop),
|
||
|
"audio-src",
|
||
|
pw_properties_new(
|
||
|
PW_KEY_MEDIA_TYPE, "Audio",
|
||
|
PW_KEY_MEDIA_CATEGORY, "Playback",
|
||
|
PW_KEY_MEDIA_ROLE, "Test",
|
||
|
NULL),
|
||
|
&stream_events,
|
||
|
&bookkeep);
|
||
|
|
||
|
const spa_pod* params[1];
|
||
|
uint8_t buffer[1024];
|
||
|
spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
|
||
|
|
||
|
auto audio_info = SPA_AUDIO_INFO_RAW_INIT(
|
||
|
.format = SPA_AUDIO_FORMAT_F32_LE,
|
||
|
.rate = 44100,
|
||
|
.channels = 1,);
|
||
|
|
||
|
params[0] = spa_format_audio_raw_build(&b, SPA_PARAM_EnumFormat,&audio_info);
|
||
|
|
||
|
pw_stream_connect(bookkeep.stream,
|
||
|
PW_DIRECTION_OUTPUT,
|
||
|
PW_ID_ANY,
|
||
|
(pw_stream_flags)(PW_STREAM_FLAG_AUTOCONNECT |
|
||
|
PW_STREAM_FLAG_MAP_BUFFERS |
|
||
|
PW_STREAM_FLAG_RT_PROCESS),
|
||
|
params, 1);
|
||
|
|
||
|
pw_main_loop_run(bookkeep.loop);
|
||
|
|
||
|
pw_stream_destroy(bookkeep.stream);
|
||
|
pw_main_loop_destroy(bookkeep.loop);
|
||
|
return 0;
|
||
|
}
|