diff --git a/Makefile b/Makefile index 5853e3f..58178c5 100644 --- a/Makefile +++ b/Makefile @@ -79,7 +79,7 @@ PAWPAW_PREFIX = $(PAWPAW_DIR)/targets/$(PAWPAW_TARGET)$(PAWPAW_SUFFIX) # --------------------------------------------------------------------------------------------------------------------- # List of files created by PawPaw bootstrap, to ensure we have run it at least once -BOOTSTRAP_FILES = $(PAWPAW_PREFIX)/bin/cxfreeze +BOOTSTRAP_FILES = $(PAWPAW_PREFIX)/bin/cxfreeze-quickstart BOOTSTRAP_FILES += $(PAWPAW_PREFIX)/bin/jackd$(APP_EXT) BOOTSTRAP_FILES += $(PAWPAW_PREFIX)/include/armadillo @@ -144,6 +144,7 @@ TARGETS += build/pedalboards TARGETS += build/VERSION ifeq ($(WINDOWS),true) TARGETS += build/jack/jack_dummy.dll +TARGETS += build/jack/jack_desktop.dll TARGETS += build/jack/jack_portaudio.dll TARGETS += build/jack/jack_winmme.dll TARGETS += build/libjack64.dll @@ -276,10 +277,13 @@ TARGETS += $(foreach PLUGIN,$(PLUGINS),$(call PLUGIN_STAMP,$(PLUGIN))) # --------------------------------------------------------------------------------------------------------------------- all: $(TARGETS) + $(MAKE) -C src/plugin clean: + $(MAKE) clean -C src/DPF $(MAKE) clean -C src/mod-host $(MAKE) clean -C src/mod-ui/utils + $(MAKE) clean -C src/plugin $(MAKE) clean -C src/systray rm -rf build rm -rf build-midi-merger @@ -320,6 +324,9 @@ win64-app: win64-bootstrap: ./src/PawPaw/bootstrap-mod.sh win64 +win64-plugin: + ./utils/run.sh win64 $(MAKE) -C src/plugin + win64-plugins: $(MAKE) PAWPAW_TARGET=win64 plugins diff --git a/src/PawPaw b/src/PawPaw index adf8b2a..352e2dd 160000 --- a/src/PawPaw +++ b/src/PawPaw @@ -1 +1 @@ -Subproject commit adf8b2ad4768aed4b6204ee6301739b64faf8896 +Subproject commit 352e2dd43ad0c85f82473dfa5f496c342f46f18a diff --git a/src/plugin/ChildProcess.hpp b/src/plugin/ChildProcess.hpp index 5e6bb5a..ca99278 100644 --- a/src/plugin/ChildProcess.hpp +++ b/src/plugin/ChildProcess.hpp @@ -12,6 +12,9 @@ #endif #ifdef DISTRHO_OS_WINDOWS +# include +# include +# include #else # include # include @@ -27,6 +30,7 @@ START_NAMESPACE_DISTRHO #if defined(DISTRHO_OS_MAC) # define P "/Users/falktx/Source/MOD/mod-app/build/mod-desktop.app/Contents" #elif defined(DISTRHO_OS_WINDOWS) +# define P "Z:\\home\\falktx\\Source\\MOD\\mod-app\\build" #else # define P "/home/falktx/Source/MOD/mod-app/build" #endif @@ -36,6 +40,7 @@ START_NAMESPACE_DISTRHO class ChildProcess { #ifdef _WIN32 + PROCESS_INFORMATION process = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, 0, 0 }; #else pid_t pid = -1; #endif @@ -53,6 +58,13 @@ class ChildProcess bool start(const char* const args[]) { // FIXME + #ifdef DISTRHO_OS_WINDOWS + const CHAR* const envp = ( + "MOD_DATA_DIR=" P "\\data\0" + "MOD_FACTORY_PEDALBOARDS_DIR=" P "\\pedalboards\0" + "LV2_PATH=" P "\\plugins\0" + "\0"); + #else const char* const envp[] = { "MOD_DESKTOP=1", "LANG=en_US.UTF-8", @@ -61,8 +73,7 @@ class ChildProcess "JACK_DRIVER_DIR=" P "/MacOS/jack", "MOD_DATA_DIR=/Users/falktx/Documents/MOD Desktop", "MOD_FACTORY_PEDALBOARDS_DIR=" P "/Resources/pedalboards", - "LV2_PATH=" P "/PlugIns/LV2", // FIXME - #elif defined(DISTRHO_OS_WINDOWS) + "LV2_PATH=" P "/LV2", #else "LD_LIBRARY_PATH=" P, "JACK_DRIVER_DIR=" P "/jack", @@ -72,7 +83,35 @@ class ChildProcess #endif nullptr }; + #endif + #ifdef _WIN32 + std::string cmd; + + for (uint i = 0; args[i] != nullptr; ++i) + { + if (i != 0) + cmd += " "; + + cmd += args[i]; + } + + STARTUPINFOA si = {}; + si.cb = sizeof(si); + + d_stdout("will start process with args '%s'", cmd.data()); + + return CreateProcessA(nullptr, // lpApplicationName + &cmd[0], // lpCommandLine + nullptr, // lpProcessAttributes + nullptr, // lpThreadAttributes + TRUE, // bInheritHandles + 0, // CREATE_NO_WINDOW /*| CREATE_UNICODE_ENVIRONMENT*/, // dwCreationFlags + const_cast(envp), // lpEnvironment + nullptr, // lpCurrentDirectory + &si, // lpStartupInfo + &process) != FALSE; + #else const pid_t ret = pid = vfork(); switch (ret) @@ -92,20 +131,57 @@ class ChildProcess } return ret > 0; + #endif } void stop(const uint32_t timeoutInMilliseconds = 2000) { + const uint32_t timeout = d_gettime_ms() + timeoutInMilliseconds; + bool sendTerminate = true; + + #ifdef _WIN32 + if (process.hProcess == INVALID_HANDLE_VALUE) + return; + + const PROCESS_INFORMATION oprocess = process; + process = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, 0, 0 }; + + for (;;) + { + switch (WaitForSingleObject(oprocess.hProcess, 0)) + { + case WAIT_OBJECT_0: + case WAIT_FAILED: + CloseHandle(oprocess.hThread); + CloseHandle(oprocess.hProcess); + return; + } + + if (sendTerminate) + { + sendTerminate = false; + TerminateProcess(oprocess.hProcess, 15); + } + if (d_gettime_ms() < timeout) + { + d_msleep(5); + continue; + } + d_stderr("ChildProcess::stop() - timed out"); + TerminateProcess(oprocess.hProcess, 9); + d_msleep(5); + CloseHandle(oprocess.hThread); + CloseHandle(oprocess.hProcess); + break; + } + #else if (pid <= 0) return; - const uint32_t timeout = d_gettime_ms() + timeoutInMilliseconds; const pid_t opid = pid; - pid_t ret; - bool sendTerminate = true; pid = -1; - for (;;) + for (pid_t ret;;) { try { ret = ::waitpid(opid, nullptr, WNOHANG); @@ -130,16 +206,17 @@ class ChildProcess if (sendTerminate) { sendTerminate = false; - ::kill(opid, SIGTERM); + kill(opid, SIGTERM); } if (d_gettime_ms() < timeout) { d_msleep(5); continue; } + d_stderr("ChildProcess::stop() - timed out"); - ::kill(opid, SIGKILL); - ::waitpid(opid, nullptr, WNOHANG); + kill(opid, SIGKILL); + waitpid(opid, nullptr, WNOHANG); break; default: @@ -157,6 +234,7 @@ class ChildProcess break; } + #endif } DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ChildProcess) diff --git a/src/plugin/DesktopAudioDriver.cpp b/src/plugin/DesktopAudioDriver.cpp index 1e24460..7443ddf 100644 --- a/src/plugin/DesktopAudioDriver.cpp +++ b/src/plugin/DesktopAudioDriver.cpp @@ -4,6 +4,8 @@ #include "JackAudioDriver.h" #include "JackDriverLoader.h" #include "JackEngineControl.h" +#include "JackLockedEngine.h" +#include "JackMidiPort.h" #include "JackTools.h" #ifdef _WIN32 @@ -53,7 +55,9 @@ class DesktopAudioDriver : public JackAudioDriver Data* fShmData; - #ifndef _WIN32 + #ifdef _WIN32 + HANDLE fShm; + #else int fShmFd; #endif @@ -75,19 +79,20 @@ class DesktopAudioDriver : public JackAudioDriver #elif defined(_WIN32) void post() { + ReleaseSemaphore(fShmData->sem2, 1, nullptr); } bool wait() { - return false; + return WaitForSingleObject(fShmData->sem1, 1000) == WAIT_OBJECT_0; } #else void post() { - const bool unlocked = __sync_bool_compare_and_swap(&data->sem2, 0, 1); + const bool unlocked = __sync_bool_compare_and_swap(&fShmData->sem2, 0, 1); if (! unlocked) return; - ::syscall(__NR_futex, &data->sem2, FUTEX_WAKE, 1, nullptr, nullptr, 0); + ::syscall(__NR_futex, &fShmData->sem2, FUTEX_WAKE, 1, nullptr, nullptr, 0); } bool wait() @@ -96,10 +101,10 @@ class DesktopAudioDriver : public JackAudioDriver for (;;) { - if (__sync_bool_compare_and_swap(&data->sem1, 1, 0)) + if (__sync_bool_compare_and_swap(&fShmData->sem1, 1, 0)) return true; - if (::syscall(__NR_futex, &data->sem1, FUTEX_WAIT, 0, &timeout, nullptr, 0) != 0) + if (::syscall(__NR_futex, &fShmData->sem1, FUTEX_WAIT, 0, &timeout, nullptr, 0) != 0) if (errno != EAGAIN && errno != EINTR) return false; } @@ -107,6 +112,8 @@ class DesktopAudioDriver : public JackAudioDriver #endif jack_native_thread_t fProcessThread; + int fCaptureMidiPort; + int fPlaybackMidiPort; bool fIsProcessing, fIsRunning; static void* on_process(void* const arg) @@ -136,13 +143,16 @@ class DesktopAudioDriver : public JackAudioDriver } public: - DesktopAudioDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) : JackAudioDriver(name, alias, engine, table), fShmData(nullptr), - #ifndef _WIN32 + #ifdef _WIN32 + fShm(nullptr), + #else fShmFd(-1), #endif + fCaptureMidiPort(0), + fPlaybackMidiPort(0), fIsProcessing(false), fIsRunning(false) { @@ -172,8 +182,27 @@ class DesktopAudioDriver : public JackAudioDriver return -1; } - #ifdef _WIN32 - #else + void* ptr; + + #ifdef _WIN32 + fShm = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, "/mod-desktop-test1"); + if (fShm == nullptr) + { + Close(); + jack_error("Can't open default MOD Desktop driver 1"); + return -1; + } + + ptr = MapViewOfFile(fShm, FILE_MAP_ALL_ACCESS, 0, 0, kDataSize); + if (ptr == nullptr) + { + Close(); + jack_error("Can't open default MOD Desktop driver 2"); + return -1; + } + + VirtualLock(ptr, kDataSize); + #else fShmFd = shm_open("/mod-desktop-test1", O_RDWR, 0); if (fShmFd < 0) { @@ -182,8 +211,6 @@ class DesktopAudioDriver : public JackAudioDriver return -1; } - void* ptr; - #ifdef MAP_LOCKED ptr = mmap(nullptr, kDataSize, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_LOCKED, fShmFd, 0); if (ptr == nullptr || ptr == MAP_FAILED) @@ -202,9 +229,9 @@ class DesktopAudioDriver : public JackAudioDriver #ifndef MAP_LOCKED mlock(ptr, kDataSize); #endif + #endif fShmData = static_cast(ptr); - #endif if (fShmData->magic != 1337) { @@ -235,6 +262,32 @@ class DesktopAudioDriver : public JackAudioDriver } #endif + jack_port_id_t port_index; + JackPort* port; + if (fEngine->PortRegister(fClientControl.fRefNum, "system:midi_capture_1", JACK_DEFAULT_MIDI_TYPE, + CaptureDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) + { + Close(); + jack_error("Can't open default MOD Desktop driver 6"); + return -1; + } + fCaptureMidiPort = port_index; + port = fGraphManager->GetPort(port_index); + port->SetAlias("MOD Desktop MIDI Capture"); + + if (fEngine->PortRegister(fClientControl.fRefNum, "system:midi_playback_1", JACK_DEFAULT_MIDI_TYPE, + PlaybackDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) + { + { + Close(); + jack_error("Can't open default MOD Desktop driver 7"); + return -1; + } + } + fPlaybackMidiPort = port_index; + port = fGraphManager->GetPort(port_index); + port->SetAlias("MOD Desktop MIDI Playback"); + return 0; } @@ -258,10 +311,21 @@ class DesktopAudioDriver : public JackAudioDriver #endif #ifdef _WIN32 + if (fShmData != nullptr) + { + UnmapViewOfFile(fShmData); + fShmData = nullptr; + } + + if (fShm != nullptr) + { + CloseHandle(fShm); + fShm = nullptr; + } #else if (fShmData != nullptr) { - ::munmap(fShmData, kDataSize); + munmap(fShmData, kDataSize); fShmData = nullptr; } @@ -292,7 +356,7 @@ class DesktopAudioDriver : public JackAudioDriver #endif fIsProcessing = fIsRunning = true; - return JackPosixThread::StartImp(&fProcessThread, 0, 0, on_process, this); + return JackThread::StartImp(&fProcessThread, 80, 1, on_process, this); } int Stop() override @@ -303,7 +367,7 @@ class DesktopAudioDriver : public JackAudioDriver if (fIsRunning) { fIsRunning = false; - JackPosixThread::StopImp(fProcessThread); + JackThread::StopImp(fProcessThread); } return JackAudioDriver::Stop(); @@ -311,15 +375,37 @@ class DesktopAudioDriver : public JackAudioDriver int Read() override { - memcpy(GetInputBuffer(0), fShmData->audio, sizeof(float) * 128); - memcpy(GetInputBuffer(1), fShmData->audio + 128, sizeof(float) * 128); + memcpy(GetInputBuffer(0), fShmData->audio, sizeof(float) * fEngineControl->fBufferSize); + memcpy(GetInputBuffer(1), fShmData->audio + fEngineControl->fBufferSize, sizeof(float) * fEngineControl->fBufferSize); + + JackMidiBuffer* cbuf = (JackMidiBuffer*)fGraphManager->GetBuffer(fCaptureMidiPort, fEngineControl->fBufferSize); + JackMidiBuffer* pbuf = (JackMidiBuffer*)fGraphManager->GetBuffer(fPlaybackMidiPort, fEngineControl->fBufferSize); + pbuf->Reset(fEngineControl->fBufferSize); + + for (uint16_t i = 0; i < fShmData->midiEventCount; ++i) + { + if (jack_midi_data_t* const data = pbuf->ReserveEvent(fShmData->midiFrames[i], 4)) + { + memcpy(data, fShmData->midiData + (i * 4), 4); + continue; + } + + break; + } + return 0; } int Write() override { - memcpy(fShmData->audio, GetOutputBuffer(0), sizeof(float) * 128); - memcpy(fShmData->audio + 128, GetOutputBuffer(1), sizeof(float) * 128); + memcpy(fShmData->audio, GetOutputBuffer(0), sizeof(float) * fEngineControl->fBufferSize); + memcpy(fShmData->audio + fEngineControl->fBufferSize, GetOutputBuffer(1), sizeof(float) * fEngineControl->fBufferSize); + + JackMidiBuffer* cbuf = (JackMidiBuffer*)fGraphManager->GetBuffer(fCaptureMidiPort, fEngineControl->fBufferSize); + cbuf->Reset(fEngineControl->fBufferSize); + + fShmData->midiEventCount = 0; + return 0; } diff --git a/src/plugin/DesktopPlugin.cpp b/src/plugin/DesktopPlugin.cpp index 2702da2..f193c6b 100644 --- a/src/plugin/DesktopPlugin.cpp +++ b/src/plugin/DesktopPlugin.cpp @@ -20,7 +20,6 @@ class DesktopPlugin : public Plugin bool processing = false; bool firstTimeProcessing = true; float parameters[24] = {}; - float* shmBuffers[2] = {}; float* tmpBuffers[2] = {}; uint32_t numFramesInShmBuffer = 0; uint32_t numFramesInTmpBuffer = 0; @@ -36,14 +35,18 @@ class DesktopPlugin : public Plugin const char* const jackd_args[] = { #if defined(DISTRHO_OS_MAC) P "/MacOS/jackd", + #elif defined(DISTRHO_OS_WINDOWS) + P "\\jackd.exe", #else P "/jackd", #endif "-R", "-S", "-n", "mod-desktop", "-C", - #ifdef DISTRHO_OS_MAC + #if defined(DISTRHO_OS_MAC) P "/MacOS/jack/jack-session.conf", + #elif defined(DISTRHO_OS_WINDOWS) + P "\\jack\\jack-session.conf", #else P "/jack/jack-session.conf", #endif @@ -52,6 +55,8 @@ class DesktopPlugin : public Plugin const char* const mod_ui_args[] = { #if defined(DISTRHO_OS_MAC) P "/MacOS/mod-ui", + #elif defined(DISTRHO_OS_WINDOWS) + P "\\mod-ui.exe", #else P "/mod-ui", #endif @@ -61,7 +66,6 @@ class DesktopPlugin : public Plugin if (shm.init() && jackd.start(jackd_args)) { processing = true; - shm.getAudioData(shmBuffers); bufferSizeChanged(getBufferSize()); d_msleep(500); @@ -215,7 +219,8 @@ class DesktopPlugin : public Plugin /** Run/process function for plugins without MIDI input. */ - void run(const float** const inputs, float** const outputs, const uint32_t frames) override + void run(const float** const inputs, float** const outputs, const uint32_t frames, + const MidiEvent* midiEvents, uint32_t midiEventCount) override { if (! processing) { @@ -230,13 +235,43 @@ class DesktopPlugin : public Plugin for (uint32_t i = 0; i < frames; ++i) { - shmBuffers[0][ti] = inputs[0][i]; - shmBuffers[1][ti] = inputs[1][i]; + shm.data->audio[ti] = inputs[0][i]; + shm.data->audio[128 + ti] = inputs[1][i]; if (++ti == 128) { ti = 0; + if (midiEventCount != 0) + { + uint16_t mec = shm.data->midiEventCount; + + while (midiEventCount != 0 && mec != 511) + { + if (midiEvents->size > 4) + { + --midiEventCount; + ++midiEvents; + continue; + } + + if (midiEvents->frame >= i) + break; + + shm.data->midiFrames[mec] = ti + (midiEvents->frame - i); + shm.data->midiData[mec * 4 + 0] = midiEvents->data[0]; + shm.data->midiData[mec * 4 + 1] = midiEvents->data[1]; + shm.data->midiData[mec * 4 + 2] = midiEvents->data[2]; + shm.data->midiData[mec * 4 + 3] = midiEvents->data[3]; + + --midiEventCount; + ++midiEvents; + ++mec; + } + + shm.data->midiEventCount = mec; + } + if (! shm.process(tmpBuffers, to)) { d_stdout("shm processing failed"); @@ -246,6 +281,24 @@ class DesktopPlugin : public Plugin return; } + for (uint16_t j = 0; j < shm.data->midiEventCount; ++j) + { + MidiEvent midiEvent = { + 4, + i + shm.data->midiFrames[j], + { + shm.data->midiData[j * 4 + 0], + shm.data->midiData[j * 4 + 1], + shm.data->midiData[j * 4 + 2], + shm.data->midiData[j * 4 + 3], + }, + nullptr + }; + + if (! writeMidiEvent(midiEvent)) + break; + } + to += 128; if (firstTimeProcessing) @@ -307,14 +360,18 @@ class DesktopPlugin : public Plugin const char* const jackd_args[] = { #if defined(DISTRHO_OS_MAC) P "/MacOS/jackd", + #elif defined(DISTRHO_OS_WINDOWS) + P "\\jackd.exe", #else P "/jackd", #endif "-R", "-S", "-n", "mod-desktop", "-C", - #ifdef DISTRHO_OS_MAC + #if defined(DISTRHO_OS_MAC) P "/MacOS/jack/jack-session.conf", + #elif defined(DISTRHO_OS_WINDOWS) + P "\\jack\\jack-session.conf", #else P "/jack/jack-session.conf", #endif diff --git a/src/plugin/DistrhoPluginInfo.h b/src/plugin/DistrhoPluginInfo.h index 881ed25..3d30431 100644 --- a/src/plugin/DistrhoPluginInfo.h +++ b/src/plugin/DistrhoPluginInfo.h @@ -11,10 +11,12 @@ #define DISTRHO_PLUGIN_BRAND_ID MODa #define DISTRHO_PLUGIN_UNIQUE_ID dskt -#define DISTRHO_PLUGIN_HAS_UI 1 -#define DISTRHO_PLUGIN_IS_RT_SAFE 0 -#define DISTRHO_PLUGIN_NUM_INPUTS 2 -#define DISTRHO_PLUGIN_NUM_OUTPUTS 2 -#define DISTRHO_PLUGIN_WANT_STATE 1 -#define DISTRHO_UI_FILE_BROWSER 0 -#define DISTRHO_UI_USER_RESIZABLE 1 +#define DISTRHO_PLUGIN_HAS_UI 1 +#define DISTRHO_PLUGIN_IS_RT_SAFE 0 +#define DISTRHO_PLUGIN_NUM_INPUTS 2 +#define DISTRHO_PLUGIN_NUM_OUTPUTS 2 +#define DISTRHO_PLUGIN_WANT_MIDI_INPUT 1 +#define DISTRHO_PLUGIN_WANT_MIDI_OUTPUT 1 +#define DISTRHO_PLUGIN_WANT_STATE 1 +#define DISTRHO_UI_FILE_BROWSER 0 +#define DISTRHO_UI_USER_RESIZABLE 1 diff --git a/src/plugin/Makefile b/src/plugin/Makefile index f5a4233..1e252fd 100644 --- a/src/plugin/Makefile +++ b/src/plugin/Makefile @@ -19,8 +19,15 @@ FILES_UI = \ # --------------------------------------------------------------------------------------------------------------------- # Do some magic +DPF_BUILD_DIR = ../../build-plugin/build +DPF_TARGET_DIR = ../../build-plugin + include ../DPF/Makefile.plugins.mk +ifeq ($(WINDOWS),true) +LINK_FLAGS += -lwinmm +endif + all: jack vst2 # --------------------------------------------------------------------------------------------------------------------- diff --git a/src/plugin/SharedMemory.hpp b/src/plugin/SharedMemory.hpp index 177db7e..b9fb413 100644 --- a/src/plugin/SharedMemory.hpp +++ b/src/plugin/SharedMemory.hpp @@ -28,6 +28,26 @@ START_NAMESPACE_DISTRHO class SharedMemory { public: + struct Data { + uint32_t magic; + int32_t padding1; + #if defined(DISTRHO_OS_MAC) + char bootname1[32]; + char bootname2[32]; + #elif defined(DISTRHO_OS_WINDOWS) + HANDLE sem1; + HANDLE sem2; + #else + int32_t sem1; + int32_t sem2; + #endif + uint16_t midiEventCount; + uint16_t midiFrames[511]; + uint8_t midiData[511 * 4]; + uint8_t padding2[4]; + float audio[]; + }* data = nullptr; + SharedMemory() { } @@ -39,42 +59,52 @@ class SharedMemory bool init() { - #ifdef DISTRHO_OS_WINDOWS - #else - fd = shm_open("/mod-desktop-test1", O_CREAT|O_EXCL|O_RDWR, 0600); - DISTRHO_SAFE_ASSERT_RETURN(fd >= 0, false); - + void* ptr; + + #ifdef DISTRHO_OS_WINDOWS + SECURITY_ATTRIBUTES sa = {}; + sa.nLength = sizeof(sa); + sa.bInheritHandle = TRUE; + + shm = CreateFileMappingA(INVALID_HANDLE_VALUE, + &sa, + PAGE_READWRITE|SEC_COMMIT, + 0, + static_cast(kDataSize), + "/mod-desktop-test1"); + DISTRHO_SAFE_ASSERT_RETURN(shm != nullptr, false); + + ptr = MapViewOfFile(shm, FILE_MAP_ALL_ACCESS, 0, 0, kDataSize); + DISTRHO_SAFE_ASSERT_RETURN(ptr != nullptr, fail_deinit()); + + VirtualLock(ptr, kDataSize); + #else + shmfd = shm_open("/mod-desktop-test1", O_CREAT|O_EXCL|O_RDWR, 0600); + DISTRHO_SAFE_ASSERT_RETURN(shmfd >= 0, false); + + DISTRHO_SAFE_ASSERT_RETURN(ftruncate(shmfd, static_cast(kDataSize)) == 0, fail_deinit()); + + #ifdef MAP_LOCKED + ptr = mmap(nullptr, kDataSize, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_LOCKED, shmfd, 0); + if (ptr == nullptr || ptr == MAP_FAILED) + #endif { - const int ret = ftruncate(fd, static_cast(kDataSize)); - DISTRHO_SAFE_ASSERT_RETURN(ret == 0, fail_deinit()); + ptr = mmap(nullptr, kDataSize, PROT_READ|PROT_WRITE, MAP_SHARED, shmfd, 0); } + DISTRHO_SAFE_ASSERT_RETURN(ptr != nullptr, fail_deinit()); + DISTRHO_SAFE_ASSERT_RETURN(ptr != MAP_FAILED, fail_deinit()); - { - void* ptr; - - #ifdef MAP_LOCKED - ptr = mmap(nullptr, kDataSize, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_LOCKED, fd, 0); - if (ptr == nullptr || ptr == MAP_FAILED) - #endif - { - ptr = mmap(nullptr, kDataSize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); - } - - DISTRHO_SAFE_ASSERT_RETURN(ptr != nullptr, fail_deinit()); - DISTRHO_SAFE_ASSERT_RETURN(ptr != MAP_FAILED, fail_deinit()); - - #ifndef MAP_LOCKED - mlock(ptr, kDataSize); - #endif - - data = static_cast(ptr); - } + #ifndef MAP_LOCKED + mlock(ptr, kDataSize); #endif + #endif + + data = static_cast(ptr); std::memset(data, 0, kDataSize); data->magic = 1337; - #ifdef DISTRHO_OS_MAC + #if defined(DISTRHO_OS_MAC) task = mach_task_self(); mach_port_t bootport1, bootport2; @@ -93,6 +123,12 @@ class SharedMemory DISTRHO_SAFE_ASSERT_RETURN(bootstrap_register(bootport1, data->bootname1, sem1) == KERN_SUCCESS, fail_deinit()); DISTRHO_SAFE_ASSERT_RETURN(bootstrap_register(bootport2, data->bootname2, sem2) == KERN_SUCCESS, fail_deinit()); #pragma clang diagnostic pop + #elif defined(DISTRHO_OS_WINDOWS) + data->sem1 = CreateSemaphoreA(&sa, 0, 1, nullptr); + DISTRHO_SAFE_ASSERT_RETURN(data->sem1 != nullptr, fail_deinit()); + + data->sem2 = CreateSemaphoreA(&sa, 0, 1, nullptr); + DISTRHO_SAFE_ASSERT_RETURN(data->sem2 != nullptr, fail_deinit()); #endif return true; @@ -100,7 +136,7 @@ class SharedMemory void deinit() { - #ifdef DISTRHO_OS_MAC + #if defined(DISTRHO_OS_MAC) if (sem1 != MACH_PORT_NULL) { semaphore_destroy(task, sem1); @@ -115,6 +151,29 @@ class SharedMemory #endif #ifdef DISTRHO_OS_WINDOWS + if (data != nullptr) + { + if (data->sem1 != nullptr) + { + CloseHandle(data->sem1); + data->sem1 = nullptr; + } + + if (data->sem2 != nullptr) + { + CloseHandle(data->sem2); + data->sem2 = nullptr; + } + + UnmapViewOfFile(data); + data = nullptr; + } + + if (shm != nullptr) + { + CloseHandle(shm); + shm = nullptr; + } #else if (data != nullptr) { @@ -122,25 +181,17 @@ class SharedMemory data = nullptr; } - if (fd >= 0) + if (shmfd >= 0) { - close(fd); + close(shmfd); shm_unlink("/mod-desktop-test1"); - fd = -1; + shmfd = -1; } #endif } // ---------------------------------------------------------------------------------------------------------------- - void getAudioData(float* audio[2]) - { - DISTRHO_SAFE_ASSERT_RETURN(data != nullptr,); - - audio[0] = data->audio; - audio[1] = data->audio + 128; - } - void reset() { if (data == nullptr) @@ -169,34 +220,15 @@ class SharedMemory // ---------------------------------------------------------------------------------------------------------------- private: - struct Data { - uint32_t magic; - int32_t padding1; - #if defined(DISTRHO_OS_MAC) - char bootname1[32]; - char bootname2[32]; - #elif defined(DISTRHO_OS_WINDOWS) - HANDLE sem1; - HANDLE sem2; - #else - int32_t sem1; - int32_t sem2; - #endif - uint16_t midiEventCount; - uint16_t midiFrames[511]; - uint8_t midiData[511 * 4]; - uint8_t padding2[4]; - float audio[]; - }* data = nullptr; - static constexpr const size_t kDataSize = sizeof(Data) + sizeof(float) * 128 * 2; // ---------------------------------------------------------------------------------------------------------------- // shared memory details #ifdef DISTRHO_OS_WINDOWS + HANDLE shm; #else - int fd = -1; + int shmfd = -1; #endif #ifdef DISTRHO_OS_MAC diff --git a/src/plugin/Time.hpp b/src/plugin/Time.hpp index c1485d0..91a1987 100644 --- a/src/plugin/Time.hpp +++ b/src/plugin/Time.hpp @@ -20,6 +20,8 @@ #include "DistrhoUtils.hpp" #ifdef DISTRHO_OS_WINDOWS +# include +# include # include #else # include