diff --git a/source_modules/hermes_source/src/hermes.cpp b/source_modules/hermes_source/src/hermes.cpp index 68ad7827..a96c7fdb 100644 --- a/source_modules/hermes_source/src/hermes.cpp +++ b/source_modules/hermes_source/src/hermes.cpp @@ -2,6 +2,13 @@ #include namespace hermes { + const int SAMPLERATE_LIST[] = { + 48000, + 96000, + 192000, + 384000 + }; + Client::Client(std::shared_ptr sock) { this->sock = sock; @@ -33,6 +40,7 @@ namespace hermes { void Client::setSamplerate(HermesLiteSamplerate samplerate) { writeReg(0, (uint32_t)samplerate << 24); + blockSize = SAMPLERATE_LIST[samplerate] / 200; } void Client::setFrequency(double freq) { @@ -157,6 +165,8 @@ namespace hermes { void Client::worker() { uint8_t rbuf[2048]; MetisUSBPacket* pkt = (MetisUSBPacket*)rbuf; + int sampleCount = 0; + while (true) { // Wait for a packet or exit if connection closed int len = sock->recv(rbuf, 2048); @@ -183,9 +193,10 @@ namespace hermes { flog::warn("Got response! Reg={0}, Seq={1}", reg, (uint32_t)htonl(pkt->seq)); } - // Decode and send IQ to stream + // Decode and save IQ to buffer uint8_t* iq = &frame[8]; - for (int i = 0; i < 63; i++) { + dsp::complex_t* writeBuf = &out.writeBuf[sampleCount]; + for (int i = 0; i < HERMES_SAMPLES_PER_FRAME; i++) { // Convert to 32bit int32_t si = ((uint32_t)iq[(i*8) + 0] << 16) | ((uint32_t)iq[(i*8) + 1] << 8) | (uint32_t)iq[(i*8) + 2]; int32_t sq = ((uint32_t)iq[(i*8) + 3] << 16) | ((uint32_t)iq[(i*8) + 4] << 8) | (uint32_t)iq[(i*8) + 5]; @@ -195,11 +206,16 @@ namespace hermes { sq = (sq << 8) >> 8; // Convert to float (IQ swapped for some reason) - out.writeBuf[i].im = (float)si / (float)0x1000000; - out.writeBuf[i].re = (float)sq / (float)0x1000000; + writeBuf[i].im = (float)si / (float)0x1000000; + writeBuf[i].re = (float)sq / (float)0x1000000; + } + sampleCount += HERMES_SAMPLES_PER_FRAME; + + // If enough samples are in the buffer, send to stream + if (sampleCount >= blockSize) { + out.swap(sampleCount); + sampleCount = 0; } - out.swap(63); - // TODO: Buffer the data to avoid having a very high DSP frame rate } } } diff --git a/source_modules/hermes_source/src/hermes.h b/source_modules/hermes_source/src/hermes.h index 0d76ea7f..78628f10 100644 --- a/source_modules/hermes_source/src/hermes.h +++ b/source_modules/hermes_source/src/hermes.h @@ -7,11 +7,12 @@ #include #include -#define HERMES_METIS_REPEAT 5 -#define HERMES_METIS_TIMEOUT 1000 -#define HERMES_METIS_SIGNATURE 0xEFFE -#define HERMES_HPSDR_USB_SYNC 0x7F -#define HERMES_I2C_DELAY 50 +#define HERMES_METIS_REPEAT 5 +#define HERMES_METIS_TIMEOUT 1000 +#define HERMES_METIS_SIGNATURE 0xEFFE +#define HERMES_HPSDR_USB_SYNC 0x7F +#define HERMES_I2C_DELAY 50 +#define HERMES_SAMPLES_PER_FRAME 63 namespace hermes { enum MetisPacketType { @@ -140,7 +141,7 @@ namespace hermes { dsp::stream out; - //private: + private: void sendMetisUSB(uint8_t endpoint, void* frame0, void* frame1 = NULL); void sendMetisControl(MetisControl ctrl); @@ -149,12 +150,12 @@ namespace hermes { void writeI2C(I2CPort port, uint8_t addr, uint8_t reg, uint8_t data); - - void worker(); double freq = 0; + int blockSize = 63; + std::thread workerThread; std::shared_ptr sock; uint32_t usbSeq = 0;