diff --git a/.github/workflows/ssr-win-mxe.yml b/.github/workflows/ssr-win-mxe.yml new file mode 100644 index 00000000..90f89f08 --- /dev/null +++ b/.github/workflows/ssr-win-mxe.yml @@ -0,0 +1,32 @@ +name: Build SSR-win with MXE +on: [push, pull_request] +jobs: + build-win: + runs-on: ubuntu-20.04 + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Add MXE repository + run: | + sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 86B72ED9 && \ + sudo add-apt-repository 'deb [arch=amd64] https://mirror.mxe.cc/repos/apt focal main' && \ + sudo apt update + - name: Install pre-build MXE + run: | + export PKG_PREFIX=mxe-x86-64-w64-mingw32.shared && \ + sudo apt install -y ${PKG_PREFIX}-cc \ + ${PKG_PREFIX}-cmake-conf \ + ${PKG_PREFIX}-pthreads \ + ${PKG_PREFIX}-fftw \ + ${PKG_PREFIX}-libsndfile \ + ${PKG_PREFIX}-libxml2 \ + ${PKG_PREFIX}-qtbase \ + ${PKG_PREFIX}-jack + + - name: adapt PATH + run: ls /usr/lib/mxe/usr/bin && export PATH=/usr/lib/mxe/usr/bin:$PATH + - name: CMAKE + run: /usr/lib/mxe/usr/bin/x86_64-w64-mingw32.shared-cmake -S . -B _build/ -DCMAKE_BUILD_TYPE=RELEASE -DVRPN=OFF -DSOFA=OFF .. + - name: BUILD + run: /usr/lib/mxe/usr/bin/x86_64-w64-mingw32.shared-cmake --build ./_build -j4 diff --git a/.gitignore b/.gitignore index 324d18fc..7c917002 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,9 @@ data/Makefile.in man/Makefile.in src/Makefile.in src/config.h.in +src/config.h +_build/ +bin/ +ssr-bin/ +ssr-win-bin/ +*.exe diff --git a/.gitmodules b/.gitmodules index dd27bddd..161d9db4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -19,3 +19,12 @@ [submodule "example-scenes"] path = example-scenes url = https://github.com/SoundScapeRenderer/example-scenes.git +[submodule "extern/include/asio"] + path = extern/include/asio + url = https://github.com/chriskohlhoff/asio.git +[submodule "extern/include/jack"] + path = extern/include/jack + url = https://github.com/jackaudio/headers.git +[submodule "extern/include/websocketpp"] + path = extern/include/websocketpp + url = https://github.com/zaphoyd/websocketpp.git diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..8f04d30a --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,369 @@ +# Specify the minimum version for CMake +message(STATUS "CMAKE_VERSION: " ${CMAKE_VERSION}) +cmake_minimum_required(VERSION 3.8) + +# Project's name +project(SSR) + +# The version number +set(SSR_VERSION 0.6.0-cmake) + +# Show more of make +set(CMAKE_VERBOSE_MAKEFILE ON) + +# shared or static build +option(BUILD_SHARED_LIBS "Build using shared libraries" ON) +message(STATUS "Shared libs: " ${BUILD_SHARED_LIBS}) + +# Set the output folder where your program will be created +set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/_build) +if(WIN32) + set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/ssr-win-bin) +else(WIN32) + set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/ssr-bin) +endif(WIN32) + +# Show the compiler +message(STATUS "Comiler: " ${CMAKE_CXX_COMPILER}) +message(STATUS "Compiler ID: " ${CMAKE_CXX_COMPILER_ID}) + +# Enable C++17 +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +set(SOURCE_FILES + src/configuration.cpp + src/ssr_global.cpp + src/xmlparser.cpp + src/legacy_directionalpoint.cpp + src/legacy_orientation.cpp + src/legacy_position.cpp + src/legacy_scene.cpp + ) + + +# The following folders will be included +include_directories(${PROJECT_SOURCE_DIR}/src) + +# Dependencies + +# Include APF +set(APF_PATH ${PROJECT_SOURCE_DIR}/apf) +include_directories(${APF_PATH}) + +# Include GML +set(GML_PATH ${PROJECT_SOURCE_DIR}/gml/include) +include_directories(${GML_PATH}) + + +# Add libraries to EXTRA_LIBS +set(EXTRA_LIBS) + +#set(CMAKE_THREAD_PREFER_PTHREAD TRUE) +set(THREADS_PREFER_PTHREAD_FLAG TRUE) +find_package(Threads REQUIRED) + +# TODO +#find_package(PkgConfig REQUIRED) + +if(WIN32) + # Set Path to extern headers and libraries for Windows builds + set(EXTERN_PATH ${PROJECT_SOURCE_DIR}/extern) + + #set(CMAKE_PREFIX_PATH ${EXTERN_PATH}) + #message(STATUS "WINDOWS Prefix: " ${CMAKE_PREFIX_PATH}) + + # Include extern headers + include_directories(${EXTERN_PATH}/include) + message(STATUS "Included: " ${EXTERN_PATH}/include) + + # here is the target environment located + set(CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH} ${EXTERN_PATH}) +endif(WIN32) + +if(WIN32) + # Use custom static libxml2 build for MSVC + #if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + # find_library(LibXml2 NAMES libxml2_msvc) + #endif() + if(NOT ${BUILD_SHARED_LIBS}) + add_definitions(-DLIBXML_STATIC) + endif() + find_package(LibXml2 REQUIRED) + include_directories(${LIBXML2_INCLUDE_DIR}) + list(APPEND EXTRA_LIBS ${LIBXML2_LIBRARY}) + #list(APPEND EXTRA_LIBS "-lxml2 -lz -llzma -lws2_32") + list(APPEND EXTRA_LIBS "-llzma -lz") + message(STATUS "Found XML2: " ${LIBXML2_LIBRARY}) + message(STATUS "Found XML2 headers: " ${LIBXML2_INCLUDE_DIR}) +else(WIN32) + find_package(LibXml2 REQUIRED) + include_directories(${LIBXML2_INCLUDE_DIR}) + list(APPEND EXTRA_LIBS ${LIBXML2_LIBRARY}) +endif(WIN32) + +find_library(LIBSNDFILE_LIBRARY NAMES sndfile libsndfile-1) +list(APPEND EXTRA_LIBS ${LIBSNDFILE_LIBRARY}) +if(WIN32) + list(APPEND EXTRA_LIBS -lFLAC -lopus -lvorbisenc -lvorbis -logg) +endif(WIN32) +message(STATUS "Found SNDFILE: " ${LIBSNDFILE_LIBRARY}) + +option(ENABLE_ECASOUND "Ecasound soundfile playback/recording" OFF) +if(ENABLE_ECASOUND) + list(APPEND SOURCE_FILES + src/audioplayer.cpp + src/audiorecorder.cpp + ) + find_path(ECASOUND_INCLUDE_DIR NAMES ecasoundc.h HINTS /usr/include/libecasoundc) + include_directories(${ECASOUND_INCLUDE_DIR}) + find_library(ECASOUND_LIBRARY NAMES ecasoundc) + list(APPEND EXTRA_LIBS ${ECASOUND_LIBRARY}) + message(STATUS "Found ECASOUND: " ${ECASOUND_LIBRARY}) +else(ENABLE_ECASOUND) + message(WARNING "ECASOUND disabled.") +endif(ENABLE_ECASOUND) + +find_library(JACK_LIBRARY NAMES jack libjack64) +list(APPEND EXTRA_LIBS ${JACK_LIBRARY}) +message(STATUS "Found JACK :" ${JACK_LIBRARY}) + +find_library(FFTW_LIBRARY NAMES fftw3 libfftw3-3) +list(APPEND EXTRA_LIBS ${FFTW_LIBRARY}) +message(STATUS "Found FFTW: " ${FFTW_LIBRARY}) + +find_library(FFTWF_LIBRARY NAMES fftw3f libfftw3f-3) +list(APPEND EXTRA_LIBS ${FFTWF_LIBRARY}) +message(STATUS "Found FFTWF: " ${FFTWF_LIBRARY}) + +# GUI +option(GUI "Build GUI" ON) +if(GUI) + # Find includes in corresponding build directories + set(CMAKE_INCLUDE_CURRENT_DIR ON) + # Turn on automatic invocation of the MOC + set(CMAKE_AUTOMOC ON) + + include_directories(${PROJECT_SOURCE_DIR}/src/gui) # necessary? + aux_source_directory(${PROJECT_SOURCE_DIR}/src/gui GUI_SOURCE_FILES) + list(APPEND SOURCE_FILES ${GUI_SOURCE_FILES}) + + option(ENABLE_GUI "graphical user interface (using Qt)" ON) + option(ENABLE_FLOATING_CONTROL_PANEL "separate control window" OFF) + + + find_package(Qt5 COMPONENTS Core Gui Widgets OpenGL REQUIRED) + message(STATUS "Found QT5: " ${Qt5_DIR}) + + if(WIN32) + if(NOT ${BUILD_SHARED_LIBS}) + option(STATIC_QT "Use static Qt5 libraries (Windows)" ON) + endif() + if(STATIC_QT) + add_definitions(-DQT_STATICPLUGIN) + endif(STATIC_QT) + + # Platform support libs for Windows + set(QT5PLATFORMSUPPORT_LIBS + Qt5::QWindowsIntegrationPlugin + ) + + # Qt5PlatformSupport modules + find_library(Qt5PlatformCompositorSupportLIBRARY Qt5PlatformCompositorSupport) + list(APPEND QT5PLATFORMSUPPORT_LIBS ${Qt5PlatformCompositorSupportLIBRARY}) + find_library(Qt5ThemeSupport_LIBRARY Qt5ThemeSupport) + list(APPEND QT5PLATFORMSUPPORT_LIBS ${Qt5ThemeSupport_LIBRARY}) + find_library(Qt5FontDatabaseSupport_LIBRARY Qt5FontDatabaseSupport) + list(APPEND QT5PLATFORMSUPPORT_LIBS ${Qt5FontDatabaseSupport_LIBRARY}) + find_library(Qt5EventDispatcherSupport_LIBRARY Qt5EventDispatcherSupport) + list(APPEND QT5PLATFORMSUPPORT_LIBS ${Qt5EventDispatcherSupport_LIBRARY}) + find_library(Qt5AccessibilitySupport_LIBRARY Qt5AccessibilitySupport) + list(APPEND QT5PLATFORMSUPPORT_LIBS ${Qt5AccessibilitySupport_LIBRARY}) + find_library(Qt5WindowsUIAutomationSupport_LIBRARY Qt5WindowsUIAutomationSupport) + list(APPEND QT5PLATFORMSUPPORT_LIBS ${Qt5WindowsUIAutomationSupport_LIBRARY}) + + find_package(Freetype REQUIRED) + list(APPEND QT5PLATFORMSUPPORT_LIBS ${FREETYPE_LIBRARIES}) + + #list(APPEND QT5PLATFORMSUPPORT_LIBS "-lwtsapi32") + + message(STATUS "Found Qt5PlatformSupport: " ${QT5PLATFORMSUPPORT_LIBS}) + endif(WIN32) + + # OpenGL + find_package(OpenGL REQUIRED) + include_directories(${OPENGL_INCLUDE_DIR}) + list(APPEND EXTRA_LIBS ${OPENGL_gl_LIBRARY}) + list(APPEND EXTRA_LIBS ${OPENGL_glu_LIBRARY}) + + message(STATUS "Build GUI") + +else(GUI) + message(WARNING "GUI disabled. Switch on with 'cmake .. -DGUI=ON'") +endif(GUI) + +# Network +option(ENABLE_WEBSOCKET_INTERFACE "network websocket interface" ON) +if(ENABLE_WEBSOCKET_INTERFACE) + add_definitions(-DASIO_STANDALONE) + set(ASIO_PATH ${PROJECT_SOURCE_DIR}/extern/include/asio/asio/include/) + include_directories(${ASIO_PATH}) + + add_definitions(-D_WEBSOCKETPP_CPP11_THREAD_) # https://github.com/zaphoyd/websocketpp/issues/980 + include_directories(${EXTERN_PATH}/include/websocketpp) + set(RAPIDJSON_PATH ${PROJECT_SOURCE_DIR}/rapidjson) + include_directories(${RAPIDJSON_PATH}/include/) + + set(WEBSOCKET_PATH ${PROJECT_SOURCE_DIR}/src/websocket/) + include_directories(${WEBSOCKET_PATH}) + message(STATUS "Enabled WEBSOCKET_INTERFACE interface") +else(ENABLE_WEBSOCKET_INTERFACE) + message(WARNING "WEBSOCKET_INTERFACE disabled.") +endif(ENABLE_WEBSOCKET_INTERFACE) + +option(ENABLE_LEGACY_NETWORK_INTERFACE "network xml interface (legacy)" ON) +if(ENABLE_LEGACY_NETWORK_INTERFACE) + set(ENABLE_IP_INTERFACE ON) + add_definitions(-DASIO_STANDALONE) + set(ASIO_PATH ${PROJECT_SOURCE_DIR}/extern/include/asio/asio/include/) + include_directories(${ASIO_PATH}) + + aux_source_directory(${PROJECT_SOURCE_DIR}/src/legacy_network NETWORK_SOURCE_FILES) + list(APPEND SOURCE_FILES ${NETWORK_SOURCE_FILES}) + + include_directories(${PROJECT_SOURCE_DIR}/src/legacy_network) + if(WIN32) + #add_definitions(-D_WIN32_WINNT=0x0601) # min Windows 7, conflict VRPN + list(APPEND EXTRA_LIBS "-lws2_32 -lmswsock") + endif(WIN32) + message(STATUS "Enabled LEGACY_NETWORK interface") +else(ENABLE_LEGACY_NETWORK_INTERFACE) + message(WARNING "LEGACY_NETWORK_INTERFACE disabled.") +endif(ENABLE_LEGACY_NETWORK_INTERFACE) + +# Head tracker +option(HEAD_TRACKER "Basic head tracker support" ON) +if(HEAD_TRACKER) + list(APPEND SOURCE_FILES + src/trackerrazor.cpp + src/razor-ahrs/RazorAHRS.cpp + src/trackerpolhemus.cpp + ) + set(ENABLE_RAZOR ON) + set(ENABLE_POLHEMUS ON) + if(WIN32) + add_definitions(-DENABLE_O_NDELAY_WORKAROUND) # bits/fcntl2.h + endif(WIN32) + message(STATUS "Basic head tracker support") + + option(VRPN "VRPN tracker support" ON) + if(VRPN) + message(STATUS "Adding VRPN:") + list(APPEND SOURCE_FILES + src/trackervrpn.cpp + ) + set(VRPN_BUILD_CLIENT_LIBRARY TRUE CACHE INTERNAL "" FORCE) + add_subdirectory(vrpn) + include_directories(vrpn) + list(APPEND EXTRA_LIBS vrpn) + set(ENABLE_VRPN ON) + message(STATUS "VRPN head tracker support") + endif(VRPN) + option(INTERSENSE "INTERSENSE tracker support" OFF) + if(INTERSENSE) + add_definitions(-DHAVE_INTERSENSE_404) + list(APPEND SOURCE_FILES + src/trackerintersense.cpp + ) + include_directories(intersense) + list(APPEND EXTRA_LIBS isense) + set(ENABLE_INTERSENSE ON) + message(STATUS "INTERSENSE head tracker support") + endif(INTERSENSE) +else(HEAD_TRACKER) + message(WARNING "HEAD_TRACKER disabled.") +endif(HEAD_TRACKER) + + +# SOFA support +option(SOFA "SOFA file support" ON) +if(SOFA) + message(STATUS "Adding SOFA:") + option(BUILD_TESTS OFF) + add_subdirectory(libmysofa) + include_directories(libmysofa/src/hrtf) + if(${BUILD_SHARED_LIBS}) + list(APPEND EXTRA_LIBS mysofa-shared) + else() + list(APPEND EXTRA_LIBS mysofa-static) + endif() + set(ENABLE_SOFA ON) + message(STATUS "SOFA file support") +endif(SOFA) + +# Preprocessor symbols +add_definitions(-DSSR_DATA_DIR="./data") +#add_definitions(-DAPF_JACK_POLICY_DEBUG) +#add_definitions(-DAPF_JACKCLIENT_DEBUG) + +# Config definitions +# configure a header file to pass some of the CMake settings +# to the source code +add_definitions(-DHAVE_CONFIG_H) +configure_file( + "${PROJECT_SOURCE_DIR}/generate_config.h.in" + "${PROJECT_SOURCE_DIR}/src/config.h" + ) + + +# Compiler flags +# Add a few for release builds (MAKE_BUILD_TYPE=RELEASE) +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall -fomit-frame-pointer -ffast-math -funroll-loops -march=x86-64 -mmmx -msse -msse2 -mfpmath=sse") +message(STATUS "Release Flags: " ${CMAKE_CXX_FLAGS_RELEASE}) +# And for debug builds (MAKE_BUILD_TYPE=DEBUG) +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Wextra") # -Weffc++ -Wa,-mbig-obj +message(STATUS "Debug Flags: " ${CMAKE_CXX_FLAGS_DEBUG}) + +# Compile executables +set(EXECUTABLES + ssr-binaural + ssr-brs + ssr-vbap + ssr-wfs + ssr-aap + ssr-dca + ssr-generic + ) +add_executable(ssr-binaural src/ssr_binaural.cpp) +add_executable(ssr-brs src/ssr_brs.cpp) +add_executable(ssr-vbap src/ssr_vbap.cpp) +add_executable(ssr-wfs src/ssr_wfs.cpp) +add_executable(ssr-aap src/ssr_aap.cpp) +add_executable(ssr-dca src/ssr_dca.cpp) +add_executable(ssr-generic src/ssr_generic.cpp) + + +# Link +if(NOT ${BUILD_SHARED_LIBS}) + set(CMAKE_EXE_LINKER_FLAGS "-static -static-libgcc -static-libstdc++") +endif() + +message(STATUS "Linking: " ${EXTRA_LIBS} ${QT5PLATFORMSUPPORT_LIBS}) + +foreach(executable ${EXECUTABLES}) + target_sources(${executable} + PRIVATE + ${SOURCE_FILES} + ) + target_link_libraries(${executable} Threads::Threads) + target_link_libraries(${executable} ${EXTRA_LIBS}) + if(GUI) + target_link_libraries(${executable} Qt5::Gui Qt5::Core Qt5::Widgets Qt5::OpenGL ${QT5PLATFORMSUPPORT_LIBS}) + endif(GUI) +endforeach(executable ${EXECUTABLES}) + +# Using MXE with LOCAL_PKG_LIST := cc cmake fftw libsndfile libxml2 qtbase jack pthreads +# x86_64-w64-mingw32.shared.posix-cmake -S . -B _build/ -DCMAKE_BUILD_TYPE=RELEASE -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON +# x86_64-w64-mingw32.shared.posix-cmake --build ./_build -j4 +# ../mxe/tools/copydlldeps.sh --indir ./ssr-win-bin --destdir ./ssr-win-bin/deps --recursivesrcdir ../mxe/usr/x86_64-w64-mingw32.shared/ --srcdir ./_build --copy --enforcedir ./_build/*.dll --enforcedir ../mxe/usr/x86_64-w64-mingw32.shared/qt5/plugins/platforms/ diff --git a/README.md b/README.md new file mode 100644 index 00000000..d4bb235c --- /dev/null +++ b/README.md @@ -0,0 +1,57 @@ +[![Build Status](https://travis-ci.com/chris-hld/ssr.svg?branch=ssr-windows)](https://travis-ci.com/chris-hld/ssr) + +This is a fork of the SoundScape Renderer ([SSR](https://github.com/SoundScapeRenderer/ssr)), which aims at porting the source code to Windows. + +The basic idea is to cross-compile on a linux machine an executable (.exe) for Windows. +We use the M cross environment ([MXE](http://mxe.cc/)), which provides cross-compilation scripts for the dependencies and the MinGW64 (GCC) compiler. + +Pre-compiled binaries for Windows currently include: + `ssr-binaural.exe`, `ssr-brs.exe`, `ssr-vbap.exe`, `ssr-wfs.exe`, `ssr-aap.exe`, `ssr-dca.exe` and `ssr-generic.exe`. + +They should run on all x86-64 CPUs. + + +Getting started +--------------- +* Install Jack Audio for Windows (64bit) from [Jack Audio Downloads](http://www.jackaudio.org/downloads/). +* Get it running by following the [Installation and Configuration](http://jackaudio.org/faq/jack_on_windows.html). +* Download and run the latest installer [Release](https://github.com/chris-hld/ssr/releases). +* Adapt the configuration file e.g. `ssr.conf.windows` to your needs. + +Running the SSR on Windows +-------------------------- +* Have a look at the [Documentation](http://ssr.readthedocs.io/en/latest/operation.html#running-the-ssr) +* First, start the Jack Audio Server, e.g. with `qjackctl.exe`. +* Start the SSR. Navigate a terminal to your installation folder and start from the terminal. +* Optional: Start your ASIO playback Software. +* Connect everything using Jack Audio Connection. + +This could look like this: + +![Jack](doc/manual/images/screenshot_jack.png) +![SSR-Windows](doc/manual/images/screenshot_ssr-windows.png) + + +--- + +This is the source distribution of SoundScape Renderer (SSR) licensed under the +GPLv3+. Please consult the file COPYING for more information about this license. + +The user manual in the doc/ directory contains relevant informations about the +SSR, including installation instructions. Additional (very detailed) +installation instructions can be found in the file INSTALL. + +For questions, bug reports and feature requests: + +Contact: ssr@spatialaudio.net +Website: http://spatialaudio.net/ssr/ +Documentation: https://ssr.readthedocs.io/ + +Copyright (c) 2016-2018 Division of Applied Acoustics + Chalmers University of Technology + +Copyright (c) 2012-2021 Institut für Nachrichtentechnik, Universität Rostock + +Copyright (c) 2006-2012 Quality & Usability Lab + Deutsche Telekom Laboratories, TU Berlin + diff --git a/SSR-installer.nsi b/SSR-installer.nsi new file mode 100644 index 00000000..533ddfc0 --- /dev/null +++ b/SSR-installer.nsi @@ -0,0 +1,63 @@ +# define name of installer +OutFile "SSR-installer.exe" + +# The default installation directory +InstallDir $PROGRAMFILES64\SoundScapeRenderer + +RequestExecutionLevel admin + +;-------------------------------- +Page components +Page directory +Page instfiles + +UninstPage uninstConfirm +UninstPage instfiles +;------------------------------- + + +# start default section +Section "Installer Section" + + # set the installation directory as the destination for the following actions + SetOutPath $INSTDIR + + # specify file to go in output path + File ssr-win-bin\*.exe + + # add dependencies + File /r /x libjack*.dll ssr-win-bin\deps\*.* + + # add resources + File /r ssr-win-bin\data\ + + File /oname=data\default_hrirs.wav ssr-win-bin\data\impulse_responses\hrirs\hrirs_fabian_min_phase_eq.wav + + # create the uninstaller + WriteUninstaller "$INSTDIR\uninstall.exe" + +SectionEnd + +Section "Start Menu Shortcuts" + # create a shortcut named "SoundScapeRenderer" in the start menu programs directory + # point the new shortcut at the program uninstaller + CreateDirectory "$SMPROGRAMS\SoundScapeRenderer" + CreateShortcut "$SMPROGRAMS\SoundScapeRenderer\uninstall.lnk" "$INSTDIR\uninstall.exe" + +SectionEnd + + +# uninstaller section start +Section "un.Uninstaller Section" + # TODO + + # Remove the link from the start menu + Delete "$SMPROGRAMS\SoundScapeRenderer\uninstall.lnk" + + RMDir "$SMPROGRAMS\SoundScapeRenderer" + RMDir $INSTDIR + + MessageBox MB_OK "You need to manually remove the files for now!" + +# uninstaller section end +SectionEnd \ No newline at end of file diff --git a/data/ssr.conf.example b/data/ssr.conf.example index 762cddcf..332bcd39 100644 --- a/data/ssr.conf.example +++ b/data/ssr.conf.example @@ -24,7 +24,7 @@ #AUTO_ROTATION = off # Default Scene file name -#SCENE_FILE_NAME = my_scene.asd +SCENE_FILE_NAME = reproduction_setups/circle.asd # GUI scene shortcuts #SCENE_MENU = scene_menu.conf diff --git a/doc/manual/images/screenshot_jack.png b/doc/manual/images/screenshot_jack.png new file mode 100644 index 00000000..9df011b7 Binary files /dev/null and b/doc/manual/images/screenshot_jack.png differ diff --git a/doc/manual/images/screenshot_ssr-windows.png b/doc/manual/images/screenshot_ssr-windows.png new file mode 100644 index 00000000..ebb22f34 Binary files /dev/null and b/doc/manual/images/screenshot_ssr-windows.png differ diff --git a/extern/include/asio b/extern/include/asio new file mode 160000 index 00000000..a71f5232 --- /dev/null +++ b/extern/include/asio @@ -0,0 +1 @@ +Subproject commit a71f5232d207b4f3bbd253eb1041e30b5e4ea606 diff --git a/extern/include/bits/fcntl2.h b/extern/include/bits/fcntl2.h new file mode 100644 index 00000000..b2386594 --- /dev/null +++ b/extern/include/bits/fcntl2.h @@ -0,0 +1,297 @@ +#ifndef FCNCTL2_H +#define FCNCTL2_H + +// Prevent Winsock.h from being included by the Windows.h header. +// This must be done if we plan to include Winsock2.h in other files. +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif // WIN32_LEAN_AND_MEAN +#include + +#include + +#include +#include +#include + +#ifdef _MSC_VER +// Disable some Visual Studio warnings. +#pragma warning(disable : 4996) +#endif // _MSC_VER + +/* open/fcntl. */ +#ifndef O_NOCTTY +# define O_NOCTTY 0400 /* Not fcntl. */ +#endif +//#ifndef O_TRUNC +//# define O_TRUNC 01000 /* Not fcntl. */ +//#endif +//#ifndef O_APPEND +//# define O_APPEND 02000 +//#endif +#ifndef O_NONBLOCK +# define O_NONBLOCK 04000 +#endif +#ifndef O_NDELAY +# define O_NDELAY O_NONBLOCK +#endif + +#ifndef __O_DIRECTORY +# define __O_DIRECTORY 0200000 +#endif +#ifndef __O_NOFOLLOW +# define __O_NOFOLLOW 0400000 +#endif +#ifndef __O_CLOEXEC +# define __O_CLOEXEC 02000000 +#endif +#ifndef __O_DIRECT +# define __O_DIRECT 040000 +#endif +#ifndef __O_NOATIME +# define __O_NOATIME 01000000 +#endif +#ifndef __O_PATH +# define __O_PATH 010000000 +#endif +#ifndef __O_TMPFILE +# define __O_TMPFILE (020000000 | __O_DIRECTORY) +#endif + +# define O_DIRECTORY __O_DIRECTORY /* Must be a directory. */ +# define O_NOFOLLOW __O_NOFOLLOW /* Do not follow links. */ +# define O_CLOEXEC __O_CLOEXEC /* Set close_on_exec. */ + +# define O_DIRECT __O_DIRECT /* Direct disk access. */ +# define O_NOATIME __O_NOATIME /* Do not set atime. */ +# define O_PATH __O_PATH /* Resolve pathname but do not open file. */ +# define O_TMPFILE __O_TMPFILE /* Atomically create nameless file. */ + +/* Values for the second argument to `fcntl'. */ +#define F_DUPFD 0 /* Duplicate file descriptor. */ +#define F_GETFD 1 /* Get file descriptor flags. */ +#define F_SETFD 2 /* Set file descriptor flags. */ +#define F_GETFL 3 /* Get file status flags. */ +#define F_SETFL 4 /* Set file status flags. */ + +#define MAX_PATH_LENGTH_OPEN_LINUX (128-8) + +// Very limited implementation... +__inline int fcntl(int __fd, int __cmd, ...) +{ + HANDLE hDev = (HANDLE)(intptr_t)__fd; + COMMTIMEOUTS timeouts; + // Disable if XON/XOFF are necessary, enable if fcntl() is used together with O_NDELAY and timeouts... +#ifdef ENABLE_O_NDELAY_WORKAROUND + DCB dcb; + DWORD ReadIntervalTimeout = 0, ReadTotalTimeoutConstant = 0, ReadTotalTimeoutMultiplier = 0, WriteTotalTimeoutConstant = 0; +#endif // ENABLE_O_NDELAY_WORKAROUND + va_list argptr; + va_start(argptr, __cmd); + + if (__cmd == F_SETFL) + { + int flags = va_arg(argptr, int); + + memset(&timeouts, 0, sizeof(COMMTIMEOUTS)); + if (!GetCommTimeouts(hDev, &timeouts)) + { + errno = EIO; + return -1; + } + if (flags & O_NDELAY) + { + // Disable if XON/XOFF are necessary, enable if fcntl() is used together with O_NDELAY and timeouts... +#ifdef ENABLE_O_NDELAY_WORKAROUND + // Need to save the original timeouts settings for next calls of fcntl()... + + memset(&dcb, 0, sizeof(DCB)); + if (!GetCommState(hDev, &dcb)) + { + errno = EIO; + return -1; + } + + // Warning : XoffLim and XonLim are just used as placeholders to save the original timeouts settings, + // they are not normally related to timeouts... + + ReadIntervalTimeout = timeouts.ReadIntervalTimeout; + ReadTotalTimeoutConstant = timeouts.ReadTotalTimeoutConstant; + ReadTotalTimeoutMultiplier = timeouts.ReadTotalTimeoutMultiplier; + WriteTotalTimeoutConstant = timeouts.WriteTotalTimeoutConstant; + if (ReadIntervalTimeout == MAXDWORD) ReadIntervalTimeout = 255*100; + else if (ReadIntervalTimeout/100 > 254) ReadIntervalTimeout = 254*100; + if (ReadTotalTimeoutConstant == MAXDWORD) ReadTotalTimeoutConstant = 255*100; + else if (ReadTotalTimeoutConstant/100 > 254) ReadTotalTimeoutConstant = 254*100; + if (ReadTotalTimeoutMultiplier == MAXDWORD) ReadTotalTimeoutMultiplier = 255*100; + else if (ReadTotalTimeoutMultiplier/100 > 254) ReadTotalTimeoutMultiplier = 254*100; + if (WriteTotalTimeoutConstant == MAXDWORD) WriteTotalTimeoutConstant = 255*100; + else if (WriteTotalTimeoutConstant/100 > 254) WriteTotalTimeoutConstant = 254*100; + dcb.XoffLim = (WORD)(((ReadIntervalTimeout/100)<<8)|(ReadTotalTimeoutConstant/100)); + dcb.XonLim = (WORD)(((ReadTotalTimeoutMultiplier/100)<<8)|(WriteTotalTimeoutConstant/100)); + if (!SetCommState(hDev, &dcb)) + { + errno = EIO; + return -1; + } +#endif // ENABLE_O_NDELAY_WORKAROUND + // Change timeout settings. + timeouts.ReadIntervalTimeout = MAXDWORD; + timeouts.ReadTotalTimeoutConstant = 0; + timeouts.ReadTotalTimeoutMultiplier = 0; + timeouts.WriteTotalTimeoutConstant = 1; // ??? + timeouts.WriteTotalTimeoutMultiplier = 0; + if (!SetCommTimeouts(hDev, &timeouts)) + { + errno = EIO; + return -1; + } + } + else + { + // Disable if XON/XOFF are necessary, enable if fcntl() is used together with O_NDELAY and timeouts... +#ifdef ENABLE_O_NDELAY_WORKAROUND + // Should restore original timeout values... + + memset(&dcb, 0, sizeof(DCB)); + if (!GetCommState(hDev, &dcb)) + { + errno = EIO; + return -1; + } + + // Warning : XoffLim and XonLim are just used as placeholders to save the original timeouts settings, + // they are not normally related to timeouts... + + if ((dcb.XoffLim>>8) == 255) timeouts.ReadIntervalTimeout = MAXDWORD; + else timeouts.ReadIntervalTimeout = (dcb.XoffLim>>8)*100; + if ((dcb.XoffLim&0x00FF) == 255) timeouts.ReadTotalTimeoutConstant = MAXDWORD; + else timeouts.ReadTotalTimeoutConstant = (dcb.XoffLim&0x00FF)*100; + if ((dcb.XonLim>>8) == 255) timeouts.ReadTotalTimeoutMultiplier = MAXDWORD; + else timeouts.ReadTotalTimeoutMultiplier = (dcb.XonLim>>8)*100; + if ((dcb.XonLim&0x00FF) == 255) timeouts.WriteTotalTimeoutConstant = MAXDWORD; + else timeouts.WriteTotalTimeoutConstant = (dcb.XonLim&0x00FF)*100; + timeouts.WriteTotalTimeoutMultiplier = 0; + // Set to full blocking in case the restored values were non-blocking. + if ((timeouts.ReadIntervalTimeout == MAXDWORD)&&(timeouts.ReadTotalTimeoutConstant == 0)&&(timeouts.ReadTotalTimeoutMultiplier == 0)) + { + timeouts.ReadIntervalTimeout = 0; + timeouts.ReadTotalTimeoutConstant = 0; + timeouts.ReadTotalTimeoutMultiplier = 0; + timeouts.WriteTotalTimeoutConstant = 0; + timeouts.WriteTotalTimeoutMultiplier = 0; + } +#else + timeouts.ReadIntervalTimeout = 0; + timeouts.ReadTotalTimeoutConstant = 0; + timeouts.ReadTotalTimeoutMultiplier = 0; + timeouts.WriteTotalTimeoutConstant = 0; + timeouts.WriteTotalTimeoutMultiplier = 0; +#endif // ENABLE_O_NDELAY_WORKAROUND + if (!SetCommTimeouts(hDev, &timeouts)) + { + errno = EIO; + return -1; + } + } + } + else if (__cmd == F_GETFL) + { + int flags = 0; + + memset(&timeouts, 0, sizeof(COMMTIMEOUTS)); + if (!GetCommTimeouts(hDev, &timeouts)) + { + errno = EIO; + return -1; + } + if ((timeouts.ReadIntervalTimeout == MAXDWORD)&&(timeouts.ReadTotalTimeoutConstant == 0)&&(timeouts.ReadTotalTimeoutMultiplier == 0)) + { + // Polling read. + flags |= O_NDELAY; + } + else + { + // Blocking read. + flags &= ~O_NDELAY; + } + return flags; + } + + return 0; +} + +__inline int open_linux(const char *__path, int __oflag, ...) +{ + // The optional arguments are ignored... + + int fd = -1; + HANDLE hDev = INVALID_HANDLE_VALUE; + char szDeviceTemp[2*(MAX_PATH_LENGTH_OPEN_LINUX+8)]; + TCHAR tstr[2*(MAX_PATH_LENGTH_OPEN_LINUX+8)]; + DWORD dwDesiredAccess = 0; + DWORD dwCreationDisposition = 0; + DWORD dwShareMode = 0; + //SECURITY_ATTRIBUTES SecurityAttributes; + DWORD dwFlagsAndAttributes = 0; + + // To be able to use COM10 and greater we need to add "\\.\" (that becomes "\\\\.\\" + // in C because the '\' is a special character). + memset(szDeviceTemp, 0, sizeof(szDeviceTemp)); +//#ifdef WINCE + strcpy(szDeviceTemp, __path); +//#else +// sprintf(szDeviceTemp, "\\\\.\\%s", __path); +//#endif // WINCE + +#ifdef UNICODE + mbstowcs(tstr, szDeviceTemp, sizeof(szDeviceTemp)/2); +#else + memcpy(tstr, szDeviceTemp, sizeof(szDeviceTemp)/2); +#endif // UNICODE + tstr[sizeof(tstr)-1] = 0; + + if (__oflag & O_RDONLY) dwDesiredAccess |= GENERIC_READ; + if (__oflag & O_WRONLY) dwDesiredAccess |= GENERIC_WRITE; + if (__oflag & O_RDWR) dwDesiredAccess |= GENERIC_READ|GENERIC_WRITE; + + if (__oflag & O_APPEND) dwCreationDisposition |= OPEN_EXISTING; + if (__oflag & O_CREAT) + { + if (__oflag & O_EXCL) dwCreationDisposition |= CREATE_NEW; + else dwCreationDisposition |= CREATE_ALWAYS; + } + if (__oflag & O_TRUNC) dwCreationDisposition |= TRUNCATE_EXISTING; + + if ((__oflag & O_NONBLOCK)||(__oflag&O_NDELAY)) dwFlagsAndAttributes |= 0; // ? + + if (__oflag & O_DIRECT) dwFlagsAndAttributes |= FILE_FLAG_NO_BUFFERING|FILE_FLAG_WRITE_THROUGH; + + if (__oflag & O_TMPFILE) dwFlagsAndAttributes |= FILE_ATTRIBUTE_TEMPORARY; + + hDev = CreateFile(tstr, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL); + + if (hDev == INVALID_HANDLE_VALUE) + { + errno = EIO; + return -1; + } + + //#ifndef DISABLE_FORCE_CLEAR_DTR + //if (!EscapeCommFunction(hDev, CLRDTR)) + //{ + // + //} + //#endif // DISABLE_FORCE_CLEAR_DTR + + fd = (int)(intptr_t)hDev; + + return fd; +} + +#ifdef _MSC_VER +// Restore the Visual Studio warnings previously disabled. +#pragma warning(default : 4996) +#endif // _MSC_VER + +#endif // FCNCTL2_H diff --git a/extern/include/bits/termios.h b/extern/include/bits/termios.h new file mode 100644 index 00000000..bbf093dc --- /dev/null +++ b/extern/include/bits/termios.h @@ -0,0 +1,219 @@ +/* termios type and macro definitions. Linux version. + Copyright (C) 1993-2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _TERMIOS_H +# error "Never include directly; use instead." +#endif + +typedef unsigned char cc_t; +typedef unsigned int speed_t; +typedef unsigned int tcflag_t; + +#define NCCS 32 +struct termios + { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +#define _HAVE_STRUCT_TERMIOS_C_ISPEED 1 +#define _HAVE_STRUCT_TERMIOS_C_OSPEED 1 + }; + +/* c_cc characters */ +#define VINTR 0 +#define VQUIT 1 +#define VERASE 2 +#define VKILL 3 +#define VEOF 4 +#define VTIME 5 +#define VMIN 6 +#define VSWTC 7 +#define VSTART 8 +#define VSTOP 9 +#define VSUSP 10 +#define VEOL 11 +#define VREPRINT 12 +#define VDISCARD 13 +#define VWERASE 14 +#define VLNEXT 15 +#define VEOL2 16 + +/* c_iflag bits */ +#define IGNBRK 0000001 +#define BRKINT 0000002 +#define IGNPAR 0000004 +#define PARMRK 0000010 +#define INPCK 0000020 +#define ISTRIP 0000040 +#define INLCR 0000100 +#define IGNCR 0000200 +#define ICRNL 0000400 +#define IUCLC 0001000 +#define IXON 0002000 +#define IXANY 0004000 +#define IXOFF 0010000 +#define IMAXBEL 0020000 +#define IUTF8 0040000 + +/* c_oflag bits */ +#define OPOST 0000001 +#define OLCUC 0000002 +#define ONLCR 0000004 +#define OCRNL 0000010 +#define ONOCR 0000020 +#define ONLRET 0000040 +#define OFILL 0000100 +#define OFDEL 0000200 +#if defined __USE_MISC || defined __USE_XOPEN +# define NLDLY 0000400 +# define NL0 0000000 +# define NL1 0000400 +# define CRDLY 0003000 +# define CR0 0000000 +# define CR1 0001000 +# define CR2 0002000 +# define CR3 0003000 +# define TABDLY 0014000 +# define TAB0 0000000 +# define TAB1 0004000 +# define TAB2 0010000 +# define TAB3 0014000 +# define BSDLY 0020000 +# define BS0 0000000 +# define BS1 0020000 +# define FFDLY 0100000 +# define FF0 0000000 +# define FF1 0100000 +#endif + +#define VTDLY 0040000 +#define VT0 0000000 +#define VT1 0040000 + +#ifdef __USE_MISC +# define XTABS 0014000 +#endif + +/* c_cflag bit meaning */ +#ifdef __USE_MISC +# define CBAUD 0010017 +#endif +#define B0 0000000 /* hang up */ +#define B50 0000001 +#define B75 0000002 +#define B110 0000003 +#define B134 0000004 +#define B150 0000005 +#define B200 0000006 +#define B300 0000007 +#define B600 0000010 +#define B1200 0000011 +#define B1800 0000012 +#define B2400 0000013 +#define B4800 0000014 +#define B9600 0000015 +#define B19200 0000016 +#define B38400 0000017 +#ifdef __USE_MISC +# define EXTA B19200 +# define EXTB B38400 +#endif +#define CSIZE 0000060 +#define CS5 0000000 +#define CS6 0000020 +#define CS7 0000040 +#define CS8 0000060 +#define CSTOPB 0000100 +#define CREAD 0000200 +#define PARENB 0000400 +#define PARODD 0001000 +#define HUPCL 0002000 +#define CLOCAL 0004000 +#ifdef __USE_MISC +# define CBAUDEX 0010000 +#endif +#define B57600 0010001 +#define B115200 0010002 +#define B230400 0010003 +#define B460800 0010004 +#define B500000 0010005 +#define B576000 0010006 +#define B921600 0010007 +#define B1000000 0010010 +#define B1152000 0010011 +#define B1500000 0010012 +#define B2000000 0010013 +#define B2500000 0010014 +#define B3000000 0010015 +#define B3500000 0010016 +#define B4000000 0010017 +#define __MAX_BAUD B4000000 +#ifdef __USE_MISC +# define CIBAUD 002003600000 /* input baud rate (not used) */ +# define CMSPAR 010000000000 /* mark or space (stick) parity */ +# define CRTSCTS 020000000000 /* flow control */ +#endif + +/* c_lflag bits */ +#define ISIG 0000001 +#define ICANON 0000002 +#if defined __USE_MISC || defined __USE_XOPEN +# define XCASE 0000004 +#endif +#define ECHO 0000010 +#define ECHOE 0000020 +#define ECHOK 0000040 +#define ECHONL 0000100 +#define NOFLSH 0000200 +#define TOSTOP 0000400 +#ifdef __USE_MISC +# define ECHOCTL 0001000 +# define ECHOPRT 0002000 +# define ECHOKE 0004000 +# define FLUSHO 0010000 +# define PENDIN 0040000 +#endif +#define IEXTEN 0100000 +#ifdef __USE_MISC +# define EXTPROC 0200000 +#endif + +/* tcflow() and TCXONC use these */ +#define TCOOFF 0 +#define TCOON 1 +#define TCIOFF 2 +#define TCION 3 + +/* tcflush() and TCFLSH use these */ +#define TCIFLUSH 0 +#define TCOFLUSH 1 +#define TCIOFLUSH 2 + +/* tcsetattr uses these */ +#define TCSANOW 0 +#define TCSADRAIN 1 +#define TCSAFLUSH 2 + + +#define _IOT_termios /* Hurd ioctl type field. */ \ + _IOT (_IOTS (cflag_t), 4, _IOTS (cc_t), NCCS, _IOTS (speed_t), 2) diff --git a/extern/include/jack b/extern/include/jack new file mode 160000 index 00000000..2bfa5069 --- /dev/null +++ b/extern/include/jack @@ -0,0 +1 @@ +Subproject commit 2bfa5069718ca4f4dc091e0be845958f2d8a5ba8 diff --git a/extern/include/termios.h b/extern/include/termios.h new file mode 100644 index 00000000..45bfc458 --- /dev/null +++ b/extern/include/termios.h @@ -0,0 +1,656 @@ +#ifndef _TERMIOS_H +#define _TERMIOS_H + +/* +This file intended to serve as a drop-in replacement for termios.h on Windows. +Please add/remove functionality as neeeded. +*/ + +// Not sure what is that... +#ifndef __USE_MISC +#define __USE_MISC +#endif // __USE_MISC + +/* Get the system-dependent definitions of `struct termios', `tcflag_t', + `cc_t', `speed_t', and all the macros specifying the flag bits. */ +#include + +#ifdef __USE_MISC +/* Compare a character C to a value VAL from the `c_cc' array in a + `struct termios'. If VAL is _POSIX_VDISABLE, no character can match it. */ +# define CCEQ(val, c) ((c) == (val) && (val) != _POSIX_VDISABLE) +#endif + +// Prevent Winsock.h from being included by the Windows.h header. +// This must be done if we plan to include Winsock2.h in other files. +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif // WIN32_LEAN_AND_MEAN +#include + +#include + +//#include "NtPathFromHandle.h" + +inline UINT _linuxbaudrate2windows(speed_t BaudRate) +{ + switch (BaudRate) + { + case B110: + return CBR_110; + case B300: + return CBR_300; + case B600: + return CBR_600; + case B1200: + return CBR_1200; + case B4800: + return CBR_4800; + case B2400: + return CBR_2400; + case B9600: + return CBR_9600; + case B19200: + return CBR_19200; + case B38400: + return CBR_38400; + case B57600: + return CBR_57600; + case B115200: + return CBR_115200; + default: + return 0; + } +} + +inline speed_t _windowsbaudrate2linux(UINT BaudRate) +{ + switch (BaudRate) + { + case CBR_110: + return B110; + case CBR_300: + return B300; + case CBR_600: + return B600; + case CBR_1200: + return B1200; + case CBR_4800: + return B4800; + case CBR_2400: + return B2400; + case CBR_9600: + return B9600; + case CBR_19200: + return B19200; + case CBR_38400: + return B38400; + case CBR_57600: + return B57600; + case CBR_115200: + return B115200; + default: + return 0; + } +} + +__inline speed_t cfgetospeed(const struct termios *__termios_p) +{ + return __termios_p->c_ospeed; +} + +__inline speed_t cfgetispeed(const struct termios *__termios_p) +{ + return __termios_p->c_ispeed; +} + +__inline int cfsetospeed(struct termios *__termios_p, speed_t __speed) +{ + __termios_p->c_ospeed = __speed; + return 0; +} + +__inline int cfsetispeed(struct termios *__termios_p, speed_t __speed) +{ + __termios_p->c_ispeed = __speed; + return 0; +} + +#ifdef __USE_MISC +__inline int cfsetspeed(struct termios *__termios_p, speed_t __speed) +{ + __termios_p->c_ispeed = __speed; + __termios_p->c_ospeed = __speed; + return 0; +} +#endif + +/* Put the state of FD into *TERMIOS_P. */ +__inline int tcgetattr(int __fd, struct termios *__termios_p) +{ + HANDLE hDev = (HANDLE)(intptr_t)__fd; + COMMTIMEOUTS timeouts; + DCB dcb; + speed_t speed = 0; + +//#pragma region TIMEOUTS + memset(&timeouts, 0, sizeof(COMMTIMEOUTS)); + if (!GetCommTimeouts(hDev, &timeouts)) + { + errno = EIO; + return -1; + } + + if ((timeouts.ReadIntervalTimeout == MAXDWORD)&&(timeouts.ReadTotalTimeoutConstant == 0)&&(timeouts.ReadTotalTimeoutMultiplier == 0)) + { + // Polling read. + __termios_p->c_cc[VMIN] = 0; // Minimum number of characters to read. + __termios_p->c_cc[VTIME] = 0; // Time to wait for every character read in tenths of seconds. + } + else if ((timeouts.ReadIntervalTimeout == 0)&&(timeouts.ReadTotalTimeoutConstant == 0)&&(timeouts.ReadTotalTimeoutMultiplier == 0)) + { + // Blocking read. + __termios_p->c_cc[VMIN] = 1; // Minimum number of characters to read. + __termios_p->c_cc[VTIME] = 0; // Time to wait for every character read in tenths of seconds. + } + else if ((timeouts.ReadIntervalTimeout == MAXDWORD)&&(timeouts.ReadTotalTimeoutMultiplier == MAXDWORD)) + { + // Read with timeout. + if (timeouts.ReadTotalTimeoutConstant/100 > 255) + { + errno = EINVAL; + return -1; + } + __termios_p->c_cc[VMIN] = 0; // Minimum number of characters to read. + __termios_p->c_cc[VTIME] = (cc_t)(timeouts.ReadTotalTimeoutConstant/100); // Time to wait for every character read in tenths of seconds. + } + else if ((timeouts.ReadTotalTimeoutConstant == 0)&&(timeouts.ReadTotalTimeoutMultiplier == 0)) + { + // Should be approximately equivalent... + + // Read with interbyte timeout. + if (timeouts.ReadIntervalTimeout/100 > 255) + { + errno = EINVAL; + return -1; + } + __termios_p->c_cc[VMIN] = 255; // Minimum number of characters to read. + __termios_p->c_cc[VTIME] = (cc_t)(timeouts.ReadIntervalTimeout/100); // Time to wait for every character read in tenths of seconds. + } + else + { + // Not sure what to do... + + // Read with timeout. + if (timeouts.ReadTotalTimeoutConstant/100 > 255) + { + errno = EINVAL; + return -1; + } + __termios_p->c_cc[VMIN] = 0; // Minimum number of characters to read. + __termios_p->c_cc[VTIME] = (cc_t)(timeouts.ReadTotalTimeoutConstant/100); // Time to wait for every character read in tenths of seconds. + } +//#pragma endregion + +//#pragma region DCB + memset(&dcb, 0, sizeof(DCB)); + if (!GetCommState(hDev, &dcb)) + { + errno = EIO; + return -1; + } + + speed = _windowsbaudrate2linux(dcb.BaudRate); + __termios_p->c_ispeed = speed; + __termios_p->c_ospeed = speed; + + switch (dcb.Parity) + { + case NOPARITY : + __termios_p->c_cflag &= ~CMSPAR; + __termios_p->c_cflag &= ~PARENB; + __termios_p->c_cflag &= ~PARODD; + break; + case MARKPARITY : + __termios_p->c_cflag |= CMSPAR; + __termios_p->c_cflag &= ~PARENB; + __termios_p->c_cflag |= PARODD; + break; + case SPACEPARITY : + __termios_p->c_cflag |= CMSPAR; + __termios_p->c_cflag &= ~PARENB; + __termios_p->c_cflag &= ~PARODD; + break; + case ODDPARITY : + __termios_p->c_cflag &= ~CMSPAR; + __termios_p->c_cflag |= PARENB; + __termios_p->c_cflag |= PARODD; + break; + case EVENPARITY : + __termios_p->c_cflag &= ~CMSPAR; + __termios_p->c_cflag |= PARENB; + __termios_p->c_cflag &= ~PARODD; + break; + default : + errno = EINVAL; + return -1; + } + + if (dcb.fParity) + { + __termios_p->c_iflag |= INPCK; + } + else + { + __termios_p->c_iflag &= ~INPCK; + } + + if (!dcb.fErrorChar) + { + __termios_p->c_iflag |= IGNPAR; // A character with a framing or parity error will be discarded. + // This is only valid (at least for parity errors) if parity checking is enabled. + } + else + { + __termios_p->c_iflag &= ~IGNPAR; + } + + if (dcb.ErrorChar == 0) + { + __termios_p->c_iflag &= ~PARMRK; // Never mark a framing or parity error with prefix bytes. + } + else + { + __termios_p->c_iflag |= PARMRK; + } + + __termios_p->c_cflag &= ~CSIZE; // Erase the previous flag for the number of data bits. + + switch (dcb.ByteSize) + { + case 8: + __termios_p->c_cflag |= CS8; + break; + case 7: + __termios_p->c_cflag |= CS7; + break; + case 6: + __termios_p->c_cflag |= CS6; + break; + case 5: + __termios_p->c_cflag |= CS5; + break; + default : + errno = EINVAL; + return -1; + } + + switch (dcb.StopBits) + { + case ONESTOPBIT: + __termios_p->c_cflag &= ~CSTOPB; + break; + case TWOSTOPBITS: + __termios_p->c_cflag |= CSTOPB; + break; + default : + errno = EINVAL; + return -1; + } + + // Binary mode. + if (dcb.fBinary) + { + // The c_cflag member contains two options that should always be enabled, + // CLOCAL and CREAD. These will ensure that your program does not become + // the 'owner' of the port subject to sporatic job control and hangup signals, and + // also that the serial interface driver will read incoming data bytes. + __termios_p->c_cflag |= (CLOCAL | CREAD); + + // Raw input, no echo, no signals. + __termios_p->c_lflag &= ~(ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHONL | ISIG); + + // Raw input. + __termios_p->c_iflag &= ~(IGNBRK | BRKINT | INLCR | IGNCR | ICRNL); + + // Raw output. + __termios_p->c_oflag &= ~(OPOST | ONLCR | ONOCR | ONLRET | OCRNL); + } + else + { + // What should be done...? + + // The c_cflag member contains two options that should always be enabled, + // CLOCAL and CREAD. These will ensure that your program does not become + // the 'owner' of the port subject to sporatic job control and hangup signals, and + // also that the serial interface driver will read incoming data bytes. + __termios_p->c_cflag |= (CLOCAL | CREAD); + + __termios_p->c_lflag |= ICANON; + } + + // Software flow control. + if (!(dcb.fOutX||dcb.fInX)) + { + __termios_p->c_iflag &= ~(IXON | IXOFF | IXANY); + } + else + { + __termios_p->c_iflag |= (IXON | IXOFF); + } + + __termios_p->c_cc[VSTART] = dcb.XonChar; + __termios_p->c_cc[VSTOP] = dcb.XoffChar; + __termios_p->c_cc[VEOF] = dcb.EofChar; + + // Hardware flow control. + if (!dcb.fOutxCtsFlow) + { +#ifdef CRTSCTS + __termios_p->c_cflag &= ~CRTSCTS; +#endif // CRTSCTS +#ifdef CNEW_RTSCTS + __termios_p->c_cflag &= ~CNEW_RTSCTS; +#endif // CNEW_RTSCTS + } + else + { +#ifdef CRTSCTS + __termios_p->c_cflag |= CRTSCTS; +#endif // CRTSCTS +#ifdef CNEW_RTSCTS + __termios_p->c_cflag |= CNEW_RTSCTS; +#endif // CNEW_RTSCTS + } + + // The most likely scenario where this flag is useful is if the communication channel is + // configured for parity and seven bits per character. In this case, the eigth bit on every + // received character is a parity bit, not part of the data payload. The user program does + // not need to know the value of the parity bit. + __termios_p->c_iflag &= ~ISTRIP; +//#pragma endregion + + return 0; +} + +/* Set the state of FD to *TERMIOS_P. + Values for OPTIONAL_ACTIONS (TCSA*) are in . */ +__inline int tcsetattr(int __fd, int __optional_actions, const struct termios *__termios_p) +{ + HANDLE hDev = (HANDLE)(intptr_t)__fd; + COMMTIMEOUTS timeouts; +#ifdef ENABLE_O_NDELAY_WORKAROUND + DWORD ReadIntervalTimeout = 0, ReadTotalTimeoutConstant = 0, ReadTotalTimeoutMultiplier = 0, WriteTotalTimeoutConstant = 0; +#endif // ENABLE_O_NDELAY_WORKAROUND + DCB dcb; + + UNREFERENCED_PARAMETER(__optional_actions); + +//#pragma region TIMEOUTS + memset(&timeouts, 0, sizeof(COMMTIMEOUTS)); + if (!GetCommTimeouts(hDev, &timeouts)) + { + errno = EIO; + return -1; + } + + if ((__termios_p->c_cc[VMIN] == 0)&&(__termios_p->c_cc[VTIME]) == 0) + { + // Polling read. + timeouts.ReadIntervalTimeout = MAXDWORD; timeouts.ReadTotalTimeoutConstant = 0; timeouts.ReadTotalTimeoutMultiplier = 0; + timeouts.WriteTotalTimeoutConstant = 1; // ??? + } + else if ((__termios_p->c_cc[VMIN] == 1)&&(__termios_p->c_cc[VTIME]) == 0) + { + // Blocking read. + timeouts.ReadIntervalTimeout = 0; timeouts.ReadTotalTimeoutConstant = 0; timeouts.ReadTotalTimeoutMultiplier = 0; + timeouts.WriteTotalTimeoutConstant = 0; // ??? + } + else if ((__termios_p->c_cc[VMIN] == 0)&&(__termios_p->c_cc[VTIME]) > 0) + { + // Read with timeout. + if (__termios_p->c_cc[VTIME]*100 > MAXDWORD) + { + errno = EINVAL; + return -1; + } + timeouts.ReadIntervalTimeout = MAXDWORD; timeouts.ReadTotalTimeoutConstant = __termios_p->c_cc[VTIME]*100; timeouts.ReadTotalTimeoutMultiplier = MAXDWORD; + timeouts.WriteTotalTimeoutConstant = __termios_p->c_cc[VTIME]*100; // ??? + } + else if ((__termios_p->c_cc[VMIN] == 255)&&(__termios_p->c_cc[VTIME]) > 0) + { + // Should be approximately equivalent... + + // Read with interbyte timeout. + if (__termios_p->c_cc[VTIME]*100 > MAXDWORD) + { + errno = EINVAL; + return -1; + } + timeouts.ReadIntervalTimeout = __termios_p->c_cc[VTIME]*100; timeouts.ReadTotalTimeoutConstant = 0; timeouts.ReadTotalTimeoutMultiplier = 0; + timeouts.WriteTotalTimeoutConstant = 0; // ??? + } + else + { + // Not sure what to do... + + // Read with interbyte timeout. + if (__termios_p->c_cc[VTIME]*100 > MAXDWORD) + { + errno = EINVAL; + return -1; + } + timeouts.ReadIntervalTimeout = __termios_p->c_cc[VTIME]*100; timeouts.ReadTotalTimeoutConstant = 0; timeouts.ReadTotalTimeoutMultiplier = 0; + timeouts.WriteTotalTimeoutConstant = 0; // ??? + } + + // Disable if XON/XOFF are necessary, enable if fcntl() is used together with O_NDELAY and timeouts... +#ifdef ENABLE_O_NDELAY_WORKAROUND + // Need to save the original timeouts settings for next calls of fcntl()... + + memset(&dcb, 0, sizeof(DCB)); + if (!GetCommState(hDev, &dcb)) + { + errno = EIO; + return -1; + } + + // Warning : XoffLim and XonLim are just used as placeholders to save the original timeouts settings, + // they are not normally related to timeouts... + + ReadIntervalTimeout = timeouts.ReadIntervalTimeout; + ReadTotalTimeoutConstant = timeouts.ReadTotalTimeoutConstant; + ReadTotalTimeoutMultiplier = timeouts.ReadTotalTimeoutMultiplier; + WriteTotalTimeoutConstant = timeouts.WriteTotalTimeoutConstant; + if (ReadIntervalTimeout == MAXDWORD) ReadIntervalTimeout = 255*100; + else if (ReadIntervalTimeout/100 > 254) ReadIntervalTimeout = 254*100; + if (ReadTotalTimeoutConstant == MAXDWORD) ReadTotalTimeoutConstant = 255*100; + else if (ReadTotalTimeoutConstant/100 > 254) ReadTotalTimeoutConstant = 254*100; + if (ReadTotalTimeoutMultiplier == MAXDWORD) ReadTotalTimeoutMultiplier = 255*100; + else if (ReadTotalTimeoutMultiplier/100 > 254) ReadTotalTimeoutMultiplier = 254*100; + if (WriteTotalTimeoutConstant == MAXDWORD) WriteTotalTimeoutConstant = 255*100; + else if (WriteTotalTimeoutConstant/100 > 254) WriteTotalTimeoutConstant = 254*100; + dcb.XoffLim = (WORD)(((ReadIntervalTimeout/100)<<8)|(ReadTotalTimeoutConstant/100)); + dcb.XonLim = (WORD)(((ReadTotalTimeoutMultiplier/100)<<8)|(WriteTotalTimeoutConstant/100)); + if (!SetCommState(hDev, &dcb)) + { + errno = EIO; + return -1; + } +#endif // ENABLE_O_NDELAY_WORKAROUND + + if (!SetCommTimeouts(hDev, &timeouts)) + { + errno = EIO; + return -1; + } +//#pragma endregion + +//#pragma region DCB + memset(&dcb, 0, sizeof(DCB)); + if (!GetCommState(hDev, &dcb)) + { + errno = EIO; + return -1; + } + + // Not possible to have different c_ispeed and c_ospeed on Windows... + dcb.BaudRate = _linuxbaudrate2windows(__termios_p->c_ispeed); + if (dcb.BaudRate == 0) + { + errno = EINVAL; + return -1; + } + + switch (__termios_p->c_cflag & (CMSPAR | PARENB | PARODD)) + { + case 0: + dcb.Parity = NOPARITY; + break; + case (CMSPAR | PARODD): + dcb.Parity = MARKPARITY; + break; + case (CMSPAR): + dcb.Parity = SPACEPARITY; + break; + case (PARENB | PARODD): + dcb.Parity = ODDPARITY; + break; + case (PARENB): + dcb.Parity = EVENPARITY; + break; + default: + errno = EINVAL; + return -1; + } + + dcb.fParity = (__termios_p->c_iflag & INPCK)? TRUE: FALSE; + + if (__termios_p->c_iflag & IGNPAR) + { + dcb.fErrorChar = FALSE; // Indicates whether bytes received with parity errors are + // replaced with the character specified by the ErrorChar member. + } + else + { + dcb.fErrorChar = TRUE; + } + + if (__termios_p->c_iflag & PARMRK) + { + dcb.ErrorChar = 37; // ? + } + else + { + dcb.ErrorChar = 0; + } + + switch (__termios_p->c_cflag & CSIZE) + { + case CS8: + dcb.ByteSize = 8; + break; + case CS7: + dcb.ByteSize = 7; + break; + case CS6: + dcb.ByteSize = 6; + break; + case CS5: + dcb.ByteSize = 5; + break; + default: + errno = EINVAL; + return -1; + } + + dcb.StopBits = (__termios_p->c_cflag & CSTOPB)? TWOSTOPBITS: ONESTOPBIT; + + // Binary mode. + if (__termios_p->c_lflag & ~ICANON) + { + dcb.fBinary = TRUE; + } + else + { + dcb.fBinary = FALSE; + } + + // Software flow control. + if (!(__termios_p->c_iflag & IXON)||(__termios_p->c_iflag & IXOFF)) + { + dcb.fOutX = FALSE; + dcb.fInX = FALSE; + } + else + { + dcb.fOutX = TRUE; + dcb.fInX = TRUE; + } + + dcb.XonChar = __termios_p->c_cc[VSTART]; + dcb.XoffChar = __termios_p->c_cc[VSTOP]; + dcb.EofChar = __termios_p->c_cc[VEOF]; + +#ifdef CRTSCTS + if (__termios_p->c_cflag & CRTSCTS) + { + dcb.fOutxCtsFlow = TRUE; + dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; + dcb.fOutxDsrFlow = TRUE; + //dcb.fDsrSensitivity = FALSE; + } + else + { + dcb.fOutxCtsFlow = FALSE; + dcb.fRtsControl = RTS_CONTROL_DISABLE; + dcb.fOutxDsrFlow = FALSE; + //dcb.fDsrSensitivity = FALSE; + } +#endif // CRTSCTS +#ifdef CNEW_RTSCTS + if (__termios_p->c_cflag & CNEW_RTSCTS) + { + dcb.fOutxCtsFlow = TRUE; + dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; + dcb.fOutxDsrFlow = TRUE; + //dcb.fDsrSensitivity = FALSE; + } + else + { + dcb.fOutxCtsFlow = FALSE; + dcb.fRtsControl = RTS_CONTROL_DISABLE; + dcb.fOutxDsrFlow = FALSE; + //dcb.fDsrSensitivity = FALSE; + } +#endif // CNEW_RTSCTS + + // Miscellaneous default options. + //dcb.fDtrControl = DTR_CONTROL_DISABLE; + //dcb.fAbortOnError = FALSE; + + // The SetCommState() function reconfigures the communications resource, but it does not affect + // the internal output and input buffers of the specified driver. The buffers are not flushed, + // and pending read and write operations are not terminated prematurely. + if (!SetCommState(hDev, &dcb)) + { + errno = EIO; + return -1; + } +//#pragma endregion + + return 0; +} + +#ifdef __USE_MISC +__inline void cfmakeraw(struct termios *__termios_p) +{ + __termios_p->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); + __termios_p->c_oflag &= ~OPOST; + __termios_p->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); + __termios_p->c_cflag &= ~(CSIZE | PARENB); + __termios_p->c_cflag |= CS8; +} +#endif + +#endif // _TERMIOS_H diff --git a/extern/include/unistd_extra.h b/extern/include/unistd_extra.h new file mode 100644 index 00000000..fee60dfd --- /dev/null +++ b/extern/include/unistd_extra.h @@ -0,0 +1,100 @@ +//#ifdef __MINGW32__ +// +//# include_next +// +//#else + +#ifndef UNISTD_EXTRA_H +#define UNISTD_EXTRA_H + +/* +This file intended to serve as a drop-in replacement for unistd.h on Windows. +Please add/remove functionality as neeeded. + +See http://pubs.opengroup.org/onlinepubs/7908799/xsh/unistd.h.html. +*/ + +#include +#include +#include +//#include // getopt from: http://www.pwilson.net/sample.html. +// To get Sleep(). +//#include + +// Prevent Winsock.h from being included by the Windows.h header. +// This must be done if we plan to include Winsock2.h in other files. +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif // WIN32_LEAN_AND_MEAN +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include + +#include + +#include + +//#define srandom srand +//#define random rand + +//const W_OK = 2; +//const R_OK = 4; + +//#define access _access +//#define ftruncate _chsize + +#ifndef _SSIZE_T_ +#ifndef ssize_t +#define ssize_t long +#endif // ssize_t +#endif // _SSIZE_T_ + + +__inline ssize_t read_linux(int __fd, void* __buf, size_t __nbytes) +{ + HANDLE hDev = (HANDLE)(intptr_t)__fd; + DWORD readBytes = 0; + + if (!ReadFile(hDev, __buf, (DWORD)__nbytes, &readBytes, NULL)) + { + // To be improved by checking GetLastError()... + errno = EIO; + return -1; + } + + return (ssize_t)readBytes; +} + +__inline ssize_t write_linux(int __fd, const void* __buf, size_t __nbytes) +{ + HANDLE hDev = (HANDLE)(intptr_t)__fd; + DWORD writtenBytes = 0; + + if (!WriteFile(hDev, __buf, (DWORD)__nbytes, &writtenBytes, NULL)) + { + // To be improved by checking GetLastError()... + errno = EIO; + return -1; + } + + return (ssize_t)writtenBytes; +} + +__inline int close_linux(int __fd) +{ + HANDLE hDev = (HANDLE)(intptr_t)__fd; + + if (!CloseHandle(hDev)) + { + // To be improved by checking GetLastError()... + errno = EIO; + return -1; + } + + return 0; +} + +#endif // UNISTD_EXTRA_H + +//#endif // __MINGW32__ diff --git a/extern/include/websocketpp b/extern/include/websocketpp new file mode 160000 index 00000000..1b11fd30 --- /dev/null +++ b/extern/include/websocketpp @@ -0,0 +1 @@ +Subproject commit 1b11fd301531e6df35a6107c1e8665b1e77a2d8e diff --git a/extern/lib/libjack64.lib b/extern/lib/libjack64.lib new file mode 100644 index 00000000..7fdbcb7d Binary files /dev/null and b/extern/lib/libjack64.lib differ diff --git a/extern/lib/libjackserver64.lib b/extern/lib/libjackserver64.lib new file mode 100644 index 00000000..d8385c24 Binary files /dev/null and b/extern/lib/libjackserver64.lib differ diff --git a/generate_config.h.in b/generate_config.h.in new file mode 100644 index 00000000..31fde76e --- /dev/null +++ b/generate_config.h.in @@ -0,0 +1,68 @@ +/* CMake generates src/config.h from this.*/ + + +/* graphical user interface (using Qt) */ +#cmakedefine ENABLE_GUI + +/* separate control window */ +#cmakedefine ENABLE_FLOATING_CONTROL_PANEL + +/* Ecasound soundfile playback/recording */ +#cmakedefine ENABLE_ECASOUND + +/* XML network (TCP/IP) interface : LEGACY*/ +#cmakedefine ENABLE_IP_INTERFACE + +/* Websocket++ network (TCP/IP) interface : WEBSOCKET*/ +#cmakedefine ENABLE_WEBSOCKET_INTERFACE + +/* Razor AHRS tracker support */ +#cmakedefine ENABLE_RAZOR + +/* Polhemus Fastrak/Patriot tracker support */ +#cmakedefine ENABLE_POLHEMUS + +/* VRPN head tracker support */ +#cmakedefine ENABLE_VRPN + +/* INTERSENSE tracker support */ +#cmakedefine ENABLE_INTERSENSE + +/* SOFA file support */ +#cmakedefine ENABLE_SOFA + +/*?? support for isatty() ??*/ +#define ENABLE_ISATTY 1 + +/* Name of package */ +#define PACKAGE "ssr" + +/* Version number of package */ +#define VERSION "@SSR_VERSION@" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "ssr@spatialaudio.net" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "SSR (SoundScape Renderer)" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "@SSR_VERSION@" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "SSR (SoundScape Renderer) @SSR_VERSION@" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "ssr" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "http://spatialaudio.net/ssr/" + +/* List of SSR authors */ +#define SSR_AUTHORS "Written by:\n Matthias Geier, Jens Ahrens\nScientific supervision:\n Sascha Spors\nContributions by:\n Peter Bartz, Florian Hinterleitner, Torben Hohn,\n Christoph Hohnerlein, Christoph Hold, Lukas Kaser, \n André Möhl, Till Rettberg, David Runge, Fiete Winter, \n IOhannes m zmölnig \nGUI design:\n Katharina Bredies, Jonas Loh, Jens Ahrens\nLogo design:\n Fabian Hemmert" + +/* List of SSR authors (with Qt markup) */ +#define SSR_AUTHORS_QT "The SSR Authors." + +/* SSR copyright notice */ +#define SSR_COPYRIGHT "Copyright © 2016 Division of Applied Acoustics, Chalmers University of Technology\nCopyright © 2014 Institut für Nachrichtentechnik, Universität Rostock\nCopyright © 2012 Quality & Usability Lab, Telekom Innovation Laboratories, TU Berlin\n\nLicense GPLv3+: GNU GPL version 3 or later \nThis is free software: you are free to change and redistribute it.\nThere is NO WARRANTY, to the extent permitted by law." diff --git a/src/gui/qgui.h b/src/gui/qgui.h index e4f1dccb..fd6a49d4 100644 --- a/src/gui/qgui.h +++ b/src/gui/qgui.h @@ -33,6 +33,12 @@ #include #include #include +#ifdef _WIN32 +#ifdef STATIC_QT +#include +Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin) // for static build +#endif // STATIC_QT +#endif // _WIN32 #include "quserinterface.h" #include "scene.h" diff --git a/src/razor-ahrs/RazorAHRS.h b/src/razor-ahrs/RazorAHRS.h index 5a59d021..8f314189 100644 --- a/src/razor-ahrs/RazorAHRS.h +++ b/src/razor-ahrs/RazorAHRS.h @@ -24,7 +24,20 @@ #include #include // for write(), close(), ... #include // for speed_t, cfsetispeed(), ... +#ifdef _WIN32 +#include // for open(), ... +#include // for write(), close(), ... + +// Since open(), close(), read(), write() functions already exist on Windows but with a +// limited compatibility with Linux, we need to replace them with other versions... +#define open open_linux +#define close close_linux +#define read read_linux +#define write write_linux +#else #include // for open(), ... +#include // for write(), close(), ... +#endif // _WIN32 #include #include diff --git a/src/trackerpolhemus.cpp b/src/trackerpolhemus.cpp index c2bb060d..c865ae1f 100644 --- a/src/trackerpolhemus.cpp +++ b/src/trackerpolhemus.cpp @@ -29,12 +29,28 @@ #include // for write(), fsync(), close(), ... #include // for cfsetispeed(), ... -#include // for open(), ... #include // for std::stringstream -#include // for poll(), pollfd, ... #include // for assert() #include // std::chrono::milliseconds +#ifndef _WIN32 +#include // for open(), ... +#include // for poll(), pollfd, ... +#else +#include // for open(), ... +// Since open(), close(), read(), write() functions already exist on Windows but with a +// limited compatibility with Linux, we need to replace them with other versions... +#define open open_linux + +// Prevent Winsock.h from being included by the Windows.h header. +// This must be done if we plan to include Winsock2.h in other files. +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif // WIN32_LEAN_AND_MEAN +#include +#include +#endif // !_WIN32 + #include "api.h" // for Publisher #include "legacy_orientation.h" // for Orientation #include "trackerpolhemus.h" @@ -134,7 +150,11 @@ ssr::TrackerPolhemus::TrackerPolhemus(api::Publisher& controller assert(false); } + #ifndef _WIN32 fsync(_tracker_port); + #else + FlushFileBuffers(&_tracker_port); + #endif _start(); @@ -232,7 +252,11 @@ ssr::TrackerPolhemus::_thread() while (c != '\n') { + #ifndef _WIN32 error = poll(&fds, 1, 100); + #else + error = WSAPoll(&fds, 1, 100); + #endif if (error < 1) {