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. audiooutput
QtWS25 Last Chance

audiooutput

Scheduled Pinned Locked Moved Unsolved General and Desktop
23 Posts 4 Posters 4.8k Views
  • 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.
  • L Offline
    L Offline
    Leopold
    wrote on last edited by
    #1

    hello again,
    i have found the audiooutput -example in the examples and want to understand the code but i'm not used to soundcards.As well i would like to change this small app in that way that I can output an intermittend tone.( tone ,pause,tone,pause and so on)
    Therefore I have created a sleeper in the .h file

    class Sleeper : public QThread
    {
    public:
        static void usleep(unsigned long usecs){QThread::usleep(usecs);}
        static void msleep(unsigned long msecs){QThread::msleep(msecs);}
        static void sleep(unsigned long secs){QThread::sleep(secs);}
    };
    

    next I have created a slider and connected its output to a variable:

    
    
       m_sleepSlider = new QSlider(Qt::Horizontal);
        connect(m_sleepSlider, SIGNAL(valueChanged(int)), this, SLOT(rpmChanged(int)));
        volumeBox->addWidget(m_volumeLabel);
        volumeBox->addWidget(m_volumeSlider);
         volumeBox->addWidget(m_sleepSlider);
    

    the slot:

    void AudioTest::rpmChanged(int value)
    {
        if (m_audioOutput)
            drehzahl=m_sleepSlider->value();
    }
    

    and now I want to create a for-loop that ihave a tone with 17 interupts.Where can I place this loop. Here it is not working:

    void Generator::generateData(const QAudioFormat &format, qint64 durationUs, int sampleRate)
    {for (int i=0;i>=17;i++){
        const int channelBytes = format.sampleSize() / 8;
        const int sampleBytes = format.channelCount() * channelBytes;
    
        qint64 length = (format.sampleRate() * format.channelCount() * (format.sampleSize() / 8))
                            * durationUs / 100000;
    
        Q_ASSERT(length % sampleBytes == 0);
        Q_UNUSED(sampleBytes) // suppress warning in release builds
    
        m_buffer.resize(length);
        unsigned char *ptr = reinterpret_cast<unsigned char *>(m_buffer.data());
        int sampleIndex = 0;
    
        while (length) {
    
    
            const qreal x = qSin(2 * M_PI * sampleRate * qreal(sampleIndex % format.sampleRate()) / format.sampleRate());
            for (int i=0; i<format.channelCount(); ++i) {
                if (format.sampleSize() == 8 && format.sampleType() == QAudioFormat::UnSignedInt) {
                    const quint8 value = static_cast<quint8>((1.0 + x) / 2 * 255);
                    *reinterpret_cast<quint8*>(ptr) = value;
                } else if (format.sampleSize() == 8 && format.sampleType() == QAudioFormat::SignedInt) {
                    const qint8 value = static_cast<qint8>(x * 127);
                    *reinterpret_cast<quint8*>(ptr) = value;
                } else if (format.sampleSize() == 16 && format.sampleType() == QAudioFormat::UnSignedInt) {
                    quint16 value = static_cast<quint16>((1.0 + x) / 2 * 65535);
                    if (format.byteOrder() == QAudioFormat::LittleEndian)
                        qToLittleEndian<quint16>(value, ptr);
                    else
                        qToBigEndian<quint16>(value, ptr);
                } else if (format.sampleSize() == 16 && format.sampleType() == QAudioFormat::SignedInt) {
                    qint16 value = static_cast<qint16>(x * 32767);
                    if (format.byteOrder() == QAudioFormat::LittleEndian)
                        qToLittleEndian<qint16>(value, ptr);
                    else
                        qToBigEndian<qint16>(value, ptr);
                }
                Sleeper::msleep(drehzahl);
                  }
    
                ptr += channelBytes;
                length -= channelBytes;
            }
            ++sampleIndex;
        }
    }
    
    jsulmJ 1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by SGaist
      #2

      Hi,

      The rpmChangedslot as written does nothing.

      Since you know the exact length of what you want to produce here, why not generate the full audio sample and then play it ?

      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
      2
      • L Leopold

        hello again,
        i have found the audiooutput -example in the examples and want to understand the code but i'm not used to soundcards.As well i would like to change this small app in that way that I can output an intermittend tone.( tone ,pause,tone,pause and so on)
        Therefore I have created a sleeper in the .h file

        class Sleeper : public QThread
        {
        public:
            static void usleep(unsigned long usecs){QThread::usleep(usecs);}
            static void msleep(unsigned long msecs){QThread::msleep(msecs);}
            static void sleep(unsigned long secs){QThread::sleep(secs);}
        };
        

        next I have created a slider and connected its output to a variable:

        
        
           m_sleepSlider = new QSlider(Qt::Horizontal);
            connect(m_sleepSlider, SIGNAL(valueChanged(int)), this, SLOT(rpmChanged(int)));
            volumeBox->addWidget(m_volumeLabel);
            volumeBox->addWidget(m_volumeSlider);
             volumeBox->addWidget(m_sleepSlider);
        

        the slot:

        void AudioTest::rpmChanged(int value)
        {
            if (m_audioOutput)
                drehzahl=m_sleepSlider->value();
        }
        

        and now I want to create a for-loop that ihave a tone with 17 interupts.Where can I place this loop. Here it is not working:

        void Generator::generateData(const QAudioFormat &format, qint64 durationUs, int sampleRate)
        {for (int i=0;i>=17;i++){
            const int channelBytes = format.sampleSize() / 8;
            const int sampleBytes = format.channelCount() * channelBytes;
        
            qint64 length = (format.sampleRate() * format.channelCount() * (format.sampleSize() / 8))
                                * durationUs / 100000;
        
            Q_ASSERT(length % sampleBytes == 0);
            Q_UNUSED(sampleBytes) // suppress warning in release builds
        
            m_buffer.resize(length);
            unsigned char *ptr = reinterpret_cast<unsigned char *>(m_buffer.data());
            int sampleIndex = 0;
        
            while (length) {
        
        
                const qreal x = qSin(2 * M_PI * sampleRate * qreal(sampleIndex % format.sampleRate()) / format.sampleRate());
                for (int i=0; i<format.channelCount(); ++i) {
                    if (format.sampleSize() == 8 && format.sampleType() == QAudioFormat::UnSignedInt) {
                        const quint8 value = static_cast<quint8>((1.0 + x) / 2 * 255);
                        *reinterpret_cast<quint8*>(ptr) = value;
                    } else if (format.sampleSize() == 8 && format.sampleType() == QAudioFormat::SignedInt) {
                        const qint8 value = static_cast<qint8>(x * 127);
                        *reinterpret_cast<quint8*>(ptr) = value;
                    } else if (format.sampleSize() == 16 && format.sampleType() == QAudioFormat::UnSignedInt) {
                        quint16 value = static_cast<quint16>((1.0 + x) / 2 * 65535);
                        if (format.byteOrder() == QAudioFormat::LittleEndian)
                            qToLittleEndian<quint16>(value, ptr);
                        else
                            qToBigEndian<quint16>(value, ptr);
                    } else if (format.sampleSize() == 16 && format.sampleType() == QAudioFormat::SignedInt) {
                        qint16 value = static_cast<qint16>(x * 32767);
                        if (format.byteOrder() == QAudioFormat::LittleEndian)
                            qToLittleEndian<qint16>(value, ptr);
                        else
                            qToBigEndian<qint16>(value, ptr);
                    }
                    Sleeper::msleep(drehzahl);
                      }
        
                    ptr += channelBytes;
                    length -= channelBytes;
                }
                ++sampleIndex;
            }
        }
        
        jsulmJ Offline
        jsulmJ Offline
        jsulm
        Lifetime Qt Champion
        wrote on last edited by
        #3

        @Leopold Instead of using a thread and a loop you could simply use a QTimer.

        https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        2
        • L Offline
          L Offline
          Leopold
          wrote on last edited by
          #4

          @Leopold said in audiooutput:

             }
                  Sleeper::msleep(drehzahl);
                    }
          

          the rpmChanged sets the variable "drehzahl" and so i want to change the length of the pauses.

          aha_1980A 1 Reply Last reply
          0
          • L Leopold

            @Leopold said in audiooutput:

               }
                    Sleeper::msleep(drehzahl);
                      }
            

            the rpmChanged sets the variable "drehzahl" and so i want to change the length of the pauses.

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

            @Leopold

            If you sleep in the main thread of an event-driven program, then you most likely don't get the result you expect.

            Better use a QTimer as @jsulm suggested.

            Qt has to stay free or it will die.

            1 Reply Last reply
            0
            • L Offline
              L Offline
              Leopold
              wrote on last edited by
              #6

              You are right,
              i have set a qtimer in genarateData now , but now the app does not start at all.
              And yes qtimer wouldbe much easier.I would like to build a metronom out of this example.But like i said i do not completely understand the code.There is no comment to the code.Where can i place the loop and the timer.If i have an example for one interrupt i think i can extent to what I want.Or does anybody know the code for a programmable metronom?

              jsulmJ 1 Reply Last reply
              0
              • L Leopold

                You are right,
                i have set a qtimer in genarateData now , but now the app does not start at all.
                And yes qtimer wouldbe much easier.I would like to build a metronom out of this example.But like i said i do not completely understand the code.There is no comment to the code.Where can i place the loop and the timer.If i have an example for one interrupt i think i can extent to what I want.Or does anybody know the code for a programmable metronom?

                jsulmJ Offline
                jsulmJ Offline
                jsulm
                Lifetime Qt Champion
                wrote on last edited by
                #7

                @Leopold You don't need any loop. Just set time out interval in QTimer correctly (to achieve needed frequency).

                https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply
                0
                • L Offline
                  L Offline
                  Leopold
                  wrote on last edited by
                  #8

                  @jsulm ,
                  hi, i do not think that I can solve it over the frequency.In the end state , i want to regulate the length of the pause and have an additional pause after 17 tones.Then I want the ability to set the anount of tones ( x instead of 17) and then regulate to which channel these tones will be output.
                  for3 tones: tone,pause,tone,pause,tone,pause,pause and the same loop again.
                  volume slider for volume,
                  rpmslider for length of timer timer.start(rpmslider->volume(),this)
                  tickslider for the amount of tones(x)

                  1 Reply Last reply
                  0
                  • L Offline
                    L Offline
                    Leopold
                    wrote on last edited by
                    #9

                    Nobody here who can explain the app?

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

                      There are several possibilities. You can use a QTimer for the interval between two tones, increment a counter each time you play it up to 17 (or in your case the variable you'll use to be able to set the number you want). As for the tone itself, like I suggested before you can build a QByteArray containing the audio data you need to send and the send it to the output.

                      As for channel selection, what do you have in mind ?

                      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
                      1
                      • L Offline
                        L Offline
                        Leopold
                        wrote on last edited by
                        #11

                        "As for channel selection, what do you have in mind ?"
                        On one channel i want the sequenz with a doble pause after 17 tones and on the second channel (stereo) i want the sequenz with only tones and pauses.

                        1 Reply Last reply
                        0
                        • L Offline
                          L Offline
                          Leopold
                          wrote on last edited by
                          #12

                          @SGaist said in audiooutput:

                          You can use a QTimer for the interval between two tones,

                          this is what I want to to but i can not figure out where to set the loop. When I try to debug the programm it runs for ever in background but never reaches the return app.exec in main.

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

                            The you have to build your stereo data accordingly.

                            Start your QTimer when you want to start sending data or rather after you sent your first data to QAudioOutput.

                            app.exec() will return either when you close the last window of your application or call QApplication::quit from e.g. a menu action.

                            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
                            • L Offline
                              L Offline
                              Leopold
                              wrote on last edited by
                              #14

                              now I had some time to play with this topic again:
                              I'm still wondering where to set my loop.I did it here```

                              void AudioTest::createAudioOutput()
                              {
                              delete m_audioOutput;
                              m_audioOutput = 0;
                              m_audioOutput = new QAudioOutput(m_device, m_format, this);
                              m_generator->start();
                              m_audioOutput->start(m_generator);
                              for (int i=0;i<17;i++)
                              {
                              m_audioOutput->stop();
                              connect(m_pushTimer, SIGNAL(timeout()), this, SLOT(update()));
                              m_pushTimer->start(1000);

                                m_audioOutput->start(m_generator);
                              }
                              
                              qreal initialVolume = QAudio::convertVolume(m_audioOutput->volume(),
                                                                          QAudio::LinearVolumeScale,
                                                                          QAudio::LogarithmicVolumeScale);
                              m_volumeSlider->setValue(qRound(initialVolume * 100));
                              

                              }
                              I can compile but when it comes to running, i get a sigsev error from system.

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

                                With that loop you are connecting the timeout signal 17 time, why ?

                                You should also post your backtrace.

                                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
                                2
                                • L Offline
                                  L Offline
                                  Leopold
                                  wrote on last edited by
                                  #16

                                  @SGaist said in audiooutput:

                                  With that loop you are connecting the timeout signal 17 time, why ?

                                  still the old problem, I want the rattling noise,then I'll continue to attapt the programm to my needs. I do not know where to place the loop.Could you have a look to the example programm and give me a hint?

                                  aha_1980A 1 Reply Last reply
                                  0
                                  • L Leopold

                                    @SGaist said in audiooutput:

                                    With that loop you are connecting the timeout signal 17 time, why ?

                                    still the old problem, I want the rattling noise,then I'll continue to attapt the programm to my needs. I do not know where to place the loop.Could you have a look to the example programm and give me a hint?

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

                                    @Leopold why do you need a loop? please explain.

                                    you already have a timer and this timer call its SLOT every second. just do what you want there. if you want to stop, stop the timer.

                                    regards

                                    Qt has to stay free or it will die.

                                    L 1 Reply Last reply
                                    0
                                    • aha_1980A aha_1980

                                      @Leopold why do you need a loop? please explain.

                                      you already have a timer and this timer call its SLOT every second. just do what you want there. if you want to stop, stop the timer.

                                      regards

                                      L Offline
                                      L Offline
                                      Leopold
                                      wrote on last edited by
                                      #18

                                      @aha_1980
                                      have you read the complete thread?
                                      can you help, give me a hint!

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

                                        Did you try my suggestion of pre-generating the complete audio sequence ?

                                        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
                                        • L Offline
                                          L Offline
                                          Leopold
                                          wrote on last edited by
                                          #20

                                          no, if i generate a wav file, I can not change sequenzes while running.I could play wav.files with other means.There are complete programs for metronoms they are too big and nearly not changeable.There must be a possibility to change this small program to my needs.When I had a first look to it i thought its easy but now its a challenge. I have set the loop to different places but always get a sigsev error when app starts.

                                          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