/*********************************************************************** * work functions **********************************************************************/ void ConstellationDisplay::handleSamples(const Pothos::BufferChunk &buff) { if (_queueDepth.fetch_sub(1) != 1) return; //create curve that it doesnt exist if (not _curve) { _curve.reset(new QwtPlotCurve()); _curve->attach(_mainPlot); _curve->setPen(pastelize(getDefaultCurveColor(0)), 2.0); _curve->setStyle(QwtPlotCurve::Dots); } //convert to points and post to curve const auto samps = buff.as<const std::complex<float> *>(); QVector<QPointF> points(buff.elements()); for (int i = 0; i < points.size(); i++) { points[i] = QPointF(samps[i].real(), samps[i].imag()); } _curve->setSamples(points); //replot _mainPlot->replot(); }
/*********************************************************************** * buffer chunk to/from numpy **********************************************************************/ static Pothos::Proxy convertBufferChunkToNumpyArray(Pothos::ProxyEnvironment::Sptr env, const Pothos::BufferChunk &buffer) { auto module = env->findProxy("Pothos.Buffer"); auto dtype = module.get("dtype_to_numpy")(buffer.dtype); return module.get("pointer_to_ndarray")(buffer.address, buffer.elements(), dtype); }
void work(void) { auto inputPort = this->input(0); auto outputPort = this->output(0); size_t consumed = 0; //get input buffer auto inBuff = inputPort->buffer(); if (inBuff.length == 0) return; //label propagation offset incremented as preambles are posted size_t labelIndexOffset = 0; //track the index of the last found frame start label int lastFoundIndex = -1; for (auto &label : inputPort->labels()) { // Skip any label that doesn't yet appear in the data buffer if (label.index >= inputPort->elements()) continue; Pothos::Label outLabel(label); //modified and posted below //increment the offset as soon as we are past the last found index if (lastFoundIndex != -1 and size_t(lastFoundIndex) != label.index) { lastFoundIndex = -1; labelIndexOffset += _preambleBuff.elements(); } if (label.id == _frameStartId) { //post everything before this label Pothos::BufferChunk headBuff = inBuff; size_t headElems = label.index - consumed; headBuff.length = headElems*sizeof(Type); if (headBuff.length != 0) outputPort->postBuffer(headBuff); //fill the preamble buffer Pothos::BufferChunk newPreambleBuff(typeid(Type), _preambleBuff.elements()); std::memcpy(newPreambleBuff.as<void *>(), _preambleBuff.as<const void *>(), _preambleBuff.length); auto p = newPreambleBuff.as<Type *>() + _syncWordWidth; //encode the header field into bits char headerBits[NUM_HEADER_BITS]; FrameHeaderFields headerFields; headerFields.id = _headerId; headerFields.length = 0; if (label.data.canConvert(typeid(size_t))) { headerFields.length = label.data.template convert<size_t>()*label.width; } headerFields.chksum = headerFields.doChecksum(); encodeHeaderWord(headerBits, headerFields); //encode header fields as BPSK into the preamble buffer const auto sym = _preamble.back(); for (size_t i = 0; i < NUM_HEADER_BITS; i++) { *p++ = (headerBits[i] != 0)?+sym:-sym; } //post the preamble buffer outputPort->postBuffer(newPreambleBuff); //remove header from the remaining buffer inBuff.length -= headBuff.length; inBuff.address += headBuff.length; consumed += headBuff.elements(); //mark for increment on next label index lastFoundIndex = label.index; } else if (label.id == _frameEndId) { //post everything before this label Pothos::BufferChunk headBuff = inBuff; size_t headElems = label.index + label.width - consumed; //place at end of width headBuff.length = headElems*sizeof(Type); headBuff.length = std::min(headBuff.length, inBuff.length); //bounds check if (headBuff.length != 0) outputPort->postBuffer(headBuff); //post the buffer outputPort->postBuffer(_paddingBuff); //remove header from the remaining buffer inBuff.length -= headBuff.length; inBuff.address += headBuff.length; consumed += headBuff.elements(); //increment index for insertion of padding labelIndexOffset += _paddingBuff.elements(); } //propagate labels here with the offset outLabel.index += labelIndexOffset; outputPort->postLabel(outLabel); } //post the remaining bytes if (inBuff.length != 0) outputPort->postBuffer(inBuff); //consume the entire buffer inputPort->consume(inputPort->elements()); }