#include "main.h" #include #include #if QT_VERSION_MAJOR > 5 # include # include # include #else # include # include #endif #include Tester::Tester (QByteArray loop, bool underrun, QObject *parent) : QIODevice(parent), simUnderrun(underrun), loop(loop), looppos(0), bytesRead(0) { open(QIODevice::ReadOnly); timer.start(); } qint64 Tester::bytesAvailable () const { if (simUnderrun) { simUnderrun = false; return 0; } return loop.size(); } qint64 Tester::writeData (const char *, qint64) { return -1; } qint64 Tester::readData (char *data, qint64 maxlen) { for (qint64 k = 0; k < maxlen; ++ k) { data[k] = loop.at(looppos ++); looppos %= loop.size(); } bytesRead += maxlen; if (bytesRead >= 256*1024) { float Bps = bytesRead / (timer.nsecsElapsed() / 1000000000.0); float sps = Bps / sizeof(float); qDebug() << "current read rate" << sps << "samples/sec"; bytesRead = 0; timer.restart(); } return maxlen; } int main (int argc, char *argv[]) { #if QT_VERSION_MAJOR > 5 using DeviceInfo = QAudioDevice; using Output = QAudioSink; const auto Outputs = [](){return QMediaDevices::audioOutputs();}; const auto DeviceName = [](auto dev){return dev.description();}; #else using DeviceInfo = QAudioDeviceInfo; using Output = QAudioOutput; const auto Outputs = [](){return QAudioDeviceInfo::availableDevices(QAudio::AudioOutput);}; const auto DeviceName = [](auto dev){return dev.deviceName();}; #endif QCoreApplication a(argc, argv); DeviceInfo device; bool underrun; // usage: audioissue // audioissue [] // no params = list devices // = device index // = can be anything; simulate underrun if set. if (argc < 2) { auto devs = Outputs(); for (int k = 0; k < devs.size(); ++ k) qDebug() << k << DeviceName(devs[k]); return 0; } else { device = Outputs()[atoi(argv[1])]; underrun = (argc >= 3); } QAudioFormat format = device.preferredFormat(); format.setChannelCount(1); #if QT_VERSION_MAJOR > 5 format.setSampleFormat(QAudioFormat::Float); #else format.setSampleSize(32); format.setSampleType(QAudioFormat::Float); #endif assert(device.isFormatSupported(format)); Output *output = new Output(device, format); // 1 second of a 440hz sine wave QByteArray loop; for (int k = 0; k < format.sampleRate(); ++ k) { float val = sinf(440.0f * 2.0f * 3.141592653f * k / format.sampleRate()); loop.append((const char *)&val, sizeof(float)); } Tester *tester = new Tester(loop, underrun); output->start(tester); qDebug() << output->state() << output->error(); return a.exec(); }