added audio settings options for selection of device, samplrate and buffer size, also fixed: #65 & fixed: #64

This commit is contained in:
Dave Griffiths
2022-10-03 09:56:25 +01:00
parent fb8d607e2d
commit 4a4ab8b41a
19 changed files with 859 additions and 282 deletions

View File

@ -14,6 +14,9 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef MAIN_WINDOW
#define MAIN_WINDOW
#include <QtGui>
#include <iostream>
#include <list>
@ -45,7 +48,9 @@ MainWindow::MainWindow() :
m_Ui.brain_contents->setAlignment(Qt::AlignTop);
m_Ui.brain_contents->setSpacing(0);
m_Ui.brain_contents->setContentsMargins(0,0,0,0);
m_settings_dialog = new SettingsDialog(this);
// add default local dest
// turn on first one
@ -183,3 +188,5 @@ void MainWindow::init_from_session(const string &filename) {
}
#endif

View File

@ -19,6 +19,7 @@
#include <QFileDialog>
#include <QLineEdit>
#include "ui_samplebrain.h"
#include "SettingsDialog.h"
#include <iostream>
#include <lo/lo.h>
@ -26,6 +27,7 @@
#include <list>
#include "feedback.h"
#include "sound_items.h"
#include "audio_thread.h"
using namespace std;
using namespace spiralcore;
@ -37,7 +39,65 @@ class MainWindow : public QMainWindow
public:
MainWindow();
// all this to work around liblo's use of varargs...
void send_audio_osc(const char *name, const char *types) {
for (auto dest:m_destinations) {
if (dest.m_enabled) {
lo_send(dest.m_audio_address,name,types);
}
}
}
template <class T>
void send_audio_osc(const char *name, const char *types, T val) {
for (auto dest:m_destinations) {
if (dest.m_enabled) {
lo_send(dest.m_audio_address,name,types,val);
}
}
}
void send_process_osc(const char *name, const char *types) {
for (auto dest:m_destinations) {
if (dest.m_enabled) {
lo_send(dest.m_process_address,name,types);
}
}
}
template <class T>
void send_process_osc(const char *name, const char *types, T val) {
for (auto dest:m_destinations) {
if (dest.m_enabled) {
lo_send(dest.m_process_address,name,types,val);
}
}
}
void set_audio_thread(audio_thread *at) {
m_audio_thread=at;
m_audio_thread->start_audio();
for (auto &d:m_audio_thread->m_audio_device->m_client.m_devices) {
if (d.id==0) {
m_settings_dialog->m_Ui.deviceComboBox->clear();
}
m_settings_dialog->m_Ui.deviceComboBox->addItem(d.name.c_str());
if (d.default_output==1) {
m_settings_dialog->m_device=d.name;
m_settings_dialog->m_Ui.deviceComboBox->setCurrentText(d.name.c_str());
}
}
m_settings_dialog->m_Ui.messagesLabel->setText(m_audio_thread->m_audio_device->m_client.m_status.c_str());
}
audio_thread *get_audio_thread() {
return m_audio_thread;
}
protected:
private slots:
@ -310,7 +370,7 @@ private slots:
}
void update_status() {
m_feedback.poll(m_Ui.statusbar,&m_sound_items);
m_feedback.poll(m_Ui.statusbar,&m_sound_items,m_settings_dialog);
}
void stereo_mode(bool s) {
@ -336,7 +396,10 @@ private slots:
}
void settings() {
m_settings_dialog->show();
}
private:
///////////////////////////////////////////////
@ -362,41 +425,6 @@ private:
vector<osc_destination> m_destinations;
// all this to work around liblo's use of varargs...
void send_audio_osc(const char *name, const char *types) {
for (auto dest:m_destinations) {
if (dest.m_enabled) {
lo_send(dest.m_audio_address,name,types);
}
}
}
template <class T>
void send_audio_osc(const char *name, const char *types, T val) {
for (auto dest:m_destinations) {
if (dest.m_enabled) {
lo_send(dest.m_audio_address,name,types,val);
}
}
}
void send_process_osc(const char *name, const char *types) {
for (auto dest:m_destinations) {
if (dest.m_enabled) {
lo_send(dest.m_process_address,name,types);
}
}
}
template <class T>
void send_process_osc(const char *name, const char *types, T val) {
for (auto dest:m_destinations) {
if (dest.m_enabled) {
lo_send(dest.m_process_address,name,types,val);
}
}
}
void init_from_session(const string &filename);
void add_gui_address(osc_destination &dest,
@ -411,5 +439,7 @@ private:
QSignalMapper* m_sound_item_delete_mapper;
sound_items m_sound_items;
SettingsDialog *m_settings_dialog;
audio_thread *m_audio_thread;
};

39
app/SettingsDialog.cpp Normal file
View File

@ -0,0 +1,39 @@
// Copyright (C) 2022 Then Try This
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <QtGui>
#include <iostream>
#include <list>
#include "MainWindow.h"
#include "SettingsDialog.h"
#include "feedback.h"
using namespace std;
SettingsDialog::SettingsDialog(MainWindow *parent):
m_device(""),
m_parent(parent),
m_buffersize(2048),
m_samplerate(44100) {
m_Ui.setupUi(this);
}
void SettingsDialog::connect() {
audio_thread *at = m_parent->get_audio_thread();
at->restart_audio(m_device,m_samplerate,m_buffersize);
m_Ui.messagesLabel->setText(at->m_audio_device->m_client.m_status.c_str());
}

75
app/SettingsDialog.h Normal file
View File

@ -0,0 +1,75 @@
// Copyright (C) 2022 Then Try This
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef SETTINGS_DIALOG
#define SETTINGS_DIALOG
#include <QtGui>
#include <QDialog>
#include <QLineEdit>
#include "ui_settings.h"
#include <iostream>
#include <lo/lo.h>
#include <string>
#include <list>
using namespace std;
class MainWindow;
class SettingsDialog : public QDialog
{
Q_OBJECT
public:
SettingsDialog(MainWindow *parent);
Ui_SettingsDialog m_Ui;
string m_device;
protected:
private slots:
void samplerate(QString str) {
try { m_samplerate=stoi(str.toStdString()); }
catch(std::exception const & e) {
m_samplerate=44100;
}
}
void output_device(QString v) { m_device=v.toStdString(); }
void buffersize(QString str) {
try { m_buffersize=stoi(str.toStdString()); }
catch(std::exception const & e) {
m_buffersize=44100;
}
}
void accept() { connect(); hide(); }
void reject() { hide(); }
void apply() { connect(); }
private:
void connect();
MainWindow *m_parent;
unsigned int m_buffersize;
unsigned int m_samplerate;
};
#endif

View File

@ -28,15 +28,18 @@ audio_thread::audio_thread(process_thread &p) :
m_stereo_mode(false),
m_mic_mode(false),
m_bufsize(2048),
m_samplerate(44100)
m_samplerate(44100),
m_device("")
{
start_audio();
// start_audio();
pthread_mutex_lock(m_brain_mutex);
m_left_renderer = new renderer(p.m_source,p.m_left_target);
m_right_renderer = new renderer(p.m_source,p.m_right_target);
m_block_stream = new block_stream();
pthread_mutex_unlock(m_brain_mutex);
m_osc.run();
// it this threadsafe?
// m_audio_device->report_devices();
}
static bool state = 1;
@ -54,13 +57,24 @@ void audio_thread::start_audio() {
m_audio_device->m_client.set_callback(run_audio, this);
}
void audio_thread::restart_audio(const string device, unsigned int samplerate, unsigned int bufsize) {
m_samplerate = samplerate;
m_bufsize = bufsize;
m_device = device;
m_audio_device->connect(m_device,
"samplebrain",
m_samplerate,
m_bufsize);
}
void audio_thread::run_audio(void* c, unsigned int frames) {
if (state) {
audio_thread *at = (audio_thread*)c;
at->m_audio_device->left_out.zero();
at->process(at->m_audio_device->left_in,
at->m_audio_device->right_in,
at->m_audio_device->left_out,
at->m_audio_device->right_in,
at->m_audio_device->left_out,
at->m_audio_device->right_out);
at->m_audio_device->maybe_record();
}
@ -187,12 +201,12 @@ void audio_thread::process(sample &left_in, sample &right_in, sample &left_out,
}
m_left_renderer->process(left_out.get_length(),
left_out.get_non_const_buffer(),
bs);
left_out.get_non_const_buffer(),
bs);
if (m_stereo_mode) {
m_right_renderer->process(right_out.get_length(),
right_out.get_non_const_buffer(),
bs);
right_out.get_non_const_buffer(),
bs);
} else {
right_out=left_out;
}

View File

@ -29,6 +29,9 @@ namespace spiralcore {
audio_thread(process_thread &p);
~audio_thread();
void start_audio();
void restart_audio(const string device, unsigned int samplerate, unsigned int bufsize);
void process(sample &left_in, sample &right_in, sample &left_out, sample &right_out);
static void run_audio(void* c, unsigned int frames);
@ -39,7 +42,6 @@ namespace spiralcore {
block_stream *m_block_stream;
private:
void start_audio();
OSC_server m_osc;
process_thread &m_process_thread;
@ -48,6 +50,7 @@ namespace spiralcore {
bool m_mic_mode;
u32 m_bufsize;
u32 m_samplerate;
string m_device;
};
}

View File

@ -16,6 +16,7 @@
#include "feedback.h"
#include "sound_items.h"
#include "SettingsDialog.h"
#include <iostream>
using namespace spiralcore;
@ -28,7 +29,7 @@ feedback::feedback(string address) :
}
void feedback::poll(QStatusBar *s, sound_items *sound_items) {
void feedback::poll(QStatusBar *s, sound_items *sound_items, SettingsDialog *settings) {
command_ring_buffer::command cmd;
while (m_osc.get(cmd)) {

View File

@ -17,6 +17,7 @@
#include <string>
#include <QtGui>
#include <QStatusBar>
#include "SettingsDialog.h"
#include "spiralcore/OSC_server.h"
#pragma once
@ -26,12 +27,12 @@ class sound_items;
class feedback {
public:
feedback(std::string address);
void poll(QStatusBar *s, sound_items *sound_items);
feedback(std::string address);
void poll(QStatusBar *s, sound_items *sound_items, SettingsDialog *settings);
private:
OSC_server m_osc;
OSC_server m_osc;
};
}

View File

@ -34,9 +34,9 @@ static void* _process(void *c) {
process_thread::process_thread() :
m_osc("8889"),
m_source_block_size(3000),
m_source_block_size(1000),
m_source_overlap(0.75),
m_target_block_size(3000),
m_target_block_size(1000),
m_target_overlap(0.75),
m_window_type(window::DODGY),
m_target_window_type(window::DODGY)

View File

@ -30,12 +30,11 @@ int main( int argc , char *argv[] ){
QApplication app(argc, argv);
MainWindow mainWin;
mainWin.show();
cerr<<"Qt version: "<<qVersion()<<endl;
process_thread pt;
audio_thread at(pt);
pt.register_renderer(at.m_left_renderer, at.m_right_renderer, at.m_block_stream);
mainWin.set_audio_thread(&at);
return app.exec();
}