#pragma once #include #include namespace dsp { template class Block { public: Block(std::vector inBs, std::vector outBs, D* inst, void (*workerFunc)(D* _this)) { derived = inst; worker = workerFunc; inputBlockSize = inBs; outputBlockSize = outBs; in.reserve(IC); out.reserve(OC); for (int i = 0; i < IC; i++) { in.push_back(NULL); } for (int i = 0; i < OC; i++) { out.push_back(new stream(outBs[i] * 2)); } } void start() { if (running) { return; } running = true; startHandler(); workerThread = std::thread(worker, derived); } void stop() { if (!running) { return; } stopHandler(); for (auto is : in) { is->stopReader(); } for (auto os : out) { os->stopWriter(); } workerThread.join(); for (auto is : in) { is->clearReadStop(); } for (auto os : out) { os->clearWriteStop(); } running = false; } virtual void setBlockSize(int blockSize) { if (running) { return; } for (int i = 0; i < IC; i++) { in[i]->setMaxLatency(blockSize * 2); inputBlockSize[i] = blockSize; } for (int i = 0; i < OC; i++) { out[i]->setMaxLatency(blockSize * 2); outputBlockSize[i] = blockSize; } } std::vector*> out; protected: virtual void startHandler() {} virtual void stopHandler() {} std::vector*> in; std::vector inputBlockSize; std::vector outputBlockSize; bool running = false; private: void (*worker)(D* _this); std::thread workerThread; D* derived; }; class DemoMultiplier : public Block { public: DemoMultiplier() : Block({2}, {1}, this, worker) {} void init(stream* a, stream* b, int blockSize) { in[0] = a; in[1] = b; inputBlockSize[0] = blockSize; inputBlockSize[1] = blockSize; out[0]->setMaxLatency(blockSize * 2); outputBlockSize[0] = blockSize; } private: static void worker(DemoMultiplier* _this) { int blockSize = _this->inputBlockSize[0]; stream* inA = _this->in[0]; stream* inB = _this->in[1]; stream* out = _this->out[0]; complex_t* aBuf = (complex_t*)volk_malloc(sizeof(complex_t) * blockSize, volk_get_alignment()); complex_t* bBuf = (complex_t*)volk_malloc(sizeof(complex_t) * blockSize, volk_get_alignment()); complex_t* outBuf = (complex_t*)volk_malloc(sizeof(complex_t) * blockSize, volk_get_alignment()); while (true) { if (inA->read(aBuf, blockSize) < 0) { break; }; if (inB->read(bBuf, blockSize) < 0) { break; }; volk_32fc_x2_multiply_32fc((lv_32fc_t*)outBuf, (lv_32fc_t*)aBuf, (lv_32fc_t*)bBuf, blockSize); if (out->write(outBuf, blockSize) < 0) { break; }; } volk_free(aBuf); volk_free(bBuf); volk_free(outBuf); } }; };