From 0cf29addd1c52a50e2f11c0611b841d3756f537b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jarom=C3=ADr=20Mike=C5=A1?= Date: Sun, 15 Jan 2017 18:50:59 +0100 Subject: [PATCH] New upstream version 0.13.2~dfsg1 --- .travis.yml | 60 --- ChangeLog | 13 + Makefile.am | 110 ++-- src/core/channel.cpp | 43 +- src/core/channel.h | 9 +- src/core/conf.cpp | 23 +- src/core/conf.h | 46 +- src/core/const.h | 32 +- src/core/init.cpp | 7 + src/core/kernelMidi.cpp | 49 +- src/core/kernelMidi.h | 5 +- src/core/midiChannel.cpp | 24 +- src/core/midiChannel.h | 5 +- src/core/mixer.cpp | 30 +- src/core/mixer.h | 2 +- src/core/mixerHandler.cpp | 5 +- src/core/patch.cpp | 30 +- src/core/patch.h | 7 +- src/core/patch_DEPR_.cpp | 3 +- src/core/plugin.cpp | 177 ++++++- src/core/plugin.h | 46 +- src/core/pluginHost.cpp | 94 ++-- src/core/pluginHost.h | 12 +- src/core/recorder.cpp | 149 ++---- src/core/recorder.h | 20 +- src/core/sampleChannel.cpp | 18 +- src/core/sampleChannel.h | 6 +- src/deps/juce-config.h | 21 + src/glue/channel.cpp | 25 +- src/glue/channel.h | 1 + src/glue/io.cpp | 61 ++- src/glue/main.cpp | 39 +- src/glue/plugin.cpp | 73 +++ src/glue/plugin.h | 46 ++ src/glue/storage.cpp | 12 +- src/gui/dialogs/gd_about.cpp | 4 +- src/gui/dialogs/gd_actionEditor.cpp | 3 +- src/gui/dialogs/gd_actionEditor.h | 2 +- src/gui/dialogs/gd_beatsInput.cpp | 1 + src/gui/dialogs/gd_browser.cpp | 75 ++- src/gui/dialogs/gd_browser.h | 31 +- src/gui/dialogs/gd_config.cpp | 9 +- src/gui/dialogs/gd_editor.cpp | 4 +- src/gui/dialogs/gd_keyGrabber.cpp | 6 +- src/gui/dialogs/gd_mainWindow.cpp | 488 ++---------------- src/gui/dialogs/gd_mainWindow.h | 132 +---- src/gui/dialogs/gd_midiInput.cpp | 196 ------- src/gui/dialogs/gd_midiOutput.cpp | 258 --------- src/gui/dialogs/gd_pluginChooser.cpp | 20 +- src/gui/dialogs/gd_pluginList.cpp | 95 ++-- src/gui/dialogs/gd_pluginWindow.cpp | 11 +- src/gui/dialogs/gd_pluginWindowGUI.cpp | 2 +- src/gui/dialogs/midiIO/midiInputBase.cpp | 103 ++++ .../midiInputBase.h} | 51 +- src/gui/dialogs/midiIO/midiInputChannel.cpp | 172 ++++++ src/gui/dialogs/midiIO/midiInputChannel.h | 68 +++ src/gui/dialogs/midiIO/midiInputMaster.cpp | 60 +++ src/gui/dialogs/midiIO/midiInputMaster.h | 45 ++ src/gui/dialogs/midiIO/midiOutputBase.cpp | 116 +++++ .../midiOutputBase.h} | 68 +-- src/gui/dialogs/midiIO/midiOutputMidiCh.cpp | 119 +++++ src/gui/dialogs/midiIO/midiOutputMidiCh.h | 61 +++ src/gui/dialogs/midiIO/midiOutputSampleCh.cpp | 72 +++ src/gui/dialogs/midiIO/midiOutputSampleCh.h | 54 ++ src/gui/elems/actionEditor.cpp | 18 +- src/gui/elems/basics/boxtypes.cpp | 59 +++ src/gui/elems/basics/boxtypes.h | 47 ++ src/gui/elems/basics/scroll.cpp | 50 ++ src/gui/elems/basics/scroll.h | 46 ++ src/gui/elems/{ge_browser.cpp => browser.cpp} | 57 +- src/gui/elems/{ge_browser.h => browser.h} | 12 +- src/gui/elems/envelopeEditor.cpp | 16 +- src/gui/elems/ge_mixed.cpp | 78 +-- src/gui/elems/ge_mixed.h | 23 - src/gui/elems/ge_pluginBrowser.cpp | 9 +- src/gui/elems/ge_waveTools.cpp | 3 +- src/gui/elems/ge_waveform.cpp | 3 +- src/gui/elems/mainWindow/beatMeter.cpp | 72 +++ src/gui/elems/mainWindow/beatMeter.h | 46 ++ .../{ => mainWindow/keyboard}/channel.cpp | 26 +- .../elems/{ => mainWindow/keyboard}/channel.h | 2 +- .../keyboard}/channelButton.cpp | 3 +- .../{ => mainWindow/keyboard}/channelButton.h | 9 +- .../keyboard/channelMode.cpp} | 24 +- .../keyboard/channelMode.h} | 11 +- .../keyboard/channelStatus.cpp} | 16 +- .../keyboard/channelStatus.h} | 11 +- .../keyboard/column.cpp} | 75 ++- .../keyboard/column.h} | 9 +- .../keyboard/keyboard.cpp} | 103 ++-- .../keyboard/keyboard.h} | 27 +- .../{ => mainWindow/keyboard}/midiChannel.cpp | 41 +- .../{ => mainWindow/keyboard}/midiChannel.h | 0 .../keyboard}/sampleChannel.cpp | 97 ++-- .../{ => mainWindow/keyboard}/sampleChannel.h | 4 +- src/gui/elems/mainWindow/mainIO.cpp | 180 +++++++ src/gui/elems/mainWindow/mainIO.h | 81 +++ src/gui/elems/mainWindow/mainMenu.cpp | 229 ++++++++ src/gui/elems/mainWindow/mainMenu.h | 62 +++ src/gui/elems/mainWindow/mainTimer.cpp | 180 +++++++ src/gui/elems/mainWindow/mainTimer.h | 74 +++ .../mainTransport.cpp} | 43 +- .../mainTransport.h} | 11 +- .../{ge_midiIoTools.cpp => midiLearner.cpp} | 39 +- .../elems/{ge_midiIoTools.h => midiLearner.h} | 36 +- src/gui/elems/muteEditor.cpp | 23 +- src/gui/elems/pianoItem.cpp | 7 +- src/utils/gui.cpp | 26 +- 108 files changed, 3429 insertions(+), 2188 deletions(-) delete mode 100644 .travis.yml create mode 100644 src/deps/juce-config.h create mode 100644 src/glue/plugin.cpp create mode 100644 src/glue/plugin.h delete mode 100644 src/gui/dialogs/gd_midiInput.cpp delete mode 100644 src/gui/dialogs/gd_midiOutput.cpp create mode 100644 src/gui/dialogs/midiIO/midiInputBase.cpp rename src/gui/dialogs/{gd_midiInput.h => midiIO/midiInputBase.h} (62%) create mode 100644 src/gui/dialogs/midiIO/midiInputChannel.cpp create mode 100644 src/gui/dialogs/midiIO/midiInputChannel.h create mode 100644 src/gui/dialogs/midiIO/midiInputMaster.cpp create mode 100644 src/gui/dialogs/midiIO/midiInputMaster.h create mode 100644 src/gui/dialogs/midiIO/midiOutputBase.cpp rename src/gui/dialogs/{gd_midiOutput.h => midiIO/midiOutputBase.h} (63%) create mode 100644 src/gui/dialogs/midiIO/midiOutputMidiCh.cpp create mode 100644 src/gui/dialogs/midiIO/midiOutputMidiCh.h create mode 100644 src/gui/dialogs/midiIO/midiOutputSampleCh.cpp create mode 100644 src/gui/dialogs/midiIO/midiOutputSampleCh.h create mode 100644 src/gui/elems/basics/boxtypes.cpp create mode 100644 src/gui/elems/basics/boxtypes.h create mode 100644 src/gui/elems/basics/scroll.cpp create mode 100644 src/gui/elems/basics/scroll.h rename src/gui/elems/{ge_browser.cpp => browser.cpp} (78%) rename src/gui/elems/{ge_browser.h => browser.h} (93%) create mode 100644 src/gui/elems/mainWindow/beatMeter.cpp create mode 100644 src/gui/elems/mainWindow/beatMeter.h rename src/gui/elems/{ => mainWindow/keyboard}/channel.cpp (91%) rename src/gui/elems/{ => mainWindow/keyboard}/channel.h (99%) rename src/gui/elems/{ => mainWindow/keyboard}/channelButton.cpp (98%) rename src/gui/elems/{ => mainWindow/keyboard}/channelButton.h (94%) rename src/gui/elems/{ge_modeBox.cpp => mainWindow/keyboard/channelMode.cpp} (84%) rename src/gui/elems/{ge_modeBox.h => mainWindow/keyboard/channelMode.h} (87%) rename src/gui/elems/{ge_status.cpp => mainWindow/keyboard/channelStatus.cpp} (85%) rename src/gui/elems/{ge_status.h => mainWindow/keyboard/channelStatus.h} (85%) rename src/gui/elems/{ge_column.cpp => mainWindow/keyboard/column.cpp} (77%) rename src/gui/elems/{ge_column.h => mainWindow/keyboard/column.h} (93%) rename src/gui/elems/{ge_keyboard.cpp => mainWindow/keyboard/keyboard.cpp} (80%) rename src/gui/elems/{ge_keyboard.h => mainWindow/keyboard/keyboard.h} (87%) rename src/gui/elems/{ => mainWindow/keyboard}/midiChannel.cpp (90%) rename src/gui/elems/{ => mainWindow/keyboard}/midiChannel.h (100%) rename src/gui/elems/{ => mainWindow/keyboard}/sampleChannel.cpp (87%) rename src/gui/elems/{ => mainWindow/keyboard}/sampleChannel.h (97%) create mode 100644 src/gui/elems/mainWindow/mainIO.cpp create mode 100644 src/gui/elems/mainWindow/mainIO.h create mode 100644 src/gui/elems/mainWindow/mainMenu.cpp create mode 100644 src/gui/elems/mainWindow/mainMenu.h create mode 100644 src/gui/elems/mainWindow/mainTimer.cpp create mode 100644 src/gui/elems/mainWindow/mainTimer.h rename src/gui/elems/{ge_controller.cpp => mainWindow/mainTransport.cpp} (74%) rename src/gui/elems/{ge_controller.h => mainWindow/mainTransport.h} (92%) rename src/gui/elems/{ge_midiIoTools.cpp => midiLearner.cpp} (73%) rename src/gui/elems/{ge_midiIoTools.h => midiLearner.h} (72%) diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 5c770bc..0000000 --- a/.travis.yml +++ /dev/null @@ -1,60 +0,0 @@ -sudo: required - -dist: trusty - -language: cpp - -compiler: gcc - -notifications: - email: - recipients: - - giadaloopmachine@gmail.com - on_success: never - on_failure: always - -before_install: - - sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y # for gcc 6 - - sudo apt-get update -qq - - sudo apt-get install -y gcc-6 g++-6 libsndfile1-dev libsamplerate0-dev libfltk1.3-dev libasound2-dev libxpm-dev libpulse-dev libjack-dev libxrandr-dev libx11-dev libxinerama-dev libxcursor-dev - -before_script: - - sudo ln -f -s /usr/bin/g++-6 /usr/bin/g++ - - # Download and build latest version of RtMidi - - - wget http://www.music.mcgill.ca/~gary/rtmidi/release/rtmidi-2.1.0.tar.gz - - tar -xvf rtmidi-2.1.0.tar.gz - - cd rtmidi-2.1.0 && ./configure --with-jack --with-alsa && make && sudo make install || true - - cd .. - - # Download and install latest version of Jansson - - - wget http://www.digip.org/jansson/releases/jansson-2.7.tar.gz - - tar -xvf jansson-2.7.tar.gz - - cd jansson-2.7 && ./configure && make && sudo make install || true - - sudo ldconfig - - cd .. - - # Download midimaps package for testing purposes - - - wget https://github.com/monocasual/giada-midimaps/archive/master.zip -O giada-midimaps-master.zip - - unzip giada-midimaps-master.zip - - mkdir -p $HOME/.giada/midimaps - - cp giada-midimaps-master/midimaps/* $HOME/.giada/midimaps - - # Download vst plugin for testing purposes - - - wget http://www.discodsp.com/download/?id=18 -O bliss-linux.zip - - unzip bliss-linux.zip -d bliss-linux - - cp bliss-linux/64-bit/Bliss64Demo.so . - - # Build Giada. Note the CFLAGS: optimization levels are set to O1 in order - # not to throw up nasty errors from JUCE modules. - - - ./autogen.sh - - ./configure CXXFLAGS='-g -O1' --target=linux --enable-vst - -script: make && make check - -after_failure: cat $TRAVIS_BUILD_DIR/test-suite.log diff --git a/ChangeLog b/ChangeLog index 22878ce..65e29a5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,19 @@ -------------------------------------------------------------------------------- +0.13.2 --- 2017 . 01 . 14 +- MIDI learn for plugins parameters +- Toggle hidden files in File Browser +- Fix broken compilation when build without VST support +- Make sure PluginChooser window has a sane size +- Decouple Recorder from any global variable +- Better source code organization +- Make plugin creation more robust +- More source code reorganization +- Fix crash on clicking scrollbar arrows (GitHub #53) +- Fix crash when doubling/dividing length while recording (GitHub #110) + + 0.13.1 --- 2016 . 11 . 16 - Input MIDI to MIDI channels/plugins - Refinements to show/hide 'R' button's dynamics diff --git a/Makefile.am b/Makefile.am index 7990158..edb15a4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -55,6 +55,8 @@ src/glue/storage.h \ src/glue/storage.cpp \ src/glue/channel.h \ src/glue/channel.cpp \ +src/glue/plugin.h \ +src/glue/plugin.cpp \ src/gui/dialogs/gd_keyGrabber.h \ src/gui/dialogs/gd_keyGrabber.cpp \ src/gui/dialogs/gd_about.h \ @@ -81,28 +83,30 @@ src/gui/dialogs/gd_editor.h \ src/gui/dialogs/gd_editor.cpp \ src/gui/dialogs/gd_pluginWindowGUI.h \ src/gui/dialogs/gd_pluginWindowGUI.cpp \ -src/gui/dialogs/gd_midiOutput.h \ -src/gui/dialogs/gd_midiOutput.cpp \ -src/gui/dialogs/gd_midiInput.h \ -src/gui/dialogs/gd_midiInput.cpp \ src/gui/dialogs/gd_actionEditor.h \ src/gui/dialogs/gd_actionEditor.cpp \ src/gui/dialogs/gd_pluginChooser.h \ src/gui/dialogs/gd_pluginChooser.cpp \ -src/gui/elems/ge_column.h \ -src/gui/elems/ge_column.cpp \ -src/gui/elems/sampleChannel.h \ -src/gui/elems/sampleChannel.cpp \ -src/gui/elems/midiChannel.h \ -src/gui/elems/midiChannel.cpp \ -src/gui/elems/ge_midiIoTools.h \ -src/gui/elems/ge_midiIoTools.cpp \ +src/gui/dialogs/midiIO/midiOutputBase.h \ +src/gui/dialogs/midiIO/midiOutputBase.cpp \ +src/gui/dialogs/midiIO/midiOutputSampleCh.h \ +src/gui/dialogs/midiIO/midiOutputSampleCh.cpp \ +src/gui/dialogs/midiIO/midiOutputMidiCh.h \ +src/gui/dialogs/midiIO/midiOutputMidiCh.cpp \ +src/gui/dialogs/midiIO/midiInputBase.h \ +src/gui/dialogs/midiIO/midiInputBase.cpp \ +src/gui/dialogs/midiIO/midiInputChannel.h \ +src/gui/dialogs/midiIO/midiInputChannel.cpp \ +src/gui/dialogs/midiIO/midiInputMaster.h \ +src/gui/dialogs/midiIO/midiInputMaster.cpp \ +src/gui/elems/midiLearner.h \ +src/gui/elems/midiLearner.cpp \ src/gui/elems/ge_mixed.h \ src/gui/elems/ge_mixed.cpp \ src/gui/elems/ge_waveform.h \ src/gui/elems/ge_waveform.cpp \ -src/gui/elems/ge_browser.h \ -src/gui/elems/ge_browser.cpp \ +src/gui/elems/browser.h \ +src/gui/elems/browser.cpp \ src/gui/elems/baseActionEditor.h \ src/gui/elems/baseActionEditor.cpp \ src/gui/elems/envelopeEditor.h \ @@ -113,28 +117,46 @@ src/gui/elems/noteEditor.h \ src/gui/elems/noteEditor.cpp \ src/gui/elems/pianoItem.h \ src/gui/elems/pianoItem.cpp \ -src/gui/elems/channel.h \ -src/gui/elems/channel.cpp \ src/gui/elems/muteEditor.h \ src/gui/elems/muteEditor.cpp \ src/gui/elems/actionEditor.h \ src/gui/elems/actionEditor.cpp \ src/gui/elems/ge_window.h \ src/gui/elems/ge_window.cpp \ -src/gui/elems/ge_status.h \ -src/gui/elems/ge_status.cpp \ -src/gui/elems/ge_keyboard.h \ -src/gui/elems/ge_keyboard.cpp \ src/gui/elems/ge_waveTools.h \ src/gui/elems/ge_waveTools.cpp \ -src/gui/elems/ge_modeBox.h \ -src/gui/elems/ge_modeBox.cpp \ -src/gui/elems/ge_controller.h \ -src/gui/elems/ge_controller.cpp \ -src/gui/elems/channelButton.h \ -src/gui/elems/channelButton.cpp \ src/gui/elems/ge_pluginBrowser.h \ src/gui/elems/ge_pluginBrowser.cpp \ +src/gui/elems/mainWindow/mainIO.h \ +src/gui/elems/mainWindow/mainIO.cpp \ +src/gui/elems/mainWindow/mainMenu.h \ +src/gui/elems/mainWindow/mainMenu.cpp \ +src/gui/elems/mainWindow/mainTimer.h \ +src/gui/elems/mainWindow/mainTimer.cpp \ +src/gui/elems/mainWindow/mainTransport.h \ +src/gui/elems/mainWindow/mainTransport.cpp \ +src/gui/elems/mainWindow/beatMeter.h \ +src/gui/elems/mainWindow/beatMeter.cpp \ +src/gui/elems/mainWindow/keyboard/channelMode.h \ +src/gui/elems/mainWindow/keyboard/channelMode.cpp \ +src/gui/elems/mainWindow/keyboard/channelButton.h \ +src/gui/elems/mainWindow/keyboard/channelButton.cpp \ +src/gui/elems/mainWindow/keyboard/channelStatus.h \ +src/gui/elems/mainWindow/keyboard/channelStatus.cpp \ +src/gui/elems/mainWindow/keyboard/keyboard.h \ +src/gui/elems/mainWindow/keyboard/keyboard.cpp \ +src/gui/elems/mainWindow/keyboard/column.h \ +src/gui/elems/mainWindow/keyboard/column.cpp \ +src/gui/elems/mainWindow/keyboard/sampleChannel.h \ +src/gui/elems/mainWindow/keyboard/sampleChannel.cpp \ +src/gui/elems/mainWindow/keyboard/midiChannel.h \ +src/gui/elems/mainWindow/keyboard/midiChannel.cpp \ +src/gui/elems/mainWindow/keyboard/channel.h \ +src/gui/elems/mainWindow/keyboard/channel.cpp \ +src/gui/elems/basics/scroll.h \ +src/gui/elems/basics/scroll.cpp \ +src/gui/elems/basics/boxtypes.h \ +src/gui/elems/basics/boxtypes.cpp \ src/utils/log.h \ src/utils/log.cpp \ src/utils/gui.h \ @@ -147,14 +169,14 @@ src/utils/string.cpp if WITH_VST giada_SOURCES += \ -src/deps/juce/juce_audio_basics/juce_audio_basics.cpp \ -src/deps/juce/juce_audio_processors/juce_audio_processors.cpp \ -src/deps/juce/juce_core/juce_core.cpp \ -src/deps/juce/juce_data_structures/juce_data_structures.cpp \ -src/deps/juce/juce_events/juce_events.cpp \ -src/deps/juce/juce_graphics/juce_graphics.cpp \ -src/deps/juce/juce_gui_basics/juce_gui_basics.cpp \ -src/deps/juce/juce_gui_extra/juce_gui_extra.cpp +src/deps/juce/modules/juce_audio_basics/juce_audio_basics.cpp \ +src/deps/juce/modules/juce_audio_processors/juce_audio_processors.cpp \ +src/deps/juce/modules/juce_core/juce_core.cpp \ +src/deps/juce/modules/juce_data_structures/juce_data_structures.cpp \ +src/deps/juce/modules/juce_events/juce_events.cpp \ +src/deps/juce/modules/juce_graphics/juce_graphics.cpp \ +src/deps/juce/modules/juce_gui_basics/juce_gui_basics.cpp \ +src/deps/juce/modules/juce_gui_extra/juce_gui_extra.cpp endif # Check for environment: WITH_VST, LINUX, WINDOWS and OSX are varibles defined @@ -173,7 +195,7 @@ giada_CPPFLAGS = if WITH_VST giada_CPPFLAGS += \ - -I./src/deps/juce \ + -I./src/deps/juce/modules \ -I./src/deps/vst \ -I/usr/include \ -I/usr/include/freetype2 \ @@ -270,14 +292,14 @@ src/utils/log.cpp if WITH_VST giada_tests_SOURCES += \ -src/deps/juce/juce_audio_basics/juce_audio_basics.cpp \ -src/deps/juce/juce_audio_processors/juce_audio_processors.cpp \ -src/deps/juce/juce_core/juce_core.cpp \ -src/deps/juce/juce_data_structures/juce_data_structures.cpp \ -src/deps/juce/juce_events/juce_events.cpp \ -src/deps/juce/juce_graphics/juce_graphics.cpp \ -src/deps/juce/juce_gui_basics/juce_gui_basics.cpp \ -src/deps/juce/juce_gui_extra/juce_gui_extra.cpp +src/deps/juce/modules/juce_audio_basics/juce_audio_basics.cpp \ +src/deps/juce/modules/juce_audio_processors/juce_audio_processors.cpp \ +src/deps/juce/modules/juce_core/juce_core.cpp \ +src/deps/juce/modules/juce_data_structures/juce_data_structures.cpp \ +src/deps/juce/modules/juce_events/juce_events.cpp \ +src/deps/juce/modules/juce_graphics/juce_graphics.cpp \ +src/deps/juce/modules/juce_gui_basics/juce_gui_basics.cpp \ +src/deps/juce/modules/juce_gui_extra/juce_gui_extra.cpp endif giada_tests_LDADD = -ljansson -lsndfile -lsamplerate -lfltk -lXext -lX11 -lXft \ @@ -288,7 +310,7 @@ giada_tests_CXXFLAGS = -std=c++11 if WITH_VST giada_tests_CPPFLAGS = \ - -I./src/deps/juce \ + -I./src/deps/juce/modules \ -I./src/deps/vst \ -I/usr/include \ -I/usr/include/freetype2 \ diff --git a/src/core/channel.cpp b/src/core/channel.cpp index bcbafeb..95ad99a 100644 --- a/src/core/channel.cpp +++ b/src/core/channel.cpp @@ -28,7 +28,7 @@ #include "../utils/log.h" -#include "../gui/elems/channel.h" +#include "../gui/elems/mainWindow/keyboard/channel.h" #include "channel.h" #include "pluginHost.h" #include "plugin.h" @@ -69,6 +69,7 @@ Channel::Channel(int type, int status, int bufferSize, MidiMapConf *midiMapConf) mute (false), solo (false), hasActions (false), + readActions (false), armed (false), recStatus (REC_STOPPED), vChan (nullptr), @@ -147,8 +148,10 @@ void Channel::copy(const Channel *src, pthread_mutex_t *pluginMutex) for (unsigned i=0; ichan == src->index) + if (a->chan == src->index) { G_Recorder.rec(index, a->type, a->frame, a->iValue, a->fValue); + hasActions = true; + } } } } @@ -255,14 +258,14 @@ int Channel::writePatch(int i, bool isProject, Patch *patch) unsigned numPlugs = pluginHost->countPlugins(PluginHost::CHANNEL, this); for (unsigned i=0; igetPluginByIndex(i, PluginHost::CHANNEL, this); - if (pPlugin->getStatus()) { - Patch::plugin_t pp; - pp.path = pPlugin->getUniqueId(); - pp.bypass = pPlugin->isBypassed(); - for (int k=0; kgetNumParameters(); k++) - pp.params.push_back(pPlugin->getParameter(k)); - pch.plugins.push_back(pp); - } + Patch::plugin_t pp; + pp.path = pPlugin->getUniqueId(); + pp.bypass = pPlugin->isBypassed(); + for (int k=0; kgetNumParameters(); k++) + pp.params.push_back(pPlugin->getParameter(k)); + for (unsigned k=0; kmidiInParams.size(); k++) + pp.midiInParams.push_back(pPlugin->midiInParams.at(k)); + pch.plugins.push_back(pp); } #endif @@ -305,6 +308,7 @@ int Channel::readPatch(const string &path, int i, Patch *patch, for (unsigned k=0; kactions.size(); k++) { Patch::action_t *ac = &pch->actions.at(k); G_Recorder.rec(index, ac->type, ac->frame, ac->iValue, ac->fValue); + hasActions = true; } #ifdef WITH_VST @@ -313,14 +317,17 @@ int Channel::readPatch(const string &path, int i, Patch *patch, Patch::plugin_t *ppl = &pch->plugins.at(k); Plugin *plugin = pluginHost->addPlugin(ppl->path, PluginHost::CHANNEL, pluginMutex, this); - if (plugin != nullptr) { - plugin->setBypass(ppl->bypass); - for (unsigned j=0; jparams.size(); j++) - plugin->setParameter(j, ppl->params.at(j)); - ret &= 1; - } - else - ret &= 0; + if (plugin == nullptr) { + ret &= 0; + continue; + } + plugin->setBypass(ppl->bypass); + for (unsigned j=0; jparams.size(); j++) + plugin->setParameter(j, ppl->params.at(j)); + plugin->midiInParams.clear(); + for (unsigned j=0; jmidiInParams.size(); j++) + plugin->midiInParams.push_back(ppl->midiInParams.at(j)); + ret &= 1; } #endif diff --git a/src/core/channel.h b/src/core/channel.h index df9fe64..2df3d14 100644 --- a/src/core/channel.h +++ b/src/core/channel.h @@ -37,7 +37,7 @@ #include "recorder.h" #ifdef WITH_VST - #include "../deps/juce/config.h" + #include "../deps/juce-config.h" #endif @@ -143,10 +143,10 @@ public: /* quantize * start channel according to quantizer. Index = array index of - * mixer::channels, used by recorder. LocalFrame = frame within buffer. - * GloalFrame = actual frame from mixer. */ + * mixer::channels, used by recorder. LocalFrame = frame within the current + * buffer. */ - virtual void quantize(int index, int localFrame, int globalFrame) = 0; + virtual void quantize(int index, int localFrame, class Mixer *m) = 0; /* onZero * action to do when frame goes to zero, i.e. sequencer restart. */ @@ -213,6 +213,7 @@ public: bool mute; // global mute bool solo; bool hasActions; // has something recorded + bool readActions; // read what's recorded bool armed; // armed for recording int recStatus; // status of recordings (waiting, ending, ...) float *vChan; // virtual channel diff --git a/src/core/conf.cpp b/src/core/conf.cpp index 021549b..1a690ac 100644 --- a/src/core/conf.cpp +++ b/src/core/conf.cpp @@ -154,6 +154,11 @@ void Conf::init() sampleEditorW = 640; sampleEditorH = 480; + midiInputX = 0; + midiInputY = 0; + midiInputW = G_DEFAULT_MIDI_INPUT_UI_W; + midiInputH = G_DEFAULT_MIDI_INPUT_UI_H; + pianoRollY = -1; pianoRollH = 422; @@ -260,6 +265,10 @@ int Conf::read() if (!setInt(jRoot, CONF_KEY_BEATS_Y, beatsY)) return 0; if (!setInt(jRoot, CONF_KEY_ABOUT_X, aboutX)) return 0; if (!setInt(jRoot, CONF_KEY_ABOUT_Y, aboutY)) return 0; + if (!setInt(jRoot, CONF_KEY_MIDI_INPUT_X, midiInputX)) return 0; + if (!setInt(jRoot, CONF_KEY_MIDI_INPUT_Y, midiInputY)) return 0; + if (!setInt(jRoot, CONF_KEY_MIDI_INPUT_W, midiInputW)) return 0; + if (!setInt(jRoot, CONF_KEY_MIDI_INPUT_H, midiInputH)) return 0; #ifdef WITH_VST @@ -361,6 +370,10 @@ int Conf::write() json_object_set_new(jRoot, CONF_KEY_BEATS_Y, json_integer(beatsY)); json_object_set_new(jRoot, CONF_KEY_ABOUT_X, json_integer(aboutX)); json_object_set_new(jRoot, CONF_KEY_ABOUT_Y, json_integer(aboutY)); + json_object_set_new(jRoot, CONF_KEY_MIDI_INPUT_X, json_integer(midiInputX)); + 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)); #ifdef WITH_VST @@ -413,11 +426,19 @@ void Conf::sanitize() if (sampleEditorH < 292) sampleEditorH = 292; if (sampleEditorGridVal < 0) 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 (configX < 0) configX = 0; if (configY < 0) configY = 0; if (pluginListX < 0) pluginListX = 0; if (pluginListY < 0) pluginListY = 0; - if (bpmX < 0) bpmX = 0; +#ifdef WITH_VST + if (pluginChooserW < 640) pluginChooserW = 640; + if (pluginChooserH < 480) pluginChooserW = 480; +#endif + if (bpmX < 0) bpmX = 0; if (bpmY < 0) bpmY = 0; if (beatsX < 0) beatsX = 0; if (beatsY < 0) beatsY = 0; diff --git a/src/core/conf.h b/src/core/conf.h index f96265d..81901bc 100644 --- a/src/core/conf.h +++ b/src/core/conf.h @@ -80,14 +80,14 @@ public: bool limitOutput; int rsmpQuality; - int midiSystem; - int midiPortOut; - int midiPortIn; - bool noNoteOff; - string midiMapPath; - string lastFileMap; - int midiSync; // see const.h - float midiTCfps; + int midiSystem; + int midiPortOut; + int midiPortIn; + bool noNoteOff; + string midiMapPath; + string lastFileMap; + int midiSync; // see const.h + float midiTCfps; uint32_t midiInRewind; uint32_t midiInStartStop; @@ -108,25 +108,27 @@ public: string patchPath; string samplePath; - int mainWindowX, mainWindowY, mainWindowW, mainWindowH; + int mainWindowX, mainWindowY, mainWindowW, mainWindowH; - int browserX, browserY, browserW, browserH, browserPosition, browserLastValue; + int browserX, browserY, browserW, browserH, browserPosition, browserLastValue; string browserLastPath; - int actionEditorX, actionEditorY, actionEditorW, actionEditorH, actionEditorZoom; - int actionEditorGridVal; - int actionEditorGridOn; + int actionEditorX, actionEditorY, actionEditorW, actionEditorH, actionEditorZoom; + int actionEditorGridVal; + int actionEditorGridOn; - int sampleEditorX, sampleEditorY, sampleEditorW, sampleEditorH; - int sampleEditorGridVal; - int sampleEditorGridOn; + int sampleEditorX, sampleEditorY, sampleEditorW, sampleEditorH; + int sampleEditorGridVal; + int sampleEditorGridOn; - int pianoRollY, pianoRollH; - int pluginListX, pluginListY; - int configX, configY; - int bpmX, bpmY; - int beatsX, beatsY; - int aboutX, aboutY; + int midiInputX, midiInputY, midiInputW, midiInputH; + + int pianoRollY, pianoRollH; + int pluginListX, pluginListY; + int configX, configY; + int bpmX, bpmY; + int beatsX, beatsY; + int aboutX, aboutY; #ifdef WITH_VST diff --git a/src/core/const.h b/src/core/const.h index 9571b2d..99fa701 100644 --- a/src/core/const.h +++ b/src/core/const.h @@ -32,11 +32,11 @@ /* -- version --------------------------------------------------------------- */ -#define G_VERSION_STR "0.13.1" +#define G_VERSION_STR "0.13.2" #define G_APP_NAME "Giada" #define G_VERSION_MAJOR 0 #define G_VERSION_MINOR 13 -#define G_VERSION_PATCH 1 +#define G_VERSION_PATCH 2 #define CONF_FILENAME "giada.conf" @@ -64,17 +64,17 @@ #define GUI_PLUGIN_RATE 0.05 // refresh rate for plugin GUIs #define GUI_FONT_SIZE_BASE 12 -#define COLOR_BD_0 fl_rgb_color(78, 78, 78) // border off +#define COLOR_BD_0 fl_rgb_color(78, 78, 78) // border off - TODO duplicate! #define COLOR_BD_1 fl_rgb_color(188, 188, 188) // border on #define COLOR_BG_0 fl_rgb_color(37, 37, 37) // bg off -#define COLOR_BG_1 fl_rgb_color(78, 78, 78) // bg on (clicked) +#define COLOR_BG_1 fl_rgb_color(78, 78, 78) // bg on (clicked) - TODO duplicate! #define COLOR_BG_2 fl_rgb_color(177, 142, 142) // bg active (play, for some widgets) #define COLOR_BG_3 fl_rgb_color(28, 32, 80) // bg input rec #define COLOR_BG_4 fl_rgb_color(113, 31, 31) // bg action rec #define COLOR_ALERT fl_rgb_color(239, 75, 53) // peak meter alert #define COLOR_TEXT_0 fl_rgb_color(200, 200, 200) -#define COLOR_TEXT_1 fl_rgb_color(25, 25, 25) // TODO - duplicate! -#define COLOR_BG_MAIN fl_rgb_color(25, 25, 25) // windows background +#define COLOR_TEXT_1 fl_rgb_color(25, 25, 25) // TODO duplicate! +#define COLOR_BG_MAIN fl_rgb_color(25, 25, 25) // windows background - TODO duplicate! #define COLOR_BG_RICH fl_rgb_color(30, 30, 30) // lighter background #define COLOR_BG_LINE fl_rgb_color(54, 54, 54) // lighter, for bg lines #define COLOR_BG_DARK fl_rgb_color(0, 0, 0) // inputs background @@ -131,8 +131,8 @@ #define DEFAULT_BUFSIZE 1024 #define DEFAULT_DELAYCOMP 0 #define DEFAULT_VOL 1.0f +#define G_DEFAULT_PITCH 1.0f #define DEFAULT_BOOST 0.0f -#define gDEFAULT_PITCH 1.0f // ugly and temporary fix to avoid conflicts with wingdi.h (Windows only). #define DEFAULT_OUT_VOL 1.0f #define DEFAULT_IN_VOL 1.0f #define DEFAULT_CHANMODE SINGLE_BASIC @@ -143,6 +143,8 @@ #define DEFAULT_FADEOUT_STEP 0.01f // micro-fadeout speed #define 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 @@ -213,17 +215,6 @@ -/* -- browser types --------------------------------------------------------- */ -/* TODO - USELESS, remove them */ -#define BROWSER_LOAD_PATCH 0x00 -#define BROWSER_LOAD_SAMPLE 0x01 -#define BROWSER_SAVE_PATCH 0x02 -#define BROWSER_SAVE_SAMPLE 0x04 -#define BROWSER_SAVE_PROJECT 0x08 -#define BROWSER_LOAD_PLUGIN 0x10 - - - /* -- channel types --------------------------------------------------------- */ #define CHANNEL_SAMPLE 0x01 #define CHANNEL_MIDI 0x02 @@ -384,6 +375,7 @@ const int MIDI_CHANS[16] = { #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" @@ -466,6 +458,10 @@ const int MIDI_CHANS[16] = { #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" /* JSON midimaps keys */ diff --git a/src/core/init.cpp b/src/core/init.cpp index e280d46..41105a6 100644 --- a/src/core/init.cpp +++ b/src/core/init.cpp @@ -37,6 +37,7 @@ #include "mixer.h" #include "wave.h" #include "const.h" +#include "channel.h" #include "mixerHandler.h" #include "patch_DEPR_.h" #include "patch.h" @@ -207,6 +208,12 @@ void init_shutdown() } G_Recorder.clearAll(); + for (unsigned i=0; ihasActions = false; + G_Mixer.channels.at(i)->readActions = false; + //if (G_Mixer.channels.at(i)->type == CHANNEL_SAMPLE) + // ((SampleChannel*)G_Mixer.channels.at(i))->readActions = false; + } gu_log("[init] Recorder cleaned up\n"); #ifdef WITH_VST diff --git a/src/core/kernelMidi.cpp b/src/core/kernelMidi.cpp index 9676143..f8c519b 100644 --- a/src/core/kernelMidi.cpp +++ b/src/core/kernelMidi.cpp @@ -39,7 +39,10 @@ #include "midiChannel.h" #include "conf.h" #include "midiMapConf.h" -#include "pluginHost.h" +#ifdef WITH_VST + #include "pluginHost.h" + #include "plugin.h" +#endif #include "kernelMidi.h" @@ -48,8 +51,9 @@ extern Conf G_Conf; extern Mixer G_Mixer; extern KernelMidi G_KernelMidi; extern MidiMapConf G_MidiMap; +#ifdef WITH_VST extern PluginHost G_PluginHost; - +#endif using std::string; using std::vector; @@ -415,7 +419,15 @@ void KernelMidi::processChannels(uint32_t pure, uint32_t value) glue_startStopReadingRecs((SampleChannel*)ch, false); } - /* redirect full midi message to plugins */ +#ifdef WITH_VST + + /* Process plugins' parameters */ + + processPlugins(ch, pure, value); + +#endif + + /* Redirect full midi message (pure + value) to plugins */ ch->receiveMidi(pure | value); } @@ -425,6 +437,37 @@ void KernelMidi::processChannels(uint32_t pure, uint32_t value) /* -------------------------------------------------------------------------- */ +#ifdef WITH_VST + +void KernelMidi::processPlugins(Channel *ch, uint32_t pure, uint32_t value) +{ + /* Plugins' parameters layout reflect the structure of the matrix + Channel::midiInPlugins. It is safe to assume then that i and k indexes match + both the structure of Channel::midiInPlugins and vector *plugins. */ + + vector *plugins = G_PluginHost.getStack(PluginHost::CHANNEL, ch); + + for (unsigned i=0; isize(); i++) + { + Plugin *plugin = plugins->at(i); + for (unsigned k=0; kmidiInParams.size(); k++) { + uint32_t midiInParam = plugin->midiInParams.at(k); + if (pure != midiInParam) + continue; + float vf = (value >> 8)/127.0f; + plugin->setParameter(k, vf); + gu_log(" >>> [plugin %d parameter %d] ch=%d (pure=0x%X, value=%d, float=%f)\n", + i, k, ch->index, pure, value >> 8, vf); + } + } +} + +#endif + + +/* -------------------------------------------------------------------------- */ + + string KernelMidi::getRtMidiVersion() { return midiOut->getVersion(); diff --git a/src/core/kernelMidi.h b/src/core/kernelMidi.h index 834e0de..e8cb0f4 100644 --- a/src/core/kernelMidi.h +++ b/src/core/kernelMidi.h @@ -96,7 +96,7 @@ public: private: - int api; + int api; class RtMidiOut *midiOut; class RtMidiIn *midiIn; @@ -119,6 +119,9 @@ private: void processMaster(uint32_t pure, uint32_t value); void processChannels(uint32_t pure, uint32_t value); +#ifdef WITH_VST + void processPlugins(class Channel *ch, uint32_t pure, uint32_t value); +#endif }; #endif diff --git a/src/core/midiChannel.cpp b/src/core/midiChannel.cpp index cf1f88a..ad531d6 100644 --- a/src/core/midiChannel.cpp +++ b/src/core/midiChannel.cpp @@ -30,19 +30,22 @@ #include "../utils/log.h" #include "midiChannel.h" #include "channel.h" -#include "pluginHost.h" #include "patch_DEPR_.h" #include "patch.h" #include "conf.h" #include "mixer.h" +#ifdef WITH_VST + #include "pluginHost.h" +#endif #include "kernelMidi.h" extern Recorder G_Recorder; extern KernelMidi G_KernelMidi; -extern PluginHost G_PluginHost; extern Mixer G_Mixer; - +#ifdef WITH_VST +extern PluginHost G_PluginHost; +#endif MidiChannel::MidiChannel(int bufferSize, MidiMapConf *midiMapConf) : Channel (CHANNEL_MIDI, STATUS_OFF, bufferSize, midiMapConf), @@ -108,7 +111,7 @@ void MidiChannel::empty() {} /* -------------------------------------------------------------------------- */ -void MidiChannel::quantize(int index, int localFrame, int globalFrame) {} +void MidiChannel::quantize(int index, int localFrame, Mixer *m) {} /* -------------------------------------------------------------------------- */ @@ -335,19 +338,24 @@ void MidiChannel::receiveMidi(uint32_t msg) { if (!armed) return; + +#ifdef WITH_VST + while (true) { if (pthread_mutex_trylock(&G_PluginHost.mutex_midi) != 0) continue; gu_log("[Channel::processMidi] msg=%X\n", msg); -#ifdef WITH_VST addVstMidiEvent(msg, 0); -#endif pthread_mutex_unlock(&G_PluginHost.mutex_midi); break; } - if (G_Recorder.canRec(this)) - G_Recorder.rec(index, ACTION_MIDI, G_Mixer.actualFrame, msg); +#endif + + if (G_Recorder.canRec(this, &G_Mixer)) { + G_Recorder.rec(index, ACTION_MIDI, G_Mixer.currentFrame, msg); + hasActions = true; + } } diff --git a/src/core/midiChannel.h b/src/core/midiChannel.h index dcaaa27..94336b8 100644 --- a/src/core/midiChannel.h +++ b/src/core/midiChannel.h @@ -32,7 +32,7 @@ #ifdef WITH_VST - #include "../deps/juce/config.h" + #include "../deps/juce-config.h" #endif #include "channel.h" @@ -65,7 +65,7 @@ public: int readPatch(const string &basePath, int i, class Patch *patch, pthread_mutex_t *pluginMutex, int samplerate, int rsmpQuality) override; int writePatch(int i, bool isProject, class Patch *patch) override; - void quantize(int index, int localFrame, int globalFrame) override; + void quantize(int index, int localFrame, class Mixer *m) override; void onZero(int frame, bool recsStopOnChanHalt) override; void onBar(int frame) override; void parseAction(Recorder::action *a, int localFrame, int globalFrame, @@ -81,7 +81,6 @@ public: void sendMidi(Recorder::action *a, int localFrame); void sendMidi(uint32_t data); - #ifdef WITH_VST /* addVstMidiEvent diff --git a/src/core/mixer.cpp b/src/core/mixer.cpp index 7321f1b..efe2532 100644 --- a/src/core/mixer.cpp +++ b/src/core/mixer.cpp @@ -99,7 +99,7 @@ void Mixer::init() recording = false; ready = true; waitRec = 0; - actualFrame = 0; + currentFrame = 0; bpm = DEFAULT_BPM; bars = DEFAULT_BARS; beats = DEFAULT_BEATS; @@ -246,7 +246,7 @@ Channel *Mixer::getChannelByIndex(int index) void Mixer::sendMIDIsync() { if (G_Conf.midiSync == MIDI_SYNC_CLOCK_M) { - if (actualFrame % (framesPerBeat/24) == 0) + if (currentFrame % (framesPerBeat/24) == 0) G_KernelMidi.send(MIDI_CLOCK, -1, -1); } else @@ -257,7 +257,7 @@ void Mixer::sendMIDIsync() * 1-4 and 5-8. We check timecode frame's parity: if even, send * range 1-4, if odd send 5-8. */ - if (actualFrame % midiTCrate == 0) { + if (currentFrame % midiTCrate == 0) { /* frame low nibble * frame high nibble @@ -363,7 +363,7 @@ int Mixer::__masterPlay(void *_outBuf, void *_inBuf, unsigned bufferSize) testBar(j); testFirstBeat(j); readActions(j); - actualFrame += 2; + currentFrame += 2; testLastBeat(); // this test must be the last one sendMIDIsync(); } @@ -463,7 +463,7 @@ bool Mixer::isSilent() void Mixer::rewind() { - actualFrame = 0; + currentFrame = 0; actualBeat = 0; if (running) @@ -586,11 +586,11 @@ void Mixer::readActions(unsigned frame) { pthread_mutex_lock(&mutex_recs); for (unsigned i=0; ichan; Channel *ch = getChannelByIndex(index); - ch->parseAction(G_Recorder.global.at(i).at(j), frame, actualFrame, quantize, running); + ch->parseAction(G_Recorder.global.at(i).at(j), frame, currentFrame, quantize, running); } break; } @@ -606,7 +606,7 @@ void Mixer::doQuantize(unsigned frame) { if (quantize < 0 || quanto <= 0) // if quantizer disabled return; - if (actualFrame % (quanto) != 0) // if a quanto has not passed yet + if (currentFrame % (quanto) != 0) // if a quanto has not passed yet return; if (rewindWait) { @@ -615,7 +615,7 @@ void Mixer::doQuantize(unsigned frame) } pthread_mutex_lock(&mutex_chans); for (unsigned i=0; iquantize(i, frame, actualFrame); // j == localFrame + channels.at(i)->quantize(i, frame, this); // j == localFrame pthread_mutex_unlock(&mutex_chans); } @@ -625,7 +625,7 @@ void Mixer::doQuantize(unsigned frame) void Mixer::testBar(unsigned frame) { - if (actualFrame % framesPerBar != 0 || actualFrame == 0) + if (currentFrame % framesPerBar != 0 || currentFrame == 0) return; if (metronome) @@ -643,7 +643,7 @@ void Mixer::testBar(unsigned frame) void Mixer::testFirstBeat(unsigned frame) { - if (actualFrame != 0) + if (currentFrame != 0) return; pthread_mutex_lock(&mutex_chans); for (unsigned k=0; k totalFrames the sequencer returns to frame 0, + /* if currentFrame > totalFrames the sequencer returns to frame 0, * beat 0. This must be the last operation. */ - if (actualFrame > totalFrames) { - actualFrame = 0; + if (currentFrame > totalFrames) { + currentFrame = 0; actualBeat = 0; } else - if (actualFrame % framesPerBeat == 0 && actualFrame > 0) { + if (currentFrame % framesPerBeat == 0 && currentFrame > 0) { actualBeat++; /* avoid tick and tock to overlap when a new bar has passed (which diff --git a/src/core/mixer.h b/src/core/mixer.h index f8afb46..66d0823 100644 --- a/src/core/mixer.h +++ b/src/core/mixer.h @@ -150,7 +150,7 @@ public: int framesPerBeat; // frames in one beat int framesInSequencer; // frames in the whole sequencer int totalFrames; // frames in the selected range (e.g. 4/4) - int actualFrame; + int currentFrame; int actualBeat; #define TICKSIZE 38 diff --git a/src/core/mixerHandler.cpp b/src/core/mixerHandler.cpp index e3d1945..5bb2bd4 100644 --- a/src/core/mixerHandler.cpp +++ b/src/core/mixerHandler.cpp @@ -76,6 +76,7 @@ static int __mh_readPatchPlugins__(vector *list, int type) int ret = 1; for (unsigned i=0; isize(); i++) { Patch::plugin_t *ppl = &list->at(i); + // TODO use glue_addPlugin() Plugin *plugin = G_PluginHost.addPlugin(ppl->path.c_str(), type, &G_Mixer.mutex_plugins, NULL); if (plugin != NULL) { @@ -238,9 +239,9 @@ bool mh_startInputRec() if (channelsReady > 0) { G_Mixer.recording = true; - /* start to write from the actualFrame, not the beginning */ + /* start to write from the currentFrame, not the beginning */ /** FIXME: this should be done before wave allocation */ - G_Mixer.inputTracker = G_Mixer.actualFrame; + G_Mixer.inputTracker = G_Mixer.currentFrame; return true; } return false; diff --git a/src/core/patch.cpp b/src/core/patch.cpp index dbc1aa7..b622537 100644 --- a/src/core/patch.cpp +++ b/src/core/patch.cpp @@ -119,17 +119,23 @@ void Patch::writePlugins(json_t *jContainer, vector *plugins, const ch for (unsigned j=0; jsize(); j++) { json_t *jPlugin = json_object(); plugin_t plugin = plugins->at(j); - json_object_set_new(jPlugin, PATCH_KEY_PLUGIN_PATH, json_string(plugin.path.c_str())); - json_object_set_new(jPlugin, PATCH_KEY_PLUGIN_BYPASS, json_boolean(plugin.bypass)); + json_object_set_new(jPlugin, PATCH_KEY_PLUGIN_PATH, json_string(plugin.path.c_str())); + json_object_set_new(jPlugin, PATCH_KEY_PLUGIN_BYPASS, json_boolean(plugin.bypass)); json_array_append_new(jPlugins, jPlugin); /* plugin params */ json_t *jPluginParams = json_array(); - for (unsigned z=0; z *container, const c return 0; plugin_t plugin; - if (!setString (jPlugin, PATCH_KEY_PLUGIN_PATH, plugin.path)) return 0; - if (!setBool (jPlugin, PATCH_KEY_PLUGIN_BYPASS, plugin.bypass)) return 0; + if (!setString(jPlugin, PATCH_KEY_PLUGIN_PATH, plugin.path)) return 0; + if (!setBool (jPlugin, PATCH_KEY_PLUGIN_BYPASS, plugin.bypass)) return 0; /* read plugin params */ @@ -426,6 +432,16 @@ bool Patch::readPlugins(json_t *jContainer, vector *container, const c json_array_foreach(jParams, paramIndex, jParam) plugin.params.push_back(json_real_value(jParam)); + /* read midiIn params (midi learning on plugins' parameters) */ + + json_t *jMidiInParams = json_object_get(jPlugin, PATCH_KEY_PLUGIN_MIDI_IN_PARAMS); + if (!checkArray(jMidiInParams, PATCH_KEY_PLUGIN_MIDI_IN_PARAMS)) return 0; + + size_t midiInParamIndex; + json_t *jMidiInParam; + json_array_foreach(jMidiInParams, midiInParamIndex, jMidiInParam) + plugin.midiInParams.push_back(json_integer_value(jMidiInParam)); + container->push_back(plugin); } return 1; @@ -459,7 +475,7 @@ void Patch::sanitize() ch->panLeft = ch->panLeft < 0.0f || ch->panLeft > 1.0f ? 1.0f : ch->panLeft; ch->panRight = ch->panRight < 0.0f || ch->panRight > 1.0f ? 1.0f : ch->panRight; ch->boost = ch->boost < 1.0f ? DEFAULT_BOOST : ch->boost; - ch->pitch = ch->pitch < 0.1f || ch->pitch > 4.0f ? gDEFAULT_PITCH : ch->pitch; + ch->pitch = ch->pitch < 0.1f || ch->pitch > 4.0f ? G_DEFAULT_PITCH : ch->pitch; } } diff --git a/src/core/patch.h b/src/core/patch.h index 99ef6a1..ba17077 100644 --- a/src/core/patch.h +++ b/src/core/patch.h @@ -56,9 +56,10 @@ public: #ifdef WITH_VST struct plugin_t { - string path; - bool bypass; - vector params; + string path; + bool bypass; + vector params; + vector midiInParams; }; #endif diff --git a/src/core/patch_DEPR_.cpp b/src/core/patch_DEPR_.cpp index 99010a0..5ded87d 100644 --- a/src/core/patch_DEPR_.cpp +++ b/src/core/patch_DEPR_.cpp @@ -31,7 +31,7 @@ #include "../utils/log.h" #include "../utils/fs.h" #include "../gui/dialogs/gd_mainWindow.h" -#include "../gui/elems/ge_keyboard.h" +#include "../gui/elems/mainWindow/keyboard/keyboard.h" #include "patch_DEPR_.h" #include "init.h" #include "recorder.h" @@ -514,6 +514,7 @@ int Patch_DEPR_::readRecs() G_Recorder.rec(ch->index, type, frame, iValue_fix, fValue); else G_Recorder.rec(ch->index, type, frame, iValue, fValue); + ch->hasActions = true; } } } diff --git a/src/core/plugin.cpp b/src/core/plugin.cpp index bf4a1c4..1ef79b2 100644 --- a/src/core/plugin.cpp +++ b/src/core/plugin.cpp @@ -41,24 +41,44 @@ int Plugin::idGenerator = 1; /* -------------------------------------------------------------------------- */ -void Plugin::init() +Plugin::Plugin(juce::AudioPluginInstance *plugin, double samplerate, + int buffersize) + : ui (nullptr), + plugin(plugin), + id (idGenerator++), + bypass(false) { - ui = NULL; - id = idGenerator++;; - bypass = false; - status = 1; + /* Fill midiInParams. All values are empty (0x0): they will be filled during + midi learning process. */ - if (getActiveEditor() != NULL) { - gu_log("[Plugin::init] plugin has an already active editor!\n"); + for (int i=0; igetNumParameters(); i++) + midiInParams.push_back(0x0); + + /* Try to enable editor (i.e. plugin's UI) */ + + if (plugin->getActiveEditor() != NULL) { + gu_log("[Plugin] plugin has an already active editor!\n"); return; } - ui = createEditorIfNeeded(); + ui = plugin->createEditorIfNeeded(); if (ui == NULL) { - gu_log("[Plugin::init] unable to create editor, the plugin might be GUI-less!\n"); + gu_log("[Plugin] unable to create editor, the plugin might be GUI-less!\n"); return; } - gu_log("[Plugin::init] editor initialized and ready\n"); + plugin->prepareToPlay(samplerate, buffersize); + + gu_log("[Plugin] editor initialized and ready\n"); +} + + +/* -------------------------------------------------------------------------- */ + + +Plugin::~Plugin() +{ + plugin->suspendProcessing(true); + plugin->releaseResources(); } @@ -90,7 +110,142 @@ bool Plugin::isEditorOpen() string Plugin::getUniqueId() { - return getPluginDescription().fileOrIdentifier.toStdString(); + return plugin->getPluginDescription().fileOrIdentifier.toStdString(); +} + + +/* -------------------------------------------------------------------------- */ + + +int Plugin::getNumParameters() +{ + return plugin->getNumParameters(); +} + + +/* -------------------------------------------------------------------------- */ + + +float Plugin::getParameter(int paramIndex) +{ + return plugin->getParameter(paramIndex); +} + + +/* -------------------------------------------------------------------------- */ + + +void Plugin::setParameter(int paramIndex, float value) +{ + return plugin->setParameter(paramIndex, value); +} + + +/* -------------------------------------------------------------------------- */ + + +void Plugin::prepareToPlay(double samplerate, int buffersize) +{ + plugin->prepareToPlay(samplerate, buffersize); +} + + +/* -------------------------------------------------------------------------- */ + + +string Plugin::getName() +{ + return plugin->getName().toStdString(); +} + + +/* -------------------------------------------------------------------------- */ + + +bool Plugin::isSuspended() +{ + return plugin->isSuspended(); +} + + +/* -------------------------------------------------------------------------- */ + + +void Plugin::process(juce::AudioBuffer &b, juce::MidiBuffer &m) +{ + plugin->processBlock(b, m); +} + + +/* -------------------------------------------------------------------------- */ + + +int Plugin::getNumPrograms() +{ + return plugin->getNumPrograms(); +} + + +/* -------------------------------------------------------------------------- */ + + +int Plugin::getCurrentProgram() +{ + return plugin->getCurrentProgram(); +} + + +/* -------------------------------------------------------------------------- */ + + +void Plugin::setCurrentProgram(int index) +{ + plugin->setCurrentProgram(index); +} + + +/* -------------------------------------------------------------------------- */ + + +bool Plugin::hasEditor() +{ + return plugin->hasEditor(); +} + + +/* -------------------------------------------------------------------------- */ + + +string Plugin::getProgramName(int index) +{ + return plugin->getProgramName(index).toStdString(); +} + + +/* -------------------------------------------------------------------------- */ + + +string Plugin::getParameterName(int index) +{ + return plugin->getParameterName(index).toStdString(); +} + + +/* -------------------------------------------------------------------------- */ + + +string Plugin::getParameterText(int index) +{ + return plugin->getParameterText(index).toStdString(); +} + + +/* -------------------------------------------------------------------------- */ + + +string Plugin::getParameterLabel(int index) +{ + return plugin->getParameterLabel(index).toStdString(); } diff --git a/src/core/plugin.h b/src/core/plugin.h index 38e411c..d295e50 100644 --- a/src/core/plugin.h +++ b/src/core/plugin.h @@ -26,32 +26,32 @@ * * -------------------------------------------------------------------------- */ + #ifdef WITH_VST #ifndef __PLUGIN_H__ #define __PLUGIN_H__ -#include "../deps/juce/config.h" - +#include "../deps/juce-config.h" -using std::string; - -class Plugin : public juce::AudioPluginInstance +class Plugin { private: + static int idGenerator; + juce::AudioProcessorEditor *ui; // gui + juce::AudioPluginInstance *plugin; // core - static int idGenerator; - int id; - bool bypass; - bool status; + int id; + bool bypass; public: - void init(); + Plugin(juce::AudioPluginInstance *p, double samplerate, int buffersize); + ~Plugin(); void showEditor(void *parent); @@ -67,16 +67,36 @@ public: /* getUniqueId * Return a string-based UID. */ - string getUniqueId(); + std::string getUniqueId(); + + std::string getName(); + + bool hasEditor(); + int getNumParameters(); + float getParameter(int index); + void setParameter(int index, float value); + std::string getParameterName(int index); + std::string getParameterText(int index); + std::string getParameterLabel(int index); + void prepareToPlay(double samplerate, int buffersize); + bool isSuspended(); + void process(juce::AudioBuffer &b, juce::MidiBuffer &m); + int getNumPrograms(); + int getCurrentProgram(); + void setCurrentProgram(int index); + std::string getProgramName(int index); int getId() { return id; } - bool getStatus() { return status; } bool isBypassed() { return bypass; } int getEditorW() { return ui->getWidth(); } int getEditorH() { return ui->getHeight(); } void toggleBypass() { bypass = !bypass; } - void setStatus(int s) { status = s; } void setBypass(bool b) { bypass = b; } + + /* midiInParams + A list of midiIn hex values for parameter automation. */ + + std::vector midiInParams; }; #endif diff --git a/src/core/pluginHost.cpp b/src/core/pluginHost.cpp index f95a966..a23f266 100644 --- a/src/core/pluginHost.cpp +++ b/src/core/pluginHost.cpp @@ -144,35 +144,28 @@ Plugin *PluginHost::addPlugin(const string &fid, int stackType, return NULL; } - Plugin *p = (Plugin *) pluginFormat.createInstanceFromDescription(*pd, samplerate, buffersize); - if (!p) { + 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 NULL; } - - //p->setStatus(1); - //p->setId(); - //p->initEditor(); - p->init(); - p->prepareToPlay(samplerate, buffersize); - gu_log("[PluginHost::addPlugin] plugin instance with fid=%s created\n", fid.c_str()); + Plugin *p = new Plugin(pi, samplerate, buffersize); + /* Try to inject the plugin as soon as possible. */ - int lockStatus; while (true) { - lockStatus = pthread_mutex_trylock(mutex); - if (lockStatus == 0) { - pStack->push_back(p); - pthread_mutex_unlock(mutex); - break; - } + 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().toStdString().c_str(), stackType, pStack->size()); + fid.c_str(), p->getName().c_str(), stackType, pStack->size()); return p; } @@ -286,22 +279,14 @@ void PluginHost::freeStack(int stackType, pthread_mutex_t *mutex, Channel *ch) if (pStack->size() == 0) return; - int lockStatus; while (true) { - lockStatus = pthread_mutex_trylock(mutex); - if (lockStatus == 0) { - for (unsigned i=0; isize(); i++) { - Plugin *pPlugin = pStack->at(i); - if (pPlugin->getStatus() != 0) { // take care if plugin is in good status - pPlugin->suspendProcessing(true); - pPlugin->releaseResources(); - } - delete pPlugin; - } - pStack->clear(); - pthread_mutex_unlock(mutex); - break; - } + 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); } @@ -337,17 +322,17 @@ void PluginHost::processStack(float *buffer, int stackType, Channel *ch) for (unsigned i=0; isize(); i++) { Plugin *plugin = pStack->at(i); - if (plugin->getStatus() != 1 || plugin->isSuspended() || plugin->isBypassed()) + if (plugin->isSuspended() || plugin->isBypassed()) continue; if (ch) { // ch might be null if stackType is MASTER_IN/OUT pthread_mutex_lock(&mutex_midi); - plugin->processBlock(audioBuffer, ch->getPluginMidiEvents()); + plugin->process(audioBuffer, ch->getPluginMidiEvents()); ch->clearMidiBuffer(); pthread_mutex_unlock(&mutex_midi); } else { juce::MidiBuffer midiBuffer; // empty buffer - plugin->processBlock(audioBuffer, midiBuffer); + plugin->process(audioBuffer, midiBuffer); } } @@ -395,17 +380,13 @@ void PluginHost::swapPlugin(unsigned indexA, unsigned indexB, int stackType, pthread_mutex_t *mutex, Channel *ch) { vector *pStack = getStack(stackType, ch); - int lockStatus; while (true) { - lockStatus = pthread_mutex_trylock(mutex); - if (lockStatus == 0) { - 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; - } - //else - //gu_log("[pluginHost] waiting for mutex...\n"); + 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; } } @@ -413,35 +394,26 @@ void PluginHost::swapPlugin(unsigned indexA, unsigned indexB, int stackType, /* -------------------------------------------------------------------------- */ -void PluginHost::freePlugin(int id, int stackType, pthread_mutex_t *mutex, +int PluginHost::freePlugin(int id, int stackType, pthread_mutex_t *mutex, Channel *ch) { vector *pStack = getStack(stackType, ch); - for (unsigned i=0; isize(); i++) { Plugin *pPlugin = pStack->at(i); if (pPlugin->getId() != id) continue; - if (pPlugin->getStatus() == 0) { // no frills if plugin is missing - delete pPlugin; - pStack->erase(pStack->begin() + i); - gu_log("[pluginHost::freePlugin] plugin id=%d removed with no frills, since it had status=0\n", id); - return; - } - while (true) { if (pthread_mutex_trylock(mutex) != 0) continue; - pPlugin->suspendProcessing(true); - pPlugin->releaseResources(); delete pPlugin; pStack->erase(pStack->begin() + i); pthread_mutex_unlock(mutex); gu_log("[pluginHost::freePlugin] plugin id=%d removed\n", id); - return; + return i; } } gu_log("[pluginHost::freePlugin] plugin id=%d not found\n", id); + return -1; } @@ -475,15 +447,15 @@ void PluginHost::freeAllStacks(vector *channels, pthread_mutex_t *mut int PluginHost::clonePlugin(Plugin *src, int stackType, pthread_mutex_t *mutex, Channel *ch) { - juce::PluginDescription pd = src->getPluginDescription(); - Plugin *p = addPlugin(pd.fileOrIdentifier.toStdString(), stackType, mutex, 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; } - for (int k=0; kgetNumParameters(); k++) { + + for (int k=0; kgetNumParameters(); k++) p->setParameter(k, src->getParameter(k)); - } + return 1; } diff --git a/src/core/pluginHost.h b/src/core/pluginHost.h index c1f0a51..2ddc7a5 100644 --- a/src/core/pluginHost.h +++ b/src/core/pluginHost.h @@ -33,7 +33,7 @@ #include -#include "../deps/juce/config.h" +#include "../deps/juce-config.h" using std::string; @@ -186,19 +186,19 @@ public: void swapPlugin(unsigned indexA, unsigned indexB, int stackType, pthread_mutex_t *mutex, class Channel *ch=NULL); - /* freePlugin */ + /* freePlugin. + Returns the internal stack index of the deleted plugin. */ - void freePlugin(int id, int stackType, pthread_mutex_t *mutex, + int freePlugin(int id, int stackType, pthread_mutex_t *mutex, class Channel *ch=NULL); - /* runDispatchLoop - * Wake up plugins' GUI manager for N milliseconds. */ + * Wakes up plugins' GUI manager for N milliseconds. */ void runDispatchLoop(); /* freeAllStacks - * Free everything. */ + * Frees everything. */ void freeAllStacks(vector *channels, pthread_mutex_t *mutex); diff --git a/src/core/recorder.cpp b/src/core/recorder.cpp index 57958c7..992a98e 100644 --- a/src/core/recorder.cpp +++ b/src/core/recorder.cpp @@ -29,23 +29,12 @@ #include #include "../utils/log.h" -#include "../utils/fs.h" -#include "const.h" #include "mixer.h" -#include "mixerHandler.h" -#include "kernelAudio.h" -#include "kernelMidi.h" #include "patch_DEPR_.h" -#include "conf.h" -#include "channel.h" #include "sampleChannel.h" #include "recorder.h" -extern KernelAudio G_KernelAudio; -extern Mixer G_Mixer; - - Recorder::Recorder() : active (false), sortedActions(false) @@ -66,7 +55,7 @@ void Recorder::init() /* -------------------------------------------------------------------------- */ -bool Recorder::canRec(Channel *ch) +bool Recorder::canRec(Channel *ch, Mixer *mixer) { /* NO recording if: * recorder is inactive @@ -74,9 +63,9 @@ bool Recorder::canRec(Channel *ch) * mixer is recording a take somewhere * channel is empty */ - if (!active || - !G_Mixer.running || - G_Mixer.recording || + if (!active || + !mixer->running || + mixer->recording || (ch->type == CHANNEL_SAMPLE && ((SampleChannel*)ch)->wave == NULL) ) return false; @@ -142,11 +131,6 @@ void Recorder::rec(int index, int type, int frame, uint32_t iValue, float fValue global.at(frameToExpand).push_back(a); // expand array } - /* don't activate the channel (readActions == false), it's up to - * the other layers */ - - G_Mixer.getChannelByIndex(index)->hasActions = true; - sortedActions = false; gu_log("[REC] action recorded, type=%d frame=%d chan=%d iValue=%d (0x%X) fValue=%f\n", @@ -175,9 +159,6 @@ void Recorder::clearChan(int index) j++; } } - - Channel *ch = G_Mixer.getChannelByIndex(index); - ch->hasActions = false; optimize(); //print(); } @@ -203,10 +184,7 @@ void Recorder::clearAction(int index, char act) j++; } } - Channel *ch = G_Mixer.getChannelByIndex(index); - ch->hasActions = false; /// FIXME - why this? Isn't it useless if we call setChanHasActionsStatus? optimize(); - setChanHasActionsStatus(index); /// FIXME //print(); } @@ -215,7 +193,7 @@ void Recorder::clearAction(int index, char act) void Recorder::deleteAction(int chan, int frame, char type, bool checkValues, - uint32_t iValue, float fValue) + pthread_mutex_t *mixerMutex, uint32_t iValue, float fValue) { /* make sure frame is even */ @@ -226,41 +204,39 @@ void Recorder::deleteAction(int chan, int frame, char type, bool checkValues, bool found = false; for (unsigned i=0; ichan == chan && a->type == (type & a->type)); - if (checkValues) - doit &= (a->iValue == iValue && a->fValue == fValue); - - if (doit) { - // TODO - wft? just do: while (true); if (pthread_mutex_trylock(&G_Mixer.mutex_recs)) - int lockStatus = 0; - while (lockStatus == 0) { - lockStatus = pthread_mutex_trylock(&G_Mixer.mutex_recs); - if (lockStatus == 0) { - free(a); - global.at(i).erase(global.at(i).begin() + j); - pthread_mutex_unlock(&G_Mixer.mutex_recs); - found = true; - break; - } - else - gu_log("[REC] delete action: waiting for mutex...\n"); - } - } - } + for (unsigned j=0; jchan == chan && a->type == (type & a->type)); + if (checkValues) + doit &= (a->iValue == iValue && a->fValue == fValue); + + if (!doit) + continue; + + while (true) { + if (pthread_mutex_trylock(mixerMutex)) { + free(a); + global.at(i).erase(global.at(i).begin() + j); + pthread_mutex_unlock(mixerMutex); + found = true; + break; + } + else + gu_log("[REC] delete action: waiting for mutex...\n"); + } } } if (found) { optimize(); - setChanHasActionsStatus(chan); gu_log("[REC] action deleted, type=%d frame=%d chan=%d iValue=%d (%X) fValue=%f\n", type, frame, chan, iValue, iValue, fValue); } @@ -273,7 +249,8 @@ void Recorder::deleteAction(int chan, int frame, char type, bool checkValues, /* -------------------------------------------------------------------------- */ -void Recorder::deleteActions(int chan, int frame_a, int frame_b, char type) +void Recorder::deleteActions(int chan, int frame_a, int frame_b, char type, + pthread_mutex_t *mixerMutex) { sortActions(); vector dels; @@ -283,7 +260,7 @@ void Recorder::deleteActions(int chan, int frame_a, int frame_b, char type) dels.push_back(frames.at(i)); for (unsigned i=0; ihasActions = false; - if (G_Mixer.channels.at(i)->type == CHANNEL_SAMPLE) - ((SampleChannel*)G_Mixer.channels.at(i))->readActions = false; - } - global.clear(); frames.clear(); } @@ -494,22 +464,17 @@ void Recorder::shrink(int new_fpb) /* -------------------------------------------------------------------------- */ -void Recorder::setChanHasActionsStatus(int index) +bool Recorder::hasActions(int chanIndex) { - Channel *ch = G_Mixer.getChannelByIndex(index); - if (global.size() == 0) { - ch->hasActions = false; - return; - } + if (global.size() == 0) + return false; for (unsigned i=0; ichan == index) { - ch->hasActions = true; - return; - } + if (global.at(i).at(j)->chan == chanIndex) + return true; } } - ch->hasActions = false; + return false; } @@ -564,7 +529,8 @@ int Recorder::getAction(int chan, char action, int frame, struct action **out) /* -------------------------------------------------------------------------- */ -void Recorder::startOverdub(int index, char actionMask, int frame) +void Recorder::startOverdub(int index, char actionMask, int frame, + unsigned bufferSize) { /* prepare the composite struct */ @@ -590,25 +556,22 @@ void Recorder::startOverdub(int index, char actionMask, int frame) int res = getNextAction(index, cmp.a1.type | cmp.a2.type, cmp.a1.frame, &act); if (res == 1) { if (act->type == cmp.a2.type) { - int truncFrame = cmp.a1.frame - G_KernelAudio.realBufsize; + int truncFrame = cmp.a1.frame - bufferSize; if (truncFrame < 0) truncFrame = 0; gu_log("[REC] add truncation at frame %d, type=%d\n", truncFrame, cmp.a2.type); rec(index, cmp.a2.type, truncFrame); } } - - SampleChannel *ch = (SampleChannel*) G_Mixer.getChannelByIndex(index); - ch->readActions = false; // don't use disableRead() } /* -------------------------------------------------------------------------- */ -void Recorder::stopOverdub(int frame) +void Recorder::stopOverdub(Mixer *mixer) { - cmp.a2.frame = frame; + cmp.a2.frame = mixer->currentFrame; bool ringLoop = false; bool nullLoop = false; @@ -618,23 +581,20 @@ void Recorder::stopOverdub(int frame) if (cmp.a2.frame < cmp.a1.frame) { ringLoop = true; gu_log("[REC] ring loop! frame1=%d < frame2=%d\n", cmp.a1.frame, cmp.a2.frame); - rec(cmp.a2.chan, cmp.a2.type, G_Mixer.totalFrames); // record at the end of the sequencer + rec(cmp.a2.chan, cmp.a2.type, mixer->totalFrames); // record at the end of the sequencer } else if (cmp.a2.frame == cmp.a1.frame) { nullLoop = true; gu_log("[REC] null loop! frame1=%d == frame2=%d\n", cmp.a1.frame, cmp.a2.frame); - deleteAction(cmp.a1.chan, cmp.a1.frame, cmp.a1.type, false); // false == don't check values + deleteAction(cmp.a1.chan, cmp.a1.frame, cmp.a1.type, false, &mixer->mutex_recs); // false == don't check values } - SampleChannel *ch = (SampleChannel*) G_Mixer.getChannelByIndex(cmp.a2.chan); - ch->readActions = false; // don't use disableRead() - /* remove any nested action between keypress----keyrel, then record */ if (!nullLoop) { - deleteActions(cmp.a2.chan, cmp.a1.frame, cmp.a2.frame, cmp.a1.type); - deleteActions(cmp.a2.chan, cmp.a1.frame, cmp.a2.frame, cmp.a2.type); + deleteActions(cmp.a2.chan, cmp.a1.frame, cmp.a2.frame, cmp.a1.type, &mixer->mutex_recs); + deleteActions(cmp.a2.chan, cmp.a1.frame, cmp.a2.frame, cmp.a2.type, &mixer->mutex_recs); } if (!ringLoop && !nullLoop) { @@ -645,11 +605,9 @@ void Recorder::stopOverdub(int frame) action *act = NULL; int res = getNextAction(cmp.a2.chan, cmp.a1.type | cmp.a2.type, cmp.a2.frame, &act); - if (res == 1) { - if (act->type == cmp.a2.type) { - gu_log("[REC] add truncation at frame %d, type=%d\n", act->frame, act->type); - deleteAction(act->chan, act->frame, act->type, false); // false == don't check values - } + if (res == 1 && act->type == cmp.a2.type) { + gu_log("[REC] add truncation at frame %d, type=%d\n", act->frame, act->type); + deleteAction(act->chan, act->frame, act->type, false, &mixer->mutex_recs); // false == don't check values } } } @@ -664,7 +622,8 @@ void Recorder::print() for (unsigned i=0; itype, global.at(i).at(j)->chan, global.at(i).at(j)->frame); + gu_log(" action %d | chan %d | frame %d\n", global.at(i).at(j)->type, + global.at(i).at(j)->chan, global.at(i).at(j)->frame); } } } diff --git a/src/core/recorder.h b/src/core/recorder.h index 307b408..a4f0210 100644 --- a/src/core/recorder.h +++ b/src/core/recorder.h @@ -37,6 +37,7 @@ #include #endif #include +#include using std::vector; @@ -79,16 +80,16 @@ public: void init(); - /* setChanHasActionsStatus - * Check if the channel has at least one action recorded. If false, sets - * ch->hasActions = false. Used after an action deletion. */ + /* hasActions + Checks if the channel has at least one action recorded. Used after an + action deletion. */ - void setChanHasActionsStatus(int chan); + bool hasActions(int chanIndex); /* canRec * can a channel rec an action? Call this one BEFORE rec(). */ - bool canRec(class Channel *ch); + bool canRec(class Channel *ch, class Mixer *m); /* rec * record an action. */ @@ -110,13 +111,14 @@ public: * delete ONE action. Useful in the action editor. 'type' can be a mask. */ void deleteAction(int chan, int frame, char type, bool checkValues, - uint32_t iValue=0, float fValue=0.0); + pthread_mutex_t *mixerMutex, uint32_t iValue=0, float fValue=0.0); /* deleteActions * delete A RANGE of actions from frame_a to frame_b in channel 'chan'. * 'type' can be a bitmask. Exclusive range (frame_a, frame_b). */ - void deleteActions(int chan, int frame_a, int frame_b, char type); + void deleteActions(int chan, int frame_a, int frame_b, char type, + pthread_mutex_t *mixerMutex); /* clearAll * delete everything. */ @@ -164,8 +166,8 @@ public: /* start/endOverdub */ - void startOverdub(int chan, char action, int frame); - void stopOverdub(int frame); + void startOverdub(int chan, char action, int frame, unsigned bufferSize); + void stopOverdub(class Mixer *m); private: diff --git a/src/core/sampleChannel.cpp b/src/core/sampleChannel.cpp index 4489801..650d36f 100644 --- a/src/core/sampleChannel.cpp +++ b/src/core/sampleChannel.cpp @@ -34,6 +34,7 @@ #include "patch_DEPR_.h" #include "patch.h" #include "conf.h" +#include "mixer.h" #include "wave.h" #include "pluginHost.h" #include "waveFx.h" @@ -56,7 +57,7 @@ SampleChannel::SampleChannel(int bufferSize, MidiMapConf *midiMapConf) tracker (0), begin (0), end (0), - pitch (gDEFAULT_PITCH), + pitch (G_DEFAULT_PITCH), boost (1.0f), mode (DEFAULT_CHANMODE), qWait (false), @@ -66,7 +67,6 @@ SampleChannel::SampleChannel(int bufferSize, MidiMapConf *midiMapConf) fadeoutVol (1.0f), fadeoutTracker (0), fadeoutStep (DEFAULT_FADEOUT_STEP), - readActions (false), midiInReadActions(0x0), midiInPitch (0x0) { @@ -477,7 +477,7 @@ void SampleChannel::onZero(int frame, bool recsStopOnChanHalt) /* -------------------------------------------------------------------------- */ -void SampleChannel::quantize(int index, int localFrame, int globalFrame) +void SampleChannel::quantize(int index, int localFrame, Mixer *mixer) { /* skip if LOOP_ANY or not in quantizer-wait mode */ @@ -500,11 +500,15 @@ void SampleChannel::quantize(int index, int localFrame, int globalFrame) /* this is the moment in which we record the keypress, if the * quantizer is on. SINGLE_PRESS needs overdub */ - if (G_Recorder.canRec(this)) { - if (mode == SINGLE_PRESS) - G_Recorder.startOverdub(index, ACTION_KEYS, globalFrame); + if (G_Recorder.canRec(this, mixer)) { + if (mode == SINGLE_PRESS) { + G_Recorder.startOverdub(index, ACTION_KEYS, mixer->currentFrame, + G_KernelAudio.realBufsize); + readActions = false; // don't read actions while overdubbing + } else - G_Recorder.rec(index, ACTION_KEYPRESS, globalFrame); + G_Recorder.rec(index, ACTION_KEYPRESS, mixer->currentFrame); + hasActions = true; } } diff --git a/src/core/sampleChannel.h b/src/core/sampleChannel.h index 751b999..2eeb574 100644 --- a/src/core/sampleChannel.h +++ b/src/core/sampleChannel.h @@ -106,7 +106,7 @@ public: int readPatch(const string &basePath, int i, class Patch *patch, pthread_mutex_t *pluginMutex, int samplerate, int rsmpQuality) override; int writePatch(int i, bool isProject, class Patch *patch) override; - void quantize(int index, int localFrame, int globalFrame) override; + void quantize(int index, int localFrame, class Mixer *m) override; void onZero(int frame, bool recsStopOnChanHalt) override; void onBar(int frame) override; void parseAction(Recorder::action *a, int localFrame, int globalFrame, @@ -193,10 +193,6 @@ public: int fadeoutType; // xfade or fadeout int fadeoutEnd; // what to do when fadeout ends - /* recorder:: stuff */ - - bool readActions; // read actions or not - /* midi stuff */ uint32_t midiInReadActions; diff --git a/src/deps/juce-config.h b/src/deps/juce-config.h new file mode 100644 index 0000000..ea20a6c --- /dev/null +++ b/src/deps/juce-config.h @@ -0,0 +1,21 @@ +#ifndef __JUCE_APPCONFIG_H__ +#define __JUCE_APPCONFIG_H__ + + +#ifdef _WIN32 + #include + #include +#endif + + +#include "juce/modules/juce_audio_basics/juce_audio_basics.h" +#include "juce/modules/juce_audio_processors/juce_audio_processors.h" +#include "juce/modules/juce_core/juce_core.h" +#include "juce/modules/juce_data_structures/juce_data_structures.h" +#include "juce/modules/juce_events/juce_events.h" +#include "juce/modules/juce_graphics/juce_graphics.h" +#include "juce/modules/juce_gui_basics/juce_gui_basics.h" +#include "juce/modules/juce_gui_extra/juce_gui_extra.h" + + +#endif diff --git a/src/glue/channel.cpp b/src/glue/channel.cpp index c1fa9ba..0af1044 100644 --- a/src/glue/channel.cpp +++ b/src/glue/channel.cpp @@ -30,10 +30,11 @@ #include "../gui/dialogs/gd_mainWindow.h" #include "../gui/dialogs/gd_editor.h" -#include "../gui/elems/ge_keyboard.h" #include "../gui/elems/ge_waveTools.h" #include "../gui/elems/ge_waveform.h" -#include "../gui/elems/channel.h" +#include "../gui/elems/ge_mixed.h" +#include "../gui/elems/mainWindow/keyboard/keyboard.h" +#include "../gui/elems/mainWindow/keyboard/channel.h" #include "../utils/gui.h" #include "../core/mixerHandler.h" #include "../core/mixer.h" @@ -43,16 +44,18 @@ #include "../core/channel.h" #include "../core/sampleChannel.h" #include "../core/midiChannel.h" +#include "../core/plugin.h" #include "main.h" #include "channel.h" extern gdMainWindow *G_MainWin; extern Conf G_Conf; +extern KernelAudio G_KernelAudio; extern Recorder G_Recorder; extern Mixer G_Mixer; #ifdef WITH_VST -extern PluginHost G_PluginHost; +extern PluginHost G_PluginHost; #endif @@ -101,6 +104,7 @@ Channel *glue_addChannel(int column, int type) void glue_deleteChannel(Channel *ch) { G_Recorder.clearChan(ch->index); + ch->hasActions = false; #ifdef WITH_VST G_PluginHost.freeStack(PluginHost::CHANNEL, &G_Mixer.mutex_plugins, ch); #endif @@ -125,6 +129,7 @@ void glue_freeChannel(Channel *ch) #endif G_MainWin->keyboard->freeChannel(ch->guiChannel); G_Recorder.clearChan(ch->index); + ch->hasActions = false; ch->empty(); } @@ -243,11 +248,14 @@ void glue_setPanning(gdEditor *win, SampleChannel *ch, float val) void glue_setMute(Channel *ch, bool gui) { - if (G_Recorder.active && G_Recorder.canRec(ch)) { - if (!ch->mute) - G_Recorder.startOverdub(ch->index, ACTION_MUTES, G_Mixer.actualFrame); + if (G_Recorder.active && G_Recorder.canRec(ch, &G_Mixer)) { + if (!ch->mute) { + G_Recorder.startOverdub(ch->index, ACTION_MUTES, G_Mixer.currentFrame, + G_KernelAudio.realBufsize); + ch->readActions = false; // don't read actions while overdubbing + } else - G_Recorder.stopOverdub(G_Mixer.actualFrame); + G_Recorder.stopOverdub(&G_Mixer); } ch->mute ? ch->unsetMute(false) : ch->setMute(false); @@ -434,8 +442,7 @@ void glue_setBoost(gdEditor *win, SampleChannel *ch, float val, bool numeric) /* -------------------------------------------------------------------------- */ -void glue_setVolEditor(class gdEditor *win, SampleChannel *ch, float val, - bool numeric) +void glue_setVolEditor(gdEditor *win, SampleChannel *ch, float val, bool numeric) { if (numeric) { if (val > 0.0f) diff --git a/src/glue/channel.h b/src/glue/channel.h index 25523e0..3534add 100644 --- a/src/glue/channel.h +++ b/src/glue/channel.h @@ -94,4 +94,5 @@ void glue_setBoost(class gdEditor *win, class SampleChannel *ch, float val, void glue_setVolEditor(class gdEditor *win, class SampleChannel *ch, float val, bool numeric); + #endif diff --git a/src/glue/io.cpp b/src/glue/io.cpp index bdc932e..4dc9acf 100644 --- a/src/glue/io.cpp +++ b/src/glue/io.cpp @@ -35,9 +35,11 @@ #include #include "../gui/dialogs/gd_mainWindow.h" #include "../gui/dialogs/gd_warnings.h" -#include "../gui/elems/ge_keyboard.h" -#include "../gui/elems/channel.h" -#include "../gui/elems/sampleChannel.h" +#include "../gui/elems/mainWindow/mainTransport.h" +#include "../gui/elems/mainWindow/mainTimer.h" +#include "../gui/elems/mainWindow/keyboard/keyboard.h" +#include "../gui/elems/mainWindow/keyboard/channel.h" +#include "../gui/elems/mainWindow/keyboard/sampleChannel.h" #include "../utils/gui.h" #include "../utils/log.h" #include "../core/recorder.h" @@ -53,6 +55,7 @@ extern Recorder G_Recorder; +extern KernelAudio G_KernelAudio; extern bool G_audio_status; extern Mixer G_Mixer; extern gdMainWindow *G_MainWin; @@ -117,8 +120,10 @@ void glue_keyPress(SampleChannel *ch, bool ctrl, bool shift) if (G_Recorder.active) { if (G_Mixer.running) { ch->kill(0); // on frame 0: user-generated event - if (G_Recorder.canRec(ch) && !(ch->mode & LOOP_ANY)) // don't record killChan actions for LOOP channels - G_Recorder.rec(ch->index, ACTION_KILLCHAN, G_Mixer.actualFrame); + if (G_Recorder.canRec(ch, &G_Mixer) && !(ch->mode & LOOP_ANY)) { // don't record killChan actions for LOOP channels + G_Recorder.rec(ch->index, ACTION_KILLCHAN, G_Mixer.currentFrame); + ch->hasActions = true; + } } } else { @@ -138,14 +143,18 @@ void glue_keyPress(SampleChannel *ch, bool ctrl, bool shift) * when a quantoWait has passed. Moreover, KEYPRESS and KEYREL are * meaningless for loop modes */ - if (G_Mixer.quantize == 0 && - G_Recorder.canRec(ch) && + if (G_Mixer.quantize == 0 && + G_Recorder.canRec(ch, &G_Mixer) && !(ch->mode & LOOP_ANY)) { - if (ch->mode == SINGLE_PRESS) - G_Recorder.startOverdub(ch->index, ACTION_KEYS, G_Mixer.actualFrame); + if (ch->mode == SINGLE_PRESS) { + G_Recorder.startOverdub(ch->index, ACTION_KEYS, G_Mixer.currentFrame, + G_KernelAudio.realBufsize); + ch->readActions = false; // don't read actions while overdubbing + } else { - G_Recorder.rec(ch->index, ACTION_KEYPRESS, G_Mixer.actualFrame); + G_Recorder.rec(ch->index, ACTION_KEYPRESS, G_Mixer.currentFrame); + ch->hasActions = true; /* Why return here? You record an action (as done on line 148) and then you call ch->start (line 165): Mixer, which is on another thread, reads @@ -182,8 +191,8 @@ void glue_keyRelease(SampleChannel *ch, bool ctrl, bool shift) /* record a key release only if channel is single_press. For any * other mode the KEY REL is meaningless. */ - if (ch->mode == SINGLE_PRESS && G_Recorder.canRec(ch)) - G_Recorder.stopOverdub(G_Mixer.actualFrame); + if (ch->mode == SINGLE_PRESS && G_Recorder.canRec(ch, &G_Mixer)) + G_Recorder.stopOverdub(&G_Mixer); /* the GUI update is done by gui_refresh() */ @@ -214,7 +223,7 @@ void glue_startActionRec(bool gui) if (!gui) { Fl::lock(); - G_MainWin->controller->updateRecAction(1); + G_MainWin->mainTransport->updateRecAction(1); Fl::unlock(); } } @@ -242,7 +251,7 @@ void glue_stopActionRec(bool gui) if (!gui) { Fl::lock(); - G_MainWin->controller->updateRecAction(0); + G_MainWin->mainTransport->updateRecAction(0); Fl::unlock(); } @@ -273,7 +282,7 @@ int glue_startInputRec(bool gui) if (!mh_startInputRec()) { Fl::lock(); - G_MainWin->controller->updateRecInput(0); // set it off, anyway + G_MainWin->mainTransport->updateRecInput(0); // set it off, anyway Fl::unlock(); return false; } @@ -281,11 +290,11 @@ int glue_startInputRec(bool gui) if (!G_Mixer.running) glue_startSeq(false); // update gui anyway - if (!gui) { - Fl::lock(); - G_MainWin->controller->updateRecInput(1); - Fl::unlock(); - } + 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. */ @@ -314,14 +323,14 @@ int glue_stopInputRec(bool gui) continue; SampleChannel *ch = (SampleChannel*) G_Mixer.channels.at(i); if (ch->mode & (LOOP_ANY) && ch->status == STATUS_OFF && ch->armed) - ch->start(G_Mixer.actualFrame, true, G_Mixer.quantize, G_Mixer.running, true, true); + ch->start(G_Mixer.currentFrame, true, G_Mixer.quantize, G_Mixer.running, true, true); } - if (!gui) { - Fl::lock(); - G_MainWin->controller->updateRecInput(0); - Fl::unlock(); - } + Fl::lock(); + if (!gui) + G_MainWin->mainTransport->updateRecInput(0); + G_MainWin->mainTimer->setLock(false); + Fl::unlock(); return 1; } diff --git a/src/glue/main.cpp b/src/glue/main.cpp index 4c3638f..d9033d0 100644 --- a/src/glue/main.cpp +++ b/src/glue/main.cpp @@ -35,10 +35,13 @@ #include #include "../gui/elems/ge_waveform.h" #include "../gui/elems/ge_mixed.h" -#include "../gui/elems/channel.h" -#include "../gui/elems/sampleChannel.h" #include "../gui/elems/ge_waveTools.h" -#include "../gui/elems/ge_keyboard.h" +#include "../gui/elems/mainWindow/mainTransport.h" +#include "../gui/elems/mainWindow/mainIO.h" +#include "../gui/elems/mainWindow/mainTimer.h" +#include "../gui/elems/mainWindow/keyboard/channel.h" +#include "../gui/elems/mainWindow/keyboard/sampleChannel.h" +#include "../gui/elems/mainWindow/keyboard/keyboard.h" #include "../gui/dialogs/gd_mainWindow.h" #include "../gui/dialogs/gd_editor.h" #include "../gui/dialogs/gd_warnings.h" @@ -74,6 +77,11 @@ extern PluginHost G_PluginHost; void glue_setBpm(const char *v1, const char *v2) { + /* Never change this stuff while recording audio */ + + if (G_Mixer.recording) + return; + char buf[6]; float value = atof(v1) + (atof(v2)/10); if (value < 20.0f) { @@ -96,7 +104,7 @@ void glue_setBpm(const char *v1, const char *v2) G_Recorder.updateBpm(old_bpm, value, G_Mixer.quanto); gu_refreshActionEditor(); - G_MainWin->timing->setBpm(buf); + G_MainWin->mainTimer->setBpm(buf); gu_log("[glue] Bpm changed to %s (real=%f)\n", buf, G_Mixer.bpm); } @@ -106,7 +114,12 @@ void glue_setBpm(const char *v1, const char *v2) void glue_setBeats(int beats, int bars, bool expand) { - /* temp vars to store old data (they are necessary) */ + /* Never change this stuff while recording audio */ + + if (G_Mixer.recording) + return; + + /* Temp vars to store old data (they are necessary) */ int oldvalue = G_Mixer.beats; unsigned oldfpb = G_Mixer.totalFrames; @@ -145,7 +158,7 @@ void glue_setBeats(int beats, int bars, bool expand) // G_Recorder.shrink(G_Mixer.totalFrames); } - G_MainWin->timing->setMeter(G_Mixer.beats, G_Mixer.bars); + G_MainWin->mainTimer->setMeter(G_Mixer.beats, G_Mixer.bars); gu_refreshActionEditor(); // in case the action editor is open } @@ -179,7 +192,7 @@ void glue_startSeq(bool gui) if (!gui) { Fl::lock(); - G_MainWin->controller->updatePlay(1); + G_MainWin->mainTransport->updatePlay(1); Fl::unlock(); } } @@ -206,7 +219,7 @@ void glue_stopSeq(bool gui) if (G_Recorder.active) { G_Recorder.active = false; Fl::lock(); - G_MainWin->controller->updateRecAction(0); + G_MainWin->mainTransport->updateRecAction(0); Fl::unlock(); } @@ -216,13 +229,13 @@ void glue_stopSeq(bool gui) if (G_Mixer.recording) { mh_stopInputRec(); Fl::lock(); - G_MainWin->controller->updateRecInput(0); + G_MainWin->mainTransport->updateRecInput(0); Fl::unlock(); } if (!gui) { Fl::lock(); - G_MainWin->controller->updatePlay(0); + G_MainWin->mainTransport->updatePlay(0); Fl::unlock(); } } @@ -321,7 +334,7 @@ void glue_setOutVol(float v, bool gui) G_Mixer.outVol = v; if (!gui) { Fl::lock(); - G_MainWin->inOut->setOutVol(v); + G_MainWin->mainIO->setOutVol(v); Fl::unlock(); } } @@ -335,7 +348,7 @@ void glue_setInVol(float v, bool gui) G_Mixer.inVol = v; if (!gui) { Fl::lock(); - G_MainWin->inOut->setInVol(v); + G_MainWin->mainIO->setInVol(v); Fl::unlock(); } } @@ -398,7 +411,7 @@ void glue_startStopMetronome(bool gui) G_Mixer.metronome = !G_Mixer.metronome; if (!gui) { Fl::lock(); - G_MainWin->controller->updateMetronome(G_Mixer.metronome); + G_MainWin->mainTransport->updateMetronome(G_Mixer.metronome); Fl::unlock(); } } diff --git a/src/glue/plugin.cpp b/src/glue/plugin.cpp new file mode 100644 index 0000000..8c4ee23 --- /dev/null +++ b/src/glue/plugin.cpp @@ -0,0 +1,73 @@ +/* ----------------------------------------------------------------------------- + * + * Giada - Your Hardcore Loopmachine + * + * glue + * Intermediate layer GUI <-> CORE. + * + * ----------------------------------------------------------------------------- + * + * Copyright (C) 2010-2016 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 "../core/pluginHost.h" +#include "../core/mixer.h" +#include "../core/plugin.h" +#include "../core/channel.h" +#include "plugin.h" + + +extern Mixer G_Mixer; +extern PluginHost G_PluginHost; + + +Plugin *glue_addPlugin(Channel *ch, int index, int stackType) +{ + if (index >= G_PluginHost.countAvailablePlugins()) + return nullptr; + + return G_PluginHost.addPlugin(index, stackType, &G_Mixer.mutex_plugins, ch); +} + + +/* -------------------------------------------------------------------------- */ + + +void glue_swapPlugins(Channel *ch, int index1, int index2, int stackType) +{ + G_PluginHost.swapPlugin(index1, index2, stackType, &G_Mixer.mutex_plugins, + ch); +} + + +/* -------------------------------------------------------------------------- */ + + +void glue_freePlugin(Channel *ch, int index, int stackType) +{ + G_PluginHost.freePlugin(index, stackType, &G_Mixer.mutex_plugins, ch); +} + + +#endif diff --git a/src/glue/plugin.h b/src/glue/plugin.h new file mode 100644 index 0000000..02e8278 --- /dev/null +++ b/src/glue/plugin.h @@ -0,0 +1,46 @@ +/* ----------------------------------------------------------------------------- + * + * Giada - Your Hardcore Loopmachine + * + * glue + * Intermediate layer GUI <-> CORE. + * + * ----------------------------------------------------------------------------- + * + * Copyright (C) 2010-2016 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 __GLUE_PLUGIN_H__ +#define __GLUE_PLUGIN_H__ + + +#ifdef WITH_VST + +class Plugin *glue_addPlugin(class Channel *ch, int index, int stackType); + +void glue_swapPlugins(class Channel *ch, int indexP1, int indexP2, int stackType); + +void glue_freePlugin(class Channel *ch, int index, int stackType); + +#endif + + +#endif diff --git a/src/glue/storage.cpp b/src/glue/storage.cpp index 41924d9..997389a 100644 --- a/src/glue/storage.cpp +++ b/src/glue/storage.cpp @@ -28,11 +28,6 @@ * -------------------------------------------------------------------------- */ -#include "../gui/elems/ge_column.h" -#include "../gui/elems/ge_keyboard.h" -#include "../gui/dialogs/gd_mainWindow.h" -#include "../gui/dialogs/gd_warnings.h" -#include "../gui/dialogs/gd_browser.h" #include "../core/mixer.h" #include "../core/mixerHandler.h" #include "../core/channel.h" @@ -46,6 +41,11 @@ #include "../core/wave.h" #include "../utils/gui.h" #include "../utils/log.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/gd_browser.h" #include "main.h" // TODO - remove, used only for DEPR calls #include "channel.h" #include "storage.h" @@ -91,7 +91,7 @@ static void __glue_fillPatchGlobalsPlugins__(vector *host, vectorkeyboard->getTotalColumns(); i++) { - gColumn *gCol = G_MainWin->keyboard->getColumn(i); + geColumn *gCol = G_MainWin->keyboard->getColumn(i); Patch::column_t pCol; pCol.index = gCol->getIndex(); pCol.width = gCol->w(); diff --git a/src/gui/dialogs/gd_about.cpp b/src/gui/dialogs/gd_about.cpp index 5c42d26..e47076d 100644 --- a/src/gui/dialogs/gd_about.cpp +++ b/src/gui/dialogs/gd_about.cpp @@ -33,7 +33,9 @@ #include "../../core/kernelAudio.h" #include "../../core/kernelMidi.h" #include "../../core/graphics.h" -#include "../../deps/juce/config.h" +#ifdef WITH_VST + #include "../../deps/juce-config.h" +#endif #include "../../utils/gui.h" #include "../elems/ge_mixed.h" #include "gd_about.h" diff --git a/src/gui/dialogs/gd_actionEditor.cpp b/src/gui/dialogs/gd_actionEditor.cpp index 9d70506..cf860be 100644 --- a/src/gui/dialogs/gd_actionEditor.cpp +++ b/src/gui/dialogs/gd_actionEditor.cpp @@ -40,6 +40,7 @@ #include "../elems/muteEditor.h" #include "../elems/noteEditor.h" #include "../elems/ge_mixed.h" +#include "../elems/basics/scroll.h" #include "gd_actionEditor.h" @@ -94,7 +95,7 @@ gdActionEditor::gdActionEditor(Channel *chan) /* main scroller: contains all widgets */ - scroller = new gScroll(8, 36, w()-16, h()-44); + scroller = new geScroll(8, 36, w()-16, h()-44); if (chan->type == CHANNEL_SAMPLE) { diff --git a/src/gui/dialogs/gd_actionEditor.h b/src/gui/dialogs/gd_actionEditor.h index 435619d..c7f60f2 100644 --- a/src/gui/dialogs/gd_actionEditor.h +++ b/src/gui/dialogs/gd_actionEditor.h @@ -72,7 +72,7 @@ public: class gGridTool *gridTool; class gClick *zoomIn; class gClick *zoomOut; - class gScroll *scroller; // widget container + class geScroll *scroller; // widget container class geActionEditor *ac; class geMuteEditor *mc; diff --git a/src/gui/dialogs/gd_beatsInput.cpp b/src/gui/dialogs/gd_beatsInput.cpp index e77e839..35ca62e 100644 --- a/src/gui/dialogs/gd_beatsInput.cpp +++ b/src/gui/dialogs/gd_beatsInput.cpp @@ -32,6 +32,7 @@ #include "../../core/conf.h" #include "../../core/const.h" #include "../../glue/main.h" +#include "../elems/ge_mixed.h" #include "gd_beatsInput.h" #include "gd_mainWindow.h" diff --git a/src/gui/dialogs/gd_browser.cpp b/src/gui/dialogs/gd_browser.cpp index 0c45a18..cbb7e46 100644 --- a/src/gui/dialogs/gd_browser.cpp +++ b/src/gui/dialogs/gd_browser.cpp @@ -28,17 +28,11 @@ #include "../../core/graphics.h" -#include "../../core/wave.h" -#include "../../core/channel.h" -#include "../../core/sampleChannel.h" #include "../../core/conf.h" #include "../../core/const.h" -#include "../../glue/main.h" -#include "../../glue/channel.h" -#include "../../glue/storage.h" #include "../../utils/gui.h" -#include "../elems/ge_browser.h" -#include "../elems/channel.h" +#include "../elems/ge_mixed.h" +#include "../elems/browser.h" #include "gd_browser.h" @@ -54,19 +48,22 @@ gdBaseBrowser::gdBaseBrowser(int x, int y, int w, int h, const string &title, { set_non_modal(); - groupTop = new Fl_Group(8, 8, w-16, 20); - where = new gInput(groupTop->x(), groupTop->y(), 152, 20); - updir = new gClick(groupTop->x()+groupTop->w()-20, groupTop->y(), 20, 20, "", updirOff_xpm, updirOn_xpm); + groupTop = new Fl_Group(8, 8, w-16, 40); + hiddenFiles = new gCheck(groupTop->x(), groupTop->y(), 400, 20, "Show hidden files"); + where = new gInput(groupTop->x(), hiddenFiles->y()+hiddenFiles->h(), 152, 20); + updir = new gClick(groupTop->x()+groupTop->w()-20, where->y(), 20, 20, "", updirOff_xpm, updirOn_xpm); groupTop->end(); groupTop->resizable(where); + hiddenFiles->callback(cb_toggleHiddenFiles, (void*) this); + where->readonly(true); where->cursor_color(COLOR_BG_DARK); where->value(path.c_str()); updir->callback(cb_up, (void*) this); - browser = new gBrowser(8, groupTop->y()+groupTop->h()+8, w-16, h-73); + browser = new geBrowser(8, groupTop->y()+groupTop->h()+8, w-16, h-93); browser->loadDir(path); if (path == G_Conf.browserLastPath) browser->preselect(G_Conf.browserPosition, G_Conf.browserLastValue); @@ -113,12 +110,14 @@ gdBaseBrowser::~gdBaseBrowser() void gdBaseBrowser::cb_up (Fl_Widget *v, void *p) { ((gdBaseBrowser*)p)->__cb_up(); } void gdBaseBrowser::cb_close(Fl_Widget *v, void *p) { ((gdBaseBrowser*)p)->__cb_close(); } +void gdBaseBrowser::cb_toggleHiddenFiles(Fl_Widget *v, void *p) { ((gdBaseBrowser*)p)->__cb_toggleHiddenFiles(); } /* -------------------------------------------------------------------------- */ -void gdBaseBrowser::__cb_up() { +void gdBaseBrowser::__cb_up() +{ string dir = browser->getCurrentDir(); dir = dir.substr(0, dir.find_last_of(G_SLASH_STR)); // remove up to the next slash browser->loadDir(dir); @@ -129,7 +128,8 @@ void gdBaseBrowser::__cb_up() { /* -------------------------------------------------------------------------- */ -void gdBaseBrowser::__cb_close() { +void gdBaseBrowser::__cb_close() +{ do_callback(); } @@ -137,6 +137,15 @@ void gdBaseBrowser::__cb_close() { /* -------------------------------------------------------------------------- */ +void gdBaseBrowser::__cb_toggleHiddenFiles() +{ + browser->toggleHiddenFiles(); +} + + +/* -------------------------------------------------------------------------- */ + + void gdBaseBrowser::setStatusBar(float v) { status->value(status->value() + v); @@ -147,6 +156,33 @@ void gdBaseBrowser::setStatusBar(float v) /* -------------------------------------------------------------------------- */ +void gdBaseBrowser::showStatusBar() +{ + status->show(); +} + + +/* -------------------------------------------------------------------------- */ + + +void gdBaseBrowser::hideStatusBar() +{ + status->hide(); +} + + +/* -------------------------------------------------------------------------- */ + + +string gdBaseBrowser::getCurrentPath() +{ + return where->value(); +} + + +/* -------------------------------------------------------------------------- */ + + string gdBaseBrowser::getSelectedItem() { return browser->getSelectedItem(); @@ -166,7 +202,7 @@ gdSaveBrowser::gdSaveBrowser(int x, int y, int w, int h, const string &title, where->size(groupTop->w()-236, 20); - name = new gInput(where->x()+where->w()+8, 8, 200, 20); + name = new gInput(where->x()+where->w()+8, where->y(), 200, 20); name->value(_name.c_str()); groupTop->add(name); @@ -210,6 +246,15 @@ void gdSaveBrowser::__cb_down() /* -------------------------------------------------------------------------- */ +string gdSaveBrowser::getName() +{ + return name->value(); +} + + +/* -------------------------------------------------------------------------- */ + + void gdSaveBrowser::__cb_save() { callback((void*) this); diff --git a/src/gui/dialogs/gd_browser.h b/src/gui/dialogs/gd_browser.h index bf797ec..5606b52 100644 --- a/src/gui/dialogs/gd_browser.h +++ b/src/gui/dialogs/gd_browser.h @@ -31,9 +31,6 @@ #define GD_BROWSER_H -#include -#include -#include "../elems/ge_mixed.h" #include "../elems/ge_window.h" @@ -42,18 +39,21 @@ class gdBaseBrowser : public gWindow protected: class Fl_Group *groupTop; - class gBrowser *browser; + class gCheck *hiddenFiles; + class geBrowser *browser; class gClick *ok; class gClick *cancel; class gInput *where; class gClick *updir; class gProgress *status; - static void cb_up (Fl_Widget *v, void *p); - static void cb_close(Fl_Widget *w, void *p); + static void cb_up (Fl_Widget *v, void *p); + static void cb_close (Fl_Widget *w, void *p); + static void cb_toggleHiddenFiles(Fl_Widget *w, void *p); - inline void __cb_up (); - inline void __cb_close(); + inline void __cb_up (); + inline void __cb_close (); + inline void __cb_toggleHiddenFiles(); /* Callback * Fired when the save/load button is pressed. */ @@ -79,12 +79,13 @@ public: void setStatusBar(float v); - inline gProgress *getStatusBar() { return status; } // TODO - remove with Patch_DEPR_ - inline void showStatusBar() { status->show(); } - inline void hideStatusBar() { status->hide(); } - inline Channel *getChannel() { return channel; } - inline void fireCallback() { callback((void*) this); } - inline string getCurrentPath() { return where->value(); } + gProgress *getStatusBar() { return status; } // TODO - remove with Patch_DEPR_ + void showStatusBar(); + void hideStatusBar(); + string getCurrentPath(); + + Channel *getChannel() { return channel; } + void fireCallback() { callback((void*) this); } }; @@ -109,7 +110,7 @@ public: const string &path, const string &name, void (*callback)(void*), class Channel *ch); - string getName() { return name->value(); } + string getName(); }; diff --git a/src/gui/dialogs/gd_config.cpp b/src/gui/dialogs/gd_config.cpp index 832b75a..10c49ad 100644 --- a/src/gui/dialogs/gd_config.cpp +++ b/src/gui/dialogs/gd_config.cpp @@ -39,6 +39,7 @@ #include "../../utils/log.h" #include "../../utils/string.h" #include "../elems/ge_mixed.h" +#include "../elems/basics/boxtypes.h" #include "gd_config.h" #include "gd_keyGrabber.h" #include "gd_devInfo.h" @@ -954,6 +955,10 @@ gdConfig::gdConfig(int w, int h) : gWindow(w, h, "Configuration") resize(G_Conf.configX, G_Conf.configY, this->w(), this->h()); Fl_Tabs *tabs = new Fl_Tabs(8, 8, w-16, h-44); + tabs->box(G_CUSTOM_BORDER_BOX); + tabs->labelcolor(COLOR_TEXT_0); + tabs->begin(); + tabAudio = new gTabAudio(tabs->x()+10, tabs->y()+20, tabs->w()-20, tabs->h()-40); tabMidi = new gTabMidi(tabs->x()+10, tabs->y()+20, tabs->w()-20, tabs->h()-40); tabBehaviors = new gTabBehaviors(tabs->x()+10, tabs->y()+20, tabs->w()-20, tabs->h()-40); @@ -969,10 +974,6 @@ gdConfig::gdConfig(int w, int h) : gWindow(w, h, "Configuration") end(); - tabs->box(FL_FLAT_BOX); // TODO - G_BOX crashes FLTK 1.3.3 - - tabs->labelcolor(COLOR_TEXT_0); - save->callback(cb_save_config, (void*)this); cancel->callback(cb_cancel, (void*)this); diff --git a/src/gui/dialogs/gd_editor.cpp b/src/gui/dialogs/gd_editor.cpp index af5d55b..881b4ab 100644 --- a/src/gui/dialogs/gd_editor.cpp +++ b/src/gui/dialogs/gd_editor.cpp @@ -35,10 +35,10 @@ #include "../../core/sampleChannel.h" #include "../../core/mixer.h" #include "../../core/wave.h" -#include "../elems/channel.h" #include "../elems/ge_waveform.h" #include "../elems/ge_mixed.h" #include "../elems/ge_waveTools.h" +#include "../elems/mainWindow/keyboard/channel.h" #include "gd_warnings.h" #include "gd_editor.h" @@ -407,7 +407,7 @@ void gdEditor::__cb_reload() ch->load(ch->wave->pathfile.c_str(), G_Conf.samplerate, G_Conf.rsmpQuality); glue_setBoost(this, ch, DEFAULT_BOOST, true); - glue_setPitch(this, ch, gDEFAULT_PITCH, true); + glue_setPitch(this, ch, G_DEFAULT_PITCH, true); glue_setPanning(this, ch, 1.0f); pan->value(1.0f); // glue_setPanning doesn't do it pan->redraw(); // glue_setPanning doesn't do it diff --git a/src/gui/dialogs/gd_keyGrabber.cpp b/src/gui/dialogs/gd_keyGrabber.cpp index 508867b..d76e41f 100644 --- a/src/gui/dialogs/gd_keyGrabber.cpp +++ b/src/gui/dialogs/gd_keyGrabber.cpp @@ -33,10 +33,10 @@ #include "../../core/sampleChannel.h" #include "../../core/midiChannel.h" #include "../../utils/log.h" -#include "../elems/ge_keyboard.h" #include "../elems/ge_mixed.h" -#include "../elems/channel.h" -#include "../elems/channelButton.h" +#include "../elems/mainWindow/keyboard/keyboard.h" +#include "../elems/mainWindow/keyboard/channel.h" +#include "../elems/mainWindow/keyboard/channelButton.h" #include "gd_keyGrabber.h" #include "gd_config.h" #include "gd_mainWindow.h" diff --git a/src/gui/dialogs/gd_mainWindow.cpp b/src/gui/dialogs/gd_mainWindow.cpp index dba5764..0220f7a 100644 --- a/src/gui/dialogs/gd_mainWindow.cpp +++ b/src/gui/dialogs/gd_mainWindow.cpp @@ -27,43 +27,23 @@ * -------------------------------------------------------------------------- */ -#ifdef __linux__ - #include // for mkdir -#endif - - -#include "../../core/graphics.h" -#include "../../core/mixer.h" -#include "../../core/recorder.h" -#include "../../core/mixerHandler.h" -#include "../../core/channel.h" -#include "../../core/sampleChannel.h" +#include +#include "../../core/const.h" #include "../../core/init.h" -#include "../../core/patch_DEPR_.h" -#include "../../core/patch.h" -#include "../../core/conf.h" -#include "../../core/pluginHost.h" -#include "../../glue/main.h" -#include "../../glue/storage.h" -#include "../elems/ge_keyboard.h" +#include "../../utils/gui.h" +#include "../elems/ge_mixed.h" +#include "../elems/basics/boxtypes.h" +#include "../elems/mainWindow/mainIO.h" +#include "../elems/mainWindow/mainMenu.h" +#include "../elems/mainWindow/mainTimer.h" +#include "../elems/mainWindow/mainTransport.h" +#include "../elems/mainWindow/beatMeter.h" +#include "../elems/mainWindow/keyboard/keyboard.h" #include "gd_warnings.h" -#include "gd_bpmInput.h" -#include "gd_beatsInput.h" -#include "gd_midiInput.h" -#include "gd_about.h" -#include "gd_config.h" -#include "gd_browser.h" #include "gd_mainWindow.h" -#include "gd_pluginList.h" -extern Mixer G_Mixer; -extern Patch_DEPR_ G_Patch_DEPR_; -extern Patch G_Patch; -extern Conf G_Conf; extern gdMainWindow *G_MainWin; -extern bool G_quit; -extern bool G_audio_status; gdMainWindow::gdMainWindow(int W, int H, const char *title, int argc, char **argv) @@ -72,30 +52,37 @@ gdMainWindow::gdMainWindow(int W, int H, const char *title, int argc, char **arg Fl::visible_focus(0); Fl::background(25, 25, 25); - Fl::set_boxtype(G_BOX, gDrawBox, 1, 1, 2, 2); // custom box G_BOX + + Fl::set_boxtype(G_CUSTOM_BORDER_BOX, g_customBorderBox, 1, 1, 2, 2); + Fl::set_boxtype(G_CUSTOM_UP_BOX, g_customUpBox, 1, 1, 2, 2); + Fl::set_boxtype(G_CUSTOM_DOWN_BOX, g_customDownBox, 1, 1, 2, 2); + + Fl::set_boxtype(FL_BORDER_BOX, G_CUSTOM_BORDER_BOX); + Fl::set_boxtype(FL_UP_BOX, G_CUSTOM_UP_BOX); + Fl::set_boxtype(FL_DOWN_BOX, G_CUSTOM_DOWN_BOX); size_range(GUI_WIDTH, GUI_HEIGHT); - menu = new gMenu(8, -1); - inOut = new gInOut(412, 8); - controller = new gController(8, 39); - timing = new gTiming(628, 44); - beatMeter = new gBeatMeter(100, 83, 609, 20); - keyboard = new gKeyboard(8, 122, w()-16, 380); + mainMenu = new geMainMenu(8, -1); + mainIO = new geMainIO(412, 8); + mainTransport = new geMainTransport(8, 39); + mainTimer = new geMainTimer(628, 44); + beatMeter = new geBeatMeter(100, 83, 609, 20); + keyboard = new geKeyboard(8, 122, w()-16, 380); /* zone 1 - menus, and I/O tools */ Fl_Group *zone1 = new Fl_Group(8, 8, W-16, 20); - zone1->add(menu); + zone1->add(mainMenu); zone1->resizable(new Fl_Box(300, 8, 80, 20)); - zone1->add(inOut); + zone1->add(mainIO); - /* zone 2 - controller and timing tools */ + /* zone 2 - mainTransport and timing tools */ - Fl_Group *zone2 = new Fl_Group(8, controller->y(), W-16, controller->h()); - zone2->add(controller); - zone2->resizable(new Fl_Box(controller->x()+controller->w()+4, zone2->y(), 80, 20)); - zone2->add(timing); + Fl_Group *zone2 = new Fl_Group(8, mainTransport->y(), W-16, mainTransport->h()); + zone2->add(mainTransport); + zone2->resizable(new Fl_Box(mainTransport->x()+mainTransport->w()+4, zone2->y(), 80, 20)); + zone2->add(mainTimer); /* zone 3 - beat meter */ @@ -135,414 +122,3 @@ void gdMainWindow::__cb_endprogram() hide(); delete this; } - - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - - -gInOut::gInOut(int x, int y) - : Fl_Group(x, y, 396, 20) -{ - begin(); - -#if defined(WITH_VST) - masterFxIn = new gFxButton (x, y, 20, 20, fxOff_xpm, fxOn_xpm); - inVol = new gDial (masterFxIn->x()+masterFxIn->w()+4, y, 20, 20); - inMeter = new gSoundMeter(inVol->x()+inVol->w()+4, y+4, 140, 12); - inToOut = new gClick (inMeter->x()+inMeter->w()+4, y+4, 12, 12, "", inputToOutputOff_xpm, inputToOutputOn_xpm); - outMeter = new gSoundMeter(inToOut->x()+inToOut->w()+4, y+4, 140, 12); - outVol = new gDial (outMeter->x()+outMeter->w()+4, y, 20, 20); - masterFxOut = new gFxButton (outVol->x()+outVol->w()+4, y, 20, 20, fxOff_xpm, fxOn_xpm); -#else - inVol = new gDial (x+62, y, 20, 20); - inMeter = new gSoundMeter(inVol->x()+inVol->w()+4, y+5, 140, 12); - outMeter = new gSoundMeter(inMeter->x()+inMeter->w()+4, y+5, 140, 12); - outVol = new gDial (outMeter->x()+outMeter->w()+4, y, 20, 20); -#endif - - end(); - - resizable(NULL); // don't resize any widget - - outVol->callback(cb_outVol, (void*)this); - outVol->value(G_Mixer.outVol); - inVol->callback(cb_inVol, (void*)this); - inVol->value(G_Mixer.inVol); - -#ifdef WITH_VST - masterFxOut->callback(cb_masterFxOut, (void*)this); - masterFxIn->callback(cb_masterFxIn, (void*)this); - inToOut->callback(cb_inToOut, (void*)this); - inToOut->type(FL_TOGGLE_BUTTON); -#endif -} - - -/* -------------------------------------------------------------------------- */ - - -void gInOut::cb_outVol (Fl_Widget *v, void *p) { ((gInOut*)p)->__cb_outVol(); } -void gInOut::cb_inVol (Fl_Widget *v, void *p) { ((gInOut*)p)->__cb_inVol(); } -#ifdef WITH_VST -void gInOut::cb_masterFxOut(Fl_Widget *v, void *p) { ((gInOut*)p)->__cb_masterFxOut(); } -void gInOut::cb_masterFxIn (Fl_Widget *v, void *p) { ((gInOut*)p)->__cb_masterFxIn(); } -void gInOut::cb_inToOut (Fl_Widget *v, void *p) { ((gInOut*)p)->__cb_inToOut(); } -#endif - - -/* -------------------------------------------------------------------------- */ - - -void gInOut::__cb_outVol() -{ - glue_setOutVol(outVol->value()); -} - - -/* -------------------------------------------------------------------------- */ - - -void gInOut::__cb_inVol() -{ - glue_setInVol(inVol->value()); -} - - -/* -------------------------------------------------------------------------- */ - - -#ifdef WITH_VST -void gInOut::__cb_masterFxOut() -{ - gu_openSubWindow(G_MainWin, new gdPluginList(PluginHost::MASTER_OUT), WID_FX_LIST); -} - -void gInOut::__cb_masterFxIn() -{ - gu_openSubWindow(G_MainWin, new gdPluginList(PluginHost::MASTER_IN), WID_FX_LIST); -} - -void gInOut::__cb_inToOut() -{ - G_Mixer.inToOut = inToOut->value(); -} -#endif - - -/* -------------------------------------------------------------------------- */ - - -void gInOut::refresh() -{ - outMeter->mixerPeak = G_Mixer.peakOut; - inMeter->mixerPeak = G_Mixer.peakIn; - outMeter->redraw(); - inMeter->redraw(); -} - - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - - -gMenu::gMenu(int x, int y) - : Fl_Group(x, y, 300, 20) -{ - begin(); - - file = new gClick(x, y, 70, 21, "file"); - edit = new gClick(file->x()+file->w()+4, y, 70, 21, "edit"); - config = new gClick(edit->x()+edit->w()+4, y, 70, 21, "config"); - about = new gClick(config->x()+config->w()+4, y, 70, 21, "about"); - - end(); - - resizable(NULL); // don't resize any widget - - about->callback(cb_about, (void*)this); - file->callback(cb_file, (void*)this); - edit->callback(cb_edit, (void*)this); - config->callback(cb_config, (void*)this); -} - - -/* -------------------------------------------------------------------------- */ - - -void gMenu::cb_about (Fl_Widget *v, void *p) { ((gMenu*)p)->__cb_about(); } -void gMenu::cb_config(Fl_Widget *v, void *p) { ((gMenu*)p)->__cb_config(); } -void gMenu::cb_file (Fl_Widget *v, void *p) { ((gMenu*)p)->__cb_file(); } -void gMenu::cb_edit (Fl_Widget *v, void *p) { ((gMenu*)p)->__cb_edit(); } - - -/* -------------------------------------------------------------------------- */ - - -void gMenu::__cb_about() -{ - gu_openSubWindow(G_MainWin, new gdAbout(), WID_ABOUT); -} - - -/* -------------------------------------------------------------------------- */ - - -void gMenu::__cb_config() -{ - gu_openSubWindow(G_MainWin, new gdConfig(380, 370), WID_CONFIG); -} - - -/* -------------------------------------------------------------------------- */ - - -void gMenu::__cb_file() -{ - /* An Fl_Menu_Button is made of many Fl_Menu_Item */ - - Fl_Menu_Item menu[] = { - {"Open patch or project..."}, - {"Save patch..."}, - {"Save project..."}, - {"Quit Giada"}, - {0} - }; - - Fl_Menu_Button *b = new Fl_Menu_Button(0, 0, 100, 50); - b->box(G_BOX); - b->textsize(GUI_FONT_SIZE_BASE); - b->textcolor(COLOR_TEXT_0); - b->color(COLOR_BG_0); - - const Fl_Menu_Item *m = menu->popup(Fl::event_x(), Fl::event_y(), 0, 0, b); - if (!m) return; - - - if (strcmp(m->label(), "Open patch or project...") == 0) { - //gWindow *childWin = new gdBrowser("Load Patch", G_Conf.patchPath.c_str(), 0, BROWSER_LOAD_PATCH); - //gu_openSubWindow(G_MainWin, childWin, WID_FILE_BROWSER); - gWindow *childWin = new gdLoadBrowser(G_Conf.browserX, G_Conf.browserY, - G_Conf.browserW, G_Conf.browserH, "Load patch or project", - G_Conf.patchPath, glue_loadPatch, NULL); - gu_openSubWindow(G_MainWin, childWin, WID_FILE_BROWSER); - return; - } - if (strcmp(m->label(), "Save patch...") == 0) { - if (G_Mixer.hasLogicalSamples() || G_Mixer.hasEditedSamples()) - if (!gdConfirmWin("Warning", "You should save a project in order to store\nyour takes and/or processed samples.")) - return; - gWindow *childWin = new gdSaveBrowser(G_Conf.browserX, G_Conf.browserY, - G_Conf.browserW, G_Conf.browserH, "Save patch", - G_Conf.patchPath, G_Patch.name, glue_savePatch, NULL); - gu_openSubWindow(G_MainWin, childWin, WID_FILE_BROWSER); - return; - } - if (strcmp(m->label(), "Save project...") == 0) { - gWindow *childWin = new gdSaveBrowser(G_Conf.browserX, G_Conf.browserY, - G_Conf.browserW, G_Conf.browserH, "Save project", - G_Conf.patchPath, G_Patch.name, glue_saveProject, NULL); - gu_openSubWindow(G_MainWin, childWin, WID_FILE_BROWSER); - return; - } - if (strcmp(m->label(), "Quit Giada") == 0) { - G_MainWin->do_callback(); - return; - } -} - - -/* -------------------------------------------------------------------------- */ - - -void gMenu::__cb_edit() -{ - Fl_Menu_Item menu[] = { - {"Clear all samples"}, - {"Clear all actions"}, - {"Remove empty columns"}, - {"Reset to init state"}, - {"Setup global MIDI input..."}, - {0} - }; - - /* clear all actions disabled if no recs, clear all samples disabled - * if no samples. */ - - menu[1].deactivate(); - - for (unsigned i=0; ihasActions) { - menu[1].activate(); - break; - } - for (unsigned i=0; itype == CHANNEL_SAMPLE) - if (((SampleChannel*)G_Mixer.channels.at(i))->wave != NULL) { - menu[0].activate(); - break; - } - - Fl_Menu_Button *b = new Fl_Menu_Button(0, 0, 100, 50); - b->box(G_BOX); - b->textsize(GUI_FONT_SIZE_BASE); - b->textcolor(COLOR_TEXT_0); - b->color(COLOR_BG_0); - - const Fl_Menu_Item *m = menu->popup(Fl::event_x(), Fl::event_y(), 0, 0, b); - if (!m) return; - - if (strcmp(m->label(), "Clear all samples") == 0) { - if (!gdConfirmWin("Warning", "Clear all samples: are you sure?")) - return; - G_MainWin->delSubWindow(WID_SAMPLE_EDITOR); - glue_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_clearAllRecs(); - return; - } - if (strcmp(m->label(), "Reset to init state") == 0) { - if (!gdConfirmWin("Warning", "Reset to init state: are you sure?")) - return; - gu_closeAllSubwindows(); - glue_resetToInitState(); - return; - } - if (strcmp(m->label(), "Remove empty columns") == 0) { - G_MainWin->keyboard->organizeColumns(); - return; - } - if (strcmp(m->label(), "Setup global MIDI input...") == 0) { - gu_openSubWindow(G_MainWin, new gdMidiInputMaster(), 0); - return; - } -} - - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - - -gTiming::gTiming(int x, int y) - : Fl_Group(x, y, 180, 20) -{ - begin(); - - quantizer = new gChoice(x, y, 40, 20, "", false); - bpm = new gClick (quantizer->x()+quantizer->w()+4, y, 40, 20); - meter = new gClick (bpm->x()+bpm->w()+8, y, 40, 20, "4/1"); - multiplier = new gClick (meter->x()+meter->w()+4, y, 20, 20, "", multiplyOff_xpm, multiplyOn_xpm); - divider = new gClick (multiplier->x()+multiplier->w()+4, y, 20, 20, "", divideOff_xpm, divideOn_xpm); - - end(); - - resizable(NULL); // don't resize any widget - - char buf[6]; snprintf(buf, 6, "%f", G_Mixer.bpm); - bpm->copy_label(buf); - - bpm->callback(cb_bpm, (void*)this); - meter->callback(cb_meter, (void*)this); - multiplier->callback(cb_multiplier, (void*)this); - divider->callback(cb_divider, (void*)this); - - quantizer->add("off", 0, cb_quantizer, (void*)this); - quantizer->add("1b", 0, cb_quantizer, (void*)this); - quantizer->add("2b", 0, cb_quantizer, (void*)this); - quantizer->add("3b", 0, cb_quantizer, (void*)this); - quantizer->add("4b", 0, cb_quantizer, (void*)this); - quantizer->add("6b", 0, cb_quantizer, (void*)this); - quantizer->add("8b", 0, cb_quantizer, (void*)this); - quantizer->value(0); // "off" by default -} - - -/* -------------------------------------------------------------------------- */ - - -void gTiming::cb_bpm (Fl_Widget *v, void *p) { ((gTiming*)p)->__cb_bpm(); } -void gTiming::cb_meter (Fl_Widget *v, void *p) { ((gTiming*)p)->__cb_meter(); } -void gTiming::cb_quantizer (Fl_Widget *v, void *p) { ((gTiming*)p)->__cb_quantizer(); } -void gTiming::cb_multiplier(Fl_Widget *v, void *p) { ((gTiming*)p)->__cb_multiplier(); } -void gTiming::cb_divider (Fl_Widget *v, void *p) { ((gTiming*)p)->__cb_divider(); } - - -/* -------------------------------------------------------------------------- */ - - -void gTiming::__cb_bpm() -{ - gu_openSubWindow(G_MainWin, new gdBpmInput(bpm->label()), WID_BPM); -} - - -/* -------------------------------------------------------------------------- */ - - -void gTiming::__cb_meter() -{ - gu_openSubWindow(G_MainWin, new gdBeatsInput(), WID_BEATS); -} - - -/* -------------------------------------------------------------------------- */ - - -void gTiming::__cb_quantizer() -{ - glue_quantize(quantizer->value()); -} - - -/* -------------------------------------------------------------------------- */ - - -void gTiming::__cb_multiplier() -{ - glue_beatsMultiply(); -} - - -/* -------------------------------------------------------------------------- */ - - -void gTiming::__cb_divider() -{ - glue_beatsDivide(); -} - - -/* -------------------------------------------------------------------------- */ - - -void gTiming::setBpm(const char *v) -{ - bpm->copy_label(v); -} - - -void gTiming::setBpm(float v) -{ - char buf[6]; - sprintf(buf, "%.01f", v); // only 1 decimal place (e.g. 120.0) - bpm->copy_label(buf); -} - - -/* -------------------------------------------------------------------------- */ - - -void gTiming::setMeter(int beats, int bars) -{ - char buf[8]; - sprintf(buf, "%d/%d", beats, bars); - meter->copy_label(buf); -} diff --git a/src/gui/dialogs/gd_mainWindow.h b/src/gui/dialogs/gd_mainWindow.h index a0a0489..6b07917 100644 --- a/src/gui/dialogs/gd_mainWindow.h +++ b/src/gui/dialogs/gd_mainWindow.h @@ -30,145 +30,27 @@ #define GD_MAINWINDOW_H -#include -#include -#include "../elems/ge_mixed.h" #include "../elems/ge_window.h" -#include "../elems/ge_controller.h" - - -/* -------------------------------------------------------------------------- */ class gdMainWindow : public gWindow { private: - static void cb_endprogram (Fl_Widget *v, void *p); + static void cb_endprogram (class Fl_Widget *v, void *p); inline void __cb_endprogram(); public: - class gKeyboard *keyboard; - class gBeatMeter *beatMeter; - class gMenu *menu; - class gInOut *inOut; - class gController *controller; - class gTiming *timing; + class geKeyboard *keyboard; + class geBeatMeter *beatMeter; + class geMainMenu *mainMenu; + class geMainIO *mainIO; + class geMainTimer *mainTimer; + class geMainTransport *mainTransport; gdMainWindow(int w, int h, const char *title, int argc, char **argv); }; -/* -------------------------------------------------------------------------- */ - - -class gInOut : public Fl_Group -{ -private: - - class gSoundMeter *outMeter; - class gSoundMeter *inMeter; - class gDial *outVol; - class gDial *inVol; -#ifdef WITH_VST - class gFxButton *masterFxOut; - class gFxButton *masterFxIn; - class gClick *inToOut; -#endif - - 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); -#endif - - inline void __cb_outVol (); - inline void __cb_inVol (); -#ifdef WITH_VST - inline void __cb_masterFxOut(); - inline void __cb_masterFxIn (); - inline void __cb_inToOut (); -#endif - -public: - - gInOut(int x, int y); - - void refresh(); - - inline void setOutVol(float v) { outVol->value(v); } - inline void setInVol (float v) { inVol->value(v); } -#ifdef WITH_VST - inline void setMasterFxOutFull(bool v) { masterFxOut->full = v; masterFxOut->redraw(); } - inline void setMasterFxInFull(bool v) { masterFxIn->full = v; masterFxIn->redraw(); } -#endif -}; - - -/* -------------------------------------------------------------------------- */ - - -class gMenu : public Fl_Group -{ -private: - - class gClick *file; - class gClick *edit; - class gClick *config; - class gClick *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); - - inline void __cb_about (); - inline void __cb_config(); - inline void __cb_file (); - inline void __cb_edit (); - -public: - - gMenu(int x, int y); -}; - - -/* -------------------------------------------------------------------------- */ - - -class gTiming : public Fl_Group -{ -private: - - class gClick *bpm; - class gClick *meter; - class gChoice *quantizer; - class gClick *multiplier; - class gClick *divider; - - static void cb_bpm (Fl_Widget *v, void *p); - static void cb_meter (Fl_Widget *v, void *p); - static void cb_quantizer (Fl_Widget *v, void *p); - static void cb_multiplier(Fl_Widget *v, void *p); - static void cb_divider (Fl_Widget *v, void *p); - - inline void __cb_bpm(); - inline void __cb_meter(); - inline void __cb_quantizer(); - inline void __cb_multiplier(); - inline void __cb_divider(); - -public: - - gTiming(int x, int y); - - void setBpm(const char *v); - void setBpm(float v); - void setMeter(int beats, int bars); -}; - - #endif diff --git a/src/gui/dialogs/gd_midiInput.cpp b/src/gui/dialogs/gd_midiInput.cpp deleted file mode 100644 index e713416..0000000 --- a/src/gui/dialogs/gd_midiInput.cpp +++ /dev/null @@ -1,196 +0,0 @@ -/* ----------------------------------------------------------------------------- - * - * Giada - Your Hardcore Loopmachine - * - * gd_midiInput - * - * ----------------------------------------------------------------------------- - * - * Copyright (C) 2010-2016 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 "../../utils/gui.h" -#include "../../core/kernelMidi.h" -#include "../../core/conf.h" -#include "../../core/const.h" -#include "../../core/sampleChannel.h" -#include "../../utils/log.h" -#include "../../utils/string.h" -#include "../elems/ge_mixed.h" -#include "../elems/ge_midiIoTools.h" -#include "gd_midiInput.h" - - -extern Conf G_Conf; -extern KernelMidi G_KernelMidi; - - -using std::string; - - -gdMidiInput::gdMidiInput(int w, int h, const char *title) - : gWindow(w, h, title) -{ -} - - -/* -------------------------------------------------------------------------- */ - - -gdMidiInput::~gdMidiInput() -{ - G_KernelMidi.stopMidiLearn(); -} - - -/* -------------------------------------------------------------------------- */ - - -void gdMidiInput::stopMidiLearn(gLearner *learner) -{ - G_KernelMidi.stopMidiLearn(); - learner->updateValue(); -} - - -/* -------------------------------------------------------------------------- */ - - -void gdMidiInput::__cb_learn(uint32_t *param, uint32_t msg, gLearner *l) -{ - *param = msg; - stopMidiLearn(l); - gu_log("[gdMidiGrabber] MIDI learn done - message=0x%X\n", msg); -} - - -/* -------------------------------------------------------------------------- */ - - -void gdMidiInput::cb_learn(uint32_t msg, void *d) -{ - cbData *data = (cbData*) d; - gdMidiInput *window = (gdMidiInput*) data->window; - gLearner *learner = data->learner; - uint32_t *param = learner->param; - window->__cb_learn(param, msg, learner); - free(data); -} - - -/* -------------------------------------------------------------------------- */ - - -void gdMidiInput::cb_close(Fl_Widget *w, void *p) { ((gdMidiInput*)p)->__cb_close(); } - - -/* -------------------------------------------------------------------------- */ - - -void gdMidiInput::__cb_close() -{ - do_callback(); -} - - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - - -gdMidiInputChannel::gdMidiInputChannel(Channel *ch) - : gdMidiInput(300, 230, "MIDI Input Setup"), - ch(ch) -{ - string title = "MIDI Input Setup (channel " + gu_itoa(ch->index+1) + ")"; - label(title.c_str()); - - set_modal(); - - enable = new gCheck(8, 8, 120, 20, "enable MIDI input"); - new gLearner(8, 30, w()-16, "key press", cb_learn, &ch->midiInKeyPress); - new gLearner(8, 54, w()-16, "key release", cb_learn, &ch->midiInKeyRel); - new gLearner(8, 78, w()-16, "key kill", cb_learn, &ch->midiInKill); - new gLearner(8, 102, w()-16, "arm", cb_learn, &ch->midiInArm); - new gLearner(8, 126, w()-16, "mute", cb_learn, &ch->midiInMute); - new gLearner(8, 150, w()-16, "solo", cb_learn, &ch->midiInSolo); - new gLearner(8, 174, w()-16, "volume", cb_learn, &ch->midiInVolume); - int yy = 202; - - if (ch->type == CHANNEL_SAMPLE) { - size(300, 278); - new gLearner(8, 198, w()-16, "pitch", cb_learn, &((SampleChannel*)ch)->midiInPitch); - new gLearner(8, 222, w()-16, "read actions", cb_learn, &((SampleChannel*)ch)->midiInReadActions); - yy = 250; - } - - ok = new gButton(w()-88, yy, 80, 20, "Close"); - ok->callback(cb_close, (void*)this); - - enable->value(ch->midiIn); - enable->callback(cb_enable, (void*)this); - - gu_setFavicon(this); - show(); -} - - -/* -------------------------------------------------------------------------- */ - - -void gdMidiInputChannel::cb_enable(Fl_Widget *w, void *p) { ((gdMidiInputChannel*)p)->__cb_enable(); } - - -/* -------------------------------------------------------------------------- */ - - -void gdMidiInputChannel::__cb_enable() -{ - ch->midiIn = enable->value(); -} - - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - - -gdMidiInputMaster::gdMidiInputMaster() - : gdMidiInput(300, 256, "MIDI Input Setup (global)") -{ - set_modal(); - - new gLearner(8, 8, w()-16, "rewind", &cb_learn, &G_Conf.midiInRewind); - new gLearner(8, 32, w()-16, "play/stop", &cb_learn, &G_Conf.midiInStartStop); - new gLearner(8, 56, w()-16, "action recording", &cb_learn, &G_Conf.midiInActionRec); - new gLearner(8, 80, w()-16, "input recording", &cb_learn, &G_Conf.midiInInputRec); - new gLearner(8, 104, w()-16, "metronome", &cb_learn, &G_Conf.midiInMetronome); - new gLearner(8, 128, w()-16, "input volume", &cb_learn, &G_Conf.midiInVolumeIn); - new gLearner(8, 152, w()-16, "output volume", &cb_learn, &G_Conf.midiInVolumeOut); - new gLearner(8, 176, w()-16, "sequencer ×2", &cb_learn, &G_Conf.midiInBeatDouble); - new gLearner(8, 200, w()-16, "sequencer ÷2", &cb_learn, &G_Conf.midiInBeatHalf); - ok = new gButton(w()-88, 228, 80, 20, "Close"); - - ok->callback(cb_close, (void*)this); - - gu_setFavicon(this); - show(); -} diff --git a/src/gui/dialogs/gd_midiOutput.cpp b/src/gui/dialogs/gd_midiOutput.cpp deleted file mode 100644 index 5b2be1f..0000000 --- a/src/gui/dialogs/gd_midiOutput.cpp +++ /dev/null @@ -1,258 +0,0 @@ -/* ----------------------------------------------------------------------------- - * - * Giada - Your Hardcore Loopmachine - * - * gd_midiOutput - * - * ----------------------------------------------------------------------------- - * - * Copyright (C) 2010-2016 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 "../../core/channel.h" -#include "../../core/sampleChannel.h" -#include "../../core/conf.h" -#include "../../core/midiChannel.h" -#include "../../utils/gui.h" -#include "../../utils/log.h" -#include "../elems/ge_mixed.h" -#include "../elems/channel.h" -#include "../elems/ge_midiIoTools.h" -#include "../elems/ge_keyboard.h" -#include "gd_midiOutput.h" - - -extern Conf G_Conf; -extern KernelMidi G_KernelMidi; - - -gdMidiOutput::gdMidiOutput(int w, int h) - : gWindow(w, h, "Midi Output Setup") -{ -} - - -/* -------------------------------------------------------------------------- */ - - -void gdMidiOutput::stopMidiLearn(gLearner *learner) -{ - G_KernelMidi.stopMidiLearn(); - learner->updateValue(); -} - - -/* -------------------------------------------------------------------------- */ - - -void gdMidiOutput::__cb_learn(uint32_t *param, uint32_t msg, gLearner *l) -{ - *param = msg; - stopMidiLearn(l); - gu_log("[gdMidiGrabber] MIDI learn done - message=0x%X\n", msg); -} - - -/* -------------------------------------------------------------------------- */ - - -void gdMidiOutput::cb_learn(uint32_t msg, void *d) -{ - cbData *data = (cbData*) d; - gdMidiOutput *window = (gdMidiOutput*) data->window; - gLearner *learner = data->learner; - uint32_t *param = learner->param; - window->__cb_learn(param, msg, learner); - free(data); -} - - -/* -------------------------------------------------------------------------- */ - - -void gdMidiOutput::cb_close(Fl_Widget *w, void *p) { ((gdMidiOutput*)p)->__cb_close(); } - - -/* -------------------------------------------------------------------------- */ - - -void gdMidiOutput::__cb_close() -{ - do_callback(); -} - - -/* -------------------------------------------------------------------------- */ - - -void gdMidiOutput::cb_enableLightning(Fl_Widget *w, void *p) -{ - ((gdMidiOutput*)p)->__cb_enableLightning(); -} - - -/* -------------------------------------------------------------------------- */ - - -void gdMidiOutput::__cb_enableLightning() {} - - -/* -------------------------------------------------------------------------- */ - - -void gdMidiOutput::setTitle(int chanNum) -{ - char title[64]; - sprintf(title, "MIDI Output Setup (channel %d)", chanNum); - copy_label(title); -} - - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - - -gdMidiOutputMidiCh::gdMidiOutputMidiCh(MidiChannel *ch) - : gdMidiOutput(300, 168), ch(ch) -{ - setTitle(ch->index+1); - begin(); - - enableOut = new gCheck(x()+8, y()+8, 150, 20, "Enable MIDI output"); - chanListOut = new gChoice(w()-108, y()+8, 100, 20); - - enableLightning = new gCheck(x()+8, chanListOut->y()+chanListOut->h()+8, 120, 20, "Enable MIDI lightning output"); - new gLearner(x()+8, enableLightning->y()+enableLightning->h()+8, w()-16, "playing", cb_learn, &ch->midiOutLplaying); - new gLearner(x()+8, enableLightning->y()+enableLightning->h()+32, w()-16, "mute", cb_learn, &ch->midiOutLmute); - new gLearner(x()+8, enableLightning->y()+enableLightning->h()+56, w()-16, "solo", cb_learn, &ch->midiOutLsolo); - - close = new gButton(w()-88, enableLightning->y()+enableLightning->h()+84, 80, 20, "Close"); - - end(); - - chanListOut->add("Channel 1"); - chanListOut->add("Channel 2"); - chanListOut->add("Channel 3"); - chanListOut->add("Channel 4"); - chanListOut->add("Channel 5"); - chanListOut->add("Channel 6"); - chanListOut->add("Channel 7"); - chanListOut->add("Channel 8"); - chanListOut->add("Channel 9"); - chanListOut->add("Channel 10"); - chanListOut->add("Channel 11"); - chanListOut->add("Channel 12"); - chanListOut->add("Channel 13"); - chanListOut->add("Channel 14"); - chanListOut->add("Channel 15"); - chanListOut->add("Channel 16"); - chanListOut->value(0); - - if (ch->midiOut) - enableOut->value(1); - else - chanListOut->deactivate(); - - if (ch->midiOutL) - enableLightning->value(1); - - chanListOut->value(ch->midiOutChan); - - enableOut->callback(cb_enableChanList, (void*)this); - close->callback(cb_close, (void*)this); - - set_modal(); - gu_setFavicon(this); - show(); -} - - -/* -------------------------------------------------------------------------- */ - - -void gdMidiOutputMidiCh::cb_close (Fl_Widget *w, void *p) { ((gdMidiOutputMidiCh*)p)->__cb_close(); } -void gdMidiOutputMidiCh::cb_enableChanList(Fl_Widget *w, void *p) { ((gdMidiOutputMidiCh*)p)->__cb_enableChanList(); } - - -/* -------------------------------------------------------------------------- */ - - -void gdMidiOutputMidiCh::__cb_enableChanList() -{ - enableOut->value() ? chanListOut->activate() : chanListOut->deactivate(); -} - - -/* -------------------------------------------------------------------------- */ - - -void gdMidiOutputMidiCh::__cb_close() -{ - ch->midiOut = enableOut->value(); - ch->midiOutChan = chanListOut->value(); - ch->midiOutL = enableLightning->value(); - ch->guiChannel->update(); - do_callback(); -} - - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - - -gdMidiOutputSampleCh::gdMidiOutputSampleCh(SampleChannel *ch) - : gdMidiOutput(300, 140), ch(ch) -{ - setTitle(ch->index+1); - - enableLightning = new gCheck(8, 8, 120, 20, "Enable MIDI lightning output"); - new gLearner(8, enableLightning->y()+enableLightning->h()+8, w()-16, "playing", cb_learn, &ch->midiOutLplaying); - new gLearner(8, enableLightning->y()+enableLightning->h()+32, w()-16, "mute", cb_learn, &ch->midiOutLmute); - new gLearner(8, enableLightning->y()+enableLightning->h()+56, w()-16, "solo", cb_learn, &ch->midiOutLsolo); - - close = new gButton(w()-88, enableLightning->y()+enableLightning->h()+84, 80, 20, "Close"); - close->callback(cb_close, (void*)this); - - enableLightning->value(ch->midiOutL); - enableLightning->callback(cb_enableLightning, (void*)this); - - set_modal(); - gu_setFavicon(this); - show(); -} - - -/* -------------------------------------------------------------------------- */ - - -void gdMidiOutputSampleCh::cb_close(Fl_Widget *w, void *p) { ((gdMidiOutputSampleCh*)p)->__cb_close(); } - - -/* -------------------------------------------------------------------------- */ - - -void gdMidiOutputSampleCh::__cb_close() -{ - ch->midiOutL = enableLightning->value(); - do_callback(); -} diff --git a/src/gui/dialogs/gd_pluginChooser.cpp b/src/gui/dialogs/gd_pluginChooser.cpp index d868108..0e20dc1 100644 --- a/src/gui/dialogs/gd_pluginChooser.cpp +++ b/src/gui/dialogs/gd_pluginChooser.cpp @@ -30,9 +30,9 @@ #ifdef WITH_VST +#include "../../glue/plugin.h" #include "../../utils/gui.h" #include "../../core/channel.h" -#include "../../core/mixer.h" #include "../../core/conf.h" #include "../../core/pluginHost.h" #include "../elems/ge_pluginBrowser.h" @@ -41,7 +41,6 @@ extern PluginHost G_PluginHost; -extern Mixer G_Mixer; extern Conf G_Conf; @@ -108,7 +107,8 @@ void gdPluginChooser::cb_sort(Fl_Widget *v, void *p) { ((gdPluginChooser*)p)->_ /* -------------------------------------------------------------------------- */ -void gdPluginChooser::__cb_close() { +void gdPluginChooser::__cb_close() +{ do_callback(); } @@ -116,7 +116,8 @@ void gdPluginChooser::__cb_close() { /* -------------------------------------------------------------------------- */ -void gdPluginChooser::__cb_sort() { +void gdPluginChooser::__cb_sort() +{ G_PluginHost.sortPlugins(sortMethod->value()); browser->refresh(); } @@ -125,12 +126,13 @@ void gdPluginChooser::__cb_sort() { /* -------------------------------------------------------------------------- */ -void gdPluginChooser::__cb_add() { +void gdPluginChooser::__cb_add() +{ int index = browser->value() - 3; // subtract header lines - if (index >= 0 && index < G_PluginHost.countAvailablePlugins()) { - G_PluginHost.addPlugin(index, stackType, &G_Mixer.mutex_plugins, ch); - do_callback(); - } + if (index < 0) + return; + glue_addPlugin(ch, index, stackType); + do_callback(); } #endif // #ifdef WITH_VST diff --git a/src/gui/dialogs/gd_pluginList.cpp b/src/gui/dialogs/gd_pluginList.cpp index 003ca63..65d8e6d 100644 --- a/src/gui/dialogs/gd_pluginList.cpp +++ b/src/gui/dialogs/gd_pluginList.cpp @@ -39,10 +39,13 @@ #include "../../core/plugin.h" #include "../../core/mixer.h" #include "../../core/channel.h" +#include "../../glue/plugin.h" #include "../../utils/log.h" #include "../../utils/string.h" #include "../elems/ge_mixed.h" -#include "../elems/channel.h" +#include "../elems/basics/boxtypes.h" +#include "../elems/mainWindow/mainIO.h" +#include "../elems/mainWindow/keyboard/channel.h" #include "gd_pluginList.h" #include "gd_pluginChooser.h" #include "gd_pluginWindow.h" @@ -71,7 +74,7 @@ gdPluginList::gdPluginList(int stackType, Channel *ch) list->scrollbar.color(COLOR_BG_0); list->scrollbar.selection_color(COLOR_BG_1); list->scrollbar.labelcolor(COLOR_BD_1); - list->scrollbar.slider(G_BOX); + list->scrollbar.slider(G_CUSTOM_BORDER_BOX); list->begin(); refreshList(); @@ -101,7 +104,8 @@ gdPluginList::gdPluginList(int stackType, Channel *ch) /* -------------------------------------------------------------------------- */ -gdPluginList::~gdPluginList() { +gdPluginList::~gdPluginList() +{ G_Conf.pluginListX = x(); G_Conf.pluginListY = y(); } @@ -116,8 +120,8 @@ void gdPluginList::cb_addPlugin(Fl_Widget *v, void *p) { ((gdPluginList*)p)->_ /* -------------------------------------------------------------------------- */ -void gdPluginList::cb_refreshList(Fl_Widget *v, void *p) { - +void gdPluginList::cb_refreshList(Fl_Widget *v, void *p) +{ /* note: this callback is fired by gdBrowser. Close its window first, * by calling the parent (pluginList) and telling it to delete its * subwindow (i.e. gdBrowser). */ @@ -138,8 +142,8 @@ void gdPluginList::cb_refreshList(Fl_Widget *v, void *p) { /* -------------------------------------------------------------------------- */ -void gdPluginList::__cb_addPlugin() { - +void gdPluginList::__cb_addPlugin() +{ /* the usual callback that gWindow adds to each subwindow in this case * is not enough, because when we close the browser the plugin list * must be redrawn. We have a special callback, cb_refreshList, which @@ -156,8 +160,8 @@ void gdPluginList::__cb_addPlugin() { /* -------------------------------------------------------------------------- */ -void gdPluginList::refreshList() { - +void gdPluginList::refreshList() +{ /* delete the previous list */ list->clear(); @@ -198,12 +202,12 @@ void gdPluginList::refreshList() { gdPluginListMaster */ if (stackType == PluginHost::MASTER_OUT) { - G_MainWin->inOut->setMasterFxOutFull( + G_MainWin->mainIO->setMasterFxOutFull( G_PluginHost.countPlugins(stackType, ch) > 0); } else if (stackType == PluginHost::MASTER_IN) { - G_MainWin->inOut->setMasterFxInFull( + G_MainWin->mainIO->setMasterFxInFull( G_PluginHost.countPlugins(stackType, ch) > 0); } else { @@ -230,32 +234,24 @@ gdPlugin::gdPlugin(gdPluginList *gdp, Plugin *p, int X, int Y, int W) remove = new gButton(shiftDown->x()+shiftDown->w()+4, y(), 20, 20, "", fxRemoveOff_xpm, fxRemoveOn_xpm); end(); - if (pPlugin->getStatus() != 1) { // bad state - string l = "* " + pPlugin->getName().toStdString() + " *"; - button->copy_label(l.c_str()); - } - else { - button->copy_label(pPlugin->getName().toStdString().c_str()); - button->callback(cb_openPluginWindow, (void*)this); + button->copy_label(pPlugin->getName().c_str()); + button->callback(cb_openPluginWindow, (void*)this); - program->callback(cb_setProgram, (void*)this); - - for (int i=0; igetNumPrograms(); i++) { - string name = gu_removeFltkChars(pPlugin->getProgramName(i).toStdString()); - program->add(name.c_str()); - } + program->callback(cb_setProgram, (void*)this); - if (program->size() == 0) { - program->add("-- no programs --\0"); - program->deactivate(); - } - else - program->value(pPlugin->getCurrentProgram()); + for (int i=0; igetNumPrograms(); i++) + program->add(gu_removeFltkChars(pPlugin->getProgramName(i)).c_str()); - bypass->callback(cb_setBypass, (void*)this); - bypass->type(FL_TOGGLE_BUTTON); - bypass->value(pPlugin->isBypassed() ? 0 : 1); + if (program->size() == 0) { + program->add("-- no programs --\0"); + program->deactivate(); } + else + program->value(pPlugin->getCurrentProgram()); + + bypass->callback(cb_setBypass, (void*)this); + bypass->type(FL_TOGGLE_BUTTON); + bypass->value(pPlugin->isBypassed() ? 0 : 1); shiftUp->callback(cb_shiftUp, (void*)this); shiftDown->callback(cb_shiftDown, (void*)this); @@ -277,20 +273,20 @@ void gdPlugin::cb_setProgram (Fl_Widget *v, void *p) { ((gdPlugin*)p)->_ /* -------------------------------------------------------------------------- */ -void gdPlugin::__cb_shiftUp() { - +void gdPlugin::__cb_shiftUp() +{ /*nothing to do if there's only one plugin */ if (G_PluginHost.countPlugins(pParent->stackType, pParent->ch) == 1) return; - int pluginIndex = G_PluginHost.getPluginIndex(pPlugin->getId(), pParent->stackType, pParent->ch); + int pluginIndex = G_PluginHost.getPluginIndex(pPlugin->getId(), + pParent->stackType, pParent->ch); if (pluginIndex == 0) // first of the stack, do nothing return; - G_PluginHost.swapPlugin(pluginIndex, pluginIndex - 1, pParent->stackType, - &G_Mixer.mutex_plugins, pParent->ch); + glue_swapPlugins(pParent->ch, pluginIndex, pluginIndex-1, pParent->stackType); pParent->refreshList(); } @@ -298,8 +294,8 @@ void gdPlugin::__cb_shiftUp() { /* -------------------------------------------------------------------------- */ -void gdPlugin::__cb_shiftDown() { - +void gdPlugin::__cb_shiftDown() +{ /*nothing to do if there's only one plugin */ if (G_PluginHost.countPlugins(pParent->stackType, pParent->ch) == 1) @@ -311,8 +307,7 @@ void gdPlugin::__cb_shiftDown() { if (pluginIndex == stackSize-1) // last one in the stack, do nothing return; - G_PluginHost.swapPlugin(pluginIndex, pluginIndex + 1, pParent->stackType, - &G_Mixer.mutex_plugins, pParent->ch); + glue_swapPlugins(pParent->ch, pluginIndex, pluginIndex+1, pParent->stackType); pParent->refreshList(); } @@ -320,14 +315,12 @@ void gdPlugin::__cb_shiftDown() { /* -------------------------------------------------------------------------- */ -void gdPlugin::__cb_removePlugin() { - - /* any subwindow linked to the plugin must be destroyed */ +void gdPlugin::__cb_removePlugin() +{ + /* any subwindow linked to the plugin must be destroyed first */ pParent->delSubWindow(pPlugin->getId()); - G_PluginHost.freePlugin(pPlugin->getId(), pParent->stackType, - &G_Mixer.mutex_plugins, pParent->ch); - + glue_freePlugin(pParent->ch, pPlugin->getId(), pParent->stackType); pParent->refreshList(); } @@ -366,7 +359,8 @@ void gdPlugin::__cb_openPluginWindow() /* -------------------------------------------------------------------------- */ -void gdPlugin::__cb_setBypass() { +void gdPlugin::__cb_setBypass() +{ pPlugin->toggleBypass(); } @@ -374,7 +368,8 @@ void gdPlugin::__cb_setBypass() { /* -------------------------------------------------------------------------- */ -void gdPlugin::__cb_setProgram() { +void gdPlugin::__cb_setProgram() +{ pPlugin->setCurrentProgram(program->value()); } diff --git a/src/gui/dialogs/gd_pluginWindow.cpp b/src/gui/dialogs/gd_pluginWindow.cpp index 0c0be5f..d3b7136 100644 --- a/src/gui/dialogs/gd_pluginWindow.cpp +++ b/src/gui/dialogs/gd_pluginWindow.cpp @@ -34,6 +34,7 @@ #include "../../utils/gui.h" #include "../../core/plugin.h" #include "../elems/ge_mixed.h" +#include "../elems/basics/boxtypes.h" #include "gd_pluginWindow.h" @@ -46,7 +47,7 @@ Parameter::Parameter(int paramIndex, Plugin *p, int X, int Y, int W) begin(); label = new gBox(x(), y(), 60, 20); - label->copy_label(pPlugin->getParameterName(paramIndex).toRawUTF8()); + label->copy_label(pPlugin->getParameterName(paramIndex).c_str()); label->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE); slider = new gSlider(label->x()+label->w()+8, y(), W-200, 20); @@ -55,7 +56,7 @@ Parameter::Parameter(int paramIndex, Plugin *p, int X, int Y, int W) value = new gBox(slider->x()+slider->w()+8, y(), 100, 20); value->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE); - value->box(G_BOX); + value->box(G_CUSTOM_BORDER_BOX); updateValue(); resizable(slider); @@ -86,8 +87,8 @@ void Parameter::__cb_setValue() void Parameter::updateValue() { - string v = pPlugin->getParameterText(paramIndex).toStdString() + " " + - pPlugin->getParameterLabel(paramIndex).toStdString(); + string v = pPlugin->getParameterText(paramIndex) + " " + + pPlugin->getParameterLabel(paramIndex); value->copy_label(v.c_str()); } @@ -113,7 +114,7 @@ gdPluginWindow::gdPluginWindow(Plugin *p) end(); - label(pPlugin->getName().toRawUTF8()); + label(pPlugin->getName().c_str()); size_range(400, (24*1)+12); resizable(list); diff --git a/src/gui/dialogs/gd_pluginWindowGUI.cpp b/src/gui/dialogs/gd_pluginWindowGUI.cpp index e8ba698..7a5c772 100644 --- a/src/gui/dialogs/gd_pluginWindowGUI.cpp +++ b/src/gui/dialogs/gd_pluginWindowGUI.cpp @@ -79,7 +79,7 @@ gdPluginWindowGUI::gdPluginWindowGUI(Plugin *pPlugin) Fl::add_timeout(GUI_PLUGIN_RATE, cb_refresh, (void*) this); - copy_label(pPlugin->getName().toRawUTF8()); + copy_label(pPlugin->getName().c_str()); } diff --git a/src/gui/dialogs/midiIO/midiInputBase.cpp b/src/gui/dialogs/midiIO/midiInputBase.cpp new file mode 100644 index 0000000..256c9d5 --- /dev/null +++ b/src/gui/dialogs/midiIO/midiInputBase.cpp @@ -0,0 +1,103 @@ +/* ----------------------------------------------------------------------------- + * + * Giada - Your Hardcore Loopmachine + * + * midiInputBase + * + * ----------------------------------------------------------------------------- + * + * Copyright (C) 2010-2016 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 "../../../core/kernelMidi.h" +#include "../../../utils/log.h" +#include "../../elems/midiLearner.h" +#include "midiInputBase.h" + + +extern KernelMidi G_KernelMidi; + + +using std::string; + + +gdMidiInputBase::gdMidiInputBase(int x, int y, int w, int h, const char *title) + : gWindow(x, y, w, h, title) +{ +} + + +/* -------------------------------------------------------------------------- */ + + +gdMidiInputBase::~gdMidiInputBase() +{ + G_KernelMidi.stopMidiLearn(); +} + + +/* -------------------------------------------------------------------------- */ + + +void gdMidiInputBase::stopMidiLearn(geMidiLearner *learner) +{ + G_KernelMidi.stopMidiLearn(); + learner->updateValue(); +} + + +/* -------------------------------------------------------------------------- */ + + +void gdMidiInputBase::__cb_learn(uint32_t *param, uint32_t msg, geMidiLearner *l) +{ + *param = msg; + stopMidiLearn(l); + gu_log("[gdMidiGrabber] MIDI learn done - message=0x%X\n", msg); +} + + +/* -------------------------------------------------------------------------- */ + + +void gdMidiInputBase::cb_learn(uint32_t msg, void *d) +{ + geMidiLearner::cbData_t *data = (geMidiLearner::cbData_t *) d; + gdMidiInputBase *window = (gdMidiInputBase*) data->window; + geMidiLearner *learner = data->learner; + uint32_t *param = learner->param; + window->__cb_learn(param, msg, learner); +} + + +/* -------------------------------------------------------------------------- */ + + +void gdMidiInputBase::cb_close(Fl_Widget *w, void *p) { ((gdMidiInputBase*)p)->__cb_close(); } + + +/* -------------------------------------------------------------------------- */ + + +void gdMidiInputBase::__cb_close() +{ + do_callback(); +} diff --git a/src/gui/dialogs/gd_midiInput.h b/src/gui/dialogs/midiIO/midiInputBase.h similarity index 62% rename from src/gui/dialogs/gd_midiInput.h rename to src/gui/dialogs/midiIO/midiInputBase.h index eb236e7..48f213b 100644 --- a/src/gui/dialogs/gd_midiInput.h +++ b/src/gui/dialogs/midiIO/midiInputBase.h @@ -2,7 +2,7 @@ * * Giada - Your Hardcore Loopmachine * - * gd_midiInput + * midiInputBase * * ----------------------------------------------------------------------------- * @@ -27,67 +27,34 @@ * -------------------------------------------------------------------------- */ -#ifndef GD_MIDI_INPUT_H -#define GD_MIDI_INPUT_H +#ifndef GD_MIDI_INPUT_BASE_H +#define GD_MIDI_INPUT_BASE_H -#include "../elems/ge_window.h" +#include "../../elems/ge_window.h" -class gdMidiInput : public gWindow +class gdMidiInputBase : public gWindow { protected: class gClick *ok; - void stopMidiLearn(class gLearner *l); + void stopMidiLearn(class 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, gLearner *l); + inline void __cb_learn(uint32_t *param, uint32_t msg, geMidiLearner *l); static void cb_close (Fl_Widget *w, void *p); inline void __cb_close(); public: - gdMidiInput(int w, int h, const char *title); - ~gdMidiInput(); -}; - - -/* -------------------------------------------------------------------------- */ - - -class gdMidiInputChannel : public gdMidiInput -{ -private: - - class Channel *ch; - - class gCheck *enable; - - //gVector items; for future use, with vst parameters - - static void cb_enable (Fl_Widget *w, void *p); - inline void __cb_enable(); - -public: - - gdMidiInputChannel(class Channel *ch); -}; - - -/* -------------------------------------------------------------------------- */ - - -class gdMidiInputMaster : public gdMidiInput -{ -public: - - gdMidiInputMaster(); + gdMidiInputBase(int x, int y, int w, int h, const char *title); + ~gdMidiInputBase(); }; diff --git a/src/gui/dialogs/midiIO/midiInputChannel.cpp b/src/gui/dialogs/midiIO/midiInputChannel.cpp new file mode 100644 index 0000000..6bb75e3 --- /dev/null +++ b/src/gui/dialogs/midiIO/midiInputChannel.cpp @@ -0,0 +1,172 @@ +/* ----------------------------------------------------------------------------- + * + * Giada - Your Hardcore Loopmachine + * + * midiInputChannel + * + * ----------------------------------------------------------------------------- + * + * Copyright (C) 2010-2016 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 "../../../utils/gui.h" +#include "../../../core/const.h" +#include "../../../core/conf.h" +#include "../../../core/sampleChannel.h" +#ifdef WITH_VST + #include "../../../core/pluginHost.h" + #include "../../../core/plugin.h" +#endif +#include "../../../utils/string.h" +#include "../../elems/ge_mixed.h" +#include "../../elems/midiLearner.h" +#include "../../elems/basics/scroll.h" +#include "midiInputChannel.h" + + +#ifdef WITH_VST +extern PluginHost G_PluginHost; +#endif +extern Conf G_Conf; + + +using std::string; + + +gdMidiInputChannel::gdMidiInputChannel(Channel *ch) + : gdMidiInputBase(G_Conf.midiInputX, G_Conf.midiInputY, G_Conf.midiInputW, + G_Conf.midiInputH, "MIDI Input Setup"), + ch(ch) +{ + string title = "MIDI Input Setup (channel " + gu_itoa(ch->index+1) + ")"; + label(title.c_str()); + size_range(G_DEFAULT_MIDI_INPUT_UI_W, G_DEFAULT_MIDI_INPUT_UI_H); + + enable = new gCheck(8, 8, 120, 20, "enable MIDI input"); + + container = new geScroll(8, enable->y()+enable->h()+4, w()-16, h()-70); + container->begin(); + + addChannelLearners(); +#ifdef WITH_VST + addPluginLearners(); +#endif + + container->end(); + + ok = new gButton(w()-88, container->y()+container->h()+8, 80, 20, "Close"); + ok->callback(cb_close, (void*)this); + + enable->value(ch->midiIn); + enable->callback(cb_enable, (void*)this); + + resizable(container); + + gu_setFavicon(this); + set_modal(); + show(); +} + + +/* -------------------------------------------------------------------------- */ + + +gdMidiInputChannel::~gdMidiInputChannel() +{ + G_Conf.midiInputX = x(); + G_Conf.midiInputY = y(); + G_Conf.midiInputW = w(); + G_Conf.midiInputH = h(); +} + + +/* -------------------------------------------------------------------------- */ + + +void gdMidiInputChannel::addChannelLearners() +{ + Fl_Pack *pack = new Fl_Pack(container->x(), container->y(), LEARNER_WIDTH, 200); + pack->spacing(4); + pack->begin(); + + gBox *header = new gBox(0, 0, LEARNER_WIDTH, 20, "channel"); + header->box(FL_BORDER_BOX); + new geMidiLearner(0, 0, LEARNER_WIDTH, "key press", cb_learn, &ch->midiInKeyPress); + new geMidiLearner(0, 0, LEARNER_WIDTH, "key release", cb_learn, &ch->midiInKeyRel); + new geMidiLearner(0, 0, LEARNER_WIDTH, "key kill", cb_learn, &ch->midiInKill); + new geMidiLearner(0, 0, LEARNER_WIDTH, "arm", cb_learn, &ch->midiInArm); + new geMidiLearner(0, 0, LEARNER_WIDTH, "mute", cb_learn, &ch->midiInMute); + new geMidiLearner(0, 0, LEARNER_WIDTH, "solo", cb_learn, &ch->midiInSolo); + new geMidiLearner(0, 0, LEARNER_WIDTH, "volume", cb_learn, &ch->midiInVolume); + if (ch->type == CHANNEL_SAMPLE) { + new geMidiLearner(0, 0, LEARNER_WIDTH, "pitch", cb_learn, &((SampleChannel*)ch)->midiInPitch); + new geMidiLearner(0, 0, LEARNER_WIDTH, "read actions", cb_learn, &((SampleChannel*)ch)->midiInReadActions); + } + + pack->end(); +} + + +/* -------------------------------------------------------------------------- */ + + +#ifdef WITH_VST + +void gdMidiInputChannel::addPluginLearners() +{ + vector *plugins = G_PluginHost.getStack(PluginHost::CHANNEL, ch); + for (unsigned i=0; isize(); i++) { + + 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); + + gBox *header = new gBox(0, 0, LEARNER_WIDTH, 20, plugin->getName().c_str()); + header->box(FL_BORDER_BOX); + + for (int k=0; kgetNumParameters(); k++) + new geMidiLearner(0, 0, LEARNER_WIDTH, plugin->getParameterName(k).c_str(), + cb_learn, &plugin->midiInParams.at(k)); + + pack->end(); + } +} + +#endif + + +/* -------------------------------------------------------------------------- */ + + +void gdMidiInputChannel::cb_enable(Fl_Widget *w, void *p) { ((gdMidiInputChannel*)p)->__cb_enable(); } + + +/* -------------------------------------------------------------------------- */ + + +void gdMidiInputChannel::__cb_enable() +{ + ch->midiIn = enable->value(); +} diff --git a/src/gui/dialogs/midiIO/midiInputChannel.h b/src/gui/dialogs/midiIO/midiInputChannel.h new file mode 100644 index 0000000..462a158 --- /dev/null +++ b/src/gui/dialogs/midiIO/midiInputChannel.h @@ -0,0 +1,68 @@ +/* ----------------------------------------------------------------------------- + * + * Giada - Your Hardcore Loopmachine + * + * midiInputChannel + * + * ----------------------------------------------------------------------------- + * + * Copyright (C) 2010-2016 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 GD_MIDI_INPUT_CHANNEL_H +#define GD_MIDI_INPUT_CHANNEL_H + + +#include "midiInputBase.h" + + +class gdMidiInputChannel : public gdMidiInputBase +{ +private: + + static const int LEARNER_WIDTH = 284; + + class Channel *ch; + + class geScroll *container; + class gCheck *enable; + + //gVector items; // plugins parameters + + static void cb_enable (Fl_Widget *w, void *p); + inline void __cb_enable(); + + void addChannelLearners(); + +#ifdef WITH_VST + + void addPluginLearners(); + +#endif + +public: + + gdMidiInputChannel(class Channel *ch); + ~gdMidiInputChannel(); +}; + + +#endif diff --git a/src/gui/dialogs/midiIO/midiInputMaster.cpp b/src/gui/dialogs/midiIO/midiInputMaster.cpp new file mode 100644 index 0000000..e7a8def --- /dev/null +++ b/src/gui/dialogs/midiIO/midiInputMaster.cpp @@ -0,0 +1,60 @@ +/* ----------------------------------------------------------------------------- + * + * Giada - Your Hardcore Loopmachine + * + * midiInputMaster + * + * ----------------------------------------------------------------------------- + * + * Copyright (C) 2010-2016 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 "../../../utils/gui.h" +#include "../../../core/conf.h" +#include "../../elems/ge_mixed.h" +#include "../../elems/midiLearner.h" +#include "midiInputMaster.h" + + +extern Conf G_Conf; + + +gdMidiInputMaster::gdMidiInputMaster() + : gdMidiInputBase(0, 0, 300, 256, "MIDI Input Setup (global)") +{ + set_modal(); + + new geMidiLearner(8, 8, w()-16, "rewind", &cb_learn, &G_Conf.midiInRewind); + new geMidiLearner(8, 32, w()-16, "play/stop", &cb_learn, &G_Conf.midiInStartStop); + new geMidiLearner(8, 56, w()-16, "action recording", &cb_learn, &G_Conf.midiInActionRec); + new geMidiLearner(8, 80, w()-16, "input recording", &cb_learn, &G_Conf.midiInInputRec); + new geMidiLearner(8, 104, w()-16, "metronome", &cb_learn, &G_Conf.midiInMetronome); + new geMidiLearner(8, 128, w()-16, "input volume", &cb_learn, &G_Conf.midiInVolumeIn); + new geMidiLearner(8, 152, w()-16, "output volume", &cb_learn, &G_Conf.midiInVolumeOut); + new geMidiLearner(8, 176, w()-16, "sequencer ×2", &cb_learn, &G_Conf.midiInBeatDouble); + new geMidiLearner(8, 200, w()-16, "sequencer ÷2", &cb_learn, &G_Conf.midiInBeatHalf); + ok = new gButton(w()-88, 228, 80, 20, "Close"); + + ok->callback(cb_close, (void*)this); + + gu_setFavicon(this); + show(); +} diff --git a/src/gui/dialogs/midiIO/midiInputMaster.h b/src/gui/dialogs/midiIO/midiInputMaster.h new file mode 100644 index 0000000..55a4cd5 --- /dev/null +++ b/src/gui/dialogs/midiIO/midiInputMaster.h @@ -0,0 +1,45 @@ +/* ----------------------------------------------------------------------------- + * + * Giada - Your Hardcore Loopmachine + * + * midiInputMaster + * + * ----------------------------------------------------------------------------- + * + * Copyright (C) 2010-2016 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 GD_MIDI_INPUT_MASTER_H +#define GD_MIDI_INPUT_MASTER_H + + +#include "midiInputBase.h" + + +class gdMidiInputMaster : public gdMidiInputBase +{ +public: + + gdMidiInputMaster(); +}; + + +#endif diff --git a/src/gui/dialogs/midiIO/midiOutputBase.cpp b/src/gui/dialogs/midiIO/midiOutputBase.cpp new file mode 100644 index 0000000..d8afd77 --- /dev/null +++ b/src/gui/dialogs/midiIO/midiOutputBase.cpp @@ -0,0 +1,116 @@ +/* ----------------------------------------------------------------------------- + * + * Giada - Your Hardcore Loopmachine + * + * gd_midiOutput + * + * ----------------------------------------------------------------------------- + * + * Copyright (C) 2010-2016 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 "../../../utils/log.h" +#include "../../elems/midiLearner.h" +#include "midiOutputBase.h" + + +extern KernelMidi G_KernelMidi; + + +gdMidiOutputBase::gdMidiOutputBase(int w, int h) + : gWindow(w, h, "Midi Output Setup") +{ +} + + +/* -------------------------------------------------------------------------- */ + + +void gdMidiOutputBase::stopMidiLearn(geMidiLearner *learner) +{ + G_KernelMidi.stopMidiLearn(); + learner->updateValue(); +} + + +/* -------------------------------------------------------------------------- */ + + +void gdMidiOutputBase::__cb_learn(uint32_t *param, uint32_t msg, geMidiLearner *l) +{ + *param = msg; + stopMidiLearn(l); + gu_log("[gdMidiGrabber] MIDI learn done - message=0x%X\n", msg); +} + + +/* -------------------------------------------------------------------------- */ + + +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); +} + + +/* -------------------------------------------------------------------------- */ + + +void gdMidiOutputBase::cb_close(Fl_Widget *w, void *p) { ((gdMidiOutputBase*)p)->__cb_close(); } + + +/* -------------------------------------------------------------------------- */ + + +void gdMidiOutputBase::__cb_close() +{ + do_callback(); +} + + +/* -------------------------------------------------------------------------- */ + + +void gdMidiOutputBase::cb_enableLightning(Fl_Widget *w, void *p) +{ + ((gdMidiOutputBase*)p)->__cb_enableLightning(); +} + + +/* -------------------------------------------------------------------------- */ + + +void gdMidiOutputBase::__cb_enableLightning() {} + + +/* -------------------------------------------------------------------------- */ + + +void gdMidiOutputBase::setTitle(int chanNum) +{ + char title[64]; + sprintf(title, "MIDI Output Setup (channel %d)", chanNum); + copy_label(title); +} diff --git a/src/gui/dialogs/gd_midiOutput.h b/src/gui/dialogs/midiIO/midiOutputBase.h similarity index 63% rename from src/gui/dialogs/gd_midiOutput.h rename to src/gui/dialogs/midiIO/midiOutputBase.h index 03cc32a..fd639d4 100644 --- a/src/gui/dialogs/gd_midiOutput.h +++ b/src/gui/dialogs/midiIO/midiOutputBase.h @@ -1,10 +1,10 @@ -/* ---------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- * * Giada - Your Hardcore Loopmachine * * gd_midiOutput * - * --------------------------------------------------------------------- + * ----------------------------------------------------------------------------- * * Copyright (C) 2010-2016 Giovanni A. Zuliani | Monocasual * @@ -24,16 +24,15 @@ * along with Giada - Your Hardcore Loopmachine. If not, see * . * - * ------------------------------------------------------------------ */ + * -------------------------------------------------------------------------- */ -#ifndef GD_MIDI_OUTPUT_H -#define GD_MIDI_OUTPUT_H +#ifndef GD_MIDI_OUTPUT_BASE_H +#define GD_MIDI_OUTPUT_BASE_H #include -#include -#include "../elems/ge_window.h" +#include "../../elems/ge_window.h" /* There's no such thing as a gdMidiOutputMaster vs gdMidiOutputChannel. MIDI @@ -46,20 +45,20 @@ In addition MidiOutputMidiCh has the MIDI message output box. */ /* TODO - gdMidiOutput is almost the same thing of gdMidiInput. Create another parent class gdMidiIO to inherit from */ -class gdMidiOutput : public gWindow +class gdMidiOutputBase : public gWindow { protected: class gClick *close; class gCheck *enableLightning; - void stopMidiLearn(class gLearner *l); + void stopMidiLearn(class 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, class gLearner *l); + inline void __cb_learn(uint32_t *param, uint32_t msg, class geMidiLearner *l); /* cb_close close current window. */ @@ -80,55 +79,8 @@ protected: public: - gdMidiOutput(int w, int h); + gdMidiOutputBase(int w, int h); }; -/* -------------------------------------------------------------------------- */ - - -class gdMidiOutputMidiCh : public gdMidiOutput -{ -private: - - static void cb_enableChanList (Fl_Widget *w, void *p); - inline void __cb_enableChanList(); - - /* __cb_close - override parent method, we need to do more stuff on close. */ - - static void cb_close (Fl_Widget *w, void *p); - inline void __cb_close(); - - class gCheck *enableOut; - class gChoice *chanListOut; - - class MidiChannel *ch; - -public: - - gdMidiOutputMidiCh(class MidiChannel *ch); -}; - - -/* -------------------------------------------------------------------------- */ - - -class gdMidiOutputSampleCh : public gdMidiOutput -{ -private: - - class SampleChannel *ch; - - /* __cb_close - override parent method, we need to do more stuff on close. */ - - static void cb_close (Fl_Widget *w, void *p); - inline void __cb_close(); - -public: - - gdMidiOutputSampleCh(class SampleChannel *ch); -}; - #endif diff --git a/src/gui/dialogs/midiIO/midiOutputMidiCh.cpp b/src/gui/dialogs/midiIO/midiOutputMidiCh.cpp new file mode 100644 index 0000000..08954dd --- /dev/null +++ b/src/gui/dialogs/midiIO/midiOutputMidiCh.cpp @@ -0,0 +1,119 @@ +/* ----------------------------------------------------------------------------- + * + * Giada - Your Hardcore Loopmachine + * + * midiOutputMidiCh + * + * ----------------------------------------------------------------------------- + * + * Copyright (C) 2010-2016 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 "../../../core/midiChannel.h" +#include "../../../utils/gui.h" +#include "../../elems/ge_mixed.h" +#include "../../elems/midiLearner.h" +#include "../../elems/mainWindow/keyboard/channel.h" +#include "midiOutputMidiCh.h" + + +gdMidiOutputMidiCh::gdMidiOutputMidiCh(MidiChannel *ch) + : gdMidiOutputBase(300, 168), ch(ch) +{ + setTitle(ch->index+1); + begin(); + + enableOut = new gCheck(x()+8, y()+8, 150, 20, "Enable MIDI output"); + chanListOut = new gChoice(w()-108, y()+8, 100, 20); + + enableLightning = new gCheck(x()+8, chanListOut->y()+chanListOut->h()+8, 120, 20, "Enable MIDI lightning output"); + new geMidiLearner(x()+8, enableLightning->y()+enableLightning->h()+8, w()-16, "playing", cb_learn, &ch->midiOutLplaying); + new geMidiLearner(x()+8, enableLightning->y()+enableLightning->h()+32, w()-16, "mute", cb_learn, &ch->midiOutLmute); + new geMidiLearner(x()+8, enableLightning->y()+enableLightning->h()+56, w()-16, "solo", cb_learn, &ch->midiOutLsolo); + + close = new gButton(w()-88, enableLightning->y()+enableLightning->h()+84, 80, 20, "Close"); + + end(); + + chanListOut->add("Channel 1"); + chanListOut->add("Channel 2"); + chanListOut->add("Channel 3"); + chanListOut->add("Channel 4"); + chanListOut->add("Channel 5"); + chanListOut->add("Channel 6"); + chanListOut->add("Channel 7"); + chanListOut->add("Channel 8"); + chanListOut->add("Channel 9"); + chanListOut->add("Channel 10"); + chanListOut->add("Channel 11"); + chanListOut->add("Channel 12"); + chanListOut->add("Channel 13"); + chanListOut->add("Channel 14"); + chanListOut->add("Channel 15"); + chanListOut->add("Channel 16"); + chanListOut->value(0); + + if (ch->midiOut) + enableOut->value(1); + else + chanListOut->deactivate(); + + if (ch->midiOutL) + enableLightning->value(1); + + chanListOut->value(ch->midiOutChan); + + enableOut->callback(cb_enableChanList, (void*)this); + close->callback(cb_close, (void*)this); + + set_modal(); + gu_setFavicon(this); + show(); +} + + +/* -------------------------------------------------------------------------- */ + + +void gdMidiOutputMidiCh::cb_close (Fl_Widget *w, void *p) { ((gdMidiOutputMidiCh*)p)->__cb_close(); } +void gdMidiOutputMidiCh::cb_enableChanList(Fl_Widget *w, void *p) { ((gdMidiOutputMidiCh*)p)->__cb_enableChanList(); } + + +/* -------------------------------------------------------------------------- */ + + +void gdMidiOutputMidiCh::__cb_enableChanList() +{ + enableOut->value() ? chanListOut->activate() : chanListOut->deactivate(); +} + + +/* -------------------------------------------------------------------------- */ + + +void gdMidiOutputMidiCh::__cb_close() +{ + ch->midiOut = enableOut->value(); + ch->midiOutChan = chanListOut->value(); + ch->midiOutL = enableLightning->value(); + ch->guiChannel->update(); + do_callback(); +} diff --git a/src/gui/dialogs/midiIO/midiOutputMidiCh.h b/src/gui/dialogs/midiIO/midiOutputMidiCh.h new file mode 100644 index 0000000..a0deb21 --- /dev/null +++ b/src/gui/dialogs/midiIO/midiOutputMidiCh.h @@ -0,0 +1,61 @@ +/* ----------------------------------------------------------------------------- + * + * Giada - Your Hardcore Loopmachine + * + * midiOutputMidiCh + * + * ----------------------------------------------------------------------------- + * + * Copyright (C) 2010-2016 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 GD_MIDI_OUTPUT_MIDI_CH_H +#define GD_MIDI_OUTPUT_MIDI_CH_H + + +#include "midiOutputBase.h" + + +class gdMidiOutputMidiCh : public gdMidiOutputBase +{ +private: + + static void cb_enableChanList (Fl_Widget *w, void *p); + inline void __cb_enableChanList(); + + /* __cb_close + override parent method, we need to do more stuff on close. */ + + static void cb_close (Fl_Widget *w, void *p); + inline void __cb_close(); + + class gCheck *enableOut; + class gChoice *chanListOut; + + class MidiChannel *ch; + +public: + + gdMidiOutputMidiCh(class MidiChannel *ch); +}; + + +#endif diff --git a/src/gui/dialogs/midiIO/midiOutputSampleCh.cpp b/src/gui/dialogs/midiIO/midiOutputSampleCh.cpp new file mode 100644 index 0000000..4cbe682 --- /dev/null +++ b/src/gui/dialogs/midiIO/midiOutputSampleCh.cpp @@ -0,0 +1,72 @@ +/* ----------------------------------------------------------------------------- + * + * Giada - Your Hardcore Loopmachine + * + * midiOutputSampleCh + * + * ----------------------------------------------------------------------------- + * + * Copyright (C) 2010-2016 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 "../../../core/sampleChannel.h" +#include "../../../utils/gui.h" +#include "../../elems/ge_mixed.h" +#include "../../elems/midiLearner.h" +#include "midiOutputSampleCh.h" + + +gdMidiOutputSampleCh::gdMidiOutputSampleCh(SampleChannel *ch) + : gdMidiOutputBase(300, 140), ch(ch) +{ + setTitle(ch->index+1); + + enableLightning = new gCheck(8, 8, 120, 20, "Enable MIDI lightning output"); + new geMidiLearner(8, enableLightning->y()+enableLightning->h()+8, w()-16, "playing", cb_learn, &ch->midiOutLplaying); + new geMidiLearner(8, enableLightning->y()+enableLightning->h()+32, w()-16, "mute", cb_learn, &ch->midiOutLmute); + new geMidiLearner(8, enableLightning->y()+enableLightning->h()+56, w()-16, "solo", cb_learn, &ch->midiOutLsolo); + + close = new gButton(w()-88, enableLightning->y()+enableLightning->h()+84, 80, 20, "Close"); + close->callback(cb_close, (void*)this); + + enableLightning->value(ch->midiOutL); + enableLightning->callback(cb_enableLightning, (void*)this); + + set_modal(); + gu_setFavicon(this); + show(); +} + + +/* -------------------------------------------------------------------------- */ + + +void gdMidiOutputSampleCh::cb_close(Fl_Widget *w, void *p) { ((gdMidiOutputSampleCh*)p)->__cb_close(); } + + +/* -------------------------------------------------------------------------- */ + + +void gdMidiOutputSampleCh::__cb_close() +{ + ch->midiOutL = enableLightning->value(); + do_callback(); +} diff --git a/src/gui/dialogs/midiIO/midiOutputSampleCh.h b/src/gui/dialogs/midiIO/midiOutputSampleCh.h new file mode 100644 index 0000000..b229ca8 --- /dev/null +++ b/src/gui/dialogs/midiIO/midiOutputSampleCh.h @@ -0,0 +1,54 @@ +/* ----------------------------------------------------------------------------- + * + * Giada - Your Hardcore Loopmachine + * + * midiOutputSampleCh + * + * ----------------------------------------------------------------------------- + * + * Copyright (C) 2010-2016 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 GD_MIDI_OUTPUT_SAMPLE_CH_H +#define GD_MIDI_OUTPUT_SAMPLE_CH_H + + +#include "midiOutputBase.h" + + +class gdMidiOutputSampleCh : public gdMidiOutputBase +{ +private: + + class SampleChannel *ch; + + /* __cb_close + override parent method, we need to do more stuff on close. */ + + static void cb_close (Fl_Widget *w, void *p); + inline void __cb_close(); + +public: + + gdMidiOutputSampleCh(class SampleChannel *ch); +}; + +#endif diff --git a/src/gui/elems/actionEditor.cpp b/src/gui/elems/actionEditor.cpp index 4a88413..065860d 100644 --- a/src/gui/elems/actionEditor.cpp +++ b/src/gui/elems/actionEditor.cpp @@ -35,7 +35,7 @@ #include "../../utils/log.h" #include "../dialogs/gd_mainWindow.h" #include "../dialogs/gd_actionEditor.h" -#include "ge_keyboard.h" +#include "mainWindow/keyboard/keyboard.h" #include "actionEditor.h" @@ -591,6 +591,8 @@ void gAction::addAction() //gu_log("action added, [%d]\n", frame_a); } + parent->chan->hasActions = true; + G_Recorder.sortActions(); index++; // important! @@ -606,11 +608,17 @@ void gAction::delAction() * actions. */ if (ch->mode == SINGLE_PRESS) { - G_Recorder.deleteAction(parent->chan->index, frame_a, ACTION_KEYPRESS, false); - G_Recorder.deleteAction(parent->chan->index, frame_b, ACTION_KEYREL, false); + G_Recorder.deleteAction(parent->chan->index, frame_a, ACTION_KEYPRESS, + false, &G_Mixer.mutex_recs); + G_Recorder.deleteAction(parent->chan->index, frame_b, ACTION_KEYREL, + false, &G_Mixer.mutex_recs); } else - G_Recorder.deleteAction(parent->chan->index, frame_a, type, false); + G_Recorder.deleteAction(parent->chan->index, frame_a, type, false, + &G_Mixer.mutex_recs); + + parent->chan->hasActions = G_Recorder.hasActions(parent->chan->index); + /* restore the initial cursor shape, in case you delete an action and * the double arrow (for resizing) is displayed */ @@ -648,6 +656,8 @@ void gAction::moveAction(int frame_a) G_Recorder.rec(parent->chan->index, ACTION_KEYREL, frame_b); } + parent->chan->hasActions = true; + G_Recorder.sortActions(); } diff --git a/src/gui/elems/basics/boxtypes.cpp b/src/gui/elems/basics/boxtypes.cpp new file mode 100644 index 0000000..547d1aa --- /dev/null +++ b/src/gui/elems/basics/boxtypes.cpp @@ -0,0 +1,59 @@ +/* ----------------------------------------------------------------------------- + * + * Giada - Your Hardcore Loopmachine + * + * boxtypes + * + * ----------------------------------------------------------------------------- + * + * Copyright (C) 2010-2016 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/const.h" +#include "boxtypes.h" + + +void g_customBorderBox(int x, int y, int w, int h, Fl_Color c) +{ + fl_color(c); + fl_rectf(x, y, w, h); + fl_color(COLOR_BD_0); + fl_rect(x, y, w, h); +} + + +void g_customUpBox(int x, int y, int w, int h, Fl_Color c) +{ + fl_color(COLOR_BG_0); + fl_rectf(x, y, w, h); + fl_color(COLOR_BG_0); + fl_rect(x, y, w, h); +} + + +void g_customDownBox(int x, int y, int w, int h, Fl_Color c) +{ + fl_color(c); + fl_rectf(x, y, w, h); + fl_color(COLOR_BG_0); + fl_rect(x, y, w, h); +} diff --git a/src/gui/elems/basics/boxtypes.h b/src/gui/elems/basics/boxtypes.h new file mode 100644 index 0000000..d717c86 --- /dev/null +++ b/src/gui/elems/basics/boxtypes.h @@ -0,0 +1,47 @@ +/* ----------------------------------------------------------------------------- + * + * Giada - Your Hardcore Loopmachine + * + * boxtypes + * + * ----------------------------------------------------------------------------- + * + * Copyright (C) 2010-2016 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 __BOXTYPES_H__ +#define __BOXTYPES_H__ + + +#include + + +#define G_CUSTOM_BORDER_BOX FL_FREE_BOXTYPE +#define G_CUSTOM_UP_BOX (Fl_Boxtype)(FL_FREE_BOXTYPE + 1) +#define G_CUSTOM_DOWN_BOX (Fl_Boxtype)(FL_FREE_BOXTYPE + 3) + + +void g_customBorderBox(int x, int y, int w, int h, Fl_Color c); +void g_customUpBox (int x, int y, int w, int h, Fl_Color c); +void g_customDownBox (int x, int y, int w, int h, Fl_Color c); + + +#endif diff --git a/src/gui/elems/basics/scroll.cpp b/src/gui/elems/basics/scroll.cpp new file mode 100644 index 0000000..9cee240 --- /dev/null +++ b/src/gui/elems/basics/scroll.cpp @@ -0,0 +1,50 @@ +/* ----------------------------------------------------------------------------- + * + * Giada - Your Hardcore Loopmachine + * + * geScroll + * Custom scroll with nice scrollbars and something else. + * + * ----------------------------------------------------------------------------- + * + * Copyright (C) 2010-2016 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 "../../../core/const.h" +#include "boxtypes.h" +#include "scroll.h" + + +geScroll::geScroll(int x, int y, int w, int h, int t) + : Fl_Scroll(x, y, w, h) +{ + type(t); + + scrollbar.color(COLOR_BG_0); + scrollbar.selection_color(COLOR_BG_1); + scrollbar.labelcolor(COLOR_BD_1); + scrollbar.slider(G_CUSTOM_BORDER_BOX); + + hscrollbar.color(COLOR_BG_0); + hscrollbar.selection_color(COLOR_BG_1); + hscrollbar.labelcolor(COLOR_BD_1); + hscrollbar.slider(G_CUSTOM_BORDER_BOX); +} diff --git a/src/gui/elems/basics/scroll.h b/src/gui/elems/basics/scroll.h new file mode 100644 index 0000000..b122d44 --- /dev/null +++ b/src/gui/elems/basics/scroll.h @@ -0,0 +1,46 @@ +/* ----------------------------------------------------------------------------- + * + * Giada - Your Hardcore Loopmachine + * + * geScroll + * Custom scroll with nice scrollbars and something else. + * + * ----------------------------------------------------------------------------- + * + * Copyright (C) 2010-2016 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 __GE_SCROLL_H__ +#define __GE_SCROLL_H__ + + +#include + + +class geScroll : public Fl_Scroll +{ +public: + + geScroll(int x, int y, int w, int h, int type=Fl_Scroll::BOTH); +}; + + +#endif diff --git a/src/gui/elems/ge_browser.cpp b/src/gui/elems/browser.cpp similarity index 78% rename from src/gui/elems/ge_browser.cpp rename to src/gui/elems/browser.cpp index 9ae3235..812aaba 100644 --- a/src/gui/elems/ge_browser.cpp +++ b/src/gui/elems/browser.cpp @@ -2,7 +2,7 @@ * * Giada - Your Hardcore Loopmachine * - * gd_browser + * ge_browser * * ----------------------------------------------------------------------------- * @@ -27,19 +27,19 @@ * -------------------------------------------------------------------------- */ -#include #include "../../core/const.h" -#include "../../utils/fs.h" #include "../../utils/string.h" -#include "../../utils/log.h" #include "../dialogs/gd_browser.h" -#include "ge_browser.h" +#include "../elems/ge_mixed.h" +#include "basics/boxtypes.h" +#include "browser.h" -gBrowser::gBrowser(int x, int y, int w, int h) - : Fl_File_Browser(x, y, w, h) +geBrowser::geBrowser(int x, int y, int w, int h) + : Fl_File_Browser(x, y, w, h), + showHiddenFiles(false) { - box(G_BOX); + box(G_CUSTOM_BORDER_BOX); textsize(GUI_FONT_SIZE_BASE); textcolor(COLOR_TEXT_0); selection_color(COLOR_BG_1); @@ -49,12 +49,12 @@ gBrowser::gBrowser(int x, int y, int w, int h) this->scrollbar.color(COLOR_BG_0); this->scrollbar.selection_color(COLOR_BG_1); this->scrollbar.labelcolor(COLOR_BD_1); - this->scrollbar.slider(G_BOX); + this->scrollbar.slider(G_CUSTOM_BORDER_BOX); this->hscrollbar.color(COLOR_BG_0); this->hscrollbar.selection_color(COLOR_BG_1); this->hscrollbar.labelcolor(COLOR_BD_1); - this->hscrollbar.slider(G_BOX); + this->hscrollbar.slider(G_CUSTOM_BORDER_BOX); take_focus(); // let it have focus on startup } @@ -63,21 +63,36 @@ gBrowser::gBrowser(int x, int y, int w, int h) /* -------------------------------------------------------------------------- */ -void gBrowser::loadDir(const string &dir) +void geBrowser::toggleHiddenFiles() +{ + showHiddenFiles = !showHiddenFiles; + loadDir(currentDir); +} + + +/* -------------------------------------------------------------------------- */ + + +void geBrowser::loadDir(const string &dir) { currentDir = dir; load(currentDir.c_str()); - /* hide "../", it just screws up things */ + /* Clean up unwanted elements. Hide "../" first, it just screws up things. + Also remove hidden files, if requested. */ - if (text(1) != NULL && strcmp(text(1), "../") == 0) - remove(1); + for (int i=size(); i>=0; i--) { + if (text(i) == nullptr) + continue; + if (strcmp(text(i), "../") == 0 || (!showHiddenFiles && strncmp(text(i), ".", 1) == 0)) + remove(i); + } } /* -------------------------------------------------------------------------- */ -int gBrowser::handle(int e) +int geBrowser::handle(int e) { int ret = Fl_File_Browser::handle(e); switch (e) { @@ -120,7 +135,7 @@ int gBrowser::handle(int e) /* -------------------------------------------------------------------------- */ -string gBrowser::getCurrentDir() +string geBrowser::getCurrentDir() { return normalize(gu_getRealPath(currentDir)); } @@ -129,7 +144,7 @@ string gBrowser::getCurrentDir() /* -------------------------------------------------------------------------- */ -string gBrowser::getSelectedItem(bool fullPath) +string geBrowser::getSelectedItem(bool fullPath) { if (!fullPath) // no full path requested? return the selected text return normalize(text(value())); @@ -144,7 +159,7 @@ string gBrowser::getSelectedItem(bool fullPath) /* -------------------------------------------------------------------------- */ -void gBrowser::preselect(int pos, int line) +void geBrowser::preselect(int pos, int line) { position(pos); select(line); @@ -154,12 +169,12 @@ void gBrowser::preselect(int pos, int line) /* -------------------------------------------------------------------------- */ -string gBrowser::normalize(const string &s) +string geBrowser::normalize(const string &s) { string out = s; - /* If string ends with G_SLASH, remove it. Don't do it if has length > 1, it - means that the string is just '/'. Note: our crappy version of Clang doesn't + /* If string ends with G_SLASH, remove it. Don't do it if has length > 1, it + means that the string is just '/'. Note: our crappy version of Clang doesn't seem to support std::string::back() */ #ifdef __APPLE__ diff --git a/src/gui/elems/ge_browser.h b/src/gui/elems/browser.h similarity index 93% rename from src/gui/elems/ge_browser.h rename to src/gui/elems/browser.h index e338143..4515dbf 100644 --- a/src/gui/elems/ge_browser.h +++ b/src/gui/elems/browser.h @@ -30,20 +30,20 @@ #ifndef GE_BROWSER_H #define GE_BROWSER_H -#include -#include + #include -#include "ge_mixed.h" +#include using std::string; -class gBrowser : public Fl_File_Browser +class geBrowser : public Fl_File_Browser { private: string currentDir; + bool showHiddenFiles; /* normalize * Make sure the string never ends with a trailing slash. */ @@ -52,7 +52,9 @@ private: public: - gBrowser(int x, int y, int w, int h); + geBrowser(int x, int y, int w, int h); + + void toggleHiddenFiles(); /* init * Initialize browser and show 'dir' as initial directory. */ diff --git a/src/gui/elems/envelopeEditor.cpp b/src/gui/elems/envelopeEditor.cpp index 7ade209..796a3fe 100644 --- a/src/gui/elems/envelopeEditor.cpp +++ b/src/gui/elems/envelopeEditor.cpp @@ -36,7 +36,7 @@ #include "../../core/mixer.h" #include "../dialogs/gd_actionEditor.h" #include "../dialogs/gd_mainWindow.h" -#include "ge_keyboard.h" +#include "mainWindow/keyboard/keyboard.h" #include "envelopeEditor.h" @@ -194,6 +194,7 @@ int geEnvelopeEditor::handle(int e) { G_Recorder.rec(pParent->chan->index, type, 0, 0, 1.0f); addPoint(G_Mixer.totalFrames, 0, 1.0f, pParent->coverX, 1); G_Recorder.rec(pParent->chan->index, type, G_Mixer.totalFrames, 0, 1.0f); + pParent->chan->hasActions = true; } /* line between 2 points y = (x-a) / (b-a); a = h() - 8; b = 1 */ @@ -202,6 +203,7 @@ int geEnvelopeEditor::handle(int e) { float value = (my - h() + 8) / (float) (1 - h() + 8); addPoint(frame, 0, value, mx, my); G_Recorder.rec(pParent->chan->index, type, frame, 0, value); + pParent->chan->hasActions = true; G_Recorder.sortActions(); sortPoints(); } @@ -219,11 +221,14 @@ int geEnvelopeEditor::handle(int e) { if (selectedPoint != -1) { if (selectedPoint == 0 || (unsigned) selectedPoint == points.size()-1) { G_Recorder.clearAction(pParent->chan->index, type); + pParent->chan->hasActions = G_Recorder.hasActions(pParent->chan->index); points.clear(); } else { - G_Recorder.deleteAction(pParent->chan->index, points.at(selectedPoint).frame, type, false); - G_Recorder.sortActions(); + G_Recorder.deleteAction(pParent->chan->index, + points.at(selectedPoint).frame, type, false, &G_Mixer.mutex_recs); + pParent->chan->hasActions = G_Recorder.hasActions(pParent->chan->index); + G_Recorder.sortActions(); points.erase(points.begin() + selectedPoint); } G_MainWin->keyboard->setChannelWithActions((geSampleChannel*)pParent->chan->guiChannel); // update mainWindow @@ -259,11 +264,14 @@ int geEnvelopeEditor::handle(int e) { /* delete previous point and record a new one */ - G_Recorder.deleteAction(pParent->chan->index, points.at(draggedPoint).frame, type, false); + G_Recorder.deleteAction(pParent->chan->index, + points.at(draggedPoint).frame, type, false, &G_Mixer.mutex_recs); + pParent->chan->hasActions = G_Recorder.hasActions(pParent->chan->index); if (range == RANGE_FLOAT) { float value = (points.at(draggedPoint).y - h() + 8) / (float) (1 - h() + 8); G_Recorder.rec(pParent->chan->index, type, newFrame, 0, value); + pParent->chan->hasActions = true; } else { /// TODO diff --git a/src/gui/elems/ge_mixed.cpp b/src/gui/elems/ge_mixed.cpp index 0969a8a..913f023 100644 --- a/src/gui/elems/ge_mixed.cpp +++ b/src/gui/elems/ge_mixed.cpp @@ -36,6 +36,7 @@ #include "../../core/sampleChannel.h" #include "../../utils/gui.h" #include "../dialogs/gd_mainWindow.h" +#include "basics/boxtypes.h" #include "ge_mixed.h" @@ -130,8 +131,8 @@ void gClickRepeat::draw() gInput::gInput(int x, int y, int w, int h, const char *L) : Fl_Input(x, y, w, h, L) { - //Fl::set_boxtype(G_BOX, gDrawBox, 1, 1, 2, 2); - box(G_BOX); + //Fl::set_boxtype(G_CUSTOM_BORDER_BOX, gDrawBox, 1, 1, 2, 2); + box(G_CUSTOM_BORDER_BOX); labelsize(GUI_FONT_SIZE_BASE); labelcolor(COLOR_TEXT_0); color(COLOR_BG_DARK); @@ -173,8 +174,9 @@ void gDial::draw() gBox::gBox(int x, int y, int w, int h, const char *L, Fl_Align al) -: Fl_Box(x, y, w, h, L) +: Fl_Box(x, y, w, h) { + copy_label(L); labelsize(GUI_FONT_SIZE_BASE); box(FL_NO_BOX); labelcolor(COLOR_TEXT_0); @@ -241,7 +243,7 @@ void gRadio::draw() gProgress::gProgress(int x, int y, int w, int h, const char *L) : Fl_Progress(x, y, w, h, L) { color(COLOR_BG_0, COLOR_BD_0); - box(G_BOX); + box(G_CUSTOM_BORDER_BOX); } @@ -294,38 +296,6 @@ void gSoundMeter::draw() fl_rectf(x()+1, y()+1, (int) px_level, h()-2, clip || !G_audio_status ? COLOR_ALERT : COLOR_BD_0); } -/* -------------------------------------------------------------------------- */ - -gBeatMeter::gBeatMeter(int x, int y, int w, int h, const char *L) - : Fl_Box(x, y, w, h, L) {} - -void gBeatMeter::draw() -{ - int cursorW = w() / MAX_BEATS; - int greyX = G_Mixer.beats * cursorW; - - fl_rect(x(), y(), w(), h(), COLOR_BD_0); // border - fl_rectf(x()+1, y()+1, w()-2, h()-2, FL_BACKGROUND_COLOR); // bg - fl_rectf(x()+(G_Mixer.actualBeat*cursorW)+3, y()+3, cursorW-5, h()-6, COLOR_BG_2); // cursor - - /* beat cells */ - - fl_color(COLOR_BD_0); - for (int i=1; i<=G_Mixer.beats; i++) - fl_line(x()+cursorW*i, y()+1, x()+cursorW*i, y()+h()-2); - - /* bar line */ - - fl_color(COLOR_BG_2); - int delta = G_Mixer.beats / G_Mixer.bars; - for (int i=1; iscrollbar.color(COLOR_BG_0); this->scrollbar.selection_color(COLOR_BG_1); this->scrollbar.labelcolor(COLOR_BD_1); - this->scrollbar.slider(G_BOX); + this->scrollbar.slider(G_CUSTOM_BORDER_BOX); this->hscrollbar.color(COLOR_BG_0); this->hscrollbar.selection_color(COLOR_BG_1); this->hscrollbar.labelcolor(COLOR_BD_1); - this->hscrollbar.slider(G_BOX); + this->hscrollbar.slider(G_CUSTOM_BORDER_BOX); type(FL_HOLD_BROWSER); @@ -81,7 +82,7 @@ gePluginBrowser::gePluginBrowser(int x, int y, int w, int h) void gePluginBrowser::refresh() { clear(); - + add("NAME\tMANUFACTURER\tCATEGORY\tFORMAT\tUID"); add("---\t---\t---\t---\t---"); diff --git a/src/gui/elems/ge_waveTools.cpp b/src/gui/elems/ge_waveTools.cpp index 7e7b197..e2ec4b7 100644 --- a/src/gui/elems/ge_waveTools.cpp +++ b/src/gui/elems/ge_waveTools.cpp @@ -32,6 +32,7 @@ #include "../../core/const.h" #include "../elems/ge_mixed.h" #include "../elems/ge_waveform.h" +#include "basics/boxtypes.h" #include "ge_waveTools.h" @@ -42,7 +43,7 @@ gWaveTools::gWaveTools(int x, int y, int w, int h, SampleChannel *ch, const char hscrollbar.color(COLOR_BG_0); hscrollbar.selection_color(COLOR_BG_1); hscrollbar.labelcolor(COLOR_BD_1); - hscrollbar.slider(G_BOX); + hscrollbar.slider(G_CUSTOM_BORDER_BOX); waveform = new gWaveform(x, y, w, h-24, ch); diff --git a/src/gui/elems/ge_waveform.cpp b/src/gui/elems/ge_waveform.cpp index dd893ce..022257f 100644 --- a/src/gui/elems/ge_waveform.cpp +++ b/src/gui/elems/ge_waveform.cpp @@ -42,6 +42,7 @@ #include "../dialogs/gd_editor.h" #include "ge_waveTools.h" #include "ge_mixed.h" +#include "basics/boxtypes.h" #include "ge_waveform.h" @@ -621,7 +622,7 @@ void gWaveform::openEditMenu() } Fl_Menu_Button *b = new Fl_Menu_Button(0, 0, 100, 50); - b->box(G_BOX); + b->box(G_CUSTOM_BORDER_BOX); b->textsize(GUI_FONT_SIZE_BASE); b->textcolor(COLOR_TEXT_0); b->color(COLOR_BG_0); diff --git a/src/gui/elems/mainWindow/beatMeter.cpp b/src/gui/elems/mainWindow/beatMeter.cpp new file mode 100644 index 0000000..d0bb077 --- /dev/null +++ b/src/gui/elems/mainWindow/beatMeter.cpp @@ -0,0 +1,72 @@ +/* ----------------------------------------------------------------------------- + * + * Giada - Your Hardcore Loopmachine + * + * beatMeter + * + * ----------------------------------------------------------------------------- + * + * Copyright (C) 2010-2016 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/const.h" +#include "../../../core/mixer.h" +#include "beatMeter.h" + + +extern Mixer G_Mixer; + + +geBeatMeter::geBeatMeter(int x, int y, int w, int h, const char *L) + : Fl_Box(x, y, w, h, L) {} + + +/* -------------------------------------------------------------------------- */ + + +void geBeatMeter::draw() +{ + int cursorW = w() / MAX_BEATS; + int greyX = G_Mixer.beats * cursorW; + + fl_rect(x(), y(), w(), h(), COLOR_BD_0); // border + fl_rectf(x()+1, y()+1, w()-2, h()-2, FL_BACKGROUND_COLOR); // bg + fl_rectf(x()+(G_Mixer.actualBeat*cursorW)+3, y()+3, cursorW-5, h()-6, + COLOR_BG_2); // cursor + + /* beat cells */ + + fl_color(COLOR_BD_0); + for (int i=1; i<=G_Mixer.beats; i++) + fl_line(x()+cursorW*i, y()+1, x()+cursorW*i, y()+h()-2); + + /* bar line */ + + fl_color(COLOR_BG_2); + int delta = G_Mixer.beats / G_Mixer.bars; + for (int i=1; i. + * + * -------------------------------------------------------------------------- */ + + +#ifndef GE_BEAT_METER_H +#define GE_BEAT_METER_H + + +#include + + +class geBeatMeter : public Fl_Box +{ +public: + + geBeatMeter(int X,int Y,int W,int H,const char *L=0); + void draw(); +}; + + +#endif diff --git a/src/gui/elems/channel.cpp b/src/gui/elems/mainWindow/keyboard/channel.cpp similarity index 91% rename from src/gui/elems/channel.cpp rename to src/gui/elems/mainWindow/keyboard/channel.cpp index a33f121..1114d7c 100644 --- a/src/gui/elems/channel.cpp +++ b/src/gui/elems/mainWindow/keyboard/channel.cpp @@ -27,25 +27,19 @@ * -------------------------------------------------------------------------- */ -#include "../../core/mixer.h" -#include "../../core/conf.h" -#include "../../core/channel.h" -#include "../../core/patch_DEPR_.h" -#include "../../core/graphics.h" -#include "../../core/pluginHost.h" -#include "../../utils/gui.h" -#include "../../glue/channel.h" -#include "../../glue/main.h" -#include "../dialogs/gd_mainWindow.h" -#include "../dialogs/gd_pluginList.h" -#include "ge_column.h" +#include "../../../../core/const.h" +#include "../../../../core/channel.h" +#include "../../../../core/graphics.h" +#include "../../../../core/pluginHost.h" +#include "../../../../utils/gui.h" +#include "../../../../glue/channel.h" +#include "../../../dialogs/gd_mainWindow.h" +#include "../../../dialogs/gd_pluginList.h" +#include "column.h" #include "channelButton.h" #include "channel.h" -extern Mixer G_Mixer; -extern Conf G_Conf; -extern Patch_DEPR_ G_Patch_DEPR_; extern gdMainWindow *G_MainWin; @@ -131,7 +125,7 @@ int geChannel::keyPress(int e) int geChannel::getColumnIndex() { - return ((gColumn*)parent())->getIndex(); + return ((geColumn*)parent())->getIndex(); } diff --git a/src/gui/elems/channel.h b/src/gui/elems/mainWindow/keyboard/channel.h similarity index 99% rename from src/gui/elems/channel.h rename to src/gui/elems/mainWindow/keyboard/channel.h index 33dc00d..f76378f 100644 --- a/src/gui/elems/channel.h +++ b/src/gui/elems/mainWindow/keyboard/channel.h @@ -122,7 +122,7 @@ public: class Channel *ch; class gButton *button; - class gStatus *status; + class geChannelStatus *status; class gClick *arm; class geChannelButton *mainButton; class gClick *mute; diff --git a/src/gui/elems/channelButton.cpp b/src/gui/elems/mainWindow/keyboard/channelButton.cpp similarity index 98% rename from src/gui/elems/channelButton.cpp rename to src/gui/elems/mainWindow/keyboard/channelButton.cpp index 69d262d..9a17eb4 100644 --- a/src/gui/elems/channelButton.cpp +++ b/src/gui/elems/mainWindow/keyboard/channelButton.cpp @@ -27,8 +27,7 @@ * -------------------------------------------------------------------------- */ -#include "../../core/const.h" -#include "../../utils/fs.h" +#include "../../../../core/const.h" #include "channelButton.h" diff --git a/src/gui/elems/channelButton.h b/src/gui/elems/mainWindow/keyboard/channelButton.h similarity index 94% rename from src/gui/elems/channelButton.h rename to src/gui/elems/mainWindow/keyboard/channelButton.h index da08cd8..5163983 100644 --- a/src/gui/elems/channelButton.h +++ b/src/gui/elems/mainWindow/keyboard/channelButton.h @@ -31,17 +31,14 @@ #define GE_CHANNEL_BUTTON_H -#include "ge_mixed.h" - - -using std::string; +#include "../../ge_mixed.h" class geChannelButton : public gClick { private: - string key; + std::string key; public: @@ -50,7 +47,7 @@ public: virtual int handle(int e) = 0; void draw(); - void setKey(const string &k); + void setKey(const std::string &k); void setKey(int k); void setPlayMode(); void setEndingMode(); diff --git a/src/gui/elems/ge_modeBox.cpp b/src/gui/elems/mainWindow/keyboard/channelMode.cpp similarity index 84% rename from src/gui/elems/ge_modeBox.cpp rename to src/gui/elems/mainWindow/keyboard/channelMode.cpp index 4a6915b..5babd63 100644 --- a/src/gui/elems/ge_modeBox.cpp +++ b/src/gui/elems/mainWindow/keyboard/channelMode.cpp @@ -27,18 +27,20 @@ * -------------------------------------------------------------------------- */ -#include "../../utils/gui.h" -#include "../../core/graphics.h" -#include "../../core/sampleChannel.h" -#include "../../core/const.h" -#include "../dialogs/gd_mainWindow.h" -#include "ge_modeBox.h" +#include +#include "../../../../utils/gui.h" +#include "../../../../core/graphics.h" +#include "../../../../core/sampleChannel.h" +#include "../../../../core/const.h" +#include "../../basics/boxtypes.h" +#include "channelMode.h" -gModeBox::gModeBox(int x, int y, int w, int h, SampleChannel *ch, const char *L) +geChannelMode::geChannelMode(int x, int y, int w, int h, SampleChannel *ch, + const char *L) : Fl_Menu_Button(x, y, w, h, L), ch(ch) { - box(G_BOX); + box(G_CUSTOM_BORDER_BOX); textsize(GUI_FONT_SIZE_BASE); textcolor(COLOR_TEXT_0); color(COLOR_BG_0); @@ -57,7 +59,7 @@ gModeBox::gModeBox(int x, int y, int w, int h, SampleChannel *ch, const char *L) /* -------------------------------------------------------------------------- */ -void gModeBox::draw() { +void geChannelMode::draw() { fl_rect(x(), y(), w(), h(), COLOR_BD_0); // border switch (ch->mode) { case LOOP_BASIC: @@ -91,13 +93,13 @@ void gModeBox::draw() { /* -------------------------------------------------------------------------- */ -void gModeBox::cb_changeMode(Fl_Widget *v, void *p) { ((gModeBox*)v)->__cb_changeMode((intptr_t)p); } +void geChannelMode::cb_changeMode(Fl_Widget *v, void *p) { ((geChannelMode*)v)->__cb_changeMode((intptr_t)p); } /* -------------------------------------------------------------------------- */ -void gModeBox::__cb_changeMode(int mode) +void geChannelMode::__cb_changeMode(int mode) { ch->mode = mode; diff --git a/src/gui/elems/ge_modeBox.h b/src/gui/elems/mainWindow/keyboard/channelMode.h similarity index 87% rename from src/gui/elems/ge_modeBox.h rename to src/gui/elems/mainWindow/keyboard/channelMode.h index 2e82cd3..0829be9 100644 --- a/src/gui/elems/ge_modeBox.h +++ b/src/gui/elems/mainWindow/keyboard/channelMode.h @@ -27,14 +27,14 @@ * -------------------------------------------------------------------------- */ -#ifndef GE_MODEBOX_H -#define GE_MODEBOX_H +#ifndef GE_CHANNEL_MODE_H +#define GE_CHANNEL_MODE_H #include -class gModeBox : public Fl_Menu_Button +class geChannelMode : public Fl_Menu_Button { private: @@ -44,8 +44,9 @@ private: class SampleChannel *ch; public: - - gModeBox(int x, int y, int w, int h, class SampleChannel *ch, const char *l=0); + + geChannelMode(int x, int y, int w, int h, class SampleChannel *ch, + const char *l=0); void draw(); }; diff --git a/src/gui/elems/ge_status.cpp b/src/gui/elems/mainWindow/keyboard/channelStatus.cpp similarity index 85% rename from src/gui/elems/ge_status.cpp rename to src/gui/elems/mainWindow/keyboard/channelStatus.cpp index 80cbac7..bc89239 100644 --- a/src/gui/elems/ge_status.cpp +++ b/src/gui/elems/mainWindow/keyboard/channelStatus.cpp @@ -27,23 +27,27 @@ * -------------------------------------------------------------------------- */ -#include "../../core/mixer.h" -#include "../../core/const.h" -#include "ge_status.h" +#include +#include "../../../../core/mixer.h" +#include "../../../../core/sampleChannel.h" +#include "../../../../core/recorder.h" +#include "../../../../core/const.h" +#include "channelStatus.h" extern Mixer G_Mixer; extern Recorder G_Recorder; -gStatus::gStatus(int x, int y, int w, int h, SampleChannel *ch, const char *L) +geChannelStatus::geChannelStatus(int x, int y, int w, int h, SampleChannel *ch, + const char *L) : Fl_Box(x, y, w, h, L), ch(ch) {} /* -------------------------------------------------------------------------- */ -void gStatus::draw() +void geChannelStatus::draw() { fl_rect(x(), y(), w(), h(), COLOR_BD_0); // reset border fl_rectf(x()+1, y()+1, w()-2, h()-2, COLOR_BG_0); // reset background @@ -64,7 +68,7 @@ void gStatus::draw() if (G_Mixer.recording && ch->armed) fl_rectf(x()+1, y()+1, w()-2, h()-2, COLOR_BG_3); // take in progress else - if (G_Recorder.active && G_Recorder.canRec(ch)) + if (G_Recorder.active && G_Recorder.canRec(ch, &G_Mixer)) fl_rectf(x()+1, y()+1, w()-2, h()-2, COLOR_BG_4); // action record /* equation for the progress bar: diff --git a/src/gui/elems/ge_status.h b/src/gui/elems/mainWindow/keyboard/channelStatus.h similarity index 85% rename from src/gui/elems/ge_status.h rename to src/gui/elems/mainWindow/keyboard/channelStatus.h index e75d919..6e911cb 100644 --- a/src/gui/elems/ge_status.h +++ b/src/gui/elems/mainWindow/keyboard/channelStatus.h @@ -27,19 +27,18 @@ * -------------------------------------------------------------------------- */ -#ifndef GE_STATUS_H -#define GE_STATUS_H +#ifndef GE_CHANNEL_STATUS_H +#define GE_CHANNEL_STATUS_H #include -#include "../../core/sampleChannel.h" -#include "ge_mixed.h" -class gStatus : public Fl_Box +class geChannelStatus : public Fl_Box { public: - gStatus(int X, int Y, int W, int H, class SampleChannel *ch, const char *L=0); + geChannelStatus(int X, int Y, int W, int H, class SampleChannel *ch, + const char *L=0); void draw(); class SampleChannel *ch; }; diff --git a/src/gui/elems/ge_column.cpp b/src/gui/elems/mainWindow/keyboard/column.cpp similarity index 77% rename from src/gui/elems/ge_column.cpp rename to src/gui/elems/mainWindow/keyboard/column.cpp index 7f8a046..6518aed 100644 --- a/src/gui/elems/ge_column.cpp +++ b/src/gui/elems/mainWindow/keyboard/column.cpp @@ -27,41 +27,28 @@ * -------------------------------------------------------------------------- */ -#include "../../core/mixer.h" -#include "../../core/conf.h" -#include "../../core/patch_DEPR_.h" -#include "../../core/channel.h" -#include "../../core/sampleChannel.h" -#include "../../core/midiChannel.h" -#include "../../glue/main.h" -#include "../../glue/channel.h" -#include "../../utils/log.h" -#include "../../utils/string.h" -#include "../dialogs/gd_mainWindow.h" -#include "../dialogs/gd_warnings.h" -#include "../elems/ge_keyboard.h" -#include "ge_column.h" -#include "channel.h" +#include "../../../../core/sampleChannel.h" +#include "../../../../glue/channel.h" +#include "../../../../utils/log.h" +#include "../../../../utils/string.h" +#include "../../../dialogs/gd_warnings.h" +#include "../../../elems/basics/boxtypes.h" +#include "keyboard.h" #include "sampleChannel.h" #include "midiChannel.h" +#include "column.h" -extern Mixer G_Mixer; -extern Conf G_Conf; -extern Patch_DEPR_ G_Patch_DEPR_; -extern gdMainWindow *mainWin; - - -gColumn::gColumn(int X, int Y, int W, int H, int index, gKeyboard *parent) +geColumn::geColumn(int X, int Y, int W, int H, int index, geKeyboard *parent) : Fl_Group(X, Y, W, H), parent(parent), index(index) { - /* gColumn does a bit of a mess: we pass a pointer to its parent (gKeyboard) and - the gColumn itself deals with the creation of another widget, outside gColumn - and inside gKeyboard, which handles the vertical resize bar (gResizerBar). - The resizer cannot stay inside gColumn: it needs a broader view on the other - side widgets. The view can be obtained from gKeyboard only (the upper level). + /* geColumn does a bit of a mess: we pass a pointer to its parent (geKeyboard) and + the geColumn itself deals with the creation of another widget, outside geColumn + and inside geKeyboard, which handles the vertical resize bar (gResizerBar). + The resizer cannot stay inside geColumn: it needs a broader view on the other + side widgets. The view can be obtained from geKeyboard only (the upper level). Unfortunately, parent() can be NULL: at this point (i.e the constructor) - gColumn is still detached from any parent. We use a custom gKeyboard *parent + geColumn is still detached from any parent. We use a custom geKeyboard *parent instead. */ begin(); @@ -79,7 +66,7 @@ gColumn::gColumn(int X, int Y, int W, int H, int index, gKeyboard *parent) /* -------------------------------------------------------------------------- */ -gColumn::~gColumn() +geColumn::~geColumn() { /* FIXME - this could actually cause a memory leak. resizer is just removed, not deleted. But we cannot delete it right now. */ @@ -92,7 +79,7 @@ gColumn::~gColumn() -int gColumn::handle(int e) +int geColumn::handle(int e) { switch (e) { case FL_RELEASE: { @@ -112,7 +99,7 @@ int gColumn::handle(int e) bool fails = false; int result = 0; for (unsigned i=0; irefresh(); @@ -173,7 +160,7 @@ void gColumn::refreshChannels() /* -------------------------------------------------------------------------- */ -void gColumn::draw() +void geColumn::draw() { fl_color(fl_rgb_color(27, 27, 27)); fl_rectf(x(), y(), w(), h()); @@ -191,13 +178,13 @@ void gColumn::draw() /* -------------------------------------------------------------------------- */ -void gColumn::cb_addChannel(Fl_Widget *v, void *p) { ((gColumn*)p)->__cb_addChannel(); } +void geColumn::cb_addChannel(Fl_Widget *v, void *p) { ((geColumn*)p)->__cb_addChannel(); } /* -------------------------------------------------------------------------- */ -geChannel *gColumn::addChannel(Channel *ch) +geChannel *geColumn::addChannel(Channel *ch) { int currentY = y() + children() * 24; geChannel *gch = NULL; @@ -217,7 +204,7 @@ geChannel *gColumn::addChannel(Channel *ch) /* -------------------------------------------------------------------------- */ -void gColumn::deleteChannel(geChannel *gch) +void geColumn::deleteChannel(geChannel *gch) { gch->hide(); remove(gch); @@ -225,7 +212,7 @@ void gColumn::deleteChannel(geChannel *gch) /* reposition all other channels and resize this group */ /** TODO - * reposition is useless when called by gColumn::clear(). Add a new + * reposition is useless when called by geColumn::clear(). Add a new * parameter to skip the operation */ for (int i=0; ibox(G_BOX); + b->box(G_CUSTOM_BORDER_BOX); b->textsize(GUI_FONT_SIZE_BASE); b->textcolor(COLOR_TEXT_0); b->color(COLOR_BG_0); @@ -280,7 +267,7 @@ int gColumn::openTypeMenu() /* -------------------------------------------------------------------------- */ -void gColumn::clear(bool full) +void geColumn::clear(bool full) { if (full) Fl_Group::clear(); @@ -296,7 +283,7 @@ void gColumn::clear(bool full) /* -------------------------------------------------------------------------- */ -Channel *gColumn::getChannel(int i) +Channel *geColumn::getChannel(int i) { geChannel *gch = (geChannel*) child(i); if (gch->type == CHANNEL_SAMPLE) diff --git a/src/gui/elems/ge_column.h b/src/gui/elems/mainWindow/keyboard/column.h similarity index 93% rename from src/gui/elems/ge_column.h rename to src/gui/elems/mainWindow/keyboard/column.h index bcaa2ca..1d78540 100644 --- a/src/gui/elems/ge_column.h +++ b/src/gui/elems/mainWindow/keyboard/column.h @@ -31,11 +31,10 @@ #define GE_COLUMN_H -#include #include -class gColumn : public Fl_Group +class geColumn : public Fl_Group { private: @@ -46,14 +45,14 @@ private: class gClick *addChannelBtn; class gResizerBar *resizer; - class gKeyboard *parent; + class geKeyboard *parent; int index; public: - gColumn(int x, int y, int w, int h, int index, class gKeyboard *parent); - ~gColumn(); + geColumn(int x, int y, int w, int h, int index, class geKeyboard *parent); + ~geColumn(); /* addChannel * add a new channel in this column and set the internal pointer diff --git a/src/gui/elems/ge_keyboard.cpp b/src/gui/elems/mainWindow/keyboard/keyboard.cpp similarity index 80% rename from src/gui/elems/ge_keyboard.cpp rename to src/gui/elems/mainWindow/keyboard/keyboard.cpp index 68a8228..00d2bef 100644 --- a/src/gui/elems/ge_keyboard.cpp +++ b/src/gui/elems/mainWindow/keyboard/keyboard.cpp @@ -27,37 +27,24 @@ * -------------------------------------------------------------------------- */ -#include "../../core/mixer.h" -#include "../../core/conf.h" -#include "../../core/const.h" -#include "../../core/patch_DEPR_.h" -#include "../../core/channel.h" -#include "../../core/sampleChannel.h" -#include "../../glue/main.h" -#include "../../glue/io.h" -#include "../../utils/log.h" -#include "../dialogs/gd_browser.h" -#include "../dialogs/gd_mainWindow.h" -#include "../dialogs/gd_editor.h" -#include "../dialogs/gd_warnings.h" -#include "channel.h" +#include "../../../../core/sampleChannel.h" +#include "../../../../glue/main.h" +#include "../../../../glue/io.h" +#include "../../../../utils/log.h" +#include "../../../dialogs/gd_warnings.h" +#include "../../basics/boxtypes.h" +#include "column.h" #include "sampleChannel.h" -#include "ge_keyboard.h" +#include "keyboard.h" -extern Mixer G_Mixer; -extern Conf G_Conf; -extern Patch_DEPR_ G_Patch_DEPR_; -extern gdMainWindow *mainWin; - - -int gKeyboard::indexColumn = 0; +int geKeyboard::indexColumn = 0; /* -------------------------------------------------------------------------- */ -gKeyboard::gKeyboard(int X, int Y, int W, int H) +geKeyboard::geKeyboard(int X, int Y, int W, int H) : Fl_Scroll (X, Y, W, H), bckspcPressed(false), endPressed (false), @@ -69,11 +56,11 @@ gKeyboard::gKeyboard(int X, int Y, int W, int H) scrollbar.color(COLOR_BG_0); scrollbar.selection_color(COLOR_BG_1); scrollbar.labelcolor(COLOR_BD_1); - scrollbar.slider(G_BOX); + scrollbar.slider(G_CUSTOM_BORDER_BOX); hscrollbar.color(COLOR_BG_0); hscrollbar.selection_color(COLOR_BG_1); hscrollbar.labelcolor(COLOR_BD_1); - hscrollbar.slider(G_BOX); + hscrollbar.slider(G_CUSTOM_BORDER_BOX); addColumnBtn = new gClick(8, y(), 200, 20, "Add new column"); addColumnBtn->callback(cb_addColumn, (void*) this); @@ -86,7 +73,7 @@ gKeyboard::gKeyboard(int X, int Y, int W, int H) /* -------------------------------------------------------------------------- */ -void gKeyboard::init() +void geKeyboard::init() { /* add 6 empty columns as init layout */ @@ -102,7 +89,7 @@ void gKeyboard::init() /* -------------------------------------------------------------------------- */ -void gKeyboard::freeChannel(geChannel *gch) +void geKeyboard::freeChannel(geChannel *gch) { gch->reset(); } @@ -111,7 +98,7 @@ void gKeyboard::freeChannel(geChannel *gch) /* -------------------------------------------------------------------------- */ -void gKeyboard::deleteChannel(geChannel *gch) +void geKeyboard::deleteChannel(geChannel *gch) { for (unsigned i=0; ifind(gch); @@ -126,7 +113,7 @@ void gKeyboard::deleteChannel(geChannel *gch) /* -------------------------------------------------------------------------- */ -void gKeyboard::updateChannel(geChannel *gch) +void geKeyboard::updateChannel(geChannel *gch) { gch->update(); } @@ -135,7 +122,7 @@ void gKeyboard::updateChannel(geChannel *gch) /* -------------------------------------------------------------------------- */ -void gKeyboard::organizeColumns() +void geKeyboard::organizeColumns() { /* if only one column exists don't cleanup: the initial column must * stay here. */ @@ -172,18 +159,18 @@ void gKeyboard::organizeColumns() /* -------------------------------------------------------------------------- */ -void gKeyboard::cb_addColumn(Fl_Widget *v, void *p) +void geKeyboard::cb_addColumn(Fl_Widget *v, void *p) { - ((gKeyboard*)p)->__cb_addColumn(DEFAULT_COLUMN_WIDTH); + ((geKeyboard*)p)->__cb_addColumn(DEFAULT_COLUMN_WIDTH); } /* -------------------------------------------------------------------------- */ -geChannel *gKeyboard::addChannel(int colIndex, Channel *ch, bool build) +geChannel *geKeyboard::addChannel(int colIndex, Channel *ch, bool build) { - gColumn *col = getColumnByIndex(colIndex); + geColumn *col = getColumnByIndex(colIndex); /* no column with index 'colIndex' found? Just create it and set its index to 'colIndex'. */ @@ -192,10 +179,10 @@ geChannel *gKeyboard::addChannel(int colIndex, Channel *ch, bool build) __cb_addColumn(); col = columns.back(); col->setIndex(colIndex); - gu_log("[gKeyboard::addChannel] created new column with index=%d\n", colIndex); + gu_log("[geKeyboard::addChannel] created new column with index=%d\n", colIndex); } - gu_log("[gKeyboard::addChannel] add to column with index = %d\n", col->getIndex()); + gu_log("[geKeyboard::addChannel] add to column with index = %d\n", col->getIndex()); return col->addChannel(ch); } @@ -203,7 +190,7 @@ geChannel *gKeyboard::addChannel(int colIndex, Channel *ch, bool build) /* -------------------------------------------------------------------------- */ -void gKeyboard::refreshColumns() +void geKeyboard::refreshColumns() { for (unsigned i=0; irefreshChannels(); @@ -213,7 +200,7 @@ void gKeyboard::refreshColumns() /* -------------------------------------------------------------------------- */ -gColumn *gKeyboard::getColumnByIndex(int index) +geColumn *geKeyboard::getColumnByIndex(int index) { for (unsigned i=0; igetIndex() == index) @@ -227,7 +214,7 @@ gColumn *gKeyboard::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 gKeyboard::handle(int e) +int geKeyboard::handle(int e) { int ret = Fl_Group::handle(e); // assume the buttons won't handle the Keyboard events switch (e) { @@ -296,7 +283,7 @@ int gKeyboard::handle(int e) /* -------------------------------------------------------------------------- */ -void gKeyboard::clear() +void geKeyboard::clear() { for (unsigned i=0; ich->hasActions) gch->showActionButton(); @@ -321,7 +308,7 @@ void gKeyboard::setChannelWithActions(geSampleChannel *gch) /* -------------------------------------------------------------------------- */ -void gKeyboard::printChannelMessage(int res) +void geKeyboard::printChannelMessage(int res) { if (res == SAMPLE_NOT_VALID) gdAlert("This is not a valid WAVE file."); @@ -345,7 +332,7 @@ void gKeyboard::printChannelMessage(int res) /* -------------------------------------------------------------------------- */ -void gKeyboard::__cb_addColumn(int width) +void geKeyboard::__cb_addColumn(int width) { int colx; int colxw; @@ -355,14 +342,14 @@ void gKeyboard::__cb_addColumn(int width) colxw = colx + width; } else { - gColumn *prev = columns.back(); + geColumn *prev = columns.back(); colx = prev->x()+prev->w() + gap; colxw = colx + width; } - /* add gColumn to gKeyboard and to columns vector */ + /* add geColumn to geKeyboard and to columns vector */ - gColumn *gc = new gColumn(colx, y(), width, 2000, indexColumn, this); + geColumn *gc = new geColumn(colx, y(), width, 2000, indexColumn, this); add(gc); columns.push_back(gc); indexColumn++; @@ -372,7 +359,7 @@ void gKeyboard::__cb_addColumn(int width) addColumnBtn->position(colxw + gap, y()); redraw(); - gu_log("[gKeyboard::__cb_addColumn] new column added (index=%d, w=%d), total count=%d, addColumn(x)=%d\n", + gu_log("[geKeyboard::__cb_addColumn] new column added (index=%d, w=%d), total count=%d, addColumn(x)=%d\n", gc->getIndex(), width, columns.size(), addColumnBtn->x()); /* recompute col indexes */ @@ -384,7 +371,7 @@ void gKeyboard::__cb_addColumn(int width) /* -------------------------------------------------------------------------- */ -void gKeyboard::addColumn(int width) +void geKeyboard::addColumn(int width) { __cb_addColumn(width); } @@ -393,8 +380,26 @@ void gKeyboard::addColumn(int width) /* -------------------------------------------------------------------------- */ -void gKeyboard::refreshColIndexes() +void geKeyboard::refreshColIndexes() { for (unsigned i=0; isetIndex(i); } + + +/* -------------------------------------------------------------------------- */ + + +int geKeyboard::getColumnWidth(int i) +{ + return getColumnByIndex(i)->w(); +} + + +/* -------------------------------------------------------------------------- */ + + +geColumn *geKeyboard::getColumn(int i) +{ + return columns.at(i); +} diff --git a/src/gui/elems/ge_keyboard.h b/src/gui/elems/mainWindow/keyboard/keyboard.h similarity index 87% rename from src/gui/elems/ge_keyboard.h rename to src/gui/elems/mainWindow/keyboard/keyboard.h index c5558b9..8778c2a 100644 --- a/src/gui/elems/ge_keyboard.h +++ b/src/gui/elems/mainWindow/keyboard/keyboard.h @@ -31,21 +31,12 @@ #define GE_KEYBOARD_H -#include -#include -#include -#include -#include #include -#include "../elems/ge_column.h" -#include "../../core/const.h" -#include "../../utils/fs.h" - - -using std::vector; +#include +#include "../../../../core/const.h" -class gKeyboard : public Fl_Scroll +class geKeyboard : public Fl_Scroll { private: @@ -73,11 +64,11 @@ private: /* columns * a vector of columns which in turn contain channels. */ - vector columns; + std::vector columns; public: - gKeyboard(int X, int Y, int W, int H); + geKeyboard(int X, int Y, int W, int H); int handle(int e); @@ -129,12 +120,12 @@ public: /* getColumnByIndex * return the column with index 'index', or NULL if not found. */ - gColumn *getColumnByIndex(int index); + geColumn *getColumnByIndex(int index); /* getColumn * return the column with from columns->at(i). */ - inline gColumn *getColumn(int i) { return columns.at(i); } + geColumn *getColumn(int i); /* clear * delete all channels and groups. */ @@ -154,13 +145,13 @@ public: /* getTotalColumns */ - inline unsigned getTotalColumns() { return columns.size(); } + unsigned getTotalColumns() { return columns.size(); } /* getColumnWidth * return the width in pixel of i-th column. Warning: 'i' is the i-th column * in the column array, NOT the index. */ - inline int getColumnWidth(int i) { return getColumnByIndex(i)->w(); } + int getColumnWidth(int i); }; diff --git a/src/gui/elems/midiChannel.cpp b/src/gui/elems/mainWindow/keyboard/midiChannel.cpp similarity index 90% rename from src/gui/elems/midiChannel.cpp rename to src/gui/elems/mainWindow/keyboard/midiChannel.cpp index bfdbea5..183bc71 100644 --- a/src/gui/elems/midiChannel.cpp +++ b/src/gui/elems/mainWindow/keyboard/midiChannel.cpp @@ -27,33 +27,25 @@ * -------------------------------------------------------------------------- */ -#include "../../core/mixer.h" -#include "../../core/conf.h" -#include "../../core/patch_DEPR_.h" -#include "../../core/graphics.h" -#include "../../core/channel.h" -#include "../../core/midiChannel.h" -#include "../../glue/channel.h" -#include "../../glue/main.h" -#include "../../glue/io.h" -#include "../../utils/gui.h" -#include "../dialogs/gd_mainWindow.h" -#include "../dialogs/gd_keyGrabber.h" -#include "../dialogs/gd_midiInput.h" -#include "../dialogs/gd_editor.h" -#include "../dialogs/gd_actionEditor.h" -#include "../dialogs/gd_warnings.h" -#include "../dialogs/gd_browser.h" -#include "../dialogs/gd_keyGrabber.h" -#include "../dialogs/gd_midiOutput.h" -#include "../dialogs/gd_pluginList.h" +#include "../../../../core/const.h" +#include "../../../../core/graphics.h" +#include "../../../../core/midiChannel.h" +#include "../../../../glue/channel.h" +#include "../../../../glue/io.h" +#include "../../../dialogs/gd_mainWindow.h" +#include "../../../dialogs/gd_editor.h" +#include "../../../dialogs/gd_actionEditor.h" +#include "../../../dialogs/gd_warnings.h" +#include "../../../dialogs/gd_browser.h" +#include "../../../dialogs/gd_keyGrabber.h" +#include "../../../dialogs/gd_pluginList.h" +#include "../../../dialogs/midiIO/midiInputChannel.h" +#include "../../../dialogs/midiIO/midiOutputMidiCh.h" +#include "../../basics/boxtypes.h" #include "midiChannel.h" -extern Mixer G_Mixer; -extern Conf G_Conf; extern Recorder G_Recorder; -extern Patch_DEPR_ G_Patch_DEPR_; extern gdMainWindow *G_MainWin; @@ -151,7 +143,7 @@ void geMidiChannel::__cb_openMenu() rclick_menu[1].deactivate(); Fl_Menu_Button *b = new Fl_Menu_Button(0, 0, 100, 50); - b->box(G_BOX); + b->box(G_CUSTOM_BORDER_BOX); b->textsize(GUI_FONT_SIZE_BASE); b->textcolor(COLOR_TEXT_0); b->color(COLOR_BG_0); @@ -181,6 +173,7 @@ void geMidiChannel::__cb_openMenu() if (!gdConfirmWin("Warning", "Clear all actions: are you sure?")) return; G_Recorder.clearChan(ch->index); + ch->hasActions = false; gu_refreshActionEditor(); // refresh a.editor window, it could be open return; } diff --git a/src/gui/elems/midiChannel.h b/src/gui/elems/mainWindow/keyboard/midiChannel.h similarity index 100% rename from src/gui/elems/midiChannel.h rename to src/gui/elems/mainWindow/keyboard/midiChannel.h diff --git a/src/gui/elems/sampleChannel.cpp b/src/gui/elems/mainWindow/keyboard/sampleChannel.cpp similarity index 87% rename from src/gui/elems/sampleChannel.cpp rename to src/gui/elems/mainWindow/keyboard/sampleChannel.cpp index 5b7e4c9..fa3289c 100644 --- a/src/gui/elems/sampleChannel.cpp +++ b/src/gui/elems/mainWindow/keyboard/sampleChannel.cpp @@ -27,51 +27,49 @@ * -------------------------------------------------------------------------- */ -#include "../../core/pluginHost.h" -#include "../../core/mixer.h" -#include "../../core/conf.h" -#include "../../core/patch_DEPR_.h" -#include "../../core/recorder.h" -#include "../../core/graphics.h" -#include "../../core/wave.h" -#include "../../glue/main.h" -#include "../../glue/io.h" -#include "../../glue/channel.h" -#include "../../glue/storage.h" -#include "../../utils/gui.h" -#include "../../utils/string.h" -#include "../dialogs/gd_mainWindow.h" -#include "../dialogs/gd_keyGrabber.h" -#include "../dialogs/gd_midiOutput.h" -#include "../dialogs/gd_midiInput.h" -#include "../dialogs/gd_editor.h" -#include "../dialogs/gd_actionEditor.h" -#include "../dialogs/gd_warnings.h" -#include "../dialogs/gd_browser.h" -#include "ge_status.h" -#include "ge_modeBox.h" -#include "ge_keyboard.h" +#include "../../../../core/mixer.h" +#include "../../../../core/conf.h" +#include "../../../../core/recorder.h" +#include "../../../../core/graphics.h" +#include "../../../../core/wave.h" +#include "../../../../core/sampleChannel.h" +#include "../../../../glue/main.h" +#include "../../../../glue/io.h" +#include "../../../../glue/channel.h" +#include "../../../../glue/storage.h" +#include "../../../../utils/string.h" +#include "../../../dialogs/gd_mainWindow.h" +#include "../../../dialogs/gd_keyGrabber.h" +#include "../../../dialogs/gd_editor.h" +#include "../../../dialogs/gd_actionEditor.h" +#include "../../../dialogs/gd_warnings.h" +#include "../../../dialogs/gd_browser.h" +#include "../../../dialogs/midiIO/midiOutputSampleCh.h" +#include "../../../dialogs/midiIO/midiInputChannel.h" +#include "../../basics/boxtypes.h" +#include "channelStatus.h" +#include "channelMode.h" +#include "keyboard.h" #include "sampleChannel.h" extern Mixer G_Mixer; extern Conf G_Conf; extern Recorder G_Recorder; -extern Patch_DEPR_ G_Patch_DEPR_; extern gdMainWindow *G_MainWin; geSampleChannel::geSampleChannel(int X, int Y, int W, int H, SampleChannel *ch) - : geChannel(X, Y, W, H, CHANNEL_SAMPLE, ch) + : geChannel(X, Y, W, H, CHANNEL_SAMPLE, (Channel*) ch) { begin(); button = new gButton(x(), y(), 20, 20, "", channelStop_xpm, channelPlay_xpm); arm = new gClick(button->x()+button->w()+4, y(), 20, 20, "", armOff_xpm, armOn_xpm); - status = new gStatus(arm->x()+arm->w()+4, y(), 20, 20, ch); + status = new geChannelStatus(arm->x()+arm->w()+4, y(), 20, 20, ch); mainButton = new geSampleChannelButton(status->x()+status->w()+4, y(), 20, 20, "-- no sample --"); readActions = new gClick(mainButton->x()+mainButton->w()+4, y(), 20, 20, "", readActionOff_xpm, readActionOn_xpm); - modeBox = new gModeBox(readActions->x()+readActions->w()+4, y(), 20, 20, ch); + modeBox = new geChannelMode(readActions->x()+readActions->w()+4, y(), 20, 20, ch); mute = new gClick(modeBox->x()+modeBox->w()+4, y(), 20, 20, "", muteOff_xpm, muteOn_xpm); solo = new gClick(mute->x()+mute->w()+4, y(), 20, 20, "", soloOff_xpm, soloOn_xpm); #ifdef WITH_VST @@ -187,7 +185,7 @@ void geSampleChannel::__cb_openMenu() rclick_menu[11].deactivate(); Fl_Menu_Button *b = new Fl_Menu_Button(0, 0, 100, 50); - b->box(G_BOX); + b->box(G_CUSTOM_BORDER_BOX); b->textsize(GUI_FONT_SIZE_BASE); b->textcolor(COLOR_TEXT_0); b->color(COLOR_BG_0); @@ -196,7 +194,10 @@ void geSampleChannel::__cb_openMenu() if (!m) return; if (strcmp(m->label(), "Load new sample...") == 0) { - openBrowser(BROWSER_LOAD_SAMPLE); + gWindow *w = new gdLoadBrowser(G_Conf.browserX, G_Conf.browserY, + G_Conf.browserW, G_Conf.browserH, "Browse sample", + G_Conf.samplePath.c_str(), glue_loadSample, ch); + gu_openSubWindow(G_MainWin, w, WID_FILE_BROWSER); return; } @@ -221,7 +222,10 @@ void geSampleChannel::__cb_openMenu() } if (strcmp(m->label(), "Export sample to file...") == 0) { - openBrowser(BROWSER_SAVE_SAMPLE); + gWindow *w = new gdSaveBrowser(G_Conf.browserX, G_Conf.browserY, + G_Conf.browserW, G_Conf.browserH, "Save sample", \ + G_Conf.samplePath.c_str(), "", glue_saveSample, ch); + gu_openSubWindow(G_MainWin, w, WID_FILE_BROWSER); return; } @@ -263,6 +267,8 @@ void geSampleChannel::__cb_openMenu() if (!gdConfirmWin("Warning", "Clear all mute actions: are you sure?")) return; G_Recorder.clearAction(ch->index, ACTION_MUTEON | ACTION_MUTEOFF); + ch->hasActions = G_Recorder.hasActions(ch->index); + if (!ch->hasActions) hideActionButton(); @@ -276,6 +282,8 @@ void geSampleChannel::__cb_openMenu() if (!gdConfirmWin("Warning", "Clear all start/stop actions: are you sure?")) return; G_Recorder.clearAction(ch->index, ACTION_KEYPRESS | ACTION_KEYREL | ACTION_KILLCHAN); + ch->hasActions = G_Recorder.hasActions(ch->index); + if (!ch->hasActions) hideActionButton(); gu_refreshActionEditor(); // refresh a.editor window, it could be open @@ -286,6 +294,7 @@ void geSampleChannel::__cb_openMenu() if (!gdConfirmWin("Warning", "Clear all volume actions: are you sure?")) return; G_Recorder.clearAction(ch->index, ACTION_VOLUME); + ch->hasActions = G_Recorder.hasActions(ch->index); if (!ch->hasActions) hideActionButton(); gu_refreshActionEditor(); // refresh a.editor window, it could be open @@ -296,6 +305,7 @@ void geSampleChannel::__cb_openMenu() if (!gdConfirmWin("Warning", "Clear all actions: are you sure?")) return; G_Recorder.clearChan(ch->index); + ch->hasActions = false; hideActionButton(); gu_refreshActionEditor(); // refresh a.editor window, it could be open return; @@ -320,29 +330,6 @@ void geSampleChannel::__cb_readActions() /* -------------------------------------------------------------------------- */ -void geSampleChannel::openBrowser(int type) -{ - gWindow *childWin = NULL; - switch (type) { - case BROWSER_LOAD_SAMPLE: - childWin = new gdLoadBrowser(G_Conf.browserX, G_Conf.browserY, - G_Conf.browserW, G_Conf.browserH, "Browse sample", - G_Conf.samplePath.c_str(), glue_loadSample, ch); - break; - case BROWSER_SAVE_SAMPLE: - childWin = new gdSaveBrowser(G_Conf.browserX, G_Conf.browserY, - G_Conf.browserW, G_Conf.browserH, "Save sample", \ - G_Conf.samplePath.c_str(), "", glue_saveSample, ch); - break; - } - if (childWin) - gu_openSubWindow(G_MainWin, childWin, WID_FILE_BROWSER); -} - - -/* -------------------------------------------------------------------------- */ - - void geSampleChannel::refresh() { if (!mainButton->visible()) // mainButton invisible? status too (see below) @@ -354,7 +341,7 @@ void geSampleChannel::refresh() if (G_Mixer.recording && ch->armed) mainButton->setInputRecordMode(); if (G_Recorder.active) { - if (G_Recorder.canRec(ch)) + if (G_Recorder.canRec(ch, &G_Mixer)) mainButton->setActionRecordMode(); } status->redraw(); // status invisible? sampleButton too (see below) diff --git a/src/gui/elems/sampleChannel.h b/src/gui/elems/mainWindow/keyboard/sampleChannel.h similarity index 97% rename from src/gui/elems/sampleChannel.h rename to src/gui/elems/mainWindow/keyboard/sampleChannel.h index efde2a6..5c52151 100644 --- a/src/gui/elems/sampleChannel.h +++ b/src/gui/elems/mainWindow/keyboard/sampleChannel.h @@ -47,8 +47,6 @@ private: inline void __cb_openMenu (); inline void __cb_readActions (); - void openBrowser(int type); - public: geSampleChannel(int x, int y, int w, int h, class SampleChannel *ch); @@ -64,7 +62,7 @@ public: void showActionButton(); void hideActionButton(); - class gModeBox *modeBox; + class geChannelMode *modeBox; class gClick *readActions; }; diff --git a/src/gui/elems/mainWindow/mainIO.cpp b/src/gui/elems/mainWindow/mainIO.cpp new file mode 100644 index 0000000..7e61889 --- /dev/null +++ b/src/gui/elems/mainWindow/mainIO.cpp @@ -0,0 +1,180 @@ +/* ----------------------------------------------------------------------------- +* +* Giada - Your Hardcore Loopmachine +* +* mainIO +* +* ----------------------------------------------------------------------------- +* +* Copyright (C) 2010-2016 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 "../../../core/const.h" +#include "../../../core/graphics.h" +#include "../../../core/mixer.h" +#include "../../../core/pluginHost.h" +#include "../../../glue/main.h" +#include "../../../utils/gui.h" +#include "../../elems/ge_mixed.h" +#include "../../dialogs/gd_mainWindow.h" +#include "../../dialogs/gd_pluginList.h" +#include "mainIO.h" + + +extern Mixer G_Mixer; +extern gdMainWindow *G_MainWin; + + +geMainIO::geMainIO(int x, int y) + : Fl_Group(x, y, 396, 20) +{ + begin(); + +#if defined(WITH_VST) + masterFxIn = new gFxButton (x, y, 20, 20, fxOff_xpm, fxOn_xpm); + inVol = new gDial (masterFxIn->x()+masterFxIn->w()+4, y, 20, 20); + inMeter = new gSoundMeter(inVol->x()+inVol->w()+4, y+4, 140, 12); + inToOut = new gClick (inMeter->x()+inMeter->w()+4, y+4, 12, 12, "", inputToOutputOff_xpm, inputToOutputOn_xpm); + outMeter = new gSoundMeter(inToOut->x()+inToOut->w()+4, y+4, 140, 12); + outVol = new gDial (outMeter->x()+outMeter->w()+4, y, 20, 20); + masterFxOut = new gFxButton (outVol->x()+outVol->w()+4, y, 20, 20, fxOff_xpm, fxOn_xpm); +#else + inVol = new gDial (x+62, y, 20, 20); + inMeter = new gSoundMeter(inVol->x()+inVol->w()+4, y+5, 140, 12); + outMeter = new gSoundMeter(inMeter->x()+inMeter->w()+4, y+5, 140, 12); + outVol = new gDial (outMeter->x()+outMeter->w()+4, y, 20, 20); +#endif + + end(); + + resizable(NULL); // don't resize any widget + + outVol->callback(cb_outVol, (void*)this); + outVol->value(G_Mixer.outVol); + inVol->callback(cb_inVol, (void*)this); + inVol->value(G_Mixer.inVol); + +#ifdef WITH_VST + masterFxOut->callback(cb_masterFxOut, (void*)this); + masterFxIn->callback(cb_masterFxIn, (void*)this); + inToOut->callback(cb_inToOut, (void*)this); + inToOut->type(FL_TOGGLE_BUTTON); +#endif +} + + +/* -------------------------------------------------------------------------- */ + + +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(); } +#endif + + +/* -------------------------------------------------------------------------- */ + + +void geMainIO::__cb_outVol() +{ + glue_setOutVol(outVol->value()); +} + + +/* -------------------------------------------------------------------------- */ + + +void geMainIO::__cb_inVol() +{ + glue_setInVol(inVol->value()); +} + + +/* -------------------------------------------------------------------------- */ + + +#ifdef WITH_VST +void geMainIO::__cb_masterFxOut() +{ + gu_openSubWindow(G_MainWin, new gdPluginList(PluginHost::MASTER_OUT), WID_FX_LIST); +} + +void geMainIO::__cb_masterFxIn() +{ + gu_openSubWindow(G_MainWin, new gdPluginList(PluginHost::MASTER_IN), WID_FX_LIST); +} + +void geMainIO::__cb_inToOut() +{ + G_Mixer.inToOut = inToOut->value(); +} +#endif + + +/* -------------------------------------------------------------------------- */ + + +void geMainIO::setOutVol(float v) +{ + outVol->value(v); +} + + +void geMainIO::setInVol(float v) +{ + inVol->value(v); +} + + +/* -------------------------------------------------------------------------- */ + + +#ifdef WITH_VST + +void geMainIO::setMasterFxOutFull(bool v) +{ + masterFxOut->full = v; + masterFxOut->redraw(); +} + + +void geMainIO::setMasterFxInFull(bool v) +{ + masterFxIn->full = v; + masterFxIn->redraw(); +} + +#endif + + +/* -------------------------------------------------------------------------- */ + + +void geMainIO::refresh() +{ + outMeter->mixerPeak = G_Mixer.peakOut; + inMeter->mixerPeak = G_Mixer.peakIn; + outMeter->redraw(); + inMeter->redraw(); +} diff --git a/src/gui/elems/mainWindow/mainIO.h b/src/gui/elems/mainWindow/mainIO.h new file mode 100644 index 0000000..f275211 --- /dev/null +++ b/src/gui/elems/mainWindow/mainIO.h @@ -0,0 +1,81 @@ +/* ----------------------------------------------------------------------------- + * + * Giada - Your Hardcore Loopmachine + * + * mainIO + * + * ----------------------------------------------------------------------------- + * + * Copyright (C) 2010-2016 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 GE_MAIN_IO_H +#define GE_MAIN_IO_H + + +#include + + +class geMainIO : public Fl_Group +{ +private: + + class gSoundMeter *outMeter; + class gSoundMeter *inMeter; + class gDial *outVol; + class gDial *inVol; +#ifdef WITH_VST + class gFxButton *masterFxOut; + class gFxButton *masterFxIn; + class gClick *inToOut; +#endif + + 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); +#endif + + inline void __cb_outVol (); + inline void __cb_inVol (); +#ifdef WITH_VST + inline void __cb_masterFxOut(); + inline void __cb_masterFxIn (); + inline void __cb_inToOut (); +#endif + +public: + + geMainIO(int x, int y); + + void refresh(); + + void setOutVol(float v); + void setInVol (float v); +#ifdef WITH_VST + void setMasterFxOutFull(bool v); + void setMasterFxInFull(bool v); +#endif +}; + +#endif diff --git a/src/gui/elems/mainWindow/mainMenu.cpp b/src/gui/elems/mainWindow/mainMenu.cpp new file mode 100644 index 0000000..5c9a0f4 --- /dev/null +++ b/src/gui/elems/mainWindow/mainMenu.cpp @@ -0,0 +1,229 @@ +/* ----------------------------------------------------------------------------- + * + * Giada - Your Hardcore Loopmachine + * + * mainMenu + * + * ----------------------------------------------------------------------------- + * + * Copyright (C) 2010-2016 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 "../../../core/const.h" +#include "../../../core/mixer.h" +#include "../../../core/conf.h" +#include "../../../core/patch.h" +#include "../../../core/channel.h" +#include "../../../core/sampleChannel.h" +#include "../../../utils/gui.h" +#include "../../../glue/storage.h" +#include "../../../glue/main.h" +#include "../../elems/ge_mixed.h" +#include "../../elems/basics/boxtypes.h" +#include "../../dialogs/gd_mainWindow.h" +#include "../../dialogs/gd_about.h" +#include "../../dialogs/gd_config.h" +#include "../../dialogs/gd_browser.h" +#include "../../dialogs/gd_warnings.h" +#include "../../dialogs/midiIO/midiInputMaster.h" +#include "keyboard/keyboard.h" +#include "mainMenu.h" + + +extern Mixer G_Mixer; +extern Patch G_Patch; +extern Conf G_Conf; +extern gdMainWindow *G_MainWin; + + +geMainMenu::geMainMenu(int x, int y) + : Fl_Group(x, y, 300, 20) +{ + begin(); + + file = new gClick(x, y, 70, 21, "file"); + edit = new gClick(file->x()+file->w()+4, y, 70, 21, "edit"); + config = new gClick(edit->x()+edit->w()+4, y, 70, 21, "config"); + about = new gClick(config->x()+config->w()+4, y, 70, 21, "about"); + + end(); + + resizable(NULL); // don't resize any widget + + about->callback(cb_about, (void*)this); + file->callback(cb_file, (void*)this); + edit->callback(cb_edit, (void*)this); + config->callback(cb_config, (void*)this); +} + + +/* -------------------------------------------------------------------------- */ + + +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() +{ + gu_openSubWindow(G_MainWin, new gdAbout(), WID_ABOUT); +} + + +/* -------------------------------------------------------------------------- */ + + +void geMainMenu::__cb_config() +{ + gu_openSubWindow(G_MainWin, new gdConfig(380, 370), WID_CONFIG); +} + + +/* -------------------------------------------------------------------------- */ + + +void geMainMenu::__cb_file() +{ + /* An Fl_Menu_Button is made of many Fl_Menu_Item */ + + Fl_Menu_Item menu[] = { + {"Open patch or project..."}, + {"Save patch..."}, + {"Save project..."}, + {"Quit Giada"}, + {0} + }; + + Fl_Menu_Button *b = new Fl_Menu_Button(0, 0, 100, 50); + b->box(G_CUSTOM_BORDER_BOX); + b->textsize(GUI_FONT_SIZE_BASE); + b->textcolor(COLOR_TEXT_0); + b->color(COLOR_BG_0); + + const Fl_Menu_Item *m = menu->popup(Fl::event_x(), Fl::event_y(), 0, 0, b); + if (!m) return; + + if (strcmp(m->label(), "Open patch or project...") == 0) { + gWindow *childWin = new gdLoadBrowser(G_Conf.browserX, G_Conf.browserY, + G_Conf.browserW, G_Conf.browserH, "Load patch or project", + G_Conf.patchPath, glue_loadPatch, NULL); + gu_openSubWindow(G_MainWin, childWin, WID_FILE_BROWSER); + return; + } + if (strcmp(m->label(), "Save patch...") == 0) { + if (G_Mixer.hasLogicalSamples() || G_Mixer.hasEditedSamples()) + if (!gdConfirmWin("Warning", "You should save a project in order to store\nyour takes and/or processed samples.")) + return; + gWindow *childWin = new gdSaveBrowser(G_Conf.browserX, G_Conf.browserY, + G_Conf.browserW, G_Conf.browserH, "Save patch", + G_Conf.patchPath, G_Patch.name, glue_savePatch, NULL); + gu_openSubWindow(G_MainWin, childWin, WID_FILE_BROWSER); + return; + } + if (strcmp(m->label(), "Save project...") == 0) { + gWindow *childWin = new gdSaveBrowser(G_Conf.browserX, G_Conf.browserY, + G_Conf.browserW, G_Conf.browserH, "Save project", + G_Conf.patchPath, G_Patch.name, glue_saveProject, NULL); + gu_openSubWindow(G_MainWin, childWin, WID_FILE_BROWSER); + return; + } + if (strcmp(m->label(), "Quit Giada") == 0) { + G_MainWin->do_callback(); + return; + } +} + + +/* -------------------------------------------------------------------------- */ + + +void geMainMenu::__cb_edit() +{ + Fl_Menu_Item menu[] = { + {"Clear all samples"}, + {"Clear all actions"}, + {"Remove empty columns"}, + {"Reset to init state"}, + {"Setup global MIDI input..."}, + {0} + }; + + /* clear all actions disabled if no recs, clear all samples disabled + * if no samples. */ + + menu[1].deactivate(); + + for (unsigned i=0; ihasActions) { + menu[1].activate(); + break; + } + for (unsigned i=0; itype == CHANNEL_SAMPLE) + if (((SampleChannel*)G_Mixer.channels.at(i))->wave != NULL) { + menu[0].activate(); + break; + } + + Fl_Menu_Button *b = new Fl_Menu_Button(0, 0, 100, 50); + b->box(G_CUSTOM_BORDER_BOX); + b->textsize(GUI_FONT_SIZE_BASE); + b->textcolor(COLOR_TEXT_0); + b->color(COLOR_BG_0); + + const Fl_Menu_Item *m = menu->popup(Fl::event_x(), Fl::event_y(), 0, 0, b); + if (!m) return; + + if (strcmp(m->label(), "Clear all samples") == 0) { + if (!gdConfirmWin("Warning", "Clear all samples: are you sure?")) + return; + G_MainWin->delSubWindow(WID_SAMPLE_EDITOR); + glue_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_clearAllRecs(); + return; + } + if (strcmp(m->label(), "Reset to init state") == 0) { + if (!gdConfirmWin("Warning", "Reset to init state: are you sure?")) + return; + gu_closeAllSubwindows(); + glue_resetToInitState(); + return; + } + if (strcmp(m->label(), "Remove empty columns") == 0) { + G_MainWin->keyboard->organizeColumns(); + return; + } + if (strcmp(m->label(), "Setup global MIDI input...") == 0) { + gu_openSubWindow(G_MainWin, new gdMidiInputMaster(), 0); + return; + } +} diff --git a/src/gui/elems/mainWindow/mainMenu.h b/src/gui/elems/mainWindow/mainMenu.h new file mode 100644 index 0000000..a8e6f4f --- /dev/null +++ b/src/gui/elems/mainWindow/mainMenu.h @@ -0,0 +1,62 @@ +/* ----------------------------------------------------------------------------- + * + * Giada - Your Hardcore Loopmachine + * + * mainMenu + * + * ----------------------------------------------------------------------------- + * + * Copyright (C) 2010-2016 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 GE_MAIN_MENU_H +#define GE_MAIN_MENU_H + + +#include + + +class geMainMenu : public Fl_Group +{ +private: + + class gClick *file; + class gClick *edit; + class gClick *config; + class gClick *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); + + inline void __cb_about (); + inline void __cb_config(); + inline void __cb_file (); + inline void __cb_edit (); + +public: + + geMainMenu(int x, int y); +}; + + +#endif diff --git a/src/gui/elems/mainWindow/mainTimer.cpp b/src/gui/elems/mainWindow/mainTimer.cpp new file mode 100644 index 0000000..e1c0d94 --- /dev/null +++ b/src/gui/elems/mainWindow/mainTimer.cpp @@ -0,0 +1,180 @@ +/* ----------------------------------------------------------------------------- + * + * Giada - Your Hardcore Loopmachine + * + * mainTimer + * + * ----------------------------------------------------------------------------- + * + * Copyright (C) 2010-2016 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 "../../../core/const.h" +#include "../../../core/mixer.h" +#include "../../../core/graphics.h" +#include "../../../glue/main.h" +#include "../../../utils/gui.h" +#include "../../elems/ge_mixed.h" +#include "../../dialogs/gd_mainWindow.h" +#include "../../dialogs/gd_bpmInput.h" +#include "../../dialogs/gd_beatsInput.h" +#include "mainTimer.h" + + +extern Mixer G_Mixer; +extern gdMainWindow *G_MainWin; + + +geMainTimer::geMainTimer(int x, int y) + : Fl_Group(x, y, 180, 20) +{ + begin(); + + quantizer = new gChoice(x, y, 40, 20, "", false); + bpm = new gClick (quantizer->x()+quantizer->w()+4, y, 40, 20); + meter = new gClick (bpm->x()+bpm->w()+8, y, 40, 20, "4/1"); + multiplier = new gClick (meter->x()+meter->w()+4, y, 20, 20, "", multiplyOff_xpm, multiplyOn_xpm); + divider = new gClick (multiplier->x()+multiplier->w()+4, y, 20, 20, "", divideOff_xpm, divideOn_xpm); + + end(); + + resizable(NULL); // don't resize any widget + + char buf[6]; snprintf(buf, 6, "%f", G_Mixer.bpm); + bpm->copy_label(buf); + + bpm->callback(cb_bpm, (void*)this); + meter->callback(cb_meter, (void*)this); + multiplier->callback(cb_multiplier, (void*)this); + divider->callback(cb_divider, (void*)this); + + quantizer->add("off", 0, cb_quantizer, (void*)this); + quantizer->add("1b", 0, cb_quantizer, (void*)this); + quantizer->add("2b", 0, cb_quantizer, (void*)this); + quantizer->add("3b", 0, cb_quantizer, (void*)this); + quantizer->add("4b", 0, cb_quantizer, (void*)this); + quantizer->add("6b", 0, cb_quantizer, (void*)this); + quantizer->add("8b", 0, cb_quantizer, (void*)this); + quantizer->value(0); // "off" by default +} + + +/* -------------------------------------------------------------------------- */ + + +void geMainTimer::cb_bpm (Fl_Widget *v, void *p) { ((geMainTimer*)p)->__cb_bpm(); } +void geMainTimer::cb_meter (Fl_Widget *v, void *p) { ((geMainTimer*)p)->__cb_meter(); } +void geMainTimer::cb_quantizer (Fl_Widget *v, void *p) { ((geMainTimer*)p)->__cb_quantizer(); } +void geMainTimer::cb_multiplier(Fl_Widget *v, void *p) { ((geMainTimer*)p)->__cb_multiplier(); } +void geMainTimer::cb_divider (Fl_Widget *v, void *p) { ((geMainTimer*)p)->__cb_divider(); } + + +/* -------------------------------------------------------------------------- */ + + +void geMainTimer::__cb_bpm() +{ + gu_openSubWindow(G_MainWin, new gdBpmInput(bpm->label()), WID_BPM); +} + + +/* -------------------------------------------------------------------------- */ + + +void geMainTimer::__cb_meter() +{ + gu_openSubWindow(G_MainWin, new gdBeatsInput(), WID_BEATS); +} + + +/* -------------------------------------------------------------------------- */ + + +void geMainTimer::__cb_quantizer() +{ + glue_quantize(quantizer->value()); +} + + +/* -------------------------------------------------------------------------- */ + + +void geMainTimer::__cb_multiplier() +{ + glue_beatsMultiply(); +} + + +/* -------------------------------------------------------------------------- */ + + +void geMainTimer::__cb_divider() +{ + glue_beatsDivide(); +} + + +/* -------------------------------------------------------------------------- */ + + +void geMainTimer::setBpm(const char *v) +{ + bpm->copy_label(v); +} + + +void geMainTimer::setBpm(float v) +{ + char buf[6]; + sprintf(buf, "%.01f", v); // only 1 decimal place (e.g. 120.0) + bpm->copy_label(buf); +} + + +/* -------------------------------------------------------------------------- */ + + +void geMainTimer::setLock(bool v) +{ + if (v) { + bpm->deactivate(); + meter->deactivate(); + multiplier->deactivate(); + divider->deactivate(); + } + else { + bpm->activate(); + meter->activate(); + multiplier->activate(); + divider->activate(); + } +} + + +/* -------------------------------------------------------------------------- */ + + +void geMainTimer::setMeter(int beats, int bars) +{ + char buf[8]; + sprintf(buf, "%d/%d", beats, bars); + meter->copy_label(buf); +} diff --git a/src/gui/elems/mainWindow/mainTimer.h b/src/gui/elems/mainWindow/mainTimer.h new file mode 100644 index 0000000..8be1d82 --- /dev/null +++ b/src/gui/elems/mainWindow/mainTimer.h @@ -0,0 +1,74 @@ +/* ----------------------------------------------------------------------------- + * + * Giada - Your Hardcore Loopmachine + * + * mainTimer + * + * ----------------------------------------------------------------------------- + * + * Copyright (C) 2010-2016 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 GE_MAIN_TIMER_H +#define GE_MAIN_TIMER_H + + +#include + + +class geMainTimer : public Fl_Group +{ +private: + + class gClick *bpm; + class gClick *meter; + class gChoice *quantizer; + class gClick *multiplier; + class gClick *divider; + + static void cb_bpm (Fl_Widget *v, void *p); + static void cb_meter (Fl_Widget *v, void *p); + static void cb_quantizer (Fl_Widget *v, void *p); + static void cb_multiplier(Fl_Widget *v, void *p); + static void cb_divider (Fl_Widget *v, void *p); + + inline void __cb_bpm(); + inline void __cb_meter(); + inline void __cb_quantizer(); + inline void __cb_multiplier(); + inline void __cb_divider(); + +public: + + geMainTimer(int x, int y); + + void setBpm(const char *v); + void setBpm(float v); + void setMeter(int beats, int bars); + + /* setLock + Locks bpm, beter and multipliers. Used during audio recordings. */ + + void setLock(bool v); +}; + + +#endif diff --git a/src/gui/elems/ge_controller.cpp b/src/gui/elems/mainWindow/mainTransport.cpp similarity index 74% rename from src/gui/elems/ge_controller.cpp rename to src/gui/elems/mainWindow/mainTransport.cpp index 9ff5f25..9b54c22 100644 --- a/src/gui/elems/ge_controller.cpp +++ b/src/gui/elems/mainWindow/mainTransport.cpp @@ -1,7 +1,8 @@ /* ----------------------------------------------------------------------------- * * Giada - Your Hardcore Loopmachine - * ge_controller + * + * mainTransport * * ----------------------------------------------------------------------------- * @@ -26,14 +27,14 @@ * -------------------------------------------------------------------------- */ -#include "../../core/graphics.h" -#include "../../glue/main.h" -#include "../../glue/io.h" -#include "ge_mixed.h" -#include "ge_controller.h" +#include "../../../core/graphics.h" +#include "../../../glue/main.h" +#include "../../../glue/io.h" +#include "../ge_mixed.h" +#include "mainTransport.h" -gController::gController(int x, int y) +geMainTransport::geMainTransport(int x, int y) : Fl_Group(x, y, 131, 25) { begin(); @@ -67,17 +68,17 @@ gController::gController(int x, int y) /* -------------------------------------------------------------------------- */ -void gController::cb_rewind (Fl_Widget *v, void *p) { ((gController*)p)->__cb_rewind(); } -void gController::cb_play (Fl_Widget *v, void *p) { ((gController*)p)->__cb_play(); } -void gController::cb_recAction(Fl_Widget *v, void *p) { ((gController*)p)->__cb_recAction(); } -void gController::cb_recInput (Fl_Widget *v, void *p) { ((gController*)p)->__cb_recInput(); } -void gController::cb_metronome(Fl_Widget *v, void *p) { ((gController*)p)->__cb_metronome(); } +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 gController::__cb_rewind() +void geMainTransport::__cb_rewind() { glue_rewindSeq(); } @@ -86,7 +87,7 @@ void gController::__cb_rewind() /* -------------------------------------------------------------------------- */ -void gController::__cb_play() +void geMainTransport::__cb_play() { glue_startStopSeq(true); } @@ -95,7 +96,7 @@ void gController::__cb_play() /* -------------------------------------------------------------------------- */ -void gController::__cb_recAction() +void geMainTransport::__cb_recAction() { glue_startStopActionRec(true); } @@ -104,7 +105,7 @@ void gController::__cb_recAction() /* -------------------------------------------------------------------------- */ -void gController::__cb_recInput() +void geMainTransport::__cb_recInput() { glue_startStopInputRec(true); } @@ -113,7 +114,7 @@ void gController::__cb_recInput() /* -------------------------------------------------------------------------- */ -void gController::__cb_metronome() +void geMainTransport::__cb_metronome() { glue_startStopMetronome(true); } @@ -122,7 +123,7 @@ void gController::__cb_metronome() /* -------------------------------------------------------------------------- */ -void gController::updatePlay(int v) +void geMainTransport::updatePlay(int v) { play->value(v); play->redraw(); @@ -132,7 +133,7 @@ void gController::updatePlay(int v) /* -------------------------------------------------------------------------- */ -void gController::updateMetronome(int v) +void geMainTransport::updateMetronome(int v) { metronome->value(v); metronome->redraw(); @@ -142,7 +143,7 @@ void gController::updateMetronome(int v) /* -------------------------------------------------------------------------- */ -void gController::updateRecInput(int v) +void geMainTransport::updateRecInput(int v) { recInput->value(v); recInput->redraw(); @@ -152,7 +153,7 @@ void gController::updateRecInput(int v) /* -------------------------------------------------------------------------- */ -void gController::updateRecAction(int v) +void geMainTransport::updateRecAction(int v) { recAction->value(v); recAction->redraw(); diff --git a/src/gui/elems/ge_controller.h b/src/gui/elems/mainWindow/mainTransport.h similarity index 92% rename from src/gui/elems/ge_controller.h rename to src/gui/elems/mainWindow/mainTransport.h index 4c4aa6c..57b83e3 100644 --- a/src/gui/elems/ge_controller.h +++ b/src/gui/elems/mainWindow/mainTransport.h @@ -1,7 +1,8 @@ /* ----------------------------------------------------------------------------- * * Giada - Your Hardcore Loopmachine - * ge_controller + * + * mainTransport * * ----------------------------------------------------------------------------- * @@ -26,14 +27,14 @@ * -------------------------------------------------------------------------- */ -#ifndef GE_CONTROLLER_H -#define GE_CONTROLLER_H +#ifndef GE_MAIN_TRANSPORT_H +#define GE_MAIN_TRANSPORT_H #include -class gController : public Fl_Group +class geMainTransport : public Fl_Group { private: @@ -57,7 +58,7 @@ private: public: - gController(int x, int y); + geMainTransport(int x, int y); void updatePlay (int v); void updateMetronome(int v); diff --git a/src/gui/elems/ge_midiIoTools.cpp b/src/gui/elems/midiLearner.cpp similarity index 73% rename from src/gui/elems/ge_midiIoTools.cpp rename to src/gui/elems/midiLearner.cpp index 8c20101..f63b208 100644 --- a/src/gui/elems/ge_midiIoTools.cpp +++ b/src/gui/elems/midiLearner.cpp @@ -2,7 +2,7 @@ * * Giada - Your Hardcore Loopmachine * - * ge_midiIoTools + * midiLearner * * ----------------------------------------------------------------------------- * @@ -28,28 +28,29 @@ #include "ge_mixed.h" -#include "ge_midiIoTools.h" +#include "basics/boxtypes.h" +#include "midiLearner.h" -extern KernelMidi G_KernelMidi; +extern KernelMidi G_KernelMidi; -gLearner::gLearner(int X, int Y, int W, const char *l, KernelMidi::cb_midiLearn *cb, - uint32_t *param) +geMidiLearner::geMidiLearner(int X, int Y, int W, const char *l, + KernelMidi::cb_midiLearn *cb, uint32_t *param) : Fl_Group(X, Y, W, 20), callback(cb), param (param) { begin(); text = new gBox(x(), y(), 156, 20, l); - value = new gClick(text->x()+text->w()+4, y(), 80, 20, "(not set)"); + value = new gClick(text->x()+text->w()+4, y(), 80, 20); button = new gButton(value->x()+value->w()+4, y(), 40, 20, "learn"); end(); - text->box(G_BOX); + text->box(G_CUSTOM_BORDER_BOX); text->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE); - value->box(G_BOX); + value->box(G_CUSTOM_BORDER_BOX); value->callback(cb_value, (void*)this); value->when(FL_WHEN_RELEASE); updateValue(); @@ -62,7 +63,8 @@ gLearner::gLearner(int X, int Y, int W, const char *l, KernelMidi::cb_midiLearn /* -------------------------------------------------------------------------- */ -void gLearner::updateValue() { +void geMidiLearner::updateValue() +{ char buf[16]; if (*param != 0x0) snprintf(buf, 9, "0x%X", *param); @@ -76,14 +78,15 @@ void gLearner::updateValue() { /* -------------------------------------------------------------------------- */ -void gLearner::cb_button(Fl_Widget *v, void *p) { ((gLearner*)p)->__cb_button(); } -void gLearner::cb_value(Fl_Widget *v, void *p) { ((gLearner*)p)->__cb_value(); } +void geMidiLearner::cb_button(Fl_Widget *v, void *p) { ((geMidiLearner*)p)->__cb_button(); } +void geMidiLearner::cb_value(Fl_Widget *v, void *p) { ((geMidiLearner*)p)->__cb_value(); } /* -------------------------------------------------------------------------- */ -void gLearner::__cb_value() { +void geMidiLearner::__cb_value() +{ if (Fl::event_button() == FL_RIGHT_MOUSE) { *param = 0x0; updateValue(); @@ -95,14 +98,12 @@ void gLearner::__cb_value() { /* -------------------------------------------------------------------------- */ -/* FIXME - do not malloc on each callback! do it on the constructor! */ - -void gLearner::__cb_button() { +void geMidiLearner::__cb_button() +{ if (button->value() == 1) { - cbData *data = (cbData*) malloc(sizeof(cbData)); - data->window = (gdMidiInput*) parent(); // parent = gdMidiGrabberChannel - data->learner = this; - G_KernelMidi.startMidiLearn(callback, (void*)data); + cbData.window = (gdMidiInput*) parent(); // parent = gdMidiInput + cbData.learner = this; + G_KernelMidi.startMidiLearn(callback, (void*)&cbData); } else G_KernelMidi.stopMidiLearn(); diff --git a/src/gui/elems/ge_midiIoTools.h b/src/gui/elems/midiLearner.h similarity index 72% rename from src/gui/elems/ge_midiIoTools.h rename to src/gui/elems/midiLearner.h index 0712937..9d5b0a0 100644 --- a/src/gui/elems/ge_midiIoTools.h +++ b/src/gui/elems/midiLearner.h @@ -2,7 +2,7 @@ * * Giada - Your Hardcore Loopmachine * - * ge_midiIoTools + * midiLearner * * ----------------------------------------------------------------------------- * @@ -33,13 +33,12 @@ #include #include "../../core/kernelMidi.h" -#include "../dialogs/gd_midiInput.h" extern KernelMidi G_KernelMidi; -class gLearner : public Fl_Group +class geMidiLearner : public Fl_Group { private: @@ -61,34 +60,25 @@ private: public: + /* cbData_t + * struct we pass to kernelMidi as extra parameter. */ + + struct cbData_t + { + class gdMidiInput *window; + class geMidiLearner *learner; + } cbData; + /* param * pointer to ch->midiIn[value] */ uint32_t *param; - gLearner(int x, int y, int w, const char *l, KernelMidi::cb_midiLearn *cb, uint32_t *param); + geMidiLearner(int x, int y, int w, const char *l, KernelMidi::cb_midiLearn *cb, + uint32_t *param); void updateValue(); }; -/* -------------------------------------------------------------------------- */ - - -/* cbData - * struct we pass to kernelMidi as extra parameter. Local scope made - * with unnamed namespace. Infos: - * http://stackoverflow.com/questions/4422507/superiority-of-unnamed-namespace-over-static */ - -/* TODO - instead of the unnamed namespace, why don't we make the struct as a -(static) member of gLearner? */ - -namespace { - struct cbData { - gdMidiInput *window; - gLearner *learner; - }; -} - - #endif diff --git a/src/gui/elems/muteEditor.cpp b/src/gui/elems/muteEditor.cpp index e2861b2..1c9ae3b 100644 --- a/src/gui/elems/muteEditor.cpp +++ b/src/gui/elems/muteEditor.cpp @@ -32,7 +32,7 @@ #include "../../utils/log.h" #include "../dialogs/gd_actionEditor.h" #include "../dialogs/gd_mainWindow.h" -#include "ge_keyboard.h" +#include "mainWindow/keyboard/keyboard.h" #include "muteEditor.h" @@ -253,6 +253,7 @@ int geMuteEditor::handle(int e) { G_Recorder.rec(pParent->chan->index, ACTION_MUTEON, frame_a); G_Recorder.rec(pParent->chan->index, ACTION_MUTEOFF, frame_b); } + pParent->chan->hasActions = true; G_Recorder.sortActions(); G_MainWin->keyboard->setChannelWithActions((geSampleChannel*)pParent->chan->guiChannel); // update mainWindow @@ -281,9 +282,13 @@ int geMuteEditor::handle(int e) { //gu_log("selected: a=%d, b=%d >>> frame_a=%d, frame_b=%d\n", // a, b, points.at(a).frame, points.at(b).frame); - G_Recorder.deleteAction(pParent->chan->index, points.at(a).frame, points.at(a).type, false); // false = don't check vals - G_Recorder.deleteAction(pParent->chan->index, points.at(b).frame, points.at(b).type, false); // false = don't check vals - G_Recorder.sortActions(); + G_Recorder.deleteAction(pParent->chan->index, points.at(a).frame, + points.at(a).type, false, &G_Mixer.mutex_recs); // false = don't check vals + G_Recorder.deleteAction(pParent->chan->index, points.at(b).frame, + points.at(b).type, false, &G_Mixer.mutex_recs); // false = don't check vals + pParent->chan->hasActions = G_Recorder.hasActions(pParent->chan->index); + + G_Recorder.sortActions(); G_MainWin->keyboard->setChannelWithActions((geSampleChannel*)pParent->chan->guiChannel); // update mainWindow extractPoints(); @@ -305,17 +310,17 @@ int geMuteEditor::handle(int e) { int newFrame = points.at(draggedPoint).x * pParent->zoom; - G_Recorder.deleteAction( - pParent->chan->index, - points.at(draggedPoint).frame, - points.at(draggedPoint).type, - false); // don't check values + G_Recorder.deleteAction(pParent->chan->index, + points.at(draggedPoint).frame, points.at(draggedPoint).type, false, + &G_Mixer.mutex_recs); // don't check values + pParent->chan->hasActions = G_Recorder.hasActions(pParent->chan->index); G_Recorder.rec( pParent->chan->index, points.at(draggedPoint).type, newFrame); + pParent->chan->hasActions = true; G_Recorder.sortActions(); points.at(draggedPoint).frame = newFrame; diff --git a/src/gui/elems/pianoItem.cpp b/src/gui/elems/pianoItem.cpp index 870b61a..c6449cb 100644 --- a/src/gui/elems/pianoItem.cpp +++ b/src/gui/elems/pianoItem.cpp @@ -143,6 +143,7 @@ void gePianoItem::record() G_Recorder.rec(pParent->chan->index, ACTION_MIDI, frame_a, event_a); G_Recorder.rec(pParent->chan->index, ACTION_MIDI, frame_b, event_b); + pParent->chan->hasActions = true; } @@ -151,8 +152,10 @@ void gePianoItem::record() void gePianoItem::remove() { - G_Recorder.deleteAction(pParent->chan->index, frame_a, ACTION_MIDI, true, event_a, 0.0); - G_Recorder.deleteAction(pParent->chan->index, frame_b, ACTION_MIDI, true, event_b, 0.0); + G_Recorder.deleteAction(pParent->chan->index, frame_a, ACTION_MIDI, true, + &G_Mixer.mutex_recs, event_a, 0.0); + G_Recorder.deleteAction(pParent->chan->index, frame_b, ACTION_MIDI, true, + &G_Mixer.mutex_recs, event_b, 0.0); /* send a note-off in case we are deleting it in a middle of a key_on * key_off sequence. */ diff --git a/src/utils/gui.cpp b/src/utils/gui.cpp index 5daf5d5..715126d 100644 --- a/src/utils/gui.cpp +++ b/src/utils/gui.cpp @@ -38,9 +38,13 @@ #include "../gui/dialogs/gd_warnings.h" #include "../gui/dialogs/gd_mainWindow.h" #include "../gui/dialogs/gd_actionEditor.h" -#include "../gui/elems/ge_keyboard.h" #include "../gui/elems/ge_window.h" -#include "../gui/elems/channel.h" +#include "../gui/elems/mainWindow/mainIO.h" +#include "../gui/elems/mainWindow/mainTimer.h" +#include "../gui/elems/mainWindow/mainTransport.h" +#include "../gui/elems/mainWindow/beatMeter.h" +#include "../gui/elems/mainWindow/keyboard/keyboard.h" +#include "../gui/elems/mainWindow/keyboard/channel.h" #include "log.h" #include "string.h" #include "gui.h" @@ -68,7 +72,7 @@ void gu_refreshUI() /* update dynamic elements: in and out meters, beat meter and * each channel */ - G_MainWin->inOut->refresh(); + G_MainWin->mainIO->refresh(); G_MainWin->beatMeter->redraw(); G_MainWin->keyboard->refreshColumns(); @@ -102,18 +106,18 @@ void gu_updateControls() for (unsigned i=0; iguiChannel->update(); - G_MainWin->inOut->setOutVol(G_Mixer.outVol); - G_MainWin->inOut->setInVol(G_Mixer.inVol); + G_MainWin->mainIO->setOutVol(G_Mixer.outVol); + G_MainWin->mainIO->setInVol(G_Mixer.inVol); #ifdef WITH_VST - G_MainWin->inOut->setMasterFxOutFull(G_PluginHost.getStack(PluginHost::MASTER_OUT)->size() > 0); - G_MainWin->inOut->setMasterFxInFull(G_PluginHost.getStack(PluginHost::MASTER_IN)->size() > 0); + G_MainWin->mainIO->setMasterFxOutFull(G_PluginHost.getStack(PluginHost::MASTER_OUT)->size() > 0); + G_MainWin->mainIO->setMasterFxInFull(G_PluginHost.getStack(PluginHost::MASTER_IN)->size() > 0); #endif - G_MainWin->timing->setMeter(G_Mixer.beats, G_Mixer.bars); - G_MainWin->timing->setBpm(G_Mixer.bpm); + G_MainWin->mainTimer->setMeter(G_Mixer.beats, G_Mixer.bars); + G_MainWin->mainTimer->setBpm(G_Mixer.bpm); - G_MainWin->controller->updatePlay(G_Mixer.running); - G_MainWin->controller->updateMetronome(G_Mixer.metronome); + G_MainWin->mainTransport->updatePlay(G_Mixer.running); + G_MainWin->mainTransport->updateMetronome(G_Mixer.metronome); } -- 2.30.2