diff --git a/Builds/MacOSX/Info-App.plist b/Builds/MacOSX/Info-App.plist index 05a0490cc..29dcc934b 100644 --- a/Builds/MacOSX/Info-App.plist +++ b/Builds/MacOSX/Info-App.plist @@ -20,9 +20,9 @@ CFBundleSignature ???? CFBundleShortVersionString - 3.0.0.10 + 3.0.0.11 CFBundleVersion - 3.0.0.10 + 3.0.0.11 NSHumanReadableCopyright NSHighResolutionCapable diff --git a/Builds/MacOSX/MIDI2LR.xcodeproj/project.pbxproj b/Builds/MacOSX/MIDI2LR.xcodeproj/project.pbxproj index 32fdd7b4c..898b91a14 100644 --- a/Builds/MacOSX/MIDI2LR.xcodeproj/project.pbxproj +++ b/Builds/MacOSX/MIDI2LR.xcodeproj/project.pbxproj @@ -951,8 +951,8 @@ "DONT_SET_USING_JUCE_NAMESPACE=1", "GSL_THROW_ON_CONTRACT_VIOLATION=1", "JUCER_XCODE_MAC_F6D2F4CF=1", - "JUCE_APP_VERSION=3.0.0.10", - "JUCE_APP_VERSION_HEX=0x300000a", + "JUCE_APP_VERSION=3.0.0.11", + "JUCE_APP_VERSION_HEX=0x300000b", "JucePlugin_Build_VST=0", "JucePlugin_Build_VST3=0", "JucePlugin_Build_AU=0", @@ -1001,8 +1001,8 @@ "DONT_SET_USING_JUCE_NAMESPACE=1", "GSL_UNENFORCED_ON_CONTRACT_VIOLATION=1", "JUCER_XCODE_MAC_F6D2F4CF=1", - "JUCE_APP_VERSION=3.0.0.10", - "JUCE_APP_VERSION_HEX=0x300000a", + "JUCE_APP_VERSION=3.0.0.11", + "JUCE_APP_VERSION_HEX=0x300000b", "JucePlugin_Build_VST=0", "JucePlugin_Build_VST3=0", "JucePlugin_Build_AU=0", diff --git a/Builds/VisualStudio2017/MIDI2LR_App.vcxproj b/Builds/VisualStudio2017/MIDI2LR_App.vcxproj index d5eb734b0..8a245344a 100644 --- a/Builds/VisualStudio2017/MIDI2LR_App.vcxproj +++ b/Builds/VisualStudio2017/MIDI2LR_App.vcxproj @@ -64,7 +64,7 @@ Disabled ProgramDatabase ..\..\JuceLibraryCode;..\..\JuceLibraryCode\modules;../../;../../icu/source/common/;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;U_STATIC_IMPLEMENTATION=1;DONT_SET_USING_JUCE_NAMESPACE=1;GSL_THROW_ON_CONTRACT_VIOLATION=1;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=3.0.0.10;JUCE_APP_VERSION_HEX=0x300000a;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;U_STATIC_IMPLEMENTATION=1;DONT_SET_USING_JUCE_NAMESPACE=1;GSL_THROW_ON_CONTRACT_VIOLATION=1;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=3.0.0.11;JUCE_APP_VERSION_HEX=0x300000b;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions) MultiThreadedDebug true @@ -105,7 +105,7 @@ Full ..\..\JuceLibraryCode;..\..\JuceLibraryCode\modules;../../;../../icu/source/common/;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;U_STATIC_IMPLEMENTATION=1;DONT_SET_USING_JUCE_NAMESPACE=1;GSL_UNENFORCED_ON_CONTRACT_VIOLATION=1;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=3.0.0.10;JUCE_APP_VERSION_HEX=0x300000a;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;U_STATIC_IMPLEMENTATION=1;DONT_SET_USING_JUCE_NAMESPACE=1;GSL_UNENFORCED_ON_CONTRACT_VIOLATION=1;JUCER_VS2017_78A5024=1;JUCE_APP_VERSION=3.0.0.11;JUCE_APP_VERSION_HEX=0x300000b;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions) MultiThreadedDLL true diff --git a/Builds/VisualStudio2017/resources.rc b/Builds/VisualStudio2017/resources.rc index 6854173c5..b75107177 100644 --- a/Builds/VisualStudio2017/resources.rc +++ b/Builds/VisualStudio2017/resources.rc @@ -7,16 +7,16 @@ #include VS_VERSION_INFO VERSIONINFO -FILEVERSION 3,0,0,10 +FILEVERSION 3,0,0,11 BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904E4" BEGIN VALUE "FileDescription", "MIDI2LR\0" - VALUE "FileVersion", "3.0.0.10\0" + VALUE "FileVersion", "3.0.0.11\0" VALUE "ProductName", "MIDI2LR\0" - VALUE "ProductVersion", "3.0.0.10\0" + VALUE "ProductVersion", "3.0.0.11\0" END END diff --git a/Builds/VisualStudio2019/MIDI2LR_App.vcxproj b/Builds/VisualStudio2019/MIDI2LR_App.vcxproj index 5d1731f8d..1eedbf78c 100644 --- a/Builds/VisualStudio2019/MIDI2LR_App.vcxproj +++ b/Builds/VisualStudio2019/MIDI2LR_App.vcxproj @@ -64,7 +64,7 @@ Disabled ProgramDatabase ..\..\JuceLibraryCode;..\..\JuceLibraryCode\modules;../../;../../icu/source/common/;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;U_STATIC_IMPLEMENTATION=1;DONT_SET_USING_JUCE_NAMESPACE=1;GSL_THROW_ON_CONTRACT_VIOLATION=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=3.0.0.10;JUCE_APP_VERSION_HEX=0x300000a;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;U_STATIC_IMPLEMENTATION=1;DONT_SET_USING_JUCE_NAMESPACE=1;GSL_THROW_ON_CONTRACT_VIOLATION=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=3.0.0.11;JUCE_APP_VERSION_HEX=0x300000b;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions) MultiThreadedDebug true @@ -105,7 +105,7 @@ Full ..\..\JuceLibraryCode;..\..\JuceLibraryCode\modules;../../;../../icu/source/common/;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;U_STATIC_IMPLEMENTATION=1;DONT_SET_USING_JUCE_NAMESPACE=1;GSL_UNENFORCED_ON_CONTRACT_VIOLATION=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=3.0.0.10;JUCE_APP_VERSION_HEX=0x300000a;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;U_STATIC_IMPLEMENTATION=1;DONT_SET_USING_JUCE_NAMESPACE=1;GSL_UNENFORCED_ON_CONTRACT_VIOLATION=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=3.0.0.11;JUCE_APP_VERSION_HEX=0x300000b;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_RTAS=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;%(PreprocessorDefinitions) MultiThreadedDLL true diff --git a/Builds/VisualStudio2019/resources.rc b/Builds/VisualStudio2019/resources.rc index 6854173c5..b75107177 100644 --- a/Builds/VisualStudio2019/resources.rc +++ b/Builds/VisualStudio2019/resources.rc @@ -7,16 +7,16 @@ #include VS_VERSION_INFO VERSIONINFO -FILEVERSION 3,0,0,10 +FILEVERSION 3,0,0,11 BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904E4" BEGIN VALUE "FileDescription", "MIDI2LR\0" - VALUE "FileVersion", "3.0.0.10\0" + VALUE "FileVersion", "3.0.0.11\0" VALUE "ProductName", "MIDI2LR\0" - VALUE "ProductVersion", "3.0.0.10\0" + VALUE "ProductVersion", "3.0.0.11\0" END END diff --git a/DoxyGen/Midi2lr.Doxyfile b/DoxyGen/Midi2lr.Doxyfile index 2627ffd0e..0629351cb 100644 --- a/DoxyGen/Midi2lr.Doxyfile +++ b/DoxyGen/Midi2lr.Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = MIDI2LR # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 3.0.0.10 +PROJECT_NUMBER = 3.0.0.11 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/Installer/MIDI2LR.xml b/Installer/MIDI2LR.xml index a4c73c56c..e81dde4b9 100644 --- a/Installer/MIDI2LR.xml +++ b/Installer/MIDI2LR.xml @@ -1,7 +1,7 @@ MIDI2LR MIDI2LR - 3.0.0.10 + 3.0.0.11 ${product_shortname}-${product_version}-${debuglabel}${platform_name}-installer.${platform_exec_suffix} ../Source/LRPlugin/ReadMe.txt ../LICENSE.txt diff --git a/JuceLibraryCode/JuceHeader.h b/JuceLibraryCode/JuceHeader.h index 6e8b42bb1..27d30be64 100644 --- a/JuceLibraryCode/JuceHeader.h +++ b/JuceLibraryCode/JuceHeader.h @@ -35,7 +35,7 @@ namespace ProjectInfo { const char* const projectName = "MIDI2LR"; const char* const companyName = ""; - const char* const versionString = "3.0.0.10"; - const int versionNumber = 0x300000a; + const char* const versionString = "3.0.0.11"; + const int versionNumber = 0x300000b; } #endif diff --git a/MIDI2LR.jucer b/MIDI2LR.jucer index 2bcfc4992..89e8f6f60 100644 --- a/MIDI2LR.jucer +++ b/MIDI2LR.jucer @@ -1,6 +1,6 @@ -. */ #include "MIDIReceiver.h" +#include //sleep_for timing #include #include +#include //sleep_for #include "Misc.h" @@ -123,16 +125,99 @@ void MidiReceiver::RescanDevices() InitDevices(); // initdevices has own try catch block } +void MidiReceiver::TryToOpen() +{ + for (auto idx = 0; idx < juce::MidiInput::getDevices().size(); ++idx) { + const auto dev = juce::MidiInput::openDevice(idx, this); + if (dev) { + devices_.emplace_back(dev); + dev->start(); + rsj::Log("Opened input device " + dev->getName()); + } + } +} + +namespace { + // zepto yocto zetta and yotta too large/small to be represented by intmax_t + // TODO: change to consteval, find way to convert digit to string for unexpected + // values, so return could be, e.g., "23425/125557 ", instead of error message + template constexpr auto RatioToPrefix() + { + if (R::num == 1) { + switch (R::den) { + case 1: + return ""; + case 10: + return "deci"; + case 100: + return "centi"; + case 1000: + return "milli"; + case 1000000: + return "micro"; + case 1000000000: + return "nano"; + case 1000000000000: + return "pico"; + case 1000000000000000: + return "femto"; + case 1000000000000000000: + return "atto"; + } + } + switch (R::num) { + case 10: + return "deca"; + case 100: + return "hecto"; + case 1000: + return "kilo"; + case 1000000: + return "mega"; + case 1000000000: + return "giga"; + case 1000000000000: + return "tera"; + case 1000000000000000: + return "peta"; + case 1000000000000000000: + return "exa"; + } + return "unexpected ratio encountered "; + } + + template + auto SleepTimed(const std::chrono::duration sleep_duration) + { + const auto start = std::chrono::high_resolution_clock::now(); + std::this_thread::sleep_for(sleep_duration); + const auto end = std::chrono::high_resolution_clock::now(); + const std::chrono::duration elapsed = end - start; + return elapsed; + } + + template + void SleepTimedLogged( + std::string_view msg_prefix, std::chrono::duration sleep_duration) + { + const auto elapsed = SleepTimed(sleep_duration); + rsj::Log(juce::String(msg_prefix.data(), msg_prefix.size()) + " thread slept for " + + juce::String(elapsed.count()) + ' ' + RatioToPrefix() + "seconds."); + } + +} // namespace + void MidiReceiver::InitDevices() { + using namespace std::chrono_literals; try { - for (auto idx = 0; idx < juce::MidiInput::getDevices().size(); ++idx) { - const auto dev = juce::MidiInput::openDevice(idx, this); - if (dev) { - devices_.emplace_back(dev); - dev->start(); - rsj::Log("Opened input device " + dev->getName()); - } + rsj::Log("Trying to open input devices"); + TryToOpen(); + if (devices_.empty()) // encountering errors first try on MacOS + { + rsj::Log("Retrying to open input devices"); + SleepTimedLogged("Open input devices", 20ms); + TryToOpen(); } } catch (const std::exception& e) { diff --git a/Source/MIDIReceiver.h b/Source/MIDIReceiver.h index 148012b2d..8ecad39b9 100644 --- a/Source/MIDIReceiver.h +++ b/Source/MIDIReceiver.h @@ -52,6 +52,7 @@ class MidiReceiver final : juce::MidiInputCallback { void handleIncomingMidiMessage(juce::MidiInput*, const juce::MidiMessage&) override; void DispatchMessages(); void InitDevices(); + void TryToOpen(); //inner code for InitDevices moodycamel::BlockingConcurrentQueue messages_; NrpnFilter nrpn_filter_; diff --git a/Source/MainWindow.cpp b/Source/MainWindow.cpp index 691b9e74a..6fb9fcf45 100644 --- a/Source/MainWindow.cpp +++ b/Source/MainWindow.cpp @@ -39,4 +39,16 @@ MainWindow::MainWindow(const juce::String& name, CommandMap& command_map, juce::Component::centreWithSize(getWidth(), getHeight()); juce::Component::setVisible(true); window_content_->Init(std::move(lr_ipc_out), std::move(midi_receiver), std::move(midi_sender)); + // get the auto time setting + auto hide_sec = settings_manager.GetAutoHideTime(); + // start timing + if (hide_sec) //don't start timer if time is zero! + juce::Timer::startTimer(1000 * hide_sec); +} + +void MainWindow::timerCallback() +{ + juce::Timer::stopTimer(); + if (!juce::ResizableWindow::isMinimised()) + juce::DocumentWindow::minimiseButtonPressed(); } \ No newline at end of file diff --git a/Source/MainWindow.h b/Source/MainWindow.h index df657d40c..eff99bca8 100644 --- a/Source/MainWindow.h +++ b/Source/MainWindow.h @@ -31,7 +31,7 @@ class MainContentComponent; class ProfileManager; class SettingsManager; -class MainWindow final : juce::DocumentWindow { +class MainWindow final : juce::DocumentWindow, juce::Timer { public: MainWindow(const juce::String& name, CommandMap& command_map, ProfileManager& profile_manager, SettingsManager& settings_manager, std::weak_ptr&& lr_ipc_out, @@ -58,6 +58,8 @@ class MainWindow final : juce::DocumentWindow { juce::JUCEApplication::getInstance()->systemRequestedQuit(); } MainContentComponent* window_content_; + // the timer callback function + void timerCallback() override; }; #endif // MAINWINDOW_H_INCLUDED diff --git a/Source/Misc.cpp b/Source/Misc.cpp index 7ba3e929c..550d4ea83 100644 --- a/Source/Misc.cpp +++ b/Source/Misc.cpp @@ -142,7 +142,7 @@ std::wstring rsj::Utf8ToWide(std::string_view input) MultiByteToWideCharErrorChecked(CP_UTF8, 0, input.data(), input.size(), nullptr, 0) + 1; std::vector buffer(buffersize, 0); // all zero MultiByteToWideCharErrorChecked( - CP_UTF8, 0, input.data(), input.size(), buffer.data(), buffer.size()); + CP_UTF8, 0, input.data(), input.size(), buffer.data(), gsl::narrow_cast(buffer.size())); return buffer.data(); } @@ -152,8 +152,8 @@ std::string rsj::WideToUtf8(std::wstring_view wstr) CP_UTF8, 0, wstr.data(), wstr.size(), nullptr, 0, nullptr, nullptr) + 1; std::vector buffer(buffersize, 0); - WideCharToMultiByteErrorChecked( - CP_UTF8, 0, wstr.data(), wstr.size(), buffer.data(), buffer.size(), nullptr, nullptr); + WideCharToMultiByteErrorChecked(CP_UTF8, 0, wstr.data(), wstr.size(), buffer.data(), + gsl::narrow_cast(buffer.size()), nullptr, nullptr); return buffer.data(); } #else diff --git a/Source/SendKeys.cpp b/Source/SendKeys.cpp index 21dddf019..a4d454534 100644 --- a/Source/SendKeys.cpp +++ b/Source/SendKeys.cpp @@ -196,10 +196,11 @@ namespace { kUCKeyTranslateNoDeadKeysMask, &keys_down, sizeof(chars) / sizeof(chars[0]), &real_length, chars); if (real_length != 1) { - rsj::Log(juce::String("For key code ") + juce::String(key_code) - + juce::String(", Unicode character is ") + juce::String(real_length) - + juce::String(" long. It starts with ") + juce::String(chars[0]) - + juce::String(".")); + if (real_length > 1) + rsj::Log(juce::String("For key code ") + juce::String(key_code) + + juce::String(", Unicode character is ") + juce::String(real_length) + + juce::String(" long. It starts with ") + juce::String(chars[0]) + + juce::String(".")); chars[0] = 0; } // shifted @@ -211,10 +212,11 @@ namespace { kUCKeyTranslateNoDeadKeysMask, &s_keys_down, sizeof(s_chars) / sizeof(s_chars[0]), &s_real_length, s_chars); if (s_real_length != 1) { - rsj::Log(juce::String("For shifted key code ") + juce::String(key_code) - + juce::String(", Unicode character is ") + juce::String(s_real_length) - + juce::String(" long. It starts with ") + juce::String(s_chars[0]) - + juce::String(".")); + if (s_real_length > 1) + rsj::Log(juce::String("For shifted key code ") + juce::String(key_code) + + juce::String(", Unicode character is ") + juce::String(s_real_length) + + juce::String(" long. It starts with ") + juce::String(s_chars[0]) + + juce::String(".")); s_chars[0] = 0; } if (chars[0] == s_chars[0])