New upstream version 0.15.4+ds1
authorIOhannes m zmölnig <zmoelnig@umlautS.umlaeute.mur.at>
Tue, 20 Aug 2019 12:40:57 +0000 (14:40 +0200)
committerIOhannes m zmölnig <zmoelnig@umlautS.umlaeute.mur.at>
Tue, 20 Aug 2019 12:40:57 +0000 (14:40 +0200)
295 files changed:
ChangeLog
Makefile.am
README.md
src/core/action.h
src/core/channel.cpp
src/core/channel.h
src/core/channelManager.cpp
src/core/channelManager.h
src/core/clock.cpp
src/core/clock.h
src/core/conf.cpp
src/core/conf.h
src/core/const.h
src/core/graphics.cpp
src/core/graphics.h
src/core/init.cpp
src/core/init.h
src/core/kernelAudio.cpp
src/core/kernelAudio.h
src/core/kernelMidi.cpp
src/core/kernelMidi.h
src/core/midiChannel.cpp
src/core/midiChannel.h
src/core/midiChannelProc.cpp
src/core/midiDispatcher.cpp
src/core/midiDispatcher.h
src/core/midiEvent.cpp
src/core/midiEvent.h
src/core/midiMapConf.cpp
src/core/midiMapConf.h
src/core/mixer.cpp
src/core/mixer.h
src/core/mixerHandler.cpp
src/core/mixerHandler.h
src/core/patch.cpp
src/core/patch.h
src/core/plugin.cpp
src/core/plugin.h
src/core/pluginHost.cpp
src/core/pluginHost.h
src/core/pluginManager.cpp [new file with mode: 0644]
src/core/pluginManager.h [new file with mode: 0644]
src/core/range.h
src/core/recManager.cpp [new file with mode: 0644]
src/core/recManager.h [new file with mode: 0644]
src/core/recorder.cpp
src/core/recorder.h
src/core/recorderHandler.cpp
src/core/recorderHandler.h
src/core/sampleChannel.cpp
src/core/sampleChannel.h
src/core/sampleChannelProc.cpp
src/core/sampleChannelProc.h
src/core/sampleChannelRec.cpp
src/core/sampleChannelRec.h
src/core/storager.cpp
src/core/storager.h
src/core/types.h
src/core/wave.cpp
src/core/wave.h
src/core/waveFx.cpp
src/core/waveFx.h
src/core/waveManager.cpp
src/core/waveManager.h
src/glue/actionEditor.cpp
src/glue/actionEditor.h
src/glue/channel.cpp
src/glue/channel.h
src/glue/io.cpp
src/glue/io.h
src/glue/main.cpp
src/glue/main.h
src/glue/plugin.cpp
src/glue/plugin.h
src/glue/recorder.cpp
src/glue/recorder.h
src/glue/sampleEditor.cpp
src/glue/sampleEditor.h
src/glue/storage.cpp
src/glue/storage.h
src/glue/transport.cpp
src/glue/transport.h
src/gui/dialogs/about.cpp
src/gui/dialogs/about.h
src/gui/dialogs/actionEditor/baseActionEditor.cpp
src/gui/dialogs/actionEditor/baseActionEditor.h
src/gui/dialogs/actionEditor/midiActionEditor.cpp
src/gui/dialogs/actionEditor/midiActionEditor.h
src/gui/dialogs/actionEditor/sampleActionEditor.cpp
src/gui/dialogs/actionEditor/sampleActionEditor.h
src/gui/dialogs/beatsInput.cpp
src/gui/dialogs/beatsInput.h
src/gui/dialogs/bpmInput.cpp
src/gui/dialogs/bpmInput.h
src/gui/dialogs/browser/browserBase.cpp
src/gui/dialogs/browser/browserBase.h
src/gui/dialogs/browser/browserDir.cpp
src/gui/dialogs/browser/browserDir.h
src/gui/dialogs/browser/browserLoad.cpp
src/gui/dialogs/browser/browserLoad.h
src/gui/dialogs/browser/browserSave.cpp
src/gui/dialogs/browser/browserSave.h
src/gui/dialogs/channelNameInput.cpp
src/gui/dialogs/channelNameInput.h
src/gui/dialogs/config.cpp [new file with mode: 0644]
src/gui/dialogs/config.h [new file with mode: 0644]
src/gui/dialogs/devInfo.cpp [new file with mode: 0644]
src/gui/dialogs/devInfo.h [new file with mode: 0644]
src/gui/dialogs/gd_config.cpp [deleted file]
src/gui/dialogs/gd_config.h [deleted file]
src/gui/dialogs/gd_devInfo.cpp [deleted file]
src/gui/dialogs/gd_devInfo.h [deleted file]
src/gui/dialogs/gd_keyGrabber.cpp [deleted file]
src/gui/dialogs/gd_keyGrabber.h [deleted file]
src/gui/dialogs/gd_mainWindow.cpp [deleted file]
src/gui/dialogs/gd_mainWindow.h [deleted file]
src/gui/dialogs/gd_warnings.cpp [deleted file]
src/gui/dialogs/gd_warnings.h [deleted file]
src/gui/dialogs/keyGrabber.cpp [new file with mode: 0644]
src/gui/dialogs/keyGrabber.h [new file with mode: 0644]
src/gui/dialogs/mainWindow.cpp [new file with mode: 0644]
src/gui/dialogs/mainWindow.h [new file with mode: 0644]
src/gui/dialogs/midiIO/midiInputBase.cpp
src/gui/dialogs/midiIO/midiInputBase.h
src/gui/dialogs/midiIO/midiInputChannel.cpp
src/gui/dialogs/midiIO/midiInputChannel.h
src/gui/dialogs/midiIO/midiInputMaster.cpp
src/gui/dialogs/midiIO/midiInputMaster.h
src/gui/dialogs/midiIO/midiOutputBase.cpp
src/gui/dialogs/midiIO/midiOutputBase.h
src/gui/dialogs/midiIO/midiOutputMidiCh.cpp
src/gui/dialogs/midiIO/midiOutputMidiCh.h
src/gui/dialogs/midiIO/midiOutputSampleCh.cpp
src/gui/dialogs/midiIO/midiOutputSampleCh.h
src/gui/dialogs/pluginChooser.cpp
src/gui/dialogs/pluginChooser.h
src/gui/dialogs/pluginList.cpp
src/gui/dialogs/pluginList.h
src/gui/dialogs/pluginWindow.cpp
src/gui/dialogs/pluginWindow.h
src/gui/dialogs/pluginWindowGUI.cpp
src/gui/dialogs/pluginWindowGUI.h
src/gui/dialogs/sampleEditor.cpp
src/gui/dialogs/sampleEditor.h
src/gui/dialogs/warnings.cpp [new file with mode: 0644]
src/gui/dialogs/warnings.h [new file with mode: 0644]
src/gui/dialogs/window.cpp
src/gui/dialogs/window.h
src/gui/dispatcher.cpp [new file with mode: 0644]
src/gui/dispatcher.h [new file with mode: 0644]
src/gui/elems/actionEditor/baseAction.cpp
src/gui/elems/actionEditor/baseAction.h
src/gui/elems/actionEditor/baseActionEditor.cpp
src/gui/elems/actionEditor/baseActionEditor.h
src/gui/elems/actionEditor/envelopeEditor.cpp
src/gui/elems/actionEditor/envelopeEditor.h
src/gui/elems/actionEditor/envelopePoint.cpp
src/gui/elems/actionEditor/envelopePoint.h
src/gui/elems/actionEditor/gridTool.cpp
src/gui/elems/actionEditor/gridTool.h
src/gui/elems/actionEditor/noteEditor.cpp
src/gui/elems/actionEditor/noteEditor.h
src/gui/elems/actionEditor/pianoItem.cpp
src/gui/elems/actionEditor/pianoItem.h
src/gui/elems/actionEditor/pianoRoll.cpp
src/gui/elems/actionEditor/pianoRoll.h
src/gui/elems/actionEditor/sampleAction.cpp
src/gui/elems/actionEditor/sampleAction.h
src/gui/elems/actionEditor/sampleActionEditor.cpp
src/gui/elems/actionEditor/sampleActionEditor.h
src/gui/elems/actionEditor/velocityEditor.cpp
src/gui/elems/actionEditor/velocityEditor.h
src/gui/elems/basics/baseButton.cpp
src/gui/elems/basics/baseButton.h
src/gui/elems/basics/box.cpp
src/gui/elems/basics/box.h
src/gui/elems/basics/boxtypes.cpp
src/gui/elems/basics/boxtypes.h
src/gui/elems/basics/button.cpp
src/gui/elems/basics/button.h
src/gui/elems/basics/check.cpp
src/gui/elems/basics/check.h
src/gui/elems/basics/choice.cpp
src/gui/elems/basics/choice.h
src/gui/elems/basics/dial.cpp
src/gui/elems/basics/dial.h
src/gui/elems/basics/idButton.cpp [deleted file]
src/gui/elems/basics/idButton.h [deleted file]
src/gui/elems/basics/input.cpp
src/gui/elems/basics/input.h
src/gui/elems/basics/liquidScroll.cpp
src/gui/elems/basics/liquidScroll.h
src/gui/elems/basics/progress.cpp
src/gui/elems/basics/progress.h
src/gui/elems/basics/radio.cpp
src/gui/elems/basics/radio.h
src/gui/elems/basics/resizerBar.cpp
src/gui/elems/basics/resizerBar.h
src/gui/elems/basics/scroll.cpp
src/gui/elems/basics/scroll.h
src/gui/elems/basics/slider.cpp
src/gui/elems/basics/slider.h
src/gui/elems/basics/statusButton.cpp
src/gui/elems/basics/statusButton.h
src/gui/elems/browser.cpp
src/gui/elems/browser.h
src/gui/elems/config/tabAudio.cpp
src/gui/elems/config/tabAudio.h
src/gui/elems/config/tabBehaviors.cpp
src/gui/elems/config/tabBehaviors.h
src/gui/elems/config/tabMidi.cpp
src/gui/elems/config/tabMidi.h
src/gui/elems/config/tabMisc.cpp
src/gui/elems/config/tabMisc.h
src/gui/elems/config/tabPlugins.cpp
src/gui/elems/config/tabPlugins.h
src/gui/elems/mainWindow/beatMeter.cpp
src/gui/elems/mainWindow/beatMeter.h
src/gui/elems/mainWindow/keyboard/channel.cpp
src/gui/elems/mainWindow/keyboard/channel.h
src/gui/elems/mainWindow/keyboard/channelButton.cpp
src/gui/elems/mainWindow/keyboard/channelButton.h
src/gui/elems/mainWindow/keyboard/channelMode.cpp
src/gui/elems/mainWindow/keyboard/channelMode.h
src/gui/elems/mainWindow/keyboard/channelStatus.cpp
src/gui/elems/mainWindow/keyboard/channelStatus.h
src/gui/elems/mainWindow/keyboard/column.cpp
src/gui/elems/mainWindow/keyboard/column.h
src/gui/elems/mainWindow/keyboard/keyboard.cpp
src/gui/elems/mainWindow/keyboard/keyboard.h
src/gui/elems/mainWindow/keyboard/midiChannel.cpp
src/gui/elems/mainWindow/keyboard/midiChannel.h
src/gui/elems/mainWindow/keyboard/midiChannelButton.cpp
src/gui/elems/mainWindow/keyboard/midiChannelButton.h
src/gui/elems/mainWindow/keyboard/sampleChannel.cpp
src/gui/elems/mainWindow/keyboard/sampleChannel.h
src/gui/elems/mainWindow/keyboard/sampleChannelButton.cpp
src/gui/elems/mainWindow/keyboard/sampleChannelButton.h
src/gui/elems/mainWindow/mainIO.cpp
src/gui/elems/mainWindow/mainIO.h
src/gui/elems/mainWindow/mainMenu.cpp
src/gui/elems/mainWindow/mainMenu.h
src/gui/elems/mainWindow/mainTimer.cpp
src/gui/elems/mainWindow/mainTimer.h
src/gui/elems/mainWindow/mainTransport.cpp
src/gui/elems/mainWindow/mainTransport.h
src/gui/elems/midiLearner.cpp
src/gui/elems/midiLearner.h
src/gui/elems/plugin/pluginBrowser.cpp
src/gui/elems/plugin/pluginBrowser.h
src/gui/elems/plugin/pluginElement.cpp
src/gui/elems/plugin/pluginElement.h
src/gui/elems/plugin/pluginParameter.cpp
src/gui/elems/plugin/pluginParameter.h
src/gui/elems/sampleEditor/boostTool.cpp
src/gui/elems/sampleEditor/boostTool.h
src/gui/elems/sampleEditor/panTool.cpp
src/gui/elems/sampleEditor/panTool.h
src/gui/elems/sampleEditor/pitchTool.cpp
src/gui/elems/sampleEditor/pitchTool.h
src/gui/elems/sampleEditor/rangeTool.cpp
src/gui/elems/sampleEditor/rangeTool.h
src/gui/elems/sampleEditor/shiftTool.cpp
src/gui/elems/sampleEditor/shiftTool.h
src/gui/elems/sampleEditor/volumeTool.cpp
src/gui/elems/sampleEditor/volumeTool.h
src/gui/elems/sampleEditor/waveTools.cpp
src/gui/elems/sampleEditor/waveTools.h
src/gui/elems/sampleEditor/waveform.cpp
src/gui/elems/sampleEditor/waveform.h
src/gui/elems/soundMeter.cpp
src/gui/elems/soundMeter.h
src/main.cpp
src/utils/cocoa.h
src/utils/fs.cpp
src/utils/fs.h
src/utils/gui.cpp
src/utils/gui.h
src/utils/log.cpp
src/utils/log.h
src/utils/math.cpp
src/utils/math.h
src/utils/string.cpp
src/utils/string.h
src/utils/time.cpp
src/utils/time.h
src/utils/vector.h [new file with mode: 0644]
src/utils/ver.cpp
src/utils/ver.h
tests/conf.cpp
tests/patch.cpp
tests/sampleChannel.cpp
tests/sampleChannelProc.cpp
tests/utils.cpp
tests/waveManager.cpp

index ea1d5b227f508a68c9d91001e051bc68d15f99f5..b4bdc9e74701bd7b005a5d46acf4d8e6f798a623 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
 --------------------------------------------------------------------------------
 
 
+0.15.4 --- 2019 . 03 . 22
+- New record-on-signal option for input and action recording
+- Initial support for plug-ins with mono I/O buses
+- PluginHost refactoring
+- Smart pointers for Wave and Plugin objects
+- Remove old and deprecated input delay compensation
+- Optimized audio IO processing in Mixer callback
+- Atomic I/O meters with improved accuracy
+- Fix memory leak when replacing samples in a Sample Channel
+- Fix plug-ins ordering method when re-opening Giada
+- Fix silent Sample Channel when recording actions a second time
+- Fix velocity always discarded when sending key-press to Sample Channel
+- Fix inability to record actions with quantizer enabled
+
+
 0.15.3 --- 2018 . 12 . 24
 - Action recorder refactoring
 - Optional midimap parameters (thank you @tomek-szczesny)
index 4cb3529114bb7c371074757764ff45b8c9fc7e78..93e11fc6c2b0f1c306374c99afb2125fe1cb4c92 100644 (file)
@@ -6,7 +6,7 @@ AUTOMAKE_OPTIONS = foreign
 
 
 cppFlags =
-cxxFlags = -std=c++11 -Wall
+cxxFlags = -std=c++14 -Wall
 ldAdd =
 ldFlags =
 sourcesExtra = 
@@ -34,8 +34,10 @@ sourcesCore =                            \
        src/core/conf.cpp                      \
        src/core/kernelAudio.h                 \
        src/core/kernelAudio.cpp               \
-       src/core/pluginHost.h                      \
+       src/core/pluginHost.h                  \
        src/core/pluginHost.cpp                \
+       src/core/pluginManager.h               \
+       src/core/pluginManager.cpp             \
        src/core/mixerHandler.h                \
        src/core/mixerHandler.cpp              \
        src/core/init.h                        \
@@ -72,6 +74,8 @@ sourcesCore =                            \
        src/core/sampleChannelRec.cpp          \
        src/core/midiChannelProc.h             \
        src/core/midiChannelProc.cpp           \
+       src/core/recManager.h                  \
+       src/core/recManager.cpp                \
        src/glue/main.h                        \
        src/glue/main.cpp                      \
        src/glue/io.h                          \
@@ -92,24 +96,26 @@ sourcesCore =                            \
        src/glue/actionEditor.cpp              \
        src/gui/dialogs/window.h               \
        src/gui/dialogs/window.cpp             \
-       src/gui/dialogs/gd_keyGrabber.h        \
-       src/gui/dialogs/gd_keyGrabber.cpp      \
+       src/gui/dispatcher.h                   \
+       src/gui/dispatcher.cpp                 \
+       src/gui/dialogs/keyGrabber.h           \
+       src/gui/dialogs/keyGrabber.cpp         \
        src/gui/dialogs/about.h                \
        src/gui/dialogs/about.cpp              \
-       src/gui/dialogs/gd_mainWindow.h        \
-       src/gui/dialogs/gd_mainWindow.cpp      \
+       src/gui/dialogs/mainWindow.h           \
+       src/gui/dialogs/mainWindow.cpp         \
        src/gui/dialogs/beatsInput.h           \
        src/gui/dialogs/beatsInput.cpp         \
-       src/gui/dialogs/gd_warnings.h          \
-       src/gui/dialogs/gd_warnings.cpp        \
+       src/gui/dialogs/warnings.h             \
+       src/gui/dialogs/warnings.cpp           \
        src/gui/dialogs/bpmInput.h             \
        src/gui/dialogs/bpmInput.cpp           \
        src/gui/dialogs/channelNameInput.h     \
        src/gui/dialogs/channelNameInput.cpp   \
-       src/gui/dialogs/gd_config.h            \
-       src/gui/dialogs/gd_config.cpp          \
-       src/gui/dialogs/gd_devInfo.h           \
-       src/gui/dialogs/gd_devInfo.cpp         \
+       src/gui/dialogs/config.h               \
+       src/gui/dialogs/config.cpp             \
+       src/gui/dialogs/devInfo.h              \
+       src/gui/dialogs/devInfo.cpp            \
        src/gui/dialogs/pluginList.h           \
        src/gui/dialogs/pluginList.cpp         \
        src/gui/dialogs/pluginWindow.h         \
@@ -246,8 +252,6 @@ sourcesCore =                            \
        src/gui/elems/basics/statusButton.cpp  \
        src/gui/elems/basics/button.h          \
        src/gui/elems/basics/button.cpp        \
-       src/gui/elems/basics/idButton.h        \
-       src/gui/elems/basics/idButton.cpp      \
        src/gui/elems/basics/resizerBar.h      \
        src/gui/elems/basics/resizerBar.cpp    \
        src/gui/elems/basics/input.h           \
@@ -279,6 +283,7 @@ sourcesCore =                            \
        src/utils/gvector.h                    \
        src/utils/fs.h                         \
        src/utils/fs.cpp                       \
+       src/utils/vector.h                     \
        src/utils/ver.h                        \
        src/utils/ver.cpp                      \
        src/utils/string.h                     \
index 91998f3428e993a34bf7f74b7729b4fe8341d5ce..e46b63aa1aff5bb3df46460b7e4cf504d2302db1 100644 (file)
--- a/README.md
+++ b/README.md
@@ -61,7 +61,7 @@ Feel free to ask anything on [our end-user forum](https://www.giadamusic.com/for
 
 ## Copyright
 
-Giada is Copyright (C) 2010-2018 by Giovanni A. Zuliani | Monocasual
+Giada is Copyright (C) 2010-2019 by Giovanni A. Zuliani | Monocasual
 
 Giada - Your Hardcore Loopmachine 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.
 
index af283ed1a2be45a297f9c34bdd1d6ee728a91ba9..b4ee058ef2f32a3d1cabc9f98f1c4d260ba56bb9 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 5c5e554d2176ba684658efa5ef667a0fe7efeda2..ae9654aa63cd8963efaf05377be04e8e957a50e1 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -32,6 +32,7 @@
 #include "const.h"
 #include "channelManager.h"
 #include "pluginHost.h"
+#include "pluginManager.h"
 #include "plugin.h"
 #include "kernelMidi.h"
 #include "patch.h"
@@ -116,8 +117,11 @@ void Channel::copy(const Channel* src, pthread_mutex_t* pluginMutex)
        midiOutLsolo    = src->midiOutLsolo;
 
 #ifdef WITH_VST
-       for (Plugin* plugin : src->plugins)
-               pluginHost::clonePlugin(plugin, pluginHost::CHANNEL, pluginMutex, this);
+
+       for (const std::unique_ptr<Plugin>& plugin : src->plugins)
+               pluginHost::addPlugin(pluginManager::makePlugin(*plugin.get()), 
+                       pluginHost::StackType::CHANNEL, pluginMutex, this);
+
 #endif
 
        hasActions = recorderHandler::cloneActions(src->index, index);
@@ -287,7 +291,7 @@ bool Channel::isReadingActions() const
 
 #ifdef WITH_VST
 
-juce::MidiBuffer &Channel::getPluginMidiEvents()
+const juce::MidiBuffer& Channel::getPluginMidiEvents() const
 {
        return midiBuffer;
 }
index 45ec277a8526acdcec8f4dd4b949709f903df490..150d7e87d409ed34bee2d316c5d83098a7662830 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -42,6 +42,7 @@
 
 #ifdef WITH_VST
        #include "../deps/juce-config.h"
+       #include "plugin.h"
 #endif
 
 
@@ -49,10 +50,8 @@ class geChannel;
 
 
 namespace giada {
-namespace m 
+namespace m
 {
-class Plugin;
-
 class Channel
 {
 public:
@@ -71,7 +70,8 @@ public:
 
        /* process
        Merges working buffers into 'out', plus plugin processing (if any). Warning:
-       inBuffer might be nullptr if no input devices are available for recording. */
+       inBuffer might be unallocated if no input devices are available for 
+       recording. */
 
        virtual void process(AudioBuffer& out, const AudioBuffer& in, bool audible, 
                bool running) = 0;
@@ -122,8 +122,7 @@ public:
        Midi channels, true for Sample channels only if they don't contain a
        sample yet.*/
 
-       virtual bool canInputRec() = 0;
-
+       virtual bool canInputRec()    const { return false; };
        virtual bool hasLogicalData() const { return false; };
        virtual bool hasEditedData()  const { return false; };
        virtual bool hasData()        const { return false; };
@@ -187,10 +186,10 @@ public:
 #ifdef WITH_VST
 
        /* getPluginMidiEvents
-        * Return a reference to midiBuffer stack. This is available for any kind of
-        * channel, but it makes sense only for MIDI channels. */
+       Returns a reference to midiBuffer stack. This is available for any kind of
+       channel, but it makes sense only for MIDI channels. */
 
-       juce::MidiBuffer& getPluginMidiEvents();
+       const juce::MidiBuffer& getPluginMidiEvents() const;
 
        void clearMidiBuffer();
 
@@ -233,8 +232,8 @@ public:
        double volume_i;
        double volume_d;
        
-       bool hasActions;      // has something recorded
-       bool readActions;     // read what's recorded
+       bool hasActions;      // If has some actions recorded
+       bool readActions;     // If should read recorded actions
 
        bool      midiIn;               // enable midi input
        uint32_t  midiInKeyPress;
@@ -262,7 +261,7 @@ public:
        uint32_t midiOutLsolo;
 
 #ifdef WITH_VST
-       std::vector <Plugin*> plugins;
+       std::vector<std::unique_ptr<Plugin>> plugins;
 #endif
 
 protected:
index d138be3454cb8205d2652e74009e4ae852a56c02..cd6464067c6fec17e7169df8bdbd45a0b9ad60ac 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -36,6 +36,7 @@
 #include "sampleChannel.h"
 #include "midiChannel.h"
 #include "pluginHost.h"
+#include "pluginManager.h"
 #include "plugin.h"
 #include "action.h"
 #include "recorderHandler.h"
@@ -55,7 +56,7 @@ void writePlugins_(const Channel* ch, patch::channel_t& pch)
 {
 #ifdef WITH_VST
 
-       pluginHost::forEachPlugin(pluginHost::CHANNEL, ch, [&] (const Plugin* p) {
+       pluginHost::forEachPlugin(pluginHost::StackType::CHANNEL, ch, [&] (const Plugin* p) {
                patch::plugin_t pp;
                pp.path   = p->getUniqueId();
                pp.bypass = p->isBypassed();
@@ -89,8 +90,8 @@ void readPlugins_(Channel* ch, const patch::channel_t& pch)
 #ifdef WITH_VST
 
        for (const patch::plugin_t& ppl : pch.plugins) {
-               Plugin* plugin = pluginHost::addPlugin(ppl.path, pluginHost::CHANNEL,
-                       &mixer::mutex, ch);
+
+               std::unique_ptr<Plugin> plugin = pluginManager::makePlugin(ppl.path);
                if (plugin == nullptr)
                        continue;
 
@@ -106,6 +107,8 @@ void readPlugins_(Channel* ch, const patch::channel_t& pch)
                        for (uint32_t midiInParam : ppl.midiInParams)
                                plugin->midiInParams.push_back(midiInParam);
                }
+
+               pluginHost::addPlugin(std::move(plugin), pluginHost::StackType::CHANNEL, &mixer::mutex, ch);
        }
 
 #endif
@@ -196,7 +199,7 @@ void writePatch(const SampleChannel* ch, bool isProject, int index)
        pch.begin             = ch->getBegin();
        pch.end               = ch->getEnd();
        pch.boost             = ch->getBoost();
-       pch.recActive         = ch->readActions;
+       pch.readActions       = ch->readActions;
        pch.pitch             = ch->getPitch();
        pch.inputMonitor      = ch->inputMonitor;
        pch.midiInReadActions = ch->midiInReadActions;
@@ -242,28 +245,27 @@ void readPatch(Channel* ch, const patch::channel_t& pch)
 void readPatch(SampleChannel* ch, const string& basePath, const patch::channel_t& pch)
 {
        ch->mode              = static_cast<ChannelMode>(pch.mode);
-       ch->readActions       = pch.recActive;
-       ch->recStatus         = pch.recActive ? ChannelStatus::PLAY : ChannelStatus::OFF;
+       ch->readActions       = pch.readActions;
+       ch->recStatus         = pch.readActions ? ChannelStatus::PLAY : ChannelStatus::OFF;
        ch->midiInVeloAsVol   = pch.midiInVeloAsVol;
        ch->midiInReadActions = pch.midiInReadActions;
        ch->midiInPitch       = pch.midiInPitch;
        ch->inputMonitor      = pch.inputMonitor;
        ch->setBoost(pch.boost);
 
-       Wave* w = nullptr;
-       int res = waveManager::create(basePath + pch.samplePath, &w); 
+       waveManager::Result res = waveManager::createFromFile(basePath + pch.samplePath);
 
-       if (res == G_RES_OK) {
-               ch->pushWave(w);
+       if (res.status == G_RES_OK) {
+               ch->pushWave(std::move(res.wave));
                ch->setBegin(pch.begin);
                ch->setEnd(pch.end);
                ch->setPitch(pch.pitch);
        }
        else {
-               if (res == G_RES_ERR_NO_DATA)
+               if (res.status == G_RES_ERR_NO_DATA)
                        ch->status = ChannelStatus::EMPTY;
                else
-               if (res == G_RES_ERR_IO)
+               if (res.status == G_RES_ERR_IO)
                        ch->status = ChannelStatus::MISSING;
                ch->sendMidiLstatus();  // FIXME - why sending MIDI lightning if sample status is wrong?
        }
index d9fd4905c057277e8012c62ec9351118eaef11f0..d3d7c6b3faa91ce11b11b6eac147ca1259f1ebe1 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index ea6dfbe62cb19b17b3fa46a65b697d7e114e6bb2..4fe106822d24e23161c2660862e5742988df6f4c 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -25,6 +25,7 @@
  * -------------------------------------------------------------------------- */
 
 
+#include <atomic>
 #include <cassert>
 #include "../glue/transport.h"
 #include "../glue/main.h"
@@ -41,35 +42,36 @@ namespace clock
 {
 namespace
 {
-bool  running  = false;
-float bpm      = G_DEFAULT_BPM;
-int   bars     = G_DEFAULT_BARS;
-int   beats    = G_DEFAULT_BEATS;
-int   quantize = G_DEFAULT_QUANTIZE;
-int   quanto   = 1;            // quantizer step
-
-int framesInLoop = 0;
-int framesInBar  = 0;
-int framesInBeat = 0;
-int framesInSeq  = 0;
-int currentFrame = 0;
-int currentBeat  = 0;
-
-int midiTCrate    = 0;      // send MTC data every midiTCrate frames
-int midiTCframes  = 0;
-int midiTCseconds = 0;
-int midiTCminutes = 0;
-int midiTChours   = 0;
+float bpm_      = G_DEFAULT_BPM;
+int   bars_     = G_DEFAULT_BARS;
+int   beats_    = G_DEFAULT_BEATS;
+int   quanto_   = 1;            // quantizer step
+std::atomic<int>         quantize_(G_DEFAULT_QUANTIZE);
+std::atomic<ClockStatus> status_(ClockStatus::STOPPED);
+
+int framesInLoop_ = 0;
+int framesInBar_  = 0;
+int framesInBeat_ = 0;
+int framesInSeq_  = 0;
+std::atomic<int> currentFrameWait_(0);  // Used only in wait mode
+std::atomic<int> currentFrame_(0);
+std::atomic<int> currentBeat_(0);
+
+int midiTCrate_    = 0;      // Send MTC data every midiTCrate_ frames
+int midiTCframes_  = 0;
+int midiTCseconds_ = 0;
+int midiTCminutes_ = 0;
+int midiTChours_   = 0;
 
 #ifdef G_OS_LINUX
-kernelAudio::JackState jackStatePrev;
+kernelAudio::JackState jackStatePrev_;
 #endif
 
 
-void updateQuanto()
+void updateQuanto_()
 {
-       if (quantize != 0)
-               quanto = framesInBeat / quantize;
+       if (quantize_.load() != 0)
+               quanto_ = framesInBeat_ / quantize_.load();
 }
 
 }; // {anonymous}
@@ -82,12 +84,12 @@ void updateQuanto()
 
 void init(int sampleRate, float midiTCfps)
 {
-       midiTCrate = (sampleRate / midiTCfps) * G_MAX_IO_CHANS;  // stereo values
-       running    = false;
-       bpm        = G_DEFAULT_BPM;
-       bars       = G_DEFAULT_BARS;
-       beats      = G_DEFAULT_BEATS;
-       quantize   = G_DEFAULT_QUANTIZE;
+       status_.store(ClockStatus::STOPPED);  // Must be the first thing to do
+       midiTCrate_ = (sampleRate / midiTCfps) * G_MAX_IO_CHANS;  // stereo values
+       bpm_        = G_DEFAULT_BPM;
+       bars_       = G_DEFAULT_BARS;
+       beats_      = G_DEFAULT_BEATS;
+       quantize_.store(G_DEFAULT_QUANTIZE);
        updateFrameBars();
 }
 
@@ -97,52 +99,41 @@ void init(int sampleRate, float midiTCfps)
 
 bool isRunning()
 {
-       return running;
+       return status_.load() == ClockStatus::RUNNING;
 }
 
 
-bool quantoHasPassed()
-{
-       return currentFrame % (quanto) == 0;
-}
-
-
-bool isOnBar()
+bool isActive()
 {
-       /* A bar cannot occur at frame 0. That's the first beat. */
-       return currentFrame % framesInBar == 0 && currentFrame != 0;
+       return status_.load() == ClockStatus::RUNNING || status_.load() == ClockStatus::WAITING;
 }
 
 
-bool isOnBeat()
+bool quantoHasPassed()
 {
-       /* Skip frame 0: it is intended as 'first beat'. */
-       /* TODO - this is wrong! */
-       return currentFrame % framesInBeat == 0 && currentFrame > 0;
+       return currentFrame_.load() % (quanto_) == 0;
 }
 
 
-bool isOnFirstBeat()
+bool isOnBar()
 {
-       return currentFrame == 0;
+       if (status_.load() == ClockStatus::WAITING)
+               return false;
+       return currentFrame_.load() % framesInBar_ == 0;
 }
 
 
-void start()
+bool isOnBeat()
 {
-       running = true;
-       if (conf::midiSync == MIDI_SYNC_CLOCK_M) {
-               kernelMidi::send(MIDI_START, -1, -1);
-               kernelMidi::send(MIDI_POSITION_PTR, 0, 0);
-       }
+       if (status_.load() == ClockStatus::WAITING)
+               return currentFrameWait_.load() % framesInBeat_ == 0;
+       return currentFrame_.load() % framesInBeat_ == 0;
 }
 
 
-void stop()
+bool isOnFirstBeat()
 {
-       running = false;
-       if (conf::midiSync == MIDI_SYNC_CLOCK_M)
-               kernelMidi::send(MIDI_STOP, -1, -1);
+       return currentFrame_.load() == 0;
 }
 
 
@@ -150,67 +141,94 @@ void setBpm(float b)
 {
        if (b < G_MIN_BPM)
                b = G_MIN_BPM;
-       bpm = b;
+       bpm_ = b;
        updateFrameBars();
 }
 
 
 void setBars(int newBars)
 {
-       /* Bars cannot be greater than beats and must be a sub multiple of beats. If
+       /* Bars cannot be greater than beats_ and must be a sub multiple of beats_. If
        not, approximate to the nearest (and greater) value available. */
 
-       if (newBars > beats)
-               bars = beats;
+       if (newBars > beats_)
+               bars_ = beats_;
        else if (newBars <= 0)
-               bars = 1;
-       else if (beats % newBars != 0) {
-               bars = newBars + (beats % newBars);
-               if (beats % bars != 0) // it could be an odd value, let's check it (and avoid it)
-                       bars = bars - (beats % bars);
+               bars_ = 1;
+       else if (beats_ % newBars != 0) {
+               bars_ = newBars + (beats_ % newBars);
+               if (beats_ % bars_ != 0) // it could be an odd value, let's check it (and avoid it)
+                       bars_ = bars_ - (beats_ % bars_);
        }
        else
-               bars = newBars;
+               bars_ = newBars;
 }
 
 
 void setBeats(int b)
 {
        if (b > G_MAX_BEATS)
-               beats = G_MAX_BEATS;
+               beats_ = G_MAX_BEATS;
        else if (b < 1)
-               beats = 1;
+               beats_ = 1;
        else
-               beats = b;
+               beats_ = b;
 }
 
 
 void setQuantize(int q)
 {
-       quantize = q;
-       updateQuanto();
+       quantize_.store(q);
+       updateQuanto_();
+}
+
+
+void setStatus(ClockStatus s)
+{
+       status_.store(s);
+       
+       if (s == ClockStatus::RUNNING) {
+               if (conf::midiSync == MIDI_SYNC_CLOCK_M) {
+                       kernelMidi::send(MIDI_START, -1, -1);
+                       kernelMidi::send(MIDI_POSITION_PTR, 0, 0);
+               }
+       }
+       else
+       if (s == ClockStatus::STOPPED) {
+               if (conf::midiSync == MIDI_SYNC_CLOCK_M)
+                       kernelMidi::send(MIDI_STOP, -1, -1);
+       }
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void incrCurrentFrame() {
-       currentFrame++;
-       if (currentFrame >= framesInLoop) {
-               currentFrame = 0;
-               currentBeat  = 0;
+void incrCurrentFrame() 
+{
+       if (status_.load() == ClockStatus::WAITING) {
+               currentFrameWait_++;
+               if (currentFrameWait_.load() >= framesInLoop_)
+                       currentFrameWait_ = 0;
+       }
+       else {
+               currentFrame_++;
+               if (currentFrame_.load() >= framesInLoop_) {
+                       currentFrame_.store(0);
+                       currentBeat_.store(0);
+               }
+               else
+               if (isOnBeat())
+                       currentBeat_++;
        }
-       else
-       if (isOnBeat())
-               currentBeat++;
 }
 
 
 void rewind()
 {
-       currentFrame = 0;
-       currentBeat  = 0;
+       currentFrameWait_.store(0);
+       currentFrame_.store(0);
+       currentBeat_.store(0);
        sendMIDIrewind();
 }
 
@@ -220,18 +238,18 @@ void rewind()
 
 void updateFrameBars()
 {
-       /* framesInLoop ... loop length in frames, or samplerate * # frames per 
-        *                  current bpm * beats;
-        * framesInBar .... n. of frames within a bar;
-        * framesInBeat ... n. of frames within a beat;
-        * framesInSeq .... number of frames in the whole sequencer. */
+       /* framesInLoop_ ... loop length in frames, or samplerate * # frames per 
+        *                  current bpm_ * beats_;
+        * framesInBar_ .... n. of frames within a bar;
+        * framesInBeat_ ... n. of frames within a beat;
+        * framesInSeq_ .... number of frames in the whole sequencer. */
 
-       framesInLoop = (conf::samplerate * (60.0f / bpm)) * beats;
-       framesInBar  = framesInLoop / bars;
-       framesInBeat = framesInLoop / beats;
-       framesInSeq  = framesInBeat * G_MAX_BEATS;
+       framesInLoop_ = (conf::samplerate * (60.0f / bpm_)) * beats_;
+       framesInBar_  = framesInLoop_ / bars_;
+       framesInBeat_ = framesInLoop_ / beats_;
+       framesInSeq_  = framesInBeat_ * G_MAX_BEATS;
 
-       updateQuanto();
+       updateQuanto_();
 }
 
 
@@ -240,10 +258,15 @@ void updateFrameBars()
 
 void sendMIDIsync()
 {
+       /* Sending MIDI sync while waiting is meaningless. */
+
+       if (status_.load() == ClockStatus::WAITING)
+               return;
+
        /* TODO - only Master (_M) is implemented so far. */
 
        if (conf::midiSync == MIDI_SYNC_CLOCK_M) {
-               if (currentFrame % (framesInBeat/24) == 0)
+               if (currentFrame_.load() % (framesInBeat_/24) == 0)
                        kernelMidi::send(MIDI_CLOCK, -1, -1);
                return;
        }
@@ -255,7 +278,7 @@ void sendMIDIsync()
                 * 1-4 and 5-8. We check timecode frame's parity: if even, send
                 * range 1-4, if odd send 5-8. */
 
-               if (currentFrame % midiTCrate != 0)  // no timecode frame passed
+               if (currentFrame_.load() % midiTCrate_ != 0)  // no timecode frame passed
                        return;
 
                /* frame low nibble
@@ -263,11 +286,11 @@ void sendMIDIsync()
                 * seconds low nibble
                 * seconds high nibble */
 
-               if (midiTCframes % 2 == 0) {
-                       kernelMidi::send(MIDI_MTC_QUARTER, (midiTCframes & 0x0F)  | 0x00, -1);
-                       kernelMidi::send(MIDI_MTC_QUARTER, (midiTCframes >> 4)    | 0x10, -1);
-                       kernelMidi::send(MIDI_MTC_QUARTER, (midiTCseconds & 0x0F) | 0x20, -1);
-                       kernelMidi::send(MIDI_MTC_QUARTER, (midiTCseconds >> 4)   | 0x30, -1);
+               if (midiTCframes_ % 2 == 0) {
+                       kernelMidi::send(MIDI_MTC_QUARTER, (midiTCframes_ & 0x0F)  | 0x00, -1);
+                       kernelMidi::send(MIDI_MTC_QUARTER, (midiTCframes_ >> 4)    | 0x10, -1);
+                       kernelMidi::send(MIDI_MTC_QUARTER, (midiTCseconds_ & 0x0F) | 0x20, -1);
+                       kernelMidi::send(MIDI_MTC_QUARTER, (midiTCseconds_ >> 4)   | 0x30, -1);
                }
 
                /* minutes low nibble
@@ -276,29 +299,29 @@ void sendMIDIsync()
                 * hours high nibble SMPTE frame rate */
 
                else {
-                       kernelMidi::send(MIDI_MTC_QUARTER, (midiTCminutes & 0x0F) | 0x40, -1);
-                       kernelMidi::send(MIDI_MTC_QUARTER, (midiTCminutes >> 4)   | 0x50, -1);
-                       kernelMidi::send(MIDI_MTC_QUARTER, (midiTChours & 0x0F)   | 0x60, -1);
-                       kernelMidi::send(MIDI_MTC_QUARTER, (midiTChours >> 4)     | 0x70, -1);
+                       kernelMidi::send(MIDI_MTC_QUARTER, (midiTCminutes_ & 0x0F) | 0x40, -1);
+                       kernelMidi::send(MIDI_MTC_QUARTER, (midiTCminutes_ >> 4)   | 0x50, -1);
+                       kernelMidi::send(MIDI_MTC_QUARTER, (midiTChours_ & 0x0F)   | 0x60, -1);
+                       kernelMidi::send(MIDI_MTC_QUARTER, (midiTChours_ >> 4)     | 0x70, -1);
                }
 
-               midiTCframes++;
+               midiTCframes_++;
 
                /* check if total timecode frames are greater than timecode fps:
                 * if so, a second has passed */
 
-               if (midiTCframes > conf::midiTCfps) {
-                       midiTCframes = 0;
-                       midiTCseconds++;
-                       if (midiTCseconds >= 60) {
-                               midiTCminutes++;
-                               midiTCseconds = 0;
-                               if (midiTCminutes >= 60) {
-                                       midiTChours++;
-                                       midiTCminutes = 0;
+               if (midiTCframes_ > conf::midiTCfps) {
+                       midiTCframes_ = 0;
+                       midiTCseconds_++;
+                       if (midiTCseconds_ >= 60) {
+                               midiTCminutes_++;
+                               midiTCseconds_ = 0;
+                               if (midiTCminutes_ >= 60) {
+                                       midiTChours_++;
+                                       midiTCminutes_ = 0;
                                }
                        }
-                       //gu_log("%d:%d:%d:%d\n", midiTChours, midiTCminutes, midiTCseconds, midiTCframes);
+                       //gu_log("%d:%d:%d:%d\n", midiTChours_, midiTCminutes_, midiTCseconds_, midiTCframes_);
                }
        }
 }
@@ -309,10 +332,10 @@ void sendMIDIsync()
 
 void sendMIDIrewind()
 {
-       midiTCframes  = 0;
-       midiTCseconds = 0;
-       midiTCminutes = 0;
-       midiTChours   = 0;
+       midiTCframes_  = 0;
+       midiTCseconds_ = 0;
+       midiTCminutes_ = 0;
+       midiTChours_   = 0;
 
        /* For cueing the slave to a particular start point, Quarter Frame
         * messages are not used. Instead, an MTC Full Frame message should
@@ -337,7 +360,7 @@ void recvJackSync()
 {
        kernelAudio::JackState jackState = kernelAudio::jackTransportQuery();
 
-       if (jackState.running != jackStatePrev.running) {
+       if (jackState.running != jackStatePrev_.running) {
                if (jackState.running) {
                        if (!isRunning())
                                c::transport::startSeq(false); // not from UI
@@ -347,14 +370,14 @@ void recvJackSync()
                                c::transport::stopSeq(false); // not from UI
                }
        }
-       if (jackState.bpm != jackStatePrev.bpm)
+       if (jackState.bpm != jackStatePrev_.bpm)
                if (jackState.bpm > 1.0f)  // 0 bpm if Jack does not send that info
-                       glue_setBpm(jackState.bpm);
+                       c::main::setBpm(jackState.bpm);
 
-       if (jackState.frame == 0 && jackState.frame != jackStatePrev.frame)
+       if (jackState.frame == 0 && jackState.frame != jackStatePrev_.frame)
                c::transport::rewindSeq(false, false);  // not from UI, don't notify jack (avoid loop)
 
-       jackStatePrev = jackState;
+       jackStatePrev_ = jackState;
 }
 
 #endif
@@ -374,68 +397,73 @@ bool canQuantize()
 
 int getCurrentFrame()
 {
-       return currentFrame;
+       return currentFrame_.load();
 }
 
 
 int getFramesInLoop()
 {
-       return framesInLoop;
+       return framesInLoop_;
 }
 
 
 int getCurrentBeat()
 {
-       return currentBeat;
+       return currentBeat_.load();
 }
 
 
 int getQuantize()
 {
-       return quantize;
+       return quantize_.load();
 }
 
 
 float getBpm()
 {
-       return bpm;
+       return bpm_;
 }
 
 
 int getBeats()
 {
-       return beats;
+       return beats_;
 }
 
 
 int getBars()
 {
-       return bars;
+       return bars_;
 }
 
 
 int getQuanto()
 {
-       return quanto;
+       return quanto_;
 }
 
 
 int getFramesInBar()
 {
-       return framesInBar;
+       return framesInBar_;
 }
 
 
 int getFramesInBeat()
 {
-       return framesInBeat;
+       return framesInBeat_;
 }
 
 
 int getFramesInSeq()
 {
-       return framesInSeq;
+       return framesInSeq_;
 }
 
 
+ClockStatus getStatus()
+{
+       return status_;
+}
+
 }}}; // giada::m::clock::
index 43f225b1933c2c0506d8f4c3002343d91693c8ab..3f5e9fb56b3e441adfb54691af3e404c9b782f2c 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -29,6 +29,9 @@
 #define G_CLOCK_H
 
 
+#include "types.h"
+
+
 namespace giada {
 namespace m {
 namespace clock
@@ -60,6 +63,7 @@ int getFramesInLoop();
 int getFramesInSeq();
 int getQuantize();
 int getQuanto();
+ClockStatus getStatus();
 
 /* incrCurrentFrame
 Increases current frame of a single step (+1). */
@@ -86,14 +90,23 @@ void setBars(int b);
 void setBeats(int b);
 void setQuantize(int q);
 
+/* isRunning
+When clock is actually moving forward, i.e. ClockStatus == RUNNING. */
+
 bool isRunning();
+
+/* isActive
+Clock is enabled, but might be in wait mode, i.e. ClockStatus == RUNNING or
+ClockStatus == WAITING. */
+
+bool isActive();
+
 bool isOnBeat();
 bool isOnBar();
 bool isOnFirstBeat();
 
 void rewind();
-void start();
-void stop();
+void setStatus(ClockStatus s);
 }}}; // giada::m::clock::
 
 
index 975543cb3d0ab5b90fe7c9f9984103b5b7c249fe..ce69e9faa1a43462e5eb2d02c9592cd18205f1a0 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -31,6 +31,7 @@
 #include "../utils/log.h"
 #include "storager.h"
 #include "const.h"
+#include "types.h"
 #include "conf.h"
 
 
@@ -60,7 +61,6 @@ void sanitize()
        if (channelsOut < 0) channelsOut = 0;
        if (channelsIn < 0)  channelsIn  = 0;
        if (buffersize < G_MIN_BUF_SIZE || buffersize > G_MAX_BUF_SIZE) buffersize = G_DEFAULT_BUFSIZE;
-       if (delayComp < 0) delayComp = G_DEFAULT_DELAYCOMP;
        if (midiPortOut < -1) midiPortOut = G_DEFAULT_MIDI_SYSTEM;
        if (midiPortOut < -1) midiPortOut = G_DEFAULT_MIDI_PORT_OUT;
        if (midiPortIn < -1) midiPortIn = G_DEFAULT_MIDI_PORT_IN;
@@ -79,16 +79,16 @@ void sanitize()
        if (sampleActionEditorH <= 0) sampleActionEditorH = 40;
        if (velocityEditorH <= 0) velocityEditorH = 40;
        if (envelopeEditorH <= 0) envelopeEditorH = 40;
-  if (sampleEditorX < 0) sampleEditorX = 0;
+       if (sampleEditorX < 0) sampleEditorX = 0;
        if (sampleEditorY < 0) sampleEditorY = 0;
        if (sampleEditorW < 500) sampleEditorW = 500;
        if (sampleEditorH < 292) sampleEditorH = 292;
        if (sampleEditorGridVal < 0 || sampleEditorGridVal > G_MAX_GRID_VAL) sampleEditorGridVal = 0;
        if (sampleEditorGridOn < 0) sampleEditorGridOn = 0;
-  if (midiInputX < 0) midiInputX = 0;
-  if (midiInputY < 0) midiInputY = 0;
-  if (midiInputW < G_DEFAULT_MIDI_INPUT_UI_W) midiInputW = G_DEFAULT_MIDI_INPUT_UI_W;
-  if (midiInputH < G_DEFAULT_MIDI_INPUT_UI_H) midiInputH = G_DEFAULT_MIDI_INPUT_UI_H;
+       if (midiInputX < 0) midiInputX = 0;
+       if (midiInputY < 0) midiInputY = 0;
+       if (midiInputW < G_DEFAULT_MIDI_INPUT_UI_W) midiInputW = G_DEFAULT_MIDI_INPUT_UI_W;
+       if (midiInputH < G_DEFAULT_MIDI_INPUT_UI_H) midiInputH = G_DEFAULT_MIDI_INPUT_UI_H;
        if (configX < 0) configX = 0;
        if (configY < 0) configY = 0;
        if (pluginListX < 0) pluginListX = 0;
@@ -158,7 +158,6 @@ int  channelsOut    = 0;
 int  channelsIn     = 0;
 int  samplerate     = G_DEFAULT_SAMPLERATE;
 int  buffersize     = G_DEFAULT_BUFSIZE;
-int  delayComp      = G_DEFAULT_DELAYCOMP;
 bool limitOutput    = false;
 int  rsmpQuality    = 0;
 
@@ -249,6 +248,9 @@ int aboutY = 0;
 int nameX = 0;
 int nameY = 0;
 
+int   recTriggerMode  = static_cast<int>(RecTriggerMode::NORMAL);
+float recTriggerLevel = G_DEFAULT_REC_TRIGGER_LEVEL;
+
 #ifdef WITH_VST
 
 int pluginChooserX   = 0;
@@ -320,7 +322,6 @@ int read()
        if (!storager::setInt(jRoot, CONF_KEY_CHANNELS_IN, channelsIn)) return 0;
        if (!storager::setInt(jRoot, CONF_KEY_SAMPLERATE, samplerate)) return 0;
        if (!storager::setInt(jRoot, CONF_KEY_BUFFER_SIZE, buffersize)) return 0;
-       if (!storager::setInt(jRoot, CONF_KEY_DELAY_COMPENSATION, delayComp)) return 0;
        if (!storager::setBool(jRoot, CONF_KEY_LIMIT_OUTPUT, limitOutput)) return 0;
        if (!storager::setInt(jRoot, CONF_KEY_RESAMPLE_QUALITY, rsmpQuality)) return 0;
        if (!storager::setInt(jRoot, CONF_KEY_MIDI_SYSTEM, midiSystem)) return 0;
@@ -387,12 +388,14 @@ int read()
        if (!storager::setInt(jRoot, CONF_KEY_BEATS_Y, beatsY)) return 0;
        if (!storager::setInt(jRoot, CONF_KEY_ABOUT_X, aboutX)) return 0;
        if (!storager::setInt(jRoot, CONF_KEY_ABOUT_Y, aboutY)) return 0;
-  if (!storager::setInt(jRoot, CONF_KEY_NAME_X, nameX)) return 0;
-  if (!storager::setInt(jRoot, CONF_KEY_NAME_Y, nameY)) return 0;
-  if (!storager::setInt(jRoot, CONF_KEY_MIDI_INPUT_X, midiInputX)) return 0;
-  if (!storager::setInt(jRoot, CONF_KEY_MIDI_INPUT_Y, midiInputY)) return 0;
-  if (!storager::setInt(jRoot, CONF_KEY_MIDI_INPUT_W, midiInputW)) return 0;
-  if (!storager::setInt(jRoot, CONF_KEY_MIDI_INPUT_H, midiInputH)) return 0;
+       if (!storager::setInt(jRoot, CONF_KEY_NAME_X, nameX)) return 0;
+       if (!storager::setInt(jRoot, CONF_KEY_NAME_Y, nameY)) return 0;
+       if (!storager::setInt(jRoot, CONF_KEY_MIDI_INPUT_X, midiInputX)) return 0;
+       if (!storager::setInt(jRoot, CONF_KEY_MIDI_INPUT_Y, midiInputY)) return 0;
+       if (!storager::setInt(jRoot, CONF_KEY_MIDI_INPUT_W, midiInputW)) return 0;
+       if (!storager::setInt(jRoot, CONF_KEY_MIDI_INPUT_H, midiInputH)) return 0;
+       if (!storager::setInt(jRoot, CONF_KEY_REC_TRIGGER_MODE, recTriggerMode)) return 0;
+       if (!storager::setFloat(jRoot, CONF_KEY_REC_TRIGGER_LEVEL, recTriggerLevel)) return 0;
 
 #ifdef WITH_VST
 
@@ -431,7 +434,6 @@ int write()
        json_object_set_new(jRoot, CONF_KEY_CHANNELS_IN,               json_integer(channelsIn));
        json_object_set_new(jRoot, CONF_KEY_SAMPLERATE,                json_integer(samplerate));
        json_object_set_new(jRoot, CONF_KEY_BUFFER_SIZE,               json_integer(buffersize));
-       json_object_set_new(jRoot, CONF_KEY_DELAY_COMPENSATION,        json_integer(delayComp));
        json_object_set_new(jRoot, CONF_KEY_LIMIT_OUTPUT,              json_boolean(limitOutput));
        json_object_set_new(jRoot, CONF_KEY_RESAMPLE_QUALITY,          json_integer(rsmpQuality));
        json_object_set_new(jRoot, CONF_KEY_MIDI_SYSTEM,               json_integer(midiSystem));
@@ -445,13 +447,13 @@ int write()
        json_object_set_new(jRoot, CONF_KEY_MIDI_IN_FILTER,            json_integer(midiInFilter));
        json_object_set_new(jRoot, CONF_KEY_MIDI_IN_REWIND,            json_integer(midiInRewind));
        json_object_set_new(jRoot, CONF_KEY_MIDI_IN_START_STOP,        json_integer(midiInStartStop));
-       json_object_set_new(jRoot, CONF_KEY_MIDI_IN_ACTION_REC,            json_integer(midiInActionRec));
-       json_object_set_new(jRoot, CONF_KEY_MIDI_IN_INPUT_REC,               json_integer(midiInInputRec));
-       json_object_set_new(jRoot, CONF_KEY_MIDI_IN_METRONOME,               json_integer(midiInMetronome));
-       json_object_set_new(jRoot, CONF_KEY_MIDI_IN_VOLUME_IN,               json_integer(midiInVolumeIn));
-       json_object_set_new(jRoot, CONF_KEY_MIDI_IN_VOLUME_OUT,              json_integer(midiInVolumeOut));
-       json_object_set_new(jRoot, CONF_KEY_MIDI_IN_BEAT_DOUBLE,           json_integer(midiInBeatDouble));
-       json_object_set_new(jRoot, CONF_KEY_MIDI_IN_BEAT_HALF,               json_integer(midiInBeatHalf));
+       json_object_set_new(jRoot, CONF_KEY_MIDI_IN_ACTION_REC,        json_integer(midiInActionRec));
+       json_object_set_new(jRoot, CONF_KEY_MIDI_IN_INPUT_REC,         json_integer(midiInInputRec));
+       json_object_set_new(jRoot, CONF_KEY_MIDI_IN_METRONOME,         json_integer(midiInMetronome));
+       json_object_set_new(jRoot, CONF_KEY_MIDI_IN_VOLUME_IN,         json_integer(midiInVolumeIn));
+       json_object_set_new(jRoot, CONF_KEY_MIDI_IN_VOLUME_OUT,        json_integer(midiInVolumeOut));
+       json_object_set_new(jRoot, CONF_KEY_MIDI_IN_BEAT_DOUBLE,       json_integer(midiInBeatDouble));
+       json_object_set_new(jRoot, CONF_KEY_MIDI_IN_BEAT_HALF,         json_integer(midiInBeatHalf));
        json_object_set_new(jRoot, CONF_KEY_RECS_STOP_ON_CHAN_HALT,    json_boolean(recsStopOnChanHalt));
        json_object_set_new(jRoot, CONF_KEY_CHANS_STOP_ON_SEQ_HALT,    json_boolean(chansStopOnSeqHalt));
        json_object_set_new(jRoot, CONF_KEY_TREAT_RECS_AS_LOOPS,       json_boolean(treatRecsAsLoops));
@@ -504,6 +506,8 @@ int write()
        json_object_set_new(jRoot, CONF_KEY_MIDI_INPUT_Y,              json_integer(midiInputY));
        json_object_set_new(jRoot, CONF_KEY_MIDI_INPUT_W,              json_integer(midiInputW));
        json_object_set_new(jRoot, CONF_KEY_MIDI_INPUT_H,              json_integer(midiInputH));
+       json_object_set_new(jRoot, CONF_KEY_REC_TRIGGER_MODE,          json_integer(recTriggerMode));
+       json_object_set_new(jRoot, CONF_KEY_REC_TRIGGER_LEVEL,         json_real(recTriggerLevel));
 
 #ifdef WITH_VST
 
index dd2c53b3c3c0a674fdb3bfb49031cb255dae2216..b7aca0f77ec6532ed0e84d490f0adef3d47c8628 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -56,7 +56,6 @@ extern int  channelsOut;
 extern int  channelsIn;
 extern int  samplerate;
 extern int  buffersize;
-extern int  delayComp;
 extern bool limitOutput;
 extern int  rsmpQuality;
 
@@ -115,6 +114,9 @@ extern int beatsX, beatsY;
 extern int aboutX, aboutY;
 extern int nameX, nameY;
 
+extern int   recTriggerMode;
+extern float recTriggerLevel;
+
 #ifdef WITH_VST
 
 extern int pluginChooserX, pluginChooserY, pluginChooserW, pluginChooserH;
index 81e38c91fab5fb35f286b52530b8ae22fce71901..0bf91075bcb34cc2ba7f8d57537ad14e428e7f4a 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
 
 
 /* -- version --------------------------------------------------------------- */
-#define G_APP_NAME      "Giada"
-#define G_VERSION_STR   "0.15.3"
-#define G_VERSION_MAJOR 0
-#define G_VERSION_MINOR 15
-#define G_VERSION_PATCH 3
+constexpr auto G_APP_NAME      = "Giada";
+constexpr auto G_VERSION_STR   = "0.15.4";
+constexpr int  G_VERSION_MAJOR = 0;
+constexpr int  G_VERSION_MINOR = 15;
+constexpr int  G_VERSION_PATCH = 4;
 
-#define CONF_FILENAME "giada.conf"
+constexpr auto CONF_FILENAME = "giada.conf";
 
 #ifdef G_OS_WINDOWS
        #define G_SLASH '\\'
@@ -117,21 +117,21 @@ constexpr int   G_MAX_POLYPHONY    = 32;
 
 
 /* -- kernel audio ---------------------------------------------------------- */
-#define G_SYS_API_NONE    0x00  // 0000 0000
-#define G_SYS_API_JACK    0x01  // 0000 0001
-#define G_SYS_API_ALSA    0x02  // 0000 0010
-#define G_SYS_API_DS      0x04  // 0000 0100
-#define G_SYS_API_ASIO    0x08  // 0000 1000
-#define G_SYS_API_CORE    0x10  // 0001 0000
-#define G_SYS_API_PULSE   0x20  // 0010 0000
-#define G_SYS_API_WASAPI  0x40  // 0100 0000
-#define G_SYS_API_ANY     0x7F  // 0111 1111
+constexpr int G_SYS_API_NONE   = 0x00;  // 0000 0000
+constexpr int G_SYS_API_JACK   = 0x01;  // 0000 0001
+constexpr int G_SYS_API_ALSA   = 0x02;  // 0000 0010
+constexpr int G_SYS_API_DS     = 0x04;  // 0000 0100
+constexpr int G_SYS_API_ASIO   = 0x08;  // 0000 1000
+constexpr int G_SYS_API_CORE   = 0x10;  // 0001 0000
+constexpr int G_SYS_API_PULSE  = 0x20;  // 0010 0000
+constexpr int G_SYS_API_WASAPI = 0x40;  // 0100 0000
+constexpr int G_SYS_API_ANY    = 0x7F;  // 0111 1111
 
 
 
 /* -- kernel midi ----------------------------------------------------------- */
-#define G_MIDI_API_JACK   0x01  // 0000 0001
-#define G_MIDI_API_ALSA   0x02  // 0000 0010
+constexpr int G_MIDI_API_JACK = 0x01;  // 0000 0001
+constexpr int G_MIDI_API_ALSA = 0x02;  // 0000 0010
 
 
 
@@ -144,45 +144,31 @@ constexpr int   G_MAX_POLYPHONY    = 32;
        #define G_DEFAULT_SOUNDSYS      G_SYS_API_CORE
 #endif
 
-#define G_DEFAULT_SOUNDDEV_OUT     0      // FIXME - please override with rtAudio::getDefaultDevice (or similar)
-#define G_DEFAULT_SOUNDDEV_IN     -1      // no recording by default: input disabled
-#define G_DEFAULT_MIDI_SYSTEM      0
-#define G_DEFAULT_MIDI_PORT_IN    -1
-#define G_DEFAULT_MIDI_PORT_OUT   -1
-#define G_DEFAULT_SAMPLERATE       44100
-#define G_DEFAULT_BUFSIZE          1024
-#define G_DEFAULT_DELAYCOMP        0
-#define G_DEFAULT_BIT_DEPTH        32     // float
-#define G_DEFAULT_VOL              1.0f
-#define G_DEFAULT_PITCH            1.0f
-#define G_DEFAULT_BOOST            1.0f
-#define G_DEFAULT_OUT_VOL          1.0f
-#define G_DEFAULT_IN_VOL           1.0f
-#define G_DEFAULT_BPM              120.0f
-#define G_DEFAULT_BEATS            4
-#define G_DEFAULT_BARS             1
-#define G_DEFAULT_QUANTIZE         0      // quantizer off
-#define G_DEFAULT_FADEOUT_STEP     0.01f  // micro-fadeout speed
-#define G_DEFAULT_COLUMN_WIDTH     380
-#define G_DEFAULT_PATCH_NAME       "(default patch)"
-#define G_DEFAULT_MIDI_INPUT_UI_W  300
-#define G_DEFAULT_MIDI_INPUT_UI_H  350
-#define G_DEFAULT_ACTION_SIZE      8192  // frames
-#define G_DEFAULT_ZOOM_RATIO       128
-
-
-
-/* -- actions --------------------------------------------------------------- */
-#define G_ACTION_KEYPRESS              0x01 // 0000 0001
-#define G_ACTION_KEYREL                        0x02 // 0000 0010
-#define G_ACTION_KILL              0x04 // 0000 0100
-#define G_ACTION_VOLUME     0x20 // 0010 0000
-#define G_ACTION_MIDI       0x40 // 0100 0000
-
-#define G_ACTION_KEYS       0x03 // 0000 0011 any key
-
-#define G_RANGE_CHAR        0x01 // range for MIDI (0-127)
-#define G_RANGE_FLOAT       0x02 // range for volumes and VST params (0.0-1.0)
+constexpr int   G_DEFAULT_SOUNDDEV_OUT      = 0;      // FIXME - please override with rtAudio::getDefaultDevice (or similar)
+constexpr int   G_DEFAULT_SOUNDDEV_IN       = -1;     // no recording by default: input disabled
+constexpr int   G_DEFAULT_MIDI_SYSTEM       = 0;
+constexpr int   G_DEFAULT_MIDI_PORT_IN      = -1;
+constexpr int   G_DEFAULT_MIDI_PORT_OUT     = -1;
+constexpr int   G_DEFAULT_SAMPLERATE        = 44100;
+constexpr int   G_DEFAULT_BUFSIZE           = 1024;
+constexpr int   G_DEFAULT_BIT_DEPTH         = 32;     // float
+constexpr float G_DEFAULT_VOL               = 1.0f;
+constexpr float G_DEFAULT_PITCH             = 1.0f;
+constexpr float G_DEFAULT_BOOST             = 1.0f;
+constexpr float G_DEFAULT_OUT_VOL           = 1.0f;
+constexpr float G_DEFAULT_IN_VOL            = 1.0f;
+constexpr float G_DEFAULT_BPM               = 120.0f;
+constexpr int   G_DEFAULT_BEATS             = 4;
+constexpr int   G_DEFAULT_BARS              = 1;
+constexpr int   G_DEFAULT_QUANTIZE          = 0;      // quantizer off
+constexpr float G_DEFAULT_FADEOUT_STEP      = 0.01f;  // micro-fadeout speed
+constexpr int   G_DEFAULT_COLUMN_WIDTH      = 380;
+constexpr auto  G_DEFAULT_PATCH_NAME        = "(default patch)";
+constexpr int   G_DEFAULT_MIDI_INPUT_UI_W   = 300;
+constexpr int   G_DEFAULT_MIDI_INPUT_UI_H   = 350;
+constexpr int   G_DEFAULT_ACTION_SIZE       = 8192;  // frames
+constexpr int   G_DEFAULT_ZOOM_RATIO        = 128;
+constexpr float G_DEFAULT_REC_TRIGGER_LEVEL = -10.0f;
 
 
 
@@ -239,17 +225,11 @@ constexpr int   G_MAX_POLYPHONY    = 32;
 
 
 /* -- MIDI signals -------------------------------------------------------------
-All signals are set to channel 0 (where channels are considered). It's up to the
-caller to bitmask them with the proper channel number.
 Channel voices messages - controller (0xB0) is a special subset of this family:
 it drives knobs, volume, faders and such. */
 
 #define MIDI_CONTROLLER     0xB0 << 24
-#define MIDI_NOTE_ON        0x90 << 24
-#define MIDI_NOTE_OFF       0x80 << 24
-#define MIDI_VELOCITY       0x3F <<  8
 #define MIDI_ALL_NOTES_OFF (MIDI_CONTROLLER) | (0x7B << 16)
-#define MIDI_VOLUME        (MIDI_CONTROLLER) | (0x07 << 16)
 
 /* system common / real-time messages. Single bytes */
 
@@ -281,188 +261,189 @@ constexpr int G_MIDI_CHANS[G_MAX_MIDI_CHANS] = {
 
 /* JSON patch keys */
 
-#define PATCH_KEY_HEADER                       "header"
-#define PATCH_KEY_VERSION                      "version"
-#define PATCH_KEY_VERSION_MAJOR                "version_major"
-#define PATCH_KEY_VERSION_MINOR                "version_minor"
-#define PATCH_KEY_VERSION_PATCH                "version_patch"
-#define PATCH_KEY_NAME                         "name"
-#define PATCH_KEY_BPM                          "bpm"
-#define PATCH_KEY_BARS                         "bars"
-#define PATCH_KEY_BEATS                        "beats"
-#define PATCH_KEY_QUANTIZE                     "quantize"
-#define PATCH_KEY_MASTER_VOL_IN                "master_vol_in"
-#define PATCH_KEY_MASTER_VOL_OUT               "master_vol_out"
-#define PATCH_KEY_METRONOME                    "metronome"
-#define PATCH_KEY_LAST_TAKE_ID                 "last_take_id"
-#define PATCH_KEY_SAMPLERATE                   "samplerate"
-#define PATCH_KEY_COLUMNS                      "columns"
-#define PATCH_KEY_MASTER_OUT_PLUGINS           "master_out_plugins"
-#define PATCH_KEY_MASTER_IN_PLUGINS            "master_in_plugins"
-#define PATCH_KEY_CHANNELS                     "channels"
-#define PATCH_KEY_CHANNEL_TYPE                 "type"
-#define PATCH_KEY_CHANNEL_INDEX                "index"
-#define PATCH_KEY_CHANNEL_SIZE                 "size"
-#define PATCH_KEY_CHANNEL_NAME                 "name"
-#define PATCH_KEY_CHANNEL_COLUMN               "column"
-#define PATCH_KEY_CHANNEL_MUTE                 "mute"
-#define PATCH_KEY_CHANNEL_SOLO                 "solo"
-#define PATCH_KEY_CHANNEL_VOLUME               "volume"
-#define PATCH_KEY_CHANNEL_PAN                  "pan"
-#define PATCH_KEY_CHANNEL_MIDI_IN              "midi_in"
-#define PATCH_KEY_CHANNEL_MIDI_IN_VELO_AS_VOL  "midi_in_velo_as_vol"
-#define PATCH_KEY_CHANNEL_MIDI_IN_KEYPRESS     "midi_in_keypress"
-#define PATCH_KEY_CHANNEL_MIDI_IN_KEYREL       "midi_in_keyrel"
-#define PATCH_KEY_CHANNEL_MIDI_IN_KILL         "midi_in_kill"
-#define PATCH_KEY_CHANNEL_MIDI_IN_ARM          "midi_in_arm"
-#define PATCH_KEY_CHANNEL_MIDI_IN_VOLUME       "midi_in_volume"
-#define PATCH_KEY_CHANNEL_MIDI_IN_MUTE         "midi_in_mute"
-#define PATCH_KEY_CHANNEL_MIDI_IN_FILTER       "midi_in_filter"
-#define PATCH_KEY_CHANNEL_MIDI_IN_SOLO         "midi_in_solo"
-#define PATCH_KEY_CHANNEL_MIDI_OUT_L           "midi_out_l"
-#define PATCH_KEY_CHANNEL_MIDI_OUT_L_PLAYING   "midi_out_l_playing"
-#define PATCH_KEY_CHANNEL_MIDI_OUT_L_MUTE      "midi_out_l_mute"
-#define PATCH_KEY_CHANNEL_MIDI_OUT_L_SOLO      "midi_out_l_solo"
-#define PATCH_KEY_CHANNEL_SAMPLE_PATH          "sample_path"
-#define PATCH_KEY_CHANNEL_KEY                  "key"
-#define PATCH_KEY_CHANNEL_MODE                 "mode"
-#define PATCH_KEY_CHANNEL_BEGIN                "begin"
-#define PATCH_KEY_CHANNEL_END                  "end"
-#define PATCH_KEY_CHANNEL_BOOST                "boost"
-#define PATCH_KEY_CHANNEL_REC_ACTIVE           "rec_active"
-#define PATCH_KEY_CHANNEL_PITCH                "pitch"
-#define PATCH_KEY_CHANNEL_INPUT_MONITOR        "input_monitor"
-#define PATCH_KEY_CHANNEL_MIDI_IN_READ_ACTIONS "midi_in_read_actions"
-#define PATCH_KEY_CHANNEL_MIDI_IN_PITCH        "midi_in_pitch"
-#define PATCH_KEY_CHANNEL_MIDI_OUT             "midi_out"
-#define PATCH_KEY_CHANNEL_MIDI_OUT_CHAN        "midi_out_chan"
-#define PATCH_KEY_CHANNEL_PLUGINS              "plugins"
-#define PATCH_KEY_CHANNEL_ACTIONS              "actions"
-#define PATCH_KEY_CHANNEL_ARMED                "armed"
-#define PATCH_KEY_ACTION_TYPE                  "type"
-#define PATCH_KEY_ACTION_FRAME                 "frame"
-#define PATCH_KEY_ACTION_F_VALUE               "f_value"
-#define PATCH_KEY_ACTION_I_VALUE               "i_value"
-#define PATCH_KEY_PLUGIN_PATH                  "path"
-#define PATCH_KEY_PLUGIN_BYPASS                "bypass"
-#define PATCH_KEY_PLUGIN_PARAMS                "params"
-#define PATCH_KEY_PLUGIN_MIDI_IN_PARAMS        "midi_in_params"
-#define PATCH_KEY_COLUMN_INDEX                 "index"
-#define PATCH_KEY_COLUMN_WIDTH                 "width"
-#define PATCH_KEY_COLUMN_CHANNELS              "channels"
-
-#define G_PATCH_KEY_ACTION_ID                  "id"
-#define G_PATCH_KEY_ACTION_CHANNEL             "channel"     
-#define G_PATCH_KEY_ACTION_FRAME               "frame"   
-#define G_PATCH_KEY_ACTION_EVENT               "event"   
-#define G_PATCH_KEY_ACTION_PREV                "prev"  
-#define G_PATCH_KEY_ACTION_NEXT                "next"
+constexpr auto PATCH_KEY_HEADER                       = "header";
+constexpr auto PATCH_KEY_VERSION                      = "version";
+constexpr auto PATCH_KEY_VERSION_MAJOR                = "version_major";
+constexpr auto PATCH_KEY_VERSION_MINOR                = "version_minor";
+constexpr auto PATCH_KEY_VERSION_PATCH                = "version_patch";
+constexpr auto PATCH_KEY_NAME                         = "name";
+constexpr auto PATCH_KEY_BPM                          = "bpm";
+constexpr auto PATCH_KEY_BARS                         = "bars";
+constexpr auto PATCH_KEY_BEATS                        = "beats";
+constexpr auto PATCH_KEY_QUANTIZE                     = "quantize";
+constexpr auto PATCH_KEY_MASTER_VOL_IN                = "master_vol_in";
+constexpr auto PATCH_KEY_MASTER_VOL_OUT               = "master_vol_out";
+constexpr auto PATCH_KEY_METRONOME                    = "metronome";
+constexpr auto PATCH_KEY_LAST_TAKE_ID                 = "last_take_id";
+constexpr auto PATCH_KEY_SAMPLERATE                   = "samplerate";
+constexpr auto PATCH_KEY_COLUMNS                      = "columns";
+constexpr auto PATCH_KEY_MASTER_OUT_PLUGINS           = "master_out_plugins";
+constexpr auto PATCH_KEY_MASTER_IN_PLUGINS            = "master_in_plugins";
+constexpr auto PATCH_KEY_CHANNELS                     = "channels";
+constexpr auto PATCH_KEY_CHANNEL_TYPE                 = "type";
+constexpr auto PATCH_KEY_CHANNEL_INDEX                = "index";
+constexpr auto PATCH_KEY_CHANNEL_SIZE                 = "size";
+constexpr auto PATCH_KEY_CHANNEL_NAME                 = "name";
+constexpr auto PATCH_KEY_CHANNEL_COLUMN               = "column";
+constexpr auto PATCH_KEY_CHANNEL_MUTE                 = "mute";
+constexpr auto PATCH_KEY_CHANNEL_SOLO                 = "solo";
+constexpr auto PATCH_KEY_CHANNEL_VOLUME               = "volume";
+constexpr auto PATCH_KEY_CHANNEL_PAN                  = "pan";
+constexpr auto PATCH_KEY_CHANNEL_MIDI_IN              = "midi_in";
+constexpr auto PATCH_KEY_CHANNEL_MIDI_IN_VELO_AS_VOL  = "midi_in_velo_as_vol";
+constexpr auto PATCH_KEY_CHANNEL_MIDI_IN_KEYPRESS     = "midi_in_keypress";
+constexpr auto PATCH_KEY_CHANNEL_MIDI_IN_KEYREL       = "midi_in_keyrel";
+constexpr auto PATCH_KEY_CHANNEL_MIDI_IN_KILL         = "midi_in_kill";
+constexpr auto PATCH_KEY_CHANNEL_MIDI_IN_ARM          = "midi_in_arm";
+constexpr auto PATCH_KEY_CHANNEL_MIDI_IN_VOLUME       = "midi_in_volume";
+constexpr auto PATCH_KEY_CHANNEL_MIDI_IN_MUTE         = "midi_in_mute";
+constexpr auto PATCH_KEY_CHANNEL_MIDI_IN_FILTER       = "midi_in_filter";
+constexpr auto PATCH_KEY_CHANNEL_MIDI_IN_SOLO         = "midi_in_solo";
+constexpr auto PATCH_KEY_CHANNEL_MIDI_OUT_L           = "midi_out_l";
+constexpr auto PATCH_KEY_CHANNEL_MIDI_OUT_L_PLAYING   = "midi_out_l_playing";
+constexpr auto PATCH_KEY_CHANNEL_MIDI_OUT_L_MUTE      = "midi_out_l_mute";
+constexpr auto PATCH_KEY_CHANNEL_MIDI_OUT_L_SOLO      = "midi_out_l_solo";
+constexpr auto PATCH_KEY_CHANNEL_SAMPLE_PATH          = "sample_path";
+constexpr auto PATCH_KEY_CHANNEL_KEY                  = "key";
+constexpr auto PATCH_KEY_CHANNEL_MODE                 = "mode";
+constexpr auto PATCH_KEY_CHANNEL_BEGIN                = "begin";
+constexpr auto PATCH_KEY_CHANNEL_END                  = "end";
+constexpr auto PATCH_KEY_CHANNEL_BOOST                = "boost";
+constexpr auto PATCH_KEY_CHANNEL_READ_ACTIONS         = "rec_active";  // TODO update string key in 1.0
+constexpr auto PATCH_KEY_CHANNEL_PITCH                = "pitch";
+constexpr auto PATCH_KEY_CHANNEL_INPUT_MONITOR        = "input_monitor";
+constexpr auto PATCH_KEY_CHANNEL_MIDI_IN_READ_ACTIONS = "midi_in_read_actions";
+constexpr auto PATCH_KEY_CHANNEL_MIDI_IN_PITCH        = "midi_in_pitch";
+constexpr auto PATCH_KEY_CHANNEL_MIDI_OUT             = "midi_out";
+constexpr auto PATCH_KEY_CHANNEL_MIDI_OUT_CHAN        = "midi_out_chan";
+constexpr auto PATCH_KEY_CHANNEL_PLUGINS              = "plugins";
+constexpr auto PATCH_KEY_CHANNEL_ACTIONS              = "actions";
+constexpr auto PATCH_KEY_CHANNEL_ARMED                = "armed";
+constexpr auto PATCH_KEY_ACTION_TYPE                  = "type";
+constexpr auto PATCH_KEY_ACTION_FRAME                 = "frame";
+constexpr auto PATCH_KEY_ACTION_F_VALUE               = "f_value";
+constexpr auto PATCH_KEY_ACTION_I_VALUE               = "i_value";
+constexpr auto PATCH_KEY_PLUGIN_PATH                  = "path";
+constexpr auto PATCH_KEY_PLUGIN_BYPASS                = "bypass";
+constexpr auto PATCH_KEY_PLUGIN_PARAMS                = "params";
+constexpr auto PATCH_KEY_PLUGIN_MIDI_IN_PARAMS        = "midi_in_params";
+constexpr auto PATCH_KEY_COLUMN_INDEX                 = "index";
+constexpr auto PATCH_KEY_COLUMN_WIDTH                 = "width";
+constexpr auto PATCH_KEY_COLUMN_CHANNELS              = "channels";
+constexpr auto G_PATCH_KEY_ACTION_ID                  = "id";
+constexpr auto G_PATCH_KEY_ACTION_CHANNEL             = "channel";     
+constexpr auto G_PATCH_KEY_ACTION_FRAME               = "frame";   
+constexpr auto G_PATCH_KEY_ACTION_EVENT               = "event";   
+constexpr auto G_PATCH_KEY_ACTION_PREV                = "prev";  
+constexpr auto G_PATCH_KEY_ACTION_NEXT                = "next";
 
 /* JSON config keys */
 
-#define CONF_KEY_HEADER                   "header"
-#define CONF_KEY_LOG_MODE                 "log_mode"
-#define CONF_KEY_SOUND_SYSTEM             "sound_system"
-#define CONF_KEY_SOUND_DEVICE_IN          "sound_device_in"
-#define CONF_KEY_SOUND_DEVICE_OUT         "sound_device_out"
-#define CONF_KEY_CHANNELS_IN              "channels_in"
-#define CONF_KEY_CHANNELS_OUT             "channels_out"
-#define CONF_KEY_SAMPLERATE               "samplerate"
-#define CONF_KEY_BUFFER_SIZE              "buffer_size"
-#define CONF_KEY_DELAY_COMPENSATION       "delay_compensation"
-#define CONF_KEY_LIMIT_OUTPUT             "limit_output"
-#define CONF_KEY_RESAMPLE_QUALITY         "resample_quality"
-#define CONF_KEY_MIDI_SYSTEM              "midi_system"
-#define CONF_KEY_MIDI_PORT_OUT            "midi_port_out"
-#define CONF_KEY_MIDI_PORT_IN             "midi_port_in"
-#define CONF_KEY_MIDIMAP_PATH             "midimap_path"
-#define CONF_KEY_LAST_MIDIMAP             "last_midimap"
-#define CONF_KEY_MIDI_SYNC                "midi_sync"
-#define CONF_KEY_MIDI_TC_FPS              "midi_tc_fps"
-#define CONF_KEY_MIDI_IN                  "midi_in"
-#define CONF_KEY_MIDI_IN_FILTER           "midi_in_filter"
-#define CONF_KEY_MIDI_IN_REWIND           "midi_in_rewind"
-#define CONF_KEY_MIDI_IN_START_STOP       "midi_in_start_stop"
-#define CONF_KEY_MIDI_IN_ACTION_REC       "midi_in_action_rec"
-#define CONF_KEY_MIDI_IN_INPUT_REC        "midi_in_input_rec"
-#define CONF_KEY_MIDI_IN_METRONOME        "midi_in_metronome"
-#define CONF_KEY_MIDI_IN_VOLUME_IN        "midi_in_volume_in"
-#define CONF_KEY_MIDI_IN_VOLUME_OUT       "midi_in_volume_out"
-#define CONF_KEY_MIDI_IN_BEAT_DOUBLE      "midi_in_beat_doble"
-#define CONF_KEY_MIDI_IN_BEAT_HALF        "midi_in_beat_half"
-#define CONF_KEY_RECS_STOP_ON_CHAN_HALT   "recs_stop_on_chan_halt"
-#define CONF_KEY_CHANS_STOP_ON_SEQ_HALT   "chans_stop_on_seq_halt"
-#define CONF_KEY_TREAT_RECS_AS_LOOPS      "treat_recs_as_loops"
-#define CONF_KEY_INPUT_MONITOR_DEFAULT_ON "input_monitor_default_on"
-#define CONF_KEY_PLUGINS_PATH             "plugins_path"
-#define CONF_KEY_PATCHES_PATH             "patches_path"
-#define CONF_KEY_SAMPLES_PATH             "samples_path"
-#define CONF_KEY_MAIN_WINDOW_X            "main_window_x"
-#define CONF_KEY_MAIN_WINDOW_Y            "main_window_y"
-#define CONF_KEY_MAIN_WINDOW_W            "main_window_w"
-#define CONF_KEY_MAIN_WINDOW_H            "main_window_h"
-#define CONF_KEY_BROWSER_X                "browser_x"
-#define CONF_KEY_BROWSER_Y                "browser_y"
-#define CONF_KEY_BROWSER_W                "browser_w"
-#define CONF_KEY_BROWSER_H                "browser_h"
-#define CONF_KEY_BROWSER_POSITION         "browser_position"
-#define CONF_KEY_BROWSER_LAST_PATH        "browser_last_path"
-#define CONF_KEY_BROWSER_LAST_VALUE       "browser_last_value"
-#define CONF_KEY_ACTION_EDITOR_X          "action_editor_x"
-#define CONF_KEY_ACTION_EDITOR_Y          "action_editor_y"
-#define CONF_KEY_ACTION_EDITOR_W          "action_editor_w"
-#define CONF_KEY_ACTION_EDITOR_H          "action_editor_h"
-#define CONF_KEY_ACTION_EDITOR_ZOOM       "action_editor_zoom"
-#define CONF_KEY_ACTION_EDITOR_GRID_VAL   "action_editor_grid_val"
-#define CONF_KEY_ACTION_EDITOR_GRID_ON    "action_editor_grid_on"
-#define CONF_KEY_SAMPLE_EDITOR_X          "sample_editor_x"
-#define CONF_KEY_SAMPLE_EDITOR_Y          "sample_editor_y"
-#define CONF_KEY_SAMPLE_EDITOR_W          "sample_editor_w"
-#define CONF_KEY_SAMPLE_EDITOR_H          "sample_editor_h"
-#define CONF_KEY_SAMPLE_EDITOR_GRID_VAL   "sample_editor_grid_val"
-#define CONF_KEY_SAMPLE_EDITOR_GRID_ON    "sample_editor_grid_on"
-#define CONF_KEY_PIANO_ROLL_Y             "piano_roll_y"
-#define CONF_KEY_PIANO_ROLL_H             "piano_roll_h"
-#define CONF_KEY_SAMPLE_ACTION_EDITOR_H   "sample_action_editor_h"
-#define CONF_KEY_VELOCITY_EDITOR_H        "velocity_editor_h"
-#define CONF_KEY_ENVELOPE_EDITOR_H        "envelope_editor_h"
-#define CONF_KEY_PLUGIN_LIST_X            "plugin_list_x"
-#define CONF_KEY_PLUGIN_LIST_Y            "plugin_list_y"
-#define CONF_KEY_CONFIG_X                 "config_x"
-#define CONF_KEY_CONFIG_Y                 "config_y"
-#define CONF_KEY_BPM_X                    "bpm_x"
-#define CONF_KEY_BPM_Y                    "bpm_y"
-#define CONF_KEY_BEATS_X                  "beats_x"
-#define CONF_KEY_BEATS_Y                  "beats_y"
-#define CONF_KEY_ABOUT_X                  "about_x"
-#define CONF_KEY_ABOUT_Y                  "about_y"
-#define CONF_KEY_NAME_X                   "name_x"
-#define CONF_KEY_NAME_Y                   "name_y"
-#define CONF_KEY_PLUGIN_CHOOSER_X         "plugin_chooser_x"
-#define CONF_KEY_PLUGIN_CHOOSER_Y         "plugin_chooser_y"
-#define CONF_KEY_PLUGIN_CHOOSER_W         "plugin_chooser_w"
-#define CONF_KEY_PLUGIN_CHOOSER_H         "plugin_chooser_h"
-#define CONF_KEY_MIDI_INPUT_X             "midi_input_x"
-#define CONF_KEY_MIDI_INPUT_Y             "midi_input_y"
-#define CONF_KEY_MIDI_INPUT_W             "midi_input_w"
-#define CONF_KEY_MIDI_INPUT_H             "midi_input_h"
-#define CONF_KEY_PLUGIN_SORT_METHOD       "plugin_sort_method"
+constexpr auto CONF_KEY_HEADER                   = "header";
+constexpr auto CONF_KEY_LOG_MODE                 = "log_mode";
+constexpr auto CONF_KEY_SOUND_SYSTEM             = "sound_system";
+constexpr auto CONF_KEY_SOUND_DEVICE_IN          = "sound_device_in";
+constexpr auto CONF_KEY_SOUND_DEVICE_OUT         = "sound_device_out";
+constexpr auto CONF_KEY_CHANNELS_IN              = "channels_in";
+constexpr auto CONF_KEY_CHANNELS_OUT             = "channels_out";
+constexpr auto CONF_KEY_SAMPLERATE               = "samplerate";
+constexpr auto CONF_KEY_BUFFER_SIZE              = "buffer_size";
+constexpr auto CONF_KEY_DELAY_COMPENSATION       = "delay_compensation";
+constexpr auto CONF_KEY_LIMIT_OUTPUT             = "limit_output";
+constexpr auto CONF_KEY_RESAMPLE_QUALITY         = "resample_quality";
+constexpr auto CONF_KEY_MIDI_SYSTEM              = "midi_system";
+constexpr auto CONF_KEY_MIDI_PORT_OUT            = "midi_port_out";
+constexpr auto CONF_KEY_MIDI_PORT_IN             = "midi_port_in";
+constexpr auto CONF_KEY_MIDIMAP_PATH             = "midimap_path";
+constexpr auto CONF_KEY_LAST_MIDIMAP             = "last_midimap";
+constexpr auto CONF_KEY_MIDI_SYNC                = "midi_sync";
+constexpr auto CONF_KEY_MIDI_TC_FPS              = "midi_tc_fps";
+constexpr auto CONF_KEY_MIDI_IN                  = "midi_in";
+constexpr auto CONF_KEY_MIDI_IN_FILTER           = "midi_in_filter";
+constexpr auto CONF_KEY_MIDI_IN_REWIND           = "midi_in_rewind";
+constexpr auto CONF_KEY_MIDI_IN_START_STOP       = "midi_in_start_stop";
+constexpr auto CONF_KEY_MIDI_IN_ACTION_REC       = "midi_in_action_rec";
+constexpr auto CONF_KEY_MIDI_IN_INPUT_REC        = "midi_in_input_rec";
+constexpr auto CONF_KEY_MIDI_IN_METRONOME        = "midi_in_metronome";
+constexpr auto CONF_KEY_MIDI_IN_VOLUME_IN        = "midi_in_volume_in";
+constexpr auto CONF_KEY_MIDI_IN_VOLUME_OUT       = "midi_in_volume_out";
+constexpr auto CONF_KEY_MIDI_IN_BEAT_DOUBLE      = "midi_in_beat_doble";
+constexpr auto CONF_KEY_MIDI_IN_BEAT_HALF        = "midi_in_beat_half";
+constexpr auto CONF_KEY_RECS_STOP_ON_CHAN_HALT   = "recs_stop_on_chan_halt";
+constexpr auto CONF_KEY_CHANS_STOP_ON_SEQ_HALT   = "chans_stop_on_seq_halt";
+constexpr auto CONF_KEY_TREAT_RECS_AS_LOOPS      = "treat_recs_as_loops";
+constexpr auto CONF_KEY_INPUT_MONITOR_DEFAULT_ON = "input_monitor_default_on";
+constexpr auto CONF_KEY_PLUGINS_PATH             = "plugins_path";
+constexpr auto CONF_KEY_PATCHES_PATH             = "patches_path";
+constexpr auto CONF_KEY_SAMPLES_PATH             = "samples_path";
+constexpr auto CONF_KEY_MAIN_WINDOW_X            = "main_window_x";
+constexpr auto CONF_KEY_MAIN_WINDOW_Y            = "main_window_y";
+constexpr auto CONF_KEY_MAIN_WINDOW_W            = "main_window_w";
+constexpr auto CONF_KEY_MAIN_WINDOW_H            = "main_window_h";
+constexpr auto CONF_KEY_BROWSER_X                = "browser_x";
+constexpr auto CONF_KEY_BROWSER_Y                = "browser_y";
+constexpr auto CONF_KEY_BROWSER_W                = "browser_w";
+constexpr auto CONF_KEY_BROWSER_H                = "browser_h";
+constexpr auto CONF_KEY_BROWSER_POSITION         = "browser_position";
+constexpr auto CONF_KEY_BROWSER_LAST_PATH        = "browser_last_path";
+constexpr auto CONF_KEY_BROWSER_LAST_VALUE       = "browser_last_value";
+constexpr auto CONF_KEY_ACTION_EDITOR_X          = "action_editor_x";
+constexpr auto CONF_KEY_ACTION_EDITOR_Y          = "action_editor_y";
+constexpr auto CONF_KEY_ACTION_EDITOR_W          = "action_editor_w";
+constexpr auto CONF_KEY_ACTION_EDITOR_H          = "action_editor_h";
+constexpr auto CONF_KEY_ACTION_EDITOR_ZOOM       = "action_editor_zoom";
+constexpr auto CONF_KEY_ACTION_EDITOR_GRID_VAL   = "action_editor_grid_val";
+constexpr auto CONF_KEY_ACTION_EDITOR_GRID_ON    = "action_editor_grid_on";
+constexpr auto CONF_KEY_SAMPLE_EDITOR_X          = "sample_editor_x";
+constexpr auto CONF_KEY_SAMPLE_EDITOR_Y          = "sample_editor_y";
+constexpr auto CONF_KEY_SAMPLE_EDITOR_W          = "sample_editor_w";
+constexpr auto CONF_KEY_SAMPLE_EDITOR_H          = "sample_editor_h";
+constexpr auto CONF_KEY_SAMPLE_EDITOR_GRID_VAL   = "sample_editor_grid_val";
+constexpr auto CONF_KEY_SAMPLE_EDITOR_GRID_ON    = "sample_editor_grid_on";
+constexpr auto CONF_KEY_PIANO_ROLL_Y             = "piano_roll_y";
+constexpr auto CONF_KEY_PIANO_ROLL_H             = "piano_roll_h";
+constexpr auto CONF_KEY_SAMPLE_ACTION_EDITOR_H   = "sample_action_editor_h";
+constexpr auto CONF_KEY_VELOCITY_EDITOR_H        = "velocity_editor_h";
+constexpr auto CONF_KEY_ENVELOPE_EDITOR_H        = "envelope_editor_h";
+constexpr auto CONF_KEY_PLUGIN_LIST_X            = "plugin_list_x";
+constexpr auto CONF_KEY_PLUGIN_LIST_Y            = "plugin_list_y";
+constexpr auto CONF_KEY_CONFIG_X                 = "config_x";
+constexpr auto CONF_KEY_CONFIG_Y                 = "config_y";
+constexpr auto CONF_KEY_BPM_X                    = "bpm_x";
+constexpr auto CONF_KEY_BPM_Y                    = "bpm_y";
+constexpr auto CONF_KEY_BEATS_X                  = "beats_x";
+constexpr auto CONF_KEY_BEATS_Y                  = "beats_y";
+constexpr auto CONF_KEY_ABOUT_X                  = "about_x";
+constexpr auto CONF_KEY_ABOUT_Y                  = "about_y";
+constexpr auto CONF_KEY_NAME_X                   = "name_x";
+constexpr auto CONF_KEY_NAME_Y                   = "name_y";
+constexpr auto CONF_KEY_PLUGIN_CHOOSER_X         = "plugin_chooser_x";
+constexpr auto CONF_KEY_PLUGIN_CHOOSER_Y         = "plugin_chooser_y";
+constexpr auto CONF_KEY_PLUGIN_CHOOSER_W         = "plugin_chooser_w";
+constexpr auto CONF_KEY_PLUGIN_CHOOSER_H         = "plugin_chooser_h";
+constexpr auto CONF_KEY_MIDI_INPUT_X             = "midi_input_x";
+constexpr auto CONF_KEY_MIDI_INPUT_Y             = "midi_input_y";
+constexpr auto CONF_KEY_MIDI_INPUT_W             = "midi_input_w";
+constexpr auto CONF_KEY_MIDI_INPUT_H             = "midi_input_h";
+constexpr auto CONF_KEY_PLUGIN_SORT_METHOD       = "plugin_sort_method";
+constexpr auto CONF_KEY_REC_TRIGGER_MODE         = "rec_trigger_mode";
+constexpr auto CONF_KEY_REC_TRIGGER_LEVEL        = "rec_trigger_level";
 
 /* JSON midimaps keys */
 
-#define MIDIMAP_KEY_BRAND                   "brand"
-#define MIDIMAP_KEY_DEVICE                  "device"
-#define MIDIMAP_KEY_INIT_COMMANDS           "init_commands"
-#define MIDIMAP_KEY_MUTE_ON                 "mute_on"
-#define MIDIMAP_KEY_MUTE_OFF                "mute_off"
-#define MIDIMAP_KEY_SOLO_ON                 "solo_on"
-#define MIDIMAP_KEY_SOLO_OFF                "solo_off"
-#define MIDIMAP_KEY_WAITING                 "waiting"
-#define MIDIMAP_KEY_PLAYING                 "playing"
-#define MIDIMAP_KEY_PLAYING_INAUDIBLE       "playing_inaudible"
-#define MIDIMAP_KEY_STOPPING                "stopping"
-#define MIDIMAP_KEY_STOPPED                 "stopped"
-#define MIDIMAP_KEY_CHANNEL                 "channel"
-#define MIDIMAP_KEY_MESSAGE                 "message"
+constexpr auto MIDIMAP_KEY_BRAND             = "brand";
+constexpr auto MIDIMAP_KEY_DEVICE            = "device";
+constexpr auto MIDIMAP_KEY_INIT_COMMANDS     = "init_commands";
+constexpr auto MIDIMAP_KEY_MUTE_ON           = "mute_on";
+constexpr auto MIDIMAP_KEY_MUTE_OFF          = "mute_off";
+constexpr auto MIDIMAP_KEY_SOLO_ON           = "solo_on";
+constexpr auto MIDIMAP_KEY_SOLO_OFF          = "solo_off";
+constexpr auto MIDIMAP_KEY_WAITING           = "waiting";
+constexpr auto MIDIMAP_KEY_PLAYING           = "playing";
+constexpr auto MIDIMAP_KEY_PLAYING_INAUDIBLE = "playing_inaudible";
+constexpr auto MIDIMAP_KEY_STOPPING          = "stopping";
+constexpr auto MIDIMAP_KEY_STOPPED           = "stopped";
+constexpr auto MIDIMAP_KEY_CHANNEL           = "channel";
+constexpr auto MIDIMAP_KEY_MESSAGE           = "message";
 
 #endif
index b73474b02cde5e6ba7bd946a8b27d07dcf1f2f10..7655b91d83059e874a5e120e30d11f933740786f 100644 (file)
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -992,6 +992,57 @@ const char* metronomeOn_xpm[] = {
 "             "};
 
 
+const char* recTriggerModeOff_xpm[] = {
+"13 13 8 1",
+"   c #242523",
+".  c #272826",
+"+  c #2C2827",
+"@  c #292B28",
+"#  c #493E3F",
+"$  c #6A595B",
+"%  c #896E6D",
+"&  c #B08E8E",
+"@...........@",
+".           .",
+". #$$$$$$$# .",
+". +%&&&&&%+ .",
+".  +%&&&%+  .",
+".   +%&%+   .",
+".    +&+    .",
+".   +%&%+   .",
+".  +%&&&%+  .",
+". +%&&&&&%+ .",
+". #$$$$$$$# .",
+".           .",
+"@...........@"};
+
+
+const char* recTriggerModeOn_xpm[] = {
+"13 13 9 1",
+"   c None",
+".  c #4D4F4C",
+"+  c #544F4E",
+"@  c #675C5C",
+"#  c #6A5F5F",
+"$  c #7D6B6E",
+"%  c #827072",
+"&  c #967B7A",
+"*  c #B18E8F",
+".............",
+".............",
+"..@$$$$$$$@..",
+"..+&*****&+..",
+"...+&***&+...",
+"....+&*&+....",
+".....+*+.....",
+"....+&*&+....",
+"...+&***&+...",
+"..+&*****&+..",
+"..#%%%%%%%#..",
+".............",
+"............."};
+
+
 const char* zoomInOff_xpm[] = {
 "18 18 8 1",
 "      c None",
index 5fae68b566fe0e00c18a286548d7b65eeb688a2d..6427a31658ed7968e0c84f18ece909bab329efa4 100644 (file)
@@ -6,7 +6,7 @@
  *
  * ---------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -65,6 +65,9 @@ extern const char* recOn_xpm[];
 extern const char* metronomeOff_xpm[];
 extern const char* metronomeOn_xpm[];
 
+extern const char* recTriggerModeOff_xpm[];
+extern const char* recTriggerModeOn_xpm[];
+
 extern const char* inputRecOn_xpm[];
 extern const char* inputRecOff_xpm[];
 
index e03ff650af28951d74bda9b95566efb800aa46e7..eb677f71929f4964d69d6526b47e9aea5814a699 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -26,7 +26,9 @@
 
 
 #include <thread>
+#include <atomic>
 #include <ctime>
+#include <atomic>
 #ifdef __APPLE__
        #include <pwd.h>
 #endif
@@ -38,8 +40,8 @@
 #include "../utils/fs.h"
 #include "../utils/time.h"
 #include "../utils/gui.h"
-#include "../gui/dialogs/gd_mainWindow.h"
-#include "../gui/dialogs/gd_warnings.h"
+#include "../gui/dialogs/mainWindow.h"
+#include "../gui/dialogs/warnings.h"
 #include "../glue/main.h"
 #include "mixer.h"
 #include "wave.h"
 #include "mixerHandler.h"
 #include "patch.h"
 #include "conf.h"
+#include "pluginManager.h"
 #include "pluginHost.h"
 #include "recorder.h"
+#include "recManager.h"
 #include "midiMapConf.h"
 #include "kernelMidi.h"
 #include "kernelAudio.h"
@@ -67,17 +71,17 @@ namespace init
 {
 namespace
 {
-std::thread videoThread;
+std::thread UIThread_;
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void videoThreadCallback_()
+void UIThreadCallback_()
 {
        while (G_quit.load() == false) {
                if (m::kernelAudio::getStatus())
-                       gu_refreshUI();
+                       u::gui::refreshUI();
                u::time::sleep(G_GUI_REFRESH_RATE);
        }
 }
@@ -108,22 +112,17 @@ void initConf_()
 
 void initAudio_()
 {
-  kernelAudio::openDevice();
-  clock::init(conf::samplerate, conf::midiTCfps);
+       kernelAudio::openDevice();
+       clock::init(conf::samplerate, conf::midiTCfps);
        mixer::init(clock::getFramesInLoop(), kernelAudio::getRealBufSize());
        recorder::init(&mixer::mutex);
+       recManager::init(&mixer::mutex);
 
 #ifdef WITH_VST
 
-       /* If with Jack don't use buffer size stored in Conf. Use real buffersize
-       from the soundcard (kernelAudio::realBufsize). */
-
-       if (conf::soundSystem == G_SYS_API_JACK)
-               pluginHost::init(kernelAudio::getRealBufSize(), conf::samplerate);
-       else
-               pluginHost::init(conf::buffersize, conf::samplerate);
-
-       pluginHost::sortPlugins(conf::pluginSortMethod);
+       pluginManager::init(conf::samplerate, kernelAudio::getRealBufSize());
+       pluginManager::sortPlugins(static_cast<pluginManager::SortMethod>(conf::pluginSortMethod));
+       pluginHost::init(kernelAudio::getRealBufSize());
 
 #endif
 
@@ -164,17 +163,17 @@ void initGUI_(int argc, char** argv)
 
        G_MainWin = new gdMainWindow(G_MIN_GUI_WIDTH, G_MIN_GUI_HEIGHT, "", argc, argv);
        G_MainWin->resize(conf::mainWindowX, conf::mainWindowY, conf::mainWindowW,
-    conf::mainWindowH);
+               conf::mainWindowH);
 
-  gu_updateMainWinLabel(patch::name == "" ? G_DEFAULT_PATCH_NAME : patch::name);
+       u::gui::updateMainWinLabel(patch::name == "" ? G_DEFAULT_PATCH_NAME : patch::name);
 
        if (!kernelAudio::getStatus())
                gdAlert("Your soundcard isn't configured correctly.\n"
                        "Check the configuration and restart Giada.");
 
-       gu_updateControls();
+       u::gui::updateControls();
        
-       videoThread = std::thread(videoThreadCallback_);
+       UIThread_ = std::thread(UIThreadCallback_);
 }
 
 
@@ -186,7 +185,7 @@ void shutdownAudio_()
 #ifdef WITH_VST
 
        pluginHost::freeAllStacks(&mixer::channels, &mixer::mutex);
-  pluginHost::close();
+       pluginHost::close();
        gu_log("[init] PluginHost cleaned up\n");
 
 #endif
@@ -205,8 +204,8 @@ void shutdownAudio_()
 
 void shutdownGUI_()
 {
-       gu_closeAllSubwindows();
-       videoThread.join();     
+       u::gui::closeAllSubwindows();
+       UIThread_.join();       
 
        gu_log("[init] All subwindows and UI thread closed\n");
 }
@@ -221,8 +220,8 @@ void shutdownGUI_()
 void startup(int argc, char** argv)
 {
        time_t t;
-  time (&t);
-       gu_log("[init] Giada " G_VERSION_STR " - %s", ctime(&t));
+       time (&t);
+       gu_log("[init] Giada %s - %s", G_VERSION_STR, ctime(&t));
 
        initConf_();
        initAudio_();
@@ -234,6 +233,19 @@ void startup(int argc, char** argv)
 /* -------------------------------------------------------------------------- */
 
 
+void closeMainWindow()
+{
+       if (!gdConfirmWin("Warning", "Quit Giada: are you sure?"))
+               return;
+
+       G_MainWin->hide();
+       delete G_MainWin;
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
 void shutdown()
 {
        G_quit.store(true);
@@ -247,7 +259,7 @@ void shutdown()
 
        shutdownAudio_();
 
-       gu_log("[init] Giada " G_VERSION_STR " closed\n\n");
+       gu_log("[init] Giada %s closed\n\n", G_VERSION_STR);
        gu_logClose();
 }
 }}} // giada::m::init
\ No newline at end of file
index 27a5f6e941afef33e018f25b63de3bacca35bfda..b56ace4a53afcf3db863b92f7b339a9bf7a202cf 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -34,6 +34,7 @@ namespace m {
 namespace init
 {
 void startup(int argc, char** argv);
+void closeMainWindow();
 void shutdown();
 }}} // giada::m::init
 
index e30c6f68906d54bdc68ee7f3db0bfc5d48fff6af..4d42806b8be2efcaf148b107a005d9bfb562a8e5 100644 (file)
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index bd256fef7fa99adbced35b0ceeef64f2362b669c..7177923cf7da4b97c27408c5226f811a899b6070 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 485f7c1d2a0fd1defd81928ba1466c10679db7ab..cdb47316c67986a1d84806d7cc3e5a76c037cc78 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -47,15 +47,15 @@ namespace kernelMidi
 {
 namespace
 {
-bool status = false;
-int api = 0;
-RtMidiOut* midiOut = nullptr;
-RtMidiIn*  midiIn  = nullptr;
-unsigned numOutPorts = 0;
-unsigned numInPorts  = 0;
+bool status_ = false;
+int api_ = 0;
+RtMidiOut* midiOut_ = nullptr;
+RtMidiIn*  midiIn_  = nullptr;
+unsigned numOutPorts_ = 0;
+unsigned numInPorts_  = 0;
 
 
-static void callback(double t, std::vector<unsigned char>* msg, void* data)
+static void callback_(double t, vector<unsigned char>* msg, void* data)
 {
        if (msg->size() < 3) {
                //gu_log("[KM] MIDI received - unknown signal - size=%d, value=0x", (int) msg->size());
@@ -71,7 +71,7 @@ static void callback(double t, std::vector<unsigned char>* msg, void* data)
 /* -------------------------------------------------------------------------- */
 
 
-void sendMidiLightningInitMsgs()
+void sendMidiLightningInitMsgs_()
 {
        for(unsigned i=0; i<midimap::initCommands.size(); i++) {
                midimap::message_t msg = midimap::initCommands.at(i);
@@ -82,7 +82,7 @@ void sendMidiLightningInitMsgs()
        }
 }
 
-}; // {anonymous}
+} // {anonymous}
 
 
 /* -------------------------------------------------------------------------- */
@@ -90,10 +90,10 @@ void sendMidiLightningInitMsgs()
 /* -------------------------------------------------------------------------- */
 
 
-void setApi(int _api)
+void setApi(int api)
 {
-       api = _api;
-       gu_log("[KM] using system 0x%x\n", api);
+       api_ = api;
+       gu_log("[KM] using system 0x%x\n", api_);
 }
 
 
@@ -103,38 +103,38 @@ void setApi(int _api)
 int openOutDevice(int port)
 {
        try {
-               midiOut = new RtMidiOut((RtMidi::Api) api, "Giada MIDI Output");
-               status = true;
+               midiOut_ = new RtMidiOut((RtMidi::Api) api_, "Giada MIDI Output");
+               status = true;
        }
        catch (RtMidiError &error) {
                gu_log("[KM] MIDI out device error: %s\n", error.getMessage().c_str());
-               status = false;
+               status_ = false;
                return 0;
        }
 
        /* print output ports */
 
-       numOutPorts = midiOut->getPortCount();
-       gu_log("[KM] %d output MIDI ports found\n", numOutPorts);
-       for (unsigned i=0; i<numOutPorts; i++)
+       numOutPorts_ = midiOut_->getPortCount();
+       gu_log("[KM] %d output MIDI ports found\n", numOutPorts_);
+       for (unsigned i=0; i<numOutPorts_; i++)
                gu_log("  %d) %s\n", i, getOutPortName(i).c_str());
 
        /* try to open a port, if enabled */
 
-       if (port != -1 && numOutPorts > 0) {
+       if (port != -1 && numOutPorts_ > 0) {
                try {
-                       midiOut->openPort(port, getOutPortName(port));
+                       midiOut_->openPort(port, getOutPortName(port));
                        gu_log("[KM] MIDI out port %d open\n", port);
 
                        /* TODO - it shold send midiLightning message only if there is a map loaded
                        and available in midimap:: */
 
-                       sendMidiLightningInitMsgs();
+                       sendMidiLightningInitMsgs_();
                        return 1;
                }
-               catch (RtMidiError &error) {
+               catch (RtMidiErrorerror) {
                        gu_log("[KM] unable to open MIDI out port %d: %s\n", port, error.getMessage().c_str());
-                       status = false;
+                       status_ = false;
                        return 0;
                }
        }
@@ -149,35 +149,35 @@ int openOutDevice(int port)
 int openInDevice(int port)
 {
        try {
-               midiIn = new RtMidiIn((RtMidi::Api) api, "Giada MIDI input");
-               status = true;
+               midiIn_ = new RtMidiIn((RtMidi::Api) api_, "Giada MIDI input");
+               status_ = true;
        }
        catch (RtMidiError &error) {
                gu_log("[KM] MIDI in device error: %s\n", error.getMessage().c_str());
-               status = false;
+               status_ = false;
                return 0;
        }
 
        /* print input ports */
 
-       numInPorts = midiIn->getPortCount();
-       gu_log("[KM] %d input MIDI ports found\n", numInPorts);
-       for (unsigned i=0; i<numInPorts; i++)
+       numInPorts_ = midiIn_->getPortCount();
+       gu_log("[KM] %d input MIDI ports found\n", numInPorts_);
+       for (unsigned i=0; i<numInPorts_; i++)
                gu_log("  %d) %s\n", i, getInPortName(i).c_str());
 
        /* try to open a port, if enabled */
 
-       if (port != -1 && numInPorts > 0) {
+       if (port != -1 && numInPorts_ > 0) {
                try {
-                       midiIn->openPort(port, getInPortName(port));
-                       midiIn->ignoreTypes(true, false, true); // ignore all system/time msgs, for now
+                       midiIn_->openPort(port, getInPortName(port));
+                       midiIn_->ignoreTypes(true, false, true); // ignore all system/time msgs, for now
                        gu_log("[KM] MIDI in port %d open\n", port);
-                       midiIn->setCallback(&callback);
+                       midiIn_->setCallback(&callback_);
                        return 1;
                }
-               catch (RtMidiError &error) {
+               catch (RtMidiErrorerror) {
                        gu_log("[KM] unable to open MIDI in port %d: %s\n", port, error.getMessage().c_str());
-                       status = false;
+                       status_ = false;
                        return 0;
                }
        }
@@ -205,13 +205,13 @@ bool hasAPI(int API)
 
 string getOutPortName(unsigned p)
 {
-       try { return midiOut->getPortName(p); }
+       try { return midiOut_->getPortName(p); }
        catch (RtMidiError &error) { return ""; }
 }
 
 string getInPortName(unsigned p)
 {
-       try { return midiIn->getPortName(p); }
+       try { return midiIn_->getPortName(p); }
        catch (RtMidiError &error) { return ""; }
 }
 
@@ -221,14 +221,14 @@ string getInPortName(unsigned p)
 
 void send(uint32_t data)
 {
-       if (!status)
+       if (!status_)
                return;
 
        vector<unsigned char> msg(1, getB1(data));
        msg.push_back(getB2(data));
        msg.push_back(getB3(data));
 
-       midiOut->sendMessage(&msg);
+       midiOut_->sendMessage(&msg);
        gu_log("[KM] send msg=0x%X (%X %X %X)\n", data, msg[0], msg[1], msg[2]);
 }
 
@@ -238,7 +238,7 @@ void send(uint32_t data)
 
 void send(int b1, int b2, int b3)
 {
-       if (!status)
+       if (!status_)
                return;
 
        vector<unsigned char> msg(1, b1);
@@ -248,7 +248,7 @@ void send(int b1, int b2, int b3)
        if (b3 != -1)
                msg.push_back(b3);
 
-       midiOut->sendMessage(&msg);
+       midiOut_->sendMessage(&msg);
        //gu_log("[KM] send msg=(%X %X %X)\n", b1, b2, b3);
 }
 
@@ -283,17 +283,9 @@ void sendMidiLightning(uint32_t learn, const midimap::message_t& msg)
 /* -------------------------------------------------------------------------- */
 
 
-unsigned countInPorts()
-{
-       return numInPorts;
-}
-
-
-unsigned countOutPorts()
-{
-       return numOutPorts;
-}
-
+unsigned countInPorts()  { return numInPorts_; }
+unsigned countOutPorts() { return numOutPorts_; }
+bool getStatus()         { return status_; }
 
 /* -------------------------------------------------------------------------- */
 
@@ -318,13 +310,4 @@ uint32_t setChannel(uint32_t iValue, int channel)
        return (iValue & (~chanMask)) | (channel << 24);
 }
 
-
-/* -------------------------------------------------------------------------- */
-
-
-bool getStatus()
-{
-       return status;
-}
-
 }}}; // giada::m::kernelMidi::
index 450854c41b2b60ab9da91f50dab67b7a020f511b..55a5b7650bc7cc6a48c203aeaa04bf5a853eb515 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 7cc871f278d47f0924ef111da7421949d1a285cd..20ead792574efafe77fe0526f41b54f9fe46ee5b 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -224,9 +224,9 @@ void MidiChannel::receiveMidi(const MidiEvent& midiEvent)
 
 #ifdef WITH_VST
 
-       pthread_mutex_lock(&pluginHost::mutex_midi);
+       pthread_mutex_lock(&pluginHost::mutex);
        addVstMidiEvent(midiEventFlat.getRaw(), 0);
-       pthread_mutex_unlock(&pluginHost::mutex_midi);
+       pthread_mutex_unlock(&pluginHost::mutex);
 
 #endif
 
@@ -236,13 +236,4 @@ void MidiChannel::receiveMidi(const MidiEvent& midiEvent)
        }
 }
 
-
-/* -------------------------------------------------------------------------- */
-
-
-bool MidiChannel::canInputRec()
-{
-       return false; // midi channels don't handle input audio
-}
-
 }} // giada::m::
index ee22e3fa64c5834955a99ddd59015b09010a65aa..16de0692ebcdda0f54266d21e93bebf24c1f7a82 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -58,19 +58,18 @@ public:
        void readPatch(const std::string& basePath, const patch::channel_t& pch) override;
        void writePatch(int i, bool isProject) override;
        void receiveMidi(const MidiEvent& midiEvent) override;
-       bool canInputRec() override;
 
        /* sendMidi
-        * send Midi event to the outside world. */
+       Sends Midi event to the outside world. */
 
        void sendMidi(const Action* a, int localFrame);
 
 #ifdef WITH_VST
 
        /* addVstMidiEvent
-        * Add a new Midi event to the midiEvent stack fom a composite uint32_t raw
-        * Midi event. LocalFrame is the offset: it tells where to put the event
-        * inside the buffer. */
+       Adds a new Midi event to the midiEvent stack fom a composite uint32_t raw
+       Midi event. LocalFrame is the offset: it tells where to put the event
+       inside the buffer. */
 
        void addVstMidiEvent(uint32_t msg, int localFrame);
 
index 646c84db42edd7527d83009b037a78cde6977fbc..d85ad30a9f224b903fe1f8cec64604b24c565421 100644 (file)
@@ -48,7 +48,7 @@ void parseEvents(MidiChannel* ch, mixer::FrameEvents fe)
 void process(MidiChannel* ch, AudioBuffer& out, const AudioBuffer& in, bool audible)
 {
 #ifdef WITH_VST
-       pluginHost::processStack(ch->buffer, pluginHost::CHANNEL, ch);
+       pluginHost::processStack(ch->buffer, pluginHost::StackType::CHANNEL, ch);
 #endif
 
        /* Process the plugin stack first, then quit if the channel is muted/soloed. 
index bb65bd825aa1e9e720a582631ba9831c9fbed47c..64d40a7117d5a3ae5244f7d78f91985a5e9a527e 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -51,12 +51,14 @@ namespace midiDispatcher
 {
 namespace
 {
-/* cb_midiLearn, cb_data
+/* cb_midiLearn, cb_data_
 Callback prepared by the gdMidiGrabber window and called by midiDispatcher. It 
 contains things to do once the midi message has been stored. */
 
-cb_midiLearn* cb_learn = nullptr;
-void* cb_data = nullptr;       
+cb_midiLearn* cb_learn_ = nullptr;
+void* cb_data_ = nullptr;      
+
+std::function<void()> signalCb_ = nullptr;
 
 
 /* -------------------------------------------------------------------------- */
@@ -64,7 +66,7 @@ void* cb_data = nullptr;
 
 #ifdef WITH_VST
 
-void processPlugins(Channel* ch, const MidiEvent& midiEvent)
+void processPlugins_(Channel* ch, const MidiEvent& midiEvent)
 {
        uint32_t pure = midiEvent.getRawNoVelocity();
 
@@ -73,9 +75,9 @@ void processPlugins(Channel* ch, const MidiEvent& midiEvent)
        indexes match both the structure of Channel::midiInPlugins and 
        vector<Plugin*>* plugins. */
 
-       vector<Plugin*>* plugins = pluginHost::getStack(pluginHost::CHANNEL, ch);
+       std::vector<Plugin*> plugins = pluginHost::getStack(pluginHost::StackType::CHANNEL, ch);
 
-       for (Plugin* plugin : *plugins) {
+       for (Plugin* plugin : plugins) {
                for (unsigned k=0; k<plugin->midiInParams.size(); k++) {
                        uint32_t midiInParam = plugin->midiInParams.at(k);
                        if (pure != midiInParam)
@@ -94,7 +96,7 @@ void processPlugins(Channel* ch, const MidiEvent& midiEvent)
 /* -------------------------------------------------------------------------- */
 
 
-void processChannels(const MidiEvent& midiEvent)
+void processChannels_(const MidiEvent& midiEvent)
 {
        uint32_t pure = midiEvent.getRawNoVelocity();
 
@@ -154,7 +156,7 @@ void processChannels(const MidiEvent& midiEvent)
 #ifdef WITH_VST
 
                /* Process learned plugins parameters. */
-               processPlugins(ch, midiEvent); 
+               processPlugins_(ch, midiEvent); 
 
 #endif
 
@@ -167,7 +169,7 @@ void processChannels(const MidiEvent& midiEvent)
 /* -------------------------------------------------------------------------- */
 
 
-void processMaster(const MidiEvent& midiEvent)
+void processMaster_(const MidiEvent& midiEvent)
 {
        uint32_t pure = midiEvent.getRawNoVelocity();
 
@@ -181,38 +183,49 @@ void processMaster(const MidiEvent& midiEvent)
        }
        else if (pure == conf::midiInActionRec) {
                gu_log("  >>> actionRec (master) (pure=0x%X)\n", pure);
-               c::io::startStopActionRec(false);
+               c::io::toggleActionRec(false);
        }
        else if (pure == conf::midiInInputRec) {
                gu_log("  >>> inputRec (master) (pure=0x%X)\n", pure);
-               c::io::startStopInputRec(false);
+               c::io::toggleInputRec(false);
        }
        else if (pure == conf::midiInMetronome) {
                gu_log("  >>> metronome (master) (pure=0x%X)\n", pure);
-               c::transport::startStopMetronome(false);
+               c::transport::toggleMetronome(false);
        }
        else if (pure == conf::midiInVolumeIn) {
                float vf = midiEvent.getVelocity() / 127.0f;
                gu_log("  >>> input volume (master) (pure=0x%X, value=%d, float=%f)\n",
                        pure, midiEvent.getVelocity(), vf);
-               glue_setInVol(vf, false);
+               c::main::setInVol(vf, false);
        }
        else if (pure == conf::midiInVolumeOut) {
                float vf = midiEvent.getVelocity() / 127.0f;
                gu_log("  >>> output volume (master) (pure=0x%X, value=%d, float=%f)\n",
                        pure, midiEvent.getVelocity(), vf);
-               glue_setOutVol(vf, false);
+               c::main::setOutVol(vf, false);
        }
        else if (pure == conf::midiInBeatDouble) {
                gu_log("  >>> sequencer x2 (master) (pure=0x%X)\n", pure);
-               glue_beatsMultiply();
+               c::main::beatsMultiply();
        }
        else if (pure == conf::midiInBeatHalf) {
                gu_log("  >>> sequencer /2 (master) (pure=0x%X)\n", pure);
-               glue_beatsDivide();
+               c::main::beatsDivide();
        }
 }
 
+
+/* -------------------------------------------------------------------------- */
+
+
+void triggerSignalCb_()
+{
+       if (signalCb_ == nullptr) 
+               return;
+       signalCb_();
+       signalCb_ = nullptr;
+}
 } // {anonymous}
 
 
@@ -223,8 +236,8 @@ void processMaster(const MidiEvent& midiEvent)
 
 void startMidiLearn(cb_midiLearn* cb, void* data)
 {
-       cb_learn = cb;
-       cb_data  = data;
+       cb_learn_ = cb;
+       cb_data_  = data;
 }
 
 
@@ -233,8 +246,8 @@ void startMidiLearn(cb_midiLearn* cb, void* data)
 
 void stopMidiLearn()
 {
-       cb_learn = nullptr;
-       cb_data  = nullptr;
+       cb_learn_ = nullptr;
+       cb_data_  = nullptr;
 }
 
 
@@ -260,12 +273,23 @@ void dispatch(int byte1, int byte2, int byte3)
        then each channel in the stack. This way incoming signals don't get processed 
        by glue_* when MIDI learning is on. */
 
-       if (cb_learn)
-               cb_learn(midiEvent.getRawNoVelocity(), cb_data);
+       if (cb_learn_)
+               cb_learn_(midiEvent.getRawNoVelocity(), cb_data_);
        else {
-               processMaster(midiEvent);
-               processChannels(midiEvent);
+               processMaster_(midiEvent);
+               processChannels_(midiEvent);
+               triggerSignalCb_();
        }       
 }
+
+
+/* -------------------------------------------------------------------------- */
+
+
+void setSignalCallback(std::function<void()> f)
+{
+       signalCb_ = f;
+}
+
 }}}; // giada::m::midiDispatcher::
 
index 395622eda8400c6f84169459639d6c2aac0e63fa..e8df2f8704cd1eac362c305484896ae6910757f1 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
 #define G_MIDI_DISPATCHER_H
 
 
-#ifdef __APPLE__  // our Clang still doesn't know about cstdint (c++11 stuff)
-       #include <stdint.h>
-#else
-       #include <cstdint>
-#endif
+#include <functional>
+#include <cstdint>
 
 
 namespace giada {
@@ -47,6 +44,7 @@ void stopMidiLearn();
 
 void dispatch(int byte1, int byte2, int byte3);
 
+void setSignalCallback(std::function<void()> f);
 }}}; // giada::m::midiDispatcher::
 
 
index fdf63e08d83830930084dabb3c86987496c0c82c..db25f766d2b39cded4968be8e2d3a325e2fd8750 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 3694b57704d23eb29a190aee2d4efdd1be406536..111fceb6fab69708b0fbcfc2bdece6974cf3230f 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 0b04a8c16bd137411717a3ebf5243b71d78977ae..c8a962e77413499d52d71f8a5843c12c85ec45a5 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -57,7 +57,7 @@ bool readInitCommands(json_t *jContainer)
        json_t *jInitCommand;
        json_array_foreach(jInitCommands, commandIndex, jInitCommand) {
 
-               string indexStr = "init command " + gu_iToString(commandIndex);
+               string indexStr = "init command " + u::string::iToString(commandIndex);
                if (!storager::checkObject(jInitCommand, indexStr.c_str()))
                        return 0;
 
index 6584d3518948afd5bc5084ea32842a2ce736fd0a..3a5f9da732a70cbc3ad7824d17967c469a702e54 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 2707572f49f400a5736aedc9eed37570e44b1754..f6f799637b2ae87be50ef6e3ed0feaea98b7336a 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -29,6 +29,7 @@
 #include <cstring>
 #include "../deps/rtaudio-mod/RtAudio.h"
 #include "../utils/log.h"
+#include "../utils/math.h"
 #include "wave.h"
 #include "kernelAudio.h"
 #include "recorder.h"
@@ -51,51 +52,74 @@ namespace mixer
 {
 namespace
 {
-constexpr Frame TICKSIZE = 38;
-
-float tock[TICKSIZE] = {
-       0.059033,  0.117240,  0.173807,  0.227943,  0.278890,  0.325936,
-       0.368423,  0.405755,  0.437413,  0.462951,  0.482013,  0.494333,
-       0.499738,  0.498153,  0.489598,  0.474195,  0.452159,  0.423798,
-       0.389509,  0.349771,  0.289883,  0.230617,  0.173194,  0.118739,
-       0.068260,  0.022631, -0.017423, -0.051339,      -0.078721, -0.099345,
- -0.113163, -0.120295, -0.121028, -0.115804, -0.105209, -0.089954,
- -0.070862, -0.048844
-};
-
-float tick[TICKSIZE] = {
-       0.175860,  0.341914,  0.488904,  0.608633,  0.694426,  0.741500,
-       0.747229,  0.711293,    0.635697,  0.524656,  0.384362,  0.222636,
-       0.048496, -0.128348, -0.298035, -0.451105, -0.579021, -0.674653,
- -0.732667, -0.749830, -0.688924, -0.594091, -0.474481, -0.340160,
- -0.201360, -0.067752,  0.052194,  0.151746,  0.226280,  0.273493,
-       0.293425,  0.288307,  0.262252,  0.220811,  0.170435,  0.117887,
-       0.069639,  0.031320
-};
-
-AudioBuffer vChanInput;   // virtual channel for recording
-AudioBuffer vChanInToOut; // virtual channel in->out bridge (hear what you're playin)
-
-Frame tickTracker = 0;
-Frame tockTracker = 0;
-bool tickPlay = false;
-bool tockPlay = false;
+struct Metronome
+{
+       static constexpr Frame CLICK_SIZE = 38;
+
+       float beat[CLICK_SIZE] = {
+                0.059033,  0.117240,  0.173807,  0.227943,  0.278890,  0.325936,
+                0.368423,  0.405755,  0.437413,  0.462951,  0.482013,  0.494333,
+                0.499738,  0.498153,  0.489598,  0.474195,  0.452159,  0.423798,
+                0.389509,  0.349771,  0.289883,  0.230617,  0.173194,  0.118739,
+                0.068260,  0.022631, -0.017423, -0.051339,     -0.078721, -0.099345,
+               -0.113163, -0.120295, -0.121028, -0.115804, -0.105209, -0.089954,
+               -0.070862, -0.048844
+       };
+
+       float bar[CLICK_SIZE] = {
+                0.175860,  0.341914,  0.488904,  0.608633,  0.694426,  0.741500,
+                0.747229,  0.711293,  0.635697,  0.524656,  0.384362,  0.222636,
+                0.048496, -0.128348, -0.298035, -0.451105, -0.579021, -0.674653,
+               -0.732667, -0.749830, -0.688924, -0.594091, -0.474481, -0.340160,
+               -0.201360, -0.067752,  0.052194,  0.151746,  0.226280,  0.273493,
+                0.293425,  0.288307,  0.262252,  0.220811,  0.170435,  0.117887,
+                0.069639,  0.031320
+       };
+
+       Frame tracker  = 0;
+       bool  running  = false;
+       bool  playBar  = false;
+       bool  playBeat = false;
+
+       void render(AudioBuffer& outBuf, bool& process, float* data, Frame f)
+       {
+               process = true;
+               for (int i=0; i<outBuf.countChannels(); i++)
+                       outBuf[f][i] += data[tracker];
+               if (++tracker > Metronome::CLICK_SIZE) {
+                       process = false;
+                       tracker = 0;
+               }       
+       }
+} metronome_;
+
+/* vChanInput
+Virtual channel for input recording. */
+
+AudioBuffer vChanInput_;
+
+/* vChanInToOut
+Virtual channel in->out bridge (hear what you're playin). */
+
+AudioBuffer vChanInToOut_;
 
 /* inputTracker
-Sample position while recording. */
+Frame position while recording. */
+
+Frame inputTracker_ = 0;
 
-Frame inputTracker = 0;
+std::function<void()> signalCb_ = nullptr;
 
 
 /* -------------------------------------------------------------------------- */
 
-/* computePeak */
 
-void computePeak(const AudioBuffer& buf, float& peak, Frame frame)
+void computePeak_(const AudioBuffer& buf, std::atomic<float>& peak)
 {
-       for (int i=0; i<buf.countChannels(); i++)
-               if (buf[frame][i] > peak)
-                       peak = buf[frame][i];
+       for (int i=0; i<buf.countFrames(); i++)
+               for (int j=0; j<buf.countChannels(); j++)
+                       if (buf[i][j] > peak.load())
+                               peak.store(buf[i][j]);
 }
 
 
@@ -104,46 +128,44 @@ void computePeak(const AudioBuffer& buf, float& peak, Frame frame)
 /* lineInRec
 Records from line in. */
 
-void lineInRec(const AudioBuffer& inBuf, unsigned frame)
+void lineInRec_(const AudioBuffer& inBuf)
 {
        if (!mh::hasArmedSampleChannels() || !kernelAudio::isInputEnabled() || !recording)
                return;
 
-       /* Delay comp: wait until waitRec reaches delayComp. WaitRec returns to 0 in 
-       mixerHandler, as soon as the recording ends. */
-
-       if (waitRec < conf::delayComp) {
-               waitRec++;
-               return;
-       }
-
-       for (int i=0; i<vChanInput.countChannels(); i++)
-               vChanInput[inputTracker][i] += inBuf[frame][i] * inVol;  // adding: overdub!
-
-       inputTracker++;
-       if (inputTracker >= clock::getFramesInLoop())
-               inputTracker = 0;
+       for (int i=0; i<inBuf.countFrames(); i++, inputTracker_++)
+               for (int j=0; j<inBuf.countChannels(); j++) {
+                       if (inputTracker_ >= clock::getFramesInLoop())
+                               inputTracker_ = 0;
+                       vChanInput_[inputTracker_][j] += inBuf[i][j] * inVol.load();  // adding: overdub!
+               }
 }
 
 
 /* -------------------------------------------------------------------------- */
 
-/* ProcessLineIn
+/* processLineIn
 Computes line in peaks, plus handles "hear what you're playin'" thing. */
 
-void processLineIn(const AudioBuffer& inBuf, unsigned frame)
+void processLineIn_(const AudioBuffer& inBuf)
 {
        if (!kernelAudio::isInputEnabled())
                return;
 
-       computePeak(inBuf, peakIn, frame);
+       computePeak_(inBuf, peakIn);
+
+       if (signalCb_ != nullptr && u::math::linearToDB(peakIn) > conf::recTriggerLevel) {
+               signalCb_();
+               signalCb_ = nullptr;
+       }
 
        /* "hear what you're playing" - process, copy and paste the input buffer onto 
        the output buffer. */
 
        if (inToOut)
-               for (int i=0; i<vChanInToOut.countChannels(); i++)
-                       vChanInToOut[frame][i] = inBuf[frame][i] * inVol;
+               for (int i=0; i<vChanInToOut_.countFrames(); i++)
+                       for (int j=0; j<vChanInToOut_.countChannels(); j++)
+                               vChanInToOut_[i][j] = inBuf[i][j] * inVol.load();
 }
 
 
@@ -152,10 +174,10 @@ void processLineIn(const AudioBuffer& inBuf, unsigned frame)
 /* prepareBuffers
 Cleans up every buffer, both in Mixer and in channels. */
 
-void prepareBuffers(AudioBuffer& outBuf)
+void prepareBuffers_(AudioBuffer& outBuf)
 {
        outBuf.clear();
-       vChanInToOut.clear();
+       vChanInToOut_.clear();
        for (Channel* channel : channels)
                channel->prepareBuffer(clock::isRunning());
 }
@@ -166,7 +188,7 @@ void prepareBuffers(AudioBuffer& outBuf)
 /* doQuantize
 Computes quantization on 'rewind' button and all channels. */
 
-void doQuantize(unsigned frame)
+void doQuantize_(unsigned frame)
 {
        /* Nothing to do if quantizer disabled or a quanto has not passed yet. */
 
@@ -180,48 +202,20 @@ void doQuantize(unsigned frame)
 }
 
 
-/* -------------------------------------------------------------------------- */
-
-/* renderMetronome
-Generates metronome when needed and pastes it to the output buffer. */
-
-void renderMetronome(AudioBuffer& outBuf, unsigned frame)
-{
-       if (tockPlay) {
-               for (int i=0; i<outBuf.countChannels(); i++)
-                       outBuf[frame][i] += tock[tockTracker];
-               tockTracker++;
-               if (tockTracker >= TICKSIZE-1) {
-                       tockPlay    = false;
-                       tockTracker = 0;
-               }
-       }
-       if (tickPlay) {
-               for (int i=0; i<outBuf.countChannels(); i++)
-                       outBuf[frame][i] += tick[tickTracker];
-               tickTracker++;
-               if (tickTracker >= TICKSIZE-1) {
-                       tickPlay    = false;
-                       tickTracker = 0;
-               }
-       }
-}
-
-
 /* -------------------------------------------------------------------------- */
 
 /* renderIO
 Final processing stage. Take each channel and process it (i.e. copy its
 content to the output buffer). Process plugins too, if any. */
 
-void renderIO(AudioBuffer& outBuf, const AudioBuffer& inBuf)
+void renderIO_(AudioBuffer& outBuf, const AudioBuffer& inBuf)
 {
        for (Channel* channel : channels)
                channel->process(outBuf, inBuf, isChannelAudible(channel), clock::isRunning());
 
 #ifdef WITH_VST
-       pluginHost::processStack(outBuf, pluginHost::MASTER_OUT);
-       pluginHost::processStack(vChanInToOut, pluginHost::MASTER_IN);
+       pluginHost::processStack(outBuf, pluginHost::StackType::MASTER_OUT);
+       pluginHost::processStack(vChanInToOut_, pluginHost::StackType::MASTER_IN);
 #endif
 }
 
@@ -231,13 +225,14 @@ void renderIO(AudioBuffer& outBuf, const AudioBuffer& inBuf)
 /* limitOutput
 Applies a very dumb hard limiter. */
 
-void limitOutput(AudioBuffer& outBuf, unsigned frame)
+void limitOutput_(AudioBuffer& outBuf)
 {
-       for (int i=0; i<outBuf.countChannels(); i++)
-               if      (outBuf[frame][i] > 1.0f)
-                       outBuf[frame][i] = 1.0f;
-               else if (outBuf[frame][i] < -1.0f)      
-                       outBuf[frame][i] = -1.0f;       
+       if (!conf::limitOutput)
+               return;
+       for (int i=0; i<outBuf.countFrames(); i++)
+               for (int j=0; j<outBuf.countChannels(); j++)
+                       if      (outBuf[i][j] > 1.0f)  outBuf[i][j] = 1.0f;
+                       else if (outBuf[i][j] < -1.0f) outBuf[i][j] = -1.0f;    
 }
 
 
@@ -247,30 +242,49 @@ void limitOutput(AudioBuffer& outBuf, unsigned frame)
 Last touches after the output has been rendered: apply inToOut if any, apply
 output volume. */
 
-void finalizeOutput(AudioBuffer& outBuf, unsigned frame)
+void finalizeOutput_(AudioBuffer& outBuf)
 {
-       /* Merge vChanInToOut, if enabled. */
-
-       if (inToOut)
-               outBuf.copyFrame(frame, vChanInToOut[frame]); 
-
-       for (int i=0; i<outBuf.countChannels(); i++)
-               outBuf[frame][i] *= outVol; 
+       for (int i=0; i<outBuf.countFrames(); i++)
+               for (int j=0; j<outBuf.countChannels(); j++) {
+                       if (inToOut) // Merge vChanInToOut_, if enabled
+                               outBuf[i][j] += vChanInToOut_[i][j];
+                       outBuf[i][j] *= outVol.load(); 
+               }
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void renderMetronome()
+void renderMetronome_(AudioBuffer& outBuf, Frame f)
 {
-       if (!metronome)
+       if (!metronome_.running)
                return;
-       if (clock::isOnBar() || clock::isOnFirstBeat())
-               tickPlay = true;
+
+       if (clock::isOnBar() || metronome_.playBar)
+               metronome_.render(outBuf, metronome_.playBar, metronome_.bar, f);
        else
-       if (clock::isOnBeat())
-               tockPlay = true;
+       if (clock::isOnBeat() || metronome_.playBeat)
+               metronome_.render(outBuf, metronome_.playBeat, metronome_.beat, f);
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+void parseEvents_(Frame f)
+{
+       FrameEvents fe;
+       fe.frameLocal   = f;
+       fe.frameGlobal  = clock::getCurrentFrame();
+       fe.doQuantize   = clock::getQuantize() == 0 || !clock::quantoHasPassed();
+       fe.onBar        = clock::isOnBar();
+       fe.onFirstBeat  = clock::isOnFirstBeat();
+       fe.quantoPassed = clock::quantoHasPassed();
+       fe.actions      = recorder::getActionsOnFrame(clock::getCurrentFrame());
+
+       for (Channel* channel : channels)
+               channel->parseEvents(fe);       
 }
 }; // {anonymous}
 
@@ -282,17 +296,17 @@ void renderMetronome()
 
 std::vector<Channel*> channels;
 
-bool   recording    = false;
-bool   ready        = true;
-float  outVol       = G_DEFAULT_OUT_VOL;
-float  inVol        = G_DEFAULT_IN_VOL;
-float  peakOut      = 0.0f;
-float  peakIn       = 0.0f;
-bool    metronome    = false;
-int    waitRec      = 0;
-bool   rewindWait   = false;
-bool   hasSolos     = false;
-bool   inToOut      = false;
+bool  recording  = false;
+bool  ready      = true;
+bool  metronome  = false;
+int   waitRec    = 0;
+bool  rewindWait = false;
+bool  hasSolos   = false;
+bool  inToOut    = false;
+std::atomic<float> outVol(G_DEFAULT_OUT_VOL);
+std::atomic<float> inVol(G_DEFAULT_IN_VOL);
+std::atomic<float> peakOut(0.0);
+std::atomic<float> peakIn(0.0);
 
 pthread_mutex_t mutex;
 
@@ -302,11 +316,11 @@ pthread_mutex_t mutex;
 
 void init(Frame framesInSeq, Frame framesInBuffer)
 {
-       /* Allocate virtual input channels. vChanInput has variable size: it depends
+       /* Allocate virtual input channels. vChanInput_ has variable size: it depends
        on how many frames there are in sequencer. */
        
-       vChanInput.alloc(framesInSeq, G_MAX_IO_CHANS);
-       vChanInToOut.alloc(framesInBuffer, G_MAX_IO_CHANS);
+       vChanInput_.alloc(framesInSeq, G_MAX_IO_CHANS);
+       vChanInToOut_.alloc(framesInBuffer, G_MAX_IO_CHANS);
 
        gu_log("[Mixer::init] buffers ready - framesInSeq=%d, framesInBuffer=%d\n", 
                framesInSeq, framesInBuffer);   
@@ -324,7 +338,7 @@ void init(Frame framesInSeq, Frame framesInBuffer)
 
 void allocVirtualInput(Frame frames)
 {
-       vChanInput.alloc(frames, G_MAX_IO_CHANS);
+       vChanInput_.alloc(frames, G_MAX_IO_CHANS);
 }
 
 
@@ -337,8 +351,6 @@ int masterPlay(void* outBuf, void* inBuf, unsigned bufferSize,
        if (!ready)
                return 0;
 
-       pthread_mutex_lock(&mutex);
-
 #ifdef __linux__
        clock::recvJackSync();
 #endif
@@ -348,56 +360,41 @@ int masterPlay(void* outBuf, void* inBuf, unsigned bufferSize,
        if (kernelAudio::isInputEnabled())
                in.setData((float*) inBuf, bufferSize, G_MAX_IO_CHANS);
 
-       peakOut = 0.0f;  // reset peak calculator
-       peakIn  = 0.0f;  // reset peak calculator
-
-       prepareBuffers(out);
-
-       // TODO - move lock here
-
-       for (unsigned j=0; j<bufferSize; j++) {
-               processLineIn(in, j);   // TODO - can go outside this loop
+       peakOut.store(0.0);  // reset peak calculator
+       peakIn.store(0.0);   // reset peak calculator
 
-               if (clock::isRunning()) {
-                       FrameEvents fe;
-                       fe.frameLocal   = j;
-                       fe.frameGlobal  = clock::getCurrentFrame();
-                       fe.doQuantize   = clock::getQuantize() == 0 || !clock::quantoHasPassed();
-                       fe.onBar        = clock::isOnBar();
-                       fe.onFirstBeat  = clock::isOnFirstBeat();
-                       fe.quantoPassed = clock::quantoHasPassed();
-                       fe.actions      = recorder::getActionsOnFrame(clock::getCurrentFrame());
+       prepareBuffers_(out);
+       processLineIn_(in);
 
-                       for (Channel* channel : channels)
-                               channel->parseEvents(fe);
+       pthread_mutex_lock(&mutex);
 
-                       lineInRec(in, j);   // TODO - can go outside this loop
-                       doQuantize(j);
-                       renderMetronome();
-                       clock::incrCurrentFrame();
+       if (clock::isActive()) {
+               for (unsigned j=0; j<bufferSize; j++) {
+                       if (clock::isRunning()) {
+                               parseEvents_(j);
+                               doQuantize_(j);
+                       }
                        clock::sendMIDIsync();
+                       clock::incrCurrentFrame();
+                       renderMetronome_(out, j);
                }
+               lineInRec_(in);
        }
-       
-       renderIO(out, in);
 
-       // TODO - move unlock here
+       renderIO_(out, in);
 
-       /* Post processing. */
-       for (unsigned j=0; j<bufferSize; j++) {
-               finalizeOutput(out, j); 
-               if (conf::limitOutput)
-                       limitOutput(out, j);
-               computePeak(out, peakOut, j); 
-               renderMetronome(out, j);
-       }
+       pthread_mutex_unlock(&mutex);
+
+       /* Post processing */
+
+       finalizeOutput_(out);
+       limitOutput_(out);
+       computePeak_(out, peakOut);
 
        /* Unset data in buffers. If you don't do this, buffers go out of scope and
        destroy memory allocated by RtAudio ---> havoc. */
        out.setData(nullptr, 0, 0);
-       in.setData(nullptr, 0, 0);
-
-       pthread_mutex_unlock(&mutex);
+       in.setData (nullptr, 0, 0);
 
        return 0;
 }
@@ -408,7 +405,7 @@ int masterPlay(void* outBuf, void* inBuf, unsigned bufferSize,
 
 void close()
 {
-       clock::stop();
+       clock::setStatus(ClockStatus::STOPPED);
        while (channels.size() > 0)
                mh::deleteChannel(channels.at(0));
        pthread_mutex_destroy(&mutex);
@@ -427,7 +424,6 @@ bool isSilent()
 }
 
 
-
 /* -------------------------------------------------------------------------- */
 
 
@@ -436,6 +432,8 @@ bool isChannelAudible(Channel* ch)
        return !hasSolos || (hasSolos && ch->solo);
 }
 
+bool isMetronomeOn() { return metronome_.running; }
+
 
 /* -------------------------------------------------------------------------- */
 
@@ -454,11 +452,35 @@ void rewind()
 
 void startInputRec()
 {
-       /* Start inputTracker from the current frame, not the beginning. */
-       recording    = true;
-       inputTracker = clock::getCurrentFrame();
+       /* Start inputTracker_ from the current frame, not the beginning. */
+       recording     = true;
+       inputTracker_ = clock::getCurrentFrame();
+}
+
+/* -------------------------------------------------------------------------- */
+
+
+void toggleMetronome()
+{
+       metronome_.running = !metronome_.running;
 }
 
+
+void setMetronome(bool v) 
+{ 
+       metronome_.running = v; 
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+void setSignalCallback(std::function<void()> f)
+{
+       signalCb_ = f;
+}
+
+
 /* -------------------------------------------------------------------------- */
 
 
@@ -470,8 +492,8 @@ void mergeVirtualInput()
                        continue;
                SampleChannel* sch = static_cast<SampleChannel*>(ch);
                if (sch->armed)
-                       sch->wave->copyData(vChanInput[0], vChanInput.countFrames());
+                       sch->wave->copyData(vChanInput_[0], vChanInput_.countFrames());
        }
-       vChanInput.clear();
+       vChanInput_.clear();
 }
 }}}; // giada::m::mixer::
index fea09bb9b7cf7f6d1ce097d3be3e715df8cfb90f..10b18dc28fe06a257f0225b520f6c07628a674e2 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -29,7 +29,9 @@
 #define G_MIXER_H
 
 
+#include <atomic>
 #include <pthread.h>
+#include <functional>
 #include <vector>
 #include "recorder.h"
 #include "types.h"
@@ -57,16 +59,14 @@ struct FrameEvents
 
 extern std::vector<Channel*> channels;
 
-extern bool   recording;         // is recording something?
+extern bool   recording;     // is recording something?
 extern bool   ready;
-extern float  outVol;
-extern float  inVol;
-extern float  peakOut;
-extern float  peakIn;
-extern bool      metronome;
-extern int    waitRec;       // delayComp guard
-extern bool   rewindWait;         // rewind guard, if quantized
+extern bool   rewindWait;    // rewind guard, if quantized
 extern bool   hasSolos;      // more than 0 channels soloed
+extern std::atomic<float> outVol;
+extern std::atomic<float> inVol;
+extern std::atomic<float> peakOut;
+extern std::atomic<float> peakIn;
 
 /* inToOut
 Copy, process and paste the input into the output, in order to obtain a "hear 
@@ -114,6 +114,12 @@ Copies the virtual channel input in the channels designed for input recording.
 Called by mixerHandler on stopInputRec(). */
 
 void mergeVirtualInput();
+
+void toggleMetronome();
+bool isMetronomeOn();
+void setMetronome(bool v);
+
+void setSignalCallback(std::function<void()> f);
 }}} // giada::m::mixer::;
 
 
index 8601ed8d00a420a71e5b8641fe7ca19c29a1715e..4864a24936bc7f353f610146802b884de21e003a 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
  * -------------------------------------------------------------------------- */
 
 
+#include <cassert>
 #include <vector>
 #include <algorithm>
 #include "../utils/fs.h"
 #include "../utils/string.h"
 #include "../utils/log.h"
+#include "../utils/vector.h"
 #include "../glue/main.h"
 #include "../glue/channel.h"
 #include "kernelMidi.h"
@@ -37,6 +39,7 @@
 #include "const.h"
 #include "init.h"
 #include "pluginHost.h"
+#include "pluginManager.h"
 #include "plugin.h"
 #include "waveFx.h"
 #include "conf.h"
@@ -66,18 +69,16 @@ namespace
 {
 #ifdef WITH_VST
 
-int readPatchPlugins(vector<patch::plugin_t>* list, int type)
+int readPatchPlugins_(const vector<patch::plugin_t>& list, pluginHost::StackType t)
 {
        int ret = 1;
-       for (unsigned i=0; i<list->size(); i++) {
-               patch::plugin_t *ppl = &list->at(i);
-               // TODO use glue_addPlugin()
-               Plugin *plugin = pluginHost::addPlugin(ppl->path.c_str(), type, 
-                       &mixer::mutex, nullptr);
-               if (plugin != nullptr) {
-                       plugin->setBypass(ppl->bypass);
-                       for (unsigned j=0; j<ppl->params.size(); j++)
-                               plugin->setParameter(j, ppl->params.at(j));
+       for (const patch::plugin_t& ppl : list) {
+               std::unique_ptr<Plugin> p = pluginManager::makePlugin(ppl.path);
+               if (p != nullptr) {
+                       p->setBypass(ppl.bypass);
+                       for (unsigned j=0; j<ppl.params.size(); j++)
+                               p->setParameter(j, ppl.params.at(j));
+                       pluginHost::addPlugin(std::move(p), t, &mixer::mutex, nullptr);
                        ret &= 1;
                }
                else
@@ -138,13 +139,9 @@ Channel* addChannel(ChannelType type)
        Channel* ch = channelManager::create(type, kernelAudio::getRealBufSize(), 
                conf::inputMonitorDefaultOn);
 
-       while (true) {
-               if (pthread_mutex_trylock(&mixer::mutex) != 0)
-                       continue;
-               mixer::channels.push_back(ch);
-               pthread_mutex_unlock(&mixer::mutex);
-               break;
-       }
+       pthread_mutex_lock(&mixer::mutex);
+       mixer::channels.push_back(ch);
+       pthread_mutex_unlock(&mixer::mutex);
 
        ch->index = getNewChanIndex();
        gu_log("[addChannel] channel index=%d added, type=%d, total=%d\n",
@@ -158,15 +155,13 @@ Channel* addChannel(ChannelType type)
 
 void deleteChannel(Channel* target)
 {
-       while (true) {
-               if (pthread_mutex_trylock(&mixer::mutex) != 0)
-                       continue;
-               auto it = std::find(mixer::channels.begin(), mixer::channels.end(), target);
-               if (it != mixer::channels.end()) 
-                       mixer::channels.erase(it);
-               pthread_mutex_unlock(&mixer::mutex);
-               return;
-       }
+       int index = u::vector::indexOf(mixer::channels, target);
+       assert(index != -1);
+       
+       pthread_mutex_lock(&mixer::mutex);
+       delete mixer::channels.at(index);
+       mixer::channels.erase(mixer::channels.begin() + index);
+       pthread_mutex_unlock(&mixer::mutex);
 }
 
 
@@ -186,33 +181,9 @@ Channel* getChannelByIndex(int index)
 /* -------------------------------------------------------------------------- */
 
 
-bool hasLogicalSamples()
-{
-       for (const Channel* ch : mixer::channels)
-               if (ch->hasLogicalData())
-                       return true;
-       return false;
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
-bool hasEditedSamples()
-{
-       for (const Channel* ch : mixer::channels)
-               if (ch->hasEditedData())
-                       return true;
-       return false;
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
 void stopSequencer()
 {
-       clock::stop();
+       clock::setStatus(ClockStatus::STOPPED);
        for (Channel* ch : mixer::channels)
                ch->stopBySeq(conf::chansStopOnSeqHalt);
 }
@@ -239,19 +210,19 @@ void readPatch()
 {
        mixer::ready = false;
 
-       mixer::outVol = patch::masterVolOut;
-       mixer::inVol = patch::masterVolIn;
+       mixer::outVol.store(patch::masterVolOut);
+       mixer::inVol.store(patch::masterVolIn);
        clock::setBpm(patch::bpm);
        clock::setBars(patch::bars);
        clock::setBeats(patch::beats);
        clock::setQuantize(patch::quantize);
        clock::updateFrameBars();
-       mixer::metronome = patch::metronome;
+       mixer::setMetronome(patch::metronome);
 
 #ifdef WITH_VST
 
-       readPatchPlugins(&patch::masterInPlugins, pluginHost::MASTER_IN);
-       readPatchPlugins(&patch::masterOutPlugins, pluginHost::MASTER_OUT);
+       readPatchPlugins_(patch::masterInPlugins, pluginHost::StackType::MASTER_IN);
+       readPatchPlugins_(patch::masterOutPlugins, pluginHost::StackType::MASTER_OUT);
 
 #endif
 
@@ -282,7 +253,8 @@ void rewindSequencer()
 
 bool startInputRec()
 {
-       int channelsReady = 0;
+       if (!hasRecordableSampleChannels())
+               return false;
 
        for (Channel* ch : mixer::channels) {
 
@@ -293,25 +265,17 @@ bool startInputRec()
 
                /* Allocate empty sample for the current channel. */
 
-               Wave*  wave = nullptr;
-               string name = string("TAKE-" + gu_iToString(patch::lastTakeId++)); // Increase lastTakeId 
+               string name    = string("TAKE-" + u::string::iToString(patch::lastTakeId++));
+               string nameExt = name + ".wav";
 
-               waveManager::createEmpty(clock::getFramesInLoop(), G_MAX_IO_CHANS, 
-                       conf::samplerate, name + ".wav", &wave); 
-
-               sch->pushWave(wave);
+               sch->pushWave(waveManager::createEmpty(clock::getFramesInLoop(), 
+                       G_MAX_IO_CHANS, conf::samplerate, nameExt));
                sch->name = name; 
-               channelsReady++;
 
-               gu_log("[startInputRec] start input recs using chan %d with size %d "
+               gu_log("[startInputRec] start input recs using Channel %d with size %d "
                        "on frame=%d\n", sch->index, clock::getFramesInLoop(), clock::getCurrentFrame());
        }
 
-       /** FIXME: mixer::startInputRec() should be called before wave allocation */
-       /** FIXME: mixer::startInputRec() should be called before wave allocation */
-       /** FIXME: mixer::startInputRec() should be called before wave allocation */
-       if (channelsReady == 0)
-               return false;
        mixer::startInputRec();
        return true;
 }
@@ -324,7 +288,6 @@ void stopInputRec()
 {
        mixer::mergeVirtualInput();
        mixer::recording = false;
-       mixer::waitRec = 0; // in case delay compensation is in use
 
        for (Channel* ch : mixer::channels)
                ch->stopInputRec(clock::getCurrentFrame());
@@ -338,10 +301,37 @@ void stopInputRec()
 
 bool hasArmedSampleChannels()
 {
-       for (const Channel* ch : mixer::channels)
-               if (ch->type == ChannelType::SAMPLE && ch->armed)
-                       return true;
-       return false;
+       return std::any_of(mixer::channels.begin(), mixer::channels.end(), [](const Channel* ch)
+       {
+               return ch->type == ChannelType::SAMPLE && ch->armed;
+       });
+}
+
+
+bool hasRecordableSampleChannels()
+{
+       return std::any_of(mixer::channels.begin(), mixer::channels.end(), [](const Channel* ch)
+       {
+               return ch->canInputRec();
+       });
+}
+
+
+bool hasLogicalSamples()
+{
+       return std::any_of(mixer::channels.begin(), mixer::channels.end(), [](const Channel* ch)
+       {
+               return ch->hasLogicalData();
+       });
+}
+
+
+bool hasEditedSamples()
+{
+       return std::any_of(mixer::channels.begin(), mixer::channels.end(), [](const Channel* ch)
+       {
+               return ch->hasEditedData();
+       });
 }
 
 
index 895a1dcceefcd225553a4f30649546c3c8d1c390..19e514e2a5ebf74fff143915f6ad99f43d6020c5 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -58,16 +58,6 @@ Returns channel with given index 'i'. */
 
 Channel* getChannelByIndex(int i);
 
-/* hasLogicalSamples
-True if 1 or more samples are logical (memory only, such as takes) */
-
-bool hasLogicalSamples();
-
-/* hasEditedSamples
-True if 1 or more samples was edited via gEditor */
-
-bool hasEditedSamples();
-
 /* stopSequencer
 Stops the sequencer, with special case if samplesStopOnSeqHalt is true. */
 
@@ -88,7 +78,7 @@ void readPatch();
 
 /* startInputRec - record from line in
 Creates a new empty wave in the first available channels. Returns false if
-something went wrong. */
+there are no available channels. */
 
 bool startInputRec();
 
@@ -100,11 +90,26 @@ to skip check against itself. */
 
 bool uniqueSamplePath(const SampleChannel* skip, const std::string& p);
 
+/* hasLogicalSamples
+True if 1 or more samples are logical (memory only, such as takes) */
+
+bool hasLogicalSamples();
+
+/* hasEditedSamples
+True if 1 or more samples was edited via gEditor */
+
+bool hasEditedSamples();
+
 /* hasArmedSampleChannels
-Tells whether Mixer has one or more sample channels armed for input
-recording. */
+Tells whether Mixer has one or more Sample Channels armed for input recording. */
 
 bool hasArmedSampleChannels();
+
+/* hasRecordableSampleChannels
+Tells whether Mixer has one or more recordable Sample Channels, that is: 
+a) armed; b) empty (no Wave). */
+
+bool hasRecordableSampleChannels();
 }}}  // giada::m::mh::
 
 
index 2add0b9f5e15d347f08fd2234e25021a90738fee..5f61b17147e9e208d70d2199769719bb92d2db68 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -259,7 +259,7 @@ bool readChannels(json_t* jContainer)
        json_t* jChannel;
        json_array_foreach(jChannels, channelIndex, jChannel) {
 
-               string channelIndexStr = "channel " + gu_iToString(channelIndex);
+               string channelIndexStr = "channel " + u::string::iToString(channelIndex);
                if (!storager::checkObject(jChannel, channelIndexStr.c_str()))
                        return 0;
 
@@ -294,7 +294,7 @@ bool readChannels(json_t* jContainer)
                if (!storager::setInt   (jChannel, PATCH_KEY_CHANNEL_BEGIN,                channel.begin)) return 0;
                if (!storager::setInt   (jChannel, PATCH_KEY_CHANNEL_END,                  channel.end)) return 0;
                if (!storager::setFloat (jChannel, PATCH_KEY_CHANNEL_BOOST,                channel.boost)) return 0;
-               if (!storager::setInt   (jChannel, PATCH_KEY_CHANNEL_REC_ACTIVE,           channel.recActive)) return 0;
+               if (!storager::setInt   (jChannel, PATCH_KEY_CHANNEL_READ_ACTIONS,         channel.readActions)) return 0;
                if (!storager::setFloat (jChannel, PATCH_KEY_CHANNEL_PITCH,                channel.pitch)) return 0;
                if (!storager::setBool  (jChannel, PATCH_KEY_CHANNEL_INPUT_MONITOR,        channel.inputMonitor)) return 0;
                if (!storager::setUint32(jChannel, PATCH_KEY_CHANNEL_MIDI_IN_READ_ACTIONS, channel.midiInReadActions)) return 0;
@@ -327,7 +327,7 @@ bool readColumns(json_t* jContainer)
        json_t* jColumn;
        json_array_foreach(jColumns, columnIndex, jColumn) {
 
-               string columnIndexStr = "column " + gu_iToString(columnIndex);
+               string columnIndexStr = "column " + u::string::iToString(columnIndex);
                if (!storager::checkObject(jColumn, columnIndexStr.c_str()))
                        return 0;
 
@@ -473,7 +473,7 @@ void writeChannels(json_t* jContainer, vector<channel_t>* channels)
                json_object_set_new(jChannel, PATCH_KEY_CHANNEL_BEGIN,                json_integer(channel.begin));
                json_object_set_new(jChannel, PATCH_KEY_CHANNEL_END,                  json_integer(channel.end));
                json_object_set_new(jChannel, PATCH_KEY_CHANNEL_BOOST,                json_real(channel.boost));
-               json_object_set_new(jChannel, PATCH_KEY_CHANNEL_REC_ACTIVE,           json_integer(channel.recActive));
+               json_object_set_new(jChannel, PATCH_KEY_CHANNEL_READ_ACTIONS,         json_integer(channel.readActions));
                json_object_set_new(jChannel, PATCH_KEY_CHANNEL_PITCH,                json_real(channel.pitch));
                json_object_set_new(jChannel, PATCH_KEY_CHANNEL_INPUT_MONITOR,        json_boolean(channel.inputMonitor));
                json_object_set_new(jChannel, PATCH_KEY_CHANNEL_MIDI_IN_READ_ACTIONS, json_integer(channel.midiInReadActions));
index afc51801552360f684200a972576fca426fe0144..833ade2332e94b9e7e0e86cdb0e22524e72c88e7 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -91,7 +91,7 @@ struct channel_t
        int         begin;
        int         end;
        float       boost;
-       int         recActive;
+       int         readActions; // TODO - should be bool
        float       pitch;
        bool        inputMonitor;
        uint32_t    midiInReadActions;
index 2af8fae2790bae19b26dc69fcf7efbd952709b8d..32e9b888d57fde04417514812b039a4e2a003705 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -42,31 +42,40 @@ using std::string;
 namespace giada {
 namespace m 
 {
-int Plugin::idGenerator = 1;
+int Plugin::m_idGenerator = 1;
 
 
 /* -------------------------------------------------------------------------- */
 
 
-Plugin::Plugin(juce::AudioPluginInstance* plugin, double samplerate,
-       int buffersize)
-       : ui    (nullptr),
-         plugin(plugin),
-         id    (idGenerator++),
-         bypass(false)
+Plugin::Plugin(juce::AudioPluginInstance* plugin, double samplerate, int buffersize)
+: m_ui    (nullptr),
+  m_plugin(plugin),
+  m_id    (m_idGenerator++),
+  m_bypass(false)
 {
        using namespace juce;
-
+       
        /* Init midiInParams. All values are empty (0x0): they will be filled during
        midi learning process. */
 
-       const OwnedArray<AudioProcessorParameter>& params = plugin->getParameters();
+       const OwnedArray<AudioProcessorParameter>& params = m_plugin->getParameters();
        for (int i=0; i<params.size(); i++)
                midiInParams.push_back(0x0);
        
-       plugin->prepareToPlay(samplerate, buffersize);
+       m_buffer.setSize(G_MAX_IO_CHANS, buffersize);
+
+       /* Try to set the main bus to the current number of channels. In the future
+       this setup will be performed manually through a proper channel matrix. */
 
-       gu_log("[Plugin] plugin initialized and ready. MIDI input params: %lu\n",
+       juce::AudioProcessor::Bus* outBus = getMainBus(BusType::OUT);
+       juce::AudioProcessor::Bus* inBus  = getMainBus(BusType::IN);
+       if (outBus != nullptr) outBus->setNumberOfChannels(G_MAX_IO_CHANS);
+       if (inBus != nullptr)  inBus->setNumberOfChannels(G_MAX_IO_CHANS);
+
+       m_plugin->prepareToPlay(samplerate, buffersize);
+
+       gu_log("[Plugin] plugin initialized and ready. MIDI input params: %lu\n", 
                midiInParams.size());
 }
 
@@ -77,8 +86,29 @@ Plugin::Plugin(juce::AudioPluginInstance* plugin, double samplerate,
 Plugin::~Plugin()
 {
        closeEditor();
-       plugin->suspendProcessing(true);
-       plugin->releaseResources();
+       m_plugin->suspendProcessing(true);
+       m_plugin->releaseResources();
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+juce::AudioProcessor::Bus* Plugin::getMainBus(BusType b) const
+{
+       const bool isInput = static_cast<bool>(b);
+       for (int i=0; i<m_plugin->getBusCount(isInput); i++)
+               if (m_plugin->getBus(isInput, i)->isMain())
+                       return m_plugin->getBus(isInput, i); 
+       return nullptr;
+}
+
+
+int Plugin::countMainOutChannels() const
+{
+       juce::AudioProcessor::Bus* b = getMainBus(BusType::OUT);
+       assert(b != nullptr);
+       return b->getNumberOfChannels();
 }
 
 
@@ -87,13 +117,13 @@ Plugin::~Plugin()
 
 void Plugin::showEditor(void* parent)
 {
-       ui = plugin->createEditorIfNeeded();
-       if (ui == nullptr) {
+       m_ui = m_plugin->createEditorIfNeeded();
+       if (m_ui == nullptr) {
                gu_log("[Plugin::showEditor] unable to create editor!\n");
                return;
        }
-       ui->setOpaque(true);
-       ui->addToDesktop(0, parent);
+       m_ui->setOpaque(true);
+       m_ui->addToDesktop(0, parent);
 }
 
 
@@ -102,7 +132,7 @@ void Plugin::showEditor(void* parent)
 
 bool Plugin::isEditorOpen() const
 {
-       return ui != nullptr && ui->isVisible() && ui->isOnDesktop();
+       return m_ui != nullptr && m_ui->isVisible() && m_ui->isOnDesktop();
 }
 
 
@@ -111,7 +141,7 @@ bool Plugin::isEditorOpen() const
 
 string Plugin::getUniqueId() const
 {
-       return plugin->getPluginDescription().createIdentifierString().toStdString();
+       return m_plugin->getPluginDescription().createIdentifierString().toStdString();
 }
 
 
@@ -120,7 +150,7 @@ string Plugin::getUniqueId() const
 
 int Plugin::getNumParameters() const
 {
-       return plugin->getParameters().size();
+       return m_plugin->getParameters().size();
 }
 
 
@@ -129,7 +159,7 @@ int Plugin::getNumParameters() const
 
 float Plugin::getParameter(int paramIndex) const
 {
-       return plugin->getParameters()[paramIndex]->getValue();
+       return m_plugin->getParameters()[paramIndex]->getValue();
 }
 
 
@@ -138,16 +168,7 @@ float Plugin::getParameter(int paramIndex) const
 
 void Plugin::setParameter(int paramIndex, float value) const
 {
-       plugin->getParameters()[paramIndex]->setValue(value);
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
-void Plugin::prepareToPlay(double samplerate, int buffersize) const
-{
-       plugin->prepareToPlay(samplerate, buffersize);
+       m_plugin->getParameters()[paramIndex]->setValue(value);
 }
 
 
@@ -156,7 +177,7 @@ void Plugin::prepareToPlay(double samplerate, int buffersize) const
 
 string Plugin::getName() const
 {
-       return plugin->getName().toStdString();
+       return m_plugin->getName().toStdString();
 }
 
 
@@ -165,7 +186,7 @@ string Plugin::getName() const
 
 bool Plugin::isSuspended() const
 {
-       return plugin->isSuspended();
+       return m_plugin->isSuspended();
 }
 
 
@@ -174,37 +195,64 @@ bool Plugin::isSuspended() const
 
 bool Plugin::acceptsMidi() const
 {
-       return plugin->acceptsMidi();
+       return m_plugin->acceptsMidi();
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-bool Plugin::isBypassed() const { return bypass; }
-void Plugin::toggleBypass() { bypass = !bypass; }
-void Plugin::setBypass(bool b) { bypass = b; }
+bool Plugin::isBypassed() const { return m_bypass; }
+void Plugin::toggleBypass() { m_bypass = !m_bypass; }
+void Plugin::setBypass(bool b) { m_bypass = b; }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-int Plugin::getId() const { return id; }
+int Plugin::getId() const { return m_id; }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-int Plugin::getEditorW() const { assert(ui != nullptr); return ui->getWidth(); }
-int Plugin::getEditorH() const { assert(ui != nullptr); return ui->getHeight(); }
+int Plugin::getEditorW() const { assert(m_ui != nullptr); return m_ui->getWidth(); }
+int Plugin::getEditorH() const { assert(m_ui != nullptr); return m_ui->getHeight(); }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void Plugin::process(juce::AudioBuffer<float>& b, juce::MidiBuffer m) const
+void Plugin::process(juce::AudioBuffer<float>& out, juce::MidiBuffer m)
 {
-       plugin->processBlock(b, m);
+       /* If this is not an instrument (i.e. doesn't accept MIDI), copy the 
+       incoming buffer data into the temporary one. This way FXes will process
+       existing audio data. Conversely, if the plug-in is an instrument, it 
+       generates its own audio data inside a clean m_buffer and we can play more 
+       than one plug-in instrument in the same stack, driven by the same set of 
+       MIDI events. */
+
+       const bool isInstrument = m_plugin->acceptsMidi();
+
+       if (!isInstrument)
+               m_buffer = out;
+       else
+               m_buffer.clear();
+
+       m_plugin->processBlock(m_buffer, m);
+
+       /* The local buffer is now filled. Let's try to fill the 'out' one as well
+       by taking into account the bus layout - many plug-ins might have mono output
+       and we have a stereo buffer to fill. */
+
+       for (int i=0, j=0; i<out.getNumChannels(); i++) {
+               if (isInstrument)
+                       out.addFrom(i, 0, m_buffer, j, 0, m_buffer.getNumSamples());
+               else
+                       out.copyFrom(i, 0, m_buffer, j, 0, m_buffer.getNumSamples());
+               if (i < countMainOutChannels() - 1)
+                       j++;
+       }
 }
 
 
@@ -213,7 +261,7 @@ void Plugin::process(juce::AudioBuffer<float>& b, juce::MidiBuffer m) const
 
 int Plugin::getNumPrograms() const
 {
-       return plugin->getNumPrograms();
+       return m_plugin->getNumPrograms();
 }
 
 
@@ -222,7 +270,7 @@ int Plugin::getNumPrograms() const
 
 int Plugin::getCurrentProgram() const
 {
-       return plugin->getCurrentProgram();
+       return m_plugin->getCurrentProgram();
 }
 
 
@@ -231,7 +279,7 @@ int Plugin::getCurrentProgram() const
 
 void Plugin::setCurrentProgram(int index) const
 {
-       plugin->setCurrentProgram(index);
+       m_plugin->setCurrentProgram(index);
 }
 
 
@@ -240,7 +288,7 @@ void Plugin::setCurrentProgram(int index) const
 
 bool Plugin::hasEditor() const
 {
-       return plugin->hasEditor();
+       return m_plugin->hasEditor();
 }
 
 
@@ -249,7 +297,7 @@ bool Plugin::hasEditor() const
 
 string Plugin::getProgramName(int index) const
 {
-       return plugin->getProgramName(index).toStdString();
+       return m_plugin->getProgramName(index).toStdString();
 }
 
 
@@ -258,7 +306,7 @@ string Plugin::getProgramName(int index) const
 
 string Plugin::getParameterName(int index) const
 {
-       return plugin->getParameters()[index]->getName(MAX_LABEL_SIZE).toStdString();
+       return m_plugin->getParameters()[index]->getName(MAX_LABEL_SIZE).toStdString();
 }
 
 
@@ -267,7 +315,7 @@ string Plugin::getParameterName(int index) const
 
 string Plugin::getParameterText(int index) const
 {
-       return plugin->getParameters()[index]->getCurrentValueAsText().toStdString();
+       return m_plugin->getParameters()[index]->getCurrentValueAsText().toStdString();
 }
 
 
@@ -276,7 +324,7 @@ string Plugin::getParameterText(int index) const
 
 string Plugin::getParameterLabel(int index) const
 {
-       return plugin->getParameters()[index]->getLabel().toStdString();
+       return m_plugin->getParameters()[index]->getLabel().toStdString();
 }
 
 
@@ -285,8 +333,8 @@ string Plugin::getParameterLabel(int index) const
 
 void Plugin::closeEditor()
 {
-       delete ui;
-       ui = nullptr;
+       delete m_ui;
+       m_ui = nullptr;
 }
 
 }} // giada::m::
index 61202b6144e6dbf4e46f51a1d2f0f39de0f1bbe6..a7cca047a7ffcbc2cc152a903afad386e2c1c719 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -39,18 +39,6 @@ namespace m
 {
 class Plugin
 {
-private:
-
-       static const int MAX_LABEL_SIZE = 64;
-       
-       static int idGenerator;
-
-       juce::AudioProcessorEditor* ui;    // gui
-       juce::AudioPluginInstance* plugin; // core
-
-       int id;
-       bool bypass;
-
 public:
 
        Plugin(juce::AudioPluginInstance* p, double samplerate, int buffersize);
@@ -61,15 +49,6 @@ public:
 
        std::string getUniqueId() const;
 
-       /* process
-       Process the plug-in with audio and MIDI data. The audio buffer is a reference:
-       it has to be altered by the plug-in itself. Conversely, the MIDI buffer must
-       be passed by copy: each plug-in must receive its own copy of the event set, so
-       that any attempt to change/clear the MIDI buffer will only modify the local 
-       copy. */
-
-       void process(juce::AudioBuffer<float>& b, juce::MidiBuffer m) const;
-
        std::string getName() const;
        bool isEditorOpen() const;
        bool hasEditor() const;
@@ -87,10 +66,18 @@ public:
        int getEditorW() const;
        int getEditorH() const;
        void setParameter(int index, float value) const;
-       void prepareToPlay(double samplerate, int buffersize) const;
        void setCurrentProgram(int index) const;
        bool acceptsMidi() const;
 
+       /* process
+       Process the plug-in with audio and MIDI data. The audio buffer is a reference:
+       it has to be altered by the plug-in itself. Conversely, the MIDI buffer must
+       be passed by copy: each plug-in must receive its own copy of the event set, so
+       that any attempt to change/clear the MIDI buffer will only modify the local 
+       copy. */
+
+       void process(juce::AudioBuffer<float>& b, juce::MidiBuffer m);
+
        void showEditor(void* parent);
 
        /* closeEditor
@@ -105,6 +92,28 @@ public:
        A list of midiIn hex values for parameter automation. */
 
        std::vector<uint32_t> midiInParams;
+
+private:
+
+       enum class BusType { IN = true, OUT = false };
+
+       static const int MAX_LABEL_SIZE = 64;
+       
+       static int m_idGenerator;
+
+       juce::AudioProcessorEditor* m_ui;     // gui
+       juce::AudioPluginInstance*  m_plugin; // core
+       juce::AudioBuffer<float>    m_buffer;
+
+       int m_id;
+       bool m_bypass;
+
+       juce::AudioProcessor::Bus* getMainBus(BusType b) const;
+
+       /* countMainOutChannels
+       Returns the current channel layout for the main output bus. */
+
+       int countMainOutChannels() const;
 };
 
 }} // giada::m::
index 2e84fe8a7f752619b8c7d58433ca4a2732c8ef13..98f09d8db3c6e9986c06d321f6d8c64adddc459e 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
 
 #include <cassert>
 #include "../utils/log.h"
-#include "../utils/fs.h"
-#include "../utils/string.h"
+#include "../utils/vector.h"
 #include "const.h"
 #include "channel.h"
 #include "plugin.h"
 #include "pluginHost.h"
 
 
-using std::vector;
-using std::string;
-
-
 namespace giada {
 namespace m {
 namespace pluginHost
 {
 namespace
 {
-juce::MessageManager* messageManager;
-
-/* pluginFormat
- * Plugin format manager. */
-
-juce::VSTPluginFormat pluginFormat;
-
-/* knownPuginList
- * List of known (i.e. scanned) plugins. */
+juce::MessageManager* messageManager_;
+juce::AudioBuffer<float> audioBuffer_;
 
-juce::KnownPluginList knownPluginList;
+std::vector<std::unique_ptr<Plugin>> masterOut_;
+std::vector<std::unique_ptr<Plugin>> masterIn_;
 
-/* unknownPluginList
- * List of unrecognized plugins found in a patch. */
 
-vector<string> unknownPluginList;
-
-vector<Plugin*> masterOut;
-vector<Plugin*> masterIn;
-
-/* Audio|MidiBuffer
- * Dynamic buffers. */
-
-juce::AudioBuffer<float> audioBuffer;
+/* -------------------------------------------------------------------------- */
 
-int samplerate;
-int buffersize;
 
-/* missingPlugins
- * If some plugins from any stack are missing. */
+void processPlugin_(Plugin& p, Channel* ch)
+{
+       if (p.isSuspended() || p.isBypassed())
+               return;
 
-bool missingPlugins;
+       juce::MidiBuffer events;
+       if (ch != nullptr)
+               events = ch->getPluginMidiEvents();
 
-void splitPluginDescription(const string& descr, vector<string>& out)
-{
-       // input:  VST-mda-Ambience-18fae2d2-6d646141  string
-       // output: [2-------------] [1-----] [0-----]  vector.size() == 3
-       
-       string chunk = "";
-       int count = 2;
-       for (int i=descr.length()-1; i >= 0; i--) {
-               if (descr[i] == '-' && count != 0) {
-                       out.push_back(chunk);
-                       count--;
-                       chunk = "";
-               }
-               else
-                       chunk += descr[i];
-       }
-       out.push_back(chunk);
+       p.process(audioBuffer_, events);
 }
 
 
-/* findPluginDescription
-Browses the list of known plug-ins until plug-in with id == 'id' is found.
-Unfortunately knownPluginList.getTypeForIdentifierString(id) doesn't work for
-VSTs: their ID is based on the plug-in file location. E.g.:
-
-       /home/vst/mdaAmbience.so      -> VST-mdaAmbience-18fae2d2-6d646141
-       /home/vst-test/mdaAmbience.so -> VST-mdaAmbience-b328b2f6-6d646141
+/* -------------------------------------------------------------------------- */
 
-The following function simply drops the first hash code during comparison. */
+/* getStack_
+Returns a vector of unique_ptr's given the stackType. If stackType == CHANNEL
+a pointer to Channel is also required. */
 
-const juce::PluginDescription* findPluginDescription(const string& id)
+std::vector<std::unique_ptr<Plugin>>& getStack_(StackType t, Channel* ch=nullptr)
 {
-       vector<string> idParts;
-       splitPluginDescription(id, idParts);
-
-       for (const juce::PluginDescription* pd : knownPluginList) {
-               vector<string> tmpIdParts;
-               splitPluginDescription(pd->createIdentifierString().toStdString(), tmpIdParts);
-               if (idParts[0] == tmpIdParts[0] && idParts[2] == tmpIdParts[2])
-                       return pd;
+       switch(t) {
+               case StackType::MASTER_OUT:
+                       return masterOut_;
+               case StackType::MASTER_IN:
+                       return masterIn_;
+               case StackType::CHANNEL:
+                       return ch->plugins;
+               default:
+                       assert(false);
        }
-       return nullptr;
 }
+
 }; // {anonymous}
 
 
@@ -132,7 +94,7 @@ const juce::PluginDescription* findPluginDescription(const string& id)
 /* -------------------------------------------------------------------------- */
 
 
-pthread_mutex_t mutex_midi;
+pthread_mutex_t mutex;
 
 
 /* -------------------------------------------------------------------------- */
@@ -140,325 +102,124 @@ pthread_mutex_t mutex_midi;
 
 void close()
 {
-       messageManager->deleteInstance();
-       pthread_mutex_destroy(&mutex_midi);
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
-void init(int buffersize_, int samplerate_)
-{
-       messageManager = juce::MessageManager::getInstance();
-       audioBuffer.setSize(G_MAX_IO_CHANS, buffersize_);
-       samplerate = samplerate_;
-       buffersize = buffersize_;
-       missingPlugins = false;
-       //unknownPluginList.empty();
-       loadList(gu_getHomePath() + G_SLASH + "plugins.xml");
-
-       pthread_mutex_init(&mutex_midi, nullptr);
-
-       gu_log("[pluginHost::init] initialized with buffersize=%d, samplerate=%d\n",
-       buffersize, samplerate);
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
-int scanDirs(const string& dirs, const std::function<void(float)>& cb)
-{
-       gu_log("[pluginHost::scanDir] requested directories: '%s'\n", dirs.c_str());
-       gu_log("[pluginHost::scanDir] current plugins: %d\n", knownPluginList.getNumTypes());
-
-       knownPluginList.clear();   // clear up previous plugins
-
-       vector<string> dirVec;
-       gu_split(dirs, ";", &dirVec);
-
-       juce::VSTPluginFormat format;
-       juce::FileSearchPath searchPath;
-       for (const string& dir : dirVec)
-               searchPath.add(juce::File(dir));
-
-       juce::PluginDirectoryScanner scanner(knownPluginList, format, searchPath, 
-               true, juce::File()); // true: recursive
-
-       juce::String name;
-       while (scanner.scanNextFile(false, name)) {
-               gu_log("[pluginHost::scanDir]   scanning '%s'\n", name.toRawUTF8());
-               cb(scanner.getProgress());
-       }
-
-       gu_log("[pluginHost::scanDir] %d plugin(s) found\n", knownPluginList.getNumTypes());
-       return knownPluginList.getNumTypes();
+       messageManager_->deleteInstance();
+       pthread_mutex_destroy(&mutex);
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-int saveList(const string& filepath)
+void init(int buffersize)
 {
-       int out = knownPluginList.createXml()->writeToFile(juce::File(filepath), "");
-       if (!out)
-               gu_log("[pluginHost::saveList] unable to save plugin list to %s\n", filepath.c_str());
-       return out;
-}
-
+       messageManager_ = juce::MessageManager::getInstance();
+       audioBuffer_.setSize(G_MAX_IO_CHANS, buffersize);
 
-/* -------------------------------------------------------------------------- */
-
-
-int loadList(const string& filepath)
-{
-       juce::XmlElement* elem = juce::XmlDocument::parse(juce::File(filepath));
-       if (elem) {
-               knownPluginList.recreateFromXml(*elem);
-               delete elem;
-               return 1;
-       }
-       return 0;
+       pthread_mutex_init(&mutex, nullptr);
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-Plugin* addPlugin(const string& fid, int stackType, pthread_mutex_t* mutex, 
+void addPlugin(std::unique_ptr<Plugin> p, StackType t, pthread_mutex_t* mixerMutex, 
        Channel* ch)
 {
-       vector<Plugin*>* pStack = getStack(stackType, ch);
-
-       /* Initialize plugin. The default mode uses getTypeForIdentifierString, 
-       falling back to  getTypeForFile (deprecated) for old patches (< 0.14.4). */
-
-       const juce::PluginDescription* pd = findPluginDescription(fid);
-       if (pd == nullptr) {
-               gu_log("[pluginHost::addPlugin] no plugin found with fid=%s! Trying with "
-                       "deprecated mode...\n", fid.c_str());
-               pd = knownPluginList.getTypeForFile(fid);
-               if (pd == nullptr) {
-                       gu_log("[pluginHost::addPlugin] still nothing to do, returning unknown plugin\n");
-                       missingPlugins = true;
-                       unknownPluginList.push_back(fid);
-                       return nullptr;
-               }
-       }
-
-       juce::AudioPluginInstance* pi = pluginFormat.createInstanceFromDescription(*pd, samplerate, buffersize);
-       if (!pi) {
-               gu_log("[pluginHost::addPlugin] unable to create instance with fid=%s!\n", fid.c_str());
-               missingPlugins = true;
-               return nullptr;
-       }
-       gu_log("[pluginHost::addPlugin] plugin instance with fid=%s created\n", fid.c_str());
+       std::vector<std::unique_ptr<Plugin>>& stack = getStack_(t, ch);
 
-       Plugin* p = new Plugin(pi, samplerate, buffersize);
+       gu_log("[pluginHost::addPlugin] load plugin (%s), stack type=%d, stack size=%d\n",
+               p->getName().c_str(), t, stack.size());
 
-       /* Try to inject the plugin as soon as possible. */
-
-       while (true) {
-               if (pthread_mutex_trylock(mutex) != 0)
-                       continue;
-               pStack->push_back(p);
-               pthread_mutex_unlock(mutex);
-               break;
-       }
-
-       gu_log("[pluginHost::addPlugin] plugin id=%s loaded (%s), stack type=%d, stack size=%d\n",
-               fid.c_str(), p->getName().c_str(), stackType, pStack->size());
-
-       return p;
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
-Plugin* addPlugin(int index, int stackType, pthread_mutex_t* mutex,
-       Channel* ch)
-{
-       juce::PluginDescription* pd = knownPluginList.getType(index);
-       if (pd) {
-               gu_log("[pluginHost::addPlugin] plugin found, uid=%s, name=%s...\n",
-                       pd->createIdentifierString().toRawUTF8(), pd->name.toRawUTF8());
-               return addPlugin(pd->createIdentifierString().toStdString(), stackType, mutex, ch);
-       }
-       gu_log("[pluginHost::addPlugin] no plugins found at index=%d!\n", index);
-       return nullptr;
+       pthread_mutex_lock(mixerMutex);
+       stack.push_back(std::move(p));
+       pthread_mutex_unlock(mixerMutex);
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-vector<Plugin*>* getStack(int stackType, Channel* ch)
+std::vector<Plugin*> getStack(StackType t, Channel* ch)
 {
-       switch(stackType) {
-               case MASTER_OUT:
-                       return &masterOut;
-               case MASTER_IN:
-                       return &masterIn;
-               case CHANNEL:
-                       return &ch->plugins;
-               default:
-                       return nullptr;
-       }
-}
+       std::vector<std::unique_ptr<Plugin>>& stack = getStack_(t, ch);
 
+       std::vector<Plugin*> out;
+       for (const std::unique_ptr<Plugin>& p : stack)
+               out.push_back(p.get());
 
-/* -------------------------------------------------------------------------- */
-
-
-unsigned countPlugins(int stackType, Channel* ch)
-{
-       vector<Plugin*>* pStack = getStack(stackType, ch);
-       return pStack->size();
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
-int countAvailablePlugins()
-{
-       return knownPluginList.getNumTypes();
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
-unsigned countUnknownPlugins()
-{
-       return unknownPluginList.size();
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
-pluginHost::PluginInfo getAvailablePluginInfo(int i)
-{
-       juce::PluginDescription* pd = knownPluginList.getType(i);
-       PluginInfo pi;
-       pi.uid              = pd->fileOrIdentifier.toStdString();
-       pi.name             = pd->name.toStdString();
-       pi.category         = pd->category.toStdString();
-       pi.manufacturerName = pd->manufacturerName.toStdString();
-       pi.format           = pd->pluginFormatName.toStdString();
-       pi.isInstrument     = pd->isInstrument;
-       return pi;
+       return out;
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-bool hasMissingPlugins()
-{
-       return missingPlugins;
-};
-
-
-/* -------------------------------------------------------------------------- */
-
-
-string getUnknownPluginInfo(int i)
+int countPlugins(StackType t, Channel* ch)
 {
-       return unknownPluginList.at(i);
+       return getStack_(t, ch).size();
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void freeStack(int stackType, pthread_mutex_t* mutex, Channel* ch)
+void freeStack(StackType t, pthread_mutex_t* mixerMutex, Channel* ch)
 {
-       vector<Plugin*>* pStack = getStack(stackType, ch);
+       std::vector<std::unique_ptr<Plugin>>& stack = getStack_(t, ch);
 
-       if (pStack->size() == 0)
+       if (stack.size() == 0)
                return;
 
-       while (true) {
-               if (pthread_mutex_trylock(mutex) != 0)
-                       continue;
-               for (unsigned i=0; i<pStack->size(); i++)
-                       delete pStack->at(i);
-               pStack->clear();
-               pthread_mutex_unlock(mutex);
-               break;
-       }
-       gu_log("[pluginHost::freeStack] stack type=%d freed\n", stackType);
+       pthread_mutex_lock(mixerMutex);
+       stack.clear();
+       pthread_mutex_unlock(mixerMutex);
+
+       gu_log("[pluginHost::freeStack] stack type=%d freed\n", t);
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void processStack(AudioBuffer& outBuf, int stackType, Channel* ch)
+void processStack(AudioBuffer& outBuf, StackType t, Channel* ch)
 {
-       vector<Plugin*>* pStack = getStack(stackType, ch);
-
-       /* Empty stack, stack not found or mixer not ready: do nothing. */
+       std::vector<std::unique_ptr<Plugin>>& stack = getStack_(t, ch);
 
-       if (pStack == nullptr || pStack->size() == 0)
+       if (stack.size() == 0)
                return;
 
-       assert(outBuf.countFrames() == audioBuffer.getNumSamples());
+       assert(outBuf.countFrames() == audioBuffer_.getNumSamples());
 
        /* MIDI channels must not process the current buffer: give them an empty one. 
        Sample channels and Master in/out want audio data instead: let's convert the 
        internal buffer from Giada to Juce. */
 
        if (ch != nullptr && ch->type == ChannelType::MIDI) 
-               audioBuffer.clear();
+               audioBuffer_.clear();
        else
                for (int i=0; i<outBuf.countFrames(); i++)
                        for (int j=0; j<outBuf.countChannels(); j++)
-                               audioBuffer.setSample(j, i, outBuf[i][j]);
-
-       /* Hardcore processing. At the end we swap input and output, so that he N-th
-       plugin will process the result of the plugin N-1. Part of this loop must be
-       guarded by mutexes, i.e. the MIDI process part. You definitely don't want
-       a situation like the following one:
-               this::processStack()
-               [a new midi event comes in from kernelMidi thread]
-               channel::clearMidiBuffer()
+                               audioBuffer_.setSample(j, i, outBuf[i][j]);
+
+       /* Hardcore processing. Part of this loop must be guarded by mutexes, i.e. 
+       the MIDI process part. You definitely don't want a situation like the 
+       following one:
+               1. this::processStack()
+               2. [a new midi event comes in from kernelMidi thread]
+               3. channel::clearMidiBuffer()
        The midi event in between would be surely lost, deleted by the last call to
-       channel::clearMidiBuffer()! */
+       channel::clearMidiBuffer()! 
+       TODO - that's why we need a proper queue for MIDI events in input... */
 
        if (ch != nullptr)
-               pthread_mutex_lock(&mutex_midi);
-
-       for (const Plugin* plugin : *pStack) {
-               if (plugin->isSuspended() || plugin->isBypassed())
-                       continue;
-
-               /* If this is a Channel (ch != nullptr) and the current plugin is an 
-               instrument (i.e. accepts MIDI), don't let it fill the current audio buffer: 
-               create a new temporary one instead and then merge the result into the main
-               one when done. This way each plug-in generates its own audio data and we can
-               play more than one plug-in instrument in the same stack, driven by the same
-               set of MIDI events. */
-
-               if (ch != nullptr && plugin->acceptsMidi()) {
-                       juce::AudioBuffer<float> tmp(audioBuffer.getNumChannels(), buffersize);
-                       plugin->process(tmp, ch->getPluginMidiEvents());
-                       for (int i=0; i<audioBuffer.getNumSamples(); i++)
-                               for (int j=0; j<audioBuffer.getNumChannels(); j++)
-                                       audioBuffer.addSample(j, i, tmp.getSample(j, i));       
-               }
-               else
-                       plugin->process(audioBuffer, juce::MidiBuffer()); // Empty MIDI buffer
-       }
+               pthread_mutex_lock(&mutex);
+
+       for (std::unique_ptr<Plugin>& plugin : stack)
+               processPlugin_(*plugin.get(), ch);
 
        if (ch != nullptr) {
                ch->clearMidiBuffer();
-               pthread_mutex_unlock(&mutex_midi);
+               pthread_mutex_unlock(&mutex);
        }
 
        /* Converting buffer from Juce to Giada. A note for the future: if we 
@@ -466,167 +227,103 @@ void processStack(AudioBuffer& outBuf, int stackType, Channel* ch)
 
        for (int i=0; i<outBuf.countFrames(); i++)
                for (int j=0; j<outBuf.countChannels(); j++)    
-                       outBuf[i][j] = audioBuffer.getSample(j, i);
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
-Plugin* getPluginByIndex(int index, int stackType, Channel* ch)
-{
-       vector<Plugin*>* pStack = getStack(stackType, ch);
-       if (pStack->size() == 0)
-               return nullptr;
-       if ((unsigned) index >= pStack->size())
-               return nullptr;
-       return pStack->at(index);
+                       outBuf[i][j] = audioBuffer_.getSample(j, i);
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-int getPluginIndex(int id, int stackType, Channel* ch)
+Plugin* getPluginByIndex(int index, StackType t, Channel* ch)
 {
-       vector<Plugin*>* pStack = getStack(stackType, ch);
-       for (unsigned i=0; i<pStack->size(); i++)
-               if (pStack->at(i)->getId() == id)
-                       return i;
-       return -1;
+       std::vector<std::unique_ptr<Plugin>>& stack = getStack_(t, ch);
+       assert((size_t) index < stack.size());
+       return stack.at(index).get();
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void swapPlugin(unsigned indexA, unsigned indexB, int stackType,
-       pthread_mutex_t* mutex, Channel* ch)
+int getPluginIndex(int id, StackType t, Channel* ch)
 {
-       vector<Plugin*>* pStack = getStack(stackType, ch);
-       while (true) {
-               if (pthread_mutex_trylock(mutex) != 0)
-                       continue;
-               std::swap(pStack->at(indexA), pStack->at(indexB));
-               pthread_mutex_unlock(mutex);
-               gu_log("[pluginHost::swapPlugin] plugin at index %d and %d swapped\n", indexA, indexB);
-               return;
-       }
+       std::vector<std::unique_ptr<Plugin>>& stack = getStack_(t, ch);
+       return u::vector::indexOf(stack, [&](const std::unique_ptr<Plugin>& p) 
+       { 
+               return p->getId() == id;
+       });
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-int freePlugin(int id, int stackType, pthread_mutex_t* mutex, Channel* ch)
+void swapPlugin(int indexA, int indexB, StackType t, pthread_mutex_t* mixerMutex, 
+       Channel* ch)
 {
-       vector<Plugin*>* pStack = getStack(stackType, ch);
-       for (unsigned i=0; i<pStack->size(); i++) {
-               Plugin *pPlugin = pStack->at(i);
-               if (pPlugin->getId() != id)
-                       continue;
-               while (true) {
-                       if (pthread_mutex_trylock(mutex) != 0)
-                               continue;
-                       delete pPlugin;
-                       pStack->erase(pStack->begin() + i);
-                       pthread_mutex_unlock(mutex);
-                       gu_log("[pluginHost::freePlugin] plugin id=%d removed\n", id);
-                       return i;
-               }
-       }
-       gu_log("[pluginHost::freePlugin] plugin id=%d not found\n", id);
-       return -1;
-}
+       std::vector<std::unique_ptr<Plugin>>& stack = getStack_(t, ch);
 
+       pthread_mutex_lock(mixerMutex);
+       std::swap(stack.at(indexA), stack.at(indexB));
+       pthread_mutex_unlock(mixerMutex);
 
-/* -------------------------------------------------------------------------- */
-
-
-void runDispatchLoop()
-{
-       messageManager->runDispatchLoopUntil(10);
-       //gu_log("[pluginHost::runDispatchLoop] %d, hasStopMessageBeenSent=%d\n", r, messageManager->hasStopMessageBeenSent());
+       gu_log("[pluginHost::swapPlugin] plugin at index %d and %d swapped\n", indexA, indexB);
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void freeAllStacks(vector<Channel*>* channels, pthread_mutex_t* mutex)
+int freePlugin(int id, StackType t, pthread_mutex_t* mixerMutex, Channel* ch)
 {
-       freeStack(pluginHost::MASTER_OUT, mutex);
-       freeStack(pluginHost::MASTER_IN, mutex);
-       for (unsigned i=0; i<channels->size(); i++)
-               freeStack(pluginHost::CHANNEL, mutex, channels->at(i));
-       missingPlugins = false;
-       unknownPluginList.clear();
-}
-
-
-/* -------------------------------------------------------------------------- */
-
+       std::vector<std::unique_ptr<Plugin>>& stack = getStack_(t, ch);
 
-int clonePlugin(Plugin* src, int stackType, pthread_mutex_t* mutex,
-       Channel* ch)
-{
-       Plugin* p = addPlugin(src->getUniqueId(), stackType, mutex, ch);
-       if (!p) {
-               gu_log("[pluginHost::clonePlugin] unable to add new plugin to stack!\n");
-               return 0;
-       }
+       int index = u::vector::indexOf(stack, [&](const std::unique_ptr<Plugin>& p) 
+       { 
+               return p->getId() == id; 
+       });
+       assert(index != -1);
 
-       for (int k=0; k<src->getNumParameters(); k++)
-               p->setParameter(k, src->getParameter(k));
+       pthread_mutex_lock(mixerMutex);
+       stack.erase(stack.begin() + index);
+       pthread_mutex_unlock(mixerMutex);       
 
-       return 1;
+       gu_log("[pluginHost::freePlugin] plugin id=%d removed\n", id);
+       return index;
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-bool doesPluginExist(const string& fid)
+void runDispatchLoop()
 {
-       return pluginFormat.doesPluginStillExist(*knownPluginList.getTypeForFile(fid));
+       messageManager_->runDispatchLoopUntil(10);
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void sortPlugins(int method)
+void freeAllStacks(std::vector<Channel*>* channels, pthread_mutex_t* mixerMutex)
 {
-       switch (method) {
-               case sortMethod::NAME:
-                       knownPluginList.sort(juce::KnownPluginList::SortMethod::sortAlphabetically, true);
-                       break;
-               case sortMethod::CATEGORY:
-                       knownPluginList.sort(juce::KnownPluginList::SortMethod::sortByCategory, true);
-                       break;
-               case sortMethod::MANUFACTURER:
-                       knownPluginList.sort(juce::KnownPluginList::SortMethod::sortByManufacturer, true);
-                       break;
-               case sortMethod::FORMAT:
-                       knownPluginList.sort(juce::KnownPluginList::SortMethod::sortByFormat, true);
-                       break;
-       }
+       freeStack(StackType::MASTER_OUT, mixerMutex);
+       freeStack(StackType::MASTER_IN, mixerMutex);
+       for (Channel* c : *channels)
+               freeStack(StackType::CHANNEL, mixerMutex, c);
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void forEachPlugin(int stackType, const Channel* ch, std::function<void(const Plugin* p)> f)
+void forEachPlugin(StackType t, const Channel* ch, std::function<void(const Plugin* p)> f)
 {
-       /* TODO - Remove const is ugly. This is a temporary workaround until all
-       PluginHost functions params will be const-correct. */
-       vector<Plugin*>* stack = getStack(stackType, const_cast<Channel*>(ch));
-       for (const Plugin* p : *stack)
-               f(p);
+       std::vector<std::unique_ptr<Plugin>>& stack = getStack_(t, const_cast<Channel*>(ch));
+       for (const std::unique_ptr<Plugin>& p : stack)
+               f(p.get());
 }
 
-
 }}}; // giada::m::pluginHost::
 
 
index aff17a9e9da28a82632d06957cf0c33d4ca61c20..4852d4ac3c892560b894dc7f9db01e75a60a867c 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -27,6 +27,7 @@
 
 #ifdef WITH_VST
 
+
 #ifndef G_PLUGIN_HOST_H
 #define G_PLUGIN_HOST_H
 
@@ -34,9 +35,6 @@
 #include <functional>
 #include <pthread.h>
 #include "../deps/juce-config.h"
-#include "audioBuffer.h"
-
-
 
 
 namespace giada {
@@ -44,148 +42,73 @@ namespace m
 {
 class Plugin;
 class Channel;
+class AudioBuffer;
 
 namespace pluginHost
 {
-enum stackType
-{
-       MASTER_OUT,
-       MASTER_IN,
-       CHANNEL
-};
+enum class StackType { MASTER_OUT, MASTER_IN, CHANNEL };
 
-enum sortMethod
-{
-       NAME,
-       CATEGORY,
-       MANUFACTURER,
-       FORMAT
-};
-
-struct PluginInfo
-{
-       std::string uid;
-       std::string name;
-       std::string category;
-       std::string manufacturerName;
-       std::string format;
-       bool isInstrument;
-};
+extern pthread_mutex_t mutex;
 
-extern pthread_mutex_t mutex_midi;
-
-void init(int bufSize, int samplerate);
+void init(int buffersize);
 void close();
 
-/* scanDirs
-Parses plugin directories (semicolon-separated) and store list in 
-knownPluginList. The callback is called on each plugin found. Used to update the 
-main window from the GUI thread. */
-
-int scanDirs(const std::string& paths, const std::function<void(float)>& cb);
-
-/* (save|load)List
- * (Save|Load) knownPluginList (in|from) an XML file. */
-
-int saveList(const std::string& path);
-int loadList(const std::string& path);
-
 /* addPlugin
- * Add a new plugin to 'stackType' by unique id or by index in knownPluginList
- * std::vector. Requires:
- * fid - plugin unique file id (i.e. path to dynamic library)
- * stackType - which stack to add plugin to
- * mutex - Mixer.mutex_plugin
- * freq - current audio frequency
- * bufSize - buffer size
- * ch - if stackType == CHANNEL. */
-
-Plugin* addPlugin(const std::string& fid, int stackType, pthread_mutex_t* mutex,
-       Channel* ch=nullptr);
-Plugin *addPlugin(int index, int stackType, pthread_mutex_t* mutex,
-       Channel* ch=nullptr);
+Adds a new plugin to 'stackType'. */
 
-/* countPlugins
- * Return size of 'stackType'. */
+void addPlugin(std::unique_ptr<Plugin> p, StackType t, pthread_mutex_t* mutex, 
+    Channel* ch=nullptr);
 
-unsigned countPlugins(int stackType, Channel* ch=nullptr);
-
-/* countAvailablePlugins
- * Return size of knownPluginList. */
-
-int countAvailablePlugins();
-
-/* countUnknownPlugins
- * Return size of unknownPluginList. */
-
-unsigned countUnknownPlugins();
-
-/* getAvailablePluginInfo
- * Return the available plugin information (name, type, ...) from
- * knownPluginList at index 'index'. */
-
-PluginInfo getAvailablePluginInfo(int index);
+/* countPlugins
+Returns the size of 'stackType'. */
 
-std::string getUnknownPluginInfo(int index);
+int countPlugins(StackType t, Channel* ch=nullptr);
 
 /* freeStack
- * free plugin stack of type 'stackType'. */
+Frees plugin stack of type 'stackType'. */
 
-void freeStack(int stackType, pthread_mutex_t* mutex, Channel* ch=nullptr);
+void freeStack(StackType t, pthread_mutex_t* mutex, Channel* ch=nullptr);
 
 /* processStack
 Applies the fx list to the buffer. */
 
-void processStack(AudioBuffer& outBuf, int stackType, Channel* ch=nullptr);
+void processStack(AudioBuffer& outBuf, StackType t, Channel* ch=nullptr);
 
 /* getStack
-* Return a std::vector <Plugin *> given the stackType. If stackType == CHANNEL
-a pointer to Channel is also required. */
+Returns a vector of Plugin pointers given the stackType. If stackType == CHANNEL
+a pointer to Channel is also required. */
 
-std::vector<Plugin*>* getStack(int stackType, Channel* ch=nullptr);
+std::vector<Plugin*> getStack(StackType t, Channel* ch=nullptr);
 
 /* getPluginByIndex */
 
-Plugin* getPluginByIndex(int index, int stackType, Channel* ch=nullptr);
+Plugin* getPluginByIndex(int index, StackType t, Channel* ch=nullptr);
 
 /* getPluginIndex */
 
-int getPluginIndex(int id, int stackType, Channel* ch=nullptr);
+int getPluginIndex(int id, StackType t, Channel* ch=nullptr);
 
 /* swapPlugin */
 
-void swapPlugin(unsigned indexA, unsigned indexB, int stackType,
-       pthread_mutex_t* mutex, Channel* ch=nullptr);
+void swapPlugin(int indexA, int indexB, StackType t, pthread_mutex_t* mutex, 
+    Channel* ch=nullptr);
 
 /* freePlugin.
 Returns the internal stack index of the deleted plugin. */
 
-int freePlugin(int id, int stackType, pthread_mutex_t *mutex,
-       Channel* ch=nullptr);
+int freePlugin(int id, StackType t, pthread_mutex_t* mutex, Channel* ch=nullptr);
 
 /* runDispatchLoop
- * Wakes up plugins' GUI manager for N milliseconds. */
+Wakes up plugins' GUI manager for N milliseconds. */
 
 void runDispatchLoop();
 
 /* freeAllStacks
- * Frees everything. */
+Frees everything. */
 
 void freeAllStacks(std::vector<Channel*>* channels, pthread_mutex_t* mutex);
 
-/* clonePlugin */
-
-int clonePlugin(Plugin* src, int stackType, pthread_mutex_t* mutex, Channel* ch);
-/* doesPluginExist */
-
-bool doesPluginExist(const std::string& fid);
-
-bool hasMissingPlugins();
-
-void sortPlugins(int sortMethod);
-
-void forEachPlugin(int stackType, const Channel* ch, std::function<void(const Plugin* p)> f);
+void forEachPlugin(StackType t, const Channel* ch, std::function<void(const Plugin* p)> f);
 
 }}}; // giada::m::pluginHost::
 
diff --git a/src/core/pluginManager.cpp b/src/core/pluginManager.cpp
new file mode 100644 (file)
index 0000000..4b6d1a1
--- /dev/null
@@ -0,0 +1,345 @@
+/* -----------------------------------------------------------------------------
+ *
+ * Giada - Your Hardcore Loopmachine
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
+ *
+ * This file is part of Giada - Your Hardcore Loopmachine.
+ *
+ * Giada - Your Hardcore Loopmachine 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.
+ *
+ * Giada - Your Hardcore Loopmachine 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 Giada - Your Hardcore Loopmachine. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * -------------------------------------------------------------------------- */
+
+
+#ifdef WITH_VST
+
+
+#include <cassert>
+#include "../utils/log.h"
+#include "../utils/fs.h"
+#include "../utils/string.h"
+#include "const.h"
+#include "plugin.h"
+#include "pluginManager.h"
+
+
+using std::vector;
+using std::string;
+
+
+namespace giada {
+namespace m {
+namespace pluginManager
+{
+namespace
+{
+int samplerate_;
+int buffersize_;
+
+/* pluginFormat
+Plugin format manager. */
+
+juce::VSTPluginFormat pluginFormat_;
+
+/* knownPuginList
+List of known (i.e. scanned) plugins. */
+
+juce::KnownPluginList knownPluginList_;
+
+/* unknownPluginList
+List of unrecognized plugins found in a patch. */
+
+vector<string> unknownPluginList_;
+
+/* missingPlugins
+If some plugins from any stack are missing. */
+
+bool missingPlugins_;
+
+vector<string> splitPluginDescription_(const string& descr)
+{
+       // input:  VST-mda-Ambience-18fae2d2-6d646141  string
+       // output: [2-------------] [1-----] [0-----]  vector.size() == 3
+       
+       vector<string> out;
+
+       string chunk = "";
+       int count = 2;
+       for (int i=descr.length()-1; i >= 0; i--) {
+               if (descr[i] == '-' && count != 0) {
+                       out.push_back(chunk);
+                       count--;
+                       chunk = "";
+               }
+               else
+                       chunk += descr[i];
+       }
+       out.push_back(chunk);
+
+       return out;
+}
+
+
+/* findPluginDescription
+Browses the list of known plug-ins until plug-in with id == 'id' is found.
+Unfortunately knownPluginList_.getTypeForIdentifierString(id) doesn't work for
+VSTs: their ID is based on the plug-in file location. E.g.:
+
+       /home/vst/mdaAmbience.so      -> VST-mdaAmbience-18fae2d2-6d646141
+       /home/vst-test/mdaAmbience.so -> VST-mdaAmbience-b328b2f6-6d646141
+
+The following function simply drops the first hash code during comparison. */
+
+const juce::PluginDescription* findPluginDescription_(const string& id)
+{
+       vector<string> idParts = splitPluginDescription_(id);
+
+       for (const juce::PluginDescription* pd : knownPluginList_) {
+               vector<string> tmpIdParts = splitPluginDescription_(pd->createIdentifierString().toStdString());
+               if (idParts[0] == tmpIdParts[0] && idParts[2] == tmpIdParts[2])
+                       return pd;
+       }
+       return nullptr;
+}
+}; // {anonymous}
+
+
+/* -------------------------------------------------------------------------- */
+/* -------------------------------------------------------------------------- */
+/* -------------------------------------------------------------------------- */
+
+
+void init(int samplerate, int buffersize)
+{
+       samplerate_     = samplerate;
+    buffersize_     = buffersize;
+       missingPlugins_ = false;
+       unknownPluginList_.clear();
+       loadList(gu_getHomePath() + G_SLASH + "plugins.xml");
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+int scanDirs(const string& dirs, const std::function<void(float)>& cb)
+{
+       gu_log("[pluginManager::scanDir] requested directories: '%s'\n", dirs.c_str());
+       gu_log("[pluginManager::scanDir] current plugins: %d\n", knownPluginList_.getNumTypes());
+
+       knownPluginList_.clear();   // clear up previous plugins
+
+       vector<string> dirVec = u::string::split(dirs, ";");
+
+       juce::VSTPluginFormat format;
+       juce::FileSearchPath searchPath;
+       for (const string& dir : dirVec)
+               searchPath.add(juce::File(dir));
+
+       juce::PluginDirectoryScanner scanner(knownPluginList_, format, searchPath, 
+               /*recursive=*/true, juce::File());
+
+       juce::String name;
+       while (scanner.scanNextFile(false, name)) {
+               gu_log("[pluginManager::scanDir]   scanning '%s'\n", name.toRawUTF8());
+               cb(scanner.getProgress());
+       }
+
+       gu_log("[pluginManager::scanDir] %d plugin(s) found\n", knownPluginList_.getNumTypes());
+       return knownPluginList_.getNumTypes();
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+int saveList(const string& filepath)
+{
+       int out = knownPluginList_.createXml()->writeToFile(juce::File(filepath), "");
+       if (!out)
+               gu_log("[pluginManager::saveList] unable to save plugin list to %s\n", filepath.c_str());
+       return out;
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+int loadList(const string& filepath)
+{
+       juce::XmlElement* elem = juce::XmlDocument::parse(juce::File(filepath));
+       if (elem != nullptr) {
+               knownPluginList_.recreateFromXml(*elem);
+               delete elem;
+               return 1;
+       }
+       return 0;
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+std::unique_ptr<Plugin> makePlugin(const string& fid)
+{
+       /* Initialize plugin. The default mode uses getTypeForIdentifierString, 
+       falling back to  getTypeForFile (deprecated) for old patches (< 0.14.4). */
+
+       const juce::PluginDescription* pd = findPluginDescription_(fid);
+       if (pd == nullptr) {
+               gu_log("[pluginManager::makePlugin] no plugin found with fid=%s! Trying with "
+                       "deprecated mode...\n", fid.c_str());
+               pd = knownPluginList_.getTypeForFile(fid);
+               if (pd == nullptr) {
+                       gu_log("[pluginManager::makePlugin] still nothing to do, returning unknown plugin\n");
+                       missingPlugins_ = true;
+                       unknownPluginList_.push_back(fid);
+                       return {};
+               }
+       }
+
+       juce::AudioPluginInstance* pi = pluginFormat_.createInstanceFromDescription(*pd, samplerate_, buffersize_);
+       if (!pi) {
+               gu_log("[pluginManager::makePlugin] unable to create instance with fid=%s!\n", fid.c_str());
+               missingPlugins_ = true;
+               return {};
+       }
+       gu_log("[pluginManager::makePlugin] plugin instance with fid=%s created\n", fid.c_str());
+
+       return std::make_unique<Plugin>(pi, samplerate_, buffersize_);
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+std::unique_ptr<Plugin> makePlugin(int index)
+{
+       juce::PluginDescription* pd = knownPluginList_.getType(index);
+       
+       if (pd == nullptr) 
+               return {};
+       
+       gu_log("[pluginManager::makePlugin] plugin found, uid=%s, name=%s...\n",
+               pd->createIdentifierString().toRawUTF8(), pd->name.toRawUTF8());
+       
+       return makePlugin(pd->createIdentifierString().toStdString());
+
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+std::unique_ptr<Plugin> makePlugin(const Plugin& src)
+{
+       std::unique_ptr<Plugin> p = makePlugin(src.getUniqueId());
+       
+       for (int i=0; i<src.getNumParameters(); i++)
+               p->setParameter(i, src.getParameter(i));        
+
+       return p;
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+int countAvailablePlugins()
+{
+       return knownPluginList_.getNumTypes();
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+unsigned countUnknownPlugins()
+{
+       return unknownPluginList_.size();
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+PluginInfo getAvailablePluginInfo(int i)
+{
+       juce::PluginDescription* pd = knownPluginList_.getType(i);
+       PluginInfo pi;
+       pi.uid              = pd->fileOrIdentifier.toStdString();
+       pi.name             = pd->name.toStdString();
+       pi.category         = pd->category.toStdString();
+       pi.manufacturerName = pd->manufacturerName.toStdString();
+       pi.format           = pd->pluginFormatName.toStdString();
+       pi.isInstrument     = pd->isInstrument;
+       return pi;
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+bool hasMissingPlugins()
+{
+       return missingPlugins_;
+};
+
+
+/* -------------------------------------------------------------------------- */
+
+
+string getUnknownPluginInfo(int i)
+{
+       return unknownPluginList_.at(i);
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+bool doesPluginExist(const string& fid)
+{
+       return pluginFormat_.doesPluginStillExist(*knownPluginList_.getTypeForFile(fid));
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+void sortPlugins(SortMethod method)
+{
+       switch (method) {
+               case SortMethod::NAME:
+                       knownPluginList_.sort(juce::KnownPluginList::SortMethod::sortAlphabetically, true);
+                       break;
+               case SortMethod::CATEGORY:
+                       knownPluginList_.sort(juce::KnownPluginList::SortMethod::sortByCategory, true);
+                       break;
+               case SortMethod::MANUFACTURER:
+                       knownPluginList_.sort(juce::KnownPluginList::SortMethod::sortByManufacturer, true);
+                       break;
+               case SortMethod::FORMAT:
+                       knownPluginList_.sort(juce::KnownPluginList::SortMethod::sortByFormat, true);
+                       break;
+       }
+}
+
+}}}; // giada::m::pluginManager::
+
+
+#endif // #ifdef WITH_VST
diff --git a/src/core/pluginManager.h b/src/core/pluginManager.h
new file mode 100644 (file)
index 0000000..1e345b1
--- /dev/null
@@ -0,0 +1,106 @@
+/* -----------------------------------------------------------------------------
+ *
+ * Giada - Your Hardcore Loopmachine
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
+ *
+ * This file is part of Giada - Your Hardcore Loopmachine.
+ *
+ * Giada - Your Hardcore Loopmachine 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.
+ *
+ * Giada - Your Hardcore Loopmachine 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 Giada - Your Hardcore Loopmachine. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * -------------------------------------------------------------------------- */
+
+
+#ifdef WITH_VST
+
+#ifndef G_PLUGIN_MANAGER_H
+#define G_PLUGIN_MANAGER_H
+
+
+#include "../deps/juce-config.h"
+#include "plugin.h"
+
+
+namespace giada {
+namespace m
+{
+namespace pluginManager
+{
+enum class SortMethod : int
+{
+       NAME = 0, CATEGORY,     MANUFACTURER, FORMAT
+};
+
+struct PluginInfo
+{
+       std::string uid;
+       std::string name;
+       std::string category;
+       std::string manufacturerName;
+       std::string format;
+       bool isInstrument;
+};
+
+void init(int samplerate, int buffersize);
+
+/* scanDirs
+Parses plugin directories (semicolon-separated) and store list in 
+knownPluginList. The callback is called on each plugin found. Used to update the 
+main window from the GUI thread. */
+
+int scanDirs(const std::string& paths, const std::function<void(float)>& cb);
+
+/* (save|load)List
+(Save|Load) knownPluginList (in|from) an XML file. */
+
+int saveList(const std::string& path);
+int loadList(const std::string& path);
+
+/* countAvailablePlugins
+Returns how many plug-ins are ready and available for usage. */
+
+int countAvailablePlugins();
+
+/* countUnknownPlugins
+Returns how many plug-ins are in a unknown/not-found state. */
+
+unsigned countUnknownPlugins();
+
+std::unique_ptr<Plugin> makePlugin(const std::string& fid);
+std::unique_ptr<Plugin> makePlugin(int index);
+std::unique_ptr<Plugin> makePlugin(const Plugin& other);
+
+/* getAvailablePluginInfo
+Returns the available plugin information (name, type, ...) given a plug-in
+index. */
+
+PluginInfo getAvailablePluginInfo(int index);
+
+std::string getUnknownPluginInfo(int index);
+
+bool doesPluginExist(const std::string& fid);
+
+bool hasMissingPlugins();
+
+void sortPlugins(SortMethod sortMethod);
+
+}}}; // giada::m::pluginManager::
+
+
+#endif
+
+#endif // #ifdef WITH_VST
index 296dac03617f332b2a0a7774ae87ead3868b7b04..6ba031d358be1b732910e747f6a422803d32bec6 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/core/recManager.cpp b/src/core/recManager.cpp
new file mode 100644 (file)
index 0000000..57bb283
--- /dev/null
@@ -0,0 +1,179 @@
+/* -----------------------------------------------------------------------------
+ *
+ * Giada - Your Hardcore Loopmachine
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
+ *
+ * This file is part of Giada - Your Hardcore Loopmachine.
+ *
+ * Giada - Your Hardcore Loopmachine 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.
+ *
+ * Giada - Your Hardcore Loopmachine 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 Giada - Your Hardcore Loopmachine. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * -------------------------------------------------------------------------- */
+
+
+#include "../gui/dispatcher.h"
+#include "../glue/transport.h"
+#include "types.h"
+#include "clock.h"
+#include "kernelAudio.h"
+#include "conf.h"
+#include "channel.h"
+#include "mixer.h"
+#include "mixerHandler.h"
+#include "midiDispatcher.h"
+#include "recorder.h"
+#include "recorderHandler.h"
+#include "recManager.h"
+
+
+namespace giada {
+namespace m {
+namespace recManager
+{
+namespace
+{
+pthread_mutex_t* mixerMutex_ = nullptr;
+bool isActive_ = false;
+
+
+/* -------------------------------------------------------------------------- */
+
+
+bool startActionRec_()
+{
+       if (!kernelAudio::getStatus())
+               return false;
+       clock::setStatus(ClockStatus::RUNNING);
+       recorder::enable();
+       c::transport::startSeq(/*gui=*/false);
+       return true;    
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+bool startInputRec_()
+{
+       if (!kernelAudio::getStatus() || !mh::startInputRec())
+               return false;
+       c::transport::startSeq(/*gui=*/false);
+       return true;
+}
+} // {anonymous}
+
+
+/* -------------------------------------------------------------------------- */
+/* -------------------------------------------------------------------------- */
+/* -------------------------------------------------------------------------- */
+
+
+void init(pthread_mutex_t* mixerMutex)
+{
+       mixerMutex_ = mixerMutex;
+       isActive_   = false;
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+bool isActive()  { return isActive_; }
+
+
+/* -------------------------------------------------------------------------- */
+
+
+bool startActionRec(RecTriggerMode mode)
+{
+       isActive_ = true;
+       if (mode == RecTriggerMode::NORMAL)
+               return startActionRec_();
+       if (mode == RecTriggerMode::SIGNAL) {
+               clock::setStatus(ClockStatus::WAITING);
+               clock::rewind();
+               m::midiDispatcher::setSignalCallback(startActionRec_);
+               v::dispatcher::setSignalCallback(startActionRec_);
+       }
+       return true;
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+void stopActionRec()
+{
+       isActive_ = false;
+
+       if (clock::getStatus() == ClockStatus::WAITING) {
+               clock::setStatus(ClockStatus::STOPPED);
+               return;
+       }
+
+       clock::setStatus(ClockStatus::RUNNING);
+
+       recorder::disable();
+       std::unordered_set<int> channels = recorderHandler::consolidate();
+
+       /* Enable reading actions for Channels that have just been filled with 
+       actions. Start reading right away, without checking whether 
+       conf::treatRecsAsLoops is enabled or not. */
+
+       pthread_mutex_lock(mixerMutex_);
+       for (int index : channels)
+               mh::getChannelByIndex(index)->startReadingActions(
+                       /*treatRecsAsLoops=*/false, /*recsStopOnChanHalt=*/false); 
+       pthread_mutex_unlock(mixerMutex_);
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+bool startInputRec(RecTriggerMode mode)
+{
+       if (mode == RecTriggerMode::NORMAL)
+               isActive_ = startInputRec_();
+       if (mode == RecTriggerMode::SIGNAL) {
+               if (!mh::hasRecordableSampleChannels())
+                       return false;
+               clock::setStatus(ClockStatus::WAITING);
+               clock::rewind();
+               mixer::setSignalCallback(startInputRec_);
+               isActive_ = true;
+       }
+       return isActive_;
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+void stopInputRec()
+{
+       isActive_ = false;
+
+       if (clock::getStatus() == ClockStatus::WAITING) {
+               clock::setStatus(ClockStatus::STOPPED);
+       }
+       else {
+               clock::setStatus(ClockStatus::RUNNING);
+               mh::stopInputRec();
+       }
+}
+}}} // giada::m::recManager
\ No newline at end of file
diff --git a/src/core/recManager.h b/src/core/recManager.h
new file mode 100644 (file)
index 0000000..13c6f85
--- /dev/null
@@ -0,0 +1,54 @@
+/* -----------------------------------------------------------------------------
+ *
+ * Giada - Your Hardcore Loopmachine
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
+ *
+ * This file is part of Giada - Your Hardcore Loopmachine.
+ *
+ * Giada - Your Hardcore Loopmachine 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.
+ *
+ * Giada - Your Hardcore Loopmachine 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 Giada - Your Hardcore Loopmachine. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * -------------------------------------------------------------------------- */
+
+
+#ifndef G_REC_MANAGER_H
+#define G_REC_MANAGER_H
+
+
+#include <pthread.h>
+#include "types.h"
+
+
+namespace giada {
+namespace m {
+namespace recManager
+{
+void init(pthread_mutex_t* mixerMutex);
+
+/* isActive
+Returns true if its ready for recording, whether it is actually recording 
+something or is in wait mode for a signal. */
+
+bool isActive();
+
+bool startActionRec(RecTriggerMode m);
+void stopActionRec();
+bool startInputRec(RecTriggerMode m);
+void stopInputRec();
+}}} // giada::m::recManager
+
+#endif
\ No newline at end of file
index 0f7803bfbc8839499f195e89e4a2c5ce6fd58989..c5fb6e72243cd225d0ba08739e3e88651f8bb0ef 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -52,9 +52,9 @@ lock-free solution will be implemented. */
 
 ActionMap actions;
 
-pthread_mutex_t* mixerMutex = nullptr;
-bool             active     = false;
-int              actionId   = 0;
+pthread_mutex_t* mixerMutex_ = nullptr;
+bool             active_     = false;
+int              actionId_   = 0;
 
 
 /* -------------------------------------------------------------------------- */
@@ -62,10 +62,10 @@ int              actionId   = 0;
 
 void lock_(std::function<void()> f)
 {
-       assert(mixerMutex != nullptr);
-       pthread_mutex_lock(mixerMutex);
+       assert(mixerMutex_ != nullptr);
+       pthread_mutex_lock(mixerMutex_);
        f();
-       pthread_mutex_unlock(mixerMutex);
+       pthread_mutex_unlock(mixerMutex_);
 }
 
 
@@ -118,9 +118,9 @@ void removeIf_(std::function<bool(const Action*)> f)
 
 void init(pthread_mutex_t* m)
 {
-       mixerMutex = m;
-       active     = false;
-       actionId   = 0;
+       mixerMutex_ = m;
+       active_     = false;
+       actionId_   = 0;
        clearAll();
 }
 
@@ -248,8 +248,8 @@ void updateActionMap(ActionMap&& am)
 
 void updateActionId(int id)
 {
-       if (actionId <= id)  // Never decrease it
-               actionId = id;
+       if (actionId_ <= id)  // Never decrease it
+               actionId_ = id;
 }
 
 
@@ -269,9 +269,9 @@ bool hasActions(int channel, int type)
 /* -------------------------------------------------------------------------- */
 
 
-bool isActive() { return active; }
-void enable()   { active = true; }
-void disable()  { active = false; }
+bool isActive() { return active_; }
+void enable()   { active_ = true; }
+void disable()  { active_ = false; }
 
 
 /* -------------------------------------------------------------------------- */
@@ -293,7 +293,7 @@ const Action* rec(int channel, Frame frame, MidiEvent event)
 
        lock_([&]
        { 
-               actions[frame].push_back(makeAction(actionId++, channel, frame, event));
+               actions[frame].push_back(makeAction(actionId_++, channel, frame, event));
        });
        return actions[frame].back();
 }
@@ -307,7 +307,7 @@ void rec(const std::vector<const Action*>& as)
        ActionMap temp = actions;
 
        for (const Action* a : as) {
-               const_cast<Action*>(a)->id = actionId++;
+               const_cast<Action*>(a)->id = actionId_++;
                temp[a->frame].push_back(a); // Memory is already allocated by recorderHandler
        }
 
@@ -346,7 +346,7 @@ const Action* getClosestAction(int channel, Frame f, int type)
 
 ActionMap getActionMap() { return actions; }
 
-int getLatestActionId() { return actionId; }
+int getLatestActionId() { return actionId_; }
 
 
 /* -------------------------------------------------------------------------- */
index dfb6b0aa7b9fa41a3d4d80364e415c2aa1451f90..0f3f1fb513b55cccace9e31a3512d67971ec92d3 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 7879be612b4b806fe4d3bf748a34ff3ecc2e74b0..53415db5aa6dcdef848717633a80f7d2cef72590 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -213,11 +213,17 @@ void liveRec(int channel, MidiEvent e)
 /* -------------------------------------------------------------------------- */
 
 
-void consolidate()
+std::unordered_set<int> consolidate()
 {
        consolidate_();
        recorder::rec(recs_);
+
+       std::unordered_set<int> out;
+       for (const Action* action : recs_)
+               out.insert(action->channel);
+
        recs_.clear();
+       return out;
 }
 
 
index 7b256a71e212a31ce2826a2e25b1366d547959a4..0554b15fcfcae5cb7b4a664a0f23c5ace34663da 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -29,6 +29,7 @@
 #define G_RECORDER_HANDLER_H
 
 
+#include <unordered_set>
 #include "midiEvent.h"
 #include "patch.h"
 
@@ -38,6 +39,7 @@ namespace m
 {
 struct Action;
 
+
 namespace recorderHandler
 {
 bool isBoundaryEnvelopeAction(const Action* a);
@@ -65,7 +67,11 @@ Records a user-generated action. NOTE_ON or NOTE_OFF only for now. */
 
 void liveRec(int channel, MidiEvent e);
 
-void consolidate();
+/* consolidate
+Records all live actions. Returns a set of channels indexes that have been 
+recorded. */
+
+std::unordered_set<int> consolidate();
 
 void writePatch(int chanIndex, std::vector<patch::action_t>& pactions);
 void readPatch(const std::vector<patch::action_t>& pactions);
index b352430b9bea437ed031797e0fc8b1f71cdd3be9..3a5d986480bb6a904c47666464eb9e3a3721406a 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -47,7 +47,7 @@ SampleChannel::SampleChannel(bool inputMonitor, int bufferSize)
          tracker          (0),
          trackerPreview   (0),
          shift            (0),
-         qWait            (false),
+         quantizing       (false),
          inputMonitor     (inputMonitor),
          boost            (G_DEFAULT_BOOST),
          pitch            (G_DEFAULT_PITCH),
@@ -71,7 +71,6 @@ SampleChannel::SampleChannel(bool inputMonitor, int bufferSize)
 
 SampleChannel::~SampleChannel()
 {
-       delete wave;
        if (rsmp_state != nullptr)
                src_delete(rsmp_state);
 }
@@ -89,11 +88,11 @@ void SampleChannel::copy(const Channel* src_, pthread_mutex_t* pluginMutex)
        end             = src->end;
        boost           = src->boost;
        mode            = src->mode;
-       qWait           = src->qWait;
+       quantizing      = src->quantizing;
        setPitch(src->pitch);
 
        if (src->wave)
-               pushWave(new Wave(*src->wave)); // invoke Wave's copy constructor
+               pushWave(std::make_unique<Wave>(*src->wave)); // invoke Wave's copy constructor
 }
 
 
@@ -402,8 +401,7 @@ void SampleChannel::empty()
        volume     = G_DEFAULT_VOL;
        boost      = G_DEFAULT_BOOST;
        hasActions = false;
-       delete wave;
-       wave = nullptr;
+       wave.reset(nullptr);
        sendMidiLstatus();
 }
 
@@ -411,10 +409,10 @@ void SampleChannel::empty()
 /* -------------------------------------------------------------------------- */
 
 
-void SampleChannel::pushWave(Wave* w)
+void SampleChannel::pushWave(std::unique_ptr<Wave>&& w)
 {
        status = ChannelStatus::OFF;
-       wave   = w;
+       wave   = std::move(w);
        begin  = 0;
        end    = wave->getSize() - 1;
        sendMidiLstatus();
@@ -424,7 +422,7 @@ void SampleChannel::pushWave(Wave* w)
 /* -------------------------------------------------------------------------- */
 
 
-bool SampleChannel::canInputRec()
+bool SampleChannel::canInputRec() const
 {
        return wave == nullptr && armed;
 }
index 4514f0e28f9104a09619cb67d870b3f00c8e9a88..c2b2dd14bfa526e4262a4f05a1d695b1bda00887 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -29,6 +29,7 @@
 #define G_SAMPLE_CHANNEL_H
 
 
+#include <memory>
 #include <functional>
 #include <samplerate.h>
 #include "types.h"
@@ -69,8 +70,8 @@ public:
        void empty() override;
        void stopBySeq(bool chansStopOnSeqHalt) override;
        void rewindBySeq() override;
-       bool canInputRec() override;
        void stopInputRec(int globalFrame) override;
+       bool canInputRec() const override;
        bool hasLogicalData() const override;
        bool hasEditedData() const override;
        bool hasData() const override;
@@ -96,9 +97,9 @@ public:
        int fillBuffer(AudioBuffer& dest, int start, int offset);
 
        /* pushWave
-       Adds a new wave to an existing channel. */
+       Adds a new wave to this channel. */
 
-       void pushWave(Wave* w);
+       void pushWave(std::unique_ptr<Wave>&& w);
 
        void setPitch(float v);
        void setBegin(int f);
@@ -119,11 +120,11 @@ public:
        
        ChannelMode mode;
        
-       Wave* wave;
+       std::unique_ptr<Wave> wave;
        int   tracker;         // chan position
        int   trackerPreview;  // chan position for audio preview
        int   shift;
-       bool  qWait;           // quantizer wait
+       bool  quantizing;      // quantization in progress
        bool  inputMonitor;  
        float boost;
        float pitch;
index ef3569ecf1ad30d86817c0fffb8d83591e97be59..4612f5b7a57587dc9418e0df18e51fa219b80022 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -42,8 +42,8 @@ namespace
 {
 void rewind_(SampleChannel* ch, int localFrame)
 {
-       ch->tracker = ch->begin;
-       ch->qWait   = false;  // Was in qWait mode? Reset occured, no more qWait now.
+       ch->tracker    = ch->begin;
+       ch->quantizing = false;  // No more quantization now
 
        /* On rewind, if channel is playing fill again buffer to create something like 
        this:
@@ -66,15 +66,15 @@ void quantize_(SampleChannel* ch, int localFrame, bool quantoPassed)
        /* Skip if LOOP_ANY, not in quantizer-wait mode or still waiting for the 
        quantization time to end. */
 
-       if (ch->isAnyLoopMode() || !ch->qWait || !quantoPassed)
+       if (ch->isAnyLoopMode() || !ch->quantizing || !quantoPassed)
                return;
 
        switch (ch->status) {
                case ChannelStatus::OFF:
                        ch->status   = ChannelStatus::PLAY;
-                       ch->qWait    = false;
                        ch->tracker += ch->fillBuffer(ch->buffer, ch->tracker, localFrame);
                        ch->sendMidiLstatus();
+                       // ch->quantizing = false is set by sampleChannelRec::quantize()
                        break;
 
                default:
@@ -205,7 +205,7 @@ void processData_(SampleChannel* ch, m::AudioBuffer& out, const m::AudioBuffer&
        }
 
 #ifdef WITH_VST
-       pluginHost::processStack(ch->buffer, pluginHost::CHANNEL, ch);
+       pluginHost::processStack(ch->buffer, pluginHost::StackType::CHANNEL, ch);
 #endif
 
        for (int i=0; i<out.countFrames(); i++) {
@@ -289,8 +289,8 @@ void stop(SampleChannel* ch)
 
                default:
                        /* If quantizing, stop a SINGLE_PRESS immediately. */
-                       if (ch->mode == ChannelMode::SINGLE_PRESS && ch->qWait)
-                               ch->qWait = false;      
+                       if (ch->mode == ChannelMode::SINGLE_PRESS && ch->quantizing)
+                               ch->quantizing = false; 
                        break;          
        }
 }
@@ -402,7 +402,7 @@ void start(SampleChannel* ch, int localFrame, bool doQuantize, int velocity)
                        }
                        else {
                                if (doQuantize)
-                                       ch->qWait = true;
+                                       ch->quantizing = true;
                                else {
                                        ch->status = ChannelStatus::PLAY;
                                        ch->sendMidiLstatus();
@@ -413,7 +413,7 @@ void start(SampleChannel* ch, int localFrame, bool doQuantize, int velocity)
                case ChannelStatus::PLAY:
                        if (ch->mode == ChannelMode::SINGLE_RETRIG) {
                                if (doQuantize)
-                                       ch->qWait = true;
+                                       ch->quantizing = true;
                                else
                                        rewind_(ch, localFrame);
                        }
index 5f14e852e1d922a24763c45932e251b17a37a84a..36d39e2975dfe308e304b6d931589b51dd16d6e8 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index ec8a7a8ccf397a026c26ba44d7b855ec9b565436..a79f0124a8d6598b428bf197f31c3210f392fc26 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -147,7 +147,9 @@ void recordKeyPressAction_(SampleChannel* ch)
        if (!recorderCanRec_(ch))
                return;
 
-       /* Disable reading actions while recording SINGLE_PRESS mode. */
+       /* Disable reading actions while recording SINGLE_PRESS mode. Don't let 
+       existing actions interfere with the current one being recorded. */
+
        if (ch->mode == ChannelMode::SINGLE_PRESS)
                ch->readActions = false;
        
@@ -161,12 +163,13 @@ void recordKeyPressAction_(SampleChannel* ch)
 
 void quantize_(SampleChannel* ch, bool quantoPassed)
 {
-       /* Skip if LOOP_ANY or not in quantizer-wait mode. Otherwise the quantize wait 
-       has expired: record the keypress.  */
+       /* Skip if in loop mode or not in a quantization stage. Otherwise the 
+       quantization wait has expired: record the keypress.  */
 
-       if (ch->isAnyLoopMode() || !ch->qWait || !quantoPassed)
-               return;
-       recordKeyPressAction_(ch);
+       if (!ch->isAnyLoopMode() && ch->quantizing && quantoPassed && ch->status == ChannelStatus::PLAY) {
+               ch->quantizing = false;
+               recordKeyPressAction_(ch);
+       }
 }
 }; // {anonymous}
 
@@ -197,20 +200,7 @@ bool recordStart(SampleChannel* ch, bool canQuantize)
        channel is in any loop mode, where KEYPRESS and KEYREL are meaningless. */
 
        if (!canQuantize && !ch->isAnyLoopMode() && recorderCanRec_(ch))
-       {
                recordKeyPressAction_(ch);
-
-               /* Why return here? You record an action and then you call ch->start: 
-               Mixer, which is on another thread, reads your newly recorded action if you 
-               have readActions == true, and then ch->start kicks in right after it.
-               The result: Mixer plays the channel (due to the new action) but the code
-               in the switch in start() kills it right away (because the sample is playing). 
-               Fix: start channel only if you are not recording anything, i.e. let 
-               Mixer play it. */
-
-               if (ch->readActions)
-                       return false;
-       }
        return true;
 }
 
index 720a7483249e709cc0bf8a191dc874aaf188f3a6..ef64e33e8758a7ba181a7fd5361d1155d5b3a391 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -41,13 +41,13 @@ namespace sampleChannelRec
 void parseEvents(SampleChannel* ch, mixer::FrameEvents fe);
 
 /* recordStart
-Records a G_ACTION_KEYPRESS if capable of. Returns true if a start() call can
+Records a 'start' action if capable of. Returns true if a start() call can
 be performed. */
 
 bool recordStart(SampleChannel* ch, bool doQuantize);
 
 /* recordKill
-Records a G_ACTION_KILL if capable of. Returns true if a kill() call can
+Records a 'kill' action if capable of. Returns true if a kill() call can
 be performed. */
 
 bool recordKill(SampleChannel* ch);
index bf08fdd4314cd48e9176f5d94e1efed23b040856..eb36fcfc7d18b528cb3e2222958e4bdc3c56505c 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 58a17566cbd005b1e3aaeb87022d70409f8153af..52500a2c3b5501b12ac4e581c28e3ba482a89cb5 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 4754a1006ee49c40afb96792d924d6cfc11fcb31..15efc16d0e8714a92f3e20e59482b9b7b0a4a584 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -34,25 +34,22 @@ namespace giada
 using Pixel = int;
 using Frame = int;
 
+enum class ClockStatus { STOPPED, WAITING, RUNNING };
 
-enum class ChannelType : int 
-{
-       SAMPLE = 1, MIDI
-};
-
+enum class ChannelType : int { SAMPLE = 1, MIDI };
 
 enum class ChannelStatus : int
 {
        ENDING = 1, WAIT, PLAY, OFF, EMPTY, MISSING, WRONG  
 };
 
-
 enum class ChannelMode : int
 {
        LOOP_BASIC = 1, LOOP_ONCE, LOOP_REPEAT, LOOP_ONCE_BAR,
        SINGLE_BASIC, SINGLE_PRESS, SINGLE_RETRIG, SINGLE_ENDLESS
 };
 
+enum class RecTriggerMode : int { NORMAL = 0, SIGNAL };
 
 enum class PreviewMode : int { NONE = 0, NORMAL, LOOP };
 enum class EventType : int { AUTO = 0, MANUAL };
index 40a68d4e6abd4272231556657572824b573409ff..7841338c53d0c4a968333becda42137c9f69462f 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -35,6 +35,7 @@
 
 
 using std::string;
+using namespace giada;
 
 
 Wave::Wave()
@@ -146,7 +147,7 @@ void Wave::setPath(const string& p, int id)
        if (id == -1)
                m_path = p; 
        else 
-               m_path = gu_stripExt(p) + "-" + gu_iToString(id) + "." + gu_getExt(p);
+               m_path = gu_stripExt(p) + "-" + u::string::iToString(id) + "." + gu_getExt(p);
 }
 
 
index f285bf305752179478ff01137d69e2ac6373cda0..50bedb8aa448c661a1802f45339990156f318f2e 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index d3f147eaafaf4da5ceb010f227db7030e369204a..18cf80c4abb8426d3d34bfde399622b8d7b55f15 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 51146ba1c1d496bf60ebef0b11d21ffdf698d8e1..f5e48b13b2e597bbbca1c0fa06d513179e0ec2ad 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index c7e48e0b2f07ec7b4105d7c0d257ba7ba5e8096c..64cb1d7a333df828e3d9aec6bde8fb29f023df06 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -71,30 +71,30 @@ int getBits(SF_INFO& header)
 /* -------------------------------------------------------------------------- */
 
 
-int create(const string& path, Wave** out)
+Result createFromFile(const string& path)
 {
        if (path == "" || gu_isDir(path)) {
                gu_log("[waveManager::create] malformed path (was '%s')\n", path.c_str());
-               return G_RES_ERR_NO_DATA;
+               return { G_RES_ERR_NO_DATA };
        }
 
        if (path.size() > FILENAME_MAX)
-               return G_RES_ERR_PATH_TOO_LONG;
+               return { G_RES_ERR_PATH_TOO_LONG };
 
        SF_INFO header;
        SNDFILE* fileIn = sf_open(path.c_str(), SFM_READ, &header);
 
        if (fileIn == nullptr) {
                gu_log("[waveManager::create] unable to read %s. %s\n", path.c_str(), sf_strerror(fileIn));
-               return G_RES_ERR_IO;
+               return { G_RES_ERR_IO };
        }
 
        if (header.channels > G_MAX_IO_CHANS) {
                gu_log("[waveManager::create] unsupported multi-channel sample\n");
-               return G_RES_ERR_WRONG_DATA;
+               return { G_RES_ERR_WRONG_DATA };
        }
 
-       Wave* wave = new Wave();
+       std::unique_ptr<Wave> wave = std::make_unique<Wave>();
        wave->alloc(header.frames, header.channels, header.samplerate, getBits(header), path);
 
        if (sf_readf_float(fileIn, wave->getFrame(0), header.frames) != header.frames)
@@ -102,54 +102,47 @@ int create(const string& path, Wave** out)
 
        sf_close(fileIn);
 
-       if (header.channels == 1 && !wfx::monoToStereo(*wave)) {
-               delete wave;
-               return G_RES_ERR_PROCESSING;
-       }
-
-       *out = wave;
+       if (header.channels == 1 && !wfx::monoToStereo(*wave))
+               return { G_RES_ERR_PROCESSING };
 
        gu_log("[waveManager::create] new Wave created, %d frames\n", wave->getSize());
 
-       return G_RES_OK;
+       return { G_RES_OK, std::move(wave) };
 }
 
-
 /* -------------------------------------------------------------------------- */
 
 
-void createEmpty(int frames, int channels, int samplerate, const string& name, 
-       Wave** out)
+std::unique_ptr<Wave> createEmpty(int frames, int channels, int samplerate, 
+       const string& name)
 {
-       Wave* wave = new Wave();
+       std::unique_ptr<Wave> wave = std::make_unique<Wave>();
        wave->alloc(frames, channels, samplerate, G_DEFAULT_BIT_DEPTH, name);
-
        wave->setLogical(true);
 
-       *out = wave;
-
        gu_log("[waveManager::createEmpty] new empty Wave created, %d frames\n", 
                wave->getSize());
+
+       return wave;
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void createFromWave(const Wave* src, int a, int b, Wave** out)
+std::unique_ptr<Wave> createFromWave(const Wave* src, int a, int b)
 {
        int channels = src->getChannels();
        int frames   = b - a;
 
-       Wave* wave = new Wave();
+       std::unique_ptr<Wave> wave = std::make_unique<Wave>();
        wave->alloc(frames, channels, src->getRate(), src->getBits(), src->getPath());
-
        wave->copyData(src->getFrame(a), frames);
        wave->setLogical(true);
 
-       *out = wave;
-
        gu_log("[waveManager::createFromWave] new Wave created, %d frames\n", frames);
+
+       return wave;
 }
 
 
index 0f0b7640afed718534733677bf2d24af6ac337af..927054a840f8827bdc68c01b19bf6a4e9ab63c4f 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -30,6 +30,7 @@
 
 
 #include <string>
+#include <memory>
 
 
 class Wave;
@@ -39,21 +40,27 @@ namespace giada {
 namespace m {
 namespace waveManager
 {
+struct Result
+{
+    int status;
+    std::unique_ptr<Wave> wave;
+};
+
 /* create
 Creates a new Wave object with data read from file 'path'. */
 
-int create(const std::string& path, Wave** out);
+Result createFromFile(const std::string& path);
 
 /* createEmpty
 Creates a new silent Wave object. */
 
-void createEmpty(int frames, int channels, int samplerate, const std::string& name, 
-       Wave** out);
+std::unique_ptr<Wave> createEmpty(int frames, int channels, int samplerate, 
+    const std::string& name);
 
 /* createFromWave
 Creates a new Wave from an existing one, copying the data in range a - b. */
 
-void createFromWave(const Wave* src, int a, int b, Wave** out);
+std::unique_ptr<Wave> createFromWave(const Wave* src, int a, int b);
 
 int resample(Wave* w, int quality, int samplerate); 
 int save(Wave* w, const std::string& path);
index 22c8d224fa3881a1126a5950da4d35c405842118..5d2c6d53695fd0618024a59a57102c0c39d6ca2f 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 17fd7fbda4afaab2f4bc908177b52107a58b2dc6..7c4f81423e8f4f3f6206ddee530e1ae251e472f7 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -36,7 +36,7 @@
 namespace giada {
 namespace m
 {
-class Action;
+struct Action;
 class SampleChannel;
 class MidiChannel;
 }
index 74db5c94b9ebf27a45f0845b2b90220e99957d09..41df9413528ebf57743e847a1bcf6d78721998ab 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -27,9 +27,9 @@
 
 #include <cmath>
 #include <FL/Fl.H>
-#include "../gui/dialogs/gd_mainWindow.h"
+#include "../gui/dialogs/mainWindow.h"
 #include "../gui/dialogs/sampleEditor.h"
-#include "../gui/dialogs/gd_warnings.h"
+#include "../gui/dialogs/warnings.h"
 #include "../gui/elems/basics/input.h"
 #include "../gui/elems/basics/dial.h"
 #include "../gui/elems/sampleEditor/waveTools.h"
@@ -88,26 +88,24 @@ int loadChannel(m::SampleChannel* ch, const string& fname)
 
        conf::samplePath = gu_dirname(fname);
 
-       Wave* wave = nullptr;
-       int result = waveManager::create(fname, &wave); 
-       if (result != G_RES_OK)
-               return result;
+       waveManager::Result res = waveManager::createFromFile(fname); 
 
-       if (wave->getRate() != conf::samplerate) {
+       if (res.status != G_RES_OK)
+               return res.status;
+
+       if (res.wave->getRate() != conf::samplerate) {
                gu_log("[loadChannel] input rate (%d) != system rate (%d), conversion needed\n",
-                       wave->getRate(), conf::samplerate);
-               result = waveManager::resample(wave, conf::rsmpQuality, conf::samplerate); 
-               if (result != G_RES_OK) {
-                       delete wave;
-                       return result;
-               }
+                       res.wave->getRate(), conf::samplerate);
+               res.status = waveManager::resample(res.wave.get(), conf::rsmpQuality, conf::samplerate); 
+               if (res.status != G_RES_OK)
+                       return res.status;
        }
 
-       ch->pushWave(wave);
+       ch->pushWave(std::move(res.wave));
 
        G_MainWin->keyboard->updateChannel(ch->guiChannel);
 
-       return result;
+       return res.status;
 }
 
 
@@ -135,13 +133,13 @@ void deleteChannel(m::Channel* ch)
        recorder::clearChannel(ch->index);
        ch->hasActions = false;
 #ifdef WITH_VST
-       pluginHost::freeStack(pluginHost::CHANNEL, &mixer::mutex, ch);
+       pluginHost::freeStack(pluginHost::StackType::CHANNEL, &mixer::mutex, ch);
 #endif
        Fl::lock();
        G_MainWin->keyboard->deleteChannel(ch->guiChannel);
        Fl::unlock();
        mh::deleteChannel(ch);
-       gu_closeAllSubwindows();
+       u::gui::closeAllSubwindows();
 }
 
 
@@ -221,7 +219,7 @@ void setVolume(m::Channel* ch, float v, bool gui, bool editor)
        /* Changing channel volume? Update wave editor (if it's shown). */
 
        if (!editor) {
-               gdSampleEditor* gdEditor = static_cast<gdSampleEditor*>(gu_getSubwindow(G_MainWin, WID_SAMPLE_EDITOR));
+               gdSampleEditor* gdEditor = static_cast<gdSampleEditor*>(u::gui::getSubwindow(G_MainWin, WID_SAMPLE_EDITOR));
                if (gdEditor) {
                        Fl::lock();
                        gdEditor->volumeTool->refresh();
@@ -243,7 +241,7 @@ void setVolume(m::Channel* ch, float v, bool gui, bool editor)
 void setPitch(m::SampleChannel* ch, float val)
 {
        ch->setPitch(val);
-       gdSampleEditor* gdEditor = static_cast<gdSampleEditor*>(gu_getSubwindow(G_MainWin, WID_SAMPLE_EDITOR));
+       gdSampleEditor* gdEditor = static_cast<gdSampleEditor*>(u::gui::getSubwindow(G_MainWin, WID_SAMPLE_EDITOR));
        if (gdEditor) {
                Fl::lock();
                gdEditor->pitchTool->refresh();
@@ -258,7 +256,7 @@ void setPitch(m::SampleChannel* ch, float val)
 void setPanning(m::SampleChannel* ch, float val)
 {
        ch->setPan(val);
-       gdSampleEditor* gdEditor = static_cast<gdSampleEditor*>(gu_getSubwindow(G_MainWin, WID_SAMPLE_EDITOR));
+       gdSampleEditor* gdEditor = static_cast<gdSampleEditor*>(u::gui::getSubwindow(G_MainWin, WID_SAMPLE_EDITOR));
        if (gdEditor) {
                Fl::lock();
                gdEditor->panTool->refresh();
@@ -310,7 +308,7 @@ void kill(m::Channel* ch)
 void setBoost(m::SampleChannel* ch, float val)
 {
        ch->setBoost(val);
-       gdSampleEditor *gdEditor = static_cast<gdSampleEditor*>(gu_getSubwindow(G_MainWin, WID_SAMPLE_EDITOR));
+       gdSampleEditor *gdEditor = static_cast<gdSampleEditor*>(u::gui::getSubwindow(G_MainWin, WID_SAMPLE_EDITOR));
        if (gdEditor) {
                Fl::lock();
                gdEditor->boostTool->refresh();
index 9c18db7f9f1a2dcf79c914d4114f015563e0c114..0808297a15a3af45c0c0c1fd6388ef2ecf30a5e4 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index d2f1ea4a1130c01f557e413acb7790795e8dc7fa..0a269149e87dbeff6b8a5858612252ea7f0a6a2c 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -26,8 +26,9 @@
 
 
 #include <FL/Fl.H>
-#include "../gui/dialogs/gd_mainWindow.h"
-#include "../gui/dialogs/gd_warnings.h"
+#include "../gui/dialogs/mainWindow.h"
+#include "../gui/dialogs/warnings.h"
+#include "../gui/elems/basics/button.h"
 #include "../gui/elems/mainWindow/mainTransport.h"
 #include "../gui/elems/mainWindow/mainTimer.h"
 #include "../gui/elems/mainWindow/keyboard/keyboard.h"
 #include "../utils/log.h"
 #include "../utils/math.h"
 #include "../core/recorder.h"
+#include "../core/conf.h"
+#include "../core/recManager.h"
 #include "../core/kernelAudio.h"
+#include "../core/channel.h"
 #include "../core/mixer.h"
 #include "../core/mixerHandler.h"
 #include "../core/wave.h"
+#include "../core/midiDispatcher.h"
 #include "../core/channel.h"
 #include "../core/clock.h"
 #include "../core/sampleChannel.h"
@@ -71,7 +76,7 @@ void keyPress(m::Channel* ch, bool ctrl, bool shift, int velocity)
        }
        else {
                if (ch->recordStart(m::clock::canQuantize()))
-                       ch->start(0, m::clock::canQuantize(), 0);
+                       ch->start(0, m::clock::canQuantize(), velocity);
        }
 }
 
@@ -91,9 +96,9 @@ void keyRelease(m::Channel* ch, bool ctrl, bool shift)
 /* -------------------------------------------------------------------------- */
 
 
-void startStopActionRec(bool gui)
+void toggleActionRec(bool gui)
 {
-       m::recorder::isActive() ? stopActionRec(gui) : startActionRec(gui);
+       m::recManager::isActive() ? stopActionRec(gui) : startActionRec(gui);
 }
 
 
@@ -102,19 +107,15 @@ void startStopActionRec(bool gui)
 
 void startActionRec(bool gui)
 {
-       if (m::kernelAudio::getStatus() == false)
-               return;
-
-       m::recorder::enable();
+       RecTriggerMode triggerMode = static_cast<RecTriggerMode>(m::conf::recTriggerMode);
 
-       if (!m::clock::isRunning())
-               c::transport::startSeq(false);  // update gui
-
-       if (!gui) {
-               Fl::lock();
-               G_MainWin->mainTransport->updateRecAction(1);
-               Fl::unlock();
-       }
+       if (!m::recManager::startActionRec(triggerMode))
+               return;
+       if (!gui) Fl::lock();
+       G_MainWin->mainTransport->setRecTriggerModeActive(false);
+       G_MainWin->mainTransport->updatePlay(m::clock::isRunning());
+       G_MainWin->mainTransport->updateRecAction(1);
+       if (!gui) Fl::unlock();
 }
 
 
@@ -123,33 +124,26 @@ void startActionRec(bool gui)
 
 void stopActionRec(bool gui)
 {
-       m::recorder::disable();
-       m::recorderHandler::consolidate();
-
-       for (m::Channel* ch : m::mixer::channels) {
-               if (ch->type == ChannelType::MIDI)
-                       continue;
-               G_MainWin->keyboard->setChannelWithActions(static_cast<geSampleChannel*>(ch->guiChannel));
-               if (!ch->readActions && ch->hasActions)
-                       c::channel::startReadingActions(ch, false);
-       }
+       m::recManager::stopActionRec();
 
-       if (!gui) {
-               Fl::lock();
-               G_MainWin->mainTransport->updateRecAction(0);
-               Fl::unlock();
-       }
+       if (!gui) Fl::lock();
+       G_MainWin->mainTransport->updateRecAction(0);
+       G_MainWin->mainTransport->setRecTriggerModeActive(true);
+       for (m::Channel* ch : m::mixer::channels)
+               if (ch->type == ChannelType::SAMPLE)
+                       G_MainWin->keyboard->setChannelWithActions(static_cast<geSampleChannel*>(ch->guiChannel));
+       if (!gui) Fl::unlock();
 
-       gu_refreshActionEditor();  // in case it's open
+       u::gui::refreshActionEditor();  // in case it's open
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void startStopInputRec(bool gui)
+void toggleInputRec(bool gui)
 {
-       if (m::mixer::recording)
+       if (m::recManager::isActive())
                stopInputRec(gui);
        else
        if (!startInputRec(gui))
@@ -160,34 +154,23 @@ void startStopInputRec(bool gui)
 /* -------------------------------------------------------------------------- */
 
 
-int startInputRec(bool gui)
+bool startInputRec(bool gui)
 {
-       using namespace giada::m;
-
-       if (kernelAudio::getStatus() == false)
-               return false;
+       RecTriggerMode triggerMode = static_cast<RecTriggerMode>(m::conf::recTriggerMode);
 
-       if (!mh::startInputRec()) {
-               Fl::lock();
+       if (!m::recManager::startInputRec(triggerMode)) {
+               if (!gui) Fl::lock();
                G_MainWin->mainTransport->updateRecInput(0);  // set it off, anyway
-               Fl::unlock();
+               if (!gui) Fl::unlock();
                return false;
-       }
-
-       if (!clock::isRunning())
-               transport::startSeq(false); // update gui anyway
+       }       
 
-       Fl::lock();
-               if (!gui)
-                       G_MainWin->mainTransport->updateRecInput(1);
-               G_MainWin->mainTimer->setLock(true);
-       Fl::unlock();
-
-       /* Update sample name inside sample channels' main button. This is useless for
-       midi channel, but let's do it anyway. */
-
-       for (Channel* ch : m::mixer::channels)
-               ch->guiChannel->update();
+       if (!gui) Fl::lock();
+       G_MainWin->mainTransport->setRecTriggerModeActive(false);
+       G_MainWin->mainTransport->updatePlay(m::clock::isRunning());
+       G_MainWin->mainTransport->updateRecInput(1);
+       G_MainWin->mainTimer->setLock(true);
+       if (!gui) Fl::unlock();
 
        return true;
 }
@@ -196,19 +179,19 @@ int startInputRec(bool gui)
 /* -------------------------------------------------------------------------- */
 
 
-int stopInputRec(bool gui)
+void stopInputRec(bool gui)
 {
-       using namespace giada::m;
-       
-       mh::stopInputRec();
-
-       Fl::lock();
-               if (!gui)
-                       G_MainWin->mainTransport->updateRecInput(0);
-               G_MainWin->mainTimer->setLock(false);
-       Fl::unlock();
-
-       return 1;
+       m::recManager::stopInputRec();
+
+       if (!gui) Fl::lock();
+       G_MainWin->mainTransport->setRecTriggerModeActive(true);
+       G_MainWin->mainTransport->updateRecInput(0);
+       G_MainWin->mainTimer->setLock(false);
+       /* Update sample name inside sample channels' main button. This is useless 
+       for MIDI channels, but let's do it anyway. */
+       for (const m::Channel* ch : m::mixer::channels)
+               ch->guiChannel->update();
+       if (!gui) Fl::unlock();
 }
 
 }}} // giada::c::io::
\ No newline at end of file
index e8e8eee6f0472cdb385a312ac4286253c438a032..2233d400b24dc6559362010890e3f5fd8acfe50d 100644 (file)
@@ -11,7 +11,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -39,7 +39,6 @@
 namespace giada {
 namespace m
 {
-class Plugin;
 class Channel;
 }
 namespace c {
@@ -57,18 +56,17 @@ void keyRelease(m::Channel* ch, bool ctrl, bool shift);
 Handles the action recording. If gui == true the signal comes from an user
 interaction, otherwise it's a MIDI/Jack/external signal. */
 
-void startStopActionRec(bool gui=true);
-void startActionRec(bool gui=true);
-void stopActionRec(bool gui=true);
+void toggleActionRec(bool gui=true);
+void startActionRec (bool gui=true);
+void stopActionRec  (bool gui=true);
 
 /* start/stopInputRec
 Handles the input recording (take). If gui == true the signal comes from an
 internal interaction on the GUI, otherwise it's a MIDI/Jack/external signal. */
 
-void startStopInputRec(bool gui=true);
-int  startInputRec    (bool gui=true);
-int  stopInputRec     (bool gui=true);
-
+void toggleInputRec(bool gui=true);
+bool startInputRec (bool gui=true);
+void stopInputRec  (bool gui=true);
 }}} // giada::c::io::
 
 #endif
index 1aad7a041e67bbe8bd820d3e8366be3c05ff0e1c..fe0ef93bd3a071016d09c49bf33d659e71d82a28 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -31,7 +31,7 @@
 #include "../gui/elems/mainWindow/mainTimer.h"
 #include "../gui/elems/mainWindow/keyboard/sampleChannel.h"
 #include "../gui/elems/mainWindow/keyboard/keyboard.h"
-#include "../gui/dialogs/gd_mainWindow.h"
+#include "../gui/dialogs/mainWindow.h"
 #include "../utils/gui.h"
 #include "../utils/string.h"
 #include "../utils/log.h"
@@ -45,9 +45,8 @@
 #include "../core/recorderHandler.h"
 #include "../core/conf.h"
 #include "../core/const.h"
-#ifdef WITH_VST
+#include "../core/pluginManager.h"
 #include "../core/pluginHost.h"
-#endif
 #include "main.h"
 
 
@@ -57,7 +56,10 @@ extern gdMainWindow *G_MainWin;
 using std::string;
 using namespace giada::m;
 
-
+namespace giada {
+namespace c {
+namespace main
+{
 namespace
 {
 void setBpm_(float f, string s)
@@ -77,8 +79,13 @@ void setBpm_(float f, string s)
        recorderHandler::updateBpm(vPre, f, clock::getQuanto());
        mixer::allocVirtualInput(clock::getFramesInLoop());
 
-       gu_refreshActionEditor();
-       G_MainWin->mainTimer->setBpm(s.c_str());
+       /* This function might get called by Jack callback BEFORE the UI is up
+       and running, that is when G_MainWin == nullptr. */
+       
+       if (G_MainWin != nullptr) {
+               u::gui::refreshActionEditor();
+               G_MainWin->mainTimer->setBpm(s.c_str());
+       }
 
        gu_log("[glue::setBpm_] Bpm changed to %s (real=%f)\n", s.c_str(), clock::getBpm());
 }
@@ -90,7 +97,7 @@ void setBpm_(float f, string s)
 /* -------------------------------------------------------------------------- */
 
 
-void glue_setBpm(const char* v1, const char* v2)
+void setBpm(const char* v1, const char* v2)
 {
        /* Never change this stuff while recording audio */
 
@@ -117,7 +124,7 @@ void glue_setBpm(const char* v1, const char* v2)
 /* -------------------------------------------------------------------------- */
 
 
-void glue_setBpm(float f)
+void setBpm(float f)
 {
        /* Never change this stuff while recording audio */
 
@@ -135,7 +142,7 @@ void glue_setBpm(float f)
 /* -------------------------------------------------------------------------- */
 
 
-void glue_setBeats(int beats, int bars)
+void setBeats(int beats, int bars)
 {
        /* Never change this stuff while recording audio */
 
@@ -148,14 +155,14 @@ void glue_setBeats(int beats, int bars)
        mixer::allocVirtualInput(clock::getFramesInLoop());
 
        G_MainWin->mainTimer->setMeter(clock::getBeats(), clock::getBars());
-       gu_refreshActionEditor();  // in case the action editor is open
+       u::gui::refreshActionEditor();  // in case the action editor is open
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void glue_quantize(int val)
+void quantize(int val)
 {
        clock::setQuantize(val);
 }
@@ -164,9 +171,9 @@ void glue_quantize(int val)
 /* -------------------------------------------------------------------------- */
 
 
-void glue_setOutVol(float v, bool gui)
+void setOutVol(float v, bool gui)
 {
-       mixer::outVol = v;
+       mixer::outVol.store(v);
        if (!gui) {
                Fl::lock();
                G_MainWin->mainIO->setOutVol(v);
@@ -178,9 +185,9 @@ void glue_setOutVol(float v, bool gui)
 /* -------------------------------------------------------------------------- */
 
 
-void glue_setInVol(float v, bool gui)
+void setInVol(float v, bool gui)
 {
-       mixer::inVol = v;
+       mixer::inVol.store(v);
        if (!gui) {
                Fl::lock();
                G_MainWin->mainIO->setInVol(v);
@@ -192,9 +199,9 @@ void glue_setInVol(float v, bool gui)
 /* -------------------------------------------------------------------------- */
 
 
-void glue_clearAllSamples()
+void clearAllSamples()
 {
-       clock::stop();
+       clock::setStatus(ClockStatus::STOPPED);
        for (Channel* ch : mixer::channels) {
                ch->empty();
                ch->guiChannel->reset();
@@ -207,49 +214,53 @@ void glue_clearAllSamples()
 /* -------------------------------------------------------------------------- */
 
 
-void glue_clearAllActions()
+void clearAllActions()
 {
        recorder::clearAll();
        for (Channel* ch : mixer::channels)
                ch->hasActions = false;
-       gu_updateControls();
+       u::gui::updateControls();
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void glue_resetToInitState(bool resetGui, bool createColumns)
+void resetToInitState(bool resetGui, bool createColumns)
 {
-       gu_closeAllSubwindows();
+       u::gui::closeAllSubwindows();
        mixer::close();
        clock::init(conf::samplerate, conf::midiTCfps);
        mixer::init(clock::getFramesInLoop(), kernelAudio::getRealBufSize());
        recorder::init(&mixer::mutex);
+
 #ifdef WITH_VST
        pluginHost::freeAllStacks(&mixer::channels, &mixer::mutex);
+       pluginManager::init(conf::samplerate, kernelAudio::getRealBufSize());
 #endif
 
        G_MainWin->keyboard->clear();
        if (createColumns)
                G_MainWin->keyboard->init();
 
-       gu_updateMainWinLabel(G_DEFAULT_PATCH_NAME);
+       u::gui::updateMainWinLabel(G_DEFAULT_PATCH_NAME);
 
        if (resetGui)
-               gu_updateControls();
+               u::gui::updateControls();
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void glue_beatsMultiply()
+void beatsMultiply()
 {
-       glue_setBeats(clock::getBeats() * 2, clock::getBars());
+       setBeats(clock::getBeats() * 2, clock::getBars());
 }
 
-void glue_beatsDivide()
+void beatsDivide()
 {
-       glue_setBeats(clock::getBeats() / 2, clock::getBars());
+       setBeats(clock::getBeats() / 2, clock::getBars());
 }
+
+}}} // giada::c::main::
\ No newline at end of file
index ef7c7941c26898e263bb24a79b0f0db918d60849..d3db874174b0d770655886be7a0e2ed526fc9d28 100644 (file)
@@ -5,13 +5,13 @@
  * glue
  * Intermediate layer GUI <-> CORE.
  *
- * How to know if you need another glue_ function? Ask yourself if the
+ * How to know if you need another  function? Ask yourself if the
  * new action will ever be called via MIDI or keyboard/mouse. If yes,
  * put it here.
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
  * -------------------------------------------------------------------------- */
 
 
-#ifndef G_GLUE_MAIN_H
-#define G_GLUE_MAIN_H
+#ifndef G_MAIN_H
+#define G_MAIN_H
 
 
-/* glue_setBpm (1)
+namespace giada {
+namespace c {
+namespace main
+{
+/* setBpm (1)
 Sets bpm value from string to float. */
 
-void glue_setBpm(const char* v1, const char* v2);
+void setBpm(const char* v1, const char* v2);
 
-/* glue_setBpm (2)
+/* setBpm (2)
 Sets bpm value. Usually called from the Jack callback or non-UI components. */
 
-void glue_setBpm(float v);
+void setBpm(float v);
 
-void glue_setBeats(int beats, int bars);
-void glue_quantize(int val);
-void glue_setOutVol(float v, bool gui=true);
-void glue_setInVol(float v, bool gui=true);
-void glue_clearAllSamples();
-void glue_clearAllActions();
+void setBeats(int beats, int bars);
+void quantize(int val);
+void setOutVol(float v, bool gui=true);
+void setInVol(float v, bool gui=true);
+void clearAllSamples();
+void clearAllActions();
 
 /* resetToInitState
 Resets Giada to init state. If resetGui also refresh all widgets. If 
 createColumns also build initial empty columns. */
 
-void glue_resetToInitState(bool resetGui=true, bool createColumns=true);
+void resetToInitState(bool resetGui=true, bool createColumns=true);
 
 /* beatsDivide/Multiply
 Shrinks or enlarges the number of beats by 2. */
 
-void glue_beatsMultiply();
-void glue_beatsDivide();
+void beatsMultiply();
+void beatsDivide();
+
+}}} // giada::c::main::
 
 #endif
index c5282ac427311b4d196e37813ea879b171417752..906971da24be7721cfd9f9a995dce48ef0bbc391 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -29,6 +29,7 @@
 
 
 #include <FL/Fl.H>
+#include "../core/pluginManager.h"
 #include "../core/pluginHost.h"
 #include "../core/mixer.h"
 #include "../core/plugin.h"
 #include "../core/const.h"
 #include "../core/conf.h"
 #include "../utils/gui.h"
-#include "../gui/dialogs/gd_mainWindow.h"
+#include "../gui/dialogs/mainWindow.h"
 #include "../gui/dialogs/pluginWindow.h"
 #include "../gui/dialogs/pluginList.h"
-#include "../gui/dialogs/gd_warnings.h"
-#include "../gui/dialogs/gd_config.h"
+#include "../gui/dialogs/warnings.h"
+#include "../gui/dialogs/config.h"
 #include "../gui/dialogs/browser/browserDir.h"
 #include "plugin.h"
 
@@ -66,10 +67,10 @@ gdPluginWindow* getPluginWindow(const Plugin* p)
        /* Get the parent window first: the plug-in list. Then, if it exists, get
        the child window - the actual pluginWindow. */
 
-       gdPluginList* parent = static_cast<gdPluginList*>(gu_getSubwindow(G_MainWin, WID_FX_LIST));
+       gdPluginList* parent = static_cast<gdPluginList*>(u::gui::getSubwindow(G_MainWin, WID_FX_LIST));
        if (parent == nullptr)
                return nullptr;
-       return static_cast<gdPluginWindow*>(gu_getSubwindow(parent, p->getId() + 1));
+       return static_cast<gdPluginWindow*>(u::gui::getSubwindow(parent, p->getId() + 1));
 }
 } // {anonymous}
 
@@ -79,20 +80,22 @@ gdPluginWindow* getPluginWindow(const Plugin* p)
 /* -------------------------------------------------------------------------- */
 
 
-Plugin* addPlugin(Channel* ch, int index, int stackType)
+void addPlugin(Channel* ch, int index, m::pluginHost::StackType t)
 {
-  if (index >= pluginHost::countAvailablePlugins())
-    return nullptr;
-  return pluginHost::addPlugin(index, stackType, &mixer::mutex, ch);
+       if (index >= pluginManager::countAvailablePlugins())
+               return;
+       std::unique_ptr<Plugin> p = pluginManager::makePlugin(index);
+       if (p != nullptr)
+               pluginHost::addPlugin(std::move(p), t, &mixer::mutex, ch);
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void swapPlugins(Channel* ch, int index1, int index2, int stackType)
+void swapPlugins(Channel* ch, int index1, int index2, m::pluginHost::StackType t)
 {
-  pluginHost::swapPlugin(index1, index2, stackType, &mixer::mutex,
+  pluginHost::swapPlugin(index1, index2, t, &mixer::mutex,
     ch);
 }
 
@@ -100,9 +103,9 @@ void swapPlugins(Channel* ch, int index1, int index2, int stackType)
 /* -------------------------------------------------------------------------- */
 
 
-void freePlugin(Channel* ch, int index, int stackType)
+void freePlugin(Channel* ch, int index, m::pluginHost::StackType t)
 {
-  pluginHost::freePlugin(index, stackType, &mixer::mutex, ch);
+  pluginHost::freePlugin(index, t, &mixer::mutex, ch);
 }
 
 
@@ -170,7 +173,7 @@ void setPluginPathCb(void* data)
 
        browser->do_callback();
 
-       gdConfig* configWin = static_cast<gdConfig*>(gu_getSubwindow(G_MainWin, WID_CONFIG));
+       gdConfig* configWin = static_cast<gdConfig*>(u::gui::getSubwindow(G_MainWin, WID_CONFIG));
        configWin->refreshVstPath();
 }
 
index 4b55afd0ce8d6c66fa881896358f518625e26df9..7ce3ee16bd836b33852e2c5cd0847ee1c409b91c 100644 (file)
@@ -7,7 +7,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -35,6 +35,9 @@
 #ifdef WITH_VST
 
 
+#include "../core/pluginHost.h"
+
+
 namespace giada {
 namespace m
 {
@@ -44,9 +47,9 @@ class Channel;
 namespace c {
 namespace plugin 
 {
-m::Plugin* addPlugin(m::Channel* ch, int index, int stackType);
-void swapPlugins(m::Channel* ch, int indexP1, int indexP2, int stackType);
-void freePlugin(m::Channel* ch, int index, int stackType);
+void addPlugin(m::Channel* ch, int index, m::pluginHost::StackType t);
+void swapPlugins(m::Channel* ch, int indexP1, int indexP2, m::pluginHost::StackType t);
+void freePlugin(m::Channel* ch, int index, m::pluginHost::StackType t);
 void setParameter(m::Plugin* p, int index, float value, bool gui=true); 
 void setProgram(m::Plugin* p, int index);
 
index 2b166cbf45051ae008ea8bd4112d59c0f698e7b3..ec99dc2cecd8e9bffa1b75d05ac07711f6afe82d 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -26,7 +26,7 @@
 
 
 #include <cassert>
-#include "../gui/dialogs/gd_warnings.h"
+#include "../gui/dialogs/warnings.h"
 #include "../gui/elems/mainWindow/keyboard/channel.h"
 #include "../gui/elems/mainWindow/keyboard/sampleChannel.h"
 #include "../core/const.h"
 #include "recorder.h"
 
 
-using std::vector;
-using namespace giada;
-
-
 namespace giada {
 namespace c {
 namespace recorder 
@@ -95,12 +91,15 @@ void clearStartStopActions(geChannel* gch)
 void updateChannel(geChannel* gch, bool refreshActionEditor)
 {
        gch->ch->hasActions = m::recorder::hasActions(gch->ch->index);
+       if (!gch->ch->hasActions)
+               gch->ch->readActions = false;
+
        if (gch->ch->type == ChannelType::SAMPLE) {
                geSampleChannel* gsch = static_cast<geSampleChannel*>(gch);
                gsch->ch->hasActions ? gsch->showActionButton() : gsch->hideActionButton();
        }
        if (refreshActionEditor)
-               gu_refreshActionEditor(); // refresh a.editor window, it could be open
+               u::gui::refreshActionEditor(); // refresh a.editor window, it could be open
 }
 
 }}} // giada::c::recorder::
\ No newline at end of file
index f28a3ccd00c8a1703ae94f035cc91f29ed3b1c28..54e2361ba8c5fbe11e4878a18a89be6c534618ac 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index f86c67bfa19abdba105059ff4b0b49f90096f352..1252b10168399cb1efb712287379459990b9204a 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -27,9 +27,9 @@
 
 #include <cassert>
 #include <FL/Fl.H>
-#include "../gui/dialogs/gd_mainWindow.h"
+#include "../gui/dialogs/mainWindow.h"
 #include "../gui/dialogs/sampleEditor.h"
-#include "../gui/dialogs/gd_warnings.h"
+#include "../gui/dialogs/warnings.h"
 #include "../gui/elems/basics/button.h"
 #include "../gui/elems/sampleEditor/waveTools.h"
 #include "../gui/elems/sampleEditor/volumeTool.h"
@@ -55,15 +55,15 @@ extern gdMainWindow* G_MainWin;
 
 
 namespace giada {
-namespace c     {
+namespace c {
 namespace sampleEditor
 {
 namespace
 {
-       /* m_waveBuffer
+       /* waveBuffer
        A Wave used during cut/copy/paste operations. */
 
-       Wave* m_waveBuffer = nullptr;
+       std::unique_ptr<Wave> waveBuffer_;
 }; // {anonymous}
 
 
@@ -72,7 +72,7 @@ namespace
 
 gdSampleEditor* getSampleEditorWindow()
 {
-       gdSampleEditor* se = static_cast<gdSampleEditor*>(gu_getSubwindow(G_MainWin, WID_SAMPLE_EDITOR));
+       gdSampleEditor* se = static_cast<gdSampleEditor*>(u::gui::getSubwindow(G_MainWin, WID_SAMPLE_EDITOR));
        assert(se != nullptr);
        return se;
 }
@@ -119,9 +119,7 @@ void cut(m::SampleChannel* ch, int a, int b)
 
 void copy(m::SampleChannel* ch, int a, int b)
 {
-       if (m_waveBuffer != nullptr)
-               delete m_waveBuffer;
-       m::waveManager::createFromWave(ch->wave, a, b, &m_waveBuffer);
+       waveBuffer_ = m::waveManager::createFromWave(ch->wave.get(), a, b);
 }
 
 
@@ -135,11 +133,11 @@ void paste(m::SampleChannel* ch, int a)
                return;
        }
        
-       m::wfx::paste(*m_waveBuffer, *ch->wave, a);
+       m::wfx::paste(*waveBuffer_.get(), *ch->wave.get(), a);
 
        /* Shift begin/end points to keep the previous position. */
 
-       int delta = m_waveBuffer->getSize();
+       int delta = waveBuffer_->getSize();
        if (a < ch->getBegin() && a < ch->getEnd())
                setBeginEnd(ch, ch->getBegin() + delta, ch->getEnd() + delta);
        else
@@ -267,10 +265,7 @@ void toNewChannel(m::SampleChannel* ch, int a, int b)
        m::SampleChannel* newCh = static_cast<m::SampleChannel*>(c::channel::addChannel(
                ch->guiChannel->getColumnIndex(), ChannelType::SAMPLE, G_GUI_CHANNEL_H_1));
 
-       Wave* wave = nullptr;
-       m::waveManager::createFromWave(ch->wave, a, b, &wave);
-
-       newCh->pushWave(wave);
+       newCh->pushWave(m::waveManager::createFromWave(ch->wave.get(), a, b));
        newCh->guiChannel->update();
 }
 
@@ -280,7 +275,7 @@ void toNewChannel(m::SampleChannel* ch, int a, int b)
 
 bool isWaveBufferFull()
 {
-       return m_waveBuffer != nullptr;
+       return waveBuffer_ != nullptr;
 }
 
 
index 3cd4bc87316f2c2d7686c0d1592a8337693dea78..a7339f815db3780c5b074effe5a731639c3aebeb 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index e3779e2d5548c4aca515b925812eead5234c78b7..d04c49475c9aa7ed7a22d663a337475cce7eaa35 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -29,6 +29,7 @@
 #include "../core/mixerHandler.h"
 #include "../core/channel.h"
 #include "../core/recorderHandler.h"
+#include "../core/pluginManager.h"
 #include "../core/pluginHost.h"
 #include "../core/plugin.h"
 #include "../core/conf.h"
@@ -45,8 +46,8 @@
 #include "../gui/elems/basics/progress.h"
 #include "../gui/elems/mainWindow/keyboard/column.h"
 #include "../gui/elems/mainWindow/keyboard/keyboard.h"
-#include "../gui/dialogs/gd_mainWindow.h"
-#include "../gui/dialogs/gd_warnings.h"
+#include "../gui/dialogs/mainWindow.h"
+#include "../gui/dialogs/warnings.h"
 #include "../gui/dialogs/browser/browserSave.h"
 #include "../gui/dialogs/browser/browserLoad.h"
 #include "main.h"
 #include "storage.h"
 
 
-extern gdMainWindow *G_MainWin;
+extern gdMainWindowG_MainWin;
 
 
 using std::string;
 using std::vector;
-using namespace giada;
 
 
+namespace giada {
+namespace c {
+namespace storage
+{
+namespace
+{
 #ifdef WITH_VST
 
-static void glue_fillPatchGlobalsPlugins__(vector <m::Plugin*>* host, vector<m::patch::plugin_t>* patch)
+void fillPatchGlobalsPlugins_(vector<m::Plugin*> stack, vector<m::patch::plugin_t>& patch)
 {
        using namespace giada::m;
 
-       for (unsigned i=0; i<host->size(); i++) {
-               Plugin *pl = host->at(i);
+       for (const Plugin* plugin : stack) {
                patch::plugin_t ppl;
-               ppl.path = pl->getUniqueId();
-               ppl.bypass = pl->isBypassed();
-               int numParams = pl->getNumParameters();
-               for (int k=0; k<numParams; k++)
-                       ppl.params.push_back(pl->getParameter(k));
-               patch->push_back(ppl);
+               ppl.path   = plugin->getUniqueId();
+               ppl.bypass = plugin->isBypassed();
+               for (int k=0; k<plugin->getNumParameters(); k++)
+                       ppl.params.push_back(plugin->getParameter(k));
+               patch.push_back(ppl);
        }
 }
 
@@ -86,7 +90,7 @@ static void glue_fillPatchGlobalsPlugins__(vector <m::Plugin*>* host, vector<m::
 /* -------------------------------------------------------------------------- */
 
 
-static void glue_fillPatchColumns__()
+void fillPatchColumns_()
 {
        using namespace giada::m;
 
@@ -112,20 +116,19 @@ static void glue_fillPatchColumns__()
 /* -------------------------------------------------------------------------- */
 
 
-static void glue_fillPatchChannels__(bool isProject)
+void fillPatchChannels_(bool isProject)
 {
        using namespace giada::m;
 
-       for (unsigned i=0; i<mixer::channels.size(); i++) {
+       for (unsigned i=0; i<mixer::channels.size(); i++)
                mixer::channels.at(i)->writePatch(i, isProject);
-       }
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-static void glue_fillPatchGlobals__(const string &name)
+void fillPatchGlobals_(const string& name)
 {
        using namespace giada::m;
 
@@ -138,16 +141,16 @@ static void glue_fillPatchGlobals__(const string &name)
        patch::bars         = clock::getBars();
        patch::beats        = clock::getBeats();
        patch::quantize     = clock::getQuantize();
-       patch::masterVolIn  = mixer::inVol;
-       patch::masterVolOut = mixer::outVol;
-       patch::metronome    = mixer::metronome;
+       patch::masterVolIn  = mixer::inVol.load();
+       patch::masterVolOut = mixer::outVol.load();
+       patch::metronome    = mixer::isMetronomeOn();
 
 #ifdef WITH_VST
 
-       glue_fillPatchGlobalsPlugins__(pluginHost::getStack(pluginHost::MASTER_IN),
-                       &patch::masterInPlugins);
-       glue_fillPatchGlobalsPlugins__(pluginHost::getStack(pluginHost::MASTER_OUT),
-                       &patch::masterOutPlugins);
+       fillPatchGlobalsPlugins_(pluginHost::getStack(pluginHost::StackType::MASTER_IN),
+                       patch::masterInPlugins);
+       fillPatchGlobalsPlugins_(pluginHost::getStack(pluginHost::StackType::MASTER_OUT),
+                       patch::masterOutPlugins);
 
 #endif
 }
@@ -156,20 +159,19 @@ static void glue_fillPatchGlobals__(const string &name)
 /* -------------------------------------------------------------------------- */
 
 
-static bool glue_savePatch__(const string &fullPath, const string &name,
-               bool isProject)
+bool savePatch_(const string& fullPath, const string& name, bool isProject)
 {
        using namespace giada::m;
 
        patch::init();
 
-       glue_fillPatchGlobals__(name);
-       glue_fillPatchChannels__(isProject);
-       glue_fillPatchColumns__();
+       fillPatchGlobals_(name);
+       fillPatchChannels_(isProject);
+       fillPatchColumns_();
 
        if (patch::write(fullPath)) {
-               gu_updateMainWinLabel(name);
-               gu_log("[glue_savePatch] patch saved as %s\n", fullPath.c_str());
+               u::gui::updateMainWinLabel(name);
+               gu_log("[savePatch] patch saved as %s\n", fullPath.c_str());
                return true;
        }
        return false;
@@ -179,13 +181,13 @@ static bool glue_savePatch__(const string &fullPath, const string &name,
 /* -------------------------------------------------------------------------- */
 
 
-static string glue_makeSamplePath__(const string& base, const Wave* w, int k)
+string makeSamplePath_(const string& base, const Wave& w, int k)
 {
-       return base + G_SLASH + w->getBasename(false) + "-" + gu_iToString(k) + "." +  w->getExtension();
+       return base + G_SLASH + w.getBasename(false) + "-" + u::string::iToString(k) + "." +  w.getExtension();
 } 
 
 
-static string glue_makeUniqueSamplePath__(const string& base, const m::SampleChannel* ch)
+string makeUniqueSamplePath_(const string& base, const m::SampleChannel* ch)
 {
        using namespace giada::m;
 
@@ -194,17 +196,20 @@ static string glue_makeUniqueSamplePath__(const string& base, const m::SampleCha
                return path;
 
        int k = 0;
-       path = glue_makeSamplePath__(base, ch->wave, k);
+       path = makeSamplePath_(base, *ch->wave.get(), k);
        while (!mh::uniqueSamplePath(ch, path))
-               path = glue_makeSamplePath__(base, ch->wave, k++);
+               path = makeSamplePath_(base, *ch->wave.get(), k++);
        return path;
 }
+} // {anonymous}
 
 
+/* -------------------------------------------------------------------------- */
+/* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
 
 
-void glue_savePatch(void* data)
+void savePatch(void* data)
 {
        gdBrowserSave* browser = (gdBrowserSave*) data;
        string name            = gu_stripExt(browser->getName());
@@ -219,7 +224,7 @@ void glue_savePatch(void* data)
                if (!gdConfirmWin("Warning", "File exists: overwrite?"))
                        return;
 
-       if (glue_savePatch__(fullPath, name, false)) {  // false == not a project
+       if (savePatch_(fullPath, name, false)) {  // false == not a project
                m::conf::patchPath = gu_dirname(fullPath);
                browser->do_callback();
        }
@@ -231,7 +236,7 @@ void glue_savePatch(void* data)
 /* -------------------------------------------------------------------------- */
 
 
-void glue_loadPatch(void* data)
+void loadPatch(void* data)
 {
        using namespace giada::m;
 
@@ -264,12 +269,12 @@ void glue_loadPatch(void* data)
        /* Close all other windows. This prevents problems if plugin windows are 
        open. */
 
-       gu_closeAllSubwindows();
+       u::gui::closeAllSubwindows();
 
        /* Reset the system. False(1): don't update the gui right now. False(2): do 
        not create empty columns. */
 
-       glue_resetToInitState(false, false);
+       c::main::resetToInitState(false, false);
 
        browser->setStatusBar(0.1f);
 
@@ -303,8 +308,8 @@ void glue_loadPatch(void* data)
 
        /* Refresh GUI. */
 
-       gu_updateControls();
-       gu_updateMainWinLabel(patch::name);
+       u::gui::updateControls();
+       u::gui::updateMainWinLabel(patch::name);
 
        browser->setStatusBar(0.1f);
 
@@ -312,7 +317,7 @@ void glue_loadPatch(void* data)
 
 #ifdef WITH_VST
 
-       if (pluginHost::hasMissingPlugins())
+       if (pluginManager::hasMissingPlugins())
                gdAlert("Some plugins were not loaded successfully.\nCheck the plugin browser to know more.");
 
 #endif
@@ -324,7 +329,7 @@ void glue_loadPatch(void* data)
 /* -------------------------------------------------------------------------- */
 
 
-void glue_saveProject(void* data)
+void saveProject(void* data)
 {
        using namespace giada::m;
 
@@ -342,14 +347,14 @@ void glue_saveProject(void* data)
                return;
 
        if (!gu_dirExists(fullPath) && !gu_mkdir(fullPath)) {
-               gu_log("[glue_saveProject] Unable to make project directory!\n");
+               gu_log("[saveProject] Unable to make project directory!\n");
                return;
        }
 
-       gu_log("[glue_saveProject] Project dir created: %s\n", fullPath.c_str());
+       gu_log("[saveProject] Project dir created: %s\n", fullPath.c_str());
 
        /* Copy all samples inside the folder. Takes and logical ones are saved via 
-       glue_saveSample(). Update the new sample path: everything now comes from the 
+       saveSample(). Update the new sample path: everything now comes from the 
        project folder (folderPath). Also make sure the file path is unique inside the 
        project folder.*/
 
@@ -363,15 +368,15 @@ void glue_saveProject(void* data)
                if (sch->wave == nullptr)
                        continue;
 
-               sch->wave->setPath(glue_makeUniqueSamplePath__(fullPath, sch));
+               sch->wave->setPath(makeUniqueSamplePath_(fullPath, sch));
 
-               gu_log("[glue_saveProject] Save file to %s\n", sch->wave->getPath().c_str());
+               gu_log("[saveProject] Save file to %s\n", sch->wave->getPath().c_str());
 
-               waveManager::save(sch->wave, sch->wave->getPath()); // TODO - error checking    
+               waveManager::save(sch->wave.get(), sch->wave->getPath()); // TODO - error checking      
        }
 
        string gptcPath = fullPath + G_SLASH + name + ".gptc";
-       if (glue_savePatch__(gptcPath, name, true)) // true == it's a project
+       if (savePatch_(gptcPath, name, true)) // true == it's a project
                browser->do_callback();
        else
                gdAlert("Unable to save the project!");
@@ -381,7 +386,7 @@ void glue_saveProject(void* data)
 /* -------------------------------------------------------------------------- */
 
 
-void glue_loadSample(void* data)
+void loadSample(void* data)
 {
        gdBrowserLoad* browser = (gdBrowserLoad*) data;
        string fullPath        = browser->getSelectedItem();
@@ -405,7 +410,7 @@ void glue_loadSample(void* data)
 /* -------------------------------------------------------------------------- */
 
 
-void glue_saveSample(void* data)
+void saveSample(void* data)
 {
        using namespace giada::m;
 
@@ -428,11 +433,13 @@ void glue_saveSample(void* data)
 
        SampleChannel* ch = static_cast<SampleChannel*>(browser->getChannel());
 
-       if (waveManager::save(ch->wave, filePath)) {
-               gu_log("[glue_saveSample] sample saved to %s\n", filePath.c_str());
+       if (waveManager::save(ch->wave.get(), filePath)) {
+               gu_log("[saveSample] sample saved to %s\n", filePath.c_str());
                conf::samplePath = gu_dirname(filePath);
                browser->do_callback();
        }
        else
                gdAlert("Unable to save this sample!");
 }
+
+}}} // giada::c::storage::
\ No newline at end of file
index 35f15d2fbbd9822f0be7e84a7682ae40d6fa51b2..779dcf0b59256f84216e5b1f83af62bcb095ea68 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
 #define G_GLUE_STORAGE_H
 
 
-void glue_loadPatch  (void* data);
-void glue_savePatch  (void* data);
-void glue_saveProject(void* data);
-void glue_saveSample (void* data);
-void glue_loadSample (void* data);
-
+namespace giada {
+namespace c {
+namespace storage
+{
+void loadPatch  (void* data);
+void savePatch  (void* data);
+void saveProject(void* data);
+void saveSample (void* data);
+void loadSample (void* data);
+}}} // giada::c::storage::
 
 #endif
index 4e958dce94b4dfd8483ce48bb6cf964864bfee5d..bb7ba34c8791d913d2849a0e2394a9733829467d 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -27,7 +27,7 @@
 
 #include <FL/Fl.H>
 #include "../gui/elems/mainWindow/mainTransport.h"
-#include "../gui/dialogs/gd_mainWindow.h"
+#include "../gui/dialogs/mainWindow.h"
 #include "../core/clock.h"
 #include "../core/conf.h"
 #include "../core/const.h"
@@ -36,6 +36,7 @@
 #include "../core/mixerHandler.h"
 #include "../core/mixer.h"
 #include "../core/recorder.h"
+#include "../core/recManager.h"
 #include "transport.h"
 
 
@@ -60,7 +61,20 @@ void startStopSeq(bool gui)
 
 void startSeq(bool gui)
 {
-       clock::start();
+       switch (clock::getStatus()) {
+               case ClockStatus::STOPPED:
+                       clock::setStatus(ClockStatus::RUNNING); 
+                       break;
+               case ClockStatus::WAITING:
+                       clock::setStatus(ClockStatus::RUNNING); 
+                       m::recManager::stopActionRec();
+                       G_MainWin->mainTransport->setRecTriggerModeActive(true);
+                       G_MainWin->mainTransport->updateRecAction(0);
+                       G_MainWin->mainTransport->updateRecInput(0);
+                       break;
+               default: 
+                       break;
+       }
 
 #ifdef __linux__
        kernelAudio::jackStart();
@@ -70,7 +84,7 @@ void startSeq(bool gui)
                Fl::lock();
                G_MainWin->mainTransport->updatePlay(1);
                Fl::unlock();
-  }
+       }
 }
 
 
@@ -136,12 +150,12 @@ void rewindSeq(bool gui, bool notifyJack)
 /* -------------------------------------------------------------------------- */
 
 
-void startStopMetronome(bool gui)
+void toggleMetronome(bool gui)
 {
-       mixer::metronome = !mixer::metronome;
+       mixer::toggleMetronome();
        if (!gui) {
                Fl::lock();
-               G_MainWin->mainTransport->updateMetronome(mixer::metronome);
+               G_MainWin->mainTransport->updateMetronome(mixer::isMetronomeOn());
                Fl::unlock();
        }
 }
index 3be492fd50e85a414392753b6744b78bead2ced9..69713bc24048e10129583e56e4a496f4a8f9e961 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -37,7 +37,7 @@ void startStopSeq(bool gui=true);
 void startSeq(bool gui=true);
 void stopSeq(bool gui=true);
 void rewindSeq(bool gui=true, bool notifyJack=true);
-void startStopMetronome(bool gui=true);
+void toggleMetronome(bool gui=true);
 }}} // giada::c::transport::
 
 
index dfe503a6b440a1f040fd2b07871b3f0279d88de9..841d1f1e1b8da7a8caa81194364001ef2d8d6651 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -42,9 +42,7 @@
 #include "about.h"
 
 
-using std::string;
-using namespace giada::m;
-using namespace giada::u;
+using namespace giada;
 
 
 gdAbout::gdAbout()
@@ -54,8 +52,8 @@ gdAbout::gdAbout()
 : gdWindow(340, 350, "About Giada")
 #endif
 {
-       if (conf::aboutX)
-               resize(conf::aboutX, conf::aboutY, w(), h());
+       if (m::conf::aboutX)
+               resize(m::conf::aboutX, m::conf::aboutY, w(), h());
 
        set_modal();
 
@@ -71,8 +69,8 @@ gdAbout::gdAbout()
        logo->image(new Fl_Pixmap(giada_logo_xpm));
        text->align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE | FL_ALIGN_TOP);
 
-       string message = gu_format(
-         "Version " G_VERSION_STR " (" BUILD_DATE ")\n\n"
+       std::string message = u::string::format(
+         "Version %s (" BUILD_DATE ")\n\n"
                "Developed by Monocasual Laboratories\n"
                "Based on FLTK (%d.%d.%d), RtAudio (%s),\n"
                "RtMidi (%s), Libsamplerate, Jansson (%s),\n"
@@ -86,10 +84,10 @@ gdAbout::gdAbout()
                "Public License (GPL v3)\n\n"
                "News, infos, contacts and documentation:\n"
                "www.giadamusic.com",
-               FL_MAJOR_VERSION, FL_MINOR_VERSION, FL_PATCH_VERSION,
-               ver::getRtAudioVersion().c_str(),
-               ver::getRtMidiVersion().c_str(),
-               JANSSON_VERSION, ver::getLibsndfileVersion().c_str()
+               G_VERSION_STR, FL_MAJOR_VERSION, FL_MINOR_VERSION, FL_PATCH_VERSION,
+               u::ver::getRtAudioVersion().c_str(),
+               u::ver::getRtMidiVersion().c_str(),
+               JANSSON_VERSION, u::ver::getLibsndfileVersion().c_str()
 #ifdef WITH_VST
                , JUCE_MAJOR_VERSION, JUCE_MINOR_VERSION, JUCE_BUILDNUMBER
 #endif
@@ -113,7 +111,7 @@ gdAbout::gdAbout()
 #endif
 
        close->callback(cb_close, (void*)this);
-       gu_setFavicon(this);
+       u::gui::setFavicon(this);
        setId(WID_ABOUT);
        show();
 }
@@ -124,8 +122,8 @@ gdAbout::gdAbout()
 
 gdAbout::~gdAbout()
 {
-       conf::aboutX = x();
-       conf::aboutY = y();
+       m::conf::aboutX = x();
+       m::conf::aboutY = y();
 }
 
 
index 8d37cdace854d119392dea2ab2a868a9ffbfe38c..6be2063bbafe28b4a274d11fdbfed5f73ff50d28 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index c7fc692d66946e567f89cbac3ccf385f48149ef5..84a72637bb2b94bc10ca31ba270b14927ad4ad65 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -41,9 +41,6 @@
 #include "baseActionEditor.h"
 
 
-using std::string;
-
-
 namespace giada {
 namespace v
 {
@@ -79,8 +76,8 @@ gdBaseActionEditor::~gdBaseActionEditor()
 /* -------------------------------------------------------------------------- */
 
 
-void gdBaseActionEditor::cb_zoomIn(Fl_Widget *w, void *p)  { ((gdBaseActionEditor*)p)->zoomIn(); }
-void gdBaseActionEditor::cb_zoomOut(Fl_Widget *w, void *p) { ((gdBaseActionEditor*)p)->zoomOut(); }
+void gdBaseActionEditor::cb_zoomIn(Fl_Widget* w, void* p)  { ((gdBaseActionEditor*)p)->zoomIn(); }
+void gdBaseActionEditor::cb_zoomOut(Fl_Widget* w, void* p) { ((gdBaseActionEditor*)p)->zoomOut(); }
 
 
 /* -------------------------------------------------------------------------- */
@@ -197,9 +194,9 @@ int gdBaseActionEditor::getActionType() const
 
 void gdBaseActionEditor::prepareWindow()
 {
-       gu_setFavicon(this);
+       u::gui::setFavicon(this);
 
-       string l = "Action Editor";
+       std::string l = "Action Editor";
        if (ch->name != "") l += " - " + ch->name;
        copy_label(l.c_str());
 
index da7ce46cd783ab59c9571e12f76c3ac7e87d0ba3..0f6dbeaf4d97475ae66c7eb33eb44f64bb1f5d70 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -42,7 +42,7 @@ namespace giada {
 namespace m
 {
 class Channel;
-class Action;
+struct Action;
 }
 namespace v
 {
index 28bd61a05adeda2e49064578455519c33b85bd6b..d1547aa5688ad7c8ab746fa512e8602b4d7d3a08 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index f850099f819243b80e1aeefac4f61d4e7d67dee8..2cf5d63eb5414c4ea2001b0c84325229adfee749 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index e69a89cbd78da325e0e9db6f7b01db39bf2c7007..17715ee4f6e0ee317b814bcf2792515c29b5203f 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 9d459a8baa9d66f057743be47117d28345d74a54..2e170d85a1a65d1949894a3d7692a32bd6075b5a 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 710893bb215935671698425b5b5841f5f21e646b..b7857a2bbc48ba83b340625344bd75cd9a5676bc 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
 #include "../elems/basics/button.h"
 #include "../elems/basics/check.h"
 #include "beatsInput.h"
-#include "gd_mainWindow.h"
+#include "mainWindow.h"
 
 
 extern gdMainWindow* mainWin;
 
 
-using namespace giada::m;
+using namespace giada;
 
 
 gdBeatsInput::gdBeatsInput()
        : gdWindow(180, 36, "Beats")
 {
-       if (conf::beatsX)
-               resize(conf::beatsX, conf::beatsY, w(), h());
+       if (m::conf::beatsX)
+               resize(m::conf::beatsX, m::conf::beatsY, w(), h());
 
        set_modal();
 
@@ -60,17 +60,17 @@ gdBeatsInput::gdBeatsInput()
        end();
 
        beats->maximum_size(2);
-       beats->value(gu_iToString(clock::getBeats()).c_str());
+       beats->value(u::string::iToString(m::clock::getBeats()).c_str());
        beats->type(FL_INT_INPUT);
        
        bars->maximum_size(2);
-       bars->value(gu_iToString(clock::getBars()).c_str());
+       bars->value(u::string::iToString(m::clock::getBars()).c_str());
        bars->type(FL_INT_INPUT);
        
        ok->shortcut(FL_Enter);
        ok->callback(cb_update, (void*)this);
 
-       gu_setFavicon(this);
+       u::gui::setFavicon(this);
        setId(WID_BEATS);
        show();
 }
@@ -81,8 +81,8 @@ gdBeatsInput::gdBeatsInput()
 
 gdBeatsInput::~gdBeatsInput()
 {
-       conf::beatsX = x();
-       conf::beatsY = y();
+       m::conf::beatsX = x();
+       m::conf::beatsY = y();
 }
 
 
@@ -99,6 +99,6 @@ void gdBeatsInput::cb_update()
 {
        if (!strcmp(beats->value(), "") || !strcmp(bars->value(), ""))
                return;
-       glue_setBeats(atoi(beats->value()), atoi(bars->value()));
+       c::main::setBeats(atoi(beats->value()), atoi(bars->value()));
        do_callback();
 }
index 6b06da89f07535aac1045029e887a4ab789f1ea3..5a245ebdb1fa15ec3e83baf59e775c09f15e03f8 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index b5ea70f48433288c701a4b41ced4be038f43090a..69e2296a7c71bdb4d08d91f247705771ebcda5f6 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
 #include "../elems/basics/button.h"
 #include "../elems/basics/input.h"
 #include "bpmInput.h"
-#include "gd_mainWindow.h"
+#include "mainWindow.h"
 
 
-extern gdMainWindow *mainWin;
+extern gdMainWindowmainWin;
 
 
 using std::vector;
 using std::string;
-using namespace giada::m;
+using namespace giada;
 
 
 gdBpmInput::gdBpmInput(const char* label)
 : gdWindow(144, 36, "Bpm")
 {
-       if (conf::bpmX)
-               resize(conf::bpmX, conf::bpmY, w(), h());
+       if (m::conf::bpmX)
+               resize(m::conf::bpmX, m::conf::bpmY, w(), h());
 
        set_modal();
 
        input_a = new geInput(8,  8, 30, G_GUI_UNIT);
        input_b = new geInput(42, 8, 20, G_GUI_UNIT);
-       ok                = new geButton(66, 8, 70, G_GUI_UNIT, "Ok");
+       ok              = new geButton(66, 8, 70, G_GUI_UNIT, "Ok");
        end();
 
        input_a->maximum_size(3);
        input_a->type(FL_INT_INPUT);
-       input_a->value(gu_fToString(clock::getBpm(), 0).c_str());
+       input_a->value(u::string::fToString(m::clock::getBpm(), 0).c_str());
 
        /* Use the decimal value from the string label. */
 
-       vector<string> tokens;
-       gu_split(label, ".", &tokens);
+       vector<string> tokens = u::string::split(label, ".");
+       
        input_b->maximum_size(1);
        input_b->type(FL_INT_INPUT);
        input_b->value(tokens[1].c_str());
@@ -75,7 +75,7 @@ gdBpmInput::gdBpmInput(const char* label)
        ok->shortcut(FL_Enter);
        ok->callback(cb_update, (void*)this);
 
-       gu_setFavicon(this);
+       u::gui::setFavicon(this);
        setId(WID_BPM);
        show();
 }
@@ -86,8 +86,8 @@ gdBpmInput::gdBpmInput(const char* label)
 
 gdBpmInput::~gdBpmInput()
 {
-       conf::bpmX = x();
-       conf::bpmY = y();
+       m::conf::bpmX = x();
+       m::conf::bpmY = y();
 }
 
 
@@ -104,6 +104,6 @@ void gdBpmInput::cb_update()
 {
        if (strcmp(input_a->value(), "") == 0)
                return;
-       glue_setBpm(input_a->value(), input_b->value());
+       c::main::setBpm(input_a->value(), input_b->value());
        do_callback();
 }
index 492ae35d059649533ac2b30f975d1bd5988b1d30..954323d62e28bf0b77e1e987e03d53918f4ebcf5 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index b0b05b528e4a2562fbc361400d8e58d459167eb0..d97bd047f4c5d39822883c19029774a5b98d13ef 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -39,6 +39,7 @@
 
 
 using std::string;
+using namespace giada;
 using namespace giada::m;
 
 
@@ -85,7 +86,7 @@ gdBrowserBase::gdBrowserBase(int x, int y, int w, int h, const string& title,
        resizable(browser);
        size_range(320, 200);
 
-       gu_setFavicon(this);
+       u::gui::setFavicon(this);
        show();
 }
 
index 883afdfd50f2cec62613003bb5badde98c52966b..458706c2c1df58ef64c802c7cfb1e5c89ea58237 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index daddec9b79d653af2eeac2628c8a01745257e979..ebf8d077db919760c7d8dc00c485eaebf2f7d165 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 18f34b24f325118801dad6405c0e77b984a69441..c65ff24c6ddcb12c5f714ad9e6d05bda9bd421f0 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index a46c42e22eb775978d36c8d046ef3b652bc17d8b..2664dbd84b3ed282215c553e9223d722792b633d 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 9ef7d1823ad7ae38a9611005dfd623ef170dc750..10f085c9497a1f164384e2ce1a383dc31d020cb0 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 018b81b065ec81dfef58cfdd0cef08a762cac6e5..1c39c4bf7b9f94b205893dc1bea3b8022280c540 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 867089c2c7ad0df29a0def9cdcbdf16042875629..e88f5bf94ac970299d37a859bcf3b9ba76907bbd 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index bca1a3556ad6262c22e6fcd920bf464dae9d2cca..aef4d8c0184f3bd6e1e32f437bc55598d249e8b2 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -61,7 +61,7 @@ gdChannelNameInput::gdChannelNameInput(m::Channel* ch)
 
        m_cancel->callback(cb_cancel, (void*)this);
 
-       gu_setFavicon(this);
+       u::gui::setFavicon(this);
        setId(WID_SAMPLE_NAME);
        show();
 }
index 8f3214715830f40b6cc7acd3b1d2c2a09f016f9f..00bdf0ebfdd9505319780640f7269604e7e545f3 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/dialogs/config.cpp b/src/gui/dialogs/config.cpp
new file mode 100644 (file)
index 0000000..90afcb2
--- /dev/null
@@ -0,0 +1,131 @@
+/* -----------------------------------------------------------------------------
+ *
+ * Giada - Your Hardcore Loopmachine
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
+ *
+ * This file is part of Giada - Your Hardcore Loopmachine.
+ *
+ * Giada - Your Hardcore Loopmachine 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.
+ *
+ * Giada - Your Hardcore Loopmachine 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 Giada - Your Hardcore Loopmachine. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * -------------------------------------------------------------------------- */
+
+
+#include <FL/Fl_Tabs.H>
+#include "../../core/conf.h"
+#include "../../core/const.h"
+#include "../../utils/gui.h"
+#include "../elems/basics/boxtypes.h"
+#include "../elems/basics/button.h"
+#include "../elems/config/tabMisc.h"
+#include "../elems/config/tabMidi.h"
+#include "../elems/config/tabAudio.h"
+#include "../elems/config/tabBehaviors.h"
+#include "../elems/config/tabPlugins.h"
+#include "config.h"
+
+
+using namespace giada;
+using namespace giada::m;
+
+
+gdConfig::gdConfig(int w, int h) : gdWindow(w, h, "Configuration")
+{
+       if (conf::configX)
+               resize(conf::configX, conf::configY, this->w(), this->h());
+
+       Fl_Tabs* tabs = new Fl_Tabs(8, 8, w-16, h-44);
+  tabs->box(G_CUSTOM_BORDER_BOX);
+  tabs->labelcolor(G_COLOR_LIGHT_2);
+  tabs->begin();
+
+               tabAudio     = new geTabAudio(tabs->x()+10, tabs->y()+20, tabs->w()-20, tabs->h()-40);
+               tabMidi      = new geTabMidi(tabs->x()+10, tabs->y()+20, tabs->w()-20, tabs->h()-40);
+               tabBehaviors = new geTabBehaviors(tabs->x()+10, tabs->y()+20, tabs->w()-20, tabs->h()-40);
+               tabMisc      = new geTabMisc(tabs->x()+10, tabs->y()+20, tabs->w()-20, tabs->h()-40);
+#ifdef WITH_VST
+               tabPlugins   = new geTabPlugins(tabs->x()+10, tabs->y()+20, tabs->w()-20, tabs->h()-40);
+#endif
+
+       tabs->end();
+
+       save     = new geButton (w-88, h-28, 80, 20, "Save");
+       cancel = new geButton (w-176, h-28, 80, 20, "Cancel");
+
+       end();
+
+       save->callback(cb_save_config, (void*)this);
+       cancel->callback(cb_cancel, (void*)this);
+
+       u::gui::setFavicon(this);
+       setId(WID_CONFIG);
+       show();
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+gdConfig::~gdConfig()
+{
+       conf::configX = x();
+       conf::configY = y();
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+void gdConfig::cb_save_config(Fl_Widget* w, void* p) { ((gdConfig*)p)->cb_save_config(); }
+void gdConfig::cb_cancel     (Fl_Widget* w, void* p) { ((gdConfig*)p)->cb_cancel(); }
+
+
+/* -------------------------------------------------------------------------- */
+
+
+void gdConfig::cb_save_config()
+{
+       tabAudio->save();
+       tabBehaviors->save();
+       tabMidi->save();
+       tabMisc->save();
+#ifdef WITH_VST
+       tabPlugins->save();
+#endif
+       do_callback();
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+void gdConfig::cb_cancel()
+{
+       do_callback();
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+#ifdef WITH_VST
+
+void gdConfig::refreshVstPath()
+{
+       tabPlugins->refreshVstPath();
+}
+
+#endif
\ No newline at end of file
diff --git a/src/gui/dialogs/config.h b/src/gui/dialogs/config.h
new file mode 100644 (file)
index 0000000..cae3300
--- /dev/null
@@ -0,0 +1,80 @@
+/* -----------------------------------------------------------------------------
+ *
+ * Giada - Your Hardcore Loopmachine
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
+ *
+ * This file is part of Giada - Your Hardcore Loopmachine.
+ *
+ * Giada - Your Hardcore Loopmachine 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.
+ *
+ * Giada - Your Hardcore Loopmachine 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 Giada - Your Hardcore Loopmachine. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * -------------------------------------------------------------------------- */
+
+
+#ifndef GD_CONFIG_H
+#define GD_CONFIG_H
+
+
+#include "window.h"
+
+
+class geTabAudio;
+class geTabBehaviors;
+class geTabMidi;
+class geTabMisc;
+#ifdef WITH_VST
+class geTabPlugins;
+#endif
+class geButton;
+class geChoice;
+class geCheck;
+class geInput;
+class geRadio;
+class geBox;
+
+
+class gdConfig : public gdWindow
+{
+private:
+
+       static void cb_save_config(Fl_Widget* w, void* p);
+       static void cb_cancel(Fl_Widget* w, void* p);
+       void cb_save_config();
+       void cb_cancel();
+
+public:
+
+       geTabAudio* tabAudio;
+       geTabBehaviors* tabBehaviors;
+       geTabMidi* tabMidi;
+       geTabMisc* tabMisc;
+#ifdef WITH_VST
+       geTabPlugins* tabPlugins;
+#endif
+       geButton* save;
+       geButton* cancel;
+
+       gdConfig(int w, int h);
+       ~gdConfig();
+
+#ifdef WITH_VST
+       void refreshVstPath();
+#endif
+};
+
+
+#endif
diff --git a/src/gui/dialogs/devInfo.cpp b/src/gui/dialogs/devInfo.cpp
new file mode 100644 (file)
index 0000000..8a34abf
--- /dev/null
@@ -0,0 +1,86 @@
+/* -----------------------------------------------------------------------------
+ *
+ * Giada - Your Hardcore Loopmachine
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
+ *
+ * This file is part of Giada - Your Hardcore Loopmachine.
+ *
+ * Giada - Your Hardcore Loopmachine 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.
+ *
+ * Giada - Your Hardcore Loopmachine 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 Giada - Your Hardcore Loopmachine. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * -------------------------------------------------------------------------- */
+
+
+#include <FL/fl_draw.H>
+#include "../../core/kernelAudio.h"
+#include "../../utils/gui.h"
+#include "../../utils/string.h"
+#include "../elems/basics/button.h"
+#include "../elems/basics/box.h"
+#include "window.h"
+#include "devInfo.h"
+
+
+using std::string;
+using namespace giada;
+
+
+gdDevInfo::gdDevInfo(unsigned dev)
+       : Fl_Window(340, 300, "Device information")
+{
+       set_modal();
+
+       text  = new geBox(8, 8, 320, 200, "", (Fl_Align) (FL_ALIGN_LEFT | FL_ALIGN_TOP));
+       close = new geButton(252, h()-28, 80, 20, "Close");
+       end();
+
+       string body  = "";
+       int    lines = 7;
+
+       body  = "Device name: " + m::kernelAudio::getDeviceName(dev) + "\n";
+       body += "Total output(s): " + u::string::iToString(m::kernelAudio::getMaxOutChans(dev)) + "\n";
+       body += "Total intput(s): " + u::string::iToString(m::kernelAudio::getMaxInChans(dev)) + "\n";
+       body += "Duplex channel(s): " + u::string::iToString(m::kernelAudio::getDuplexChans(dev)) + "\n";
+       body += "Default output: " + string(m::kernelAudio::isDefaultOut(dev) ? "yes" : "no") + "\n";
+       body += "Default input: " + string(m::kernelAudio::isDefaultIn(dev) ? "yes" : "no") + "\n";
+
+       int totalFreq = m::kernelAudio::getTotalFreqs(dev);
+       body += "Supported frequencies: " + u::string::iToString(totalFreq);
+
+       for (int i=0; i<totalFreq; i++) {
+               if (i % 6 == 0) {
+                       body += "\n    ";  // add new line each 6 printed freqs AND on the first line (i % 0 != 0)
+                       lines++;
+               }
+               body += u::string::iToString(m::kernelAudio::getFreq(dev, i)) + "  ";
+       }
+
+       text->copy_label(body.c_str());
+
+       /* resize the window to fit the content. fl_height() returns the height
+        * of a line. fl_height() * total lines + margins + button size */
+
+       resize(x(), y(), w(), (lines * fl_height()) + 8 + 8 + 8 + 20);
+       close->position(close->x(), (lines * fl_height()) + 8 + 8);
+
+       close->callback(__cb_window_closer, (void*)this);
+       u::gui::setFavicon(this);
+       show();
+}
+
+
+gdDevInfo::~gdDevInfo() {}
diff --git a/src/gui/dialogs/devInfo.h b/src/gui/dialogs/devInfo.h
new file mode 100644 (file)
index 0000000..3861967
--- /dev/null
@@ -0,0 +1,52 @@
+/* -----------------------------------------------------------------------------
+ *
+ * Giada - Your Hardcore Loopmachine
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
+ *
+ * This file is part of Giada - Your Hardcore Loopmachine.
+ *
+ * Giada - Your Hardcore Loopmachine 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.
+ *
+ * Giada - Your Hardcore Loopmachine 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 Giada - Your Hardcore Loopmachine. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * -------------------------------------------------------------------------- */
+
+
+#ifndef GD_DEV_INFO_H
+#define GD_DEV_INFO_H
+
+
+#include <FL/Fl_Window.H>
+
+
+class geBox;
+class geButton;
+
+
+class gdDevInfo : public Fl_Window
+{
+private:
+
+       geBox            *text;
+       geButton *close;
+
+public:
+
+       gdDevInfo(unsigned dev);
+       ~gdDevInfo();
+};
+
+#endif
diff --git a/src/gui/dialogs/gd_config.cpp b/src/gui/dialogs/gd_config.cpp
deleted file mode 100644 (file)
index ce4ee29..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/* -----------------------------------------------------------------------------
- *
- * Giada - Your Hardcore Loopmachine
- *
- * -----------------------------------------------------------------------------
- *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
- *
- * This file is part of Giada - Your Hardcore Loopmachine.
- *
- * Giada - Your Hardcore Loopmachine 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.
- *
- * Giada - Your Hardcore Loopmachine 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 Giada - Your Hardcore Loopmachine. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * -------------------------------------------------------------------------- */
-
-
-#include <FL/Fl_Tabs.H>
-#include "../../core/conf.h"
-#include "../../core/const.h"
-#include "../../utils/gui.h"
-#include "../elems/basics/boxtypes.h"
-#include "../elems/basics/button.h"
-#include "../elems/config/tabMisc.h"
-#include "../elems/config/tabMidi.h"
-#include "../elems/config/tabAudio.h"
-#include "../elems/config/tabBehaviors.h"
-#include "../elems/config/tabPlugins.h"
-#include "gd_config.h"
-
-
-using namespace giada::m;
-
-
-gdConfig::gdConfig(int w, int h) : gdWindow(w, h, "Configuration")
-{
-       if (conf::configX)
-               resize(conf::configX, conf::configY, this->w(), this->h());
-
-       Fl_Tabs* tabs = new Fl_Tabs(8, 8, w-16, h-44);
-  tabs->box(G_CUSTOM_BORDER_BOX);
-  tabs->labelcolor(G_COLOR_LIGHT_2);
-  tabs->begin();
-
-               tabAudio     = new geTabAudio(tabs->x()+10, tabs->y()+20, tabs->w()-20, tabs->h()-40);
-               tabMidi      = new geTabMidi(tabs->x()+10, tabs->y()+20, tabs->w()-20, tabs->h()-40);
-               tabBehaviors = new geTabBehaviors(tabs->x()+10, tabs->y()+20, tabs->w()-20, tabs->h()-40);
-               tabMisc      = new geTabMisc(tabs->x()+10, tabs->y()+20, tabs->w()-20, tabs->h()-40);
-#ifdef WITH_VST
-               tabPlugins   = new geTabPlugins(tabs->x()+10, tabs->y()+20, tabs->w()-20, tabs->h()-40);
-#endif
-
-       tabs->end();
-
-       save     = new geButton (w-88, h-28, 80, 20, "Save");
-       cancel = new geButton (w-176, h-28, 80, 20, "Cancel");
-
-       end();
-
-       save->callback(cb_save_config, (void*)this);
-       cancel->callback(cb_cancel, (void*)this);
-
-       gu_setFavicon(this);
-       setId(WID_CONFIG);
-       show();
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
-gdConfig::~gdConfig()
-{
-       conf::configX = x();
-       conf::configY = y();
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
-void gdConfig::cb_save_config(Fl_Widget* w, void* p) { ((gdConfig*)p)->cb_save_config(); }
-void gdConfig::cb_cancel     (Fl_Widget* w, void* p) { ((gdConfig*)p)->cb_cancel(); }
-
-
-/* -------------------------------------------------------------------------- */
-
-
-void gdConfig::cb_save_config()
-{
-       tabAudio->save();
-       tabBehaviors->save();
-       tabMidi->save();
-       tabMisc->save();
-#ifdef WITH_VST
-       tabPlugins->save();
-#endif
-       do_callback();
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
-void gdConfig::cb_cancel()
-{
-       do_callback();
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-#ifdef WITH_VST
-
-void gdConfig::refreshVstPath()
-{
-       tabPlugins->refreshVstPath();
-}
-
-#endif
\ No newline at end of file
diff --git a/src/gui/dialogs/gd_config.h b/src/gui/dialogs/gd_config.h
deleted file mode 100644 (file)
index 989f560..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/* -----------------------------------------------------------------------------
- *
- * Giada - Your Hardcore Loopmachine
- *
- * -----------------------------------------------------------------------------
- *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
- *
- * This file is part of Giada - Your Hardcore Loopmachine.
- *
- * Giada - Your Hardcore Loopmachine 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.
- *
- * Giada - Your Hardcore Loopmachine 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 Giada - Your Hardcore Loopmachine. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * -------------------------------------------------------------------------- */
-
-
-#ifndef GD_CONFIG_H
-#define GD_CONFIG_H
-
-
-#include "window.h"
-
-
-class geTabAudio;
-class geTabBehaviors;
-class geTabMidi;
-class geTabMisc;
-#ifdef WITH_VST
-class geTabPlugins;
-#endif
-class geButton;
-class geChoice;
-class geCheck;
-class geInput;
-class geRadio;
-class geBox;
-
-
-class gdConfig : public gdWindow
-{
-private:
-
-       static void cb_save_config(Fl_Widget* w, void* p);
-       static void cb_cancel(Fl_Widget* w, void* p);
-       void cb_save_config();
-       void cb_cancel();
-
-public:
-
-       geTabAudio* tabAudio;
-       geTabBehaviors* tabBehaviors;
-       geTabMidi* tabMidi;
-       geTabMisc* tabMisc;
-#ifdef WITH_VST
-       geTabPlugins* tabPlugins;
-#endif
-       geButton* save;
-       geButton* cancel;
-
-       gdConfig(int w, int h);
-       ~gdConfig();
-
-#ifdef WITH_VST
-       void refreshVstPath();
-#endif
-};
-
-
-#endif
diff --git a/src/gui/dialogs/gd_devInfo.cpp b/src/gui/dialogs/gd_devInfo.cpp
deleted file mode 100644 (file)
index 2521274..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/* -----------------------------------------------------------------------------
- *
- * Giada - Your Hardcore Loopmachine
- *
- * -----------------------------------------------------------------------------
- *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
- *
- * This file is part of Giada - Your Hardcore Loopmachine.
- *
- * Giada - Your Hardcore Loopmachine 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.
- *
- * Giada - Your Hardcore Loopmachine 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 Giada - Your Hardcore Loopmachine. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * -------------------------------------------------------------------------- */
-
-
-#include <FL/fl_draw.H>
-#include "../../core/kernelAudio.h"
-#include "../../utils/gui.h"
-#include "../../utils/string.h"
-#include "../elems/basics/button.h"
-#include "../elems/basics/box.h"
-#include "window.h"
-#include "gd_devInfo.h"
-
-
-using std::string;
-using namespace giada::m;
-
-
-gdDevInfo::gdDevInfo(unsigned dev)
-       : Fl_Window(340, 300, "Device information")
-{
-       set_modal();
-
-       text  = new geBox(8, 8, 320, 200, "", (Fl_Align) (FL_ALIGN_LEFT | FL_ALIGN_TOP));
-       close = new geButton(252, h()-28, 80, 20, "Close");
-       end();
-
-       string body  = "";
-       int    lines = 7;
-
-       body  = "Device name: " + kernelAudio::getDeviceName(dev) + "\n";
-       body += "Total output(s): " + gu_iToString(kernelAudio::getMaxOutChans(dev)) + "\n";
-       body += "Total intput(s): " + gu_iToString(kernelAudio::getMaxInChans(dev)) + "\n";
-       body += "Duplex channel(s): " + gu_iToString(kernelAudio::getDuplexChans(dev)) + "\n";
-       body += "Default output: " + string(kernelAudio::isDefaultOut(dev) ? "yes" : "no") + "\n";
-       body += "Default input: " + string(kernelAudio::isDefaultIn(dev) ? "yes" : "no") + "\n";
-
-       int totalFreq = kernelAudio::getTotalFreqs(dev);
-       body += "Supported frequencies: " + gu_iToString(totalFreq);
-
-       for (int i=0; i<totalFreq; i++) {
-               if (i % 6 == 0) {
-                       body += "\n    ";  // add new line each 6 printed freqs AND on the first line (i % 0 != 0)
-                       lines++;
-               }
-               body += gu_iToString( kernelAudio::getFreq(dev, i)) + "  ";
-       }
-
-       text->copy_label(body.c_str());
-
-       /* resize the window to fit the content. fl_height() returns the height
-        * of a line. fl_height() * total lines + margins + button size */
-
-       resize(x(), y(), w(), (lines * fl_height()) + 8 + 8 + 8 + 20);
-       close->position(close->x(), (lines * fl_height()) + 8 + 8);
-
-       close->callback(__cb_window_closer, (void*)this);
-       gu_setFavicon(this);
-       show();
-}
-
-
-gdDevInfo::~gdDevInfo() {}
diff --git a/src/gui/dialogs/gd_devInfo.h b/src/gui/dialogs/gd_devInfo.h
deleted file mode 100644 (file)
index e65deea..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/* -----------------------------------------------------------------------------
- *
- * Giada - Your Hardcore Loopmachine
- *
- * -----------------------------------------------------------------------------
- *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
- *
- * This file is part of Giada - Your Hardcore Loopmachine.
- *
- * Giada - Your Hardcore Loopmachine 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.
- *
- * Giada - Your Hardcore Loopmachine 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 Giada - Your Hardcore Loopmachine. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * -------------------------------------------------------------------------- */
-
-
-#ifndef GD_DEV_INFO_H
-#define GD_DEV_INFO_H
-
-
-#include <FL/Fl_Window.H>
-
-
-class geBox;
-class geButton;
-
-
-class gdDevInfo : public Fl_Window
-{
-private:
-
-       geBox            *text;
-       geButton *close;
-
-public:
-
-       gdDevInfo(unsigned dev);
-       ~gdDevInfo();
-};
-
-#endif
diff --git a/src/gui/dialogs/gd_keyGrabber.cpp b/src/gui/dialogs/gd_keyGrabber.cpp
deleted file mode 100644 (file)
index 418eb50..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/* -----------------------------------------------------------------------------
- *
- * Giada - Your Hardcore Loopmachine
- *
- * -----------------------------------------------------------------------------
- *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
- *
- * This file is part of Giada - Your Hardcore Loopmachine.
- *
- * Giada - Your Hardcore Loopmachine 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.
- *
- * Giada - Your Hardcore Loopmachine 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 Giada - Your Hardcore Loopmachine. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * -------------------------------------------------------------------------- */
-
-
-#include "../../utils/gui.h"
-#include "../../utils/string.h"
-#include "../../core/conf.h"
-#include "../../core/channel.h"
-#include "../../core/sampleChannel.h"
-#include "../../core/midiChannel.h"
-#include "../../utils/log.h"
-#include "../elems/basics/box.h"
-#include "../elems/mainWindow/keyboard/keyboard.h"
-#include "../elems/mainWindow/keyboard/channel.h"
-#include "../elems/mainWindow/keyboard/channelButton.h"
-#include "gd_keyGrabber.h"
-#include "gd_config.h"
-#include "gd_mainWindow.h"
-
-
-extern gdMainWindow *mainWin;
-
-
-using std::string;
-using namespace giada;
-
-
-gdKeyGrabber::gdKeyGrabber(m::Channel* ch)
-       : gdWindow(300, 126, "Key configuration"), ch(ch)
-{
-       set_modal();
-       text   = new geBox(8, 8, 284, 80, "");
-       clear  = new geButton(w()-88, text->y()+text->h()+8, 80, 20, "Clear");
-       cancel = new geButton(clear->x()-88, clear->y(), 80, 20, "Close");
-       end();
-
-       clear->callback(cb_clear, (void*)this);
-       cancel->callback(cb_cancel, (void*)this);
-
-       updateText(ch->key);
-
-       gu_setFavicon(this);
-       show();
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
-void gdKeyGrabber::cb_clear (Fl_Widget* w, void* p) { ((gdKeyGrabber*)p)->cb_clear(); }
-void gdKeyGrabber::cb_cancel(Fl_Widget* w, void* p) { ((gdKeyGrabber*)p)->cb_cancel(); }
-
-
-/* -------------------------------------------------------------------------- */
-
-
-void gdKeyGrabber::cb_cancel()
-{
-       do_callback();
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
-void gdKeyGrabber::cb_clear()
-{
-       updateText(0);
-       setButtonLabel(0);
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
-void gdKeyGrabber::setButtonLabel(int key)
-{
-       ch->guiChannel->mainButton->setKey(key);
-       ch->key = key;
-}
-
-/* -------------------------------------------------------------------------- */
-
-
-void gdKeyGrabber::updateText(int key)
-{
-       string tmp = "Press a key.\n\nCurrent binding: ";
-       if (key != 0)
-               tmp += static_cast<char>(key);
-       else
-               tmp += "[none]";
-       text->copy_label(tmp.c_str());
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
-int gdKeyGrabber::handle(int e)
-{
-       int ret = Fl_Group::handle(e);
-       switch(e) {
-               case FL_KEYUP: {
-                       int x = Fl::event_key();
-                       if (strlen(Fl::event_text()) != 0
-                           && x != FL_BackSpace
-                           && x != FL_Enter
-                           && x != FL_Delete
-                           && x != FL_Tab
-                           && x != FL_End
-                           && x != ' ')
-                       {
-                               gu_log("set key '%c' (%d) for channel %d\n", x, x, ch->index);
-                               setButtonLabel(x);
-                               updateText(x);
-                               break;
-                       }
-                       else
-                               gu_log("invalid key\n");
-               }
-       }
-       return(ret);
-}
diff --git a/src/gui/dialogs/gd_keyGrabber.h b/src/gui/dialogs/gd_keyGrabber.h
deleted file mode 100644 (file)
index 92f2af1..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/* -----------------------------------------------------------------------------
- *
- * Giada - Your Hardcore Loopmachine
- *
- * -----------------------------------------------------------------------------
- *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
- *
- * This file is part of Giada - Your Hardcore Loopmachine.
- *
- * Giada - Your Hardcore Loopmachine 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.
- *
- * Giada - Your Hardcore Loopmachine 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 Giada - Your Hardcore Loopmachine. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * -------------------------------------------------------------------------- */
-
-
-#ifndef GD_KEYGRABBER_H
-#define GD_KEYGRABBER_H
-
-
-#include <FL/Fl.H>
-#include "window.h"
-
-
-class geBox;
-class geButton;
-
-
-class gdKeyGrabber : public gdWindow
-{
-private:
-
-       giada::m::Channel* ch;
-
-       geBox*    text;
-       geButton* clear;
-       geButton* cancel;
-
-       static void cb_clear (Fl_Widget* w, void* p);
-       static void cb_cancel(Fl_Widget* w, void* p);
-       void cb_clear ();
-       void cb_cancel();
-
-       void setButtonLabel(int key);
-       void updateText(int key);
-
-public:
-
-       gdKeyGrabber(giada::m::Channel* ch);
-       int handle(int e);
-};
-
-#endif
diff --git a/src/gui/dialogs/gd_mainWindow.cpp b/src/gui/dialogs/gd_mainWindow.cpp
deleted file mode 100644 (file)
index cab1399..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/* -----------------------------------------------------------------------------
- *
- * Giada - Your Hardcore Loopmachine
- *
- * -----------------------------------------------------------------------------
- *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
- *
- * This file is part of Giada - Your Hardcore Loopmachine.
- *
- * Giada - Your Hardcore Loopmachine 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.
- *
- * Giada - Your Hardcore Loopmachine 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 Giada - Your Hardcore Loopmachine. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * -------------------------------------------------------------------------- */
-
-
-#include <FL/Fl.H>
-#include "../../core/const.h"
-#include "../../core/conf.h"
-#include "../../core/init.h"
-#include "../../utils/gui.h"
-#include "../elems/basics/boxtypes.h"
-#include "../elems/mainWindow/mainIO.h"
-#include "../elems/mainWindow/mainMenu.h"
-#include "../elems/mainWindow/mainTimer.h"
-#include "../elems/mainWindow/mainTransport.h"
-#include "../elems/mainWindow/beatMeter.h"
-#include "../elems/mainWindow/keyboard/keyboard.h"
-#include "gd_warnings.h"
-#include "gd_mainWindow.h"
-
-
-extern gdMainWindow* G_MainWin;
-
-
-using namespace giada;
-
-
-gdMainWindow::gdMainWindow(int W, int H, const char* title, int argc, char** argv)
-       : gdWindow(W, H, title)
-{
-       Fl::visible_focus(0);
-
-       Fl::background(25, 25, 25);
-
-       Fl::set_boxtype(G_CUSTOM_BORDER_BOX, g_customBorderBox, 1, 1, 2, 2);
-       Fl::set_boxtype(G_CUSTOM_UP_BOX,     g_customUpBox,     1, 1, 2, 2);
-       Fl::set_boxtype(G_CUSTOM_DOWN_BOX,   g_customDownBox,   1, 1, 2, 2);
-
-       Fl::set_boxtype(FL_BORDER_BOX, G_CUSTOM_BORDER_BOX);
-       Fl::set_boxtype(FL_UP_BOX,     G_CUSTOM_UP_BOX);
-       Fl::set_boxtype(FL_DOWN_BOX,   G_CUSTOM_DOWN_BOX);
-
-       size_range(G_MIN_GUI_WIDTH, G_MIN_GUI_HEIGHT);
-
-       mainMenu      = new geMainMenu(8, -1);
-       mainIO        = new geMainIO(412, 8);
-       mainTransport = new geMainTransport(8, 39);
-       mainTimer     = new geMainTimer(628, 44);
-       beatMeter     = new geBeatMeter(100, 83, 609, 20);
-       keyboard      = new geKeyboard(8, 122, w()-16, 380);
-
-       /* zone 1 - menus, and I/O tools */
-
-       Fl_Group* zone1 = new Fl_Group(8, 8, W-16, 20);
-       zone1->add(mainMenu);
-       zone1->resizable(new Fl_Box(300, 8, 80, 20));
-       zone1->add(mainIO);
-
-       /* zone 2 - mainTransport and timing tools */
-
-       Fl_Group* zone2 = new Fl_Group(8, mainTransport->y(), W-16, mainTransport->h());
-       zone2->add(mainTransport);
-       zone2->resizable(new Fl_Box(mainTransport->x()+mainTransport->w()+4, zone2->y(), 80, 20));
-       zone2->add(mainTimer);
-
-       /* zone 3 - beat meter */
-
-       Fl_Group* zone3 = new Fl_Group(8, beatMeter->y(), W-16, beatMeter->h());
-       zone3->add(beatMeter);
-
-       /* zone 4 - the keyboard (Fl_Group is unnecessary here, keyboard is
-        * a group by itself) */
-
-       resizable(keyboard);
-
-       add(zone1);
-       add(zone2);
-       add(zone3);
-       add(keyboard);
-       callback(cb_endprogram);
-       gu_setFavicon(this);
-
-       show(argc, argv);
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
-void gdMainWindow::cb_endprogram(Fl_Widget* v, void* p) { G_MainWin->cb_endprogram(); }
-
-
-/* -------------------------------------------------------------------------- */
-
-
-void gdMainWindow::cb_endprogram()
-{
-       if (!gdConfirmWin("Warning", "Quit Giada: are you sure?"))
-               return;
-
-       m::conf::mainWindowX = x();
-       m::conf::mainWindowY = y();
-       m::conf::mainWindowW = w();
-       m::conf::mainWindowH = h();
-
-       hide();
-       delete this;
-}
diff --git a/src/gui/dialogs/gd_mainWindow.h b/src/gui/dialogs/gd_mainWindow.h
deleted file mode 100644 (file)
index 8d7616e..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/* -----------------------------------------------------------------------------
- *
- * Giada - Your Hardcore Loopmachine
- *
- * -----------------------------------------------------------------------------
- *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
- *
- * This file is part of Giada - Your Hardcore Loopmachine.
- *
- * Giada - Your Hardcore Loopmachine 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.
- *
- * Giada - Your Hardcore Loopmachine 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 Giada - Your Hardcore Loopmachine. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * -------------------------------------------------------------------------- */
-
-
-#ifndef GD_MAINWINDOW_H
-#define GD_MAINWINDOW_H
-
-
-#include "window.h"
-
-
-class Fl_Widget;
-class geKeyboard;
-class geBeatMeter;
-class geMainMenu;
-class geMainIO;
-class geMainTimer;
-class geMainTransport;
-
-
-class gdMainWindow : public gdWindow
-{
-private:
-
-       static void cb_endprogram(Fl_Widget* v, void* p);
-       inline void cb_endprogram();
-
-public:
-
-       geKeyboard* keyboard;
-       geBeatMeter* beatMeter;
-       geMainMenu* mainMenu;
-       geMainIO* mainIO;
-  geMainTimer* mainTimer;
-       geMainTransport* mainTransport;
-
-       gdMainWindow(int w, int h, const char* title, int argc, char** argv);
-};
-
-
-#endif
diff --git a/src/gui/dialogs/gd_warnings.cpp b/src/gui/dialogs/gd_warnings.cpp
deleted file mode 100644 (file)
index fc013f8..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/* -----------------------------------------------------------------------------
- *
- * Giada - Your Hardcore Loopmachine
- *
- * -----------------------------------------------------------------------------
- *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
- *
- * This file is part of Giada - Your Hardcore Loopmachine.
- *
- * Giada - Your Hardcore Loopmachine 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.
- *
- * Giada - Your Hardcore Loopmachine 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 Giada - Your Hardcore Loopmachine. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * -------------------------------------------------------------------------- */
-
-
-#include <FL/Fl.H>
-#include <FL/Fl_Window.H>
-#include "../../utils/gui.h"
-#include "../../core/const.h"
-#include "../elems/basics/button.h"
-#include "../elems/basics/box.h"
-#include "window.h"
-#include "gd_warnings.h"
-
-
-void gdAlert(const char *c)
-{
-       Fl_Window *modal = new Fl_Window(
-                       (Fl::w() / 2) - 150,
-                       (Fl::h() / 2) - 47,
-                       300, 90, "Alert");
-       modal->set_modal();
-       modal->begin();
-               geBox *box = new geBox(10, 10, 280, 40, c);
-               geButton *b = new geButton(210, 60, 80, 20, "Close");
-       modal->end();
-       box->labelsize(G_GUI_FONT_SIZE_BASE);
-       b->callback(__cb_window_closer, (void *)modal);
-       b->shortcut(FL_Enter);
-       gu_setFavicon(modal);
-       modal->show();
-}
-
-
-int gdConfirmWin(const char *title, const char *msg)
-{
-       Fl_Window *win = new Fl_Window(
-                       (Fl::w() / 2) - 150,
-                       (Fl::h() / 2) - 47,
-                       300, 90, title);
-       win->set_modal();
-       win->begin();
-               new geBox(10, 10, 280, 40, msg);
-               geButton *ok = new geButton(212, 62, 80, 20, "Ok");
-               geButton *ko = new geButton(124, 62, 80, 20, "Cancel");
-       win->end();
-       ok->shortcut(FL_Enter);
-       gu_setFavicon(win);
-       win->show();
-
-       /* no callbacks here. readqueue() check the event stack. */
-
-       int r = 0;
-       while (true) {
-               Fl_Widget *o = Fl::readqueue();
-               if (!o) Fl::wait();
-               else if (o == ok) {r = 1; break;}
-               else if (o == ko) {r = 0; break;}
-       }
-       //delete win;
-       win->hide();
-       return r;
-}
diff --git a/src/gui/dialogs/gd_warnings.h b/src/gui/dialogs/gd_warnings.h
deleted file mode 100644 (file)
index fb96a8a..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/* -----------------------------------------------------------------------------
- *
- * Giada - Your Hardcore Loopmachine
- *
- * -----------------------------------------------------------------------------
- *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
- *
- * This file is part of Giada - Your Hardcore Loopmachine.
- *
- * Giada - Your Hardcore Loopmachine 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.
- *
- * Giada - Your Hardcore Loopmachine 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 Giada - Your Hardcore Loopmachine. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * -------------------------------------------------------------------------- */
-
-
-#ifndef GD_WARNINGS_H
-#define GD_WARNINGS_H
-
-
-void gdAlert(const char *c);
-int  gdConfirmWin(const char *title, const char *msg);
-
-
-#endif
diff --git a/src/gui/dialogs/keyGrabber.cpp b/src/gui/dialogs/keyGrabber.cpp
new file mode 100644 (file)
index 0000000..2f1acd3
--- /dev/null
@@ -0,0 +1,146 @@
+/* -----------------------------------------------------------------------------
+ *
+ * Giada - Your Hardcore Loopmachine
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
+ *
+ * This file is part of Giada - Your Hardcore Loopmachine.
+ *
+ * Giada - Your Hardcore Loopmachine 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.
+ *
+ * Giada - Your Hardcore Loopmachine 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 Giada - Your Hardcore Loopmachine. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * -------------------------------------------------------------------------- */
+
+
+#include "../../utils/gui.h"
+#include "../../utils/string.h"
+#include "../../core/conf.h"
+#include "../../core/channel.h"
+#include "../../core/sampleChannel.h"
+#include "../../core/midiChannel.h"
+#include "../../utils/log.h"
+#include "../elems/basics/box.h"
+#include "../elems/mainWindow/keyboard/keyboard.h"
+#include "../elems/mainWindow/keyboard/channel.h"
+#include "../elems/mainWindow/keyboard/channelButton.h"
+#include "keyGrabber.h"
+#include "config.h"
+#include "mainWindow.h"
+
+
+extern gdMainWindow *mainWin;
+
+
+using std::string;
+using namespace giada;
+
+
+gdKeyGrabber::gdKeyGrabber(m::Channel* ch)
+       : gdWindow(300, 126, "Key configuration"), ch(ch)
+{
+       set_modal();
+       text   = new geBox(8, 8, 284, 80, "");
+       clear  = new geButton(w()-88, text->y()+text->h()+8, 80, 20, "Clear");
+       cancel = new geButton(clear->x()-88, clear->y(), 80, 20, "Close");
+       end();
+
+       clear->callback(cb_clear, (void*)this);
+       cancel->callback(cb_cancel, (void*)this);
+
+       updateText(ch->key);
+
+       u::gui::setFavicon(this);
+       show();
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+void gdKeyGrabber::cb_clear (Fl_Widget* w, void* p) { ((gdKeyGrabber*)p)->cb_clear(); }
+void gdKeyGrabber::cb_cancel(Fl_Widget* w, void* p) { ((gdKeyGrabber*)p)->cb_cancel(); }
+
+
+/* -------------------------------------------------------------------------- */
+
+
+void gdKeyGrabber::cb_cancel()
+{
+       do_callback();
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+void gdKeyGrabber::cb_clear()
+{
+       updateText(0);
+       setButtonLabel(0);
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+void gdKeyGrabber::setButtonLabel(int key)
+{
+       ch->guiChannel->mainButton->setKey(key);
+       ch->key = key;
+}
+
+/* -------------------------------------------------------------------------- */
+
+
+void gdKeyGrabber::updateText(int key)
+{
+       string tmp = "Press a key.\n\nCurrent binding: ";
+       if (key != 0)
+               tmp += static_cast<char>(key);
+       else
+               tmp += "[none]";
+       text->copy_label(tmp.c_str());
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+int gdKeyGrabber::handle(int e)
+{
+       int ret = Fl_Group::handle(e);
+       switch(e) {
+               case FL_KEYUP: {
+                       int x = Fl::event_key();
+                       if (strlen(Fl::event_text()) != 0
+                           && x != FL_BackSpace
+                           && x != FL_Enter
+                           && x != FL_Delete
+                           && x != FL_Tab
+                           && x != FL_End
+                           && x != ' ')
+                       {
+                               gu_log("set key '%c' (%d) for channel %d\n", x, x, ch->index);
+                               setButtonLabel(x);
+                               updateText(x);
+                               break;
+                       }
+                       else
+                               gu_log("invalid key\n");
+               }
+       }
+       return(ret);
+}
diff --git a/src/gui/dialogs/keyGrabber.h b/src/gui/dialogs/keyGrabber.h
new file mode 100644 (file)
index 0000000..24c27b7
--- /dev/null
@@ -0,0 +1,64 @@
+/* -----------------------------------------------------------------------------
+ *
+ * Giada - Your Hardcore Loopmachine
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
+ *
+ * This file is part of Giada - Your Hardcore Loopmachine.
+ *
+ * Giada - Your Hardcore Loopmachine 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.
+ *
+ * Giada - Your Hardcore Loopmachine 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 Giada - Your Hardcore Loopmachine. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * -------------------------------------------------------------------------- */
+
+
+#ifndef GD_KEYGRABBER_H
+#define GD_KEYGRABBER_H
+
+
+#include <FL/Fl.H>
+#include "window.h"
+
+
+class geBox;
+class geButton;
+
+
+class gdKeyGrabber : public gdWindow
+{
+private:
+
+       giada::m::Channel* ch;
+
+       geBox*    text;
+       geButton* clear;
+       geButton* cancel;
+
+       static void cb_clear (Fl_Widget* w, void* p);
+       static void cb_cancel(Fl_Widget* w, void* p);
+       void cb_clear ();
+       void cb_cancel();
+
+       void setButtonLabel(int key);
+       void updateText(int key);
+
+public:
+
+       gdKeyGrabber(giada::m::Channel* ch);
+       int handle(int e);
+};
+
+#endif
diff --git a/src/gui/dialogs/mainWindow.cpp b/src/gui/dialogs/mainWindow.cpp
new file mode 100644 (file)
index 0000000..45a2ca1
--- /dev/null
@@ -0,0 +1,120 @@
+/* -----------------------------------------------------------------------------
+ *
+ * Giada - Your Hardcore Loopmachine
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
+ *
+ * This file is part of Giada - Your Hardcore Loopmachine.
+ *
+ * Giada - Your Hardcore Loopmachine 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.
+ *
+ * Giada - Your Hardcore Loopmachine 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 Giada - Your Hardcore Loopmachine. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * -------------------------------------------------------------------------- */
+
+
+#include <FL/Fl.H>
+#include "../../core/const.h"
+#include "../../core/conf.h"
+#include "../../core/init.h"
+#include "../../utils/gui.h"
+#include "../elems/basics/boxtypes.h"
+#include "../elems/mainWindow/mainIO.h"
+#include "../elems/mainWindow/mainMenu.h"
+#include "../elems/mainWindow/mainTimer.h"
+#include "../elems/mainWindow/mainTransport.h"
+#include "../elems/mainWindow/beatMeter.h"
+#include "../elems/mainWindow/keyboard/keyboard.h"
+#include "warnings.h"
+#include "mainWindow.h"
+
+
+extern gdMainWindow* G_MainWin;
+
+
+using namespace giada;
+
+
+gdMainWindow::gdMainWindow(int W, int H, const char* title, int argc, char** argv)
+       : gdWindow(W, H, title)
+{
+       Fl::visible_focus(0);
+
+       Fl::background(25, 25, 25);
+
+       Fl::set_boxtype(G_CUSTOM_BORDER_BOX, g_customBorderBox, 1, 1, 2, 2);
+       Fl::set_boxtype(G_CUSTOM_UP_BOX,     g_customUpBox,     1, 1, 2, 2);
+       Fl::set_boxtype(G_CUSTOM_DOWN_BOX,   g_customDownBox,   1, 1, 2, 2);
+
+       Fl::set_boxtype(FL_BORDER_BOX, G_CUSTOM_BORDER_BOX);
+       Fl::set_boxtype(FL_UP_BOX,     G_CUSTOM_UP_BOX);
+       Fl::set_boxtype(FL_DOWN_BOX,   G_CUSTOM_DOWN_BOX);
+
+       size_range(G_MIN_GUI_WIDTH, G_MIN_GUI_HEIGHT);
+
+       mainMenu      = new v::geMainMenu(8, -1);
+       mainIO        = new v::geMainIO(412, 8);
+       mainTransport = new v::geMainTransport(8, 39);
+       mainTimer     = new v::geMainTimer(598, 44);
+       beatMeter     = new v::geBeatMeter(100, 83, 609, 20);
+       keyboard      = new v::geKeyboard(8, 122, w()-16, 380);
+
+       /* zone 1 - menus, and I/O tools */
+
+       Fl_Group* zone1 = new Fl_Group(8, 8, W-16, 20);
+       zone1->add(mainMenu);
+       zone1->resizable(new Fl_Box(300, 8, 80, 20));
+       zone1->add(mainIO);
+
+       /* zone 2 - mainTransport and timing tools */
+
+       Fl_Group* zone2 = new Fl_Group(8, mainTransport->y(), W-16, mainTransport->h());
+       zone2->add(mainTransport);
+       zone2->resizable(new Fl_Box(mainTransport->x()+mainTransport->w()+4, zone2->y(), 80, 20));
+       zone2->add(mainTimer);
+
+       /* zone 3 - beat meter */
+
+       Fl_Group* zone3 = new Fl_Group(8, beatMeter->y(), W-16, beatMeter->h());
+       zone3->add(beatMeter);
+
+       /* zone 4 - the keyboard (Fl_Group is unnecessary here, keyboard is
+        * a group by itself) */
+
+       resizable(keyboard);
+
+       add(zone1);
+       add(zone2);
+       add(zone3);
+       add(keyboard);
+       callback([](Fl_Widget* w, void* v) {
+               m::init::closeMainWindow();
+       });
+       u::gui::setFavicon(this);
+
+       show(argc, argv);
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+gdMainWindow::~gdMainWindow()
+{
+       m::conf::mainWindowX = x();
+       m::conf::mainWindowY = y();
+       m::conf::mainWindowW = w();
+       m::conf::mainWindowH = h();
+}
\ No newline at end of file
diff --git a/src/gui/dialogs/mainWindow.h b/src/gui/dialogs/mainWindow.h
new file mode 100644 (file)
index 0000000..30479ff
--- /dev/null
@@ -0,0 +1,66 @@
+/* -----------------------------------------------------------------------------
+ *
+ * Giada - Your Hardcore Loopmachine
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
+ *
+ * This file is part of Giada - Your Hardcore Loopmachine.
+ *
+ * Giada - Your Hardcore Loopmachine 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.
+ *
+ * Giada - Your Hardcore Loopmachine 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 Giada - Your Hardcore Loopmachine. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * -------------------------------------------------------------------------- */
+
+
+#ifndef GD_MAINWINDOW_H
+#define GD_MAINWINDOW_H
+
+
+#include "window.h"
+
+
+class Fl_Widget;
+
+
+namespace giada {
+namespace v 
+{
+class geKeyboard;
+class geMainIO;
+class geMainMenu;
+class geBeatMeter;
+class geMainTransport;
+class geMainTimer;
+}}
+
+
+class gdMainWindow : public gdWindow
+{
+public:
+
+       giada::v::geKeyboard* keyboard;
+       giada::v::geBeatMeter* beatMeter;
+       giada::v::geMainMenu* mainMenu;
+       giada::v::geMainIO* mainIO;
+       giada::v::geMainTimer* mainTimer;
+       giada::v::geMainTransport* mainTransport;
+
+    gdMainWindow(int w, int h, const char* title, int argc, char** argv);
+       ~gdMainWindow();
+};
+
+
+#endif
index d461166e7425e466734cd48665184988435d859d..495d65c1a4b86e583932f3645fee1d1b96002d16 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 646bc4462ef585dbe719e79058909ed92b62e68d..f750c8d707907316d3fad1494fa98f3f41dbe0d7 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 8656fdb4de617ce03040a8b4d5296144c91eb586..2d82e1897ea3c2bb6bd264424e39e8d6b57b1bc8 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -56,7 +56,7 @@ gdMidiInputChannel::gdMidiInputChannel(Channel* ch)
                        conf::midiInputH, "MIDI Input Setup"),
                ch(ch)
 {
-       string title = "MIDI Input Setup (channel " + gu_iToString(ch->index+1) + ")";
+       string title = "MIDI Input Setup (channel " + u::string::iToString(ch->index+1) + ")";
        label(title.c_str());
        size_range(G_DEFAULT_MIDI_INPUT_UI_W, G_DEFAULT_MIDI_INPUT_UI_H);
 
@@ -130,7 +130,7 @@ gdMidiInputChannel::gdMidiInputChannel(Channel* ch)
 
        end();
 
-       gu_setFavicon(this);
+       u::gui::setFavicon(this);
        set_modal();
        show();
 }
@@ -184,16 +184,16 @@ void gdMidiInputChannel::addChannelLearners()
 
 void gdMidiInputChannel::addPluginLearners()
 {
-       vector<Plugin*>* plugins = pluginHost::getStack(pluginHost::CHANNEL, ch);
-       for (unsigned i=0; i<plugins->size(); i++) {
+       vector<Plugin*> plugins = pluginHost::getStack(pluginHost::StackType::CHANNEL, ch);
+
+       int i = 0;
+       for (Plugin* plugin : plugins) {
 
                Fl_Pack* pack = new Fl_Pack(container->x() + ((i + 1) * (LEARNER_WIDTH + 8)),
                        container->y(), LEARNER_WIDTH, 200);
                pack->spacing(4);
                pack->begin();
 
-                       Plugin* plugin = plugins->at(i);
-
                        geBox* header = new geBox(0, 0, LEARNER_WIDTH, 20, plugin->getName().c_str());
                        header->box(FL_BORDER_BOX);
 
@@ -202,6 +202,8 @@ void gdMidiInputChannel::addPluginLearners()
                                        cb_learn, &plugin->midiInParams.at(k), ch);
 
                pack->end();
+
+               i++;
        }
 }
 
index 3a06680cf3c6799f70bde96d5236a5e45f284559..b9e95ea8c9d2db78b275e327f09cf793a0869088 100644 (file)
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index f583bcf072d7299e767ec1c6896b479c2d42dd8f..089d9665dd7965262acf78aa287f6e479a960cfe 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -36,6 +36,7 @@
 #include "midiInputMaster.h"
 
 
+using namespace giada;
 using namespace giada::m;
 
 
@@ -100,7 +101,7 @@ gdMidiInputMaster::gdMidiInputMaster()
        channel->value(conf::midiInFilter -1 ? 0 : conf::midiInFilter + 1);
        channel->callback(cb_setChannel, (void*)this);
 
-       gu_setFavicon(this);
+       u::gui::setFavicon(this);
        show();
 }
 
index 1a0bec65cfe5566a5c9826188bd4f9369d78de36..002925c65d867d1ae5cabce1ce49fa3d15016a03 100644 (file)
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index f6c3da046f0ebf09ace17ac616968b7f08ef8547..9ec2fcd99e8e388e96aeb261c02b82ec10ba1498 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -32,7 +32,7 @@
 
 
 using std::string;
-using namespace giada::m;
+using namespace giada;
 
 
 gdMidiOutputBase::gdMidiOutputBase(int w, int h)
@@ -46,7 +46,7 @@ gdMidiOutputBase::gdMidiOutputBase(int w, int h)
 
 void gdMidiOutputBase::stopMidiLearn(geMidiLearner *learner)
 {
-       midiDispatcher::stopMidiLearn();
+       m::midiDispatcher::stopMidiLearn();
        learner->updateValue();
 }
 
@@ -54,7 +54,7 @@ void gdMidiOutputBase::stopMidiLearn(geMidiLearner *learner)
 /* -------------------------------------------------------------------------- */
 
 
-void gdMidiOutputBase::__cb_learn(uint32_t *param, uint32_t msg, geMidiLearner *l)
+void gdMidiOutputBase::cb_learn(uint32_t* param, uint32_t msg, geMidiLearner* l)
 {
        *param = msg;
        stopMidiLearn(l);
@@ -67,24 +67,24 @@ void gdMidiOutputBase::__cb_learn(uint32_t *param, uint32_t msg, geMidiLearner *
 
 void gdMidiOutputBase::cb_learn(uint32_t msg, void *d)
 {
-       geMidiLearner::cbData_t *data = (geMidiLearner::cbData_t*) d;
-       gdMidiOutputBase  *window  = (gdMidiOutputBase*) data->window;
-       geMidiLearner *learner = data->learner;
-       uint32_t      *param   = learner->param;
-       window->__cb_learn(param, msg, learner);
+       geMidiLearner::cbData_t* data   = (geMidiLearner::cbData_t*) d;
+       gdMidiOutputBase*        window = (gdMidiOutputBase*) data->window;
+       geMidiLearnerlearner = data->learner;
+       uint32_t*      param   = learner->param;
+       window->cb_learn(param, msg, learner);
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void gdMidiOutputBase::cb_close(Fl_Widget *w, void *p)  { ((gdMidiOutputBase*)p)->__cb_close(); }
+void gdMidiOutputBase::cb_close(Fl_Widget* w, void* p)  { ((gdMidiOutputBase*)p)->cb_close(); }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void gdMidiOutputBase::__cb_close()
+void gdMidiOutputBase::cb_close()
 {
        do_callback();
 }
@@ -93,16 +93,16 @@ void gdMidiOutputBase::__cb_close()
 /* -------------------------------------------------------------------------- */
 
 
-void gdMidiOutputBase::cb_enableLightning(Fl_Widget *w, void *p)
+void gdMidiOutputBase::cb_enableLightning(Fl_Widget* w, void* p)
 {
-       ((gdMidiOutputBase*)p)->__cb_enableLightning();
+       ((gdMidiOutputBase*)p)->cb_enableLightning();
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void gdMidiOutputBase::__cb_enableLightning() {}
+void gdMidiOutputBase::cb_enableLightning() {}
 
 
 /* -------------------------------------------------------------------------- */
@@ -110,6 +110,6 @@ void gdMidiOutputBase::__cb_enableLightning() {}
 
 void gdMidiOutputBase::setTitle(int chanNum)
 {
-       string tmp = "MIDI Output Setup (channel " + gu_iToString(chanNum) + ")"; 
+       string tmp = "MIDI Output Setup (channel " + u::string::iToString(chanNum) + ")"; 
        copy_label(tmp.c_str());
 }
index 343aa8901668a987c9893f8e63daacd497778c20..abdd89d856ffb1e3d248eb346fa8498c55f28da6 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -52,28 +52,28 @@ class gdMidiOutputBase : public gdWindow
 {
 protected:
 
-       geButton *close;
-       geCheck   *enableLightning;
+       geButtonclose;
+       geCheck*  enableLightning;
 
-       void stopMidiLearn(geMidiLearner *l);
+       void stopMidiLearn(geMidiLearnerl);
 
        /* cb_learn
         * callback attached to kernelMidi to learn various actions. */
 
-       static void cb_learn  (uint32_t msg, void *data);
-       inline void __cb_learn(uint32_t *param, uint32_t msg, geMidiLearner *l);
+       static void cb_learn(uint32_t msg, void* data);
+       void cb_learn(uint32_t* param, uint32_t msg, geMidiLearner* l);
 
        /* cb_close
        close current window. */
 
-       static void cb_close  (Fl_Widget *w, void *p);
-       inline void __cb_close();
+       static void cb_close(Fl_Widget* w, void* p);
+       void cb_close();
 
        /* cb_enableLightning
        enable MIDI lightning output. */
 
-       static void cb_enableLightning  (Fl_Widget *w, void *p);
-       inline void __cb_enableLightning();
+       static void cb_enableLightning  (Fl_Widget* w, void* p);
+       void cb_enableLightning();
 
        /* setTitle
         * set window title. */
index 1e19ad2958c03fe6c121fb05c88bb926cdfb45fa..c4b0753bbd121eedd38cf2525e77049fb8890480 100644 (file)
@@ -5,7 +5,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -92,7 +92,7 @@ gdMidiOutputMidiCh::gdMidiOutputMidiCh(m::MidiChannel* ch)
        close->callback(cb_close, (void*)this);
 
        set_modal();
-       gu_setFavicon(this);
+       u::gui::setFavicon(this);
        show();
 }
 
index b1fb4d87c792cd9f877f8975320cb4ad90ddc0b3..a5bfd5a0c621b002eed1e0440a5e903e98cb7d46 100644 (file)
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index fdb21df2ce43b667163cfd75a9a1db18e25b9041..50f675f1645c1b50314677f2146edca3fb1c967c 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -56,7 +56,7 @@ gdMidiOutputSampleCh::gdMidiOutputSampleCh(m::SampleChannel* ch)
        enableLightning->callback(cb_enableLightning, (void*)this);
 
        set_modal();
-       gu_setFavicon(this);
+       u::gui::setFavicon(this);
        show();
 }
 
index fbd14eca1615699381bce2011206e892cc5428c2..dea121fde12df3a8872cc56583659720906621f3 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 361d735dd8a47d9d3dc958603add8d727889666f..f8dcb26e6064192a6d5c36c2e427422dabc3b6a2 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -32,6 +32,7 @@
 #include "../../utils/gui.h"
 #include "../../core/channel.h"
 #include "../../core/conf.h"
+#include "../../core/pluginManager.h"
 #include "../../core/pluginHost.h"
 #include "../elems/plugin/pluginBrowser.h"
 #include "../elems/basics/button.h"
 #include "pluginChooser.h"
 
 
+using namespace giada;
 using namespace giada::m;
 using namespace giada::c;
 
 
-gdPluginChooser::gdPluginChooser(int X, int Y, int W, int H, int stackType, Channel* ch)
-  : gdWindow(X, Y, W, H, "Available plugins"), ch(ch), stackType(stackType)
+gdPluginChooser::gdPluginChooser(int X, int Y, int W, int H, pluginHost::StackType t, Channel* ch)
+  : gdWindow(X, Y, W, H, "Available plugins"), ch(ch), stackType(t)
 {
   /* top area */
   Fl_Group *group_top = new Fl_Group(8, 8, w()-16, 20);
@@ -78,7 +80,7 @@ gdPluginChooser::gdPluginChooser(int X, int Y, int W, int H, int stackType, Chan
   cancelBtn->callback(cb_close, (void*) this);
 
   resizable(browser);
-       gu_setFavicon(this);
+       u::gui::setFavicon(this);
   show();
 }
 
@@ -118,7 +120,7 @@ void gdPluginChooser::cb_close()
 
 void gdPluginChooser::cb_sort()
 {
-       pluginHost::sortPlugins(sortMethod->value());
+       pluginManager::sortPlugins(static_cast<pluginManager::SortMethod>(sortMethod->value()));
   browser->refresh();
 }
 
index 53b3b14324c8df5031213a7cf246231fea9c61b3..d8bb3b2e63d6edcb47c00bcadb303ee333febf9f 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -47,7 +47,7 @@ class gdPluginChooser : public gdWindow
 private:
 
        giada::m::Channel* ch;      // ch == nullptr ? masterOut
-       int stackType;
+       giada::m::pluginHost::StackType stackType;
 
        geChoice*        sortMethod;
        geButton*        addBtn;
@@ -63,7 +63,8 @@ private:
 
 public:
 
-       gdPluginChooser(int x, int y, int w, int h, int stackType, giada::m::Channel* ch=nullptr);
+       gdPluginChooser(int x, int y, int w, int h, giada::m::pluginHost::StackType t, 
+               giada::m::Channel* ch=nullptr);
        ~gdPluginChooser();
 };
 
index b93e51d99d9249a940b5e478e2e565ed96fea02e..7353e28768f96a8376e2fadbd3a57bd6c4438c09 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -43,7 +43,7 @@
 #include "../elems/mainWindow/keyboard/channel.h"
 #include "../elems/plugin/pluginElement.h"
 #include "pluginChooser.h"
-#include "gd_mainWindow.h"
+#include "mainWindow.h"
 #include "pluginList.h"
 
 
@@ -54,8 +54,8 @@ using std::string;
 using namespace giada;
 
 
-gdPluginList::gdPluginList(int stackType, m::Channel* ch)
-       : gdWindow(468, 204), ch(ch), stackType(stackType)
+gdPluginList::gdPluginList(m::pluginHost::StackType t, m::Channel* ch)
+       : gdWindow(468, 204), ch(ch), stackType(t)
 {
        using namespace giada::m;
 
@@ -79,17 +79,17 @@ gdPluginList::gdPluginList(int stackType, m::Channel* ch)
        /* TODO - awful stuff... we should subclass into gdPluginListChannel and
        gdPluginListMaster */
 
-       if (stackType == pluginHost::MASTER_OUT)
+       if (stackType == pluginHost::StackType::MASTER_OUT)
                label("Master Out Plugins");
        else
-       if (stackType == pluginHost::MASTER_IN)
+       if (stackType == pluginHost::StackType::MASTER_IN)
                label("Master In Plugins");
        else {
-               string l = "Channel " + gu_iToString(ch->index+1) + " Plugins";
+               string l = "Channel " + u::string::iToString(ch->index+1) + " Plugins";
                copy_label(l.c_str());
        }
 
-       gu_setFavicon(this);
+       u::gui::setFavicon(this);
        show();
 }
 
@@ -199,11 +199,11 @@ void gdPluginList::refreshList()
        /* TODO - awful stuff... we should subclass into gdPluginListChannel and
        gdPluginListMaster */
 
-       if (stackType == pluginHost::MASTER_OUT) {
+       if (stackType == pluginHost::StackType::MASTER_OUT) {
                G_MainWin->mainIO->setMasterFxOutFull(pluginHost::countPlugins(stackType, ch) > 0);
        }
        else
-       if (stackType == pluginHost::MASTER_IN) {
+       if (stackType == pluginHost::StackType::MASTER_IN) {
                G_MainWin->mainIO->setMasterFxInFull(pluginHost::countPlugins(stackType, ch) > 0);
        }
        else {
index c3513bc4816f2be9414f235480a153298b963998..3b89961fb4b1936856c0d45f2bd41eddfd5cfcda 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -31,6 +31,7 @@
 #define GD_PLUGINLIST_H
 
 
+#include "../../core/pluginHost.h"
 #include "window.h"
 
 
@@ -51,9 +52,9 @@ private:
 public:
 
        giada::m::Channel* ch;      // ch == nullptr ? masterOut
-       int stackType;
+       giada::m::pluginHost::StackType stackType;
 
-       gdPluginList(int stackType, giada::m::Channel* ch=nullptr);
+       gdPluginList(giada::m::pluginHost::StackType t, giada::m::Channel* ch=nullptr);
        ~gdPluginList();
 
        /* special callback, passed to browser. When closed (i.e. plugin
index 8dfca8b6d7b7245bdc359ae2159ff90b73e7de3d..9c4ab8a0c89fa77a77ec91d6f11d572eccdc6b2e 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -66,7 +66,7 @@ gdPluginWindow::gdPluginWindow(m::Plugin* p)
        size_range(450, (G_GUI_UNIT + (G_GUI_OUTER_MARGIN*2)));
        resizable(m_list);
 
-       gu_setFavicon(this);
+       u::gui::setFavicon(this);
        show();
 }
 
index a34befec0cb5224cbff71407a161306d43a05079..dcd81bb8e4a6bc32848c518b20b2ccf950579529 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 0e64c3acaf64d8830a365d0fadc60df4bfcc1bd8..6eb8181a669a90bc276ef97f510ec6c7a783c057 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 8dd6779656652c9d1e6e0afdd3555728e63ea487..605e670aae753c1cdcdc7759b1832f37a5cf1134 100644 (file)
@@ -7,7 +7,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index b13ef70c5218f3d141528d025c325b601fb1db3c..8715da71a74f9df1925079787787f9654ca5683e 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -55,7 +55,7 @@
 #include "../elems/sampleEditor/rangeTool.h"
 #include "../elems/sampleEditor/shiftTool.h"
 #include "../elems/mainWindow/keyboard/channel.h"
-#include "gd_warnings.h"
+#include "warnings.h"
 #include "sampleEditor.h"
 
 
@@ -83,7 +83,7 @@ gdSampleEditor::gdSampleEditor(m::SampleChannel* ch)
 
   resizable(waveTools);
 
-  gu_setFavicon(this);
+  u::gui::setFavicon(this);
   set_non_modal();
   copy_label(ch->name.c_str());
 
@@ -141,7 +141,7 @@ Fl_Group* gdSampleEditor::createUpperBar()
   if (conf::sampleEditorGridVal == 0)
     grid->value(0);
   else 
-    grid->value(grid->find_item(gu_iToString(conf::sampleEditorGridVal).c_str()));
+    grid->value(grid->find_item(u::string::iToString(conf::sampleEditorGridVal).c_str()));
   grid->callback(cb_changeGrid, (void*)this);
 
   snap->value(conf::sampleEditorGridOn);
@@ -356,12 +356,12 @@ void gdSampleEditor::cb_changeGrid()
 
 void gdSampleEditor::updateInfo()
 {
-       string bitDepth = ch->wave->getBits() != 0 ? gu_iToString(ch->wave->getBits()) : "(unknown)";
+       string bitDepth = ch->wave->getBits() != 0 ? u::string::iToString(ch->wave->getBits()) : "(unknown)";
        string infoText = 
                "File: "  + ch->wave->getPath() + "\n"
-               "Size: " + gu_iToString(ch->wave->getSize()) + " frames\n"
-               "Duration: " + gu_iToString(ch->wave->getDuration()) + " seconds\n"
+               "Size: " + u::string::iToString(ch->wave->getSize()) + " frames\n"
+               "Duration: " + u::string::iToString(ch->wave->getDuration()) + " seconds\n"
                "Bit depth: " + bitDepth + "\n"
-               "Frequency: " + gu_iToString(ch->wave->getRate()) + " Hz\n";
+               "Frequency: " + u::string::iToString(ch->wave->getRate()) + " Hz\n";
        info->copy_label(infoText.c_str());
 }
index 0ab76e6794922aed93838b0643ea39d105aef77e..6373bd580620b405fb790258a1f8617bd7d431bd 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/dialogs/warnings.cpp b/src/gui/dialogs/warnings.cpp
new file mode 100644 (file)
index 0000000..204971e
--- /dev/null
@@ -0,0 +1,88 @@
+/* -----------------------------------------------------------------------------
+ *
+ * Giada - Your Hardcore Loopmachine
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
+ *
+ * This file is part of Giada - Your Hardcore Loopmachine.
+ *
+ * Giada - Your Hardcore Loopmachine 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.
+ *
+ * Giada - Your Hardcore Loopmachine 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 Giada - Your Hardcore Loopmachine. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * -------------------------------------------------------------------------- */
+
+
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include "../../utils/gui.h"
+#include "../../core/const.h"
+#include "../elems/basics/button.h"
+#include "../elems/basics/box.h"
+#include "window.h"
+#include "warnings.h"
+
+
+using namespace giada;
+
+
+void gdAlert(const char *c)
+{
+       Fl_Window *modal = new Fl_Window(
+                       (Fl::w() / 2) - 150,
+                       (Fl::h() / 2) - 47,
+                       300, 90, "Alert");
+       modal->set_modal();
+       modal->begin();
+               geBox *box = new geBox(10, 10, 280, 40, c);
+               geButton *b = new geButton(210, 60, 80, 20, "Close");
+       modal->end();
+       box->labelsize(G_GUI_FONT_SIZE_BASE);
+       b->callback(__cb_window_closer, (void *)modal);
+       b->shortcut(FL_Enter);
+       u::gui::setFavicon(modal);
+       modal->show();
+}
+
+
+int gdConfirmWin(const char *title, const char *msg)
+{
+       Fl_Window *win = new Fl_Window(
+                       (Fl::w() / 2) - 150,
+                       (Fl::h() / 2) - 47,
+                       300, 90, title);
+       win->set_modal();
+       win->begin();
+               new geBox(10, 10, 280, 40, msg);
+               geButton *ok = new geButton(212, 62, 80, 20, "Ok");
+               geButton *ko = new geButton(124, 62, 80, 20, "Cancel");
+       win->end();
+       ok->shortcut(FL_Enter);
+       u::gui::setFavicon(win);
+       win->show();
+
+       /* no callbacks here. readqueue() check the event stack. */
+
+       int r = 0;
+       while (true) {
+               Fl_Widget *o = Fl::readqueue();
+               if (!o) Fl::wait();
+               else if (o == ok) {r = 1; break;}
+               else if (o == ko) {r = 0; break;}
+       }
+       //delete win;
+       win->hide();
+       return r;
+}
diff --git a/src/gui/dialogs/warnings.h b/src/gui/dialogs/warnings.h
new file mode 100644 (file)
index 0000000..564db6f
--- /dev/null
@@ -0,0 +1,36 @@
+/* -----------------------------------------------------------------------------
+ *
+ * Giada - Your Hardcore Loopmachine
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
+ *
+ * This file is part of Giada - Your Hardcore Loopmachine.
+ *
+ * Giada - Your Hardcore Loopmachine 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.
+ *
+ * Giada - Your Hardcore Loopmachine 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 Giada - Your Hardcore Loopmachine. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * -------------------------------------------------------------------------- */
+
+
+#ifndef GD_WARNINGS_H
+#define GD_WARNINGS_H
+
+
+void gdAlert(const char *c);
+int  gdConfirmWin(const char *title, const char *msg);
+
+
+#endif
index a8c8ce0a21e139958d0e680d855b27f791fae725..ca5c914590781d0a8d24332a4d6b40fa8e58bd43 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 888e898fb71b2a7bdc9192269ce608372ccac06f..1b6044950805aacbac5d9dd0e9c440723bc6be0c 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/dispatcher.cpp b/src/gui/dispatcher.cpp
new file mode 100644 (file)
index 0000000..fae6992
--- /dev/null
@@ -0,0 +1,165 @@
+/* -----------------------------------------------------------------------------
+ *
+ * Giada - Your Hardcore Loopmachine
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
+ *
+ * This file is part of Giada - Your Hardcore Loopmachine.
+ *
+ * Giada - Your Hardcore Loopmachine 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.
+ *
+ * Giada - Your Hardcore Loopmachine 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 Giada - Your Hardcore Loopmachine. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * -------------------------------------------------------------------------- */
+
+
+#include <FL/Fl.H>
+#include "../core/init.h"
+#include "../core/const.h"
+#include "../core/mixer.h"
+#include "../core/channel.h"
+#include "../glue/transport.h"
+#include "../glue/io.h"
+#include "elems/mainWindow/keyboard/channel.h"
+#include "dispatcher.h"
+
+
+namespace giada {
+namespace v {
+namespace dispatcher
+{
+namespace
+{
+bool backspace_ = false;
+bool end_       = false;
+bool enter_     = false;
+bool space_     = false;
+bool esc_       = false;
+
+std::function<void()> signalCb_ = nullptr;
+
+
+/* -------------------------------------------------------------------------- */
+
+
+void perform_(m::Channel* ch, int event)
+{
+       if (event == FL_KEYDOWN)
+               c::io::keyPress(ch, Fl::event_ctrl(), Fl::event_shift(), G_MAX_VELOCITY);
+       else
+       if (event == FL_KEYUP)  
+               c::io::keyRelease(ch, Fl::event_ctrl(), Fl::event_shift());
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+/* Walk channels array, trying to match button's bound key with the event. If 
+found, trigger the key-press function. */
+
+void dispatchChannels_(int event)
+{
+       for (m::Channel* ch : m::mixer::channels)
+               if (ch->guiChannel->handleKey(event))
+                       perform_(ch, event);
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+void triggerSignalCb_()
+{
+       if (signalCb_ == nullptr) 
+               return;
+       signalCb_();
+       signalCb_ = nullptr;
+}
+} // {anonymous}
+
+
+/* -------------------------------------------------------------------------- */
+/* -------------------------------------------------------------------------- */
+/* -------------------------------------------------------------------------- */
+
+
+void dispatchKey(int event)
+{
+       /* These events come from the keyboard, not from a direct interaction on the 
+       UI with the mouse/touch. So the 'gui' parameter is set to false. */
+
+       const bool gui = false;
+
+       if (event == FL_KEYDOWN) {
+               if (Fl::event_key() == FL_BackSpace && !backspace_) {
+                       backspace_ = true;
+                       c::transport::rewindSeq(gui);
+               }
+               else if (Fl::event_key() == FL_End && !end_) {
+                       end_ = true;
+                       c::io::toggleInputRec(gui);
+               }
+               else if (Fl::event_key() == FL_Enter && !enter_) {
+                       enter_ = true;
+                       c::io::toggleActionRec(gui);
+               }
+               else if (Fl::event_key() == ' ' && !space_) {
+                       space_ = true;
+                       c::transport::startStopSeq(gui);
+               }
+               else if (Fl::event_key() == FL_Escape && !esc_) {
+                       esc_ = true;
+                       m::init::closeMainWindow();
+               }
+               else
+                       triggerSignalCb_();
+       }
+       else if (event == FL_KEYUP) {
+               if (Fl::event_key() == FL_BackSpace)
+                       backspace_ = false;
+               else if (Fl::event_key() == FL_End)
+                       end_ = false;
+               else if (Fl::event_key() == ' ')
+                       space_ = false;
+               else if (Fl::event_key() == FL_Enter)
+                       enter_ = false;
+               else if (Fl::event_key() == FL_Escape)
+                       esc_ = false;
+       }
+
+       dispatchChannels_(event);
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+void dispatchTouch(m::Channel* ch, bool status)
+{
+       triggerSignalCb_();
+       perform_(ch, status ? FL_KEYDOWN : FL_KEYUP);
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+void setSignalCallback(std::function<void()> f)
+{
+       signalCb_ = f;
+}
+
+}}} // giada::v::dispatcher
diff --git a/src/gui/dispatcher.h b/src/gui/dispatcher.h
new file mode 100644 (file)
index 0000000..580dc4e
--- /dev/null
@@ -0,0 +1,49 @@
+/* -----------------------------------------------------------------------------
+ *
+ * Giada - Your Hardcore Loopmachine
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
+ *
+ * This file is part of Giada - Your Hardcore Loopmachine.
+ *
+ * Giada - Your Hardcore Loopmachine 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.
+ *
+ * Giada - Your Hardcore Loopmachine 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 Giada - Your Hardcore Loopmachine. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * -------------------------------------------------------------------------- */
+
+
+#ifndef G_V_DISPATCHER_H
+#define G_V_DISPATCHER_H
+
+
+#include <functional>
+
+
+namespace giada {
+namespace m 
+{
+    class Channel;
+}
+namespace v {
+namespace dispatcher
+{
+void dispatchKey(int event);
+void dispatchTouch(m::Channel* ch, bool status);
+void setSignalCallback(std::function<void()> f);
+}}} // giada::v::dispatcher
+
+
+#endif
\ No newline at end of file
index 1283c7a35feb1ac883aefc4418a37e7ce9518f45..d62523b751b6b7d1c326a125aa774c49197e9c42 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index c3b4b1284db317df5ac3d0e615a04c59f2887784..1d77df43da64ea8f3e2da36de9ee98b9f966f4a8 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -37,7 +37,7 @@
 namespace giada {
 namespace m 
 {
-class Action;
+struct Action;
 }
 namespace v
 {
index 75c6d2240b3b7f093986150e9404a2f8c863a87d..c615ffc5c66863f7db16340dbfb3678a69544669 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index bcd3cfb57d74ffdc041dda29cdfb28d51c9d4f55..2db996c47c2834624220cba375066134c5954563 100644 (file)
@@ -5,7 +5,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index ff27f5bffaa990f79f616074bb98dbb2b92fba85..3f2e1314dc1aab32e482be3a30260d0ee9825af8 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index c8046df479cf206510442a1d80b1bbe7e7516c5d..192a4a1c3ca6f4ee3c8e631b04ffbde77cd9f204 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index a32965deaad2f989db5cf7fcf272a0f396e4f4c1..68e3ceca4dc4ce398896855ec5cb4a4621bbaf31 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 05f7bc3f27929cf549f4f276c1cd453324eb4ba0..3724fa72f794f30289e7969e9cd592006b7259ad 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 52cf3f1407b4af2b43df16687f9e7ceebd34f486..4c4b021e681037e8ecfedafd29f8e4068a1ab1a5 100644 (file)
@@ -4,7 +4,7 @@
 *
 * ------------------------------------------------------------------------------
 *
-* Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+* Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
 *
 * This file is part of Giada - Your Hardcore Loopmachine.
 *
index f86e3d90370e5791b201f0ac744587e97afa4cc1..90690c7760d8b2110c20249761baafc5e01e498b 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 4992af7ef998b22c4fdeedd54372cb8784a6f512..6f4b44f5dd789a523d338cf2b05fc0335d697e27 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 130e92578747c139676c4485de40c4991316289f..ffe57c806ec8ab760f114e7f14b1b4a02c81a093 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index d6082769326eca99e72378a982133233ce0a30d0..361e422ce2a68c1d20152086a40167211fb33290 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 6f84cc980b45d6ffeb9512dc0437758f3717ca5c..dd9d3f6fed378536ac69d912e22074ccc80d338f 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -35,7 +35,7 @@
 namespace giada {
 namespace m 
 {
-class Action;
+struct Action;
 }
 namespace v
 {
index f6291012d7ddd080ad2bb93cc6fae5f0f2f706c5..5bb6b316a78ba65a12bd112cf5c0cb3751b05050 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -80,7 +80,7 @@ void gePianoRoll::drawSurface1()
 
                /* print key note label. C C# D D# E F F# G G# A A# B */
 
-               string note = gu_iToString(octave);
+               string note = u::string::iToString(octave);
                switch (i % KEYS) {
                        case (int) Notes::G:
                                fl_rectf(0, i*CELL_H, CELL_W, CELL_H, G_COLOR_GREY_2);
index aedb641c8e630c38419c648450e5d529e96db5a0..aecd56edbfe86279bea6b0c9c15716c9b14d2bb0 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index bd6975504a7f89ea18f16decfa5461f25b039020..a488736bd390adcb48016db45c923a9088ebcea0 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index e85ab13c42656fc932e15611fead5bc0056004d3..6b4fc0a76b1c2ddc81da4f49b78c5b60359d9e9e 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -39,7 +39,7 @@ namespace giada {
 namespace m
 {
 class SampleChannel;
-class Action;
+struct Action;
 }
 namespace v
 {
index ae1cb9e86c31b98705ac6b71463fe2ba1bd61ed2..31f73192fe4391e89cb559b8951808811221797b 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index c71d0ad3866dd961ee34837dccb5fd63ff892d99..59e5ea31a74eba13a32374dad84664e91c638f5f 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -36,7 +36,7 @@ namespace giada {
 namespace m
 {
 class SampleChannel;
-class Action;
+struct Action;
 }
 namespace v
 {
index 58bcc6e39f815835e0025a155fa4d7b318bf68a8..030af9a619b5965657561326821fbd127eb73451 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index f3415ddbad8d62e692ddd185de4ac3b386da93d5..456ae58ba5d4398cdb5f520ffdc8eb5bbdb510d7 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index ca8c84c9ae50b411b9a02aa41398e01c0b6abfef..b4ed84f7d185ba1a354492ab201f45673df422d3 100644 (file)
@@ -7,7 +7,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index f2dffeda7ab0dd2c3fe046a4ba500291e32d19a2..cb8e1dd42eac63c5b9a9f05493666ef033360228 100644 (file)
@@ -7,7 +7,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 6b15e1a15e43360964a42614c06967c6fbbd741d..02814b15ac0c495a18881ac66f222e0e62f6f172 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index c73a8ebece4c87a4e6822b7d6063d21f0c70f993..f8e138975829234405bbfba45e9818c232e2c1e4 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index d22510da1538f5cdd77c15df39a26b6c204d6ef0..42df73b2ed2a04a66f308800d2ff93b64023346e 100644 (file)
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index b4ae0ce9f385782ae2a27b149c862f27ba0a2c3a..b5e58f656a25632b67783610444f375b89a3f3aa 100644 (file)
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index eb874004ec6b2f2200483e138cd176fa25582dcb..b113b6c055597e914ec3f4230ad737e8e0c94570 100644 (file)
@@ -7,7 +7,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index ce33ed12fe39944e50293a06a32f05a4220dd5e9..4f51e3a28b47a9c0de868c20298519e9abde90d3 100644 (file)
@@ -7,7 +7,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index daed5493b8c4ee8dabfab2b8ed647f5640ba12a2..aa2a0beb95c46f487834560bdc65f9492944763a 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 4d845569368b9892b234cab609f5d99d599003a4..486466c03354246a11dc722a8889e89841efc295 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index b0f52b3934efd80295623375c1e6c1540839bb41..2764b31366abf16d6f9e89dad56865ddc64765b3 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index ef37938d03846327454eae3576b27efdabdc3258..ebf01a4f529e88a7b4b39da95d6973893a889299 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 5f65e9fa8968737811217356fcd50371fbf4a234..55d541acc50689ebe3cc9545d6fa2f65d0ac81fe 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index f0b93ac6297a74efcdb1bb65b0c192fc48892209..0699a0d6fff6199afa6141ba1c9e0b9f16c2bda3 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/gui/elems/basics/idButton.cpp b/src/gui/elems/basics/idButton.cpp
deleted file mode 100644 (file)
index 3f2ffaf..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/* -----------------------------------------------------------------------------
- *
- * Giada - Your Hardcore Loopmachine
- *
- * geIdButton
- * Exactly as geButton but with a unique id. Used for the buttons in channels
- * and for FXs.
- *
- * -----------------------------------------------------------------------------
- *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
- *
- * This file is part of Giada - Your Hardcore Loopmachine.
- *
- * Giada - Your Hardcore Loopmachine 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.
- *
- * Giada - Your Hardcore Loopmachine 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 Giada - Your Hardcore Loopmachine. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * -------------------------------------------------------------------------- */
-
-
-#include "idButton.h"
-
-
-geIdButton::geIdButton(int X, int Y, int W, int H, const char *L,
-  const char **imgOff, const char **imgOn)
-  : geButton(X, Y, W, H, L, imgOff, imgOn)
-{
-}
diff --git a/src/gui/elems/basics/idButton.h b/src/gui/elems/basics/idButton.h
deleted file mode 100644 (file)
index 312930d..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/* -----------------------------------------------------------------------------
- *
- * Giada - Your Hardcore Loopmachine
- *
- * geIdButton
- * Exactly as geButton but with a unique id. Used for the buttons in channels
- * and for FXs.
- *
- * -----------------------------------------------------------------------------
- *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
- *
- * This file is part of Giada - Your Hardcore Loopmachine.
- *
- * Giada - Your Hardcore Loopmachine 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.
- *
- * Giada - Your Hardcore Loopmachine 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 Giada - Your Hardcore Loopmachine. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * -------------------------------------------------------------------------- */
-
-
-#ifndef GE_ID_BUTTON_H
-#define GE_ID_BUTTON_H
-
-
-#include "button.h"
-
-
-class geIdButton : public geButton
-{
-public:
-
-  geIdButton(int X,int Y,int W,int H,const char *L=0,
-    const char **imgOff=nullptr, const char **imgOn=nullptr);
-
-  int key;
-       int id;
-};
-
-
-#endif
index 6466a15a60220e75d8ff78c2c817e6d21f0c1180..7df58e27a402c0138bffae229781d684559952b2 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index bef8ef898edab76f8a4b7b67fc7d29ac87646f7f..74124b6fe6336f9a5e841777e6d1024bbae33ecb 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index b66a8f228777056eb8237d0d15fd7281f9a5bd0e..cfc561554be8c1eff867d04e691f5da6ecfdf675 100644 (file)
@@ -9,7 +9,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 56386845ba92a55798bf6731be8f8707d09c633c..e803120cbca14a730b4b4ae48048ed2be6d870ae 100644 (file)
@@ -9,7 +9,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index b1a1e23d024c6ea1e38b298fadb0b9738a17d498..b5e3159dd9323a3572425db18c71b036dee64bc4 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index d884ac99051aba62464eee2607dcecc224059bd4..2c7a5d0dada918f5f0d0fe3f8e01cc57e99ee4e1 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index dbc40fe2316d3433875a5e75079990f000d03604..dbbc651f70e5e87d9556b83b0d1aa60f9fa318f6 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index aece5efcbec50927454ed6d8ba53329fe015b175..d8bcb4207e9c0ba4eeb9687cf695f65978a9e7d0 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 6831a09589af37c5e8936a42a0c4d15678b25a5f..9d4b66bb86dae451b4854c3b232a4ca04c3e9f7b 100644 (file)
@@ -20,7 +20,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index fb208790305561c0061ba2a7b401c44a6e33cd12..64fa249d935971b130e5b2a8a46221948713b027 100644 (file)
@@ -20,7 +20,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 273a0532ed1cc3a90454624568bfa69fde5bcda2..578b5b72afe4622f6cf0aeb0d53799f87cea0bd1 100644 (file)
@@ -7,7 +7,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 92262f236ebdd4e8ce4b296a05f70fdf90263658..31549744ae931fd7fb982360002a7a9ac99c984d 100644 (file)
@@ -7,7 +7,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index a984a436a1f782fa34fd5e2004ab4ec083a3435f..75769a331e09d66142646fab5c35b49f0a8378e5 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 2dd0acae2cd9172f9433e148e18c1be55f91e4c9..98f729d06e2f16843b0160748ce3c0c28f627b48 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 38b9b638b71cec1bc54bc54786ec19b55f31a81b..64623d3d7a0b95068dea212f937a74de0202bb54 100644 (file)
@@ -7,7 +7,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 317a5a562fe689cd72400503ad0a4f5d56baf863..1f8f9242873e05a4fa0eec6d1f7e76f6efb9f8ea 100644 (file)
@@ -7,7 +7,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 00f95f1141afd6c7337ef7b6c3c00aaf62fb593a..9a2512f5f07257ba60fd653ec0b25be2fbd41240 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -34,6 +34,7 @@
 
 
 using std::string;
+using namespace giada;
 
 
 geBrowser::geBrowser(int x, int y, int w, int h)
@@ -138,7 +139,7 @@ int geBrowser::handle(int e)
 
 string geBrowser::getCurrentDir()
 {
-  return normalize(gu_getRealPath(m_currentDir));
+  return normalize(u::string::getRealPath(m_currentDir));
 }
 
 
@@ -158,7 +159,7 @@ string geBrowser::getSelectedItem(bool fullPath)
 #else
     string sep = G_SLASH_STR;
 #endif
-    return normalize(gu_getRealPath(m_currentDir + sep + normalize(text(value()))));
+    return normalize(u::string::getRealPath(m_currentDir + sep + normalize(text(value()))));
   }
 }
 
index 12dc3832d9e02ced1baf31a395c75d3de5aa8642..533d1a3f63b6424f0cb44e342821cf4dc383c111 100644 (file)
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index baf56d4355c5547d917626c3bd178ed074c2ebaa..bb192f8220228b6e2fe2074ec6f32900a7ccbc7f 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -31,7 +31,7 @@
 #include "../../../core/conf.h"
 #include "../../../core/kernelAudio.h"
 #include "../../../utils/string.h"
-#include "../../../gui/dialogs/gd_devInfo.h"
+#include "../../../gui/dialogs/devInfo.h"
 #include "../basics/box.h"
 #include "../basics/choice.h"
 #include "../basics/check.h"
@@ -41,6 +41,7 @@
 
 
 using std::string;
+using namespace giada;
 using namespace giada::m;
 
 
@@ -48,20 +49,19 @@ geTabAudio::geTabAudio(int X, int Y, int W, int H)
        : Fl_Group(X, Y, W, H, "Sound System")
 {
        begin();
-       soundsys    = new geChoice(x()+114, y()+9,  250, 20, "System");
-       buffersize  = new geChoice(x()+114, y()+37, 55,  20, "Buffer size");
-       samplerate  = new geChoice(x()+309, y()+37, 55,  20, "Sample rate");
-       sounddevOut = new geChoice(x()+114, y()+65, 222, 20, "Output device");
-       devOutInfo  = new geButton(x()+344, y()+65, 20,  20, "?");
-       channelsOut = new geChoice(x()+114, y()+93, 55,  20, "Output channels");
-       limitOutput = new geCheck (x()+177, y()+97, 55,  20, "Limit output");
-       sounddevIn  = new geChoice(x()+114, y()+121, 222, 20, "Input device");
-       devInInfo   = new geButton(x()+344, y()+121, 20,  20, "?");
-       channelsIn  = new geChoice(x()+114, y()+149, 55,  20, "Input channels");
-       delayComp   = new geInput (x()+309, y()+149, 55,  20, "Rec delay comp.");
-       rsmpQuality = new geChoice(x()+114, y()+177, 250, 20, "Resampling");
-                new geBox(x(), rsmpQuality->y()+rsmpQuality->h()+8, w(), 92,
-                                                                               "Restart Giada for the changes to take effect.");
+       soundsys        = new geChoice(x()+114, y()+9,  250, 20, "System");
+       buffersize      = new geChoice(x()+114, y()+37, 55,  20, "Buffer size");
+       samplerate      = new geChoice(x()+309, y()+37, 55,  20, "Sample rate");
+       sounddevOut     = new geChoice(x()+114, y()+65, 222, 20, "Output device");
+       devOutInfo      = new geButton(x()+344, y()+65, 20,  20, "?");
+       channelsOut     = new geChoice(x()+114, y()+93, 55,  20, "Output channels");
+       limitOutput     = new geCheck (x()+177, y()+97, 55,  20, "Limit output");
+       sounddevIn      = new geChoice(x()+114, y()+121, 222, 20, "Input device");
+       devInInfo       = new geButton(x()+344, y()+121, 20,  20, "?");
+       channelsIn      = new geChoice(x()+114, y()+149, 55,  20, "Input channels");
+       recTriggerLevel = new geInput (x()+309, y()+149, 55,  20, "Rec threshold (dB)");
+       rsmpQuality     = new geChoice(x()+114, y()+177, 250, 20, "Resampling");
+                      new geBox(x(), rsmpQuality->y()+rsmpQuality->h()+8, w(), 92, "Restart Giada for the changes to take effect.");
        end();
 
        labelsize(G_GUI_FONT_SIZE_BASE);
@@ -156,7 +156,7 @@ geTabAudio::geTabAudio(int X, int Y, int W, int H)
                int nfreq = kernelAudio::getTotalFreqs(sounddevOut->value());
                for (int i=0; i<nfreq; i++) {
                        int freq = kernelAudio::getFreq(sounddevOut->value(), i);
-                       samplerate->add(gu_iToString(freq).c_str());
+                       samplerate->add(u::string::iToString(freq).c_str());
                        if (freq == conf::samplerate)
                                samplerate->value(i);
                }
@@ -181,7 +181,7 @@ geTabAudio::geTabAudio(int X, int Y, int W, int H)
        buffersize->add("1024");
        buffersize->add("2048");
        buffersize->add("4096");
-       buffersize->showItem(gu_iToString(conf::buffersize).c_str());
+       buffersize->showItem(u::string::iToString(conf::buffersize).c_str());
 
        rsmpQuality->add("Sinc best quality (very slow)");
        rsmpQuality->add("Sinc medium quality (slow)");
@@ -190,9 +190,7 @@ geTabAudio::geTabAudio(int X, int Y, int W, int H)
        rsmpQuality->add("Linear (very fast)");
        rsmpQuality->value(conf::rsmpQuality);
 
-       delayComp->value(gu_iToString(conf::delayComp).c_str());
-       delayComp->type(FL_INT_INPUT);
-       delayComp->maximum_size(5);
+       recTriggerLevel->value(u::string::fToString(conf::recTriggerLevel, 1).c_str());
 
        limitOutput->value(conf::limitOutput);
 }
@@ -201,17 +199,17 @@ geTabAudio::geTabAudio(int X, int Y, int W, int H)
 /* -------------------------------------------------------------------------- */
 
 
-void geTabAudio::cb_deactivate_sounddev(Fl_Widget *w, void *p) { ((geTabAudio*)p)->__cb_deactivate_sounddev(); }
-void geTabAudio::cb_fetchInChans(Fl_Widget *w, void *p)        { ((geTabAudio*)p)->__cb_fetchInChans(); }
-void geTabAudio::cb_fetchOutChans(Fl_Widget *w, void *p)       { ((geTabAudio*)p)->__cb_fetchOutChans(); }
-void geTabAudio::cb_showInputInfo(Fl_Widget *w, void *p)       { ((geTabAudio*)p)->__cb_showInputInfo(); }
-void geTabAudio::cb_showOutputInfo(Fl_Widget *w, void *p)      { ((geTabAudio*)p)->__cb_showOutputInfo(); }
+void geTabAudio::cb_deactivate_sounddev(Fl_Widget* w, void* p) { ((geTabAudio*)p)->cb_deactivate_sounddev(); }
+void geTabAudio::cb_fetchInChans(Fl_Widget* w, void* p)        { ((geTabAudio*)p)->cb_fetchInChans(); }
+void geTabAudio::cb_fetchOutChans(Fl_Widget* w, void* p)       { ((geTabAudio*)p)->cb_fetchOutChans(); }
+void geTabAudio::cb_showInputInfo(Fl_Widget* w, void* p)       { ((geTabAudio*)p)->cb_showInputInfo(); }
+void geTabAudio::cb_showOutputInfo(Fl_Widget* w, void* p)      { ((geTabAudio*)p)->cb_showOutputInfo(); }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void geTabAudio::__cb_fetchInChans()
+void geTabAudio::cb_fetchInChans()
 {
        fetchInChans(sounddevIn->value());
        channelsIn->value(0);
@@ -221,7 +219,7 @@ void geTabAudio::__cb_fetchInChans()
 /* -------------------------------------------------------------------------- */
 
 
-void geTabAudio::__cb_fetchOutChans()
+void geTabAudio::cb_fetchOutChans()
 {
        fetchOutChans(sounddevOut->value());
        channelsOut->value(0);
@@ -231,7 +229,7 @@ void geTabAudio::__cb_fetchOutChans()
 /* -------------------------------------------------------------------------- */
 
 
-void geTabAudio::__cb_showInputInfo()
+void geTabAudio::cb_showInputInfo()
 {
        unsigned dev = kernelAudio::getDeviceByName(sounddevIn->text(sounddevIn->value()));
        new gdDevInfo(dev);
@@ -241,7 +239,7 @@ void geTabAudio::__cb_showInputInfo()
 /* -------------------------------------------------------------------------- */
 
 
-void geTabAudio::__cb_showOutputInfo()
+void geTabAudio::cb_showOutputInfo()
 {
        unsigned dev = kernelAudio::getDeviceByName(sounddevOut->text(sounddevOut->value()));
        new gdDevInfo(dev);
@@ -251,7 +249,7 @@ void geTabAudio::__cb_showOutputInfo()
 /* -------------------------------------------------------------------------- */
 
 
-void geTabAudio::__cb_deactivate_sounddev()
+void geTabAudio::cb_deactivate_sounddev()
 {
        /* if the user changes sound system (eg ALSA->JACK) device menu deactivates.
         * If it returns to the original sound system, we re-fill the list by
@@ -302,15 +300,15 @@ void geTabAudio::fetchInChans(int menuItem)
        /* if menuItem==0 device in input is disabled. */
 
        if (menuItem == 0) {
-               devInInfo ->deactivate();
+               devInInfo->deactivate();
                channelsIn->deactivate();
-               delayComp ->deactivate();
+               recTriggerLevel->deactivate();
                return;
        }
 
-       devInInfo ->activate();
+       devInInfo->activate();
        channelsIn->activate();
-       delayComp ->activate();
+       recTriggerLevel->activate();
 
        channelsIn->clear();
 
@@ -323,7 +321,7 @@ void geTabAudio::fetchInChans(int menuItem)
                return;
        }
        for (unsigned i=0; i<chs; i+=2) {
-               string tmp = gu_iToString(i+1) + "-" + gu_iToString(i+2);
+               string tmp = u::string::iToString(i+1) + "-" + u::string::iToString(i+2);
                channelsIn->add(tmp.c_str());
        }
        channelsIn->value(conf::channelsIn);
@@ -346,7 +344,7 @@ void geTabAudio::fetchOutChans(int menuItem)
                return;
        }
        for (unsigned i=0; i<chs; i+=2) {
-               string tmp = gu_iToString(i+1) + "-" + gu_iToString(i+2);
+               string tmp = u::string::iToString(i+1) + "-" + u::string::iToString(i+2);
                channelsOut->add(tmp.c_str());
        }
        channelsOut->value(conf::channelsOut);
@@ -497,16 +495,11 @@ void geTabAudio::save()
        if (conf::soundDeviceOut == -1)
                conf::soundDeviceOut = 0;
 
-       int bufsize = atoi(buffersize->text());
-       if (bufsize % 2 != 0) bufsize++;
-       if (bufsize < 8)                  bufsize = 8;
-       if (bufsize > 8192)             bufsize = 8192;
-       conf::buffersize = bufsize;
+       conf::buffersize = std::atoi(buffersize->text());
+       conf::recTriggerLevel = std::atof(recTriggerLevel->value());
 
-       const Fl_Menu_Item *i = nullptr;
+       const Fl_Menu_Itemi = nullptr;
        i = samplerate->mvalue(); // mvalue() returns a pointer to the last menu item that was picked
-       if (i)
-               conf::samplerate = atoi(i->label());
-
-       conf::delayComp = atoi(delayComp->value());
+       if (i != nullptr)
+               conf::samplerate = std::atoi(i->label());
 }
index bb3e91896f1e14835aa3c14d40dee00ac6cd89dc..65f0cc5dbcc47660b237c614493a6c72965aaf42 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -42,38 +42,38 @@ class geTabAudio : public Fl_Group
 {
 private:
 
-       static void cb_deactivate_sounddev(Fl_Widget *w, void *p);
-       static void cb_fetchInChans       (Fl_Widget *w, void *p);
-       static void cb_fetchOutChans      (Fl_Widget *w, void *p);
-       static void cb_showInputInfo      (Fl_Widget *w, void *p);
-       static void cb_showOutputInfo     (Fl_Widget *w, void *p);
-       inline void __cb_deactivate_sounddev();
-       inline void __cb_fetchInChans();
-       inline void __cb_fetchOutChans();
-       inline void __cb_showInputInfo();
-       inline void __cb_showOutputInfo();
+       static void cb_deactivate_sounddev(Fl_Widget* w, void* p);
+       static void cb_fetchInChans       (Fl_Widget* w, void* p);
+       static void cb_fetchOutChans      (Fl_Widget* w, void* p);
+       static void cb_showInputInfo      (Fl_Widget* w, void* p);
+       static void cb_showOutputInfo     (Fl_Widget* w, void* p);
+       void cb_deactivate_sounddev();
+       void cb_fetchInChans();
+       void cb_fetchOutChans();
+       void cb_showInputInfo();
+       void cb_showOutputInfo();
 
        void fetchSoundDevs();
        void fetchInChans(int menuItem);
        void fetchOutChans(int menuItem);
-       int  findMenuDevice(geChoice *m, int device);
+       int  findMenuDevice(geChoicem, int device);
 
        int soundsysInitValue;
 
 public:
 
-       geChoice *soundsys;
-       geChoice *samplerate;
-       geChoice *rsmpQuality;
-       geChoice *sounddevIn;
-       geButton  *devInInfo;
-       geChoice *channelsIn;
-       geChoice *sounddevOut;
-       geButton  *devOutInfo;
-       geChoice *channelsOut;
-       geCheck  *limitOutput;
-       geChoice *buffersize;
-       geInput  *delayComp;
+       geChoicesoundsys;
+       geChoice* buffersize;
+       geChoice* samplerate;
+       geChoice* sounddevOut;
+       geButton* devOutInfo;
+       geChoice* channelsOut;
+       geCheck*  limitOutput;
+       geChoice* sounddevIn;
+       geButton* devInInfo;
+       geChoice* channelsIn;
+       geInput*  recTriggerLevel;
+       geChoice* rsmpQuality;
 
        geTabAudio(int x, int y, int w, int h);
 
index b6a57c4c4c704e216e6338b5c88d0c6dcdab5dc7..3926e5c3c3483c4e75bb9f4365f74692df656bfa 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index d0a3ecee594e2e4250900561d0e356a05cc46449..07f29f1ffeaa74f1a86a4b36701a36b7c7242741 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 527bfeb3d7716da14f24e1764435ef83c0b9ab90..9af5b1a60dd6e20529e4b16f2a8f7eaa43ce743d 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -43,6 +43,7 @@
 
 
 using std::string;
+using namespace giada;
 using namespace giada::m;
 
 
@@ -97,7 +98,7 @@ void geTabMidi::fetchOutPorts()
                portOut->add("(disabled)");
 
                for (unsigned i=0; i<kernelMidi::countOutPorts(); i++)
-                       portOut->add(gu_removeFltkChars(kernelMidi::getOutPortName(i)).c_str());
+                       portOut->add(u::gui::removeFltkChars(kernelMidi::getOutPortName(i)).c_str());
 
                portOut->value(conf::midiPortOut+1);    // +1 because midiPortOut=-1 is '(disabled)'
        }
@@ -118,7 +119,7 @@ void geTabMidi::fetchInPorts()
                portIn->add("(disabled)");
 
                for (unsigned i=0; i<kernelMidi::countInPorts(); i++)
-                       portIn->add(gu_removeFltkChars(kernelMidi::getInPortName(i)).c_str());
+                       portIn->add(u::gui::removeFltkChars(kernelMidi::getInPortName(i)).c_str());
 
                portIn->value(conf::midiPortIn+1);    // +1 because midiPortIn=-1 is '(disabled)'
        }
index 9b48a92b77748777e3c68771ddf9d943ea09e229..c134aac84173ef190d40a105ce5651581f4905f6 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index b1f4e2dc4fd607fbbd18d90118303c31b853b5dc..0e2cc10097353c156938f6e46fe84a5b6488300b 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index bf900bf3efab2f64ec74c4b9c38f54413cea1b60..138f6d1b173e14912282750bcec3237a3cd77e30 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index d9074a67ca64cf54fae47c03262e8d4eb5ab0cf8..343b2565b5dba1429114c52f35b8353ba01024c4 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
 #include "../../../core/const.h"
 #include "../../../core/conf.h"
 #include "../../../core/graphics.h"
-#include "../../../core/pluginHost.h"
+#include "../../../core/pluginManager.h"
 #include "../../../glue/plugin.h"
 #include "../../../utils/string.h"
 #include "../../../utils/fs.h"
 #include "../../../utils/gui.h"
 #include "../../dialogs/window.h"
-#include "../../dialogs/gd_mainWindow.h"
+#include "../../dialogs/mainWindow.h"
 #include "../../dialogs/browser/browserDir.h"
 #include "../basics/box.h"
 #include "../basics/radio.h"
@@ -53,6 +53,7 @@ extern gdMainWindow* G_MainWin;
 
 
 using std::string;
+using namespace giada;
 using namespace giada::m;
 
 
@@ -88,7 +89,7 @@ geTabPlugins::geTabPlugins(int X, int Y, int W, int H)
 
 void geTabPlugins::refreshCount()
 {
-       string scanLabel = "Scan (" + gu_iToString(pluginHost::countAvailablePlugins()) + " found)";
+       string scanLabel = "Scan (" + u::string::iToString(pluginManager::countAvailablePlugins()) + " found)";
        m_scanButton->label(scanLabel.c_str());
 }
 
@@ -119,14 +120,14 @@ void geTabPlugins::cb_scan()
 {
        std::function<void(float)> callback = [this] (float progress) 
        {
-               string l = "Scan in progress (" + gu_iToString((int)(progress*100)) + "%). Please wait...";
+               string l = "Scan in progress (" + u::string::iToString((int)(progress*100)) + "%). Please wait...";
                m_info->label(l.c_str());
                Fl::wait();
        };
 
        m_info->show();
-       pluginHost::scanDirs(m_folderPath->value(), callback);
-       pluginHost::saveList(gu_getHomePath() + G_SLASH + "plugins.xml");
+       pluginManager::scanDirs(m_folderPath->value(), callback);
+       pluginManager::saveList(gu_getHomePath() + G_SLASH + "plugins.xml");
        m_info->hide();
        refreshCount();
 }
index cc8ffd9f66d7078e522e37f2ded1fdce03178ddb..31c346da3d1a33f1b0ef0891ff042b50b1fbc75a 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index d10efed396b3a4e08a6a70bf1e7b3d27a1051635..c1fe379680685eb128aecf6db8843fbab70d1658 100644 (file)
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
 
 #include <FL/fl_draw.H>
 #include "../../../core/const.h"
+#include "../../../core/recManager.h"
 #include "../../../core/mixer.h"
 #include "../../../core/clock.h"
+#include "../../../utils/gui.h"
 #include "beatMeter.h"
 
 
-using namespace giada::m;
+namespace giada {
+namespace v
+{
+geBeatMeter::geBeatMeter(int x, int y, int w, int h, const char* l)
+: Fl_Box(x, y, w, h, l)
+{
+}
+
+
+/* -------------------------------------------------------------------------- */
 
 
-geBeatMeter::geBeatMeter(int x, int y, int w, int h, const char *L)
-  : Fl_Box(x, y, w, h, L) {}
+Fl_Color geBeatMeter::getCursorColor()
+{
+       if (m::clock::getStatus() == ClockStatus::WAITING && u::gui::shouldBlink())
+               return FL_BACKGROUND_COLOR;
+       return G_COLOR_LIGHT_1;
+}
 
 
 /* -------------------------------------------------------------------------- */
@@ -46,28 +61,36 @@ geBeatMeter::geBeatMeter(int x, int y, int w, int h, const char *L)
 
 void geBeatMeter::draw()
 {
-  int cursorW = w() / G_MAX_BEATS;
-  int greyX   = clock::getBeats() * cursorW;
+       using namespace giada::m;
+
+       int cursorW = w() / G_MAX_BEATS;
+       int greyX   = clock::getBeats() * cursorW;
 
-  fl_rect(x(), y(), w(), h(), G_COLOR_GREY_4);                            // border
-  fl_rectf(x()+1, y()+1, w()-2, h()-2, FL_BACKGROUND_COLOR);          // bg
-  fl_rectf(x()+(clock::getCurrentBeat()*cursorW)+3, y()+3, cursorW-5, h()-6,
-    G_COLOR_LIGHT_1); // cursor
+       /* Border and background. */
+       
+       fl_rect(x(), y(), w(), h(), G_COLOR_GREY_4);
+       fl_rectf(x()+1, y()+1, w()-2, h()-2, FL_BACKGROUND_COLOR);
 
-  /* beat cells */
+       /* Cursor. */
 
-  fl_color(G_COLOR_GREY_4);
-  for (int i=1; i<=clock::getBeats(); i++)
-    fl_line(x()+cursorW*i, y()+1, x()+cursorW*i, y()+h()-2);
+       fl_rectf(x() + (clock::getCurrentBeat() * cursorW) + 3, y() + 3, cursorW - 5, h() - 6, getCursorColor());       
 
-  /* bar line */
+       /* Beat cells. */
 
-  fl_color(G_COLOR_LIGHT_1);
-  int delta = clock::getBeats() / clock::getBars();
-  for (int i=1; i<clock::getBars(); i++)
-    fl_line(x()+cursorW*(i*delta), y()+1, x()+cursorW*(i*delta), y()+h()-2);
+       fl_color(G_COLOR_GREY_4);
+       for (int i=1; i<=clock::getBeats(); i++)
+               fl_line(x()+cursorW*i, y()+1, x()+cursorW*i, y()+h()-2);
 
-  /* unused grey area */
+       /* Bar line. */
 
-  fl_rectf(x()+greyX+1, y()+1, w()-greyX-1,  h()-2, G_COLOR_GREY_4);
+       fl_color(G_COLOR_LIGHT_1);
+       int delta = clock::getBeats() / clock::getBars();
+       for (int i=1; i<clock::getBars(); i++)
+               fl_line(x()+cursorW*(i*delta), y()+1, x()+cursorW*(i*delta), y()+h()-2);
+
+       /* Unused grey area. */
+
+       fl_rectf(x()+greyX+1, y()+1, w()-greyX-1,  h()-2, G_COLOR_GREY_4);
 }
+
+}} // giada::v::
\ No newline at end of file
index d1e5a11a2e951a3a68d94d97c54695884f11e43b..d6214ca48026031c5ae85b5ecf0ef56435397b49 100644 (file)
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
 #include <FL/Fl_Box.H>
 
 
+namespace giada {
+namespace v
+{
 class geBeatMeter : public Fl_Box
 {
 public:
 
-       geBeatMeter(int X,int Y,int W,int H,const char *L=0);
-       void draw();
+       geBeatMeter(int x, int y, int w, int h, const char* l=nullptr);
+       void draw();
+
+private:
+
+    Fl_Color getCursorColor();
 };
+}} // giada::v::
 
 
 #endif
index 2d563ce2ac44e820a5bf1493b8c03ccd2ca21c30..b99558cdbf3c25e6e046cbb64b877c9015fcb4a7 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -32,9 +32,9 @@
 #include "../../../../core/pluginHost.h"
 #include "../../../../utils/gui.h"
 #include "../../../../glue/channel.h"
-#include "../../../dialogs/gd_mainWindow.h"
+#include "../../../dialogs/mainWindow.h"
 #include "../../../dialogs/pluginList.h"
-#include "../../basics/idButton.h"
+#include "../../basics/button.h"
 #include "../../basics/dial.h"
 #include "../../basics/statusButton.h"
 #include "column.h"
@@ -50,8 +50,8 @@ using namespace giada;
 
 
 geChannel::geChannel(int X, int Y, int W, int H, giada::m::Channel* ch)
- : Fl_Group(X, Y, W, H, nullptr),
-        ch      (ch)
+: Fl_Group    (X, Y, W, H, nullptr),
+  ch          (ch)
 {
 }
 
@@ -110,7 +110,7 @@ void geChannel::cb_changeVol()
 #ifdef WITH_VST
 void geChannel::cb_openFxWindow()
 {
-       gu_openSubWindow(G_MainWin, new gdPluginList(m::pluginHost::CHANNEL, ch), WID_FX_LIST);
+       u::gui::openSubWindow(G_MainWin, new gdPluginList(m::pluginHost::StackType::CHANNEL, ch), WID_FX_LIST);
 }
 #endif
 
@@ -118,15 +118,6 @@ void geChannel::cb_openFxWindow()
 /* -------------------------------------------------------------------------- */
 
 
-int geChannel::keyPress(int e)
-{
-       return handleKey(e, ch->key);
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
 
 int geChannel::getColumnIndex()
 {
@@ -139,7 +130,7 @@ int geChannel::getColumnIndex()
 
 void geChannel::blink()
 {
-       if (gu_getBlinker() > 6)
+       if (u::gui::shouldBlink())
                mainButton->setPlayMode();
        else
                mainButton->setDefaultMode();
@@ -148,9 +139,10 @@ void geChannel::blink()
 
 /* -------------------------------------------------------------------------- */
 
-void geChannel::setColorsByStatus(ChannelStatus playStatus, ChannelStatus recStatus)
+
+void geChannel::setColorsByStatus()
 {
-       switch (playStatus) {
+       switch (ch->status) {
                case ChannelStatus::OFF:
                case ChannelStatus::EMPTY:
                        mainButton->setDefaultMode();
@@ -160,9 +152,11 @@ void geChannel::setColorsByStatus(ChannelStatus playStatus, ChannelStatus recSta
                        break;
                case ChannelStatus::PLAY:
                        mainButton->setPlayMode();
-                       button->imgOn  = channelStop_xpm;
-                       button->imgOff = channelPlay_xpm;
-                       button->redraw();
+                       if (!button->value()) { // If not manually pressed (it would interfere)
+                               button->imgOn  = channelStop_xpm;
+                               button->imgOff = channelPlay_xpm;
+                               button->redraw();                       
+                       }
                        break;
                case ChannelStatus::WAIT:
                        blink();
@@ -173,7 +167,7 @@ void geChannel::setColorsByStatus(ChannelStatus playStatus, ChannelStatus recSta
                default: break;
        }
 
-       switch (recStatus) {
+       switch (ch->recStatus) {
                case ChannelStatus::WAIT:
                        blink();
                        break;
@@ -222,25 +216,23 @@ void geChannel::packWidgets()
 /* -------------------------------------------------------------------------- */
 
 
-int geChannel::handleKey(int e, int key)
+bool geChannel::handleKey(int e)
 {
-       int ret;
-       if (e == FL_KEYDOWN && button->value())                              // key already pressed! skip it
-               ret = 1;
-       else
-       if (Fl::event_key() == key && !button->value()) {
-               button->take_focus();                                              // move focus to this button
-               button->value((e == FL_KEYDOWN || e == FL_SHORTCUT) ? 1 : 0);      // change the button's state
-               button->do_callback();                                             // invoke the button's callback
-               ret = 1;
-       }
-       else
-               ret = 0;
+       if (Fl::event_key() != ch->key) 
+               return false;
 
-       if (Fl::event_key() == key)
-               button->value((e == FL_KEYDOWN || e == FL_SHORTCUT) ? 1 : 0);      // change the button's state
+       if (e == FL_KEYDOWN && !button->value()) {  // Key not already pressed
+               button->take_focus();                   // Move focus to this button
+               button->value(1);
+               return true;
+       }
 
-       return ret;
+       if (e == FL_KEYUP) {
+               button->value(0);
+               return true;
+       }
+       
+       return false;
 }
 
 
index 785b94dd7fa784ea4b06c42a9a4ef2dd097d2649..6308f27c29b0bde0521e3c1d8c8e694f72ec827c 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -34,7 +34,6 @@
 #include "../../../../core/channel.h"
 
 
-class geIdButton;
 class geChannelStatus;
 class geButton;
 class geChannelButton;
@@ -46,6 +45,57 @@ class geStatusButton;
 
 class geChannel : public Fl_Group
 {
+public:
+
+       geChannel(int x, int y, int w, int h, giada::m::Channel* ch);
+
+       /* reset
+       Resets channel to initial status. */
+
+       virtual void reset() = 0;
+
+       /* update
+       Updates the label of sample button and everything else such as 'R' button, 
+       key box and so on, according to global values. */
+
+       virtual void update() = 0;
+
+       /* refresh
+       Updates graphics. */
+
+       virtual void refresh() = 0;
+
+       /* changeSize
+       Changes channel's size according to a template (x1, x2, ...). */
+
+       virtual void changeSize(int h);
+
+       /* getColumnIndex
+       Returns the numeric index of the column in which this channel is located. */
+
+       int getColumnIndex();
+
+       int getSize();
+
+       /* handleKey
+       Performs some UI-related operations when the bound key is pressed. Returns
+       whether the bound key has been pressed or not. */
+
+       bool handleKey(int e);
+
+       giada::m::Channel* ch;
+       geButton*        button;
+       geChannelStatus* status;
+       geButton*        arm;
+       geChannelButton* mainButton;
+       geButton*        mute;
+       geButton*        solo;
+       geDial*          vol;
+#ifdef WITH_VST
+       geStatusButton*  fx;
+#endif
+
 protected:
 
        /* Define some breakpoints for dynamic resize. BREAK_DELTA: base amount of
@@ -69,7 +119,7 @@ protected:
        static void cb_solo(Fl_Widget* v, void* p);
        static void cb_changeVol(Fl_Widget* v, void* p);
 #ifdef WITH_VST
-               static void cb_openFxWindow(Fl_Widget* v, void* p);
+       static void cb_openFxWindow(Fl_Widget* v, void* p);
 #endif
        void cb_mute();
        void cb_arm();
@@ -80,75 +130,19 @@ protected:
 #endif
 
        /* blink
-        * blink button when channel is in wait/ending status. */
+       Blinks button when channel is in wait/ending status. */
 
        void blink();
 
        /* setColorByStatus
-        * update colors depending on channel status. */
-
-       void setColorsByStatus(giada::ChannelStatus chan, giada::ChannelStatus rec);
+       Updates colors depending on channel status. */
 
-       /* handleKey
-        * method wrapped by virtual handle(int e). */
-
-       int handleKey(int e, int key);
+       void setColorsByStatus();
 
        /* packWidgets
        Spread widgets across available space. */
 
        void packWidgets();
-
-public:
-
-       geChannel(int x, int y, int w, int h, giada::m::Channel* ch);
-
-       /* reset
-        * reset channel to initial status. */
-
-       virtual void reset() = 0;
-
-       /* update
-        * update the label of sample button and everything else such as 'R'
-        * button, key box and so on, according to global values. */
-
-       virtual void update() = 0;
-
-       /* refresh
-        * update graphics. */
-
-       virtual void refresh() = 0;
-
-       /* changeSize
-       Changes channel's size according to a template (x1, x2, ...). */
-
-       virtual void changeSize(int h);
-
-       /* keypress
-        * what to do when the corresponding key is pressed. */
-
-       int keyPress(int event);
-
-       /* getColumnIndex
-        * return the numeric index of the column in which this channel is
-        * located. */
-
-       int getColumnIndex();
-
-       int getSize();
-
-       giada::m::Channel* ch;
-       geIdButton*      button;
-       geChannelStatus* status;
-       geButton*        arm;
-       geChannelButton* mainButton;
-       geButton*        mute;
-       geButton*        solo;
-       geDial*          vol;
-#ifdef WITH_VST
-       geStatusButton*  fx;
-#endif
 };
 
 
index a93dee5c4ef43d76cf7eaf6d090f1636999af31c..ff5232e850ef3eeee9326872aabd743048218515 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 4a5958923a188f94651bd9ff754237b76ada4d76..95f34339e03aa6e25984239de95f35f3e2b61be8 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index d67abae7e72fcaa2705714c66d27df845532a2c1..7153e695110e5f57facaa9cf0b0f1520bf01aee5 100644 (file)
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
 using namespace giada;
 
 
-geChannelMode::geChannelMode(int x, int y, int w, int h, m::SampleChannel *ch,
-  const char *L)
-  : Fl_Menu_Button(x, y, w, h, L), ch(ch)
+geChannelMode::geChannelMode(int x, int y, int w, int h, m::SampleChannel *ch, 
+       const char *L)
+: Fl_Menu_Button(x, y, w, h, L), ch(ch)
 {
-  box(G_CUSTOM_BORDER_BOX);
-  textsize(G_GUI_FONT_SIZE_BASE);
-  textcolor(G_COLOR_LIGHT_2);
-  color(G_COLOR_GREY_2);
-
-  add("Loop . basic",      0, cb_changeMode, (void*) ChannelMode::LOOP_BASIC);
-  add("Loop . once",       0, cb_changeMode, (void*) ChannelMode::LOOP_ONCE);
-  add("Loop . once . bar", 0, cb_changeMode, (void*) ChannelMode::LOOP_ONCE_BAR);
-  add("Loop . repeat",     0, cb_changeMode, (void*) ChannelMode::LOOP_REPEAT);
-  add("Oneshot . basic",   0, cb_changeMode, (void*) ChannelMode::SINGLE_BASIC);
-  add("Oneshot . press",   0, cb_changeMode, (void*) ChannelMode::SINGLE_PRESS);
-  add("Oneshot . retrig",  0, cb_changeMode, (void*) ChannelMode::SINGLE_RETRIG);
-  add("Oneshot . endless", 0, cb_changeMode, (void*) ChannelMode::SINGLE_ENDLESS);
+       box(G_CUSTOM_BORDER_BOX);
+       textsize(G_GUI_FONT_SIZE_BASE);
+       textcolor(G_COLOR_LIGHT_2);
+       color(G_COLOR_GREY_2);
+
+       add("Loop . basic",      0, cb_changeMode, (void*) ChannelMode::LOOP_BASIC);
+       add("Loop . once",       0, cb_changeMode, (void*) ChannelMode::LOOP_ONCE);
+       add("Loop . once . bar", 0, cb_changeMode, (void*) ChannelMode::LOOP_ONCE_BAR);
+       add("Loop . repeat",     0, cb_changeMode, (void*) ChannelMode::LOOP_REPEAT);
+       add("Oneshot . basic",   0, cb_changeMode, (void*) ChannelMode::SINGLE_BASIC);
+       add("Oneshot . press",   0, cb_changeMode, (void*) ChannelMode::SINGLE_PRESS);
+       add("Oneshot . retrig",  0, cb_changeMode, (void*) ChannelMode::SINGLE_RETRIG);
+       add("Oneshot . endless", 0, cb_changeMode, (void*) ChannelMode::SINGLE_ENDLESS);
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void geChannelMode::draw() {
-  fl_rect(x(), y(), w(), h(), G_COLOR_GREY_4);    // border
-  switch (ch->mode) {
-    case ChannelMode::LOOP_BASIC:
-      fl_draw_pixmap(loopBasic_xpm, x()+1, y()+1);
-      break;
-    case ChannelMode::LOOP_ONCE:
-      fl_draw_pixmap(loopOnce_xpm, x()+1, y()+1);
-      break;
-    case ChannelMode::LOOP_ONCE_BAR:
-      fl_draw_pixmap(loopOnceBar_xpm, x()+1, y()+1);
-      break;
-    case ChannelMode::LOOP_REPEAT:
-      fl_draw_pixmap(loopRepeat_xpm, x()+1, y()+1);
-      break;
-    case ChannelMode::SINGLE_BASIC:
-      fl_draw_pixmap(oneshotBasic_xpm, x()+1, y()+1);
-      break;
-    case ChannelMode::SINGLE_PRESS:
-      fl_draw_pixmap(oneshotPress_xpm, x()+1, y()+1);
-      break;
-    case ChannelMode::SINGLE_RETRIG:
-      fl_draw_pixmap(oneshotRetrig_xpm, x()+1, y()+1);
-      break;
-    case ChannelMode::SINGLE_ENDLESS:
-      fl_draw_pixmap(oneshotEndless_xpm, x()+1, y()+1);
-      break;
-  }
+void geChannelMode::draw() 
+{
+       fl_rect(x(), y(), w(), h(), G_COLOR_GREY_4);    // border
+       switch (ch->mode) {
+               case ChannelMode::LOOP_BASIC:
+                       fl_draw_pixmap(loopBasic_xpm, x()+1, y()+1);
+                       break;
+               case ChannelMode::LOOP_ONCE:
+                       fl_draw_pixmap(loopOnce_xpm, x()+1, y()+1);
+                       break;
+               case ChannelMode::LOOP_ONCE_BAR:
+                       fl_draw_pixmap(loopOnceBar_xpm, x()+1, y()+1);
+                       break;
+               case ChannelMode::LOOP_REPEAT:
+                       fl_draw_pixmap(loopRepeat_xpm, x()+1, y()+1);
+                       break;
+               case ChannelMode::SINGLE_BASIC:
+                       fl_draw_pixmap(oneshotBasic_xpm, x()+1, y()+1);
+                       break;
+               case ChannelMode::SINGLE_PRESS:
+                       fl_draw_pixmap(oneshotPress_xpm, x()+1, y()+1);
+                       break;
+               case ChannelMode::SINGLE_RETRIG:
+                       fl_draw_pixmap(oneshotRetrig_xpm, x()+1, y()+1);
+                       break;
+               case ChannelMode::SINGLE_ENDLESS:
+                       fl_draw_pixmap(oneshotEndless_xpm, x()+1, y()+1);
+                       break;
+       }
 }
 
 
@@ -104,10 +105,10 @@ void geChannelMode::cb_changeMode(Fl_Widget *v, void *p) { ((geChannelMode*)v)->
 
 void geChannelMode::__cb_changeMode(int mode)
 {
-  ch->mode = static_cast<ChannelMode>(mode);
+       ch->mode = static_cast<ChannelMode>(mode);
 
-  /* What to do when the channel is playing and you change the mode? Nothing, 
-  since v0.5.3. Just refresh the action editor window, in case it's open. */
+       /* What to do when the channel is playing and you change the mode? Nothing, 
+       since v0.5.3. Just refresh the action editor window, in case it's open. */
 
-  gu_refreshActionEditor();
+       u::gui::refreshActionEditor();
 }
index 248c2f57684e4817cf2d5aceeb187ea39bf4674d..03a2bbfb6dab6be24c80d1aee14bb4a7c68ed22a 100644 (file)
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index e5171e3e8b6e938ea06a2ea3b52d3b5cfa13500a..63653941569b50c8a21d9c7eb4087886ebcad0e4 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 8e8bd5e89151bcc226ab076379dd42a1c5a5846b..44d6ccce20ec995e31f00f030463ec73cd47cd4b 100644 (file)
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index b63f2f214b2939483551c2102a60ab5a6f2b4729..f925885201910dbb729cce07e5989251c118341a 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -34,7 +34,7 @@
 #include "../../../../utils/log.h"
 #include "../../../../utils/fs.h"
 #include "../../../../utils/string.h"
-#include "../../../dialogs/gd_warnings.h"
+#include "../../../dialogs/warnings.h"
 #include "../../../elems/basics/boxtypes.h"
 #include "../../../elems/basics/resizerBar.h"
 #include "keyboard.h"
@@ -48,7 +48,7 @@ using std::string;
 using namespace giada;
 
 
-geColumn::geColumn(int X, int Y, int W, int H, int index, geKeyboard* parent)
+geColumn::geColumn(int X, int Y, int W, int H, int index, v::geKeyboard* parent)
        : Fl_Group(X, Y, W, H), 
                m_parent(parent), 
                m_index (index)
@@ -105,12 +105,12 @@ int geColumn::handle(int e)
                        return 1;
                }
                case FL_PASTE: {              // handle actual drop (paste) operation
-                       vector<string> paths;
-                       gu_split(Fl::event_text(), "\n", &paths);
+                       vector<string> paths = u::string::split(Fl::event_text(), "\n");
                        bool fails = false;
                        int result = 0;
                        for (string& path : paths) {
                                gu_log("[geColumn::handle] loading %s...\n", path.c_str());
+                               // TODO - c::channel::addAndLoad(...)
                                m::SampleChannel* c = static_cast<m::SampleChannel*>(c::channel::addChannel(
                                        m_index, ChannelType::SAMPLE, G_GUI_CHANNEL_H_1));
                                result = c::channel::loadChannel(c, gu_stripFileUrl(path));
index b980100081c3b70dfdc30ed2e13f4fd2dc85db8e..209bc9c26c09c84ea407ed584307d67dfc5c99bc 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
 class geButton;
 class geChannel;
 class geResizerBar;
+namespace giada {
+namespace v 
+{
 class geKeyboard;
+}}
 
 
 class geColumn : public Fl_Group
@@ -47,13 +51,13 @@ private:
 
        geButton*     m_addChannelBtn;
        geResizerBar* m_resizer;
-       geKeyboard*   m_parent;
+       giada::v::geKeyboard* m_parent;
 
        int m_index;
 
 public:
 
-       geColumn(int x, int y, int w, int h, int index, geKeyboard* parent);
+       geColumn(int x, int y, int w, int h, int index, giada::v::geKeyboard* parent);
        ~geColumn();
 
        /* addChannel
index 10bfbb95bd7182c9c73a2df4349ee0c43cd935e7..8ca0a028caaf8a7aa9a96f13502f491f84ac2ec2 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -29,7 +29,8 @@
 #include "../../../../glue/transport.h"
 #include "../../../../glue/io.h"
 #include "../../../../utils/log.h"
-#include "../../../dialogs/gd_warnings.h"
+#include "../../../dialogs/warnings.h"
+#include "../../../dispatcher.h"
 #include "../../basics/boxtypes.h"
 #include "column.h"
 #include "sampleChannel.h"
@@ -37,9 +38,9 @@
 #include "keyboard.h"
 
 
-using namespace giada;
-
-
+namespace giada {
+namespace v
+{
 int geKeyboard::indexColumn = 0;
 
 
@@ -47,11 +48,8 @@ int geKeyboard::indexColumn = 0;
 
 
 geKeyboard::geKeyboard(int X, int Y, int W, int H)
-: Fl_Scroll    (X, Y, W, H),
-       bckspcPressed(false),
-       endPressed   (false),
-       spacePressed (false),
-       addColumnBtn (nullptr)
+: Fl_Scroll     (X, Y, W, H),
+       addColumnBtn(nullptr)
 {
        color(G_COLOR_GREY_1);
        type(Fl_Scroll::BOTH_ALWAYS);
@@ -212,74 +210,22 @@ geColumn* geKeyboard::getColumnByIndex(int index)
 
 /* -------------------------------------------------------------------------- */
 
-/* TODO - the following event handling for play, stop, rewind, start rec and
-so on should be moved to the proper widget: gdMainWindow or (better) geController. */
 
 int geKeyboard::handle(int e)
 {
-       using namespace giada::c;
-
-       int ret = Fl_Group::handle(e);  // assume the buttons won't handle the Keyboard events
        switch (e) {
                case FL_FOCUS:
                case FL_UNFOCUS: {
-                       ret = 1;                        // enables receiving Keyboard events
-                       break;
+                       return 1;               // Enables receiving Keyboard events
                }
-               case FL_SHORTCUT:           // in case widget that isn't ours has focus
+               case FL_SHORTCUT:           // In case widget that isn't ours has focus
                case FL_KEYDOWN:            // Keyboard key pushed
                case FL_KEYUP: {            // Keyboard key released
-
-                       /* rewind session. Avoid retrigs */
-
-                       if (e == FL_KEYDOWN) {
-                               if (Fl::event_key() == FL_BackSpace && !bckspcPressed) {
-                                       bckspcPressed = true;
-                                       transport::rewindSeq(false);          // not from GUI
-                                       ret = 1;
-                                       break;
-                               }
-                               else if (Fl::event_key() == FL_End && !endPressed) {
-                                       endPressed = true;
-                                       io::startStopInputRec(false);  // not from GUI
-                                       ret = 1;
-                                       break;
-                               }
-                               else if (Fl::event_key() == FL_Enter && !enterPressed) {
-                                       enterPressed = true;
-                                       io::startStopActionRec(false); // not from GUI
-                                       ret = 1;
-                                       break;
-                               }
-                               else if (Fl::event_key() == ' ' && !spacePressed) {
-                                       spacePressed = true;
-                                       transport::startStopSeq(false);      // unot from GUI
-                                       ret = 1;
-                                       break;
-                               }
-                       }
-                       else if (e == FL_KEYUP) {
-                               if (Fl::event_key() == FL_BackSpace)
-                                       bckspcPressed = false;
-                               else if (Fl::event_key() == FL_End)
-                                       endPressed = false;
-                               else if (Fl::event_key() == ' ')
-                                       spacePressed = false;
-                               else if (Fl::event_key() == FL_Enter)
-                                       enterPressed = false;
-                       }
-
-                       /* Walk button arrays, trying to match button's label with the Keyboard event.
-                        * If found, set that button's value() based on up/down event,
-                        * and invoke that button's callback() */
-
-                       for (unsigned i=0; i<columns.size(); i++)
-                               for (int k=1; k<columns.at(i)->children(); k++)
-                                       ret &= static_cast<geChannel*>(columns.at(i)->child(k))->keyPress(e);
-                       break;
+                       dispatcher::dispatchKey(e);
+                       return 1;
                }
        }
-       return ret;
+       return Fl_Group::handle(e);     // Assume the buttons won't handle the Keyboard events
 }
 
 
@@ -399,3 +345,5 @@ geColumn* geKeyboard::getColumn(int i)
 {
   return columns.at(i);
 }
+
+}} // giada::v::
\ No newline at end of file
index 339394e5ebc7e9240e7b1084e5542993e11b545a..daac4c8352ba282c734d71a97bc5555e301d5318 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -41,6 +41,9 @@ class geChannel;
 class geSampleChannel;
 
 
+namespace giada {
+namespace v
+{
 class geKeyboard : public Fl_Scroll
 {
 private:
@@ -56,11 +59,6 @@ private:
        static void cb_addColumn  (Fl_Widget* v, void* p);
        inline void __cb_addColumn(int width=G_DEFAULT_COLUMN_WIDTH);
 
-       bool bckspcPressed;
-       bool endPressed;
-       bool spacePressed;
-       bool enterPressed;
-
        /* indexColumn
         * the last index used for column. */
 
@@ -159,6 +157,7 @@ public:
 
        int getColumnWidth(int i);
 };
+}} // giada::v::
 
 
 #endif
index ab2c670ff3bab8eff6ef5a19faff672b031a1990..862b1727f084aa9a97e469b60d0c630068bf41c2 100644 (file)
 #include "../../../../glue/channel.h"
 #include "../../../../glue/io.h"
 #include "../../../../glue/recorder.h"
-#include "../../../dialogs/gd_mainWindow.h"
+#include "../../../dispatcher.h"
+#include "../../../dialogs/mainWindow.h"
 #include "../../../dialogs/channelNameInput.h"
-#include "../../../dialogs/gd_warnings.h"
-#include "../../../dialogs/gd_keyGrabber.h"
+#include "../../../dialogs/warnings.h"
+#include "../../../dialogs/keyGrabber.h"
 #include "../../../dialogs/pluginList.h"
 #include "../../../dialogs/actionEditor/midiActionEditor.h"
 #include "../../../dialogs/midiIO/midiInputChannel.h"
 #include "../../../dialogs/midiIO/midiOutputMidiCh.h"
 #include "../../basics/boxtypes.h"
-#include "../../basics/idButton.h"
+#include "../../basics/button.h"
 #include "../../basics/statusButton.h"
 #include "../../basics/dial.h"
 #include "column.h"
@@ -102,19 +103,19 @@ void menuCallback(Fl_Widget* w, void* v)
                case Menu::__END_RESIZE_SUBMENU__:
                        break;
                case Menu::EDIT_ACTIONS:
-                       gu_openSubWindow(G_MainWin, new v::gdMidiActionEditor(ch), WID_ACTION_EDITOR);
+                       u::gui::openSubWindow(G_MainWin, new v::gdMidiActionEditor(ch), WID_ACTION_EDITOR);
                        break;
                case Menu::CLEAR_ACTIONS_ALL:
                        c::recorder::clearAllActions(gch);
                        break;
                case Menu::SETUP_KEYBOARD_INPUT:
-                       gu_openSubWindow(G_MainWin, new gdKeyGrabber(gch->ch), 0);
+                       u::gui::openSubWindow(G_MainWin, new gdKeyGrabber(gch->ch), 0);
                        break;
                case Menu::SETUP_MIDI_INPUT:
-                       gu_openSubWindow(G_MainWin, new gdMidiInputChannel(gch->ch), 0);
+                       u::gui::openSubWindow(G_MainWin, new gdMidiInputChannel(gch->ch), 0);
                        break;
                case Menu::SETUP_MIDI_OUTPUT:
-                       gu_openSubWindow(G_MainWin, new gdMidiOutputMidiCh(ch), 0);
+                       u::gui::openSubWindow(G_MainWin, new gdMidiOutputMidiCh(ch), 0);
                        break;
                case Menu::RESIZE_H1:
                        gch->changeSize(G_GUI_CHANNEL_H_1);
@@ -136,7 +137,7 @@ void menuCallback(Fl_Widget* w, void* v)
                        c::channel::cloneChannel(gch->ch);
                        break;          
                case Menu::RENAME_CHANNEL:
-                       gu_openSubWindow(G_MainWin, new gdChannelNameInput(gch->ch), WID_SAMPLE_NAME);
+                       u::gui::openSubWindow(G_MainWin, new gdChannelNameInput(gch->ch), WID_SAMPLE_NAME);
                        break;
                case Menu::DELETE_CHANNEL:
                        c::channel::deleteChannel(gch->ch);
@@ -161,7 +162,7 @@ geMidiChannel::geMidiChannel(int X, int Y, int W, int H, m::MidiChannel* ch)
        int delta = 120; // (5 widgets * G_GUI_UNIT) + (5 paddings * 4)
 #endif
 
-       button     = new geIdButton(x(), y(), G_GUI_UNIT, G_GUI_UNIT, "", channelStop_xpm, channelPlay_xpm);
+       button     = new geButton(x(), y(), G_GUI_UNIT, G_GUI_UNIT, "", channelStop_xpm, channelPlay_xpm);
        arm        = new geButton(button->x()+button->w()+4, y(), G_GUI_UNIT, G_GUI_UNIT, "", armOff_xpm, armOn_xpm);
        mainButton = new geMidiChannelButton(arm->x()+arm->w()+4, y(), w() - delta, H, "-- MIDI --");
        mute       = new geButton(mainButton->x()+mainButton->w()+4, y(), G_GUI_UNIT, G_GUI_UNIT, "", muteOff_xpm, muteOn_xpm);
@@ -217,10 +218,7 @@ void geMidiChannel::cb_openMenu(Fl_Widget* v, void* p) { ((geMidiChannel*)p)->cb
 
 void geMidiChannel::cb_button()
 {
-       using namespace giada;
-       
-       if (button->value())
-               c::io::keyPress(static_cast<m::MidiChannel*>(ch), Fl::event_ctrl(), Fl::event_shift(), 0);
+       v::dispatcher::dispatchTouch(ch, button->value());
 }
 
 
@@ -272,7 +270,7 @@ void geMidiChannel::cb_openMenu()
 
 void geMidiChannel::refresh()
 {
-       setColorsByStatus(ch->status, ch->recStatus);
+       setColorsByStatus();
        if (m::recorder::isActive() && ch->armed)
                mainButton->setActionRecordMode();
        mainButton->redraw();
@@ -303,7 +301,7 @@ void geMidiChannel::update()
                label = mch->name.c_str();
 
        if (mch->midiOut) 
-               label += " (ch " + gu_iToString(mch->midiOutChan + 1) + " out)";
+               label += " (ch " + u::string::iToString(mch->midiOutChan + 1) + " out)";
 
        mainButton->label(label.c_str());
 
index 43b9ce8addb77e7254793f7d2546278de1677136..e917506e27cc923cb3ddd4bf277a6ec587586657 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 0bfdcd07975343d4249d74ef1f8c82be8da17d6b..4308d5932bce1baed902572edade5965796e87c4 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index c461ff1dd6e8626bfc770a16a300c24e712400b5..225aa327026bb1b51beca9208f0e9d503525b0d0 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 785f0f927f3b7f8f76588f25336b73da3eb74864..2bb03a02e15ae71807bf0b123f25a1505234fff1 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
 #include "../../../../glue/recorder.h"
 #include "../../../../glue/storage.h"
 #include "../../../../utils/gui.h"
-#include "../../../dialogs/gd_mainWindow.h"
-#include "../../../dialogs/gd_keyGrabber.h"
+#include "../../../dispatcher.h"
+#include "../../../dialogs/mainWindow.h"
+#include "../../../dialogs/keyGrabber.h"
 #include "../../../dialogs/sampleEditor.h"
 #include "../../../dialogs/channelNameInput.h"
-#include "../../../dialogs/gd_warnings.h"
+#include "../../../dialogs/warnings.h"
 #include "../../../dialogs/actionEditor/sampleActionEditor.h"
 #include "../../../dialogs/browser/browserSave.h"
 #include "../../../dialogs/browser/browserLoad.h"
 #include "../../../dialogs/midiIO/midiOutputSampleCh.h"
 #include "../../../dialogs/midiIO/midiInputChannel.h"
 #include "../../basics/boxtypes.h"
-#include "../../basics/idButton.h"
+#include "../../basics/button.h"
 #include "../../basics/statusButton.h"
 #include "../../basics/dial.h"
 #include "channelStatus.h"
@@ -115,15 +116,15 @@ void menuCallback(Fl_Widget* w, void* v)
                case Menu::LOAD_SAMPLE: {
                        gdWindow *w = new gdBrowserLoad(m::conf::browserX, m::conf::browserY,
                                m::conf::browserW, m::conf::browserH, "Browse sample",
-                               m::conf::samplePath.c_str(), glue_loadSample, gch->ch);
-                       gu_openSubWindow(G_MainWin, w, WID_FILE_BROWSER);
+                               m::conf::samplePath.c_str(), c::storage::loadSample, gch->ch);
+                       u::gui::openSubWindow(G_MainWin, w, WID_FILE_BROWSER);
                        break;
                }
                case Menu::EXPORT_SAMPLE: {
                        gdWindow *w = new gdBrowserSave(m::conf::browserX, m::conf::browserY,
                                m::conf::browserW, m::conf::browserH, "Save sample",
-                               m::conf::samplePath.c_str(), "", glue_saveSample, gch->ch);
-                       gu_openSubWindow(G_MainWin, w, WID_FILE_BROWSER);
+                               m::conf::samplePath.c_str(), "", c::storage::saveSample, gch->ch);
+                       u::gui::openSubWindow(G_MainWin, w, WID_FILE_BROWSER);
                        break;
                }
                case Menu::SETUP_KEYBOARD_INPUT: {
@@ -131,19 +132,19 @@ void menuCallback(Fl_Widget* w, void* v)
                        break;
                }
                case Menu::SETUP_MIDI_INPUT: {
-                       gu_openSubWindow(G_MainWin, new gdMidiInputChannel(gch->ch), 0);
+                       u::gui::openSubWindow(G_MainWin, new gdMidiInputChannel(gch->ch), 0);
                        break;
                }
                case Menu::SETUP_MIDI_OUTPUT: {
-                       gu_openSubWindow(G_MainWin, new gdMidiOutputSampleCh(ch), 0);
+                       u::gui::openSubWindow(G_MainWin, new gdMidiOutputSampleCh(ch), 0);
                        break;
                }
                case Menu::EDIT_SAMPLE: {
-                       gu_openSubWindow(G_MainWin, new gdSampleEditor(ch), WID_SAMPLE_EDITOR);
+                       u::gui::openSubWindow(G_MainWin, new gdSampleEditor(ch), WID_SAMPLE_EDITOR);
                        break;
                }
                case Menu::EDIT_ACTIONS: {
-                       gu_openSubWindow(G_MainWin, new v::gdSampleActionEditor(ch), WID_ACTION_EDITOR);
+                       u::gui::openSubWindow(G_MainWin, new v::gdSampleActionEditor(ch), WID_ACTION_EDITOR);
                        break;
                }
                case Menu::CLEAR_ACTIONS:
@@ -188,7 +189,7 @@ void menuCallback(Fl_Widget* w, void* v)
                        break;
                }
                case Menu::RENAME_CHANNEL: {
-                       gu_openSubWindow(G_MainWin, new gdChannelNameInput(gch->ch), WID_SAMPLE_NAME);
+                       u::gui::openSubWindow(G_MainWin, new gdChannelNameInput(gch->ch), WID_SAMPLE_NAME);
                        break;
                }
                case Menu::FREE_CHANNEL: {
@@ -215,7 +216,7 @@ geSampleChannel::geSampleChannel(int X, int Y, int W, int H, m::SampleChannel* c
 {
        begin();
 
-       button      = new geIdButton(x(), y(), G_GUI_UNIT, G_GUI_UNIT, "", channelStop_xpm, channelPlay_xpm);
+       button      = new geButton(x(), y(), G_GUI_UNIT, G_GUI_UNIT, "", channelStop_xpm, channelPlay_xpm);
        arm         = new geButton(button->x()+button->w()+4, y(), G_GUI_UNIT, G_GUI_UNIT, "", armOff_xpm, armOn_xpm);
        status      = new geChannelStatus(arm->x()+arm->w()+4, y(), G_GUI_UNIT, H, ch);
        mainButton  = new geSampleChannelButton(status->x()+status->w()+4, y(), G_GUI_UNIT, H, "-- no sample --");
@@ -269,9 +270,9 @@ geSampleChannel::geSampleChannel(int X, int Y, int W, int H, m::SampleChannel* c
 /* -------------------------------------------------------------------------- */
 
 
-void geSampleChannel::cb_button      (Fl_Widget* v, void* p) { ((geSampleChannel*)p)->cb_button(); }
-void geSampleChannel::cb_openMenu    (Fl_Widget* v, void* p) { ((geSampleChannel*)p)->cb_openMenu(); }
-void geSampleChannel::cb_readActions (Fl_Widget* v, void* p) { ((geSampleChannel*)p)->cb_readActions(); }
+void geSampleChannel::cb_button     (Fl_Widget* v, void* p) { ((geSampleChannel*)p)->cb_button(); }
+void geSampleChannel::cb_openMenu   (Fl_Widget* v, void* p) { ((geSampleChannel*)p)->cb_openMenu(); }
+void geSampleChannel::cb_readActions(Fl_Widget* v, void* p) { ((geSampleChannel*)p)->cb_readActions(); }
 
 
 /* -------------------------------------------------------------------------- */
@@ -279,12 +280,7 @@ void geSampleChannel::cb_readActions (Fl_Widget* v, void* p) { ((geSampleChannel
 
 void geSampleChannel::cb_button()
 {
-       using namespace giada;
-
-       if (button->value())    // pushed, max velocity (127 i.e. 0x7f)
-               c::io::keyPress(ch, Fl::event_ctrl(), Fl::event_shift(), 0x7F);
-       else                    // released
-               c::io::keyRelease(ch, Fl::event_ctrl(), Fl::event_shift());
+       v::dispatcher::dispatchTouch(ch, button->value());
 }
 
 
@@ -381,7 +377,7 @@ void geSampleChannel::refresh()
        if (!mainButton->visible()) // mainButton invisible? status too (see below)
                return;
 
-       setColorsByStatus(ch->status, ch->recStatus);
+       setColorsByStatus();
 
        if (static_cast<m::SampleChannel*>(ch)->wave != nullptr) {
                if (m::mixer::recording && ch->armed)
index 0d43db954a75b0bdcfb71fd68592d1b91c50b618..24e02a63b3a7361266610a5f63004f60912cc32e 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index c5d631725e7145b65081bd3514007f5cb8f1dbe8..25b35bc8c0a7984ac70f82286d2347565a5478f8 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -31,7 +31,7 @@
 #include "../../../../utils/string.h"
 #include "../../../../utils/fs.h"
 #include "../../../../glue/channel.h"
-#include "../../../dialogs/gd_mainWindow.h"
+#include "../../../dialogs/mainWindow.h"
 #include "sampleChannel.h"
 #include "keyboard.h"
 #include "sampleChannelButton.h"
@@ -66,7 +66,7 @@ int geSampleChannelButton::handle(int e)
                case FL_PASTE: {
                        geSampleChannel*  gch = static_cast<geSampleChannel*>(parent());
                        m::SampleChannel* ch  = static_cast<m::SampleChannel*>(gch->ch);
-                       int result = c::channel::loadChannel(ch, gu_trim(gu_stripFileUrl(Fl::event_text())));
+                       int result = c::channel::loadChannel(ch, u::string::trim(gu_stripFileUrl(Fl::event_text())));
                        if (result != G_RES_OK)
                                G_MainWin->keyboard->printChannelMessage(result);
                        ret = 1;
index b814fa81154ebe2bb17147456ccecc58810d9a50..213581aedf6d4b30e12d7d4fc4d1bd85e3a463ea 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index e246dd83bfbe1f68edf91434d84a07db02c7c416..9affcef4f010b654fda2dfde087440c5220a2689 100644 (file)
@@ -4,7 +4,7 @@
 *
 * -----------------------------------------------------------------------------
 *
-* Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+* Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
 *
 * This file is part of Giada - Your Hardcore Loopmachine.
 *
 #include "../../elems/soundMeter.h"
 #include "../../elems/basics/statusButton.h"
 #include "../../elems/basics/dial.h"
-#include "../../dialogs/gd_mainWindow.h"
+#include "../../dialogs/mainWindow.h"
 #include "../../dialogs/pluginList.h"
 #include "mainIO.h"
 
 
-extern gdMainWindow *G_MainWin;
-
-
-using namespace giada::m;
+extern gdMainWindow* G_MainWin;
 
 
+namespace giada {
+namespace v
+{
 geMainIO::geMainIO(int x, int y)
        : Fl_Group(x, y, 396, 20)
 {
@@ -52,17 +52,17 @@ geMainIO::geMainIO(int x, int y)
 
 #if defined(WITH_VST)
        masterFxIn  = new geStatusButton  (x, y, 20, 20, fxOff_xpm, fxOn_xpm);
-       inVol               = new geDial      (masterFxIn->x()+masterFxIn->w()+4, y, 20, 20);
+       inVol       = new geDial      (masterFxIn->x()+masterFxIn->w()+4, y, 20, 20);
        inMeter     = new geSoundMeter(inVol->x()+inVol->w()+4, y+4, 140, 12);
        inToOut     = new geButton   (inMeter->x()+inMeter->w()+4, y+4, 12, 12, "", inputToOutputOff_xpm, inputToOutputOn_xpm);
        outMeter    = new geSoundMeter(inToOut->x()+inToOut->w()+4, y+4, 140, 12);
-       outVol            = new geDial      (outMeter->x()+outMeter->w()+4, y, 20, 20);
+       outVol      = new geDial      (outMeter->x()+outMeter->w()+4, y, 20, 20);
        masterFxOut = new geStatusButton  (outVol->x()+outVol->w()+4, y, 20, 20, fxOff_xpm, fxOn_xpm);
 #else
-       inVol               = new geDial      (x+62, y, 20, 20);
+       inVol       = new geDial      (x+62, y, 20, 20);
        inMeter     = new geSoundMeter(inVol->x()+inVol->w()+4, y+5, 140, 12);
        outMeter    = new geSoundMeter(inMeter->x()+inMeter->w()+4, y+5, 140, 12);
-       outVol            = new geDial      (outMeter->x()+outMeter->w()+4, y, 20, 20);
+       outVol      = new geDial      (outMeter->x()+outMeter->w()+4, y, 20, 20);
 #endif
 
        end();
@@ -70,9 +70,9 @@ geMainIO::geMainIO(int x, int y)
        resizable(nullptr);   // don't resize any widget
 
        outVol->callback(cb_outVol, (void*)this);
-       outVol->value(mixer::outVol);
+       outVol->value(m::mixer::outVol.load());
        inVol->callback(cb_inVol, (void*)this);
-       inVol->value(mixer::inVol);
+       inVol->value(m::mixer::inVol.load());
 
 #ifdef WITH_VST
        masterFxOut->callback(cb_masterFxOut, (void*)this);
@@ -86,30 +86,30 @@ geMainIO::geMainIO(int x, int y)
 /* -------------------------------------------------------------------------- */
 
 
-void geMainIO::cb_outVol     (Fl_Widget *v, void *p)   { ((geMainIO*)p)->__cb_outVol(); }
-void geMainIO::cb_inVol      (Fl_Widget *v, void *p)   { ((geMainIO*)p)->__cb_inVol(); }
+void geMainIO::cb_outVol     (Fl_Widget *v, void *p)   { ((geMainIO*)p)->cb_outVol(); }
+void geMainIO::cb_inVol      (Fl_Widget *v, void *p)   { ((geMainIO*)p)->cb_inVol(); }
 #ifdef WITH_VST
-void geMainIO::cb_masterFxOut(Fl_Widget *v, void *p)    { ((geMainIO*)p)->__cb_masterFxOut(); }
-void geMainIO::cb_masterFxIn (Fl_Widget *v, void *p)    { ((geMainIO*)p)->__cb_masterFxIn(); }
-void geMainIO::cb_inToOut    (Fl_Widget *v, void *p)    { ((geMainIO*)p)->__cb_inToOut(); }
+void geMainIO::cb_masterFxOut(Fl_Widget *v, void *p)    { ((geMainIO*)p)->cb_masterFxOut(); }
+void geMainIO::cb_masterFxIn (Fl_Widget *v, void *p)    { ((geMainIO*)p)->cb_masterFxIn(); }
+void geMainIO::cb_inToOut    (Fl_Widget *v, void *p)    { ((geMainIO*)p)->cb_inToOut(); }
 #endif
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void geMainIO::__cb_outVol()
+void geMainIO::cb_outVol()
 {
-       glue_setOutVol(outVol->value());
+       c::main::setOutVol(outVol->value());
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void geMainIO::__cb_inVol()
+void geMainIO::cb_inVol()
 {
-       glue_setInVol(inVol->value());
+       c::main::setInVol(inVol->value());
 }
 
 
@@ -117,19 +117,19 @@ void geMainIO::__cb_inVol()
 
 
 #ifdef WITH_VST
-void geMainIO::__cb_masterFxOut()
+void geMainIO::cb_masterFxOut()
 {
-       gu_openSubWindow(G_MainWin, new gdPluginList(pluginHost::MASTER_OUT), WID_FX_LIST);
+       u::gui::openSubWindow(G_MainWin, new gdPluginList(m::pluginHost::StackType::MASTER_OUT), WID_FX_LIST);
 }
 
-void geMainIO::__cb_masterFxIn()
+void geMainIO::cb_masterFxIn()
 {
-       gu_openSubWindow(G_MainWin, new gdPluginList(pluginHost::MASTER_IN), WID_FX_LIST);
+       u::gui::openSubWindow(G_MainWin, new gdPluginList(m::pluginHost::StackType::MASTER_IN), WID_FX_LIST);
 }
 
-void geMainIO::__cb_inToOut()
+void geMainIO::cb_inToOut()
 {
-       mixer::inToOut = inToOut->value();
+       m::mixer::inToOut = inToOut->value();
 }
 #endif
 
@@ -175,8 +175,10 @@ void geMainIO::setMasterFxInFull(bool v)
 
 void geMainIO::refresh()
 {
-       outMeter->mixerPeak = mixer::peakOut;
-       inMeter->mixerPeak  = mixer::peakIn;
+       outMeter->mixerPeak = m::mixer::peakOut.load();
+       inMeter->mixerPeak  = m::mixer::peakIn.load();
        outMeter->redraw();
        inMeter->redraw();
 }
+
+}} // giada::v::
\ No newline at end of file
index 5debc8e9cd6533531d6fa8f2161f299e1349ea83..cec4ad726012e21f4f57d32b8c405c7b9495777f 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -38,34 +38,37 @@ class geStatusButton;
 class geButton;
 #endif
 
+namespace giada {
+namespace v
+{
 class geMainIO : public Fl_Group
 {
 private:
 
-       geSoundMeter *outMeter;
-       geSoundMeter *inMeter;
-       geDial        *outVol;
-       geDial        *inVol;
+       geSoundMeteroutMeter;
+       geSoundMeterinMeter;
+       geDial*       outVol;
+       geDial*       inVol;
 #ifdef WITH_VST
-  geStatusButton *masterFxOut;
-  geStatusButton *masterFxIn;
-  geButton       *inToOut;
+  geStatusButtonmasterFxOut;
+  geStatusButtonmasterFxIn;
+  geButton*       inToOut;
 #endif
 
-       static void cb_outVol     (Fl_Widget *v, void *p);
-       static void cb_inVol      (Fl_Widget *v, void *p);
+       static void cb_outVol     (Fl_Widget* v, void* p);
+       static void cb_inVol      (Fl_Widget* v, void* p);
 #ifdef WITH_VST
-       static void cb_masterFxOut(Fl_Widget *v, void *p);
-       static void cb_masterFxIn (Fl_Widget *v, void *p);
-       static void cb_inToOut    (Fl_Widget *v, void *p);
+       static void cb_masterFxOut(Fl_Widget* v, void* p);
+       static void cb_masterFxIn (Fl_Widget* v, void* p);
+       static void cb_inToOut    (Fl_Widget* v, void* p);
 #endif
 
-       inline void __cb_outVol     ();
-       inline void __cb_inVol      ();
+       void cb_outVol     ();
+       void cb_inVol      ();
 #ifdef WITH_VST
-       inline void __cb_masterFxOut();
-       inline void __cb_masterFxIn ();
-       inline void __cb_inToOut    ();
+       void cb_masterFxOut();
+       void cb_masterFxIn ();
+       void cb_inToOut    ();
 #endif
 
 public:
@@ -81,5 +84,7 @@ public:
        void setMasterFxInFull(bool v);
 #endif
 };
+}} // giada::v::
+
 
 #endif
index 5a165dc79d1d27b681583bcb40894601ecc563b9..0416ca4f3ab878c8a9129179cc61c62a690be55f 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
 #include "../../../glue/main.h"
 #include "../../elems/basics/boxtypes.h"
 #include "../../elems/basics/button.h"
-#include "../../dialogs/gd_mainWindow.h"
+#include "../../dialogs/mainWindow.h"
 #include "../../dialogs/about.h"
-#include "../../dialogs/gd_config.h"
-#include "../../dialogs/gd_warnings.h"
+#include "../../dialogs/config.h"
+#include "../../dialogs/warnings.h"
 #include "../../dialogs/browser/browserLoad.h"
 #include "../../dialogs/browser/browserSave.h"
 #include "../../dialogs/midiIO/midiInputMaster.h"
@@ -52,9 +52,9 @@
 extern gdMainWindow* G_MainWin;
 
 
-using namespace giada::m;
-
-
+namespace giada {
+namespace v
+{
 geMainMenu::geMainMenu(int x, int y)
        : Fl_Group(x, y, 300, 20)
 {
@@ -79,35 +79,37 @@ geMainMenu::geMainMenu(int x, int y)
 /* -------------------------------------------------------------------------- */
 
 
-void geMainMenu::cb_about (Fl_Widget* v, void* p) { ((geMainMenu*)p)->__cb_about(); }
-void geMainMenu::cb_config(Fl_Widget* v, void* p) { ((geMainMenu*)p)->__cb_config(); }
-void geMainMenu::cb_file  (Fl_Widget* v, void* p) { ((geMainMenu*)p)->__cb_file(); }
-void geMainMenu::cb_edit  (Fl_Widget* v, void* p) { ((geMainMenu*)p)->__cb_edit(); }
+void geMainMenu::cb_about (Fl_Widget* v, void* p) { ((geMainMenu*)p)->cb_about(); }
+void geMainMenu::cb_config(Fl_Widget* v, void* p) { ((geMainMenu*)p)->cb_config(); }
+void geMainMenu::cb_file  (Fl_Widget* v, void* p) { ((geMainMenu*)p)->cb_file(); }
+void geMainMenu::cb_edit  (Fl_Widget* v, void* p) { ((geMainMenu*)p)->cb_edit(); }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void geMainMenu::__cb_about()
+void geMainMenu::cb_about()
 {
-       gu_openSubWindow(G_MainWin, new gdAbout(), WID_ABOUT);
+       u::gui::openSubWindow(G_MainWin, new gdAbout(), WID_ABOUT);
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void geMainMenu::__cb_config()
+void geMainMenu::cb_config()
 {
-       gu_openSubWindow(G_MainWin, new gdConfig(400, 370), WID_CONFIG);
+       u::gui::openSubWindow(G_MainWin, new gdConfig(400, 370), WID_CONFIG);
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void geMainMenu::__cb_file()
+void geMainMenu::cb_file()
 {
+       using namespace giada::m;
+
        /* An Fl_Menu_Button is made of many Fl_Menu_Item */
 
        Fl_Menu_Item menu[] = {
@@ -128,10 +130,10 @@ void geMainMenu::__cb_file()
        if (!m) return;
 
        if (strcmp(m->label(), "Open patch or project...") == 0) {
-               gdWindow *childWin = new gdBrowserLoad(conf::browserX, conf::browserY,
+               gdWindowchildWin = new gdBrowserLoad(conf::browserX, conf::browserY,
                                conf::browserW, conf::browserH, "Load patch or project",
-                               conf::patchPath, glue_loadPatch, nullptr);
-               gu_openSubWindow(G_MainWin, childWin, WID_FILE_BROWSER);
+                               conf::patchPath, c::storage::loadPatch, nullptr);
+               u::gui::openSubWindow(G_MainWin, childWin, WID_FILE_BROWSER);
                return;
        }
        if (strcmp(m->label(), "Save patch...") == 0) {
@@ -140,15 +142,15 @@ void geMainMenu::__cb_file()
                                return;
                gdWindow *childWin = new gdBrowserSave(conf::browserX, conf::browserY,
                                conf::browserW, conf::browserH, "Save patch",
-                               conf::patchPath, patch::name, glue_savePatch, nullptr);
-               gu_openSubWindow(G_MainWin, childWin, WID_FILE_BROWSER);
+                               conf::patchPath, patch::name, c::storage::savePatch, nullptr);
+               u::gui::openSubWindow(G_MainWin, childWin, WID_FILE_BROWSER);
                return;
        }
        if (strcmp(m->label(), "Save project...") == 0) {
                gdWindow *childWin = new gdBrowserSave(conf::browserX, conf::browserY,
                                conf::browserW, conf::browserH, "Save project",
-                               conf::patchPath, patch::name, glue_saveProject, nullptr);
-               gu_openSubWindow(G_MainWin, childWin, WID_FILE_BROWSER);
+                               conf::patchPath, patch::name, c::storage::saveProject, nullptr);
+               u::gui::openSubWindow(G_MainWin, childWin, WID_FILE_BROWSER);
                return;
        }
        if (strcmp(m->label(), "Quit Giada") == 0) {
@@ -161,7 +163,7 @@ void geMainMenu::__cb_file()
 /* -------------------------------------------------------------------------- */
 
 
-void geMainMenu::__cb_edit()
+void geMainMenu::cb_edit()
 {
        Fl_Menu_Item menu[] = {
                {"Clear all samples"},
@@ -177,13 +179,13 @@ void geMainMenu::__cb_edit()
 
        menu[1].deactivate();
 
-       for (const Channel* ch : mixer::channels)
+       for (const m::Channel* ch : m::mixer::channels)
                if (ch->hasActions) {
                        menu[1].activate();
                        break;
                }
 
-       for (const Channel* ch : mixer::channels)
+       for (const m::Channel* ch : m::mixer::channels)
                if (ch->hasData()) {
                        menu[0].activate();
                        break;
@@ -202,20 +204,20 @@ void geMainMenu::__cb_edit()
                if (!gdConfirmWin("Warning", "Clear all samples: are you sure?"))
                        return;
                G_MainWin->delSubWindow(WID_SAMPLE_EDITOR);
-               glue_clearAllSamples();
+               c::main::clearAllSamples();
                return;
        }
        if (strcmp(m->label(), "Clear all actions") == 0) {
                if (!gdConfirmWin("Warning", "Clear all actions: are you sure?"))
                        return;
                G_MainWin->delSubWindow(WID_ACTION_EDITOR);
-               glue_clearAllActions();
+               c::main::clearAllActions();
                return;
        }
        if (strcmp(m->label(), "Reset to init state") == 0) {
                if (!gdConfirmWin("Warning", "Reset to init state: are you sure?"))
                        return;
-               glue_resetToInitState();
+               c::main::resetToInitState();
                return;
        }
        if (strcmp(m->label(), "Remove empty columns") == 0) {
@@ -223,7 +225,9 @@ void geMainMenu::__cb_edit()
                return;
        }
        if (strcmp(m->label(), "Setup global MIDI input...") == 0) {
-               gu_openSubWindow(G_MainWin, new gdMidiInputMaster(), 0);
+               u::gui::openSubWindow(G_MainWin, new gdMidiInputMaster(), 0);
                return;
        }
 }
+
+}} // giada::v::
\ No newline at end of file
index c6dde20a051d55d64e89608c3ee9a6ebf38fcc46..57e2b437f35a62fc17454d15bfa44d8fc0bfaa9e 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
 class geButton;
 
 
+namespace giada {
+namespace v
+{
 class geMainMenu : public Fl_Group
 {
 private:
 
-  geButton *file;
-  geButton *edit;
-  geButton *config;
-  geButton *about;
-
-       static void cb_about (Fl_Widget *v, void *p);
-       static void cb_config(Fl_Widget *v, void *p);
-       static void cb_file  (Fl_Widget *v, void *p);
-       static void cb_edit  (Fl_Widget *v, void *p);
+  geButton* file;
+  geButton* edit;
+  geButton* config;
+  geButton* about;
 
-       inline void __cb_about ();
-       inline void __cb_config();
-       inline void __cb_file  ();
-       inline void __cb_edit  ();
+       static void cb_about (Fl_Widget* v, void* p);
+       static void cb_config(Fl_Widget* v, void* p);
+       static void cb_file  (Fl_Widget* v, void* p);
+       static void cb_edit  (Fl_Widget* v, void* p);
+       void cb_about ();
+       void cb_config();
+       void cb_file  ();
+       void cb_edit  ();
 
 public:
 
        geMainMenu(int x, int y);
 };
+}} // giada::v::
 
 
 #endif
index 053fa895c7b11f204b313b0e249456e04aa55938..aa07f937ed729e552e2a8d36a2ef78c563ff3cf8 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
 #include "../../../utils/string.h"
 #include "../../elems/basics/button.h"
 #include "../../elems/basics/choice.h"
-#include "../../dialogs/gd_mainWindow.h"
+#include "../../dialogs/mainWindow.h"
 #include "../../dialogs/bpmInput.h"
 #include "../../dialogs/beatsInput.h"
 #include "mainTimer.h"
 
 
-extern gdMainWindow *G_MainWin;
+extern gdMainWindowG_MainWin;
 
 
 using std::string;
-using namespace giada::m;
 
 
+namespace giada {
+namespace v
+{
 geMainTimer::geMainTimer(int x, int y)
-       : Fl_Group(x, y, 180, 20)
+       : Fl_Group(x, y, 210, 20)
 {
        begin();
 
-       quantizer  = new geChoice(x, y, 40, 20, "", false);
-       bpm        = new geButton (quantizer->x()+quantizer->w()+4,  y, 40, 20);
-       meter      = new geButton (bpm->x()+bpm->w()+8,  y, 40, 20, "4/1");
-       multiplier = new geButton (meter->x()+meter->w()+4, y, 20, 20, "", multiplyOff_xpm, multiplyOn_xpm);
-       divider    = new geButton (multiplier->x()+multiplier->w()+4, y, 20, 20, "", divideOff_xpm, divideOn_xpm);
+       quantizer  = new geChoice(x, y, 50, 20, "", false);
+       bpm        = new geButton(quantizer->x()+quantizer->w()+4,  y, 50, 20);
+       meter      = new geButton(bpm->x()+bpm->w()+8,  y, 50, 20, "4/1");
+       multiplier = new geButton(meter->x()+meter->w()+4, y, 20, 20, "", multiplyOff_xpm, multiplyOn_xpm);
+       divider    = new geButton(multiplier->x()+multiplier->w()+4, y, 20, 20, "", divideOff_xpm, divideOn_xpm);
 
        end();
 
        resizable(nullptr);   // don't resize any widget
 
-       bpm->copy_label(gu_fToString(clock::getBpm(), 1).c_str());
+       bpm->copy_label(u::string::fToString(m::clock::getBpm(), 1).c_str());
        bpm->callback(cb_bpm, (void*)this);
 
        meter->callback(cb_meter, (void*)this);
@@ -97,7 +99,7 @@ void geMainTimer::cb_divider   (Fl_Widget* v, void* p) { ((geMainTimer*)p)->cb_d
 
 void geMainTimer::cb_bpm()
 {
-       gu_openSubWindow(G_MainWin, new gdBpmInput(bpm->label()), WID_BPM);
+       u::gui::openSubWindow(G_MainWin, new gdBpmInput(bpm->label()), WID_BPM);
 }
 
 
@@ -106,7 +108,7 @@ void geMainTimer::cb_bpm()
 
 void geMainTimer::cb_meter()
 {
-       gu_openSubWindow(G_MainWin, new gdBeatsInput(), WID_BEATS);
+       u::gui::openSubWindow(G_MainWin, new gdBeatsInput(), WID_BEATS);
 }
 
 
@@ -115,7 +117,7 @@ void geMainTimer::cb_meter()
 
 void geMainTimer::cb_quantizer()
 {
-       glue_quantize(quantizer->value());
+       c::main::quantize(quantizer->value());
 }
 
 
@@ -124,7 +126,7 @@ void geMainTimer::cb_quantizer()
 
 void geMainTimer::cb_multiplier()
 {
-       glue_beatsMultiply();
+       c::main::beatsMultiply();
 }
 
 
@@ -133,7 +135,7 @@ void geMainTimer::cb_multiplier()
 
 void geMainTimer::cb_divider()
 {
-       glue_beatsDivide();
+       c::main::beatsDivide();
 }
 
 
@@ -148,7 +150,7 @@ void geMainTimer::setBpm(const char* v)
 
 void geMainTimer::setBpm(float v)
 {
-       bpm->copy_label(gu_fToString((float) v, 1).c_str()); // Only 1 decimal place (e.g. 120.0)
+       bpm->copy_label(u::string::fToString((float) v, 1).c_str()); // Only 1 decimal place (e.g. 120.0)
 }
 
 
@@ -186,6 +188,8 @@ void geMainTimer::setQuantizer(int q)
 
 void geMainTimer::setMeter(int beats, int bars)
 {
-       string tmp = gu_iToString(beats) + "/" + gu_iToString(bars);
+       string tmp = u::string::iToString(beats) + "/" + u::string::iToString(bars);
        meter->copy_label(tmp.c_str());
 }
+
+}} // giada::v::
\ No newline at end of file
index 917c05450cb98801e37ec727db19c3887b4ef86d..03ac84054d1ddb0e7724a37fcd33270dec01c405 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -36,6 +36,9 @@ class geButton;
 class geChoice;
 
 
+namespace giada {
+namespace v
+{
 class geMainTimer : public Fl_Group
 {
 private:
@@ -71,6 +74,7 @@ public:
 
   void setLock(bool v);
 };
+}} // giada::v::
 
 
 #endif
index 3e83d2d219af0e62f24e9968571fdf8e01fc5993..d4f0b3ec0de8f3eff12220688dcb75fb0f0e621a 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
 
 
 #include "../../../core/graphics.h"
+#include "../../../core/conf.h"
 #include "../../../glue/transport.h"
 #include "../../../glue/io.h"
 #include "../../elems/basics/button.h"
 #include "mainTransport.h"
 
 
-using namespace giada;
-
-
+namespace giada {
+namespace v
+{
 geMainTransport::geMainTransport(int x, int y)
-       : Fl_Group(x, y, 131, 25)
+       : Fl_Group(x, y, 174, 25)
 {
        begin();
 
-       rewind    = new geButton(x,  y, 25, 25, "", rewindOff_xpm, rewindOn_xpm);
-       play      = new geButton(rewind->x()+rewind->w()+4, y, 25, 25, "", play_xpm, pause_xpm);
-       recAction = new geButton(play->x()+play->w()+4, y, 25, 25, "", recOff_xpm, recOn_xpm);
-       recInput  = new geButton(recAction->x()+recAction->w()+4, y, 25, 25, "", inputRecOff_xpm, inputRecOn_xpm);
-       metronome = new geButton(recInput->x()+recInput->w()+4, y+10, 15, 15, "", metronomeOff_xpm, metronomeOn_xpm);
+       rewind         = new geButton(x, y, 25, 25, "", rewindOff_xpm, rewindOn_xpm);
+       play           = new geButton(rewind->x()+rewind->w()+4, y, 25, 25, "", play_xpm, pause_xpm);
+       recTriggerMode = new geButton(play->x()+play->w()+16, y+5, 15, 15, "", recTriggerModeOff_xpm, recTriggerModeOn_xpm);
+       recAction      = new geButton(recTriggerMode->x()+recTriggerMode->w()+4, y, 25, 25, "", recOff_xpm, recOn_xpm);
+       recInput       = new geButton(recAction->x()+recAction->w()+4, y, 25, 25, "", inputRecOff_xpm, inputRecOn_xpm);
+       metronome      = new geButton(recInput->x()+recInput->w()+16, y+5, 15, 15, "", metronomeOff_xpm, metronomeOn_xpm);
 
        end();
 
        resizable(nullptr);   // don't resize any widget
 
-       rewind->callback(cb_rewind, (void*)this);
+       rewind->callback([](Fl_Widget* w, void* v) { 
+               c::transport::rewindSeq(/*gui=*/true);
+       });
 
-       play->callback(cb_play);
+       play->callback([](Fl_Widget* w, void* v) { 
+               c::transport::startStopSeq(/*gui=*/true);
+       });
        play->type(FL_TOGGLE_BUTTON);
 
-       recAction->callback(cb_recAction, (void*)this);
+       recAction->callback([](Fl_Widget* w, void* v) { 
+               c::io::toggleActionRec(/*gui=*/true);
+       });
        recAction->type(FL_TOGGLE_BUTTON);
 
-       recInput->callback(cb_recInput, (void*)this);
+       recInput->callback([](Fl_Widget* w, void* v) { 
+               c::io::toggleInputRec(/*gui=*/true);
+       });
        recInput->type(FL_TOGGLE_BUTTON);
 
-       metronome->callback(cb_metronome);
-       metronome->type(FL_TOGGLE_BUTTON);
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
-void geMainTransport::cb_rewind   (Fl_Widget *v, void *p) { ((geMainTransport*)p)->cb_rewind(); }
-void geMainTransport::cb_play     (Fl_Widget *v, void *p) { ((geMainTransport*)p)->cb_play(); }
-void geMainTransport::cb_recAction(Fl_Widget *v, void *p) { ((geMainTransport*)p)->cb_recAction(); }
-void geMainTransport::cb_recInput (Fl_Widget *v, void *p) { ((geMainTransport*)p)->cb_recInput(); }
-void geMainTransport::cb_metronome(Fl_Widget *v, void *p) { ((geMainTransport*)p)->cb_metronome(); }
-
-
-/* -------------------------------------------------------------------------- */
-
-
-void geMainTransport::cb_rewind()
-{
-       c::transport::rewindSeq(true);
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
-void geMainTransport::cb_play()
-{
-       c::transport::startStopSeq(true);
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
-void geMainTransport::cb_recAction()
-{
-       using namespace giada::c::io;
-       startStopActionRec(true);
-}
-
-
-/* -------------------------------------------------------------------------- */
-
-
-void geMainTransport::cb_recInput()
-{
-       using namespace giada::c::io;
-       startStopInputRec(true);
-}
-
+       recTriggerMode->value(m::conf::recTriggerMode);
+       recTriggerMode->type(FL_TOGGLE_BUTTON);
+       recTriggerMode->callback([](Fl_Widget* w, void* v) { 
+               m::conf::recTriggerMode = static_cast<geButton*>(w)->value();
+       });
 
-/* -------------------------------------------------------------------------- */
-
-
-void geMainTransport::cb_metronome()
-{
-       c::transport::startStopMetronome(true);
+       metronome->callback([](Fl_Widget* w, void* v) {
+               c::transport::toggleMetronome(/*gui=*/true);
+       });
+       metronome->type(FL_TOGGLE_BUTTON);
 }
 
 
@@ -161,3 +122,14 @@ void geMainTransport::updateRecAction(int v)
        recAction->value(v);
        recAction->redraw();
 }
+
+
+/* -------------------------------------------------------------------------- */
+
+
+void geMainTransport::setRecTriggerModeActive(bool v)
+{
+       v ? recTriggerMode->activate() : recTriggerMode->deactivate();
+}
+
+}} // giada::v::
\ No newline at end of file
index cd9290948016ca6261add7be83c6780e816952e4..1172c67b8ea767e8acdd4db8e08d65d5de88f880 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
 
 
 #include <FL/Fl_Group.H>
+#include "../../../core/types.h"
 
 
 class geButton;
 
 
+namespace giada {
+namespace v
+{
 class geMainTransport : public Fl_Group
 {
 private:
 
-       geButton *rewind;
-       geButton *play;
-       geButton *recAction;
-       geButton *recInput;
-       geButton *metronome;
+       geButton* rewind;
+       geButton* play;
+       
+       geButton* recTriggerMode;
+       geButton* recAction;
+       geButton* recInput;
 
-       static void cb_rewind   (Fl_Widget *v, void *p);
-       static void cb_play     (Fl_Widget *v, void *p);
-       static void cb_recAction(Fl_Widget *v, void *p);
-       static void cb_recInput (Fl_Widget *v, void *p);
-       static void cb_metronome(Fl_Widget *v, void *p);
-       void cb_rewind   ();
-       void cb_play     ();
-       void cb_recAction();
-       void cb_recInput ();
-       void cb_metronome();
+       geButton* metronome;
 
 public:
 
        geMainTransport(int x, int y);
-
-       void updatePlay     (int v);
+       
+       void updatePlay(int v);
        void updateMetronome(int v);
-       void updateRecInput (int v);
+       void updateRecInput(int v);
        void updateRecAction(int v);
+       void setRecTriggerModeActive(bool v);
+
 };
+}} // giada::v::
+
 
 #endif
index 0085d6c8cfdadfd04d1399b3b512d9e560ec1cc6..c17b50c79af8b9da6cd0cbd65394909b1a3c89da 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
 
 
 using std::string;
-using namespace giada::m;
+using namespace giada;
 
 
 geMidiLearner::geMidiLearner(int X, int Y, int W, const char* l,
-  midiDispatcher::cb_midiLearn* cb, uint32_t* param, Channel* ch)
-       : Fl_Group(X, Y, W, 20),
-               callback(cb),
-               ch      (ch),
-               param   (param)
+  m::midiDispatcher::cb_midiLearn* cb, uint32_t* param, m::Channel* ch)
+: Fl_Group(X, Y, W, 20),
+  callback(cb),
+  ch      (ch),
+  param   (param)
 {
        begin();
        text   = new geBox(x(), y(), 156, 20, l);
@@ -70,7 +70,7 @@ void geMidiLearner::updateValue()
 {
        string tmp;
        if (*param != 0x0) {
-               tmp = "0x" + gu_iToString(*param, true); // true: hex mode
+               tmp = "0x" + u::string::iToString(*param, true); // true: hex mode
                tmp.pop_back();  // Remove last two digits, useless in MIDI messages
                tmp.pop_back();  // Remove last two digits, useless in MIDI messages
        }
@@ -110,8 +110,8 @@ void geMidiLearner::cb_button()
                cbData.window  = static_cast<gdMidiInputBase*>(parent()); // parent = gdMidiInput
                cbData.learner = this;
                cbData.channel = ch;
-               midiDispatcher::startMidiLearn(callback, (void*)&cbData);
+               m::midiDispatcher::startMidiLearn(callback, (void*)&cbData);
        }
        else
-               midiDispatcher::stopMidiLearn();
+               m::midiDispatcher::stopMidiLearn();
 }
index 28ac2e6bc308b633caee2a02b319dea0bbd2b55e..c3ece9c499761765daef562d15f71dd904283998 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index adfb9072f427cb104389e86183899c1b355e8961..a8c7b86ccbb7d115d9aba4dedbbe9006c1f09fc3 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -31,6 +31,7 @@
 #include <FL/fl_draw.H>
 #include "../../../core/plugin.h"
 #include "../../../core/const.h"
+#include "../../../core/pluginManager.h"
 #include "../../../core/pluginHost.h"
 #include "../basics/boxtypes.h"
 #include "pluginBrowser.h"
@@ -83,16 +84,16 @@ void gePluginBrowser::refresh()
        add("NAME\tMANUFACTURER\tCATEGORY\tFORMAT\tUID");
        add("---\t---\t---\t---\t---");
 
-       for (int i=0; i<pluginHost::countAvailablePlugins(); i++) {
-               pluginHost::PluginInfo pi = pluginHost::getAvailablePluginInfo(i);
-               string m = pluginHost::doesPluginExist(pi.uid) ? "" : "@-";
+       for (int i=0; i<pluginManager::countAvailablePlugins(); i++) {
+               pluginManager::PluginInfo pi = pluginManager::getAvailablePluginInfo(i);
+               string m = pluginManager::doesPluginExist(pi.uid) ? "" : "@-";
                string s = m + pi.name + "\t" + m + pi.manufacturerName + "\t" + m +
                                pi.category +   "\t" + m + pi.format + "\t" + m + pi.uid;
                add(s.c_str());
        }
 
-       for (unsigned i=0; i<pluginHost::countUnknownPlugins(); i++) {
-               string s = "?\t?\t?\t?\t? " + pluginHost::getUnknownPluginInfo(i) + " ?";
+       for (unsigned i=0; i<pluginManager::countUnknownPlugins(); i++) {
+               string s = "?\t?\t?\t?\t? " + pluginManager::getUnknownPluginInfo(i) + " ?";
                add(s.c_str());
        }
 }
@@ -104,8 +105,8 @@ void gePluginBrowser::refresh()
 void gePluginBrowser::computeWidths()
 {
        int w0, w1, w3;
-       for (int i=0; i<pluginHost::countAvailablePlugins(); i++) {
-               pluginHost::PluginInfo pi = pluginHost::getAvailablePluginInfo(i);
+       for (int i=0; i<pluginManager::countAvailablePlugins(); i++) {
+               pluginManager::PluginInfo pi = pluginManager::getAvailablePluginInfo(i);
                w0 = (int) fl_width(pi.name.c_str());
                w1 = (int) fl_width(pi.manufacturerName.c_str());
                w3 = (int) fl_width(pi.format.c_str());
index e442af21c1c2ab6158591499dbe084bdbffc0428..6f7999054fbff54fc6618b7ae12157ab2f221082 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index fcedf0fc692a0a8c1fffdb4a9e2b9ea2ebe42851..5ed188669c21433648644dfe50778aea46bb104a 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -35,9 +35,9 @@
 #include "../../../utils/gui.h"
 #include "../../../utils/log.h"
 #include "../../../glue/plugin.h"
-#include "../../elems/basics/idButton.h"
+#include "../../elems/basics/button.h"
 #include "../../elems/basics/choice.h"
-#include "../../dialogs/gd_mainWindow.h"
+#include "../../dialogs/mainWindow.h"
 #include "../../dialogs/pluginList.h"
 #include "../../dialogs/pluginWindowGUI.h"
 #include "../../dialogs/pluginWindow.h"
@@ -57,12 +57,12 @@ gePluginElement::gePluginElement(gdPluginList* gdp, m::Plugin* p, int X, int Y,
          m_plugin    (p)
 {
        begin();
-       button    = new geIdButton(8, y(), 220, 20);
+       button    = new geButton(8, y(), 220, 20);
        program   = new geChoice(button->x()+button->w()+4, y(), 132, 20);
-       bypass    = new geIdButton(program->x()+program->w()+4, y(), 20, 20);
-       shiftUp   = new geIdButton(bypass->x()+bypass->w()+4, y(), 20, 20, "", fxShiftUpOff_xpm, fxShiftUpOn_xpm);
-       shiftDown = new geIdButton(shiftUp->x()+shiftUp->w()+4, y(), 20, 20, "", fxShiftDownOff_xpm, fxShiftDownOn_xpm);
-       remove    = new geIdButton(shiftDown->x()+shiftDown->w()+4, y(), 20, 20, "", fxRemoveOff_xpm, fxRemoveOn_xpm);
+       bypass    = new geButton(program->x()+program->w()+4, y(), 20, 20);
+       shiftUp   = new geButton(bypass->x()+bypass->w()+4, y(), 20, 20, "", fxShiftUpOff_xpm, fxShiftUpOn_xpm);
+       shiftDown = new geButton(shiftUp->x()+shiftUp->w()+4, y(), 20, 20, "", fxShiftDownOff_xpm, fxShiftDownOn_xpm);
+       remove    = new geButton(shiftDown->x()+shiftDown->w()+4, y(), 20, 20, "", fxRemoveOff_xpm, fxRemoveOn_xpm);
        end();
 
        button->copy_label(m_plugin->getName().c_str());
@@ -71,7 +71,7 @@ gePluginElement::gePluginElement(gdPluginList* gdp, m::Plugin* p, int X, int Y,
        program->callback(cb_setProgram, (void*)this);
 
        for (int i=0; i<m_plugin->getNumPrograms(); i++)
-               program->add(gu_removeFltkChars(m_plugin->getProgramName(i)).c_str());
+               program->add(u::gui::removeFltkChars(m_plugin->getProgramName(i)).c_str());
 
        if (program->size() == 0) {
                program->add("-- no programs --\0");
@@ -132,8 +132,8 @@ void gePluginElement::cb_shiftDown()
        if (m::pluginHost::countPlugins(m_parentWin->stackType, m_parentWin->ch) == 1)
                return;
 
-       unsigned pluginIndex = m::pluginHost::getPluginIndex(m_plugin->getId(), m_parentWin->stackType, m_parentWin->ch);
-       unsigned stackSize   = (m::pluginHost::getStack(m_parentWin->stackType, m_parentWin->ch))->size();
+       int pluginIndex = m::pluginHost::getPluginIndex(m_plugin->getId(), m_parentWin->stackType, m_parentWin->ch);
+       int stackSize   = m::pluginHost::getStack(m_parentWin->stackType, m_parentWin->ch).size();
 
        if (pluginIndex == stackSize-1)  // last one in the stack, do nothing
                return;
index 8409322db27fedb6853b3a8748dd159ca4eb2a32..c3b1f456c1b1b7636425e3471fb1d810b0f58887 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -36,8 +36,8 @@
 
 
 class gdPluginList;
-class geIdButton;
 class geChoice;
+class geButton;
 
 
 class gePluginElement : public Fl_Group
@@ -62,12 +62,12 @@ private:
 
 public:
 
-       geIdButton* button;
-       geChoice*   program;
-       geIdButton* bypass;
-       geIdButton* shiftUp;
-       geIdButton* shiftDown;
-       geIdButton* remove;
+       geButton* button;
+       geChoice* program;
+       geButton* bypass;
+       geButton* shiftUp;
+       geButton* shiftDown;
+       geButton* remove;
 
        gePluginElement(gdPluginList* gdp, giada::m::Plugin* p, int x, int y, int w);
 };
index 81bbb3dcf68afb895dc29b891e64b2f62bc37ee6..f7a9624e2c2bbb9012cac39dfe4d65f17f771821 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index e07c9407a488abb812042d4f1a15d5a9ab014936..266de5e39008d5a5d6011afc58d3577d931a7559 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 284b3f416368af8782334709bcf5e5071ffa710f..35ba256b1ac71134e9a9a75802e9c2650dca912a 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -50,7 +50,7 @@ geBoostTool::geBoostTool(int X, int Y, m::SampleChannel* ch)
     ch      (ch)
 {
   begin();
-    label     = new geBox(x(), y(), gu_getStringWidth("Boost"), 20, "Boost", FL_ALIGN_RIGHT);
+    label     = new geBox(x(), y(), u::gui::getStringWidth("Boost"), 20, "Boost", FL_ALIGN_RIGHT);
     dial      = new geDial(label->x()+label->w()+4, y(), 20, 20);
     input     = new geInput(dial->x()+dial->w()+4, y(), 70, 20);
     normalize = new geButton(input->x()+input->w()+4, y(), 70, 20, "Normalize");
@@ -75,7 +75,7 @@ void geBoostTool::refresh()
 {
   using namespace giada::u;
 
-  input->value(gu_fToString(math::linearToDB(ch->getBoost()), 2).c_str());  // 2 digits
+  input->value(string::fToString(math::linearToDB(ch->getBoost()), 2).c_str());  // 2 digits
   // A dial greater than it's max value goes crazy
   dial->value(ch->getBoost() <= 10.0f ? ch->getBoost() : 10.0f);
 }
index a922a6edd535b0587f5881dfa70fe65b34c04810..496717ca4d0033e35424b1e3200a88cae809e5be 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index e9478a88ce82a5bc1e0017db2deccd0103de4913..8d12056c349e6b886f6778f4527c8f706cd839b8 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -51,7 +51,7 @@ gePanTool::gePanTool(int x, int y, m::SampleChannel* ch)
     ch      (ch)
 {
   begin();
-    label = new geBox(x, y, gu_getStringWidth("Pan"), 20, "Pan", FL_ALIGN_RIGHT);
+    label = new geBox(x, y, u::gui::getStringWidth("Pan"), 20, "Pan", FL_ALIGN_RIGHT);
     dial  = new geDial(label->x()+label->w()+4, y, 20, 20);
     input = new geInput(dial->x()+dial->w()+4, y, 70, 20);
     reset = new geButton(input->x()+input->w()+4, y, 70, 20, "Reset");
@@ -78,14 +78,14 @@ void gePanTool::refresh()
   dial->value(ch->getPan());
 
   if (ch->getPan() < 0.5f) {
-    string tmp = gu_iToString((int) ((-ch->getPan() * 200.0f) + 100.0f)) + " L";
+    string tmp = u::string::iToString((int) ((-ch->getPan() * 200.0f) + 100.0f)) + " L";
     input->value(tmp.c_str());
   }
   else 
   if (ch->getPan() == 0.5)
     input->value("C");
   else {
-    string tmp = gu_iToString((int) ((ch->getPan() * 200.0f) - 100.0f)) + " R";
+    string tmp = u::string::iToString((int) ((ch->getPan() * 200.0f) - 100.0f)) + " R";
     input->value(tmp.c_str());
   }
 }
@@ -94,8 +94,8 @@ void gePanTool::refresh()
 /* -------------------------------------------------------------------------- */
 
 
-void gePanTool::cb_panning (Fl_Widget *w, void *p) { ((gePanTool*)p)->cb_panning(); }
-void gePanTool::cb_panReset(Fl_Widget *w, void *p) { ((gePanTool*)p)->cb_panReset(); }
+void gePanTool::cb_panning (Fl_Widget* w, void* p) { ((gePanTool*)p)->cb_panning(); }
+void gePanTool::cb_panReset(Fl_Widget* w, void* p) { ((gePanTool*)p)->cb_panReset(); }
 
 
 
index fd485f50f749f6dbe8261c53890e291ed6e16de2..17170166a3e32a01687d65e4df43d5e5238023e2 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index e5eac55503f4ade73acafeff2895bd1ea00dc167..5770435fe3eeb96022df7d48e48310bd727224a4 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -49,7 +49,7 @@ gePitchTool::gePitchTool(int x, int y, m::SampleChannel* ch)
     ch      (ch)
 {
   begin();
-    label       = new geBox(x, y, gu_getStringWidth("Pitch"), 20, "Pitch", FL_ALIGN_RIGHT);
+    label       = new geBox(x, y, u::gui::getStringWidth("Pitch"), 20, "Pitch", FL_ALIGN_RIGHT);
     dial        = new geDial(label->x()+label->w()+4, y, 20, 20);
     input       = new geInput(dial->x()+dial->w()+4, y, 70, 20);
     pitchToBar  = new geButton(input->x()+input->w()+4, y, 70, 20, "To bar");
@@ -83,7 +83,7 @@ gePitchTool::gePitchTool(int x, int y, m::SampleChannel* ch)
 void gePitchTool::refresh()
 {
   dial->value(ch->getPitch());
-  input->value(gu_fToString(ch->getPitch(), 4).c_str()); // 4 digits
+  input->value(u::string::fToString(ch->getPitch(), 4).c_str()); // 4 digits
 }
 
 
index 0ccfcdf9e7fe11a640a6170384fde225f31d56d3..ee6594e4b5479a8440407b104422869d04689691 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 7dae165248a2fc5a440c49f88fbdd4120a873195..9cf66d5b10222e49857a87a0f27ea3d44790d099 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -40,7 +40,7 @@
 #include "rangeTool.h"
 
 
-using namespace giada::c;
+using namespace giada;
 
 
 geRangeTool::geRangeTool(int x, int y, giada::m::SampleChannel* ch)
@@ -48,7 +48,7 @@ geRangeTool::geRangeTool(int x, int y, giada::m::SampleChannel* ch)
                m_ch    (ch)
 {
        begin();
-               m_label = new geBox(x, y, gu_getStringWidth("Range"), G_GUI_UNIT, "Range", FL_ALIGN_RIGHT);
+               m_label = new geBox(x, y, u::gui::getStringWidth("Range"), G_GUI_UNIT, "Range", FL_ALIGN_RIGHT);
                m_begin = new geInput(m_label->x()+m_label->w()+G_GUI_INNER_MARGIN, y, 70, G_GUI_UNIT);
                m_end   = new geInput(m_begin->x()+m_begin->w()+G_GUI_INNER_MARGIN, y, 70, G_GUI_UNIT);
                m_reset = new geButton(m_end->x()+m_end->w()+G_GUI_INNER_MARGIN, y, 70, G_GUI_UNIT, "Reset");
@@ -73,8 +73,8 @@ geRangeTool::geRangeTool(int x, int y, giada::m::SampleChannel* ch)
 
 void geRangeTool::refresh()
 {
-       m_begin->value(gu_iToString(m_ch->getBegin()).c_str());
-       m_end->value(gu_iToString(m_ch->getEnd()).c_str());
+       m_begin->value(u::string::iToString(m_ch->getBegin()).c_str());
+       m_end->value(u::string::iToString(m_ch->getEnd()).c_str());
 }
 
 
@@ -90,7 +90,7 @@ void geRangeTool::cb_resetStartEnd(Fl_Widget* w, void* p) { ((geRangeTool*)p)->c
 
 void geRangeTool::cb_setChanPos()
 {
-       sampleEditor::setBeginEnd(m_ch, atoi(m_begin->value()), atoi(m_end->value()));
+       c::sampleEditor::setBeginEnd(m_ch, atoi(m_begin->value()), atoi(m_end->value()));
        static_cast<gdSampleEditor*>(window())->waveTools->updateWaveform(); // TODO - glue's business!
 }
 
@@ -100,6 +100,6 @@ void geRangeTool::cb_setChanPos()
 
 void geRangeTool::cb_resetStartEnd()
 {
-       sampleEditor::setBeginEnd(m_ch, 0, m_ch->wave->getSize() - 1);
+       c::sampleEditor::setBeginEnd(m_ch, 0, m_ch->wave->getSize() - 1);
        static_cast<gdSampleEditor*>(window())->waveTools->updateWaveform(); // TODO - glue's business!
 }
index 69efdfa6d8bfa3a181be0877488fdc1094f31648..2e41bf01326c4934d52ba0d73466978ba4578831 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 0ab12c0f1f688b1eca1feb31fc42047ab46b40ee..5ec899d18cd70f10ed37cd235f2834d2870922d5 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
 #include "../../../utils/gui.h"
 #include "../../../utils/string.h"
 #include "../../../glue/sampleEditor.h"
-#include "../../dialogs/gd_warnings.h"
+#include "../../dialogs/warnings.h"
 #include "../basics/input.h"
 #include "../basics/box.h"
 #include "../basics/button.h"
 #include "shiftTool.h"
 
 
-using namespace giada::c;
+using namespace giada;
 
 
 geShiftTool::geShiftTool(int x, int y, giada::m::SampleChannel* ch)
@@ -46,14 +46,14 @@ geShiftTool::geShiftTool(int x, int y, giada::m::SampleChannel* ch)
                m_ch    (ch)
 {
        begin();
-               m_label = new geBox(x, y, gu_getStringWidth("Shift"), G_GUI_UNIT, "Shift", FL_ALIGN_RIGHT);
+               m_label = new geBox(x, y, u::gui::getStringWidth("Shift"), G_GUI_UNIT, "Shift", FL_ALIGN_RIGHT);
                m_shift = new geInput(m_label->x()+m_label->w()+G_GUI_INNER_MARGIN, y, 70, G_GUI_UNIT);
                m_reset = new geButton(m_shift->x()+m_shift->w()+G_GUI_INNER_MARGIN, y, 70, G_GUI_UNIT, "Reset");
        end();
 
        m_shift->type(FL_INT_INPUT);
        m_shift->when(FL_WHEN_RELEASE | FL_WHEN_ENTER_KEY); // on focus lost or enter key
-       m_shift->value(gu_iToString(ch->shift).c_str());
+       m_shift->value(u::string::iToString(ch->shift).c_str());
        m_shift->callback(cb_setShift, (void*)this);
 
        m_reset->callback(cb_reset, (void*)this);
@@ -92,7 +92,7 @@ void geShiftTool::cb_reset()
 
 void geShiftTool::refresh()
 {
-       m_shift->value(gu_iToString(m_ch->shift).c_str());
+       m_shift->value(u::string::iToString(m_ch->shift).c_str());
 }
 
 
@@ -104,5 +104,5 @@ void geShiftTool::shift(int f)
        if (m_ch->isPlaying())
                gdAlert("Can't shift sample while playing.");
        else
-               sampleEditor::shift(m_ch, f);   
+               c::sampleEditor::shift(m_ch, f);        
 }
index 0b1a6d379c147ca826891419ff7fcb797989ce72..4734c0f1b391b1a7a5f99e5bd0b92a914a11c91e 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index d937c9cb4b04fa1fa9c1f4450acc269a75862f96..97e06d8e45602c8425650d987b767d20caf6b1e8 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -50,7 +50,7 @@ geVolumeTool::geVolumeTool(int X, int Y, m::SampleChannel* ch)
     ch      (ch)
 {
   begin();
-    label = new geBox  (x(), y(), gu_getStringWidth("Volume"), 20, "Volume", FL_ALIGN_RIGHT);
+    label = new geBox  (x(), y(), u::gui::getStringWidth("Volume"), 20, "Volume", FL_ALIGN_RIGHT);
     dial  = new geDial (label->x()+label->w()+4, y(), 20, 20);
     input = new geInput(dial->x()+dial->w()+4, y(), 70, 20);
   end();
@@ -69,11 +69,9 @@ geVolumeTool::geVolumeTool(int X, int Y, m::SampleChannel* ch)
 
 void geVolumeTool::refresh()
 {
-  using namespace giada::u;
-
   string tmp;
-  float dB = math::linearToDB(ch->volume);
-  if (dB > -INFINITY) tmp = gu_fToString(dB, 2);  // 2 digits
+  float dB = u::math::linearToDB(ch->volume);
+  if (dB > -INFINITY) tmp = u::string::fToString(dB, 2);  // 2 digits
   else                tmp = "-inf";
   input->value(tmp.c_str());
   dial->value(ch->guiChannel->vol->value());
index b38323c38fcd0e9b65b8a931aed8b65dcb57ac19..be9484a66e34b9f54f9a1e7fedd31549d49c082e 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 622bb2cbd370b9f53893183d5c7b9d594faf998a..f3d6fce81d82fc8ec230fe6f1a861fd5a1f0d1b1 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index b224c5318176d728fcc223c32d0e276d014a0dec..af095dc809bdf1409f51b00900bbe8efbfb70ed8 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 5b1b77f7101ad7441c13991b1a078936d2e338b2..476c1e827463cfd11f21acec8100c3dd3e535c0c 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -103,7 +103,7 @@ void geWaveform::freeData()
 
 int geWaveform::alloc(int datasize, bool force)
 {
-       Wave* wave = m_ch->wave;
+       const Wave* wave = m_ch->wave.get();
 
        m_ratio = wave->getSize() / (float) datasize;
 
index 1e7b426a4af57b21d6ebce4837855fb81ce5fabb..fdeb185bfd1a213d8389f39efdd8f19533354d16 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 036fc0a1d1cace212386e59aa4e0530340a5c559..34a7d7c3996f20ab618b15f8f7c65f67e6589e64 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
 #include <FL/fl_draw.H>
 #include "../../core/const.h"
 #include "../../core/kernelAudio.h"
+#include "../../utils/math.h"
 #include "soundMeter.h"
 
 
-using namespace giada::m;
+using namespace giada;
 
 
 geSoundMeter::geSoundMeter(int x, int y, int w, int h, const char* l)
-: Fl_Box    (x, y, w, h, l),
-       clip      (false),
-       mixerPeak (0.0f),
-       peak      (0.0f),
-       dbLevel   (0.0f),
-       dbLevelOld(0.0f)
+: Fl_Box      (x, y, w, h, l),
+  mixerPeak   (0.0f),
+  m_dbLevelCur(0.0f),
+  m_dbLevelOld(0.0f)
 {
 }
 
@@ -53,35 +52,23 @@ void geSoundMeter::draw()
 {
        fl_rect(x(), y(), w(), h(), G_COLOR_GREY_4);
 
-       /* peak = the highest value inside the frame */
+       /* Compute peak level on 0.0 -> 1.0 scale. 1.0 is considered clip. */
 
-       peak = 0.0f;
-       float tmp_peak = 0.0f;
+       bool clip = std::fabs(mixerPeak) >= 1.0f ? true : false;
 
-       tmp_peak = fabs(mixerPeak);
-       if (tmp_peak > peak)
-               peak = tmp_peak;
+       /*  dBFS (full scale) calculation, plus decay of -2dB per frame. */
 
-       clip = peak >= 1.0f ? true : false; // 1.0f is considered clip
+       m_dbLevelCur = u::math::linearToDB(std::fabs(mixerPeak));
 
+       if (m_dbLevelCur < m_dbLevelOld && m_dbLevelOld > -G_MIN_DB_SCALE)
+               m_dbLevelCur = m_dbLevelOld - 2.0f;
 
-       /*  dBFS (full scale) calculation, plus decay of -2dB per frame */
+       m_dbLevelOld = m_dbLevelCur;
 
-       dbLevel = 20 * log10(peak);
-       if (dbLevel < dbLevelOld)
-               if (dbLevelOld > -G_MIN_DB_SCALE)
-                       dbLevel = dbLevelOld - 2.0f;
+       /* Paint the meter on screen. */
 
-       dbLevelOld = dbLevel;
-
-       /* graphical part */
-
-       float px_level = 0.0f;
-       if (dbLevel < 0.0f)
-               px_level = ((w()/G_MIN_DB_SCALE) * dbLevel) + w();
-       else
-               px_level = w();
+       float pxLevel = ((w()/G_MIN_DB_SCALE) * m_dbLevelCur) + w();
 
        fl_rectf(x()+1, y()+1, w()-2, h()-2, G_COLOR_GREY_2);
-       fl_rectf(x()+1, y()+1, (int) px_level, h()-2, clip || !kernelAudio::getStatus() ? G_COLOR_RED_ALERT : G_COLOR_GREY_4);
+       fl_rectf(x()+1, y()+1, (int) pxLevel, h()-2, clip || !m::kernelAudio::getStatus() ? G_COLOR_RED_ALERT : G_COLOR_GREY_4);
 }
index 02de14e6f8a396e0eb21cd5e051386e83b62b19c..65c42155152e686262ad8d32f2157765714c8819 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -40,14 +40,12 @@ public:
 
        void draw() override;
 
-       bool clip;
-       float mixerPeak;        // peak from mixer
+    float mixerPeak;    // peak from mixer
 
 private:
 
-       float peak;
-       float dbLevel;
-       float dbLevelOld;
+       float m_dbLevelCur;
+       float m_dbLevelOld;
 };
 
 
index ec809d9ac06d0229df50bbd74a6c7b4308c7f5bf..8303e1ba806f50aaa56e3ecd37c32c3d05fe2bdb 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 69b9628d7d13474bfc3295db1f82356d39f45c23..73e0d696744f340f61a639695d74115616600562 100644 (file)
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index b29ba781e0de013a0b97cdf07329570196bcbe6d..d3c83089d0b9892935b41414fe77b9eb03431e3e 100644 (file)
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -58,6 +58,7 @@
 
 using std::string;
 using std::vector;
+using namespace giada;
 
 
 bool gu_fileExists(const string &filename)
@@ -232,8 +233,8 @@ bool gu_isProject(const string& path)
 string gu_stripFileUrl(const string& f)
 {
        string out = f;
-       out = gu_replace(out, "file://", "");
-       out = gu_replace(out, "%20", " ");
+       out = u::string::replace(out, "file://", "");
+       out = u::string::replace(out, "%20", " ");
        return out;
 }
 
index 2b9a21610dc2df9328e5f5d7426220c3cdb20715..63aba64c1d1ff170124ddefa67c82eab64eb7a12 100644 (file)
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index a481d690de753812f6171e021a22653f0aeef542..035ee0aa91f56af76996d2466bcc98b9dc2cc915 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -39,8 +39,8 @@
 #include "../core/channel.h"
 #include "../core/conf.h"
 #include "../core/graphics.h"
-#include "../gui/dialogs/gd_warnings.h"
-#include "../gui/dialogs/gd_mainWindow.h"
+#include "../gui/dialogs/warnings.h"
+#include "../gui/dialogs/mainWindow.h"
 #include "../gui/dialogs/actionEditor/baseActionEditor.h"
 #include "../gui/dialogs/window.h"
 #include "../gui/dialogs/sampleEditor.h"
 extern gdMainWindow* G_MainWin;
 
 
-using std::string;
-using namespace giada;
-using namespace giada::m;
-using namespace giada::v;
+namespace giada {
+namespace u {
+namespace gui 
+{
+namespace
+{
+int blinker_ = 0;
+} // {anonymous}
 
 
-static int blinker = 0;
+/* -------------------------------------------------------------------------- */
+/* -------------------------------------------------------------------------- */
+/* -------------------------------------------------------------------------- */
 
 
-void gu_refreshUI()
+void refreshUI()
 {
        Fl::lock();
 
@@ -81,13 +87,12 @@ void gu_refreshUI()
 
        /* compute timer for blinker */
 
-       blinker++;
-       if (blinker > 12)
-               blinker = 0;
+       if (blinker_++ > 12)
+               blinker_ = 0;
 
        /* If Sample Editor is open, repaint it (for dynamic play head). */
 
-       gdSampleEditor* se = static_cast<gdSampleEditor*>(gu_getSubwindow(G_MainWin, WID_SAMPLE_EDITOR));
+       gdSampleEditor* se = static_cast<gdSampleEditor*>(getSubwindow(G_MainWin, WID_SAMPLE_EDITOR));
        if (se != nullptr)
                se->waveTools->redrawWaveformAsync();
 
@@ -101,25 +106,30 @@ void gu_refreshUI()
 /* -------------------------------------------------------------------------- */
 
 
-int gu_getBlinker()
+bool shouldBlink()
 {
-       return blinker;
+       return blinker_ > 6;
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void gu_updateControls()
+void updateControls()
 {
+       using namespace giada::m;
+
        for (const Channel* ch : mixer::channels)
                ch->guiChannel->update();
 
-       G_MainWin->mainIO->setOutVol(mixer::outVol);
-       G_MainWin->mainIO->setInVol(mixer::inVol);
+       G_MainWin->mainIO->setOutVol(mixer::outVol.load());
+       G_MainWin->mainIO->setInVol(mixer::inVol.load());
+
 #ifdef WITH_VST
-       G_MainWin->mainIO->setMasterFxOutFull(pluginHost::getStack(pluginHost::MASTER_OUT)->size() > 0);
-       G_MainWin->mainIO->setMasterFxInFull(pluginHost::getStack(pluginHost::MASTER_IN)->size() > 0);
+
+       G_MainWin->mainIO->setMasterFxOutFull(pluginHost::getStack(pluginHost::StackType::MASTER_OUT).size() > 0);
+       G_MainWin->mainIO->setMasterFxInFull(pluginHost::getStack(pluginHost::StackType::MASTER_IN).size() > 0);
+       
 #endif
 
        G_MainWin->mainTimer->setMeter(clock::getBeats(), clock::getBars());
@@ -127,14 +137,14 @@ void gu_updateControls()
        G_MainWin->mainTimer->setQuantizer(clock::getQuantize());
 
        G_MainWin->mainTransport->updatePlay(clock::isRunning());
-       G_MainWin->mainTransport->updateMetronome(mixer::metronome);
+       G_MainWin->mainTransport->updateMetronome(mixer::isMetronomeOn());
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void gu_updateMainWinLabel(const string& s)
+void updateMainWinLabel(const std::string& s)
 {
        std::string out = std::string(G_APP_NAME) + " - " + s;
        G_MainWin->copy_label(out.c_str());
@@ -144,7 +154,7 @@ void gu_updateMainWinLabel(const string& s)
 /* -------------------------------------------------------------------------- */
 
 
-void gu_setFavicon(Fl_Window* w)
+void setFavicon(Fl_Window* w)
 {
 #if defined(__linux__)
 
@@ -165,7 +175,7 @@ void gu_setFavicon(Fl_Window* w)
 /* -------------------------------------------------------------------------- */
 
 
-void gu_openSubWindow(gdWindow* parent, gdWindow* child, int id)
+void openSubWindow(gdWindow* parent, gdWindow* child, int id)
 {
        if (parent->hasWindow(id)) {
                gu_log("[GU] parent has subwindow with id=%d, deleting\n", id);
@@ -179,9 +189,9 @@ void gu_openSubWindow(gdWindow* parent, gdWindow* child, int id)
 /* -------------------------------------------------------------------------- */
 
 
-void gu_refreshActionEditor()
+void refreshActionEditor()
 {
-       gdBaseActionEditor* ae = static_cast<gdBaseActionEditor*>(G_MainWin->getChild(WID_ACTION_EDITOR));
+       v::gdBaseActionEditor* ae = static_cast<v::gdBaseActionEditor*>(G_MainWin->getChild(WID_ACTION_EDITOR));
        if (ae != nullptr)
                ae->rebuild();
 }
@@ -190,7 +200,7 @@ void gu_refreshActionEditor()
 /* -------------------------------------------------------------------------- */
 
 
-gdWindow* gu_getSubwindow(gdWindow* parent, int id)
+gdWindow* getSubwindow(gdWindow* parent, int id)
 {
        if (parent->hasWindow(id))
                return parent->getChild(id);
@@ -202,7 +212,7 @@ gdWindow* gu_getSubwindow(gdWindow* parent, int id)
 /* -------------------------------------------------------------------------- */
 
 
-void gu_closeAllSubwindows()
+void closeAllSubwindows()
 {
        /* don't close WID_FILE_BROWSER, because it's the caller of this
         * function */
@@ -217,7 +227,7 @@ void gu_closeAllSubwindows()
 /* -------------------------------------------------------------------------- */
 
 
-int gu_getStringWidth(const std::string& s)
+int getStringWidth(const std::string& s)
 {
        int w = 0;
        int h = 0;
@@ -229,11 +239,13 @@ int gu_getStringWidth(const std::string& s)
 /* -------------------------------------------------------------------------- */
 
 
-string gu_removeFltkChars(const string& s)
+std::string removeFltkChars(const std::string& s)
 {
-       string out = gu_replace(s, "/", "-");
-       out = gu_replace(out, "|", "-");
-       out = gu_replace(out, "&", "-");
-       out = gu_replace(out, "_", "-");
+       std::string out = u::string::replace(s, "/", "-");
+       out = u::string::replace(out, "|", "-");
+       out = u::string::replace(out, "&", "-");
+       out = u::string::replace(out, "_", "-");
        return out;
 }
+
+}}} // giada::u::gui::
\ No newline at end of file
index d69ca371acb67208cd174d86ebdf7ab154131cf6..745b5145d6e1a31d41dd4e3bb0945ee008603151 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -36,54 +36,60 @@ class Fl_Window;
 class gdWindow;
 
 
+namespace giada {
+namespace u {
+namespace gui 
+{
 /* refresh
- * refresh all GUI elements. */
+Repaints some dynamic GUI elements. */
 
-void gu_refreshUI();
+void refreshUI();
 
-/* getBlinker
-*  return blinker value, used to make widgets blink. */
+/* shouldBlink
+Return whether is time to blink something or not. This is used to make widgets 
+blink. */
 
-int gu_getBlinker();
+bool shouldBlink();
 
 /* updateControls
- * update attributes of control elements (sample names, volumes, ...).
- * Useful when loading a new patch. */
+Updates attributes of control elements (sample names, volumes, ...). Useful when 
+loading a new patch. */
 
-void gu_updateControls();
+void updateControls();
 
-/* update_win_label
- * update the name of the main window */
+/* updateMainWinLabel
+Updates the name of the main window */
 
-void gu_updateMainWinLabel(const std::string &s);
+void updateMainWinLabel(const std::string& s);
 
-void gu_setFavicon(Fl_Window *w);
+void setFavicon(Fl_Window* w);
 
-void gu_openSubWindow(gdWindow *parent, gdWindow *child, int id);
+void openSubWindow(gdWindow* parent, gdWindow* child, int id);
 
 /* refreshActionEditor
- * reload the action editor window by closing and reopening it. It's used
- * when you delete some actions from the mainWindow and the action editor
- * window is open. */
+Reloads the action editor window by closing and reopening it. It's used when you
+delete some actions from the mainWindow and the action editor window is open. */
 
-void gu_refreshActionEditor();
+void refreshActionEditor();
 
 /* closeAllSubwindows
- * close all subwindows attached to mainWin. */
+Closes all subwindows attached to mainWin. */
 
-void gu_closeAllSubwindows();
+void closeAllSubwindows();
 
 /* getSubwindow
- * return a pointer to an open subwindow, otherwise nullptr. */
+Returns a pointer to an open subwindow, otherwise nullptr. */
 
-gdWindow *gu_getSubwindow(gdWindow *parent, int id);
+gdWindow* getSubwindow(gdWindow* parent, int id);
 
 /* removeFltkChars
- * Strip special chars used by FLTK to split menus into sub-menus. */
+Strips special chars used by FLTK to split menus into sub-menus. */
 
-std::string gu_removeFltkChars(const std::string &s);
+std::string removeFltkChars(const std::string& s);
 
-int gu_getStringWidth(const std::string &s);
+int getStringWidth(const std::string& s);
+
+}}} // giada::u::gui::
 
 
 #endif
index 8cfdf8fc7d28688339946ceddcda2d6513d34cc8..262ecf2225a99ea40f59df56549dcdb71d9948df 100644 (file)
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 5f4e8e6c39437f848906ca91cbe618b45ed49198..80657e3baa2b31a33a6c311eb02dad43514153a6 100644 (file)
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 324816bc92c48d3e09678caf4a180d0aee0a838f..e45c59e84ee7bdac7ca5eb1006a71fa7f2473fdd 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
@@ -46,7 +46,7 @@ int quantize(int x, int step)
 {
        /* Source:
        https://en.wikipedia.org/wiki/Quantization_(signal_processing)#Rounding_example */
-       return step * floor((x / (float) step) + 0.5f);
+       return step * std::floor((x / (float) step) + 0.5f);
 }
 
 
index 174978ae501494b4ac2d682a88a1c70671833e2a..a5d7fba5fdcd189ee9ea18dd42ef740cade6a655 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 2fc883efc1466c03289af8b3514df94fee4743c0..2438f395db1e94c50f6dd9b1d210ca644cae90e1 100644 (file)
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
 #include "string.h"
 
 
-using std::string;
-using std::vector;
-
-
-string gu_getRealPath(const string& path)
+namespace giada {
+namespace u     {
+namespace string 
 {
-       string out = "";
+std::string getRealPath(const std::string& path)
+{
+       std::string out = "";
 
 #if defined(G_OS_LINUX) || defined(G_OS_MAC)
 
@@ -65,7 +65,7 @@ string gu_getRealPath(const string& path)
 
 /* TODO - use std::to_string() */
 
-string gu_fToString(float f, int precision)
+std::string fToString(float f, int precision)
 {
        std::stringstream out;
        out << std::fixed << std::setprecision(precision) << f;
@@ -76,7 +76,7 @@ string gu_fToString(float f, int precision)
 /* -------------------------------------------------------------------------- */
 
 
-string gu_trim(const string& s)
+std::string trim(const std::string& s)
 {
        std::size_t first = s.find_first_not_of(" \n\t");
        std::size_t last  = s.find_last_not_of(" \n\t");
@@ -87,10 +87,10 @@ string gu_trim(const string& s)
 /* -------------------------------------------------------------------------- */
 
 
-string gu_replace(string in, const string& search, const string& replace)
+std::string replace(std::string in, const std::string& search, const std::string& replace)
 {
        size_t pos = 0;
-       while ((pos = in.find(search, pos)) != string::npos) {
+       while ((pos = in.find(search, pos)) != std::string::npos) {
                in.replace(pos, search.length(), replace);
                pos += replace.length();
        }
@@ -101,38 +101,39 @@ string gu_replace(string in, const string& search, const string& replace)
 /* -------------------------------------------------------------------------- */
 
 
-std::string gu_format(const char* format, ...)
+std::string format(const char* format, ...)
 {
        va_list args;
 
-       /* Compute the size of the new expanded string (i.e. with replacement taken
+       /* Compute the size of the new expanded std::string (i.e. with replacement taken
        into account). */
 
        va_start(args, format);
        size_t size = vsnprintf(nullptr, 0, format, args) + 1;
        va_end(args);
        
-       /* Create a new temporary char array to hold the new expanded string. */
+       /* Create a new temporary char array to hold the new expanded std::string. */
 
        std::unique_ptr<char[]> tmp(new char[size]);
 
-       /* Fill the temporary string with the formatted data. */
+       /* Fill the temporary std::string with the formatted data. */
 
-  va_start(args, format);
+       va_start(args, format);
        vsprintf(tmp.get(), format, args);
-  va_end(args);
-  
-       return string(tmp.get(), tmp.get() + size - 1); 
+       va_end(args);
+
+       return std::string(tmp.get(), tmp.get() + size - 1);
 }
 
 
 /* -------------------------------------------------------------------------- */
 
 
-void gu_split(string in, string sep, vector<string>* v)
+std::vector<std::string> split(std::string in, std::string sep)
 {
-       string full  = in;
-       string token = "";
+       std::vector<std::string> out;
+       std::string full  = in;
+       std::string token = "";
        size_t curr = 0;
        size_t next = -1;
        do {
@@ -140,7 +141,10 @@ void gu_split(string in, string sep, vector<string>* v)
                next  = full.find_first_of(sep, curr);
                token = full.substr(curr, next - curr);
                if (token != "")
-                       v->push_back(token);
+                       out.push_back(token);
        }
-       while (next != string::npos);
+       while (next != std::string::npos);
+       return out;
 }
+
+}}} // giada::u::string
\ No newline at end of file
index e59937e3ab0e79d103fabdea24844e866583ba0c..062f39bcde8314c208603fd500ffb06e90ca742b 100644 (file)
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
 #include <string>
 #include <vector>
 #include <sstream>
-#include "../core/const.h"
 
 
+namespace giada {
+namespace u     {
+namespace string 
+{
 template <typename T>
-std::string gu_iToString(T t, bool hex=false)
+std::string iToString(T t, bool hex=false)
 {
        std::stringstream out;
        if (hex)
@@ -48,18 +51,19 @@ std::string gu_iToString(T t, bool hex=false)
        return out.str();       
 }
 
-std::string gu_getRealPath(const std::string& path);
+std::string getRealPath(const std::string& path);
 
-std::string gu_replace(std::string in, const std::string& search,
+std::string replace(std::string in, const std::string& search,
   const std::string& replace);
 
-std::string gu_trim(const std::string& s);
+std::string trim(const std::string& s);
 
-void gu_split(std::string in, std::string sep, std::vector<std::string>* v);
+std::vector<std::string> split(std::string in, std::string sep);
 
-std::string gu_fToString(float f, int precision);
+std::string fToString(float f, int precision);
 
-std::string gu_format(const char* format, ...);
+std::string format(const char* format, ...);
 
+}}} // giada::u::string
 
 #endif
index 2667c8170eda4a1fa9e3903b222f8a498c0c79dc..adbc4002388125dde7daf42e5c7eb4880718e28f 100644 (file)
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 4afdc479e372c3657868b3845320cabdb0c1ce46..6c5c239b276e0e6e483f8b9419fc708f3003aa12 100644 (file)
@@ -6,7 +6,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
diff --git a/src/utils/vector.h b/src/utils/vector.h
new file mode 100644 (file)
index 0000000..a21f2f9
--- /dev/null
@@ -0,0 +1,57 @@
+/* -----------------------------------------------------------------------------
+ *
+ * Giada - Your Hardcore Loopmachine
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
+ *
+ * This file is part of Giada - Your Hardcore Loopmachine.
+ *
+ * Giada - Your Hardcore Loopmachine 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.
+ *
+ * Giada - Your Hardcore Loopmachine 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 Giada - Your Hardcore Loopmachine. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * -------------------------------------------------------------------------- */
+
+
+#ifndef G_UTILS_VECTOR_H
+#define G_UTILS_VECTOR_H
+
+
+#include <vector>
+#include <algorithm>
+#include <functional>
+
+
+namespace giada {
+namespace u     {
+namespace vector 
+{
+template <typename T>
+int indexOf(std::vector<T>& v, T obj)
+{
+    auto it = std::find(v.begin(), v.end(), obj);
+    return it != v.end() ? std::distance(v.begin(), it) : -1;
+}
+
+
+template <typename T, typename F>
+int indexOf(std::vector<T>& v, F&& func)
+{
+       auto it = std::find_if(v.begin(), v.end(), func);
+       return it != v.end() ? std::distance(v.begin(), it) : -1;
+}
+}}};  // giada::u::vector::
+
+#endif
\ No newline at end of file
index c22089f8031c64192eaf91786f5663c62e5d34b0..cace9efde2f877b95cb6d0a46c30996803ade3ba 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index a8322f405de58e295c985aa200c4fe6e365c92cf..96b5f166deec42147167dbf548f600d915ef29ec 100644 (file)
@@ -4,7 +4,7 @@
  *
  * -----------------------------------------------------------------------------
  *
- * Copyright (C) 2010-2018 Giovanni A. Zuliani | Monocasual
+ * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual
  *
  * This file is part of Giada - Your Hardcore Loopmachine.
  *
index 00418d523754a9a164a0b7e3704a9623318f7577..88e7114e4fc283f5c893c43c5a486dc3aa0601c8 100644 (file)
@@ -22,7 +22,6 @@ TEST_CASE("conf")
     conf::channelsIn = 6;
     conf::samplerate = 7;
     conf::buffersize = 8;
-    conf::delayComp = 9;
     conf::limitOutput = true;
     conf::rsmpQuality = 10;
     conf::midiSystem = 11;
@@ -96,7 +95,6 @@ TEST_CASE("conf")
     REQUIRE(conf::channelsIn == 6);
     REQUIRE(conf::samplerate == 44100);  // sanitized
     REQUIRE(conf::buffersize == 8);
-    REQUIRE(conf::delayComp == 9);
     REQUIRE(conf::limitOutput == true);
     REQUIRE(conf::rsmpQuality == 0); // sanitized
     REQUIRE(conf::midiSystem == 11);
index 59f7b39f9246f2dec0067467280e9a05a3ee7611..3a72fbcd2451c966d1814c12faa583fd68f6c729 100644 (file)
@@ -87,7 +87,7 @@ TEST_CASE("patch")
                channel1.begin             = 0;
                channel1.end               = 0;
                channel1.boost             = 0;
-               channel1.recActive         = 0;
+               channel1.readActions       = 0;
                channel1.pitch             = 1.2f;
                channel1.midiInReadActions = 0;
                channel1.midiInPitch       = 0;
@@ -175,7 +175,7 @@ TEST_CASE("patch")
                REQUIRE(channel0.begin == 0);
                REQUIRE(channel0.end == 0);
                REQUIRE(channel0.boost == 1.0f);
-               REQUIRE(channel0.recActive == 0);
+               REQUIRE(channel0.readActions == 0);
                REQUIRE(channel0.pitch == Approx(1.2f));
                REQUIRE(channel0.midiInReadActions == 0);
                REQUIRE(channel0.midiInPitch == 0);
index 59ecdbef0e38fe79c4e715371a8ddc26cf69ab4b..9362f97c0207e78fcfbf9eb4197d432a6cf10e6a 100644 (file)
@@ -19,16 +19,15 @@ TEST_CASE("sampleChannel")
                ChannelMode::SINGLE_ENDLESS };
 
        SampleChannel ch(false, BUFFER_SIZE);
-       Wave* w;
-       waveManager::create("tests/resources/test.wav", &w); 
-       ch.pushWave(w);
+       waveManager::Result res = waveManager::createFromFile("tests/resources/test.wav");
+       int waveSize = res.wave->getSize();
+       ch.pushWave(std::move(res.wave));
 
        SECTION("push wave")
        {
                REQUIRE(ch.status == ChannelStatus::OFF);
-               REQUIRE(ch.wave == w);
                REQUIRE(ch.begin == 0);
-               REQUIRE(ch.end == w->getSize() - 1);
+               REQUIRE(ch.end == waveSize - 1);
                REQUIRE(ch.name == "");         
        }
 
@@ -42,9 +41,9 @@ TEST_CASE("sampleChannel")
 
                ch.setBegin(100000);
 
-               REQUIRE(ch.getBegin() == w->getSize());
-               REQUIRE(ch.tracker == w->getSize());
-               REQUIRE(ch.trackerPreview == w->getSize());
+               REQUIRE(ch.getBegin() == waveSize);
+               REQUIRE(ch.tracker == waveSize);
+               REQUIRE(ch.trackerPreview == waveSize);
 
                ch.setBegin(16);
 
@@ -58,7 +57,7 @@ TEST_CASE("sampleChannel")
 
                ch.setEnd(100000);
 
-               REQUIRE(ch.getEnd() == w->getSize() - 1);
+               REQUIRE(ch.getEnd() == waveSize - 1);
 
                ch.setEnd(32);
 
index 82f2e0799ca3cd993ff683ca36e5ee4cfe2a01e0..510363dd999fd04a0916bdd793cace8ddded7d3f 100644 (file)
@@ -19,9 +19,8 @@ TEST_CASE("sampleChannelProc")
                ChannelMode::SINGLE_PRESS, ChannelMode::SINGLE_RETRIG, 
                ChannelMode::SINGLE_ENDLESS };
 
-       Wave* w;
        SampleChannel ch(false, BUFFER_SIZE);
-       waveManager::create("tests/resources/test.wav", &w); 
+       waveManager::Result res = waveManager::createFromFile("tests/resources/test.wav");
 
        REQUIRE(ch.status == ChannelStatus::EMPTY);
        REQUIRE(ch.mode == ChannelMode::SINGLE_BASIC);
@@ -36,7 +35,7 @@ TEST_CASE("sampleChannelProc")
                        REQUIRE(ch.tracker == 0);
 
                        /* With data, stopped. */
-                       ch.pushWave(w);
+                       ch.pushWave(std::move(res.wave));
                        sampleChannelProc::prepareBuffer(&ch, /*running=*/false);
 
                        REQUIRE(ch.tracker == 0);
@@ -50,7 +49,7 @@ TEST_CASE("sampleChannelProc")
 
                SECTION("fill")
                {
-                       ch.pushWave(w);
+                       ch.pushWave(std::move(res.wave));
 
                        /* Zero offset. */
                        REQUIRE(ch.fillBuffer(ch.buffer, 0, 0) == BUFFER_SIZE);
@@ -65,7 +64,7 @@ TEST_CASE("sampleChannelProc")
 
        SECTION("statuses")
        {
-               ch.pushWave(w);
+               ch.pushWave(std::move(res.wave));
 
                SECTION("start from OFF")
                {
@@ -180,7 +179,7 @@ TEST_CASE("sampleChannelProc")
                                        REQUIRE(ch.status == ChannelStatus::WAIT);      
                                else {
                                        REQUIRE(ch.status == ChannelStatus::OFF);       
-                                       REQUIRE(ch.qWait == true);      
+                                       REQUIRE(ch.quantizing == true); 
                                }
                        }
                }
@@ -210,7 +209,7 @@ TEST_CASE("sampleChannelProc")
 
        SECTION("rewind by sequencer")
        {
-               ch.pushWave(w);
+               ch.pushWave(std::move(res.wave));
 
                /* Test loop modes. */
 
index 79aeb4de4ca156e1bd8c30fd177f8774fd36c534..1a8ba4f4e58772dabf3348f171856dd89b2025de 100644 (file)
@@ -36,16 +36,16 @@ TEST_CASE("u::fs")
 TEST_CASE("u::string")
 {
        using std::vector;
+       using namespace giada::u::string;
 
-       REQUIRE(gu_replace("Giada is cool", "cool", "hot") == "Giada is hot");
-       REQUIRE(gu_trim("   Giada is cool       ") == "Giada is cool");
-       REQUIRE(gu_iToString(666) == "666");
-       REQUIRE(gu_iToString(0x99AABB, true) == "99AABB");
-       REQUIRE(gu_fToString(3.14159, 2) == "3.14");
-       REQUIRE(gu_format("I see %d men with %s hats", 5, "strange") == "I see 5 men with strange hats");
+       REQUIRE(replace("Giada is cool", "cool", "hot") == "Giada is hot");
+       REQUIRE(trim("   Giada is cool       ") == "Giada is cool");
+       REQUIRE(iToString(666) == "666");
+       REQUIRE(iToString(0x99AABB, true) == "99AABB");
+       REQUIRE(fToString(3.14159, 2) == "3.14");
+       REQUIRE(format("I see %d men with %s hats", 5, "strange") == "I see 5 men with strange hats");
 
-       vector<std::string> v;
-       gu_split("Giada is cool", " ", &v);
+       vector<std::string> v = split("Giada is cool", " ");
        REQUIRE(v.size() == 3);
        REQUIRE(v.at(0) == "Giada");
        REQUIRE(v.at(1) == "is");
index f19905ce819e0a7bedf8c0ab89c81b84dc60d23e..2fbeceec954a6f76914eb5b032281fee412c64a6 100644 (file)
@@ -16,48 +16,43 @@ using namespace giada::m;
 
 TEST_CASE("waveManager")
 {
-  /* Each SECTION the TEST_CASE is executed from the start. Any code between 
-  this comment and the first SECTION macro is exectuted before each SECTION. */
-
-  Wave* w;
-
-  SECTION("test creation")
-  {
-    int res = waveManager::create("tests/resources/test.wav", &w);
-    std::unique_ptr<Wave> wave(w);
-    
-    REQUIRE(res == G_RES_OK);
-    REQUIRE(wave->getRate() == G_SAMPLE_RATE);
-    REQUIRE(wave->getChannels() == G_CHANNELS);
-    REQUIRE(wave->isLogical() == false);
-    REQUIRE(wave->isEdited() == false);
-  }
-
-  SECTION("test recording")
-  {
-    waveManager::createEmpty(G_BUFFER_SIZE, G_MAX_IO_CHANS, G_SAMPLE_RATE, 
-      "test.wav", &w);
-    std::unique_ptr<Wave> wave(w);
-
-    REQUIRE(wave->getRate() == G_SAMPLE_RATE);
-    REQUIRE(wave->getSize() == G_BUFFER_SIZE);
-    REQUIRE(wave->getChannels() == G_CHANNELS);
-    REQUIRE(wave->isLogical() == true);
-    REQUIRE(wave->isEdited() == false);
-  }
-
-  SECTION("test resampling")
-  {
-    waveManager::create("tests/resources/test.wav", &w);
-    std::unique_ptr<Wave> wave(w);
-
-    int oldSize = wave->getSize();
-    waveManager::resample(wave.get(), 1, G_SAMPLE_RATE * 2);
-    
-    REQUIRE(wave->getRate() == G_SAMPLE_RATE * 2);
-    REQUIRE(wave->getSize() == oldSize * 2);
-    REQUIRE(wave->getChannels() == G_CHANNELS);
-    REQUIRE(wave->isLogical() == false);
-    REQUIRE(wave->isEdited() == false);
-  }
+       /* Each SECTION the TEST_CASE is executed from the start. Any code between 
+       this comment and the first SECTION macro is exectuted before each SECTION. */
+
+       SECTION("test creation")
+       {
+               waveManager::Result res = waveManager::createFromFile("tests/resources/test.wav");
+
+               REQUIRE(res.status == G_RES_OK);
+               REQUIRE(res.wave->getRate() == G_SAMPLE_RATE);
+               REQUIRE(res.wave->getChannels() == G_CHANNELS);
+               REQUIRE(res.wave->isLogical() == false);
+               REQUIRE(res.wave->isEdited() == false);
+       }
+
+       SECTION("test recording")
+       {
+               std::unique_ptr<Wave> wave = waveManager::createEmpty(G_BUFFER_SIZE, 
+                       G_MAX_IO_CHANS, G_SAMPLE_RATE, "test.wav");
+
+               REQUIRE(wave->getRate() == G_SAMPLE_RATE);
+               REQUIRE(wave->getSize() == G_BUFFER_SIZE);
+               REQUIRE(wave->getChannels() == G_CHANNELS);
+               REQUIRE(wave->isLogical() == true);
+               REQUIRE(wave->isEdited() == false);
+       }
+
+       SECTION("test resampling")
+       {
+               waveManager::Result res = waveManager::createFromFile("tests/resources/test.wav");
+
+               int oldSize = res.wave->getSize();
+               waveManager::resample(res.wave.get(), 1, G_SAMPLE_RATE * 2);
+               
+               REQUIRE(res.wave->getRate() == G_SAMPLE_RATE * 2);
+               REQUIRE(res.wave->getSize() == oldSize * 2);
+               REQUIRE(res.wave->getChannels() == G_CHANNELS);
+               REQUIRE(res.wave->isLogical() == false);
+               REQUIRE(res.wave->isEdited() == false);
+       }
 }