Basic whitenoise generator
This commit is contained in:
parent
1c607a875c
commit
48a0cd1377
3 changed files with 93 additions and 13 deletions
|
@ -2,4 +2,4 @@
|
|||
|
||||
build: main.out
|
||||
main.out: main.o
|
||||
$(CC) $(LDFLAGS) $^ -o $@
|
||||
$(CXX) $(LDFLAGS) $^ -o $@
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
#include <pipewire/pipewire.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
pw_init(&argc, &argv);
|
||||
|
||||
fprintf(stdout, "Compiled with libpipewire %s\n"
|
||||
"Linked with libpipewire %s\n",
|
||||
pw_get_headers_version(),
|
||||
pw_get_library_version());
|
||||
return 0;
|
||||
}
|
92
pw_plugin/main.cc
Normal file
92
pw_plugin/main.cc
Normal file
|
@ -0,0 +1,92 @@
|
|||
#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;
|
||||
}
|
Loading…
Add table
Reference in a new issue