#pragma once #include namespace dsp { class MonoToStereo : public generic_block { public: MonoToStereo() {} MonoToStereo(stream* in) { init(in); } void init(stream* in) { _in = in; generic_block::registerInput(_in); generic_block::registerOutput(&out); generic_block::_block_init = true; } void setInput(stream* in) { assert(generic_block::_block_init); std::lock_guard lck(generic_block::ctrlMtx); generic_block::tempStop(); generic_block::unregisterInput(_in); _in = in; generic_block::registerInput(_in); generic_block::tempStart(); } int run() { int count = _in->read(); if (count < 0) { return -1; } volk_32f_x2_interleave_32fc((lv_32fc_t*)out.writeBuf, _in->readBuf, _in->readBuf, count); _in->flush(); if (!out.swap(count)) { return -1; } return count; } stream out; private: stream* _in; }; class ChannelsToStereo : public generic_block { public: ChannelsToStereo() {} ChannelsToStereo(stream* in_left, stream* in_right) { init(in_left, in_right); } void init(stream* in_left, stream* in_right) { _in_left = in_left; _in_right = in_right; nullbuf = new float[STREAM_BUFFER_SIZE]; for (int i = 0; i < STREAM_BUFFER_SIZE; i++) { nullbuf[i] = 0; } generic_block::registerInput(_in_left); generic_block::registerInput(_in_right); generic_block::registerOutput(&out); generic_block::_block_init = true; } void setInput(stream* in_left, stream* in_right) { assert(generic_block::_block_init); std::lock_guard lck(generic_block::ctrlMtx); generic_block::tempStop(); generic_block::unregisterInput(_in_left); generic_block::unregisterInput(_in_right); _in_left = in_left; _in_right = in_right; generic_block::registerInput(_in_left); generic_block::registerInput(_in_right); generic_block::tempStart(); } int run() { int count_l = _in_left->read(); if (count_l < 0) { return -1; } int count_r = _in_right->read(); if (count_r < 0) { return -1; } if (count_l != count_r) { spdlog::warn("ChannelsToStereo block size mismatch"); } volk_32f_x2_interleave_32fc((lv_32fc_t*)out.writeBuf, _in_left->readBuf, _in_right->readBuf, count_l); _in_left->flush(); _in_right->flush(); if (!out.swap(count_l)) { return -1; } return count_l; } stream out; private: stream* _in_left; stream* _in_right; float* nullbuf; }; class StereoToMono : public generic_block { public: StereoToMono() {} StereoToMono(stream* in) { init(in); } ~StereoToMono() { if (!generic_block::_block_init) { return; } generic_block::stop(); delete[] l_buf; delete[] r_buf; generic_block::_block_init = false; } void init(stream* in) { _in = in; l_buf = new float[STREAM_BUFFER_SIZE]; r_buf = new float[STREAM_BUFFER_SIZE]; generic_block::registerInput(_in); generic_block::registerOutput(&out); generic_block::_block_init = true; } void setInput(stream* in) { assert(generic_block::_block_init); std::lock_guard lck(generic_block::ctrlMtx); generic_block::tempStop(); generic_block::unregisterInput(_in); _in = in; generic_block::registerInput(_in); generic_block::tempStart(); } int run() { int count = _in->read(); if (count < 0) { return -1; } for (int i = 0; i < count; i++) { out.writeBuf[i] = (_in->readBuf[i].l + _in->readBuf[i].r) * 0.5f; } _in->flush(); if (!out.swap(count)) { return -1; } return count; } stream out; private: float* l_buf, *r_buf; stream* _in; }; class StereoToChannels : public generic_block { public: StereoToChannels() {} StereoToChannels(stream* in) { init(in); } void init(stream* in) { _in = in; generic_block::registerInput(_in); generic_block::registerOutput(&out_left); generic_block::registerOutput(&out_right); generic_block::_block_init = true; } void setInput(stream* in) { assert(generic_block::_block_init); std::lock_guard lck(generic_block::ctrlMtx); generic_block::tempStop(); generic_block::unregisterInput(_in); _in = in; generic_block::registerInput(_in); generic_block::tempStart(); } int run() { int count = _in->read(); if (count < 0) { return -1; } volk_32fc_deinterleave_32f_x2(out_left.writeBuf, out_right.writeBuf, (lv_32fc_t*)_in->readBuf, count); _in->flush(); if (!out_left.swap(count)) { return -1; } if (!out_right.swap(count)) { return -1; } return count; } stream out_left; stream out_right; private: stream* _in; }; }