#pragma once #include namespace dsp { class MonoToStereo : public generic_block { public: MonoToStereo() {} MonoToStereo(stream* in) { init(in); } ~MonoToStereo() { generic_block::stop(); } void init(stream* in) { _in = in; generic_block::registerInput(_in); generic_block::registerOutput(&out); } void setInput(stream* in) { 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() { count = _in->read(); if (count < 0) { return -1; } for (int i = 0; i < count; i++) { out.writeBuf[i].l = _in->readBuf[i]; out.writeBuf[i].r = _in->readBuf[i]; } _in->flush(); if (!out.swap(count)) { return -1; } return count; } stream out; private: int count; stream* _in; }; class ChannelsToStereo : public generic_block { public: ChannelsToStereo() {} ChannelsToStereo(stream* in_left, stream* in_right) { init(in_left, in_right); } ~ChannelsToStereo() { generic_block::stop(); } void init(stream* in_left, stream* in_right) { _in_left = in_left; _in_right = in_right; generic_block::registerInput(_in_left); generic_block::registerInput(_in_right); generic_block::registerOutput(&out); } void setInput(stream* in_left, stream* in_right) { 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() { count_l = _in_left->read(); if (count_l < 0) { return -1; } count_r = _in_right->read(); if (count_r < 0) { return -1; } if (count_l != count_r) { spdlog::warn("ChannelsToStereo block size missmatch"); } for (int i = 0; i < count_l; i++) { out.writeBuf[i].l = _in_left->readBuf[i]; out.writeBuf[i].r = _in_right->readBuf[i]; } _in_left->flush(); _in_right->flush(); if (!out.swap(count_l)) { return -1; } return count_l; } stream out; private: int count_l; int count_r; stream* _in_left; stream* _in_right; }; class StereoToMono : public generic_block { public: StereoToMono() {} StereoToMono(stream* in) { init(in); } ~StereoToMono() { generic_block::stop(); } void init(stream* in) { _in = in; generic_block::registerInput(_in); generic_block::registerOutput(&out); } void setInput(stream* in) { 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() { 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) / 2.0f; } _in->flush(); if (!out.swap(count)) { return -1; } return count; } stream out; private: int count; stream* _in; }; class StereoToChannels : public generic_block { public: StereoToChannels() {} StereoToChannels(stream* in) { init(in); } ~StereoToChannels() { generic_block::stop(); } void init(stream* in) { _in = in; generic_block::registerInput(_in); generic_block::registerOutput(&out_left); generic_block::registerOutput(&out_right); } void setInput(stream* in) { 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() { count = _in->read(); if (count < 0) { return -1; } for (int i = 0; i < count; i++) { out_left.writeBuf[i] = _in->readBuf[i].l; out_right.writeBuf[i] = _in->readBuf[i].r; } _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: int count; stream* _in; }; }