Beginning of code for the RSPduo + bugfix for the hackrf

This commit is contained in:
Ryzerth
2021-04-10 03:06:59 +02:00
parent 26e623bec4
commit d41ae73e0d
11 changed files with 1415 additions and 0 deletions

View File

@ -0,0 +1,65 @@
#pragma once
#include <dsp/block.h>
#include <dsp/utils/bitstream.h>
namespace dsp {
namespace meteor {
class HRPTDemux : public generic_block<HRPTDemux> {
public:
HRPTDemux() {}
HRPTDemux(stream<uint8_t>* in) { init(in); }
void init(stream<uint8_t>* in) {
_in = in;
generic_block<HRPTDemux>::registerInput(_in);
generic_block<HRPTDemux>::registerOutput(&telemOut);
generic_block<HRPTDemux>::registerOutput(&BISMout);
generic_block<HRPTDemux>::registerOutput(&SSPDOut);
generic_block<HRPTDemux>::registerOutput(&MTVZAOut);
generic_block<HRPTDemux>::registerOutput(&MSUMROut);
}
void setInput(stream<uint8_t>* in) {
std::lock_guard<std::mutex> lck(generic_block<HRPTDemux>::ctrlMtx);
generic_block<HRPTDemux>::tempStop();
generic_block<HRPTDemux>::unregisterInput(_in);
_in = in;
generic_block<HRPTDemux>::registerInput(_in);
generic_block<HRPTDemux>::tempStart();
}
int run() {
int count = _in->read();
if (count < 0) { return -1; }
for (int i = 0; i < 4; i++) {
memcpy(telemOut.writeBuf + (i * 2), _in->readBuf + 4 + (i * 256), 2);
memcpy(BISMout.writeBuf + (i * 4), _in->readBuf + 4 + (i * 256) + 2, 4);
memcpy(SSPDOut.writeBuf + (i * 4), _in->readBuf + 4 + (i * 256) + 6, 4);
memcpy(MTVZAOut.writeBuf + (i * 8), _in->readBuf + 4 + (i * 256) + 10, 8);
memcpy(MSUMROut.writeBuf + (i * 238), _in->readBuf + 4 + (i * 256) + 18, (i == 3) ? 234 : 238);
}
if (!telemOut.swap(8)) { return -1; }
if (!BISMout.swap(16)) { return -1; }
if (!SSPDOut.swap(16)) { return -1; }
if (!MTVZAOut.swap(32)) { return -1; }
if (!MSUMROut.swap(948)) { return -1; }
_in->flush();
return count;
}
stream<uint8_t> telemOut;
stream<uint8_t> BISMout;
stream<uint8_t> SSPDOut;
stream<uint8_t> MTVZAOut;
stream<uint8_t> MSUMROut;
private:
stream<uint8_t>* _in;
};
}
}

View File

@ -0,0 +1,76 @@
#pragma once
#include <dsp/block.h>
#include <dsp/utils/bitstream.h>
namespace dsp {
namespace meteor {
const uint64_t MSUMR_SYNC_WORD = 0x0218A7A392DD9ABF;
const uint8_t MSUMR_SYNC_BYTES[8] = { 0x02, 0x18, 0xA7, 0xA3, 0x92, 0xDD, 0x9A, 0xBF };
class MSUMRDemux : public generic_block<MSUMRDemux> {
public:
MSUMRDemux() {}
MSUMRDemux(stream<uint8_t>* in) { init(in); }
void init(stream<uint8_t>* in) {
_in = in;
generic_block<MSUMRDemux>::registerInput(_in);
generic_block<MSUMRDemux>::registerOutput(&msumr1Out);
generic_block<MSUMRDemux>::registerOutput(&msumr2Out);
generic_block<MSUMRDemux>::registerOutput(&msumr3Out);
generic_block<MSUMRDemux>::registerOutput(&msumr4Out);
generic_block<MSUMRDemux>::registerOutput(&msumr5Out);
generic_block<MSUMRDemux>::registerOutput(&msumr6Out);
}
void setInput(stream<uint8_t>* in) {
std::lock_guard<std::mutex> lck(generic_block<MSUMRDemux>::ctrlMtx);
generic_block<MSUMRDemux>::tempStop();
generic_block<MSUMRDemux>::unregisterInput(_in);
_in = in;
generic_block<MSUMRDemux>::registerInput(_in);
generic_block<MSUMRDemux>::tempStart();
}
int run() {
int count = _in->read();
if (count < 0) { return -1; }
int pixels = 0;
for (int i = 0; i < 11790; i += 30) {
for (int j = 0; j < 4; j++) {
msumr1Out.writeBuf[pixels + j] = (uint16_t)readBits((50 * 8) + (i * 8) + (j * 10), 10, _in->readBuf);
msumr2Out.writeBuf[pixels + j] = (uint16_t)readBits((50 * 8) + (i * 8) + (j * 10) + (40 * 1), 10, _in->readBuf);
msumr3Out.writeBuf[pixels + j] = (uint16_t)readBits((50 * 8) + (i * 8) + (j * 10) + (40 * 2), 10, _in->readBuf);
msumr4Out.writeBuf[pixels + j] = (uint16_t)readBits((50 * 8) + (i * 8) + (j * 10) + (40 * 3), 10, _in->readBuf);
msumr5Out.writeBuf[pixels + j] = (uint16_t)readBits((50 * 8) + (i * 8) + (j * 10) + (40 * 4), 10, _in->readBuf);
msumr6Out.writeBuf[pixels + j] = (uint16_t)readBits((50 * 8) + (i * 8) + (j * 10) + (40 * 5), 10, _in->readBuf);
}
pixels += 4;
}
if (!msumr1Out.swap(1572)) { return -1; }
if (!msumr2Out.swap(1572)) { return -1; }
if (!msumr3Out.swap(1572)) { return -1; }
if (!msumr4Out.swap(1572)) { return -1; }
if (!msumr5Out.swap(1572)) { return -1; }
if (!msumr6Out.swap(1572)) { return -1; }
_in->flush();
return count;
}
stream<uint16_t> msumr1Out;
stream<uint16_t> msumr2Out;
stream<uint16_t> msumr3Out;
stream<uint16_t> msumr4Out;
stream<uint16_t> msumr5Out;
stream<uint16_t> msumr6Out;
private:
stream<uint8_t>* _in;
};
}
}

109
core/src/dsp/noaa/hrpt.h Normal file
View File

@ -0,0 +1,109 @@
#pragma once
#include <dsp/block.h>
#include <dsp/utils/bitstream.h>
namespace dsp {
namespace noaa {
inline uint16_t HRPTReadWord(int offset, uint8_t* buffer) {
return (uint16_t)readBits(offset * 10, 10, buffer);
}
const uint8_t HRPTSyncWord[] = {
1,0,1,0,0,0,0,1,0,0,
0,1,0,1,1,0,1,1,1,1,
1,1,0,1,0,1,1,1,0,0,
0,1,1,0,0,1,1,1,0,1,
1,0,0,0,0,0,1,1,1,1,
0,0,1,0,0,1,0,1,0,1
};
class HRPTDemux : public generic_block<HRPTDemux> {
public:
HRPTDemux() {}
HRPTDemux(stream<uint8_t>* in) { init(in); }
void init(stream<uint8_t>* in) {
_in = in;
generic_block<HRPTDemux>::registerInput(_in);
generic_block<HRPTDemux>::registerOutput(&AVHRRChan1Out);
generic_block<HRPTDemux>::registerOutput(&AVHRRChan2Out);
generic_block<HRPTDemux>::registerOutput(&AVHRRChan3Out);
generic_block<HRPTDemux>::registerOutput(&AVHRRChan4Out);
generic_block<HRPTDemux>::registerOutput(&AVHRRChan5Out);
}
void setInput(stream<uint8_t>* in) {
std::lock_guard<std::mutex> lck(generic_block<HRPTDemux>::ctrlMtx);
generic_block<HRPTDemux>::tempStop();
generic_block<HRPTDemux>::unregisterInput(_in);
_in = in;
generic_block<HRPTDemux>::registerInput(_in);
generic_block<HRPTDemux>::tempStart();
}
int run() {
int count = _in->read();
if (count < 0) { return -1; }
int minFrame = readBits(61, 2, _in->readBuf);
// If GAC frame, reject
if (minFrame == 0) {
_in->flush();
return count;
}
// Extract TIP frames if present
if (minFrame == 1) {
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 104; j++) {
TIPOut.writeBuf[j] = (HRPTReadWord(103 + (i * 104) + j, _in->readBuf) >> 2) & 0xFF;
}
if (!TIPOut.swap(104)) { return -1; };
}
}
// Exctact AIP otherwise
else if (minFrame == 3) {
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 104; j++) {
AIPOut.writeBuf[j] = (HRPTReadWord(103 + (i * 104) + j, _in->readBuf) >> 2) & 0xFF;
}
if (!AIPOut.swap(104)) { return -1; };
}
}
// Extract AVHRR data
for (int i = 0; i < 2048; i++) {
AVHRRChan1Out.writeBuf[i] = HRPTReadWord(750 + (i * 5), _in->readBuf);
AVHRRChan2Out.writeBuf[i] = HRPTReadWord(750 + (i * 5) + 1, _in->readBuf);
AVHRRChan3Out.writeBuf[i] = HRPTReadWord(750 + (i * 5) + 2, _in->readBuf);
AVHRRChan4Out.writeBuf[i] = HRPTReadWord(750 + (i * 5) + 3, _in->readBuf);
AVHRRChan5Out.writeBuf[i] = HRPTReadWord(750 + (i * 5) + 4, _in->readBuf);
}
if (!AVHRRChan1Out.swap(2048)) { return -1; };
if (!AVHRRChan2Out.swap(2048)) { return -1; };
if (!AVHRRChan3Out.swap(2048)) { return -1; };
if (!AVHRRChan4Out.swap(2048)) { return -1; };
if (!AVHRRChan5Out.swap(2048)) { return -1; };
_in->flush();
return count;
}
stream<uint8_t> TIPOut;
stream<uint8_t> AIPOut;
stream<uint16_t> AVHRRChan1Out;
stream<uint16_t> AVHRRChan2Out;
stream<uint16_t> AVHRRChan3Out;
stream<uint16_t> AVHRRChan4Out;
stream<uint16_t> AVHRRChan5Out;
private:
stream<uint8_t>* _in;
};
}
}

240
core/src/dsp/noaa/tip.h Normal file
View File

@ -0,0 +1,240 @@
#pragma once
#include <dsp/block.h>
#include <dsp/utils/bitstream.h>
namespace dsp {
namespace noaa {
class TIPDemux : public generic_block<TIPDemux> {
public:
TIPDemux() {}
TIPDemux(stream<uint8_t>* in) { init(in); }
void init(stream<uint8_t>* in) {
_in = in;
generic_block<TIPDemux>::registerInput(_in);
generic_block<TIPDemux>::registerOutput(&HIRSOut);
generic_block<TIPDemux>::registerOutput(&SEMOut);
generic_block<TIPDemux>::registerOutput(&DCSOut);
generic_block<TIPDemux>::registerOutput(&SBUVOut);
}
void setInput(stream<uint8_t>* in) {
std::lock_guard<std::mutex> lck(generic_block<TIPDemux>::ctrlMtx);
generic_block<TIPDemux>::tempStop();
generic_block<TIPDemux>::unregisterInput(_in);
_in = in;
generic_block<TIPDemux>::registerInput(_in);
generic_block<TIPDemux>::tempStart();
}
int run() {
int count = _in->read();
if (count < 0) { return -1; }
// Extract HIRS
HIRSOut.writeBuf[0] = _in->readBuf[16];
HIRSOut.writeBuf[1] = _in->readBuf[17];
HIRSOut.writeBuf[2] = _in->readBuf[22];
HIRSOut.writeBuf[3] = _in->readBuf[23];
HIRSOut.writeBuf[4] = _in->readBuf[26];
HIRSOut.writeBuf[5] = _in->readBuf[27];
HIRSOut.writeBuf[6] = _in->readBuf[30];
HIRSOut.writeBuf[7] = _in->readBuf[31];
HIRSOut.writeBuf[8] = _in->readBuf[34];
HIRSOut.writeBuf[9] = _in->readBuf[35];
HIRSOut.writeBuf[10] = _in->readBuf[38];
HIRSOut.writeBuf[11] = _in->readBuf[39];
HIRSOut.writeBuf[12] = _in->readBuf[42];
HIRSOut.writeBuf[13] = _in->readBuf[43];
HIRSOut.writeBuf[14] = _in->readBuf[54];
HIRSOut.writeBuf[15] = _in->readBuf[55];
HIRSOut.writeBuf[16] = _in->readBuf[58];
HIRSOut.writeBuf[17] = _in->readBuf[59];
HIRSOut.writeBuf[18] = _in->readBuf[62];
HIRSOut.writeBuf[19] = _in->readBuf[63];
HIRSOut.writeBuf[20] = _in->readBuf[66];
HIRSOut.writeBuf[21] = _in->readBuf[67];
HIRSOut.writeBuf[22] = _in->readBuf[70];
HIRSOut.writeBuf[23] = _in->readBuf[71];
HIRSOut.writeBuf[24] = _in->readBuf[74];
HIRSOut.writeBuf[25] = _in->readBuf[75];
HIRSOut.writeBuf[26] = _in->readBuf[78];
HIRSOut.writeBuf[27] = _in->readBuf[79];
HIRSOut.writeBuf[28] = _in->readBuf[82];
HIRSOut.writeBuf[29] = _in->readBuf[83];
HIRSOut.writeBuf[30] = _in->readBuf[84];
HIRSOut.writeBuf[31] = _in->readBuf[85];
HIRSOut.writeBuf[32] = _in->readBuf[88];
HIRSOut.writeBuf[33] = _in->readBuf[89];
HIRSOut.writeBuf[34] = _in->readBuf[92];
HIRSOut.writeBuf[35] = _in->readBuf[93];
if (!HIRSOut.swap(36)) { return -1; };
// Extract SEM
SEMOut.writeBuf[0] = _in->readBuf[20];
SEMOut.writeBuf[1] = _in->readBuf[21];
if (!SEMOut.swap(2)) { return -1; };
// Extract DCS
DCSOut.writeBuf[0] = _in->readBuf[18];
DCSOut.writeBuf[1] = _in->readBuf[19];
DCSOut.writeBuf[2] = _in->readBuf[24];
DCSOut.writeBuf[3] = _in->readBuf[25];
DCSOut.writeBuf[4] = _in->readBuf[28];
DCSOut.writeBuf[5] = _in->readBuf[29];
DCSOut.writeBuf[6] = _in->readBuf[32];
DCSOut.writeBuf[7] = _in->readBuf[33];
DCSOut.writeBuf[8] = _in->readBuf[40];
DCSOut.writeBuf[9] = _in->readBuf[41];
DCSOut.writeBuf[10] = _in->readBuf[44];
DCSOut.writeBuf[11] = _in->readBuf[45];
DCSOut.writeBuf[12] = _in->readBuf[52];
DCSOut.writeBuf[13] = _in->readBuf[53];
DCSOut.writeBuf[14] = _in->readBuf[56];
DCSOut.writeBuf[15] = _in->readBuf[57];
DCSOut.writeBuf[16] = _in->readBuf[60];
DCSOut.writeBuf[17] = _in->readBuf[61];
DCSOut.writeBuf[18] = _in->readBuf[64];
DCSOut.writeBuf[19] = _in->readBuf[65];
DCSOut.writeBuf[20] = _in->readBuf[68];
DCSOut.writeBuf[21] = _in->readBuf[69];
DCSOut.writeBuf[22] = _in->readBuf[72];
DCSOut.writeBuf[23] = _in->readBuf[73];
DCSOut.writeBuf[24] = _in->readBuf[76];
DCSOut.writeBuf[25] = _in->readBuf[77];
DCSOut.writeBuf[26] = _in->readBuf[86];
DCSOut.writeBuf[27] = _in->readBuf[87];
DCSOut.writeBuf[28] = _in->readBuf[90];
DCSOut.writeBuf[29] = _in->readBuf[91];
DCSOut.writeBuf[30] = _in->readBuf[94];
DCSOut.writeBuf[31] = _in->readBuf[95];
if (!DCSOut.swap(32)) { return -1; };
// Extract SBUV
SBUVOut.writeBuf[0] = _in->readBuf[36];
SBUVOut.writeBuf[1] = _in->readBuf[37];
SBUVOut.writeBuf[2] = _in->readBuf[80];
SBUVOut.writeBuf[3] = _in->readBuf[81];
if (!SBUVOut.swap(4)) { return -1; };
_in->flush();
return count;
}
stream<uint8_t> HIRSOut;
stream<uint8_t> SEMOut;
stream<uint8_t> DCSOut;
stream<uint8_t> SBUVOut;
private:
stream<uint8_t>* _in;
};
inline uint16_t HIRSSignedToUnsigned(uint16_t n) {
return (n & 0x1000) ? (0x1000 + (n & 0xFFF)) : (0xFFF - (n & 0xFFF));
}
class HIRSDemux : public generic_block<HIRSDemux> {
public:
HIRSDemux() {}
HIRSDemux(stream<uint8_t>* in) { init(in); }
void init(stream<uint8_t>* in) {
_in = in;
generic_block<HIRSDemux>::registerInput(_in);
for (int i = 0; i < 20; i++) {
generic_block<HIRSDemux>::registerOutput(&radChannels[i]);
}
// Clear buffers
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 56; j++) { radChannels[i].writeBuf[j] = 0xFFF; }
}
}
void setInput(stream<uint8_t>* in) {
std::lock_guard<std::mutex> lck(generic_block<HIRSDemux>::ctrlMtx);
generic_block<HIRSDemux>::tempStop();
generic_block<HIRSDemux>::unregisterInput(_in);
_in = in;
generic_block<HIRSDemux>::registerInput(_in);
generic_block<HIRSDemux>::tempStart();
}
int run() {
int count = _in->read();
if (count < 0) { return -1; }
int element = readBits(19, 6, _in->readBuf);
// If we've skipped or are on a non image element and there's data avilable, send it
if ((element < lastElement || element > 55) && newImageData) {
newImageData = false;
for (int i = 0; i < 20; i++) {
if (!radChannels[i].swap(56)) { return -1; }
}
// Clear buffers
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 56; j++) { radChannels[i].writeBuf[j] = 0xFFF; }
}
}
lastElement = element;
// If data is part of a line, save it
if (element <= 55) {
newImageData = true;
radChannels[0].writeBuf[element] = HIRSSignedToUnsigned(readBits(26, 13, _in->readBuf));
radChannels[1].writeBuf[element] = HIRSSignedToUnsigned(readBits(52, 13, _in->readBuf));
radChannels[2].writeBuf[element] = HIRSSignedToUnsigned(readBits(65, 13, _in->readBuf));
radChannels[3].writeBuf[element] = HIRSSignedToUnsigned(readBits(91, 13, _in->readBuf));
radChannels[4].writeBuf[element] = HIRSSignedToUnsigned(readBits(221, 13, _in->readBuf));
radChannels[5].writeBuf[element] = HIRSSignedToUnsigned(readBits(208, 13, _in->readBuf));
radChannels[6].writeBuf[element] = HIRSSignedToUnsigned(readBits(143, 13, _in->readBuf));
radChannels[7].writeBuf[element] = HIRSSignedToUnsigned(readBits(156, 13, _in->readBuf));
radChannels[8].writeBuf[element] = HIRSSignedToUnsigned(readBits(273, 13, _in->readBuf));
radChannels[9].writeBuf[element] = HIRSSignedToUnsigned(readBits(182, 13, _in->readBuf));
radChannels[10].writeBuf[element] = HIRSSignedToUnsigned(readBits(119, 13, _in->readBuf));
radChannels[11].writeBuf[element] = HIRSSignedToUnsigned(readBits(247, 13, _in->readBuf));
radChannels[12].writeBuf[element] = HIRSSignedToUnsigned(readBits(78, 13, _in->readBuf));
radChannels[13].writeBuf[element] = HIRSSignedToUnsigned(readBits(195, 13, _in->readBuf));
radChannels[14].writeBuf[element] = HIRSSignedToUnsigned(readBits(234, 13, _in->readBuf));
radChannels[15].writeBuf[element] = HIRSSignedToUnsigned(readBits(260, 13, _in->readBuf));
radChannels[16].writeBuf[element] = HIRSSignedToUnsigned(readBits(39, 13, _in->readBuf));
radChannels[17].writeBuf[element] = HIRSSignedToUnsigned(readBits(104, 13, _in->readBuf));
radChannels[18].writeBuf[element] = HIRSSignedToUnsigned(readBits(130, 13, _in->readBuf));
radChannels[19].writeBuf[element] = HIRSSignedToUnsigned(readBits(169, 13, _in->readBuf));
}
// If we are writing the last pixel of a line, send it already
if (element == 55) {
newImageData = false;
for (int i = 0; i < 20; i++) {
if (!radChannels[i].swap(56)) { return -1; }
}
// Clear buffers
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 56; j++) { radChannels[i].writeBuf[j] = 0xFFF; }
}
}
_in->flush();
return count;
}
stream<uint16_t> radChannels[20];
private:
stream<uint8_t>* _in;
int lastElement = 0;
bool newImageData = false;
};
}
}

View File

@ -0,0 +1,43 @@
#pragma once
namespace dsp {
inline uint64_t readBits(int offset, int length, uint8_t* buffer) {
uint64_t outputValue = 0;
int lastBit = offset + (length - 1);
int firstWord = offset / 8;
int lastWord = lastBit / 8;
int firstOffset = offset - (firstWord * 8);
int lastOffset = lastBit - (lastWord * 8);
int wordCount = (lastWord - firstWord) + 1;
// If the data fits in a single byte, just get it
if (wordCount == 1) {
return (buffer[firstWord] & (0xFF >> firstOffset)) >> (7 - lastOffset);
}
int bitsRead = length;
for (int i = 0; i < wordCount; i++) {
// First word
if (i == 0) {
bitsRead -= 8 - firstOffset;
outputValue |= (uint64_t)(buffer[firstWord] & (0xFF >> firstOffset)) << bitsRead;
continue;
}
// Last word
if (i == (wordCount - 1)) {
outputValue |= (uint64_t)buffer[lastWord] >> (7 - lastOffset);
break;
}
// Just a normal byte
bitsRead -= 8;
outputValue |= (uint64_t)buffer[firstWord + i] << bitsRead;
}
return outputValue;
}
}

View File

@ -0,0 +1,91 @@
#include <gui/widgets/line_push_image.h>
namespace ImGui {
LinePushImage::LinePushImage(int frameWidth, int reservedIncrement) {
_frameWidth = frameWidth;
_reservedIncrement = reservedIncrement;
frameBuffer = (uint8_t*)malloc(_frameWidth * _reservedIncrement * 4);
reservedCount = reservedIncrement;
glGenTextures(1, &textureId);
}
void LinePushImage::draw(const ImVec2& size_arg) {
std::lock_guard<std::mutex> lck(bufferMtx);
ImGuiWindow* window = GetCurrentWindow();
ImGuiStyle& style = GetStyle();
float pad = style.FramePadding.y;
ImVec2 min = window->DC.CursorPos;
// Calculate scale
float width = CalcItemWidth();
float height = roundf((width / (float)_frameWidth) * (float)_lineCount);
ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), height);
ImRect bb(min, ImVec2(min.x+size.x, min.y+size.y));
float lineHeight = size.y;
// If there are no lines, there is no point in drawing anything
if (_lineCount == 0) { return; }
ItemSize(size, style.FramePadding.y);
if (!ItemAdd(bb, 0)) {
return;
}
if (newData) {
newData = false;
updateTexture();
}
window->DrawList->AddImage((void*)(intptr_t)textureId, min, ImVec2(min.x + width, min.y + height));
}
uint8_t* LinePushImage::aquireNextLine(int count) {
bufferMtx.lock();
int oldLineCount = _lineCount;
_lineCount += count;
// If new data either fills up or excedes the limit, reallocate
// TODO: Change it to avoid bug if count >= reservedIncrement
if (_lineCount > reservedCount) {
printf("Reallocating\n");
reservedCount += _reservedIncrement;
frameBuffer = (uint8_t*)realloc(frameBuffer, _frameWidth * reservedCount * 4);
}
return &frameBuffer[_frameWidth * oldLineCount * 4];
}
void LinePushImage::releaseNextLine() {
newData = true;
bufferMtx.unlock();
}
void LinePushImage::clear() {
std::lock_guard<std::mutex> lck(bufferMtx);
_lineCount = 0;
frameBuffer = (uint8_t*)realloc(frameBuffer, _frameWidth * _reservedIncrement * 4);
reservedCount = _reservedIncrement;
newData = true;
}
void LinePushImage::save(std::string path) {
// TODO: Implement
}
int LinePushImage::getLineCount() {
return _lineCount;
}
void LinePushImage::updateTexture() {
glBindTexture(GL_TEXTURE_2D, textureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _frameWidth, _lineCount, 0, GL_RGBA, GL_UNSIGNED_BYTE, frameBuffer);
}
}

View File

@ -0,0 +1,43 @@
#pragma once
#include <imgui.h>
#include <imgui_internal.h>
#include <dsp/stream.h>
#include <mutex>
#include <GL/glew.h>
namespace ImGui {
class LinePushImage {
public:
LinePushImage(int frameWidth, int reservedIncrement);
void draw(const ImVec2& size_arg = ImVec2(0, 0));
uint8_t* aquireNextLine(int count = 1);
void releaseNextLine();
void clear();
void save(std::string path);
int getLineCount();
private:
void updateTexture();
std::mutex bufferMtx;
uint8_t* frameBuffer;
int _frameWidth;
int _reservedIncrement;
int _lineCount = 0;
int reservedCount = 0;
GLuint textureId;
bool newData = false;
};
}