title: Handeling large QByteArray with QtAudioOutput causes std::bad_alloc
body: <p>Using <code>QAudioOut</code> Im trying to play data that is stored in a <code>QByteArray</code> in a sequence... this works when there is little data being appended, however when the data gets too much, lets say a 2~3 hour RAW PCM appending from different combinations this data to a <code>QByteArray</code> all at once will result in a <code>std::bad_alloc</code> due to the heap that's not big enough to hold all the data at the same time.</p>
  
  <p>I know where the problem occurs and I think I have a possible solution, its just I have no idea on how to go about implementing it.</p>
  
  <p>Below is a converted function that takes the values in the list
  first one 440Hz for 1800000 msec and created RAW PCM square wave. Which works then appends it to a <code>QByteArray</code> then plays it. </p>
  
  <p>This will work if there isn't a lot of appended data form multiple added sequences.</p>
  
  <p>Im looking for a way to do one at a time from the list then create the wave, play that one for x milliseconds then move on to the next entry in the MySeq list. The list can contain large sequences of 3 minute frequencies that runs for hours. </p>
  
  <pre><code>QStringList MySeq;
  
  MySeq &lt;&lt; "1:440:180000";
  MySeq &lt;&lt; "1:20:180000";
  MySeq &lt;&lt; "1:2120:180000";
  MySeq &lt;&lt; "1:240:180000";
  MySeq &lt;&lt; "1:570:180000";
  
  foreach(QString seq, MySeq)
  {
      QStringList Assits = seq.split(":");
  
      qDebug() &lt;&lt; "Now At: " &lt;&lt; seq;
  
      QString A = Assits.at(0);
      QString B = Assits.at(1);
      QString C = Assits.at(2);
  
      qreal amplitude = A.toInt();
      float frequency = B.toFloat();
      int msecs = C.toInt();
  
      qreal singleWaveTime = amplitude / frequency;
  
      qreal samplesPerWave = qCeil(format-&gt;sampleRate() * singleWaveTime);
  
      quint32 waveCount = qCeil(msecs / (singleWaveTime * 1000.0));
  
      quint32 sampleSize = static_cast&lt;quint32&gt;(format-&gt;sampleSize() / 8.0);
  
      QByteArray data(waveCount * samplesPerWave * sampleSize * format-&gt;channelCount(), '\0');
  
      unsigned char* dataPointer = reinterpret_cast&lt;unsigned char*&gt;(data.data());
  
      for (quint32 currentWave = 0; currentWave &lt; waveCount; currentWave++)
      {
          for (int currentSample = 0; currentSample &lt; samplesPerWave; currentSample++)
          {
              double nextRadStep = (currentSample / static_cast&lt;double&gt;(samplesPerWave)) * (2 * M_PI);
  
              quint16 sampleValue = static_cast&lt;quint16&gt;((qSin(nextRadStep) &gt; 0 ? 1 : -1) * 32767);
  
              for (int channel = 0; channel &lt; format-&gt;channelCount(); channel++)
              {
                  qToLittleEndian(sampleValue, dataPointer);
                  dataPointer += sampleSize;
              }
          }
      }
  
      soundBuffer-&gt;append(data); // HERE IS THE Std::Bad_Alloc
      output-&gt;start(outputBuffer); 
      qDebug() &lt;&lt; data.size()
  }
  </code></pre>
  
  <p>I wish to fill the <code>QByteArray</code> with only one sequence at a time then Play it with <code>QAudioOutput</code> then clear the <code>ByteArray</code> then load the next sequence repeat until all sequences are done in the <code>QStringList</code>. </p>
  
  <p>The problem with this approach now is that <code>QAudioOutput</code> is asynchronous and doesn't wait for the first sequence to finish
  If I loop over the list as demonstrated above they load one after the other with only the last frequency actually playing. its like the loop keep overwriting the previous sequence.</p>
  
  <p>Im not sure if <code>QEventLoop</code> (Something I haven't used yet) is needed here or Threading. I have tried a couple of different approaches with no success. Any advice would be greatly appreciated.  This is a continuation of the following question I had about wave files and data and frequency generations located here
  <a href="https://stackoverflow.com/questions/51239074/qt-c-creating-a-square-audio-tone-wave-play-and-saving-it">Qt C++ Creating a square audio tone wave. Play and saving it</a></p>
  
  <p><strong>mainWindows.h</strong></p>
  
  <pre><code>#ifndef MAINWINDOW_H
  #define MAINWINDOW_H
  
  #include &lt;QMainWindow&gt;
  #include &lt;QtCore&gt;
  #include &lt;QtMultimedia/QAudioOutput&gt;
  
  namespace Ui {
  class MainWindow;
  }
  
  class MainWindow : public QMainWindow
  {
      Q_OBJECT
  
  public:
      explicit MainWindow(QWidget *parent = 0);
      ~MainWindow();
  
  public slots:
  
      void playbackFinished();
  
  private slots:
      void appendSound();
  
      void on_pushButton_Run_clicked();
  
      void on_pushButton_Stop_clicked();
  
  private:
      Ui::MainWindow *ui;
  
      QByteArray   *soundBuffer;
      QBuffer      *outputBuffer;
      QAudioFormat *format;
      QAudioOutput *output;
  };
  
  #endif // MAINWINDOW_H
  </code></pre>
  
  <p><strong>mainWindows.cpp</strong></p>
  
  <pre><code>#include "mainwindow.h"
  #include "ui_mainwindow.h"
  
  #include &lt;QDebug&gt;
  
  int sampleRate = 44100;
  int channelCount = 2;
  int sampleSize = 16;
  const QString codec = "audio/pcm";
  
  MainWindow::MainWindow(QWidget *parent) :
      QMainWindow(parent),
      ui(new Ui::MainWindow)
  {
      ui-&gt;setupUi(this);
  
      soundBuffer = new QByteArray();
  
      format = new QAudioFormat();
      format-&gt;setSampleRate(sampleRate);
      format-&gt;setChannelCount(channelCount);
      format-&gt;setSampleSize(sampleSize);
      format-&gt;setCodec(codec);
      format-&gt;setByteOrder(QAudioFormat::LittleEndian);
      format-&gt;setSampleType(QAudioFormat::UnSignedInt);
  
      output = new QAudioOutput(*format, this);
  
      connect(output, SIGNAL(stateChanged(QAudio::State)), this, SLOT(playbackFinished()));
  
      outputBuffer = new QBuffer(soundBuffer);
      if (outputBuffer-&gt;open(QIODevice::ReadOnly) == false) {
          qCritical() &lt;&lt; "Invalid operation while opening QBuffer. audio/pcm";
          return;
      }
  }
  
  MainWindow::~MainWindow()
  {
      delete ui;
      delete soundBuffer;
      delete format;
      delete output;
      delete outputBuffer;
  }
  
  void MainWindow::playbackFinished()
  {
      if (output-&gt;state() == QAudio::IdleState)
      {
          qDebug() &lt;&lt; "Playback finished";
      }
  }
  
  void MainWindow::appendSound()
  {
  
      QStringList MySq;
  
      MySq &lt;&lt; "1:440:180000";
      MySq &lt;&lt; "1:20:180000";
      MySq &lt;&lt; "1:2120:180000";
      MySq &lt;&lt; "1:240:180000";
      MySq &lt;&lt; "1:570:180000";
      MySq &lt;&lt; "1:570:180000";
      MySq &lt;&lt; "1:570:180000";
      MySq &lt;&lt; "1:850:180000";
      MySq &lt;&lt; "1:1570:180000";
      MySq &lt;&lt; "1:200:180000";
      MySq &lt;&lt; "1:50:180000";
      MySq &lt;&lt; "1:85:180000";
      MySq &lt;&lt; "1:59:180000";
      MySq &lt;&lt; "1:20:180000";
  
      foreach(QString seq, MySq)
      {
          QStringList Assits = seq.split(":");
  
          qDebug() &lt;&lt; "Now At: " &lt;&lt; seq;
  
          QString A = Assits.at(0);
          QString B = Assits.at(1);
          QString C = Assits.at(2);
  
          qreal amplitude = A.toInt();
          float frequency = B.toFloat();
          int msecs = C.toInt();
  
          msecs = (msecs &lt; 50) ? 50 : msecs;
  
          qreal singleWaveTime = amplitude / frequency;
  
          qreal samplesPerWave = qCeil(format-&gt;sampleRate() * singleWaveTime);
  
          quint32 waveCount = qCeil(msecs / (singleWaveTime * 1000.0));
  
          quint32 sampleSize = static_cast&lt;quint32&gt;(format-&gt;sampleSize() / 8.0);
  
          QByteArray data(waveCount * samplesPerWave * sampleSize * format-&gt;channelCount(), '\0');
  
          unsigned char* dataPointer = reinterpret_cast&lt;unsigned char*&gt;(data.data());
  
          for (quint32 currentWave = 0; currentWave &lt; waveCount; currentWave++)
          {
              for (int currentSample = 0; currentSample &lt; samplesPerWave; currentSample++)
              {
                  double nextRadStep = (currentSample / static_cast&lt;double&gt;(samplesPerWave)) * (2 * M_PI);
  
                  quint16 sampleValue = static_cast&lt;quint16&gt;((qSin(nextRadStep) &gt; 0 ? 1 : -1) * 32767);
  
                  for (int channel = 0; channel &lt; format-&gt;channelCount(); channel++)
                  {
                      qToLittleEndian(sampleValue, dataPointer);
                      dataPointer += sampleSize;
                  }
              }
          }
  
          soundBuffer-&gt;append(data); // &lt;-- STD::Bad_alloc Not enough memory on heap for appending all the frequencies at once in buffer 
          output-&gt;start(outputBuffer);
          qDebug() &lt;&lt; data.size();
      }
  }
  
  void MainWindow::on_pushButton_Run_clicked()
  {
      appendSound();
  }
  
  void MainWindow::on_pushButton_Stop_clicked()
  {
      output-&gt;stop();
      soundBuffer-&gt;clear();
      output-&gt;reset();
      qDebug() &lt;&lt; "Playback Stopped";
  }
  </code></pre>