@@ -55,7 +55,7 @@ ALL_LIBS += $(MODULEDIR)/carla_engine_plugin.a | |||||
ALL_LIBS += $(MODULEDIR)/carla_plugin.a | ALL_LIBS += $(MODULEDIR)/carla_plugin.a | ||||
ALL_LIBS += $(MODULEDIR)/jackbridge.a | ALL_LIBS += $(MODULEDIR)/jackbridge.a | ||||
ALL_LIBS += $(MODULEDIR)/native-plugins.a | ALL_LIBS += $(MODULEDIR)/native-plugins.a | ||||
ALL_LIBS += $(MODULEDIR)/juce_core.a | |||||
ALL_LIBS += $(MODULEDIR)/juce_audio_graph.a | |||||
ALL_LIBS += $(MODULEDIR)/lilv.a | ALL_LIBS += $(MODULEDIR)/lilv.a | ||||
ALL_LIBS += $(MODULEDIR)/rtmempool.a | ALL_LIBS += $(MODULEDIR)/rtmempool.a | ||||
@@ -149,7 +149,7 @@ theme: libs | |||||
# Binaries (posix32) | # Binaries (posix32) | ||||
LIBS_POSIX32 = $(MODULEDIR)/jackbridge.posix32.a | LIBS_POSIX32 = $(MODULEDIR)/jackbridge.posix32.a | ||||
LIBS_POSIX32 += $(MODULEDIR)/juce_core.posix32.a | |||||
LIBS_POSIX32 += $(MODULEDIR)/juce_audio_graph.posix32.a | |||||
LIBS_POSIX32 += $(MODULEDIR)/lilv.posix32.a | LIBS_POSIX32 += $(MODULEDIR)/lilv.posix32.a | ||||
LIBS_POSIX32 += $(MODULEDIR)/rtmempool.posix32.a | LIBS_POSIX32 += $(MODULEDIR)/rtmempool.posix32.a | ||||
@@ -161,7 +161,7 @@ posix32: $(LIBS_POSIX32) | |||||
# Binaries (posix64) | # Binaries (posix64) | ||||
LIBS_POSIX64 = $(MODULEDIR)/jackbridge.posix64.a | LIBS_POSIX64 = $(MODULEDIR)/jackbridge.posix64.a | ||||
LIBS_POSIX64 += $(MODULEDIR)/juce_core.posix64.a | |||||
LIBS_POSIX64 += $(MODULEDIR)/juce_audio_graph.posix64.a | |||||
LIBS_POSIX64 += $(MODULEDIR)/lilv.posix64.a | LIBS_POSIX64 += $(MODULEDIR)/lilv.posix64.a | ||||
LIBS_POSIX64 += $(MODULEDIR)/rtmempool.posix64.a | LIBS_POSIX64 += $(MODULEDIR)/rtmempool.posix64.a | ||||
@@ -177,7 +177,7 @@ LIBS_WIN32 = $(MODULEDIR)/jackbridge.win32.a | |||||
else | else | ||||
LIBS_WIN32 = $(MODULEDIR)/jackbridge.win32e.a | LIBS_WIN32 = $(MODULEDIR)/jackbridge.win32e.a | ||||
endif | endif | ||||
LIBS_WIN32 += $(MODULEDIR)/juce_core.win32.a | |||||
LIBS_WIN32 += $(MODULEDIR)/juce_audio_graph.win32.a | |||||
LIBS_WIN32 += $(MODULEDIR)/lilv.win32.a | LIBS_WIN32 += $(MODULEDIR)/lilv.win32.a | ||||
LIBS_WIN32 += $(MODULEDIR)/rtmempool.win32.a | LIBS_WIN32 += $(MODULEDIR)/rtmempool.win32.a | ||||
@@ -193,7 +193,7 @@ LIBS_WIN64 = $(MODULEDIR)/jackbridge.win64.a | |||||
else | else | ||||
LIBS_WIN64 = $(MODULEDIR)/jackbridge.win64e.a | LIBS_WIN64 = $(MODULEDIR)/jackbridge.win64e.a | ||||
endif | endif | ||||
LIBS_WIN64 += $(MODULEDIR)/juce_core.win64.a | |||||
LIBS_WIN64 += $(MODULEDIR)/juce_audio_graph.win64.a | |||||
LIBS_WIN64 += $(MODULEDIR)/lilv.win64.a | LIBS_WIN64 += $(MODULEDIR)/lilv.win64.a | ||||
LIBS_WIN64 += $(MODULEDIR)/rtmempool.win64.a | LIBS_WIN64 += $(MODULEDIR)/rtmempool.win64.a | ||||
@@ -24,7 +24,7 @@ | |||||
struct CarlaOscData; | struct CarlaOscData; | ||||
#endif | #endif | ||||
namespace juce { | |||||
namespace juce2 { | |||||
class MemoryOutputStream; | class MemoryOutputStream; | ||||
class XmlDocument; | class XmlDocument; | ||||
} | } | ||||
@@ -1134,12 +1134,12 @@ protected: | |||||
/*! | /*! | ||||
* Common save project function for main engine and plugin. | * Common save project function for main engine and plugin. | ||||
*/ | */ | ||||
void saveProjectInternal(juce::MemoryOutputStream& outStrm) const; | |||||
void saveProjectInternal(juce2::MemoryOutputStream& outStrm) const; | |||||
/*! | /*! | ||||
* Common load project function for main engine and plugin. | * Common load project function for main engine and plugin. | ||||
*/ | */ | ||||
bool loadProjectInternal(juce::XmlDocument& xmlDoc); | |||||
bool loadProjectInternal(juce2::XmlDocument& xmlDoc); | |||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
@@ -18,7 +18,7 @@ | |||||
#include "CarlaHost.h" | #include "CarlaHost.h" | ||||
#include "CarlaString.hpp" | #include "CarlaString.hpp" | ||||
#include "juce_core/juce_core.h" | |||||
#include "juce_audio_graph/juce_audio_graph.h" | |||||
namespace CB = CarlaBackend; | namespace CB = CarlaBackend; | ||||
@@ -106,7 +106,7 @@ const char* carla_get_library_filename() | |||||
if (ret.isEmpty()) | if (ret.isEmpty()) | ||||
{ | { | ||||
using namespace juce; | |||||
using namespace juce2; | |||||
ret = File(File::getSpecialLocation(File::currentExecutableFile)).getFullPathName().toRawUTF8(); | ret = File(File::getSpecialLocation(File::currentExecutableFile)).getFullPathName().toRawUTF8(); | ||||
} | } | ||||
@@ -121,7 +121,7 @@ const char* carla_get_library_folder() | |||||
if (ret.isEmpty()) | if (ret.isEmpty()) | ||||
{ | { | ||||
using namespace juce; | |||||
using namespace juce2; | |||||
ret = File(File::getSpecialLocation(File::currentExecutableFile).getParentDirectory()).getFullPathName().toRawUTF8(); | ret = File(File::getSpecialLocation(File::currentExecutableFile).getParentDirectory()).getFullPathName().toRawUTF8(); | ||||
} | } | ||||
@@ -27,13 +27,12 @@ | |||||
#include "CarlaBackendUtils.hpp" | #include "CarlaBackendUtils.hpp" | ||||
#include "CarlaBase64Utils.hpp" | #include "CarlaBase64Utils.hpp" | ||||
#ifndef BUILD_BRIDGE | |||||
#ifdef BUILD_BRIDGE | |||||
# include "juce_audio_graph/juce_audio_graph.h" | |||||
#else | |||||
# include "CarlaLogThread.hpp" | # include "CarlaLogThread.hpp" | ||||
#endif | #endif | ||||
#include "AppConfig.h" | |||||
#include "juce_core/juce_core.h" | |||||
namespace CB = CarlaBackend; | namespace CB = CarlaBackend; | ||||
using CB::EngineOptions; | using CB::EngineOptions; | ||||
@@ -145,7 +144,7 @@ static void carla_engine_init_common() | |||||
gStandalone.engine->setFileCallback(gStandalone.fileCallback, gStandalone.fileCallbackPtr); | gStandalone.engine->setFileCallback(gStandalone.fileCallback, gStandalone.fileCallbackPtr); | ||||
#ifdef BUILD_BRIDGE | #ifdef BUILD_BRIDGE | ||||
using juce::File; | |||||
using juce2::File; | |||||
File juceBinaryDir(File::getSpecialLocation(File::currentExecutableFile).getParentDirectory()); | File juceBinaryDir(File::getSpecialLocation(File::currentExecutableFile).getParentDirectory()); | ||||
/* | /* | ||||
@@ -29,8 +29,7 @@ | |||||
#include "CarlaOscUtils.hpp" | #include "CarlaOscUtils.hpp" | ||||
#include "CarlaString.hpp" | #include "CarlaString.hpp" | ||||
#include "AppConfig.h" | |||||
#include "juce_core/juce_core.h" | |||||
#include "juce_audio_graph/juce_audio_graph.h" | |||||
namespace CB = CarlaBackend; | namespace CB = CarlaBackend; | ||||
@@ -268,7 +267,7 @@ protected: | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
using namespace juce; | |||||
using namespace juce2; | |||||
if (carla_is_engine_running()) | if (carla_is_engine_running()) | ||||
carla_engine_close(); | carla_engine_close(); | ||||
@@ -513,7 +513,7 @@ const char* carla_get_supported_file_extensions() | |||||
#if 0 | #if 0 | ||||
// Audio files | // Audio files | ||||
{ | { | ||||
using namespace juce; | |||||
using namespace juce2; | |||||
AudioFormatManager afm; | AudioFormatManager afm; | ||||
afm.registerBasicFormats(); | afm.registerBasicFormats(); | ||||
@@ -553,7 +553,6 @@ void carla_set_process_name(const char* name) | |||||
carla_debug("carla_set_process_name(\"%s\")", name); | carla_debug("carla_set_process_name(\"%s\")", name); | ||||
CarlaThread::setCurrentThreadName(name); | CarlaThread::setCurrentThreadName(name); | ||||
juce::Thread::setCurrentThreadName(name); | |||||
} | } | ||||
// ------------------------------------------------------------------------------------------------------------------- | // ------------------------------------------------------------------------------------------------------------------- | ||||
@@ -694,7 +693,7 @@ const char* carla_get_library_filename() | |||||
if (ret.isEmpty()) | if (ret.isEmpty()) | ||||
{ | { | ||||
using juce::File; | |||||
using juce2::File; | |||||
ret = File(File::getSpecialLocation(File::currentExecutableFile)).getFullPathName().toRawUTF8(); | ret = File(File::getSpecialLocation(File::currentExecutableFile)).getFullPathName().toRawUTF8(); | ||||
} | } | ||||
@@ -709,7 +708,7 @@ const char* carla_get_library_folder() | |||||
if (ret.isEmpty()) | if (ret.isEmpty()) | ||||
{ | { | ||||
using juce::File; | |||||
using juce2::File; | |||||
ret = File(File::getSpecialLocation(File::currentExecutableFile).getParentDirectory()).getFullPathName().toRawUTF8(); | ret = File(File::getSpecialLocation(File::currentExecutableFile).getParentDirectory()).getFullPathName().toRawUTF8(); | ||||
} | } | ||||
@@ -26,7 +26,7 @@ STANDALONE_LIBS = $(MODULEDIR)/carla_engine.a | |||||
STANDALONE_LIBS += $(MODULEDIR)/carla_plugin.a | STANDALONE_LIBS += $(MODULEDIR)/carla_plugin.a | ||||
STANDALONE_LIBS += $(MODULEDIR)/jackbridge.a | STANDALONE_LIBS += $(MODULEDIR)/jackbridge.a | ||||
STANDALONE_LIBS += $(MODULEDIR)/juce_core.a | |||||
STANDALONE_LIBS += $(MODULEDIR)/juce_audio_graph.a | |||||
STANDALONE_LIBS += $(MODULEDIR)/lilv.a | STANDALONE_LIBS += $(MODULEDIR)/lilv.a | ||||
STANDALONE_LIBS += $(MODULEDIR)/native-plugins.a | STANDALONE_LIBS += $(MODULEDIR)/native-plugins.a | ||||
STANDALONE_LIBS += $(MODULEDIR)/rtmempool.a | STANDALONE_LIBS += $(MODULEDIR)/rtmempool.a | ||||
@@ -42,7 +42,7 @@ endif | |||||
STANDALONE_LIBS += $(MODULEDIR)/rtaudio.a | STANDALONE_LIBS += $(MODULEDIR)/rtaudio.a | ||||
STANDALONE_LIBS += $(MODULEDIR)/rtmidi.a | STANDALONE_LIBS += $(MODULEDIR)/rtmidi.a | ||||
UTILS_LIBS += $(MODULEDIR)/juce_core.a | |||||
UTILS_LIBS += $(MODULEDIR)/juce_audio_graph.a | |||||
UTILS_LIBS += $(MODULEDIR)/lilv.a | UTILS_LIBS += $(MODULEDIR)/lilv.a | ||||
# ---------------------------------------------------------------------------------------------------------------------------- | # ---------------------------------------------------------------------------------------------------------------------------- | ||||
@@ -35,18 +35,16 @@ | |||||
#include "jackbridge/JackBridge.hpp" | #include "jackbridge/JackBridge.hpp" | ||||
#include "AppConfig.h" | |||||
#include "juce_core/juce_core.h" | |||||
using juce::Array; | |||||
using juce::CharPointer_UTF8; | |||||
using juce::File; | |||||
using juce::MemoryOutputStream; | |||||
using juce::ScopedPointer; | |||||
using juce::String; | |||||
using juce::StringArray; | |||||
using juce::XmlDocument; | |||||
using juce::XmlElement; | |||||
#include "juce_audio_graph/juce_audio_graph.h" | |||||
using juce2::Array; | |||||
using juce2::CharPointer_UTF8; | |||||
using juce2::File; | |||||
using juce2::MemoryOutputStream; | |||||
using juce2::String; | |||||
using juce2::StringArray; | |||||
using juce2::XmlDocument; | |||||
using juce2::XmlElement; | |||||
CARLA_BACKEND_START_NAMESPACE | CARLA_BACKEND_START_NAMESPACE | ||||
@@ -1674,7 +1672,7 @@ void CarlaEngine::setPluginPeaks(const uint pluginId, float const inPeaks[2], fl | |||||
pluginData.outsPeak[1] = outPeaks[1]; | pluginData.outsPeak[1] = outPeaks[1]; | ||||
} | } | ||||
void CarlaEngine::saveProjectInternal(juce::MemoryOutputStream& outStream) const | |||||
void CarlaEngine::saveProjectInternal(juce2::MemoryOutputStream& outStream) const | |||||
{ | { | ||||
// send initial prepareForSave first, giving time for bridges to act | // send initial prepareForSave first, giving time for bridges to act | ||||
for (uint i=0; i < pData->curPluginCount; ++i) | for (uint i=0; i < pData->curPluginCount; ++i) | ||||
@@ -1876,7 +1874,7 @@ static String findBinaryInCustomPath(const char* const searchPath, const char* c | |||||
return String(); | return String(); | ||||
} | } | ||||
bool CarlaEngine::loadProjectInternal(juce::XmlDocument& xmlDoc) | |||||
bool CarlaEngine::loadProjectInternal(juce2::XmlDocument& xmlDoc) | |||||
{ | { | ||||
ScopedPointer<XmlElement> xmlElement(xmlDoc.getDocumentElement(true)); | ScopedPointer<XmlElement> xmlElement(xmlDoc.getDocumentElement(true)); | ||||
CARLA_SAFE_ASSERT_RETURN_ERR(xmlElement != nullptr, "Failed to parse project file"); | CARLA_SAFE_ASSERT_RETURN_ERR(xmlElement != nullptr, "Failed to parse project file"); | ||||
@@ -31,17 +31,15 @@ | |||||
# include <xmmintrin.h> | # include <xmmintrin.h> | ||||
#endif | #endif | ||||
#include "AppConfig.h" | |||||
#include "juce_core/juce_core.h" | |||||
#include "juce_audio_graph/juce_audio_graph.h" | |||||
// must be last | // must be last | ||||
#include "jackbridge/JackBridge.hpp" | #include "jackbridge/JackBridge.hpp" | ||||
using juce::File; | |||||
using juce::MemoryBlock; | |||||
using juce::String; | |||||
using juce::Time; | |||||
using juce::Thread; | |||||
using juce2::File; | |||||
using juce2::MemoryBlock; | |||||
using juce2::String; | |||||
using juce2::Time; | |||||
CARLA_BACKEND_START_NAMESPACE | CARLA_BACKEND_START_NAMESPACE | ||||
@@ -79,13 +77,13 @@ private: | |||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
class CarlaEngineBridge : public CarlaEngine, | class CarlaEngineBridge : public CarlaEngine, | ||||
private Thread, | |||||
private CarlaThread, | |||||
private LatencyChangedCallback | private LatencyChangedCallback | ||||
{ | { | ||||
public: | public: | ||||
CarlaEngineBridge(const char* const audioPoolBaseName, const char* const rtClientBaseName, const char* const nonRtClientBaseName, const char* const nonRtServerBaseName) | CarlaEngineBridge(const char* const audioPoolBaseName, const char* const rtClientBaseName, const char* const nonRtClientBaseName, const char* const nonRtServerBaseName) | ||||
: CarlaEngine(), | : CarlaEngine(), | ||||
Thread("CarlaEngineBridge"), | |||||
CarlaThread("CarlaEngineBridge"), | |||||
fShmAudioPool(), | fShmAudioPool(), | ||||
fShmRtClientControl(), | fShmRtClientControl(), | ||||
fShmNonRtClientControl(), | fShmNonRtClientControl(), | ||||
@@ -207,7 +205,8 @@ public: | |||||
fShmNonRtServerControl.commitWrite(); | fShmNonRtServerControl.commitWrite(); | ||||
} | } | ||||
startThread(Thread::realtimeAudioPriority); | |||||
// TODO | |||||
startThread(/*Thread::realtimeAudioPriority*/); | |||||
return true; | return true; | ||||
} | } | ||||
@@ -564,7 +563,7 @@ public: | |||||
if (fLastPingTime > 0 && Time::currentTimeMillis() > fLastPingTime + 30000 && ! wasFirstIdle) | if (fLastPingTime > 0 && Time::currentTimeMillis() > fLastPingTime + 30000 && ! wasFirstIdle) | ||||
{ | { | ||||
carla_stderr("Did not receive ping message from server for 30 secs, closing..."); | carla_stderr("Did not receive ping message from server for 30 secs, closing..."); | ||||
threadShouldExit(); | |||||
signalThreadShouldExit(); | |||||
callback(ENGINE_CALLBACK_QUIT, 0, 0, 0, 0.0f, nullptr); | callback(ENGINE_CALLBACK_QUIT, 0, 0, 0, 0.0f, nullptr); | ||||
} | } | ||||
} | } | ||||
@@ -955,7 +954,7 @@ protected: | |||||
bool quitReceived = false; | bool quitReceived = false; | ||||
for (; ! threadShouldExit();) | |||||
for (; ! shouldThreadExit();) | |||||
{ | { | ||||
const BridgeRtClientControl::WaitHelper helper(fShmRtClientControl); | const BridgeRtClientControl::WaitHelper helper(fShmRtClientControl); | ||||
@@ -34,14 +34,13 @@ | |||||
#include "CarlaHost.h" | #include "CarlaHost.h" | ||||
#include "CarlaNative.hpp" | #include "CarlaNative.hpp" | ||||
#include "AppConfig.h" | |||||
#include "juce_core/juce_core.h" | |||||
using juce::File; | |||||
using juce::MemoryOutputStream; | |||||
using juce::String; | |||||
using juce::XmlDocument; | |||||
using juce::XmlElement; | |||||
#include "juce_audio_graph/juce_audio_graph.h" | |||||
using juce2::File; | |||||
using juce2::MemoryOutputStream; | |||||
using juce2::String; | |||||
using juce2::XmlDocument; | |||||
using juce2::XmlElement; | |||||
CARLA_BACKEND_START_NAMESPACE | CARLA_BACKEND_START_NAMESPACE | ||||
@@ -25,16 +25,15 @@ | |||||
#include <ctime> | #include <ctime> | ||||
#include "juce_core/juce_core.h" | |||||
using juce::CharPointer_UTF8; | |||||
using juce::File; | |||||
using juce::MemoryOutputStream; | |||||
using juce::Result; | |||||
using juce::ScopedPointer; | |||||
using juce::String; | |||||
using juce::XmlDocument; | |||||
using juce::XmlElement; | |||||
#include "juce_audio_graph/juce_audio_graph.h" | |||||
using juce2::CharPointer_UTF8; | |||||
using juce2::File; | |||||
using juce2::MemoryOutputStream; | |||||
using juce2::Result; | |||||
using juce2::String; | |||||
using juce2::XmlDocument; | |||||
using juce2::XmlElement; | |||||
CARLA_BACKEND_START_NAMESPACE | CARLA_BACKEND_START_NAMESPACE | ||||
@@ -30,14 +30,15 @@ | |||||
#include <ctime> | #include <ctime> | ||||
#include "juce_audio_graph/juce_audio_graph.h" | |||||
// --------------------------------------------------------------------------------------------------------------------- | // --------------------------------------------------------------------------------------------------------------------- | ||||
using juce::ChildProcess; | |||||
using juce::File; | |||||
using juce::ScopedPointer; | |||||
using juce::String; | |||||
using juce::StringArray; | |||||
using juce::Time; | |||||
using juce2::ChildProcess; | |||||
using juce2::File; | |||||
using juce2::String; | |||||
using juce2::StringArray; | |||||
using juce2::Time; | |||||
CARLA_BACKEND_START_NAMESPACE | CARLA_BACKEND_START_NAMESPACE | ||||
@@ -171,7 +172,7 @@ protected: | |||||
arguments.add(fLabel); | arguments.add(fLabel); | ||||
// uniqueId | // uniqueId | ||||
arguments.add(String(static_cast<juce::int64>(kPlugin->getUniqueId()))); | |||||
arguments.add(String(static_cast<juce2::int64>(kPlugin->getUniqueId()))); | |||||
bool started; | bool started; | ||||
@@ -27,10 +27,9 @@ | |||||
# include "CarlaThread.hpp" | # include "CarlaThread.hpp" | ||||
#endif | #endif | ||||
using juce::ChildProcess; | |||||
using juce::ScopedPointer; | |||||
using juce::String; | |||||
using juce::StringArray; | |||||
using juce2::ChildProcess; | |||||
using juce2::String; | |||||
using juce2::StringArray; | |||||
#define CARLA_PLUGIN_DSSI_OSC_CHECK_OSC_TYPES(/* argc, types, */ argcToCompare, typesToCompare) \ | #define CARLA_PLUGIN_DSSI_OSC_CHECK_OSC_TYPES(/* argc, types, */ argcToCompare, typesToCompare) \ | ||||
/* check argument count */ \ | /* check argument count */ \ | ||||
@@ -22,7 +22,7 @@ | |||||
#include "CarlaMathUtils.hpp" | #include "CarlaMathUtils.hpp" | ||||
#include "juce_core/juce_core.h" | |||||
#include "juce_audio_graph/juce_audio_graph.h" | |||||
#include <fluidsynth.h> | #include <fluidsynth.h> | ||||
@@ -32,8 +32,8 @@ | |||||
#define FLUID_DEFAULT_POLYPHONY 64 | #define FLUID_DEFAULT_POLYPHONY 64 | ||||
using juce::String; | |||||
using juce::StringArray; | |||||
using juce2::String; | |||||
using juce2::StringArray; | |||||
CARLA_BACKEND_START_NAMESPACE | CARLA_BACKEND_START_NAMESPACE | ||||
@@ -34,12 +34,11 @@ | |||||
// ------------------------------------------------------------------------------------------------------------------- | // ------------------------------------------------------------------------------------------------------------------- | ||||
using juce::ChildProcess; | |||||
using juce::File; | |||||
using juce::ScopedPointer; | |||||
using juce::String; | |||||
using juce::StringArray; | |||||
using juce::Time; | |||||
using juce2::ChildProcess; | |||||
using juce2::File; | |||||
using juce2::String; | |||||
using juce2::StringArray; | |||||
using juce2::Time; | |||||
CARLA_BACKEND_START_NAMESPACE | CARLA_BACKEND_START_NAMESPACE | ||||
@@ -37,12 +37,12 @@ extern "C" { | |||||
#include "rtmempool/rtmempool-lv2.h" | #include "rtmempool/rtmempool-lv2.h" | ||||
} | } | ||||
#include "juce_core/juce_core.h" | |||||
#include "juce_audio_graph/juce_audio_graph.h" | |||||
#include <string> | #include <string> | ||||
#include <vector> | #include <vector> | ||||
using juce::File; | |||||
using juce2::File; | |||||
#define URI_CARLA_ATOM_WORKER "http://kxstudio.sf.net/ns/carla/atomWorker" | #define URI_CARLA_ATOM_WORKER "http://kxstudio.sf.net/ns/carla/atomWorker" | ||||
@@ -31,7 +31,7 @@ | |||||
#include "CarlaBackendUtils.hpp" | #include "CarlaBackendUtils.hpp" | ||||
#include "CarlaMathUtils.hpp" | #include "CarlaMathUtils.hpp" | ||||
#include "juce_core/juce_core.h" | |||||
#include "juce_audio_graph/juce_audio_graph.h" | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
@@ -198,9 +198,9 @@ public: | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
using juce::File; | |||||
using juce::SharedResourcePointer; | |||||
using juce::StringArray; | |||||
using juce2::File; | |||||
using juce2::SharedResourcePointer; | |||||
using juce2::StringArray; | |||||
CARLA_BACKEND_START_NAMESPACE | CARLA_BACKEND_START_NAMESPACE | ||||
@@ -461,7 +461,7 @@ public: | |||||
if (programList.size() == MAX_MIDI_CHANNELS) | if (programList.size() == MAX_MIDI_CHANNELS) | ||||
{ | { | ||||
uint8_t channel = 0; | uint8_t channel = 0; | ||||
for (juce::String *it=programList.begin(), *end=programList.end(); it != end; ++it) | |||||
for (juce2::String *it=programList.begin(), *end=programList.end(); it != end; ++it) | |||||
{ | { | ||||
const int index(it->getIntValue()); | const int index(it->getIntValue()); | ||||
@@ -1,6 +1,6 @@ | |||||
/* | /* | ||||
* Carla Native Plugin | * Carla Native Plugin | ||||
* Copyright (C) 2012-2014 Filipe Coelho <falktx@falktx.com> | |||||
* Copyright (C) 2012-2017 Filipe Coelho <falktx@falktx.com> | |||||
* | * | ||||
* This program is free software; you can redistribute it and/or | * This program is free software; you can redistribute it and/or | ||||
* modify it under the terms of the GNU General Public License as | * modify it under the terms of the GNU General Public License as | ||||
@@ -21,11 +21,11 @@ | |||||
#include "CarlaMathUtils.hpp" | #include "CarlaMathUtils.hpp" | ||||
#include "CarlaNative.h" | #include "CarlaNative.h" | ||||
#include "juce_core/juce_core.h" | |||||
#include "juce_audio_graph/juce_audio_graph.h" | |||||
using juce::jmax; | |||||
using juce::String; | |||||
using juce::StringArray; | |||||
using juce2::jmax; | |||||
using juce2::String; | |||||
using juce2::StringArray; | |||||
CARLA_EXTERN_C | CARLA_EXTERN_C | ||||
std::size_t carla_getNativePluginCount() noexcept; | std::size_t carla_getNativePluginCount() noexcept; | ||||
@@ -27,8 +27,7 @@ | |||||
#include "CarlaLv2Utils.hpp" | #include "CarlaLv2Utils.hpp" | ||||
#include "CarlaUtils.h" | #include "CarlaUtils.h" | ||||
#include "AppConfig.h" | |||||
#include "juce_core/juce_core.h" | |||||
#include "juce_audio_graph/juce_audio_graph.h" | |||||
// --------------------------------------------------------------------------------------------------------------------- | // --------------------------------------------------------------------------------------------------------------------- | ||||
// -Weffc++ compat ext widget | // -Weffc++ compat ext widget | ||||
@@ -109,7 +108,7 @@ public: | |||||
setCallback(_engine_callback, this); | setCallback(_engine_callback, this); | ||||
using juce::File; | |||||
using juce2::File; | |||||
const File pluginFile(File::getSpecialLocation(File::currentExecutableFile).withFileExtension("xml")); | const File pluginFile(File::getSpecialLocation(File::currentExecutableFile).withFileExtension("xml")); | ||||
if (! loadProject(pluginFile.getFullPathName().toRawUTF8())) | if (! loadProject(pluginFile.getFullPathName().toRawUTF8())) | ||||
@@ -825,7 +824,7 @@ const LV2_Descriptor* lv2_descriptor(uint32_t index) | |||||
if (ret.isEmpty()) | if (ret.isEmpty()) | ||||
{ | { | ||||
using namespace juce; | |||||
using namespace juce2; | |||||
const File file(File::getSpecialLocation(File::currentExecutableFile).withFileExtension("ttl")); | const File file(File::getSpecialLocation(File::currentExecutableFile).withFileExtension("ttl")); | ||||
ret = String("file://" + file.getFullPathName()).toRawUTF8(); | ret = String("file://" + file.getFullPathName()).toRawUTF8(); | ||||
} | } | ||||
@@ -853,7 +852,7 @@ const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index) | |||||
if (ret.isEmpty()) | if (ret.isEmpty()) | ||||
{ | { | ||||
using namespace juce; | |||||
using namespace juce2; | |||||
const File file(File::getSpecialLocation(File::currentExecutableFile).getSiblingFile("ext-ui")); | const File file(File::getSpecialLocation(File::currentExecutableFile).getSiblingFile("ext-ui")); | ||||
ret = String("file://" + file.getFullPathName()).toRawUTF8(); | ret = String("file://" + file.getFullPathName()).toRawUTF8(); | ||||
} | } | ||||
@@ -36,17 +36,16 @@ | |||||
#include "jackbridge/JackBridge.hpp" | #include "jackbridge/JackBridge.hpp" | ||||
#include "AppConfig.h" | |||||
#include "juce_core/juce_core.h" | |||||
#include "juce_audio_graph/juce_audio_graph.h" | |||||
using CarlaBackend::CarlaEngine; | using CarlaBackend::CarlaEngine; | ||||
using CarlaBackend::EngineCallbackOpcode; | using CarlaBackend::EngineCallbackOpcode; | ||||
using CarlaBackend::EngineCallbackOpcode2Str; | using CarlaBackend::EngineCallbackOpcode2Str; | ||||
using CarlaBackend::runMainLoopOnce; | using CarlaBackend::runMainLoopOnce; | ||||
using juce::CharPointer_UTF8; | |||||
using juce::File; | |||||
using juce::String; | |||||
using juce2::CharPointer_UTF8; | |||||
using juce2::File; | |||||
using juce2::String; | |||||
// ------------------------------------------------------------------------- | // ------------------------------------------------------------------------- | ||||
@@ -43,11 +43,11 @@ LIBS_win64 = $(MODULEDIR)/jackbridge.win64e.a | |||||
endif | endif | ||||
LINK_FLAGS += $(JACKBRIDGE_LIBS) | LINK_FLAGS += $(JACKBRIDGE_LIBS) | ||||
LIBS_native += $(MODULEDIR)/juce_core.a | |||||
LIBS_posix32 += $(MODULEDIR)/juce_core.posix32.a | |||||
LIBS_posix64 += $(MODULEDIR)/juce_core.posix64.a | |||||
LIBS_win32 += $(MODULEDIR)/juce_core.win32.a | |||||
LIBS_win64 += $(MODULEDIR)/juce_core.win64.a | |||||
LIBS_native += $(MODULEDIR)/juce_audio_graph.a | |||||
LIBS_posix32 += $(MODULEDIR)/juce_audio_graph.posix32.a | |||||
LIBS_posix64 += $(MODULEDIR)/juce_audio_graph.posix64.a | |||||
LIBS_win32 += $(MODULEDIR)/juce_audio_graph.win32.a | |||||
LIBS_win64 += $(MODULEDIR)/juce_audio_graph.win64.a | |||||
LINK_FLAGS += $(JUCE_CORE_LIBS) | LINK_FLAGS += $(JUCE_CORE_LIBS) | ||||
LIBS_native += $(MODULEDIR)/lilv.a | LIBS_native += $(MODULEDIR)/lilv.a | ||||
@@ -21,15 +21,14 @@ | |||||
#include "CarlaMIDI.h" | #include "CarlaMIDI.h" | ||||
#include "LinkedList.hpp" | #include "LinkedList.hpp" | ||||
#include "AppConfig.h" | |||||
#include "juce_core/juce_core.h" | |||||
#include "juce_audio_graph/juce_audio_graph.h" | |||||
#include <string> | #include <string> | ||||
#include <vector> | #include <vector> | ||||
#define URI_CARLA_ATOM_WORKER "http://kxstudio.sf.net/ns/carla/atomWorker" | #define URI_CARLA_ATOM_WORKER "http://kxstudio.sf.net/ns/carla/atomWorker" | ||||
using juce::File; | |||||
using juce2::File; | |||||
CARLA_BRIDGE_START_NAMESPACE | CARLA_BRIDGE_START_NAMESPACE | ||||
@@ -129,7 +129,7 @@ ui_lv2-windows: $(BINDIR)/$(MODULENAME)-lv2-windows.exe | |||||
# Common libs | # Common libs | ||||
LIBS = \ | LIBS = \ | ||||
$(MODULEDIR)/juce_core.a \ | |||||
$(MODULEDIR)/juce_audio_graph.a \ | |||||
$(MODULEDIR)/lilv.a | $(MODULEDIR)/lilv.a | ||||
# ---------------------------------------------------------------------------------------------------------------------------- | # ---------------------------------------------------------------------------------------------------------------------------- | ||||
@@ -59,11 +59,11 @@ endif | |||||
# ---------------------------------------------------------------------------------------------------------------------------- | # ---------------------------------------------------------------------------------------------------------------------------- | ||||
LIBS_native = $(MODULEDIR)/juce_core.a | |||||
LIBS_posix32 = $(MODULEDIR)/juce_core.posix32.a | |||||
LIBS_posix64 = $(MODULEDIR)/juce_core.posix64.a | |||||
LIBS_win32 = $(MODULEDIR)/juce_core.win32.a | |||||
LIBS_win64 = $(MODULEDIR)/juce_core.win64.a | |||||
LIBS_native = $(MODULEDIR)/juce_audio_graph.a | |||||
LIBS_posix32 = $(MODULEDIR)/juce_audio_graph.posix32.a | |||||
LIBS_posix64 = $(MODULEDIR)/juce_audio_graph.posix64.a | |||||
LIBS_win32 = $(MODULEDIR)/juce_audio_graph.win32.a | |||||
LIBS_win64 = $(MODULEDIR)/juce_audio_graph.win64.a | |||||
LINK_FLAGS += $(JUCE_CORE_LIBS) | LINK_FLAGS += $(JUCE_CORE_LIBS) | ||||
LIBS_native += $(MODULEDIR)/lilv.a | LIBS_native += $(MODULEDIR)/lilv.a | ||||
@@ -45,14 +45,13 @@ | |||||
#include <iostream> | #include <iostream> | ||||
#include "AppConfig.h" | |||||
#include "juce_core/juce_core.h" | |||||
#include "juce_audio_graph/juce_audio_graph.h" | |||||
#define DISCOVERY_OUT(x, y) std::cout << "\ncarla-discovery::" << x << "::" << y << std::endl; | #define DISCOVERY_OUT(x, y) std::cout << "\ncarla-discovery::" << x << "::" << y << std::endl; | ||||
using juce::CharPointer_UTF8; | |||||
using juce::File; | |||||
using juce::StringArray; | |||||
using juce2::CharPointer_UTF8; | |||||
using juce2::File; | |||||
using juce2::StringArray; | |||||
CARLA_BACKEND_USE_NAMESPACE | CARLA_BACKEND_USE_NAMESPACE | ||||
@@ -984,7 +983,7 @@ static void do_lv2_check(const char* const bundle, const bool doInit) | |||||
Lilv::Plugin lilvPlugin(lilv_plugins_get(lilvPlugins, it)); | Lilv::Plugin lilvPlugin(lilv_plugins_get(lilvPlugins, it)); | ||||
if (const char* const uri = lilvPlugin.get_uri().as_string()) | if (const char* const uri = lilvPlugin.get_uri().as_string()) | ||||
URIs.addIfNotAlreadyThere(juce::String(uri)); | |||||
URIs.addIfNotAlreadyThere(juce2::String(uri)); | |||||
} | } | ||||
if (URIs.size() == 0) | if (URIs.size() == 0) | ||||
@@ -1436,7 +1435,7 @@ static void do_vst_check(lib_t& libHandle, const bool doInit) | |||||
static void do_fluidsynth_check(const char* const filename, const bool doInit) | static void do_fluidsynth_check(const char* const filename, const bool doInit) | ||||
{ | { | ||||
#ifdef HAVE_FLUIDSYNTH | #ifdef HAVE_FLUIDSYNTH | ||||
const juce::String jfilename = juce::String(CharPointer_UTF8(filename)); | |||||
const juce2::String jfilename = juce2::String(CharPointer_UTF8(filename)); | |||||
const File file(jfilename); | const File file(jfilename); | ||||
if (! file.existsAsFile()) | if (! file.existsAsFile()) | ||||
@@ -1526,7 +1525,7 @@ static void do_fluidsynth_check(const char* const filename, const bool doInit) | |||||
static void do_linuxsampler_check(const char* const filename, const char* const stype, const bool doInit) | static void do_linuxsampler_check(const char* const filename, const char* const stype, const bool doInit) | ||||
{ | { | ||||
#ifdef HAVE_LINUXSAMPLER | #ifdef HAVE_LINUXSAMPLER | ||||
const juce::String jfilename = juce::String(CharPointer_UTF8(filename)); | |||||
const juce2::String jfilename = juce2::String(CharPointer_UTF8(filename)); | |||||
const File file(jfilename); | const File file(jfilename); | ||||
if (! file.existsAsFile()) | if (! file.existsAsFile()) | ||||
@@ -22,9 +22,8 @@ endif | |||||
# ---------------------------------------------------------------------------------------------------------------------- | # ---------------------------------------------------------------------------------------------------------------------- | ||||
BUILD_C_FLAGS += -I$(CWD) -I$(CWD)/includes | BUILD_C_FLAGS += -I$(CWD) -I$(CWD)/includes | ||||
BUILD_CXX_FLAGS += -I$(CWD) -I$(CWD)/backend -I$(CWD)/includes -I$(CWD)/modules -I$(CWD)/utils | |||||
LINK_FLAGS += $(MODULEDIR)/juce_core.a | |||||
LINK_FLAGS += $(JUCE_CORE_LIBS) | |||||
BUILD_CXX_FLAGS += -I$(CWD) -I$(CWD)/backend -I$(CWD)/includes -I$(CWD)/utils | |||||
LINK_FLAGS += -lpthread -lrt | |||||
# ---------------------------------------------------------------------------------------------------------------------- | # ---------------------------------------------------------------------------------------------------------------------- | ||||
@@ -16,12 +16,12 @@ | |||||
*/ | */ | ||||
#include "libjack.hpp" | #include "libjack.hpp" | ||||
#include <sys/prctl.h> | |||||
#include "CarlaThread.hpp" | #include "CarlaThread.hpp" | ||||
using juce::Thread; | |||||
using juce::Time; | |||||
#include <signal.h> | |||||
#include <sys/prctl.h> | |||||
#include <sys/time.h> | |||||
typedef int (*CarlaInterposedCallback)(int, void*); | typedef int (*CarlaInterposedCallback)(int, void*); | ||||
@@ -34,9 +34,16 @@ int jack_carla_interposed_action(int, int, void*) | |||||
CARLA_BACKEND_START_NAMESPACE | CARLA_BACKEND_START_NAMESPACE | ||||
static int64_t getCurrentTimeMilliseconds() noexcept | |||||
{ | |||||
struct timeval tv; | |||||
gettimeofday (&tv, nullptr); | |||||
return ((int64_t) tv.tv_sec) * 1000 + tv.tv_usec / 1000; | |||||
} | |||||
// --------------------------------------------------------------------------------------------------------------------- | // --------------------------------------------------------------------------------------------------------------------- | ||||
class CarlaJackRealtimeThread : public Thread | |||||
class CarlaJackRealtimeThread : public CarlaThread | |||||
{ | { | ||||
public: | public: | ||||
struct Callback { | struct Callback { | ||||
@@ -46,7 +53,7 @@ public: | |||||
}; | }; | ||||
CarlaJackRealtimeThread(Callback* const callback) | CarlaJackRealtimeThread(Callback* const callback) | ||||
: Thread("CarlaJackRealtimeThread"), | |||||
: CarlaThread("CarlaJackRealtimeThread"), | |||||
fCallback(callback) {} | fCallback(callback) {} | ||||
protected: | protected: | ||||
@@ -63,7 +70,7 @@ private: | |||||
// -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
class CarlaJackNonRealtimeThread : public Thread | |||||
class CarlaJackNonRealtimeThread : public CarlaThread | |||||
{ | { | ||||
public: | public: | ||||
struct Callback { | struct Callback { | ||||
@@ -73,7 +80,7 @@ public: | |||||
}; | }; | ||||
CarlaJackNonRealtimeThread(Callback* const callback) | CarlaJackNonRealtimeThread(Callback* const callback) | ||||
: Thread("CarlaJackNonRealtimeThread"), | |||||
: CarlaThread("CarlaJackNonRealtimeThread"), | |||||
fCallback(callback) {} | fCallback(callback) {} | ||||
protected: | protected: | ||||
@@ -380,7 +387,7 @@ bool CarlaJackAppClient::initSharedMemmory() | |||||
// tell backend we're live | // tell backend we're live | ||||
const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex); | const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex); | ||||
fLastPingTime = Time::currentTimeMillis(); | |||||
fLastPingTime = getCurrentTimeMilliseconds(); | |||||
CARLA_SAFE_ASSERT(fLastPingTime > 0); | CARLA_SAFE_ASSERT(fLastPingTime > 0); | ||||
// ready! | // ready! | ||||
@@ -855,7 +862,7 @@ bool CarlaJackAppClient::handleNonRtData() | |||||
#endif | #endif | ||||
if (opcode != kPluginBridgeNonRtClientNull && opcode != kPluginBridgeNonRtClientPingOnOff && fLastPingTime > 0) | if (opcode != kPluginBridgeNonRtClientNull && opcode != kPluginBridgeNonRtClientPingOnOff && fLastPingTime > 0) | ||||
fLastPingTime = Time::currentTimeMillis(); | |||||
fLastPingTime = getCurrentTimeMilliseconds(); | |||||
switch (opcode) | switch (opcode) | ||||
{ | { | ||||
@@ -872,7 +879,7 @@ bool CarlaJackAppClient::handleNonRtData() | |||||
case kPluginBridgeNonRtClientPingOnOff: { | case kPluginBridgeNonRtClientPingOnOff: { | ||||
const uint32_t onOff(fShmNonRtClientControl.readBool()); | const uint32_t onOff(fShmNonRtClientControl.readBool()); | ||||
fLastPingTime = onOff ? Time::currentTimeMillis() : -1; | |||||
fLastPingTime = onOff ? getCurrentTimeMilliseconds() : -1; | |||||
} break; | } break; | ||||
case kPluginBridgeNonRtClientActivate: | case kPluginBridgeNonRtClientActivate: | ||||
@@ -968,7 +975,7 @@ void CarlaJackAppClient::runRealtimeThread() | |||||
bool quitReceived = false; | bool quitReceived = false; | ||||
for (; ! fRealtimeThread.threadShouldExit();) | |||||
for (; ! fRealtimeThread.shouldThreadExit();) | |||||
{ | { | ||||
if (handleRtData()) | if (handleRtData()) | ||||
{ | { | ||||
@@ -1003,15 +1010,16 @@ void CarlaJackAppClient::runNonRealtimeThread() | |||||
fMidiOutBuffers[i].isInput = false; | fMidiOutBuffers[i].isInput = false; | ||||
} | } | ||||
fRealtimeThread.startThread(Thread::realtimeAudioPriority); | |||||
// TODO | |||||
fRealtimeThread.startThread(/*Thread::realtimeAudioPriority*/); | |||||
fLastPingTime = Time::currentTimeMillis(); | |||||
fLastPingTime = getCurrentTimeMilliseconds(); | |||||
carla_stdout("Carla Jack Client Ready!"); | carla_stdout("Carla Jack Client Ready!"); | ||||
bool quitReceived = false, | bool quitReceived = false, | ||||
timedOut = false; | timedOut = false; | ||||
for (; ! fNonRealtimeThread.threadShouldExit();) | |||||
for (; ! fNonRealtimeThread.shouldThreadExit();) | |||||
{ | { | ||||
carla_msleep(50); | carla_msleep(50); | ||||
@@ -1023,7 +1031,7 @@ void CarlaJackAppClient::runNonRealtimeThread() | |||||
break; | break; | ||||
/* | /* | ||||
if (fLastPingTime > 0 && Time::currentTimeMillis() > fLastPingTime + 30000) | |||||
if (fLastPingTime > 0 && getCurrentTimeMilliseconds() > fLastPingTime + 30000) | |||||
{ | { | ||||
carla_stderr("Did not receive ping message from server for 30 secs, closing..."); | carla_stderr("Did not receive ping message from server for 30 secs, closing..."); | ||||
@@ -28,9 +28,6 @@ | |||||
#include "CarlaMutex.hpp" | #include "CarlaMutex.hpp" | ||||
#include "LinkedList.hpp" | #include "LinkedList.hpp" | ||||
#include "AppConfig.h" | |||||
#include "juce_core/juce_core.h" | |||||
#if 0 | #if 0 | ||||
#include <jack/jack.h> | #include <jack/jack.h> | ||||
#include <jack/midiport.h> | #include <jack/midiport.h> | ||||
@@ -15,7 +15,6 @@ | |||||
* For a full copy of the GNU General Public License see the doc/GPL.txt file. | * For a full copy of the GNU General Public License see the doc/GPL.txt file. | ||||
*/ | */ | ||||
// need to include this first | |||||
#include "libjack.hpp" | #include "libjack.hpp" | ||||
CARLA_BACKEND_USE_NAMESPACE | CARLA_BACKEND_USE_NAMESPACE | ||||
@@ -15,7 +15,6 @@ | |||||
* For a full copy of the GNU General Public License see the doc/GPL.txt file. | * For a full copy of the GNU General Public License see the doc/GPL.txt file. | ||||
*/ | */ | ||||
// need to include this first | |||||
#include "libjack.hpp" | #include "libjack.hpp" | ||||
CARLA_BACKEND_USE_NAMESPACE | CARLA_BACKEND_USE_NAMESPACE | ||||
@@ -15,7 +15,6 @@ | |||||
* For a full copy of the GNU General Public License see the doc/GPL.txt file. | * For a full copy of the GNU General Public License see the doc/GPL.txt file. | ||||
*/ | */ | ||||
// need to include this first | |||||
#include "libjack.hpp" | #include "libjack.hpp" | ||||
CARLA_BACKEND_USE_NAMESPACE | CARLA_BACKEND_USE_NAMESPACE | ||||
@@ -15,7 +15,6 @@ | |||||
* For a full copy of the GNU General Public License see the doc/GPL.txt file. | * For a full copy of the GNU General Public License see the doc/GPL.txt file. | ||||
*/ | */ | ||||
// need to include this first | |||||
#include "libjack.hpp" | #include "libjack.hpp" | ||||
CARLA_BACKEND_USE_NAMESPACE | CARLA_BACKEND_USE_NAMESPACE | ||||
@@ -20,6 +20,8 @@ | |||||
This is safe for the case of one read thread and one write thread. | This is safe for the case of one read thread and one write thread. | ||||
*/ | */ | ||||
#define USE_MLOCK | |||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#ifdef USE_MLOCK | #ifdef USE_MLOCK | ||||
@@ -9,7 +9,7 @@ | |||||
all: | all: | ||||
clean: | clean: | ||||
$(MAKE) clean -C juce_core | |||||
$(MAKE) clean -C juce_audio_graph | |||||
$(MAKE) clean -C lilv | $(MAKE) clean -C lilv | ||||
$(MAKE) clean -C rtaudio | $(MAKE) clean -C rtaudio | ||||
$(MAKE) clean -C rtmempool | $(MAKE) clean -C rtmempool | ||||
@@ -31,8 +31,6 @@ | |||||
#ifndef JUCE_AUDIOSAMPLEBUFFER_H_INCLUDED | #ifndef JUCE_AUDIOSAMPLEBUFFER_H_INCLUDED | ||||
#define JUCE_AUDIOSAMPLEBUFFER_H_INCLUDED | #define JUCE_AUDIOSAMPLEBUFFER_H_INCLUDED | ||||
#include "CarlaMathUtils.hpp" | |||||
//============================================================================== | //============================================================================== | ||||
/** | /** | ||||
A multi-channel buffer of floating point audio samples. | A multi-channel buffer of floating point audio samples. | ||||
@@ -89,12 +89,8 @@ bool NamedValueSet::isEmpty() const noexcept | |||||
static const var& getNullVarRef() noexcept | static const var& getNullVarRef() noexcept | ||||
{ | { | ||||
#if JUCE_ALLOW_STATIC_NULL_VARIABLES | |||||
return var::null; | |||||
#else | |||||
static var nullVar; | static var nullVar; | ||||
return nullVar; | return nullVar; | ||||
#endif | |||||
} | } | ||||
const var& NamedValueSet::operator[] (const Identifier& name) const noexcept | const var& NamedValueSet::operator[] (const Identifier& name) const noexcept | ||||
@@ -76,11 +76,6 @@ public: | |||||
/** Destructor. */ | /** Destructor. */ | ||||
~var() noexcept; | ~var() noexcept; | ||||
#if JUCE_ALLOW_STATIC_NULL_VARIABLES | |||||
/** A static var object that can be used where you need an empty variant object. */ | |||||
static const var null; | |||||
#endif | |||||
var (const var& valueToCopy); | var (const var& valueToCopy); | ||||
var (int value) noexcept; | var (int value) noexcept; | ||||
var (int64 value) noexcept; | var (int64 value) noexcept; | ||||
@@ -0,0 +1,168 @@ | |||||
/* | |||||
============================================================================== | |||||
This file is part of the JUCE library. | |||||
Copyright (c) 2016 - ROLI Ltd. | |||||
Permission is granted to use this software under the terms of the ISC license | |||||
http://www.isc.org/downloads/software-support-policy/isc-license/ | |||||
Permission to use, copy, modify, and/or distribute this software for any | |||||
purpose with or without fee is hereby granted, provided that the above | |||||
copyright notice and this permission notice appear in all copies. | |||||
THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD | |||||
TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |||||
FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, | |||||
OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF | |||||
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | |||||
OF THIS SOFTWARE. | |||||
----------------------------------------------------------------------------- | |||||
To release a closed-source product which uses other parts of JUCE not | |||||
licensed under the ISC terms, commercial licenses are available: visit | |||||
www.juce.com for more information. | |||||
============================================================================== | |||||
*/ | |||||
DirectoryIterator::DirectoryIterator (const File& directory, bool recursive, | |||||
const String& pattern, const int type) | |||||
: wildCards (parseWildcards (pattern)), | |||||
fileFinder (directory, (recursive || wildCards.size() > 1) ? "*" : pattern), | |||||
wildCard (pattern), | |||||
path (File::addTrailingSeparator (directory.getFullPathName())), | |||||
index (-1), | |||||
totalNumFiles (-1), | |||||
whatToLookFor (type), | |||||
isRecursive (recursive), | |||||
hasBeenAdvanced (false) | |||||
{ | |||||
// you have to specify the type of files you're looking for! | |||||
jassert ((type & (File::findFiles | File::findDirectories)) != 0); | |||||
jassert (type > 0 && type <= 7); | |||||
} | |||||
DirectoryIterator::~DirectoryIterator() | |||||
{ | |||||
} | |||||
StringArray DirectoryIterator::parseWildcards (const String& pattern) | |||||
{ | |||||
StringArray s; | |||||
s.addTokens (pattern, ";,", "\"'"); | |||||
s.trim(); | |||||
s.removeEmptyStrings(); | |||||
return s; | |||||
} | |||||
bool DirectoryIterator::fileMatches (const StringArray& wildCards, const String& filename) | |||||
{ | |||||
for (int i = 0; i < wildCards.size(); ++i) | |||||
if (filename.matchesWildcard (wildCards[i], ! File::areFileNamesCaseSensitive())) | |||||
return true; | |||||
return false; | |||||
} | |||||
bool DirectoryIterator::next() | |||||
{ | |||||
return next (nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); | |||||
} | |||||
bool DirectoryIterator::next (bool* const isDirResult, bool* const isHiddenResult, int64* const fileSize, | |||||
Time* const modTime, Time* const creationTime, bool* const isReadOnly) | |||||
{ | |||||
for (;;) | |||||
{ | |||||
hasBeenAdvanced = true; | |||||
if (subIterator != nullptr) | |||||
{ | |||||
if (subIterator->next (isDirResult, isHiddenResult, fileSize, modTime, creationTime, isReadOnly)) | |||||
return true; | |||||
subIterator = nullptr; | |||||
} | |||||
String filename; | |||||
bool isDirectory, isHidden = false, shouldContinue = false; | |||||
while (fileFinder.next (filename, &isDirectory, | |||||
(isHiddenResult != nullptr || (whatToLookFor & File::ignoreHiddenFiles) != 0) ? &isHidden : nullptr, | |||||
fileSize, modTime, creationTime, isReadOnly)) | |||||
{ | |||||
++index; | |||||
if (! filename.containsOnly (".")) | |||||
{ | |||||
bool matches = false; | |||||
if (isDirectory) | |||||
{ | |||||
if (isRecursive && ((whatToLookFor & File::ignoreHiddenFiles) == 0 || ! isHidden)) | |||||
subIterator = new DirectoryIterator (File::createFileWithoutCheckingPath (path + filename), | |||||
true, wildCard, whatToLookFor); | |||||
matches = (whatToLookFor & File::findDirectories) != 0; | |||||
} | |||||
else | |||||
{ | |||||
matches = (whatToLookFor & File::findFiles) != 0; | |||||
} | |||||
// if we're not relying on the OS iterator to do the wildcard match, do it now.. | |||||
if (matches && (isRecursive || wildCards.size() > 1)) | |||||
matches = fileMatches (wildCards, filename); | |||||
if (matches && (whatToLookFor & File::ignoreHiddenFiles) != 0) | |||||
matches = ! isHidden; | |||||
if (matches) | |||||
{ | |||||
currentFile = File::createFileWithoutCheckingPath (path + filename); | |||||
if (isHiddenResult != nullptr) *isHiddenResult = isHidden; | |||||
if (isDirResult != nullptr) *isDirResult = isDirectory; | |||||
return true; | |||||
} | |||||
if (subIterator != nullptr) | |||||
{ | |||||
shouldContinue = true; | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
if (! shouldContinue) | |||||
return false; | |||||
} | |||||
} | |||||
const File& DirectoryIterator::getFile() const | |||||
{ | |||||
if (subIterator != nullptr && subIterator->hasBeenAdvanced) | |||||
return subIterator->getFile(); | |||||
// You need to call DirectoryIterator::next() before asking it for the file that it found! | |||||
jassert (hasBeenAdvanced); | |||||
return currentFile; | |||||
} | |||||
float DirectoryIterator::getEstimatedProgress() const | |||||
{ | |||||
if (totalNumFiles < 0) | |||||
totalNumFiles = File (path).getNumberOfChildFiles (File::findFilesAndDirectories); | |||||
if (totalNumFiles <= 0) | |||||
return 0.0f; | |||||
const float detailedIndex = (subIterator != nullptr) ? index + subIterator->getEstimatedProgress() | |||||
: (float) index; | |||||
return detailedIndex / totalNumFiles; | |||||
} |
@@ -0,0 +1,159 @@ | |||||
/* | |||||
============================================================================== | |||||
This file is part of the JUCE library. | |||||
Copyright (c) 2016 - ROLI Ltd. | |||||
Permission is granted to use this software under the terms of the ISC license | |||||
http://www.isc.org/downloads/software-support-policy/isc-license/ | |||||
Permission to use, copy, modify, and/or distribute this software for any | |||||
purpose with or without fee is hereby granted, provided that the above | |||||
copyright notice and this permission notice appear in all copies. | |||||
THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD | |||||
TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |||||
FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, | |||||
OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF | |||||
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | |||||
OF THIS SOFTWARE. | |||||
----------------------------------------------------------------------------- | |||||
To release a closed-source product which uses other parts of JUCE not | |||||
licensed under the ISC terms, commercial licenses are available: visit | |||||
www.juce.com for more information. | |||||
============================================================================== | |||||
*/ | |||||
#ifndef JUCE_DIRECTORYITERATOR_H_INCLUDED | |||||
#define JUCE_DIRECTORYITERATOR_H_INCLUDED | |||||
//============================================================================== | |||||
/** | |||||
Searches through the files in a directory, returning each file that is found. | |||||
A DirectoryIterator will search through a directory and its subdirectories using | |||||
a wildcard filepattern match. | |||||
If you may be scanning a large number of files, it's usually smarter to use this | |||||
class than File::findChildFiles() because it allows you to stop at any time, rather | |||||
than having to wait for the entire scan to finish before getting the results. | |||||
It also provides an estimate of its progress, using a (highly inaccurate!) algorithm. | |||||
*/ | |||||
class JUCE_API DirectoryIterator | |||||
{ | |||||
public: | |||||
//============================================================================== | |||||
/** Creates a DirectoryIterator for a given directory. | |||||
After creating one of these, call its next() method to get the | |||||
first file - e.g. @code | |||||
DirectoryIterator iter (File ("/animals/mooses"), true, "*.moose"); | |||||
while (iter.next()) | |||||
{ | |||||
File theFileItFound (iter.getFile()); | |||||
... etc | |||||
} | |||||
@endcode | |||||
@param directory the directory to search in | |||||
@param isRecursive whether all the subdirectories should also be searched | |||||
@param wildCard the file pattern to match. This may contain multiple patterns | |||||
separated by a semi-colon or comma, e.g. "*.jpg;*.png" | |||||
@param whatToLookFor a value from the File::TypesOfFileToFind enum, specifying | |||||
whether to look for files, directories, or both. | |||||
*/ | |||||
DirectoryIterator (const File& directory, | |||||
bool isRecursive, | |||||
const String& wildCard = "*", | |||||
int whatToLookFor = File::findFiles); | |||||
/** Destructor. */ | |||||
~DirectoryIterator(); | |||||
/** Moves the iterator along to the next file. | |||||
@returns true if a file was found (you can then use getFile() to see what it was) - or | |||||
false if there are no more matching files. | |||||
*/ | |||||
bool next(); | |||||
/** Moves the iterator along to the next file, and returns various properties of that file. | |||||
If you need to find out details about the file, it's more efficient to call this method than | |||||
to call the normal next() method and then find out the details afterwards. | |||||
All the parameters are optional, so pass null pointers for any items that you're not | |||||
interested in. | |||||
@returns true if a file was found (you can then use getFile() to see what it was) - or | |||||
false if there are no more matching files. If it returns false, then none of the | |||||
parameters will be filled-in. | |||||
*/ | |||||
bool next (bool* isDirectory, | |||||
bool* isHidden, | |||||
int64* fileSize, | |||||
Time* modTime, | |||||
Time* creationTime, | |||||
bool* isReadOnly); | |||||
/** Returns the file that the iterator is currently pointing at. | |||||
The result of this call is only valid after a call to next() has returned true. | |||||
*/ | |||||
const File& getFile() const; | |||||
/** Returns a guess of how far through the search the iterator has got. | |||||
@returns a value 0.0 to 1.0 to show the progress, although this won't be | |||||
very accurate. | |||||
*/ | |||||
float getEstimatedProgress() const; | |||||
private: | |||||
//============================================================================== | |||||
class NativeIterator | |||||
{ | |||||
public: | |||||
NativeIterator (const File& directory, const String& wildCard); | |||||
~NativeIterator(); | |||||
bool next (String& filenameFound, | |||||
bool* isDirectory, bool* isHidden, int64* fileSize, | |||||
Time* modTime, Time* creationTime, bool* isReadOnly); | |||||
class Pimpl; | |||||
private: | |||||
friend class DirectoryIterator; | |||||
ScopedPointer<Pimpl> pimpl; | |||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NativeIterator) | |||||
}; | |||||
StringArray wildCards; | |||||
NativeIterator fileFinder; | |||||
String wildCard, path; | |||||
int index; | |||||
mutable int totalNumFiles; | |||||
const int whatToLookFor; | |||||
const bool isRecursive; | |||||
bool hasBeenAdvanced; | |||||
ScopedPointer<DirectoryIterator> subIterator; | |||||
File currentFile; | |||||
static StringArray parseWildcards (const String& pattern); | |||||
static bool fileMatches (const StringArray& wildCards, const String& filename); | |||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DirectoryIterator) | |||||
}; | |||||
#endif // JUCE_DIRECTORYITERATOR_H_INCLUDED |
@@ -742,41 +742,6 @@ public: | |||||
/** The user's home folder. This is the same as using File ("~"). */ | /** The user's home folder. This is the same as using File ("~"). */ | ||||
userHomeDirectory, | userHomeDirectory, | ||||
/** The user's default documents folder. On Windows, this might be the user's | |||||
"My Documents" folder. On the Mac it'll be their "Documents" folder. Linux | |||||
doesn't tend to have one of these, so it might just return their home folder. | |||||
*/ | |||||
userDocumentsDirectory, | |||||
/** The folder that contains the user's desktop objects. */ | |||||
userDesktopDirectory, | |||||
/** The most likely place where a user might store their music files. */ | |||||
userMusicDirectory, | |||||
/** The most likely place where a user might store their movie files. */ | |||||
userMoviesDirectory, | |||||
/** The most likely place where a user might store their picture files. */ | |||||
userPicturesDirectory, | |||||
/** The folder in which applications store their persistent user-specific settings. | |||||
On Windows, this might be "\Documents and Settings\username\Application Data". | |||||
On the Mac, it might be "~/Library". If you're going to store your settings in here, | |||||
always create your own sub-folder to put them in, to avoid making a mess. | |||||
*/ | |||||
userApplicationDataDirectory, | |||||
/** An equivalent of the userApplicationDataDirectory folder that is shared by all users | |||||
of the computer, rather than just the current user. | |||||
On the Mac it'll be "/Library", on Windows, it could be something like | |||||
"\Documents and Settings\All Users\Application Data". | |||||
Depending on the setup, this folder may be read-only. | |||||
*/ | |||||
commonApplicationDataDirectory, | |||||
/** A place to put documents which are shared by all users of the machine. | /** A place to put documents which are shared by all users of the machine. | ||||
On Windows this may be somewhere like "C:\Users\Public\Documents", on OSX it | On Windows this may be somewhere like "C:\Users\Public\Documents", on OSX it | ||||
will be something like "/Users/Shared". Other OSes may have no such concept | will be something like "/Users/Shared". Other OSes may have no such concept | ||||
@@ -812,17 +777,10 @@ public: | |||||
*/ | */ | ||||
currentApplicationFile, | currentApplicationFile, | ||||
/** Returns the file that was invoked to launch this executable. | |||||
This may differ from currentExecutableFile if the app was started from e.g. a link - this | |||||
will return the name of the link that was used, whereas currentExecutableFile will return | |||||
the actual location of the target executable. | |||||
*/ | |||||
invokedExecutableFile, | |||||
/** In a plugin, this will return the path of the host executable. */ | /** In a plugin, this will return the path of the host executable. */ | ||||
hostApplicationPath, | hostApplicationPath, | ||||
#if JUCE_WINDOWS | |||||
#ifdef CARLA_OS_WIN | |||||
/** On a Windows machine, returns the location of the Windows/System32 folder. */ | /** On a Windows machine, returns the location of the Windows/System32 folder. */ | ||||
windowsSystemDirectory, | windowsSystemDirectory, | ||||
#endif | #endif | ||||
@@ -925,7 +883,7 @@ public: | |||||
*/ | */ | ||||
File getLinkedTarget() const; | File getLinkedTarget() const; | ||||
#if JUCE_WINDOWS | |||||
#ifdef CARLA_OS_WIN | |||||
/** Windows ONLY - Creates a win32 .LNK shortcut file that links to this file. */ | /** Windows ONLY - Creates a win32 .LNK shortcut file that links to this file. */ | ||||
bool createShortcut (const String& description, const File& linkFileToCreate) const; | bool createShortcut (const String& description, const File& linkFileToCreate) const; | ||||
@@ -0,0 +1,136 @@ | |||||
/* | |||||
============================================================================== | |||||
This file is part of the JUCE library. | |||||
Copyright (c) 2016 - ROLI Ltd. | |||||
Permission is granted to use this software under the terms of the ISC license | |||||
http://www.isc.org/downloads/software-support-policy/isc-license/ | |||||
Permission to use, copy, modify, and/or distribute this software for any | |||||
purpose with or without fee is hereby granted, provided that the above | |||||
copyright notice and this permission notice appear in all copies. | |||||
THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD | |||||
TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |||||
FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, | |||||
OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF | |||||
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | |||||
OF THIS SOFTWARE. | |||||
----------------------------------------------------------------------------- | |||||
To release a closed-source product which uses other parts of JUCE not | |||||
licensed under the ISC terms, commercial licenses are available: visit | |||||
www.juce.com for more information. | |||||
============================================================================== | |||||
*/ | |||||
int64 juce_fileSetPosition (void* handle, int64 pos); | |||||
//============================================================================== | |||||
FileOutputStream::FileOutputStream (const File& f, const size_t bufferSizeToUse) | |||||
: file (f), | |||||
fileHandle (nullptr), | |||||
status (Result::ok()), | |||||
currentPosition (0), | |||||
bufferSize (bufferSizeToUse), | |||||
bytesInBuffer (0), | |||||
buffer (jmax (bufferSizeToUse, (size_t) 16)) | |||||
{ | |||||
openHandle(); | |||||
} | |||||
FileOutputStream::~FileOutputStream() | |||||
{ | |||||
flushBuffer(); | |||||
closeHandle(); | |||||
} | |||||
int64 FileOutputStream::getPosition() | |||||
{ | |||||
return currentPosition; | |||||
} | |||||
bool FileOutputStream::setPosition (int64 newPosition) | |||||
{ | |||||
if (newPosition != currentPosition) | |||||
{ | |||||
flushBuffer(); | |||||
currentPosition = juce_fileSetPosition (fileHandle, newPosition); | |||||
} | |||||
return newPosition == currentPosition; | |||||
} | |||||
bool FileOutputStream::flushBuffer() | |||||
{ | |||||
bool ok = true; | |||||
if (bytesInBuffer > 0) | |||||
{ | |||||
ok = (writeInternal (buffer, bytesInBuffer) == (ssize_t) bytesInBuffer); | |||||
bytesInBuffer = 0; | |||||
} | |||||
return ok; | |||||
} | |||||
void FileOutputStream::flush() | |||||
{ | |||||
flushBuffer(); | |||||
flushInternal(); | |||||
} | |||||
bool FileOutputStream::write (const void* const src, const size_t numBytes) | |||||
{ | |||||
jassert (src != nullptr && ((ssize_t) numBytes) >= 0); | |||||
if (bytesInBuffer + numBytes < bufferSize) | |||||
{ | |||||
memcpy (buffer + bytesInBuffer, src, numBytes); | |||||
bytesInBuffer += numBytes; | |||||
currentPosition += (int64) numBytes; | |||||
} | |||||
else | |||||
{ | |||||
if (! flushBuffer()) | |||||
return false; | |||||
if (numBytes < bufferSize) | |||||
{ | |||||
memcpy (buffer + bytesInBuffer, src, numBytes); | |||||
bytesInBuffer += numBytes; | |||||
currentPosition += (int64) numBytes; | |||||
} | |||||
else | |||||
{ | |||||
const ssize_t bytesWritten = writeInternal (src, numBytes); | |||||
if (bytesWritten < 0) | |||||
return false; | |||||
currentPosition += (int64) bytesWritten; | |||||
return bytesWritten == (ssize_t) numBytes; | |||||
} | |||||
} | |||||
return true; | |||||
} | |||||
bool FileOutputStream::writeRepeatedByte (uint8 byte, size_t numBytes) | |||||
{ | |||||
jassert (((ssize_t) numBytes) >= 0); | |||||
if (bytesInBuffer + numBytes < bufferSize) | |||||
{ | |||||
memset (buffer + bytesInBuffer, byte, numBytes); | |||||
bytesInBuffer += numBytes; | |||||
currentPosition += (int64) numBytes; | |||||
return true; | |||||
} | |||||
return OutputStream::writeRepeatedByte (byte, numBytes); | |||||
} |
@@ -0,0 +1,122 @@ | |||||
/* | |||||
============================================================================== | |||||
This file is part of the JUCE library. | |||||
Copyright (c) 2016 - ROLI Ltd. | |||||
Permission is granted to use this software under the terms of the ISC license | |||||
http://www.isc.org/downloads/software-support-policy/isc-license/ | |||||
Permission to use, copy, modify, and/or distribute this software for any | |||||
purpose with or without fee is hereby granted, provided that the above | |||||
copyright notice and this permission notice appear in all copies. | |||||
THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD | |||||
TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |||||
FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, | |||||
OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF | |||||
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | |||||
OF THIS SOFTWARE. | |||||
----------------------------------------------------------------------------- | |||||
To release a closed-source product which uses other parts of JUCE not | |||||
licensed under the ISC terms, commercial licenses are available: visit | |||||
www.juce.com for more information. | |||||
============================================================================== | |||||
*/ | |||||
#ifndef JUCE_FILEOUTPUTSTREAM_H_INCLUDED | |||||
#define JUCE_FILEOUTPUTSTREAM_H_INCLUDED | |||||
//============================================================================== | |||||
/** | |||||
An output stream that writes into a local file. | |||||
@see OutputStream, FileInputStream, File::createOutputStream | |||||
*/ | |||||
class JUCE_API FileOutputStream : public OutputStream | |||||
{ | |||||
public: | |||||
//============================================================================== | |||||
/** Creates a FileOutputStream. | |||||
If the file doesn't exist, it will first be created. If the file can't be | |||||
created or opened (for example, because the parent directory of the file | |||||
does not exist), the failedToOpen() method will return true. | |||||
If the file already exists when opened, the stream's write-position will | |||||
be set to the end of the file. To overwrite an existing file, | |||||
use File::deleteFile() before opening the stream, or use setPosition(0) | |||||
after it's opened (although this won't truncate the file). | |||||
Destroying a FileOutputStream object does not force the operating system | |||||
to write the buffered data to disk immediately. If this is required you | |||||
should call flush() before triggering the destructor. | |||||
@see TemporaryFile | |||||
*/ | |||||
FileOutputStream (const File& fileToWriteTo, | |||||
size_t bufferSizeToUse = 16384); | |||||
/** Destructor. */ | |||||
~FileOutputStream(); | |||||
//============================================================================== | |||||
/** Returns the file that this stream is writing to. | |||||
*/ | |||||
const File& getFile() const { return file; } | |||||
/** Returns the status of the file stream. | |||||
The result will be ok if the file opened successfully. If an error occurs while | |||||
opening or writing to the file, this will contain an error message. | |||||
*/ | |||||
const Result& getStatus() const noexcept { return status; } | |||||
/** Returns true if the stream couldn't be opened for some reason. | |||||
@see getResult() | |||||
*/ | |||||
bool failedToOpen() const noexcept { return status.failed(); } | |||||
/** Returns true if the stream opened without problems. | |||||
@see getResult() | |||||
*/ | |||||
bool openedOk() const noexcept { return status.wasOk(); } | |||||
/** Attempts to truncate the file to the current write position. | |||||
To truncate a file to a specific size, first use setPosition() to seek to the | |||||
appropriate location, and then call this method. | |||||
*/ | |||||
Result truncate(); | |||||
//============================================================================== | |||||
void flush() override; | |||||
int64 getPosition() override; | |||||
bool setPosition (int64) override; | |||||
bool write (const void*, size_t) override; | |||||
bool writeRepeatedByte (uint8 byte, size_t numTimesToRepeat) override; | |||||
private: | |||||
//============================================================================== | |||||
File file; | |||||
void* fileHandle; | |||||
Result status; | |||||
int64 currentPosition; | |||||
size_t bufferSize, bytesInBuffer; | |||||
HeapBlock<char> buffer; | |||||
void openHandle(); | |||||
void closeHandle(); | |||||
void flushInternal(); | |||||
bool flushBuffer(); | |||||
int64 setPositionInternal (int64); | |||||
ssize_t writeInternal (const void*, size_t); | |||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FileOutputStream) | |||||
}; | |||||
#endif // JUCE_FILEOUTPUTSTREAM_H_INCLUDED |
@@ -91,7 +91,7 @@ bool TemporaryFile::overwriteTargetFileWithTemporary() const | |||||
if (temporaryFile.replaceFileIn (targetFile)) | if (temporaryFile.replaceFileIn (targetFile)) | ||||
return true; | return true; | ||||
Thread::sleep (100); | |||||
carla_msleep (100); | |||||
} | } | ||||
} | } | ||||
else | else | ||||
@@ -112,7 +112,7 @@ bool TemporaryFile::deleteTemporaryFile() const | |||||
if (temporaryFile.deleteFile()) | if (temporaryFile.deleteFile()) | ||||
return true; | return true; | ||||
Thread::sleep (50); | |||||
carla_msleep (50); | |||||
} | } | ||||
return false; | return false; | ||||
@@ -19,9 +19,28 @@ | |||||
#include "juce_audio_graph.h" | #include "juce_audio_graph.h" | ||||
#include <locale> | #include <locale> | ||||
#include <ctime> | |||||
#include <cctype> | #include <cctype> | ||||
#include <cstdarg> | #include <cstdarg> | ||||
#include <iostream> | #include <iostream> | ||||
#include <sys/time.h> | |||||
#ifdef CARLA_OS_WIN | |||||
#include <mmsystem.h> | |||||
#include <shlobj.h> | |||||
#else | |||||
#include <dlfcn.h> | |||||
#include <fcntl.h> | |||||
#include <pwd.h> | |||||
#include <signal.h> | |||||
#include <sys/stat.h> | |||||
#include <sys/wait.h> | |||||
#ifdef CARLA_OS_MAC | |||||
#else | |||||
#include <dirent.h> | |||||
#include <fnmatch.h> | |||||
#endif | |||||
#endif | |||||
// #include <wctype.h> | // #include <wctype.h> | ||||
@@ -29,18 +48,87 @@ | |||||
namespace juce2 | namespace juce2 | ||||
{ | { | ||||
#ifdef CARLA_OS_WIN | |||||
static Result getResultForLastError() | |||||
{ | |||||
TCHAR messageBuffer [256] = { 0 }; | |||||
FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, | |||||
nullptr, GetLastError(), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), | |||||
messageBuffer, (DWORD) numElementsInArray (messageBuffer) - 1, nullptr); | |||||
return Result::fail (String (messageBuffer)); | |||||
} | |||||
static int64 juce_fileSetPosition (void* handle, int64 pos) | |||||
{ | |||||
LARGE_INTEGER li; | |||||
li.QuadPart = pos; | |||||
li.LowPart = SetFilePointer ((HANDLE) handle, (LONG) li.LowPart, &li.HighPart, FILE_BEGIN); // (returns -1 if it fails) | |||||
return li.QuadPart; | |||||
} | |||||
static void* currentModuleHandle = nullptr; | |||||
void* JUCE_CALLTYPE Process::getCurrentModuleInstanceHandle() noexcept | |||||
{ | |||||
if (currentModuleHandle == nullptr) | |||||
currentModuleHandle = GetModuleHandleA (nullptr); | |||||
return currentModuleHandle; | |||||
} | |||||
#else | |||||
static Result getResultForErrno() | |||||
{ | |||||
return Result::fail (String (strerror (errno))); | |||||
} | |||||
static int getFD (void* handle) noexcept { return (int) (pointer_sized_int) handle; } | |||||
static void* fdToVoidPointer (int fd) noexcept { return (void*) (pointer_sized_int) fd; } | |||||
static int64 juce_fileSetPosition (void* handle, int64 pos) | |||||
{ | |||||
if (handle != 0 && lseek (getFD (handle), pos, SEEK_SET) == pos) | |||||
return pos; | |||||
return -1; | |||||
} | |||||
#endif | |||||
#include "memory/juce_MemoryBlock.cpp" | #include "memory/juce_MemoryBlock.cpp" | ||||
#include "text/juce_CharacterFunctions.cpp" | #include "text/juce_CharacterFunctions.cpp" | ||||
#include "text/juce_String.cpp" | #include "text/juce_String.cpp" | ||||
// #include "streams/juce_InputStream.cpp" | |||||
// #include "streams/juce_OutputStream.cpp" | |||||
//#include "containers/juce_NamedValueSet.cpp" | |||||
//#include "containers/juce_Variant.cpp" | |||||
#include "files/juce_DirectoryIterator.cpp" | |||||
#include "files/juce_File.cpp" | |||||
#include "files/juce_TemporaryFile.cpp" | |||||
#include "midi/juce_MidiBuffer.cpp" | #include "midi/juce_MidiBuffer.cpp" | ||||
#include "midi/juce_MidiMessage.cpp" | #include "midi/juce_MidiMessage.cpp" | ||||
#include "maths/juce_Random.cpp" | |||||
#include "misc/juce_Result.cpp" | |||||
#include "processors/juce_AudioProcessor.cpp" | #include "processors/juce_AudioProcessor.cpp" | ||||
#include "processors/juce_AudioProcessorGraph.cpp" | |||||
//#include "processors/juce_AudioProcessorGraph.cpp" | |||||
#include "streams/juce_FileInputSource.cpp" | |||||
#include "streams/juce_FileInputStream.cpp" | |||||
#include "streams/juce_FileOutputStream.cpp" | |||||
#include "streams/juce_InputStream.cpp" | |||||
#include "streams/juce_MemoryOutputStream.cpp" | |||||
#include "streams/juce_OutputStream.cpp" | |||||
#include "text/juce_Identifier.cpp" | |||||
#include "text/juce_StringArray.cpp" | |||||
#include "text/juce_StringPool.cpp" | |||||
#include "threads/juce_ChildProcess.cpp" | |||||
#include "time/juce_Time.cpp" | |||||
#include "xml/juce_XmlElement.cpp" | #include "xml/juce_XmlElement.cpp" | ||||
#include "xml/juce_XmlDocument.cpp" | #include "xml/juce_XmlDocument.cpp" | ||||
@@ -19,9 +19,9 @@ | |||||
#ifndef JUCE_AUDIO_GRAPH_H_INCLUDED | #ifndef JUCE_AUDIO_GRAPH_H_INCLUDED | ||||
#define JUCE_AUDIO_GRAPH_H_INCLUDED | #define JUCE_AUDIO_GRAPH_H_INCLUDED | ||||
#include "CarlaMathUtils.hpp" | |||||
#include "CarlaJuceUtils.hpp" | #include "CarlaJuceUtils.hpp" | ||||
#include "CarlaMutex.hpp" | #include "CarlaMutex.hpp" | ||||
#include "distrho/extra/ScopedPointer.hpp" | |||||
#include <algorithm> | #include <algorithm> | ||||
@@ -144,6 +144,10 @@ class XmlElement; | |||||
#include "text/juce_Identifier.h" | #include "text/juce_Identifier.h" | ||||
#include "text/juce_NewLine.h" | #include "text/juce_NewLine.h" | ||||
#include "threads/juce_ScopedLock.h" | |||||
#include "threads/juce_SpinLock.h" | |||||
#include "memory/juce_SharedResourcePointer.h" | |||||
#include "containers/juce_LinkedListPointer.h" | #include "containers/juce_LinkedListPointer.h" | ||||
#include "containers/juce_OwnedArray.h" | #include "containers/juce_OwnedArray.h" | ||||
#include "containers/juce_ReferenceCountedArray.h" | #include "containers/juce_ReferenceCountedArray.h" | ||||
@@ -156,13 +160,19 @@ class XmlElement; | |||||
#include "streams/juce_OutputStream.h" | #include "streams/juce_OutputStream.h" | ||||
#include "streams/juce_MemoryOutputStream.h" | #include "streams/juce_MemoryOutputStream.h" | ||||
#include "maths/juce_Random.h" | |||||
#include "misc/juce_Result.h" | #include "misc/juce_Result.h" | ||||
#include "text/juce_StringPool.h" | #include "text/juce_StringPool.h" | ||||
#include "time/juce_Time.h" | |||||
#include "files/juce_File.h" | #include "files/juce_File.h" | ||||
#include "files/juce_DirectoryIterator.h" | |||||
#include "files/juce_TemporaryFile.h" | |||||
#include "streams/juce_FileInputStream.h" | #include "streams/juce_FileInputStream.h" | ||||
#include "streams/juce_FileInputSource.h" | #include "streams/juce_FileInputSource.h" | ||||
#include "streams/juce_FileOutputStream.h" | |||||
#include "buffers/juce_AudioSampleBuffer.h" | #include "buffers/juce_AudioSampleBuffer.h" | ||||
#include "midi/juce_MidiBuffer.h" | #include "midi/juce_MidiBuffer.h" | ||||
@@ -173,6 +183,9 @@ class AudioProcessor; | |||||
#include "processors/juce_AudioProcessor.h" | #include "processors/juce_AudioProcessor.h" | ||||
#include "processors/juce_AudioProcessorGraph.h" | #include "processors/juce_AudioProcessorGraph.h" | ||||
#include "threads/juce_ChildProcess.h" | |||||
#include "threads/juce_Process.h" | |||||
#include "xml/juce_XmlElement.h" | #include "xml/juce_XmlElement.h" | ||||
#include "xml/juce_XmlDocument.h" | #include "xml/juce_XmlDocument.h" | ||||
@@ -0,0 +1,163 @@ | |||||
/* | |||||
============================================================================== | |||||
This file is part of the JUCE library. | |||||
Copyright (c) 2016 - ROLI Ltd. | |||||
Permission is granted to use this software under the terms of the ISC license | |||||
http://www.isc.org/downloads/software-support-policy/isc-license/ | |||||
Permission to use, copy, modify, and/or distribute this software for any | |||||
purpose with or without fee is hereby granted, provided that the above | |||||
copyright notice and this permission notice appear in all copies. | |||||
THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD | |||||
TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |||||
FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, | |||||
OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF | |||||
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | |||||
OF THIS SOFTWARE. | |||||
----------------------------------------------------------------------------- | |||||
To release a closed-source product which uses other parts of JUCE not | |||||
licensed under the ISC terms, commercial licenses are available: visit | |||||
www.juce.com for more information. | |||||
============================================================================== | |||||
*/ | |||||
Random::Random (const int64 seedValue) noexcept : seed (seedValue) | |||||
{ | |||||
} | |||||
Random::Random() : seed (1) | |||||
{ | |||||
setSeedRandomly(); | |||||
} | |||||
Random::~Random() noexcept | |||||
{ | |||||
} | |||||
void Random::setSeed (const int64 newSeed) noexcept | |||||
{ | |||||
seed = newSeed; | |||||
} | |||||
void Random::combineSeed (const int64 seedValue) noexcept | |||||
{ | |||||
seed ^= nextInt64() ^ seedValue; | |||||
} | |||||
void Random::setSeedRandomly() | |||||
{ | |||||
static int64 globalSeed = 0; | |||||
combineSeed (globalSeed ^ (int64) (pointer_sized_int) this); | |||||
#if 0 | |||||
combineSeed (Time::getMillisecondCounter()); | |||||
combineSeed (Time::getHighResolutionTicks()); | |||||
combineSeed (Time::getHighResolutionTicksPerSecond()); | |||||
#endif | |||||
combineSeed (Time::currentTimeMillis()); | |||||
globalSeed ^= seed; | |||||
} | |||||
Random& Random::getSystemRandom() noexcept | |||||
{ | |||||
static Random sysRand; | |||||
return sysRand; | |||||
} | |||||
//============================================================================== | |||||
int Random::nextInt() noexcept | |||||
{ | |||||
seed = (seed * 0x5deece66dLL + 11) & 0xffffffffffffLL; | |||||
return (int) (seed >> 16); | |||||
} | |||||
int Random::nextInt (const int maxValue) noexcept | |||||
{ | |||||
jassert (maxValue > 0); | |||||
return (int) ((((unsigned int) nextInt()) * (uint64) maxValue) >> 32); | |||||
} | |||||
#if 0 | |||||
int Random::nextInt (Range<int> range) noexcept | |||||
{ | |||||
return range.getStart() + nextInt (range.getLength()); | |||||
} | |||||
#endif | |||||
int64 Random::nextInt64() noexcept | |||||
{ | |||||
return (((int64) nextInt()) << 32) | (int64) (uint64) (uint32) nextInt(); | |||||
} | |||||
bool Random::nextBool() noexcept | |||||
{ | |||||
return (nextInt() & 0x40000000) != 0; | |||||
} | |||||
float Random::nextFloat() noexcept | |||||
{ | |||||
return static_cast<uint32> (nextInt()) / (std::numeric_limits<uint32>::max() + 1.0f); | |||||
} | |||||
double Random::nextDouble() noexcept | |||||
{ | |||||
return static_cast<uint32> (nextInt()) / (std::numeric_limits<uint32>::max() + 1.0); | |||||
} | |||||
#if 0 | |||||
BigInteger Random::nextLargeNumber (const BigInteger& maximumValue) | |||||
{ | |||||
BigInteger n; | |||||
do | |||||
{ | |||||
fillBitsRandomly (n, 0, maximumValue.getHighestBit() + 1); | |||||
} | |||||
while (n >= maximumValue); | |||||
return n; | |||||
} | |||||
void Random::fillBitsRandomly (void* const buffer, size_t bytes) | |||||
{ | |||||
int* d = static_cast<int*> (buffer); | |||||
for (; bytes >= sizeof (int); bytes -= sizeof (int)) | |||||
*d++ = nextInt(); | |||||
if (bytes > 0) | |||||
{ | |||||
const int lastBytes = nextInt(); | |||||
memcpy (d, &lastBytes, bytes); | |||||
} | |||||
} | |||||
void Random::fillBitsRandomly (BigInteger& arrayToChange, int startBit, int numBits) | |||||
{ | |||||
arrayToChange.setBit (startBit + numBits - 1, true); // to force the array to pre-allocate space | |||||
while ((startBit & 31) != 0 && numBits > 0) | |||||
{ | |||||
arrayToChange.setBit (startBit++, nextBool()); | |||||
--numBits; | |||||
} | |||||
while (numBits >= 32) | |||||
{ | |||||
arrayToChange.setBitRangeAsInt (startBit, 32, (unsigned int) nextInt()); | |||||
startBit += 32; | |||||
numBits -= 32; | |||||
} | |||||
while (--numBits >= 0) | |||||
arrayToChange.setBit (startBit + numBits, nextBool()); | |||||
} | |||||
#endif |
@@ -0,0 +1,149 @@ | |||||
/* | |||||
============================================================================== | |||||
This file is part of the JUCE library. | |||||
Copyright (c) 2016 - ROLI Ltd. | |||||
Permission is granted to use this software under the terms of the ISC license | |||||
http://www.isc.org/downloads/software-support-policy/isc-license/ | |||||
Permission to use, copy, modify, and/or distribute this software for any | |||||
purpose with or without fee is hereby granted, provided that the above | |||||
copyright notice and this permission notice appear in all copies. | |||||
THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD | |||||
TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |||||
FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, | |||||
OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF | |||||
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | |||||
OF THIS SOFTWARE. | |||||
----------------------------------------------------------------------------- | |||||
To release a closed-source product which uses other parts of JUCE not | |||||
licensed under the ISC terms, commercial licenses are available: visit | |||||
www.juce.com for more information. | |||||
============================================================================== | |||||
*/ | |||||
#ifndef JUCE_RANDOM_H_INCLUDED | |||||
#define JUCE_RANDOM_H_INCLUDED | |||||
//============================================================================== | |||||
/** | |||||
A random number generator. | |||||
You can create a Random object and use it to generate a sequence of random numbers. | |||||
*/ | |||||
class JUCE_API Random | |||||
{ | |||||
public: | |||||
//============================================================================== | |||||
/** Creates a Random object based on a seed value. | |||||
For a given seed value, the subsequent numbers generated by this object | |||||
will be predictable, so a good idea is to set this value based | |||||
on the time, e.g. | |||||
new Random (Time::currentTimeMillis()) | |||||
*/ | |||||
explicit Random (int64 seedValue) noexcept; | |||||
/** Creates a Random object using a random seed value. | |||||
Internally, this calls setSeedRandomly() to randomise the seed. | |||||
*/ | |||||
Random(); | |||||
/** Destructor. */ | |||||
~Random() noexcept; | |||||
/** Returns the next random 32 bit integer. | |||||
@returns a random integer from the full range 0x80000000 to 0x7fffffff | |||||
*/ | |||||
int nextInt() noexcept; | |||||
/** Returns the next random number, limited to a given range. | |||||
The maxValue parameter may not be negative, or zero. | |||||
@returns a random integer between 0 (inclusive) and maxValue (exclusive). | |||||
*/ | |||||
int nextInt (int maxValue) noexcept; | |||||
#if 0 | |||||
/** Returns the next random number, limited to a given range. | |||||
@returns a random integer between the range start (inclusive) and its end (exclusive). | |||||
*/ | |||||
int nextInt (Range<int> range) noexcept; | |||||
#endif | |||||
/** Returns the next 64-bit random number. | |||||
@returns a random integer from the full range 0x8000000000000000 to 0x7fffffffffffffff | |||||
*/ | |||||
int64 nextInt64() noexcept; | |||||
/** Returns the next random floating-point number. | |||||
@returns a random value in the range 0 (inclusive) to 1.0 (exclusive) | |||||
*/ | |||||
float nextFloat() noexcept; | |||||
/** Returns the next random floating-point number. | |||||
@returns a random value in the range 0 (inclusive) to 1.0 (exclusive) | |||||
*/ | |||||
double nextDouble() noexcept; | |||||
/** Returns the next random boolean value. */ | |||||
bool nextBool() noexcept; | |||||
#if 0 | |||||
/** Returns a BigInteger containing a random number. | |||||
@returns a random value in the range 0 to (maximumValue - 1). | |||||
*/ | |||||
BigInteger nextLargeNumber (const BigInteger& maximumValue); | |||||
/** Fills a block of memory with random values. */ | |||||
void fillBitsRandomly (void* bufferToFill, size_t sizeInBytes); | |||||
/** Sets a range of bits in a BigInteger to random values. */ | |||||
void fillBitsRandomly (BigInteger& arrayToChange, int startBit, int numBits); | |||||
#endif | |||||
//============================================================================== | |||||
/** Resets this Random object to a given seed value. */ | |||||
void setSeed (int64 newSeed) noexcept; | |||||
/** Returns the RNG's current seed. */ | |||||
int64 getSeed() const noexcept { return seed; } | |||||
/** Merges this object's seed with another value. | |||||
This sets the seed to be a value created by combining the current seed and this | |||||
new value. | |||||
*/ | |||||
void combineSeed (int64 seedValue) noexcept; | |||||
/** Reseeds this generator using a value generated from various semi-random system | |||||
properties like the current time, etc. | |||||
Because this function convolves the time with the last seed value, calling | |||||
it repeatedly will increase the randomness of the final result. | |||||
*/ | |||||
void setSeedRandomly(); | |||||
/** The overhead of creating a new Random object is fairly small, but if you want to avoid | |||||
it, you can call this method to get a global shared Random object. | |||||
It's not thread-safe though, so threads should use their own Random object, otherwise | |||||
you run the risk of your random numbers becoming.. erm.. randomly corrupted.. | |||||
*/ | |||||
static Random& getSystemRandom() noexcept; | |||||
private: | |||||
//============================================================================== | |||||
int64 seed; | |||||
JUCE_LEAK_DETECTOR (Random) | |||||
}; | |||||
#endif // JUCE_RANDOM_H_INCLUDED |
@@ -110,7 +110,7 @@ inline void writeUnaligned (void* dstPtr, Type value) noexcept | |||||
#if (JUCE_COMPILER_SUPPORTS_ARC && defined (__OBJC__)) || DOXYGEN | #if (JUCE_COMPILER_SUPPORTS_ARC && defined (__OBJC__)) || DOXYGEN | ||||
#define JUCE_AUTORELEASEPOOL @autoreleasepool | #define JUCE_AUTORELEASEPOOL @autoreleasepool | ||||
#else | #else | ||||
#define JUCE_AUTORELEASEPOOL const juce::ScopedAutoReleasePool JUCE_JOIN_MACRO (autoReleasePool_, __LINE__); | |||||
#define JUCE_AUTORELEASEPOOL const juce2::ScopedAutoReleasePool JUCE_JOIN_MACRO (autoReleasePool_, __LINE__); | |||||
#endif | #endif | ||||
#else | #else | ||||
@@ -0,0 +1,168 @@ | |||||
/* | |||||
============================================================================== | |||||
This file is part of the JUCE library. | |||||
Copyright (c) 2016 - ROLI Ltd. | |||||
Permission is granted to use this software under the terms of the ISC license | |||||
http://www.isc.org/downloads/software-support-policy/isc-license/ | |||||
Permission to use, copy, modify, and/or distribute this software for any | |||||
purpose with or without fee is hereby granted, provided that the above | |||||
copyright notice and this permission notice appear in all copies. | |||||
THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD | |||||
TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |||||
FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, | |||||
OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF | |||||
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | |||||
OF THIS SOFTWARE. | |||||
----------------------------------------------------------------------------- | |||||
To release a closed-source product which uses other parts of JUCE not | |||||
licensed under the ISC terms, commercial licenses are available: visit | |||||
www.juce.com for more information. | |||||
============================================================================== | |||||
*/ | |||||
#ifndef JUCE_SHAREDRESOURCEPOINTER_H_INCLUDED | |||||
#define JUCE_SHAREDRESOURCEPOINTER_H_INCLUDED | |||||
//============================================================================== | |||||
/** | |||||
A smart-pointer that automatically creates and manages the lifetime of a | |||||
shared static instance of a class. | |||||
The SharedObjectType template type indicates the class to use for the shared | |||||
object - the only requirements on this class are that it must have a public | |||||
default constructor and destructor. | |||||
The SharedResourcePointer offers a pattern that differs from using a singleton or | |||||
static instance of an object, because it uses reference-counting to make sure that | |||||
the underlying shared object is automatically created/destroyed according to the | |||||
number of SharedResourcePointer objects that exist. When the last one is deleted, | |||||
the underlying object is also immediately destroyed. This allows you to use scoping | |||||
to manage the lifetime of a shared resource. | |||||
Note: the construction/deletion of the shared object must not involve any | |||||
code that makes recursive calls to a SharedResourcePointer, or you'll cause | |||||
a deadlock. | |||||
Example: | |||||
@code | |||||
// An example of a class that contains the shared data you want to use. | |||||
struct MySharedData | |||||
{ | |||||
// There's no need to ever create an instance of this class directly yourself, | |||||
// but it does need a public constructor that does the initialisation. | |||||
MySharedData() | |||||
{ | |||||
sharedStuff = generateHeavyweightStuff(); | |||||
} | |||||
Array<SomeKindOfData> sharedStuff; | |||||
}; | |||||
struct DataUserClass | |||||
{ | |||||
DataUserClass() | |||||
{ | |||||
// Multiple instances of the DataUserClass will all have the same | |||||
// shared common instance of MySharedData referenced by their sharedData | |||||
// member variables. | |||||
useSharedStuff (sharedData->sharedStuff); | |||||
} | |||||
// By keeping this pointer as a member variable, the shared resource | |||||
// is guaranteed to be available for as long as the DataUserClass object. | |||||
SharedResourcePointer<MySharedData> sharedData; | |||||
}; | |||||
@endcode | |||||
*/ | |||||
template <typename SharedObjectType> | |||||
class SharedResourcePointer | |||||
{ | |||||
public: | |||||
/** Creates an instance of the shared object. | |||||
If other SharedResourcePointer objects for this type already exist, then | |||||
this one will simply point to the same shared object that they are already | |||||
using. Otherwise, if this is the first SharedResourcePointer to be created, | |||||
then a shared object will be created automatically. | |||||
*/ | |||||
SharedResourcePointer() | |||||
{ | |||||
initialise(); | |||||
} | |||||
SharedResourcePointer (const SharedResourcePointer&) | |||||
{ | |||||
initialise(); | |||||
} | |||||
/** Destructor. | |||||
If no other SharedResourcePointer objects exist, this will also delete | |||||
the shared object to which it refers. | |||||
*/ | |||||
~SharedResourcePointer() | |||||
{ | |||||
SharedObjectHolder& holder = getSharedObjectHolder(); | |||||
const SpinLock::ScopedLockType sl (holder.lock); | |||||
if (--(holder.refCount) == 0) | |||||
holder.sharedInstance = nullptr; | |||||
} | |||||
/** Returns the shared object. */ | |||||
operator SharedObjectType*() const noexcept { return sharedObject; } | |||||
/** Returns the shared object. */ | |||||
SharedObjectType& get() const noexcept { return *sharedObject; } | |||||
/** Returns the object that this pointer references. | |||||
The pointer returned may be a nullptr, of course. | |||||
*/ | |||||
SharedObjectType& getObject() const noexcept { return *sharedObject; } | |||||
SharedObjectType* operator->() const noexcept { return sharedObject; } | |||||
private: | |||||
struct SharedObjectHolder : public ReferenceCountedObject | |||||
{ | |||||
SpinLock lock; | |||||
ScopedPointer<SharedObjectType> sharedInstance; | |||||
int refCount; | |||||
}; | |||||
static SharedObjectHolder& getSharedObjectHolder() noexcept | |||||
{ | |||||
static void* holder [(sizeof (SharedObjectHolder) + sizeof(void*) - 1) / sizeof(void*)] = { 0 }; | |||||
return *reinterpret_cast<SharedObjectHolder*> (holder); | |||||
} | |||||
SharedObjectType* sharedObject; | |||||
void initialise() | |||||
{ | |||||
SharedObjectHolder& holder = getSharedObjectHolder(); | |||||
const SpinLock::ScopedLockType sl (holder.lock); | |||||
if (++(holder.refCount) == 1) | |||||
holder.sharedInstance = new SharedObjectType(); | |||||
sharedObject = holder.sharedInstance; | |||||
} | |||||
// There's no need to assign to a SharedResourcePointer because every | |||||
// instance of the class is exactly the same! | |||||
SharedResourcePointer& operator= (const SharedResourcePointer&) JUCE_DELETED_FUNCTION; | |||||
JUCE_LEAK_DETECTOR (SharedResourcePointer) | |||||
}; | |||||
#endif // JUCE_SHAREDRESOURCEPOINTER_H_INCLUDED |
@@ -47,6 +47,7 @@ InputStream* FileInputSource::createInputStreamFor (const String& relatedItemPat | |||||
return file.getSiblingFile (relatedItemPath).createInputStream(); | return file.getSiblingFile (relatedItemPath).createInputStream(); | ||||
} | } | ||||
#if 0 | |||||
int64 FileInputSource::hashCode() const | int64 FileInputSource::hashCode() const | ||||
{ | { | ||||
int64 h = file.hashCode(); | int64 h = file.hashCode(); | ||||
@@ -56,3 +57,4 @@ int64 FileInputSource::hashCode() const | |||||
return h; | return h; | ||||
} | } | ||||
#endif |
@@ -84,3 +84,69 @@ bool FileInputStream::setPosition (int64 pos) | |||||
return currentPosition == pos; | return currentPosition == pos; | ||||
} | } | ||||
#ifdef CARLA_OS_WIN | |||||
FileInputStream::~FileInputStream() | |||||
{ | |||||
CloseHandle ((HANDLE) fileHandle); | |||||
} | |||||
void FileInputStream::openHandle() | |||||
{ | |||||
HANDLE h = CreateFile (file.getFullPathName().toUTF8(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, | |||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, 0); | |||||
if (h != INVALID_HANDLE_VALUE) | |||||
fileHandle = (void*) h; | |||||
else | |||||
status = getResultForLastError(); | |||||
} | |||||
size_t FileInputStream::readInternal (void* buffer, size_t numBytes) | |||||
{ | |||||
if (fileHandle != 0) | |||||
{ | |||||
DWORD actualNum = 0; | |||||
if (! ReadFile ((HANDLE) fileHandle, buffer, (DWORD) numBytes, &actualNum, 0)) | |||||
status = getResultForLastError(); | |||||
return (size_t) actualNum; | |||||
} | |||||
return 0; | |||||
} | |||||
#else | |||||
FileInputStream::~FileInputStream() | |||||
{ | |||||
if (fileHandle != 0) | |||||
close (getFD (fileHandle)); | |||||
} | |||||
void FileInputStream::openHandle() | |||||
{ | |||||
const int f = open (file.getFullPathName().toUTF8(), O_RDONLY, 00644); | |||||
if (f != -1) | |||||
fileHandle = fdToVoidPointer (f); | |||||
else | |||||
status = getResultForErrno(); | |||||
} | |||||
size_t FileInputStream::readInternal (void* const buffer, const size_t numBytes) | |||||
{ | |||||
ssize_t result = 0; | |||||
if (fileHandle != 0) | |||||
{ | |||||
result = ::read (getFD (fileHandle), buffer, numBytes); | |||||
if (result < 0) | |||||
{ | |||||
status = getResultForErrno(); | |||||
result = 0; | |||||
} | |||||
} | |||||
return (size_t) result; | |||||
} | |||||
#endif |
@@ -0,0 +1,255 @@ | |||||
/* | |||||
============================================================================== | |||||
This file is part of the JUCE library. | |||||
Copyright (c) 2016 - ROLI Ltd. | |||||
Permission is granted to use this software under the terms of the ISC license | |||||
http://www.isc.org/downloads/software-support-policy/isc-license/ | |||||
Permission to use, copy, modify, and/or distribute this software for any | |||||
purpose with or without fee is hereby granted, provided that the above | |||||
copyright notice and this permission notice appear in all copies. | |||||
THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD | |||||
TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |||||
FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, | |||||
OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF | |||||
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | |||||
OF THIS SOFTWARE. | |||||
----------------------------------------------------------------------------- | |||||
To release a closed-source product which uses other parts of JUCE not | |||||
licensed under the ISC terms, commercial licenses are available: visit | |||||
www.juce.com for more information. | |||||
============================================================================== | |||||
*/ | |||||
int64 juce_fileSetPosition (void* handle, int64 pos); | |||||
//============================================================================== | |||||
FileOutputStream::FileOutputStream (const File& f, const size_t bufferSizeToUse) | |||||
: file (f), | |||||
fileHandle (nullptr), | |||||
status (Result::ok()), | |||||
currentPosition (0), | |||||
bufferSize (bufferSizeToUse), | |||||
bytesInBuffer (0), | |||||
buffer (jmax (bufferSizeToUse, (size_t) 16)) | |||||
{ | |||||
openHandle(); | |||||
} | |||||
FileOutputStream::~FileOutputStream() | |||||
{ | |||||
flushBuffer(); | |||||
closeHandle(); | |||||
} | |||||
int64 FileOutputStream::getPosition() | |||||
{ | |||||
return currentPosition; | |||||
} | |||||
bool FileOutputStream::setPosition (int64 newPosition) | |||||
{ | |||||
if (newPosition != currentPosition) | |||||
{ | |||||
flushBuffer(); | |||||
currentPosition = juce_fileSetPosition (fileHandle, newPosition); | |||||
} | |||||
return newPosition == currentPosition; | |||||
} | |||||
bool FileOutputStream::flushBuffer() | |||||
{ | |||||
bool ok = true; | |||||
if (bytesInBuffer > 0) | |||||
{ | |||||
ok = (writeInternal (buffer, bytesInBuffer) == (ssize_t) bytesInBuffer); | |||||
bytesInBuffer = 0; | |||||
} | |||||
return ok; | |||||
} | |||||
void FileOutputStream::flush() | |||||
{ | |||||
flushBuffer(); | |||||
flushInternal(); | |||||
} | |||||
bool FileOutputStream::write (const void* const src, const size_t numBytes) | |||||
{ | |||||
jassert (src != nullptr && ((ssize_t) numBytes) >= 0); | |||||
if (bytesInBuffer + numBytes < bufferSize) | |||||
{ | |||||
memcpy (buffer + bytesInBuffer, src, numBytes); | |||||
bytesInBuffer += numBytes; | |||||
currentPosition += (int64) numBytes; | |||||
} | |||||
else | |||||
{ | |||||
if (! flushBuffer()) | |||||
return false; | |||||
if (numBytes < bufferSize) | |||||
{ | |||||
memcpy (buffer + bytesInBuffer, src, numBytes); | |||||
bytesInBuffer += numBytes; | |||||
currentPosition += (int64) numBytes; | |||||
} | |||||
else | |||||
{ | |||||
const ssize_t bytesWritten = writeInternal (src, numBytes); | |||||
if (bytesWritten < 0) | |||||
return false; | |||||
currentPosition += (int64) bytesWritten; | |||||
return bytesWritten == (ssize_t) numBytes; | |||||
} | |||||
} | |||||
return true; | |||||
} | |||||
bool FileOutputStream::writeRepeatedByte (uint8 byte, size_t numBytes) | |||||
{ | |||||
jassert (((ssize_t) numBytes) >= 0); | |||||
if (bytesInBuffer + numBytes < bufferSize) | |||||
{ | |||||
memset (buffer + bytesInBuffer, byte, numBytes); | |||||
bytesInBuffer += numBytes; | |||||
currentPosition += (int64) numBytes; | |||||
return true; | |||||
} | |||||
return OutputStream::writeRepeatedByte (byte, numBytes); | |||||
} | |||||
#ifdef CARLA_OS_WIN | |||||
void FileOutputStream::openHandle() | |||||
{ | |||||
HANDLE h = CreateFile (file.getFullPathName().toUTF8(), GENERIC_WRITE, FILE_SHARE_READ, 0, | |||||
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); | |||||
if (h != INVALID_HANDLE_VALUE) | |||||
{ | |||||
LARGE_INTEGER li; | |||||
li.QuadPart = 0; | |||||
li.LowPart = SetFilePointer (h, 0, &li.HighPart, FILE_END); | |||||
if (li.LowPart != INVALID_SET_FILE_POINTER) | |||||
{ | |||||
fileHandle = (void*) h; | |||||
currentPosition = li.QuadPart; | |||||
return; | |||||
} | |||||
} | |||||
status = getResultForLastError(); | |||||
} | |||||
void FileOutputStream::closeHandle() | |||||
{ | |||||
CloseHandle ((HANDLE) fileHandle); | |||||
} | |||||
ssize_t FileOutputStream::writeInternal (const void* bufferToWrite, size_t numBytes) | |||||
{ | |||||
if (fileHandle != nullptr) | |||||
{ | |||||
DWORD actualNum = 0; | |||||
if (! WriteFile ((HANDLE) fileHandle, bufferToWrite, (DWORD) numBytes, &actualNum, 0)) | |||||
status = getResultForLastError(); | |||||
return (ssize_t) actualNum; | |||||
} | |||||
return 0; | |||||
} | |||||
void FileOutputStream::flushInternal() | |||||
{ | |||||
if (fileHandle != nullptr) | |||||
if (! FlushFileBuffers ((HANDLE) fileHandle)) | |||||
status = getResultForLastError(); | |||||
} | |||||
#else | |||||
void FileOutputStream::openHandle() | |||||
{ | |||||
if (file.exists()) | |||||
{ | |||||
const int f = open (file.getFullPathName().toUTF8(), O_RDWR, 00644); | |||||
if (f != -1) | |||||
{ | |||||
currentPosition = lseek (f, 0, SEEK_END); | |||||
if (currentPosition >= 0) | |||||
{ | |||||
fileHandle = fdToVoidPointer (f); | |||||
} | |||||
else | |||||
{ | |||||
status = getResultForErrno(); | |||||
close (f); | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
status = getResultForErrno(); | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
const int f = open (file.getFullPathName().toUTF8(), O_RDWR + O_CREAT, 00644); | |||||
if (f != -1) | |||||
fileHandle = fdToVoidPointer (f); | |||||
else | |||||
status = getResultForErrno(); | |||||
} | |||||
} | |||||
void FileOutputStream::closeHandle() | |||||
{ | |||||
if (fileHandle != 0) | |||||
{ | |||||
close (getFD (fileHandle)); | |||||
fileHandle = 0; | |||||
} | |||||
} | |||||
ssize_t FileOutputStream::writeInternal (const void* const data, const size_t numBytes) | |||||
{ | |||||
ssize_t result = 0; | |||||
if (fileHandle != 0) | |||||
{ | |||||
result = ::write (getFD (fileHandle), data, numBytes); | |||||
if (result == -1) | |||||
status = getResultForErrno(); | |||||
} | |||||
return result; | |||||
} | |||||
void FileOutputStream::flushInternal() | |||||
{ | |||||
if (fileHandle != 0) | |||||
{ | |||||
if (fsync (getFD (fileHandle)) == -1) | |||||
status = getResultForErrno(); | |||||
} | |||||
} | |||||
#endif |
@@ -0,0 +1,122 @@ | |||||
/* | |||||
============================================================================== | |||||
This file is part of the JUCE library. | |||||
Copyright (c) 2016 - ROLI Ltd. | |||||
Permission is granted to use this software under the terms of the ISC license | |||||
http://www.isc.org/downloads/software-support-policy/isc-license/ | |||||
Permission to use, copy, modify, and/or distribute this software for any | |||||
purpose with or without fee is hereby granted, provided that the above | |||||
copyright notice and this permission notice appear in all copies. | |||||
THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD | |||||
TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |||||
FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, | |||||
OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF | |||||
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | |||||
OF THIS SOFTWARE. | |||||
----------------------------------------------------------------------------- | |||||
To release a closed-source product which uses other parts of JUCE not | |||||
licensed under the ISC terms, commercial licenses are available: visit | |||||
www.juce.com for more information. | |||||
============================================================================== | |||||
*/ | |||||
#ifndef JUCE_FILEOUTPUTSTREAM_H_INCLUDED | |||||
#define JUCE_FILEOUTPUTSTREAM_H_INCLUDED | |||||
//============================================================================== | |||||
/** | |||||
An output stream that writes into a local file. | |||||
@see OutputStream, FileInputStream, File::createOutputStream | |||||
*/ | |||||
class JUCE_API FileOutputStream : public OutputStream | |||||
{ | |||||
public: | |||||
//============================================================================== | |||||
/** Creates a FileOutputStream. | |||||
If the file doesn't exist, it will first be created. If the file can't be | |||||
created or opened (for example, because the parent directory of the file | |||||
does not exist), the failedToOpen() method will return true. | |||||
If the file already exists when opened, the stream's write-position will | |||||
be set to the end of the file. To overwrite an existing file, | |||||
use File::deleteFile() before opening the stream, or use setPosition(0) | |||||
after it's opened (although this won't truncate the file). | |||||
Destroying a FileOutputStream object does not force the operating system | |||||
to write the buffered data to disk immediately. If this is required you | |||||
should call flush() before triggering the destructor. | |||||
@see TemporaryFile | |||||
*/ | |||||
FileOutputStream (const File& fileToWriteTo, | |||||
size_t bufferSizeToUse = 16384); | |||||
/** Destructor. */ | |||||
~FileOutputStream(); | |||||
//============================================================================== | |||||
/** Returns the file that this stream is writing to. | |||||
*/ | |||||
const File& getFile() const { return file; } | |||||
/** Returns the status of the file stream. | |||||
The result will be ok if the file opened successfully. If an error occurs while | |||||
opening or writing to the file, this will contain an error message. | |||||
*/ | |||||
const Result& getStatus() const noexcept { return status; } | |||||
/** Returns true if the stream couldn't be opened for some reason. | |||||
@see getResult() | |||||
*/ | |||||
bool failedToOpen() const noexcept { return status.failed(); } | |||||
/** Returns true if the stream opened without problems. | |||||
@see getResult() | |||||
*/ | |||||
bool openedOk() const noexcept { return status.wasOk(); } | |||||
/** Attempts to truncate the file to the current write position. | |||||
To truncate a file to a specific size, first use setPosition() to seek to the | |||||
appropriate location, and then call this method. | |||||
*/ | |||||
Result truncate(); | |||||
//============================================================================== | |||||
void flush() override; | |||||
int64 getPosition() override; | |||||
bool setPosition (int64) override; | |||||
bool write (const void*, size_t) override; | |||||
bool writeRepeatedByte (uint8 byte, size_t numTimesToRepeat) override; | |||||
private: | |||||
//============================================================================== | |||||
File file; | |||||
void* fileHandle; | |||||
Result status; | |||||
int64 currentPosition; | |||||
size_t bufferSize, bytesInBuffer; | |||||
HeapBlock<char> buffer; | |||||
void openHandle(); | |||||
void closeHandle(); | |||||
void flushInternal(); | |||||
bool flushBuffer(); | |||||
int64 setPositionInternal (int64); | |||||
ssize_t writeInternal (const void*, size_t); | |||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FileOutputStream) | |||||
}; | |||||
#endif // JUCE_FILEOUTPUTSTREAM_H_INCLUDED |
@@ -66,10 +66,11 @@ public: | |||||
*/ | */ | ||||
virtual InputStream* createInputStreamFor (const String& relatedItemPath) = 0; | virtual InputStream* createInputStreamFor (const String& relatedItemPath) = 0; | ||||
#if 0 | |||||
/** Returns a hash code that uniquely represents this item. | /** Returns a hash code that uniquely represents this item. | ||||
*/ | */ | ||||
virtual int64 hashCode() const = 0; | virtual int64 hashCode() const = 0; | ||||
#endif | |||||
private: | private: | ||||
//============================================================================== | //============================================================================== | ||||
@@ -176,16 +176,7 @@ bool OutputStream::writeDoubleBigEndian (double value) | |||||
bool OutputStream::writeString (const String& text) | bool OutputStream::writeString (const String& text) | ||||
{ | { | ||||
#if (JUCE_STRING_UTF_TYPE == 8) | |||||
return write (text.toRawUTF8(), text.getNumBytesAsUTF8() + 1); | return write (text.toRawUTF8(), text.getNumBytesAsUTF8() + 1); | ||||
#else | |||||
// (This avoids using toUTF8() to prevent the memory bloat that it would leave behind | |||||
// if lots of large, persistent strings were to be written to streams). | |||||
const size_t numBytes = text.getNumBytesAsUTF8() + 1; | |||||
HeapBlock<char> temp (numBytes); | |||||
text.copyToUTF8 (temp, numBytes); | |||||
return write (temp, numBytes); | |||||
#endif | |||||
} | } | ||||
bool OutputStream::writeText (const String& text, const bool asUTF16, | bool OutputStream::writeText (const String& text, const bool asUTF16, | ||||
@@ -476,11 +476,8 @@ public: | |||||
/** Parses this string as a 64-bit integer. */ | /** Parses this string as a 64-bit integer. */ | ||||
int64 getIntValue64() const noexcept | int64 getIntValue64() const noexcept | ||||
{ | { | ||||
#if JUCE_LINUX || JUCE_ANDROID || JUCE_MINGW | |||||
return atoll (data); | return atoll (data); | ||||
#elif JUCE_WINDOWS | |||||
return _atoi64 (data); | |||||
#else | |||||
#if 0 | |||||
return CharacterFunctions::getIntValue <int64, CharPointer_UTF8> (*this); | return CharacterFunctions::getIntValue <int64, CharPointer_UTF8> (*this); | ||||
#endif | #endif | ||||
} | } | ||||
@@ -42,7 +42,7 @@ juce_wchar CharacterFunctions::toLowerCase (const juce_wchar character) noexcept | |||||
bool CharacterFunctions::isUpperCase (const juce_wchar character) noexcept | bool CharacterFunctions::isUpperCase (const juce_wchar character) noexcept | ||||
{ | { | ||||
#if JUCE_WINDOWS | |||||
#ifdef CARLA_OS_WIN | |||||
return iswupper ((wint_t) character) != 0; | return iswupper ((wint_t) character) != 0; | ||||
#else | #else | ||||
return toLowerCase (character) != character; | return toLowerCase (character) != character; | ||||
@@ -51,7 +51,7 @@ bool CharacterFunctions::isUpperCase (const juce_wchar character) noexcept | |||||
bool CharacterFunctions::isLowerCase (const juce_wchar character) noexcept | bool CharacterFunctions::isLowerCase (const juce_wchar character) noexcept | ||||
{ | { | ||||
#if JUCE_WINDOWS | |||||
#ifdef CARLA_OS_WIN | |||||
return iswlower ((wint_t) character) != 0; | return iswlower ((wint_t) character) != 0; | ||||
#else | #else | ||||
return toUpperCase (character) != character; | return toUpperCase (character) != character; | ||||
@@ -729,6 +729,11 @@ String& String::operator+= (const char ch) | |||||
return operator+= (asString); | return operator+= (asString); | ||||
} | } | ||||
String& String::operator+= (const juce_wchar ch) | |||||
{ | |||||
return operator+= (charToString(ch)); | |||||
} | |||||
namespace StringHelpers | namespace StringHelpers | ||||
{ | { | ||||
template <typename T> | template <typename T> | ||||
@@ -754,6 +759,10 @@ JUCE_API String JUCE_CALLTYPE operator+ (String s1, const String& s2) | |||||
JUCE_API String JUCE_CALLTYPE operator+ (String s1, const char* const s2) { return s1 += s2; } | JUCE_API String JUCE_CALLTYPE operator+ (String s1, const char* const s2) { return s1 += s2; } | ||||
JUCE_API String JUCE_CALLTYPE operator+ (String s1, const char s2) { return s1 += s2; } | JUCE_API String JUCE_CALLTYPE operator+ (String s1, const char s2) { return s1 += s2; } | ||||
JUCE_API String JUCE_CALLTYPE operator+ (const juce_wchar s1, const String& s2) { return String::charToString (s1) + s2; } | |||||
JUCE_API String JUCE_CALLTYPE operator+ (String s1, const juce_wchar s2) { return s1 += s2; } | |||||
JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const juce_wchar s2) { return s1 += s2; } | |||||
JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const char s2) { return s1 += s2; } | JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const char s2) { return s1 += s2; } | ||||
JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const char* const s2) { return s1 += s2; } | JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const char* const s2) { return s1 += s2; } | ||||
JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const String& s2) { return s1 += s2; } | JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const String& s2) { return s1 += s2; } | ||||
@@ -1723,6 +1732,43 @@ bool String::containsNonWhitespaceChars() const noexcept | |||||
return false; | return false; | ||||
} | } | ||||
//===================================================================================================================== | |||||
static String getStringFromWindows1252Codepage (const char* data, size_t num) | |||||
{ | |||||
HeapBlock<char> unicode (num + 1); | |||||
for (size_t i = 0; i < num; ++i) | |||||
unicode[i] = CharacterFunctions::getUnicodeCharFromWindows1252Codepage ((uint8) data[i]); | |||||
unicode[num] = 0; | |||||
return CharPointer_UTF8 (unicode); | |||||
} | |||||
String String::createStringFromData (const void* const unknownData, int size) | |||||
{ | |||||
const uint8* const data = static_cast<const uint8*> (unknownData); | |||||
if (size <= 0 || data == nullptr) | |||||
return String(); | |||||
if (size == 1) | |||||
return charToString ((juce_wchar) data[0]); | |||||
const char* start = (const char*) data; | |||||
if (size >= 3 && CharPointer_UTF8::isByteOrderMark (data)) | |||||
{ | |||||
start += 3; | |||||
size -= 3; | |||||
} | |||||
if (CharPointer_UTF8::isValidString (start, size)) | |||||
return String (CharPointer_UTF8 (start), | |||||
CharPointer_UTF8 (start + size)); | |||||
return getStringFromWindows1252Codepage (start, (size_t) size); | |||||
} | |||||
// Note! The format parameter here MUST NOT be a reference, otherwise MS's va_start macro fails to work (but still compiles). | // Note! The format parameter here MUST NOT be a reference, otherwise MS's va_start macro fails to work (but still compiles). | ||||
String String::formatted (const String pf, ... ) | String String::formatted (const String pf, ... ) | ||||
{ | { | ||||
@@ -115,18 +115,7 @@ public: | |||||
/** Destructor. */ | /** Destructor. */ | ||||
~String() noexcept; | ~String() noexcept; | ||||
/** This is the character encoding type used internally to store the string. | |||||
By setting the value of JUCE_STRING_UTF_TYPE to 8, 16, or 32, you can change the | |||||
internal storage format of the String class. UTF-8 uses the least space (if your strings | |||||
contain few extended characters), but call operator[] involves iterating the string to find | |||||
the required index. UTF-32 provides instant random access to its characters, but uses 4 bytes | |||||
per character to store them. UTF-16 uses more space than UTF-8 and is also slow to index, | |||||
but is the native wchar_t format used in Windows. | |||||
It doesn't matter too much which format you pick, because the toUTF8(), toUTF16() and | |||||
toUTF32() methods let you access the string's content in any of the other formats. | |||||
*/ | |||||
/** This is the character encoding type used internally to store the string. */ | |||||
typedef CharPointer_UTF8 CharPointerType; | typedef CharPointer_UTF8 CharPointerType; | ||||
//============================================================================== | //============================================================================== | ||||
@@ -168,6 +157,8 @@ public: | |||||
String& operator+= (uint64 numberToAppend); | String& operator+= (uint64 numberToAppend); | ||||
/** Appends a character at the end of this string. */ | /** Appends a character at the end of this string. */ | ||||
String& operator+= (char characterToAppend); | String& operator+= (char characterToAppend); | ||||
/** Appends a character at the end of this string. */ | |||||
String& operator+= (juce_wchar characterToAppend); | |||||
/** Appends a string to the end of this one. | /** Appends a string to the end of this one. | ||||
@@ -807,6 +798,16 @@ public: | |||||
*/ | */ | ||||
String paddedRight (juce_wchar padCharacter, int minimumLength) const; | String paddedRight (juce_wchar padCharacter, int minimumLength) const; | ||||
/** Creates a string from data in an unknown format. | |||||
This looks at some binary data and tries to guess whether it's Unicode | |||||
or 8-bit characters, then returns a string that represents it correctly. | |||||
Should be able to handle Unicode endianness correctly, by looking at | |||||
the first two bytes. | |||||
*/ | |||||
static String createStringFromData (const void* data, int size); | |||||
/** Creates a String from a printf-style parameter list. | /** Creates a String from a printf-style parameter list. | ||||
I don't like this method. I don't use it myself, and I recommend avoiding it and | I don't like this method. I don't use it myself, and I recommend avoiding it and | ||||
@@ -1103,6 +1104,8 @@ private: | |||||
JUCE_API String JUCE_CALLTYPE operator+ (const char* string1, const String& string2); | JUCE_API String JUCE_CALLTYPE operator+ (const char* string1, const String& string2); | ||||
/** Concatenates two strings. */ | /** Concatenates two strings. */ | ||||
JUCE_API String JUCE_CALLTYPE operator+ (char string1, const String& string2); | JUCE_API String JUCE_CALLTYPE operator+ (char string1, const String& string2); | ||||
/** Concatenates two strings. */ | |||||
JUCE_API String JUCE_CALLTYPE operator+ (juce_wchar string1, const String& string2); | |||||
/** Concatenates two strings. */ | /** Concatenates two strings. */ | ||||
JUCE_API String JUCE_CALLTYPE operator+ (String string1, const String& string2); | JUCE_API String JUCE_CALLTYPE operator+ (String string1, const String& string2); | ||||
@@ -1110,10 +1113,14 @@ JUCE_API String JUCE_CALLTYPE operator+ (String string1, const String& string2); | |||||
JUCE_API String JUCE_CALLTYPE operator+ (String string1, const char* string2); | JUCE_API String JUCE_CALLTYPE operator+ (String string1, const char* string2); | ||||
/** Concatenates two strings. */ | /** Concatenates two strings. */ | ||||
JUCE_API String JUCE_CALLTYPE operator+ (String string1, char characterToAppend); | JUCE_API String JUCE_CALLTYPE operator+ (String string1, char characterToAppend); | ||||
/** Concatenates two strings. */ | |||||
JUCE_API String JUCE_CALLTYPE operator+ (String string1, juce_wchar characterToAppend); | |||||
//============================================================================== | //============================================================================== | ||||
/** Appends a character at the end of a string. */ | /** Appends a character at the end of a string. */ | ||||
JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, char characterToAppend); | JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, char characterToAppend); | ||||
/** Appends a character at the end of a string. */ | |||||
JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, juce_wchar characterToAppend); | |||||
/** Appends a string to the end of the first one. */ | /** Appends a string to the end of the first one. */ | ||||
JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const char* string2); | JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const char* string2); | ||||
@@ -64,16 +64,6 @@ StringArray::StringArray (const char* const* initialStrings, int numberOfStrings | |||||
strings.addArray (initialStrings, numberOfStrings); | strings.addArray (initialStrings, numberOfStrings); | ||||
} | } | ||||
StringArray::StringArray (const wchar_t* const* initialStrings) | |||||
{ | |||||
strings.addNullTerminatedArray (initialStrings); | |||||
} | |||||
StringArray::StringArray (const wchar_t* const* initialStrings, int numberOfStrings) | |||||
{ | |||||
strings.addArray (initialStrings, numberOfStrings); | |||||
} | |||||
StringArray& StringArray::operator= (const StringArray& other) | StringArray& StringArray::operator= (const StringArray& other) | ||||
{ | { | ||||
strings = other.strings; | strings = other.strings; | ||||
@@ -75,19 +75,6 @@ public: | |||||
*/ | */ | ||||
explicit StringArray (const char* const* strings); | explicit StringArray (const char* const* strings); | ||||
/** Creates a copy of a null-terminated array of string literals. | |||||
Each item from the array passed-in is added, until it encounters a null pointer, | |||||
at which point it stops. | |||||
*/ | |||||
explicit StringArray (const wchar_t* const* strings); | |||||
/** Creates a copy of an array of string literals. | |||||
@param strings an array of strings to add. Null pointers in the array will be | |||||
treated as empty strings | |||||
@param numberOfStrings how many items there are in the array | |||||
*/ | |||||
StringArray (const wchar_t* const* strings, int numberOfStrings); | |||||
#if JUCE_COMPILER_SUPPORTS_INITIALIZER_LISTS | #if JUCE_COMPILER_SUPPORTS_INITIALIZER_LISTS | ||||
StringArray (const std::initializer_list<const char*>& strings); | StringArray (const std::initializer_list<const char*>& strings); | ||||
#endif | #endif | ||||
@@ -108,7 +108,7 @@ String StringPool::getPooledString (const char* const newString) | |||||
if (newString == nullptr || *newString == 0) | if (newString == nullptr || *newString == 0) | ||||
return String(); | return String(); | ||||
const ScopedLock sl (lock); | |||||
const CarlaRecursiveMutexLocker sl (lock); | |||||
garbageCollectIfNeeded(); | garbageCollectIfNeeded(); | ||||
return addPooledString (strings, CharPointer_UTF8 (newString)); | return addPooledString (strings, CharPointer_UTF8 (newString)); | ||||
} | } | ||||
@@ -118,7 +118,7 @@ String StringPool::getPooledString (String::CharPointerType start, String::CharP | |||||
if (start.isEmpty() || start == end) | if (start.isEmpty() || start == end) | ||||
return String(); | return String(); | ||||
const ScopedLock sl (lock); | |||||
const CarlaRecursiveMutexLocker sl (lock); | |||||
garbageCollectIfNeeded(); | garbageCollectIfNeeded(); | ||||
return addPooledString (strings, StartEndString (start, end)); | return addPooledString (strings, StartEndString (start, end)); | ||||
} | } | ||||
@@ -128,7 +128,7 @@ String StringPool::getPooledString (StringRef newString) | |||||
if (newString.isEmpty()) | if (newString.isEmpty()) | ||||
return String(); | return String(); | ||||
const ScopedLock sl (lock); | |||||
const CarlaRecursiveMutexLocker sl (lock); | |||||
garbageCollectIfNeeded(); | garbageCollectIfNeeded(); | ||||
return addPooledString (strings, newString.text); | return addPooledString (strings, newString.text); | ||||
} | } | ||||
@@ -138,7 +138,7 @@ String StringPool::getPooledString (const String& newString) | |||||
if (newString.isEmpty()) | if (newString.isEmpty()) | ||||
return String(); | return String(); | ||||
const ScopedLock sl (lock); | |||||
const CarlaRecursiveMutexLocker sl (lock); | |||||
garbageCollectIfNeeded(); | garbageCollectIfNeeded(); | ||||
return addPooledString (strings, newString); | return addPooledString (strings, newString); | ||||
} | } | ||||
@@ -152,7 +152,7 @@ void StringPool::garbageCollectIfNeeded() | |||||
void StringPool::garbageCollect() | void StringPool::garbageCollect() | ||||
{ | { | ||||
const ScopedLock sl (lock); | |||||
const CarlaRecursiveMutexLocker sl (lock); | |||||
for (int i = strings.size(); --i >= 0;) | for (int i = strings.size(); --i >= 0;) | ||||
if (strings.getReference(i).getReferenceCount() == 1) | if (strings.getReference(i).getReferenceCount() == 1) | ||||
@@ -0,0 +1,399 @@ | |||||
/* | |||||
============================================================================== | |||||
This file is part of the JUCE library. | |||||
Copyright (c) 2016 - ROLI Ltd. | |||||
Permission is granted to use this software under the terms of the ISC license | |||||
http://www.isc.org/downloads/software-support-policy/isc-license/ | |||||
Permission to use, copy, modify, and/or distribute this software for any | |||||
purpose with or without fee is hereby granted, provided that the above | |||||
copyright notice and this permission notice appear in all copies. | |||||
THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD | |||||
TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |||||
FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, | |||||
OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF | |||||
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | |||||
OF THIS SOFTWARE. | |||||
----------------------------------------------------------------------------- | |||||
To release a closed-source product which uses other parts of JUCE not | |||||
licensed under the ISC terms, commercial licenses are available: visit | |||||
www.juce.com for more information. | |||||
============================================================================== | |||||
*/ | |||||
#define JUCE_USE_VFORK 1 | |||||
#ifdef CARLA_OS_WIN | |||||
//===================================================================================================================== | |||||
class ChildProcess::ActiveProcess | |||||
{ | |||||
public: | |||||
ActiveProcess (const String& command, int streamFlags) | |||||
: ok (false), readPipe (0), writePipe (0) | |||||
{ | |||||
SECURITY_ATTRIBUTES securityAtts; | |||||
carla_zeroStruct(securityAtts); | |||||
securityAtts.nLength = sizeof (securityAtts); | |||||
securityAtts.bInheritHandle = TRUE; | |||||
if (CreatePipe (&readPipe, &writePipe, &securityAtts, 0) | |||||
&& SetHandleInformation (readPipe, HANDLE_FLAG_INHERIT, 0)) | |||||
{ | |||||
STARTUPINFO startupInfo; | |||||
carla_zeroStruct(startupInfo); | |||||
startupInfo.cb = sizeof (startupInfo); | |||||
startupInfo.hStdOutput = (streamFlags & wantStdOut) != 0 ? writePipe : 0; | |||||
startupInfo.hStdError = (streamFlags & wantStdErr) != 0 ? writePipe : 0; | |||||
startupInfo.dwFlags = STARTF_USESTDHANDLES; | |||||
ok = CreateProcess (nullptr, const_cast<LPSTR>(command.toRawUTF8()), | |||||
nullptr, nullptr, TRUE, CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT, | |||||
nullptr, nullptr, &startupInfo, &processInfo) != FALSE; | |||||
} | |||||
} | |||||
~ActiveProcess() | |||||
{ | |||||
if (ok) | |||||
{ | |||||
CloseHandle (processInfo.hThread); | |||||
CloseHandle (processInfo.hProcess); | |||||
} | |||||
if (readPipe != 0) | |||||
CloseHandle (readPipe); | |||||
if (writePipe != 0) | |||||
CloseHandle (writePipe); | |||||
} | |||||
bool isRunning() const noexcept | |||||
{ | |||||
return WaitForSingleObject (processInfo.hProcess, 0) != WAIT_OBJECT_0; | |||||
} | |||||
int read (void* dest, int numNeeded) const noexcept | |||||
{ | |||||
int total = 0; | |||||
while (ok && numNeeded > 0) | |||||
{ | |||||
DWORD available = 0; | |||||
if (! PeekNamedPipe ((HANDLE) readPipe, nullptr, 0, nullptr, &available, nullptr)) | |||||
break; | |||||
const int numToDo = jmin ((int) available, numNeeded); | |||||
if (available == 0) | |||||
{ | |||||
if (! isRunning()) | |||||
break; | |||||
Sleep(0); | |||||
} | |||||
else | |||||
{ | |||||
DWORD numRead = 0; | |||||
if (! ReadFile ((HANDLE) readPipe, dest, numToDo, &numRead, nullptr)) | |||||
break; | |||||
total += numRead; | |||||
dest = addBytesToPointer (dest, numRead); | |||||
numNeeded -= numRead; | |||||
} | |||||
} | |||||
return total; | |||||
} | |||||
bool killProcess() const noexcept | |||||
{ | |||||
return TerminateProcess (processInfo.hProcess, 0) != FALSE; | |||||
} | |||||
uint32 getExitCode() const noexcept | |||||
{ | |||||
DWORD exitCode = 0; | |||||
GetExitCodeProcess (processInfo.hProcess, &exitCode); | |||||
return (uint32) exitCode; | |||||
} | |||||
int getPID() const noexcept | |||||
{ | |||||
return 0; | |||||
} | |||||
bool ok; | |||||
private: | |||||
HANDLE readPipe, writePipe; | |||||
PROCESS_INFORMATION processInfo; | |||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ActiveProcess) | |||||
}; | |||||
#else | |||||
class ChildProcess::ActiveProcess | |||||
{ | |||||
public: | |||||
ActiveProcess (const StringArray& arguments, int streamFlags) | |||||
: childPID (0), pipeHandle (0), readHandle (0) | |||||
{ | |||||
String exe (arguments[0].unquoted()); | |||||
// Looks like you're trying to launch a non-existent exe or a folder (perhaps on OSX | |||||
// you're trying to launch the .app folder rather than the actual binary inside it?) | |||||
jassert (File::getCurrentWorkingDirectory().getChildFile (exe).existsAsFile() | |||||
|| ! exe.containsChar (File::separator)); | |||||
int pipeHandles[2] = { 0 }; | |||||
if (pipe (pipeHandles) == 0) | |||||
{ | |||||
Array<char*> argv; | |||||
for (int i = 0; i < arguments.size(); ++i) | |||||
if (arguments[i].isNotEmpty()) | |||||
argv.add (const_cast<char*> (arguments[i].toRawUTF8())); | |||||
argv.add (nullptr); | |||||
#if JUCE_USE_VFORK | |||||
const pid_t result = vfork(); | |||||
#else | |||||
const pid_t result = fork(); | |||||
#endif | |||||
if (result < 0) | |||||
{ | |||||
close (pipeHandles[0]); | |||||
close (pipeHandles[1]); | |||||
} | |||||
else if (result == 0) | |||||
{ | |||||
#if ! JUCE_USE_VFORK | |||||
// we're the child process.. | |||||
close (pipeHandles[0]); // close the read handle | |||||
if ((streamFlags & wantStdOut) != 0) | |||||
dup2 (pipeHandles[1], STDOUT_FILENO); // turns the pipe into stdout | |||||
else | |||||
dup2 (open ("/dev/null", O_WRONLY), STDOUT_FILENO); | |||||
if ((streamFlags & wantStdErr) != 0) | |||||
dup2 (pipeHandles[1], STDERR_FILENO); | |||||
else | |||||
dup2 (open ("/dev/null", O_WRONLY), STDERR_FILENO); | |||||
close (pipeHandles[1]); | |||||
#endif | |||||
if (execvp (exe.toRawUTF8(), argv.getRawDataPointer())) | |||||
_exit (-1); | |||||
} | |||||
else | |||||
{ | |||||
// we're the parent process.. | |||||
childPID = result; | |||||
pipeHandle = pipeHandles[0]; | |||||
close (pipeHandles[1]); // close the write handle | |||||
} | |||||
// FIXME | |||||
(void)streamFlags; | |||||
} | |||||
} | |||||
~ActiveProcess() | |||||
{ | |||||
if (readHandle != 0) | |||||
fclose (readHandle); | |||||
if (pipeHandle != 0) | |||||
close (pipeHandle); | |||||
} | |||||
bool isRunning() const noexcept | |||||
{ | |||||
if (childPID != 0) | |||||
{ | |||||
int childState; | |||||
const int pid = waitpid (childPID, &childState, WNOHANG); | |||||
return pid == 0 || ! (WIFEXITED (childState) || WIFSIGNALED (childState)); | |||||
} | |||||
return false; | |||||
} | |||||
int read (void* const dest, const int numBytes) noexcept | |||||
{ | |||||
jassert (dest != nullptr); | |||||
#ifdef fdopen | |||||
#error // the zlib headers define this function as NULL! | |||||
#endif | |||||
if (readHandle == 0 && childPID != 0) | |||||
readHandle = fdopen (pipeHandle, "r"); | |||||
if (readHandle != 0) | |||||
return (int) fread (dest, 1, (size_t) numBytes, readHandle); | |||||
return 0; | |||||
} | |||||
bool killProcess() const noexcept | |||||
{ | |||||
return ::kill (childPID, SIGKILL) == 0; | |||||
} | |||||
uint32 getExitCode() const noexcept | |||||
{ | |||||
if (childPID != 0) | |||||
{ | |||||
int childState = 0; | |||||
const int pid = waitpid (childPID, &childState, WNOHANG); | |||||
if (pid >= 0 && WIFEXITED (childState)) | |||||
return WEXITSTATUS (childState); | |||||
} | |||||
return 0; | |||||
} | |||||
int getPID() const noexcept | |||||
{ | |||||
return childPID; | |||||
} | |||||
int childPID; | |||||
private: | |||||
int pipeHandle; | |||||
FILE* readHandle; | |||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ActiveProcess) | |||||
}; | |||||
#endif | |||||
//===================================================================================================================== | |||||
ChildProcess::ChildProcess() {} | |||||
ChildProcess::~ChildProcess() {} | |||||
bool ChildProcess::isRunning() const | |||||
{ | |||||
return activeProcess != nullptr && activeProcess->isRunning(); | |||||
} | |||||
int ChildProcess::readProcessOutput (void* dest, int numBytes) | |||||
{ | |||||
return activeProcess != nullptr ? activeProcess->read (dest, numBytes) : 0; | |||||
} | |||||
bool ChildProcess::kill() | |||||
{ | |||||
return activeProcess == nullptr || activeProcess->killProcess(); | |||||
} | |||||
uint32 ChildProcess::getExitCode() const | |||||
{ | |||||
return activeProcess != nullptr ? activeProcess->getExitCode() : 0; | |||||
} | |||||
bool ChildProcess::waitForProcessToFinish (const int timeoutMs) const | |||||
{ | |||||
const uint32 timeoutTime = Time::getMillisecondCounter() + (uint32) timeoutMs; | |||||
do | |||||
{ | |||||
if (! isRunning()) | |||||
return true; | |||||
} | |||||
while (timeoutMs < 0 || Time::getMillisecondCounter() < timeoutTime); | |||||
return false; | |||||
} | |||||
String ChildProcess::readAllProcessOutput() | |||||
{ | |||||
MemoryOutputStream result; | |||||
for (;;) | |||||
{ | |||||
char buffer [512]; | |||||
const int num = readProcessOutput (buffer, sizeof (buffer)); | |||||
if (num <= 0) | |||||
break; | |||||
result.write (buffer, (size_t) num); | |||||
} | |||||
return result.toString(); | |||||
} | |||||
uint32 ChildProcess::getPID() const noexcept | |||||
{ | |||||
return activeProcess != nullptr ? activeProcess->getPID() : 0; | |||||
} | |||||
//===================================================================================================================== | |||||
#ifdef CARLA_OS_WIN | |||||
bool ChildProcess::start (const String& command, int streamFlags) | |||||
{ | |||||
activeProcess = new ActiveProcess (command, streamFlags); | |||||
if (! activeProcess->ok) | |||||
activeProcess = nullptr; | |||||
return activeProcess != nullptr; | |||||
} | |||||
bool ChildProcess::start (const StringArray& args, int streamFlags) | |||||
{ | |||||
String escaped; | |||||
for (int i = 0; i < args.size(); ++i) | |||||
{ | |||||
String arg (args[i]); | |||||
#if 0 // FIXME | |||||
// If there are spaces, surround it with quotes. If there are quotes, | |||||
// replace them with \" so that CommandLineToArgv will correctly parse them. | |||||
if (arg.containsAnyOf ("\" ")) | |||||
arg = arg.replace ("\"", "\\\"").quoted(); | |||||
#endif | |||||
escaped << arg << ' '; | |||||
} | |||||
return start (escaped.trim(), streamFlags); | |||||
} | |||||
#else | |||||
bool ChildProcess::start (const String& command, int streamFlags) | |||||
{ | |||||
return start (StringArray::fromTokens (command, true), streamFlags); | |||||
} | |||||
bool ChildProcess::start (const StringArray& args, int streamFlags) | |||||
{ | |||||
if (args.size() == 0) | |||||
return false; | |||||
activeProcess = new ActiveProcess (args, streamFlags); | |||||
if (activeProcess->childPID == 0) | |||||
activeProcess = nullptr; | |||||
return activeProcess != nullptr; | |||||
} | |||||
#endif |
@@ -0,0 +1,122 @@ | |||||
/* | |||||
============================================================================== | |||||
This file is part of the JUCE library. | |||||
Copyright (c) 2016 - ROLI Ltd. | |||||
Permission is granted to use this software under the terms of the ISC license | |||||
http://www.isc.org/downloads/software-support-policy/isc-license/ | |||||
Permission to use, copy, modify, and/or distribute this software for any | |||||
purpose with or without fee is hereby granted, provided that the above | |||||
copyright notice and this permission notice appear in all copies. | |||||
THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD | |||||
TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |||||
FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, | |||||
OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF | |||||
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | |||||
OF THIS SOFTWARE. | |||||
----------------------------------------------------------------------------- | |||||
To release a closed-source product which uses other parts of JUCE not | |||||
licensed under the ISC terms, commercial licenses are available: visit | |||||
www.juce.com for more information. | |||||
============================================================================== | |||||
*/ | |||||
#ifndef JUCE_CHILDPROCESS_H_INCLUDED | |||||
#define JUCE_CHILDPROCESS_H_INCLUDED | |||||
//============================================================================== | |||||
/** | |||||
Launches and monitors a child process. | |||||
This class lets you launch an executable, and read its output. You can also | |||||
use it to check whether the child process has finished. | |||||
*/ | |||||
class JUCE_API ChildProcess | |||||
{ | |||||
public: | |||||
//============================================================================== | |||||
/** Creates a process object. | |||||
To actually launch the process, use start(). | |||||
*/ | |||||
ChildProcess(); | |||||
/** Destructor. | |||||
Note that deleting this object won't terminate the child process. | |||||
*/ | |||||
~ChildProcess(); | |||||
/** These flags are used by the start() methods. */ | |||||
enum StreamFlags | |||||
{ | |||||
wantStdOut = 1, | |||||
wantStdErr = 2 | |||||
}; | |||||
/** Attempts to launch a child process command. | |||||
The command should be the name of the executable file, followed by any arguments | |||||
that are required. | |||||
If the process has already been launched, this will launch it again. If a problem | |||||
occurs, the method will return false. | |||||
The streamFlags is a combinations of values to indicate which of the child's output | |||||
streams should be read and returned by readProcessOutput(). | |||||
*/ | |||||
bool start (const String& command, int streamFlags = wantStdOut | wantStdErr); | |||||
/** Attempts to launch a child process command. | |||||
The first argument should be the name of the executable file, followed by any other | |||||
arguments that are needed. | |||||
If the process has already been launched, this will launch it again. If a problem | |||||
occurs, the method will return false. | |||||
The streamFlags is a combinations of values to indicate which of the child's output | |||||
streams should be read and returned by readProcessOutput(). | |||||
*/ | |||||
bool start (const StringArray& arguments, int streamFlags = wantStdOut | wantStdErr); | |||||
/** Returns true if the child process is alive. */ | |||||
bool isRunning() const; | |||||
/** Attempts to read some output from the child process. | |||||
This will attempt to read up to the given number of bytes of data from the | |||||
process. It returns the number of bytes that were actually read. | |||||
*/ | |||||
int readProcessOutput (void* destBuffer, int numBytesToRead); | |||||
/** Blocks until the process has finished, and then returns its complete output | |||||
as a string. | |||||
*/ | |||||
String readAllProcessOutput(); | |||||
/** Blocks until the process is no longer running. */ | |||||
bool waitForProcessToFinish (int timeoutMs) const; | |||||
/** If the process has finished, this returns its exit code. */ | |||||
uint32 getExitCode() const; | |||||
/** Attempts to kill the child process. | |||||
Returns true if it succeeded. Trying to read from the process after calling this may | |||||
result in undefined behaviour. | |||||
*/ | |||||
bool kill(); | |||||
uint32 getPID() const noexcept; | |||||
private: | |||||
//============================================================================== | |||||
class ActiveProcess; | |||||
ScopedPointer<ActiveProcess> activeProcess; | |||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChildProcess) | |||||
}; | |||||
#endif // JUCE_CHILDPROCESS_H_INCLUDED |
@@ -0,0 +1,164 @@ | |||||
/* | |||||
============================================================================== | |||||
This file is part of the JUCE library. | |||||
Copyright (c) 2016 - ROLI Ltd. | |||||
Permission is granted to use this software under the terms of the ISC license | |||||
http://www.isc.org/downloads/software-support-policy/isc-license/ | |||||
Permission to use, copy, modify, and/or distribute this software for any | |||||
purpose with or without fee is hereby granted, provided that the above | |||||
copyright notice and this permission notice appear in all copies. | |||||
THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD | |||||
TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |||||
FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, | |||||
OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF | |||||
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | |||||
OF THIS SOFTWARE. | |||||
----------------------------------------------------------------------------- | |||||
To release a closed-source product which uses other parts of JUCE not | |||||
licensed under the ISC terms, commercial licenses are available: visit | |||||
www.juce.com for more information. | |||||
============================================================================== | |||||
*/ | |||||
#ifndef JUCE_PROCESS_H_INCLUDED | |||||
#define JUCE_PROCESS_H_INCLUDED | |||||
//============================================================================== | |||||
/** Represents the current executable's process. | |||||
This contains methods for controlling the current application at the | |||||
process-level. | |||||
@see Thread, JUCEApplicationBase | |||||
*/ | |||||
class JUCE_API Process | |||||
{ | |||||
public: | |||||
//============================================================================== | |||||
enum ProcessPriority | |||||
{ | |||||
LowPriority = 0, | |||||
NormalPriority = 1, | |||||
HighPriority = 2, | |||||
RealtimePriority = 3 | |||||
}; | |||||
/** Changes the current process's priority. | |||||
@param priority the process priority, where | |||||
0=low, 1=normal, 2=high, 3=realtime | |||||
*/ | |||||
static void JUCE_CALLTYPE setPriority (const ProcessPriority priority); | |||||
/** Kills the current process immediately. | |||||
This is an emergency process terminator that kills the application | |||||
immediately - it's intended only for use only when something goes | |||||
horribly wrong. | |||||
@see JUCEApplicationBase::quit | |||||
*/ | |||||
static void JUCE_CALLTYPE terminate(); | |||||
//============================================================================== | |||||
/** Returns true if this application process is the one that the user is | |||||
currently using. | |||||
*/ | |||||
static bool JUCE_CALLTYPE isForegroundProcess(); | |||||
/** Attempts to make the current process the active one. | |||||
(This is not possible on some platforms). | |||||
*/ | |||||
static void JUCE_CALLTYPE makeForegroundProcess(); | |||||
/** Hides the application (on an OS that supports this, e.g. OSX) */ | |||||
static void JUCE_CALLTYPE hide(); | |||||
//============================================================================== | |||||
/** Raises the current process's privilege level. | |||||
Does nothing if this isn't supported by the current OS, or if process | |||||
privilege level is fixed. | |||||
*/ | |||||
static void JUCE_CALLTYPE raisePrivilege(); | |||||
/** Lowers the current process's privilege level. | |||||
Does nothing if this isn't supported by the current OS, or if process | |||||
privilege level is fixed. | |||||
*/ | |||||
static void JUCE_CALLTYPE lowerPrivilege(); | |||||
//============================================================================== | |||||
/** Returns true if this process is being hosted by a debugger. */ | |||||
static bool JUCE_CALLTYPE isRunningUnderDebugger() noexcept; | |||||
//============================================================================== | |||||
/** Tries to launch the OS's default reader application for a given file or URL. */ | |||||
static bool JUCE_CALLTYPE openDocument (const String& documentURL, const String& parameters); | |||||
/** Tries to launch the OS's default email application to let the user create a message. */ | |||||
static bool JUCE_CALLTYPE openEmailWithAttachments (const String& targetEmailAddress, | |||||
const String& emailSubject, | |||||
const String& bodyText, | |||||
const StringArray& filesToAttach); | |||||
#ifdef CARLA_OS_WIN | |||||
//============================================================================== | |||||
/** WINDOWS ONLY - This returns the HINSTANCE of the current module. | |||||
The return type is a void* to avoid being dependent on windows.h - just cast | |||||
it to a HINSTANCE to use it. | |||||
In a normal JUCE application, this will be automatically set to the module | |||||
handle of the executable. | |||||
If you've built a DLL and plan to use any JUCE messaging or windowing classes, | |||||
you'll need to make sure you call the setCurrentModuleInstanceHandle() | |||||
to provide the correct module handle in your DllMain() function, because | |||||
the system relies on the correct instance handle when opening windows. | |||||
*/ | |||||
static void* JUCE_CALLTYPE getCurrentModuleInstanceHandle() noexcept; | |||||
/** WINDOWS ONLY - Sets a new module handle to be used by the library. | |||||
The parameter type is a void* to avoid being dependent on windows.h, but it actually | |||||
expects a HINSTANCE value. | |||||
@see getCurrentModuleInstanceHandle() | |||||
*/ | |||||
static void JUCE_CALLTYPE setCurrentModuleInstanceHandle (void* newHandle) noexcept; | |||||
#endif | |||||
#if JUCE_MAC || DOXYGEN | |||||
//============================================================================== | |||||
/** OSX ONLY - Shows or hides the OSX dock icon for this app. */ | |||||
static void setDockIconVisible (bool isVisible); | |||||
#endif | |||||
#if JUCE_MAC || JUCE_LINUX || DOXYGEN | |||||
//============================================================================== | |||||
/** UNIX ONLY - Attempts to use setrlimit to change the maximum number of file | |||||
handles that the app can open. Pass 0 or less as the parameter to mean | |||||
'infinite'. Returns true if it succeeds. | |||||
*/ | |||||
static bool setMaxNumberOfFileHandles (int maxNumberOfFiles) noexcept; | |||||
#endif | |||||
private: | |||||
Process(); | |||||
JUCE_DECLARE_NON_COPYABLE (Process) | |||||
}; | |||||
#endif // JUCE_PROCESS_H_INCLUDED |
@@ -0,0 +1,239 @@ | |||||
/* | |||||
============================================================================== | |||||
This file is part of the JUCE library. | |||||
Copyright (c) 2016 - ROLI Ltd. | |||||
Permission is granted to use this software under the terms of the ISC license | |||||
http://www.isc.org/downloads/software-support-policy/isc-license/ | |||||
Permission to use, copy, modify, and/or distribute this software for any | |||||
purpose with or without fee is hereby granted, provided that the above | |||||
copyright notice and this permission notice appear in all copies. | |||||
THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD | |||||
TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |||||
FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, | |||||
OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF | |||||
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | |||||
OF THIS SOFTWARE. | |||||
----------------------------------------------------------------------------- | |||||
To release a closed-source product which uses other parts of JUCE not | |||||
licensed under the ISC terms, commercial licenses are available: visit | |||||
www.juce.com for more information. | |||||
============================================================================== | |||||
*/ | |||||
#ifndef JUCE_SCOPEDLOCK_H_INCLUDED | |||||
#define JUCE_SCOPEDLOCK_H_INCLUDED | |||||
//============================================================================== | |||||
/** | |||||
Automatically locks and unlocks a mutex object. | |||||
Use one of these as a local variable to provide RAII-based locking of a mutex. | |||||
The templated class could be a CriticalSection, SpinLock, or anything else that | |||||
provides enter() and exit() methods. | |||||
e.g. @code | |||||
CriticalSection myCriticalSection; | |||||
for (;;) | |||||
{ | |||||
const GenericScopedLock<CriticalSection> myScopedLock (myCriticalSection); | |||||
// myCriticalSection is now locked | |||||
...do some stuff... | |||||
// myCriticalSection gets unlocked here. | |||||
} | |||||
@endcode | |||||
@see GenericScopedUnlock, CriticalSection, SpinLock, ScopedLock, ScopedUnlock | |||||
*/ | |||||
template <class LockType> | |||||
class GenericScopedLock | |||||
{ | |||||
public: | |||||
//============================================================================== | |||||
/** Creates a GenericScopedLock. | |||||
As soon as it is created, this will acquire the lock, and when the GenericScopedLock | |||||
object is deleted, the lock will be released. | |||||
Make sure this object is created and deleted by the same thread, | |||||
otherwise there are no guarantees what will happen! Best just to use it | |||||
as a local stack object, rather than creating one with the new() operator. | |||||
*/ | |||||
inline explicit GenericScopedLock (const LockType& lock) noexcept : lock_ (lock) { lock.enter(); } | |||||
/** Destructor. | |||||
The lock will be released when the destructor is called. | |||||
Make sure this object is created and deleted by the same thread, otherwise there are | |||||
no guarantees what will happen! | |||||
*/ | |||||
inline ~GenericScopedLock() noexcept { lock_.exit(); } | |||||
private: | |||||
//============================================================================== | |||||
const LockType& lock_; | |||||
JUCE_DECLARE_NON_COPYABLE (GenericScopedLock) | |||||
}; | |||||
//============================================================================== | |||||
/** | |||||
Automatically unlocks and re-locks a mutex object. | |||||
This is the reverse of a GenericScopedLock object - instead of locking the mutex | |||||
for the lifetime of this object, it unlocks it. | |||||
Make sure you don't try to unlock mutexes that aren't actually locked! | |||||
e.g. @code | |||||
CriticalSection myCriticalSection; | |||||
for (;;) | |||||
{ | |||||
const GenericScopedLock<CriticalSection> myScopedLock (myCriticalSection); | |||||
// myCriticalSection is now locked | |||||
... do some stuff with it locked .. | |||||
while (xyz) | |||||
{ | |||||
... do some stuff with it locked .. | |||||
const GenericScopedUnlock<CriticalSection> unlocker (myCriticalSection); | |||||
// myCriticalSection is now unlocked for the remainder of this block, | |||||
// and re-locked at the end. | |||||
...do some stuff with it unlocked ... | |||||
} | |||||
// myCriticalSection gets unlocked here. | |||||
} | |||||
@endcode | |||||
@see GenericScopedLock, CriticalSection, ScopedLock, ScopedUnlock | |||||
*/ | |||||
template <class LockType> | |||||
class GenericScopedUnlock | |||||
{ | |||||
public: | |||||
//============================================================================== | |||||
/** Creates a GenericScopedUnlock. | |||||
As soon as it is created, this will unlock the CriticalSection, and | |||||
when the ScopedLock object is deleted, the CriticalSection will | |||||
be re-locked. | |||||
Make sure this object is created and deleted by the same thread, | |||||
otherwise there are no guarantees what will happen! Best just to use it | |||||
as a local stack object, rather than creating one with the new() operator. | |||||
*/ | |||||
inline explicit GenericScopedUnlock (const LockType& lock) noexcept : lock_ (lock) { lock.exit(); } | |||||
/** Destructor. | |||||
The CriticalSection will be unlocked when the destructor is called. | |||||
Make sure this object is created and deleted by the same thread, | |||||
otherwise there are no guarantees what will happen! | |||||
*/ | |||||
inline ~GenericScopedUnlock() noexcept { lock_.enter(); } | |||||
private: | |||||
//============================================================================== | |||||
const LockType& lock_; | |||||
JUCE_DECLARE_NON_COPYABLE (GenericScopedUnlock) | |||||
}; | |||||
//============================================================================== | |||||
/** | |||||
Automatically locks and unlocks a mutex object. | |||||
Use one of these as a local variable to provide RAII-based locking of a mutex. | |||||
The templated class could be a CriticalSection, SpinLock, or anything else that | |||||
provides enter() and exit() methods. | |||||
e.g. @code | |||||
CriticalSection myCriticalSection; | |||||
for (;;) | |||||
{ | |||||
const GenericScopedTryLock<CriticalSection> myScopedTryLock (myCriticalSection); | |||||
// Unlike using a ScopedLock, this may fail to actually get the lock, so you | |||||
// should test this with the isLocked() method before doing your thread-unsafe | |||||
// action.. | |||||
if (myScopedTryLock.isLocked()) | |||||
{ | |||||
...do some stuff... | |||||
} | |||||
else | |||||
{ | |||||
..our attempt at locking failed because another thread had already locked it.. | |||||
} | |||||
// myCriticalSection gets unlocked here (if it was locked) | |||||
} | |||||
@endcode | |||||
@see CriticalSection::tryEnter, GenericScopedLock, GenericScopedUnlock | |||||
*/ | |||||
template <class LockType> | |||||
class GenericScopedTryLock | |||||
{ | |||||
public: | |||||
//============================================================================== | |||||
/** Creates a GenericScopedTryLock. | |||||
As soon as it is created, this will attempt to acquire the lock, and when the | |||||
GenericScopedTryLock is deleted, the lock will be released (if the lock was | |||||
successfully acquired). | |||||
Make sure this object is created and deleted by the same thread, | |||||
otherwise there are no guarantees what will happen! Best just to use it | |||||
as a local stack object, rather than creating one with the new() operator. | |||||
*/ | |||||
inline explicit GenericScopedTryLock (const LockType& lock) noexcept | |||||
: lock_ (lock), lockWasSuccessful (lock.tryEnter()) {} | |||||
/** Destructor. | |||||
The mutex will be unlocked (if it had been successfully locked) when the | |||||
destructor is called. | |||||
Make sure this object is created and deleted by the same thread, | |||||
otherwise there are no guarantees what will happen! | |||||
*/ | |||||
inline ~GenericScopedTryLock() noexcept { if (lockWasSuccessful) lock_.exit(); } | |||||
/** Returns true if the mutex was successfully locked. */ | |||||
bool isLocked() const noexcept { return lockWasSuccessful; } | |||||
private: | |||||
//============================================================================== | |||||
const LockType& lock_; | |||||
const bool lockWasSuccessful; | |||||
JUCE_DECLARE_NON_COPYABLE (GenericScopedTryLock) | |||||
}; | |||||
#endif // JUCE_SCOPEDLOCK_H_INCLUDED |
@@ -0,0 +1,110 @@ | |||||
/* | |||||
============================================================================== | |||||
This file is part of the JUCE library. | |||||
Copyright (c) 2016 - ROLI Ltd. | |||||
Permission is granted to use this software under the terms of the ISC license | |||||
http://www.isc.org/downloads/software-support-policy/isc-license/ | |||||
Permission to use, copy, modify, and/or distribute this software for any | |||||
purpose with or without fee is hereby granted, provided that the above | |||||
copyright notice and this permission notice appear in all copies. | |||||
THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD | |||||
TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |||||
FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, | |||||
OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF | |||||
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | |||||
OF THIS SOFTWARE. | |||||
----------------------------------------------------------------------------- | |||||
To release a closed-source product which uses other parts of JUCE not | |||||
licensed under the ISC terms, commercial licenses are available: visit | |||||
www.juce.com for more information. | |||||
============================================================================== | |||||
*/ | |||||
#ifndef JUCE_SPINLOCK_H_INCLUDED | |||||
#define JUCE_SPINLOCK_H_INCLUDED | |||||
//============================================================================== | |||||
/** | |||||
A simple spin-lock class that can be used as a simple, low-overhead mutex for | |||||
uncontended situations. | |||||
Note that unlike a CriticalSection, this type of lock is not re-entrant, and may | |||||
be less efficient when used it a highly contended situation, but it's very small and | |||||
requires almost no initialisation. | |||||
It's most appropriate for simple situations where you're only going to hold the | |||||
lock for a very brief time. | |||||
@see CriticalSection | |||||
*/ | |||||
class JUCE_API SpinLock | |||||
{ | |||||
public: | |||||
inline SpinLock() noexcept {} | |||||
inline ~SpinLock() noexcept {} | |||||
/** Acquires the lock. | |||||
This will block until the lock has been successfully acquired by this thread. | |||||
Note that a SpinLock is NOT re-entrant, and is not smart enough to know whether the | |||||
caller thread already has the lock - so if a thread tries to acquire a lock that it | |||||
already holds, this method will never return! | |||||
It's strongly recommended that you never call this method directly - instead use the | |||||
ScopedLockType class to manage the locking using an RAII pattern instead. | |||||
*/ | |||||
void enter() const noexcept | |||||
{ | |||||
if (! tryEnter()) | |||||
{ | |||||
for (int i = 20; --i >= 0;) | |||||
if (tryEnter()) | |||||
return; | |||||
while (! tryEnter()) | |||||
{ | |||||
#ifdef CARLA_OS_WIN | |||||
Sleep (0); | |||||
#else | |||||
sched_yield(); | |||||
#endif | |||||
} | |||||
} | |||||
} | |||||
/** Attempts to acquire the lock, returning true if this was successful. */ | |||||
inline bool tryEnter() const noexcept | |||||
{ | |||||
return lock.compareAndSetBool (1, 0); | |||||
} | |||||
/** Releases the lock. */ | |||||
inline void exit() const noexcept | |||||
{ | |||||
jassert (lock.value == 1); // Agh! Releasing a lock that isn't currently held! | |||||
lock = 0; | |||||
} | |||||
//============================================================================== | |||||
/** Provides the type of scoped lock to use for locking a SpinLock. */ | |||||
typedef GenericScopedLock <SpinLock> ScopedLockType; | |||||
/** Provides the type of scoped unlocker to use with a SpinLock. */ | |||||
typedef GenericScopedUnlock <SpinLock> ScopedUnlockType; | |||||
private: | |||||
//============================================================================== | |||||
mutable Atomic<int> lock; | |||||
JUCE_DECLARE_NON_COPYABLE (SpinLock) | |||||
}; | |||||
#endif // JUCE_SPINLOCK_H_INCLUDED |
@@ -0,0 +1,631 @@ | |||||
/* | |||||
============================================================================== | |||||
This file is part of the JUCE library. | |||||
Copyright (c) 2016 - ROLI Ltd. | |||||
Permission is granted to use this software under the terms of the ISC license | |||||
http://www.isc.org/downloads/software-support-policy/isc-license/ | |||||
Permission to use, copy, modify, and/or distribute this software for any | |||||
purpose with or without fee is hereby granted, provided that the above | |||||
copyright notice and this permission notice appear in all copies. | |||||
THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD | |||||
TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |||||
FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, | |||||
OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF | |||||
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | |||||
OF THIS SOFTWARE. | |||||
----------------------------------------------------------------------------- | |||||
To release a closed-source product which uses other parts of JUCE not | |||||
licensed under the ISC terms, commercial licenses are available: visit | |||||
www.juce.com for more information. | |||||
============================================================================== | |||||
*/ | |||||
namespace TimeHelpers | |||||
{ | |||||
#if 0 | |||||
static std::tm millisToLocal (int64 millis) noexcept | |||||
{ | |||||
#if JUCE_WINDOWS && JUCE_MINGW | |||||
time_t now = (time_t) (millis / 1000); | |||||
return *localtime (&now); | |||||
#elif JUCE_WINDOWS | |||||
std::tm result; | |||||
millis /= 1000; | |||||
if (_localtime64_s (&result, &millis) != 0) | |||||
zerostruct (result); | |||||
return result; | |||||
#else | |||||
std::tm result; | |||||
time_t now = (time_t) (millis / 1000); | |||||
if (localtime_r (&now, &result) == nullptr) | |||||
zerostruct (result); | |||||
return result; | |||||
#endif | |||||
} | |||||
static std::tm millisToUTC (int64 millis) noexcept | |||||
{ | |||||
#if JUCE_WINDOWS && JUCE_MINGW | |||||
time_t now = (time_t) (millis / 1000); | |||||
return *gmtime (&now); | |||||
#elif JUCE_WINDOWS | |||||
std::tm result; | |||||
millis /= 1000; | |||||
if (_gmtime64_s (&result, &millis) != 0) | |||||
zerostruct (result); | |||||
return result; | |||||
#else | |||||
std::tm result; | |||||
time_t now = (time_t) (millis / 1000); | |||||
if (gmtime_r (&now, &result) == nullptr) | |||||
zerostruct (result); | |||||
return result; | |||||
#endif | |||||
} | |||||
static int getUTCOffsetSeconds (const int64 millis) noexcept | |||||
{ | |||||
std::tm utc = millisToUTC (millis); | |||||
utc.tm_isdst = -1; // Treat this UTC time as local to find the offset | |||||
return (int) ((millis / 1000) - (int64) mktime (&utc)); | |||||
} | |||||
static int extendedModulo (const int64 value, const int modulo) noexcept | |||||
{ | |||||
return (int) (value >= 0 ? (value % modulo) | |||||
: (value - ((value / modulo) + 1) * modulo)); | |||||
} | |||||
static inline String formatString (const String& format, const std::tm* const tm) | |||||
{ | |||||
#if JUCE_ANDROID | |||||
typedef CharPointer_UTF8 StringType; | |||||
#elif JUCE_WINDOWS | |||||
typedef CharPointer_UTF16 StringType; | |||||
#else | |||||
typedef CharPointer_UTF32 StringType; | |||||
#endif | |||||
#ifdef JUCE_MSVC | |||||
if (tm->tm_year < -1900 || tm->tm_year > 8099) | |||||
return String(); // Visual Studio's library can only handle 0 -> 9999 AD | |||||
#endif | |||||
for (size_t bufferSize = 256; ; bufferSize += 256) | |||||
{ | |||||
HeapBlock<StringType::CharType> buffer (bufferSize); | |||||
const size_t numChars = | |||||
#if JUCE_ANDROID | |||||
strftime (buffer, bufferSize - 1, format.toUTF8(), tm); | |||||
#elif JUCE_WINDOWS | |||||
wcsftime (buffer, bufferSize - 1, format.toWideCharPointer(), tm); | |||||
#else | |||||
wcsftime (buffer, bufferSize - 1, format.toUTF32(), tm); | |||||
#endif | |||||
if (numChars > 0 || format.isEmpty()) | |||||
return String (StringType (buffer), | |||||
StringType (buffer) + (int) numChars); | |||||
} | |||||
} | |||||
//============================================================================== | |||||
static inline bool isLeapYear (int year) noexcept | |||||
{ | |||||
return (year % 400 == 0) || ((year % 100 != 0) && (year % 4 == 0)); | |||||
} | |||||
static inline int daysFromJan1 (int year, int month) noexcept | |||||
{ | |||||
const short dayOfYear[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, | |||||
0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }; | |||||
return dayOfYear [(isLeapYear (year) ? 12 : 0) + month]; | |||||
} | |||||
static inline int64 daysFromYear0 (int year) noexcept | |||||
{ | |||||
--year; | |||||
return 365 * year + (year / 400) - (year / 100) + (year / 4); | |||||
} | |||||
static inline int64 daysFrom1970 (int year) noexcept | |||||
{ | |||||
return daysFromYear0 (year) - daysFromYear0 (1970); | |||||
} | |||||
static inline int64 daysFrom1970 (int year, int month) noexcept | |||||
{ | |||||
if (month > 11) | |||||
{ | |||||
year += month / 12; | |||||
month %= 12; | |||||
} | |||||
else if (month < 0) | |||||
{ | |||||
const int numYears = (11 - month) / 12; | |||||
year -= numYears; | |||||
month += 12 * numYears; | |||||
} | |||||
return daysFrom1970 (year) + daysFromJan1 (year, month); | |||||
} | |||||
// There's no posix function that does a UTC version of mktime, | |||||
// so annoyingly we need to implement this manually.. | |||||
static inline int64 mktime_utc (const std::tm& t) noexcept | |||||
{ | |||||
return 24 * 3600 * (daysFrom1970 (t.tm_year + 1900, t.tm_mon) + (t.tm_mday - 1)) | |||||
+ 3600 * t.tm_hour | |||||
+ 60 * t.tm_min | |||||
+ t.tm_sec; | |||||
} | |||||
#endif | |||||
static uint32 lastMSCounterValue = 0; | |||||
} | |||||
//============================================================================== | |||||
Time::Time() noexcept : millisSinceEpoch (0) | |||||
{ | |||||
} | |||||
Time::Time (const Time& other) noexcept : millisSinceEpoch (other.millisSinceEpoch) | |||||
{ | |||||
} | |||||
Time::Time (const int64 ms) noexcept : millisSinceEpoch (ms) | |||||
{ | |||||
} | |||||
#if 0 | |||||
Time::Time (const int year, | |||||
const int month, | |||||
const int day, | |||||
const int hours, | |||||
const int minutes, | |||||
const int seconds, | |||||
const int milliseconds, | |||||
const bool useLocalTime) noexcept | |||||
{ | |||||
std::tm t; | |||||
t.tm_year = year - 1900; | |||||
t.tm_mon = month; | |||||
t.tm_mday = day; | |||||
t.tm_hour = hours; | |||||
t.tm_min = minutes; | |||||
t.tm_sec = seconds; | |||||
t.tm_isdst = -1; | |||||
millisSinceEpoch = 1000 * (useLocalTime ? (int64) mktime (&t) | |||||
: TimeHelpers::mktime_utc (t)) | |||||
+ milliseconds; | |||||
} | |||||
#endif | |||||
Time::~Time() noexcept | |||||
{ | |||||
} | |||||
Time& Time::operator= (const Time& other) noexcept | |||||
{ | |||||
millisSinceEpoch = other.millisSinceEpoch; | |||||
return *this; | |||||
} | |||||
//============================================================================== | |||||
int64 Time::currentTimeMillis() noexcept | |||||
{ | |||||
struct timeval tv; | |||||
gettimeofday (&tv, nullptr); | |||||
return ((int64) tv.tv_sec) * 1000 + tv.tv_usec / 1000; | |||||
} | |||||
#if 0 | |||||
Time JUCE_CALLTYPE Time::getCurrentTime() noexcept | |||||
{ | |||||
return Time (currentTimeMillis()); | |||||
} | |||||
#endif | |||||
//============================================================================== | |||||
static uint32 juce_millisecondsSinceStartup() noexcept | |||||
{ | |||||
#ifdef CARLA_OS_WIN | |||||
return (uint32) timeGetTime(); | |||||
#else | |||||
timespec t; | |||||
clock_gettime (CLOCK_MONOTONIC, &t); | |||||
return (uint32) (t.tv_sec * 1000 + t.tv_nsec / 1000000); | |||||
#endif | |||||
} | |||||
uint32 Time::getMillisecondCounter() noexcept | |||||
{ | |||||
const uint32 now = juce_millisecondsSinceStartup(); | |||||
if (now < TimeHelpers::lastMSCounterValue) | |||||
{ | |||||
// in multi-threaded apps this might be called concurrently, so | |||||
// make sure that our last counter value only increases and doesn't | |||||
// go backwards.. | |||||
if (now < TimeHelpers::lastMSCounterValue - 1000) | |||||
TimeHelpers::lastMSCounterValue = now; | |||||
} | |||||
else | |||||
{ | |||||
TimeHelpers::lastMSCounterValue = now; | |||||
} | |||||
return now; | |||||
} | |||||
uint32 Time::getApproximateMillisecondCounter() noexcept | |||||
{ | |||||
if (TimeHelpers::lastMSCounterValue == 0) | |||||
getMillisecondCounter(); | |||||
return TimeHelpers::lastMSCounterValue; | |||||
} | |||||
#if 0 | |||||
void Time::waitForMillisecondCounter (const uint32 targetTime) noexcept | |||||
{ | |||||
for (;;) | |||||
{ | |||||
const uint32 now = getMillisecondCounter(); | |||||
if (now >= targetTime) | |||||
break; | |||||
const int toWait = (int) (targetTime - now); | |||||
if (toWait > 2) | |||||
{ | |||||
Thread::sleep (jmin (20, toWait >> 1)); | |||||
} | |||||
else | |||||
{ | |||||
// xxx should consider using mutex_pause on the mac as it apparently | |||||
// makes it seem less like a spinlock and avoids lowering the thread pri. | |||||
for (int i = 10; --i >= 0;) | |||||
Thread::yield(); | |||||
} | |||||
} | |||||
} | |||||
//============================================================================== | |||||
double Time::highResolutionTicksToSeconds (const int64 ticks) noexcept | |||||
{ | |||||
return ticks / (double) getHighResolutionTicksPerSecond(); | |||||
} | |||||
int64 Time::secondsToHighResolutionTicks (const double seconds) noexcept | |||||
{ | |||||
return (int64) (seconds * (double) getHighResolutionTicksPerSecond()); | |||||
} | |||||
//============================================================================== | |||||
String Time::toString (const bool includeDate, | |||||
const bool includeTime, | |||||
const bool includeSeconds, | |||||
const bool use24HourClock) const noexcept | |||||
{ | |||||
String result; | |||||
if (includeDate) | |||||
{ | |||||
result << getDayOfMonth() << ' ' | |||||
<< getMonthName (true) << ' ' | |||||
<< getYear(); | |||||
if (includeTime) | |||||
result << ' '; | |||||
} | |||||
if (includeTime) | |||||
{ | |||||
const int mins = getMinutes(); | |||||
result << (use24HourClock ? getHours() : getHoursInAmPmFormat()) | |||||
<< (mins < 10 ? ":0" : ":") << mins; | |||||
if (includeSeconds) | |||||
{ | |||||
const int secs = getSeconds(); | |||||
result << (secs < 10 ? ":0" : ":") << secs; | |||||
} | |||||
if (! use24HourClock) | |||||
result << (isAfternoon() ? "pm" : "am"); | |||||
} | |||||
return result.trimEnd(); | |||||
} | |||||
String Time::formatted (const String& format) const | |||||
{ | |||||
std::tm t (TimeHelpers::millisToLocal (millisSinceEpoch)); | |||||
return TimeHelpers::formatString (format, &t); | |||||
} | |||||
//============================================================================== | |||||
int Time::getYear() const noexcept { return TimeHelpers::millisToLocal (millisSinceEpoch).tm_year + 1900; } | |||||
int Time::getMonth() const noexcept { return TimeHelpers::millisToLocal (millisSinceEpoch).tm_mon; } | |||||
int Time::getDayOfYear() const noexcept { return TimeHelpers::millisToLocal (millisSinceEpoch).tm_yday; } | |||||
int Time::getDayOfMonth() const noexcept { return TimeHelpers::millisToLocal (millisSinceEpoch).tm_mday; } | |||||
int Time::getDayOfWeek() const noexcept { return TimeHelpers::millisToLocal (millisSinceEpoch).tm_wday; } | |||||
int Time::getHours() const noexcept { return TimeHelpers::millisToLocal (millisSinceEpoch).tm_hour; } | |||||
int Time::getMinutes() const noexcept { return TimeHelpers::millisToLocal (millisSinceEpoch).tm_min; } | |||||
int Time::getSeconds() const noexcept { return TimeHelpers::extendedModulo (millisSinceEpoch / 1000, 60); } | |||||
int Time::getMilliseconds() const noexcept { return TimeHelpers::extendedModulo (millisSinceEpoch, 1000); } | |||||
int Time::getHoursInAmPmFormat() const noexcept | |||||
{ | |||||
const int hours = getHours(); | |||||
if (hours == 0) return 12; | |||||
if (hours <= 12) return hours; | |||||
return hours - 12; | |||||
} | |||||
bool Time::isAfternoon() const noexcept | |||||
{ | |||||
return getHours() >= 12; | |||||
} | |||||
bool Time::isDaylightSavingTime() const noexcept | |||||
{ | |||||
return TimeHelpers::millisToLocal (millisSinceEpoch).tm_isdst != 0; | |||||
} | |||||
String Time::getTimeZone() const noexcept | |||||
{ | |||||
String zone[2]; | |||||
#if JUCE_WINDOWS | |||||
#if JUCE_MSVC || JUCE_CLANG | |||||
_tzset(); | |||||
for (int i = 0; i < 2; ++i) | |||||
{ | |||||
char name[128] = { 0 }; | |||||
size_t length; | |||||
_get_tzname (&length, name, 127, i); | |||||
zone[i] = name; | |||||
} | |||||
#else | |||||
#warning "Can't find a replacement for tzset on mingw - ideas welcome!" | |||||
#endif | |||||
#else | |||||
tzset(); | |||||
const char** const zonePtr = (const char**) tzname; | |||||
zone[0] = zonePtr[0]; | |||||
zone[1] = zonePtr[1]; | |||||
#endif | |||||
if (isDaylightSavingTime()) | |||||
{ | |||||
zone[0] = zone[1]; | |||||
if (zone[0].length() > 3 | |||||
&& zone[0].containsIgnoreCase ("daylight") | |||||
&& zone[0].contains ("GMT")) | |||||
zone[0] = "BST"; | |||||
} | |||||
return zone[0].substring (0, 3); | |||||
} | |||||
int Time::getUTCOffsetSeconds() const noexcept | |||||
{ | |||||
return TimeHelpers::getUTCOffsetSeconds (millisSinceEpoch); | |||||
} | |||||
String Time::getUTCOffsetString (bool includeSemiColon) const | |||||
{ | |||||
if (int seconds = getUTCOffsetSeconds()) | |||||
{ | |||||
const int minutes = seconds / 60; | |||||
return String::formatted (includeSemiColon ? "%+03d:%02d" | |||||
: "%+03d%02d", | |||||
minutes / 60, | |||||
minutes % 60); | |||||
} | |||||
return "Z"; | |||||
} | |||||
String Time::toISO8601 (bool includeDividerCharacters) const | |||||
{ | |||||
return String::formatted (includeDividerCharacters ? "%04d-%02d-%02dT%02d:%02d:%06.03f" | |||||
: "%04d%02d%02dT%02d%02d%06.03f", | |||||
getYear(), | |||||
getMonth() + 1, | |||||
getDayOfMonth(), | |||||
getHours(), | |||||
getMinutes(), | |||||
getSeconds() + getMilliseconds() / 1000.0) | |||||
+ getUTCOffsetString (includeDividerCharacters); | |||||
} | |||||
static int parseFixedSizeIntAndSkip (String::CharPointerType& t, int numChars, char charToSkip) noexcept | |||||
{ | |||||
int n = 0; | |||||
for (int i = numChars; --i >= 0;) | |||||
{ | |||||
const int digit = (int) (*t - '0'); | |||||
if (! isPositiveAndBelow (digit, 10)) | |||||
return -1; | |||||
++t; | |||||
n = n * 10 + digit; | |||||
} | |||||
if (charToSkip != 0 && *t == (juce_wchar) charToSkip) | |||||
++t; | |||||
return n; | |||||
} | |||||
Time Time::fromISO8601 (StringRef iso) noexcept | |||||
{ | |||||
String::CharPointerType t = iso.text; | |||||
const int year = parseFixedSizeIntAndSkip (t, 4, '-'); | |||||
if (year < 0) | |||||
return Time(); | |||||
const int month = parseFixedSizeIntAndSkip (t, 2, '-'); | |||||
if (month < 0) | |||||
return Time(); | |||||
const int day = parseFixedSizeIntAndSkip (t, 2, 0); | |||||
if (day < 0) | |||||
return Time(); | |||||
int hours = 0, minutes = 0, milliseconds = 0; | |||||
if (*t == 'T') | |||||
{ | |||||
++t; | |||||
hours = parseFixedSizeIntAndSkip (t, 2, ':'); | |||||
if (hours < 0) | |||||
return Time(); | |||||
minutes = parseFixedSizeIntAndSkip (t, 2, ':'); | |||||
if (minutes < 0) | |||||
return Time(); | |||||
milliseconds = (int) (1000.0 * CharacterFunctions::readDoubleValue (t)); | |||||
} | |||||
const juce_wchar nextChar = t.getAndAdvance(); | |||||
if (nextChar == '-' || nextChar == '+') | |||||
{ | |||||
const int offsetHours = parseFixedSizeIntAndSkip (t, 2, ':'); | |||||
if (offsetHours < 0) | |||||
return Time(); | |||||
const int offsetMinutes = parseFixedSizeIntAndSkip (t, 2, 0); | |||||
if (offsetMinutes < 0) | |||||
return Time(); | |||||
const int offsetMs = (offsetHours * 60 + offsetMinutes) * 60 * 1000; | |||||
milliseconds += nextChar == '-' ? offsetMs : -offsetMs; // NB: this seems backwards but is correct! | |||||
} | |||||
else if (nextChar != 0 && nextChar != 'Z') | |||||
{ | |||||
return Time(); | |||||
} | |||||
return Time (year, month - 1, day, hours, minutes, 0, milliseconds, false); | |||||
} | |||||
String Time::getMonthName (const bool threeLetterVersion) const | |||||
{ | |||||
return getMonthName (getMonth(), threeLetterVersion); | |||||
} | |||||
String Time::getWeekdayName (const bool threeLetterVersion) const | |||||
{ | |||||
return getWeekdayName (getDayOfWeek(), threeLetterVersion); | |||||
} | |||||
static const char* const shortMonthNames[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; | |||||
static const char* const longMonthNames[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; | |||||
String Time::getMonthName (int monthNumber, const bool threeLetterVersion) | |||||
{ | |||||
monthNumber %= 12; | |||||
return TRANS (threeLetterVersion ? shortMonthNames [monthNumber] | |||||
: longMonthNames [monthNumber]); | |||||
} | |||||
String Time::getWeekdayName (int day, const bool threeLetterVersion) | |||||
{ | |||||
static const char* const shortDayNames[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; | |||||
static const char* const longDayNames[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; | |||||
day %= 7; | |||||
return TRANS (threeLetterVersion ? shortDayNames [day] | |||||
: longDayNames [day]); | |||||
} | |||||
//============================================================================== | |||||
Time& Time::operator+= (RelativeTime delta) noexcept { millisSinceEpoch += delta.inMilliseconds(); return *this; } | |||||
Time& Time::operator-= (RelativeTime delta) noexcept { millisSinceEpoch -= delta.inMilliseconds(); return *this; } | |||||
Time operator+ (Time time, RelativeTime delta) noexcept { Time t (time); return t += delta; } | |||||
Time operator- (Time time, RelativeTime delta) noexcept { Time t (time); return t -= delta; } | |||||
Time operator+ (RelativeTime delta, Time time) noexcept { Time t (time); return t += delta; } | |||||
const RelativeTime operator- (Time time1, Time time2) noexcept { return RelativeTime::milliseconds (time1.toMilliseconds() - time2.toMilliseconds()); } | |||||
bool operator== (Time time1, Time time2) noexcept { return time1.toMilliseconds() == time2.toMilliseconds(); } | |||||
bool operator!= (Time time1, Time time2) noexcept { return time1.toMilliseconds() != time2.toMilliseconds(); } | |||||
bool operator< (Time time1, Time time2) noexcept { return time1.toMilliseconds() < time2.toMilliseconds(); } | |||||
bool operator> (Time time1, Time time2) noexcept { return time1.toMilliseconds() > time2.toMilliseconds(); } | |||||
bool operator<= (Time time1, Time time2) noexcept { return time1.toMilliseconds() <= time2.toMilliseconds(); } | |||||
bool operator>= (Time time1, Time time2) noexcept { return time1.toMilliseconds() >= time2.toMilliseconds(); } | |||||
static int getMonthNumberForCompileDate (const String& m) noexcept | |||||
{ | |||||
for (int i = 0; i < 12; ++i) | |||||
if (m.equalsIgnoreCase (shortMonthNames[i])) | |||||
return i; | |||||
// If you hit this because your compiler has an unusual __DATE__ | |||||
// format, let us know so we can add support for it! | |||||
jassertfalse; | |||||
return 0; | |||||
} | |||||
Time Time::getCompilationDate() | |||||
{ | |||||
StringArray dateTokens, timeTokens; | |||||
dateTokens.addTokens (__DATE__, true); | |||||
dateTokens.removeEmptyStrings (true); | |||||
timeTokens.addTokens (__TIME__, ":", StringRef()); | |||||
return Time (dateTokens[2].getIntValue(), | |||||
getMonthNumberForCompileDate (dateTokens[0]), | |||||
dateTokens[1].getIntValue(), | |||||
timeTokens[0].getIntValue(), | |||||
timeTokens[1].getIntValue()); | |||||
} | |||||
#endif |
@@ -0,0 +1,401 @@ | |||||
/* | |||||
============================================================================== | |||||
This file is part of the JUCE library. | |||||
Copyright (c) 2016 - ROLI Ltd. | |||||
Permission is granted to use this software under the terms of the ISC license | |||||
http://www.isc.org/downloads/software-support-policy/isc-license/ | |||||
Permission to use, copy, modify, and/or distribute this software for any | |||||
purpose with or without fee is hereby granted, provided that the above | |||||
copyright notice and this permission notice appear in all copies. | |||||
THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD | |||||
TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | |||||
FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, | |||||
OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF | |||||
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | |||||
OF THIS SOFTWARE. | |||||
----------------------------------------------------------------------------- | |||||
To release a closed-source product which uses other parts of JUCE not | |||||
licensed under the ISC terms, commercial licenses are available: visit | |||||
www.juce.com for more information. | |||||
============================================================================== | |||||
*/ | |||||
#ifndef JUCE_TIME_H_INCLUDED | |||||
#define JUCE_TIME_H_INCLUDED | |||||
//============================================================================== | |||||
/** | |||||
Holds an absolute date and time. | |||||
Internally, the time is stored at millisecond precision. | |||||
@see RelativeTime | |||||
*/ | |||||
class JUCE_API Time | |||||
{ | |||||
public: | |||||
//============================================================================== | |||||
/** Creates a Time object. | |||||
This default constructor creates a time of midnight Jan 1st 1970 UTC, (which is | |||||
represented internally as 0ms). | |||||
To create a time object representing the current time, use getCurrentTime(). | |||||
@see getCurrentTime | |||||
*/ | |||||
Time() noexcept; | |||||
/** Creates a time based on a number of milliseconds. | |||||
To create a time object set to the current time, use getCurrentTime(). | |||||
@param millisecondsSinceEpoch the number of milliseconds since the unix | |||||
'epoch' (midnight Jan 1st 1970 UTC). | |||||
@see getCurrentTime, currentTimeMillis | |||||
*/ | |||||
explicit Time (int64 millisecondsSinceEpoch) noexcept; | |||||
/** Creates a time from a set of date components. | |||||
@param year the year, in 4-digit format, e.g. 2004 | |||||
@param month the month, in the range 0 to 11 | |||||
@param day the day of the month, in the range 1 to 31 | |||||
@param hours hours in 24-hour clock format, 0 to 23 | |||||
@param minutes minutes 0 to 59 | |||||
@param seconds seconds 0 to 59 | |||||
@param milliseconds milliseconds 0 to 999 | |||||
@param useLocalTime if true, assume input is in this machine's local timezone | |||||
if false, assume input is in UTC. | |||||
*/ | |||||
Time (int year, | |||||
int month, | |||||
int day, | |||||
int hours, | |||||
int minutes, | |||||
int seconds = 0, | |||||
int milliseconds = 0, | |||||
bool useLocalTime = true) noexcept; | |||||
/** Creates a copy of another Time object. */ | |||||
Time (const Time& other) noexcept; | |||||
/** Destructor. */ | |||||
~Time() noexcept; | |||||
/** Copies this time from another one. */ | |||||
Time& operator= (const Time& other) noexcept; | |||||
//============================================================================== | |||||
/** Returns a Time object that is set to the current system time. | |||||
This may not be monotonic, as the system time can change at any moment. | |||||
You should therefore not use this method for measuring time intervals. | |||||
@see currentTimeMillis | |||||
*/ | |||||
static Time JUCE_CALLTYPE getCurrentTime() noexcept; | |||||
/** Returns the time as a number of milliseconds. | |||||
@returns the number of milliseconds this Time object represents, since | |||||
midnight Jan 1st 1970 UTC. | |||||
@see getMilliseconds | |||||
*/ | |||||
int64 toMilliseconds() const noexcept { return millisSinceEpoch; } | |||||
/** Returns the year (in this machine's local timezone). | |||||
A 4-digit format is used, e.g. 2004. | |||||
*/ | |||||
int getYear() const noexcept; | |||||
/** Returns the number of the month (in this machine's local timezone). | |||||
The value returned is in the range 0 to 11. | |||||
@see getMonthName | |||||
*/ | |||||
int getMonth() const noexcept; | |||||
/** Returns the name of the month (in this machine's local timezone). | |||||
@param threeLetterVersion if true, it'll be a 3-letter abbreviation, e.g. "Jan"; if false | |||||
it'll return the long form, e.g. "January" | |||||
@see getMonth | |||||
*/ | |||||
String getMonthName (bool threeLetterVersion) const; | |||||
/** Returns the day of the month (in this machine's local timezone). | |||||
The value returned is in the range 1 to 31. | |||||
*/ | |||||
int getDayOfMonth() const noexcept; | |||||
/** Returns the number of the day of the week (in this machine's local timezone). | |||||
The value returned is in the range 0 to 6 (0 = sunday, 1 = monday, etc). | |||||
*/ | |||||
int getDayOfWeek() const noexcept; | |||||
/** Returns the number of the day of the year (in this machine's local timezone). | |||||
The value returned is in the range 0 to 365. | |||||
*/ | |||||
int getDayOfYear() const noexcept; | |||||
/** Returns the name of the weekday (in this machine's local timezone). | |||||
@param threeLetterVersion if true, it'll return a 3-letter abbreviation, e.g. "Tue"; if | |||||
false, it'll return the full version, e.g. "Tuesday". | |||||
*/ | |||||
String getWeekdayName (bool threeLetterVersion) const; | |||||
/** Returns the number of hours since midnight (in this machine's local timezone). | |||||
This is in 24-hour clock format, in the range 0 to 23. | |||||
@see getHoursInAmPmFormat, isAfternoon | |||||
*/ | |||||
int getHours() const noexcept; | |||||
/** Returns true if the time is in the afternoon (in this machine's local timezone). | |||||
@returns true for "PM", false for "AM". | |||||
@see getHoursInAmPmFormat, getHours | |||||
*/ | |||||
bool isAfternoon() const noexcept; | |||||
/** Returns the hours in 12-hour clock format (in this machine's local timezone). | |||||
This will return a value 1 to 12 - use isAfternoon() to find out | |||||
whether this is in the afternoon or morning. | |||||
@see getHours, isAfternoon | |||||
*/ | |||||
int getHoursInAmPmFormat() const noexcept; | |||||
/** Returns the number of minutes, 0 to 59 (in this machine's local timezone). */ | |||||
int getMinutes() const noexcept; | |||||
/** Returns the number of seconds, 0 to 59. */ | |||||
int getSeconds() const noexcept; | |||||
/** Returns the number of milliseconds, 0 to 999. | |||||
Unlike toMilliseconds(), this just returns the position within the | |||||
current second rather than the total number since the epoch. | |||||
@see toMilliseconds | |||||
*/ | |||||
int getMilliseconds() const noexcept; | |||||
/** Returns true if the local timezone uses a daylight saving correction. */ | |||||
bool isDaylightSavingTime() const noexcept; | |||||
//============================================================================== | |||||
/** Returns a 3-character string to indicate the local timezone. */ | |||||
String getTimeZone() const noexcept; | |||||
/** Returns the local timezone offset from UTC in seconds. */ | |||||
int getUTCOffsetSeconds() const noexcept; | |||||
/** Returns a string to indicate the offset of the local timezone from UTC. | |||||
@returns "+XX:XX", "-XX:XX" or "Z" | |||||
@param includeDividerCharacters whether to include or omit the ":" divider in the string | |||||
*/ | |||||
String getUTCOffsetString (bool includeDividerCharacters) const; | |||||
//============================================================================== | |||||
/** Returns a string version of this date and time, using this machine's local timezone. | |||||
For a more powerful way of formatting the date and time, see the formatted() method. | |||||
@param includeDate whether to include the date in the string | |||||
@param includeTime whether to include the time in the string | |||||
@param includeSeconds if the time is being included, this provides an option not to include | |||||
the seconds in it | |||||
@param use24HourClock if the time is being included, sets whether to use am/pm or 24 | |||||
hour notation. | |||||
@see formatted | |||||
*/ | |||||
String toString (bool includeDate, | |||||
bool includeTime, | |||||
bool includeSeconds = true, | |||||
bool use24HourClock = false) const noexcept; | |||||
/** Converts this date/time to a string with a user-defined format. | |||||
This uses the C strftime() function to format this time as a string. To save you | |||||
looking it up, these are the escape codes that strftime uses (other codes might | |||||
work on some platforms and not others, but these are the common ones): | |||||
- %a is replaced by the locale's abbreviated weekday name. | |||||
- %A is replaced by the locale's full weekday name. | |||||
- %b is replaced by the locale's abbreviated month name. | |||||
- %B is replaced by the locale's full month name. | |||||
- %c is replaced by the locale's appropriate date and time representation. | |||||
- %d is replaced by the day of the month as a decimal number [01,31]. | |||||
- %H is replaced by the hour (24-hour clock) as a decimal number [00,23]. | |||||
- %I is replaced by the hour (12-hour clock) as a decimal number [01,12]. | |||||
- %j is replaced by the day of the year as a decimal number [001,366]. | |||||
- %m is replaced by the month as a decimal number [01,12]. | |||||
- %M is replaced by the minute as a decimal number [00,59]. | |||||
- %p is replaced by the locale's equivalent of either a.m. or p.m. | |||||
- %S is replaced by the second as a decimal number [00,61]. | |||||
- %U is replaced by the week number of the year (Sunday as the first day of the week) as a decimal number [00,53]. | |||||
- %w is replaced by the weekday as a decimal number [0,6], with 0 representing Sunday. | |||||
- %W is replaced by the week number of the year (Monday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Monday are considered to be in week 0. | |||||
- %x is replaced by the locale's appropriate date representation. | |||||
- %X is replaced by the locale's appropriate time representation. | |||||
- %y is replaced by the year without century as a decimal number [00,99]. | |||||
- %Y is replaced by the year with century as a decimal number. | |||||
- %Z is replaced by the timezone name or abbreviation, or by no bytes if no timezone information exists. | |||||
- %% is replaced by %. | |||||
@see toString | |||||
*/ | |||||
String formatted (const String& format) const; | |||||
//============================================================================== | |||||
/** Returns a fully described string of this date and time in ISO-8601 format | |||||
(using the local timezone). | |||||
@param includeDividerCharacters whether to include or omit the "-" and ":" | |||||
dividers in the string | |||||
*/ | |||||
String toISO8601 (bool includeDividerCharacters) const; | |||||
/** Parses an ISO-8601 string and returns it as a Time. */ | |||||
static Time fromISO8601 (StringRef iso8601) noexcept; | |||||
//============================================================================== | |||||
/** Tries to set the computer's clock. | |||||
@returns true if this succeeds, although depending on the system, the | |||||
application might not have sufficient privileges to do this. | |||||
*/ | |||||
bool setSystemTimeToThisTime() const; | |||||
//============================================================================== | |||||
/** Returns the name of a day of the week. | |||||
@param dayNumber the day, 0 to 6 (0 = sunday, 1 = monday, etc) | |||||
@param threeLetterVersion if true, it'll return a 3-letter abbreviation, e.g. "Tue"; if | |||||
false, it'll return the full version, e.g. "Tuesday". | |||||
*/ | |||||
static String getWeekdayName (int dayNumber, bool threeLetterVersion); | |||||
/** Returns the name of one of the months. | |||||
@param monthNumber the month, 0 to 11 | |||||
@param threeLetterVersion if true, it'll be a 3-letter abbreviation, e.g. "Jan"; if false | |||||
it'll return the long form, e.g. "January" | |||||
*/ | |||||
static String getMonthName (int monthNumber, bool threeLetterVersion); | |||||
//============================================================================== | |||||
// Static methods for getting system timers directly.. | |||||
/** Returns the current system time. | |||||
Returns the number of milliseconds since midnight Jan 1st 1970 UTC. | |||||
Should be accurate to within a few millisecs, depending on platform, | |||||
hardware, etc. | |||||
*/ | |||||
static int64 currentTimeMillis() noexcept; | |||||
/** Returns the number of millisecs since a fixed event (usually system startup). | |||||
This returns a monotonically increasing value which it unaffected by changes to the | |||||
system clock. It should be accurate to within a few millisecs, depending on platform, | |||||
hardware, etc. | |||||
Being a 32-bit return value, it will of course wrap back to 0 after 2^32 seconds of | |||||
uptime, so be careful to take that into account. If you need a 64-bit time, you can | |||||
use currentTimeMillis() instead. | |||||
@see getApproximateMillisecondCounter | |||||
*/ | |||||
static uint32 getMillisecondCounter() noexcept; | |||||
/** Returns the number of millisecs since a fixed event (usually system startup). | |||||
This has the same function as getMillisecondCounter(), but returns a more accurate | |||||
value, using a higher-resolution timer if one is available. | |||||
@see getMillisecondCounter | |||||
*/ | |||||
static double getMillisecondCounterHiRes() noexcept; | |||||
/** Waits until the getMillisecondCounter() reaches a given value. | |||||
This will make the thread sleep as efficiently as it can while it's waiting. | |||||
*/ | |||||
static void waitForMillisecondCounter (uint32 targetTime) noexcept; | |||||
/** Less-accurate but faster version of getMillisecondCounter(). | |||||
This will return the last value that getMillisecondCounter() returned, so doesn't | |||||
need to make a system call, but is less accurate - it shouldn't be more than | |||||
100ms away from the correct time, though, so is still accurate enough for a | |||||
lot of purposes. | |||||
@see getMillisecondCounter | |||||
*/ | |||||
static uint32 getApproximateMillisecondCounter() noexcept; | |||||
//============================================================================== | |||||
// High-resolution timers.. | |||||
/** Returns the current high-resolution counter's tick-count. | |||||
This is a similar idea to getMillisecondCounter(), but with a higher | |||||
resolution. | |||||
@see getHighResolutionTicksPerSecond, highResolutionTicksToSeconds, | |||||
secondsToHighResolutionTicks | |||||
*/ | |||||
static int64 getHighResolutionTicks() noexcept; | |||||
/** Returns the resolution of the high-resolution counter in ticks per second. | |||||
@see getHighResolutionTicks, highResolutionTicksToSeconds, | |||||
secondsToHighResolutionTicks | |||||
*/ | |||||
static int64 getHighResolutionTicksPerSecond() noexcept; | |||||
/** Converts a number of high-resolution ticks into seconds. | |||||
@see getHighResolutionTicks, getHighResolutionTicksPerSecond, | |||||
secondsToHighResolutionTicks | |||||
*/ | |||||
static double highResolutionTicksToSeconds (int64 ticks) noexcept; | |||||
/** Converts a number seconds into high-resolution ticks. | |||||
@see getHighResolutionTicks, getHighResolutionTicksPerSecond, | |||||
highResolutionTicksToSeconds | |||||
*/ | |||||
static int64 secondsToHighResolutionTicks (double seconds) noexcept; | |||||
/** Returns a Time based on the value of the __DATE__ macro when this module was compiled */ | |||||
static Time getCompilationDate(); | |||||
private: | |||||
//============================================================================== | |||||
int64 millisSinceEpoch; | |||||
}; | |||||
//============================================================================== | |||||
/** Compares two Time objects. */ | |||||
JUCE_API bool operator== (Time time1, Time time2) noexcept; | |||||
/** Compares two Time objects. */ | |||||
JUCE_API bool operator!= (Time time1, Time time2) noexcept; | |||||
/** Compares two Time objects. */ | |||||
JUCE_API bool operator< (Time time1, Time time2) noexcept; | |||||
/** Compares two Time objects. */ | |||||
JUCE_API bool operator<= (Time time1, Time time2) noexcept; | |||||
/** Compares two Time objects. */ | |||||
JUCE_API bool operator> (Time time1, Time time2) noexcept; | |||||
/** Compares two Time objects. */ | |||||
JUCE_API bool operator>= (Time time1, Time time2) noexcept; | |||||
#endif // JUCE_TIME_H_INCLUDED |
@@ -124,29 +124,17 @@ XmlElement* XmlDocument::getDocumentElement (const bool onlyReadOuterDocumentEle | |||||
MemoryOutputStream data; | MemoryOutputStream data; | ||||
data.writeFromInputStream (*in, onlyReadOuterDocumentElement ? 8192 : -1); | data.writeFromInputStream (*in, onlyReadOuterDocumentElement ? 8192 : -1); | ||||
#if JUCE_STRING_UTF_TYPE == 8 | |||||
if (data.getDataSize() > 2) | if (data.getDataSize() > 2) | ||||
{ | { | ||||
data.writeByte (0); | data.writeByte (0); | ||||
const char* text = static_cast<const char*> (data.getData()); | const char* text = static_cast<const char*> (data.getData()); | ||||
if (CharPointer_UTF16::isByteOrderMarkBigEndian (text) | |||||
|| CharPointer_UTF16::isByteOrderMarkLittleEndian (text)) | |||||
{ | |||||
originalText = data.toString(); | |||||
} | |||||
else | |||||
{ | |||||
if (CharPointer_UTF8::isByteOrderMark (text)) | |||||
text += 3; | |||||
if (CharPointer_UTF8::isByteOrderMark (text)) | |||||
text += 3; | |||||
// parse the input buffer directly to avoid copying it all to a string.. | |||||
return parseDocumentElement (String::CharPointerType (text), onlyReadOuterDocumentElement); | |||||
} | |||||
// parse the input buffer directly to avoid copying it all to a string.. | |||||
return parseDocumentElement (String::CharPointerType (text), onlyReadOuterDocumentElement); | |||||
} | } | ||||
#else | |||||
originalText = data.toString(); | |||||
#endif | |||||
} | } | ||||
} | } | ||||
@@ -734,9 +722,7 @@ void XmlDocument::readEntity (String& result) | |||||
return; | return; | ||||
} | } | ||||
#if 0 // FIXME | |||||
result << (juce_wchar) charCode; | result << (juce_wchar) charCode; | ||||
#endif | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
@@ -53,7 +53,7 @@ | |||||
*/ | */ | ||||
#define forEachXmlChildElement(parentXmlElement, childElementVariableName) \ | #define forEachXmlChildElement(parentXmlElement, childElementVariableName) \ | ||||
\ | \ | ||||
for (juce::XmlElement* childElementVariableName = (parentXmlElement).getFirstChildElement(); \ | |||||
for (juce2::XmlElement* childElementVariableName = (parentXmlElement).getFirstChildElement(); \ | |||||
childElementVariableName != nullptr; \ | childElementVariableName != nullptr; \ | ||||
childElementVariableName = childElementVariableName->getNextElement()) | childElementVariableName = childElementVariableName->getNextElement()) | ||||
@@ -82,7 +82,7 @@ | |||||
*/ | */ | ||||
#define forEachXmlChildElementWithTagName(parentXmlElement, childElementVariableName, requiredTagName) \ | #define forEachXmlChildElementWithTagName(parentXmlElement, childElementVariableName, requiredTagName) \ | ||||
\ | \ | ||||
for (juce::XmlElement* childElementVariableName = (parentXmlElement).getChildByName (requiredTagName); \ | |||||
for (juce2::XmlElement* childElementVariableName = (parentXmlElement).getChildByName (requiredTagName); \ | |||||
childElementVariableName != nullptr; \ | childElementVariableName != nullptr; \ | ||||
childElementVariableName = childElementVariableName->getNextElementWithTagName (requiredTagName)) | childElementVariableName = childElementVariableName->getNextElementWithTagName (requiredTagName)) | ||||
@@ -22,7 +22,7 @@ | |||||
#include "CarlaMutex.hpp" | #include "CarlaMutex.hpp" | ||||
#include "CarlaString.hpp" | #include "CarlaString.hpp" | ||||
using namespace juce; | |||||
using namespace juce2; | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
@@ -20,10 +20,9 @@ | |||||
#include "CarlaMathUtils.hpp" | #include "CarlaMathUtils.hpp" | ||||
#include "CarlaNativeExtUI.hpp" | #include "CarlaNativeExtUI.hpp" | ||||
#include "AppConfig.h" | |||||
#include "juce_core/juce_core.h" | |||||
#include "juce_audio_graph/juce_audio_graph.h" | |||||
using juce::roundToIntAccurate; | |||||
using juce2::roundToIntAccurate; | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
@@ -23,6 +23,8 @@ | |||||
# define DISTRHO_PLUGIN_HAS_UI 0 | # define DISTRHO_PLUGIN_HAS_UI 0 | ||||
#endif | #endif | ||||
#include "CarlaJuceUtils.hpp" | |||||
// Plugin Code | // Plugin Code | ||||
#include "distrho-3bandeq/DistrhoArtwork3BandEQ.cpp" | #include "distrho-3bandeq/DistrhoArtwork3BandEQ.cpp" | ||||
#include "distrho-3bandeq/DistrhoPlugin3BandEQ.cpp" | #include "distrho-3bandeq/DistrhoPlugin3BandEQ.cpp" | ||||
@@ -23,6 +23,8 @@ | |||||
# define DISTRHO_PLUGIN_HAS_UI 0 | # define DISTRHO_PLUGIN_HAS_UI 0 | ||||
#endif | #endif | ||||
#include "CarlaJuceUtils.hpp" | |||||
// Plugin Code | // Plugin Code | ||||
#include "distrho-3bandsplitter/DistrhoArtwork3BandSplitter.cpp" | #include "distrho-3bandsplitter/DistrhoArtwork3BandSplitter.cpp" | ||||
#include "distrho-3bandsplitter/DistrhoPlugin3BandSplitter.cpp" | #include "distrho-3bandsplitter/DistrhoPlugin3BandSplitter.cpp" | ||||
@@ -1,6 +1,6 @@ | |||||
/* | /* | ||||
* Carla Native Plugins | * Carla Native Plugins | ||||
* Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
* Copyright (C) 2012-2017 Filipe Coelho <falktx@falktx.com> | |||||
* | * | ||||
* This program is free software; you can redistribute it and/or | * This program is free software; you can redistribute it and/or | ||||
* modify it under the terms of the GNU General Public License as | * modify it under the terms of the GNU General Public License as | ||||
@@ -23,6 +23,8 @@ | |||||
# define DISTRHO_PLUGIN_HAS_UI 0 | # define DISTRHO_PLUGIN_HAS_UI 0 | ||||
#endif | #endif | ||||
#include "CarlaJuceUtils.hpp" | |||||
// Plugin Code | // Plugin Code | ||||
#include "distrho-kars/DistrhoArtworkKars.cpp" | #include "distrho-kars/DistrhoArtworkKars.cpp" | ||||
#include "distrho-kars/DistrhoPluginKars.cpp" | #include "distrho-kars/DistrhoPluginKars.cpp" | ||||
@@ -1,6 +1,6 @@ | |||||
/* | /* | ||||
* Carla Native Plugins | * Carla Native Plugins | ||||
* Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
* Copyright (C) 2012-2017 Filipe Coelho <falktx@falktx.com> | |||||
* | * | ||||
* This program is free software; you can redistribute it and/or | * This program is free software; you can redistribute it and/or | ||||
* modify it under the terms of the GNU General Public License as | * modify it under the terms of the GNU General Public License as | ||||
@@ -23,6 +23,8 @@ | |||||
# define DISTRHO_PLUGIN_HAS_UI 0 | # define DISTRHO_PLUGIN_HAS_UI 0 | ||||
#endif | #endif | ||||
#include "CarlaJuceUtils.hpp" | |||||
// Plugin Code | // Plugin Code | ||||
#include "distrho-nekobi/DistrhoArtworkNekobi.cpp" | #include "distrho-nekobi/DistrhoArtworkNekobi.cpp" | ||||
#include "distrho-nekobi/DistrhoPluginNekobi.cpp" | #include "distrho-nekobi/DistrhoPluginNekobi.cpp" | ||||
@@ -1,6 +1,6 @@ | |||||
/* | /* | ||||
* Carla Native Plugins | * Carla Native Plugins | ||||
* Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
* Copyright (C) 2012-2017 Filipe Coelho <falktx@falktx.com> | |||||
* | * | ||||
* This program is free software; you can redistribute it and/or | * This program is free software; you can redistribute it and/or | ||||
* modify it under the terms of the GNU General Public License as | * modify it under the terms of the GNU General Public License as | ||||
@@ -23,6 +23,8 @@ | |||||
# define DISTRHO_PLUGIN_HAS_UI 0 | # define DISTRHO_PLUGIN_HAS_UI 0 | ||||
#endif | #endif | ||||
#include "CarlaJuceUtils.hpp" | |||||
// Plugin Code | // Plugin Code | ||||
#include "distrho-pingpongpan/DistrhoArtworkPingPongPan.cpp" | #include "distrho-pingpongpan/DistrhoArtworkPingPongPan.cpp" | ||||
#include "distrho-pingpongpan/DistrhoPluginPingPongPan.cpp" | #include "distrho-pingpongpan/DistrhoPluginPingPongPan.cpp" | ||||
@@ -1,6 +1,6 @@ | |||||
/* | /* | ||||
* Carla Native Plugins | * Carla Native Plugins | ||||
* Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
* Copyright (C) 2012-2017 Filipe Coelho <falktx@falktx.com> | |||||
* | * | ||||
* This program is free software; you can redistribute it and/or | * This program is free software; you can redistribute it and/or | ||||
* modify it under the terms of the GNU General Public License as | * modify it under the terms of the GNU General Public License as | ||||
@@ -15,6 +15,7 @@ | |||||
* For a full copy of the GNU General Public License see the doc/GPL.txt file. | * For a full copy of the GNU General Public License see the doc/GPL.txt file. | ||||
*/ | */ | ||||
#include "CarlaJuceUtils.hpp" | |||||
// Plugin Code | // Plugin Code | ||||
#include "distrho-prom/DistrhoPluginProM.cpp" | #include "distrho-prom/DistrhoPluginProM.cpp" | ||||
@@ -1,6 +1,6 @@ | |||||
/* | /* | ||||
* Carla Native Plugins | * Carla Native Plugins | ||||
* Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
* Copyright (C) 2012-2017 Filipe Coelho <falktx@falktx.com> | |||||
* | * | ||||
* This program is free software; you can redistribute it and/or | * This program is free software; you can redistribute it and/or | ||||
* modify it under the terms of the GNU General Public License as | * modify it under the terms of the GNU General Public License as | ||||
@@ -23,6 +23,8 @@ | |||||
# define DISTRHO_PLUGIN_HAS_UI 0 | # define DISTRHO_PLUGIN_HAS_UI 0 | ||||
#endif | #endif | ||||
#include "CarlaJuceUtils.hpp" | |||||
// Plugin Code | // Plugin Code | ||||
#include "distrho-vectorjuice/VectorJuicePlugin.cpp" | #include "distrho-vectorjuice/VectorJuicePlugin.cpp" | ||||
#ifdef HAVE_DGL | #ifdef HAVE_DGL | ||||
@@ -1,6 +1,6 @@ | |||||
/* | /* | ||||
* Carla Native Plugins | * Carla Native Plugins | ||||
* Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
* Copyright (C) 2012-2017 Filipe Coelho <falktx@falktx.com> | |||||
* | * | ||||
* This program is free software; you can redistribute it and/or | * This program is free software; you can redistribute it and/or | ||||
* modify it under the terms of the GNU General Public License as | * modify it under the terms of the GNU General Public License as | ||||
@@ -23,6 +23,8 @@ | |||||
# define DISTRHO_PLUGIN_HAS_UI 0 | # define DISTRHO_PLUGIN_HAS_UI 0 | ||||
#endif | #endif | ||||
#include "CarlaJuceUtils.hpp" | |||||
// Plugin Code | // Plugin Code | ||||
#include "distrho-wobblejuice/WobbleJuiceArtwork.cpp" | #include "distrho-wobblejuice/WobbleJuiceArtwork.cpp" | ||||
#include "distrho-wobblejuice/WobbleJuicePlugin.cpp" | #include "distrho-wobblejuice/WobbleJuicePlugin.cpp" | ||||
@@ -18,8 +18,7 @@ | |||||
#include "CarlaNative.hpp" | #include "CarlaNative.hpp" | ||||
#include "midi-base.hpp" | #include "midi-base.hpp" | ||||
#include "AppConfig.h" | |||||
#include "juce_core/juce_core.h" | |||||
#include "juce_audio_graph/juce_audio_graph.h" | |||||
#if 0 | #if 0 | ||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
@@ -143,7 +142,7 @@ private: | |||||
{ | { | ||||
fMidiOut.clear(); | fMidiOut.clear(); | ||||
using namespace juce; | |||||
using namespace juce2; | |||||
const String jfilename = String(CharPointer_UTF8(filename)); | const String jfilename = String(CharPointer_UTF8(filename)); | ||||
File file(jfilename); | File file(jfilename); | ||||
@@ -17,15 +17,13 @@ | |||||
#include "CarlaNativeExtUI.hpp" | #include "CarlaNativeExtUI.hpp" | ||||
#include "CarlaJuceUtils.hpp" | #include "CarlaJuceUtils.hpp" | ||||
#include "distrho/extra/ScopedPointer.hpp" | |||||
#include "zita-at1/jclient.cc" | #include "zita-at1/jclient.cc" | ||||
#include "zita-at1/retuner.cc" | #include "zita-at1/retuner.cc" | ||||
#include "AppConfig.h" | |||||
#include "juce_core/juce_core.h" | |||||
#include "juce_audio_graph/juce_audio_graph.h" | |||||
using juce::roundToIntAccurate; | |||||
using juce2::roundToIntAccurate; | |||||
using namespace AT1; | using namespace AT1; | ||||
@@ -17,7 +17,6 @@ | |||||
#include "CarlaNativeExtUI.hpp" | #include "CarlaNativeExtUI.hpp" | ||||
#include "CarlaJuceUtils.hpp" | #include "CarlaJuceUtils.hpp" | ||||
#include "distrho/extra/ScopedPointer.hpp" | |||||
#include "zita-bls1/hp3filt.cc" | #include "zita-bls1/hp3filt.cc" | ||||
#include "zita-bls1/jclient.cc" | #include "zita-bls1/jclient.cc" | ||||
@@ -17,7 +17,6 @@ | |||||
#include "CarlaNativeExtUI.hpp" | #include "CarlaNativeExtUI.hpp" | ||||
#include "CarlaJuceUtils.hpp" | #include "CarlaJuceUtils.hpp" | ||||
#include "distrho/extra/ScopedPointer.hpp" | |||||
#include "zita-rev1/jclient.cc" | #include "zita-rev1/jclient.cc" | ||||
#include "zita-rev1/pareq.cc" | #include "zita-rev1/pareq.cc" | ||||
@@ -45,10 +45,9 @@ | |||||
# pragma GCC diagnostic pop | # pragma GCC diagnostic pop | ||||
#endif | #endif | ||||
#include "AppConfig.h" | |||||
#include "juce_core/juce_core.h" | |||||
#include "juce_audio_graph/juce_audio_graph.h" | |||||
using juce::roundToIntAccurate; | |||||
using juce2::roundToIntAccurate; | |||||
using namespace zyncarla; | using namespace zyncarla; | ||||
@@ -21,7 +21,6 @@ | |||||
#include "LinkedList.hpp" | #include "LinkedList.hpp" | ||||
#include "CarlaMathUtils.hpp" | #include "CarlaMathUtils.hpp" | ||||
#include "distrho/extra/ScopedPointer.hpp" | |||||
#include <ctime> | #include <ctime> | ||||
#include <set> | #include <set> | ||||
@@ -50,10 +49,9 @@ | |||||
# pragma GCC diagnostic pop | # pragma GCC diagnostic pop | ||||
#endif | #endif | ||||
#include "AppConfig.h" | |||||
#include "juce_core/juce_core.h" | |||||
#include "juce_audio_graph/juce_audio_graph.h" | |||||
using juce::roundToIntAccurate; | |||||
using juce2::roundToIntAccurate; | |||||
using namespace zyncarla; | using namespace zyncarla; | ||||
@@ -50,7 +50,7 @@ endif | |||||
LIBS = $(MODULEDIR)/carla_engine_plugin.a | LIBS = $(MODULEDIR)/carla_engine_plugin.a | ||||
LIBS += $(MODULEDIR)/carla_plugin.a | LIBS += $(MODULEDIR)/carla_plugin.a | ||||
LIBS += $(MODULEDIR)/jackbridge.a | LIBS += $(MODULEDIR)/jackbridge.a | ||||
LIBS += $(MODULEDIR)/juce_core.a | |||||
LIBS += $(MODULEDIR)/juce_audio_graph.a | |||||
LIBS += $(MODULEDIR)/lilv.a | LIBS += $(MODULEDIR)/lilv.a | ||||
LIBS += $(MODULEDIR)/native-plugins.a | LIBS += $(MODULEDIR)/native-plugins.a | ||||
LIBS += $(MODULEDIR)/rtmempool.a | LIBS += $(MODULEDIR)/rtmempool.a | ||||
@@ -18,8 +18,7 @@ | |||||
#define CARLA_NATIVE_PLUGIN_LV2 | #define CARLA_NATIVE_PLUGIN_LV2 | ||||
#include "carla-base.cpp" | #include "carla-base.cpp" | ||||
#include "AppConfig.h" | |||||
#include "juce_core/juce_core.h" | |||||
#include "juce_audio_graph/juce_audio_graph.h" | |||||
#include "lv2/atom.h" | #include "lv2/atom.h" | ||||
#include "lv2/buf-size.h" | #include "lv2/buf-size.h" | ||||
@@ -45,9 +44,9 @@ | |||||
# define PLUGIN_EXT ".so" | # define PLUGIN_EXT ".so" | ||||
#endif | #endif | ||||
using juce::String; | |||||
using juce::StringArray; | |||||
using juce::juce_wchar; | |||||
using juce2::String; | |||||
using juce2::StringArray; | |||||
using juce2::juce_wchar; | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
// Converts a parameter name to an LV2 compatible symbol | // Converts a parameter name to an LV2 compatible symbol | ||||
@@ -24,8 +24,7 @@ | |||||
#include "CarlaMathUtils.hpp" | #include "CarlaMathUtils.hpp" | ||||
#include "AppConfig.h" | |||||
#include "juce_core/juce_core.h" | |||||
#include "juce_audio_graph/juce_audio_graph.h" | |||||
#include "vestige/aeffectx.h" | #include "vestige/aeffectx.h" | ||||
#define effFlagsProgramChunks (1 << 5) | #define effFlagsProgramChunks (1 << 5) | ||||
@@ -73,8 +72,8 @@ public: | |||||
fHost.uiParentId = 0; | fHost.uiParentId = 0; | ||||
// find resource dir | // find resource dir | ||||
using juce::File; | |||||
using juce::String; | |||||
using juce2::File; | |||||
using juce2::String; | |||||
File curExe = File::getSpecialLocation(File::currentExecutableFile).getLinkedTarget(); | File curExe = File::getSpecialLocation(File::currentExecutableFile).getLinkedTarget(); | ||||
File resDir = curExe.getSiblingFile("carla-resources"); | File resDir = curExe.getSiblingFile("carla-resources"); | ||||
@@ -22,8 +22,8 @@ | |||||
#include "CarlaUtils.hpp" | #include "CarlaUtils.hpp" | ||||
#if defined(CARLA_OS_WIN) | #if defined(CARLA_OS_WIN) | ||||
# include "AppConfig.h" | |||||
# include "juce_core/juce_core.h" | |||||
# include "CarlaJuceUtils.hpp" | |||||
# include "juce_audio_graph/juce_audio_graph.h" | |||||
#elif defined(HAVE_LIBMAGIC) | #elif defined(HAVE_LIBMAGIC) | ||||
# include <magic.h> | # include <magic.h> | ||||
#endif | #endif | ||||
@@ -76,9 +76,8 @@ BinaryType getBinaryTypeFromFile(const char* const filename) | |||||
return BINARY_NATIVE; | return BINARY_NATIVE; | ||||
#if defined(CARLA_OS_WIN) | #if defined(CARLA_OS_WIN) | ||||
using juce::File; | |||||
using juce::FileInputStream; | |||||
using juce::ScopedPointer; | |||||
using juce2::File; | |||||
using juce2::FileInputStream; | |||||
ScopedPointer<FileInputStream> stream(File(filename).createInputStream()); | ScopedPointer<FileInputStream> stream(File(filename).createInputStream()); | ||||
CARLA_SAFE_ASSERT_RETURN(stream != nullptr || stream->failedToOpen(), BINARY_NATIVE); | CARLA_SAFE_ASSERT_RETURN(stream != nullptr || stream->failedToOpen(), BINARY_NATIVE); | ||||
@@ -17,8 +17,7 @@ | |||||
#include "CarlaDssiUtils.hpp" | #include "CarlaDssiUtils.hpp" | ||||
#include "AppConfig.h" | |||||
#include "juce_core/juce_core.h" | |||||
#include "juce_audio_graph/juce_audio_graph.h" | |||||
// -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
@@ -29,7 +28,7 @@ const char* find_dssi_ui(const char* const filename, const char* const label) no | |||||
carla_debug("find_dssi_ui(\"%s\", \"%s\")", filename, label); | carla_debug("find_dssi_ui(\"%s\", \"%s\")", filename, label); | ||||
try { | try { | ||||
using namespace juce; | |||||
using namespace juce2; | |||||
String guiFilename; | String guiFilename; | ||||
String pluginDir(String(filename).upToLastOccurrenceOf(".", false, false)); | String pluginDir(String(filename).upToLastOccurrenceOf(".", false, false)); | ||||
@@ -18,8 +18,15 @@ | |||||
#ifndef CARLA_JUCE_UTILS_HPP_INCLUDED | #ifndef CARLA_JUCE_UTILS_HPP_INCLUDED | ||||
#define CARLA_JUCE_UTILS_HPP_INCLUDED | #define CARLA_JUCE_UTILS_HPP_INCLUDED | ||||
#define DISTRHO_LEAK_DETECTOR_HPP_INCLUDED | |||||
#define DISTRHO_SCOPED_POINTER_HPP_INCLUDED | |||||
#define DISTRHO_LEAK_DETECTOR CARLA_LEAK_DETECTOR | |||||
#define DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR | |||||
#include "CarlaUtils.hpp" | #include "CarlaUtils.hpp" | ||||
#include <algorithm> | |||||
/** A good old-fashioned C macro concatenation helper. | /** A good old-fashioned C macro concatenation helper. | ||||
This combines two items (which may themselves be macros) into a single string, | This combines two items (which may themselves be macros) into a single string, | ||||
avoiding the pitfalls of the ## macro operator. | avoiding the pitfalls of the ## macro operator. | ||||
@@ -138,6 +145,184 @@ private: | |||||
} | } | ||||
}; | }; | ||||
//===================================================================================================================== | |||||
/** | |||||
This class holds a pointer which is automatically deleted when this object goes | |||||
out of scope. | |||||
Once a pointer has been passed to a ScopedPointer, it will make sure that the pointer | |||||
gets deleted when the ScopedPointer is deleted. Using the ScopedPointer on the stack or | |||||
as member variables is a good way to use RAII to avoid accidentally leaking dynamically | |||||
created objects. | |||||
A ScopedPointer can be used in pretty much the same way that you'd use a normal pointer | |||||
to an object. If you use the assignment operator to assign a different object to a | |||||
ScopedPointer, the old one will be automatically deleted. | |||||
A const ScopedPointer is guaranteed not to lose ownership of its object or change the | |||||
object to which it points during its lifetime. This means that making a copy of a const | |||||
ScopedPointer is impossible, as that would involve the new copy taking ownership from the | |||||
old one. | |||||
If you need to get a pointer out of a ScopedPointer without it being deleted, you | |||||
can use the release() method. | |||||
Something to note is the main difference between this class and the std::auto_ptr class, | |||||
which is that ScopedPointer provides a cast-to-object operator, wheras std::auto_ptr | |||||
requires that you always call get() to retrieve the pointer. The advantages of providing | |||||
the cast is that you don't need to call get(), so can use the ScopedPointer in pretty much | |||||
exactly the same way as a raw pointer. The disadvantage is that the compiler is free to | |||||
use the cast in unexpected and sometimes dangerous ways - in particular, it becomes difficult | |||||
to return a ScopedPointer as the result of a function. To avoid this causing errors, | |||||
ScopedPointer contains an overloaded constructor that should cause a syntax error in these | |||||
circumstances, but it does mean that instead of returning a ScopedPointer from a function, | |||||
you'd need to return a raw pointer (or use a std::auto_ptr instead). | |||||
*/ | |||||
template<class ObjectType> | |||||
class ScopedPointer | |||||
{ | |||||
public: | |||||
//================================================================================================================= | |||||
/** Creates a ScopedPointer containing a null pointer. */ | |||||
ScopedPointer() noexcept | |||||
: object(nullptr) {} | |||||
/** Creates a ScopedPointer that owns the specified object. */ | |||||
ScopedPointer(ObjectType* const objectToTakePossessionOf) noexcept | |||||
: object(objectToTakePossessionOf) {} | |||||
/** Creates a ScopedPointer that takes its pointer from another ScopedPointer. | |||||
Because a pointer can only belong to one ScopedPointer, this transfers | |||||
the pointer from the other object to this one, and the other object is reset to | |||||
be a null pointer. | |||||
*/ | |||||
ScopedPointer(ScopedPointer& objectToTransferFrom) noexcept | |||||
: object(objectToTransferFrom.object) | |||||
{ | |||||
objectToTransferFrom.object = nullptr; | |||||
} | |||||
/** Destructor. | |||||
This will delete the object that this ScopedPointer currently refers to. | |||||
*/ | |||||
~ScopedPointer() | |||||
{ | |||||
delete object; | |||||
} | |||||
/** Changes this ScopedPointer to point to a new object. | |||||
Because a pointer can only belong to one ScopedPointer, this transfers | |||||
the pointer from the other object to this one, and the other object is reset to | |||||
be a null pointer. | |||||
If this ScopedPointer already points to an object, that object | |||||
will first be deleted. | |||||
*/ | |||||
ScopedPointer& operator=(ScopedPointer& objectToTransferFrom) | |||||
{ | |||||
if (this != objectToTransferFrom.getAddress()) | |||||
{ | |||||
// Two ScopedPointers should never be able to refer to the same object - if | |||||
// this happens, you must have done something dodgy! | |||||
CARLA_SAFE_ASSERT_RETURN(object == nullptr || object != objectToTransferFrom.object, *this); | |||||
ObjectType* const oldObject = object; | |||||
object = objectToTransferFrom.object; | |||||
objectToTransferFrom.object = nullptr; | |||||
delete oldObject; | |||||
} | |||||
return *this; | |||||
} | |||||
/** Changes this ScopedPointer to point to a new object. | |||||
If this ScopedPointer already points to an object, that object | |||||
will first be deleted. | |||||
The pointer that you pass in may be a nullptr. | |||||
*/ | |||||
ScopedPointer& operator=(ObjectType* const newObjectToTakePossessionOf) | |||||
{ | |||||
if (object != newObjectToTakePossessionOf) | |||||
{ | |||||
ObjectType* const oldObject = object; | |||||
object = newObjectToTakePossessionOf; | |||||
delete oldObject; | |||||
} | |||||
return *this; | |||||
} | |||||
//================================================================================================================= | |||||
/** Returns the object that this ScopedPointer refers to. */ | |||||
operator ObjectType*() const noexcept { return object; } | |||||
/** Returns the object that this ScopedPointer refers to. */ | |||||
ObjectType* get() const noexcept { return object; } | |||||
/** Returns the object that this ScopedPointer refers to. */ | |||||
ObjectType& operator*() const noexcept { return *object; } | |||||
/** Lets you access methods and properties of the object that this ScopedPointer refers to. */ | |||||
ObjectType* operator->() const noexcept { return object; } | |||||
//================================================================================================================= | |||||
/** Removes the current object from this ScopedPointer without deleting it. | |||||
This will return the current object, and set the ScopedPointer to a null pointer. | |||||
*/ | |||||
ObjectType* release() noexcept { ObjectType* const o = object; object = nullptr; return o; } | |||||
//================================================================================================================= | |||||
/** Swaps this object with that of another ScopedPointer. | |||||
The two objects simply exchange their pointers. | |||||
*/ | |||||
void swapWith(ScopedPointer<ObjectType>& other) noexcept | |||||
{ | |||||
// Two ScopedPointers should never be able to refer to the same object - if | |||||
// this happens, you must have done something dodgy! | |||||
CARLA_SAFE_ASSERT_RETURN(object != other.object || this == other.getAddress() || object == nullptr,); | |||||
std::swap(object, other.object); | |||||
} | |||||
private: | |||||
//================================================================================================================= | |||||
ObjectType* object; | |||||
// (Required as an alternative to the overloaded & operator). | |||||
const ScopedPointer* getAddress() const noexcept { return this; } | |||||
#ifdef CARLA_PROPER_CPP11_SUPPORT | |||||
ScopedPointer(const ScopedPointer&) = delete; | |||||
ScopedPointer& operator=(const ScopedPointer&) = delete; | |||||
#else | |||||
ScopedPointer(const ScopedPointer&); | |||||
ScopedPointer& operator=(const ScopedPointer&); | |||||
#endif | |||||
}; | |||||
//===================================================================================================================== | |||||
/** Compares a ScopedPointer with another pointer. | |||||
This can be handy for checking whether this is a null pointer. | |||||
*/ | |||||
template<class ObjectType> | |||||
bool operator==(const ScopedPointer<ObjectType>& pointer1, ObjectType* const pointer2) noexcept | |||||
{ | |||||
return static_cast<ObjectType*>(pointer1) == pointer2; | |||||
} | |||||
/** Compares a ScopedPointer with another pointer. | |||||
This can be handy for checking whether this is a null pointer. | |||||
*/ | |||||
template<class ObjectType> | |||||
bool operator!=(const ScopedPointer<ObjectType>& pointer1, ObjectType* const pointer2) noexcept | |||||
{ | |||||
return static_cast<ObjectType*>(pointer1) != pointer2; | |||||
} | |||||
//===================================================================================================================== | //===================================================================================================================== | ||||
/** | /** | ||||
Helper class providing an RAII-based mechanism for temporarily setting and | Helper class providing an RAII-based mechanism for temporarily setting and | ||||
@@ -82,8 +82,7 @@ | |||||
#ifdef USE_QT | #ifdef USE_QT | ||||
# include <QtCore/QStringList> | # include <QtCore/QStringList> | ||||
#else | #else | ||||
# include "AppConfig.h" | |||||
# include "juce_core/juce_core.h" | |||||
# include "juce_audio_graph/juce_audio_graph.h" | |||||
#endif | #endif | ||||
// used for scalepoint sorting | // used for scalepoint sorting | ||||
@@ -659,7 +658,7 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool loadPresets) | |||||
rdfDescriptor->UniqueID = uniqueId; | rdfDescriptor->UniqueID = uniqueId; | ||||
} | } | ||||
#else | #else | ||||
const juce::String replaceURI(replaceNode.as_uri()); | |||||
const juce2::String replaceURI(replaceNode.as_uri()); | |||||
if (replaceURI.startsWith("urn:")) | if (replaceURI.startsWith("urn:")) | ||||
{ | { | ||||
@@ -1199,13 +1198,13 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool loadPresets) | |||||
rdfDescriptor->PresetCount = static_cast<uint32_t>(presetListURIs.count()); | rdfDescriptor->PresetCount = static_cast<uint32_t>(presetListURIs.count()); | ||||
#else | #else | ||||
juce::StringArray presetListURIs; | |||||
juce2::StringArray presetListURIs; | |||||
LILV_FOREACH(nodes, it, presetNodes) | LILV_FOREACH(nodes, it, presetNodes) | ||||
{ | { | ||||
Lilv::Node presetNode(presetNodes.get(it)); | Lilv::Node presetNode(presetNodes.get(it)); | ||||
juce::String presetURI(presetNode.as_uri()); | |||||
juce2::String presetURI(presetNode.as_uri()); | |||||
if (presetURI.trim().isNotEmpty()) | if (presetURI.trim().isNotEmpty()) | ||||
presetListURIs.addIfNotAlreadyThere(presetURI); | presetListURIs.addIfNotAlreadyThere(presetURI); | ||||
@@ -1246,7 +1245,7 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool loadPresets) | |||||
#ifdef USE_QT | #ifdef USE_QT | ||||
const int index(presetListURIs.indexOf(QString(presetURI))); | const int index(presetListURIs.indexOf(QString(presetURI))); | ||||
#else | #else | ||||
const int index(presetListURIs.indexOf(juce::String(presetURI))); | |||||
const int index(presetListURIs.indexOf(juce2::String(presetURI))); | |||||
#endif | #endif | ||||
CARLA_SAFE_ASSERT_CONTINUE(index >= 0 && index < static_cast<int>(rdfDescriptor->PresetCount)); | CARLA_SAFE_ASSERT_CONTINUE(index >= 0 && index < static_cast<int>(rdfDescriptor->PresetCount)); | ||||
@@ -36,8 +36,7 @@ | |||||
#include <fcntl.h> | #include <fcntl.h> | ||||
#if defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN) | #if defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN) | ||||
# include "AppConfig.h" | |||||
# include "juce_core/juce_core.h" | |||||
# include "juce_audio_graph/juce_audio_graph.h" | |||||
#else | #else | ||||
# include <cerrno> | # include <cerrno> | ||||
# include <signal.h> | # include <signal.h> | ||||
@@ -99,7 +98,7 @@ static inline | |||||
uint32_t getMillisecondCounter() noexcept | uint32_t getMillisecondCounter() noexcept | ||||
{ | { | ||||
#if defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN) | #if defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN) | ||||
return juce::Time::getMillisecondCounter(); | |||||
return juce2::Time::getMillisecondCounter(); | |||||
#else | #else | ||||
uint32_t now; | uint32_t now; | ||||
timespec t; | timespec t; | ||||
@@ -132,7 +131,7 @@ bool startProcess(const char* const argv[], PROCESS_INFORMATION* const processIn | |||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(processInfo != nullptr, false); | CARLA_SAFE_ASSERT_RETURN(processInfo != nullptr, false); | ||||
using juce::String; | |||||
using juce2::String; | |||||
String command; | String command; | ||||
@@ -140,23 +139,25 @@ bool startProcess(const char* const argv[], PROCESS_INFORMATION* const processIn | |||||
{ | { | ||||
String arg(argv[i]); | String arg(argv[i]); | ||||
#if 0 // FIXME | |||||
// If there are spaces, surround it with quotes. If there are quotes, | // If there are spaces, surround it with quotes. If there are quotes, | ||||
// replace them with \" so that CommandLineToArgv will correctly parse them. | // replace them with \" so that CommandLineToArgv will correctly parse them. | ||||
if (arg.containsAnyOf("\" ")) | if (arg.containsAnyOf("\" ")) | ||||
arg = arg.replace("\"", "\\\"").quoted(); | arg = arg.replace("\"", "\\\"").quoted(); | ||||
#endif | |||||
command << arg << ' '; | command << arg << ' '; | ||||
} | } | ||||
command = command.trim(); | command = command.trim(); | ||||
STARTUPINFOW startupInfo; | |||||
STARTUPINFO startupInfo; | |||||
carla_zeroStruct(startupInfo); | carla_zeroStruct(startupInfo); | ||||
startupInfo.cb = sizeof(STARTUPINFOW); | |||||
startupInfo.cb = sizeof(startupInfo); | |||||
return CreateProcessW(nullptr, const_cast<LPWSTR>(command.toWideCharPointer()), | |||||
nullptr, nullptr, FALSE, CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT, | |||||
nullptr, nullptr, &startupInfo, processInfo) != FALSE; | |||||
return CreateProcess(nullptr, const_cast<LPSTR>(command.toRawUTF8()), | |||||
nullptr, nullptr, FALSE, CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT, | |||||
nullptr, nullptr, &startupInfo, processInfo) != FALSE; | |||||
} | } | ||||
static inline | static inline | ||||
@@ -23,9 +23,9 @@ | |||||
#include <string> | #include <string> | ||||
using juce::MemoryOutputStream; | |||||
using juce::String; | |||||
using juce::XmlElement; | |||||
using juce2::MemoryOutputStream; | |||||
using juce2::String; | |||||
using juce2::XmlElement; | |||||
CARLA_BACKEND_START_NAMESPACE | CARLA_BACKEND_START_NAMESPACE | ||||
@@ -509,7 +509,7 @@ void CarlaStateSave::dumpToMemoryStream(MemoryOutputStream& content) const | |||||
case PLUGIN_LADSPA: | case PLUGIN_LADSPA: | ||||
infoXml << " <Binary>" << xmlSafeString(binary, true) << "</Binary>\n"; | infoXml << " <Binary>" << xmlSafeString(binary, true) << "</Binary>\n"; | ||||
infoXml << " <Label>" << xmlSafeString(label, true) << "</Label>\n"; | infoXml << " <Label>" << xmlSafeString(label, true) << "</Label>\n"; | ||||
infoXml << " <UniqueID>" << juce::int64(uniqueId) << "</UniqueID>\n"; | |||||
infoXml << " <UniqueID>" << juce2::int64(uniqueId) << "</UniqueID>\n"; | |||||
break; | break; | ||||
case PLUGIN_DSSI: | case PLUGIN_DSSI: | ||||
infoXml << " <Binary>" << xmlSafeString(binary, true) << "</Binary>\n"; | infoXml << " <Binary>" << xmlSafeString(binary, true) << "</Binary>\n"; | ||||
@@ -520,7 +520,7 @@ void CarlaStateSave::dumpToMemoryStream(MemoryOutputStream& content) const | |||||
break; | break; | ||||
case PLUGIN_VST2: | case PLUGIN_VST2: | ||||
infoXml << " <Binary>" << xmlSafeString(binary, true) << "</Binary>\n"; | infoXml << " <Binary>" << xmlSafeString(binary, true) << "</Binary>\n"; | ||||
infoXml << " <UniqueID>" << juce::int64(uniqueId) << "</UniqueID>\n"; | |||||
infoXml << " <UniqueID>" << juce2::int64(uniqueId) << "</UniqueID>\n"; | |||||
break; | break; | ||||
case PLUGIN_GIG: | case PLUGIN_GIG: | ||||
case PLUGIN_SF2: | case PLUGIN_SF2: | ||||
@@ -21,8 +21,7 @@ | |||||
#include "CarlaBackend.h" | #include "CarlaBackend.h" | ||||
#include "LinkedList.hpp" | #include "LinkedList.hpp" | ||||
#include "AppConfig.h" | |||||
#include "juce_core/juce_core.h" | |||||
#include "juce_audio_graph/juce_audio_graph.h" | |||||
CARLA_BACKEND_START_NAMESPACE | CARLA_BACKEND_START_NAMESPACE | ||||
@@ -94,16 +93,16 @@ struct CarlaStateSave { | |||||
~CarlaStateSave() noexcept; | ~CarlaStateSave() noexcept; | ||||
void clear() noexcept; | void clear() noexcept; | ||||
bool fillFromXmlElement(const juce::XmlElement* const xmlElement); | |||||
void dumpToMemoryStream(juce::MemoryOutputStream& stream) const; | |||||
bool fillFromXmlElement(const juce2::XmlElement* const xmlElement); | |||||
void dumpToMemoryStream(juce2::MemoryOutputStream& stream) const; | |||||
CARLA_DECLARE_NON_COPY_STRUCT(CarlaStateSave) | CARLA_DECLARE_NON_COPY_STRUCT(CarlaStateSave) | ||||
}; | }; | ||||
static inline | static inline | ||||
juce::String xmlSafeString(const char* const cstring, const bool toXml) | |||||
juce2::String xmlSafeString(const char* const cstring, const bool toXml) | |||||
{ | { | ||||
juce::String newString = juce::String(juce::CharPointer_UTF8(cstring)); | |||||
juce2::String newString = juce2::String(juce2::CharPointer_UTF8(cstring)); | |||||
if (toXml) | if (toXml) | ||||
return newString.replace("&","&").replace("<","<").replace(">",">").replace("'","'").replace("\"","""); | return newString.replace("&","&").replace("<","<").replace(">",">").replace("'","'").replace("\"","""); | ||||
@@ -112,9 +111,9 @@ juce::String xmlSafeString(const char* const cstring, const bool toXml) | |||||
} | } | ||||
static inline | static inline | ||||
juce::String xmlSafeString(const juce::String& string, const bool toXml) | |||||
juce2::String xmlSafeString(const juce2::String& string, const bool toXml) | |||||
{ | { | ||||
juce::String newString(string); | |||||
juce2::String newString(string); | |||||
if (toXml) | if (toXml) | ||||
return newString.replace("&","&").replace("<","<").replace(">",">").replace("'","'").replace("\"","""); | return newString.replace("&","&").replace("<","<").replace(">",">").replace("'","'").replace("\"","""); | ||||
@@ -18,8 +18,8 @@ | |||||
#ifndef CARLA_STRING_HPP_INCLUDED | #ifndef CARLA_STRING_HPP_INCLUDED | ||||
#define CARLA_STRING_HPP_INCLUDED | #define CARLA_STRING_HPP_INCLUDED | ||||
#include "CarlaJuceUtils.hpp" | |||||
#include "CarlaMathUtils.hpp" | #include "CarlaMathUtils.hpp" | ||||
#include "CarlaJuceUtils.hpp" | |||||
#include <algorithm> | #include <algorithm> | ||||