Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Playing Wav over modem.
Forum Updated to NodeBB v4.3 + New Features

Playing Wav over modem.

Scheduled Pinned Locked Moved Unsolved General and Desktop
24 Posts 5 Posters 6.3k Views 2 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.
  • A Offline
    A Offline
    An other french
    wrote on last edited by
    #1

    Hello I look for a way to cut audiofile (Wav) into a buffer and send it to open com.
    As you can see with this example, i wonder how traduce this into Qt language?

    First: open a stream from wav file
    Two: Binary reader ???

    Tks for reading.

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

      Hi,

      QSerialPort
      QFile

      QSerialPort serialPort;
      // setup your serial port
      // open serialPort with checks
      QFile waveFile("/path/to/wav/file.wav");
      // open waveFile with checks
      serialPort.write(waveFile.readAll());
      

      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
      3
      • VRoninV Offline
        VRoninV Offline
        VRonin
        wrote on last edited by VRonin
        #3

        EDIT Thanks @SGaist for the guidance

        QSerialPort serial(QStringLiteral("Com2"));
        // setup your serial port
        serial.setBaudRate(115200);
        serial.setParity(QSerialPort::NoParity);
        serial.setDataBits(QSerialPort::Data8);
        serial.setStopBits(QSerialPort::OneStop);
        serial.setDataTerminalReady(true);
        // open serialPort with checks
        if(serial.open(QIODevice::WriteOnly)){
        const auto onPhoneAnswered =[&]()->void{
        serial.write(QByteArrayLiteral("AT+VTX\r"));
        QFile wavFile(R"**(C:\Users\Master\Desktop\Prmpt445.wav)**");
        // open waveFile with checks
        if(wavFile.open(QIODevice::ReadOnly)){
        serial.write(wavFile.readAll());
        // for(qint64 fileSize = wavFile.size();fileSize>0;fileSize-=1024) serial.write(wavFile.read(1024)); //1024 chunks version
        }
        }
        // you probably need just 1 (the first probably) connect in reality
        QObject::connect(serial,&QSerialPort::requestToSendChanged,onPhoneAnswered);
        QObject::connect(serial,&QSerialPort::dataTerminalReadyChanged,onPhoneAnswered);
        serial.write(QByteArrayLiteral("AT+FCLASS=8\r"));
        serial.write(QByteArrayLiteral("ATDT1231234\r"));
        }
        

        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
        ~Napoleon Bonaparte

        On a crusade to banish setIndexWidget() from the holy land of Qt

        1 Reply Last reply
        2
        • A Offline
          A Offline
          An other french
          wrote on last edited by An other french
          #4

          sammachin said :
          "You are correct in sending WAV (or RAW PCM Audio to be exact, WAV has a short header but that doesn't cause a problem) It should be 16bit 16Khz Mono with a 20ms frame size, at 16Hkz each 20ms frame will contain 320 samples of 16bits each so that give you the 640byte length."

          In fact, if isend Wavefile without buffering, the "old" Modem can't play sound. First, i need to transform wav to 16bit 16Khz Mono.
          I have to send Hayes Command AT+VSM=128, 8000 . I need perhaps to adapt the following code bellow.

           for(qint64 fileSize = wavFile.size();fileSize>0;fileSize-=1024)
           { serial.write(wavFile.read(1024)); 
          sleep(20); }
          ]
          

          It's not won yet.

          A 1 Reply Last reply
          0
          • A An other french

            sammachin said :
            "You are correct in sending WAV (or RAW PCM Audio to be exact, WAV has a short header but that doesn't cause a problem) It should be 16bit 16Khz Mono with a 20ms frame size, at 16Hkz each 20ms frame will contain 320 samples of 16bits each so that give you the 640byte length."

            In fact, if isend Wavefile without buffering, the "old" Modem can't play sound. First, i need to transform wav to 16bit 16Khz Mono.
            I have to send Hayes Command AT+VSM=128, 8000 . I need perhaps to adapt the following code bellow.

             for(qint64 fileSize = wavFile.size();fileSize>0;fileSize-=1024)
             { serial.write(wavFile.read(1024)); 
            sleep(20); }
            ]
            

            It's not won yet.

            A Offline
            A Offline
            An other french
            wrote on last edited by
            #5

            Hello, no way to play it.
            Have you seen a paper which talk about the method to send data correctly?
            I think i need to temporize the data with the number "frame". I don't find the command like sleep in Qt 's documentation.
            do you have any idea?
            Thanks for reading.

            1 Reply Last reply
            0
            • mrjjM Offline
              mrjjM Offline
              mrjj
              Lifetime Qt Champion
              wrote on last edited by mrjj
              #6

              Hi
              From the link you listed.
              "this shouldn't be required any longer since an update to the interface means you can send your audio as fast as you like and we will buffer it our end."

              So are you sure you need to send in slices ?

              1 Reply Last reply
              0
              • A Offline
                A Offline
                An other french
                wrote on last edited by An other french
                #7

                My purpose is to make an answering machine with a 56k PCIe modem.
                I don't think the caller has the capability to store the wav data.
                So, perhaps the command AT+VTX or AT+VSM=16,8000 will be necessary.

                Cmd-AT+VSM=?;
                Reply-
                0,"Signed PCM",16,0,8000,(0,122-148),0
                4,"G.711U",8,0,8000,(0,122-148),0
                5,"G.711A",8,0,8000,(0,122-148),0
                132,"IMA ADPCM",4,0,8000,(0,122-148),0
                OK

                Obviously, i need to send a 16 bits per sample with a 8000hz audio sampling rate.
                The propriety of my wav is 128kb/s. In 16b, 128kb/s is equivalent 128k/16 = 8000Hz...

                Wikipedia say
                " The modem re-raises the signal in time for the computer to resume sending audio data before the playback buffer becomes completely empty."

                I don't really understand what this really means.

                1 Reply Last reply
                0
                • A Offline
                  A Offline
                  An other french
                  wrote on last edited by An other french
                  #8

                  An idea, but Qfile as private gives some trouble to be declared.
                  Testing a QTextStream but no way at now.

                  the header:

                  private:
                      QFile *wavFile;
                      QTextStream *flux;
                      qint64 fileSize;
                      QTimer *timer;
                  

                  the void :

                      wavFile= new QFile ("msg2.wav");      
                         if(wavFile->open(QIODevice::ReadOnly)){
                  
                             timer = new QTimer(this);
                             fileSize = wavFile.size(); //usefull when try wavFile as pointor to the Slot 
                             connect(timer, SIGNAL(timeout()), this, SLOT(sendWave()));
                             flux= new QTextStream (wavFile);
                             timer->start(200);            //1000 =>1s
                              qDebug() <<"Send Data";
                  
                         } else { qDebug() << "no way to open wav file"; }
                  

                  the slot:

                  void MainWindow::sendWave(){
                          if (!flux->atEnd()) {
                                  m_serial.write(flux->readLine());
                          } else {
                                  qDebug() <<"End Send Data";
                                  timer->stop();
                          }
                    //      }
                  

                  This always loops...
                  flux->realNumberPrecision() give the same number before and after flux->readLine().

                  Thanks for reading.

                  A 1 Reply Last reply
                  0
                  • A An other french

                    An idea, but Qfile as private gives some trouble to be declared.
                    Testing a QTextStream but no way at now.

                    the header:

                    private:
                        QFile *wavFile;
                        QTextStream *flux;
                        qint64 fileSize;
                        QTimer *timer;
                    

                    the void :

                        wavFile= new QFile ("msg2.wav");      
                           if(wavFile->open(QIODevice::ReadOnly)){
                    
                               timer = new QTimer(this);
                               fileSize = wavFile.size(); //usefull when try wavFile as pointor to the Slot 
                               connect(timer, SIGNAL(timeout()), this, SLOT(sendWave()));
                               flux= new QTextStream (wavFile);
                               timer->start(200);            //1000 =>1s
                                qDebug() <<"Send Data";
                    
                           } else { qDebug() << "no way to open wav file"; }
                    

                    the slot:

                    void MainWindow::sendWave(){
                            if (!flux->atEnd()) {
                                    m_serial.write(flux->readLine());
                            } else {
                                    qDebug() <<"End Send Data";
                                    timer->stop();
                            }
                      //      }
                    

                    This always loops...
                    flux->realNumberPrecision() give the same number before and after flux->readLine().

                    Thanks for reading.

                    A Offline
                    A Offline
                    An other french
                    wrote on last edited by An other french
                    #9
                    void MainWindow::sendWave(){
                            if (!flux->atEnd()) {
                    
                                    const char *tmp= flux->read(1024).toStdString().c_str();
                                    m_serial->write(tmp);
                                    m_serial->flush();
                    
                                    flux->seek(flux->pos()+1024);
                            } else {
                                   qDebug() <<"End Send Data";
                                    timer->stop();
                            }
                    
                    }
                    

                    Need to use pos and seek
                    But wav dont play sound

                    Perhaps the timer is so slow.

                    With a wav coding in 16 bit 8000hz , 1024b corresponds to 8ms.
                    My calcul seem to be true. My wave during 1m56s for 1814 loops. So, one loop is during 8.5ms.
                    In fact, the program don't send data during more the 1 minute...
                    So surprise.

                    Try with 5 and try to see it the modem <DTE> send full buffer ...

                    Not easy to go blind.
                    Need more help.

                    A 1 Reply Last reply
                    0
                    • A An other french
                      void MainWindow::sendWave(){
                              if (!flux->atEnd()) {
                      
                                      const char *tmp= flux->read(1024).toStdString().c_str();
                                      m_serial->write(tmp);
                                      m_serial->flush();
                      
                                      flux->seek(flux->pos()+1024);
                              } else {
                                     qDebug() <<"End Send Data";
                                      timer->stop();
                              }
                      
                      }
                      

                      Need to use pos and seek
                      But wav dont play sound

                      Perhaps the timer is so slow.

                      With a wav coding in 16 bit 8000hz , 1024b corresponds to 8ms.
                      My calcul seem to be true. My wave during 1m56s for 1814 loops. So, one loop is during 8.5ms.
                      In fact, the program don't send data during more the 1 minute...
                      So surprise.

                      Try with 5 and try to see it the modem <DTE> send full buffer ...

                      Not easy to go blind.
                      Need more help.

                      A Offline
                      A Offline
                      An other french
                      wrote on last edited by
                      #10

                      const char *tmp= flux->read(1024).toStdString().c_str();

                      put this because compilator sends an error.
                      as we can see, it is not look like some hexadecimal blocks.
                      Different lengths and hexabits are traduced to arabic words..

                      1-P��(�%WAVEfmt 
                      [.. and after..]
                      1-ض�( 
                      [.. and after..]
                      1-ض�(ض�(
                      
                      1 Reply Last reply
                      0
                      • aha_1980A Offline
                        aha_1980A Offline
                        aha_1980
                        Lifetime Qt Champion
                        wrote on last edited by aha_1980
                        #11

                        @An-other-french said in Playing Wav over modem.:

                        void MainWindow::sendWave(){
                        if (!flux->atEnd()) {

                                    const char *tmp= flux->read(1024).toStdString().c_str();
                                    m_serial->write(tmp);
                                    m_serial->flush();
                        
                                    flux->seek(flux->pos()+1024);
                            } else {
                                   qDebug() <<"End Send Data";
                                    timer->stop();
                            }
                        

                        }

                        This code looks odd. How about:

                        if (!flux->atEnd()) {
                          const QByteArray data = flux->read(1024);
                          m_serial->write(data);
                          m_serial->flush();
                        }
                        

                        Need to use pos and seek

                        If you read a file sequentially, no. Every read(1024) puts the read pointer 1024 byte further. You may need to check if you have read less then 1024 byte at the end. Note: readLine() does not work well for binary files like wave.

                        Qt has to stay free or it will die.

                        1 Reply Last reply
                        1
                        • A Offline
                          A Offline
                          An other french
                          wrote on last edited by
                          #12

                          @aha_1980 said in Playing Wav over modem.:

                          if (!flux->atEnd()) {
                          const QByteArray data = flux->read(1024);
                          m_serial->write(data);
                          m_serial->flush();
                          }

                          mainwindow.cpp:396: erreur : conversion from 'QString' to non-scalar type 'const QByteArray' requested
                          const QByteArray data = flux->read(1024);

                          aha_1980A 1 Reply Last reply
                          0
                          • A An other french

                            @aha_1980 said in Playing Wav over modem.:

                            if (!flux->atEnd()) {
                            const QByteArray data = flux->read(1024);
                            m_serial->write(data);
                            m_serial->flush();
                            }

                            mainwindow.cpp:396: erreur : conversion from 'QString' to non-scalar type 'const QByteArray' requested
                            const QByteArray data = flux->read(1024);

                            aha_1980A Offline
                            aha_1980A Offline
                            aha_1980
                            Lifetime Qt Champion
                            wrote on last edited by aha_1980
                            #13

                            @An-other-french said in Playing Wav over modem.:

                            mainwindow.cpp:396: erreur : conversion from 'QString' to non-scalar type 'const QByteArray' requested
                            const QByteArray data = flux->read(1024);

                            Ah, you read from a QTextStream. Citing the documentation: "The QTextStream class provides a convenient interface for reading and writing text." This class converts your file data to QString, which is not what you want!

                            Well, you don't want to write text! You want to write binary data. So either operate directly on QFile (as I would do) or dig into QDataStream.

                            Regards.

                            Qt has to stay free or it will die.

                            A 1 Reply Last reply
                            2
                            • aha_1980A aha_1980

                              @An-other-french said in Playing Wav over modem.:

                              mainwindow.cpp:396: erreur : conversion from 'QString' to non-scalar type 'const QByteArray' requested
                              const QByteArray data = flux->read(1024);

                              Ah, you read from a QTextStream. Citing the documentation: "The QTextStream class provides a convenient interface for reading and writing text." This class converts your file data to QString, which is not what you want!

                              Well, you don't want to write text! You want to write binary data. So either operate directly on QFile (as I would do) or dig into QDataStream.

                              Regards.

                              A Offline
                              A Offline
                              An other french
                              wrote on last edited by
                              #14

                              Thanks for info.
                              I had probleme to follow the position in the QFile.
                              Perhaps made a mistake.
                              So i try again.

                              aha_1980A 1 Reply Last reply
                              0
                              • A An other french

                                Thanks for info.
                                I had probleme to follow the position in the QFile.
                                Perhaps made a mistake.
                                So i try again.

                                aha_1980A Offline
                                aha_1980A Offline
                                aha_1980
                                Lifetime Qt Champion
                                wrote on last edited by
                                #15

                                @An-other-french

                                Another tip: get yourself a serial port monitor to see what you actually write to the serial port. This makes also sure you get the timing right.

                                Good luck :)

                                Qt has to stay free or it will die.

                                1 Reply Last reply
                                0
                                • A Offline
                                  A Offline
                                  An other french
                                  wrote on last edited by An other french
                                  #16
                                  QByteArray data = wavFile->read(1024);
                                  

                                  Ok for a truncate data of 1024b , qDebug show this. I put a newline after "

                                  "\xB3\xDEV\xDD\xAA\xDB"
                                  "c\xDA\xC6\xDA\t\xDD\xF4\xE0^\xE5\x89\xEB\xAC\xF0"
                                  "7\xF6\x13\xFA\x9A\xFD\xCB\xFF"
                                  "5\x02|\x04\xC3\x07\x84\x0B\x17\x12\xE0\x19\x90%\\0\xA7<>E!M\xF8Q7V|X\xC1YpY\xB4WBU&Q\xFAL.G\xBE"
                                  "A7:R3\xA8*\\#\xAA\x1A\xCA\x13\xC5\x0B\xF6\x04\x8A\xFC)\xF5\xED\xEB\x96\xE2\n\xDB\x96\xD2"
                                  "1\xCCS\xC5K\xC0\xF9\xBA\x1E\xB7P\xB3\x06\xB1v\xAF \xAF\xC8\xAFX\xB1\xD7\xB3"
                                  "0\xB6\xEC\xB8\x96\xBBQ\xBF\xC8\xC2\x00\xC7j\xCA"
                                  "2\xCE""3\xD1v\xD5\x9C\xD9\xC5\xDE\xC2\xE2\xDC\xE6\xF6\xE9t\xED\xD2\xF0"
                                  "9\xF5\xD9\xF8~\xFC\xC0\xFE\x98\x00\x83\x01\xA8\x02$\x04\x94\x05g\x07\xC2\bf\n&\f\x98\x0E\x8C\x10p\x12\xB0\x13\xCB\x14\xC8\x15(\x17"
                                  

                                  this part is strong :

                                  %\\0\xA7<>E!M\xF8Q7V|X\xC1YpY\xB4WBU&Q\xFAL.G\xBE
                                  

                                  I except to read something like this:

                                  a9 de ce e4 86 e3 af e1 c8 de 64 e1 97 e0 ad df
                                  

                                  Sure there is a conversion somewhere.

                                  the last 16b line:

                                  Qbebug \xE5\x06 \x05$\x06\xFF\x06\x13\x05*\xFF
                                  wave file e5 06 20 05 24 06 ff 06 13 05 2a ff
                                  

                                  I can anderstand /x but $ or * is an other way.

                                  Ps: My purpose is to play wave on the phone

                                  aha_1980A 1 Reply Last reply
                                  0
                                  • A An other french
                                    QByteArray data = wavFile->read(1024);
                                    

                                    Ok for a truncate data of 1024b , qDebug show this. I put a newline after "

                                    "\xB3\xDEV\xDD\xAA\xDB"
                                    "c\xDA\xC6\xDA\t\xDD\xF4\xE0^\xE5\x89\xEB\xAC\xF0"
                                    "7\xF6\x13\xFA\x9A\xFD\xCB\xFF"
                                    "5\x02|\x04\xC3\x07\x84\x0B\x17\x12\xE0\x19\x90%\\0\xA7<>E!M\xF8Q7V|X\xC1YpY\xB4WBU&Q\xFAL.G\xBE"
                                    "A7:R3\xA8*\\#\xAA\x1A\xCA\x13\xC5\x0B\xF6\x04\x8A\xFC)\xF5\xED\xEB\x96\xE2\n\xDB\x96\xD2"
                                    "1\xCCS\xC5K\xC0\xF9\xBA\x1E\xB7P\xB3\x06\xB1v\xAF \xAF\xC8\xAFX\xB1\xD7\xB3"
                                    "0\xB6\xEC\xB8\x96\xBBQ\xBF\xC8\xC2\x00\xC7j\xCA"
                                    "2\xCE""3\xD1v\xD5\x9C\xD9\xC5\xDE\xC2\xE2\xDC\xE6\xF6\xE9t\xED\xD2\xF0"
                                    "9\xF5\xD9\xF8~\xFC\xC0\xFE\x98\x00\x83\x01\xA8\x02$\x04\x94\x05g\x07\xC2\bf\n&\f\x98\x0E\x8C\x10p\x12\xB0\x13\xCB\x14\xC8\x15(\x17"
                                    

                                    this part is strong :

                                    %\\0\xA7<>E!M\xF8Q7V|X\xC1YpY\xB4WBU&Q\xFAL.G\xBE
                                    

                                    I except to read something like this:

                                    a9 de ce e4 86 e3 af e1 c8 de 64 e1 97 e0 ad df
                                    

                                    Sure there is a conversion somewhere.

                                    the last 16b line:

                                    Qbebug \xE5\x06 \x05$\x06\xFF\x06\x13\x05*\xFF
                                    wave file e5 06 20 05 24 06 ff 06 13 05 2a ff
                                    

                                    I can anderstand /x but $ or * is an other way.

                                    Ps: My purpose is to play wave on the phone

                                    aha_1980A Offline
                                    aha_1980A Offline
                                    aha_1980
                                    Lifetime Qt Champion
                                    wrote on last edited by
                                    #17

                                    @An-other-french to output binary data for debugging, I recommend you to use QByteArray::toHex().

                                    Qt has to stay free or it will die.

                                    A 1 Reply Last reply
                                    1
                                    • aha_1980A aha_1980

                                      @An-other-french to output binary data for debugging, I recommend you to use QByteArray::toHex().

                                      A Offline
                                      A Offline
                                      An other french
                                      wrote on last edited by
                                      #18

                                      No way to play any sound.
                                      In the purpose to see modem response, i want to show Modem answer.
                                      So, i need to connect the serial com to the text object

                                      connect (m_serial, &QSerialPort::readyRead, this, &MainWindow::readData); 
                                      
                                      void MainWindow::readData(){ 
                                      QByteArray data = m_serial->readAll();
                                      ...
                                      ui->textEdit->append("1-"+ data.left(data.size()));
                                      ...
                                      }
                                      

                                      My function don't make difference between input or output(response).

                                      Do you have a idea to show them distinctly?

                                      1 Reply Last reply
                                      0
                                      • aha_1980A Offline
                                        aha_1980A Offline
                                        aha_1980
                                        Lifetime Qt Champion
                                        wrote on last edited by
                                        #19

                                        @An-other-french said in Playing Wav over modem.:

                                        Your connect and the readAll in the slot looks good so far.

                                        data.left(data.size())

                                        What do you expect from this construct? It should be the same as data alone.

                                        As suggested earlier, use a serial port monitor to see which commands you actually send to the modem and wheter it answers.

                                        Qt has to stay free or it will die.

                                        A 1 Reply Last reply
                                        0
                                        • aha_1980A aha_1980

                                          @An-other-french said in Playing Wav over modem.:

                                          Your connect and the readAll in the slot looks good so far.

                                          data.left(data.size())

                                          What do you expect from this construct? It should be the same as data alone.

                                          As suggested earlier, use a serial port monitor to see which commands you actually send to the modem and wheter it answers.

                                          A Offline
                                          A Offline
                                          An other french
                                          wrote on last edited by An other french
                                          #20

                                          @aha_1980 said in Playing Wav over modem.:

                                          data.left(data.size())

                                          It's a tentative to cut the data. Just data is better.

                                          As suggested earlier, use a serial port monitor to see which commands you actually send to the modem and wheter it answers.

                                          I don t know how to distinct the write and the read. m_serial->readAll(); give all of us.

                                          aha_1980A 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