mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-06 13:31:55 +00:00
Makes sure the timer really, really is on a different thread.
Thereby allows me substantially to reduce audio latency.
This commit is contained in:
parent
530ff7471d
commit
d08ffd6c8b
73
OSBindings/Qt/.gitignore
vendored
Normal file
73
OSBindings/Qt/.gitignore
vendored
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
# This file is used to ignore files which are generated
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
*~
|
||||||
|
*.autosave
|
||||||
|
*.a
|
||||||
|
*.core
|
||||||
|
*.moc
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
*.orig
|
||||||
|
*.rej
|
||||||
|
*.so
|
||||||
|
*.so.*
|
||||||
|
*_pch.h.cpp
|
||||||
|
*_resource.rc
|
||||||
|
*.qm
|
||||||
|
.#*
|
||||||
|
*.*#
|
||||||
|
core
|
||||||
|
!core/
|
||||||
|
tags
|
||||||
|
.DS_Store
|
||||||
|
.directory
|
||||||
|
*.debug
|
||||||
|
Makefile*
|
||||||
|
*.prl
|
||||||
|
*.app
|
||||||
|
moc_*.cpp
|
||||||
|
ui_*.h
|
||||||
|
qrc_*.cpp
|
||||||
|
Thumbs.db
|
||||||
|
*.res
|
||||||
|
*.rc
|
||||||
|
/.qmake.cache
|
||||||
|
/.qmake.stash
|
||||||
|
|
||||||
|
# qtcreator generated files
|
||||||
|
*.pro.user*
|
||||||
|
|
||||||
|
# xemacs temporary files
|
||||||
|
*.flc
|
||||||
|
|
||||||
|
# Vim temporary files
|
||||||
|
.*.swp
|
||||||
|
|
||||||
|
# Visual Studio generated files
|
||||||
|
*.ib_pdb_index
|
||||||
|
*.idb
|
||||||
|
*.ilk
|
||||||
|
*.pdb
|
||||||
|
*.sln
|
||||||
|
*.suo
|
||||||
|
*.vcproj
|
||||||
|
*vcproj.*.*.user
|
||||||
|
*.ncb
|
||||||
|
*.sdf
|
||||||
|
*.opensdf
|
||||||
|
*.vcxproj
|
||||||
|
*vcxproj.*
|
||||||
|
|
||||||
|
# MinGW generated files
|
||||||
|
*.Debug
|
||||||
|
*.Release
|
||||||
|
|
||||||
|
# Python byte code
|
||||||
|
*.pyc
|
||||||
|
|
||||||
|
# Binaries
|
||||||
|
# --------
|
||||||
|
*.dll
|
||||||
|
*.exe
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
QT += core gui multimedia quickwidgets
|
QT += core gui multimedia
|
||||||
|
|
||||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||||
|
|
||||||
|
@ -63,7 +63,15 @@ void MainWindow::open() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::~MainWindow() {
|
MainWindow::~MainWindow() {
|
||||||
// Stop the timer
|
// Stop the audio output, and its thread.
|
||||||
|
if(audioOutput) {
|
||||||
|
audioOutput->stop();
|
||||||
|
|
||||||
|
audioThread.quit();
|
||||||
|
while(audioThread.isRunning());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop the timer.
|
||||||
timer.reset();
|
timer.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,7 +150,7 @@ void MainWindow::launchMachine() {
|
|||||||
// Install audio output if required.
|
// Install audio output if required.
|
||||||
const auto audio_producer = machine->audio_producer();
|
const auto audio_producer = machine->audio_producer();
|
||||||
if(audio_producer) {
|
if(audio_producer) {
|
||||||
static constexpr size_t samplesPerBuffer = 2048; // TODO: select this dynamically; it's very high.
|
static constexpr size_t samplesPerBuffer = 256; // TODO: select this dynamically.
|
||||||
const auto speaker = audio_producer->get_speaker();
|
const auto speaker = audio_producer->get_speaker();
|
||||||
if(speaker) {
|
if(speaker) {
|
||||||
const QAudioDeviceInfo &defaultDeviceInfo = QAudioDeviceInfo::defaultOutputDevice();
|
const QAudioDeviceInfo &defaultDeviceInfo = QAudioDeviceInfo::defaultOutputDevice();
|
||||||
@ -175,8 +183,7 @@ void MainWindow::launchMachine() {
|
|||||||
// If this is a timed machine, start up the timer.
|
// If this is a timed machine, start up the timer.
|
||||||
const auto timedMachine = machine->timed_machine();
|
const auto timedMachine = machine->timed_machine();
|
||||||
if(timedMachine) {
|
if(timedMachine) {
|
||||||
timer->setMachine(timedMachine, &machineMutex);
|
timer->startWithMachine(timedMachine, &machineMutex);
|
||||||
timer->start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
@ -6,21 +6,23 @@
|
|||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
Timer::Timer(QObject *parent) : QObject(parent) {
|
Timer::Timer(QObject *parent) : QObject(parent) {
|
||||||
// Set up the emulation timer. Bluffer's guide: the QTimer will post an
|
thread.setFunction([this] {
|
||||||
// event to an event loop. QThread is a thread with an event loop.
|
// Set up the emulation timer. Bluffer's guide: the QTimer will post an
|
||||||
// My class, Timer, will be wired up to receive the QTimer's events.
|
// event to an event loop. QThread is a thread with an event loop.
|
||||||
timer = std::make_unique<QTimer>(this);
|
// My class, Timer, will be wired up to receive the QTimer's events.
|
||||||
timer->setInterval(1);
|
timer = std::make_unique<QTimer>(&thread);
|
||||||
|
timer->setInterval(1);
|
||||||
|
|
||||||
thread = std::make_unique<QThread>(this);
|
connect(timer.get(), SIGNAL(timeout()), this, SLOT(tick()), Qt::DirectConnection);
|
||||||
|
timer->start();
|
||||||
moveToThread(thread.get());
|
});
|
||||||
connect(timer.get(), SIGNAL(timeout()), this, SLOT(tick()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Timer::setMachine(MachineTypes::TimedMachine *machine, std::mutex *machineMutex) {
|
void Timer::startWithMachine(MachineTypes::TimedMachine *machine, std::mutex *machineMutex) {
|
||||||
this->machine = machine;
|
this->machine = machine;
|
||||||
this->machineMutex = machineMutex;
|
this->machineMutex = machineMutex;
|
||||||
|
|
||||||
|
thread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Timer::tick() {
|
void Timer::tick() {
|
||||||
@ -33,14 +35,9 @@ void Timer::tick() {
|
|||||||
machine->run_for(double(duration) / 1e9);
|
machine->run_for(double(duration) / 1e9);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Timer::start() {
|
|
||||||
thread->start();
|
|
||||||
timer->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
Timer::~Timer() {
|
Timer::~Timer() {
|
||||||
// Stop the timer, then ask the QThread to exit and wait for it to do so.
|
// Stop the timer, then ask the QThread to exit and wait for it to do so.
|
||||||
timer->stop();
|
timer->stop();
|
||||||
thread->exit();
|
thread.exit();
|
||||||
while(thread->isRunning());
|
while(thread.isRunning());
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
#include "../../Machines/Utility/MachineForTarget.hpp"
|
#include "../../Machines/Utility/MachineForTarget.hpp"
|
||||||
|
#include "functionthread.h"
|
||||||
|
|
||||||
class Timer : public QObject
|
class Timer : public QObject
|
||||||
{
|
{
|
||||||
@ -17,8 +18,7 @@ class Timer : public QObject
|
|||||||
explicit Timer(QObject *parent = nullptr);
|
explicit Timer(QObject *parent = nullptr);
|
||||||
~Timer();
|
~Timer();
|
||||||
|
|
||||||
void setMachine(MachineTypes::TimedMachine *machine, std::mutex *machineMutex);
|
void startWithMachine(MachineTypes::TimedMachine *machine, std::mutex *machineMutex);
|
||||||
void start();
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void tick();
|
void tick();
|
||||||
@ -27,7 +27,7 @@ class Timer : public QObject
|
|||||||
MachineTypes::TimedMachine *machine = nullptr;
|
MachineTypes::TimedMachine *machine = nullptr;
|
||||||
std::mutex *machineMutex = nullptr;
|
std::mutex *machineMutex = nullptr;
|
||||||
int64_t lastTickNanos = 0;
|
int64_t lastTickNanos = 0;
|
||||||
std::unique_ptr<QThread> thread;
|
FunctionThread thread;
|
||||||
std::unique_ptr<QTimer> timer;
|
std::unique_ptr<QTimer> timer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user