Skip to content

Commit

Permalink
Simplify the waveform reading code (#194)
Browse files Browse the repository at this point in the history
Combine the Android and non-Android implementations.  Only difference
now is the path to the waveform data.

Remove arbitrarily-sized buffers and most C-style string handling
function calls.  Use native Qt string methods instead; this should
improve memory safety.
  • Loading branch information
turboencabulator committed Nov 9, 2021
1 parent 1b45b0d commit 591940b
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 126 deletions.
99 changes: 22 additions & 77 deletions Desktop_Interface/functiongencontrol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,95 +9,40 @@ ChannelData const& SingleChannelController::getData() const {

void SingleChannelController::waveformName(QString newName)
{
qDebug() << "newName = " << newName;
newName.append(".tlw");

int length;

#ifdef PLATFORM_ANDROID
QString waveformFilePath("assets:/waveforms/");
waveformFilePath.append(newName);

QFile fptr(waveformFilePath);
bool success = fptr.open(QIODevice::ReadOnly);

QByteArray line;
char lengthString[16];
char divisibilityString[16];

line = fptr.readLine();
strcpy(lengthString, line.data());
sscanf(lengthString, "%d", &length);
qDebug() << "lengthString" << lengthString;

line = fptr.readLine();
strcpy(divisibilityString, line.data());
sscanf(divisibilityString, "%d", &m_data.divisibility);
qDebug() << "divisibilityString" << divisibilityString;

qDebug() << "Length = " << length;
qDebug() << "Divisibility = " << m_data.divisibility;

QByteArray remainingData = fptr.readAll();
char *dataString = remainingData.data();

m_data.samples.resize(length);

int dummy;
char *dataStringCurrent = dataString;
for (int i = 0; i < length; i++)
{
sscanf(dataStringCurrent, "%d", &dummy);
dataStringCurrent += strcspn(dataStringCurrent, "\t") + 1;
m_data.samples[i] = static_cast<uint8_t>(dummy);
}

QString path("assets:/waveforms/");
QFile file(path.append(newName).append(".tlw"));
#else
QString path = QCoreApplication::applicationDirPath();
QFile file(path.append("/waveforms/").append(newName).append(".tlw"));
#endif

QByteArray filePath = QCoreApplication::applicationDirPath()
.append("/waveforms/").append(newName).toLocal8Bit();

qDebug() << "opening" << filePath;

FILE *fptr = fopen(filePath.constData(), "r");
if (fptr == NULL)
qFatal("%s could not be opened!", filePath.constData());

char lengthString[16];
fgets(lengthString, 5, fptr);
sscanf(lengthString, "%d", &length);

char divisibilityString[16];
//Bit of bullshit to deal with CRLF line endings on Mac.
do
{
fgets(divisibilityString, 5, fptr);
}
while ((divisibilityString[0] == '\r') || (divisibilityString[0] == '\n'));
qDebug() << "opening" << file.fileName();
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
qFatal("could not open %s", qUtf8Printable(file.fileName()));

sscanf(divisibilityString, "%d", &m_data.divisibility);
int length = file.readLine().toInt();
m_data.divisibility = file.readLine().toInt();
QByteArray data = file.readLine().trimmed();
file.close();

qDebug() << "Length = " << length;
qDebug() << "Divisibility = " << m_data.divisibility;

// Length is redundant, could be derived from the sample list.
if (length != data.count('\t') + 1)
qFatal("%s: sample count mismatch", qUtf8Printable(file.fileName()));
m_data.samples.resize(length);

char *dataString = (char *) malloc(length*5+1);
fgets(dataString, length*5+1, fptr);

int dummy;
char *dataStringCurrent = dataString;
for (int i = 0; i < length; i++)
{
sscanf(dataStringCurrent, "%d", &dummy);
dataStringCurrent += strcspn(dataStringCurrent, "\t") + 1;
m_data.samples[i] = static_cast<uint8_t>(dummy);
data.replace('\t', '\0');
const char *dataString = data.constData();
QByteArray dataElem;
for (auto &sample : m_data.samples) {
dataElem.setRawData(dataString, strlen(dataString));
sample = static_cast<uint8_t>(dataElem.toInt());
dataString += dataElem.size() + 1;
}

free(dataString);
fclose(fptr);
#endif

double newMaxFreq = DAC_SPS / (length >> (m_data.divisibility - 1));
double newMinFreq = double(CLOCK_FREQ) / 1024.0 / 65535.0 / static_cast<double>(length);

Expand Down
61 changes: 12 additions & 49 deletions Desktop_Interface/ui_elements/espocombobox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,59 +5,22 @@ espoComboBox::espoComboBox(QWidget *parent) : QComboBox(parent)

}


void espoComboBox::readWaveformList(void)
{
//This code gets the name of the current directory, regardless of platform.
//This is so the interface knows where to find the waveform data
//QDir *dir = new QDir();
//qDebug() << dir->currentPath();
#ifdef PLATFORM_ANDROID
QFile qt_list("assets:/waveforms/_list.wfl");
bool success = qt_list.open(QIODevice::ReadOnly | QIODevice::Text);
if(!success){
qFatal("Could not load _list.wfl");
}

char nameBuffer[255];
QStringList *newNames = new QStringList();

while (!qt_list.atEnd()) {
QByteArray line = qt_list.readLine();
strcpy(nameBuffer, line.data());
strtok(nameBuffer, "\n\r");
newNames->append(nameBuffer);
qDebug() << nameBuffer;
}
this->addItems(*(newNames));
delete newNames;
qt_list.close();
QFile file("assets:/waveforms/_list.wfl");
#else
QString dirString = QCoreApplication::applicationDirPath();
dirString.append("/waveforms/_list.wfl");
QByteArray array = dirString.toLocal8Bit();
char* buffer = array.data();
//qDebug() << buffer;

qDebug() << "Attempting to open" << dirString;

FILE *listPtr = fopen(buffer, "r");
QStringList *newNames = new QStringList();
char nameBuffer[255];

if(listPtr == NULL){
qFatal("Could not load _list.wfl");
}
QString path = QCoreApplication::applicationDirPath();
QFile file(path.append("/waveforms/_list.wfl"));
#endif

while (fgets(nameBuffer, sizeof(nameBuffer), listPtr) != NULL){
qDebug() << "nameBuffer = " << nameBuffer;
strtok(nameBuffer, "\n\r");
newNames->append(nameBuffer);
}
this->addItems(*(newNames));
delete newNames;
qDebug() << "opening" << file.fileName();
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
qFatal("could not open %s", qUtf8Printable(file.fileName()));

fclose(listPtr);
#endif
qDebug() << "List loaded!!";
QStringList newNames;
while (!file.atEnd())
newNames.append(file.readLine().trimmed());
this->addItems(newNames);
file.close();
}

0 comments on commit 591940b

Please sign in to comment.