From 681f7b395a6e82b2c6726337f41c6d703cda030d Mon Sep 17 00:00:00 2001 From: =?utf8?q?IOhannes=20m=20zm=C3=B6lnig?= Date: Tue, 20 Aug 2019 14:40:57 +0200 Subject: [PATCH] New upstream version 0.15.4+ds1 --- ChangeLog | 15 + Makefile.am | 33 +- README.md | 2 +- src/core/action.h | 2 +- src/core/channel.cpp | 12 +- src/core/channel.h | 25 +- src/core/channelManager.cpp | 28 +- src/core/channelManager.h | 2 +- src/core/clock.cpp | 294 +++++----- src/core/clock.h | 19 +- src/core/conf.cpp | 50 +- src/core/conf.h | 6 +- src/core/const.h | 461 +++++++-------- src/core/graphics.cpp | 53 +- src/core/graphics.h | 5 +- src/core/init.cpp | 66 ++- src/core/init.h | 3 +- src/core/kernelAudio.cpp | 2 +- src/core/kernelAudio.h | 2 +- src/core/kernelMidi.cpp | 107 ++-- src/core/kernelMidi.h | 2 +- src/core/midiChannel.cpp | 15 +- src/core/midiChannel.h | 11 +- src/core/midiChannelProc.cpp | 2 +- src/core/midiDispatcher.cpp | 74 ++- src/core/midiDispatcher.h | 10 +- src/core/midiEvent.cpp | 2 +- src/core/midiEvent.h | 2 +- src/core/midiMapConf.cpp | 4 +- src/core/midiMapConf.h | 2 +- src/core/mixer.cpp | 368 ++++++------ src/core/mixer.h | 24 +- src/core/mixerHandler.cpp | 142 +++-- src/core/mixerHandler.h | 33 +- src/core/patch.cpp | 10 +- src/core/patch.h | 4 +- src/core/plugin.cpp | 154 +++-- src/core/plugin.h | 55 +- src/core/pluginHost.cpp | 545 ++++-------------- src/core/pluginHost.h | 129 +---- src/core/pluginManager.cpp | 345 +++++++++++ src/core/pluginManager.h | 106 ++++ src/core/range.h | 2 +- src/core/recManager.cpp | 179 ++++++ .../basics/idButton.h => core/recManager.h} | 35 +- src/core/recorder.cpp | 36 +- src/core/recorder.h | 2 +- src/core/recorderHandler.cpp | 10 +- src/core/recorderHandler.h | 10 +- src/core/sampleChannel.cpp | 18 +- src/core/sampleChannel.h | 13 +- src/core/sampleChannelProc.cpp | 20 +- src/core/sampleChannelProc.h | 2 +- src/core/sampleChannelRec.cpp | 30 +- src/core/sampleChannelRec.h | 6 +- src/core/storager.cpp | 2 +- src/core/storager.h | 2 +- src/core/types.h | 11 +- src/core/wave.cpp | 5 +- src/core/wave.h | 2 +- src/core/waveFx.cpp | 2 +- src/core/waveFx.h | 2 +- src/core/waveManager.cpp | 45 +- src/core/waveManager.h | 17 +- src/glue/actionEditor.cpp | 2 +- src/glue/actionEditor.h | 4 +- src/glue/channel.cpp | 42 +- src/glue/channel.h | 2 +- src/glue/io.cpp | 125 ++-- src/glue/io.h | 16 +- src/glue/main.cpp | 67 ++- src/glue/main.h | 40 +- src/glue/plugin.cpp | 33 +- src/glue/plugin.h | 11 +- src/glue/recorder.cpp | 13 +- src/glue/recorder.h | 2 +- src/glue/sampleEditor.cpp | 29 +- src/glue/sampleEditor.h | 2 +- src/glue/storage.cpp | 123 ++-- src/glue/storage.h | 18 +- src/glue/transport.cpp | 28 +- src/glue/transport.h | 4 +- src/gui/dialogs/about.cpp | 28 +- src/gui/dialogs/about.h | 2 +- .../dialogs/actionEditor/baseActionEditor.cpp | 13 +- .../dialogs/actionEditor/baseActionEditor.h | 4 +- .../dialogs/actionEditor/midiActionEditor.cpp | 2 +- .../dialogs/actionEditor/midiActionEditor.h | 2 +- .../actionEditor/sampleActionEditor.cpp | 2 +- .../dialogs/actionEditor/sampleActionEditor.h | 2 +- src/gui/dialogs/beatsInput.cpp | 22 +- src/gui/dialogs/beatsInput.h | 2 +- src/gui/dialogs/bpmInput.cpp | 28 +- src/gui/dialogs/bpmInput.h | 2 +- src/gui/dialogs/browser/browserBase.cpp | 5 +- src/gui/dialogs/browser/browserBase.h | 2 +- src/gui/dialogs/browser/browserDir.cpp | 2 +- src/gui/dialogs/browser/browserDir.h | 2 +- src/gui/dialogs/browser/browserLoad.cpp | 2 +- src/gui/dialogs/browser/browserLoad.h | 2 +- src/gui/dialogs/browser/browserSave.cpp | 2 +- src/gui/dialogs/browser/browserSave.h | 2 +- src/gui/dialogs/channelNameInput.cpp | 4 +- src/gui/dialogs/channelNameInput.h | 2 +- src/gui/dialogs/{gd_config.cpp => config.cpp} | 7 +- src/gui/dialogs/{gd_config.h => config.h} | 2 +- .../dialogs/{gd_devInfo.cpp => devInfo.cpp} | 26 +- src/gui/dialogs/{gd_devInfo.h => devInfo.h} | 2 +- .../{gd_keyGrabber.cpp => keyGrabber.cpp} | 10 +- .../dialogs/{gd_keyGrabber.h => keyGrabber.h} | 2 +- .../{gd_mainWindow.cpp => mainWindow.cpp} | 40 +- .../dialogs/{gd_mainWindow.h => mainWindow.h} | 34 +- src/gui/dialogs/midiIO/midiInputBase.cpp | 2 +- src/gui/dialogs/midiIO/midiInputBase.h | 2 +- src/gui/dialogs/midiIO/midiInputChannel.cpp | 16 +- src/gui/dialogs/midiIO/midiInputChannel.h | 2 +- src/gui/dialogs/midiIO/midiInputMaster.cpp | 5 +- src/gui/dialogs/midiIO/midiInputMaster.h | 2 +- src/gui/dialogs/midiIO/midiOutputBase.cpp | 30 +- src/gui/dialogs/midiIO/midiOutputBase.h | 20 +- src/gui/dialogs/midiIO/midiOutputMidiCh.cpp | 4 +- src/gui/dialogs/midiIO/midiOutputMidiCh.h | 2 +- src/gui/dialogs/midiIO/midiOutputSampleCh.cpp | 4 +- src/gui/dialogs/midiIO/midiOutputSampleCh.h | 2 +- src/gui/dialogs/pluginChooser.cpp | 12 +- src/gui/dialogs/pluginChooser.h | 7 +- src/gui/dialogs/pluginList.cpp | 20 +- src/gui/dialogs/pluginList.h | 7 +- src/gui/dialogs/pluginWindow.cpp | 4 +- src/gui/dialogs/pluginWindow.h | 2 +- src/gui/dialogs/pluginWindowGUI.cpp | 2 +- src/gui/dialogs/pluginWindowGUI.h | 2 +- src/gui/dialogs/sampleEditor.cpp | 16 +- src/gui/dialogs/sampleEditor.h | 2 +- .../dialogs/{gd_warnings.cpp => warnings.cpp} | 11 +- src/gui/dialogs/{gd_warnings.h => warnings.h} | 2 +- src/gui/dialogs/window.cpp | 2 +- src/gui/dialogs/window.h | 2 +- src/gui/dispatcher.cpp | 165 ++++++ .../basics/idButton.cpp => dispatcher.h} | 28 +- src/gui/elems/actionEditor/baseAction.cpp | 2 +- src/gui/elems/actionEditor/baseAction.h | 4 +- .../elems/actionEditor/baseActionEditor.cpp | 2 +- src/gui/elems/actionEditor/baseActionEditor.h | 2 +- src/gui/elems/actionEditor/envelopeEditor.cpp | 2 +- src/gui/elems/actionEditor/envelopeEditor.h | 2 +- src/gui/elems/actionEditor/envelopePoint.cpp | 2 +- src/gui/elems/actionEditor/envelopePoint.h | 2 +- src/gui/elems/actionEditor/gridTool.cpp | 2 +- src/gui/elems/actionEditor/gridTool.h | 2 +- src/gui/elems/actionEditor/noteEditor.cpp | 2 +- src/gui/elems/actionEditor/noteEditor.h | 2 +- src/gui/elems/actionEditor/pianoItem.cpp | 2 +- src/gui/elems/actionEditor/pianoItem.h | 4 +- src/gui/elems/actionEditor/pianoRoll.cpp | 4 +- src/gui/elems/actionEditor/pianoRoll.h | 2 +- src/gui/elems/actionEditor/sampleAction.cpp | 2 +- src/gui/elems/actionEditor/sampleAction.h | 4 +- .../elems/actionEditor/sampleActionEditor.cpp | 2 +- .../elems/actionEditor/sampleActionEditor.h | 4 +- src/gui/elems/actionEditor/velocityEditor.cpp | 2 +- src/gui/elems/actionEditor/velocityEditor.h | 2 +- src/gui/elems/basics/baseButton.cpp | 2 +- src/gui/elems/basics/baseButton.h | 2 +- src/gui/elems/basics/box.cpp | 2 +- src/gui/elems/basics/box.h | 2 +- src/gui/elems/basics/boxtypes.cpp | 2 +- src/gui/elems/basics/boxtypes.h | 2 +- src/gui/elems/basics/button.cpp | 2 +- src/gui/elems/basics/button.h | 2 +- src/gui/elems/basics/check.cpp | 2 +- src/gui/elems/basics/check.h | 2 +- src/gui/elems/basics/choice.cpp | 2 +- src/gui/elems/basics/choice.h | 2 +- src/gui/elems/basics/dial.cpp | 2 +- src/gui/elems/basics/dial.h | 2 +- src/gui/elems/basics/input.cpp | 2 +- src/gui/elems/basics/input.h | 2 +- src/gui/elems/basics/liquidScroll.cpp | 2 +- src/gui/elems/basics/liquidScroll.h | 2 +- src/gui/elems/basics/progress.cpp | 2 +- src/gui/elems/basics/progress.h | 2 +- src/gui/elems/basics/radio.cpp | 2 +- src/gui/elems/basics/radio.h | 2 +- src/gui/elems/basics/resizerBar.cpp | 2 +- src/gui/elems/basics/resizerBar.h | 2 +- src/gui/elems/basics/scroll.cpp | 2 +- src/gui/elems/basics/scroll.h | 2 +- src/gui/elems/basics/slider.cpp | 2 +- src/gui/elems/basics/slider.h | 2 +- src/gui/elems/basics/statusButton.cpp | 2 +- src/gui/elems/basics/statusButton.h | 2 +- src/gui/elems/browser.cpp | 7 +- src/gui/elems/browser.h | 2 +- src/gui/elems/config/tabAudio.cpp | 87 ++- src/gui/elems/config/tabAudio.h | 48 +- src/gui/elems/config/tabBehaviors.cpp | 2 +- src/gui/elems/config/tabBehaviors.h | 2 +- src/gui/elems/config/tabMidi.cpp | 7 +- src/gui/elems/config/tabMidi.h | 2 +- src/gui/elems/config/tabMisc.cpp | 2 +- src/gui/elems/config/tabMisc.h | 2 +- src/gui/elems/config/tabPlugins.cpp | 15 +- src/gui/elems/config/tabPlugins.h | 2 +- src/gui/elems/mainWindow/beatMeter.cpp | 65 ++- src/gui/elems/mainWindow/beatMeter.h | 14 +- src/gui/elems/mainWindow/keyboard/channel.cpp | 68 +-- src/gui/elems/mainWindow/keyboard/channel.h | 118 ++-- .../mainWindow/keyboard/channelButton.cpp | 2 +- .../elems/mainWindow/keyboard/channelButton.h | 2 +- .../elems/mainWindow/keyboard/channelMode.cpp | 99 ++-- .../elems/mainWindow/keyboard/channelMode.h | 2 +- .../mainWindow/keyboard/channelStatus.cpp | 2 +- .../elems/mainWindow/keyboard/channelStatus.h | 2 +- src/gui/elems/mainWindow/keyboard/column.cpp | 10 +- src/gui/elems/mainWindow/keyboard/column.h | 10 +- .../elems/mainWindow/keyboard/keyboard.cpp | 82 +-- src/gui/elems/mainWindow/keyboard/keyboard.h | 11 +- .../elems/mainWindow/keyboard/midiChannel.cpp | 30 +- .../elems/mainWindow/keyboard/midiChannel.h | 2 +- .../mainWindow/keyboard/midiChannelButton.cpp | 2 +- .../mainWindow/keyboard/midiChannelButton.h | 2 +- .../mainWindow/keyboard/sampleChannel.cpp | 46 +- .../elems/mainWindow/keyboard/sampleChannel.h | 2 +- .../keyboard/sampleChannelButton.cpp | 6 +- .../mainWindow/keyboard/sampleChannelButton.h | 2 +- src/gui/elems/mainWindow/mainIO.cpp | 60 +- src/gui/elems/mainWindow/mainIO.h | 41 +- src/gui/elems/mainWindow/mainMenu.cpp | 64 +- src/gui/elems/mainWindow/mainMenu.h | 31 +- src/gui/elems/mainWindow/mainTimer.cpp | 40 +- src/gui/elems/mainWindow/mainTimer.h | 6 +- src/gui/elems/mainWindow/mainTransport.cpp | 116 ++-- src/gui/elems/mainWindow/mainTransport.h | 38 +- src/gui/elems/midiLearner.cpp | 20 +- src/gui/elems/midiLearner.h | 2 +- src/gui/elems/plugin/pluginBrowser.cpp | 17 +- src/gui/elems/plugin/pluginBrowser.h | 2 +- src/gui/elems/plugin/pluginElement.cpp | 22 +- src/gui/elems/plugin/pluginElement.h | 16 +- src/gui/elems/plugin/pluginParameter.cpp | 2 +- src/gui/elems/plugin/pluginParameter.h | 2 +- src/gui/elems/sampleEditor/boostTool.cpp | 6 +- src/gui/elems/sampleEditor/boostTool.h | 2 +- src/gui/elems/sampleEditor/panTool.cpp | 12 +- src/gui/elems/sampleEditor/panTool.h | 2 +- src/gui/elems/sampleEditor/pitchTool.cpp | 6 +- src/gui/elems/sampleEditor/pitchTool.h | 2 +- src/gui/elems/sampleEditor/rangeTool.cpp | 14 +- src/gui/elems/sampleEditor/rangeTool.h | 2 +- src/gui/elems/sampleEditor/shiftTool.cpp | 14 +- src/gui/elems/sampleEditor/shiftTool.h | 2 +- src/gui/elems/sampleEditor/volumeTool.cpp | 10 +- src/gui/elems/sampleEditor/volumeTool.h | 2 +- src/gui/elems/sampleEditor/waveTools.cpp | 2 +- src/gui/elems/sampleEditor/waveTools.h | 2 +- src/gui/elems/sampleEditor/waveform.cpp | 4 +- src/gui/elems/sampleEditor/waveform.h | 2 +- src/gui/elems/soundMeter.cpp | 47 +- src/gui/elems/soundMeter.h | 10 +- src/main.cpp | 2 +- src/utils/cocoa.h | 2 +- src/utils/fs.cpp | 7 +- src/utils/fs.h | 2 +- src/utils/gui.cpp | 80 +-- src/utils/gui.h | 56 +- src/utils/log.cpp | 2 +- src/utils/log.h | 2 +- src/utils/math.cpp | 4 +- src/utils/math.h | 2 +- src/utils/string.cpp | 52 +- src/utils/string.h | 22 +- src/utils/time.cpp | 2 +- src/utils/time.h | 2 +- src/utils/vector.h | 57 ++ src/utils/ver.cpp | 2 +- src/utils/ver.h | 2 +- tests/conf.cpp | 2 - tests/patch.cpp | 4 +- tests/sampleChannel.cpp | 17 +- tests/sampleChannelProc.cpp | 13 +- tests/utils.cpp | 16 +- tests/waveManager.cpp | 83 ++- 283 files changed, 3724 insertions(+), 3070 deletions(-) create mode 100644 src/core/pluginManager.cpp create mode 100644 src/core/pluginManager.h create mode 100644 src/core/recManager.cpp rename src/{gui/elems/basics/idButton.h => core/recManager.h} (66%) rename src/gui/dialogs/{gd_config.cpp => config.cpp} (96%) rename src/gui/dialogs/{gd_config.h => config.h} (96%) rename src/gui/dialogs/{gd_devInfo.cpp => devInfo.cpp} (71%) rename src/gui/dialogs/{gd_devInfo.h => devInfo.h} (95%) rename src/gui/dialogs/{gd_keyGrabber.cpp => keyGrabber.cpp} (95%) rename src/gui/dialogs/{gd_keyGrabber.h => keyGrabber.h} (96%) rename src/gui/dialogs/{gd_mainWindow.cpp => mainWindow.cpp} (80%) rename src/gui/dialogs/{gd_mainWindow.h => mainWindow.h} (77%) rename src/gui/dialogs/{gd_warnings.cpp => warnings.cpp} (93%) rename src/gui/dialogs/{gd_warnings.h => warnings.h} (95%) create mode 100644 src/gui/dispatcher.cpp rename src/gui/{elems/basics/idButton.cpp => dispatcher.h} (73%) create mode 100644 src/utils/vector.h diff --git a/ChangeLog b/ChangeLog index ea1d5b2..b4bdc9e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,21 @@ -------------------------------------------------------------------------------- +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) diff --git a/Makefile.am b/Makefile.am index 4cb3529..93e11fc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 \ diff --git a/README.md b/README.md index 91998f3..e46b63a 100644 --- 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. diff --git a/src/core/action.h b/src/core/action.h index af283ed..b4ee058 100644 --- a/src/core/action.h +++ b/src/core/action.h @@ -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/channel.cpp b/src/core/channel.cpp index 5c5e554..ae9654a 100644 --- a/src/core/channel.cpp +++ b/src/core/channel.cpp @@ -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 : 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; } diff --git a/src/core/channel.h b/src/core/channel.h index 45ec277..150d7e8 100644 --- a/src/core/channel.h +++ b/src/core/channel.h @@ -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 plugins; + std::vector> plugins; #endif protected: diff --git a/src/core/channelManager.cpp b/src/core/channelManager.cpp index d138be3..cd64640 100644 --- a/src/core/channelManager.cpp +++ b/src/core/channelManager.cpp @@ -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 = 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(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? } diff --git a/src/core/channelManager.h b/src/core/channelManager.h index d9fd490..d3d7c6b 100644 --- a/src/core/channelManager.h +++ b/src/core/channelManager.h @@ -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/clock.cpp b/src/core/clock.cpp index ea6dfbe..4fe1068 100644 --- a/src/core/clock.cpp +++ b/src/core/clock.cpp @@ -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 #include #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 quantize_(G_DEFAULT_QUANTIZE); +std::atomic status_(ClockStatus::STOPPED); + +int framesInLoop_ = 0; +int framesInBar_ = 0; +int framesInBeat_ = 0; +int framesInSeq_ = 0; +std::atomic currentFrameWait_(0); // Used only in wait mode +std::atomic currentFrame_(0); +std::atomic 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:: diff --git a/src/core/clock.h b/src/core/clock.h index 43f225b..3f5e9fb 100644 --- a/src/core/clock.h +++ b/src/core/clock.h @@ -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:: diff --git a/src/core/conf.cpp b/src/core/conf.cpp index 975543c..ce69e9f 100644 --- a/src/core/conf.cpp +++ b/src/core/conf.cpp @@ -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(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 diff --git a/src/core/conf.h b/src/core/conf.h index dd2c53b..b7aca0f 100644 --- a/src/core/conf.h +++ b/src/core/conf.h @@ -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; diff --git a/src/core/const.h b/src/core/const.h index 81e38c9..0bf9107 100644 --- a/src/core/const.h +++ b/src/core/const.h @@ -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. * @@ -45,13 +45,13 @@ /* -- 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 diff --git a/src/core/graphics.cpp b/src/core/graphics.cpp index b73474b..7655b91 100644 --- a/src/core/graphics.cpp +++ b/src/core/graphics.cpp @@ -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", diff --git a/src/core/graphics.h b/src/core/graphics.h index 5fae68b..6427a31 100644 --- a/src/core/graphics.h +++ b/src/core/graphics.h @@ -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[]; diff --git a/src/core/init.cpp b/src/core/init.cpp index e03ff65..eb677f7 100644 --- a/src/core/init.cpp +++ b/src/core/init.cpp @@ -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 +#include #include +#include #ifdef __APPLE__ #include #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" @@ -49,8 +51,10 @@ #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(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 diff --git a/src/core/init.h b/src/core/init.h index 27a5f6e..b56ace4 100644 --- a/src/core/init.h +++ b/src/core/init.h @@ -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 diff --git a/src/core/kernelAudio.cpp b/src/core/kernelAudio.cpp index e30c6f6..4d42806 100644 --- a/src/core/kernelAudio.cpp +++ b/src/core/kernelAudio.cpp @@ -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/core/kernelAudio.h b/src/core/kernelAudio.h index bd256fe..7177923 100644 --- a/src/core/kernelAudio.h +++ b/src/core/kernelAudio.h @@ -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/kernelMidi.cpp b/src/core/kernelMidi.cpp index 485f7c1..cdb4731 100644 --- a/src/core/kernelMidi.cpp +++ b/src/core/kernelMidi.cpp @@ -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* msg, void* data) +static void callback_(double t, vector* 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* msg, void* data) /* -------------------------------------------------------------------------- */ -void sendMidiLightningInitMsgs() +void sendMidiLightningInitMsgs_() { for(unsigned i=0; igetPortCount(); - gu_log("[KM] %d output MIDI ports found\n", numOutPorts); - for (unsigned i=0; igetPortCount(); + gu_log("[KM] %d output MIDI ports found\n", numOutPorts_); + for (unsigned i=0; i 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 (RtMidiError& error) { 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; igetPortCount(); + gu_log("[KM] %d input MIDI ports found\n", numInPorts_); + for (unsigned i=0; i 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 (RtMidiError& error) { 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 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 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:: diff --git a/src/core/kernelMidi.h b/src/core/kernelMidi.h index 450854c..55a5b76 100644 --- a/src/core/kernelMidi.h +++ b/src/core/kernelMidi.h @@ -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/midiChannel.cpp b/src/core/midiChannel.cpp index 7cc871f..20ead79 100644 --- a/src/core/midiChannel.cpp +++ b/src/core/midiChannel.cpp @@ -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:: diff --git a/src/core/midiChannel.h b/src/core/midiChannel.h index ee22e3f..16de069 100644 --- a/src/core/midiChannel.h +++ b/src/core/midiChannel.h @@ -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); diff --git a/src/core/midiChannelProc.cpp b/src/core/midiChannelProc.cpp index 646c84d..d85ad30 100644 --- a/src/core/midiChannelProc.cpp +++ b/src/core/midiChannelProc.cpp @@ -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. diff --git a/src/core/midiDispatcher.cpp b/src/core/midiDispatcher.cpp index bb65bd8..64d40a7 100644 --- a/src/core/midiDispatcher.cpp +++ b/src/core/midiDispatcher.cpp @@ -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 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* plugins. */ - vector* plugins = pluginHost::getStack(pluginHost::CHANNEL, ch); + std::vector plugins = pluginHost::getStack(pluginHost::StackType::CHANNEL, ch); - for (Plugin* plugin : *plugins) { + for (Plugin* plugin : plugins) { for (unsigned k=0; kmidiInParams.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 f) +{ + signalCb_ = f; +} + }}}; // giada::m::midiDispatcher:: diff --git a/src/core/midiDispatcher.h b/src/core/midiDispatcher.h index 395622e..e8df2f8 100644 --- a/src/core/midiDispatcher.h +++ b/src/core/midiDispatcher.h @@ -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,11 +29,8 @@ #define G_MIDI_DISPATCHER_H -#ifdef __APPLE__ // our Clang still doesn't know about cstdint (c++11 stuff) - #include -#else - #include -#endif +#include +#include namespace giada { @@ -47,6 +44,7 @@ void stopMidiLearn(); void dispatch(int byte1, int byte2, int byte3); +void setSignalCallback(std::function f); }}}; // giada::m::midiDispatcher:: diff --git a/src/core/midiEvent.cpp b/src/core/midiEvent.cpp index fdf63e0..db25f76 100644 --- a/src/core/midiEvent.cpp +++ b/src/core/midiEvent.cpp @@ -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/midiEvent.h b/src/core/midiEvent.h index 3694b57..111fceb 100644 --- a/src/core/midiEvent.h +++ b/src/core/midiEvent.h @@ -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/midiMapConf.cpp b/src/core/midiMapConf.cpp index 0b04a8c..c8a962e 100644 --- a/src/core/midiMapConf.cpp +++ b/src/core/midiMapConf.cpp @@ -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; diff --git a/src/core/midiMapConf.h b/src/core/midiMapConf.h index 6584d35..3a5f9da 100644 --- a/src/core/midiMapConf.h +++ b/src/core/midiMapConf.h @@ -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/mixer.cpp b/src/core/mixer.cpp index 2707572..f6f7996 100644 --- a/src/core/mixer.cpp +++ b/src/core/mixer.cpp @@ -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 #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 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 signalCb_ = nullptr; /* -------------------------------------------------------------------------- */ -/* computePeak */ -void computePeak(const AudioBuffer& buf, float& peak, Frame frame) +void computePeak_(const AudioBuffer& buf, std::atomic& peak) { - for (int i=0; i peak) - peak = buf[frame][i]; + for (int i=0; i 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= clock::getFramesInLoop()) - inputTracker = 0; + for (int i=0; i= 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; iprepareBuffer(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= TICKSIZE-1) { - tockPlay = false; - tockTracker = 0; - } - } - if (tickPlay) { - for (int i=0; i= 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 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 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; iparseEvents(fe); } }; // {anonymous} @@ -282,17 +296,17 @@ void renderMetronome() std::vector 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 outVol(G_DEFAULT_OUT_VOL); +std::atomic inVol(G_DEFAULT_IN_VOL); +std::atomic peakOut(0.0); +std::atomic 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; jparseEvents(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 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 f) +{ + signalCb_ = f; +} + + /* -------------------------------------------------------------------------- */ @@ -470,8 +492,8 @@ void mergeVirtualInput() continue; SampleChannel* sch = static_cast(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:: diff --git a/src/core/mixer.h b/src/core/mixer.h index fea09bb..10b18dc 100644 --- a/src/core/mixer.h +++ b/src/core/mixer.h @@ -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 #include +#include #include #include "recorder.h" #include "types.h" @@ -57,16 +59,14 @@ struct FrameEvents extern std::vector 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 outVol; +extern std::atomic inVol; +extern std::atomic peakOut; +extern std::atomic 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 f); }}} // giada::m::mixer::; diff --git a/src/core/mixerHandler.cpp b/src/core/mixerHandler.cpp index 8601ed8..4864a24 100644 --- a/src/core/mixerHandler.cpp +++ b/src/core/mixerHandler.cpp @@ -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,11 +25,13 @@ * -------------------------------------------------------------------------- */ +#include #include #include #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* list, int type) +int readPatchPlugins_(const vector& list, pluginHost::StackType t) { int ret = 1; - for (unsigned i=0; isize(); 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; jparams.size(); j++) - plugin->setParameter(j, ppl->params.at(j)); + for (const patch::plugin_t& ppl : list) { + std::unique_ptr p = pluginManager::makePlugin(ppl.path); + if (p != nullptr) { + p->setBypass(ppl.bypass); + for (unsigned j=0; jsetParameter(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(); + }); } diff --git a/src/core/mixerHandler.h b/src/core/mixerHandler.h index 895a1dc..19e514e 100644 --- a/src/core/mixerHandler.h +++ b/src/core/mixerHandler.h @@ -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:: diff --git a/src/core/patch.cpp b/src/core/patch.cpp index 2add0b9..5f61b17 100644 --- a/src/core/patch.cpp +++ b/src/core/patch.cpp @@ -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* 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)); diff --git a/src/core/patch.h b/src/core/patch.h index afc5180..833ade2 100644 --- a/src/core/patch.h +++ b/src/core/patch.h @@ -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; diff --git a/src/core/plugin.cpp b/src/core/plugin.cpp index 2af8fae..32e9b88 100644 --- a/src/core/plugin.cpp +++ b/src/core/plugin.cpp @@ -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& params = plugin->getParameters(); + const OwnedArray& params = m_plugin->getParameters(); for (int i=0; iprepareToPlay(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(b); + for (int i=0; igetBusCount(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& b, juce::MidiBuffer m) const +void Plugin::process(juce::AudioBuffer& 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& 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:: diff --git a/src/core/plugin.h b/src/core/plugin.h index 61202b6..a7cca04 100644 --- a/src/core/plugin.h +++ b/src/core/plugin.h @@ -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& 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& 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 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 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:: diff --git a/src/core/pluginHost.cpp b/src/core/pluginHost.cpp index 2e84fe8..98f09d8 100644 --- a/src/core/pluginHost.cpp +++ b/src/core/pluginHost.cpp @@ -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,100 +30,62 @@ #include #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 audioBuffer_; -juce::KnownPluginList knownPluginList; +std::vector> masterOut_; +std::vector> masterIn_; -/* unknownPluginList - * List of unrecognized plugins found in a patch. */ -vector unknownPluginList; - -vector masterOut; -vector masterIn; - -/* Audio|MidiBuffer - * Dynamic buffers. */ - -juce::AudioBuffer 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& 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>& getStack_(StackType t, Channel* ch=nullptr) { - vector idParts; - splitPluginDescription(id, idParts); - - for (const juce::PluginDescription* pd : knownPluginList) { - vector 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& 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 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 p, StackType t, pthread_mutex_t* mixerMutex, Channel* ch) { - vector* 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>& 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* getStack(int stackType, Channel* ch) +std::vector 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>& stack = getStack_(t, ch); + std::vector out; + for (const std::unique_ptr& p : stack) + out.push_back(p.get()); -/* -------------------------------------------------------------------------- */ - - -unsigned countPlugins(int stackType, Channel* ch) -{ - vector* 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* pStack = getStack(stackType, ch); + std::vector>& 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; isize(); 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* pStack = getStack(stackType, ch); - - /* Empty stack, stack not found or mixer not ready: do nothing. */ + std::vector>& 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; iisSuspended() || 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 tmp(audioBuffer.getNumChannels(), buffersize); - plugin->process(tmp, ch->getPluginMidiEvents()); - for (int i=0; iprocess(audioBuffer, juce::MidiBuffer()); // Empty MIDI buffer - } + pthread_mutex_lock(&mutex); + + for (std::unique_ptr& 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* 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* pStack = getStack(stackType, ch); - for (unsigned i=0; isize(); i++) - if (pStack->at(i)->getId() == id) - return i; - return -1; + std::vector>& 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* 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>& stack = getStack_(t, ch); + return u::vector::indexOf(stack, [&](const std::unique_ptr& 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* pStack = getStack(stackType, ch); - for (unsigned i=0; isize(); 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>& 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* 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; isize(); i++) - freeStack(pluginHost::CHANNEL, mutex, channels->at(i)); - missingPlugins = false; - unknownPluginList.clear(); -} - - -/* -------------------------------------------------------------------------- */ - + std::vector>& 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& p) + { + return p->getId() == id; + }); + assert(index != -1); - for (int k=0; kgetNumParameters(); 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* 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 f) +void forEachPlugin(StackType t, const Channel* ch, std::function f) { - /* TODO - Remove const is ugly. This is a temporary workaround until all - PluginHost functions params will be const-correct. */ - vector* stack = getStack(stackType, const_cast(ch)); - for (const Plugin* p : *stack) - f(p); + std::vector>& stack = getStack_(t, const_cast(ch)); + for (const std::unique_ptr& p : stack) + f(p.get()); } - }}}; // giada::m::pluginHost:: diff --git a/src/core/pluginHost.h b/src/core/pluginHost.h index aff17a9..4852d4a 100644 --- a/src/core/pluginHost.h +++ b/src/core/pluginHost.h @@ -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 #include #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& 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 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 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* getStack(int stackType, Channel* ch=nullptr); +std::vector 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* 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 f); +void forEachPlugin(StackType t, const Channel* ch, std::function f); }}}; // giada::m::pluginHost:: diff --git a/src/core/pluginManager.cpp b/src/core/pluginManager.cpp new file mode 100644 index 0000000..4b6d1a1 --- /dev/null +++ b/src/core/pluginManager.cpp @@ -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 + * . + * + * -------------------------------------------------------------------------- */ + + +#ifdef WITH_VST + + +#include +#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 unknownPluginList_; + +/* missingPlugins +If some plugins from any stack are missing. */ + +bool missingPlugins_; + +vector splitPluginDescription_(const string& descr) +{ + // input: VST-mda-Ambience-18fae2d2-6d646141 string + // output: [2-------------] [1-----] [0-----] vector.size() == 3 + + vector 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 idParts = splitPluginDescription_(id); + + for (const juce::PluginDescription* pd : knownPluginList_) { + vector 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& 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 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 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(pi, samplerate_, buffersize_); +} + + +/* -------------------------------------------------------------------------- */ + + +std::unique_ptr 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 makePlugin(const Plugin& src) +{ + std::unique_ptr p = makePlugin(src.getUniqueId()); + + for (int i=0; isetParameter(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 index 0000000..1e345b1 --- /dev/null +++ b/src/core/pluginManager.h @@ -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 + * . + * + * -------------------------------------------------------------------------- */ + + +#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& 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 makePlugin(const std::string& fid); +std::unique_ptr makePlugin(int index); +std::unique_ptr 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 diff --git a/src/core/range.h b/src/core/range.h index 296dac0..6ba031d 100644 --- a/src/core/range.h +++ b/src/core/range.h @@ -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 index 0000000..57bb283 --- /dev/null +++ b/src/core/recManager.cpp @@ -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 + * . + * + * -------------------------------------------------------------------------- */ + + +#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 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/gui/elems/basics/idButton.h b/src/core/recManager.h similarity index 66% rename from src/gui/elems/basics/idButton.h rename to src/core/recManager.h index 312930d..13c6f85 100644 --- a/src/gui/elems/basics/idButton.h +++ b/src/core/recManager.h @@ -2,13 +2,9 @@ * * 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 + * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual * * This file is part of Giada - Your Hardcore Loopmachine. * @@ -29,23 +25,30 @@ * -------------------------------------------------------------------------- */ -#ifndef GE_ID_BUTTON_H -#define GE_ID_BUTTON_H +#ifndef G_REC_MANAGER_H +#define G_REC_MANAGER_H -#include "button.h" +#include +#include "types.h" -class geIdButton : public geButton +namespace giada { +namespace m { +namespace recManager { -public: +void init(pthread_mutex_t* mixerMutex); - geIdButton(int X,int Y,int W,int H,const char *L=0, - const char **imgOff=nullptr, const char **imgOn=nullptr); +/* isActive +Returns true if its ready for recording, whether it is actually recording +something or is in wait mode for a signal. */ - int key; - int id; -}; +bool isActive(); +bool startActionRec(RecTriggerMode m); +void stopActionRec(); +bool startInputRec(RecTriggerMode m); +void stopInputRec(); +}}} // giada::m::recManager -#endif +#endif \ No newline at end of file diff --git a/src/core/recorder.cpp b/src/core/recorder.cpp index 0f7803b..c5fb6e7 100644 --- a/src/core/recorder.cpp +++ b/src/core/recorder.cpp @@ -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 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 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& as) ActionMap temp = actions; for (const Action* a : as) { - const_cast(a)->id = actionId++; + const_cast(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_; } /* -------------------------------------------------------------------------- */ diff --git a/src/core/recorder.h b/src/core/recorder.h index dfb6b0a..0f3f1fb 100644 --- a/src/core/recorder.h +++ b/src/core/recorder.h @@ -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/recorderHandler.cpp b/src/core/recorderHandler.cpp index 7879be6..53415db 100644 --- a/src/core/recorderHandler.cpp +++ b/src/core/recorderHandler.cpp @@ -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 consolidate() { consolidate_(); recorder::rec(recs_); + + std::unordered_set out; + for (const Action* action : recs_) + out.insert(action->channel); + recs_.clear(); + return out; } diff --git a/src/core/recorderHandler.h b/src/core/recorderHandler.h index 7b256a7..0554b15 100644 --- a/src/core/recorderHandler.h +++ b/src/core/recorderHandler.h @@ -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 #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 consolidate(); void writePatch(int chanIndex, std::vector& pactions); void readPatch(const std::vector& pactions); diff --git a/src/core/sampleChannel.cpp b/src/core/sampleChannel.cpp index b352430..3a5d986 100644 --- a/src/core/sampleChannel.cpp +++ b/src/core/sampleChannel.cpp @@ -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(*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&& 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; } diff --git a/src/core/sampleChannel.h b/src/core/sampleChannel.h index 4514f0e..c2b2dd1 100644 --- a/src/core/sampleChannel.h +++ b/src/core/sampleChannel.h @@ -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 #include #include #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&& w); void setPitch(float v); void setBegin(int f); @@ -119,11 +120,11 @@ public: ChannelMode mode; - Wave* wave; + std::unique_ptr 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; diff --git a/src/core/sampleChannelProc.cpp b/src/core/sampleChannelProc.cpp index ef3569e..4612f5b 100644 --- a/src/core/sampleChannelProc.cpp +++ b/src/core/sampleChannelProc.cpp @@ -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; imode == 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); } diff --git a/src/core/sampleChannelProc.h b/src/core/sampleChannelProc.h index 5f14e85..36d39e2 100644 --- a/src/core/sampleChannelProc.h +++ b/src/core/sampleChannelProc.h @@ -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/sampleChannelRec.cpp b/src/core/sampleChannelRec.cpp index ec8a7a8..a79f012 100644 --- a/src/core/sampleChannelRec.cpp +++ b/src/core/sampleChannelRec.cpp @@ -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; } diff --git a/src/core/sampleChannelRec.h b/src/core/sampleChannelRec.h index 720a748..ef64e33 100644 --- a/src/core/sampleChannelRec.h +++ b/src/core/sampleChannelRec.h @@ -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); diff --git a/src/core/storager.cpp b/src/core/storager.cpp index bf08fdd..eb36fcf 100644 --- a/src/core/storager.cpp +++ b/src/core/storager.cpp @@ -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/storager.h b/src/core/storager.h index 58a1756..52500a2 100644 --- a/src/core/storager.h +++ b/src/core/storager.h @@ -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/types.h b/src/core/types.h index 4754a10..15efc16 100644 --- a/src/core/types.h +++ b/src/core/types.h @@ -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 }; diff --git a/src/core/wave.cpp b/src/core/wave.cpp index 40a68d4..7841338 100644 --- a/src/core/wave.cpp +++ b/src/core/wave.cpp @@ -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); } diff --git a/src/core/wave.h b/src/core/wave.h index f285bf3..50bedb8 100644 --- a/src/core/wave.h +++ b/src/core/wave.h @@ -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/waveFx.cpp b/src/core/waveFx.cpp index d3f147e..18cf80c 100644 --- a/src/core/waveFx.cpp +++ b/src/core/waveFx.cpp @@ -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/waveFx.h b/src/core/waveFx.h index 51146ba..f5e48b1 100644 --- a/src/core/waveFx.h +++ b/src/core/waveFx.h @@ -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/waveManager.cpp b/src/core/waveManager.cpp index c7e48e0..64cb1d7 100644 --- a/src/core/waveManager.cpp +++ b/src/core/waveManager.cpp @@ -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 = std::make_unique(); 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 createEmpty(int frames, int channels, int samplerate, + const string& name) { - Wave* wave = new Wave(); + std::unique_ptr wave = std::make_unique(); 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 createFromWave(const Wave* src, int a, int b) { int channels = src->getChannels(); int frames = b - a; - Wave* wave = new Wave(); + std::unique_ptr wave = std::make_unique(); 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; } diff --git a/src/core/waveManager.h b/src/core/waveManager.h index 0f0b764..927054a 100644 --- a/src/core/waveManager.h +++ b/src/core/waveManager.h @@ -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 +#include class Wave; @@ -39,21 +40,27 @@ namespace giada { namespace m { namespace waveManager { +struct Result +{ + int status; + std::unique_ptr 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 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 createFromWave(const Wave* src, int a, int b); int resample(Wave* w, int quality, int samplerate); int save(Wave* w, const std::string& path); diff --git a/src/glue/actionEditor.cpp b/src/glue/actionEditor.cpp index 22c8d22..5d2c6d5 100644 --- a/src/glue/actionEditor.cpp +++ b/src/glue/actionEditor.cpp @@ -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/glue/actionEditor.h b/src/glue/actionEditor.h index 17fd7fb..7c4f814 100644 --- a/src/glue/actionEditor.h +++ b/src/glue/actionEditor.h @@ -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; } diff --git a/src/glue/channel.cpp b/src/glue/channel.cpp index 74db5c9..41df941 100644 --- a/src/glue/channel.cpp +++ b/src/glue/channel.cpp @@ -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 #include -#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(gu_getSubwindow(G_MainWin, WID_SAMPLE_EDITOR)); + gdSampleEditor* gdEditor = static_cast(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(gu_getSubwindow(G_MainWin, WID_SAMPLE_EDITOR)); + gdSampleEditor* gdEditor = static_cast(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(gu_getSubwindow(G_MainWin, WID_SAMPLE_EDITOR)); + gdSampleEditor* gdEditor = static_cast(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(gu_getSubwindow(G_MainWin, WID_SAMPLE_EDITOR)); + gdSampleEditor *gdEditor = static_cast(u::gui::getSubwindow(G_MainWin, WID_SAMPLE_EDITOR)); if (gdEditor) { Fl::lock(); gdEditor->boostTool->refresh(); diff --git a/src/glue/channel.h b/src/glue/channel.h index 9c18db7..0808297 100644 --- a/src/glue/channel.h +++ b/src/glue/channel.h @@ -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/glue/io.cpp b/src/glue/io.cpp index d2f1ea4..0a26914 100644 --- a/src/glue/io.cpp +++ b/src/glue/io.cpp @@ -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 -#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" @@ -37,10 +38,14 @@ #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(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(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(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(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 diff --git a/src/glue/io.h b/src/glue/io.h index e8e8eee..2233d40 100644 --- a/src/glue/io.h +++ b/src/glue/io.h @@ -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 diff --git a/src/glue/main.cpp b/src/glue/main.cpp index 1aad7a0..fe0ef93 100644 --- a/src/glue/main.cpp +++ b/src/glue/main.cpp @@ -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 diff --git a/src/glue/main.h b/src/glue/main.h index ef7c794..d3db874 100644 --- a/src/glue/main.h +++ b/src/glue/main.h @@ -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. * @@ -32,37 +32,43 @@ * -------------------------------------------------------------------------- */ -#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 diff --git a/src/glue/plugin.cpp b/src/glue/plugin.cpp index c5282ac..906971d 100644 --- a/src/glue/plugin.cpp +++ b/src/glue/plugin.cpp @@ -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 +#include "../core/pluginManager.h" #include "../core/pluginHost.h" #include "../core/mixer.h" #include "../core/plugin.h" @@ -36,11 +37,11 @@ #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(gu_getSubwindow(G_MainWin, WID_FX_LIST)); + gdPluginList* parent = static_cast(u::gui::getSubwindow(G_MainWin, WID_FX_LIST)); if (parent == nullptr) return nullptr; - return static_cast(gu_getSubwindow(parent, p->getId() + 1)); + return static_cast(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 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(gu_getSubwindow(G_MainWin, WID_CONFIG)); + gdConfig* configWin = static_cast(u::gui::getSubwindow(G_MainWin, WID_CONFIG)); configWin->refreshVstPath(); } diff --git a/src/glue/plugin.h b/src/glue/plugin.h index 4b55afd..7ce3ee1 100644 --- a/src/glue/plugin.h +++ b/src/glue/plugin.h @@ -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); diff --git a/src/glue/recorder.cpp b/src/glue/recorder.cpp index 2b166cb..ec99dc2 100644 --- a/src/glue/recorder.cpp +++ b/src/glue/recorder.cpp @@ -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 -#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" @@ -44,10 +44,6 @@ #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(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 diff --git a/src/glue/recorder.h b/src/glue/recorder.h index f28a3cc..54e2361 100644 --- a/src/glue/recorder.h +++ b/src/glue/recorder.h @@ -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/glue/sampleEditor.cpp b/src/glue/sampleEditor.cpp index f86c67b..1252b10 100644 --- a/src/glue/sampleEditor.cpp +++ b/src/glue/sampleEditor.cpp @@ -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 #include -#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 waveBuffer_; }; // {anonymous} @@ -72,7 +72,7 @@ namespace gdSampleEditor* getSampleEditorWindow() { - gdSampleEditor* se = static_cast(gu_getSubwindow(G_MainWin, WID_SAMPLE_EDITOR)); + gdSampleEditor* se = static_cast(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(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; } diff --git a/src/glue/sampleEditor.h b/src/glue/sampleEditor.h index 3cd4bc8..a7339f8 100644 --- a/src/glue/sampleEditor.h +++ b/src/glue/sampleEditor.h @@ -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/glue/storage.cpp b/src/glue/storage.cpp index e3779e2..d04c494 100644 --- a/src/glue/storage.cpp +++ b/src/glue/storage.cpp @@ -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" @@ -54,29 +55,32 @@ #include "storage.h" -extern gdMainWindow *G_MainWin; +extern gdMainWindow* G_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 * host, vector* patch) +void fillPatchGlobalsPlugins_(vector stack, vector& patch) { using namespace giada::m; - for (unsigned i=0; isize(); 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; kgetParameter(k)); - patch->push_back(ppl); + ppl.path = plugin->getUniqueId(); + ppl.bypass = plugin->isBypassed(); + for (int k=0; kgetNumParameters(); k++) + ppl.params.push_back(plugin->getParameter(k)); + patch.push_back(ppl); } } @@ -86,7 +90,7 @@ static void glue_fillPatchGlobalsPlugins__(vector * host, vectorwritePatch(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(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 diff --git a/src/glue/storage.h b/src/glue/storage.h index 35f15d2..779dcf0 100644 --- a/src/glue/storage.h +++ b/src/glue/storage.h @@ -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,11 +29,15 @@ #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 diff --git a/src/glue/transport.cpp b/src/glue/transport.cpp index 4e958dc..bb7ba34 100644 --- a/src/glue/transport.cpp +++ b/src/glue/transport.cpp @@ -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 #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(); } } diff --git a/src/glue/transport.h b/src/glue/transport.h index 3be492f..69713bc 100644 --- a/src/glue/transport.h +++ b/src/glue/transport.h @@ -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:: diff --git a/src/gui/dialogs/about.cpp b/src/gui/dialogs/about.cpp index dfe503a..841d1f1 100644 --- a/src/gui/dialogs/about.cpp +++ b/src/gui/dialogs/about.cpp @@ -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(); } diff --git a/src/gui/dialogs/about.h b/src/gui/dialogs/about.h index 8d37cda..6be2063 100644 --- a/src/gui/dialogs/about.h +++ b/src/gui/dialogs/about.h @@ -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/actionEditor/baseActionEditor.cpp b/src/gui/dialogs/actionEditor/baseActionEditor.cpp index c7fc692..84a7263 100644 --- a/src/gui/dialogs/actionEditor/baseActionEditor.cpp +++ b/src/gui/dialogs/actionEditor/baseActionEditor.cpp @@ -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()); diff --git a/src/gui/dialogs/actionEditor/baseActionEditor.h b/src/gui/dialogs/actionEditor/baseActionEditor.h index da7ce46..0f6dbea 100644 --- a/src/gui/dialogs/actionEditor/baseActionEditor.h +++ b/src/gui/dialogs/actionEditor/baseActionEditor.h @@ -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 { diff --git a/src/gui/dialogs/actionEditor/midiActionEditor.cpp b/src/gui/dialogs/actionEditor/midiActionEditor.cpp index 28bd61a..d1547aa 100644 --- a/src/gui/dialogs/actionEditor/midiActionEditor.cpp +++ b/src/gui/dialogs/actionEditor/midiActionEditor.cpp @@ -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/actionEditor/midiActionEditor.h b/src/gui/dialogs/actionEditor/midiActionEditor.h index f850099..2cf5d63 100644 --- a/src/gui/dialogs/actionEditor/midiActionEditor.h +++ b/src/gui/dialogs/actionEditor/midiActionEditor.h @@ -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/actionEditor/sampleActionEditor.cpp b/src/gui/dialogs/actionEditor/sampleActionEditor.cpp index e69a89c..17715ee 100644 --- a/src/gui/dialogs/actionEditor/sampleActionEditor.cpp +++ b/src/gui/dialogs/actionEditor/sampleActionEditor.cpp @@ -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/actionEditor/sampleActionEditor.h b/src/gui/dialogs/actionEditor/sampleActionEditor.h index 9d459a8..2e170d8 100644 --- a/src/gui/dialogs/actionEditor/sampleActionEditor.h +++ b/src/gui/dialogs/actionEditor/sampleActionEditor.h @@ -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/beatsInput.cpp b/src/gui/dialogs/beatsInput.cpp index 710893b..b7857a2 100644 --- a/src/gui/dialogs/beatsInput.cpp +++ b/src/gui/dialogs/beatsInput.cpp @@ -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,20 +37,20 @@ #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(); } diff --git a/src/gui/dialogs/beatsInput.h b/src/gui/dialogs/beatsInput.h index 6b06da8..5a245eb 100644 --- a/src/gui/dialogs/beatsInput.h +++ b/src/gui/dialogs/beatsInput.h @@ -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/bpmInput.cpp b/src/gui/dialogs/bpmInput.cpp index b5ea70f..69e2296 100644 --- a/src/gui/dialogs/bpmInput.cpp +++ b/src/gui/dialogs/bpmInput.cpp @@ -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,38 +36,38 @@ #include "../elems/basics/button.h" #include "../elems/basics/input.h" #include "bpmInput.h" -#include "gd_mainWindow.h" +#include "mainWindow.h" -extern gdMainWindow *mainWin; +extern gdMainWindow* mainWin; 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 tokens; - gu_split(label, ".", &tokens); + vector 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(); } diff --git a/src/gui/dialogs/bpmInput.h b/src/gui/dialogs/bpmInput.h index 492ae35..954323d 100644 --- a/src/gui/dialogs/bpmInput.h +++ b/src/gui/dialogs/bpmInput.h @@ -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/browser/browserBase.cpp b/src/gui/dialogs/browser/browserBase.cpp index b0b05b5..d97bd04 100644 --- a/src/gui/dialogs/browser/browserBase.cpp +++ b/src/gui/dialogs/browser/browserBase.cpp @@ -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(); } diff --git a/src/gui/dialogs/browser/browserBase.h b/src/gui/dialogs/browser/browserBase.h index 883afdf..458706c 100644 --- a/src/gui/dialogs/browser/browserBase.h +++ b/src/gui/dialogs/browser/browserBase.h @@ -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/browser/browserDir.cpp b/src/gui/dialogs/browser/browserDir.cpp index daddec9..ebf8d07 100644 --- a/src/gui/dialogs/browser/browserDir.cpp +++ b/src/gui/dialogs/browser/browserDir.cpp @@ -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/browser/browserDir.h b/src/gui/dialogs/browser/browserDir.h index 18f34b2..c65ff24 100644 --- a/src/gui/dialogs/browser/browserDir.h +++ b/src/gui/dialogs/browser/browserDir.h @@ -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/browser/browserLoad.cpp b/src/gui/dialogs/browser/browserLoad.cpp index a46c42e..2664dbd 100644 --- a/src/gui/dialogs/browser/browserLoad.cpp +++ b/src/gui/dialogs/browser/browserLoad.cpp @@ -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/browser/browserLoad.h b/src/gui/dialogs/browser/browserLoad.h index 9ef7d18..10f085c 100644 --- a/src/gui/dialogs/browser/browserLoad.h +++ b/src/gui/dialogs/browser/browserLoad.h @@ -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/browser/browserSave.cpp b/src/gui/dialogs/browser/browserSave.cpp index 018b81b..1c39c4b 100644 --- a/src/gui/dialogs/browser/browserSave.cpp +++ b/src/gui/dialogs/browser/browserSave.cpp @@ -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/browser/browserSave.h b/src/gui/dialogs/browser/browserSave.h index 867089c..e88f5bf 100644 --- a/src/gui/dialogs/browser/browserSave.h +++ b/src/gui/dialogs/browser/browserSave.h @@ -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/channelNameInput.cpp b/src/gui/dialogs/channelNameInput.cpp index bca1a35..aef4d8c 100644 --- a/src/gui/dialogs/channelNameInput.cpp +++ b/src/gui/dialogs/channelNameInput.cpp @@ -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(); } diff --git a/src/gui/dialogs/channelNameInput.h b/src/gui/dialogs/channelNameInput.h index 8f32147..00bdf0e 100644 --- a/src/gui/dialogs/channelNameInput.h +++ b/src/gui/dialogs/channelNameInput.h @@ -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/gd_config.cpp b/src/gui/dialogs/config.cpp similarity index 96% rename from src/gui/dialogs/gd_config.cpp rename to src/gui/dialogs/config.cpp index ce4ee29..90afcb2 100644 --- a/src/gui/dialogs/gd_config.cpp +++ b/src/gui/dialogs/config.cpp @@ -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,9 +36,10 @@ #include "../elems/config/tabAudio.h" #include "../elems/config/tabBehaviors.h" #include "../elems/config/tabPlugins.h" -#include "gd_config.h" +#include "config.h" +using namespace giada; using namespace giada::m; @@ -70,7 +71,7 @@ gdConfig::gdConfig(int w, int h) : gdWindow(w, h, "Configuration") save->callback(cb_save_config, (void*)this); cancel->callback(cb_cancel, (void*)this); - gu_setFavicon(this); + u::gui::setFavicon(this); setId(WID_CONFIG); show(); } diff --git a/src/gui/dialogs/gd_config.h b/src/gui/dialogs/config.h similarity index 96% rename from src/gui/dialogs/gd_config.h rename to src/gui/dialogs/config.h index 989f560..cae3300 100644 --- a/src/gui/dialogs/gd_config.h +++ b/src/gui/dialogs/config.h @@ -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/gd_devInfo.cpp b/src/gui/dialogs/devInfo.cpp similarity index 71% rename from src/gui/dialogs/gd_devInfo.cpp rename to src/gui/dialogs/devInfo.cpp index 2521274..8a34abf 100644 --- a/src/gui/dialogs/gd_devInfo.cpp +++ b/src/gui/dialogs/devInfo.cpp @@ -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,11 +32,11 @@ #include "../elems/basics/button.h" #include "../elems/basics/box.h" #include "window.h" -#include "gd_devInfo.h" +#include "devInfo.h" using std::string; -using namespace giada::m; +using namespace giada; gdDevInfo::gdDevInfo(unsigned dev) @@ -51,22 +51,22 @@ gdDevInfo::gdDevInfo(unsigned dev) 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"; + 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 = kernelAudio::getTotalFreqs(dev); - body += "Supported frequencies: " + gu_iToString(totalFreq); + int totalFreq = m::kernelAudio::getTotalFreqs(dev); + body += "Supported frequencies: " + u::string::iToString(totalFreq); for (int i=0; icopy_label(body.c_str()); @@ -78,7 +78,7 @@ gdDevInfo::gdDevInfo(unsigned dev) close->position(close->x(), (lines * fl_height()) + 8 + 8); close->callback(__cb_window_closer, (void*)this); - gu_setFavicon(this); + u::gui::setFavicon(this); show(); } diff --git a/src/gui/dialogs/gd_devInfo.h b/src/gui/dialogs/devInfo.h similarity index 95% rename from src/gui/dialogs/gd_devInfo.h rename to src/gui/dialogs/devInfo.h index e65deea..3861967 100644 --- a/src/gui/dialogs/gd_devInfo.h +++ b/src/gui/dialogs/devInfo.h @@ -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/gd_keyGrabber.cpp b/src/gui/dialogs/keyGrabber.cpp similarity index 95% rename from src/gui/dialogs/gd_keyGrabber.cpp rename to src/gui/dialogs/keyGrabber.cpp index 418eb50..2f1acd3 100644 --- a/src/gui/dialogs/gd_keyGrabber.cpp +++ b/src/gui/dialogs/keyGrabber.cpp @@ -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,9 +36,9 @@ #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" +#include "keyGrabber.h" +#include "config.h" +#include "mainWindow.h" extern gdMainWindow *mainWin; @@ -62,7 +62,7 @@ gdKeyGrabber::gdKeyGrabber(m::Channel* ch) updateText(ch->key); - gu_setFavicon(this); + u::gui::setFavicon(this); show(); } diff --git a/src/gui/dialogs/gd_keyGrabber.h b/src/gui/dialogs/keyGrabber.h similarity index 96% rename from src/gui/dialogs/gd_keyGrabber.h rename to src/gui/dialogs/keyGrabber.h index 92f2af1..24c27b7 100644 --- a/src/gui/dialogs/gd_keyGrabber.h +++ b/src/gui/dialogs/keyGrabber.h @@ -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/gd_mainWindow.cpp b/src/gui/dialogs/mainWindow.cpp similarity index 80% rename from src/gui/dialogs/gd_mainWindow.cpp rename to src/gui/dialogs/mainWindow.cpp index cab1399..45a2ca1 100644 --- a/src/gui/dialogs/gd_mainWindow.cpp +++ b/src/gui/dialogs/mainWindow.cpp @@ -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,8 +37,8 @@ #include "../elems/mainWindow/mainTransport.h" #include "../elems/mainWindow/beatMeter.h" #include "../elems/mainWindow/keyboard/keyboard.h" -#include "gd_warnings.h" -#include "gd_mainWindow.h" +#include "warnings.h" +#include "mainWindow.h" extern gdMainWindow* G_MainWin; @@ -64,12 +64,12 @@ gdMainWindow::gdMainWindow(int W, int H, const char* title, int argc, char** arg 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); + 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 */ @@ -99,8 +99,10 @@ gdMainWindow::gdMainWindow(int W, int H, const char* title, int argc, char** arg add(zone2); add(zone3); add(keyboard); - callback(cb_endprogram); - gu_setFavicon(this); + callback([](Fl_Widget* w, void* v) { + m::init::closeMainWindow(); + }); + u::gui::setFavicon(this); show(argc, argv); } @@ -109,22 +111,10 @@ gdMainWindow::gdMainWindow(int W, int H, const char* title, int argc, char** arg /* -------------------------------------------------------------------------- */ -void gdMainWindow::cb_endprogram(Fl_Widget* v, void* p) { G_MainWin->cb_endprogram(); } - - -/* -------------------------------------------------------------------------- */ - - -void gdMainWindow::cb_endprogram() +gdMainWindow::~gdMainWindow() { - 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; -} +} \ No newline at end of file diff --git a/src/gui/dialogs/gd_mainWindow.h b/src/gui/dialogs/mainWindow.h similarity index 77% rename from src/gui/dialogs/gd_mainWindow.h rename to src/gui/dialogs/mainWindow.h index 8d7616e..30479ff 100644 --- a/src/gui/dialogs/gd_mainWindow.h +++ b/src/gui/dialogs/mainWindow.h @@ -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. * @@ -33,31 +33,33 @@ class Fl_Widget; + + +namespace giada { +namespace v +{ class geKeyboard; -class geBeatMeter; -class geMainMenu; class geMainIO; -class geMainTimer; +class geMainMenu; +class geBeatMeter; class geMainTransport; +class geMainTimer; +}} 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; + 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(int w, int h, const char* title, int argc, char** argv); + ~gdMainWindow(); }; diff --git a/src/gui/dialogs/midiIO/midiInputBase.cpp b/src/gui/dialogs/midiIO/midiInputBase.cpp index d461166..495d65c 100644 --- a/src/gui/dialogs/midiIO/midiInputBase.cpp +++ b/src/gui/dialogs/midiIO/midiInputBase.cpp @@ -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/midiIO/midiInputBase.h b/src/gui/dialogs/midiIO/midiInputBase.h index 646bc44..f750c8d 100644 --- a/src/gui/dialogs/midiIO/midiInputBase.h +++ b/src/gui/dialogs/midiIO/midiInputBase.h @@ -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/midiIO/midiInputChannel.cpp b/src/gui/dialogs/midiIO/midiInputChannel.cpp index 8656fdb..2d82e18 100644 --- a/src/gui/dialogs/midiIO/midiInputChannel.cpp +++ b/src/gui/dialogs/midiIO/midiInputChannel.cpp @@ -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* plugins = pluginHost::getStack(pluginHost::CHANNEL, ch); - for (unsigned i=0; isize(); i++) { + vector 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++; } } diff --git a/src/gui/dialogs/midiIO/midiInputChannel.h b/src/gui/dialogs/midiIO/midiInputChannel.h index 3a06680..b9e95ea 100644 --- a/src/gui/dialogs/midiIO/midiInputChannel.h +++ b/src/gui/dialogs/midiIO/midiInputChannel.h @@ -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/gui/dialogs/midiIO/midiInputMaster.cpp b/src/gui/dialogs/midiIO/midiInputMaster.cpp index f583bcf..089d966 100644 --- a/src/gui/dialogs/midiIO/midiInputMaster.cpp +++ b/src/gui/dialogs/midiIO/midiInputMaster.cpp @@ -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(); } diff --git a/src/gui/dialogs/midiIO/midiInputMaster.h b/src/gui/dialogs/midiIO/midiInputMaster.h index 1a0bec6..002925c 100644 --- a/src/gui/dialogs/midiIO/midiInputMaster.h +++ b/src/gui/dialogs/midiIO/midiInputMaster.h @@ -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/gui/dialogs/midiIO/midiOutputBase.cpp b/src/gui/dialogs/midiIO/midiOutputBase.cpp index f6c3da0..9ec2fcd 100644 --- a/src/gui/dialogs/midiIO/midiOutputBase.cpp +++ b/src/gui/dialogs/midiIO/midiOutputBase.cpp @@ -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; + geMidiLearner* learner = 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()); } diff --git a/src/gui/dialogs/midiIO/midiOutputBase.h b/src/gui/dialogs/midiIO/midiOutputBase.h index 343aa89..abdd89d 100644 --- a/src/gui/dialogs/midiIO/midiOutputBase.h +++ b/src/gui/dialogs/midiIO/midiOutputBase.h @@ -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; + geButton* close; + geCheck* enableLightning; - void stopMidiLearn(geMidiLearner *l); + void stopMidiLearn(geMidiLearner* l); /* 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. */ diff --git a/src/gui/dialogs/midiIO/midiOutputMidiCh.cpp b/src/gui/dialogs/midiIO/midiOutputMidiCh.cpp index 1e19ad2..c4b0753 100644 --- a/src/gui/dialogs/midiIO/midiOutputMidiCh.cpp +++ b/src/gui/dialogs/midiIO/midiOutputMidiCh.cpp @@ -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(); } diff --git a/src/gui/dialogs/midiIO/midiOutputMidiCh.h b/src/gui/dialogs/midiIO/midiOutputMidiCh.h index b1fb4d8..a5bfd5a 100644 --- a/src/gui/dialogs/midiIO/midiOutputMidiCh.h +++ b/src/gui/dialogs/midiIO/midiOutputMidiCh.h @@ -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/gui/dialogs/midiIO/midiOutputSampleCh.cpp b/src/gui/dialogs/midiIO/midiOutputSampleCh.cpp index fdb21df..50f675f 100644 --- a/src/gui/dialogs/midiIO/midiOutputSampleCh.cpp +++ b/src/gui/dialogs/midiIO/midiOutputSampleCh.cpp @@ -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(); } diff --git a/src/gui/dialogs/midiIO/midiOutputSampleCh.h b/src/gui/dialogs/midiIO/midiOutputSampleCh.h index fbd14ec..dea121f 100644 --- a/src/gui/dialogs/midiIO/midiOutputSampleCh.h +++ b/src/gui/dialogs/midiIO/midiOutputSampleCh.h @@ -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/pluginChooser.cpp b/src/gui/dialogs/pluginChooser.cpp index 361d735..f8dcb26 100644 --- a/src/gui/dialogs/pluginChooser.cpp +++ b/src/gui/dialogs/pluginChooser.cpp @@ -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" @@ -40,12 +41,13 @@ #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(sortMethod->value())); browser->refresh(); } diff --git a/src/gui/dialogs/pluginChooser.h b/src/gui/dialogs/pluginChooser.h index 53b3b14..d8bb3b2 100644 --- a/src/gui/dialogs/pluginChooser.h +++ b/src/gui/dialogs/pluginChooser.h @@ -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(); }; diff --git a/src/gui/dialogs/pluginList.cpp b/src/gui/dialogs/pluginList.cpp index b93e51d..7353e28 100644 --- a/src/gui/dialogs/pluginList.cpp +++ b/src/gui/dialogs/pluginList.cpp @@ -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 { diff --git a/src/gui/dialogs/pluginList.h b/src/gui/dialogs/pluginList.h index c3513bc..3b89961 100644 --- a/src/gui/dialogs/pluginList.h +++ b/src/gui/dialogs/pluginList.h @@ -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 diff --git a/src/gui/dialogs/pluginWindow.cpp b/src/gui/dialogs/pluginWindow.cpp index 8dfca8b..9c4ab8a 100644 --- a/src/gui/dialogs/pluginWindow.cpp +++ b/src/gui/dialogs/pluginWindow.cpp @@ -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(); } diff --git a/src/gui/dialogs/pluginWindow.h b/src/gui/dialogs/pluginWindow.h index a34befe..dcd81bb 100644 --- a/src/gui/dialogs/pluginWindow.h +++ b/src/gui/dialogs/pluginWindow.h @@ -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/pluginWindowGUI.cpp b/src/gui/dialogs/pluginWindowGUI.cpp index 0e64c3a..6eb8181 100644 --- a/src/gui/dialogs/pluginWindowGUI.cpp +++ b/src/gui/dialogs/pluginWindowGUI.cpp @@ -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/pluginWindowGUI.h b/src/gui/dialogs/pluginWindowGUI.h index 8dd6779..605e670 100644 --- a/src/gui/dialogs/pluginWindowGUI.h +++ b/src/gui/dialogs/pluginWindowGUI.h @@ -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. * diff --git a/src/gui/dialogs/sampleEditor.cpp b/src/gui/dialogs/sampleEditor.cpp index b13ef70..8715da7 100644 --- a/src/gui/dialogs/sampleEditor.cpp +++ b/src/gui/dialogs/sampleEditor.cpp @@ -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()); } diff --git a/src/gui/dialogs/sampleEditor.h b/src/gui/dialogs/sampleEditor.h index 0ab76e6..6373bd5 100644 --- a/src/gui/dialogs/sampleEditor.h +++ b/src/gui/dialogs/sampleEditor.h @@ -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/gd_warnings.cpp b/src/gui/dialogs/warnings.cpp similarity index 93% rename from src/gui/dialogs/gd_warnings.cpp rename to src/gui/dialogs/warnings.cpp index fc013f8..204971e 100644 --- a/src/gui/dialogs/gd_warnings.cpp +++ b/src/gui/dialogs/warnings.cpp @@ -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,10 @@ #include "../elems/basics/button.h" #include "../elems/basics/box.h" #include "window.h" -#include "gd_warnings.h" +#include "warnings.h" + + +using namespace giada; void gdAlert(const char *c) @@ -49,7 +52,7 @@ void gdAlert(const char *c) box->labelsize(G_GUI_FONT_SIZE_BASE); b->callback(__cb_window_closer, (void *)modal); b->shortcut(FL_Enter); - gu_setFavicon(modal); + u::gui::setFavicon(modal); modal->show(); } @@ -67,7 +70,7 @@ int gdConfirmWin(const char *title, const char *msg) geButton *ko = new geButton(124, 62, 80, 20, "Cancel"); win->end(); ok->shortcut(FL_Enter); - gu_setFavicon(win); + u::gui::setFavicon(win); win->show(); /* no callbacks here. readqueue() check the event stack. */ diff --git a/src/gui/dialogs/gd_warnings.h b/src/gui/dialogs/warnings.h similarity index 95% rename from src/gui/dialogs/gd_warnings.h rename to src/gui/dialogs/warnings.h index fb96a8a..564db6f 100644 --- a/src/gui/dialogs/gd_warnings.h +++ b/src/gui/dialogs/warnings.h @@ -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/window.cpp b/src/gui/dialogs/window.cpp index a8c8ce0..ca5c914 100644 --- a/src/gui/dialogs/window.cpp +++ b/src/gui/dialogs/window.cpp @@ -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/window.h b/src/gui/dialogs/window.h index 888e898..1b60449 100644 --- a/src/gui/dialogs/window.h +++ b/src/gui/dialogs/window.h @@ -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 index 0000000..fae6992 --- /dev/null +++ b/src/gui/dispatcher.cpp @@ -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 + * . + * + * -------------------------------------------------------------------------- */ + + +#include +#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 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 f) +{ + signalCb_ = f; +} + +}}} // giada::v::dispatcher diff --git a/src/gui/elems/basics/idButton.cpp b/src/gui/dispatcher.h similarity index 73% rename from src/gui/elems/basics/idButton.cpp rename to src/gui/dispatcher.h index 3f2ffaf..580dc4e 100644 --- a/src/gui/elems/basics/idButton.cpp +++ b/src/gui/dispatcher.h @@ -2,13 +2,9 @@ * * 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 + * Copyright (C) 2010-2019 Giovanni A. Zuliani | Monocasual * * This file is part of Giada - Your Hardcore Loopmachine. * @@ -29,11 +25,25 @@ * -------------------------------------------------------------------------- */ -#include "idButton.h" +#ifndef G_V_DISPATCHER_H +#define G_V_DISPATCHER_H + + +#include -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) +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 f); +}}} // giada::v::dispatcher + + +#endif \ No newline at end of file diff --git a/src/gui/elems/actionEditor/baseAction.cpp b/src/gui/elems/actionEditor/baseAction.cpp index 1283c7a..d62523b 100644 --- a/src/gui/elems/actionEditor/baseAction.cpp +++ b/src/gui/elems/actionEditor/baseAction.cpp @@ -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/actionEditor/baseAction.h b/src/gui/elems/actionEditor/baseAction.h index c3b4b12..1d77df4 100644 --- a/src/gui/elems/actionEditor/baseAction.h +++ b/src/gui/elems/actionEditor/baseAction.h @@ -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 { diff --git a/src/gui/elems/actionEditor/baseActionEditor.cpp b/src/gui/elems/actionEditor/baseActionEditor.cpp index 75c6d22..c615ffc 100644 --- a/src/gui/elems/actionEditor/baseActionEditor.cpp +++ b/src/gui/elems/actionEditor/baseActionEditor.cpp @@ -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/actionEditor/baseActionEditor.h b/src/gui/elems/actionEditor/baseActionEditor.h index bcd3cfb..2db996c 100644 --- a/src/gui/elems/actionEditor/baseActionEditor.h +++ b/src/gui/elems/actionEditor/baseActionEditor.h @@ -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. * diff --git a/src/gui/elems/actionEditor/envelopeEditor.cpp b/src/gui/elems/actionEditor/envelopeEditor.cpp index ff27f5b..3f2e131 100644 --- a/src/gui/elems/actionEditor/envelopeEditor.cpp +++ b/src/gui/elems/actionEditor/envelopeEditor.cpp @@ -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/actionEditor/envelopeEditor.h b/src/gui/elems/actionEditor/envelopeEditor.h index c8046df..192a4a1 100644 --- a/src/gui/elems/actionEditor/envelopeEditor.h +++ b/src/gui/elems/actionEditor/envelopeEditor.h @@ -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/actionEditor/envelopePoint.cpp b/src/gui/elems/actionEditor/envelopePoint.cpp index a32965d..68e3cec 100644 --- a/src/gui/elems/actionEditor/envelopePoint.cpp +++ b/src/gui/elems/actionEditor/envelopePoint.cpp @@ -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/actionEditor/envelopePoint.h b/src/gui/elems/actionEditor/envelopePoint.h index 05f7bc3..3724fa7 100644 --- a/src/gui/elems/actionEditor/envelopePoint.h +++ b/src/gui/elems/actionEditor/envelopePoint.h @@ -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/actionEditor/gridTool.cpp b/src/gui/elems/actionEditor/gridTool.cpp index 52cf3f1..4c4b021 100644 --- a/src/gui/elems/actionEditor/gridTool.cpp +++ b/src/gui/elems/actionEditor/gridTool.cpp @@ -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/actionEditor/gridTool.h b/src/gui/elems/actionEditor/gridTool.h index f86e3d9..90690c7 100644 --- a/src/gui/elems/actionEditor/gridTool.h +++ b/src/gui/elems/actionEditor/gridTool.h @@ -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/actionEditor/noteEditor.cpp b/src/gui/elems/actionEditor/noteEditor.cpp index 4992af7..6f4b44f 100644 --- a/src/gui/elems/actionEditor/noteEditor.cpp +++ b/src/gui/elems/actionEditor/noteEditor.cpp @@ -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/actionEditor/noteEditor.h b/src/gui/elems/actionEditor/noteEditor.h index 130e925..ffe57c8 100644 --- a/src/gui/elems/actionEditor/noteEditor.h +++ b/src/gui/elems/actionEditor/noteEditor.h @@ -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/actionEditor/pianoItem.cpp b/src/gui/elems/actionEditor/pianoItem.cpp index d608276..361e422 100644 --- a/src/gui/elems/actionEditor/pianoItem.cpp +++ b/src/gui/elems/actionEditor/pianoItem.cpp @@ -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/actionEditor/pianoItem.h b/src/gui/elems/actionEditor/pianoItem.h index 6f84cc9..dd9d3f6 100644 --- a/src/gui/elems/actionEditor/pianoItem.h +++ b/src/gui/elems/actionEditor/pianoItem.h @@ -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 { diff --git a/src/gui/elems/actionEditor/pianoRoll.cpp b/src/gui/elems/actionEditor/pianoRoll.cpp index f629101..5bb6b31 100644 --- a/src/gui/elems/actionEditor/pianoRoll.cpp +++ b/src/gui/elems/actionEditor/pianoRoll.cpp @@ -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); diff --git a/src/gui/elems/actionEditor/pianoRoll.h b/src/gui/elems/actionEditor/pianoRoll.h index aedb641..aecd56e 100644 --- a/src/gui/elems/actionEditor/pianoRoll.h +++ b/src/gui/elems/actionEditor/pianoRoll.h @@ -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/actionEditor/sampleAction.cpp b/src/gui/elems/actionEditor/sampleAction.cpp index bd69755..a488736 100644 --- a/src/gui/elems/actionEditor/sampleAction.cpp +++ b/src/gui/elems/actionEditor/sampleAction.cpp @@ -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/actionEditor/sampleAction.h b/src/gui/elems/actionEditor/sampleAction.h index e85ab13..6b4fc0a 100644 --- a/src/gui/elems/actionEditor/sampleAction.h +++ b/src/gui/elems/actionEditor/sampleAction.h @@ -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 { diff --git a/src/gui/elems/actionEditor/sampleActionEditor.cpp b/src/gui/elems/actionEditor/sampleActionEditor.cpp index ae1cb9e..31f7319 100644 --- a/src/gui/elems/actionEditor/sampleActionEditor.cpp +++ b/src/gui/elems/actionEditor/sampleActionEditor.cpp @@ -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/actionEditor/sampleActionEditor.h b/src/gui/elems/actionEditor/sampleActionEditor.h index c71d0ad..59e5ea3 100644 --- a/src/gui/elems/actionEditor/sampleActionEditor.h +++ b/src/gui/elems/actionEditor/sampleActionEditor.h @@ -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 { diff --git a/src/gui/elems/actionEditor/velocityEditor.cpp b/src/gui/elems/actionEditor/velocityEditor.cpp index 58bcc6e..030af9a 100644 --- a/src/gui/elems/actionEditor/velocityEditor.cpp +++ b/src/gui/elems/actionEditor/velocityEditor.cpp @@ -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/actionEditor/velocityEditor.h b/src/gui/elems/actionEditor/velocityEditor.h index f3415dd..456ae58 100644 --- a/src/gui/elems/actionEditor/velocityEditor.h +++ b/src/gui/elems/actionEditor/velocityEditor.h @@ -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/baseButton.cpp b/src/gui/elems/basics/baseButton.cpp index ca8c84c..b4ed84f 100644 --- a/src/gui/elems/basics/baseButton.cpp +++ b/src/gui/elems/basics/baseButton.cpp @@ -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. * diff --git a/src/gui/elems/basics/baseButton.h b/src/gui/elems/basics/baseButton.h index f2dffed..cb8e1dd 100644 --- a/src/gui/elems/basics/baseButton.h +++ b/src/gui/elems/basics/baseButton.h @@ -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. * diff --git a/src/gui/elems/basics/box.cpp b/src/gui/elems/basics/box.cpp index 6b15e1a..02814b1 100644 --- a/src/gui/elems/basics/box.cpp +++ b/src/gui/elems/basics/box.cpp @@ -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/box.h b/src/gui/elems/basics/box.h index c73a8eb..f8e1389 100644 --- a/src/gui/elems/basics/box.h +++ b/src/gui/elems/basics/box.h @@ -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/boxtypes.cpp b/src/gui/elems/basics/boxtypes.cpp index d22510d..42df73b 100644 --- a/src/gui/elems/basics/boxtypes.cpp +++ b/src/gui/elems/basics/boxtypes.cpp @@ -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/gui/elems/basics/boxtypes.h b/src/gui/elems/basics/boxtypes.h index b4ae0ce..b5e58f6 100644 --- a/src/gui/elems/basics/boxtypes.h +++ b/src/gui/elems/basics/boxtypes.h @@ -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/gui/elems/basics/button.cpp b/src/gui/elems/basics/button.cpp index eb87400..b113b6c 100644 --- a/src/gui/elems/basics/button.cpp +++ b/src/gui/elems/basics/button.cpp @@ -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. * diff --git a/src/gui/elems/basics/button.h b/src/gui/elems/basics/button.h index ce33ed1..4f51e3a 100644 --- a/src/gui/elems/basics/button.h +++ b/src/gui/elems/basics/button.h @@ -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. * diff --git a/src/gui/elems/basics/check.cpp b/src/gui/elems/basics/check.cpp index daed549..aa2a0be 100644 --- a/src/gui/elems/basics/check.cpp +++ b/src/gui/elems/basics/check.cpp @@ -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/check.h b/src/gui/elems/basics/check.h index 4d84556..486466c 100644 --- a/src/gui/elems/basics/check.h +++ b/src/gui/elems/basics/check.h @@ -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/choice.cpp b/src/gui/elems/basics/choice.cpp index b0f52b3..2764b31 100644 --- a/src/gui/elems/basics/choice.cpp +++ b/src/gui/elems/basics/choice.cpp @@ -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/choice.h b/src/gui/elems/basics/choice.h index ef37938..ebf01a4 100644 --- a/src/gui/elems/basics/choice.h +++ b/src/gui/elems/basics/choice.h @@ -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/dial.cpp b/src/gui/elems/basics/dial.cpp index 5f65e9f..55d541a 100644 --- a/src/gui/elems/basics/dial.cpp +++ b/src/gui/elems/basics/dial.cpp @@ -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/dial.h b/src/gui/elems/basics/dial.h index f0b93ac..0699a0d 100644 --- a/src/gui/elems/basics/dial.h +++ b/src/gui/elems/basics/dial.h @@ -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/input.cpp b/src/gui/elems/basics/input.cpp index 6466a15..7df58e2 100644 --- a/src/gui/elems/basics/input.cpp +++ b/src/gui/elems/basics/input.cpp @@ -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/input.h b/src/gui/elems/basics/input.h index bef8ef8..74124b6 100644 --- a/src/gui/elems/basics/input.h +++ b/src/gui/elems/basics/input.h @@ -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/liquidScroll.cpp b/src/gui/elems/basics/liquidScroll.cpp index b66a8f2..cfc5615 100644 --- a/src/gui/elems/basics/liquidScroll.cpp +++ b/src/gui/elems/basics/liquidScroll.cpp @@ -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. * diff --git a/src/gui/elems/basics/liquidScroll.h b/src/gui/elems/basics/liquidScroll.h index 5638684..e803120 100644 --- a/src/gui/elems/basics/liquidScroll.h +++ b/src/gui/elems/basics/liquidScroll.h @@ -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. * diff --git a/src/gui/elems/basics/progress.cpp b/src/gui/elems/basics/progress.cpp index b1a1e23..b5e3159 100644 --- a/src/gui/elems/basics/progress.cpp +++ b/src/gui/elems/basics/progress.cpp @@ -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/progress.h b/src/gui/elems/basics/progress.h index d884ac9..2c7a5d0 100644 --- a/src/gui/elems/basics/progress.h +++ b/src/gui/elems/basics/progress.h @@ -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/radio.cpp b/src/gui/elems/basics/radio.cpp index dbc40fe..dbbc651 100644 --- a/src/gui/elems/basics/radio.cpp +++ b/src/gui/elems/basics/radio.cpp @@ -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/radio.h b/src/gui/elems/basics/radio.h index aece5ef..d8bcb42 100644 --- a/src/gui/elems/basics/radio.h +++ b/src/gui/elems/basics/radio.h @@ -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/resizerBar.cpp b/src/gui/elems/basics/resizerBar.cpp index 6831a09..9d4b66b 100644 --- a/src/gui/elems/basics/resizerBar.cpp +++ b/src/gui/elems/basics/resizerBar.cpp @@ -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. * diff --git a/src/gui/elems/basics/resizerBar.h b/src/gui/elems/basics/resizerBar.h index fb20879..64fa249 100644 --- a/src/gui/elems/basics/resizerBar.h +++ b/src/gui/elems/basics/resizerBar.h @@ -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. * diff --git a/src/gui/elems/basics/scroll.cpp b/src/gui/elems/basics/scroll.cpp index 273a053..578b5b7 100644 --- a/src/gui/elems/basics/scroll.cpp +++ b/src/gui/elems/basics/scroll.cpp @@ -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. * diff --git a/src/gui/elems/basics/scroll.h b/src/gui/elems/basics/scroll.h index 92262f2..3154974 100644 --- a/src/gui/elems/basics/scroll.h +++ b/src/gui/elems/basics/scroll.h @@ -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. * diff --git a/src/gui/elems/basics/slider.cpp b/src/gui/elems/basics/slider.cpp index a984a43..75769a3 100644 --- a/src/gui/elems/basics/slider.cpp +++ b/src/gui/elems/basics/slider.cpp @@ -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/slider.h b/src/gui/elems/basics/slider.h index 2dd0aca..98f729d 100644 --- a/src/gui/elems/basics/slider.h +++ b/src/gui/elems/basics/slider.h @@ -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/statusButton.cpp b/src/gui/elems/basics/statusButton.cpp index 38b9b63..64623d3 100644 --- a/src/gui/elems/basics/statusButton.cpp +++ b/src/gui/elems/basics/statusButton.cpp @@ -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. * diff --git a/src/gui/elems/basics/statusButton.h b/src/gui/elems/basics/statusButton.h index 317a5a5..1f8f924 100644 --- a/src/gui/elems/basics/statusButton.h +++ b/src/gui/elems/basics/statusButton.h @@ -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. * diff --git a/src/gui/elems/browser.cpp b/src/gui/elems/browser.cpp index 00f95f1..9a2512f 100644 --- a/src/gui/elems/browser.cpp +++ b/src/gui/elems/browser.cpp @@ -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())))); } } diff --git a/src/gui/elems/browser.h b/src/gui/elems/browser.h index 12dc383..533d1a3 100644 --- a/src/gui/elems/browser.h +++ b/src/gui/elems/browser.h @@ -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/gui/elems/config/tabAudio.cpp b/src/gui/elems/config/tabAudio.cpp index baf56d4..bb192f8 100644 --- a/src/gui/elems/config/tabAudio.cpp +++ b/src/gui/elems/config/tabAudio.cpp @@ -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; ivalue(), 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; iadd(tmp.c_str()); } channelsIn->value(conf::channelsIn); @@ -346,7 +344,7 @@ void geTabAudio::fetchOutChans(int menuItem) return; } for (unsigned i=0; iadd(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_Item* i = 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()); } diff --git a/src/gui/elems/config/tabAudio.h b/src/gui/elems/config/tabAudio.h index bb3e918..65f0cc5 100644 --- a/src/gui/elems/config/tabAudio.h +++ b/src/gui/elems/config/tabAudio.h @@ -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(geChoice* m, 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; + geChoice* soundsys; + 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); diff --git a/src/gui/elems/config/tabBehaviors.cpp b/src/gui/elems/config/tabBehaviors.cpp index b6a57c4..3926e5c 100644 --- a/src/gui/elems/config/tabBehaviors.cpp +++ b/src/gui/elems/config/tabBehaviors.cpp @@ -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/config/tabBehaviors.h b/src/gui/elems/config/tabBehaviors.h index d0a3ece..07f29f1 100644 --- a/src/gui/elems/config/tabBehaviors.h +++ b/src/gui/elems/config/tabBehaviors.h @@ -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/config/tabMidi.cpp b/src/gui/elems/config/tabMidi.cpp index 527bfeb..9af5b1a 100644 --- a/src/gui/elems/config/tabMidi.cpp +++ b/src/gui/elems/config/tabMidi.cpp @@ -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; iadd(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; iadd(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)' } diff --git a/src/gui/elems/config/tabMidi.h b/src/gui/elems/config/tabMidi.h index 9b48a92..c134aac 100644 --- a/src/gui/elems/config/tabMidi.h +++ b/src/gui/elems/config/tabMidi.h @@ -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/config/tabMisc.cpp b/src/gui/elems/config/tabMisc.cpp index b1f4e2d..0e2cc10 100644 --- a/src/gui/elems/config/tabMisc.cpp +++ b/src/gui/elems/config/tabMisc.cpp @@ -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/config/tabMisc.h b/src/gui/elems/config/tabMisc.h index bf900bf..138f6d1 100644 --- a/src/gui/elems/config/tabMisc.h +++ b/src/gui/elems/config/tabMisc.h @@ -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/config/tabPlugins.cpp b/src/gui/elems/config/tabPlugins.cpp index d9074a6..343b256 100644 --- a/src/gui/elems/config/tabPlugins.cpp +++ b/src/gui/elems/config/tabPlugins.cpp @@ -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. * @@ -33,13 +33,13 @@ #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 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(); } diff --git a/src/gui/elems/config/tabPlugins.h b/src/gui/elems/config/tabPlugins.h index cc8ffd9..31c346d 100644 --- a/src/gui/elems/config/tabPlugins.h +++ b/src/gui/elems/config/tabPlugins.h @@ -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/mainWindow/beatMeter.cpp b/src/gui/elems/mainWindow/beatMeter.cpp index d10efed..c1fe379 100644 --- a/src/gui/elems/mainWindow/beatMeter.cpp +++ b/src/gui/elems/mainWindow/beatMeter.cpp @@ -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. * @@ -29,16 +29,31 @@ #include #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 +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 diff --git a/src/gui/elems/mainWindow/keyboard/channel.cpp b/src/gui/elems/mainWindow/keyboard/channel.cpp index 2d563ce..b99558c 100644 --- a/src/gui/elems/mainWindow/keyboard/channel.cpp +++ b/src/gui/elems/mainWindow/keyboard/channel.cpp @@ -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; } diff --git a/src/gui/elems/mainWindow/keyboard/channel.h b/src/gui/elems/mainWindow/keyboard/channel.h index 785b94d..6308f27 100644 --- a/src/gui/elems/mainWindow/keyboard/channel.h +++ b/src/gui/elems/mainWindow/keyboard/channel.h @@ -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 }; diff --git a/src/gui/elems/mainWindow/keyboard/channelButton.cpp b/src/gui/elems/mainWindow/keyboard/channelButton.cpp index a93dee5..ff5232e 100644 --- a/src/gui/elems/mainWindow/keyboard/channelButton.cpp +++ b/src/gui/elems/mainWindow/keyboard/channelButton.cpp @@ -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/mainWindow/keyboard/channelButton.h b/src/gui/elems/mainWindow/keyboard/channelButton.h index 4a59589..95f3433 100644 --- a/src/gui/elems/mainWindow/keyboard/channelButton.h +++ b/src/gui/elems/mainWindow/keyboard/channelButton.h @@ -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/mainWindow/keyboard/channelMode.cpp b/src/gui/elems/mainWindow/keyboard/channelMode.cpp index d67abae..7153e69 100644 --- a/src/gui/elems/mainWindow/keyboard/channelMode.cpp +++ b/src/gui/elems/mainWindow/keyboard/channelMode.cpp @@ -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. * @@ -39,57 +39,58 @@ 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(mode); + ch->mode = static_cast(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(); } diff --git a/src/gui/elems/mainWindow/keyboard/channelMode.h b/src/gui/elems/mainWindow/keyboard/channelMode.h index 248c2f5..03a2bbf 100644 --- a/src/gui/elems/mainWindow/keyboard/channelMode.h +++ b/src/gui/elems/mainWindow/keyboard/channelMode.h @@ -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/gui/elems/mainWindow/keyboard/channelStatus.cpp b/src/gui/elems/mainWindow/keyboard/channelStatus.cpp index e5171e3..6365394 100644 --- a/src/gui/elems/mainWindow/keyboard/channelStatus.cpp +++ b/src/gui/elems/mainWindow/keyboard/channelStatus.cpp @@ -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/mainWindow/keyboard/channelStatus.h b/src/gui/elems/mainWindow/keyboard/channelStatus.h index 8e8bd5e..44d6ccc 100644 --- a/src/gui/elems/mainWindow/keyboard/channelStatus.h +++ b/src/gui/elems/mainWindow/keyboard/channelStatus.h @@ -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/gui/elems/mainWindow/keyboard/column.cpp b/src/gui/elems/mainWindow/keyboard/column.cpp index b63f2f2..f925885 100644 --- a/src/gui/elems/mainWindow/keyboard/column.cpp +++ b/src/gui/elems/mainWindow/keyboard/column.cpp @@ -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 paths; - gu_split(Fl::event_text(), "\n", &paths); + vector 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(c::channel::addChannel( m_index, ChannelType::SAMPLE, G_GUI_CHANNEL_H_1)); result = c::channel::loadChannel(c, gu_stripFileUrl(path)); diff --git a/src/gui/elems/mainWindow/keyboard/column.h b/src/gui/elems/mainWindow/keyboard/column.h index b980100..209bc9c 100644 --- a/src/gui/elems/mainWindow/keyboard/column.h +++ b/src/gui/elems/mainWindow/keyboard/column.h @@ -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,11 @@ 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 diff --git a/src/gui/elems/mainWindow/keyboard/keyboard.cpp b/src/gui/elems/mainWindow/keyboard/keyboard.cpp index 10bfbb9..8ca0a02 100644 --- a/src/gui/elems/mainWindow/keyboard/keyboard.cpp +++ b/src/gui/elems/mainWindow/keyboard/keyboard.cpp @@ -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; ichildren(); k++) - ret &= static_cast(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 diff --git a/src/gui/elems/mainWindow/keyboard/keyboard.h b/src/gui/elems/mainWindow/keyboard/keyboard.h index 339394e..daac4c8 100644 --- a/src/gui/elems/mainWindow/keyboard/keyboard.h +++ b/src/gui/elems/mainWindow/keyboard/keyboard.h @@ -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 diff --git a/src/gui/elems/mainWindow/keyboard/midiChannel.cpp b/src/gui/elems/mainWindow/keyboard/midiChannel.cpp index ab2c670..862b172 100644 --- a/src/gui/elems/mainWindow/keyboard/midiChannel.cpp +++ b/src/gui/elems/mainWindow/keyboard/midiChannel.cpp @@ -35,16 +35,17 @@ #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(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()); diff --git a/src/gui/elems/mainWindow/keyboard/midiChannel.h b/src/gui/elems/mainWindow/keyboard/midiChannel.h index 43b9ce8..e917506 100644 --- a/src/gui/elems/mainWindow/keyboard/midiChannel.h +++ b/src/gui/elems/mainWindow/keyboard/midiChannel.h @@ -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/mainWindow/keyboard/midiChannelButton.cpp b/src/gui/elems/mainWindow/keyboard/midiChannelButton.cpp index 0bfdcd0..4308d59 100644 --- a/src/gui/elems/mainWindow/keyboard/midiChannelButton.cpp +++ b/src/gui/elems/mainWindow/keyboard/midiChannelButton.cpp @@ -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/mainWindow/keyboard/midiChannelButton.h b/src/gui/elems/mainWindow/keyboard/midiChannelButton.h index c461ff1..225aa32 100644 --- a/src/gui/elems/mainWindow/keyboard/midiChannelButton.h +++ b/src/gui/elems/mainWindow/keyboard/midiChannelButton.h @@ -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/mainWindow/keyboard/sampleChannel.cpp b/src/gui/elems/mainWindow/keyboard/sampleChannel.cpp index 785f0f9..2bb03a0 100644 --- a/src/gui/elems/mainWindow/keyboard/sampleChannel.cpp +++ b/src/gui/elems/mainWindow/keyboard/sampleChannel.cpp @@ -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,18 +37,19 @@ #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(ch)->wave != nullptr) { if (m::mixer::recording && ch->armed) diff --git a/src/gui/elems/mainWindow/keyboard/sampleChannel.h b/src/gui/elems/mainWindow/keyboard/sampleChannel.h index 0d43db9..24e02a6 100644 --- a/src/gui/elems/mainWindow/keyboard/sampleChannel.h +++ b/src/gui/elems/mainWindow/keyboard/sampleChannel.h @@ -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/mainWindow/keyboard/sampleChannelButton.cpp b/src/gui/elems/mainWindow/keyboard/sampleChannelButton.cpp index c5d6317..25b35bc 100644 --- a/src/gui/elems/mainWindow/keyboard/sampleChannelButton.cpp +++ b/src/gui/elems/mainWindow/keyboard/sampleChannelButton.cpp @@ -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(parent()); m::SampleChannel* ch = static_cast(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; diff --git a/src/gui/elems/mainWindow/keyboard/sampleChannelButton.h b/src/gui/elems/mainWindow/keyboard/sampleChannelButton.h index b814fa8..213581a 100644 --- a/src/gui/elems/mainWindow/keyboard/sampleChannelButton.h +++ b/src/gui/elems/mainWindow/keyboard/sampleChannelButton.h @@ -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/mainWindow/mainIO.cpp b/src/gui/elems/mainWindow/mainIO.cpp index e246dd8..9affcef 100644 --- a/src/gui/elems/mainWindow/mainIO.cpp +++ b/src/gui/elems/mainWindow/mainIO.cpp @@ -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,17 +34,17 @@ #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 diff --git a/src/gui/elems/mainWindow/mainIO.h b/src/gui/elems/mainWindow/mainIO.h index 5debc8e..cec4ad7 100644 --- a/src/gui/elems/mainWindow/mainIO.h +++ b/src/gui/elems/mainWindow/mainIO.h @@ -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; + geSoundMeter* outMeter; + geSoundMeter* inMeter; + geDial* outVol; + geDial* inVol; #ifdef WITH_VST - geStatusButton *masterFxOut; - geStatusButton *masterFxIn; - geButton *inToOut; + geStatusButton* masterFxOut; + geStatusButton* masterFxIn; + 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 diff --git a/src/gui/elems/mainWindow/mainMenu.cpp b/src/gui/elems/mainWindow/mainMenu.cpp index 5a165dc..0416ca4 100644 --- a/src/gui/elems/mainWindow/mainMenu.cpp +++ b/src/gui/elems/mainWindow/mainMenu.cpp @@ -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,10 +38,10 @@ #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, + gdWindow* childWin = 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 diff --git a/src/gui/elems/mainWindow/mainMenu.h b/src/gui/elems/mainWindow/mainMenu.h index c6dde20..57e2b43 100644 --- a/src/gui/elems/mainWindow/mainMenu.h +++ b/src/gui/elems/mainWindow/mainMenu.h @@ -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,29 +35,32 @@ 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 diff --git a/src/gui/elems/mainWindow/mainTimer.cpp b/src/gui/elems/mainWindow/mainTimer.cpp index 053fa89..aa07f93 100644 --- a/src/gui/elems/mainWindow/mainTimer.cpp +++ b/src/gui/elems/mainWindow/mainTimer.cpp @@ -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,35 +34,37 @@ #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 gdMainWindow* G_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 diff --git a/src/gui/elems/mainWindow/mainTimer.h b/src/gui/elems/mainWindow/mainTimer.h index 917c054..03ac840 100644 --- a/src/gui/elems/mainWindow/mainTimer.h +++ b/src/gui/elems/mainWindow/mainTimer.h @@ -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 diff --git a/src/gui/elems/mainWindow/mainTransport.cpp b/src/gui/elems/mainWindow/mainTransport.cpp index 3e83d2d..d4f0b3e 100644 --- a/src/gui/elems/mainWindow/mainTransport.cpp +++ b/src/gui/elems/mainWindow/mainTransport.cpp @@ -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,100 +26,61 @@ #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(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 diff --git a/src/gui/elems/mainWindow/mainTransport.h b/src/gui/elems/mainWindow/mainTransport.h index cd92909..1172c67 100644 --- a/src/gui/elems/mainWindow/mainTransport.h +++ b/src/gui/elems/mainWindow/mainTransport.h @@ -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,40 +30,40 @@ #include +#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 diff --git a/src/gui/elems/midiLearner.cpp b/src/gui/elems/midiLearner.cpp index 0085d6c..c17b50c 100644 --- a/src/gui/elems/midiLearner.cpp +++ b/src/gui/elems/midiLearner.cpp @@ -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,15 +34,15 @@ 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(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(); } diff --git a/src/gui/elems/midiLearner.h b/src/gui/elems/midiLearner.h index 28ac2e6..c3ece9c 100644 --- a/src/gui/elems/midiLearner.h +++ b/src/gui/elems/midiLearner.h @@ -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/plugin/pluginBrowser.cpp b/src/gui/elems/plugin/pluginBrowser.cpp index adfb907..a8c7b86 100644 --- a/src/gui/elems/plugin/pluginBrowser.cpp +++ b/src/gui/elems/plugin/pluginBrowser.cpp @@ -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 #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; ix()+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; igetNumPrograms(); 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; diff --git a/src/gui/elems/plugin/pluginElement.h b/src/gui/elems/plugin/pluginElement.h index 8409322..c3b1f45 100644 --- a/src/gui/elems/plugin/pluginElement.h +++ b/src/gui/elems/plugin/pluginElement.h @@ -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); }; diff --git a/src/gui/elems/plugin/pluginParameter.cpp b/src/gui/elems/plugin/pluginParameter.cpp index 81bbb3d..f7a9624 100644 --- a/src/gui/elems/plugin/pluginParameter.cpp +++ b/src/gui/elems/plugin/pluginParameter.cpp @@ -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/plugin/pluginParameter.h b/src/gui/elems/plugin/pluginParameter.h index e07c940..266de5e 100644 --- a/src/gui/elems/plugin/pluginParameter.h +++ b/src/gui/elems/plugin/pluginParameter.h @@ -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/sampleEditor/boostTool.cpp b/src/gui/elems/sampleEditor/boostTool.cpp index 284b3f4..35ba256 100644 --- a/src/gui/elems/sampleEditor/boostTool.cpp +++ b/src/gui/elems/sampleEditor/boostTool.cpp @@ -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); } diff --git a/src/gui/elems/sampleEditor/boostTool.h b/src/gui/elems/sampleEditor/boostTool.h index a922a6e..496717c 100644 --- a/src/gui/elems/sampleEditor/boostTool.h +++ b/src/gui/elems/sampleEditor/boostTool.h @@ -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/sampleEditor/panTool.cpp b/src/gui/elems/sampleEditor/panTool.cpp index e9478a8..8d12056 100644 --- a/src/gui/elems/sampleEditor/panTool.cpp +++ b/src/gui/elems/sampleEditor/panTool.cpp @@ -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(); } diff --git a/src/gui/elems/sampleEditor/panTool.h b/src/gui/elems/sampleEditor/panTool.h index fd485f5..1717016 100644 --- a/src/gui/elems/sampleEditor/panTool.h +++ b/src/gui/elems/sampleEditor/panTool.h @@ -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/sampleEditor/pitchTool.cpp b/src/gui/elems/sampleEditor/pitchTool.cpp index e5eac55..5770435 100644 --- a/src/gui/elems/sampleEditor/pitchTool.cpp +++ b/src/gui/elems/sampleEditor/pitchTool.cpp @@ -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 } diff --git a/src/gui/elems/sampleEditor/pitchTool.h b/src/gui/elems/sampleEditor/pitchTool.h index 0ccfcdf..ee6594e 100644 --- a/src/gui/elems/sampleEditor/pitchTool.h +++ b/src/gui/elems/sampleEditor/pitchTool.h @@ -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/sampleEditor/rangeTool.cpp b/src/gui/elems/sampleEditor/rangeTool.cpp index 7dae165..9cf66d5 100644 --- a/src/gui/elems/sampleEditor/rangeTool.cpp +++ b/src/gui/elems/sampleEditor/rangeTool.cpp @@ -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(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(window())->waveTools->updateWaveform(); // TODO - glue's business! } diff --git a/src/gui/elems/sampleEditor/rangeTool.h b/src/gui/elems/sampleEditor/rangeTool.h index 69efdfa..2e41bf0 100644 --- a/src/gui/elems/sampleEditor/rangeTool.h +++ b/src/gui/elems/sampleEditor/rangeTool.h @@ -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/sampleEditor/shiftTool.cpp b/src/gui/elems/sampleEditor/shiftTool.cpp index 0ab12c0..5ec899d 100644 --- a/src/gui/elems/sampleEditor/shiftTool.cpp +++ b/src/gui/elems/sampleEditor/shiftTool.cpp @@ -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,14 +31,14 @@ #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); } diff --git a/src/gui/elems/sampleEditor/shiftTool.h b/src/gui/elems/sampleEditor/shiftTool.h index 0b1a6d3..4734c0f 100644 --- a/src/gui/elems/sampleEditor/shiftTool.h +++ b/src/gui/elems/sampleEditor/shiftTool.h @@ -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/sampleEditor/volumeTool.cpp b/src/gui/elems/sampleEditor/volumeTool.cpp index d937c9c..97e06d8 100644 --- a/src/gui/elems/sampleEditor/volumeTool.cpp +++ b/src/gui/elems/sampleEditor/volumeTool.cpp @@ -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()); diff --git a/src/gui/elems/sampleEditor/volumeTool.h b/src/gui/elems/sampleEditor/volumeTool.h index b38323c..be9484a 100644 --- a/src/gui/elems/sampleEditor/volumeTool.h +++ b/src/gui/elems/sampleEditor/volumeTool.h @@ -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/sampleEditor/waveTools.cpp b/src/gui/elems/sampleEditor/waveTools.cpp index 622bb2c..f3d6fce 100644 --- a/src/gui/elems/sampleEditor/waveTools.cpp +++ b/src/gui/elems/sampleEditor/waveTools.cpp @@ -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/sampleEditor/waveTools.h b/src/gui/elems/sampleEditor/waveTools.h index b224c53..af095dc 100644 --- a/src/gui/elems/sampleEditor/waveTools.h +++ b/src/gui/elems/sampleEditor/waveTools.h @@ -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/sampleEditor/waveform.cpp b/src/gui/elems/sampleEditor/waveform.cpp index 5b1b77f..476c1e8 100644 --- a/src/gui/elems/sampleEditor/waveform.cpp +++ b/src/gui/elems/sampleEditor/waveform.cpp @@ -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; diff --git a/src/gui/elems/sampleEditor/waveform.h b/src/gui/elems/sampleEditor/waveform.h index 1e7b426..fdeb185 100644 --- a/src/gui/elems/sampleEditor/waveform.h +++ b/src/gui/elems/sampleEditor/waveform.h @@ -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/soundMeter.cpp b/src/gui/elems/soundMeter.cpp index 036fc0a..34a7d7c 100644 --- a/src/gui/elems/soundMeter.cpp +++ b/src/gui/elems/soundMeter.cpp @@ -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,19 +29,18 @@ #include #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); } diff --git a/src/gui/elems/soundMeter.h b/src/gui/elems/soundMeter.h index 02de14e..65c4215 100644 --- a/src/gui/elems/soundMeter.h +++ b/src/gui/elems/soundMeter.h @@ -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; }; diff --git a/src/main.cpp b/src/main.cpp index ec809d9..8303e1b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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/utils/cocoa.h b/src/utils/cocoa.h index 69b9628..73e0d69 100644 --- a/src/utils/cocoa.h +++ b/src/utils/cocoa.h @@ -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/fs.cpp b/src/utils/fs.cpp index b29ba78..d3c8308 100644 --- a/src/utils/fs.cpp +++ b/src/utils/fs.cpp @@ -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; } diff --git a/src/utils/fs.h b/src/utils/fs.h index 2b9a216..63aba64 100644 --- a/src/utils/fs.h +++ b/src/utils/fs.h @@ -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/gui.cpp b/src/utils/gui.cpp index a481d69..035ee0a 100644 --- a/src/utils/gui.cpp +++ b/src/utils/gui.cpp @@ -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" @@ -59,16 +59,22 @@ 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(gu_getSubwindow(G_MainWin, WID_SAMPLE_EDITOR)); + gdSampleEditor* se = static_cast(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(G_MainWin->getChild(WID_ACTION_EDITOR)); + v::gdBaseActionEditor* ae = static_cast(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 diff --git a/src/utils/gui.h b/src/utils/gui.h index d69ca37..745b514 100644 --- a/src/utils/gui.h +++ b/src/utils/gui.h @@ -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 diff --git a/src/utils/log.cpp b/src/utils/log.cpp index 8cfdf8f..262ecf2 100644 --- a/src/utils/log.cpp +++ b/src/utils/log.cpp @@ -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/log.h b/src/utils/log.h index 5f4e8e6..80657e3 100644 --- a/src/utils/log.h +++ b/src/utils/log.h @@ -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/math.cpp b/src/utils/math.cpp index 324816b..e45c59e 100644 --- a/src/utils/math.cpp +++ b/src/utils/math.cpp @@ -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); } diff --git a/src/utils/math.h b/src/utils/math.h index 174978a..a5d7fba 100644 --- a/src/utils/math.h +++ b/src/utils/math.h @@ -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/utils/string.cpp b/src/utils/string.cpp index 2fc883e..2438f39 100644 --- a/src/utils/string.cpp +++ b/src/utils/string.cpp @@ -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. * @@ -34,13 +34,13 @@ #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 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* v) +std::vector split(std::string in, std::string sep) { - string full = in; - string token = ""; + std::vector 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* 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 diff --git a/src/utils/string.h b/src/utils/string.h index e59937e..062f39b 100644 --- a/src/utils/string.h +++ b/src/utils/string.h @@ -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. * @@ -34,11 +34,14 @@ #include #include #include -#include "../core/const.h" +namespace giada { +namespace u { +namespace string +{ template -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* v); +std::vector 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 diff --git a/src/utils/time.cpp b/src/utils/time.cpp index 2667c81..adbc400 100644 --- a/src/utils/time.cpp +++ b/src/utils/time.cpp @@ -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/time.h b/src/utils/time.h index 4afdc47..6c5c239 100644 --- a/src/utils/time.h +++ b/src/utils/time.h @@ -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 index 0000000..a21f2f9 --- /dev/null +++ b/src/utils/vector.h @@ -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 + * . + * + * -------------------------------------------------------------------------- */ + + +#ifndef G_UTILS_VECTOR_H +#define G_UTILS_VECTOR_H + + +#include +#include +#include + + +namespace giada { +namespace u { +namespace vector +{ +template +int indexOf(std::vector& v, T obj) +{ + auto it = std::find(v.begin(), v.end(), obj); + return it != v.end() ? std::distance(v.begin(), it) : -1; +} + + +template +int indexOf(std::vector& 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 diff --git a/src/utils/ver.cpp b/src/utils/ver.cpp index c22089f..cace9ef 100644 --- a/src/utils/ver.cpp +++ b/src/utils/ver.cpp @@ -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/utils/ver.h b/src/utils/ver.h index a8322f4..96b5f16 100644 --- a/src/utils/ver.h +++ b/src/utils/ver.h @@ -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/tests/conf.cpp b/tests/conf.cpp index 00418d5..88e7114 100644 --- a/tests/conf.cpp +++ b/tests/conf.cpp @@ -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); diff --git a/tests/patch.cpp b/tests/patch.cpp index 59f7b39..3a72fbc 100644 --- a/tests/patch.cpp +++ b/tests/patch.cpp @@ -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); diff --git a/tests/sampleChannel.cpp b/tests/sampleChannel.cpp index 59ecdbe..9362f97 100644 --- a/tests/sampleChannel.cpp +++ b/tests/sampleChannel.cpp @@ -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); diff --git a/tests/sampleChannelProc.cpp b/tests/sampleChannelProc.cpp index 82f2e07..510363d 100644 --- a/tests/sampleChannelProc.cpp +++ b/tests/sampleChannelProc.cpp @@ -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. */ diff --git a/tests/utils.cpp b/tests/utils.cpp index 79aeb4d..1a8ba4f 100644 --- a/tests/utils.cpp +++ b/tests/utils.cpp @@ -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 v; - gu_split("Giada is cool", " ", &v); + vector v = split("Giada is cool", " "); REQUIRE(v.size() == 3); REQUIRE(v.at(0) == "Giada"); REQUIRE(v.at(1) == "is"); diff --git a/tests/waveManager.cpp b/tests/waveManager.cpp index f19905c..2fbecee 100644 --- a/tests/waveManager.cpp +++ b/tests/waveManager.cpp @@ -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(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(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(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 = 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); + } } -- 2.30.2