VIANC/pw_plugin/passthrough.cc

86 lines
2.1 KiB
C++

#include "passthrough.h"
#include <cmath>
logger_record::logger_record(pw_loop* lp, ringbuffer* r,
const char* strm_nm, const char* category) :
pwstream(48000, 2, 0, lp, strm_nm,
pw_properties_new(PW_KEY_MEDIA_TYPE, "Audio",
PW_KEY_MEDIA_CATEGORY, category,
PW_KEY_MEDIA_ROLE, "DSP", NULL)), rb(r) {}
void logger_record::on_process() {
pw_buffer* pwb;
if((pwb = pw_stream_dequeue_buffer(this->strm)) == nullptr) {
return;
}
auto* b = pwb->buffer;
float* src = (float*)b->datas[0].data;
if(src == nullptr) return;
auto n_frames = b->datas[0].chunk->size / (2 * sizeof(float));
auto headpos = rb->w_head_pos;
rb->enqueue(src, n_frames);
if(do_noise) {
for(size_t i = 0; i < n_frames; ++i) {
rb->buffer[headpos+0] += nd(rd);
rb->buffer[headpos+1] += nd(rd);
if((headpos+=2)>= ringbuffer::bsize) {
headpos -= ringbuffer::bsize;
}
}
}
pw_stream_queue_buffer(this->strm, pwb);
}
void logger_record::request_noise(bool flag, float stddev) {
nd = std::normal_distribution<float>(0.0, stddev);
do_noise = flag;
}
logger_playback::logger_playback(pw_loop* lp, ringbuffer* r,
bool lc, bool rc, bool noisy) :
pwstream(48000, 2, 1, lp, "aec-playback",
pw_properties_new(PW_KEY_MEDIA_TYPE, "Audio",
PW_KEY_MEDIA_CATEGORY, "Playback",
PW_KEY_MEDIA_ROLE, "DSP", NULL)),
rb(r), lcut(lc),rcut(rc) {}
void logger_playback::on_process() {
pw_buffer* pwb;
if((pwb = pw_stream_dequeue_buffer(this->strm)) == nullptr) {
return;
}
auto* b = pwb->buffer;
float* dst = (float*)b->datas[0].data;
if(dst == nullptr) return;
auto n_frames = b->datas[0].maxsize / (sizeof(float)*2);
if(pwb->requested) {
n_frames = SPA_MIN(pwb->requested, n_frames);
}
size_t effective = rb->dequeue(dst,n_frames);
if(lcut) {
for(size_t i = 0; i < effective; ++i) {
dst[2*i + 0] = 0.f;
}
}
if(rcut) {
for(size_t i = 0; i < effective; ++i) {
dst[2*i + 1] = 0.f;
}
}
b->datas[0].chunk->offset = 0;
b->datas[0].chunk->stride = sizeof(float)*2;
b->datas[0].chunk->size = effective*sizeof(float)*2;
pw_stream_queue_buffer(this->strm, pwb);
}