From 1bae047b98558981c20c85edc44550f4aa9714d9 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Mon, 18 Jun 2018 10:58:45 +0900 Subject: [PATCH 01/14] Fix wrong accelerator character in sv.ts Fixes #4415 --- data/locale/sv.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/locale/sv.ts b/data/locale/sv.ts index 173b1f76e..74153c7e9 100644 --- a/data/locale/sv.ts +++ b/data/locale/sv.ts @@ -3939,7 +3939,7 @@ Besök https://lmms.io/documentation/ för dokumentation (Engelska). &View - %Visa + &Visa Toggle metronome @@ -9950,4 +9950,4 @@ The LED in the lower right corner of the waveform editor determines whether the Utgångsförstärkning - \ No newline at end of file + From b52861f19f174d20b868466ef61bd25fdb2785fd Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Mon, 18 Jun 2018 12:35:17 +0900 Subject: [PATCH 02/14] Fixup 1bae047b98558981c20c85edc44550f4aa9714d9 --- data/locale/sv.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/locale/sv.ts b/data/locale/sv.ts index 74153c7e9..ec36538f0 100644 --- a/data/locale/sv.ts +++ b/data/locale/sv.ts @@ -3939,7 +3939,7 @@ Besök https://lmms.io/documentation/ för dokumentation (Engelska). &View - &Visa + &Visa Toggle metronome From 6af5154bec3a7807be64d67ad80983f8c69d58b3 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Tue, 19 Jun 2018 09:32:11 +0900 Subject: [PATCH 03/14] LADSPA: Fix undefined reference due to vectorization (#4434) --- plugins/LadspaEffect/swh/CMakeLists.txt | 22 ++++++++++------------ plugins/LadspaEffect/tap/CMakeLists.txt | 11 +++-------- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/plugins/LadspaEffect/swh/CMakeLists.txt b/plugins/LadspaEffect/swh/CMakeLists.txt index a14fc1428..07893c8a4 100644 --- a/plugins/LadspaEffect/swh/CMakeLists.txt +++ b/plugins/LadspaEffect/swh/CMakeLists.txt @@ -7,6 +7,11 @@ LINK_DIRECTORIES(${FFTW3F_LIBRARY_DIRS}) FILE(GLOB PLUGIN_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.c") LIST(SORT PLUGIN_SOURCES) +SET(COMPILE_FLAGS "${COMPILE_FLAGS} -O3 -Wall -fomit-frame-pointer -funroll-loops -ffast-math -fno-strict-aliasing") +IF(NOT LMMS_BUILD_WIN32) + SET(COMPILE_FLAGS "${COMPILE_FLAGS} -fPIC -DPIC") +ENDIF() + FOREACH(_item ${PLUGIN_SOURCES}) GET_FILENAME_COMPONENT(_plugin "${_item}" NAME_WE) @@ -15,22 +20,15 @@ FOREACH(_item ${PLUGIN_SOURCES}) IF(NOT ("${_plugin}" STREQUAL "vocoder_1337")) TARGET_LINK_LIBRARIES("${_plugin}" -lfftw3f) ENDIF() + IF(NOT MSVC) + TARGET_LINK_LIBRARIES("${_plugin}" m) + ENDIF() INSTALL(TARGETS "${_plugin}" LIBRARY DESTINATION "${PLUGIN_DIR}/ladspa") SET_TARGET_PROPERTIES("${_plugin}" PROPERTIES PREFIX "") - SET_TARGET_PROPERTIES("${_plugin}" PROPERTIES COMPILE_FLAGS "-O3 -Wall -fomit-frame-pointer -fstrength-reduce -funroll-loops -ffast-math -c -fno-strict-aliasing") IF(LMMS_BUILD_WIN32) ADD_CUSTOM_COMMAND(TARGET "${_plugin}" POST_BUILD COMMAND "${STRIP}" \"$\") - ELSE(LMMS_BUILD_WIN32) - SET_TARGET_PROPERTIES("${_plugin}" PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -fPIC -DPIC") - ENDIF(LMMS_BUILD_WIN32) - IF(LMMS_BUILD_APPLE) - SET_TARGET_PROPERTIES("${_plugin}" PROPERTIES LINK_FLAGS "${LINK_FLAGS} -Bsymbolic -lm") - ELSEIF(NOT LMMS_BUILD_APPLE AND NOT LMMS_BUILD_OPENBSD) - SET_TARGET_PROPERTIES("${_plugin}" PROPERTIES LINK_FLAGS "${LINK_FLAGS} -shared -Wl,-no-undefined -Wl,-Bsymbolic -lm") - ENDIF(LMMS_BUILD_APPLE) - IF(LMMS_BUILD_LINUX OR LMMS_BUILD_HAIKU) - SET_TARGET_PROPERTIES("${_plugin}" PROPERTIES LINK_FLAGS "${LINK_FLAGS}") - ENDIF(LMMS_BUILD_LINUX OR LMMS_BUILD_HAIKU) + ENDIF() + SET_TARGET_PROPERTIES("${_plugin}" PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS}") ENDFOREACH(_item ${PLUGIN_SOURCES}) diff --git a/plugins/LadspaEffect/tap/CMakeLists.txt b/plugins/LadspaEffect/tap/CMakeLists.txt index 309283da6..02e131ce7 100644 --- a/plugins/LadspaEffect/tap/CMakeLists.txt +++ b/plugins/LadspaEffect/tap/CMakeLists.txt @@ -10,13 +10,8 @@ FOREACH(_item ${PLUGIN_SOURCES}) IF(LMMS_BUILD_WIN32) ADD_CUSTOM_COMMAND(TARGET "${_plugin}" POST_BUILD COMMAND "${STRIP}" \"$\") ENDIF(LMMS_BUILD_WIN32) - IF(LMMS_BUILD_APPLE) - SET_TARGET_PROPERTIES("${_plugin}" PROPERTIES LINK_FLAGS "${LINK_FLAGS} -Bsymbolic -lm") - ELSEIF(NOT LMMS_BUILD_OPENBSD) - SET_TARGET_PROPERTIES("${_plugin}" PROPERTIES LINK_FLAGS "${LINK_FLAGS} -shared -Wl,-no-undefined -Wl,-Bsymbolic -lm") - ENDIF(LMMS_BUILD_APPLE) - IF(LMMS_BUILD_LINUX OR LMMS_BUILD_HAIKU) - SET_TARGET_PROPERTIES("${_plugin}" PROPERTIES LINK_FLAGS "${LINK_FLAGS}") - ENDIF(LMMS_BUILD_LINUX OR LMMS_BUILD_HAIKU) + IF(NOT MSVC) + TARGET_LINK_LIBRARIES("${_plugin}" m) + ENDIF() ENDFOREACH(_item ${PLUGIN_SOURCES}) From 583e42e5bb5e7546e6e93923b29e5867772d54ae Mon Sep 17 00:00:00 2001 From: Oskar Wallgren Date: Tue, 19 Jun 2018 21:59:12 +0200 Subject: [PATCH 04/14] Quit exit if failing to save project (#4428) * Quit exiting when failing to save project *Test outcome of save in MainWindow::saveProjectAsNewVersion() --- src/gui/MainWindow.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 18bd49144..6ff55f06f 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -943,15 +943,15 @@ bool MainWindow::saveProject() { return( saveProjectAs() ); } - else + else if( Engine::getSong()->guiSaveProject() ) { - Engine::getSong()->guiSaveProject(); if( getSession() == Recover ) { sessionCleanup(); } + return true; } - return( true ); + return false; } @@ -997,14 +997,16 @@ bool MainWindow::saveProjectAs() } } } - Engine::getSong()->guiSaveProjectAs( fname ); - if( getSession() == Recover ) + if( Engine::getSong()->guiSaveProjectAs( fname ) ) { - sessionCleanup(); + if( getSession() == Recover ) + { + sessionCleanup(); + } + return true; } - return( true ); } - return( false ); + return false; } @@ -1022,8 +1024,7 @@ bool MainWindow::saveProjectAsNewVersion() do VersionedSaveDialog::changeFileNameVersion( fileName, true ); while ( QFile( fileName ).exists() ); - Engine::getSong()->guiSaveProjectAs( fileName ); - return true; + return Engine::getSong()->guiSaveProjectAs( fileName ); } } From d1c36d7b9664a2bde688cf06e600c4dad8055429 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Tue, 19 Jun 2018 21:16:45 +0200 Subject: [PATCH 05/14] CMake: Fix errors when path contains spaces --- cmake/modules/BuildPlugin.cmake | 16 ++++++++-------- plugins/CMakeLists.txt | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/cmake/modules/BuildPlugin.cmake b/cmake/modules/BuildPlugin.cmake index a107ef5ac..f1dd95db6 100644 --- a/cmake/modules/BuildPlugin.cmake +++ b/cmake/modules/BuildPlugin.cmake @@ -7,7 +7,7 @@ MACRO(BUILD_PLUGIN PLUGIN_NAME) CMAKE_PARSE_ARGUMENTS(PLUGIN "" "" "MOCFILES;EMBEDDED_RESOURCES;UICFILES;LINK" ${ARGN}) SET(PLUGIN_SOURCES ${PLUGIN_UNPARSED_ARGUMENTS}) - INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/src/gui) + INCLUDE_DIRECTORIES("${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_BINARY_DIR}" "${CMAKE_SOURCE_DIR}/include" "${CMAKE_SOURCE_DIR}/src/gui") ADD_DEFINITIONS(-DPLUGIN_NAME=${PLUGIN_NAME}) @@ -20,15 +20,15 @@ MACRO(BUILD_PLUGIN PLUGIN_NAME) FILE(GLOB EXPANDED "${ARG}") LIST(SORT EXPANDED) FOREACH(ITEM ${EXPANDED}) - LIST(APPEND NEW_ARGS ${ITEM}) + LIST(APPEND NEW_ARGS "${ITEM}") ENDFOREACH() ENDFOREACH() SET(PLUGIN_EMBEDDED_RESOURCES ${NEW_ARGS}) - SET(ER_H ${CMAKE_CURRENT_BINARY_DIR}/embedded_resources.h) + SET(ER_H "${CMAKE_CURRENT_BINARY_DIR}/embedded_resources.h") ADD_CUSTOM_COMMAND(OUTPUT ${ER_H} COMMAND ${BIN2RES} - ARGS ${PLUGIN_EMBEDDED_RESOURCES} > ${ER_H} + ARGS ${PLUGIN_EMBEDDED_RESOURCES} > "${ER_H}" DEPENDS bin2res) ENDIF(ER_LEN) @@ -45,11 +45,11 @@ MACRO(BUILD_PLUGIN PLUGIN_NAME) ENDFOREACH(f) IF(LMMS_BUILD_APPLE) - LINK_DIRECTORIES(${CMAKE_BINARY_DIR}) + LINK_DIRECTORIES("${CMAKE_BINARY_DIR}") LINK_LIBRARIES(${QT_LIBRARIES}) ENDIF(LMMS_BUILD_APPLE) IF(LMMS_BUILD_WIN32) - LINK_DIRECTORIES(${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}) + LINK_DIRECTORIES("${CMAKE_BINARY_DIR}" "${CMAKE_SOURCE_DIR}") LINK_LIBRARIES(${QT_LIBRARIES}) ENDIF(LMMS_BUILD_WIN32) IF(LMMS_BUILD_MSYS AND CMAKE_BUILD_TYPE STREQUAL "Debug") @@ -73,12 +73,12 @@ MACRO(BUILD_PLUGIN PLUGIN_NAME) INSTALL(TARGETS ${PLUGIN_NAME} LIBRARY DESTINATION "${PLUGIN_DIR}") IF(LMMS_BUILD_APPLE) - SET_TARGET_PROPERTIES(${PLUGIN_NAME} PROPERTIES LINK_FLAGS "-bundle_loader ${CMAKE_BINARY_DIR}/lmms") + SET_TARGET_PROPERTIES(${PLUGIN_NAME} PROPERTIES LINK_FLAGS "-bundle_loader \"${CMAKE_BINARY_DIR}/lmms\"") ADD_DEPENDENCIES(${PLUGIN_NAME} lmms) ENDIF(LMMS_BUILD_APPLE) IF(LMMS_BUILD_WIN32) SET_TARGET_PROPERTIES(${PLUGIN_NAME} PROPERTIES PREFIX "") - ADD_CUSTOM_COMMAND(TARGET ${PLUGIN_NAME} POST_BUILD COMMAND ${STRIP} $) + ADD_CUSTOM_COMMAND(TARGET ${PLUGIN_NAME} POST_BUILD COMMAND ${STRIP} "$") ENDIF(LMMS_BUILD_WIN32) SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${ER_H} ${plugin_MOC_out}") diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 24c15e391..4a1196886 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -1,5 +1,5 @@ -SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) -SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) +SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") +SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") # Enable C++11 ADD_DEFINITIONS(-std=c++0x) From c45a21aac3beb0bba4c1796cf591ea44d2f2bc46 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Wed, 20 Jun 2018 08:42:26 +0200 Subject: [PATCH 06/14] CMake: Fix FindSndio module Fixes a bug where the module would set SNDIO_LIBRARY to NOT-FOUND resulting in a CMake error when trying to link to ${SNDIO_LIBRARY}. --- cmake/modules/FindSndio.cmake | 20 +++++++++++--------- src/CMakeLists.txt | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/cmake/modules/FindSndio.cmake b/cmake/modules/FindSndio.cmake index bf5b24c39..3fcd71360 100644 --- a/cmake/modules/FindSndio.cmake +++ b/cmake/modules/FindSndio.cmake @@ -19,14 +19,16 @@ if(SNDIO_LIBRARY) get_filename_component(SNDIO_LIBRARY_DIR ${SNDIO_LIBRARY} PATH) endif(SNDIO_LIBRARY) -check_library_exists(sndio sio_open "${SNDIO_LIBRARY_DIR}" HAVE_SNDIO) -if(HAVE_SNDIO) - message(STATUS "Found sndio: ${SNDIO_LIBRARY}") -else(HAVE_SNDIO) - message(STATUS "sndio not found") +check_library_exists(sndio sio_open "${SNDIO_LIBRARY_DIR}" HAVE_SIO_OPEN) + +find_path(SNDIO_INCLUDE_DIR sndio.h) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(SNDIO DEFAULT_MSG SNDIO_LIBRARY SNDIO_INCLUDE_DIR HAVE_SIO_OPEN) + +if(SNDIO_FOUND) + set(SNDIO_INCLUDE_DIRS "${SNDIO_INCLUDE_DIR}") + set(SNDIO_LIBRARIES "${SNDIO_LIBRARY}") endif(HAVE_SNDIO) -set(SNDIO_FOUND ${HAVE_SNDIO}) -find_path(SNDIO_INCLUDES sndio.h) - -mark_as_advanced(SNDIO_INCLUDES SNDIO_LIBRARY) +mark_as_advanced(SNDIO_INCLUDE_DIR SNDIO_LIBRARY SNDIO_INCLUDE_DIRS SNDIO_LIBRARIES) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 17695b5a0..b18fa897e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -138,7 +138,7 @@ SET(LMMS_REQUIRED_LIBS ${LMMS_REQUIRED_LIBS} ${SDL_LIBRARY} ${PORTAUDIO_LIBRARIES} ${SOUNDIO_LIBRARY} - ${SNDIO_LIBRARY} + ${SNDIO_LIBRARIES} ${PULSEAUDIO_LIBRARIES} ${JACK_LIBRARIES} ${OGGVORBIS_LIBRARIES} From 28a522806bb1a670b460f0bfbf8d6147910dea72 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Wed, 27 Jun 2018 08:59:36 +0900 Subject: [PATCH 07/14] Fix hang on exit from specific MIDI devices + WinMM (#4451) --- src/core/midi/MidiWinMM.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/core/midi/MidiWinMM.cpp b/src/core/midi/MidiWinMM.cpp index a59ebc69e..ef60f3015 100644 --- a/src/core/midi/MidiWinMM.cpp +++ b/src/core/midi/MidiWinMM.cpp @@ -248,9 +248,13 @@ void MidiWinMM::closeDevices() m_outputSubs.clear(); QMapIterator i( m_inputDevices ); + + HMIDIIN hInDev; while( i.hasNext() ) { - midiInClose( i.next().key() ); + hInDev = i.next().key(); + midiInReset( hInDev ); + midiInClose( hInDev ); } QMapIterator o( m_outputDevices ); From e9f2b57107a5e4fed9e61d80dac87747b2adfbdd Mon Sep 17 00:00:00 2001 From: Hyunin Song Date: Thu, 28 Jun 2018 20:23:53 +0900 Subject: [PATCH 08/14] Fix project URL for some files They were created before https://github.com/LMMS/lmms/pull/3326 and added after it. --- include/MainApplication.h | 2 +- plugins/ReverbSC/ReverbSC.cpp | 2 +- plugins/ReverbSC/ReverbSC.h | 2 +- plugins/ReverbSC/ReverbSCControlDialog.cpp | 2 +- plugins/ReverbSC/ReverbSCControlDialog.h | 2 +- plugins/ReverbSC/ReverbSCControls.cpp | 2 +- plugins/ReverbSC/ReverbSCControls.h | 2 +- src/gui/MainApplication.cpp | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/MainApplication.h b/include/MainApplication.h index d3acb95ca..4edf55d5e 100644 --- a/include/MainApplication.h +++ b/include/MainApplication.h @@ -3,7 +3,7 @@ * * Copyright (c) 2017-2017 Tres Finocchiaro * - * This file is part of LMMS - http://lmms.io + * This file is part of LMMS - https://lmms.io * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public diff --git a/plugins/ReverbSC/ReverbSC.cpp b/plugins/ReverbSC/ReverbSC.cpp index 4d938eb95..00c423784 100644 --- a/plugins/ReverbSC/ReverbSC.cpp +++ b/plugins/ReverbSC/ReverbSC.cpp @@ -1,7 +1,7 @@ /* * ReverbSC.cpp - A native reverb based on an algorithm by Sean Costello * - * This file is part of LMMS - http://lmms.io + * This file is part of LMMS - https://lmms.io * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public diff --git a/plugins/ReverbSC/ReverbSC.h b/plugins/ReverbSC/ReverbSC.h index ba987414b..0e697c197 100644 --- a/plugins/ReverbSC/ReverbSC.h +++ b/plugins/ReverbSC/ReverbSC.h @@ -3,7 +3,7 @@ * * Copyright (c) 2017 Paul Batchelor * - * This file is part of LMMS - http://lmms.io + * This file is part of LMMS - https://lmms.io * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public diff --git a/plugins/ReverbSC/ReverbSCControlDialog.cpp b/plugins/ReverbSC/ReverbSCControlDialog.cpp index e8c3c571a..71499c34a 100644 --- a/plugins/ReverbSC/ReverbSCControlDialog.cpp +++ b/plugins/ReverbSC/ReverbSCControlDialog.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 2017 Paul Batchelor * - * This file is part of LMMS - http://lmms.io + * This file is part of LMMS - https://lmms.io * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public diff --git a/plugins/ReverbSC/ReverbSCControlDialog.h b/plugins/ReverbSC/ReverbSCControlDialog.h index 9f262a88f..0d9c1f51a 100644 --- a/plugins/ReverbSC/ReverbSCControlDialog.h +++ b/plugins/ReverbSC/ReverbSCControlDialog.h @@ -3,7 +3,7 @@ * * Copyright (c) 2017 Paul Batchelor * - * This file is part of LMMS - http://lmms.io + * This file is part of LMMS - https://lmms.io * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public diff --git a/plugins/ReverbSC/ReverbSCControls.cpp b/plugins/ReverbSC/ReverbSCControls.cpp index 5e52d3faf..5d77ce0fc 100644 --- a/plugins/ReverbSC/ReverbSCControls.cpp +++ b/plugins/ReverbSC/ReverbSCControls.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 2017 Paul Batchelor * - * This file is part of LMMS - http://lmms.io + * This file is part of LMMS - https://lmms.io * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public diff --git a/plugins/ReverbSC/ReverbSCControls.h b/plugins/ReverbSC/ReverbSCControls.h index 638bdade9..36cc16a7e 100644 --- a/plugins/ReverbSC/ReverbSCControls.h +++ b/plugins/ReverbSC/ReverbSCControls.h @@ -3,7 +3,7 @@ * * Copyright (c) 2017 Paul Batchelor * - * This file is part of LMMS - http://lmms.io + * This file is part of LMMS - https://lmms.io * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public diff --git a/src/gui/MainApplication.cpp b/src/gui/MainApplication.cpp index 5210dd76c..994ae2771 100644 --- a/src/gui/MainApplication.cpp +++ b/src/gui/MainApplication.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 2017-2017 Tres Finocchiaro * - * This file is part of LMMS - http://lmms.io + * This file is part of LMMS - https://lmms.io * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public From 792e4786ad4d21d3d118afffc08daad1141b8353 Mon Sep 17 00:00:00 2001 From: Hyunin Song Date: Mon, 28 May 2018 22:15:39 +0900 Subject: [PATCH 09/14] Fix file name encoding issues with VST on Windows Fix plugin loading and setting loading/saving --- include/IoHelper.h | 72 ++++++++++++++++++++++++++++ plugins/vst_base/RemoteVstPlugin.cpp | 23 ++++----- 2 files changed, 84 insertions(+), 11 deletions(-) create mode 100644 include/IoHelper.h diff --git a/include/IoHelper.h b/include/IoHelper.h new file mode 100644 index 000000000..687e000d1 --- /dev/null +++ b/include/IoHelper.h @@ -0,0 +1,72 @@ +/* + * IoHelper.h - helper functions for file I/O + * + * Copyright (c) 2018 Hyunjin Song + * + * This file is part of LMMS - https://lmms.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + + +#include "lmmsconfig.h" + +#include + + +#ifdef _WIN32 +#include + +std::wstring toWString(const std::string& s) +{ + std::wstring ret; + int len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), + s.length(), nullptr, 0); + if (len == 0) + { + return ret; + } + ret.resize(len); + MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s.length(), &ret[0], len); + return ret; +} +#endif + +#ifdef LMMS_BUILD_WIN32 +#include +#define F_OPEN_UTF8(a, b) _wfopen(toWString(a).data(), L##b) +#else +#ifdef LMMS_HAVE_UNISTD_H +#include +#endif +#define F_OPEN_UTF8(a, b) fopen((a).data(), b) +#endif + +int fileToDescriptor(FILE* f, bool closeFile = true) +{ + int fh; + if (f == NULL) {return -1;} + +#ifdef LMMS_BUILD_WIN32 + fh = _dup(_fileno(f)); +#else + fh = dup(fileno(f)); +#endif + + if (closeFile) {fclose(f);} + return fh; +} diff --git a/plugins/vst_base/RemoteVstPlugin.cpp b/plugins/vst_base/RemoteVstPlugin.cpp index a51ac9d9a..174a80caa 100644 --- a/plugins/vst_base/RemoteVstPlugin.cpp +++ b/plugins/vst_base/RemoteVstPlugin.cpp @@ -88,6 +88,7 @@ struct ERect #include "lmms_basics.h" #include "Midi.h" #include "communication.h" +#include "IoHelper.h" #include "VstSyncData.h" @@ -678,9 +679,9 @@ void RemoteVstPlugin::init( const std::string & _plugin_file ) -static void close_check( int fd ) +static void close_check( FILE* fp ) { - if( close( fd ) ) + if( fclose( fp ) ) { perror( "close" ); } @@ -790,7 +791,7 @@ void RemoteVstPlugin::destroyEditor() bool RemoteVstPlugin::load( const std::string & _plugin_file ) { - if( ( m_libInst = LoadLibrary( _plugin_file.c_str() ) ) == NULL ) + if( ( m_libInst = LoadLibraryW( toWString(_plugin_file).c_str() ) ) == NULL ) { // give VstPlugin class a chance to start 32 bit version of RemoteVstPlugin if( GetLastError() == ERROR_BAD_EXE_FORMAT ) @@ -1072,13 +1073,13 @@ void RemoteVstPlugin::saveChunkToFile( const std::string & _file ) const int len = pluginDispatch( 23, 0, 0, &chunk ); if( len > 0 ) { - int fd = open( _file.c_str(), O_WRONLY | O_BINARY ); - if ( ::write( fd, chunk, len ) != len ) + FILE* fp = F_OPEN_UTF8( _file, "wb" ); + if ( fwrite( chunk, len, 1, fp ) != len ) { fprintf( stderr, "Error saving chunk to file.\n" ); } - close_check( fd ); + close_check( fp ); } } } @@ -1237,7 +1238,7 @@ void RemoteVstPlugin::savePreset( const std::string & _file ) if (!isPreset &&!chunky) uIntToFile = (unsigned int) m_plugin->numPrograms; pBank->numPrograms = endian_swap( uIntToFile ); - FILE * stream = fopen( _file.c_str(), "w" ); + FILE * stream = F_OPEN_UTF8( _file, "w" ); fwrite ( pBank, 1, 28, stream ); fwrite ( progName, 1, isPreset ? 28 : 128, stream ); if ( chunky ) { @@ -1289,7 +1290,7 @@ void RemoteVstPlugin::loadPresetFile( const std::string & _file ) unsigned int * pLen = new unsigned int[ 1 ]; unsigned int len = 0; sBank * pBank = (sBank*) new char[ sizeof( sBank ) ]; - FILE * stream = fopen( _file.c_str(), "r" ); + FILE * stream = F_OPEN_UTF8( _file, "r" ); if ( fread ( pBank, 1, 56, stream ) != 56 ) { fprintf( stderr, "Error loading preset file.\n" ); @@ -1390,12 +1391,12 @@ void RemoteVstPlugin::loadChunkFromFile( const std::string & _file, int _len ) { char * chunk = new char[_len]; - const int fd = open( _file.c_str(), O_RDONLY | O_BINARY ); - if ( ::read( fd, chunk, _len ) != _len ) + FILE* fp = F_OPEN_UTF8( _file, "rb" ); + if ( fread( chunk, 1, _len, fp ) != _len ) { fprintf( stderr, "Error loading chunk from file.\n" ); } - close_check( fd ); + close_check( fp ); pluginDispatch( effSetChunk, 0, _len, chunk ); From 9d0aae2708aed2fc0a18b16f31fef05f2496fd26 Mon Sep 17 00:00:00 2001 From: Hyunin Song Date: Mon, 28 May 2018 22:34:19 +0900 Subject: [PATCH 10/14] Fix file name encoding issues with ZynAddSubFX on Windows --- .../zynaddsubfx/src/Misc/QtXmlWrapper.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/plugins/zynaddsubfx/zynaddsubfx/src/Misc/QtXmlWrapper.cpp b/plugins/zynaddsubfx/zynaddsubfx/src/Misc/QtXmlWrapper.cpp index 3ebc2eeec..bab513829 100644 --- a/plugins/zynaddsubfx/zynaddsubfx/src/Misc/QtXmlWrapper.cpp +++ b/plugins/zynaddsubfx/zynaddsubfx/src/Misc/QtXmlWrapper.cpp @@ -55,10 +55,13 @@ #include #include #include -#include "lmmsconfig.h" #include "../globals.h" #include "Util.h" +// Include LMMS headers +#include "lmmsconfig.h" +#include "IoHelper.h" + struct XmlData { @@ -193,11 +196,12 @@ int QtXmlWrapper::dosavefile(const char *filename, int compression, const char *xmldata) const { + FILE *file = F_OPEN_UTF8(std::string(filename), "w"); + if(file == NULL) { + return -1; + } + if(compression == 0) { - FILE *file; - file = fopen(filename, "w"); - if(file == NULL) - return -1; fputs(xmldata, file); fclose(file); } @@ -210,7 +214,7 @@ int QtXmlWrapper::dosavefile(const char *filename, snprintf(options, 10, "wb%d", compression); gzFile gzfile; - gzfile = gzopen(filename, options); + gzfile = gzdopen(fileToDescriptor(file), options); if(gzfile == NULL) return -1; gzputs(gzfile, xmldata); @@ -313,7 +317,8 @@ int QtXmlWrapper::loadXMLfile(const std::string &filename) char *QtXmlWrapper::doloadfile(const std::string &filename) const { char *xmldata = NULL; - gzFile gzfile = gzopen(filename.c_str(), "rb"); + + gzFile gzfile = gzdopen(fileToDescriptor(F_OPEN_UTF8(filename, "rb")), "rb"); if(gzfile != NULL) { //The possibly compressed file opened std::stringstream strBuf; //reading stream From ddcae478d4a85a540f132ed38333776c5b9f95d0 Mon Sep 17 00:00:00 2001 From: Hyunin Song Date: Tue, 29 May 2018 17:37:22 +0900 Subject: [PATCH 11/14] Fix sample file loading on Windows --- include/DrumSynth.h | 12 +++++++----- include/SampleBuffer.h | 6 +++--- src/core/DrumSynth.cpp | 24 +++++++++++++++--------- src/core/SampleBuffer.cpp | 35 +++++++++++++++++++---------------- 4 files changed, 44 insertions(+), 33 deletions(-) diff --git a/include/DrumSynth.h b/include/DrumSynth.h index 22d7d3071..f7e9b1d4c 100644 --- a/include/DrumSynth.h +++ b/include/DrumSynth.h @@ -30,22 +30,24 @@ #include #include "lmms_basics.h" +class QString; + class DrumSynth { public: DrumSynth() {}; - int GetDSFileSamples(const char *dsfile, int16_t *&wave, int channels, sample_rate_t Fs); + int GetDSFileSamples(QString dsfile, int16_t *&wave, int channels, sample_rate_t Fs); private: float LoudestEnv(void); int LongestEnv(void); void UpdateEnv(int e, long t); - void GetEnv(int env, const char *sec, const char *key, const char *ini); + void GetEnv(int env, const char *sec, const char *key, QString ini); float waveform(float ph, int form); - int GetPrivateProfileString(const char *sec, const char *key, const char *def, char *buffer, int size, const char *file); - int GetPrivateProfileInt(const char *sec, const char *key, int def, const char *file); - float GetPrivateProfileFloat(const char *sec, const char *key, float def, const char *file); + int GetPrivateProfileString(const char *sec, const char *key, const char *def, char *buffer, int size, QString file); + int GetPrivateProfileInt(const char *sec, const char *key, int def, QString file); + float GetPrivateProfileFloat(const char *sec, const char *key, float def, QString file); }; diff --git a/include/SampleBuffer.h b/include/SampleBuffer.h index 66f4ec873..3acf2c10b 100644 --- a/include/SampleBuffer.h +++ b/include/SampleBuffer.h @@ -270,15 +270,15 @@ private: void convertIntToFloat ( int_sample_t * & _ibuf, f_cnt_t _frames, int _channels); void directFloatWrite ( sample_t * & _fbuf, f_cnt_t _frames, int _channels); - f_cnt_t decodeSampleSF( const char * _f, sample_t * & _buf, + f_cnt_t decodeSampleSF( QString _f, sample_t * & _buf, ch_cnt_t & _channels, sample_rate_t & _sample_rate ); #ifdef LMMS_HAVE_OGGVORBIS - f_cnt_t decodeSampleOGGVorbis( const char * _f, int_sample_t * & _buf, + f_cnt_t decodeSampleOGGVorbis( QString _f, int_sample_t * & _buf, ch_cnt_t & _channels, sample_rate_t & _sample_rate ); #endif - f_cnt_t decodeSampleDS( const char * _f, int_sample_t * & _buf, + f_cnt_t decodeSampleDS( QString _f, int_sample_t * & _buf, ch_cnt_t & _channels, sample_rate_t & _sample_rate ); diff --git a/src/core/DrumSynth.cpp b/src/core/DrumSynth.cpp index fd0695557..e1fb77793 100644 --- a/src/core/DrumSynth.cpp +++ b/src/core/DrumSynth.cpp @@ -26,11 +26,13 @@ #include "DrumSynth.h" -#include +#include #include #include //sin(), exp(), etc. +#include + #ifdef LMMS_BUILD_WIN32 #define powf pow #endif @@ -112,7 +114,7 @@ void DrumSynth::UpdateEnv(int e, long t) } -void DrumSynth::GetEnv(int env, const char *sec, const char *key, const char *ini) +void DrumSynth::GetEnv(int env, const char *sec, const char *key, QString ini) { char en[256], s[8]; int i=0, o=0, ep=0; @@ -162,9 +164,9 @@ float DrumSynth::waveform(float ph, int form) } -int DrumSynth::GetPrivateProfileString(const char *sec, const char *key, const char *def, char *buffer, int size, const char *file) +int DrumSynth::GetPrivateProfileString(const char *sec, const char *key, const char *def, char *buffer, int size, QString file) { - ifstream is; + stringstream is; bool inSection = false; char *line; char *k, *b; @@ -172,7 +174,12 @@ int DrumSynth::GetPrivateProfileString(const char *sec, const char *key, const c line = (char*)malloc(200); - is.open (file, ifstream::in); + // Use QFile to handle unicode file name on Windows + // Previously we used ifstream directly + QFile f(file); + f.open(QIODevice::ReadOnly); + QByteArray dat = f.readAll().constData(); + is.str(string(dat.constData(), dat.size())); while (is.good()) { if (!inSection) { @@ -218,13 +225,12 @@ int DrumSynth::GetPrivateProfileString(const char *sec, const char *key, const c strncpy(buffer, def, size); } - is.close(); free(line); return len; } -int DrumSynth::GetPrivateProfileInt(const char *sec, const char *key, int def, const char *file) +int DrumSynth::GetPrivateProfileInt(const char *sec, const char *key, int def, QString file) { char tmp[16]; int i=0; @@ -235,7 +241,7 @@ int DrumSynth::GetPrivateProfileInt(const char *sec, const char *key, int def, c return i; } -float DrumSynth::GetPrivateProfileFloat(const char *sec, const char *key, float def, const char *file) +float DrumSynth::GetPrivateProfileFloat(const char *sec, const char *key, float def, QString file) { char tmp[16]; float f=0.f; @@ -252,7 +258,7 @@ float DrumSynth::GetPrivateProfileFloat(const char *sec, const char *key, float // an associative array or something once we have a datastructure to load in to. // llama -int DrumSynth::GetDSFileSamples(const char *dsfile, int16_t *&wave, int channels, sample_rate_t Fs) +int DrumSynth::GetDSFileSamples(QString dsfile, int16_t *&wave, int channels, sample_rate_t Fs) { //input file char sec[32]; diff --git a/src/core/SampleBuffer.cpp b/src/core/SampleBuffer.cpp index 5fc640cb6..86f8fd55c 100644 --- a/src/core/SampleBuffer.cpp +++ b/src/core/SampleBuffer.cpp @@ -187,11 +187,6 @@ void SampleBuffer::update( bool _keep_settings ) else if( !m_audioFile.isEmpty() ) { QString file = tryToMakeAbsolute( m_audioFile ); -#ifdef LMMS_BUILD_WIN32 - char * f = qstrdup( file.toLocal8Bit().constData() ); -#else - char * f = qstrdup( file.toUtf8().constData() ); -#endif int_sample_t * buf = NULL; sample_t * fbuf = NULL; ch_cnt_t channels = DEFAULT_CHANNELS; @@ -205,10 +200,13 @@ void SampleBuffer::update( bool _keep_settings ) } else { + // Use QFile to handle unicode file names on Windows + QFile f(file); + f.open(QIODevice::ReadOnly); SNDFILE * snd_file; SF_INFO sf_info; sf_info.format = 0; - if( ( snd_file = sf_open( f, SFM_READ, &sf_info ) ) != NULL ) + if( ( snd_file = sf_open_fd( f.handle(), SFM_READ, &sf_info, false ) ) != NULL ) { f_cnt_t frames = sf_info.frames; int rate = sf_info.samplerate; @@ -218,6 +216,7 @@ void SampleBuffer::update( bool _keep_settings ) } sf_close( snd_file ); } + f.close(); } if( !fileLoadError ) @@ -228,28 +227,26 @@ void SampleBuffer::update( bool _keep_settings ) // decoder first if filename extension matches "ogg" if( m_frames == 0 && fileInfo.suffix() == "ogg" ) { - m_frames = decodeSampleOGGVorbis( f, buf, channels, samplerate ); + m_frames = decodeSampleOGGVorbis( file, buf, channels, samplerate ); } #endif if( m_frames == 0 ) { - m_frames = decodeSampleSF( f, fbuf, channels, + m_frames = decodeSampleSF( file, fbuf, channels, samplerate ); } #ifdef LMMS_HAVE_OGGVORBIS if( m_frames == 0 ) { - m_frames = decodeSampleOGGVorbis( f, buf, channels, + m_frames = decodeSampleOGGVorbis( file, buf, channels, samplerate ); } #endif if( m_frames == 0 ) { - m_frames = decodeSampleDS( f, buf, channels, + m_frames = decodeSampleDS( file, buf, channels, samplerate ); } - - delete[] f; } if ( m_frames == 0 || fileLoadError ) // if still no frames, bail @@ -405,7 +402,7 @@ void SampleBuffer::normalizeSampleRate( const sample_rate_t _src_sr, -f_cnt_t SampleBuffer::decodeSampleSF( const char * _f, +f_cnt_t SampleBuffer::decodeSampleSF(QString _f, sample_t * & _buf, ch_cnt_t & _channels, sample_rate_t & _samplerate ) @@ -416,7 +413,11 @@ f_cnt_t SampleBuffer::decodeSampleSF( const char * _f, f_cnt_t frames = 0; bool sf_rr = false; - if( ( snd_file = sf_open( _f, SFM_READ, &sf_info ) ) != NULL ) + + // Use QFile to handle unicode file names on Windows + QFile f(_f); + f.open(QIODevice::ReadOnly); + if( ( snd_file = sf_open_fd( f.handle(), SFM_READ, &sf_info, false ) ) != NULL ) { frames = sf_info.frames; @@ -442,6 +443,8 @@ f_cnt_t SampleBuffer::decodeSampleSF( const char * _f, "sample %s: %s", _f, sf_strerror( NULL ) ); #endif } + f.close(); + //write down either directly or convert i->f depending on file type if ( frames > 0 && _buf != NULL ) @@ -507,7 +510,7 @@ long qfileTellCallback( void * _udata ) -f_cnt_t SampleBuffer::decodeSampleOGGVorbis( const char * _f, +f_cnt_t SampleBuffer::decodeSampleOGGVorbis( QString _f, int_sample_t * & _buf, ch_cnt_t & _channels, sample_rate_t & _samplerate ) @@ -603,7 +606,7 @@ f_cnt_t SampleBuffer::decodeSampleOGGVorbis( const char * _f, -f_cnt_t SampleBuffer::decodeSampleDS( const char * _f, +f_cnt_t SampleBuffer::decodeSampleDS( QString _f, int_sample_t * & _buf, ch_cnt_t & _channels, sample_rate_t & _samplerate ) From 1af0f083eaad5c024c2b71e60eecabd199778790 Mon Sep 17 00:00:00 2001 From: Hyunin Song Date: Tue, 29 May 2018 17:49:51 +0900 Subject: [PATCH 12/14] Fix WAV exporting on Windows --- include/AudioFileDevice.h | 4 ++++ src/core/audio/AudioFileWave.cpp | 19 ++++++++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/include/AudioFileDevice.h b/include/AudioFileDevice.h index 7b6b81eab..e7177b30f 100644 --- a/include/AudioFileDevice.h +++ b/include/AudioFileDevice.h @@ -56,6 +56,10 @@ protected: return m_outputFile.isOpen(); } + inline int outputFileHandle() const + { + return m_outputFile.handle(); + } private: QFile m_outputFile; diff --git a/src/core/audio/AudioFileWave.cpp b/src/core/audio/AudioFileWave.cpp index 45e46b838..8a590a8b8 100644 --- a/src/core/audio/AudioFileWave.cpp +++ b/src/core/audio/AudioFileWave.cpp @@ -27,6 +27,9 @@ #include "endian_handling.h" #include "Mixer.h" +#include +#include + AudioFileWave::AudioFileWave( OutputSettings const & outputSettings, const ch_cnt_t channels, bool & successful, @@ -72,13 +75,15 @@ bool AudioFileWave::startEncoding() m_si.format |= SF_FORMAT_PCM_16; break; } - m_sf = sf_open( -#ifdef LMMS_BUILD_WIN32 - outputFile().toLocal8Bit().constData(), -#else - outputFile().toUtf8().constData(), -#endif - SFM_WRITE, &m_si ); + + // Use file handle to handle unicode file name on Windows + m_sf = sf_open_fd( outputFileHandle(), SFM_WRITE, &m_si, false ); + + if (!m_sf) + { + qWarning("Error: AudioFileWave::startEncoding: %s", sf_strerror(nullptr)); + return false; + } // Prevent fold overs when encountering clipped data sf_command(m_sf, SFC_SET_CLIPPING, NULL, SF_TRUE); From 3e538d510c135d6b6504298aa57135506397c708 Mon Sep 17 00:00:00 2001 From: Hyunin Song Date: Mon, 4 Jun 2018 14:34:51 +0900 Subject: [PATCH 13/14] Fix MIDI import encoding issue on Windows --- include/ImportFilter.h | 5 +++++ plugins/MidiImport/MidiImport.cpp | 11 ++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/include/ImportFilter.h b/include/ImportFilter.h index 304de5fa4..1b6fe2b59 100644 --- a/include/ImportFilter.h +++ b/include/ImportFilter.h @@ -78,6 +78,11 @@ protected: return m_file.read( _data, _len ); } + inline QByteArray readAllData() + { + return m_file.readAll(); + } + inline void ungetChar( char _ch ) { m_file.ungetChar( _ch ); diff --git a/plugins/MidiImport/MidiImport.cpp b/plugins/MidiImport/MidiImport.cpp index 85d244ca5..5fde7acc7 100644 --- a/plugins/MidiImport/MidiImport.cpp +++ b/plugins/MidiImport/MidiImport.cpp @@ -26,9 +26,12 @@ #include #include #include +#include #include #include +#include + #include "MidiImport.h" #include "TrackContainer.h" #include "InstrumentTrack.h" @@ -279,8 +282,6 @@ public: bool MidiImport::readSMF( TrackContainer* tc ) { - QString filename = file().fileName(); - closeFile(); const int preTrackSteps = 2; QProgressDialog pd( TrackContainer::tr( "Importing MIDI-file..." ), @@ -291,7 +292,11 @@ bool MidiImport::readSMF( TrackContainer* tc ) pd.setValue( 0 ); - Alg_seq_ptr seq = new Alg_seq(filename.toLocal8Bit(), true); + std::stringstream stream; + QByteArray arr = readAllData(); + stream.str(std::string(arr.constData(), arr.size())); + + Alg_seq_ptr seq = new Alg_seq(stream, true); seq->convert_to_beats(); pd.setMaximum( seq->tracks() + preTrackSteps ); From 62d505b2e6af03f3f2d63ed7f23c254fa64b9f95 Mon Sep 17 00:00:00 2001 From: Hyunin Song Date: Mon, 4 Jun 2018 14:41:03 +0900 Subject: [PATCH 14/14] Improve STK rawwave path encoding handling Still incomplete on Windows due to an upstream issue --- plugins/stk/mallets/mallets.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/stk/mallets/mallets.cpp b/plugins/stk/mallets/mallets.cpp index 5e5f35ffc..29b6aeb20 100644 --- a/plugins/stk/mallets/mallets.cpp +++ b/plugins/stk/mallets/mallets.cpp @@ -620,7 +620,7 @@ malletsSynth::malletsSynth( const StkFloat _pitch, { Stk::setSampleRate( _sample_rate ); Stk::setRawwavePath( QDir( ConfigManager::inst()->stkDir() ).absolutePath() - .toLatin1().constData() ); + .toLocal8Bit().constData() ); #ifndef LMMS_DEBUG Stk::showWarnings( false ); #endif @@ -670,7 +670,7 @@ malletsSynth::malletsSynth( const StkFloat _pitch, { Stk::setSampleRate( _sample_rate ); Stk::setRawwavePath( QDir( ConfigManager::inst()->stkDir() ).absolutePath() - .toLatin1().constData() ); + .toLocal8Bit().constData() ); #ifndef LMMS_DEBUG Stk::showWarnings( false ); #endif @@ -718,7 +718,7 @@ malletsSynth::malletsSynth( const StkFloat _pitch, { Stk::setSampleRate( _sample_rate ); Stk::setRawwavePath( QDir( ConfigManager::inst()->stkDir() ).absolutePath() - .toLatin1().constData() ); + .toLocal8Bit().constData() ); #ifndef LMMS_DEBUG Stk::showWarnings( false ); #endif