Created base class for sample sources
This commit is contained in:
74
audiodevice.cpp
Normal file
74
audiodevice.cpp
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
#include "audiodevice.h"
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QIODevice>
|
||||||
|
#include <QAudioInput>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
//! private helper to allow QAudioInput to write to a io device
|
||||||
|
class AudioDeviceHelper : public QIODevice
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit AudioDeviceHelper(AudioDevice &audioDevice);
|
||||||
|
|
||||||
|
qint64 readData(char *data, qint64 maxlen) override;
|
||||||
|
qint64 writeData(const char *data, qint64 len) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
AudioDevice &m_audioDevice;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioDevice::AudioDevice(QObject *parent) :
|
||||||
|
BaseDevice{parent},
|
||||||
|
m_helper(std::make_unique<AudioDeviceHelper>(*this))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioDevice::~AudioDevice() = default;
|
||||||
|
|
||||||
|
void AudioDevice::start()
|
||||||
|
{
|
||||||
|
QAudioFormat format;
|
||||||
|
format.setSampleRate(m_samplerate);
|
||||||
|
format.setChannelCount(2);
|
||||||
|
format.setSampleSize(16);
|
||||||
|
format.setSampleType(QAudioFormat::SignedInt);
|
||||||
|
format.setCodec("audio/pcm");
|
||||||
|
format.setByteOrder(QAudioFormat::LittleEndian);
|
||||||
|
|
||||||
|
m_input = std::make_unique<QAudioInput>(m_device, format);
|
||||||
|
m_input->start(m_helper.get());
|
||||||
|
m_input->setBufferSize(m_samplerate/m_framerate*sizeof(qint16)*2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioDevice::stop()
|
||||||
|
{
|
||||||
|
m_input = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
AudioDeviceHelper::AudioDeviceHelper(AudioDevice &audioDevice) :
|
||||||
|
QIODevice(&audioDevice),
|
||||||
|
m_audioDevice(audioDevice)
|
||||||
|
{
|
||||||
|
setOpenMode(QIODevice::WriteOnly);
|
||||||
|
}
|
||||||
|
|
||||||
|
qint64 AudioDeviceHelper::readData(char *data, qint64 maxlen)
|
||||||
|
{
|
||||||
|
Q_UNUSED(data)
|
||||||
|
Q_UNUSED(maxlen)
|
||||||
|
qFatal("reading is not allowed!");
|
||||||
|
}
|
||||||
|
|
||||||
|
qint64 AudioDeviceHelper::writeData(const char *data, qint64 len)
|
||||||
|
{
|
||||||
|
Q_ASSERT(len % sizeof(SamplePair) == 0);
|
||||||
|
emit m_audioDevice.samplesReceived(reinterpret_cast<const SamplePair*>(data),
|
||||||
|
reinterpret_cast<const SamplePair*>(data + (len/sizeof(SamplePair))));
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
}
|
45
audiodevice.h
Normal file
45
audiodevice.h
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "basedevice.h"
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QAudioDeviceInfo>
|
||||||
|
|
||||||
|
// system includes
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
// forward declares
|
||||||
|
namespace { class AudioDeviceHelper; }
|
||||||
|
class QAudioInput;
|
||||||
|
|
||||||
|
class AudioDevice : public BaseDevice
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit AudioDevice(QObject *parent = nullptr);
|
||||||
|
~AudioDevice() override;
|
||||||
|
|
||||||
|
void start() override;
|
||||||
|
void stop() override;
|
||||||
|
bool running() const override { return m_input != nullptr; }
|
||||||
|
|
||||||
|
int samplerate() const override { return m_samplerate; }
|
||||||
|
void setSamplerate(int samplerate) override { Q_ASSERT(!running()); m_samplerate = samplerate; }
|
||||||
|
|
||||||
|
int framerate() const override { return m_framerate; }
|
||||||
|
void setFramerate(int framerate) override { Q_ASSERT(!running()); m_framerate = framerate; }
|
||||||
|
|
||||||
|
const auto &device() const { return m_device; }
|
||||||
|
void setDevice(const QAudioDeviceInfo &device) { Q_ASSERT(!running()); m_device = device; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
const std::unique_ptr<AudioDeviceHelper> m_helper;
|
||||||
|
|
||||||
|
std::unique_ptr<QAudioInput> m_input;
|
||||||
|
|
||||||
|
int m_samplerate;
|
||||||
|
int m_framerate;
|
||||||
|
|
||||||
|
QAudioDeviceInfo m_device;
|
||||||
|
};
|
1
basedevice.cpp
Normal file
1
basedevice.cpp
Normal file
@@ -0,0 +1 @@
|
|||||||
|
#include "basedevice.h"
|
31
basedevice.h
Normal file
31
basedevice.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct SamplePairT {
|
||||||
|
T x, y;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef SamplePairT<qint16> SamplePair;
|
||||||
|
|
||||||
|
class BaseDevice : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
using QObject::QObject;
|
||||||
|
|
||||||
|
virtual void start() = 0;
|
||||||
|
virtual void stop() = 0;
|
||||||
|
virtual bool running() const = 0;
|
||||||
|
|
||||||
|
virtual int samplerate() const = 0;
|
||||||
|
virtual void setSamplerate(int samplerate) = 0;
|
||||||
|
|
||||||
|
virtual int framerate() const = 0;
|
||||||
|
virtual void setFramerate(int framerate) = 0;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void samplesReceived(const SamplePair *begin, const SamplePair *end);
|
||||||
|
};
|
49
device.cpp
49
device.cpp
@@ -1,49 +0,0 @@
|
|||||||
#include "device.h"
|
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
#include <QTimerEvent>
|
|
||||||
|
|
||||||
Device::Device(QObject *parent) :
|
|
||||||
QIODevice(parent)
|
|
||||||
{
|
|
||||||
setOpenMode(QIODevice::WriteOnly);
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 Device::readData(char *data, qint64 maxlen)
|
|
||||||
{
|
|
||||||
Q_UNUSED(data)
|
|
||||||
Q_UNUSED(maxlen)
|
|
||||||
qFatal("oida");
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 Device::writeData(const char *data, qint64 len)
|
|
||||||
{
|
|
||||||
Q_ASSERT(len % sizeof(SamplePair) == 0);
|
|
||||||
emit samplesReceived(reinterpret_cast<const SamplePair*>(data),
|
|
||||||
reinterpret_cast<const SamplePair*>(data + (len/sizeof(SamplePair))));
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
FakeDevice::FakeDevice(QObject *parent) :
|
|
||||||
QObject(parent), m_timerId(startTimer(1000/60)), m_dingsDesHaltHochZaehlt(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void FakeDevice::timerEvent(QTimerEvent *event)
|
|
||||||
{
|
|
||||||
if (event->timerId() == m_timerId)
|
|
||||||
{
|
|
||||||
std::array<SamplePair, 44100/60> samples;
|
|
||||||
for (SamplePair &pair : samples)
|
|
||||||
{
|
|
||||||
pair.x = std::sin(m_dingsDesHaltHochZaehlt) * std::numeric_limits<qint16>::max();
|
|
||||||
pair.y = std::cos(m_dingsDesHaltHochZaehlt) * std::numeric_limits<qint16>::max();
|
|
||||||
m_dingsDesHaltHochZaehlt += 0.05;
|
|
||||||
}
|
|
||||||
|
|
||||||
emit samplesReceived(samples.begin(), samples.end());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
QObject::timerEvent(event);
|
|
||||||
}
|
|
45
device.h
45
device.h
@@ -1,45 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QIODevice>
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
#define qvoid void
|
|
||||||
|
|
||||||
template<typename T> struct SamplePairT {
|
|
||||||
T x, y;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef SamplePairT<qint16> SamplePair;
|
|
||||||
|
|
||||||
class Device : public QIODevice
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit Device(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void samplesReceived(const SamplePair *begin, const SamplePair *end);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
qint64 readData(char *data, qint64 maxlen) override;
|
|
||||||
qint64 writeData(const char *data, qint64 len) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
class FakeDevice : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit FakeDevice(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void samplesReceived(const SamplePair *begin, const SamplePair *end);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
qvoid timerEvent(QTimerEvent *event) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
double m_dingsDesHaltHochZaehlt;
|
|
||||||
const int m_timerId;
|
|
||||||
};
|
|
46
fakedevice.cpp
Normal file
46
fakedevice.cpp
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
#include "fakedevice.h"
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QTimerEvent>
|
||||||
|
|
||||||
|
// system includes
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
void FakeDevice::start()
|
||||||
|
{
|
||||||
|
Q_ASSERT(!running());
|
||||||
|
m_bufferSize = m_samplerate/m_framerate;
|
||||||
|
m_buffer = std::make_unique<SamplePair[]>(m_bufferSize);
|
||||||
|
m_timerId = startTimer(1000/m_framerate);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FakeDevice::stop()
|
||||||
|
{
|
||||||
|
Q_ASSERT(running());
|
||||||
|
killTimer(m_timerId);
|
||||||
|
m_buffer = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FakeDevice::running() const
|
||||||
|
{
|
||||||
|
return m_timerId != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FakeDevice::timerEvent(QTimerEvent *event)
|
||||||
|
{
|
||||||
|
if (event->timerId() == m_timerId)
|
||||||
|
{
|
||||||
|
for (SamplePair *pair = m_buffer.get();
|
||||||
|
pair != m_buffer.get() + m_bufferSize;
|
||||||
|
pair++)
|
||||||
|
{
|
||||||
|
pair->x = std::sin(m_dingsDesHaltHochZaehlt) * std::numeric_limits<qint16>::max();
|
||||||
|
pair->y = std::cos(m_dingsDesHaltHochZaehlt) * std::numeric_limits<qint16>::max();
|
||||||
|
m_dingsDesHaltHochZaehlt += 0.05;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit samplesReceived(m_buffer.get(), m_buffer.get() + m_bufferSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
QObject::timerEvent(event);
|
||||||
|
}
|
37
fakedevice.h
Normal file
37
fakedevice.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "basedevice.h"
|
||||||
|
|
||||||
|
// system includes
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class FakeDevice : public BaseDevice
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
using BaseDevice::BaseDevice;
|
||||||
|
|
||||||
|
void start() override;
|
||||||
|
void stop() override;
|
||||||
|
bool running() const override;
|
||||||
|
|
||||||
|
int samplerate() const override { return m_samplerate; }
|
||||||
|
void setSamplerate(int samplerate) override { Q_ASSERT(!running()); m_samplerate = samplerate; }
|
||||||
|
|
||||||
|
int framerate() const override { return m_framerate; }
|
||||||
|
void setFramerate(int framerate) override { Q_ASSERT(!running()); m_framerate = framerate; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void timerEvent(QTimerEvent *event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
double m_dingsDesHaltHochZaehlt{0.};
|
||||||
|
int m_timerId{-1};
|
||||||
|
|
||||||
|
std::unique_ptr<SamplePair[]> m_buffer;
|
||||||
|
std::size_t m_bufferSize;
|
||||||
|
|
||||||
|
int m_samplerate{44100};
|
||||||
|
int m_framerate{15};
|
||||||
|
};
|
@@ -1,109 +1,98 @@
|
|||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
#include "ui_mainwindow.h"
|
||||||
|
|
||||||
#include <QAudioInput>
|
// Qt includes
|
||||||
#include <QAudioFormat>
|
|
||||||
#include <QAudioDeviceInfo>
|
|
||||||
#include <QButtonGroup>
|
#include <QButtonGroup>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QStringBuilder>
|
#include <QStringBuilder>
|
||||||
#include <QRadioButton>
|
#include <QRadioButton>
|
||||||
|
|
||||||
MainWindow::MainWindow(QWidget *parent)
|
// local includes
|
||||||
: QMainWindow(parent)
|
#include "audiodevice.h"
|
||||||
, m_audioDevices(QAudioDeviceInfo::availableDevices(QAudio::AudioInput))
|
#include "fakedevice.h"
|
||||||
, m_ui()
|
|
||||||
|
MainWindow::MainWindow(QWidget *parent) :
|
||||||
|
QMainWindow{parent},
|
||||||
|
m_ui{std::make_unique<Ui::MainWindow>()},
|
||||||
|
m_audioDevices{QAudioDeviceInfo::availableDevices(QAudio::AudioInput)},
|
||||||
|
m_input{std::make_unique<AudioDevice>()}
|
||||||
|
//m_input{std::make_unique<FakeDevice>()}
|
||||||
{
|
{
|
||||||
m_ui.setupUi(this);
|
m_ui->setupUi(this);
|
||||||
|
|
||||||
connect(&m_device, &Device::samplesReceived, m_ui.widget, &OsciWidget::renderSamples);
|
connect(m_input.get(), &BaseDevice::samplesReceived, m_ui->widget, &OsciWidget::renderSamples);
|
||||||
|
|
||||||
//connect(&m_fakeDevice, &FakeDevice::samplesReceived, m_ui.widget, &OsciWidget::samplesReceived);
|
|
||||||
|
|
||||||
for (const auto &device : m_audioDevices)
|
for (const auto &device : m_audioDevices)
|
||||||
{
|
{
|
||||||
auto name = device.deviceName();
|
auto name = device.deviceName();
|
||||||
m_ui.comboBoxDevices->addItem(name);
|
m_ui->comboBoxDevices->addItem(name);
|
||||||
|
|
||||||
// Select last element containing monitor if available
|
// Select last element containing monitor if available
|
||||||
if(name.contains("monitor"))
|
if(name.contains("monitor"))
|
||||||
{
|
{
|
||||||
m_ui.comboBoxDevices->setCurrentIndex(m_ui.comboBoxDevices->count()-1);
|
m_ui->comboBoxDevices->setCurrentIndex(m_ui->comboBoxDevices->count()-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_ui.comboBoxDevices->count())
|
|
||||||
m_ui.comboBoxDevices->setCurrentIndex(m_audioDevices.count()-1);
|
|
||||||
|
|
||||||
for (const auto samplerate : { 44100, 48000, 96000, 192000 })
|
for (const auto samplerate : { 44100, 48000, 96000, 192000 })
|
||||||
m_ui.comboBoxSamplerate->addItem(tr("%0").arg(samplerate), samplerate);
|
m_ui->comboBoxSamplerate->addItem(tr("%0").arg(samplerate), samplerate);
|
||||||
|
|
||||||
connect(m_ui.pushButtonToggle, &QAbstractButton::pressed, this, &MainWindow::toggle);
|
connect(m_ui->pushButtonToggle, &QAbstractButton::pressed, this, &MainWindow::toggle);
|
||||||
|
|
||||||
for (const auto framerate : {15, 30, 50, 60})
|
for (const auto framerate : {15, 30, 50, 60})
|
||||||
m_ui.comboBoxFps->addItem(tr("%0 FPS").arg(framerate), framerate);
|
m_ui->comboBoxFps->addItem(tr("%0 FPS").arg(framerate), framerate);
|
||||||
|
|
||||||
m_ui.comboBoxFps->setCurrentIndex(m_ui.comboBoxFps->findData(m_ui.widget->framerate()));
|
m_ui->spinBoxBlend->setValue(m_ui->widget->blend());
|
||||||
|
|
||||||
connect(m_ui.comboBoxFps, &QComboBox::currentIndexChanged, this, [&combobox=*m_ui.comboBoxFps,&widget=*m_ui.widget](){
|
connect(m_ui->spinBoxBlend, qOverload<int>(&QSpinBox::valueChanged), m_ui->widget, &OsciWidget::setBlend);
|
||||||
widget.setFramerate(combobox.currentData().toInt());
|
|
||||||
});
|
|
||||||
|
|
||||||
m_ui.spinBoxBlend->setValue(m_ui.widget->blend());
|
m_ui->spinBoxGlow->setValue(m_ui->widget->glow());
|
||||||
|
|
||||||
connect(m_ui.spinBoxBlend, qOverload<int>(&QSpinBox::valueChanged), m_ui.widget, &OsciWidget::setBlend);
|
connect(m_ui->spinBoxGlow, qOverload<int>(&QSpinBox::valueChanged), m_ui->widget, &OsciWidget::setGlow);
|
||||||
|
|
||||||
m_ui.spinBoxGlow->setValue(m_ui.widget->glow());
|
|
||||||
|
|
||||||
connect(m_ui.spinBoxGlow, qOverload<int>(&QSpinBox::valueChanged), m_ui.widget, &OsciWidget::setGlow);
|
|
||||||
|
|
||||||
auto buttonGroup = new QButtonGroup;
|
auto buttonGroup = new QButtonGroup;
|
||||||
buttonGroup->setExclusive(true);
|
buttonGroup->setExclusive(true);
|
||||||
for (auto factor : { .5f, 1.f, 2.f, 4.f, 8.f })
|
for (auto factor : { .5f, 1.f, 2.f, 4.f, 8.f })
|
||||||
{
|
{
|
||||||
auto radioButton = new QRadioButton(QString::number(factor));
|
auto radioButton = new QRadioButton(QString::number(factor));
|
||||||
connect(radioButton, &QRadioButton::pressed, this, [factor,&widget=*m_ui.widget](){
|
connect(radioButton, &QRadioButton::pressed, this, [factor,&widget=*m_ui->widget](){
|
||||||
widget.setFactor(factor);
|
widget.setFactor(factor);
|
||||||
});
|
});
|
||||||
m_ui.horizontalLayout->addWidget(radioButton);
|
m_ui->horizontalLayout->addWidget(radioButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_ui.comboBoxDevices->count())
|
if (m_ui->comboBoxDevices->count())
|
||||||
toggle();
|
toggle();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::toggle()
|
void MainWindow::toggle()
|
||||||
{
|
{
|
||||||
if (!m_ui.comboBoxDevices->count())
|
if (!m_ui->comboBoxDevices->count())
|
||||||
{
|
{
|
||||||
QMessageBox::warning(this, tr("Failed to start!"), tr("Failed to start!") % "\n\n" % tr("No audio devices available!"));
|
QMessageBox::warning(this, tr("Failed to start!"), tr("Failed to start!") % "\n\n" % tr("No audio devices available!"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_input)
|
if (m_input->running())
|
||||||
{
|
{
|
||||||
m_input = nullptr;
|
m_input->stop();
|
||||||
m_ui.comboBoxDevices->setEnabled(true);
|
m_ui->comboBoxDevices->setEnabled(true);
|
||||||
m_ui.comboBoxSamplerate->setEnabled(true);
|
m_ui->comboBoxSamplerate->setEnabled(true);
|
||||||
m_ui.pushButtonToggle->setText("▶");
|
m_ui->comboBoxFps->setEnabled(true);
|
||||||
|
m_ui->pushButtonToggle->setText("▶");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QAudioFormat format;
|
m_input->setSamplerate(m_ui->comboBoxSamplerate->currentData().toInt());
|
||||||
format.setSampleRate(m_ui.comboBoxSamplerate->currentData().toInt());
|
m_input->setFramerate(m_ui->comboBoxFps->currentData().toInt());
|
||||||
format.setChannelCount(2);
|
if (auto audioDevice = dynamic_cast<AudioDevice*>(m_input.get()))
|
||||||
format.setSampleSize(16);
|
audioDevice->setDevice(m_audioDevices.at(m_ui->comboBoxDevices->currentIndex()));
|
||||||
format.setSampleType(QAudioFormat::SignedInt);
|
m_input->start();
|
||||||
format.setCodec("audio/pcm");
|
|
||||||
format.setByteOrder(QAudioFormat::LittleEndian);
|
|
||||||
|
|
||||||
if(m_audioDevices.empty()){
|
m_ui->comboBoxDevices->setEnabled(false);
|
||||||
qFatal("No audio devices found");
|
m_ui->comboBoxSamplerate->setEnabled(false);
|
||||||
}
|
m_ui->comboBoxFps->setEnabled(false);
|
||||||
m_input = std::make_unique<QAudioInput>(m_audioDevices.at(m_ui.comboBoxDevices->currentIndex()), format);
|
m_ui->pushButtonToggle->setText("▮▮");
|
||||||
m_input->start(&m_device);
|
|
||||||
m_input->setBufferSize(format.sampleRate()/60*sizeof(qint16)*2);
|
|
||||||
m_ui.comboBoxDevices->setEnabled(false);
|
|
||||||
m_ui.comboBoxSamplerate->setEnabled(false);
|
|
||||||
m_ui.pushButtonToggle->setText("▮▮");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
18
mainwindow.h
18
mainwindow.h
@@ -1,16 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
|
|
||||||
|
// system includes
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "device.h"
|
// forward declares
|
||||||
#include "ui_mainwindow.h"
|
|
||||||
|
|
||||||
class QAudioInput;
|
|
||||||
class QAudioFormat;
|
|
||||||
class QAudioDeviceInfo;
|
class QAudioDeviceInfo;
|
||||||
namespace Ui { class MainWindow; }
|
namespace Ui { class MainWindow; }
|
||||||
|
class BaseDevice;
|
||||||
|
|
||||||
class MainWindow : public QMainWindow
|
class MainWindow : public QMainWindow
|
||||||
{
|
{
|
||||||
@@ -24,12 +23,9 @@ private slots:
|
|||||||
void toggle();
|
void toggle();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::MainWindow m_ui;
|
const std::unique_ptr<Ui::MainWindow> m_ui;
|
||||||
|
|
||||||
std::unique_ptr<QAudioInput> m_input;
|
|
||||||
|
|
||||||
Device m_device;
|
|
||||||
//FakeDevice m_fakeDevice;
|
|
||||||
|
|
||||||
const QList<QAudioDeviceInfo> m_audioDevices;
|
const QList<QAudioDeviceInfo> m_audioDevices;
|
||||||
|
|
||||||
|
const std::unique_ptr<BaseDevice> m_input;
|
||||||
};
|
};
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>800</width>
|
<width>800</width>
|
||||||
<height>600</height>
|
<height>860</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@@ -42,6 +42,9 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QComboBox" name="comboBoxSamplerate"/>
|
<widget class="QComboBox" name="comboBoxSamplerate"/>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="comboBoxFps"/>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="pushButtonToggle">
|
<widget class="QPushButton" name="pushButtonToggle">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -62,9 +65,6 @@
|
|||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="comboBoxFps"/>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QSpinBox" name="spinBoxBlend">
|
<widget class="QSpinBox" name="spinBoxBlend">
|
||||||
<property name="suffix">
|
<property name="suffix">
|
||||||
|
@@ -4,13 +4,17 @@ CONFIG += c++17
|
|||||||
DEFINES += QT_DEPRECATED_WARNINGS QT_DISABLE_DEPRECATED_BEFORE=0x060000
|
DEFINES += QT_DEPRECATED_WARNINGS QT_DISABLE_DEPRECATED_BEFORE=0x060000
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
device.cpp \
|
audiodevice.cpp \
|
||||||
|
basedevice.cpp \
|
||||||
|
fakedevice.cpp \
|
||||||
main.cpp \
|
main.cpp \
|
||||||
mainwindow.cpp \
|
mainwindow.cpp \
|
||||||
osciwidget.cpp
|
osciwidget.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
device.h \
|
audiodevice.h \
|
||||||
|
basedevice.h \
|
||||||
|
fakedevice.h \
|
||||||
mainwindow.h \
|
mainwindow.h \
|
||||||
osciwidget.h
|
osciwidget.h
|
||||||
|
|
||||||
|
@@ -5,17 +5,11 @@
|
|||||||
#include <QLine>
|
#include <QLine>
|
||||||
|
|
||||||
OsciWidget::OsciWidget(QWidget *parent) :
|
OsciWidget::OsciWidget(QWidget *parent) :
|
||||||
QOpenGLWidget(parent)
|
QOpenGLWidget{parent}
|
||||||
{
|
{
|
||||||
restartTimer();
|
|
||||||
resizePixmap();
|
resizePixmap();
|
||||||
}
|
}
|
||||||
|
|
||||||
int OsciWidget::framerate() const
|
|
||||||
{
|
|
||||||
return m_framerate;
|
|
||||||
}
|
|
||||||
|
|
||||||
int OsciWidget::blend() const
|
int OsciWidget::blend() const
|
||||||
{
|
{
|
||||||
return m_blend;
|
return m_blend;
|
||||||
@@ -31,18 +25,6 @@ float OsciWidget::glow() const
|
|||||||
return m_glow;
|
return m_glow;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OsciWidget::setFramerate(int framerate)
|
|
||||||
{
|
|
||||||
if (framerate == m_framerate)
|
|
||||||
return;
|
|
||||||
|
|
||||||
qDebug() << framerate;
|
|
||||||
|
|
||||||
m_framerate = framerate;
|
|
||||||
|
|
||||||
restartTimer();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OsciWidget::setBlend(int blend)
|
void OsciWidget::setBlend(int blend)
|
||||||
{
|
{
|
||||||
if (blend == m_blend)
|
if (blend == m_blend)
|
||||||
@@ -110,7 +92,13 @@ void OsciWidget::renderSamples(const SamplePair *begin, const SamplePair *end)
|
|||||||
m_lastPoint = p;
|
m_lastPoint = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
painter.resetTransform();
|
||||||
|
painter.setCompositionMode(QPainter::CompositionMode_Multiply);
|
||||||
|
painter.fillRect(m_pixmap.rect(), QColor(m_blend,m_blend,m_blend));
|
||||||
|
|
||||||
painter.end();
|
painter.end();
|
||||||
|
|
||||||
|
repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OsciWidget::paintEvent(QPaintEvent *event)
|
void OsciWidget::paintEvent(QPaintEvent *event)
|
||||||
@@ -121,22 +109,6 @@ void OsciWidget::paintEvent(QPaintEvent *event)
|
|||||||
painter.begin(this);
|
painter.begin(this);
|
||||||
painter.drawPixmap(0, 0, m_pixmap);
|
painter.drawPixmap(0, 0, m_pixmap);
|
||||||
painter.end();
|
painter.end();
|
||||||
// Fade pixmap by multiplying all pixels by m_blend
|
|
||||||
|
|
||||||
painter.begin(&m_pixmap);
|
|
||||||
painter.setCompositionMode(QPainter::CompositionMode_Multiply);
|
|
||||||
painter.fillRect(m_pixmap.rect(), QColor(m_blend,m_blend,m_blend));
|
|
||||||
painter.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OsciWidget::timerEvent(QTimerEvent *event)
|
|
||||||
{
|
|
||||||
if (event->timerId() == m_timerId)
|
|
||||||
{
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
QWidget::timerEvent(event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OsciWidget::resizeEvent(QResizeEvent *event)
|
void OsciWidget::resizeEvent(QResizeEvent *event)
|
||||||
@@ -146,23 +118,6 @@ void OsciWidget::resizeEvent(QResizeEvent *event)
|
|||||||
resizePixmap();
|
resizePixmap();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OsciWidget::stop()
|
|
||||||
{
|
|
||||||
if (m_timerId != -1)
|
|
||||||
killTimer(m_timerId);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OsciWidget::start()
|
|
||||||
{
|
|
||||||
m_timerId = startTimer(1000/m_framerate);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OsciWidget::restartTimer()
|
|
||||||
{
|
|
||||||
stop();
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OsciWidget::resizePixmap()
|
void OsciWidget::resizePixmap()
|
||||||
{
|
{
|
||||||
m_pixmap = QPixmap(size());
|
m_pixmap = QPixmap(size());
|
||||||
|
11
osciwidget.h
11
osciwidget.h
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
#include "device.h"
|
#include "audiodevice.h"
|
||||||
|
|
||||||
class OsciWidget : public QOpenGLWidget
|
class OsciWidget : public QOpenGLWidget
|
||||||
{
|
{
|
||||||
@@ -21,16 +21,11 @@ class OsciWidget : public QOpenGLWidget
|
|||||||
public:
|
public:
|
||||||
explicit OsciWidget(QWidget *parent = nullptr);
|
explicit OsciWidget(QWidget *parent = nullptr);
|
||||||
|
|
||||||
int framerate() const;
|
|
||||||
int blend() const;
|
int blend() const;
|
||||||
float factor() const;
|
float factor() const;
|
||||||
float glow() const;
|
float glow() const;
|
||||||
|
|
||||||
void start();
|
|
||||||
void stop();
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setFramerate(int framerate);
|
|
||||||
void setBlend(int blend);
|
void setBlend(int blend);
|
||||||
void setFactor(float factor);
|
void setFactor(float factor);
|
||||||
void setGlow(float glow);
|
void setGlow(float glow);
|
||||||
@@ -39,16 +34,12 @@ public slots:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *event) override;
|
void paintEvent(QPaintEvent *event) override;
|
||||||
void timerEvent(QTimerEvent *event) override;
|
|
||||||
void resizeEvent(QResizeEvent *event) override;
|
void resizeEvent(QResizeEvent *event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void restartTimer();
|
|
||||||
void resizePixmap();
|
void resizePixmap();
|
||||||
void createBlendPixmap();
|
void createBlendPixmap();
|
||||||
|
|
||||||
int m_timerId{-1};
|
|
||||||
int m_framerate{15};
|
|
||||||
int m_blend{150};
|
int m_blend{150};
|
||||||
float m_factor{4.f};
|
float m_factor{4.f};
|
||||||
float m_glow{512.f};
|
float m_glow{512.f};
|
||||||
|
Reference in New Issue
Block a user