diff --git a/source_modules/rtl_tcp_source/src/rtl_tcp_client.cpp b/source_modules/rtl_tcp_source/src/rtl_tcp_client.cpp new file mode 100644 index 00000000..4a03abb5 --- /dev/null +++ b/source_modules/rtl_tcp_source/src/rtl_tcp_client.cpp @@ -0,0 +1,101 @@ +#include "rtl_tcp_client.h" + +namespace rtltcp { + Client::Client(std::shared_ptr sock, dsp::stream* stream) { + this->sock = sock; + this->stream = stream; + + // Start worker + workerThread = std::thread(&Client::worker, this); + } + + Client::~Client() { + close(); + } + + bool Client::isOpen() { + return sock->isOpen(); + } + + void Client::close() { + sock->close(); + stream->stopWriter(); + if (workerThread.joinable()) { + workerThread.join(); + } + stream->clearWriteStop(); + } + + void Client::setFrequency(double freq) { + sendCommand(1, freq); + } + + void Client::setSampleRate(double sr) { + sendCommand(2, sr); + bufferSize = sr / 200.0; + } + + void Client::setGainMode(int mode) { + sendCommand(3, mode); + } + + void Client::setGain(double gain) { + sendCommand(4, gain); + } + + void Client::setPPM(int ppm) { + sendCommand(5, (uint32_t)ppm); + } + + void Client::setAGCMode(int mode) { + sendCommand(8, mode); + } + + void Client::setDirectSampling(int mode) { + sendCommand(9, mode); + } + + void Client::setOffsetTuning(bool enabled) { + sendCommand(10, enabled); + } + + void Client::setGainIndex(int index) { + sendCommand(13, index); + } + + void Client::setBiasTee(bool enabled) { + sendCommand(14, enabled); + } + + void Client::sendCommand(uint8_t command, uint32_t param) { + Command cmd = { command, htonl(param) }; + sock->send((uint8_t*)&cmd, sizeof(Command)); + } + + void Client::worker() { + uint8_t* buffer = dsp::buffer::alloc(STREAM_BUFFER_SIZE*2); + + while (true) { + // Read data + int count = sock->recv(buffer, bufferSize * 2, true); + if (count <= 0) { break; } + + // Convert to complex float + int scount = count/2; + for (int i = 0; i < scount; i++) { + stream->writeBuf[i].re = ((double)buffer[i * 2] - 128.0) / 128.0; + stream->writeBuf[i].im = ((double)buffer[(i * 2) + 1] - 128.0) / 128.0; + } + + // Swap buffer + if (!stream->swap(scount)) { break; } + } + + dsp::buffer::free(buffer); + } + + std::shared_ptr connect(dsp::stream* stream, std::string host, int port) { + auto sock = net::connect(host, port); + return std::make_shared(sock, stream); + } +} \ No newline at end of file diff --git a/source_modules/rtl_tcp_source/src/rtl_tcp_client.h b/source_modules/rtl_tcp_source/src/rtl_tcp_client.h new file mode 100644 index 00000000..a7a5055c --- /dev/null +++ b/source_modules/rtl_tcp_source/src/rtl_tcp_client.h @@ -0,0 +1,44 @@ +#pragma once +#include +#include +#include + +namespace rtltcp { +#pragma pack(push, 1) + struct Command { + uint8_t cmd; + uint32_t param; + }; +#pragma pack(pop) + + class Client { + public: + Client(std::shared_ptr sock, dsp::stream* stream); + ~Client(); + + bool isOpen(); + void close(); + + void setFrequency(double freq); + void setSampleRate(double sr); + void setGainMode(int mode); + void setGain(double gain); + void setPPM(int ppm); + void setAGCMode(int mode); + void setDirectSampling(int mode); + void setOffsetTuning(bool enabled); + void setGainIndex(int index); + void setBiasTee(bool enabled); + + private: + void sendCommand(uint8_t command, uint32_t param); + void worker(); + + std::shared_ptr sock; + std::thread workerThread; + dsp::stream* stream; + int bufferSize = 2400000 / 200; + }; + + std::shared_ptr connect(dsp::stream* stream, std::string host, int port = 1234); +} \ No newline at end of file