#include "passthrough.h" #include 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(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); }