I am about to read data From a File which has stored it's time in nanoseconds from 1/1/1970. My problem is I want to read it to a QDateTime object, but it simply does not work as I want it to and the Qt Documentation did not help me either.
Note: milliseconds raster is enough for my purposes
Here my current approach:
void setDateTime(qint64 &ns)
{
_datetime.setDate(QDate(1970,1,1));
_datetime.setTime(QTime(0,0,0,0));
ns /= 1000; //ns are now ms
qDebug() << "| ms = " << ns;
qDebug() << "| days = " << static_cast<int>(ns%(60*60*24*1E6));
_datetime.addDays( static_cast<int>(ns%(60*60*24*1000)) );
_datetime.addMSecs( ns - ((ns/(60*60*24*1000))*60*60*24*1E6) );
qDebug() << "| dt = " << _datetime;
}
the result is always
| dt = QDateTime("Thu Jan 1 00:00:00 1970")
which is surely wrong
Can anybody tell where my flaw is? Thanks for any tips and help.
Edit: setTime_t is obviously what I wanted (except for msec resolution), and that works as expected, but I am really curious why the above approach does not work.
Edit changed hack-away bug from 1E6 multiplicative to 1E6
QDateTime::addDays() and QDateTime::addMSecs() are const functions returning a new QDateTime. You're simply throwning the return value away.
And yes, this is written in the documentation.
Related
Is there in the QT libraries an equivalent of the timeGetTime() function of the Windows.h header? I wish my code was as platform-independent as possible. I know the <chrono> header exists, but I would like something that returns the value in DWORD
float AudioThread::br()
{
QTime tmp(0,0);
DWORD time = tmp.msecsSinceStartOfDay();
QWORD pos = BASS_StreamGetFilePosition(chan, BASS_FILEPOS_CURRENT);
if (pos != lastpos) {
lasttime = time;
lastpos = pos;
}
}
qDebug() << tmp.msecsSinceStartOfDay() << pos;
return 8.0 * (pos - lastpos) / (time - lasttime);
}
Inserting this code into a QTimer, tmp.msecsSinceStartOfDay() always returns 0
Can you help me?
Thanks in advance
It is a bit hard to guess, what you really want.
Looking at your code, you set tmp to 0, afterwards you calculate the difference of tmp(which is still at 0) with 0 (the start of the day) which makes your variable time = 0-0 = 0. Perfectly correct but not what you want.
If you want to know, what the current time is, you could use
QTime tm = QTime::currentTime();
DWORD dtime = tm.msecsSinceStartOfDay();
BTW: I would not use a variable named time as this might create confusion with the time() library function. I have seen very strange behaviour after using a variable named 'time'.
I'm using the pleora sdk to capture images from an external camera and I am able to successfully write the data to tiff image files on disk. My next step is to change the data storage to SQLite instead of disk files.
I have PvBuffer *lBuffer pointer working fine. Now I need to convert that data to a format I can use to write to SQLite. I'm using Qt on linux so the QByteArray would be very convenient.
This is kind of a specific question for the pleora sdk and Qt. I'm hoping someone has experience with this.
PvRawData *rawData = lBuffer->GetRawData();
QByteArray ba;
//Need to copy the data from rawData to ba.
Thank you in advance.
I found an answer and wanted to post in case anybody else has something similar. I uses the reintepret_cast method.
data = lBuffer->GetDataPointer()
imgSize = lBuffer->GetPayloadSize();
const char *d = reinterpret_cast<char *>(data);
QByteArray ba(d, imgSize);
QSqlQuery q = QSqlQuery( db );
q.prepare("INSERT INTO imgData (image) values (:imageData)");
q.bindValue(":imageData", ba);
if ( !q.exec() )
qDebug() << "Error inserting image into table: " << q.lastError() << endl;
else
qDebug() << "Query executed properly" << endl;
I'm creating a music player for PC. I want to visualize the FFT of the song. I've crated an entire class that buffers 1024 points of data does the FFT and displays it (this is handled by another class). My program was developed in my laptop which uses Debian Testing x64. My work pc uses Centos 7 x64. When I compiled my program (both use Qt 5.7.0) on my work PC the FFT visualization was garbage. Snooping into my code I found that the sample type provided by QAudioBuffer from QAudioProbe was Signed (in my work PC) while it was float in my Laptop. Here is the code that is called whenever QAudioProbe emits that data has been buffered:
void SpectrumController::setAudioBuffer(QAudioBuffer buffer){
// Used to momentarily stop the process.
if (!enableBuffering) return;
// Only process stereo frames
if (buffer.format().channelCount() != 2) return;
if (buffer.format().sampleType() == QAudioFormat::SignedInt){
//qWarning() << "Signed";
QAudioBuffer::S16S *data = buffer.data<QAudioBuffer::S16S>();
bufferData(data,buffer.frameCount());
}
else if (buffer.format().sampleType() == QAudioFormat::UnSignedInt){
//qWarning() << "Unsigned";
QAudioBuffer::S16U *data = buffer.data<QAudioBuffer::S16U>();
bufferData(data,buffer.frameCount());
}
else if(buffer.format().sampleType() == QAudioFormat::Float){
//qWarning() << "Float";
QAudioBuffer::S32F *data = buffer.data<QAudioBuffer::S32F>();
bufferData(data,buffer.frameCount());
}
}
template<typename T>
void SpectrumController::bufferData(T *data, qint32 N){
for (qint32 i = 0; i < N; i++){
//if (qAbs(data[i].left) > largest){largest = qAbs(data[i].left); qDebug() << "Largest" << largest;}
//currentBuffer << ((qreal)data[i].left/(largest));
//qWarning() << "Added data" << currentBuffer.last();
currentBuffer << data[i].left;
if (datcounter < 100000){
*writer << data[i].left;
*writer << "\n";
datcounter++;
}
else if (writeFile->isOpen()){
qWarning() << "Closed file";
writeFile->close();
}
if (currentBuffer.size() == FFT_SIZE){
dataBuffer << currentBuffer;
currentBuffer.clear();
if (!isRunning) run();
}
What I ended up doing is writing, to a file, the first 100.000 points of data gathered by both my laptop and my work PC in order to plot them.
This is what I've got
What I think is that difference is in the base system's handling of the the mp3, which, in turn, is what Qt uses. I think is gstreamer. Centos uses a much older version. The plot on the right corresponds to my laptop while the plot on the left corresponds to my work pc.
Any ideas on how to fix this? Or am I just stuck with no way of accessising the raw audio data correctly?
UPDATE:
Even though this is not a Fix or anything like that, the data in the other channel (data[i].right) did have more appropiate data. I'm using the right channnel, for now.
I would like to peek the next characters of a QTextStream reading a QFile, in order to create an efficient tokenizer.
However, I don't find any satisfying solution to do so.
QFile f("test.txt");
f.open(QIODevice::WriteOnly);
f.write("Hello world\nHello universe\n");
f.close();
f.open(QIODevice::ReadOnly);
QTextStream s(&f);
int i = 0;
while (!s.atEnd()) {
++i;
qDebug() << "Peek" << i << s.device()->peek(3);
QString v;
s >> v;
qDebug() << "Word" << i << v;
}
Gives the following output:
Peek 1 "Hel" # it works only the first time
Word 1 "Hello"
Peek 2 ""
Word 2 "world"
Peek 3 ""
Word 3 "Hello"
Peek 4 ""
Word 4 "universe"
Peek 5 ""
Word 5 ""
I tried several implementations, also with QTextStream::pos() and QTextStream::seek(). It works better, but pos() is buggy (returns -1 when the file is too big).
Does anyone have a solution to this recurrent problem? Thank you in advance.
You peek from QIODevice, but then you read from QTextStream, that's why peek works only once. Try this:
while (!s.atEnd()) {
++i;
qDebug() << "Peek" << i << s.device()->peek(3);
QByteArray v = s.device()->readLine ();
qDebug() << "Word" << i << v;
}
Unfortunately, QIODevice does not support reading single words, so you would have to do it yourself with a combination of peak and read.
Try disable QTextStream::autoDetectUnicode. This may read device ahead to perform detection and cause your problem.
Set also a codec just in case.
Add to the logs s.device()->pos() and s.device()->bytesAvailable() to verify that.
I've check QTextStream code. It looks like it always caches as much data as possible and there is no way to disable this behavior. I was expecting that it will use peek on device, but it only reads in greedy way. Bottom line is that you can't use QTextStream and peak device at the same time.
I have a Qt (4.7) program that takes a QByteArray and should break it into a list of QVariants, after using a parser to transform it into a QVariant. The problems seem to arise when I try to use the toList() function. I have something similar to this:
QVariant var = //whatever the value passed in is...
std::cout << "Data = " << var.toString().toStdString() << std::endl;
QList<QVariant> varlist = var.toList();
std::cout << "List Size = " << varlist.size() << std::endl;
which would return this:
Data = variant1 variant2 variant3
Size = 0
where the size should clearly be 3. Does anyone have an idea what I may be doing wrong? thanks!
The documentation of toList() says:
Returns the variant as a QVariantList if the variant has userType() QMetaType::QVariantList or QMetaType::QStringList; otherwise returns an empty list.
My guess is, your variant's userType() is neither of those two.
You probably need to construct your variant differently, e.g.
QVariantList list;
list << variant1 << variant2 << variant3;
QVariant var = list;
So, I have no idea why, but when I put the command I specified above into a separate function, ie QList<QVariant> myClass::ToList(QVariant v){return v.toList();}, and then call varlist = myClass::ToList(v), it works. Still doesn't the original way, but this way it's fine. Guess I'll just chalk it up to one of the quirks of Qt...