From 1313e65584dd0ed4c072301fa97c044e008e328d Mon Sep 17 00:00:00 2001 From: =?utf8?q?IOhannes=20m=20zm=C3=B6lnig?= Date: Thu, 22 Mar 2018 14:17:44 +0100 Subject: [PATCH] New upstream version 0.14.6~dfsg1 --- .travis/script.sh | 11 +- ChangeLog | 13 + Makefile.am | 35 ++- configure.ac | 11 + src/core/channel.cpp | 27 +- src/core/channel.h | 12 +- src/core/conf.cpp | 9 +- src/core/const.h | 17 +- src/core/init.cpp | 3 +- src/core/kernelAudio.cpp | 14 +- src/core/midiDispatcher.cpp | 22 +- src/core/patch.cpp | 2 + src/core/patch.h | 31 +- src/core/sampleChannel.cpp | 15 +- src/core/sampleChannel.h | 10 +- src/core/wave.h | 16 +- src/glue/channel.cpp | 112 ++++--- src/glue/channel.h | 57 ++-- src/glue/io.cpp | 287 ++++++++++-------- src/glue/io.h | 31 +- src/glue/sampleEditor.cpp | 27 +- src/glue/storage.cpp | 30 +- src/gui/dialogs/browser/browserBase.cpp | 19 +- src/gui/dialogs/channelNameInput.cpp | 10 +- src/gui/dialogs/gd_mainWindow.cpp | 14 +- src/gui/dialogs/gd_mainWindow.h | 18 +- src/gui/dialogs/midiIO/midiInputChannel.cpp | 29 +- src/gui/dialogs/midiIO/midiInputChannel.h | 3 + src/gui/dialogs/midiIO/midiOutputSampleCh.cpp | 4 +- src/gui/dialogs/midiIO/midiOutputSampleCh.h | 12 +- src/gui/dialogs/sampleEditor.cpp | 35 ++- src/gui/elems/browser.cpp | 48 +-- src/gui/elems/browser.h | 12 +- src/gui/elems/config/tabAudio.cpp | 2 + src/gui/elems/config/tabBehaviors.cpp | 1 + src/gui/elems/config/tabMidi.cpp | 1 + src/gui/elems/config/tabMisc.cpp | 1 + src/gui/elems/config/tabPlugins.cpp | 1 + src/gui/elems/mainWindow/keyboard/channel.cpp | 12 +- src/gui/elems/mainWindow/keyboard/column.cpp | 7 +- .../elems/mainWindow/keyboard/keyboard.cpp | 6 +- .../elems/mainWindow/keyboard/midiChannel.cpp | 13 +- .../mainWindow/keyboard/sampleChannel.cpp | 42 +-- .../elems/mainWindow/keyboard/sampleChannel.h | 10 +- .../keyboard/sampleChannelButton.cpp | 5 +- src/gui/elems/mainWindow/mainTransport.cpp | 6 +- src/gui/elems/sampleEditor/boostTool.cpp | 37 ++- src/gui/elems/sampleEditor/boostTool.h | 24 +- src/gui/elems/sampleEditor/panTool.cpp | 5 +- src/gui/elems/sampleEditor/pitchTool.cpp | 16 +- src/gui/elems/sampleEditor/volumeTool.cpp | 18 +- src/main.cpp | 19 +- src/utils/fs.cpp | 53 +++- src/utils/fs.h | 12 + src/utils/math.cpp | 14 +- src/utils/math.h | 19 +- src/utils/string.cpp | 6 +- src/utils/time.cpp | 13 +- tests/conf.cpp | 2 +- tests/main.cpp | 2 +- tests/midiMapConf.cpp | 2 +- tests/patch.cpp | 2 +- tests/pluginHost.cpp | 2 +- tests/recorder.cpp | 2 +- tests/utils.cpp | 78 +++-- tests/wave.cpp | 2 +- tests/waveFx.cpp | 2 +- tests/waveManager.cpp | 2 +- 68 files changed, 874 insertions(+), 561 deletions(-) diff --git a/.travis/script.sh b/.travis/script.sh index 49f67c4..af3c70e 100755 --- a/.travis/script.sh +++ b/.travis/script.sh @@ -2,4 +2,13 @@ make -j 2 make rename -make check -j 2 \ No newline at end of file + +if [[ $TRAVIS_OS_NAME == 'linux' ]]; then + + xvfb-run make check -j 2 + +else + + make check -j 2 + +fi \ No newline at end of file diff --git a/ChangeLog b/ChangeLog index dbca39f..76388e3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,19 @@ -------------------------------------------------------------------------------- +0.14.6 --- 2018 . 03 . 15 +- MIDI velocity drives volume for one-shot sample channels +- FLAC and Ogg support +- Ability to use system-provided Catch library (GitHub #151) +- Update Catch to version 2 +- Fix unreadable tabs title in Configuration Window (GitHub #168) +- Fix crash on opening About window +- Fix 'read actions' button behavior during ending and waiting statuses +- Fix sound card initialization on MacOS +- [Windows] Fix UI stuck on top-right corner +- [Windows] Fix browsing for directories + + 0.14.5 --- 2018 . 01 . 15 - OS X builds on Travis CI - AppImage executable for Linux diff --git a/Makefile.am b/Makefile.am index 3c2f529..9d0cfec 100644 --- a/Makefile.am +++ b/Makefile.am @@ -23,19 +23,25 @@ extraSources += \ src/deps/juce/modules/juce_gui_extra/juce_gui_extra.cpp cppFlags += \ - -I./src/deps/juce/modules \ - -I./src/deps/vst \ - -I/usr/include \ - -I/usr/include/freetype2 \ - -DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1 \ - -DJUCE_STANDALONE_APPLICATION=1 \ - -DJUCE_PLUGINHOST_VST=1 \ - -DJUCE_PLUGINHOST_VST3=0 \ - -DJUCE_PLUGINHOST_AU=0 \ + -I$(top_srcdir)/src/deps/juce/modules \ + -I$(top_srcdir)/src/deps/vst \ + -I/usr/include \ + -I/usr/include/freetype2 \ + -DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1 \ + -DJUCE_STANDALONE_APPLICATION=1 \ + -DJUCE_PLUGINHOST_VST=1 \ + -DJUCE_PLUGINHOST_VST3=0 \ + -DJUCE_PLUGINHOST_AU=0 \ -DJUCE_WEB_BROWSER=0 endif +if !WITH_SYSTEM_CATCH + +cppFlags += -I$(top_srcdir)/tests/catch2/single_include + +endif + if WINDOWS extraSources += \ @@ -50,9 +56,9 @@ extraSources += \ resource.rc cppFlags += \ - -I./src/deps/rtaudio-mod/include \ - -D__WINDOWS_ASIO__ \ - -D__WINDOWS_WASAPI__ \ + -I$(top_srcdir)/src/deps/rtaudio-mod/include \ + -D__WINDOWS_ASIO__ \ + -D__WINDOWS_WASAPI__ \ -D__WINDOWS_DS__ cxxFlags += -Wno-error @@ -60,7 +66,7 @@ cxxFlags += -Wno-error ldAdd += -ldsound -lwsock32 -lm -lfltk -lwininet -lgdi32 -lshell32 -lvfw32 \ -lrpcrt4 -luuid -lcomctl32 -lole32 -lws2_32 -lsndfile -lsamplerate -lrtmidi \ -lwinmm -lsetupapi -lksuser -ljansson -limm32 -lglu32 -lshell32 -lversion \ - -lopengl32 -loleaut32 -lshlwapi -lcomdlg32 + -lopengl32 -loleaut32 -lshlwapi -lcomdlg32 -lflac -lvorbis -logg -lvorbisenc # Generate a GUI application (-mwindows), make the build static (-static). ldFlags += -mwindows -static @@ -85,6 +91,9 @@ if OSX extraSources += src/utils/cocoa.mm src/utils/cocoa.h +# Add preprocessor flags to enable CoreAudio in RtAudio. +cppFlags += -D__MACOSX_CORE__ + # -ObjC++: Juce requires to build some Objective C code cxxFlags += -ObjC++ -Wno-auto-var-id diff --git a/configure.ac b/configure.ac index bc80952..9f6e959 100644 --- a/configure.ac +++ b/configure.ac @@ -55,6 +55,17 @@ AC_ARG_ENABLE( [AM_CONDITIONAL(WITH_VST, false)] ) +# ------------------------------------------------------------------------------ + +# --enable-system-catch. If enabled, use the system-provided Catch. Use bundled +# version otherwise (default mode). + +AC_ARG_ENABLE( + [system-catch], + AS_HELP_STRING([--enable-system-catch], [use system-provided Catch library]), + [AC_DEFINE(WITH_SYSTEM_CATCH) AM_CONDITIONAL(WITH_SYSTEM_CATCH, true)], + [AM_CONDITIONAL(WITH_SYSTEM_CATCH, false)] +) # ------------------------------------------------------------------------------ diff --git a/src/core/channel.cpp b/src/core/channel.cpp index b11f82c..a1dda46 100644 --- a/src/core/channel.cpp +++ b/src/core/channel.cpp @@ -54,13 +54,13 @@ Channel::Channel(int type, int status, int bufferSize) midiInFilter (-1), previewMode (G_PREVIEW_NONE), pan (0.5f), + volume (G_DEFAULT_VOL), + volume_i (1.0f), + volume_d (0.0f), armed (false), type (type), status (status), key (0), - volume (G_DEFAULT_VOL), - volume_i (1.0f), - volume_d (0.0f), mute_i (false), mute_s (false), mute (false), @@ -437,6 +437,27 @@ float Channel::getPan() const /* -------------------------------------------------------------------------- */ +void Channel::setVolume(float v) +{ + volume = v; +} + + +void Channel::setVolumeI(float v) +{ + volume_i = v; +} + + +float Channel::getVolume() const +{ + return volume; +} + + +/* -------------------------------------------------------------------------- */ + + float Channel::calcPanning(int ch) { if (pan == 0.5f) // center: nothing to do diff --git a/src/core/channel.h b/src/core/channel.h index a43b157..d8394fb 100644 --- a/src/core/channel.h +++ b/src/core/channel.h @@ -88,6 +88,9 @@ protected: int previewMode; float pan; + float volume; // global volume + float volume_i; // internal volume + float volume_d; // delta volume (for envelope) bool armed; std::string name; @@ -189,7 +192,8 @@ public: virtual void rewind() = 0; /* clear - Clears all memory buffers. This is actually useful to sample channels only. */ + Clears all memory buffers. This is actually useful to sample channels only. + TODO - please rename it to clearBuffers. */ virtual void clear() = 0; @@ -219,6 +223,7 @@ public: bool isPlaying() const; float getPan() const; + float getVolume() const; bool isArmed() const; std::string getName() const; bool isPreview() const; @@ -238,6 +243,8 @@ public: void sendMidiLplay(); void setPan(float v); + void setVolume(float v); + void setVolumeI(float v); void setArmed(bool b); void setName(const std::string& s); void setPreviewMode(int m); @@ -259,9 +266,6 @@ public: int type; // midi or sample int status; // status: see const.h int key; // keyboard button - float volume; // global volume - float volume_i; // internal volume - float volume_d; // delta volume (for envelope) bool mute_i; // internal mute bool mute_s; // previous mute status after being solo'd bool mute; // global mute diff --git a/src/core/conf.cpp b/src/core/conf.cpp index 0914d96..b24b06d 100644 --- a/src/core/conf.cpp +++ b/src/core/conf.cpp @@ -26,6 +26,7 @@ #include +#include #include "../utils/fs.h" #include "../utils/log.h" #include "storager.h" @@ -189,10 +190,10 @@ string pluginPath = ""; string patchPath = ""; string samplePath = ""; -int mainWindowX = 0; -int mainWindowY = 0; -int mainWindowW = G_GUI_WIDTH; -int mainWindowH = G_GUI_HEIGHT; +int mainWindowX = (Fl::w() / 2) - (G_MIN_GUI_WIDTH / 2); +int mainWindowY = (Fl::h() / 2) - (G_MIN_GUI_HEIGHT / 2); +int mainWindowW = G_MIN_GUI_WIDTH; +int mainWindowH = G_MIN_GUI_HEIGHT; int browserX = 0; int browserY = 0; diff --git a/src/core/const.h b/src/core/const.h index 78b8b9e..a587117 100644 --- a/src/core/const.h +++ b/src/core/const.h @@ -46,10 +46,10 @@ /* -- version --------------------------------------------------------------- */ #define G_APP_NAME "Giada" -#define G_VERSION_STR "0.14.5" +#define G_VERSION_STR "0.14.6" #define G_VERSION_MAJOR 0 #define G_VERSION_MINOR 14 -#define G_VERSION_PATCH 5 +#define G_VERSION_PATCH 6 #define CONF_FILENAME "giada.conf" @@ -63,14 +63,8 @@ /* -- GUI ------------------------------------------------------------------- */ -#ifdef G_OS_WINDOWS - #define G_GUI_SLEEP 1000/24 -#else - #define G_GUI_SLEEP 1000000/24 // == 1.000.000 / 24 == 1/24 sec == 24 Hz -#endif -#define G_GUI_WIDTH 816 -#define G_GUI_HEIGHT 510 -#define G_GUI_PLUGIN_RATE 0.05 // refresh rate for plugin GUIs +#define G_GUI_REFRESH_RATE 1000/24 +#define G_GUI_PLUGIN_RATE 0.05 // refresh rate for plugin GUI #define G_GUI_FONT_SIZE_BASE 12 #define G_GUI_INNER_MARGIN 4 #define G_GUI_OUTER_MARGIN 8 @@ -109,6 +103,8 @@ #define G_MAX_GRID_VAL 64 #define G_MIN_BUF_SIZE 8 #define G_MAX_BUF_SIZE 4096 +#define G_MIN_GUI_WIDTH 816 +#define G_MIN_GUI_HEIGHT 510 @@ -369,6 +365,7 @@ const int MIDI_CHANS[16] = { #define PATCH_KEY_CHANNEL_VOLUME "volume" #define PATCH_KEY_CHANNEL_PAN "pan" #define PATCH_KEY_CHANNEL_MIDI_IN "midi_in" +#define PATCH_KEY_CHANNEL_MIDI_IN_VELO_AS_VOL "midi_in_velo_as_vol" #define PATCH_KEY_CHANNEL_MIDI_IN_KEYPRESS "midi_in_keypress" #define PATCH_KEY_CHANNEL_MIDI_IN_KEYREL "midi_in_keyrel" #define PATCH_KEY_CHANNEL_MIDI_IN_KILL "midi_in_kill" diff --git a/src/core/init.cpp b/src/core/init.cpp index 86fcf89..5db174c 100644 --- a/src/core/init.cpp +++ b/src/core/init.cpp @@ -64,7 +64,6 @@ void init_prepareParser() time (&t); gu_log("[init] Giada " G_VERSION_STR " - %s", ctime(&t)); - conf::init(); conf::read(); patch::init(); @@ -131,7 +130,7 @@ void init_prepareMidiMap() void init_startGUI(int argc, char** argv) { - G_MainWin = new gdMainWindow(G_GUI_WIDTH, G_GUI_HEIGHT, "", argc, argv); + G_MainWin = new gdMainWindow(G_MIN_GUI_WIDTH, G_MIN_GUI_HEIGHT, "", argc, argv); G_MainWin->resize(conf::mainWindowX, conf::mainWindowY, conf::mainWindowW, conf::mainWindowH); diff --git a/src/core/kernelAudio.cpp b/src/core/kernelAudio.cpp index 15bb1eb..421eb02 100644 --- a/src/core/kernelAudio.cpp +++ b/src/core/kernelAudio.cpp @@ -46,18 +46,18 @@ namespace kernelAudio { namespace { -RtAudio *rtSystem = nullptr; -bool status = false; -unsigned numDevs = 0; -bool inputEnabled = false; -unsigned realBufsize = 0; // reale bufsize from the soundcard -int api = 0; +RtAudio* rtSystem = nullptr; +bool status = false; +unsigned numDevs = 0; +bool inputEnabled = false; +unsigned realBufsize = 0; // reale bufsize from the soundcard +int api = 0; #ifdef __linux__ JackState jackState; -jack_client_t *jackGetHandle() +jack_client_t* jackGetHandle() { return static_cast(rtSystem->rtapi_->__HACK__getJackClient()); } diff --git a/src/core/midiDispatcher.cpp b/src/core/midiDispatcher.cpp index c8a9d94..1d49fc1 100644 --- a/src/core/midiDispatcher.cpp +++ b/src/core/midiDispatcher.cpp @@ -114,33 +114,33 @@ void processChannels(const MidiEvent& midiEvent) if (pure == ch->midiInKeyPress) { gu_log(" >>> keyPress, ch=%d (pure=0x%X)\n", ch->index, pure); - glue_keyPress(ch, false, false); + c::io::keyPress(ch, false, false, midiEvent.getVelocity()); } else if (pure == ch->midiInKeyRel) { gu_log(" >>> keyRel ch=%d (pure=0x%X)\n", ch->index, pure); - glue_keyRelease(ch, false, false); + c::io::keyRelease(ch, false, false); } else if (pure == ch->midiInMute) { gu_log(" >>> mute ch=%d (pure=0x%X)\n", ch->index, pure); - glue_toggleMute(ch, false); + c::channel::toggleMute(ch, false); } else if (pure == ch->midiInKill) { gu_log(" >>> kill ch=%d (pure=0x%X)\n", ch->index, pure); - glue_kill(ch); + c::channel::kill(ch); } else if (pure == ch->midiInArm) { gu_log(" >>> arm ch=%d (pure=0x%X)\n", ch->index, pure); - glue_toggleArm(ch, false); + c::channel::toggleArm(ch, false); } else if (pure == ch->midiInSolo) { gu_log(" >>> solo ch=%d (pure=0x%X)\n", ch->index, pure); - glue_toggleSolo(ch, false); + c::channel::toggleSolo(ch, false); } else if (pure == ch->midiInVolume) { float vf = midiEvent.getVelocity() / 127.0f; gu_log(" >>> volume ch=%d (pure=0x%X, value=%d, float=%f)\n", ch->index, pure, midiEvent.getVelocity(), vf); - glue_setVolume(ch, vf, false); + c::channel::setVolume(ch, vf, false); } else { SampleChannel* sch = static_cast(ch); @@ -148,12 +148,12 @@ void processChannels(const MidiEvent& midiEvent) float vf = midiEvent.getVelocity() / (127/4.0f); // [0-127] ~> [0.0-4.0] gu_log(" >>> pitch ch=%d (pure=0x%X, value=%d, float=%f)\n", sch->index, pure, midiEvent.getVelocity(), vf); - glue_setPitch(sch, vf); + c::channel::setPitch(sch, vf); } else if (pure == sch->midiInReadActions) { gu_log(" >>> toggle read actions ch=%d (pure=0x%X)\n", sch->index, pure); - glue_toggleReadingRecs(sch, false); + c::channel::toggleReadingRecs(sch, false); } } @@ -188,11 +188,11 @@ void processMaster(const MidiEvent& midiEvent) } else if (pure == conf::midiInActionRec) { gu_log(" >>> actionRec (master) (pure=0x%X)\n", pure); - glue_startStopActionRec(false); + c::io::startStopActionRec(false); } else if (pure == conf::midiInInputRec) { gu_log(" >>> inputRec (master) (pure=0x%X)\n", pure); - glue_startStopInputRec(false); + c::io::startStopInputRec(false); } else if (pure == conf::midiInMetronome) { gu_log(" >>> metronome (master) (pure=0x%X)\n", pure); diff --git a/src/core/patch.cpp b/src/core/patch.cpp index d954ffb..dfdc9dc 100644 --- a/src/core/patch.cpp +++ b/src/core/patch.cpp @@ -216,6 +216,7 @@ bool readChannels(json_t* jContainer) if (!storager::setFloat (jChannel, PATCH_KEY_CHANNEL_VOLUME, channel.volume)) return 0; if (!storager::setFloat (jChannel, PATCH_KEY_CHANNEL_PAN, channel.pan)) return 0; if (!storager::setBool (jChannel, PATCH_KEY_CHANNEL_MIDI_IN, channel.midiIn)) return 0; + if (!storager::setBool (jChannel, PATCH_KEY_CHANNEL_MIDI_IN_VELO_AS_VOL, channel.midiInVeloAsVol)) return 0; if (!storager::setUint32(jChannel, PATCH_KEY_CHANNEL_MIDI_IN_KEYPRESS, channel.midiInKeyPress)) return 0; if (!storager::setUint32(jChannel, PATCH_KEY_CHANNEL_MIDI_IN_KEYREL, channel.midiInKeyRel)) return 0; if (!storager::setUint32(jChannel, PATCH_KEY_CHANNEL_MIDI_IN_KILL, channel.midiInKill)) return 0; @@ -394,6 +395,7 @@ void writeChannels(json_t* jContainer, vector* channels) json_object_set_new(jChannel, PATCH_KEY_CHANNEL_VOLUME, json_real(channel.volume)); json_object_set_new(jChannel, PATCH_KEY_CHANNEL_PAN, json_real(channel.pan)); json_object_set_new(jChannel, PATCH_KEY_CHANNEL_MIDI_IN, json_boolean(channel.midiIn)); + json_object_set_new(jChannel, PATCH_KEY_CHANNEL_MIDI_IN_VELO_AS_VOL, json_boolean(channel.midiInVeloAsVol)); json_object_set_new(jChannel, PATCH_KEY_CHANNEL_MIDI_IN_KEYPRESS, json_integer(channel.midiInKeyPress)); json_object_set_new(jChannel, PATCH_KEY_CHANNEL_MIDI_IN_KEYREL, json_integer(channel.midiInKeyRel)); json_object_set_new(jChannel, PATCH_KEY_CHANNEL_MIDI_IN_KILL, json_integer(channel.midiInKill)); diff --git a/src/core/patch.h b/src/core/patch.h index 28b11d0..651c2af 100644 --- a/src/core/patch.h +++ b/src/core/patch.h @@ -31,11 +31,7 @@ #include #include -#ifdef __APPLE__ // our Clang still doesn't know about cstdint (c++11 stuff) - #include -#else - #include -#endif +#include namespace giada { @@ -73,6 +69,7 @@ struct channel_t float volume; float pan; bool midiIn; + bool midiInVeloAsVol; uint32_t midiInKeyPress; uint32_t midiInKeyRel; uint32_t midiInKill; @@ -118,19 +115,19 @@ struct column_t extern std::string header; extern std::string version; -extern int versionMajor; -extern int versionMinor; -extern int versionPatch; +extern int versionMajor; +extern int versionMinor; +extern int versionPatch; extern std::string name; -extern float bpm; -extern int bars; -extern int beats; -extern int quantize; -extern float masterVolIn; -extern float masterVolOut; -extern int metronome; -extern int lastTakeId; -extern int samplerate; // original samplerate when the patch was saved +extern float bpm; +extern int bars; +extern int beats; +extern int quantize; +extern float masterVolIn; +extern float masterVolOut; +extern int metronome; +extern int lastTakeId; +extern int samplerate; // original samplerate when the patch was saved extern std::vector columns; extern std::vector channels; diff --git a/src/core/sampleChannel.cpp b/src/core/sampleChannel.cpp index b875eeb..4ab3700 100644 --- a/src/core/sampleChannel.cpp +++ b/src/core/sampleChannel.cpp @@ -421,6 +421,10 @@ void SampleChannel::parseAction(recorder::action* a, int localFrame, void SampleChannel::sum(int frame, bool running) { + // TODO - Opaque channels' processing + // TODO - Opaque channels' processing + // TODO - Opaque channels' processing + if (wave == nullptr || status & ~(STATUS_PLAY | STATUS_ENDING)) return; @@ -714,7 +718,7 @@ void SampleChannel::setBoost(float v) } -float SampleChannel::getBoost() +float SampleChannel::getBoost() const { return boost; } @@ -735,10 +739,10 @@ void SampleChannel::calcFadeoutStep() /* -------------------------------------------------------------------------- */ -void SampleChannel::setReadActions(bool v, bool recsStopOnChanHalt) +void SampleChannel::setReadActions(bool v, bool killOnFalse) { readActions = v; - if (!readActions && recsStopOnChanHalt) + if (!readActions && killOnFalse) kill(0); /// FIXME - wrong frame value } @@ -866,6 +870,7 @@ void SampleChannel::process(float* outBuffer, float* inBuffer) pluginHost::processStack(vChan, pluginHost::CHANNEL, this); #endif + // TODO - Opaque channels' processing for (int j=0; jboost; readActions = pch->recActive; recStatus = readActions ? REC_READING : REC_STOPPED; + midiInVeloAsVol = pch->midiInVeloAsVol; midiInReadActions = pch->midiInReadActions; midiInPitch = pch->midiInPitch; inputMonitor = pch->inputMonitor; @@ -1170,7 +1177,7 @@ int SampleChannel::fillChan(float *dest, int start, int offset, bool rewind) } } else { - + // TODO - Opaque channels count rsmp_data.data_in = wave->getData()+start; // source data rsmp_data.input_frames = (end-start)/2; // how many readable bytes rsmp_data.data_out = dest+offset; // destination (processed data) diff --git a/src/core/sampleChannel.h b/src/core/sampleChannel.h index 54162b0..b290640 100644 --- a/src/core/sampleChannel.h +++ b/src/core/sampleChannel.h @@ -129,6 +129,8 @@ public: int getTrackerPreview() const; int getShift() const; + float getBoost() const; + void setShift(int s); void reset(int frame); @@ -173,13 +175,12 @@ public: void hardStop(int frame); /* setReadActions - * if enabled (v == true), recorder will read actions from this channel. If - * recsStopOnChanHalt == true, stop reading actions right away. */ + If enabled (v == true), recorder will read actions from this channel. If + killOnFalse == true and disabled, will also kill the channel. */ - void setReadActions(bool v, bool recsStopOnChanHalt); + void setReadActions(bool v, bool killOnFalse); void setBoost(float v); - float getBoost(); void setOnEndPreviewCb(std::function f); @@ -199,6 +200,7 @@ public: /* midi stuff */ + bool midiInVeloAsVol; uint32_t midiInReadActions; uint32_t midiInPitch; diff --git a/src/core/wave.h b/src/core/wave.h index 300a43d..7491a14 100644 --- a/src/core/wave.h +++ b/src/core/wave.h @@ -41,7 +41,7 @@ class Wave private: float* m_data; - int m_size; // Wave size in bytes (size in stereo: size / 2) + int m_size; // Wave size in bytes (size in frames: m_size / m_channels) int m_channels; int m_rate; int m_bits; @@ -57,12 +57,6 @@ public: ~Wave(); Wave(const Wave& other); - void setRate(int v); - void setChannels(int v); - void setData(float* data, int size); - void setLogical(bool l); - void setEdited(bool e); - /* setPath Sets new path 'p'. If 'id' != -1 inserts a numeric id next to the file extension, e.g. : /path/to/sample-[id].wav */ @@ -76,11 +70,17 @@ public: std::string getPath() const; int getBits() const; float* getData() const; - int getSize() const; // with channels count + int getSize() const; // in frames int getDuration() const; bool isLogical() const; bool isEdited() const; + void setRate(int v); + void setChannels(int v); + void setData(float* data, int size); + void setLogical(bool l); + void setEdited(bool e); + /* clear Resets Wave to init state. */ diff --git a/src/glue/channel.cpp b/src/glue/channel.cpp index a2b0e6e..9fbba3e 100644 --- a/src/glue/channel.cpp +++ b/src/glue/channel.cpp @@ -66,14 +66,27 @@ extern gdMainWindow* G_MainWin; using std::string; -using namespace giada::m; -static bool __soloSession__ = false; +namespace giada { +namespace c { +namespace channel +{ +namespace +{ +bool soloSession__ = false; +} // {anonymous} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ -int glue_loadChannel(SampleChannel* ch, const string& fname) + +int loadChannel(SampleChannel* ch, const string& fname) { + using namespace giada::m; + /* Always stop a channel before loading a new sample in it. This will prevent issues if tracker is outside the boundaries of the new sample -> segfault. */ @@ -91,7 +104,7 @@ int glue_loadChannel(SampleChannel* ch, const string& fname) return result; if (wave->getRate() != conf::samplerate) { - gu_log("[glue_loadChannel] input rate (%d) != system rate (%d), conversion needed\n", + gu_log("[loadChannel] input rate (%d) != system rate (%d), conversion needed\n", wave->getRate(), conf::samplerate); result = waveManager::resample(wave, conf::rsmpQuality, conf::samplerate); if (result != G_RES_OK) { @@ -111,9 +124,9 @@ int glue_loadChannel(SampleChannel* ch, const string& fname) /* -------------------------------------------------------------------------- */ -Channel* glue_addChannel(int column, int type, int size) +Channel* addChannel(int column, int type, int size) { - Channel* ch = mh::addChannel(type); + Channel* ch = m::mh::addChannel(type); geChannel* gch = G_MainWin->keyboard->addChannel(column, ch, size); ch->guiChannel = gch; return ch; @@ -123,8 +136,10 @@ Channel* glue_addChannel(int column, int type, int size) /* -------------------------------------------------------------------------- */ -void glue_deleteChannel(Channel* ch) +void deleteChannel(Channel* ch) { + using namespace giada::m; + if (!gdConfirmWin("Warning", "Delete channel: are you sure?")) return; recorder::clearChan(ch->index); @@ -143,7 +158,7 @@ void glue_deleteChannel(Channel* ch) /* -------------------------------------------------------------------------- */ -void glue_freeChannel(Channel* ch) +void freeChannel(Channel* ch) { if (ch->status == STATUS_PLAY) { if (!gdConfirmWin("Warning", "This action will stop the channel: are you sure?")) @@ -154,7 +169,7 @@ void glue_freeChannel(Channel* ch) return; G_MainWin->keyboard->freeChannel(ch->guiChannel); - recorder::clearChan(ch->index); + m::recorder::clearChan(ch->index); ch->hasActions = false; ch->empty(); @@ -170,7 +185,7 @@ void glue_freeChannel(Channel* ch) /* -------------------------------------------------------------------------- */ -void glue_toggleArm(Channel* ch, bool gui) +void toggleArm(Channel* ch, bool gui) { ch->setArmed(!ch->isArmed()); if (!gui) @@ -181,7 +196,7 @@ void glue_toggleArm(Channel* ch, bool gui) /* -------------------------------------------------------------------------- */ -void glue_toggleInputMonitor(Channel* ch) +void toggleInputMonitor(Channel* ch) { SampleChannel* sch = static_cast(ch); sch->inputMonitor = !sch->inputMonitor; @@ -191,8 +206,10 @@ void glue_toggleInputMonitor(Channel* ch) /* -------------------------------------------------------------------------- */ -int glue_cloneChannel(Channel* src) +int cloneChannel(Channel* src) { + using namespace giada::m; + Channel* ch = mh::addChannel(src->type); geChannel* gch = G_MainWin->keyboard->addChannel(src->guiChannel->getColumnIndex(), ch, src->guiChannel->getSize()); @@ -208,14 +225,14 @@ int glue_cloneChannel(Channel* src) /* -------------------------------------------------------------------------- */ -void glue_setVolume(Channel* ch, float v, bool gui, bool editor) +void setVolume(Channel* ch, float v, bool gui, bool editor) { - ch->volume = v; + ch->setVolume(v); /* Changing channel volume? Update wave editor (if it's shown). */ if (!editor) { - gdSampleEditor *gdEditor = (gdSampleEditor*) gu_getSubwindow(G_MainWin, WID_SAMPLE_EDITOR); + gdSampleEditor* gdEditor = static_cast(gu_getSubwindow(G_MainWin, WID_SAMPLE_EDITOR)); if (gdEditor) { Fl::lock(); gdEditor->volumeTool->refresh(); @@ -234,7 +251,7 @@ void glue_setVolume(Channel* ch, float v, bool gui, bool editor) /* -------------------------------------------------------------------------- */ -void glue_setPitch(SampleChannel* ch, float val) +void setPitch(SampleChannel* ch, float val) { ch->setPitch(val); gdSampleEditor* gdEditor = static_cast(gu_getSubwindow(G_MainWin, WID_SAMPLE_EDITOR)); @@ -249,7 +266,7 @@ void glue_setPitch(SampleChannel* ch, float val) /* -------------------------------------------------------------------------- */ -void glue_setPanning(SampleChannel* ch, float val) +void setPanning(SampleChannel* ch, float val) { ch->setPan(val); gdSampleEditor* gdEditor = static_cast(gu_getSubwindow(G_MainWin, WID_SAMPLE_EDITOR)); @@ -264,8 +281,10 @@ void glue_setPanning(SampleChannel* ch, float val) /* -------------------------------------------------------------------------- */ -void glue_toggleMute(Channel* ch, bool gui) +void toggleMute(Channel* ch, bool gui) { + using namespace giada::m; + if (recorder::active && recorder::canRec(ch, clock::isRunning(), mixer::recording)) { if (!ch->mute) { recorder::startOverdub(ch->index, G_ACTION_MUTES, clock::getCurrentFrame(), @@ -290,16 +309,16 @@ void glue_toggleMute(Channel* ch, bool gui) /* -------------------------------------------------------------------------- */ -void glue_toggleSolo(Channel* ch, bool gui) +void toggleSolo(Channel* ch, bool gui) { - ch->solo ? glue_setSoloOn(ch, gui) : glue_setSoloOff(ch, gui); + ch->solo ? setSoloOn(ch, gui) : setSoloOff(ch, gui); } /* -------------------------------------------------------------------------- */ -void glue_kill(Channel* ch) +void kill(Channel* ch) { ch->kill(0); // on frame 0: it's a user-generated event } @@ -308,17 +327,19 @@ void glue_kill(Channel* ch) /* -------------------------------------------------------------------------- */ -void glue_setSoloOn(Channel* ch, bool gui) +void setSoloOn(Channel* ch, bool gui) { + using namespace giada::m; + /* if there's no solo session, store mute configuration of all chans * and start the session */ - if (!__soloSession__) { + if (!soloSession__) { for (unsigned i=0; imute_s = och->mute; } - __soloSession__ = true; + soloSession__ = true; } ch->solo = !ch->solo; @@ -354,13 +375,15 @@ void glue_setSoloOn(Channel* ch, bool gui) /* -------------------------------------------------------------------------- */ -void glue_setSoloOff(Channel* ch, bool gui) +void setSoloOff(Channel* ch, bool gui) { + using namespace giada::m; + /* if this is uniqueSolo, stop solo session and restore mute status, * else mute this */ if (mh::uniqueSolo(ch)) { - __soloSession__ = false; + soloSession__ = false; for (unsigned i=0; imute_s) { @@ -399,7 +422,7 @@ void glue_setSoloOff(Channel* ch, bool gui) /* -------------------------------------------------------------------------- */ -void glue_setBoost(SampleChannel* ch, float val) +void setBoost(SampleChannel* ch, float val) { ch->setBoost(val); gdSampleEditor *gdEditor = static_cast(gu_getSubwindow(G_MainWin, WID_SAMPLE_EDITOR)); @@ -414,7 +437,7 @@ void glue_setBoost(SampleChannel* ch, float val) /* -------------------------------------------------------------------------- */ -void glue_setName(Channel* ch, const string& name) +void setName(Channel* ch, const string& name) { ch->setName(name); ch->guiChannel->update(); @@ -424,9 +447,10 @@ void glue_setName(Channel* ch, const string& name) /* -------------------------------------------------------------------------- */ -void glue_toggleReadingRecs(SampleChannel* ch, bool gui) +void toggleReadingRecs(SampleChannel* ch, bool gui) { - /* When you call glue_startReadingRecs with conf::treatRecsAsLoops, the + + /* When you call startReadingRecs with conf::treatRecsAsLoops, the member value ch->readActions actually is not set to true immediately, because the channel is in wait mode (REC_WAITING). ch->readActions will become true on the next first beat. So a 'stop rec' command should occur also when @@ -435,24 +459,26 @@ void glue_toggleReadingRecs(SampleChannel* ch, bool gui) then you press 'R' again to undo the status. */ if (ch->readActions || (!ch->readActions && ch->recStatus == REC_WAITING)) - glue_stopReadingRecs(ch, gui); + stopReadingRecs(ch, gui); else - glue_startReadingRecs(ch, gui); + startReadingRecs(ch, gui); } /* -------------------------------------------------------------------------- */ -void glue_startReadingRecs(SampleChannel* ch, bool gui) +void startReadingRecs(SampleChannel* ch, bool gui) { + using namespace giada::m; + if (conf::treatRecsAsLoops) ch->recStatus = REC_WAITING; else ch->setReadActions(true, conf::recsStopOnChanHalt); if (!gui) { Fl::lock(); - ((geSampleChannel*)ch->guiChannel)->readActions->value(1); + static_cast(ch->guiChannel)->readActions->value(1); Fl::unlock(); } } @@ -461,17 +487,25 @@ void glue_startReadingRecs(SampleChannel* ch, bool gui) /* -------------------------------------------------------------------------- */ -void glue_stopReadingRecs(SampleChannel* ch, bool gui) +void stopReadingRecs(SampleChannel* ch, bool gui) { - /* First of all, if the mixer is not running just stop and disable everything. + using namespace giada::m; + + /* First of all, if the clock is not running just stop and disable everything. Then if "treatRecsAsLoop" wait until the sequencer reaches beat 0, so put the channel in REC_ENDING status. */ if (!clock::isRunning()) { ch->recStatus = REC_STOPPED; - ch->readActions = false; + ch->setReadActions(false, false); } else + if (ch->recStatus == REC_WAITING) + ch->recStatus = REC_STOPPED; + else + if (ch->recStatus == REC_ENDING) + ch->recStatus = REC_READING; + else if (conf::treatRecsAsLoops) ch->recStatus = REC_ENDING; else @@ -479,7 +513,9 @@ void glue_stopReadingRecs(SampleChannel* ch, bool gui) if (!gui) { Fl::lock(); - ((geSampleChannel*)ch->guiChannel)->readActions->value(0); + static_cast(ch->guiChannel)->readActions->value(0); Fl::unlock(); } } + +}}}; // giada::c::channel:: \ No newline at end of file diff --git a/src/glue/channel.h b/src/glue/channel.h index 6eac90d..2228622 100644 --- a/src/glue/channel.h +++ b/src/glue/channel.h @@ -36,55 +36,60 @@ class Channel; class SampleChannel; class gdSampleEditor; - +namespace giada { +namespace c { +namespace channel +{ /* addChannel - * add an empty new channel to the stack. Returns the new channel. */ +Adds an empty new channel to the stack. Returns the new channel. */ -Channel* glue_addChannel(int column, int type, int size); +Channel* addChannel(int column, int type, int size); /* loadChannel - * fill an existing channel with a wave. */ +Fills an existing channel with a wave. */ -int glue_loadChannel(SampleChannel* ch, const std::string& fname); +int loadChannel(SampleChannel* ch, const std::string& fname); /* deleteChannel - * Remove a channel from Mixer. */ +Removes a channel from Mixer. */ -void glue_deleteChannel(Channel* ch); +void deleteChannel(Channel* ch); /* freeChannel - * Unload the sample from a sample channel. */ +Unloads the sample from a sample channel. */ -void glue_freeChannel(Channel* ch); +void freeChannel(Channel* ch); /* cloneChannel - * Make an exact copy of Channel *ch. */ +Makes an exact copy of Channel *ch. */ -int glue_cloneChannel(Channel* ch); +int cloneChannel(Channel* ch); /* toggle/set* Toggles or set several channel properties. If gui == true the signal comes from a manual interaction on the GUI, otherwise it's a MIDI/Jack/external signal. */ -void glue_toggleArm(Channel* ch, bool gui=true); -void glue_toggleInputMonitor(Channel* ch); -void glue_kill(Channel* ch); -void glue_toggleMute(Channel* ch, bool gui=true); -void glue_setSoloOn(Channel* ch, bool gui=true); -void glue_setSoloOff(Channel* ch, bool gui=true); -void glue_toggleSolo(Channel* ch, bool gui=true); -void glue_setVolume(Channel* ch, float v, bool gui=true, bool editor=false); -void glue_setName(Channel* ch, const std::string& name); -void glue_setPitch(SampleChannel* ch, float val); -void glue_setPanning(SampleChannel* ch, float val); -void glue_setBoost(SampleChannel* ch, float val); +void toggleArm(Channel* ch, bool gui=true); +void toggleInputMonitor(Channel* ch); +void kill(Channel* ch); +void toggleMute(Channel* ch, bool gui=true); +void setSoloOn(Channel* ch, bool gui=true); +void setSoloOff(Channel* ch, bool gui=true); +void toggleSolo(Channel* ch, bool gui=true); +void setVolume(Channel* ch, float v, bool gui=true, bool editor=false); +void setName(Channel* ch, const std::string& name); +void setPitch(SampleChannel* ch, float val); +void setPanning(SampleChannel* ch, float val); +void setBoost(SampleChannel* ch, float val); /* toggleReadingRecs Handles the 'R' button. If gui == true the signal comes from an user interaction on the GUI, otherwise it's a MIDI/Jack/external signal. */ -void glue_toggleReadingRecs(SampleChannel* ch, bool gui=true); -void glue_startReadingRecs(SampleChannel* ch, bool gui=true); -void glue_stopReadingRecs(SampleChannel* ch, bool gui=true); +void toggleReadingRecs(SampleChannel* ch, bool gui=true); +void startReadingRecs(SampleChannel* ch, bool gui=true); +void stopReadingRecs(SampleChannel* ch, bool gui=true); + +}}}; // giada::c::channel:: #endif diff --git a/src/glue/io.cpp b/src/glue/io.cpp index 2f51a4e..7e85d80 100644 --- a/src/glue/io.cpp +++ b/src/glue/io.cpp @@ -35,6 +35,7 @@ #include "../gui/elems/mainWindow/keyboard/sampleChannel.h" #include "../utils/gui.h" #include "../utils/log.h" +#include "../utils/math.h" #include "../core/recorder.h" #include "../core/kernelAudio.h" #include "../core/mixer.h" @@ -50,136 +51,164 @@ #include "io.h" -extern gdMainWindow *G_MainWin; +extern gdMainWindow* G_MainWin; -using namespace giada::m; +namespace giada { +namespace c { +namespace io +{ +namespace +{ +void ctrlPress(SampleChannel* ch) +{ + c::channel::toggleMute(ch); +} + + +/* -------------------------------------------------------------------------- */ + + +void shiftPress(SampleChannel* ch) +{ + /* action recording on: + if sequencer is running, rec a killchan + action recording off: + if chan has recorded events: + | if seq is playing OR channel 'c' is stopped, de/activate recs + | else kill chan + else kill chan. */ + + if (m::recorder::active) { + if (!m::clock::isRunning()) + return; + ch->kill(0); // on frame 0: user-generated event + if (m::recorder::canRec(ch, m::clock::isRunning(), m::mixer::recording) && + !(ch->mode & LOOP_ANY)) + { // don't record killChan actions for LOOP channels + m::recorder::rec(ch->index, G_ACTION_KILL, m::clock::getCurrentFrame()); + ch->hasActions = true; + } + } + else { + if (ch->hasActions) { + if (m::clock::isRunning() || ch->status == STATUS_OFF) + ch->readActions ? c::channel::stopReadingRecs(ch) : c::channel::startReadingRecs(ch); + else + ch->kill(0); // on frame 0: user-generated event + } + else + ch->kill(0); // on frame 0: user-generated event + } +} + + +/* -------------------------------------------------------------------------- */ + + +void cleanPress(SampleChannel* ch, int velocity) +{ + /* Record now if the quantizer is off, otherwise let mixer to handle it when a + quantoWait has passed. Moreover, KEYPRESS and KEYREL are meaningless for loop + modes. */ + + if (m::clock::getQuantize() == 0 && + m::recorder::canRec(ch, m::clock::isRunning(), m::mixer::recording) && + !(ch->mode & LOOP_ANY)) + { + if (ch->mode == SINGLE_PRESS) { + m::recorder::startOverdub(ch->index, G_ACTION_KEYS, m::clock::getCurrentFrame(), + m::kernelAudio::getRealBufSize()); + ch->readActions = false; // don't read actions while overdubbing + } + else { + m::recorder::rec(ch->index, G_ACTION_KEYPRESS, m::clock::getCurrentFrame()); + ch->hasActions = true; + + /* Why return here? You record an action and then you call ch->start: + Mixer, which is on another thread, reads your newly recorded action if you + have readActions == true, and then ch->start kicks in right after it. + The result: Mixer plays the channel (due to the new action) but ch->start + kills it right away (because the sample is playing). Fix: call ch->start + only if you are not recording anything, i.e. let Mixer play it. */ + + if (ch->readActions) + return; + } + } + + /* This is a user-generated event, so it's on frame 0. For one-shot modes, + velocity drives the internal volume. */ + if (ch->mode & SINGLE_ANY && ch->midiInVeloAsVol) + ch->setVolumeI(u::math::map((float)velocity, 0.0f, 127.0f, 0.0f, 1.0f)); -void glue_keyPress(Channel *ch, bool ctrl, bool shift) + ch->start(0, true, m::clock::getQuantize(), m::clock::isRunning(), false, true); +} + +} // {anonymous} + + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + + +void keyPress(Channel* ch, bool ctrl, bool shift, int velocity) { if (ch->type == CHANNEL_SAMPLE) - glue_keyPress((SampleChannel*)ch, ctrl, shift); + keyPress(static_cast(ch), ctrl, shift, velocity); else - glue_keyPress((MidiChannel*)ch, ctrl, shift); + keyPress(static_cast(ch), ctrl, shift); } /* -------------------------------------------------------------------------- */ -void glue_keyRelease(Channel *ch, bool ctrl, bool shift) +void keyRelease(Channel* ch, bool ctrl, bool shift) { if (ch->type == CHANNEL_SAMPLE) - glue_keyRelease((SampleChannel*)ch, ctrl, shift); + keyRelease(static_cast(ch), ctrl, shift); } /* -------------------------------------------------------------------------- */ -void glue_keyPress(MidiChannel *ch, bool ctrl, bool shift) +void keyPress(MidiChannel* ch, bool ctrl, bool shift) { if (ctrl) - glue_toggleMute(ch); + c::channel::toggleMute(ch); else if (shift) ch->kill(0); // on frame 0: user-generated event else - ch->start(0, true, clock::getQuantize(), clock::isRunning(), false, true); // on frame 0: user-generated event + ch->start(0, true, m::clock::getQuantize(), m::clock::isRunning(), false, true); // on frame 0: user-generated event } /* -------------------------------------------------------------------------- */ -void glue_keyPress(SampleChannel *ch, bool ctrl, bool shift) +void keyPress(SampleChannel* ch, bool ctrl, bool shift, int velocity) { - /* case CTRL */ - if (ctrl) - glue_toggleMute(ch); - - /* case SHIFT - * - * action recording on: - * if seq is playing, rec a killchan - * action recording off: - * if chan has recorded events: - * | if seq is playing OR channel 'c' is stopped, de/activate recs - * | else kill chan - * else kill chan */ - + ctrlPress(ch); + else if (shift) + shiftPress(ch); else - if (shift) { - if (recorder::active) { - if (clock::isRunning()) { - ch->kill(0); // on frame 0: user-generated event - if (recorder::canRec(ch, clock::isRunning(), mixer::recording) && - !(ch->mode & LOOP_ANY)) - { // don't record killChan actions for LOOP channels - recorder::rec(ch->index, G_ACTION_KILL, clock::getCurrentFrame()); - ch->hasActions = true; - } - } - } - else { - if (ch->hasActions) { - if (clock::isRunning() || ch->status == STATUS_OFF) - ch->readActions ? glue_stopReadingRecs(ch) : glue_startReadingRecs(ch); - else - ch->kill(0); // on frame 0: user-generated event - } - else - ch->kill(0); // on frame 0: user-generated event - } - } - else { /* case no modifier */ - - /* record now if the quantizer is off, otherwise let mixer to handle it - * when a quantoWait has passed. Moreover, KEYPRESS and KEYREL are - * meaningless for loop modes */ - - if (clock::getQuantize() == 0 && - recorder::canRec(ch, clock::isRunning(), mixer::recording) && - !(ch->mode & LOOP_ANY)) - { - if (ch->mode == SINGLE_PRESS) { - recorder::startOverdub(ch->index, G_ACTION_KEYS, clock::getCurrentFrame(), - kernelAudio::getRealBufSize()); - ch->readActions = false; // don't read actions while overdubbing - } - else { - recorder::rec(ch->index, G_ACTION_KEYPRESS, clock::getCurrentFrame()); - 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 - your newly recorded action if you have readActions == true, and then - ch->start kicks in right after it (as done on line 165). - The result: Mixer plays the channel (due to the new action) but ch->start - kills it right away (because the sample is playing). Fix: call ch->start - only if you are not recording anything, i.e. let Mixer play it. */ - - if (ch->readActions) - return; - } - } - - /* This is a user-generated event, so it's on frame 0 */ - - ch->start(0, true, clock::getQuantize(), clock::isRunning(), false, true); - } - - /* the GUI update is done by gui_refresh() */ + cleanPress(ch, velocity); } /* -------------------------------------------------------------------------- */ -void glue_keyRelease(SampleChannel *ch, bool ctrl, bool shift) +void keyRelease(SampleChannel* ch, bool ctrl, bool shift) { + using namespace giada::m; + if (ctrl || shift) return; @@ -190,7 +219,7 @@ void glue_keyRelease(SampleChannel *ch, bool ctrl, bool shift) if (ch->mode == SINGLE_PRESS && recorder::canRec(ch, clock::isRunning(), mixer::recording)) recorder::stopOverdub(clock::getCurrentFrame(), clock::getTotalFrames(), - &mixer::mutex_recs); + &mixer::mutex_recs); /* the GUI update is done by gui_refresh() */ @@ -200,17 +229,19 @@ void glue_keyRelease(SampleChannel *ch, bool ctrl, bool shift) /* -------------------------------------------------------------------------- */ -void glue_startStopActionRec(bool gui) +void startStopActionRec(bool gui) { - recorder::active ? glue_stopActionRec(gui) : glue_startActionRec(gui); + m::recorder::active ? stopActionRec(gui) : startActionRec(gui); } /* -------------------------------------------------------------------------- */ -void glue_startActionRec(bool gui) +void startActionRec(bool gui) { + using namespace giada::m; + if (kernelAudio::getStatus() == false) return; @@ -230,21 +261,21 @@ void glue_startActionRec(bool gui) /* -------------------------------------------------------------------------- */ -void glue_stopActionRec(bool gui) +void stopActionRec(bool gui) { /* stop the recorder and sort new actions */ - recorder::active = false; - recorder::sortActions(); + m::recorder::active = false; + m::recorder::sortActions(); - for (unsigned i=0; itype == CHANNEL_MIDI) + if (ch->type == CHANNEL_MIDI) continue; - SampleChannel *ch = (SampleChannel*) mixer::channels.at(i); - G_MainWin->keyboard->setChannelWithActions((geSampleChannel*)ch->guiChannel); - if (!ch->readActions && ch->hasActions) - glue_startReadingRecs(ch, false); + SampleChannel* sch = static_cast(ch); + G_MainWin->keyboard->setChannelWithActions(static_cast(sch->guiChannel)); + if (!sch->readActions && sch->hasActions) + c::channel::startReadingRecs(sch, false); } if (!gui) { @@ -260,12 +291,12 @@ void glue_stopActionRec(bool gui) /* -------------------------------------------------------------------------- */ -void glue_startStopInputRec(bool gui) +void startStopInputRec(bool gui) { - if (mixer::recording) - glue_stopInputRec(gui); + if (m::mixer::recording) + stopInputRec(gui); else - if (!glue_startInputRec(gui)) + if (!startInputRec(gui)) gdAlert("No channels armed/available for audio recording."); } @@ -273,14 +304,16 @@ void glue_startStopInputRec(bool gui) /* -------------------------------------------------------------------------- */ -int glue_startInputRec(bool gui) +int startInputRec(bool gui) { + using namespace giada::m; + if (kernelAudio::getStatus() == false) return false; if (!mh::startInputRec()) { - Fl::lock(); - G_MainWin->mainTransport->updateRecInput(0); // set it off, anyway + Fl::lock(); + G_MainWin->mainTransport->updateRecInput(0); // set it off, anyway Fl::unlock(); return false; } @@ -288,17 +321,17 @@ int glue_startInputRec(bool gui) if (!clock::isRunning()) glue_startSeq(false); // update gui anyway - Fl::lock(); - if (!gui) - G_MainWin->mainTransport->updateRecInput(1); - G_MainWin->mainTimer->setLock(true); - 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. */ + /* Update sample name inside sample channels' main button. This is useless for + midi channel, but let's do it anyway. */ - for (unsigned i=0; iguiChannel->update(); + for (Channel* ch : m::mixer::channels) + ch->guiChannel->update(); return true; } @@ -307,14 +340,16 @@ int glue_startInputRec(bool gui) /* -------------------------------------------------------------------------- */ -int glue_stopInputRec(bool gui) +int stopInputRec(bool gui) { + using namespace giada::m; + mh::stopInputRec(); /* Start all sample channels in loop mode that were armed, i.e. that were recording stuff and not yet in play. They are also started in force mode, i.e. - they must start playing right away at the current frame, not at the next first - beat. */ + they must start playing right away at the current frame, not at the next first + beat. */ for (Channel* ch : mixer::channels) { if (ch->type == CHANNEL_MIDI) @@ -322,14 +357,16 @@ int glue_stopInputRec(bool gui) SampleChannel* sch = static_cast(ch); if (sch->mode & (LOOP_ANY) && sch->status == STATUS_OFF && sch->isArmed()) sch->start(clock::getCurrentFrame(), true, clock::getQuantize(), - clock::isRunning(), true, true); + clock::isRunning(), true, true); } - Fl::lock(); - if (!gui) - G_MainWin->mainTransport->updateRecInput(0); - G_MainWin->mainTimer->setLock(false); - Fl::unlock(); + Fl::lock(); + if (!gui) + G_MainWin->mainTransport->updateRecInput(0); + G_MainWin->mainTimer->setLock(false); + Fl::unlock(); return 1; } + +}}} // giada::c::io:: \ No newline at end of file diff --git a/src/glue/io.h b/src/glue/io.h index 3377be9..0dccf9e 100644 --- a/src/glue/io.h +++ b/src/glue/io.h @@ -36,32 +36,41 @@ #define G_GLUE_IO_H +class Channel; +class SampleChannel; +class MidiChannel; + +namespace giada { +namespace c { +namespace io +{ /* keyPress / keyRelease * handle the key pressure, either via mouse/keyboard or MIDI. If gui * is true it means that the event comes from the main window (mouse, * keyb or MIDI), otherwise the event comes from the action recorder. */ -void glue_keyPress (class Channel *ch, bool ctrl=0, bool shift=0); -void glue_keyPress (class SampleChannel *ch, bool ctrl=0, bool shift=0); -void glue_keyPress (class MidiChannel *ch, bool ctrl=0, bool shift=0); -void glue_keyRelease(class Channel *ch, bool ctrl=0, bool shift=0); -void glue_keyRelease(class SampleChannel *ch, bool ctrl=0, bool shift=0); +void keyPress (Channel* ch, bool ctrl, bool shift, int velocity); +void keyPress (SampleChannel* ch, bool ctrl, bool shift, int velocity); +void keyPress (MidiChannel* ch, bool ctrl, bool shift); +void keyRelease(Channel* ch, bool ctrl, bool shift); +void keyRelease(SampleChannel* ch, bool ctrl, bool shift); /* start/stopActionRec Handles the action recording. If gui == true the signal comes from an user interaction, otherwise it's a MIDI/Jack/external signal. */ -void glue_startStopActionRec(bool gui=true); -void glue_startActionRec(bool gui=true); -void glue_stopActionRec(bool gui=true); +void startStopActionRec(bool gui=true); +void startActionRec(bool gui=true); +void stopActionRec(bool gui=true); /* start/stopInputRec Handles the input recording (take). If gui == true the signal comes from an internal interaction on the GUI, otherwise it's a MIDI/Jack/external signal. */ -void glue_startStopInputRec(bool gui=true); -int glue_startInputRec (bool gui=true); -int glue_stopInputRec (bool gui=true); +void startStopInputRec(bool gui=true); +int startInputRec (bool gui=true); +int stopInputRec (bool gui=true); +}}} // giada::c::io:: #endif diff --git a/src/glue/sampleEditor.cpp b/src/glue/sampleEditor.cpp index bd4e9f0..da35360 100644 --- a/src/glue/sampleEditor.cpp +++ b/src/glue/sampleEditor.cpp @@ -54,9 +54,6 @@ extern gdMainWindow *G_MainWin; -using namespace giada::m; - - namespace giada { namespace c { namespace sampleEditor @@ -105,7 +102,7 @@ void setBeginEnd(SampleChannel* ch, int b, int e) void cut(SampleChannel* ch, int a, int b) { copy(ch, a, b); - if (!wfx::cut(ch->wave, a, b)) { + if (!m::wfx::cut(ch->wave, a, b)) { gdAlert("Unable to cut the sample!"); return; } @@ -125,7 +122,7 @@ void copy(SampleChannel* ch, int a, int b) if (m_waveBuffer != nullptr) delete m_waveBuffer; - int result = waveManager::createFromWave(ch->wave, a, b, &m_waveBuffer); + int result = m::waveManager::createFromWave(ch->wave, a, b, &m_waveBuffer); if (result != G_RES_OK) { gu_log("[sampleEditor::copy] unable to create wave buffer!\n"); return; @@ -143,7 +140,7 @@ void paste(SampleChannel* ch, int a) return; } - wfx::paste(m_waveBuffer, ch->wave, a); + m::wfx::paste(m_waveBuffer, ch->wave, a); /* Shift begin/end points to keep the previous position. */ @@ -165,7 +162,7 @@ void paste(SampleChannel* ch, int a) void silence(SampleChannel* ch, int a, int b) { - wfx::silence(ch->wave, a, b); + m::wfx::silence(ch->wave, a, b); gdSampleEditor* gdEditor = getSampleEditorWindow(); gdEditor->waveTools->waveform->refresh(); } @@ -176,7 +173,7 @@ void silence(SampleChannel* ch, int a, int b) void fade(SampleChannel* ch, int a, int b, int type) { - wfx::fade(ch->wave, a, b, type); + m::wfx::fade(ch->wave, a, b, type); gdSampleEditor* gdEditor = getSampleEditorWindow(); gdEditor->waveTools->waveform->refresh(); } @@ -187,7 +184,7 @@ void fade(SampleChannel* ch, int a, int b, int type) void smoothEdges(SampleChannel* ch, int a, int b) { - wfx::smooth(ch->wave, a, b); + m::wfx::smooth(ch->wave, a, b); gdSampleEditor* gdEditor = getSampleEditorWindow(); gdEditor->waveTools->waveform->refresh(); } @@ -198,7 +195,7 @@ void smoothEdges(SampleChannel* ch, int a, int b) void reverse(SampleChannel* ch, int a, int b) { - wfx::reverse(ch->wave, a, b); + m::wfx::reverse(ch->wave, a, b); gdSampleEditor* gdEditor = getSampleEditorWindow(); gdEditor->waveTools->waveform->refresh(); } @@ -209,7 +206,7 @@ void reverse(SampleChannel* ch, int a, int b) void normalizeHard(SampleChannel* ch, int a, int b) { - wfx::normalizeHard(ch->wave, a, b); + m::wfx::normalizeHard(ch->wave, a, b); gdSampleEditor* gdEditor = getSampleEditorWindow(); gdEditor->waveTools->waveform->refresh(); } @@ -220,7 +217,7 @@ void normalizeHard(SampleChannel* ch, int a, int b) void trim(SampleChannel* ch, int a, int b) { - if (!wfx::trim(ch->wave, a, b)) { + if (!m::wfx::trim(ch->wave, a, b)) { gdAlert("Unable to trim the sample!"); return; } @@ -272,11 +269,11 @@ void rewindPreview(SampleChannel* ch) void toNewChannel(SampleChannel* ch, int a, int b) { - SampleChannel* newCh = static_cast(glue_addChannel( + SampleChannel* newCh = static_cast(c::channel::addChannel( ch->guiChannel->getColumnIndex(), CHANNEL_SAMPLE, G_GUI_CHANNEL_H_1)); Wave* wave = nullptr; - int result = waveManager::createFromWave(ch->wave, a, b, &wave); + int result = m::waveManager::createFromWave(ch->wave, a, b, &wave); if (result != G_RES_OK) { gdAlert("Unable to copy to new channel!"); return; @@ -301,7 +298,7 @@ bool isWaveBufferFull() void shift(SampleChannel* ch, int offset) { - wfx::shift(ch->wave, offset - ch->getShift()); + m::wfx::shift(ch->wave, offset - ch->getShift()); ch->setShift(offset); gdSampleEditor* gdEditor = getSampleEditorWindow(); gdEditor->shiftTool->refresh(); diff --git a/src/glue/storage.cpp b/src/glue/storage.cpp index 726918e..8fc44d8 100644 --- a/src/glue/storage.cpp +++ b/src/glue/storage.cpp @@ -58,13 +58,15 @@ extern gdMainWindow *G_MainWin; using std::string; using std::vector; -using namespace giada::m; +using namespace giada; #ifdef WITH_VST -static void glue_fillPatchGlobalsPlugins__(vector *host, vector *patch) +static void glue_fillPatchGlobalsPlugins__(vector * host, vector* patch) { + using namespace giada::m; + for (unsigned i=0; isize(); i++) { Plugin *pl = host->at(i); patch::plugin_t ppl; @@ -85,6 +87,8 @@ static void glue_fillPatchGlobalsPlugins__(vector *host, vectorkeyboard->getTotalColumns(); i++) { geColumn *gCol = G_MainWin->keyboard->getColumn(i); patch::column_t pCol; @@ -110,6 +114,8 @@ static void glue_fillPatchColumns__() static void glue_fillPatchChannels__(bool isProject) { + using namespace giada::m; + for (unsigned i=0; iwritePatch(i, isProject); } @@ -121,6 +127,8 @@ static void glue_fillPatchChannels__(bool isProject) static void glue_fillPatchGlobals__(const string &name) { + using namespace giada::m; + patch::version = G_VERSION_STR; patch::versionMajor = G_VERSION_MAJOR; patch::versionMinor = G_VERSION_MINOR; @@ -151,6 +159,8 @@ static void glue_fillPatchGlobals__(const string &name) static bool glue_savePatch__(const string &fullPath, const string &name, bool isProject) { + using namespace giada::m; + patch::init(); glue_fillPatchGlobals__(name); @@ -177,6 +187,8 @@ static string glue_makeSamplePath__(const string& base, const Wave* w, int k) static string glue_makeUniqueSamplePath__(const string& base, const SampleChannel* ch) { + using namespace giada::m; + string path = base + G_SLASH + ch->wave->getBasename(true); if (mh::uniqueSamplePath(ch, path)) return path; @@ -208,7 +220,7 @@ void glue_savePatch(void* data) return; if (glue_savePatch__(fullPath, name, false)) { // false == not a project - conf::patchPath = gu_dirname(fullPath); + m::conf::patchPath = gu_dirname(fullPath); browser->do_callback(); } else @@ -221,6 +233,8 @@ void glue_savePatch(void* data) void glue_loadPatch(void* data) { + using namespace giada::m; + gdBrowserLoad* browser = (gdBrowserLoad*) data; string fullPath = browser->getSelectedItem(); bool isProject = gu_isProject(browser->getSelectedItem()); @@ -269,7 +283,7 @@ void glue_loadPatch(void* data) unsigned k = 0; for (const patch::channel_t& pch : patch::channels) { if (pch.column == col.index) { - Channel* ch = glue_addChannel(pch.column, pch.type, pch.size); + Channel* ch = c::channel::addChannel(pch.column, pch.type, pch.size); ch->readPatch(basePath, k, &mixer::mutex_plugins, conf::samplerate, conf::rsmpQuality); } @@ -317,6 +331,8 @@ void glue_loadPatch(void* data) void glue_saveProject(void* data) { + using namespace giada::m; + gdBrowserSave* browser = (gdBrowserSave*) data; string name = gu_stripExt(browser->getName()); string folderPath = browser->getCurrentPath(); @@ -378,11 +394,11 @@ void glue_loadSample(void* data) if (fullPath.empty()) return; - int res = glue_loadChannel(static_cast(browser->getChannel()), + int res = c::channel::loadChannel(static_cast(browser->getChannel()), fullPath); if (res == G_RES_OK) { - conf::samplePath = gu_dirname(fullPath); + m::conf::samplePath = gu_dirname(fullPath); browser->do_callback(); G_MainWin->delSubWindow(WID_SAMPLE_EDITOR); // if editor is open } @@ -396,6 +412,8 @@ void glue_loadSample(void* data) void glue_saveSample(void *data) { + using namespace giada::m; + gdBrowserSave* browser = (gdBrowserSave*) data; string name = browser->getName(); string folderPath = browser->getCurrentPath(); diff --git a/src/gui/dialogs/browser/browserBase.cpp b/src/gui/dialogs/browser/browserBase.cpp index ed1f72b..b0b05b5 100644 --- a/src/gui/dialogs/browser/browserBase.cpp +++ b/src/gui/dialogs/browser/browserBase.cpp @@ -100,7 +100,7 @@ gdBrowserBase::~gdBrowserBase() conf::browserW = w(); conf::browserH = h(); conf::browserPosition = browser->position(); - conf::browserLastPath = gu_dirname(browser->getSelectedItem()); + conf::browserLastPath = browser->getCurrentDir(); conf::browserLastValue = browser->value(); } @@ -118,22 +118,7 @@ void gdBrowserBase::cb_toggleHiddenFiles(Fl_Widget *v, void *p) { ((gdBrowserBas void gdBrowserBase::cb_up() { - string dir = browser->getCurrentDir(); - - /* Take 'dir' path and remove all chars up to the next slash, e.g.: - /path/to/my/dir -> /path/to/my - Make sure not to remove the leading '/' (OS X/Linux only). */ - - dir = dir.substr(0, dir.find_last_of(G_SLASH_STR)); - -#if defined(G_OS_MAC) || defined(G_OS_LINUX) - - if (dir.empty()) - dir = G_SLASH_STR; - -#endif - - browser->loadDir(dir); + browser->loadDir(gu_getUpDir(browser->getCurrentDir())); where->value(browser->getCurrentDir().c_str()); } diff --git a/src/gui/dialogs/channelNameInput.cpp b/src/gui/dialogs/channelNameInput.cpp index dca6fca..f2423a2 100644 --- a/src/gui/dialogs/channelNameInput.cpp +++ b/src/gui/dialogs/channelNameInput.cpp @@ -35,13 +35,15 @@ #include "channelNameInput.h" -using namespace giada::m; +using namespace giada; gdChannelNameInput::gdChannelNameInput(Channel* ch) : gdWindow(400, 64, "New channel name"), m_ch (ch) { + using namespace giada::m; + if (conf::nameX) resize(conf::nameX, conf::nameY, w(), h()); @@ -70,8 +72,8 @@ gdChannelNameInput::gdChannelNameInput(Channel* ch) gdChannelNameInput::~gdChannelNameInput() { - conf::nameX = x(); - conf::nameY = y(); + m::conf::nameX = x(); + m::conf::nameY = y(); } @@ -96,6 +98,6 @@ void gdChannelNameInput::cb_cancel() void gdChannelNameInput::cb_update() { - glue_setName(m_ch, m_name->value()); + c::channel::setName(m_ch, m_name->value()); do_callback(); } diff --git a/src/gui/dialogs/gd_mainWindow.cpp b/src/gui/dialogs/gd_mainWindow.cpp index 1066099..d03714f 100644 --- a/src/gui/dialogs/gd_mainWindow.cpp +++ b/src/gui/dialogs/gd_mainWindow.cpp @@ -43,7 +43,7 @@ extern gdMainWindow *G_MainWin; -gdMainWindow::gdMainWindow(int W, int H, const char *title, int argc, char **argv) +gdMainWindow::gdMainWindow(int W, int H, const char* title, int argc, char** argv) : gdWindow(W, H, title) { Fl::visible_focus(0); @@ -58,7 +58,7 @@ gdMainWindow::gdMainWindow(int W, int H, const char *title, int argc, char **arg Fl::set_boxtype(FL_UP_BOX, G_CUSTOM_UP_BOX); Fl::set_boxtype(FL_DOWN_BOX, G_CUSTOM_DOWN_BOX); - size_range(G_GUI_WIDTH, G_GUI_HEIGHT); + size_range(G_MIN_GUI_WIDTH, G_MIN_GUI_HEIGHT); mainMenu = new geMainMenu(8, -1); mainIO = new geMainIO(412, 8); @@ -69,21 +69,21 @@ gdMainWindow::gdMainWindow(int W, int H, const char *title, int argc, char **arg /* zone 1 - menus, and I/O tools */ - Fl_Group *zone1 = new Fl_Group(8, 8, W-16, 20); + Fl_Group* zone1 = new Fl_Group(8, 8, W-16, 20); zone1->add(mainMenu); zone1->resizable(new Fl_Box(300, 8, 80, 20)); zone1->add(mainIO); /* zone 2 - mainTransport and timing tools */ - Fl_Group *zone2 = new Fl_Group(8, mainTransport->y(), W-16, mainTransport->h()); + Fl_Group* zone2 = new Fl_Group(8, mainTransport->y(), W-16, mainTransport->h()); zone2->add(mainTransport); zone2->resizable(new Fl_Box(mainTransport->x()+mainTransport->w()+4, zone2->y(), 80, 20)); zone2->add(mainTimer); /* zone 3 - beat meter */ - Fl_Group *zone3 = new Fl_Group(8, beatMeter->y(), W-16, beatMeter->h()); + Fl_Group* zone3 = new Fl_Group(8, beatMeter->y(), W-16, beatMeter->h()); zone3->add(beatMeter); /* zone 4 - the keyboard (Fl_Group is unnecessary here, keyboard is @@ -105,13 +105,13 @@ gdMainWindow::gdMainWindow(int W, int H, const char *title, int argc, char **arg /* -------------------------------------------------------------------------- */ -void gdMainWindow::cb_endprogram(Fl_Widget *v, void *p) { G_MainWin->__cb_endprogram(); } +void gdMainWindow::cb_endprogram(Fl_Widget* v, void* p) { G_MainWin->cb_endprogram(); } /* -------------------------------------------------------------------------- */ -void gdMainWindow::__cb_endprogram() +void gdMainWindow::cb_endprogram() { if (!gdConfirmWin("Warning", "Quit Giada: are you sure?")) return; diff --git a/src/gui/dialogs/gd_mainWindow.h b/src/gui/dialogs/gd_mainWindow.h index 64a6733..8d7616e 100644 --- a/src/gui/dialogs/gd_mainWindow.h +++ b/src/gui/dialogs/gd_mainWindow.h @@ -45,19 +45,19 @@ class gdMainWindow : public gdWindow { private: - static void cb_endprogram (Fl_Widget *v, void *p); - inline void __cb_endprogram(); + static void cb_endprogram(Fl_Widget* v, void* p); + inline void cb_endprogram(); public: - geKeyboard *keyboard; - geBeatMeter *beatMeter; - geMainMenu *mainMenu; - geMainIO *mainIO; - geMainTimer *mainTimer; - geMainTransport *mainTransport; + geKeyboard* keyboard; + geBeatMeter* beatMeter; + geMainMenu* mainMenu; + geMainIO* mainIO; + geMainTimer* mainTimer; + geMainTransport* mainTransport; - gdMainWindow(int w, int h, const char *title, int argc, char **argv); + gdMainWindow(int w, int h, const char* title, int argc, char** argv); }; diff --git a/src/gui/dialogs/midiIO/midiInputChannel.cpp b/src/gui/dialogs/midiIO/midiInputChannel.cpp index 4992bb4..dffd298 100644 --- a/src/gui/dialogs/midiIO/midiInputChannel.cpp +++ b/src/gui/dialogs/midiIO/midiInputChannel.cpp @@ -59,18 +59,22 @@ gdMidiInputChannel::gdMidiInputChannel(Channel* ch) label(title.c_str()); size_range(G_DEFAULT_MIDI_INPUT_UI_W, G_DEFAULT_MIDI_INPUT_UI_H); - Fl_Group* groupHeader = new Fl_Group(G_GUI_OUTER_MARGIN, G_GUI_OUTER_MARGIN, w(), 20); + int extra = ch->type == CHANNEL_SAMPLE ? 28 : 0; + + Fl_Group* groupHeader = new Fl_Group(G_GUI_OUTER_MARGIN, G_GUI_OUTER_MARGIN, w(), 20 + extra); groupHeader->begin(); enable = new geCheck(G_GUI_OUTER_MARGIN, G_GUI_OUTER_MARGIN, 120, G_GUI_UNIT, - "enable MIDI input"); + "Enable MIDI input"); channel = new geChoice(enable->x()+enable->w()+44, G_GUI_OUTER_MARGIN, 120, G_GUI_UNIT); + veloAsVol = new geCheck(G_GUI_OUTER_MARGIN, enable->y()+enable->h()+G_GUI_OUTER_MARGIN , 120, G_GUI_UNIT, + "Velocity drives volume (one-shot only)"); groupHeader->resizable(nullptr); groupHeader->end(); - container = new geScroll(G_GUI_OUTER_MARGIN, enable->y()+enable->h()+G_GUI_OUTER_MARGIN, - w()-16, h()-76); + container = new geScroll(G_GUI_OUTER_MARGIN, groupHeader->y()+groupHeader->h()+G_GUI_OUTER_MARGIN, + w()-16, h()-72-extra); container->begin(); addChannelLearners(); @@ -94,6 +98,13 @@ gdMidiInputChannel::gdMidiInputChannel(Channel* ch) enable->value(ch->midiIn); enable->callback(cb_enable, (void*)this); + if (ch->type == CHANNEL_SAMPLE) { + veloAsVol->value(static_cast(ch)->midiInVeloAsVol); + veloAsVol->callback(cb_veloAsVol, (void*)this); + } + else + veloAsVol->hide(); + channel->add("Channel (any)"); channel->add("Channel 1"); channel->add("Channel 2"); @@ -201,6 +212,7 @@ void gdMidiInputChannel::addPluginLearners() void gdMidiInputChannel::cb_enable(Fl_Widget* w, void* p) { ((gdMidiInputChannel*)p)->cb_enable(); } void gdMidiInputChannel::cb_setChannel(Fl_Widget* w, void* p) { ((gdMidiInputChannel*)p)->cb_setChannel(); } +void gdMidiInputChannel::cb_veloAsVol(Fl_Widget* w, void* p) { ((gdMidiInputChannel*)p)->cb_veloAsVol(); } /* -------------------------------------------------------------------------- */ @@ -216,6 +228,15 @@ void gdMidiInputChannel::cb_enable() /* -------------------------------------------------------------------------- */ +void gdMidiInputChannel::cb_veloAsVol() +{ + static_cast(ch)->midiInVeloAsVol = veloAsVol->value(); +} + + +/* -------------------------------------------------------------------------- */ + + void gdMidiInputChannel::cb_setChannel() { ch->setMidiInFilter(channel->value() == 0 ? -1 : channel->value() - 1); diff --git a/src/gui/dialogs/midiIO/midiInputChannel.h b/src/gui/dialogs/midiIO/midiInputChannel.h index 523ab66..26e50bb 100644 --- a/src/gui/dialogs/midiIO/midiInputChannel.h +++ b/src/gui/dialogs/midiIO/midiInputChannel.h @@ -48,12 +48,15 @@ private: geScroll* container; geCheck* enable; + geCheck* veloAsVol; geChoice* channel; static void cb_enable(Fl_Widget* w, void* p); static void cb_setChannel(Fl_Widget* w, void* p); + static void cb_veloAsVol(Fl_Widget* w, void* p); void cb_enable(); void cb_setChannel(); + void cb_veloAsVol(); void addChannelLearners(); diff --git a/src/gui/dialogs/midiIO/midiOutputSampleCh.cpp b/src/gui/dialogs/midiIO/midiOutputSampleCh.cpp index e02c1a6..cd12d6c 100644 --- a/src/gui/dialogs/midiIO/midiOutputSampleCh.cpp +++ b/src/gui/dialogs/midiIO/midiOutputSampleCh.cpp @@ -61,13 +61,13 @@ gdMidiOutputSampleCh::gdMidiOutputSampleCh(SampleChannel* ch) /* -------------------------------------------------------------------------- */ -void gdMidiOutputSampleCh::cb_close(Fl_Widget *w, void *p) { ((gdMidiOutputSampleCh*)p)->__cb_close(); } +void gdMidiOutputSampleCh::cb_close(Fl_Widget* w, void* p) { ((gdMidiOutputSampleCh*)p)->cb_close(); } /* -------------------------------------------------------------------------- */ -void gdMidiOutputSampleCh::__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 index 3b956d3..7b679b1 100644 --- a/src/gui/dialogs/midiIO/midiOutputSampleCh.h +++ b/src/gui/dialogs/midiIO/midiOutputSampleCh.h @@ -39,17 +39,17 @@ class gdMidiOutputSampleCh : public gdMidiOutputBase { private: - SampleChannel *ch; + SampleChannel* ch; - /* __cb_close - override parent method, we need to do more stuff on close. */ + /* 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(); + static void cb_close(Fl_Widget* w, void* p); + inline void cb_close(); public: - gdMidiOutputSampleCh(SampleChannel *ch); + gdMidiOutputSampleCh(SampleChannel* ch); }; #endif diff --git a/src/gui/dialogs/sampleEditor.cpp b/src/gui/dialogs/sampleEditor.cpp index 9e98a71..275f5d7 100644 --- a/src/gui/dialogs/sampleEditor.cpp +++ b/src/gui/dialogs/sampleEditor.cpp @@ -60,14 +60,15 @@ using std::string; -using namespace giada::m; -using namespace giada::c; +using namespace giada; gdSampleEditor::gdSampleEditor(SampleChannel* ch) : gdWindow(640, 480), ch(ch) { + using namespace giada::m; + Fl_Group* upperBar = createUpperBar(); waveTools = new geWaveTools(G_GUI_OUTER_MARGIN, upperBar->y()+upperBar->h()+G_GUI_OUTER_MARGIN, @@ -101,13 +102,13 @@ gdSampleEditor::gdSampleEditor(SampleChannel* ch) gdSampleEditor::~gdSampleEditor() { - conf::sampleEditorX = x(); - conf::sampleEditorY = y(); - conf::sampleEditorW = w(); - conf::sampleEditorH = h(); - conf::sampleEditorGridVal = atoi(grid->text()); - conf::sampleEditorGridOn = snap->value(); - sampleEditor::setPreview(ch, G_PREVIEW_NONE); + m::conf::sampleEditorX = x(); + m::conf::sampleEditorY = y(); + m::conf::sampleEditorW = w(); + m::conf::sampleEditorH = h(); + m::conf::sampleEditorGridVal = atoi(grid->text()); + m::conf::sampleEditorGridOn = snap->value(); + c::sampleEditor::setPreview(ch, G_PREVIEW_NONE); } @@ -116,6 +117,8 @@ gdSampleEditor::~gdSampleEditor() Fl_Group* gdSampleEditor::createUpperBar() { + using namespace giada::m; + Fl_Group* g = new Fl_Group(G_GUI_OUTER_MARGIN, G_GUI_OUTER_MARGIN, w()-16, G_GUI_UNIT); g->begin(); grid = new geChoice(g->x(), g->y(), 50, G_GUI_UNIT); @@ -274,6 +277,8 @@ void gdSampleEditor::cb_enableSnap() void gdSampleEditor::cb_togglePreview() { + using namespace giada::c; + if (play->value()) sampleEditor::setPreview(ch, G_PREVIEW_NONE); else @@ -283,7 +288,7 @@ void gdSampleEditor::cb_togglePreview() void gdSampleEditor::cb_rewindPreview() { - sampleEditor::rewindPreview(ch); + c::sampleEditor::rewindPreview(ch); } @@ -292,16 +297,18 @@ void gdSampleEditor::cb_rewindPreview() void gdSampleEditor::cb_reload() { + using namespace giada::c; + /* TODO - move to glue::sampleEditor */ if (!gdConfirmWin("Warning", "Reload sample: are you sure?")) return; - if (glue_loadChannel(ch, ch->wave->getPath()) != G_RES_OK) + if (channel::loadChannel(ch, ch->wave->getPath()) != G_RES_OK) return; - glue_setBoost(ch, G_DEFAULT_BOOST); - glue_setPitch(ch, G_DEFAULT_PITCH); - glue_setPanning(ch, 0.5f); + channel::setBoost(ch, G_DEFAULT_BOOST); + channel::setPitch(ch, G_DEFAULT_PITCH); + channel::setPanning(ch, 0.5f); panTool->refresh(); boostTool->refresh(); diff --git a/src/gui/elems/browser.cpp b/src/gui/elems/browser.cpp index ebc8837..00f95f1 100644 --- a/src/gui/elems/browser.cpp +++ b/src/gui/elems/browser.cpp @@ -27,6 +27,7 @@ #include "../../core/const.h" #include "../../utils/string.h" +#include "../../utils/fs.h" #include "../dialogs/browser/browserBase.h" #include "basics/boxtypes.h" #include "browser.h" @@ -37,7 +38,7 @@ using std::string; geBrowser::geBrowser(int x, int y, int w, int h) : Fl_File_Browser(x, y, w, h), - showHiddenFiles(false) + m_showHiddenFiles(false) { box(G_CUSTOM_BORDER_BOX); textsize(G_GUI_FONT_SIZE_BASE); @@ -65,18 +66,18 @@ geBrowser::geBrowser(int x, int y, int w, int h) void geBrowser::toggleHiddenFiles() { - showHiddenFiles = !showHiddenFiles; - loadDir(currentDir); + m_showHiddenFiles = !m_showHiddenFiles; + loadDir(m_currentDir); } /* -------------------------------------------------------------------------- */ -void geBrowser::loadDir(const string &dir) +void geBrowser::loadDir(const string& dir) { - currentDir = dir; - load(currentDir.c_str()); + m_currentDir = dir; + load(m_currentDir.c_str()); /* Clean up unwanted elements. Hide "../" first, it just screws up things. Also remove hidden files, if requested. */ @@ -84,7 +85,7 @@ void geBrowser::loadDir(const string &dir) for (int i=size(); i>=0; i--) { if (text(i) == nullptr) continue; - if (strcmp(text(i), "../") == 0 || (!showHiddenFiles && strncmp(text(i), ".", 1) == 0)) + if (strcmp(text(i), "../") == 0 || (!m_showHiddenFiles && strncmp(text(i), ".", 1) == 0)) remove(i); } } @@ -108,12 +109,12 @@ int geBrowser::handle(int e) select(value() - 1); else if (Fl::event_key(FL_Enter)) - ((gdBrowserBase*) parent())->fireCallback(); + static_cast(parent())->fireCallback(); ret = 1; break; case FL_PUSH: // mouse if (Fl::event_clicks() > 0) // double click - ((gdBrowserBase*) parent())->fireCallback(); + static_cast(parent())->fireCallback(); ret = 1; break; case FL_RELEASE: // mouse @@ -137,7 +138,7 @@ int geBrowser::handle(int e) string geBrowser::getCurrentDir() { - return normalize(gu_getRealPath(currentDir)); + return normalize(gu_getRealPath(m_currentDir)); } @@ -150,9 +151,15 @@ string geBrowser::getSelectedItem(bool fullPath) return normalize(text(value())); else if (value() == 0) // no rows selected? return current directory - return normalize(currentDir); - else - return normalize(gu_getRealPath(currentDir + G_SLASH + normalize(text(value())))); + return normalize(m_currentDir); + else { +#ifdef G_OS_WINDOWS + string sep = m_currentDir != "" ? G_SLASH_STR : ""; +#else + string sep = G_SLASH_STR; +#endif + return normalize(gu_getRealPath(m_currentDir + sep + normalize(text(value())))); + } } @@ -169,20 +176,15 @@ void geBrowser::preselect(int pos, int line) /* -------------------------------------------------------------------------- */ -string geBrowser::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 - seem to support std::string::back() */ - -#ifdef __APPLE__ - if (out[out.length() - 1] == G_SLASH && out.length() > 1) -#else - if (out.back() == G_SLASH && out.length() > 1) -#endif + /* If string ends with G_SLASH, remove it. Don't do it if is the root dir, + that is '/' on Unix or '[x]:\' on Windows. */ + //if (out.back() == G_SLASH && out.length() > 1) + if (out.back() == G_SLASH && !gu_isRootDir(s)) out = out.substr(0, out.size()-1); return out; } diff --git a/src/gui/elems/browser.h b/src/gui/elems/browser.h index ef0aa07..25db7e8 100644 --- a/src/gui/elems/browser.h +++ b/src/gui/elems/browser.h @@ -39,11 +39,11 @@ class geBrowser : public Fl_File_Browser { private: - std::string currentDir; - bool showHiddenFiles; + std::string m_currentDir; + bool m_showHiddenFiles; /* normalize - * Make sure the std::string never ends with a trailing slash. */ + Makes sure the std::string never ends with a trailing slash. */ std::string normalize(const std::string &s); @@ -54,13 +54,13 @@ public: void toggleHiddenFiles(); /* init - * Initialize browser and show 'dir' as initial directory. */ + Initializes browser and show 'dir' as initial directory. */ void loadDir(const std::string &dir); /* getSelectedItem - * Return the full path or just the displayed name of the i-th selected item. - * Always with the trailing slash! */ + Returns the full path or just the displayed name of the i-th selected item. + Always with the trailing slash! */ std::string getSelectedItem(bool fullPath=true); diff --git a/src/gui/elems/config/tabAudio.cpp b/src/gui/elems/config/tabAudio.cpp index 7c27e40..baf56d4 100644 --- a/src/gui/elems/config/tabAudio.cpp +++ b/src/gui/elems/config/tabAudio.cpp @@ -63,7 +63,9 @@ geTabAudio::geTabAudio(int X, int Y, int W, int H) new geBox(x(), rsmpQuality->y()+rsmpQuality->h()+8, w(), 92, "Restart Giada for the changes to take effect."); end(); + labelsize(G_GUI_FONT_SIZE_BASE); + selection_color(G_COLOR_GREY_4); soundsys->add("(none)"); diff --git a/src/gui/elems/config/tabBehaviors.cpp b/src/gui/elems/config/tabBehaviors.cpp index 4c50efc..b6a57c4 100644 --- a/src/gui/elems/config/tabBehaviors.cpp +++ b/src/gui/elems/config/tabBehaviors.cpp @@ -61,6 +61,7 @@ geTabBehaviors::geTabBehaviors(int X, int Y, int W, int H) end(); labelsize(G_GUI_FONT_SIZE_BASE); + selection_color(G_COLOR_GREY_4); conf::recsStopOnChanHalt == 1 ? recsStopOnChanHalt_1->value(1) : recsStopOnChanHalt_0->value(1); conf::chansStopOnSeqHalt == 1 ? chansStopOnSeqHalt_1->value(1) : chansStopOnSeqHalt_0->value(1); diff --git a/src/gui/elems/config/tabMidi.cpp b/src/gui/elems/config/tabMidi.cpp index dbe3e6a..b35e0d0 100644 --- a/src/gui/elems/config/tabMidi.cpp +++ b/src/gui/elems/config/tabMidi.cpp @@ -60,6 +60,7 @@ geTabMidi::geTabMidi(int X, int Y, int W, int H) end(); labelsize(G_GUI_FONT_SIZE_BASE); + selection_color(G_COLOR_GREY_4); system->callback(cb_changeSystem, (void*)this); diff --git a/src/gui/elems/config/tabMisc.cpp b/src/gui/elems/config/tabMisc.cpp index 7f1ab07..b1f4e2d 100644 --- a/src/gui/elems/config/tabMisc.cpp +++ b/src/gui/elems/config/tabMisc.cpp @@ -46,6 +46,7 @@ geTabMisc::geTabMisc(int X, int Y, int W, int H) debugMsg->add("To file"); labelsize(G_GUI_FONT_SIZE_BASE); + selection_color(G_COLOR_GREY_4); switch (conf::logMode) { case LOG_MODE_MUTE: diff --git a/src/gui/elems/config/tabPlugins.cpp b/src/gui/elems/config/tabPlugins.cpp index 96b3acb..d9074a6 100644 --- a/src/gui/elems/config/tabPlugins.cpp +++ b/src/gui/elems/config/tabPlugins.cpp @@ -67,6 +67,7 @@ geTabPlugins::geTabPlugins(int X, int Y, int W, int H) end(); labelsize(G_GUI_FONT_SIZE_BASE); + selection_color(G_COLOR_GREY_4); m_info->label("Scan in progress. Please wait..."); m_info->hide(); diff --git a/src/gui/elems/mainWindow/keyboard/channel.cpp b/src/gui/elems/mainWindow/keyboard/channel.cpp index 36c7140..a222174 100644 --- a/src/gui/elems/mainWindow/keyboard/channel.cpp +++ b/src/gui/elems/mainWindow/keyboard/channel.cpp @@ -46,7 +46,7 @@ extern gdMainWindow* G_MainWin; -using namespace giada::m; +using namespace giada; geChannel::geChannel(int X, int Y, int W, int H, int type, Channel* ch) @@ -74,7 +74,7 @@ void geChannel::cb_openFxWindow(Fl_Widget* v, void* p) { ((geChannel*)p)->cb_ope void geChannel::cb_arm() { - glue_toggleArm(ch, true); + c::channel::toggleArm(ch, true); } @@ -83,7 +83,7 @@ void geChannel::cb_arm() void geChannel::cb_mute() { - glue_toggleMute(ch); + c::channel::toggleMute(ch); } @@ -92,7 +92,7 @@ void geChannel::cb_mute() void geChannel::cb_solo() { - solo->value() ? glue_setSoloOn(ch) : glue_setSoloOff(ch); + solo->value() ? c::channel::setSoloOn(ch) : c::channel::setSoloOff(ch); } @@ -101,7 +101,7 @@ void geChannel::cb_solo() void geChannel::cb_changeVol() { - glue_setVolume(ch, vol->value()); + c::channel::setVolume(ch, vol->value()); } @@ -111,7 +111,7 @@ void geChannel::cb_changeVol() #ifdef WITH_VST void geChannel::cb_openFxWindow() { - gu_openSubWindow(G_MainWin, new gdPluginList(pluginHost::CHANNEL, ch), WID_FX_LIST); + gu_openSubWindow(G_MainWin, new gdPluginList(m::pluginHost::CHANNEL, ch), WID_FX_LIST); } #endif diff --git a/src/gui/elems/mainWindow/keyboard/column.cpp b/src/gui/elems/mainWindow/keyboard/column.cpp index 70c178c..74861af 100644 --- a/src/gui/elems/mainWindow/keyboard/column.cpp +++ b/src/gui/elems/mainWindow/keyboard/column.cpp @@ -45,6 +45,7 @@ using std::vector; using std::string; +using namespace giada; geColumn::geColumn(int X, int Y, int W, int H, int index, geKeyboard* parent) @@ -110,9 +111,9 @@ int geColumn::handle(int e) int result = 0; for (string& path : paths) { gu_log("[geColumn::handle] loading %s...\n", path.c_str()); - SampleChannel* c = static_cast(glue_addChannel( + SampleChannel* c = static_cast(c::channel::addChannel( m_index, CHANNEL_SAMPLE, G_GUI_CHANNEL_H_1)); - result = glue_loadChannel(c, gu_stripFileUrl(path)); + result = c::channel::loadChannel(c, gu_stripFileUrl(path)); if (result != G_RES_OK) { deleteChannel(c->guiChannel); fails = true; @@ -255,7 +256,7 @@ void geColumn::__cb_addChannel() gu_log("[geColumn::__cb_addChannel] m_index = %d\n", m_index); int type = openTypeMenu(); if (type) - glue_addChannel(m_index, type, G_GUI_CHANNEL_H_1); + c::channel::addChannel(m_index, type, G_GUI_CHANNEL_H_1); } diff --git a/src/gui/elems/mainWindow/keyboard/keyboard.cpp b/src/gui/elems/mainWindow/keyboard/keyboard.cpp index 9872c66..5deaea9 100644 --- a/src/gui/elems/mainWindow/keyboard/keyboard.cpp +++ b/src/gui/elems/mainWindow/keyboard/keyboard.cpp @@ -214,6 +214,8 @@ so on should be moved to the proper widget: gdMainWindow or (better) geControlle int geKeyboard::handle(int e) { + using namespace giada::c; + int ret = Fl_Group::handle(e); // assume the buttons won't handle the Keyboard events switch (e) { case FL_FOCUS: @@ -236,13 +238,13 @@ int geKeyboard::handle(int e) } else if (Fl::event_key() == FL_End && !endPressed) { endPressed = true; - glue_startStopInputRec(false); // not from GUI + io::startStopInputRec(false); // not from GUI ret = 1; break; } else if (Fl::event_key() == FL_Enter && !enterPressed) { enterPressed = true; - glue_startStopActionRec(false); // not from GUI + io::startStopActionRec(false); // not from GUI ret = 1; break; } diff --git a/src/gui/elems/mainWindow/keyboard/midiChannel.cpp b/src/gui/elems/mainWindow/keyboard/midiChannel.cpp index 5f17b2f..8e1957c 100644 --- a/src/gui/elems/mainWindow/keyboard/midiChannel.cpp +++ b/src/gui/elems/mainWindow/keyboard/midiChannel.cpp @@ -55,7 +55,6 @@ extern gdMainWindow* G_MainWin; using std::string; -using namespace giada; namespace @@ -86,6 +85,8 @@ enum class Menu void menuCallback(Fl_Widget* w, void* v) { + using namespace giada; + geMidiChannel* gch = static_cast(w); Menu selectedItem = (Menu) (intptr_t) v; @@ -129,13 +130,13 @@ void menuCallback(Fl_Widget* w, void* v) static_cast(gch->parent())->repositionChannels(); break; case Menu::CLONE_CHANNEL: - glue_cloneChannel(gch->ch); + c::channel::cloneChannel(gch->ch); break; case Menu::RENAME_CHANNEL: gu_openSubWindow(G_MainWin, new gdChannelNameInput(gch->ch), WID_SAMPLE_NAME); break; case Menu::DELETE_CHANNEL: - glue_deleteChannel(gch->ch); + c::channel::deleteChannel(gch->ch); break; } } @@ -213,8 +214,10 @@ void geMidiChannel::cb_openMenu(Fl_Widget* v, void* p) { ((geMidiChannel*)p)->cb void geMidiChannel::cb_button() { + using namespace giada; + if (button->value()) - glue_keyPress(ch, Fl::event_ctrl(), Fl::event_shift()); + c::io::keyPress(static_cast(ch), Fl::event_ctrl(), Fl::event_shift()); } @@ -299,7 +302,7 @@ void geMidiChannel::update() mainButton->label(label.c_str()); - vol->value(mch->volume); + vol->value(mch->getVolume()); mute->value(mch->mute); solo->value(mch->solo); diff --git a/src/gui/elems/mainWindow/keyboard/sampleChannel.cpp b/src/gui/elems/mainWindow/keyboard/sampleChannel.cpp index c96b2eb..08b582b 100644 --- a/src/gui/elems/mainWindow/keyboard/sampleChannel.cpp +++ b/src/gui/elems/mainWindow/keyboard/sampleChannel.cpp @@ -61,9 +61,6 @@ extern gdMainWindow* G_MainWin; -using namespace giada; - - namespace { enum class Menu @@ -100,12 +97,14 @@ enum class Menu void menuCallback(Fl_Widget* w, void* v) { + using namespace giada; + geSampleChannel* gch = static_cast(w); Menu selectedItem = (Menu) (intptr_t) v; switch (selectedItem) { case Menu::INPUT_MONITOR: { - glue_toggleInputMonitor(gch->ch); + c::channel::toggleInputMonitor(gch->ch); break; } case Menu::LOAD_SAMPLE: { @@ -184,7 +183,7 @@ void menuCallback(Fl_Widget* w, void* v) break; } case Menu::CLONE_CHANNEL: { - glue_cloneChannel(gch->ch); + c::channel::cloneChannel(gch->ch); break; } case Menu::RENAME_CHANNEL: { @@ -192,11 +191,11 @@ void menuCallback(Fl_Widget* w, void* v) break; } case Menu::FREE_CHANNEL: { - glue_freeChannel(gch->ch); + c::channel::freeChannel(gch->ch); break; } case Menu::DELETE_CHANNEL: { - glue_deleteChannel(gch->ch); + c::channel::deleteChannel(gch->ch); break; } } @@ -267,28 +266,32 @@ geSampleChannel::geSampleChannel(int X, int Y, int W, int H, SampleChannel* ch) /* -------------------------------------------------------------------------- */ -void geSampleChannel::cb_button (Fl_Widget* v, void* p) { ((geSampleChannel*)p)->__cb_button(); } -void geSampleChannel::cb_openMenu (Fl_Widget* v, void* p) { ((geSampleChannel*)p)->__cb_openMenu(); } -void geSampleChannel::cb_readActions (Fl_Widget* v, void* p) { ((geSampleChannel*)p)->__cb_readActions(); } +void geSampleChannel::cb_button (Fl_Widget* v, void* p) { ((geSampleChannel*)p)->cb_button(); } +void geSampleChannel::cb_openMenu (Fl_Widget* v, void* p) { ((geSampleChannel*)p)->cb_openMenu(); } +void geSampleChannel::cb_readActions (Fl_Widget* v, void* p) { ((geSampleChannel*)p)->cb_readActions(); } /* -------------------------------------------------------------------------- */ -void geSampleChannel::__cb_button() +void geSampleChannel::cb_button() { - if (button->value()) // pushed - glue_keyPress(ch, Fl::event_ctrl(), Fl::event_shift()); + using namespace giada; + + if (button->value()) // pushed, max velocity (127 i.e. 0x7f) + c::io::keyPress(ch, Fl::event_ctrl(), Fl::event_shift(), 0x7F); else // released - glue_keyRelease(ch, Fl::event_ctrl(), Fl::event_shift()); + c::io::keyRelease(ch, Fl::event_ctrl(), Fl::event_shift()); } /* -------------------------------------------------------------------------- */ -void geSampleChannel::__cb_openMenu() +void geSampleChannel::cb_openMenu() { + using namespace giada; + /* If you're recording (input or actions) no menu is allowed; you can't do anything, especially deallocate the channel */ @@ -357,9 +360,10 @@ void geSampleChannel::__cb_openMenu() /* -------------------------------------------------------------------------- */ -void geSampleChannel::__cb_readActions() +void geSampleChannel::cb_readActions() { - glue_toggleReadingRecs(static_cast(ch)); + using namespace giada::c::channel; + toggleReadingRecs(static_cast(ch)); } @@ -368,6 +372,8 @@ void geSampleChannel::__cb_readActions() void geSampleChannel::refresh() { + using namespace giada; + if (!mainButton->visible()) // mainButton invisible? status too (see below) return; @@ -433,7 +439,7 @@ void geSampleChannel::update() modeBox->value(sch->mode); modeBox->redraw(); - vol->value(sch->volume); + vol->value(sch->getVolume()); mute->value(sch->mute); solo->value(sch->solo); diff --git a/src/gui/elems/mainWindow/keyboard/sampleChannel.h b/src/gui/elems/mainWindow/keyboard/sampleChannel.h index 4cb99d0..0d544c0 100644 --- a/src/gui/elems/mainWindow/keyboard/sampleChannel.h +++ b/src/gui/elems/mainWindow/keyboard/sampleChannel.h @@ -41,12 +41,12 @@ class geSampleChannel : public geChannel { private: - static void cb_button (Fl_Widget* v, void* p); - static void cb_openMenu (Fl_Widget* v, void* p); + static void cb_button(Fl_Widget* v, void* p); + static void cb_openMenu(Fl_Widget* v, void* p); static void cb_readActions(Fl_Widget* v, void* p); - void __cb_button (); - void __cb_openMenu (); - void __cb_readActions(); + void cb_button(); + void cb_openMenu(); + void cb_readActions(); public: diff --git a/src/gui/elems/mainWindow/keyboard/sampleChannelButton.cpp b/src/gui/elems/mainWindow/keyboard/sampleChannelButton.cpp index 8ec528c..405daa5 100644 --- a/src/gui/elems/mainWindow/keyboard/sampleChannelButton.cpp +++ b/src/gui/elems/mainWindow/keyboard/sampleChannelButton.cpp @@ -40,6 +40,9 @@ extern gdMainWindow* G_MainWin; +using namespace giada; + + geSampleChannelButton::geSampleChannelButton(int x, int y, int w, int h, const char* l) : geChannelButton(x, y, w, h, l) @@ -63,7 +66,7 @@ int geSampleChannelButton::handle(int e) case FL_PASTE: { geSampleChannel* gch = static_cast(parent()); SampleChannel* ch = static_cast(gch->ch); - int result = glue_loadChannel(ch, gu_trim(gu_stripFileUrl(Fl::event_text()))); + int result = c::channel::loadChannel(ch, gu_trim(gu_stripFileUrl(Fl::event_text()))); if (result != G_RES_OK) G_MainWin->keyboard->printChannelMessage(result); ret = 1; diff --git a/src/gui/elems/mainWindow/mainTransport.cpp b/src/gui/elems/mainWindow/mainTransport.cpp index 057ce67..f61207d 100644 --- a/src/gui/elems/mainWindow/mainTransport.cpp +++ b/src/gui/elems/mainWindow/mainTransport.cpp @@ -96,7 +96,8 @@ void geMainTransport::__cb_play() void geMainTransport::__cb_recAction() { - glue_startStopActionRec(true); + using namespace giada::c::io; + startStopActionRec(true); } @@ -105,7 +106,8 @@ void geMainTransport::__cb_recAction() void geMainTransport::__cb_recInput() { - glue_startStopInputRec(true); + using namespace giada::c::io; + startStopInputRec(true); } diff --git a/src/gui/elems/sampleEditor/boostTool.cpp b/src/gui/elems/sampleEditor/boostTool.cpp index f633afc..a0e1eac 100644 --- a/src/gui/elems/sampleEditor/boostTool.cpp +++ b/src/gui/elems/sampleEditor/boostTool.cpp @@ -42,10 +42,7 @@ #include "boostTool.h" -using namespace giada::m; - - -geBoostTool::geBoostTool(int X, int Y, SampleChannel *ch) +geBoostTool::geBoostTool(int X, int Y, SampleChannel* ch) : Fl_Group(X, Y, 220, 20), ch (ch) { @@ -73,7 +70,9 @@ geBoostTool::geBoostTool(int X, int Y, SampleChannel *ch) void geBoostTool::refresh() { - input->value(gu_fToString(gu_linearToDB(ch->getBoost()), 2).c_str()); // 2 digits + using namespace giada::u; + + input->value(gu_fToString(math::linearToDB(ch->getBoost()), 2).c_str()); // 2 digits // A dial greater than it's max value goes crazy dial->value(ch->getBoost() <= 10.0f ? ch->getBoost() : 10.0f); } @@ -82,21 +81,23 @@ void geBoostTool::refresh() /* -------------------------------------------------------------------------- */ -void geBoostTool::cb_setBoost (Fl_Widget *w, void *p) { ((geBoostTool*)p)->__cb_setBoost(); } -void geBoostTool::cb_setBoostNum(Fl_Widget *w, void *p) { ((geBoostTool*)p)->__cb_setBoostNum(); } -void geBoostTool::cb_normalize (Fl_Widget *w, void *p) { ((geBoostTool*)p)->__cb_normalize(); } +void geBoostTool::cb_setBoost (Fl_Widget* w, void* p) { ((geBoostTool*)p)->cb_setBoost(); } +void geBoostTool::cb_setBoostNum(Fl_Widget* w, void* p) { ((geBoostTool*)p)->cb_setBoostNum(); } +void geBoostTool::cb_normalize (Fl_Widget* w, void* p) { ((geBoostTool*)p)->cb_normalize(); } /* -------------------------------------------------------------------------- */ -void geBoostTool::__cb_setBoost() +void geBoostTool::cb_setBoost() { + using namespace giada::c; + if (Fl::event() == FL_DRAG) - glue_setBoost(ch, dial->value()); + channel::setBoost(ch, dial->value()); else if (Fl::event() == FL_RELEASE) { - glue_setBoost(ch, dial->value()); + channel::setBoost(ch, dial->value()); static_cast(window())->waveTools->updateWaveform(); } } @@ -105,9 +106,11 @@ void geBoostTool::__cb_setBoost() /* -------------------------------------------------------------------------- */ -void geBoostTool::__cb_setBoostNum() +void geBoostTool::cb_setBoostNum() { - glue_setBoost(ch, gu_dBtoLinear(atof(input->value()))); + using namespace giada; + + c::channel::setBoost(ch, u::math::dBtoLinear(atof(input->value()))); static_cast(window())->waveTools->updateWaveform(); } @@ -115,10 +118,12 @@ void geBoostTool::__cb_setBoostNum() /* -------------------------------------------------------------------------- */ -void geBoostTool::__cb_normalize() +void geBoostTool::cb_normalize() { - float val = wfx::normalizeSoft(ch->wave); - glue_setBoost(ch, val); // it's like a fake user moving the dial + using namespace giada; + + float val = m::wfx::normalizeSoft(ch->wave); + c::channel::setBoost(ch, val); // it's like a fake user moving the dial static_cast(window())->waveTools->updateWaveform(); } diff --git a/src/gui/elems/sampleEditor/boostTool.h b/src/gui/elems/sampleEditor/boostTool.h index d3ce340..1dc2d7c 100644 --- a/src/gui/elems/sampleEditor/boostTool.h +++ b/src/gui/elems/sampleEditor/boostTool.h @@ -43,23 +43,23 @@ class geBoostTool : public Fl_Group { private: - SampleChannel *ch; + SampleChannel* ch; - geBox *label; - geDial *dial; - geInput *input; - geButton *normalize; + geBox* label; + geDial* dial; + geInput* input; + geButton* normalize; - static void cb_setBoost (Fl_Widget *w, void *p); - static void cb_setBoostNum(Fl_Widget *w, void *p); - static void cb_normalize (Fl_Widget *w, void *p); - inline void __cb_setBoost (); - inline void __cb_setBoostNum(); - inline void __cb_normalize (); + static void cb_setBoost(Fl_Widget* w, void* p); + static void cb_setBoostNum(Fl_Widget* w, void* p); + static void cb_normalize(Fl_Widget* w, void* p); + inline void cb_setBoost(); + inline void cb_setBoostNum(); + inline void cb_normalize(); public: - geBoostTool(int x, int y, SampleChannel *ch); + geBoostTool(int x, int y, SampleChannel* ch); void refresh(); }; diff --git a/src/gui/elems/sampleEditor/panTool.cpp b/src/gui/elems/sampleEditor/panTool.cpp index 9c638d4..29e4530 100644 --- a/src/gui/elems/sampleEditor/panTool.cpp +++ b/src/gui/elems/sampleEditor/panTool.cpp @@ -43,6 +43,7 @@ using std::string; +using namespace giada; gePanTool::gePanTool(int x, int y, SampleChannel *ch) @@ -103,7 +104,7 @@ void gePanTool::cb_panReset(Fl_Widget *w, void *p) { ((gePanTool*)p)->__cb_panRe void gePanTool::__cb_panning() { - glue_setPanning(ch, dial->value()); + c::channel::setPanning(ch, dial->value()); } @@ -112,5 +113,5 @@ void gePanTool::__cb_panning() void gePanTool::__cb_panReset() { - glue_setPanning(ch, 0.5f); + c::channel::setPanning(ch, 0.5f); } \ No newline at end of file diff --git a/src/gui/elems/sampleEditor/pitchTool.cpp b/src/gui/elems/sampleEditor/pitchTool.cpp index a9b7dfb..33173ca 100644 --- a/src/gui/elems/sampleEditor/pitchTool.cpp +++ b/src/gui/elems/sampleEditor/pitchTool.cpp @@ -41,7 +41,7 @@ #include "pitchTool.h" -using namespace giada::m; +using namespace giada; gePitchTool::gePitchTool(int x, int y, SampleChannel* ch) @@ -104,7 +104,7 @@ void gePitchTool::cb_setPitchNum (Fl_Widget* w, void* p) { ((gePitchTool*)p)-> void gePitchTool::__cb_setPitch() { - glue_setPitch(ch, dial->value()); + c::channel::setPitch(ch, dial->value()); } @@ -113,7 +113,7 @@ void gePitchTool::__cb_setPitch() void gePitchTool::__cb_setPitchNum() { - glue_setPitch(ch, atof(input->value())); + c::channel::setPitch(ch, atof(input->value())); } @@ -122,7 +122,7 @@ void gePitchTool::__cb_setPitchNum() void gePitchTool::__cb_setPitchHalf() { - glue_setPitch(ch, dial->value()/2); + c::channel::setPitch(ch, dial->value()/2); } @@ -131,7 +131,7 @@ void gePitchTool::__cb_setPitchHalf() void gePitchTool::__cb_setPitchDouble() { - glue_setPitch(ch, dial->value()*2); + c::channel::setPitch(ch, dial->value()*2); } @@ -141,7 +141,7 @@ void gePitchTool::__cb_setPitchDouble() void gePitchTool::__cb_setPitchToBar() { // TODO - opaque channel's count - glue_setPitch(ch, (ch->getEnd()*2) / (float) clock::getFramesPerBar()); + c::channel::setPitch(ch, (ch->getEnd()*2) / (float) m::clock::getFramesPerBar()); } @@ -151,7 +151,7 @@ void gePitchTool::__cb_setPitchToBar() void gePitchTool::__cb_setPitchToSong() { // TODO - opaque channel's count - glue_setPitch(ch, (ch->getEnd()*2) / (float) clock::getTotalFrames()); + c::channel::setPitch(ch, (ch->getEnd()*2) / (float) m::clock::getTotalFrames()); } @@ -160,5 +160,5 @@ void gePitchTool::__cb_setPitchToSong() void gePitchTool::__cb_resetPitch() { - glue_setPitch(ch, G_DEFAULT_PITCH); + c::channel::setPitch(ch, G_DEFAULT_PITCH); } diff --git a/src/gui/elems/sampleEditor/volumeTool.cpp b/src/gui/elems/sampleEditor/volumeTool.cpp index 9fb8b46..ddcdfb3 100644 --- a/src/gui/elems/sampleEditor/volumeTool.cpp +++ b/src/gui/elems/sampleEditor/volumeTool.cpp @@ -44,7 +44,7 @@ using std::string; -geVolumeTool::geVolumeTool(int X, int Y, SampleChannel *ch) +geVolumeTool::geVolumeTool(int X, int Y, SampleChannel* ch) : Fl_Group(X, Y, 150, 20), ch (ch) { @@ -68,8 +68,10 @@ geVolumeTool::geVolumeTool(int X, int Y, SampleChannel *ch) void geVolumeTool::refresh() { + using namespace giada::u; + string tmp; - float dB = gu_linearToDB(ch->volume); + float dB = math::linearToDB(ch->getVolume()); if (dB > -INFINITY) tmp = gu_fToString(dB, 2); // 2 digits else tmp = "-inf"; input->value(tmp.c_str()); @@ -80,8 +82,8 @@ void geVolumeTool::refresh() /* -------------------------------------------------------------------------- */ -void geVolumeTool::cb_setVolume (Fl_Widget *w, void *p) { ((geVolumeTool*)p)->__cb_setVolume(); } -void geVolumeTool::cb_setVolumeNum(Fl_Widget *w, void *p) { ((geVolumeTool*)p)->__cb_setVolumeNum(); } +void geVolumeTool::cb_setVolume (Fl_Widget* w, void* p) { ((geVolumeTool*)p)->__cb_setVolume(); } +void geVolumeTool::cb_setVolumeNum(Fl_Widget* w, void* p) { ((geVolumeTool*)p)->__cb_setVolumeNum(); } /* -------------------------------------------------------------------------- */ @@ -89,7 +91,9 @@ void geVolumeTool::cb_setVolumeNum(Fl_Widget *w, void *p) { ((geVolumeTool*)p)-> void geVolumeTool::__cb_setVolume() { - glue_setVolume(ch, dial->value(), false, true); + using namespace giada; + + c::channel::setVolume(ch, dial->value(), false, true); refresh(); } @@ -99,7 +103,9 @@ void geVolumeTool::__cb_setVolume() void geVolumeTool::__cb_setVolumeNum() { + using namespace giada; + float value = pow(10, (atof(input->value()) / 20)); // linear = 10^(dB/20) - glue_setVolume(ch, value, false, true); + c::channel::setVolume(ch, value, false, true); dial->value(ch->guiChannel->vol->value()); } diff --git a/src/main.cpp b/src/main.cpp index e168a5f..cfa9e32 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -42,19 +42,20 @@ #include "core/kernelMidi.h" #include "core/recorder.h" #include "utils/gui.h" +#include "utils/time.h" #include "gui/dialogs/gd_mainWindow.h" #include "core/pluginHost.h" pthread_t G_videoThread; bool G_quit; -gdMainWindow *G_MainWin; +gdMainWindow* G_MainWin; -void *videoThreadCb(void *arg); +void* videoThreadCb(void* arg); -int main(int argc, char **argv) +int main(int argc, char** argv) { G_quit = false; @@ -83,16 +84,14 @@ int main(int argc, char **argv) } -void *videoThreadCb(void *arg) +void* videoThreadCb(void* arg) { - if (giada::m::kernelAudio::getStatus()) + using namespace giada; + + if (m::kernelAudio::getStatus()) while (!G_quit) { gu_refreshUI(); -#ifdef _WIN32 - Sleep(G_GUI_SLEEP); -#else - usleep(G_GUI_SLEEP); -#endif + u::time::sleep(G_GUI_REFRESH_RATE); } pthread_exit(nullptr); return 0; diff --git a/src/utils/fs.cpp b/src/utils/fs.cpp index 4cbfba1..b29ba78 100644 --- a/src/utils/fs.cpp +++ b/src/utils/fs.cpp @@ -146,7 +146,7 @@ bool gu_mkdir(const string &path) /* -------------------------------------------------------------------------- */ -string gu_basename(const string &s) +string gu_basename(const string& s) { string out = s; out.erase(0, out.find_last_of(G_SLASH_STR) + 1); @@ -157,7 +157,7 @@ string gu_basename(const string &s) /* -------------------------------------------------------------------------- */ -string gu_dirname(const string &path) +string gu_dirname(const string& path) { if (path.empty()) return ""; @@ -187,7 +187,7 @@ string gu_getCurrentPath() /* -------------------------------------------------------------------------- */ -string gu_getExt(const string &file) +string gu_getExt(const string& file) { // TODO - use std functions int len = strlen(file.c_str()); @@ -207,7 +207,7 @@ string gu_getExt(const string &file) /* -------------------------------------------------------------------------- */ -string gu_stripExt(const string &s) +string gu_stripExt(const string& s) { return s.substr(0, s.find_last_of(".")); } @@ -216,7 +216,7 @@ string gu_stripExt(const string &s) /* -------------------------------------------------------------------------- */ -bool gu_isProject(const string &path) +bool gu_isProject(const string& path) { /** FIXME - checks too weak */ @@ -229,7 +229,7 @@ bool gu_isProject(const string &path) /* -------------------------------------------------------------------------- */ -string gu_stripFileUrl(const string &f) +string gu_stripFileUrl(const string& f) { string out = f; out = gu_replace(out, "file://", ""); @@ -255,13 +255,13 @@ string gu_getHomePath() #elif defined(__APPLE__) - struct passwd *p = getpwuid(getuid()); + struct passwd* p = getpwuid(getuid()); if (p == nullptr) { gu_log("[gu_getHomePath] unable to fetch user infos\n"); return ""; } else { - const char *home = p->pw_dir; + const char* home = p->pw_dir; snprintf(path, PATH_MAX, "%s/Library/Application Support/Giada", home); } @@ -269,3 +269,40 @@ string gu_getHomePath() return string(path); } + + +/* -------------------------------------------------------------------------- */ + + +bool gu_isRootDir(const std::string& s) +{ + if (s == "") + return false; + +#ifdef G_OS_WINDOWS + + return s.length() <= 3 && s[1] == ':'; /* X: or X:\ */ + +#else + + return s == G_SLASH_STR; + +#endif +} + + +/* -------------------------------------------------------------------------- */ + + +std::string gu_getUpDir(const std::string& s) +{ +#ifdef G_OS_WINDOWS + + /* If root, let the user browse the drives list by returning "". */ + if (gu_isRootDir(s)) + return ""; + +#endif + + return s.substr(0, s.find_last_of(G_SLASH_STR)) + G_SLASH_STR; +} \ No newline at end of file diff --git a/src/utils/fs.h b/src/utils/fs.h index 27b0d2e..2b9a216 100644 --- a/src/utils/fs.h +++ b/src/utils/fs.h @@ -37,6 +37,12 @@ bool gu_fileExists(const std::string& path); bool gu_dirExists(const std::string& path); bool gu_isDir(const std::string& path); + +/* isRootDir +Tells whether 's' is '/' on Unix or '[X]:\' on Windows. */ + +bool gu_isRootDir(const std::string& s); + bool gu_isProject(const std::string& path); bool gu_mkdir(const std::string& path); std::string gu_getCurrentPath(); @@ -64,5 +70,11 @@ std::string gu_stripExt(const std::string& s); std::string gu_stripFileUrl(const std::string& s); +/* gu_getUpDir +Returns the upper directory: +/path/to/my/directory -> /path/to/my/ */ + +std::string gu_getUpDir(const std::string& s); + #endif diff --git a/src/utils/math.cpp b/src/utils/math.cpp index 402b164..9bb7ca0 100644 --- a/src/utils/math.cpp +++ b/src/utils/math.cpp @@ -29,16 +29,22 @@ #include "math.h" -float gu_linearToDB(float f) +namespace giada { +namespace u { +namespace math { - return 20 * std::log10(f); +float linearToDB(float f) +{ + return 20 * std::log10(f); } /* -------------------------------------------------------------------------- */ -float gu_dBtoLinear(float f) +float dBtoLinear(float f) { - return std::pow(10, f/20.0f); + return std::pow(10, f/20.0f); } + +}}} // giada::u::math:: \ No newline at end of file diff --git a/src/utils/math.h b/src/utils/math.h index 668c9f7..c17d82d 100644 --- a/src/utils/math.h +++ b/src/utils/math.h @@ -29,9 +29,24 @@ #define G_UTILS_MATH_H -float gu_linearToDB(float f); +namespace giada { +namespace u { +namespace math +{ +float linearToDB(float f); +float dBtoLinear(float f); -float gu_dBtoLinear(float f); +/* map (template) +Maps 'x' in range [a, b] to a new range [w, z]. Source: + https://en.wikipedia.org/wiki/Linear_equation#Two-point_form*/ + +template +T map(T x, T a, T b, T w, T z) +{ + return (((x - a) / (b - a)) * (z - w)) + w; +} + +}}} // giada::u::math:: #endif diff --git a/src/utils/string.cpp b/src/utils/string.cpp index fda5839..2fc883e 100644 --- a/src/utils/string.cpp +++ b/src/utils/string.cpp @@ -108,8 +108,10 @@ std::string gu_format(const char* format, ...) /* Compute the size of the new expanded string (i.e. with replacement taken into account). */ - size_t size = vsnprintf(nullptr, 0, format, args); - + va_start(args, format); + size_t size = vsnprintf(nullptr, 0, format, args) + 1; + va_end(args); + /* Create a new temporary char array to hold the new expanded string. */ std::unique_ptr tmp(new char[size]); diff --git a/src/utils/time.cpp b/src/utils/time.cpp index ec3faa5..2667c81 100644 --- a/src/utils/time.cpp +++ b/src/utils/time.cpp @@ -27,13 +27,8 @@ * -------------------------------------------------------------------------- */ -#include "../core/const.h" -#ifndef G_OS_MAC - #include - #include -#else - #include -#endif +#include +#include #include "time.h" @@ -43,10 +38,6 @@ namespace time { void sleep(int millisecs) { -#ifndef G_OS_MAC std::this_thread::sleep_for(std::chrono::milliseconds(millisecs)); -#else - usleep(millisecs * 1000); -#endif } }}}; // giada::u::time:: diff --git a/tests/conf.cpp b/tests/conf.cpp index a561d1a..df9113c 100644 --- a/tests/conf.cpp +++ b/tests/conf.cpp @@ -1,6 +1,6 @@ #include "../src/core/const.h" #include "../src/core/conf.h" -#include "catch/single_include/catch.hpp" +#include using std::string; diff --git a/tests/main.cpp b/tests/main.cpp index eb3c215..37c527d 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -1,3 +1,3 @@ #define CATCH_CONFIG_MAIN #define CATCH_CONFIG_FAST_COMPILE -#include "catch/single_include/catch.hpp" +#include diff --git a/tests/midiMapConf.cpp b/tests/midiMapConf.cpp index 28b3779..5903fca 100644 --- a/tests/midiMapConf.cpp +++ b/tests/midiMapConf.cpp @@ -1,6 +1,6 @@ #include "../src/core/const.h" #include "../src/core/midiMapConf.h" -#include "catch/single_include/catch.hpp" +#include using std::string; diff --git a/tests/patch.cpp b/tests/patch.cpp index da55162..b7a0808 100644 --- a/tests/patch.cpp +++ b/tests/patch.cpp @@ -1,6 +1,6 @@ #include "../src/core/patch.h" #include "../src/core/const.h" -#include "catch/single_include/catch.hpp" +#include using std::string; diff --git a/tests/pluginHost.cpp b/tests/pluginHost.cpp index 43215bb..bbdcbc0 100644 --- a/tests/pluginHost.cpp +++ b/tests/pluginHost.cpp @@ -5,7 +5,7 @@ #if 0 #include "../src/core/pluginHost.h" -#include "catch/single_include/catch.hpp" +#include TEST_CASE("Test PluginHost class") diff --git a/tests/recorder.cpp b/tests/recorder.cpp index 49a988e..6d29d85 100644 --- a/tests/recorder.cpp +++ b/tests/recorder.cpp @@ -1,6 +1,6 @@ #include "../src/core/recorder.h" #include "../src/core/const.h" -#include "catch/single_include/catch.hpp" +#include using std::string; diff --git a/tests/utils.cpp b/tests/utils.cpp index 07fb31c..c17b51d 100644 --- a/tests/utils.cpp +++ b/tests/utils.cpp @@ -1,40 +1,62 @@ #include "../src/utils/fs.h" #include "../src/utils/string.h" -#include "catch/single_include/catch.hpp" - - -using std::vector; +#include "../src/utils/math.h" +#include TEST_CASE("Test filesystem utils") { - REQUIRE(gu_fileExists("giada_tests") == true); - REQUIRE(gu_fileExists("ghost_file") == false); - REQUIRE(gu_dirExists("src/") == true); - REQUIRE(gu_dirExists("ghost_dir/") == false); - REQUIRE(gu_isDir("src/") == true); - REQUIRE(gu_isDir("giada_tests") == false); - REQUIRE(gu_basename("tests/utils.cpp") == "utils.cpp"); - REQUIRE(gu_dirname("tests/utils.cpp") == "tests"); - REQUIRE(gu_getExt("tests/utils.cpp") == "cpp"); - REQUIRE(gu_stripExt("tests/utils.cpp") == "tests/utils"); + REQUIRE(gu_fileExists("README.md") == true); + REQUIRE(gu_fileExists("ghost_file") == false); + REQUIRE(gu_dirExists("src/") == true); + REQUIRE(gu_dirExists("ghost_dir/") == false); + REQUIRE(gu_isDir("src/") == true); + REQUIRE(gu_isDir("giada_tests") == false); + REQUIRE(gu_basename("tests/utils.cpp") == "utils.cpp"); + REQUIRE(gu_dirname("tests/utils.cpp") == "tests"); + REQUIRE(gu_getExt("tests/utils.cpp") == "cpp"); + REQUIRE(gu_stripExt("tests/utils.cpp") == "tests/utils"); +#if defined(_WIN32) + REQUIRE(gu_isRootDir("C:\\") == true); + REQUIRE(gu_isRootDir("C:\\path\\to\\something") == false); + REQUIRE(gu_getUpDir("C:\\path\\to\\something") == "C:\\path\\to\\"); + REQUIRE(gu_getUpDir("C:\\path") == "C:\\"); + REQUIRE(gu_getUpDir("C:\\") == ""); +#else + REQUIRE(gu_isRootDir("/") == true); + REQUIRE(gu_isRootDir("/path/to/something") == false); + REQUIRE(gu_getUpDir("/path/to/something") == "/path/to/"); + REQUIRE(gu_getUpDir("/path") == "/"); + REQUIRE(gu_getUpDir("/") == "/"); +#endif } TEST_CASE("Test string utils") { - REQUIRE(gu_replace("Giada is cool", "cool", "hot") == "Giada is hot"); - REQUIRE(gu_trim(" Giada is cool ") == "Giada is cool"); - REQUIRE(gu_iToString(666) == "666"); - REQUIRE(gu_iToString(0x99AABB, true) == "99AABB"); - REQUIRE(gu_fToString(3.14159, 2) == "3.14"); - // Catch can't handle this so far? - //REQUIRE(gu_format("I see %d men with %s hats", 5, "strange") == "I see 5 men with strange hats"); - - vector v; - gu_split("Giada is cool", " ", &v); - REQUIRE(v.size() == 3); - REQUIRE(v.at(0) == "Giada"); - REQUIRE(v.at(1) == "is"); - REQUIRE(v.at(2) == "cool"); + using std::vector; + + REQUIRE(gu_replace("Giada is cool", "cool", "hot") == "Giada is hot"); + REQUIRE(gu_trim(" Giada is cool ") == "Giada is cool"); + REQUIRE(gu_iToString(666) == "666"); + REQUIRE(gu_iToString(0x99AABB, true) == "99AABB"); + REQUIRE(gu_fToString(3.14159, 2) == "3.14"); + REQUIRE(gu_format("I see %d men with %s hats", 5, "strange") == "I see 5 men with strange hats"); + + vector v; + gu_split("Giada is cool", " ", &v); + REQUIRE(v.size() == 3); + REQUIRE(v.at(0) == "Giada"); + REQUIRE(v.at(1) == "is"); + REQUIRE(v.at(2) == "cool"); } + + +TEST_CASE("Test math utils") +{ + using namespace giada::u::math; + + REQUIRE(map( 0.0f, 0.0f, 30.0f, 0.0f, 1.0f) == 0.0f); + REQUIRE(map(30.0f, 0.0f, 30.0f, 0.0f, 1.0f) == 1.0f); + REQUIRE(map(15.0f, 0.0f, 30.0f, 0.0f, 1.0f) == Approx(0.5f)); +} \ No newline at end of file diff --git a/tests/wave.cpp b/tests/wave.cpp index 7729024..72cffa3 100644 --- a/tests/wave.cpp +++ b/tests/wave.cpp @@ -1,6 +1,6 @@ #include #include "../src/core/wave.h" -#include "catch/single_include/catch.hpp" +#include using std::string; diff --git a/tests/waveFx.cpp b/tests/waveFx.cpp index 3032078..9c16d28 100644 --- a/tests/waveFx.cpp +++ b/tests/waveFx.cpp @@ -2,7 +2,7 @@ #include "../src/core/const.h" #include "../src/core/wave.h" #include "../src/core/waveFx.h" -#include "catch/single_include/catch.hpp" +#include using std::string; diff --git a/tests/waveManager.cpp b/tests/waveManager.cpp index 8008959..f9b2eb8 100644 --- a/tests/waveManager.cpp +++ b/tests/waveManager.cpp @@ -2,7 +2,7 @@ #include "../src/core/waveManager.h" #include "../src/core/wave.h" #include "../src/core/const.h" -#include "catch/single_include/catch.hpp" +#include using std::string; -- 2.30.2