summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--drumgizmo/drumgizmoc.cc79
-rw-r--r--drumgizmo/drumgizmoc.h17
-rw-r--r--drumgizmo/output/jackaudio.cc1
-rw-r--r--plugin/Makefile.mingw32.in3
-rw-r--r--plugin/drumgizmo_plugin.cc4
-rw-r--r--plugin/drumgizmo_plugin.h2
-rw-r--r--plugingui/Makefile.am5
-rw-r--r--plugingui/Makefile.mingw324
-rw-r--r--plugingui/button.h3
-rw-r--r--plugingui/checkbox.h3
-rw-r--r--plugingui/dgwindow.cc116
-rw-r--r--plugingui/dgwindow.h13
-rw-r--r--plugingui/eventhandler.h3
-rw-r--r--plugingui/filebrowser.h4
-rw-r--r--plugingui/knob.h3
-rw-r--r--plugingui/layout.h2
-rw-r--r--plugingui/listboxbasic.h3
-rw-r--r--plugingui/listboxthin.h3
-rw-r--r--plugingui/plugingui.cc125
-rw-r--r--plugingui/plugingui.h24
-rw-r--r--plugingui/progressbar.cc26
-rw-r--r--plugingui/progressbar.h11
-rw-r--r--plugingui/testmain.cc17
-rw-r--r--src/Makefile.am8
-rw-r--r--src/Makefile.am.drumgizmo3
-rw-r--r--src/atomic.h182
-rw-r--r--src/audiofile.cc2
-rw-r--r--src/configuration.cc38
-rw-r--r--src/configuration.h44
-rw-r--r--src/drumgizmo.cc196
-rw-r--r--src/drumgizmo.h20
-rw-r--r--src/drumkit.cc24
-rw-r--r--src/drumkit.h2
-rw-r--r--src/drumkitloader.cc101
-rw-r--r--src/drumkitloader.h16
-rw-r--r--src/drumkitparser.cc45
-rw-r--r--src/drumkitparser.h3
-rw-r--r--src/instrument.cc82
-rw-r--r--src/instrument.h8
-rw-r--r--src/instrumentparser.cc62
-rw-r--r--src/instrumentparser.h2
-rw-r--r--src/message.h121
-rw-r--r--src/messagehandler.cc89
-rw-r--r--src/messagehandler.h66
-rw-r--r--src/messagereceiver.cc78
-rw-r--r--src/messagereceiver.h75
-rw-r--r--src/midimapparser.cc3
-rw-r--r--src/midimapparser.h2
-rw-r--r--src/notifier.h (renamed from plugingui/notifier.h)4
-rw-r--r--src/path.cc18
-rw-r--r--src/path.h1
-rw-r--r--src/sample.cc21
-rw-r--r--src/sample.h22
-rw-r--r--src/saxparser.cc66
-rw-r--r--src/saxparser.h19
-rw-r--r--src/semaphore.cc96
-rw-r--r--src/semaphore.h24
-rw-r--r--src/settings.h181
-rw-r--r--src/syncedsettings.h106
-rw-r--r--test/Makefile.am14
-rw-r--r--test/atomictest.cc135
-rw-r--r--test/engine.cc3
-rw-r--r--test/memcheckertest.cc7
-rw-r--r--test/syncedsettings.cc203
65 files changed, 1371 insertions, 1300 deletions
diff --git a/ChangeLog b/ChangeLog
index 8e8afe5..10a2b28 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Version 0.9.10
+==============
+Release date: March 30th 2016
+Contributors: deva, suhr
+ - Fix the 'no sound from plugin when resampler active' bug.
+ - Fix the 'freeze on tempo change' bug.
+ - Fix backspace in lineedits.
+
Version 0.9.9
=============
Release date: March 24th 2016
diff --git a/drumgizmo/drumgizmoc.cc b/drumgizmo/drumgizmoc.cc
index 24d16e8..e993dc3 100644
--- a/drumgizmo/drumgizmoc.cc
+++ b/drumgizmo/drumgizmoc.cc
@@ -92,36 +92,7 @@ static const char usage_str[] =
" dummy:\n"
"\n";
-CliMain::CliMain()
- : MessageReceiver(MSGRCV_UI)
-{
- loading = true; // Block by default
-}
-
-CliMain::~CliMain()
-{
- hug_close();
-}
-
-void CliMain::handleMessage(Message* msg)
-{
- switch(msg->type())
- {
- case Message::LoadStatus:
- {
- auto ls = static_cast<LoadStatusMessage*>(msg);
- if(ls->numer_of_files_loaded == ls->number_of_files)
- {
- loading = false;
- }
- }
- break;
- default:
- break;
- }
-}
-
-int CliMain::run(int argc, char* argv[])
+int main(int argc, char* argv[])
{
int c;
@@ -372,7 +343,8 @@ int CliMain::run(int argc, char* argv[])
printf("Using kitfile: %s\n", kitfile.c_str());
- DrumGizmo gizmo(oe.get(), ie.get());
+ Settings settings;
+ DrumGizmo gizmo(settings, oe.get(), ie.get());
gizmo.setFrameSize(oe->getBufferSize());
@@ -382,21 +354,37 @@ int CliMain::run(int argc, char* argv[])
return 1;
}
- printf("Loading drumkit, this may take a while...");
- fflush(stdout);
- loading = true;
- while(async == false && loading)
+ printf("Loading drumkit, this may take a while:\n");
+
+ if(!async)
{
+ while(settings.drumkit_load_status.load() != LoadStatus::Done)
+ {
#ifdef WIN32
- SleepEx(500, FALSE);
+ SleepEx(10, FALSE);
#else
- usleep(500000);
+ usleep(10000);
#endif /*WIN32*/
- handleMessages();
- printf(".");
- fflush(stdout);
+
+ int total = settings.number_of_files.load();
+ int loaded = settings.number_of_files_loaded.load();
+
+ printf("\r%d of %d ", loaded, total);
+ fflush(stdout);
+
+ if(settings.drumkit_load_status.load() == LoadStatus::Error)
+ {
+ printf("\nLoad error\n");
+ return 1;
+ }
+
+ if(loaded == total)
+ {
+ //break;
+ }
+ }
+ printf("\ndone\n");
}
- printf("done.\n");
gizmo.setSamplerate(oe->getSamplerate());
@@ -411,14 +399,7 @@ int CliMain::run(int argc, char* argv[])
printf("Quit.\n");
fflush(stdout);
- return 0;
-}
-
-int main(int argc, char* argv[])
-{
- CliMain cli;
-
- cli.run(argc, argv);
+ hug_close();
return 0;
}
diff --git a/drumgizmo/drumgizmoc.h b/drumgizmo/drumgizmoc.h
index 231aec6..cc2f96c 100644
--- a/drumgizmo/drumgizmoc.h
+++ b/drumgizmo/drumgizmoc.h
@@ -24,21 +24,4 @@
* along with DrumGizmo; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-
#pragma once
-
-#include "messagereceiver.h"
-
-class CliMain : public MessageReceiver
-{
-public:
- CliMain();
- virtual ~CliMain();
-
- int run(int argc, char* argv[]);
- void handleMessage(Message* msg);
-
-private:
- bool loading;
-};
-
diff --git a/drumgizmo/output/jackaudio.cc b/drumgizmo/output/jackaudio.cc
index 7710e14..abd7d4f 100644
--- a/drumgizmo/output/jackaudio.cc
+++ b/drumgizmo/output/jackaudio.cc
@@ -33,7 +33,6 @@ JackAudioOutputEngine::JackAudioOutputEngine(JackClient& client)
: AudioOutputEngine{}
, client(client)
, channels{}
- , sema{"jackaudio"}
{
client.add(*this);
}
diff --git a/plugin/Makefile.mingw32.in b/plugin/Makefile.mingw32.in
index 40233b4..8b341c7 100644
--- a/plugin/Makefile.mingw32.in
+++ b/plugin/Makefile.mingw32.in
@@ -19,7 +19,6 @@ DG_SRC = \
@top_srcdir@/src/channelmixer.cc \
@top_srcdir@/src/chresampler.cc \
@top_srcdir@/src/configfile.cc \
- @top_srcdir@/src/configuration.cc \
@top_srcdir@/src/configparser.cc \
@top_srcdir@/src/drumgizmo.cc \
@top_srcdir@/src/drumkit.cc \
@@ -29,8 +28,6 @@ DG_SRC = \
@top_srcdir@/src/instrument.cc \
@top_srcdir@/src/instrumentparser.cc \
@top_srcdir@/src/memchecker.cc \
- @top_srcdir@/src/messagehandler.cc \
- @top_srcdir@/src/messagereceiver.cc \
@top_srcdir@/src/midimapparser.cc \
@top_srcdir@/src/midimapper.cc \
@top_srcdir@/src/mutex.cc \
diff --git a/plugin/drumgizmo_plugin.cc b/plugin/drumgizmo_plugin.cc
index b8f8822..06c2799 100644
--- a/plugin/drumgizmo_plugin.cc
+++ b/plugin/drumgizmo_plugin.cc
@@ -59,7 +59,7 @@ DrumGizmoPlugin::DrumGizmoPlugin()
{
init();
- drumgizmo = std::make_shared<DrumGizmo>(&output, &input);
+ drumgizmo = std::make_shared<DrumGizmo>(settings, &output, &input);
resizeWindow(370, 330);
drumgizmo->setFreeWheel(true);
drumgizmo->setSamplerate(44100);
@@ -143,7 +143,7 @@ bool DrumGizmoPlugin::hasGUI()
void DrumGizmoPlugin::createWindow(void *parent)
{
- plugin_gui = std::make_shared<GUI::PluginGUI>(parent);
+ plugin_gui = std::make_shared<GUI::PluginGUI>(settings, parent);
resizeWindow(370, 330);
onShowWindow();
}
diff --git a/plugin/drumgizmo_plugin.h b/plugin/drumgizmo_plugin.h
index 28a1b8f..3508c3e 100644
--- a/plugin/drumgizmo_plugin.h
+++ b/plugin/drumgizmo_plugin.h
@@ -154,6 +154,8 @@ private:
Output output{*this};
const std::vector<float*>* output_samples{nullptr};
+ Settings settings;
+
std::shared_ptr<GUI::PluginGUI> plugin_gui;
std::shared_ptr<DrumGizmo> drumgizmo;
};
diff --git a/plugingui/Makefile.am b/plugingui/Makefile.am
index 3dee864..4176c07 100644
--- a/plugingui/Makefile.am
+++ b/plugingui/Makefile.am
@@ -16,9 +16,7 @@ plugingui_SOURCES = \
$(top_srcdir)/src/configfile.cc \
$(top_srcdir)/src/thread.cc \
$(top_srcdir)/src/semaphore.cc \
- $(top_srcdir)/src/mutex.cc \
- $(top_srcdir)/src/messagehandler.cc \
- $(top_srcdir)/src/messagereceiver.cc
+ $(top_srcdir)/src/mutex.cc
rcgen_SOURCES = rcgen.cc
@@ -46,7 +44,6 @@ EXTRA_DIST = \
nativewindow.h \
nativewindow_win32.h \
nativewindow_x11.h \
- notifier.h \
painter.h \
pixelbuffer.h \
pluginconfig.h \
diff --git a/plugingui/Makefile.mingw32 b/plugingui/Makefile.mingw32
index 3f52e8a..9820d1a 100644
--- a/plugingui/Makefile.mingw32
+++ b/plugingui/Makefile.mingw32
@@ -2,9 +2,7 @@ DG_SRC = \
../src/configfile.cc \
../src/thread.cc \
../src/semaphore.cc \
- ../src/mutex.cc \
- ../src/messagehandler.cc \
- ../src/messagereceiver.cc
+ ../src/mutex.cc
DG_CFLAGS = -I.. -I../include -I../src -DSSE -msse -msse2 -DDISABLE_HUGIN
diff --git a/plugingui/button.h b/plugingui/button.h
index 7e3e168..1bfeb2d 100644
--- a/plugingui/button.h
+++ b/plugingui/button.h
@@ -28,9 +28,10 @@
#include <string>
+#include <notifier.h>
+
#include "widget.h"
#include "painter.h"
-#include "notifier.h"
#include "font.h"
namespace GUI {
diff --git a/plugingui/checkbox.h b/plugingui/checkbox.h
index 3da5511..5c658a5 100644
--- a/plugingui/checkbox.h
+++ b/plugingui/checkbox.h
@@ -26,9 +26,10 @@
*/
#pragma once
+#include <notifier.h>
+
#include "widget.h"
#include "image.h"
-#include "notifier.h"
namespace GUI {
diff --git a/plugingui/dgwindow.cc b/plugingui/dgwindow.cc
index 86a985d..c325703 100644
--- a/plugingui/dgwindow.cc
+++ b/plugingui/dgwindow.cc
@@ -30,12 +30,12 @@
#include "verticalline.h"
#include "../version.h"
-#include "messagehandler.h"
#include "pluginconfig.h"
namespace GUI {
-class LabeledControl : public Widget
+class LabeledControl
+ : public Widget
{
public:
LabeledControl(Widget* parent, const std::string& name)
@@ -60,7 +60,8 @@ public:
Label caption{this};
};
-class File : public Widget
+class File
+ : public Widget
{
public:
File(Widget* parent)
@@ -83,7 +84,8 @@ public:
Button browseButton{this};
};
-class HumanizeControls : public Widget
+class HumanizeControls
+ : public Widget
{
public:
HumanizeControls(Widget* parent)
@@ -119,11 +121,10 @@ public:
Knob falloffKnob{&falloff};
};
-DGWindow::DGWindow(void* native_window, MessageHandler& messageHandler,
- Config& config)
+DGWindow::DGWindow(void* native_window, Config& config, Settings& settings)
: Window(native_window)
- , messageHandler(messageHandler)
, config(config)
+ , settings(settings)
{
int vlineSpacing = 16;
@@ -179,6 +180,7 @@ DGWindow::DGWindow(void* native_window, MessageHandler& messageHandler,
midimapFileProgress = new ProgressBar(this);
midimapFileProgress->resize(width() - 40, 11);
+ midimapFileProgress->setTotal(2);
layout.addItem(midimapFileProgress);
VerticalLine *l2 = new VerticalLine(this);
@@ -207,7 +209,7 @@ DGWindow::DGWindow(void* native_window, MessageHandler& messageHandler,
layout.addItem(l3);
Label *lbl_version = new Label(this);
- lbl_version->setText(".::. v" VERSION " .::. http://www.drumgizmo.org .::. LGPLv3 .::.");
+ lbl_version->setText(".::. v" VERSION " .::. http://www.drumgizmo.org .::. LGPLv3 .::.");
lbl_version->resize(width(), 20);
lbl_version->setAlignment(TextAlignment::center);
layout.addItem(lbl_version);
@@ -219,6 +221,50 @@ DGWindow::DGWindow(void* native_window, MessageHandler& messageHandler,
fileBrowser->hide();
}
+void DGWindow::setDrumKitLoadStatus(LoadStatus load_status)
+{
+ ProgressBarState state = ProgressBarState::Blue;
+ switch(load_status)
+ {
+ case LoadStatus::Idle:
+ case LoadStatus::Loading:
+ state = ProgressBarState::Blue;
+ break;
+ case LoadStatus::Done:
+ state = ProgressBarState::Green;
+ break;
+ case LoadStatus::Error:
+ state = ProgressBarState::Red;
+ break;
+ }
+ drumkitFileProgress->setState(state);
+}
+
+void DGWindow::setMidiMapLoadStatus(LoadStatus load_status)
+{
+ ProgressBarState state = ProgressBarState::Blue;
+ switch(load_status)
+ {
+ case LoadStatus::Idle:
+ midimapFileProgress->setValue(0);
+ break;
+ case LoadStatus::Loading:
+ midimapFileProgress->setValue(1);
+ state = ProgressBarState::Blue;
+ break;
+ case LoadStatus::Done:
+ midimapFileProgress->setValue(2);
+ state = ProgressBarState::Green;
+ break;
+ case LoadStatus::Error:
+ midimapFileProgress->setValue(2);
+ state = ProgressBarState::Red;
+ break;
+ }
+
+ midimapFileProgress->setState(state);
+}
+
void DGWindow::repaintEvent(RepaintEvent* repaintEvent)
{
if(!visible())
@@ -233,42 +279,42 @@ void DGWindow::repaintEvent(RepaintEvent* repaintEvent)
void DGWindow::attackValueChanged(float value)
{
- ChangeSettingMessage *msg =
- new ChangeSettingMessage(ChangeSettingMessage::velocity_modifier_weight,
- value);
+ settings.velocity_modifier_weight.store(value);
- messageHandler.sendMessage(MSGRCV_ENGINE, msg);
-
-#ifdef STANDALONE
+#ifdef STANDALONE // For GUI debugging
int i = value * 4;
switch(i) {
- case 0: drumkitFileProgress->setState(ProgressBarState::Off); break;
- case 1: drumkitFileProgress->setState(ProgressBarState::Blue); break;
- case 2: drumkitFileProgress->setState(ProgressBarState::Green); break;
- case 3: drumkitFileProgress->setState(ProgressBarState::Red); break;
- default: break;
+ case 0:
+ drumkitFileProgress->setState(ProgressBarState::Off);
+ break;
+ case 1:
+ drumkitFileProgress->setState(ProgressBarState::Blue);
+ break;
+ case 2:
+ drumkitFileProgress->setState(ProgressBarState::Green);
+ break;
+ case 3:
+ drumkitFileProgress->setState(ProgressBarState::Red);
+ break;
+ default:
+ break;
}
#endif
}
void DGWindow::falloffValueChanged(float value)
{
- ChangeSettingMessage *msg =
- new ChangeSettingMessage(ChangeSettingMessage::velocity_modifier_falloff,
- value);
- messageHandler.sendMessage(MSGRCV_ENGINE, msg);
+ settings.velocity_modifier_falloff.store(value);
-#ifdef STANDALONE
- drumkitFileProgress->setProgress(value);
+#ifdef STANDALONE // For GUI debugging
+ drumkitFileProgress->setTotal(100);
+ drumkitFileProgress->setValue(value * 100);
#endif
}
void DGWindow::velocityCheckClick(bool checked)
{
- ChangeSettingMessage *msg =
- new ChangeSettingMessage(ChangeSettingMessage::enable_velocity_modifier,
- checked);
- messageHandler.sendMessage(MSGRCV_ENGINE, msg);
+ settings.enable_velocity_modifier.store(checked);
}
void DGWindow::kitBrowseClick()
@@ -318,13 +364,7 @@ void DGWindow::selectKitFile(const std::string& filename)
config.lastkit = drumkit;
config.save();
- drumkitFileProgress->setProgress(0);
- drumkitFileProgress->setState(ProgressBarState::Blue);
-
- LoadDrumKitMessage *msg = new LoadDrumKitMessage();
- msg->drumkitfile = drumkit;
-
- messageHandler.sendMessage(MSGRCV_ENGINE, msg);
+ settings.drumkit_file.store(drumkit);
}
void DGWindow::selectMapFile(const std::string& filename)
@@ -337,9 +377,7 @@ void DGWindow::selectMapFile(const std::string& filename)
config.lastmidimap = midimap;
config.save();
- LoadMidimapMessage *msg = new LoadMidimapMessage();
- msg->midimapfile = midimap;
- messageHandler.sendMessage(MSGRCV_ENGINE, msg);
+ settings.midimap_file.store(midimap);
}
diff --git a/plugingui/dgwindow.h b/plugingui/dgwindow.h
index 605e87a..72e4679 100644
--- a/plugingui/dgwindow.h
+++ b/plugingui/dgwindow.h
@@ -26,8 +26,9 @@
*/
#pragma once
-#include "window.h"
+#include <settings.h>
+#include "window.h"
#include "label.h"
#include "lineedit.h"
#include "checkbox.h"
@@ -37,8 +38,6 @@
#include "filebrowser.h"
#include "layout.h"
-class MessageHandler;
-
namespace GUI {
class Config;
@@ -47,7 +46,7 @@ class File;
class DGWindow : public Window {
public:
- DGWindow(void* native_window, MessageHandler& messageHandler, Config& config);
+ DGWindow(void* native_window, Config& config, Settings& settings);
Header* header;
@@ -65,6 +64,9 @@ public:
Knob* falloffKnob;
FileBrowser* fileBrowser;
+ void setDrumKitLoadStatus(LoadStatus load_status);
+ void setMidiMapLoadStatus(LoadStatus load_status);
+
protected:
// From Widget:
void repaintEvent(RepaintEvent* repaintEvent) override;
@@ -78,13 +80,14 @@ private:
void selectKitFile(const std::string& filename);
void selectMapFile(const std::string& filename);
- MessageHandler& messageHandler;
Config& config;
VBoxLayout layout{this};
Image back{":bg.png"};
Image logo{":logo.png"};
+
+ Settings& settings;
};
} // GUI::
diff --git a/plugingui/eventhandler.h b/plugingui/eventhandler.h
index 1fdb1e8..490c515 100644
--- a/plugingui/eventhandler.h
+++ b/plugingui/eventhandler.h
@@ -26,9 +26,10 @@
*/
#pragma once
+#include <notifier.h>
+
#include "guievent.h"
#include "nativewindow.h"
-#include "notifier.h"
namespace GUI {
diff --git a/plugingui/filebrowser.h b/plugingui/filebrowser.h
index 04b34f6..bc2019f 100644
--- a/plugingui/filebrowser.h
+++ b/plugingui/filebrowser.h
@@ -26,15 +26,15 @@
*/
#pragma once
-#include "widget.h"
+#include <notifier.h>
+#include "widget.h"
#include "button.h"
#include "listbox.h"
#include "lineedit.h"
#include "label.h"
#include "image.h"
#include "directory.h"
-#include "notifier.h"
namespace GUI {
diff --git a/plugingui/knob.h b/plugingui/knob.h
index 10d91d6..d144184 100644
--- a/plugingui/knob.h
+++ b/plugingui/knob.h
@@ -26,10 +26,11 @@
*/
#pragma once
+#include <notifier.h>
+
#include "widget.h"
#include "image.h"
#include "font.h"
-#include "notifier.h"
namespace GUI {
diff --git a/plugingui/layout.h b/plugingui/layout.h
index 55cc93f..49bf75c 100644
--- a/plugingui/layout.h
+++ b/plugingui/layout.h
@@ -29,7 +29,7 @@
#include <list>
#include <cstdlib>
-#include "notifier.h"
+#include <notifier.h>
namespace GUI {
diff --git a/plugingui/listboxbasic.h b/plugingui/listboxbasic.h
index 7953dc3..2ebe845 100644
--- a/plugingui/listboxbasic.h
+++ b/plugingui/listboxbasic.h
@@ -29,11 +29,12 @@
#include <string.h>
#include <vector>
+#include <notifier.h>
+
#include "widget.h"
#include "font.h"
#include "painter.h"
#include "scrollbar.h"
-#include "notifier.h"
namespace GUI {
diff --git a/plugingui/listboxthin.h b/plugingui/listboxthin.h
index 3139ecc..1617234 100644
--- a/plugingui/listboxthin.h
+++ b/plugingui/listboxthin.h
@@ -29,10 +29,11 @@
#include <string.h>
#include <vector>
+#include <notifier.h>
+
#include "widget.h"
#include "painter.h"
#include "listboxbasic.h"
-#include "notifier.h"
namespace GUI {
diff --git a/plugingui/plugingui.cc b/plugingui/plugingui.cc
index e34c471..2802c44 100644
--- a/plugingui/plugingui.cc
+++ b/plugingui/plugingui.cc
@@ -26,16 +26,17 @@
*/
#include "plugingui.h"
+#include <iostream>
+
#include <hugin.hpp>
#include "pluginconfig.h"
-#include "messagehandler.h"
namespace GUI {
-PluginGUI::PluginGUI(void* native_window)
- : MessageReceiver(MSGRCV_UI)
- , native_window(native_window)
+PluginGUI::PluginGUI(Settings& settings, void* native_window)
+ : native_window(native_window)
+ , settings(settings)
{
init();
}
@@ -44,70 +45,6 @@ PluginGUI::~PluginGUI()
{
}
-void PluginGUI::handleMessage(Message *msg)
-{
- Painter p(*window);// Make sure we only redraw buffer once (set refcount to 1)
-
- switch(msg->type()) {
- case Message::LoadStatus:
- {
- LoadStatusMessage *ls = (LoadStatusMessage*)msg;
- window->drumkitFileProgress->setProgress((float)ls->numer_of_files_loaded /
- (float)ls->number_of_files);
- if(ls->numer_of_files_loaded == ls->number_of_files)
- {
- window->drumkitFileProgress->setState(ProgressBarState::Green);
- }
- }
- break;
- case Message::LoadStatusMidimap:
- {
- LoadStatusMessageMidimap *ls = (LoadStatusMessageMidimap*)msg;
- window->midimapFileProgress->setProgress(1);
- if(ls->success)
- {
- window->midimapFileProgress->setState(ProgressBarState::Green);
- }
- else
- {
- window->midimapFileProgress->setState(ProgressBarState::Red);
- }
- }
- break;
- case Message::EngineSettingsMessage:
- {
- EngineSettingsMessage *settings = (EngineSettingsMessage *)msg;
- window->lineedit->setText(settings->drumkitfile);
- if(settings->drumkit_loaded)
- {
- window->drumkitFileProgress->setProgress(1);
- window->drumkitFileProgress->setState(ProgressBarState::Green);
- }
- else
- {
- window->drumkitFileProgress->setProgress(0);
- window->drumkitFileProgress->setState(ProgressBarState::Blue);
- }
- window->lineedit2->setText(settings->midimapfile);
- if(settings->midimap_loaded)
- {
- window->midimapFileProgress->setProgress(1);
- window->midimapFileProgress->setState(ProgressBarState::Green);
- }
- else
- {
- window->midimapFileProgress->setProgress(0);
- window->midimapFileProgress->setState(ProgressBarState::Blue);
- }
- window->velocityCheck->setChecked(settings->enable_velocity_modifier);
- window->attackKnob->setValue(settings->velocity_modifier_weight);
- window->falloffKnob->setValue(settings->velocity_modifier_falloff);
- }
- default:
- break;
- }
-}
-
bool PluginGUI::processEvents()
{
if(!initialised)
@@ -116,7 +53,12 @@ bool PluginGUI::processEvents()
}
window->eventHandler()->processEvents();
- handleMessages();
+
+ {
+ Painter p(*window);
+
+ settings_notifier.evaluate();
+ }
if(closing)
{
@@ -135,18 +77,51 @@ void PluginGUI::init()
config = new Config();
config->load();
- window = new DGWindow(native_window, msghandler, *config);
+ window = new DGWindow(native_window, *config, settings);
+
+
+ CONNECT(this, settings_notifier.drumkit_file,
+ window->lineedit, &LineEdit::setText);
+ CONNECT(this, settings_notifier.drumkit_load_status,
+ window, &DGWindow::setDrumKitLoadStatus);
+
+ CONNECT(this, settings_notifier.midimap_file,
+ window->lineedit2, &LineEdit::setText);
+ CONNECT(this, settings_notifier.midimap_load_status,
+ window, &DGWindow::setMidiMapLoadStatus);
+
+ CONNECT(this, settings_notifier.enable_velocity_modifier,
+ window->velocityCheck, &CheckBox::setChecked);
+
+ CONNECT(this, settings_notifier.velocity_modifier_falloff,
+ window->falloffKnob, &Knob::setValue);
+ CONNECT(this, settings_notifier.velocity_modifier_weight,
+ window->attackKnob, &Knob::setValue);
+
+
+ // TODO:
+ //CONNECT(this, settings_notifier.enable_velocity_randomiser,
+ // window->, &CheckBox::setChecked);
+ //CONNECT(this, settings_notifier.velocity_randomiser_weight,
+ // window->, &Knob::setValue);
+
+ //CONNECT(this, settings_notifier.samplerate,
+ // window->, &Knob::setValue);
+
+ //CONNECT(this, settings_notifier.enable_resampling,
+ // window->, &CheckBox::setChecked);
+
+ CONNECT(this, settings_notifier.number_of_files,
+ window->drumkitFileProgress, &ProgressBar::setTotal);
+
+ CONNECT(this, settings_notifier.number_of_files_loaded,
+ window->drumkitFileProgress, &ProgressBar::setValue);
auto eventHandler = window->eventHandler();
CONNECT(eventHandler, closeNotifier, this, &PluginGUI::closeEventHandler);
window->show();
- { // Request all engine settings
- EngineSettingsMessage *msg = new EngineSettingsMessage();
- msghandler.sendMessage(MSGRCV_ENGINE, msg);
- }
-
initialised = true;
}
diff --git a/plugingui/plugingui.h b/plugingui/plugingui.h
index f441696..04b0a29 100644
--- a/plugingui/plugingui.h
+++ b/plugingui/plugingui.h
@@ -26,26 +26,20 @@
*/
#pragma once
+#include <settings.h>
+#include <notifier.h>
+
#include "dgwindow.h"
#include "eventhandler.h"
-
#include "pluginconfig.h"
-
-#include "thread.h"
-#include "semaphore.h"
-
-#include "messagereceiver.h"
-#include "notifier.h"
-
namespace GUI {
class PluginGUI
- : public MessageReceiver
- , public Listener
+ : public Listener
{
public:
- PluginGUI(void* native_window = nullptr);
+ PluginGUI(Settings& settings, void* native_window = nullptr);
virtual ~PluginGUI();
//! Process all events and messages in queue
@@ -58,9 +52,6 @@ public:
void show();
void hide();
-
- void handleMessage(Message* msg);
-
DGWindow* window{nullptr};
EventHandler* eventhandler{nullptr};
@@ -80,11 +71,12 @@ private:
volatile bool closing{false};
volatile bool initialised{false};
- Semaphore sem{"plugingui"};
-
// For the old-style notifier.
void (*windowClosedHandler)(void *){nullptr};
void *windowClosedPtr{nullptr};
+
+ Settings& settings;
+ SettingsNotifier settings_notifier{settings};
};
} // GUI::
diff --git a/plugingui/progressbar.cc b/plugingui/progressbar.cc
index 932f17c..8a382f5 100644
--- a/plugingui/progressbar.cc
+++ b/plugingui/progressbar.cc
@@ -26,6 +26,8 @@
*/
#include "progressbar.h"
+#include <iostream>
+
namespace GUI {
ProgressBar::ProgressBar(Widget *parent)
@@ -46,9 +48,6 @@ ProgressBar::ProgressBar(Widget *parent)
bar_green.left = new Image(":progress_front_green_l.png");
bar_green.right = new Image(":progress_front_green_r.png");
bar_green.center = new Image(":progress_front_green_c.png");
-
- state = ProgressBarState::Blue;
- _progress = .5;
}
ProgressBar::~ProgressBar()
@@ -79,22 +78,31 @@ void ProgressBar::setState(ProgressBarState state)
}
}
-float ProgressBar::progress()
+void ProgressBar::setTotal(std::size_t total)
{
- return _progress;
+ if(this->total != total)
+ {
+ this->total = total;
+ repaintEvent(nullptr);
+ }
}
-void ProgressBar::setProgress(float progress)
+void ProgressBar::setValue(std::size_t value)
{
- _progress = progress;
- repaintEvent(nullptr);
+ if(this->value != value)
+ {
+ this->value = value;
+ repaintEvent(nullptr);
+ }
}
void ProgressBar::repaintEvent(RepaintEvent* repaintEvent)
{
Painter p(*this);
- int max = width() * _progress;
+ float progress = (float)value / (float)total;
+
+ int max = width() * progress;
p.clear();
diff --git a/plugingui/progressbar.h b/plugingui/progressbar.h
index d5f6c61..7485e40 100644
--- a/plugingui/progressbar.h
+++ b/plugingui/progressbar.h
@@ -43,11 +43,11 @@ enum class ProgressBarState
class ProgressBar : public Widget {
public:
- ProgressBar(Widget *parent);
+ ProgressBar(Widget* parent);
~ProgressBar();
- float progress();
- void setProgress(float progress);
+ void setTotal(std::size_t total);
+ void setValue(std::size_t value);
void setState(ProgressBarState state);
@@ -56,7 +56,7 @@ protected:
virtual void repaintEvent(RepaintEvent* repaintEvent) override;
private:
- ProgressBarState state;
+ ProgressBarState state{ProgressBarState::Blue};
Painter::Bar bar_bg;
@@ -64,7 +64,8 @@ private:
Painter::Bar bar_blue;
Painter::Bar bar_red;
- float _progress;
+ std::size_t total{0};
+ std::size_t value{0};
};
} // GUI::
diff --git a/plugingui/testmain.cc b/plugingui/testmain.cc
index 8282bc8..84d813d 100644
--- a/plugingui/testmain.cc
+++ b/plugingui/testmain.cc
@@ -26,15 +26,17 @@
*/
#include "plugingui.h"
+#ifdef WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif
+
#include <hugin.hpp>
-// Dummy Engine class.
-class Engine : public MessageHandler {
-public:
- void handleMessage(Message *msg) {}
-};
+#include <notifier.h>
+#include <settings.h>
-class TestMain : public GUI::Listener {
+class TestMain : public Listener {
public:
TestMain()
{
@@ -62,7 +64,8 @@ public:
bool running = true;
- GUI::PluginGUI gui;
+ Settings settings;
+ GUI::PluginGUI gui{settings};
};
int main()
diff --git a/src/Makefile.am b/src/Makefile.am
index a1b1615..4d167af 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -13,7 +13,6 @@ EXTRA_DIST = \
channelmixer.h \
chresampler.h \
configfile.h \
- configuration.h \
configparser.h \
cpp11fix.h \
drumgizmo.h \
@@ -24,13 +23,11 @@ EXTRA_DIST = \
instrument.h \
instrumentparser.h \
memchecker.h \
- message.h \
- messagehandler.h \
- messagereceiver.h \
midimapparser.h \
midimapper.h \
mutex.h \
nolocale.h \
+ notifier.h \
path.h \
powerlist.h \
rangemap.h \
@@ -54,7 +51,6 @@ EXTRA_DIST = \
channelmixer.cc \
chresampler.cc \
configfile.cc \
- configuration.cc \
configparser.cc \
drumgizmo.cc \
drumkit.cc \
@@ -64,8 +60,6 @@ EXTRA_DIST = \
instrument.cc \
instrumentparser.cc \
memchecker.cc \
- messagehandler.cc \
- messagereceiver.cc \
midimapparser.cc \
midimapper.cc \
mutex.cc \
diff --git a/src/Makefile.am.drumgizmo b/src/Makefile.am.drumgizmo
index 8f648d0..6fddded 100644
--- a/src/Makefile.am.drumgizmo
+++ b/src/Makefile.am.drumgizmo
@@ -11,7 +11,6 @@ DRUMGIZMO_SOURCES = \
$(top_srcdir)/src/channelmixer.cc \
$(top_srcdir)/src/chresampler.cc \
$(top_srcdir)/src/configfile.cc \
- $(top_srcdir)/src/configuration.cc \
$(top_srcdir)/src/configparser.cc \
$(top_srcdir)/src/drumgizmo.cc \
$(top_srcdir)/src/drumkit.cc \
@@ -21,8 +20,6 @@ DRUMGIZMO_SOURCES = \
$(top_srcdir)/src/instrument.cc \
$(top_srcdir)/src/instrumentparser.cc \
$(top_srcdir)/src/memchecker.cc \
- $(top_srcdir)/src/messagehandler.cc \
- $(top_srcdir)/src/messagereceiver.cc \
$(top_srcdir)/src/midimapparser.cc \
$(top_srcdir)/src/midimapper.cc \
$(top_srcdir)/src/mutex.cc \
diff --git a/src/atomic.h b/src/atomic.h
new file mode 100644
index 0000000..95a5e9d
--- /dev/null
+++ b/src/atomic.h
@@ -0,0 +1,182 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * atomic.h
+ *
+ * Wed Mar 23 09:15:05 CET 2016
+ * Copyright 2016 Christian Glöckner
+ * cgloeckner@freenet.de
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#pragma once
+
+#include <type_traits>
+#include <atomic>
+
+#include <mutex>
+#include "mutex.h"
+
+template <typename T, typename = void>
+class Atomic;
+
+// use std::atomic if possible
+template <typename T>
+class Atomic<T, typename std::enable_if<std::is_pod<T>::value>::type>
+ : public std::atomic<T>
+{
+public:
+ // inherit methods
+ using std::atomic<T>::atomic;
+ using std::atomic<T>::operator=;
+};
+
+// else work around it using a mutex
+template <typename T>
+class Atomic<T, typename std::enable_if<!std::is_pod<T>::value>::type>
+{
+public:
+ using self_type =
+ Atomic<T, typename std::enable_if<!std::is_pod<T>::value>::type>;
+
+ Atomic()
+ : data{}
+ , mutex{}
+ {
+ }
+
+ Atomic(T data)
+ : data{std::move(data)}
+ , mutex{}
+ {
+ }
+
+ Atomic(self_type const & other)
+ : data{}
+ , mutex{}
+ {
+ std::lock_guard<std::mutex> lock{other.mutex};
+ data = other.data;
+ }
+
+ Atomic(self_type&& other)
+ : data{}
+ , mutex{}
+ {
+ std::lock_guard<std::mutex> lock{other.mutex};
+ std::swap(data, other.data);
+ }
+
+ T operator=(T data)
+ {
+ std::lock_guard<std::mutex> lock{mutex};
+ this->data = std::move(data);
+ return this->data;
+ }
+
+ operator T() const
+ {
+ return load();
+ }
+
+ bool is_lock_free() const
+ {
+ return false;
+ }
+
+ void store(T data)
+ {
+ std::lock_guard<std::mutex> lock{mutex};
+ this->data = std::move(data);
+ }
+
+ T load() const {
+ std::lock_guard<std::mutex> lock{mutex};
+ return data;
+ }
+
+ T exchange(T data){
+ std::lock_guard<std::mutex> lock{mutex};
+ std::swap(data, this->data);
+ return data;
+ }
+
+ bool operator==(const T& other) const
+ {
+ std::lock_guard<std::mutex> lock{mutex};
+ return other == data;
+ }
+
+ bool operator!=(const T& other) const
+ {
+ std::lock_guard<std::mutex> lock{mutex};
+ return !(other == data);
+ }
+
+ bool operator==(const Atomic<T>& other) const
+ {
+ std::lock_guard<std::mutex> lock{mutex};
+ return other.load() == data;
+ }
+
+ bool operator!=(const Atomic<T>& other) const
+ {
+ std::lock_guard<std::mutex> lock{mutex};
+ return !(other.load() == data);
+ }
+
+private:
+ T data;
+ mutable std::mutex mutex;
+};
+
+//! Getter utility class.
+template <typename T> class SettingRef
+{
+public:
+ SettingRef(Atomic<T>& value)
+ : value(value)
+ {
+ // string isn't lock free either
+ assert((std::is_same<T, std::string>::value || value.is_lock_free()));
+ }
+
+ bool hasChanged()
+ {
+ T tmp = cache;
+ cache.exchange(value);
+
+ if(firstAccess)
+ {
+ firstAccess = false;
+ return true;
+ }
+
+ return cache != tmp;
+ }
+
+ T getValue() const
+ {
+ return cache;
+ }
+
+private:
+ bool firstAccess{true};
+ Atomic<T>& value;
+ Atomic<T> cache;
+};
diff --git a/src/audiofile.cc b/src/audiofile.cc
index 58b248b..84329f8 100644
--- a/src/audiofile.cc
+++ b/src/audiofile.cc
@@ -36,8 +36,6 @@
#include <sndfile.h>
#include <hugin.hpp>
-#include "configuration.h"
-
AudioFile::AudioFile(const std::string& filename, int filechannel)
{
is_loaded = false;
diff --git a/src/configuration.cc b/src/configuration.cc
deleted file mode 100644
index 72f6e4a..0000000
--- a/src/configuration.cc
+++ /dev/null
@@ -1,38 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/***************************************************************************
- * configuration.cc
- *
- * Sat Oct 8 14:37:14 CEST 2011
- * Copyright 2011 Bent Bisballe Nyeng
- * deva@aasimon.org
- ****************************************************************************/
-
-/*
- * This file is part of DrumGizmo.
- *
- * DrumGizmo is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * DrumGizmo 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with DrumGizmo; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-#include "configuration.h"
-
-bool Conf::enable_velocity_modifier = true;
-float Conf::velocity_modifier_falloff = 0.5;
-float Conf::velocity_modifier_weight = 0.25;
-
-bool Conf::enable_velocity_randomiser = false;
-float Conf::velocity_randomiser_weight = 0.1;
-
-int Conf::samplerate = 44100;
-
-bool Conf::enable_resampling = true;
diff --git a/src/configuration.h b/src/configuration.h
deleted file mode 100644
index 3adf525..0000000
--- a/src/configuration.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/***************************************************************************
- * configuration.h
- *
- * Sat Oct 8 14:37:13 CEST 2011
- * Copyright 2011 Bent Bisballe Nyeng
- * deva@aasimon.org
- ****************************************************************************/
-
-/*
- * This file is part of DrumGizmo.
- *
- * DrumGizmo is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * DrumGizmo 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with DrumGizmo; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-#ifndef __DRUMGIZMO_CONFIGURATION_H__
-#define __DRUMGIZMO_CONFIGURATION_H__
-
-namespace Conf {
- extern bool enable_velocity_modifier;
- extern float velocity_modifier_falloff;
- extern float velocity_modifier_weight;
-
- extern bool enable_velocity_randomiser;
- extern float velocity_randomiser_weight;
-
- extern int samplerate;
-
- extern bool enable_resampling;
-};
-
-
-#endif/*__DRUMGIZMO_CONFIGURATION_H__*/
diff --git a/src/drumgizmo.cc b/src/drumgizmo.cc
index 853e93d..aa6be23 100644
--- a/src/drumgizmo.cc
+++ b/src/drumgizmo.cc
@@ -38,26 +38,27 @@
#include <hugin.hpp>
#include <config.h>
+#include <memory>
#include "drumkitparser.h"
#include "audioinputenginemidi.h"
-#include "configuration.h"
#include "configparser.h"
#include "nolocale.h"
-DrumGizmo::DrumGizmo(AudioOutputEngine *o, AudioInputEngine *i)
- : MessageReceiver(MSGRCV_ENGINE)
- , loader()
+DrumGizmo::DrumGizmo(Settings& settings,
+ AudioOutputEngine *o, AudioInputEngine *i)
+ : loader(settings)
, oe(o)
, ie(i)
, framesize(0)
, freewheel(false)
, events{}
+ , settings(settings)
{
is_stopping = false;
audioCache.init(10000); // start thread
-
+
events.reserve(1000);
}
@@ -68,9 +69,12 @@ DrumGizmo::~DrumGizmo()
bool DrumGizmo::loadkit(std::string file)
{
+ settings.drumkit_load_status.store(LoadStatus::Idle);
+
if(file == "")
{
- return 1;
+ settings.drumkit_load_status.store(LoadStatus::Error);
+ return false;
}
DEBUG(drumgizmo, "loadkit(%s)\n", file.c_str());
@@ -81,27 +85,31 @@ bool DrumGizmo::loadkit(std::string file)
// Delete all Channels, Instruments, Samples and AudioFiles.
kit.clear();
- DrumKitParser parser(kit);
+ settings.drumkit_load_status.store(LoadStatus::Loading);
+
+ DrumKitParser parser(settings, kit);
if(parser.parseFile(file))
{
ERR(drumgizmo, "Drumkit parser failed: %s\n", file.c_str());
+ settings.drumkit_load_status.store(LoadStatus::Error);
return false;
}
- // Check if there is enough free RAM to load the drumkit.
- if(!memchecker.enoughFreeMemory(kit))
- {
- printf("WARNING: "
- "There doesn't seem to be enough RAM available to load the kit.\n"
- "Trying to load it anyway...\n");
- }
+ // TODO: Re-introduce when the code has been moved to the loader thread.
+ //// Check if there is enough free RAM to load the drumkit.
+ //if(!memchecker.enoughFreeMemory(kit))
+ //{
+ // printf("WARNING: "
+ // "There doesn't seem to be enough RAM available to load the kit.\n"
+ // "Trying to load it anyway...\n");
+ //}
loader.loadKit(&kit);
#ifdef WITH_RESAMPLER
for(int i = 0; i < MAX_NUM_CHANNELS; ++i)
{
- resampler[i].setup(kit.getSamplerate(), Conf::samplerate);
+ resampler[i].setup(kit.getSamplerate(), settings.samplerate.load());
}
#endif/*WITH_RESAMPLER*/
@@ -125,79 +133,6 @@ bool DrumGizmo::init()
return true;
}
-void DrumGizmo::handleMessage(Message *msg)
-{
- DEBUG(msg, "got message.");
- switch(msg->type()) {
- case Message::LoadDrumKit:
- {
- DEBUG(msg, "got LoadDrumKitMessage message.");
- LoadDrumKitMessage *m = (LoadDrumKitMessage*)msg;
- loadkit(m->drumkitfile);
- //init(true);
- }
- break;
- case Message::LoadMidimap:
- DEBUG(msg, "got LoadMidimapMessage message.");
- if(!ie->isMidiEngine())
- {
- break;
- }
- {
- AudioInputEngineMidi *aim = (AudioInputEngineMidi*)ie;
- LoadMidimapMessage *m = (LoadMidimapMessage*)msg;
- bool ret = aim->loadMidiMap(m->midimapfile, kit.instruments);
-
- LoadStatusMessageMidimap *ls = new LoadStatusMessageMidimap();
- ls->success = ret;
- msghandler.sendMessage(MSGRCV_UI, ls);
- }
- break;
- case Message::EngineSettingsMessage:
- {
- bool mmap_loaded = false;
- std::string mmapfile;
- if(ie->isMidiEngine())
- {
- AudioInputEngineMidi *aim = (AudioInputEngineMidi*)ie;
- mmapfile = aim->getMidimapFile();
- mmap_loaded = aim->isValid();
- }
-
- EngineSettingsMessage *msg = new EngineSettingsMessage();
- msg->midimapfile = mmapfile;
- msg->midimap_loaded = mmap_loaded;
- msg->drumkitfile = kit.getFile();
- msg->drumkit_loaded = loader.isDone();
- msg->enable_velocity_modifier = Conf::enable_velocity_modifier;
- msg->velocity_modifier_falloff = Conf::velocity_modifier_falloff;
- msg->velocity_modifier_weight = Conf::velocity_modifier_weight;
- msg->enable_velocity_randomiser = Conf::enable_velocity_randomiser;
- msg->velocity_randomiser_weight = Conf::velocity_randomiser_weight;
- msghandler.sendMessage(MSGRCV_UI, msg);
- }
- break;
- case Message::ChangeSettingMessage:
- {
- ChangeSettingMessage *ch = (ChangeSettingMessage*)msg;
- switch(ch->name) {
- case ChangeSettingMessage::enable_velocity_modifier:
- Conf::enable_velocity_modifier = ch->value;
- break;
- case ChangeSettingMessage::velocity_modifier_weight:
- Conf::velocity_modifier_weight = ch->value;
- break;
- case ChangeSettingMessage::velocity_modifier_falloff:
- Conf::velocity_modifier_falloff = ch->value;
- break;
- }
- }
- break;
- default:
- break;
- }
-}
-
void DrumGizmo::setFrameSize(size_t framesize)
{
// If we are resampling override the frame size.
@@ -259,8 +194,31 @@ bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples)
{
setFrameSize(nsamples);
- // Handle engine messages, at most one in each iteration:
- handleMessages(1);
+ // TODO: Move this to DrumKitLoader thread.
+ if(getter.drumkit_file.hasChanged())
+ {
+ loadkit(getter.drumkit_file.getValue());
+ }
+
+ // TODO: Move this to DrumKitLoader thread.
+ if(getter.midimap_file.hasChanged())
+ {
+ auto ie_midi = dynamic_cast<AudioInputEngineMidi*>(ie);
+ if(ie_midi)
+ {
+ settings.midimap_load_status.store(LoadStatus::Loading);
+ bool ret = ie_midi->loadMidiMap(getter.midimap_file.getValue(),
+ kit.instruments);
+ if(ret)
+ {
+ settings.midimap_load_status.store(LoadStatus::Done);
+ }
+ else
+ {
+ settings.midimap_load_status.store(LoadStatus::Error);
+ }
+ }
+ }
ie->pre();
oe->pre(nsamples);
@@ -398,7 +356,7 @@ bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples)
// Write audio
//
#ifdef WITH_RESAMPLER
- if((Conf::enable_resampling == false) ||
+ if((settings.enable_resampling.load() == false) ||
(resampler[0].getRatio() == 1.0)) // No resampling needed
{
#endif
@@ -636,17 +594,17 @@ void DrumGizmo::stop()
int DrumGizmo::samplerate()
{
- return Conf::samplerate;
+ return settings.samplerate.load();
}
void DrumGizmo::setSamplerate(int samplerate)
{
DEBUG(dgeditor, "%s samplerate: %d\n", __PRETTY_FUNCTION__, samplerate);
- Conf::samplerate = samplerate;
+ settings.samplerate.store(samplerate);
#ifdef WITH_RESAMPLER
for(int i = 0; i < MAX_NUM_CHANNELS; ++i)
{
- resampler[i].setup(kit.getSamplerate(), Conf::samplerate);
+ resampler[i].setup(kit.getSamplerate(), settings.samplerate.load());
}
if(resampler[0].getRatio() != 1)
{
@@ -691,15 +649,15 @@ std::string DrumGizmo::configString()
" <value name=\"drumkitfile\">" + kit.getFile() + "</value>\n"
" <value name=\"midimapfile\">" + mmapfile + "</value>\n"
" <value name=\"enable_velocity_modifier\">" +
- bool2str(Conf::enable_velocity_modifier) + "</value>\n"
+ bool2str(settings.enable_velocity_modifier.load()) + "</value>\n"
" <value name=\"velocity_modifier_falloff\">" +
- float2str(Conf::velocity_modifier_falloff) + "</value>\n"
+ float2str(settings.velocity_modifier_falloff.load()) + "</value>\n"
" <value name=\"velocity_modifier_weight\">" +
- float2str(Conf::velocity_modifier_weight) + "</value>\n"
+ float2str(settings.velocity_modifier_weight.load()) + "</value>\n"
" <value name=\"enable_velocity_randomiser\">" +
- bool2str(Conf::enable_velocity_randomiser) + "</value>\n"
+ bool2str(settings.enable_velocity_randomiser.load()) + "</value>\n"
" <value name=\"velocity_randomiser_weight\">" +
- float2str(Conf::velocity_randomiser_weight) + "</value>\n"
+ float2str(settings.velocity_randomiser_weight.load()) + "</value>\n"
"</config>";
}
@@ -711,68 +669,50 @@ bool DrumGizmo::setConfigString(std::string cfg)
ConfigParser p;
if(p.parseString(cfg))
{
- ERR(drumgizmo, "Config parse error.\n");
- return false;
+ ERR(drumgizmo, "Config parse error.\n");
+ return false;
}
if(p.value("enable_velocity_modifier") != "")
{
- Conf::enable_velocity_modifier =
- p.value("enable_velocity_modifier") == "true";
+ settings.enable_velocity_modifier.store(p.value("enable_velocity_modifier") == "true");
}
if(p.value("velocity_modifier_falloff") != "")
{
- Conf::velocity_modifier_falloff =
- str2float(p.value("velocity_modifier_falloff"));
+ settings.velocity_modifier_falloff.store(str2float(p.value("velocity_modifier_falloff")));
}
if(p.value("velocity_modifier_weight") != "")
{
- Conf::velocity_modifier_weight =
- str2float(p.value("velocity_modifier_weight"));
+ settings.velocity_modifier_weight.store(str2float(p.value("velocity_modifier_weight")));
}
if(p.value("enable_velocity_randomiser") != "")
{
- Conf::enable_velocity_randomiser =
- p.value("enable_velocity_randomiser") == "true";
+ settings.enable_velocity_randomiser.store(p.value("enable_velocity_randomiser") == "true");
}
if(p.value("velocity_randomiser_weight") != "")
{
- Conf::velocity_randomiser_weight =
- str2float(p.value("velocity_randomiser_weight"));
+ settings.velocity_randomiser_weight.store(str2float(p.value("velocity_randomiser_weight")));
}
if(p.value("enable_resampling") != "")
{
- Conf::enable_resampling =
- p.value("enable_resampling") == "true";
+ settings.enable_resampling.store(p.value("enable_resampling") == "true");
}
std::string newkit = p.value("drumkitfile");
- if(newkit != "" && kit.getFile() != newkit)
+ if(newkit != "")
{
- /*
- if(!loadkit(p.values["drumkitfile"]))
- {
- return false;
- }
- init(true);
- */
- LoadDrumKitMessage *msg = new LoadDrumKitMessage();
- msg->drumkitfile = newkit;
- msghandler.sendMessage(MSGRCV_ENGINE, msg);
+ settings.drumkit_file.store(newkit);
}
std::string newmidimap = p.value("midimapfile");
if(newmidimap != "")
{
- //midimapfile = newmidimap;
- LoadMidimapMessage *msg = new LoadMidimapMessage();
- msg->midimapfile = newmidimap;
- msghandler.sendMessage(MSGRCV_ENGINE, msg);
+ settings.midimap_file.store(newmidimap);
}
return true;
diff --git a/src/drumgizmo.h b/src/drumgizmo.h
index 632d5fc..7af5dbb 100644
--- a/src/drumgizmo.h
+++ b/src/drumgizmo.h
@@ -31,34 +31,26 @@
#include "audiooutputengine.h"
#include "audioinputengine.h"
-
#include "events.h"
#include "audiofile.h"
#include "drumkit.h"
#include "memchecker.h"
-
#include "drumkitloader.h"
#include "audiocache.h"
-
#include "mutex.h"
-
-#include "message.h"
-
-#include "messagereceiver.h"
-
#include "chresampler.h"
-
#include "configfile.h"
+#include "settings.h"
#define MAX_NUM_CHANNELS 64
#define REFSFILE "refs.conf"
#define RESAMPLER_INPUT_BUFFER 64
class DrumGizmo
- : public MessageReceiver
{
public:
- DrumGizmo(AudioOutputEngine *outputengine, AudioInputEngine *inputengine);
+ DrumGizmo(Settings& settings,
+ AudioOutputEngine *outputengine, AudioInputEngine *inputengine);
virtual ~DrumGizmo();
bool loadkit(std::string kitfile);
@@ -74,8 +66,6 @@ public:
std::string configString();
bool setConfigString(std::string cfg);
- void handleMessage(Message *msg);
-
int samplerate();
void setSamplerate(int samplerate);
@@ -106,6 +96,8 @@ protected:
size_t framesize;
bool freewheel;
-
+
std::vector<event_t> events;
+ Settings& settings;
+ SettingsGetter getter{settings};
};
diff --git a/src/drumkit.cc b/src/drumkit.cc
index 1b95c87..f25a6ea 100644
--- a/src/drumkit.cc
+++ b/src/drumkit.cc
@@ -39,12 +39,11 @@ DrumKit::~DrumKit()
void DrumKit::clear()
{
- Instruments::iterator i = instruments.begin();
- while(i != instruments.end())
+ for(auto& instrument : instruments)
{
- delete *i;
- i++;
+ delete instrument;
}
+
instruments.clear();
channels.clear();
@@ -78,20 +77,3 @@ size_t DrumKit::getSamplerate() const
{
return _samplerate;
}
-
-#ifdef TEST_DRUMKIT
-// Additional dependency files
-// deps:
-// Required cflags (autoconf vars may be used)
-// cflags:
-// Required link options (autoconf vars may be used)
-// libs:
-#include "test.h"
-
-TEST_BEGIN;
-
-// TODO: Put some testcode here (see test.h for usable macros).
-
-TEST_END;
-
-#endif /*TEST_DRUMKIT*/
diff --git a/src/drumkit.h b/src/drumkit.h
index 1ceef3e..e3ae783 100644
--- a/src/drumkit.h
+++ b/src/drumkit.h
@@ -33,11 +33,9 @@
#include "instrument.h"
#include "versionstr.h"
-class DrumKitParser;
class DrumKit
{
friend class DrumKitParser;
-
public:
DrumKit();
~DrumKit();
diff --git a/src/drumkitloader.cc b/src/drumkitloader.cc
index ff489ea..3a0e096 100644
--- a/src/drumkitloader.cc
+++ b/src/drumkitloader.cc
@@ -26,14 +26,17 @@
*/
#include "drumkitloader.h"
+#include <iostream>
+
#include <hugin.hpp>
#include "drumkitparser.h"
#include "drumgizmo.h"
-DrumKitLoader::DrumKitLoader()
- : semaphore("drumkitloader")
- , framesize(0)
+DrumKitLoader::DrumKitLoader(Settings& settings)
+ : framesize(0)
+ , settings(settings)
+ , getter(settings)
{
run();
run_semaphore.wait(); // Wait for the thread to actually start.
@@ -55,7 +58,7 @@ DrumKitLoader::~DrumKitLoader()
void DrumKitLoader::stop()
{
{
- MutexAutolock l(mutex);
+ std::lock_guard<std::mutex> guard(mutex);
load_queue.clear();
}
@@ -66,68 +69,48 @@ void DrumKitLoader::stop()
void DrumKitLoader::skip()
{
- MutexAutolock l(mutex);
+ std::lock_guard<std::mutex> guard(mutex);
load_queue.clear();
}
void DrumKitLoader::setFrameSize(size_t framesize)
{
- DEBUG(loader, "%s pre\n", __PRETTY_FUNCTION__);
-
- {
- MutexAutolock l(mutex);
- this->framesize = framesize;
- framesize_semaphore.post(); // Signal that the framesize has been set.
- }
-
- DEBUG(loader, "%s post\n", __PRETTY_FUNCTION__);
+ std::lock_guard<std::mutex> guard(mutex);
+ this->framesize = framesize;
+ framesize_semaphore.post(); // Signal that the framesize has been set.
}
bool DrumKitLoader::isDone()
{
- MutexAutolock l(mutex);
+ std::lock_guard<std::mutex> guard(mutex);
return load_queue.size() == 0;
}
void DrumKitLoader::loadKit(DrumKit *kit)
{
- MutexAutolock l(mutex);
+ std::lock_guard<std::mutex> guard(mutex);
DEBUG(loader, "Create AudioFile queue from DrumKit\n");
- total_num_audiofiles = 0;// For UI Progress Messages
-
- { // Count total number of files that need loading:
- Instruments::iterator i = kit->instruments.begin();
- while(i != kit->instruments.end())
- {
- Instrument *instr = *i;
- total_num_audiofiles += instr->audiofiles.size();
- ++i;
- }
- }
+ std::size_t total_num_audiofiles = 0;// For UI Progress Messages
- fraction = total_num_audiofiles / 200;
- if(fraction == 0)
+ // Count total number of files that need loading:
+ for(auto instr : kit->instruments)
{
- fraction = 1;
+ total_num_audiofiles += instr->audiofiles.size();
}
- { // Now actually queue them for loading:
- Instruments::iterator i = kit->instruments.begin();
- while(i != kit->instruments.end())
- {
- Instrument *instr = *i;
-
- std::vector<AudioFile*>::iterator af = instr->audiofiles.begin();
- while(af != instr->audiofiles.end())
- {
- AudioFile *audiofile = *af;
- load_queue.push_back(audiofile);
- af++;
- }
+ settings.number_of_files.store(total_num_audiofiles);
- ++i;
+ // Now actually queue them for loading:
+ for(auto instr : kit->instruments)
+ {
+ std::vector<AudioFile*>::iterator af = instr->audiofiles.begin();
+ while(af != instr->audiofiles.end())
+ {
+ AudioFile *audiofile = *af;
+ load_queue.push_back(audiofile);
+ af++;
}
}
@@ -151,23 +134,35 @@ void DrumKitLoader::thread_main()
{
size_t size;
{
- MutexAutolock l(mutex);
+ std::lock_guard<std::mutex> guard(mutex);
size = load_queue.size();
}
// Only sleep if queue is empty.
if(size == 0)
{
- semaphore.wait();
+ semaphore.wait(std::chrono::milliseconds(1000));
+ }
+
+ if(getter.drumkit_file.hasChanged())
+ {
+ //std::cout << "RELOAD DRUMKIT!" << std::endl;
+ }
+
+ if(getter.midimap_file.hasChanged())
+ {
+ //std::cout << "RELOAD MIDIMAP!" << std::endl;
}
std::string filename;
{
- MutexAutolock l(mutex);
+ std::lock_guard<std::mutex> guard(mutex);
+
if(load_queue.size() == 0)
{
continue;
}
+
AudioFile *audiofile = load_queue.front();
load_queue.pop_front();
filename = audiofile->filename;
@@ -183,15 +178,13 @@ void DrumKitLoader::thread_main()
audiofile->load(preload_size);
}
- loaded++;
+ ++loaded;
+
+ settings.number_of_files_loaded.store(loaded);
- if(loaded % fraction == 0 || loaded == total_num_audiofiles)
+ if(settings.number_of_files.load() == loaded)
{
- LoadStatusMessage *ls = new LoadStatusMessage();
- ls->number_of_files = total_num_audiofiles;
- ls->numer_of_files_loaded = loaded;
- ls->current_file = filename;
- msghandler.sendMessage(MSGRCV_UI, ls);
+ settings.drumkit_load_status.store(LoadStatus::Done);
}
}
diff --git a/src/drumkitloader.h b/src/drumkitloader.h
index 3656839..3fd7ec1 100644
--- a/src/drumkitloader.h
+++ b/src/drumkitloader.h
@@ -28,12 +28,14 @@
#include <string>
#include <list>
+#include <mutex>
+#include "mutex.h"
#include "thread.h"
#include "semaphore.h"
-#include "mutex.h"
#include "drumkit.h"
+#include "settings.h"
//! This class is responsible for loading the drumkits in its own thread.
//! All interaction calls are simply modifying queues and not doing any
@@ -45,7 +47,7 @@ class DrumKitLoader
{
public:
//! The constrcutor starts the loader thread.
- DrumKitLoader();
+ DrumKitLoader(Settings& settings);
//! The destructor signals the thread to stop and waits to merge before
//! returning (ie. deleting the object will garantuee that the thread has
@@ -75,11 +77,11 @@ protected:
Semaphore run_semaphore;
Semaphore semaphore;
Semaphore framesize_semaphore;
- Mutex mutex;
+ std::mutex mutex;
volatile bool running{false};
std::list<AudioFile*> load_queue;
- size_t total_num_audiofiles{0};
- size_t fraction{1};
- size_t loaded{0};
- size_t framesize{0};
+ std::size_t loaded{0};
+ std::size_t framesize{0};
+ Settings& settings;
+ SettingsGetter getter;
};
diff --git a/src/drumkitparser.cc b/src/drumkitparser.cc
index 3ba69c8..048a05b 100644
--- a/src/drumkitparser.cc
+++ b/src/drumkitparser.cc
@@ -34,9 +34,10 @@
#include "path.h"
#include "drumgizmo.h"
-DrumKitParser::DrumKitParser(DrumKit& kit)
- : kit(kit)
- , refs(REFSFILE)
+DrumKitParser::DrumKitParser(Settings& settings, DrumKit& k)
+ : kit(k)
+ , refs(REFSFILE)
+ , settings(settings)
{
}
@@ -46,9 +47,9 @@ int DrumKitParser::parseFile(const std::string& filename)
if(refs.load())
{
- if(filename.size() > 1 && filename[0] == '@')
+ if((filename.size() > 1) && (filename[0] == '@'))
{
- edited_filename = refs.getValue(filename.substr(1));
+ edited_filename = refs.getValue(filename.substr(1));
}
}
else
@@ -57,9 +58,10 @@ int DrumKitParser::parseFile(const std::string& filename)
}
path = getPath(edited_filename);
- auto result = SAXParser::parseFile(filename);
+ auto result = SAXParser::parseFile(edited_filename);
- if (result == 0) {
+ if(result == 0)
+ {
kit._file = edited_filename;
}
@@ -101,7 +103,7 @@ void DrumKitParser::startTag(const std::string& name, const attr_t& attr)
{
ERR(kitparser, "Error parsing version number: %s, using 1.0\n", err);
kit._version = VersionStr(1,0,0);
- }
+ }
}
else
{
@@ -112,7 +114,7 @@ void DrumKitParser::startTag(const std::string& name, const attr_t& attr)
if(name == "channels")
{
-
+
}
if(name == "channel")
@@ -140,6 +142,7 @@ void DrumKitParser::startTag(const std::string& name, const attr_t& attr)
ERR(kitparser, "Missing name in instrument tag.\n");
return;
}
+
if(attr.find("file") == attr.end())
{
ERR(kitparser, "Missing file in instrument tag.\n");
@@ -180,12 +183,14 @@ void DrumKitParser::endTag(const std::string& name)
{
if(name == "instrument")
{
- Instrument* i = new Instrument();
- i->setGroup(instr_group);
- // Instrument &i = kit.instruments[kit.instruments.size() - 1];
- InstrumentParser parser(*i);
+ Instrument* instrument = new Instrument(settings);
+ instrument->setGroup(instr_group);
+
+ InstrumentParser parser(*instrument);
parser.parseFile(path + "/" + instr_file);
- kit.instruments.push_back(i);
+
+ // Transfer ownership to the DrumKit object.
+ kit.instruments.push_back(instrument);
// Assign kit channel numbers to instruments channels.
std::vector<InstrumentChannel*>::iterator ic = parser.channellist.begin();
@@ -206,16 +211,18 @@ void DrumKitParser::endTag(const std::string& name)
c->num = kit.channels[cnt].num;
}
}
+
if(c->num == NO_CHANNEL)
{
ERR(kitparser, "Missing channel '%s' in instrument '%s'\n",
- c->name.c_str(), i->getName().c_str());
+ c->name.c_str(), instrument->getName().c_str());
}
- else {
+ else
+ {
/*
- DEBUG(kitparser, "Assigned channel '%s' to number %d in instrument '%s'\n",
- c->name.c_str(), c->num, i.name().c_str());
- */
+ DEBUG(kitparser, "Assigned channel '%s' to number %d in instrument '%s'\n",
+ c->name.c_str(), c->num, i.name().c_str());
+ */
}
ic++;
}
diff --git a/src/drumkitparser.h b/src/drumkitparser.h
index b0c8d8f..0adccb9 100644
--- a/src/drumkitparser.h
+++ b/src/drumkitparser.h
@@ -34,7 +34,7 @@ class DrumKitParser
: public SAXParser
{
public:
- DrumKitParser(DrumKit& kit);
+ DrumKitParser(Settings& setting, DrumKit& kit);
virtual int parseFile(const std::string& filename) override;
@@ -52,4 +52,5 @@ private:
std::string instr_group;
ConfigFile refs;
+ Settings& settings;
};
diff --git a/src/instrument.cc b/src/instrument.cc
index 9f18233..cc052e9 100644
--- a/src/instrument.cc
+++ b/src/instrument.cc
@@ -26,15 +26,12 @@
*/
#include "instrument.h"
-#include <stdlib.h>
-#include <stdio.h>
-
#include <hugin.hpp>
#include "sample.h"
-#include "configuration.h"
-Instrument::Instrument()
+Instrument::Instrument(Settings& settings)
+ : settings(settings)
{
DEBUG(instrument, "new %p\n", this);
mod = 1.0;
@@ -45,7 +42,7 @@ Instrument::Instrument()
Instrument::~Instrument()
{
- magic = NULL;
+ magic = nullptr;
DEBUG(instrument, "delete %p\n", this);
std::vector<AudioFile*>::iterator i = audiofiles.begin();
@@ -63,16 +60,26 @@ bool Instrument::isValid() const
Sample* Instrument::sample(level_t level, size_t pos)
{
- Sample *sample = NULL;
+ // Read out all values from settings.
+ auto enable_velocity_randomiser = settings.enable_velocity_randomiser.load();
+ auto velocity_randomiser_weight = settings.velocity_randomiser_weight.load();
+ auto samplerate = settings.samplerate.load();
+ auto velocity_modifier_falloff = settings.velocity_modifier_falloff.load();
+ auto enable_velocity_modifier = settings.enable_velocity_modifier.load();
+ auto velocity_modifier_weight = settings.velocity_modifier_weight.load();
+
+ Sample *sample = nullptr;
- if(Conf::enable_velocity_modifier == false) {
+ if(enable_velocity_modifier == false)
+ {
mod = 1.0;
lastpos = 0;
}
- if(Conf::enable_velocity_randomiser) {
- float r = rand.floatInRange(-1.0*Conf::velocity_randomiser_weight,
- Conf::velocity_randomiser_weight);
+ if(enable_velocity_randomiser)
+ {
+ float r = rand.floatInRange(-1.0 * velocity_randomiser_weight,
+ velocity_randomiser_weight);
level += r;
if(level > 1.0)
{
@@ -84,9 +91,9 @@ Sample* Instrument::sample(level_t level, size_t pos)
}
}
- if(Conf::enable_velocity_modifier) {
- mod += (pos - lastpos) /
- (Conf::samplerate * Conf::velocity_modifier_falloff);
+ if(enable_velocity_modifier)
+ {
+ mod += (pos - lastpos) / (samplerate * velocity_modifier_falloff);
if(mod > 1.0)
{
mod = 1.0;
@@ -98,21 +105,22 @@ Sample* Instrument::sample(level_t level, size_t pos)
// Version 2.0
sample = powerlist.get(level * mod);
}
- else {
+ else
+ {
// Version 1.0
std::vector<Sample*> s = samples.get(level * mod);
if(s.size() == 0)
{
- return NULL;
+ return nullptr;
}
sample = rand.choose(s);
}
- if(Conf::enable_velocity_modifier)
+ if(enable_velocity_modifier)
{
lastpos = pos;
- mod *= Conf::velocity_modifier_weight;
+ mod *= velocity_modifier_weight;
}
return sample;
@@ -157,41 +165,3 @@ void Instrument::setGroup(const std::string& g)
{
_group = g;
}
-
-#ifdef TEST_INSTRUMENT
-// deps: channel.cc sample.cc audiofile.cc
-// cflags: $(SNDFILE_CFLAGS)
-// libs: $(SNDFILE_LIBS)
-#include "test.h"
-
-TEST_BEGIN;
-
-Instrument i("test");
-
-Sample* a = new Sample();
-i.addSample(0.0, 1.0, a);
-
-Sample* b = new Sample();
-i.addSample(0.0, 1.0, b);
-
-Sample* c = new Sample();
-i.addSample(1.5, 1.7, c);
-
-TEST_EQUAL(i.sample(0.0), b, "?");
-TEST_EQUAL(i.sample(0.0), a, "?");
-TEST_EQUAL(i.sample(0.0), b, "?");
-TEST_EQUAL(i.sample(0.0), b, "?");
-TEST_EQUAL(i.sample(0.0), b, "?");
-TEST_EQUAL(i.sample(0.0), b, "?");
-TEST_EQUAL(i.sample(0.0), a, "?");
-TEST_EQUAL(i.sample(0.0), a, "?");
-
-TEST_EQUAL(i.sample(2.0), NULL, "?");
-
-TEST_EQUAL(i.sample(1.6), c, "?");
-TEST_EQUAL(i.sample(1.6), c, "?");
-TEST_EQUAL(i.sample(1.6), c, "?");
-
-TEST_END;
-
-#endif /*TEST_INSTRUMENT*/
diff --git a/src/instrument.h b/src/instrument.h
index de5546b..a531aec 100644
--- a/src/instrument.h
+++ b/src/instrument.h
@@ -36,13 +36,13 @@
#include "versionstr.h"
#include "random.h"
-class InstrumentParser;
+#include "settings.h"
+
class Instrument
{
friend class InstrumentParser;
-
public:
- Instrument();
+ Instrument(Settings& settings);
~Instrument();
Sample* sample(level_t level, size_t pos);
@@ -78,7 +78,7 @@ private:
size_t lastpos;
float mod;
-
+ Settings& settings;
Random rand;
};
diff --git a/src/instrumentparser.cc b/src/instrumentparser.cc
index 268f8f3..1e42cc3 100644
--- a/src/instrumentparser.cc
+++ b/src/instrumentparser.cc
@@ -35,8 +35,8 @@
#include "nolocale.h"
-InstrumentParser::InstrumentParser(Instrument& i)
- : instrument(i)
+InstrumentParser::InstrumentParser(Instrument& instrument)
+ : instrument(instrument)
{
}
@@ -64,14 +64,15 @@ void InstrumentParser::startTag(const std::string& name, const attr_t& attr)
if(attr.find("version") != attr.end())
{
- try {
+ try
+ {
instrument.version = VersionStr(attr.at("version"));
}
- catch(const char *err)
+ catch(const char* err)
{
ERR(instrparser, "Error parsing version number: %s, using 1.0\n", err);
instrument.version = VersionStr(1,0,0);
- }
+ }
}
else
{
@@ -82,7 +83,6 @@ void InstrumentParser::startTag(const std::string& name, const attr_t& attr)
if(name == "samples")
{
-
}
if(name == "sample")
@@ -93,10 +93,10 @@ void InstrumentParser::startTag(const std::string& name, const attr_t& attr)
return;
}
- float power;
+ float power;
if(attr.find("power") == attr.end())
{
- power = -1;
+ power = -1;
}
else
{
@@ -105,12 +105,12 @@ void InstrumentParser::startTag(const std::string& name, const attr_t& attr)
}
// TODO get rid of new or delete it properly
- s = new Sample(attr.at("name"), power);
+ sample = new Sample(attr.at("name"), power);
}
if(name == "audiofile")
{
- if(s == nullptr)
+ if(sample == nullptr)
{
ERR(instrparser,"Missing Sample!\n");
return;
@@ -139,18 +139,24 @@ void InstrumentParser::startTag(const std::string& name, const attr_t& attr)
}
}
- filechannel = filechannel - 1; // 1-based in file, but zero-based internally
- // TODO do those next two lines correspond with proper deletes? If not fix it.
- AudioFile *af = new AudioFile(path + "/" + attr.at("file"), filechannel);
- InstrumentChannel *ch = new InstrumentChannel(attr.at("channel"));
- channellist.push_back(ch);
- s->addAudioFile(ch, af);
- instrument.audiofiles.push_back(af);
+ filechannel = filechannel - 1; // 1-based in file but zero-based internally.
+
+ AudioFile *audio_file =
+ new AudioFile(path + "/" + attr.at("file"), filechannel);
+
+ // TODO: This is not deleted anywhere...
+ InstrumentChannel *instrument_channel =
+ new InstrumentChannel(attr.at("channel"));
+
+ channellist.push_back(instrument_channel);
+ sample->addAudioFile(instrument_channel, audio_file);
+
+ // Transfer audio_file ownership to the instrument.
+ instrument.audiofiles.push_back(audio_file);
}
if(name == "velocities")
{
-
}
if(name == "velocity")
@@ -179,19 +185,17 @@ void InstrumentParser::startTag(const std::string& name, const attr_t& attr)
return;
}
- Sample* sample = nullptr;
- std::vector<Sample *>::iterator i = instrument.samplelist.begin();
- while(i != instrument.samplelist.end())
+ Sample* sample_ref = nullptr;
+ for(auto& sample : instrument.samplelist)
{
- if((*i)->name == attr.at("name"))
+ if(sample->name == attr.at("name"))
{
- sample = *i;
+ sample_ref = sample;
break;
}
- i++;
}
- if(sample == nullptr)
+ if(sample_ref == nullptr)
{
ERR(instrparser,"Samplref pointed at non-existing sample.\n");
return;
@@ -200,7 +204,7 @@ void InstrumentParser::startTag(const std::string& name, const attr_t& attr)
if(instrument.version == VersionStr("1.0"))
{
// Old "velocity group" algorithm needs this
- instrument.addSample(lower, upper, sample);
+ instrument.addSample(lower, upper, sample_ref);
}
}
}
@@ -209,15 +213,15 @@ void InstrumentParser::endTag(const std::string& name)
{
if(name == "sample")
{
- if(s == nullptr)
+ if(sample == nullptr)
{
ERR(instrparser,"Missing Sample.\n");
return;
}
- instrument.samplelist.push_back(s);
+ instrument.samplelist.push_back(sample);
- s = nullptr;
+ sample = nullptr;
}
if(name == "instrument") {
diff --git a/src/instrumentparser.h b/src/instrumentparser.h
index 965694a..6cbaf8a 100644
--- a/src/instrumentparser.h
+++ b/src/instrumentparser.h
@@ -47,7 +47,7 @@ protected:
private:
Instrument& instrument;
- Sample* s{nullptr};
+ Sample* sample{nullptr};
std::string path;
diff --git a/src/message.h b/src/message.h
deleted file mode 100644
index 71d0da6..0000000
--- a/src/message.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/***************************************************************************
- * message.h
- *
- * Wed Mar 20 15:50:57 CET 2013
- * Copyright 2013 Bent Bisballe Nyeng
- * deva@aasimon.org
- ****************************************************************************/
-
-/*
- * This file is part of DrumGizmo.
- *
- * DrumGizmo is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * DrumGizmo 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with DrumGizmo; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-#ifndef __DRUMGIZMO_MESSAGE_H__
-#define __DRUMGIZMO_MESSAGE_H__
-
-#include <string>
-
-class MessageHandler;
-
-class Message {
-public:
- typedef enum {
- // Engine -> GUI Messages:
- LoadStatus, // Signal GUI the current load status.
- LoadStatusMidimap, // Signal GUI the current load status of the midimap.
-
- // GUI -> Engine, Engine -> Engine Messages:
- LoadDrumKit, // Signal engine to load drumkit.
- LoadMidimap, // Signal engine to load midimap.
- EngineSettingsMessage, // Request or receive engine settings.
- ChangeSettingMessage, // Update named setting in engine.
- } type_t;
-
- typedef enum {
- NormalProcessing, // Just add to the queue
- FilterMultiple, // Ignore top message if it has the same type.
- // SyncWait, // Block the send call until the message has been handled by the receiver.
- } processing_mode_t;
-
- virtual ~Message() {}
- virtual type_t type() = 0;
- virtual processing_mode_t processing_mode() { return NormalProcessing; }
-};
-
-class LoadStatusMessage : public Message {
-public:
- type_t type() { return Message::LoadStatus; }
- processing_mode_t processing_mode() { return FilterMultiple; }
- unsigned int number_of_files;
- unsigned int numer_of_files_loaded;
- std::string current_file;
-};
-
-class LoadStatusMessageMidimap : public Message {
-public:
- type_t type() { return Message::LoadStatusMidimap; }
- bool success;
-};
-
-class LoadDrumKitMessage : public Message {
-public:
- type_t type() { return Message::LoadDrumKit; }
- std::string drumkitfile;
-};
-
-class LoadMidimapMessage : public Message {
-public:
- type_t type() { return Message::LoadMidimap; }
- std::string midimapfile;
-};
-
-class EngineSettingsMessage : public Message {
-public:
- type_t type() { return Message::EngineSettingsMessage; }
- std::string midimapfile;
- bool midimap_loaded;
-
- std::string drumkitfile;
- bool drumkit_loaded;
-
- float enable_velocity_modifier;
- float velocity_modifier_falloff;
- float velocity_modifier_weight;
- float enable_velocity_randomiser;
- float velocity_randomiser_weight;
-};
-
-class ChangeSettingMessage : public Message {
-public:
- typedef enum {
- enable_velocity_modifier,
- velocity_modifier_weight,
- velocity_modifier_falloff,
- } setting_name_t;
-
- ChangeSettingMessage(setting_name_t n, float v) {
- name = n;
- value = v;
- }
-
- type_t type() { return Message::ChangeSettingMessage; }
-
- setting_name_t name;
- float value;
-};
-
-#endif/*__DRUMGIZMO_MESSAGE_H__*/
diff --git a/src/messagehandler.cc b/src/messagehandler.cc
deleted file mode 100644
index 7a0c7ea..0000000
--- a/src/messagehandler.cc
+++ /dev/null
@@ -1,89 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/***************************************************************************
- * messagehandler.cc
- *
- * Fri Jun 14 20:30:43 CEST 2013
- * Copyright 2013 Bent Bisballe Nyeng
- * deva@aasimon.org
- ****************************************************************************/
-
-/*
- * This file is part of DrumGizmo.
- *
- * DrumGizmo is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * DrumGizmo 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with DrumGizmo; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-#include "messagehandler.h"
-
-#include <hugin.hpp>
-
-#include "messagereceiver.h"
-
-// Global messagehandler:
-MessageHandler msghandler;
-
-MessageHandler::MessageHandler()
-{
-}
-
-void MessageHandler::addReceiver(message_receiver_id_t id,
- MessageReceiver *receiver)
-{
- MutexAutolock l(mutex);
-
- receivers[id] = receiver;
-}
-
-void MessageHandler::removeReceiver(MessageReceiver *receiver)
-{
- MutexAutolock l(mutex);
-
- std::map<message_receiver_id_t, MessageReceiver *>::iterator i =
- receivers.begin();
- while(i != receivers.end()) {
- if(i->second == receiver) {
- receivers.erase(i);
- break;
- }
- i++;
- }
-}
-
-bool MessageHandler::sendMessage(message_receiver_id_t id, Message* msg)
-{
- MutexAutolock l(mutex);
-
- if(receivers.find(id) == receivers.end()) {
- //WARN(msghandler, "Could not find id %d\n", id);
- delete msg;
- return false;
- }
-
- //DEBUG(msghandler, "Sending message to id %d\n", id);
-
- MessageReceiver *receiver = receivers[id];
- /* // This code causes sporadic segfaults on windows.
- if(msg->processing_mode() == Message::FilterMultiple) {
- Message *pmsg;
- MutexAutolock lock(receiver->message_mutex); // Make peek/receive atomic.
- while( (pmsg = receiver->peekMessage()) != NULL) {
- if(pmsg->type() != msg->type()) break;
- // Remove all old messages with same type.
- delete receiver->receiveMessage();
- }
- }
- */
- receiver->sendMessage(msg);
- return true;
-}
diff --git a/src/messagehandler.h b/src/messagehandler.h
deleted file mode 100644
index 2b6c40e..0000000
--- a/src/messagehandler.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/***************************************************************************
- * messagehandler.h
- *
- * Fri Jun 14 20:30:43 CEST 2013
- * Copyright 2013 Bent Bisballe Nyeng
- * deva@aasimon.org
- ****************************************************************************/
-
-/*
- * This file is part of DrumGizmo.
- *
- * DrumGizmo is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * DrumGizmo 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with DrumGizmo; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-#ifndef __DRUMGIZMO_MESSAGEHANDLER_H__
-#define __DRUMGIZMO_MESSAGEHANDLER_H__
-
-#include <map>
-
-#include "message.h"
-#include "mutex.h"
-
-typedef enum {
- MSGRCV_ENGINE = 1,
- MSGRCV_UI = 2,
- MSGRCV_LOADER = 3,
-} message_receiver_id_t;
-
-class MessageReceiver;
-
-class MessageHandler {
-public:
- MessageHandler();
-
- void addReceiver(message_receiver_id_t id, MessageReceiver *receiver);
- void removeReceiver(MessageReceiver *receiver);
-
- /**
- * Send Message to receiver with specified id.
- * @return Return true if id is registered. Return false if id is not
- * currently registered.
- */
- bool sendMessage(message_receiver_id_t id, Message* msg);
-
-private:
- std::map<message_receiver_id_t, MessageReceiver *> receivers;
-
- Mutex mutex;
-};
-
-// Global MessageHandler;
-extern MessageHandler msghandler;
-
-#endif/*__DRUMGIZMO_MESSAGEHANDLER_H__*/
diff --git a/src/messagereceiver.cc b/src/messagereceiver.cc
deleted file mode 100644
index 590c98a..0000000
--- a/src/messagereceiver.cc
+++ /dev/null
@@ -1,78 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/***************************************************************************
- * messagereceiver.cc
- *
- * Sun Jun 16 12:09:06 CEST 2013
- * Copyright 2013 Bent Bisballe Nyeng
- * deva@aasimon.org
- ****************************************************************************/
-
-/*
- * This file is part of DrumGizmo.
- *
- * DrumGizmo is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * DrumGizmo 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with DrumGizmo; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-#include "messagereceiver.h"
-
-#include <hugin.hpp>
-
-MessageReceiver::MessageReceiver(message_receiver_id_t id)
-{
- msghandler.addReceiver(id, this);
-}
-
-MessageReceiver::~MessageReceiver()
-{
- msghandler.removeReceiver(this);
-}
-
-void MessageReceiver::sendMessage(Message *msg)
-{
- MutexAutolock l(message_mutex);
-
- message_queue.push_back(msg);
-}
-
-Message *MessageReceiver::receiveMessage()
-{
- Message *msg = NULL;
- if(message_queue.size()) {
- msg = message_queue.front();
- message_queue.pop_front();
- }
- return msg;
-}
-
-Message *MessageReceiver::peekMessage()
-{
- Message *msg = NULL;
- if(message_queue.size()) {
- msg = message_queue.front();
- }
- return msg;
-}
-
-void MessageReceiver::handleMessages(size_t max)
-{
- MutexAutolock l(message_mutex);
- bool process_all = false;
- if(max == 0) process_all = true;
-
- while((process_all || max--) && peekMessage()) {
- Message *msg = receiveMessage();
- handleMessage(msg);
- delete msg;
- }
-}
diff --git a/src/messagereceiver.h b/src/messagereceiver.h
deleted file mode 100644
index c1a8e60..0000000
--- a/src/messagereceiver.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/***************************************************************************
- * messagereceiver.h
- *
- * Sun Jun 16 12:09:06 CEST 2013
- * Copyright 2013 Bent Bisballe Nyeng
- * deva@aasimon.org
- ****************************************************************************/
-
-/*
- * This file is part of DrumGizmo.
- *
- * DrumGizmo is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * DrumGizmo 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with DrumGizmo; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-#ifndef __DRUMGIZMO_MESSAGERECEIVER_H__
-#define __DRUMGIZMO_MESSAGERECEIVER_H__
-
-#include <list>
-
-#include "mutex.h"
-#include "message.h"
-#include "messagehandler.h"
-
-class MessageReceiver {
- friend class MessageHandler;
-public:
- MessageReceiver(message_receiver_id_t id);
- ~MessageReceiver();
-
- /**
- * Receive message from the message queue.
- */
- Message *receiveMessage();
-
- /**
- * Receive message from the message queue without removing it.
- */
- Message *peekMessage();
-
- /**
- * Add a message to the message queue.
- */
- void sendMessage(Message *msg);
-
- /**
- * Handle messages from the event queue.
- * @param max_number_of_events the maximum number of events to be handled in
- * this call. 0 means all.
- */
- void handleMessages(size_t max_number_of_events = 0);
-
- /**
- * Handler to be implemented in child classes.
- * Handles a single event.
- */
- virtual void handleMessage(Message *msg) = 0;
-
-private:
- Mutex message_mutex;
- std::list<Message *> message_queue;
-};
-
-#endif/*__DRUMGIZMO_MESSAGERECEIVER_H__*/
diff --git a/src/midimapparser.cc b/src/midimapparser.cc
index ec4c10d..cc97280 100644
--- a/src/midimapparser.cc
+++ b/src/midimapparser.cc
@@ -30,7 +30,8 @@ void MidiMapParser::startTag(const std::string& name, const attr_t& attr)
{
if(name == "map")
{
- if(attr.find("note") != attr.end() && attr.find("instr") != attr.end())
+ if((attr.find("note") != attr.end()) &&
+ (attr.find("instr") != attr.end()))
{
midimap[std::stoi(attr.at("note"))] = attr.at("instr");
}
diff --git a/src/midimapparser.h b/src/midimapparser.h
index 740cb60..8ec76c0 100644
--- a/src/midimapparser.h
+++ b/src/midimapparser.h
@@ -26,8 +26,6 @@
*/
#pragma once
-#include <stdio.h>
-
#include "saxparser.h"
#include "midimapper.h"
diff --git a/plugingui/notifier.h b/src/notifier.h
index 9e9f6eb..ff59741 100644
--- a/plugingui/notifier.h
+++ b/src/notifier.h
@@ -72,7 +72,7 @@ namespace aux
};
-namespace GUI {
+//namespace GUI {
class Listener;
class NotifierBase {
@@ -158,6 +158,6 @@ private:
};
-} // GUI::
+//} // GUI::
#define CONNECT(SRC, SIG, TAR, SLO) (SRC)->SIG.connect(TAR, SLO)
diff --git a/src/path.cc b/src/path.cc
index 43c64f0..c2e7910 100644
--- a/src/path.cc
+++ b/src/path.cc
@@ -35,17 +35,19 @@
std::string getPath(const std::string& file)
{
- std::string p;
-#ifndef __MINGW32__
- char *b = strdup(file.c_str());
- p = dirname(b);
- free(b);
-#else
+ std::string path;
+
+#ifdef __MINGW32__
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
_splitpath(file.c_str(), drive, dir, NULL, NULL);
- p = std::string(drive) + dir;
+ path = std::string(drive) + dir;
+#else
+ // POSIX
+ char* buffer = strdup(file.c_str());
+ path = dirname(buffer);
+ free(buffer);
#endif
- return p;
+ return path;
}
diff --git a/src/path.h b/src/path.h
index 7189cea..50ff842 100644
--- a/src/path.h
+++ b/src/path.h
@@ -28,4 +28,5 @@
#include <string>
+//! \returns path component of full filename with path.
std::string getPath(const std::string& file);
diff --git a/src/sample.cc b/src/sample.cc
index 66fe3c5..ced8a47 100644
--- a/src/sample.cc
+++ b/src/sample.cc
@@ -65,24 +65,3 @@ AudioFile* Sample::getAudioFile(Channel* c)
return nullptr;
}
-
-#ifdef TEST_SAMPLE
-// deps: channel.cc audiofile.cc
-// cflags: $(SNDFILE_CFLAGS)
-// libs: $(SNDFILE_LIBS)
-#include "test.h"
-
-TEST_BEGIN;
-
-Sample s;
-InstrumentChannel c;
-InstrumentChannel c2;
-AudioFile a("test");
-
-s.addAudioFile(&c, &a);
-TEST_EQUAL(s.getAudioFile(&c), &a, "?");
-TEST_EQUAL(s.getAudioFile(&c2), nullptr, "?");
-
-TEST_END;
-
-#endif /*TEST_SAMPLE*/
diff --git a/src/sample.h b/src/sample.h
index 5b4f3b5..f00db13 100644
--- a/src/sample.h
+++ b/src/sample.h
@@ -32,34 +32,22 @@
#include "channel.h"
#include "audiofile.h"
-typedef std::map<Channel*, AudioFile*> AudioFiles;
+using AudioFiles = std::map<Channel*, AudioFile*>;
-class InstrumentParser;
-class Sample
-{
+class Sample {
friend class InstrumentParser;
friend class PowerList;
-
public:
Sample(const std::string& name, float power);
~Sample();
- AudioFile* getAudioFile(InstrumentChannel* c);
+ AudioFile* getAudioFile(InstrumentChannel *instrument_channel);
private:
- void addAudioFile(InstrumentChannel* c, AudioFile* a);
+ void addAudioFile(InstrumentChannel* instrument_channel,
+ AudioFile* audio_file);
std::string name;
float power;
AudioFiles audiofiles;
};
-
-/*
- * <sample name="kick-r-1">
- * <audiofile channel="Alesis-3" file="samples/1-kick-r-Alesis-3.wav"/>
- * <audiofile channel="Amb L-3" file="samples/1-kick-r-Amb L-3.wav"/>
- * <audiofile channel="Amb R-3" file="samples/1-kick-r-Amb R-3.wav"/>
- * <audiofile channel="Kick L-3" file="samples/1-kick-r-Kick L-3.wav"/>
- * <audiofile channel="Kick R-3" file="samples/1-kick-r-Kick R-3.wav"/>
- * </sample>
- */
diff --git a/src/saxparser.cc b/src/saxparser.cc
index e32143d..280e608 100644
--- a/src/saxparser.cc
+++ b/src/saxparser.cc
@@ -26,29 +26,30 @@
*/
#include "saxparser.h"
-#include <string.h>
-#include <hugin.hpp>
#include <sstream>
#include <iostream>
+#include <hugin.hpp>
+
SAXParser::SAXParser()
{
- p = XML_ParserCreate(nullptr);
- if(!p) {
+ parser = XML_ParserCreate(nullptr);
+ if(!parser)
+ {
ERR(sax, "Couldn't allocate memory for parser\n");
// throw Exception(...); TODO
return;
}
- XML_SetUserData(p, this);
- XML_UseParserAsHandlerArg(p);
- XML_SetElementHandler(p, start_hndl, end_hndl);
- XML_SetCharacterDataHandler(p, character_hndl);
+ XML_SetUserData(parser, this);
+ XML_UseParserAsHandlerArg(parser);
+ XML_SetElementHandler(parser, SAXParser::startHandler, SAXParser::endHandler);
+ XML_SetCharacterDataHandler(parser, SAXParser::characterHandler);
}
SAXParser::~SAXParser()
{
- XML_ParserFree(p);
+ XML_ParserFree(parser);
}
int SAXParser::parseFile(const std::string& filename)
@@ -60,7 +61,8 @@ int SAXParser::parseFile(const std::string& filename)
std::ifstream file(filename, std::ifstream::in);
- if(!file.is_open()) {
+ if(!file.is_open())
+ {
return 1;
}
@@ -68,59 +70,63 @@ int SAXParser::parseFile(const std::string& filename)
ss << file.rdbuf();
std::string str = ss.str();
- parseString(str, filename);
-
- return 0;
+ return parseString(str, filename);
}
-int SAXParser::parseString(const std::string& str, const std::string& xml_source_name)
+int SAXParser::parseString(const std::string& str,
+ const std::string& xml_source_name)
{
DEBUG(sax, "parse(buffer %d bytes)\n", (int)str.length());
- if(!XML_Parse(p, str.c_str(), str.length(), true)) {
- parseError(str, XML_ErrorString(XML_GetErrorCode(p)),
- xml_source_name, (int)XML_GetCurrentLineNumber(p));
+ if(!XML_Parse(parser, str.c_str(), str.length(), true))
+ {
+ parseError(str, XML_ErrorString(XML_GetErrorCode(parser)),
+ xml_source_name, (int)XML_GetCurrentLineNumber(parser));
return 1;
}
return 0;
}
-void SAXParser::parseError(const std::string& buf, const std::string& error, const std::string& xml_source_name, std::size_t lineno)
+void SAXParser::parseError(const std::string& buf, const std::string& error,
+ const std::string& xml_source_name,
+ std::size_t lineno)
{
- std::cerr << "SAXParser error trying to parse from source: " << xml_source_name << "\n";
+ std::cerr << "SAXParser error trying to parse from source: " <<
+ xml_source_name << "\n";
std::cerr << "At line " << lineno << ": " << error << "\n";
std::cerr << "Buffer " << buf.size() << " bytes: \n[\n";
std::cerr << buf;
std::cerr << "\n]" << std::endl;
}
-void SAXParser::character_hndl(void* p, const XML_Char* s, int len)
+void SAXParser::characterHandler(void* parser, const XML_Char* cData, int len)
{
- SAXParser* parser = (SAXParser*)XML_GetUserData(p);
- std::string chars(s, len);
- parser->characterData(chars);
+ SAXParser* sax_parser = (SAXParser*)XML_GetUserData(parser);
+ std::string chars(cData, len);
+ sax_parser->characterData(chars);
}
-void SAXParser::start_hndl(void* p, const char* el, const char** attr)
+void SAXParser::startHandler(void* parser, const char* el, const char** attr)
{
- SAXParser* parser = (SAXParser*)XML_GetUserData(p);
+ SAXParser* sax_parser = (SAXParser*)XML_GetUserData(parser);
// Convert to comfy C++ values...
attr_t attributes;
- while(*attr) {
+ while(*attr)
+ {
std::string at_name = *attr++;
std::string at_value = *attr++;
attributes.emplace(at_name, at_value);
}
- parser->startTag(std::string(el), attributes);
+ sax_parser->startTag(std::string(el), attributes);
}
-void SAXParser::end_hndl(void* p, const char* el)
+void SAXParser::endHandler(void* parser, const char* el)
{
- SAXParser* parser = (SAXParser*)XML_GetUserData(p);
- parser->endTag(std::string(el));
+ SAXParser* sax_parser = (SAXParser*)XML_GetUserData(parser);
+ sax_parser->endTag(std::string(el));
}
diff --git a/src/saxparser.h b/src/saxparser.h
index 92197d1..4b1a273 100644
--- a/src/saxparser.h
+++ b/src/saxparser.h
@@ -31,7 +31,8 @@
#include <expat.h>
#include <fstream>
-class SAXParser {
+class SAXParser
+{
public:
SAXParser();
virtual ~SAXParser();
@@ -40,7 +41,8 @@ public:
virtual int parseFile(const std::string& filename);
//! Parses all the data in the buffer.
- virtual int parseString(const std::string& str, const std::string& xml_source_name = "");
+ virtual int parseString(const std::string& str,
+ const std::string& xml_source_name = "");
protected:
using attr_t = std::unordered_map<std::string, std::string>;
@@ -48,13 +50,16 @@ protected:
virtual void characterData(const std::string& data) {}
virtual void startTag(const std::string& name, const attr_t& attr) {}
virtual void endTag(const std::string& name) {}
- virtual void parseError(const std::string& buf, const std::string& error, const std::string& xml_source_name, std::size_t lineno);
+ virtual void parseError(const std::string& buf,
+ const std::string& error,
+ const std::string& xml_source_name,
+ std::size_t lineno);
private:
- XML_Parser p;
+ XML_Parser parser;
std::string filename;
- static void character_hndl(void* p, const XML_Char* s, int len);
- static void start_hndl(void* p, const char* el, const char** attr);
- static void end_hndl(void* p, const char* el);
+ static void characterHandler(void* parser, const XML_Char* cData, int len);
+ static void startHandler(void* parser, const char* el, const char** attr);
+ static void endHandler(void* parser, const char* el);
};
diff --git a/src/semaphore.cc b/src/semaphore.cc
index cd29bbf..6172251 100644
--- a/src/semaphore.cc
+++ b/src/semaphore.cc
@@ -27,87 +27,101 @@
#include "semaphore.h"
#include <hugin.hpp>
-
#include <limits>
+#include <assert.h>
#ifdef WIN32
#include <windows.h>
#else
-// Make sure we don't include /this/ file...
+// Make sure we don't include /this/ files header...
#include <../include/semaphore.h>
+#include <errno.h>
+#include <stdio.h>
#endif
struct semaphore_private_t {
#ifdef WIN32
- HANDLE semaphore;
+ HANDLE semaphore;
#else
- sem_t semaphore;
+ sem_t semaphore;
#endif
};
-Semaphore::Semaphore(const char *name)
+Semaphore::Semaphore(std::size_t initial_count)
{
- this->name = name;
- // DEBUG(semaphore, "Create [%s]\n", name);
-
- prv = new struct semaphore_private_t();
+ prv = new struct semaphore_private_t();
#ifdef WIN32
- prv->semaphore = CreateSemaphore(NULL, // default security attributes
- 0, // initial count
- std::numeric_limits<LONG>::max(),
- NULL); // unnamed semaphore
+ prv->semaphore = CreateSemaphore(nullptr, // default security attributes
+ initial_count,
+ std::numeric_limits<LONG>::max(),
+ nullptr); // unnamed semaphore
#else
- sem_init(&prv->semaphore, 0, 0);
+ const int pshared = 0;
+ sem_init(&prv->semaphore, pshared, initial_count);
#endif
}
Semaphore::~Semaphore()
{
- // DEBUG(semaphore, "Delete [%s]\n", name);
-
#ifdef WIN32
- CloseHandle(prv->semaphore);
+ CloseHandle(prv->semaphore);
#else
- sem_destroy(&prv->semaphore);
+ sem_destroy(&prv->semaphore);
#endif
- delete prv;
+ delete prv;
}
void Semaphore::post()
{
- // DEBUG(semaphore, "Post [%s]\n", name);
+#ifdef WIN32
+ ReleaseSemaphore(prv->semaphore, 1, NULL);
+#else
+ sem_post(&prv->semaphore);
+#endif
+}
+bool Semaphore::wait(const std::chrono::milliseconds& timeout)
+{
#ifdef WIN32
- ReleaseSemaphore(prv->semaphore, 1, NULL);
+ DWORD ret = WaitForSingleObject(prv->semaphore, timeout.count());
+ if(ret == WAIT_TIMEOUT)
+ {
+ return false;
+ }
+
+ assert(ret == WAIT_OBJECT_0);
#else
- sem_post(&prv->semaphore);
+ struct timespec t = {
+ // Whole seconds:
+ (time_t)(timeout.count() / 1000),
+
+ // Remainder as nanoseconds:
+ (long)((timeout.count() - ((timeout.count() / 1000) * 1000)) * 1000000)
+ };
+
+ int ret = sem_timedwait(&prv->semaphore, &t);
+ if(ret < 0)
+ {
+ if(errno == ETIMEDOUT)
+ {
+ return false;
+ }
+
+ perror("sem_timedwait()");
+ assert(false);
+ }
#endif
+
+ return true;
}
void Semaphore::wait()
{
- // DEBUG(semaphore, "Wait [%s]\n", name);
-
#ifdef WIN32
- WaitForSingleObject(prv->semaphore, INFINITE);
+ WaitForSingleObject(prv->semaphore, INFINITE);
#else
- sem_wait(&prv->semaphore);
+ sem_wait(&prv->semaphore);
#endif
}
-
-#ifdef TEST_SEMAPHORE
-//deps:
-//cflags: -I.. $(PTHREAD_CFLAGS)
-//libs: $(PTHREAD_LIBS)
-#include <test.h>
-
-TEST_BEGIN;
-
-// TODO: Put some testcode here (see test.h for usable macros).
-TEST_TRUE(false, "No tests yet!");
-
-TEST_END;
-
-#endif/*TEST_SEMAPHORE*/
diff --git a/src/semaphore.h b/src/semaphore.h
index 4464898..d5995cb 100644
--- a/src/semaphore.h
+++ b/src/semaphore.h
@@ -24,22 +24,26 @@
* along with DrumGizmo; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-#ifndef __PRACRO_SEMAPHORE_H__
-#define __PRACRO_SEMAPHORE_H__
+#pragma once
+
+#include <chrono>
struct semaphore_private_t;
-class Semaphore {
+class Semaphore
+{
public:
- Semaphore(const char *name = "");
- ~Semaphore();
+ Semaphore(std::size_t initial_count = 0);
+ ~Semaphore();
+
+ void post();
- void post();
- void wait();
+ //! Lock semaphore with timeout.
+ //! \returns true if the semaphore was locked, false on timeout.
+ bool wait(const std::chrono::milliseconds& timeout);
+
+ void wait();
private:
struct semaphore_private_t *prv{nullptr};
- const char *name{nullptr};
};
-
-#endif/*__PRACRO_SEMAPHORE_H__*/
diff --git a/src/settings.h b/src/settings.h
index 74c432d..6b4e882 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -27,52 +27,54 @@
#pragma once
#include <atomic>
+#include <string>
#include <cassert>
-template <typename T> class SettingRef
-{
-public:
- SettingRef(std::atomic<T>& value)
- : value{value}
- , cache{}
- {
- // string isn't lock free either
- assert((std::is_same<T, std::string>::value || value.is_lock_free()));
- }
-
- bool hasChanged()
- {
- T tmp = cache;
- cache.exchange(value);
- return tmp == cache;
- }
+#include "atomic.h"
+#include "notifier.h"
- T getValue() const
- {
- return cache;
- }
-
-private:
- std::atomic<T>& value;
- std::atomic<T> cache;
+enum class LoadStatus : unsigned int
+{
+ Idle,
+ Loading,
+ Done,
+ Error
};
+//! Engine settings
struct Settings
{
- std::atomic<bool> enable_velocity_modifier;
- std::atomic<float> velocity_modifier_falloff;
- std::atomic<float> velocity_modifier_weight;
+ Atomic<std::string> drumkit_file;
+ Atomic<LoadStatus> drumkit_load_status{LoadStatus::Idle};
+
+ Atomic<std::string> midimap_file;
+ Atomic<LoadStatus> midimap_load_status{LoadStatus::Idle};
+
+ Atomic<bool> enable_velocity_modifier{true};
+ Atomic<float> velocity_modifier_falloff{0.5f};
+ Atomic<float> velocity_modifier_weight{0.25f};
- std::atomic<bool> enable_velocity_randomiser;
- std::atomic<float> velocity_randomiser_weight;
+ Atomic<bool> enable_velocity_randomiser{false};
+ Atomic<float> velocity_randomiser_weight{0.1f};
- std::atomic<int> samplerate;
+ Atomic<double> samplerate{44100.0};
- std::atomic<bool> enable_resampling;
+ Atomic<bool> enable_resampling{true};
+
+ Atomic<std::size_t> number_of_files;
+ Atomic<std::size_t> number_of_files_loaded;
+ Atomic<std::string> current_file;
};
+//! Settings getter class.
struct SettingsGetter
{
+ SettingRef<std::string> drumkit_file;
+ SettingRef<LoadStatus> drumkit_load_status;
+
+ SettingRef<std::string> midimap_file;
+ SettingRef<LoadStatus> midimap_load_status;
+
SettingRef<bool> enable_velocity_modifier;
SettingRef<float> velocity_modifier_falloff;
SettingRef<float> velocity_modifier_weight;
@@ -80,48 +82,125 @@ struct SettingsGetter
SettingRef<bool> enable_velocity_randomiser;
SettingRef<float> velocity_randomiser_weight;
- SettingRef<int> samplerate;
+ SettingRef<double> samplerate;
SettingRef<bool> enable_resampling;
+ SettingRef<std::size_t> number_of_files;
+ SettingRef<std::size_t> number_of_files_loaded;
+ SettingRef<std::string> current_file;
+
SettingsGetter(Settings& settings)
- : enable_velocity_modifier{settings.enable_velocity_modifier}
+ : drumkit_file(settings.drumkit_file)
+ , drumkit_load_status(settings.drumkit_load_status)
+ , midimap_file(settings.midimap_file)
+ , midimap_load_status(settings.midimap_load_status)
+ , enable_velocity_modifier{settings.enable_velocity_modifier}
, velocity_modifier_falloff{settings.velocity_modifier_falloff}
, velocity_modifier_weight{settings.velocity_modifier_weight}
, enable_velocity_randomiser{settings.enable_velocity_randomiser}
, velocity_randomiser_weight{settings.velocity_randomiser_weight}
, samplerate{settings.samplerate}
, enable_resampling{settings.enable_resampling}
+ , number_of_files{settings.number_of_files}
+ , number_of_files_loaded{settings.number_of_files_loaded}
+ , current_file{settings.current_file}
{
}
};
+//! Settings change notifier class.
+class SettingsNotifier
+{
+public:
+ Notifier<std::string> drumkit_file;
+ Notifier<LoadStatus> drumkit_load_status;
+
+ Notifier<std::string> midimap_file;
+ Notifier<LoadStatus> midimap_load_status;
+
+ Notifier<bool> enable_velocity_modifier;
+ Notifier<float> velocity_modifier_falloff;
+ Notifier<float> velocity_modifier_weight;
+
+ Notifier<bool> enable_velocity_randomiser;
+ Notifier<float> velocity_randomiser_weight;
+
+ Notifier<double> samplerate;
+
+ Notifier<bool> enable_resampling;
+
+ Notifier<std::size_t> number_of_files;
+ Notifier<std::size_t> number_of_files_loaded;
+ Notifier<std::string> current_file;
+
+ void evaluate()
+ {
+#define EVAL(x) if(settings.x.hasChanged()) { x(settings.x.getValue()); }
+
+ EVAL(drumkit_file);
+ EVAL(drumkit_load_status);
+
+ EVAL(midimap_file);
+ EVAL(midimap_load_status);
+
+ EVAL(enable_velocity_modifier);
+ EVAL(velocity_modifier_falloff);
+ EVAL(velocity_modifier_weight);
+
+ EVAL(enable_velocity_randomiser);
+ EVAL(velocity_randomiser_weight);
+
+ EVAL(samplerate);
+
+ EVAL(enable_resampling);
+
+ EVAL(number_of_files);
+ EVAL(number_of_files_loaded);
+ EVAL(current_file);
+ }
+
+ SettingsNotifier(Settings& settings)
+ : settings(settings)
+ {
+ }
+
+private:
+ SettingsGetter settings;
+};
+
// lovely reminder: NO, GLOCKE. NOOOO!!
/*
enum class IntParams {
- Foo = 0
+ Foo = 0
};
-struct Settings {
- std::array<std::atomic<int>, 5> ints;
+struct Settings
+{
+ std::array<std::atomic<int>, 5> ints;
- Settings()
- : ints{} {
- //get(IntParams::Foo).store(3);
- }
+ Settings()
+ : ints{}
+ {
+ //get(IntParams::Foo).store(3);
+ }
- std::atomic<int>& get(IntParams param) {
- return ints[(size_t)param];
- }
+ std::atomic<int>& get(IntParams param)
+ {
+ return ints[(size_t)param];
+ }
};
-struct SettingsGetter {
- std::vector<SettingRef<int>> ints;
+struct SettingsGetter
+{
+ std::vector<SettingRef<int>> ints;
- SettingsGetter(Settings& parent) {
- for (auto& atomic: parent.ints) {
- ints.emplace_back(atomic);
- }
- }
+ SettingsGetter(Settings& parent)
+ {
+ for(auto& atomic: parent.ints)
+ {
+ ints.emplace_back(atomic);
+ }
+ }
};
*/
diff --git a/src/syncedsettings.h b/src/syncedsettings.h
new file mode 100644
index 0000000..0fe5efd
--- /dev/null
+++ b/src/syncedsettings.h
@@ -0,0 +1,106 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * syncedsettings.h
+ *
+ * Thu Mar 31 09:23:27 CEST 2016
+ * Copyright 2016 Christian Glöckner
+ * cgloeckner@freenet.de
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * DrumGizmo 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#pragma once
+
+#include <mutex>
+
+template <typename T> class Group;
+
+template <typename T> class Accessor
+{
+private:
+ std::lock_guard<std::mutex> lock;
+
+public:
+ Accessor(Group<T>& parent)
+ : lock{parent.mutex}
+ , data(parent.data)
+ {
+ }
+
+ T& data;
+};
+
+template <typename T> class Group
+{
+private:
+ friend class Accessor<T>;
+
+ mutable std::mutex mutex;
+ T data;
+
+public:
+ Group()
+ : mutex{}
+ , data{}
+ {
+ }
+
+ Group(Group<T> const& other)
+ : mutex{}
+ , data{}
+ {
+ std::lock_guard<std::mutex> lock{other.mutex};
+ data = other.data;
+ }
+
+ Group(Group<T>&& other)
+ : mutex{}
+ , data{}
+ {
+ std::lock_guard<std::mutex> lock{other.mutex};
+ std::swap(data, other.data);
+ }
+
+ Group<T>& operator=(const Group<T>& other)
+ {
+ if (*this != &other)
+ {
+ std::lock_guard<std::mutex> lock{mutex};
+ std::lock_guard<std::mutex> lock2{other.mutex};
+ data = other.data;
+ }
+ return *this;
+ }
+
+ Group<T>& operator=(Group<T>&& other)
+ {
+ if (*this != &other)
+ {
+ std::lock_guard<std::mutex> lock{mutex};
+ std::lock_guard<std::mutex> lock2{other.mutex};
+ std::swap(data, other.data);
+ }
+ return *this;
+ }
+
+ operator T() const
+ {
+ std::lock_guard<std::mutex> lock{mutex};
+ return data;
+ }
+};
diff --git a/test/Makefile.am b/test/Makefile.am
index ccb21e6..3633ad8 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -3,7 +3,7 @@ include $(top_srcdir)/src/Makefile.am.drumgizmo
TESTS = resource engine gui resampler lv2 configfile audiocache \
audiocachefile audiocacheidmanager audiocacheeventhandler \
- memchecker random
+ memchecker random atomictest syncedsettingstest
check_PROGRAMS = $(TESTS)
@@ -29,7 +29,6 @@ audiocache_SOURCES = \
$(top_srcdir)/src/thread.cc \
$(top_srcdir)/src/mutex.cc \
$(top_srcdir)/src/semaphore.cc \
- $(top_srcdir)/src/configuration.cc \
$(top_srcdir)/src/audiofile.cc \
test.cc \
audiocachetest.cc
@@ -43,7 +42,6 @@ audiocachefile_SOURCES = \
$(top_srcdir)/src/thread.cc \
$(top_srcdir)/src/mutex.cc \
$(top_srcdir)/src/semaphore.cc \
- $(top_srcdir)/src/configuration.cc \
$(top_srcdir)/src/audiofile.cc \
test.cc \
audiocachefiletest.cc
@@ -138,5 +136,15 @@ random_SOURCES = \
test.cc \
randomtest.cc
+atomictest_CXXFLAGS = -DOUTPUT=\"atomictest\" $(CPPUNIT_CFLAGS) \
+ -I$(top_srcdir)/src -I$(top_srcdir)/hugin
+atomictest_LDFLAGS = $(CPPUNIT_LIBS)
+atomictest_SOURCES = atomictest.cc test.cc
+
+syncedsettingstest_CXXFLAGS = -DOUTPUT=\"syncedsettingstest\" $(CPPUNIT_CFLAGS) \
+ -I$(top_srcdir)/src -I$(top_srcdir)/hugin
+syncedsettingstest_LDFLAGS = $(CPPUNIT_LIBS)
+syncedsettingstest_SOURCES = syncedsettings.cc test.cc
+
EXTRA_DIST = \
lv2_test_host.h
diff --git a/test/atomictest.cc b/test/atomictest.cc
new file mode 100644
index 0000000..1718b33
--- /dev/null
+++ b/test/atomictest.cc
@@ -0,0 +1,135 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * atomic.cc
+ *
+ * Wed Mar 23 09:17:12 CET 2016
+ * Copyright 2016 Christian Glöckner
+ * cgloeckner@freenet.de
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <atomic.h>
+
+class AtomicTest
+ : public CppUnit::TestFixture {
+
+ CPPUNIT_TEST_SUITE(AtomicTest);
+ CPPUNIT_TEST(podAtomicsUseStandardImpl);
+ CPPUNIT_TEST(nonPodAtomicsUseOwnImpl);
+ CPPUNIT_TEST(podAtomicCanBeDefaultInitialized);
+ CPPUNIT_TEST(nonPodAtomicCanBeDefaultInitialized);
+ CPPUNIT_TEST(podAtomicCanBeValueInitialized);
+ CPPUNIT_TEST(nonPodAtomicCanBeValueInitialized);
+ CPPUNIT_TEST(podAtomicCanBeValueAssigned);
+ CPPUNIT_TEST(nonPodAtomicCanBeValueAssigned);
+ CPPUNIT_TEST(podAtomicsAreLockFree);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ void setUp() {}
+ void tearDown() {}
+
+ void podAtomicsUseStandardImpl() {
+ CPPUNIT_ASSERT(isUsingStandardImpl<bool>());
+ CPPUNIT_ASSERT(isUsingStandardImpl<unsigned short int>());
+ CPPUNIT_ASSERT(isUsingStandardImpl<short int>());
+ CPPUNIT_ASSERT(isUsingStandardImpl<unsigned int>());
+ CPPUNIT_ASSERT(isUsingStandardImpl<int>());
+ CPPUNIT_ASSERT(isUsingStandardImpl<unsigned long int>());
+ CPPUNIT_ASSERT(isUsingStandardImpl<long int>());
+ CPPUNIT_ASSERT(isUsingStandardImpl<unsigned long long int>());
+ CPPUNIT_ASSERT(isUsingStandardImpl<long long int>());
+ CPPUNIT_ASSERT(isUsingStandardImpl<float>());
+ CPPUNIT_ASSERT(isUsingStandardImpl<double>());
+ CPPUNIT_ASSERT(isUsingStandardImpl<long double>());
+ }
+
+ void nonPodAtomicsUseOwnImpl() {
+ CPPUNIT_ASSERT(!isUsingStandardImpl<std::string>());
+ }
+
+ void podAtomicCanBeDefaultInitialized() {
+ Atomic<int> i;
+ // note: i is initialized with garbage
+ }
+
+ void nonPodAtomicCanBeDefaultInitialized() {
+ Atomic<std::string> s;
+ CPPUNIT_ASSERT_EQUAL(s.load(), std::string{});
+ }
+
+ void podAtomicCanBeValueInitialized() {
+ Atomic<int> i{5};
+ CPPUNIT_ASSERT_EQUAL(i.load(), 5);
+ }
+
+ void nonPodAtomicCanBeValueInitialized() {
+ Atomic<std::string> s{"hello world"};
+ CPPUNIT_ASSERT_EQUAL(s.load(), std::string{"hello world"});
+ }
+
+ void podAtomicCanBeValueAssigned() {
+ Atomic<int> i;
+ i = 5;
+ CPPUNIT_ASSERT_EQUAL(i.load(), 5);
+ }
+
+ void nonPodAtomicCanBeValueAssigned() {
+ Atomic<std::string> s;
+ s = "hello world";
+ CPPUNIT_ASSERT_EQUAL(s.load(), std::string{"hello world"});
+ }
+
+ void podAtomicsAreLockFree() {
+ CPPUNIT_ASSERT(isLockFree<bool>());
+ CPPUNIT_ASSERT(isLockFree<unsigned short int>());
+ CPPUNIT_ASSERT(isLockFree<short int>());
+ CPPUNIT_ASSERT(isLockFree<unsigned int>());
+ CPPUNIT_ASSERT(isLockFree<int>());
+ CPPUNIT_ASSERT(isLockFree<unsigned long int>());
+ CPPUNIT_ASSERT(isLockFree<long int>());
+ CPPUNIT_ASSERT(isLockFree<unsigned long long int>());
+ CPPUNIT_ASSERT(isLockFree<long long int>());
+ CPPUNIT_ASSERT(isLockFree<float>());
+ CPPUNIT_ASSERT(isLockFree<double>());
+
+ // compile error: undefined reference to `__atomic_is_lock_free'
+ //CPPUNIT_ASSERT(isLockFree<long double>());
+ }
+
+ // todo: further testing
+
+ private:
+ template <typename T>
+ bool isUsingStandardImpl() {
+ return std::is_base_of<std::atomic<T>, Atomic<T>>::value;
+ }
+
+ template <typename T>
+ bool isLockFree() {
+ Atomic<T> a;
+ return a.is_lock_free();
+ }
+};
+
+// Registers the fixture into the 'registry'
+CPPUNIT_TEST_SUITE_REGISTRATION(AtomicTest);
+
diff --git a/test/engine.cc b/test/engine.cc
index 86f4f4d..89c0158 100644
--- a/test/engine.cc
+++ b/test/engine.cc
@@ -40,9 +40,10 @@ public:
void tearDown() {}
void loading() {
+ Settings settings;
AudioOutputEngine *oe = NULL;
AudioInputEngine *ie = NULL;
- DrumGizmo dg(oe, ie);
+ DrumGizmo dg(settings, oe, ie);
dg.setFrameSize(100);
// Switch kits emmidiately with giving the loader time to work:
diff --git a/test/memcheckertest.cc b/test/memcheckertest.cc
index 90bd254..e312ca7 100644
--- a/test/memcheckertest.cc
+++ b/test/memcheckertest.cc
@@ -52,6 +52,7 @@ class MemCheckerTest
CPPUNIT_TEST(check_free_ram);
CPPUNIT_TEST_SUITE_END();
private:
+ Settings settings;
DrumKit kit;
const std::string small_kit_path = "kit/small_kit.xml";
@@ -70,7 +71,7 @@ public:
void small_drumkit()
{
// load the small kit
- DrumKitParser parser(kit);
+ DrumKitParser parser(settings, kit);
CPPUNIT_ASSERT(!parser.parseFile(small_kit_path));
// check if the memchecker thinks it fits into memory
@@ -80,7 +81,7 @@ public:
void huge_drumkit()
{
// load the huge kit
- DrumKitParser parser(kit);
+ DrumKitParser parser(settings, kit);
CPPUNIT_ASSERT(!parser.parseFile(huge_kit_path));
// check if the memchecker thinks it doesn't fit into memory
@@ -94,7 +95,7 @@ public:
CPPUNIT_ASSERT_EQUAL(bytes_per_channel, calcBytesPerChannel(audiofile));
// load the huge kit
- DrumKitParser parser(kit);
+ DrumKitParser parser(settings, kit);
CPPUNIT_ASSERT(!parser.parseFile(huge_kit_path));
// check if the protected method of the memchecker reports the correct size
diff --git a/test/syncedsettings.cc b/test/syncedsettings.cc
new file mode 100644
index 0000000..62bd8c6
--- /dev/null
+++ b/test/syncedsettings.cc
@@ -0,0 +1,203 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * syncedsettings.cc
+ *
+ * Wed Mar 31 09:32:12 CET 2016
+ * Copyright 2016 Christian Glöckner
+ * cgloeckner@freenet.de
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <syncedsettings.h>
+
+class SyncedSettingsTest
+ : public CppUnit::TestFixture {
+
+ CPPUNIT_TEST_SUITE(SyncedSettingsTest);
+ CPPUNIT_TEST(groupCanBeDefaultInitialized);
+ CPPUNIT_TEST(groupDataCanBeCopied);
+
+ CPPUNIT_TEST(accessorCanGetFields);
+ CPPUNIT_TEST(accessorCanSetFields);
+
+ CPPUNIT_TEST(groupHasCopyCtor);
+ CPPUNIT_TEST(groupHasMoveCtor);
+ CPPUNIT_TEST(groupHasCopyAssignOp);
+ CPPUNIT_TEST(groupHasMoveAssignOp);
+
+ CPPUNIT_TEST(mimicRealUse);
+ CPPUNIT_TEST_SUITE_END();
+
+ private:
+ struct TestData {
+ float foo;
+ bool bar;
+ std::string msg;
+ };
+
+ public:
+ void setUp() {}
+ void tearDown() {}
+
+ void groupCanBeDefaultInitialized() {
+ Group<TestData> data;
+ }
+
+ void groupDataCanBeCopied() {
+ Group<TestData> data;
+ (TestData)data; // copies
+ }
+
+ void accessorCanSetFields() {
+ Group<TestData> data;
+ {
+ Accessor<TestData> a{data};
+ a.data.foo = 3.f;
+ a.data.bar = false;
+ a.data.msg = "hello";
+ }
+ TestData copy = data;
+ CPPUNIT_ASSERT_EQUAL(copy.foo, 3.f);
+ CPPUNIT_ASSERT_EQUAL(copy.bar, false);
+ CPPUNIT_ASSERT_EQUAL(copy.msg, std::string{"hello"});
+ }
+
+ void accessorCanGetFields() {
+ Group<TestData> data;
+ {
+ Accessor<TestData> a{data};
+ a.data.foo = 3.f;
+ a.data.bar = false;
+ a.data.msg = "hello";
+ }
+ // now read
+ {
+ Accessor<TestData> a{data};
+ CPPUNIT_ASSERT_EQUAL(a.data.foo, 3.f);
+ CPPUNIT_ASSERT_EQUAL(a.data.bar, false);
+ CPPUNIT_ASSERT_EQUAL(a.data.msg, std::string{"hello"});
+ }
+ }
+
+ void groupHasCopyCtor() {
+ Group<TestData> tmp;
+ {
+ Accessor<TestData> a{tmp};
+ a.data.foo = 3.f;
+ a.data.bar = false;
+ a.data.msg = "hello";
+ }
+ Group<TestData> data{tmp};
+ TestData copy = data;
+ CPPUNIT_ASSERT_EQUAL(copy.foo, 3.f);
+ CPPUNIT_ASSERT_EQUAL(copy.bar, false);
+ CPPUNIT_ASSERT_EQUAL(copy.msg, std::string{"hello"});
+ }
+
+ void groupHasMoveCtor() {
+ Group<TestData> tmp;
+ {
+ Accessor<TestData> a{tmp};
+ a.data.foo = 3.f;
+ a.data.bar = false;
+ a.data.msg = "hello";
+ }
+ Group<TestData> data{std::move(tmp)};
+ TestData copy = data;
+ CPPUNIT_ASSERT_EQUAL(copy.foo, 3.f);
+ CPPUNIT_ASSERT_EQUAL(copy.bar, false);
+ CPPUNIT_ASSERT_EQUAL(copy.msg, std::string{"hello"});
+ }
+
+ void groupHasCopyAssignOp() {
+ Group<TestData> tmp;
+ {
+ Accessor<TestData> a{tmp};
+ a.data.foo = 3.f;
+ a.data.bar = false;
+ a.data.msg = "hello";
+ }
+ Group<TestData> data = tmp;
+ TestData copy = data;
+ CPPUNIT_ASSERT_EQUAL(copy.foo, 3.f);
+ CPPUNIT_ASSERT_EQUAL(copy.bar, false);
+ CPPUNIT_ASSERT_EQUAL(copy.msg, std::string{"hello"});
+ }
+
+ void groupHasMoveAssignOp() {
+ Group<TestData> tmp;
+ {
+ Accessor<TestData> a{tmp};
+ a.data.foo = 3.f;
+ a.data.bar = false;
+ a.data.msg = "hello";
+ }
+ Group<TestData> data = std::move(tmp);
+ TestData copy = data;
+ CPPUNIT_ASSERT_EQUAL(copy.foo, 3.f);
+ CPPUNIT_ASSERT_EQUAL(copy.bar, false);
+ CPPUNIT_ASSERT_EQUAL(copy.msg, std::string{"hello"});
+ }
+
+ void mimicRealUse() {
+ struct Settings {
+ struct Foo {
+ float a{5};
+ float b{3};
+ bool enabled{true};
+ };
+ struct Bar {
+ std::string label{"empty"};
+ float bla{0.f};
+ };
+
+ Group<Foo> foo;
+ Group<Bar> bar;
+ };
+
+ Settings s;
+
+ // set bar settings
+ {
+ Accessor<Settings::Bar> tmp{s.bar};
+ tmp.data.label = "hello world";
+ tmp.data.bla = 3.14f;
+ }
+
+ // read foo settings
+ {
+ Accessor<Settings::Foo> tmp{s.foo};
+ if (tmp.data.enabled) {
+ // do some while locked
+ }
+ }
+ // or:
+ Settings::Foo copy = s.foo;
+ if (copy.enabled) {
+ // do some stuff without locking
+ }
+ CPPUNIT_ASSERT(copy.enabled);
+ }
+};
+
+// Registers the fixture into the 'registry'
+CPPUNIT_TEST_SUITE_REGISTRATION(SyncedSettingsTest);
+