From 4a4ab8b41a5aa563a981f71791dc14469d21d30c Mon Sep 17 00:00:00 2001 From: Dave Griffiths Date: Mon, 3 Oct 2022 09:56:25 +0100 Subject: [PATCH] added audio settings options for selection of device, samplrate and buffer size, also fixed: #65 & fixed: #64 --- app/MainWindow.cpp | 9 +- app/MainWindow.h | 104 ++++--- app/SettingsDialog.cpp | 39 +++ app/SettingsDialog.h | 75 ++++++ app/audio_thread.cpp | 30 ++- app/audio_thread.h | 5 +- app/feedback.cpp | 3 +- app/feedback.h | 7 +- app/process_thread.cpp | 4 +- app/qtmain.cpp | 5 +- brain/src/spiralcore/audio.cpp | 41 +-- brain/src/spiralcore/audio.h | 4 +- brain/src/spiralcore/portaudio_client.cpp | 174 +++++++----- brain/src/spiralcore/portaudio_client.h | 32 ++- brain/src/status.cpp | 4 - brain/src/status.h | 3 +- gui/samplebrain.ui | 281 ++++++++++--------- gui/settings.ui | 314 ++++++++++++++++++++++ samplebrain.pro | 7 +- 19 files changed, 859 insertions(+), 282 deletions(-) create mode 100644 app/SettingsDialog.cpp create mode 100644 app/SettingsDialog.h create mode 100644 gui/settings.ui diff --git a/app/MainWindow.cpp b/app/MainWindow.cpp index 850d0de..8a0555f 100644 --- a/app/MainWindow.cpp +++ b/app/MainWindow.cpp @@ -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 #include #include @@ -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 diff --git a/app/MainWindow.h b/app/MainWindow.h index 90abd9d..14d05c4 100644 --- a/app/MainWindow.h +++ b/app/MainWindow.h @@ -19,6 +19,7 @@ #include #include #include "ui_samplebrain.h" +#include "SettingsDialog.h" #include #include @@ -26,6 +27,7 @@ #include #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 + 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 + 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 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 - 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 - 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; }; diff --git a/app/SettingsDialog.cpp b/app/SettingsDialog.cpp new file mode 100644 index 0000000..a2edf7b --- /dev/null +++ b/app/SettingsDialog.cpp @@ -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 +#include +#include + +#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()); +} diff --git a/app/SettingsDialog.h b/app/SettingsDialog.h new file mode 100644 index 0000000..df5248f --- /dev/null +++ b/app/SettingsDialog.h @@ -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 +#include +#include +#include "ui_settings.h" + +#include +#include +#include +#include + +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 diff --git a/app/audio_thread.cpp b/app/audio_thread.cpp index a6307b4..1d51bcf 100644 --- a/app/audio_thread.cpp +++ b/app/audio_thread.cpp @@ -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; } diff --git a/app/audio_thread.h b/app/audio_thread.h index 0c00911..bcee447 100644 --- a/app/audio_thread.h +++ b/app/audio_thread.h @@ -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; }; } diff --git a/app/feedback.cpp b/app/feedback.cpp index 30d4887..582329c 100644 --- a/app/feedback.cpp +++ b/app/feedback.cpp @@ -16,6 +16,7 @@ #include "feedback.h" #include "sound_items.h" +#include "SettingsDialog.h" #include 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)) { diff --git a/app/feedback.h b/app/feedback.h index 9638f91..4de48d8 100644 --- a/app/feedback.h +++ b/app/feedback.h @@ -17,6 +17,7 @@ #include #include #include +#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; }; } diff --git a/app/process_thread.cpp b/app/process_thread.cpp index fec26f2..8208b5b 100644 --- a/app/process_thread.cpp +++ b/app/process_thread.cpp @@ -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) diff --git a/app/qtmain.cpp b/app/qtmain.cpp index f734c68..c505db3 100644 --- a/app/qtmain.cpp +++ b/app/qtmain.cpp @@ -30,12 +30,11 @@ int main( int argc , char *argv[] ){ QApplication app(argc, argv); MainWindow mainWin; mainWin.show(); - - cerr<<"Qt version: "<maxOutputChannels>=2) { + device_desc desc; + desc.name = deviceInfo->name; + desc.id = i; + desc.default_input = i==default_input_num; + desc.default_output = i==default_output_num; + m_devices.push_back(desc); + } + } + + m_initialised=true; + return true; + } + return true; +} + +int portaudio_client::device_name_to_id(const string &name) { + for (auto &d:m_devices) { + if (d.name==name) return d.id; + } + return -1; +} + +///////////////////////////////////////////////////////////////////////////////////////////// + +bool portaudio_client::attach(const string &requested_output_device, const string &client_name, const device_options &dopt) { + if (!init()) return false; detach(); -} - -///////////////////////////////////////////////////////////////////////////////////////////// - -vector portaudio_client::sniff_devices() { - vector ret; - int numDevices = Pa_GetDeviceCount(); - if(numDevices < 0) { - // this is an error I guess - return ret; - } - const PaDeviceInfo *deviceInfo; - for(int i=0; iname); - } - return ret; -} - -///////////////////////////////////////////////////////////////////////////////////////////// - -bool portaudio_client::attach(const string &client_name, const device_options &dopt) { - if (m_attached) return true; - - PaError err; - err = Pa_Initialize(); - if( err != paNoError ) { - cerr<<"could not init portaudio_client"<defaultLowOutputLatency; - output_parameters.hostApiSpecificStreamInfo = NULL; - cerr<<"Connecting to "<name<<" for output"<defaultLowOutputLatency; + output_parameters.hostApiSpecificStreamInfo = NULL; + m_status="connecting to "+string(Pa_GetDeviceInfo(output_parameters.device)->name)+" for output\n"; + + // turn off input for the moment, it's causing + // too many cross platform security issues + + /*PaStreamParameters input_parameters; PaStreamParameters *input_p=&input_parameters; input_parameters.device = input_device_num; if (true || input_parameters.device == paNoDevice) { cerr<<"error: no default input device."<defaultLowInputLatency; input_parameters.hostApiSpecificStreamInfo = NULL; cerr<<"Connecting to "<name<<" for input"< sniff_devices(); - bool attach(const string &client_name, const device_options &dopt); + class device_desc { + public: + string name; + int id; + bool default_input; + bool default_output; + }; + + vector m_devices; + + bool attach(const string &requested_output_device, const string &client_name, const device_options &dopt); void detach(); - bool is_attached() { return m_attached; } + bool is_attached() { return m_attached_device!=-1; } void set_callback(void(*run)(void*, unsigned int),void *context) { run_callback=run; run_context=context; } void set_outputs(const float *l, const float *r) { m_left_data=l; m_right_data=r; } void set_inputs(float *l, float *r) { m_left_in_data=l; m_right_in_data=r; } + string m_status; + protected: static int process(const void *input_buffer, void *output_buffer, @@ -60,16 +71,21 @@ class portaudio_client private: + int device_name_to_id(const string &name); + static long unsigned int m_buffer_size; - static bool m_attached; - + static bool m_initialised; + static int m_attached_device; + static const float *m_right_data; static const float *m_left_data; static float *m_right_in_data; static float *m_left_in_data; - + static void(*run_callback)(void *, unsigned int); static void *run_context; + static PaStream *m_stream; + }; #endif diff --git a/brain/src/status.cpp b/brain/src/status.cpp index 86c61b2..4fc07ec 100644 --- a/brain/src/status.cpp +++ b/brain/src/status.cpp @@ -34,10 +34,6 @@ void status::sound_item_refresh() { lo_send(m_address,"/sound-item-refresh",""); } -void status::add_audio_device(const std::string &name) { - lo_send(m_address,"/add_audio_device",name.c_str()); -} - void status::update(const char *msg, ...) { va_list args; va_start(args, msg); diff --git a/brain/src/status.h b/brain/src/status.h index f3da884..0add04f 100644 --- a/brain/src/status.h +++ b/brain/src/status.h @@ -28,7 +28,8 @@ public: static void update(const char *msg, ...); static void sound_item(const std::string &name, const std::string &colour); static void sound_item_refresh(); - static void add_audio_device(const std::string &name); + static void add_audio_device(int id, const std::string &name, bool default_output); + static void audio_device_status(const std::string &status); static lo_address m_address; }; diff --git a/gui/samplebrain.ui b/gui/samplebrain.ui index fc4d160..e5d802a 100644 --- a/gui/samplebrain.ui +++ b/gui/samplebrain.ui @@ -403,7 +403,7 @@ - how long it takes for the novelty to wear off + likelihood of playing the next block rather than the closest 100 @@ -752,7 +752,7 @@ 99999 - 3000 + 1000 @@ -783,7 +783,7 @@ 0.010000000000000 - 0.800000000000000 + 0.750000000000000 @@ -1236,7 +1236,7 @@ 99999 - 3000 + 1000 @@ -1267,7 +1267,7 @@ 0.010000000000000 - 0.000000000000000 + 0.750000000000000 @@ -1562,6 +1562,20 @@ + + + + + Comic Sans MS + 75 + true + + + + settings + + + @@ -1604,8 +1618,8 @@ play_slot() - 64 - 62 + 78 + 830 399 @@ -1620,8 +1634,8 @@ stop_slot() - 155 - 62 + 180 + 830 399 @@ -1636,8 +1650,8 @@ volume_slot(int) - 189 - 480 + 465 + 852 361 @@ -1652,8 +1666,8 @@ stop_record() - 328 - 543 + 356 + 840 361 @@ -1668,8 +1682,8 @@ record() - 236 - 543 + 268 + 840 361 @@ -1684,8 +1698,8 @@ fft1_end_slot(int) - 154 - 310 + 421 + 293 399 @@ -1700,8 +1714,8 @@ ratio_slot(double) - 109 - 223 + 421 + 185 399 @@ -1716,12 +1730,12 @@ setValue(int) - 237 - 289 + 319 + 603 - 341 - 289 + 421 + 614 @@ -1732,8 +1746,8 @@ target_mix_slot(double) - 330 - 446 + 720 + 669 361 @@ -1748,8 +1762,8 @@ generate_target_blocks() - 277 - 202 + 670 + 395 399 @@ -1764,8 +1778,8 @@ target_block_size(int) - 313 - 136 + 720 + 237 399 @@ -1780,8 +1794,8 @@ load_target() - 277 - 103 + 670 + 184 399 @@ -1796,8 +1810,8 @@ fft1_start_slot(int) - 154 - 277 + 298 + 293 399 @@ -1812,8 +1826,8 @@ target_block_overlap(double) - 619 - 196 + 720 + 291 361 @@ -1828,12 +1842,12 @@ setValue(int) - 341 - 289 + 421 + 614 - 237 - 289 + 319 + 603 @@ -1844,8 +1858,8 @@ synapses(int) - 341 - 289 + 421 + 614 566 @@ -1860,8 +1874,8 @@ ratio_slot(int) - 189 - 141 + 323 + 174 361 @@ -1876,8 +1890,8 @@ n_ratio_slot(int) - 159 - 211 + 323 + 228 361 @@ -1892,8 +1906,8 @@ n_ratio_slot(double) - 330 - 211 + 421 + 239 361 @@ -1908,8 +1922,8 @@ target_mix_slot(int) - 159 - 446 + 622 + 658 361 @@ -1924,8 +1938,8 @@ n_mix_slot(int) - 159 - 386 + 622 + 604 361 @@ -1940,8 +1954,8 @@ n_mix_slot(double) - 330 - 386 + 720 + 615 361 @@ -1956,8 +1970,8 @@ load_brain() - 615 - 357 + 941 + 661 566 @@ -1972,8 +1986,8 @@ boredom_slot(double) - 411 - 253 + 421 + 401 321 @@ -1988,8 +2002,8 @@ novelty_slot(double) - 411 - 217 + 421 + 347 321 @@ -2004,8 +2018,8 @@ novelty_slot(int) - 291 - 217 + 323 + 336 321 @@ -2020,8 +2034,8 @@ boredom_slot(int) - 291 - 253 + 323 + 390 321 @@ -2036,8 +2050,8 @@ synapses(int) - 237 - 289 + 319 + 603 566 @@ -2052,8 +2066,8 @@ block_size(int) - 728 - 109 + 1157 + 450 566 @@ -2068,8 +2082,8 @@ block_overlap(double) - 728 - 145 + 1157 + 504 566 @@ -2084,8 +2098,8 @@ save_brain() - 728 - 357 + 1157 + 661 566 @@ -2100,8 +2114,8 @@ clear_brain() - 1061 - 550 + 1157 + 396 566 @@ -2116,8 +2130,8 @@ generate() - 671 - 322 + 1158 + 608 566 @@ -2132,8 +2146,8 @@ load_sound() - 841 - 550 + 868 + 396 566 @@ -2148,12 +2162,12 @@ setValue(int) - 241 - 282 + 346 + 498 - 343 - 282 + 421 + 509 @@ -2164,12 +2178,12 @@ setValue(int) - 343 - 282 + 421 + 509 - 241 - 282 + 346 + 498 @@ -2180,8 +2194,8 @@ search_stretch(int) - 241 - 282 + 346 + 498 566 @@ -2196,12 +2210,12 @@ setValue(int) - 231 - 410 + 305 + 657 - 337 - 410 + 421 + 668 @@ -2212,12 +2226,12 @@ setValue(int) - 337 - 410 + 421 + 668 - 231 - 410 + 305 + 657 @@ -2228,8 +2242,8 @@ slide_error(int) - 231 - 410 + 305 + 657 566 @@ -2244,8 +2258,8 @@ stickyness_slot(double) - 385 - 296 + 421 + 455 609 @@ -2260,8 +2274,8 @@ stickyness_slot(int) - 266 - 296 + 323 + 444 609 @@ -2276,8 +2290,8 @@ autotune(int) - 531 - 477 + 622 + 550 454 @@ -2292,8 +2306,8 @@ autotune(double) - 616 - 477 + 720 + 561 454 @@ -2308,8 +2322,8 @@ load_session() - 535 - 707 + 616 + 799 454 @@ -2324,8 +2338,8 @@ save_session() - 535 - 744 + 616 + 851 454 @@ -2340,8 +2354,8 @@ stereo_mode(bool) - 539 - 594 + 721 + 717 454 @@ -2356,8 +2370,8 @@ algo(int) - 273 - 395 + 421 + 560 454 @@ -2372,8 +2386,8 @@ target_shape(int) - 557 - 233 + 720 + 342 454 @@ -2388,8 +2402,8 @@ brain_shape(int) - 824 - 432 + 1157 + 555 454 @@ -2404,8 +2418,8 @@ load_sounds() - 754 - 321 + 1013 + 396 454 @@ -2420,8 +2434,8 @@ select_all() - 813 - 74 + 1073 + 124 454 @@ -2436,8 +2450,8 @@ select_none() - 862 - 74 + 1157 + 124 454 @@ -2452,8 +2466,8 @@ mic(bool) - 404 - 601 + 721 + 442 454 @@ -2461,6 +2475,22 @@ + + pushButton + clicked() + MainWindow + settings() + + + 680 + 809 + + + 776 + 849 + + + play_slot() @@ -2518,5 +2548,6 @@ select_all() select_none() mic(bool) + settings() diff --git a/gui/settings.ui b/gui/settings.ui new file mode 100644 index 0000000..b530397 --- /dev/null +++ b/gui/settings.ui @@ -0,0 +1,314 @@ + + + SettingsDialog + + + + 0 + 0 + 400 + 522 + + + + settings + + + + + + + + + + + Comic Sans MS + + + + device + + + + + + + + + + + + + + + Comic Sans MS + + + + sample rate + + + + + + + + 0 + 0 + + + + 44100 + + + + + + + + + + Comic Sans MS + 8 + + + + (note: this currently should probably match your sample file's input rate as no conversion is run on them - yet) + + + true + + + + + + + + + + + + Comic Sans MS + + + + buffer size + + + + + + + 5 + + + + 64 + + + + + 128 + + + + + 256 + + + + + 512 + + + + + 1024 + + + + + 2048 + + + + + 4096 + + + + + + + + + + + Comic Sans MS + + + + messages + + + + + + + + 0 + 0 + + + + + Comic Sans MS + 8 + + + + false + + + border: 1px solid; + + + + + + + + + + + Comic Sans MS + + + + apply settings + + + + + + + + Comic Sans MS + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + SettingsDialog + accept() + + + 231 + 358 + + + 157 + 274 + + + + + buttonBox + rejected() + SettingsDialog + reject() + + + 299 + 364 + + + 286 + 274 + + + + + samplerateLineEdit + textEdited(QString) + SettingsDialog + samplerate(QString) + + + 270 + 71 + + + 394 + 156 + + + + + applyPushButton + clicked() + SettingsDialog + apply() + + + 112 + 321 + + + 4 + 315 + + + + + deviceComboBox + currentTextChanged(QString) + SettingsDialog + output_device(QString) + + + 323 + 45 + + + 393 + 64 + + + + + buffersizeComboBox + currentTextChanged(QString) + SettingsDialog + buffersize(QString) + + + 326 + 131 + + + 395 + 208 + + + + + + output_device(QString) + samplerate(QString) + buffersize(QString) + apply() + + diff --git a/samplebrain.pro b/samplebrain.pro index 22799fb..8b047df 100644 --- a/samplebrain.pro +++ b/samplebrain.pro @@ -10,11 +10,14 @@ INCLUDEPATH += . 2 QT += core gui widgets # Input -HEADERS += app/MainWindow.h +HEADERS += app/MainWindow.h \ + app/SettingsDialog.h -FORMS += gui/samplebrain.ui +FORMS += gui/samplebrain.ui \ + gui/settings.ui SOURCES += app/MainWindow.cpp \ + app/SettingsDialog.cpp \ app/sound_items.cpp \ app/audio_thread.cpp \ app/process_thread.cpp \