简体   繁体   中英

QProcess How to deal with too much input? (Solved)

I'm using 3 command line tools via QProcesses to play music on my Linux (Mint) desktop via the Jack server. It's all working very well, but the input from one of the tools 'jack_showtime' arrives at about 12,000 lines per second.

I only need to see one line every 0.1 seconds, but the only way I've found to get a full recent line is like:

j_s->readAll(); // j_s is the jack_showtime QProcess
waitAbit(20);   // a 20 mS delay
QString aShowtimeLine = j_s->readLine();
aShowtimeLine = j_s->readLine();

What would be a better way to deal with so much unwanted input? It seems that; without the readAll, a line will be much too old. Without the delay, I get a blank line and without the two readLines I get part of a line.

I'd also be interested in a Bash script that could absorb most of the input, or similar.

I suggest something like this, such that no matter how fast or how slow you get input from the child process, you always use the only most recent value, every 100mS:

// at startup or in your class constructor or wherever
connect(j_s, SIGNAL(readyRead()), this, SLOT(ReadDataFromJack()));
connect(&_myQTimer, SIGNAL(timeout()), this, SLOT(UseOneLine()));
_myQTimer.start(100);

void MyClass :: ReadDataFromJack()
{
    while(j_s->canReadLine())
    {
       char buf[1024];
       qint64 bytesRead = j_s->readLine(buf, sizeof(buf));
       if ((bytes > 0)&&(CanParseText(buf))
       {
          this->_mostRecentResult = ParseText(buf);
       }
    }
}

void MyClass :: UseOneLine()
{
    printf("100mS have elapsed, time to use _mostRecentResult=%i for something!\n", this->_mostRecentResult)
}

(Note that CanParseText(buf) and ParseText(buf) above are imaginary placeholders for whatever code you use to parse ASCII text coming from your child process into data to be used by your program)

Bulls eye. Thank you, You seem to know what I already had. so it was easy to add the bits I didn't have, Mainly the limited size buffer and, as I've never seen a line longer than 79 characters. I reduced it to 100, I may have been on the right track, while looking for a script solution, when I tried to use 'stdbuf'. but dealing with it all in my program is much better.

Lines received are easy to parse. I only want the first number (which can be as low as zero) from something like this:

frame = 293532731 frame_time = 114978548 usecs = 2421437949 state: Rolling

I use the following, which seems reasonably minimal:

QString recentLine = QString::fromLocal8Bit(buf);
recentLine.remove(0,8);
recentLine.chop(recentLine.length() - recentLine.indexOf(" "));
int numSamples = recentLine.toInt();

I put a counter in the ReadDataFromJack() class and see between 2,000 and 3,000 visits per 100mS!

The number represents the position of the 'play head' in samples (at 48k per second) and wont exceed the integer range in Qt, but I see you use a qint64 (long long) in your example. Should I do the same for my number?

Sorry it's an answer (and a further question), but it's too long for a comment.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM