Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. QProcess cannot write data to stdin
Forum Updated to NodeBB v4.3 + New Features

QProcess cannot write data to stdin

Scheduled Pinned Locked Moved Mobile and Embedded
11 Posts 2 Posters 5.9k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • E Offline
    E Offline
    elpidiovaldez5
    wrote on last edited by
    #1

    I want to use QProcess to start a small console program which reads a line from stdin and speaks the text read.

    I start the process like this:

    @
    QProcess *cons = new QProcess();
    cons->start("/home/elp/ConsoleTTS");
    if (!cons->waitForStarted()) {
    Print("Speech server not started");
    } else {
    Print("Speech server started");
    server = 1;
    }
    @

    I subsequently (after a few seconds) try to send the text to be spoken like this (the text is terminated with '\n'):
    @
    int err = cons->write(text.c_str());

      if (err==-1) {
        QString qerr = cons->errorString();
        Print("Err: %s", qerr.toStdString().c_str());
      }
    

    @

    I know that the ConsoleTTS is started correcly. I see it appear in task manager.

    I know that the call to 'write' fails. It returns -1. Then, very oddly I do not get to see the message returned by errorString as the call crashes the system.

    I am using Qt 5.2.0 (GCC 4.6.1, 64 bit). The OS is lubuntu 13.04.

    I am right out of ideas on what is wrong. Am I right in thinking that errorString refers to errors in QIODevice (from which it is inherited) ? I am not so concerned about errorString crashing, but I really need to get 'write' to send data to stdin of the process.

    The full code of ConsoleTTS is here in case it helps shed light. The program works fine when run in a console.

    #include <QCoreApplication>
    #include <QTextStream>
    #include <flite.h>

    @
    extern "C" cst_voice register_cmu_us_kal(const char);

    int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);

    QTextStream cin(stdin);
    QTextStream cout(stdout);

    cst_voice *v;
    flite_init();
    v = register_cmu_us_kal(NULL);

    do {
    QString text = cin.readLine();
    cout << text << "\n";
    cout.flush();
    flite_text_to_speech(text.toStdString().c_str(), v, "play");
    } while(true);

    return a.exec();
    }
    @

    1 Reply Last reply
    0
    • E Offline
      E Offline
      elpidiovaldez5
      wrote on last edited by
      #2

      PS I just tried this:
      @
      cons->setStandardInputFile("/home/elp/text.txt");
      @

      I set a file to be connected to stdin before starting the process. The process starts correctly and speaks the contents of the file.

      Conclusion: Most of QProcess functionality is working. It is just the 'write' function that is not working.

      Writing to the file actually provides a workaround to get the speech functionality working, but it would be much neater to pipe the text via QProcess::write.

      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Hi,

        Do you mean that if you do something like:

        @qDebug() << cons->errorString()@

        it crashes ?

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        0
        • E Offline
          E Offline
          elpidiovaldez5
          wrote on last edited by
          #4

          The line that crashes is:

          @ QString qerr = cons->errorString();
          @

          Although I would not need to get an error string if the QProcess::write invocation was not failing. That is the crux of my problems I think.

          1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #5

            What kind of error are you getting ?

            Are you sure that cons is initialized properly ? That you have not shadowed it at creation time ?

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            0
            • E Offline
              E Offline
              elpidiovaldez5
              wrote on last edited by
              #6

              First of all many thanks to the people who are trying to help me.

              The error that I got was a termination signal that threw me into the debugger. I have now solved the problem. Turns out that the QProcess object was created in a different thread to where 'write' and 'errorString' were called. I guess this sort of explains the writes failing and the errorString crashing the program.

              I have rewritten the program very simply and free of any threading issues. The aim is to provide a completely non-blocking means of outputting speech. I include the full definition below and also the console program that QProcess communicates with.

              • The console program works correctly when operated from the keyboard.

              • The 'write' invocations indicate the correct number of bytes sent, but the console program does not seem to receive the data. It does not produce speech output.

              @#include <QProcess>

              class Voice {
              public:

              QProcess *speechServer;

              Voice() {
              run();
              }

              void run() {
              string speechServerName = SessionDirectory() + "ConsoleTTS";

              speechServer = new QProcess();
              speechServer->start(speechServerName.c_str(), QProcess::Unbuffered | QProcess::ReadWrite);
              if (!speechServer->waitForStarted()) {
                Print("Speech server not started");
              }
              

              }

              void say(const string &text) {
              int err1 = speechServer->write(text.c_str());
              if (err1==-1) {
              Print("QProcess::write failed");
              }

              int err2 = speechServer->write("\n");
              if (err2==-1) {
                Print("QProcess::write failed");
              }
              

              }

              };
              @

              The console program is:

              @#include <QCoreApplication>
              #include <QTextStream>
              #include <flite.h>

              extern "C" cst_voice register_cmu_us_kal(const char);

              int main(int argc, char *argv[]) {
              QCoreApplication a(argc, argv);

              QTextStream cin(stdin);
              QTextStream cout(stdout);

              cst_voice *v;
              flite_init();
              v = register_cmu_us_kal(NULL);

              do {
              QString text = cin.readLine();
              cout << text << "\n";
              cout.flush();
              flite_text_to_speech(text.toStdString().c_str(), v, "play");
              } while(true);

              return a.exec();
              }

              @

              1 Reply Last reply
              0
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #7

                Not that I don't want to help debug your situation but I just thought of something: there's the "QtSpeech":https://gitorious.org/qt-speech module (not part of Qt) that could be interesting for you

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply
                0
                • E Offline
                  E Offline
                  elpidiovaldez5
                  wrote on last edited by
                  #8

                  It is very interesting, as it does just what I wanted (non-blocking TTS). I'm a bit worried about installing it as I think it will destroy my current installation of Festival (took quite a bit of work to get it going with the high-quality voices). However I will give it a go before I update my OS as I will have to re-install everything after that.

                  Even so I would still like to understand why my very simple piece of code fails. I can think of several other uses for QProcess when I get a handle on it.

                  Is there much probability that the problem is due to my version of Lubuntu, the now unsupported 13.04 ?

                  1 Reply Last reply
                  0
                  • SGaistS Offline
                    SGaistS Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    Since you already have Festival installed, just skip that part and build QtSpeech directly.

                    Your QApplication never start since you have an infinite loop running before exec is called. I also don't see anywhere a call to Voice

                    Interested in AI ? www.idiap.ch
                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                    1 Reply Last reply
                    0
                    • E Offline
                      E Offline
                      elpidiovaldez5
                      wrote on last edited by
                      #10

                      I see what you mean about exec not been called, however the program works perfectly well when run in a console from the keyboard. I suppose it is possible that the event loop is needed when stdin is connected to something other than the keyboard _but isn't the source of the input stream totally irrelevant to a console program ?

                      I did not include the code that calls Voice::say as it did not seem relevant. The call is made though (I have set a breakpoint to check).

                      I will give QtSpeech a try. I actually got my program to work by using a named pipe to send the data instead of QProcess::write, but QtSpeech would be a better solution.

                      Thank you for your help and time. It is much appreciated.

                      1 Reply Last reply
                      0
                      • SGaistS Offline
                        SGaistS Offline
                        SGaist
                        Lifetime Qt Champion
                        wrote on last edited by
                        #11

                        What i'd try (I haven't thus far) is to have a QThread dedicated to read stdin and emit a signal that would write to QProcess's input so you can have the event loop running.

                        Interested in AI ? www.idiap.ch
                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved