Browse Source

Finish moving things to mini juce

tags/1.9.8
falkTX 7 years ago
parent
commit
0fc5553a49
99 changed files with 4870 additions and 573 deletions
  1. +5
    -5
      Makefile
  2. +3
    -3
      source/backend/CarlaEngine.hpp
  3. +3
    -3
      source/backend/CarlaHostCommon.cpp
  4. +4
    -5
      source/backend/CarlaStandalone.cpp
  5. +2
    -3
      source/backend/CarlaStandaloneNSM.cpp
  6. +3
    -4
      source/backend/CarlaUtils.cpp
  7. +2
    -2
      source/backend/Makefile
  8. +12
    -14
      source/backend/engine/CarlaEngine.cpp
  9. +11
    -12
      source/backend/engine/CarlaEngineBridge.cpp
  10. +7
    -8
      source/backend/engine/CarlaEngineNative.cpp
  11. +9
    -10
      source/backend/plugin/CarlaPlugin.cpp
  12. +8
    -7
      source/backend/plugin/CarlaPluginBridge.cpp
  13. +3
    -4
      source/backend/plugin/CarlaPluginDSSI.cpp
  14. +3
    -3
      source/backend/plugin/CarlaPluginFluidSynth.cpp
  15. +5
    -6
      source/backend/plugin/CarlaPluginJack.cpp
  16. +2
    -2
      source/backend/plugin/CarlaPluginLV2.cpp
  17. +5
    -5
      source/backend/plugin/CarlaPluginLinuxSampler.cpp
  18. +5
    -5
      source/backend/plugin/CarlaPluginNative.cpp
  19. +4
    -5
      source/bridges-plugin/CarlaBridgeLV2.cpp
  20. +4
    -5
      source/bridges-plugin/CarlaBridgePlugin.cpp
  21. +5
    -5
      source/bridges-plugin/Makefile
  22. +2
    -3
      source/bridges-ui/CarlaBridgeUI-LV2.cpp
  23. +1
    -1
      source/bridges-ui/Makefile
  24. +5
    -5
      source/discovery/Makefile
  25. +7
    -8
      source/discovery/carla-discovery.cpp
  26. +2
    -3
      source/libjack/Makefile
  27. +23
    -15
      source/libjack/libjack.cpp
  28. +0
    -3
      source/libjack/libjack.hpp
  29. +0
    -1
      source/libjack/libjack_error.cpp
  30. +0
    -1
      source/libjack/libjack_latency.cpp
  31. +0
    -1
      source/libjack/libjack_port-searching.cpp
  32. +0
    -1
      source/libjack/libjack_server-control.cpp
  33. +2
    -0
      source/libjack/ringbuffer.c
  34. +1
    -1
      source/modules/Makefile
  35. +0
    -2
      source/modules/juce_audio_graph/buffers/juce_AudioSampleBuffer.h
  36. +0
    -4
      source/modules/juce_audio_graph/containers/juce_NamedValueSet.cpp
  37. +0
    -5
      source/modules/juce_audio_graph/containers/juce_Variant.h
  38. +168
    -0
      source/modules/juce_audio_graph/files/juce_DirectoryIterator.cpp
  39. +159
    -0
      source/modules/juce_audio_graph/files/juce_DirectoryIterator.h
  40. +696
    -203
      source/modules/juce_audio_graph/files/juce_File.cpp
  41. +2
    -44
      source/modules/juce_audio_graph/files/juce_File.h
  42. +136
    -0
      source/modules/juce_audio_graph/files/juce_FileOutputStream.cpp
  43. +122
    -0
      source/modules/juce_audio_graph/files/juce_FileOutputStream.h
  44. +2
    -2
      source/modules/juce_audio_graph/files/juce_TemporaryFile.cpp
  45. +91
    -3
      source/modules/juce_audio_graph/juce_audio_graph.cpp
  46. +14
    -1
      source/modules/juce_audio_graph/juce_audio_graph.h
  47. +163
    -0
      source/modules/juce_audio_graph/maths/juce_Random.cpp
  48. +149
    -0
      source/modules/juce_audio_graph/maths/juce_Random.h
  49. +1
    -1
      source/modules/juce_audio_graph/memory/juce_Memory.h
  50. +168
    -0
      source/modules/juce_audio_graph/memory/juce_SharedResourcePointer.h
  51. +2
    -0
      source/modules/juce_audio_graph/streams/juce_FileInputSource.cpp
  52. +66
    -0
      source/modules/juce_audio_graph/streams/juce_FileInputStream.cpp
  53. +255
    -0
      source/modules/juce_audio_graph/streams/juce_FileOutputStream.cpp
  54. +122
    -0
      source/modules/juce_audio_graph/streams/juce_FileOutputStream.h
  55. +2
    -1
      source/modules/juce_audio_graph/streams/juce_InputSource.h
  56. +0
    -9
      source/modules/juce_audio_graph/streams/juce_OutputStream.cpp
  57. +1
    -4
      source/modules/juce_audio_graph/text/juce_CharPointer_UTF8.h
  58. +2
    -2
      source/modules/juce_audio_graph/text/juce_CharacterFunctions.cpp
  59. +46
    -0
      source/modules/juce_audio_graph/text/juce_String.cpp
  60. +19
    -12
      source/modules/juce_audio_graph/text/juce_String.h
  61. +0
    -10
      source/modules/juce_audio_graph/text/juce_StringArray.cpp
  62. +0
    -13
      source/modules/juce_audio_graph/text/juce_StringArray.h
  63. +5
    -5
      source/modules/juce_audio_graph/text/juce_StringPool.cpp
  64. +399
    -0
      source/modules/juce_audio_graph/threads/juce_ChildProcess.cpp
  65. +122
    -0
      source/modules/juce_audio_graph/threads/juce_ChildProcess.h
  66. +164
    -0
      source/modules/juce_audio_graph/threads/juce_Process.h
  67. +239
    -0
      source/modules/juce_audio_graph/threads/juce_ScopedLock.h
  68. +110
    -0
      source/modules/juce_audio_graph/threads/juce_SpinLock.h
  69. +631
    -0
      source/modules/juce_audio_graph/time/juce_Time.cpp
  70. +401
    -0
      source/modules/juce_audio_graph/time/juce_Time.h
  71. +4
    -18
      source/modules/juce_audio_graph/xml/juce_XmlDocument.cpp
  72. +2
    -2
      source/modules/juce_audio_graph/xml/juce_XmlElement.h
  73. +1
    -1
      source/native-plugins/audio-file.cpp
  74. +2
    -3
      source/native-plugins/bigmeter.cpp
  75. +2
    -0
      source/native-plugins/distrho-3bandeq.cpp
  76. +2
    -0
      source/native-plugins/distrho-3bandsplitter.cpp
  77. +3
    -1
      source/native-plugins/distrho-kars.cpp
  78. +3
    -1
      source/native-plugins/distrho-nekobi.cpp
  79. +3
    -1
      source/native-plugins/distrho-pingpongpan.cpp
  80. +2
    -1
      source/native-plugins/distrho-prom.cpp
  81. +3
    -1
      source/native-plugins/distrho-vectorjuice.cpp
  82. +3
    -1
      source/native-plugins/distrho-wobblejuice.cpp
  83. +2
    -3
      source/native-plugins/midi-file.cpp
  84. +2
    -4
      source/native-plugins/zita-at1.cpp
  85. +0
    -1
      source/native-plugins/zita-bls1.cpp
  86. +0
    -1
      source/native-plugins/zita-rev1.cpp
  87. +2
    -3
      source/native-plugins/zynaddsubfx-fx.cpp
  88. +2
    -4
      source/native-plugins/zynaddsubfx-synth.cpp
  89. +1
    -1
      source/plugin/Makefile
  90. +4
    -5
      source/plugin/carla-lv2-export.cpp
  91. +3
    -4
      source/plugin/carla-vst.cpp
  92. +4
    -5
      source/utils/CarlaBinaryUtils.hpp
  93. +2
    -3
      source/utils/CarlaDssiUtils.cpp
  94. +185
    -0
      source/utils/CarlaJuceUtils.hpp
  95. +5
    -6
      source/utils/CarlaLv2Utils.hpp
  96. +10
    -9
      source/utils/CarlaPipeUtils.cpp
  97. +5
    -5
      source/utils/CarlaStateUtils.cpp
  98. +7
    -8
      source/utils/CarlaStateUtils.hpp
  99. +1
    -1
      source/utils/CarlaString.hpp

+ 5
- 5
Makefile View File

@@ -55,7 +55,7 @@ ALL_LIBS += $(MODULEDIR)/carla_engine_plugin.a
ALL_LIBS += $(MODULEDIR)/carla_plugin.a
ALL_LIBS += $(MODULEDIR)/jackbridge.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)/rtmempool.a

@@ -149,7 +149,7 @@ theme: libs
# Binaries (posix32)

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)/rtmempool.posix32.a

@@ -161,7 +161,7 @@ posix32: $(LIBS_POSIX32)
# Binaries (posix64)

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)/rtmempool.posix64.a

@@ -177,7 +177,7 @@ LIBS_WIN32 = $(MODULEDIR)/jackbridge.win32.a
else
LIBS_WIN32 = $(MODULEDIR)/jackbridge.win32e.a
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)/rtmempool.win32.a

@@ -193,7 +193,7 @@ LIBS_WIN64 = $(MODULEDIR)/jackbridge.win64.a
else
LIBS_WIN64 = $(MODULEDIR)/jackbridge.win64e.a
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)/rtmempool.win64.a



+ 3
- 3
source/backend/CarlaEngine.hpp View File

@@ -24,7 +24,7 @@
struct CarlaOscData;
#endif

namespace juce {
namespace juce2 {
class MemoryOutputStream;
class XmlDocument;
}
@@ -1134,12 +1134,12 @@ protected:
/*!
* 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.
*/
bool loadProjectInternal(juce::XmlDocument& xmlDoc);
bool loadProjectInternal(juce2::XmlDocument& xmlDoc);

#ifndef BUILD_BRIDGE
// -------------------------------------------------------------------


+ 3
- 3
source/backend/CarlaHostCommon.cpp View File

@@ -18,7 +18,7 @@
#include "CarlaHost.h"
#include "CarlaString.hpp"

#include "juce_core/juce_core.h"
#include "juce_audio_graph/juce_audio_graph.h"

namespace CB = CarlaBackend;

@@ -106,7 +106,7 @@ const char* carla_get_library_filename()

if (ret.isEmpty())
{
using namespace juce;
using namespace juce2;
ret = File(File::getSpecialLocation(File::currentExecutableFile)).getFullPathName().toRawUTF8();
}

@@ -121,7 +121,7 @@ const char* carla_get_library_folder()

if (ret.isEmpty())
{
using namespace juce;
using namespace juce2;
ret = File(File::getSpecialLocation(File::currentExecutableFile).getParentDirectory()).getFullPathName().toRawUTF8();
}



+ 4
- 5
source/backend/CarlaStandalone.cpp View File

@@ -27,13 +27,12 @@
#include "CarlaBackendUtils.hpp"
#include "CarlaBase64Utils.hpp"

#ifndef BUILD_BRIDGE
#ifdef BUILD_BRIDGE
# include "juce_audio_graph/juce_audio_graph.h"
#else
# include "CarlaLogThread.hpp"
#endif

#include "AppConfig.h"
#include "juce_core/juce_core.h"

namespace CB = CarlaBackend;
using CB::EngineOptions;

@@ -145,7 +144,7 @@ static void carla_engine_init_common()
gStandalone.engine->setFileCallback(gStandalone.fileCallback, gStandalone.fileCallbackPtr);

#ifdef BUILD_BRIDGE
using juce::File;
using juce2::File;
File juceBinaryDir(File::getSpecialLocation(File::currentExecutableFile).getParentDirectory());

/*


+ 2
- 3
source/backend/CarlaStandaloneNSM.cpp View File

@@ -29,8 +29,7 @@
#include "CarlaOscUtils.hpp"
#include "CarlaString.hpp"

#include "AppConfig.h"
#include "juce_core/juce_core.h"
#include "juce_audio_graph/juce_audio_graph.h"

namespace CB = CarlaBackend;

@@ -268,7 +267,7 @@ protected:
}
else
{
using namespace juce;
using namespace juce2;

if (carla_is_engine_running())
carla_engine_close();


+ 3
- 4
source/backend/CarlaUtils.cpp View File

@@ -513,7 +513,7 @@ const char* carla_get_supported_file_extensions()
#if 0
// Audio files
{
using namespace juce;
using namespace juce2;

AudioFormatManager afm;
afm.registerBasicFormats();
@@ -553,7 +553,6 @@ void carla_set_process_name(const char* name)
carla_debug("carla_set_process_name(\"%s\")", name);

CarlaThread::setCurrentThreadName(name);
juce::Thread::setCurrentThreadName(name);
}

// -------------------------------------------------------------------------------------------------------------------
@@ -694,7 +693,7 @@ const char* carla_get_library_filename()

if (ret.isEmpty())
{
using juce::File;
using juce2::File;
ret = File(File::getSpecialLocation(File::currentExecutableFile)).getFullPathName().toRawUTF8();
}

@@ -709,7 +708,7 @@ const char* carla_get_library_folder()

if (ret.isEmpty())
{
using juce::File;
using juce2::File;
ret = File(File::getSpecialLocation(File::currentExecutableFile).getParentDirectory()).getFullPathName().toRawUTF8();
}



+ 2
- 2
source/backend/Makefile View File

@@ -26,7 +26,7 @@ STANDALONE_LIBS = $(MODULEDIR)/carla_engine.a
STANDALONE_LIBS += $(MODULEDIR)/carla_plugin.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)/native-plugins.a
STANDALONE_LIBS += $(MODULEDIR)/rtmempool.a
@@ -42,7 +42,7 @@ endif
STANDALONE_LIBS += $(MODULEDIR)/rtaudio.a
STANDALONE_LIBS += $(MODULEDIR)/rtmidi.a

UTILS_LIBS += $(MODULEDIR)/juce_core.a
UTILS_LIBS += $(MODULEDIR)/juce_audio_graph.a
UTILS_LIBS += $(MODULEDIR)/lilv.a

# ----------------------------------------------------------------------------------------------------------------------------


+ 12
- 14
source/backend/engine/CarlaEngine.cpp View File

@@ -35,18 +35,16 @@

#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

@@ -1674,7 +1672,7 @@ void CarlaEngine::setPluginPeaks(const uint pluginId, float const inPeaks[2], fl
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
for (uint i=0; i < pData->curPluginCount; ++i)
@@ -1876,7 +1874,7 @@ static String findBinaryInCustomPath(const char* const searchPath, const char* c
return String();
}

bool CarlaEngine::loadProjectInternal(juce::XmlDocument& xmlDoc)
bool CarlaEngine::loadProjectInternal(juce2::XmlDocument& xmlDoc)
{
ScopedPointer<XmlElement> xmlElement(xmlDoc.getDocumentElement(true));
CARLA_SAFE_ASSERT_RETURN_ERR(xmlElement != nullptr, "Failed to parse project file");


+ 11
- 12
source/backend/engine/CarlaEngineBridge.cpp View File

@@ -31,17 +31,15 @@
# include <xmmintrin.h>
#endif

#include "AppConfig.h"
#include "juce_core/juce_core.h"
#include "juce_audio_graph/juce_audio_graph.h"

// must be last
#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

@@ -79,13 +77,13 @@ private:
// -------------------------------------------------------------------

class CarlaEngineBridge : public CarlaEngine,
private Thread,
private CarlaThread,
private LatencyChangedCallback
{
public:
CarlaEngineBridge(const char* const audioPoolBaseName, const char* const rtClientBaseName, const char* const nonRtClientBaseName, const char* const nonRtServerBaseName)
: CarlaEngine(),
Thread("CarlaEngineBridge"),
CarlaThread("CarlaEngineBridge"),
fShmAudioPool(),
fShmRtClientControl(),
fShmNonRtClientControl(),
@@ -207,7 +205,8 @@ public:
fShmNonRtServerControl.commitWrite();
}

startThread(Thread::realtimeAudioPriority);
// TODO
startThread(/*Thread::realtimeAudioPriority*/);

return true;
}
@@ -564,7 +563,7 @@ public:
if (fLastPingTime > 0 && Time::currentTimeMillis() > fLastPingTime + 30000 && ! wasFirstIdle)
{
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);
}
}
@@ -955,7 +954,7 @@ protected:

bool quitReceived = false;

for (; ! threadShouldExit();)
for (; ! shouldThreadExit();)
{
const BridgeRtClientControl::WaitHelper helper(fShmRtClientControl);



+ 7
- 8
source/backend/engine/CarlaEngineNative.cpp View File

@@ -34,14 +34,13 @@
#include "CarlaHost.h"
#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



+ 9
- 10
source/backend/plugin/CarlaPlugin.cpp View File

@@ -25,16 +25,15 @@

#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



+ 8
- 7
source/backend/plugin/CarlaPluginBridge.cpp View File

@@ -30,14 +30,15 @@

#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

@@ -171,7 +172,7 @@ protected:
arguments.add(fLabel);

// uniqueId
arguments.add(String(static_cast<juce::int64>(kPlugin->getUniqueId())));
arguments.add(String(static_cast<juce2::int64>(kPlugin->getUniqueId())));

bool started;



+ 3
- 4
source/backend/plugin/CarlaPluginDSSI.cpp View File

@@ -27,10 +27,9 @@
# include "CarlaThread.hpp"
#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) \
/* check argument count */ \


+ 3
- 3
source/backend/plugin/CarlaPluginFluidSynth.cpp View File

@@ -22,7 +22,7 @@

#include "CarlaMathUtils.hpp"

#include "juce_core/juce_core.h"
#include "juce_audio_graph/juce_audio_graph.h"

#include <fluidsynth.h>

@@ -32,8 +32,8 @@

#define FLUID_DEFAULT_POLYPHONY 64

using juce::String;
using juce::StringArray;
using juce2::String;
using juce2::StringArray;

CARLA_BACKEND_START_NAMESPACE



+ 5
- 6
source/backend/plugin/CarlaPluginJack.cpp View File

@@ -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



+ 2
- 2
source/backend/plugin/CarlaPluginLV2.cpp View File

@@ -37,12 +37,12 @@ extern "C" {
#include "rtmempool/rtmempool-lv2.h"
}

#include "juce_core/juce_core.h"
#include "juce_audio_graph/juce_audio_graph.h"

#include <string>
#include <vector>

using juce::File;
using juce2::File;

#define URI_CARLA_ATOM_WORKER "http://kxstudio.sf.net/ns/carla/atomWorker"



+ 5
- 5
source/backend/plugin/CarlaPluginLinuxSampler.cpp View File

@@ -31,7 +31,7 @@
#include "CarlaBackendUtils.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

@@ -461,7 +461,7 @@ public:
if (programList.size() == MAX_MIDI_CHANNELS)
{
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());



+ 5
- 5
source/backend/plugin/CarlaPluginNative.cpp View File

@@ -1,6 +1,6 @@
/*
* 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
* modify it under the terms of the GNU General Public License as
@@ -21,11 +21,11 @@
#include "CarlaMathUtils.hpp"
#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
std::size_t carla_getNativePluginCount() noexcept;


+ 4
- 5
source/bridges-plugin/CarlaBridgeLV2.cpp View File

@@ -27,8 +27,7 @@
#include "CarlaLv2Utils.hpp"
#include "CarlaUtils.h"

#include "AppConfig.h"
#include "juce_core/juce_core.h"
#include "juce_audio_graph/juce_audio_graph.h"

// ---------------------------------------------------------------------------------------------------------------------
// -Weffc++ compat ext widget
@@ -109,7 +108,7 @@ public:

setCallback(_engine_callback, this);

using juce::File;
using juce2::File;
const File pluginFile(File::getSpecialLocation(File::currentExecutableFile).withFileExtension("xml"));

if (! loadProject(pluginFile.getFullPathName().toRawUTF8()))
@@ -825,7 +824,7 @@ const LV2_Descriptor* lv2_descriptor(uint32_t index)

if (ret.isEmpty())
{
using namespace juce;
using namespace juce2;
const File file(File::getSpecialLocation(File::currentExecutableFile).withFileExtension("ttl"));
ret = String("file://" + file.getFullPathName()).toRawUTF8();
}
@@ -853,7 +852,7 @@ const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index)

if (ret.isEmpty())
{
using namespace juce;
using namespace juce2;
const File file(File::getSpecialLocation(File::currentExecutableFile).getSiblingFile("ext-ui"));
ret = String("file://" + file.getFullPathName()).toRawUTF8();
}


+ 4
- 5
source/bridges-plugin/CarlaBridgePlugin.cpp View File

@@ -36,17 +36,16 @@

#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::EngineCallbackOpcode;
using CarlaBackend::EngineCallbackOpcode2Str;
using CarlaBackend::runMainLoopOnce;

using juce::CharPointer_UTF8;
using juce::File;
using juce::String;
using juce2::CharPointer_UTF8;
using juce2::File;
using juce2::String;

// -------------------------------------------------------------------------



+ 5
- 5
source/bridges-plugin/Makefile View File

@@ -43,11 +43,11 @@ LIBS_win64 = $(MODULEDIR)/jackbridge.win64e.a
endif
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)

LIBS_native += $(MODULEDIR)/lilv.a


+ 2
- 3
source/bridges-ui/CarlaBridgeUI-LV2.cpp View File

@@ -21,15 +21,14 @@
#include "CarlaMIDI.h"
#include "LinkedList.hpp"

#include "AppConfig.h"
#include "juce_core/juce_core.h"
#include "juce_audio_graph/juce_audio_graph.h"

#include <string>
#include <vector>

#define URI_CARLA_ATOM_WORKER "http://kxstudio.sf.net/ns/carla/atomWorker"

using juce::File;
using juce2::File;

CARLA_BRIDGE_START_NAMESPACE



+ 1
- 1
source/bridges-ui/Makefile View File

@@ -129,7 +129,7 @@ ui_lv2-windows: $(BINDIR)/$(MODULENAME)-lv2-windows.exe
# Common libs

LIBS = \
$(MODULEDIR)/juce_core.a \
$(MODULEDIR)/juce_audio_graph.a \
$(MODULEDIR)/lilv.a

# ----------------------------------------------------------------------------------------------------------------------------


+ 5
- 5
source/discovery/Makefile View File

@@ -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)

LIBS_native += $(MODULEDIR)/lilv.a


+ 7
- 8
source/discovery/carla-discovery.cpp View File

@@ -45,14 +45,13 @@

#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;

using juce::CharPointer_UTF8;
using juce::File;
using juce::StringArray;
using juce2::CharPointer_UTF8;
using juce2::File;
using juce2::StringArray;

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));

if (const char* const uri = lilvPlugin.get_uri().as_string())
URIs.addIfNotAlreadyThere(juce::String(uri));
URIs.addIfNotAlreadyThere(juce2::String(uri));
}

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)
{
#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);

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)
{
#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);

if (! file.existsAsFile())


+ 2
- 3
source/libjack/Makefile View File

@@ -22,9 +22,8 @@ endif
# ----------------------------------------------------------------------------------------------------------------------

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

# ----------------------------------------------------------------------------------------------------------------------



+ 23
- 15
source/libjack/libjack.cpp View File

@@ -16,12 +16,12 @@
*/

#include "libjack.hpp"
#include <sys/prctl.h>

#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*);

@@ -34,9 +34,16 @@ int jack_carla_interposed_action(int, int, void*)

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:
struct Callback {
@@ -46,7 +53,7 @@ public:
};

CarlaJackRealtimeThread(Callback* const callback)
: Thread("CarlaJackRealtimeThread"),
: CarlaThread("CarlaJackRealtimeThread"),
fCallback(callback) {}

protected:
@@ -63,7 +70,7 @@ private:

// --------------------------------------------------------------------------------------------------------------------

class CarlaJackNonRealtimeThread : public Thread
class CarlaJackNonRealtimeThread : public CarlaThread
{
public:
struct Callback {
@@ -73,7 +80,7 @@ public:
};

CarlaJackNonRealtimeThread(Callback* const callback)
: Thread("CarlaJackNonRealtimeThread"),
: CarlaThread("CarlaJackNonRealtimeThread"),
fCallback(callback) {}

protected:
@@ -380,7 +387,7 @@ bool CarlaJackAppClient::initSharedMemmory()
// tell backend we're live
const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);

fLastPingTime = Time::currentTimeMillis();
fLastPingTime = getCurrentTimeMilliseconds();
CARLA_SAFE_ASSERT(fLastPingTime > 0);

// ready!
@@ -855,7 +862,7 @@ bool CarlaJackAppClient::handleNonRtData()
#endif

if (opcode != kPluginBridgeNonRtClientNull && opcode != kPluginBridgeNonRtClientPingOnOff && fLastPingTime > 0)
fLastPingTime = Time::currentTimeMillis();
fLastPingTime = getCurrentTimeMilliseconds();

switch (opcode)
{
@@ -872,7 +879,7 @@ bool CarlaJackAppClient::handleNonRtData()
case kPluginBridgeNonRtClientPingOnOff: {
const uint32_t onOff(fShmNonRtClientControl.readBool());

fLastPingTime = onOff ? Time::currentTimeMillis() : -1;
fLastPingTime = onOff ? getCurrentTimeMilliseconds() : -1;
} break;

case kPluginBridgeNonRtClientActivate:
@@ -968,7 +975,7 @@ void CarlaJackAppClient::runRealtimeThread()

bool quitReceived = false;

for (; ! fRealtimeThread.threadShouldExit();)
for (; ! fRealtimeThread.shouldThreadExit();)
{
if (handleRtData())
{
@@ -1003,15 +1010,16 @@ void CarlaJackAppClient::runNonRealtimeThread()
fMidiOutBuffers[i].isInput = false;
}

fRealtimeThread.startThread(Thread::realtimeAudioPriority);
// TODO
fRealtimeThread.startThread(/*Thread::realtimeAudioPriority*/);

fLastPingTime = Time::currentTimeMillis();
fLastPingTime = getCurrentTimeMilliseconds();
carla_stdout("Carla Jack Client Ready!");

bool quitReceived = false,
timedOut = false;

for (; ! fNonRealtimeThread.threadShouldExit();)
for (; ! fNonRealtimeThread.shouldThreadExit();)
{
carla_msleep(50);

@@ -1023,7 +1031,7 @@ void CarlaJackAppClient::runNonRealtimeThread()
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...");



+ 0
- 3
source/libjack/libjack.hpp View File

@@ -28,9 +28,6 @@
#include "CarlaMutex.hpp"
#include "LinkedList.hpp"

#include "AppConfig.h"
#include "juce_core/juce_core.h"

#if 0
#include <jack/jack.h>
#include <jack/midiport.h>


+ 0
- 1
source/libjack/libjack_error.cpp View File

@@ -15,7 +15,6 @@
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/

// need to include this first
#include "libjack.hpp"

CARLA_BACKEND_USE_NAMESPACE


+ 0
- 1
source/libjack/libjack_latency.cpp View File

@@ -15,7 +15,6 @@
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/

// need to include this first
#include "libjack.hpp"

CARLA_BACKEND_USE_NAMESPACE


+ 0
- 1
source/libjack/libjack_port-searching.cpp View File

@@ -15,7 +15,6 @@
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/

// need to include this first
#include "libjack.hpp"

CARLA_BACKEND_USE_NAMESPACE


+ 0
- 1
source/libjack/libjack_server-control.cpp View File

@@ -15,7 +15,6 @@
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/

// need to include this first
#include "libjack.hpp"

CARLA_BACKEND_USE_NAMESPACE


+ 2
- 0
source/libjack/ringbuffer.c View File

@@ -20,6 +20,8 @@
This is safe for the case of one read thread and one write thread.
*/

#define USE_MLOCK

#include <stdlib.h>
#include <string.h>
#ifdef USE_MLOCK


+ 1
- 1
source/modules/Makefile View File

@@ -9,7 +9,7 @@
all:

clean:
$(MAKE) clean -C juce_core
$(MAKE) clean -C juce_audio_graph
$(MAKE) clean -C lilv
$(MAKE) clean -C rtaudio
$(MAKE) clean -C rtmempool


+ 0
- 2
source/modules/juce_audio_graph/buffers/juce_AudioSampleBuffer.h View File

@@ -31,8 +31,6 @@
#ifndef JUCE_AUDIOSAMPLEBUFFER_H_INCLUDED
#define JUCE_AUDIOSAMPLEBUFFER_H_INCLUDED
#include "CarlaMathUtils.hpp"
//==============================================================================
/**
A multi-channel buffer of floating point audio samples.


+ 0
- 4
source/modules/juce_audio_graph/containers/juce_NamedValueSet.cpp View File

@@ -89,12 +89,8 @@ bool NamedValueSet::isEmpty() const noexcept
static const var& getNullVarRef() noexcept
{
#if JUCE_ALLOW_STATIC_NULL_VARIABLES
return var::null;
#else
static var nullVar;
return nullVar;
#endif
}
const var& NamedValueSet::operator[] (const Identifier& name) const noexcept


+ 0
- 5
source/modules/juce_audio_graph/containers/juce_Variant.h View File

@@ -76,11 +76,6 @@ public:
/** Destructor. */
~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 (int value) noexcept;
var (int64 value) noexcept;


+ 168
- 0
source/modules/juce_audio_graph/files/juce_DirectoryIterator.cpp View File

@@ -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;
}

+ 159
- 0
source/modules/juce_audio_graph/files/juce_DirectoryIterator.h View File

@@ -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

+ 696
- 203
source/modules/juce_audio_graph/files/juce_File.cpp
File diff suppressed because it is too large
View File


+ 2
- 44
source/modules/juce_audio_graph/files/juce_File.h View File

@@ -742,41 +742,6 @@ public:
/** The user's home folder. This is the same as using File ("~"). */
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.
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
@@ -812,17 +777,10 @@ public:
*/
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. */
hostApplicationPath,
#if JUCE_WINDOWS
#ifdef CARLA_OS_WIN
/** On a Windows machine, returns the location of the Windows/System32 folder. */
windowsSystemDirectory,
#endif
@@ -925,7 +883,7 @@ public:
*/
File getLinkedTarget() const;
#if JUCE_WINDOWS
#ifdef CARLA_OS_WIN
/** Windows ONLY - Creates a win32 .LNK shortcut file that links to this file. */
bool createShortcut (const String& description, const File& linkFileToCreate) const;


+ 136
- 0
source/modules/juce_audio_graph/files/juce_FileOutputStream.cpp View File

@@ -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);
}

+ 122
- 0
source/modules/juce_audio_graph/files/juce_FileOutputStream.h View File

@@ -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

+ 2
- 2
source/modules/juce_audio_graph/files/juce_TemporaryFile.cpp View File

@@ -91,7 +91,7 @@ bool TemporaryFile::overwriteTargetFileWithTemporary() const
if (temporaryFile.replaceFileIn (targetFile))
return true;
Thread::sleep (100);
carla_msleep (100);
}
}
else
@@ -112,7 +112,7 @@ bool TemporaryFile::deleteTemporaryFile() const
if (temporaryFile.deleteFile())
return true;
Thread::sleep (50);
carla_msleep (50);
}
return false;


+ 91
- 3
source/modules/juce_audio_graph/juce_audio_graph.cpp View File

@@ -19,9 +19,28 @@
#include "juce_audio_graph.h"
#include <locale>
#include <ctime>
#include <cctype>
#include <cstdarg>
#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>
@@ -29,18 +48,87 @@
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 "text/juce_CharacterFunctions.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_MidiMessage.cpp"
#include "maths/juce_Random.cpp"
#include "misc/juce_Result.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_XmlDocument.cpp"


+ 14
- 1
source/modules/juce_audio_graph/juce_audio_graph.h View File

@@ -19,9 +19,9 @@
#ifndef JUCE_AUDIO_GRAPH_H_INCLUDED
#define JUCE_AUDIO_GRAPH_H_INCLUDED
#include "CarlaMathUtils.hpp"
#include "CarlaJuceUtils.hpp"
#include "CarlaMutex.hpp"
#include "distrho/extra/ScopedPointer.hpp"
#include <algorithm>
@@ -144,6 +144,10 @@ class XmlElement;
#include "text/juce_Identifier.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_OwnedArray.h"
#include "containers/juce_ReferenceCountedArray.h"
@@ -156,13 +160,19 @@ class XmlElement;
#include "streams/juce_OutputStream.h"
#include "streams/juce_MemoryOutputStream.h"
#include "maths/juce_Random.h"
#include "misc/juce_Result.h"
#include "text/juce_StringPool.h"
#include "time/juce_Time.h"
#include "files/juce_File.h"
#include "files/juce_DirectoryIterator.h"
#include "files/juce_TemporaryFile.h"
#include "streams/juce_FileInputStream.h"
#include "streams/juce_FileInputSource.h"
#include "streams/juce_FileOutputStream.h"
#include "buffers/juce_AudioSampleBuffer.h"
#include "midi/juce_MidiBuffer.h"
@@ -173,6 +183,9 @@ class AudioProcessor;
#include "processors/juce_AudioProcessor.h"
#include "processors/juce_AudioProcessorGraph.h"
#include "threads/juce_ChildProcess.h"
#include "threads/juce_Process.h"
#include "xml/juce_XmlElement.h"
#include "xml/juce_XmlDocument.h"


+ 163
- 0
source/modules/juce_audio_graph/maths/juce_Random.cpp View File

@@ -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

+ 149
- 0
source/modules/juce_audio_graph/maths/juce_Random.h View File

@@ -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

+ 1
- 1
source/modules/juce_audio_graph/memory/juce_Memory.h View File

@@ -110,7 +110,7 @@ inline void writeUnaligned (void* dstPtr, Type value) noexcept
#if (JUCE_COMPILER_SUPPORTS_ARC && defined (__OBJC__)) || DOXYGEN
#define JUCE_AUTORELEASEPOOL @autoreleasepool
#else
#define JUCE_AUTORELEASEPOOL const juce::ScopedAutoReleasePool JUCE_JOIN_MACRO (autoReleasePool_, __LINE__);
#define JUCE_AUTORELEASEPOOL const juce2::ScopedAutoReleasePool JUCE_JOIN_MACRO (autoReleasePool_, __LINE__);
#endif
#else


+ 168
- 0
source/modules/juce_audio_graph/memory/juce_SharedResourcePointer.h View File

@@ -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

+ 2
- 0
source/modules/juce_audio_graph/streams/juce_FileInputSource.cpp View File

@@ -47,6 +47,7 @@ InputStream* FileInputSource::createInputStreamFor (const String& relatedItemPat
return file.getSiblingFile (relatedItemPath).createInputStream();
}
#if 0
int64 FileInputSource::hashCode() const
{
int64 h = file.hashCode();
@@ -56,3 +57,4 @@ int64 FileInputSource::hashCode() const
return h;
}
#endif

+ 66
- 0
source/modules/juce_audio_graph/streams/juce_FileInputStream.cpp View File

@@ -84,3 +84,69 @@ bool FileInputStream::setPosition (int64 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

+ 255
- 0
source/modules/juce_audio_graph/streams/juce_FileOutputStream.cpp View File

@@ -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

+ 122
- 0
source/modules/juce_audio_graph/streams/juce_FileOutputStream.h View File

@@ -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

+ 2
- 1
source/modules/juce_audio_graph/streams/juce_InputSource.h View File

@@ -66,10 +66,11 @@ public:
*/
virtual InputStream* createInputStreamFor (const String& relatedItemPath) = 0;
#if 0
/** Returns a hash code that uniquely represents this item.
*/
virtual int64 hashCode() const = 0;
#endif
private:
//==============================================================================


+ 0
- 9
source/modules/juce_audio_graph/streams/juce_OutputStream.cpp View File

@@ -176,16 +176,7 @@ bool OutputStream::writeDoubleBigEndian (double value)
bool OutputStream::writeString (const String& text)
{
#if (JUCE_STRING_UTF_TYPE == 8)
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,


+ 1
- 4
source/modules/juce_audio_graph/text/juce_CharPointer_UTF8.h View File

@@ -476,11 +476,8 @@ public:
/** Parses this string as a 64-bit integer. */
int64 getIntValue64() const noexcept
{
#if JUCE_LINUX || JUCE_ANDROID || JUCE_MINGW
return atoll (data);
#elif JUCE_WINDOWS
return _atoi64 (data);
#else
#if 0
return CharacterFunctions::getIntValue <int64, CharPointer_UTF8> (*this);
#endif
}


+ 2
- 2
source/modules/juce_audio_graph/text/juce_CharacterFunctions.cpp View File

@@ -42,7 +42,7 @@ juce_wchar CharacterFunctions::toLowerCase (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;
#else
return toLowerCase (character) != character;
@@ -51,7 +51,7 @@ bool CharacterFunctions::isUpperCase (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;
#else
return toUpperCase (character) != character;


+ 46
- 0
source/modules/juce_audio_graph/text/juce_String.cpp View File

@@ -729,6 +729,11 @@ String& String::operator+= (const char ch)
return operator+= (asString);
}
String& String::operator+= (const juce_wchar ch)
{
return operator+= (charToString(ch));
}
namespace StringHelpers
{
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 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* const 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;
}
//=====================================================================================================================
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).
String String::formatted (const String pf, ... )
{


+ 19
- 12
source/modules/juce_audio_graph/text/juce_String.h View File

@@ -115,18 +115,7 @@ public:
/** Destructor. */
~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;
//==============================================================================
@@ -168,6 +157,8 @@ public:
String& operator+= (uint64 numberToAppend);
/** Appends a character at the end of this string. */
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.
@@ -807,6 +798,16 @@ public:
*/
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.
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);
/** Concatenates two strings. */
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. */
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);
/** Concatenates two strings. */
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. */
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. */
JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const char* string2);


+ 0
- 10
source/modules/juce_audio_graph/text/juce_StringArray.cpp View File

@@ -64,16 +64,6 @@ StringArray::StringArray (const char* const* initialStrings, int 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)
{
strings = other.strings;


+ 0
- 13
source/modules/juce_audio_graph/text/juce_StringArray.h View File

@@ -75,19 +75,6 @@ public:
*/
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
StringArray (const std::initializer_list<const char*>& strings);
#endif


+ 5
- 5
source/modules/juce_audio_graph/text/juce_StringPool.cpp View File

@@ -108,7 +108,7 @@ String StringPool::getPooledString (const char* const newString)
if (newString == nullptr || *newString == 0)
return String();
const ScopedLock sl (lock);
const CarlaRecursiveMutexLocker sl (lock);
garbageCollectIfNeeded();
return addPooledString (strings, CharPointer_UTF8 (newString));
}
@@ -118,7 +118,7 @@ String StringPool::getPooledString (String::CharPointerType start, String::CharP
if (start.isEmpty() || start == end)
return String();
const ScopedLock sl (lock);
const CarlaRecursiveMutexLocker sl (lock);
garbageCollectIfNeeded();
return addPooledString (strings, StartEndString (start, end));
}
@@ -128,7 +128,7 @@ String StringPool::getPooledString (StringRef newString)
if (newString.isEmpty())
return String();
const ScopedLock sl (lock);
const CarlaRecursiveMutexLocker sl (lock);
garbageCollectIfNeeded();
return addPooledString (strings, newString.text);
}
@@ -138,7 +138,7 @@ String StringPool::getPooledString (const String& newString)
if (newString.isEmpty())
return String();
const ScopedLock sl (lock);
const CarlaRecursiveMutexLocker sl (lock);
garbageCollectIfNeeded();
return addPooledString (strings, newString);
}
@@ -152,7 +152,7 @@ void StringPool::garbageCollectIfNeeded()
void StringPool::garbageCollect()
{
const ScopedLock sl (lock);
const CarlaRecursiveMutexLocker sl (lock);
for (int i = strings.size(); --i >= 0;)
if (strings.getReference(i).getReferenceCount() == 1)


+ 399
- 0
source/modules/juce_audio_graph/threads/juce_ChildProcess.cpp View File

@@ -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

+ 122
- 0
source/modules/juce_audio_graph/threads/juce_ChildProcess.h View File

@@ -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

+ 164
- 0
source/modules/juce_audio_graph/threads/juce_Process.h View File

@@ -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

+ 239
- 0
source/modules/juce_audio_graph/threads/juce_ScopedLock.h View File

@@ -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

+ 110
- 0
source/modules/juce_audio_graph/threads/juce_SpinLock.h View File

@@ -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

+ 631
- 0
source/modules/juce_audio_graph/time/juce_Time.cpp View File

@@ -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

+ 401
- 0
source/modules/juce_audio_graph/time/juce_Time.h View File

@@ -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

+ 4
- 18
source/modules/juce_audio_graph/xml/juce_XmlDocument.cpp View File

@@ -124,29 +124,17 @@ XmlElement* XmlDocument::getDocumentElement (const bool onlyReadOuterDocumentEle
MemoryOutputStream data;
data.writeFromInputStream (*in, onlyReadOuterDocumentElement ? 8192 : -1);
#if JUCE_STRING_UTF_TYPE == 8
if (data.getDataSize() > 2)
{
data.writeByte (0);
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;
}
#if 0 // FIXME
result << (juce_wchar) charCode;
#endif
}
else
{


+ 2
- 2
source/modules/juce_audio_graph/xml/juce_XmlElement.h View File

@@ -53,7 +53,7 @@
*/
#define forEachXmlChildElement(parentXmlElement, childElementVariableName) \
\
for (juce::XmlElement* childElementVariableName = (parentXmlElement).getFirstChildElement(); \
for (juce2::XmlElement* childElementVariableName = (parentXmlElement).getFirstChildElement(); \
childElementVariableName != nullptr; \
childElementVariableName = childElementVariableName->getNextElement())
@@ -82,7 +82,7 @@
*/
#define forEachXmlChildElementWithTagName(parentXmlElement, childElementVariableName, requiredTagName) \
\
for (juce::XmlElement* childElementVariableName = (parentXmlElement).getChildByName (requiredTagName); \
for (juce2::XmlElement* childElementVariableName = (parentXmlElement).getChildByName (requiredTagName); \
childElementVariableName != nullptr; \
childElementVariableName = childElementVariableName->getNextElementWithTagName (requiredTagName))


+ 1
- 1
source/native-plugins/audio-file.cpp View File

@@ -22,7 +22,7 @@
#include "CarlaMutex.hpp"
#include "CarlaString.hpp"

using namespace juce;
using namespace juce2;

// -----------------------------------------------------------------------



+ 2
- 3
source/native-plugins/bigmeter.cpp View File

@@ -20,10 +20,9 @@
#include "CarlaMathUtils.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;

// -----------------------------------------------------------------------



+ 2
- 0
source/native-plugins/distrho-3bandeq.cpp View File

@@ -23,6 +23,8 @@
# define DISTRHO_PLUGIN_HAS_UI 0
#endif

#include "CarlaJuceUtils.hpp"

// Plugin Code
#include "distrho-3bandeq/DistrhoArtwork3BandEQ.cpp"
#include "distrho-3bandeq/DistrhoPlugin3BandEQ.cpp"


+ 2
- 0
source/native-plugins/distrho-3bandsplitter.cpp View File

@@ -23,6 +23,8 @@
# define DISTRHO_PLUGIN_HAS_UI 0
#endif

#include "CarlaJuceUtils.hpp"

// Plugin Code
#include "distrho-3bandsplitter/DistrhoArtwork3BandSplitter.cpp"
#include "distrho-3bandsplitter/DistrhoPlugin3BandSplitter.cpp"


+ 3
- 1
source/native-plugins/distrho-kars.cpp View File

@@ -1,6 +1,6 @@
/*
* 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
* modify it under the terms of the GNU General Public License as
@@ -23,6 +23,8 @@
# define DISTRHO_PLUGIN_HAS_UI 0
#endif

#include "CarlaJuceUtils.hpp"

// Plugin Code
#include "distrho-kars/DistrhoArtworkKars.cpp"
#include "distrho-kars/DistrhoPluginKars.cpp"


+ 3
- 1
source/native-plugins/distrho-nekobi.cpp View File

@@ -1,6 +1,6 @@
/*
* 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
* modify it under the terms of the GNU General Public License as
@@ -23,6 +23,8 @@
# define DISTRHO_PLUGIN_HAS_UI 0
#endif

#include "CarlaJuceUtils.hpp"

// Plugin Code
#include "distrho-nekobi/DistrhoArtworkNekobi.cpp"
#include "distrho-nekobi/DistrhoPluginNekobi.cpp"


+ 3
- 1
source/native-plugins/distrho-pingpongpan.cpp View File

@@ -1,6 +1,6 @@
/*
* 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
* modify it under the terms of the GNU General Public License as
@@ -23,6 +23,8 @@
# define DISTRHO_PLUGIN_HAS_UI 0
#endif

#include "CarlaJuceUtils.hpp"

// Plugin Code
#include "distrho-pingpongpan/DistrhoArtworkPingPongPan.cpp"
#include "distrho-pingpongpan/DistrhoPluginPingPongPan.cpp"


+ 2
- 1
source/native-plugins/distrho-prom.cpp View File

@@ -1,6 +1,6 @@
/*
* 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
* 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.
*/

#include "CarlaJuceUtils.hpp"

// Plugin Code
#include "distrho-prom/DistrhoPluginProM.cpp"


+ 3
- 1
source/native-plugins/distrho-vectorjuice.cpp View File

@@ -1,6 +1,6 @@
/*
* 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
* modify it under the terms of the GNU General Public License as
@@ -23,6 +23,8 @@
# define DISTRHO_PLUGIN_HAS_UI 0
#endif

#include "CarlaJuceUtils.hpp"

// Plugin Code
#include "distrho-vectorjuice/VectorJuicePlugin.cpp"
#ifdef HAVE_DGL


+ 3
- 1
source/native-plugins/distrho-wobblejuice.cpp View File

@@ -1,6 +1,6 @@
/*
* 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
* modify it under the terms of the GNU General Public License as
@@ -23,6 +23,8 @@
# define DISTRHO_PLUGIN_HAS_UI 0
#endif

#include "CarlaJuceUtils.hpp"

// Plugin Code
#include "distrho-wobblejuice/WobbleJuiceArtwork.cpp"
#include "distrho-wobblejuice/WobbleJuicePlugin.cpp"


+ 2
- 3
source/native-plugins/midi-file.cpp View File

@@ -18,8 +18,7 @@
#include "CarlaNative.hpp"
#include "midi-base.hpp"

#include "AppConfig.h"
#include "juce_core/juce_core.h"
#include "juce_audio_graph/juce_audio_graph.h"

#if 0
// -----------------------------------------------------------------------
@@ -143,7 +142,7 @@ private:
{
fMidiOut.clear();

using namespace juce;
using namespace juce2;

const String jfilename = String(CharPointer_UTF8(filename));
File file(jfilename);


+ 2
- 4
source/native-plugins/zita-at1.cpp View File

@@ -17,15 +17,13 @@

#include "CarlaNativeExtUI.hpp"
#include "CarlaJuceUtils.hpp"
#include "distrho/extra/ScopedPointer.hpp"

#include "zita-at1/jclient.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;



+ 0
- 1
source/native-plugins/zita-bls1.cpp View File

@@ -17,7 +17,6 @@

#include "CarlaNativeExtUI.hpp"
#include "CarlaJuceUtils.hpp"
#include "distrho/extra/ScopedPointer.hpp"

#include "zita-bls1/hp3filt.cc"
#include "zita-bls1/jclient.cc"


+ 0
- 1
source/native-plugins/zita-rev1.cpp View File

@@ -17,7 +17,6 @@

#include "CarlaNativeExtUI.hpp"
#include "CarlaJuceUtils.hpp"
#include "distrho/extra/ScopedPointer.hpp"

#include "zita-rev1/jclient.cc"
#include "zita-rev1/pareq.cc"


+ 2
- 3
source/native-plugins/zynaddsubfx-fx.cpp View File

@@ -45,10 +45,9 @@
# pragma GCC diagnostic pop
#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;



+ 2
- 4
source/native-plugins/zynaddsubfx-synth.cpp View File

@@ -21,7 +21,6 @@
#include "LinkedList.hpp"

#include "CarlaMathUtils.hpp"
#include "distrho/extra/ScopedPointer.hpp"

#include <ctime>
#include <set>
@@ -50,10 +49,9 @@
# pragma GCC diagnostic pop
#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;



+ 1
- 1
source/plugin/Makefile View File

@@ -50,7 +50,7 @@ endif
LIBS = $(MODULEDIR)/carla_engine_plugin.a
LIBS += $(MODULEDIR)/carla_plugin.a
LIBS += $(MODULEDIR)/jackbridge.a
LIBS += $(MODULEDIR)/juce_core.a
LIBS += $(MODULEDIR)/juce_audio_graph.a
LIBS += $(MODULEDIR)/lilv.a
LIBS += $(MODULEDIR)/native-plugins.a
LIBS += $(MODULEDIR)/rtmempool.a


+ 4
- 5
source/plugin/carla-lv2-export.cpp View File

@@ -18,8 +18,7 @@
#define CARLA_NATIVE_PLUGIN_LV2
#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/buf-size.h"
@@ -45,9 +44,9 @@
# define PLUGIN_EXT ".so"
#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


+ 3
- 4
source/plugin/carla-vst.cpp View File

@@ -24,8 +24,7 @@

#include "CarlaMathUtils.hpp"

#include "AppConfig.h"
#include "juce_core/juce_core.h"
#include "juce_audio_graph/juce_audio_graph.h"

#include "vestige/aeffectx.h"
#define effFlagsProgramChunks (1 << 5)
@@ -73,8 +72,8 @@ public:
fHost.uiParentId = 0;

// find resource dir
using juce::File;
using juce::String;
using juce2::File;
using juce2::String;

File curExe = File::getSpecialLocation(File::currentExecutableFile).getLinkedTarget();
File resDir = curExe.getSiblingFile("carla-resources");


+ 4
- 5
source/utils/CarlaBinaryUtils.hpp View File

@@ -22,8 +22,8 @@
#include "CarlaUtils.hpp"

#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)
# include <magic.h>
#endif
@@ -76,9 +76,8 @@ BinaryType getBinaryTypeFromFile(const char* const filename)
return BINARY_NATIVE;

#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());
CARLA_SAFE_ASSERT_RETURN(stream != nullptr || stream->failedToOpen(), BINARY_NATIVE);


+ 2
- 3
source/utils/CarlaDssiUtils.cpp View File

@@ -17,8 +17,7 @@

#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);

try {
using namespace juce;
using namespace juce2;

String guiFilename;
String pluginDir(String(filename).upToLastOccurrenceOf(".", false, false));


+ 185
- 0
source/utils/CarlaJuceUtils.hpp View File

@@ -18,8 +18,15 @@
#ifndef 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 <algorithm>

/** A good old-fashioned C macro concatenation helper.
This combines two items (which may themselves be macros) into a single string,
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


+ 5
- 6
source/utils/CarlaLv2Utils.hpp View File

@@ -82,8 +82,7 @@
#ifdef USE_QT
# include <QtCore/QStringList>
#else
# include "AppConfig.h"
# include "juce_core/juce_core.h"
# include "juce_audio_graph/juce_audio_graph.h"
#endif

// 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;
}
#else
const juce::String replaceURI(replaceNode.as_uri());
const juce2::String replaceURI(replaceNode.as_uri());

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());
#else
juce::StringArray presetListURIs;
juce2::StringArray presetListURIs;

LILV_FOREACH(nodes, it, presetNodes)
{
Lilv::Node presetNode(presetNodes.get(it));

juce::String presetURI(presetNode.as_uri());
juce2::String presetURI(presetNode.as_uri());

if (presetURI.trim().isNotEmpty())
presetListURIs.addIfNotAlreadyThere(presetURI);
@@ -1246,7 +1245,7 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool loadPresets)
#ifdef USE_QT
const int index(presetListURIs.indexOf(QString(presetURI)));
#else
const int index(presetListURIs.indexOf(juce::String(presetURI)));
const int index(presetListURIs.indexOf(juce2::String(presetURI)));
#endif
CARLA_SAFE_ASSERT_CONTINUE(index >= 0 && index < static_cast<int>(rdfDescriptor->PresetCount));



+ 10
- 9
source/utils/CarlaPipeUtils.cpp View File

@@ -36,8 +36,7 @@
#include <fcntl.h>

#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
# include <cerrno>
# include <signal.h>
@@ -99,7 +98,7 @@ static inline
uint32_t getMillisecondCounter() noexcept
{
#if defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN)
return juce::Time::getMillisecondCounter();
return juce2::Time::getMillisecondCounter();
#else
uint32_t now;
timespec t;
@@ -132,7 +131,7 @@ bool startProcess(const char* const argv[], PROCESS_INFORMATION* const processIn
{
CARLA_SAFE_ASSERT_RETURN(processInfo != nullptr, false);

using juce::String;
using juce2::String;

String command;

@@ -140,23 +139,25 @@ bool startProcess(const char* const argv[], PROCESS_INFORMATION* const processIn
{
String arg(argv[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

command << arg << ' ';
}

command = command.trim();

STARTUPINFOW startupInfo;
STARTUPINFO 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


+ 5
- 5
source/utils/CarlaStateUtils.cpp View File

@@ -23,9 +23,9 @@

#include <string>

using juce::MemoryOutputStream;
using juce::String;
using juce::XmlElement;
using juce2::MemoryOutputStream;
using juce2::String;
using juce2::XmlElement;

CARLA_BACKEND_START_NAMESPACE

@@ -509,7 +509,7 @@ void CarlaStateSave::dumpToMemoryStream(MemoryOutputStream& content) const
case PLUGIN_LADSPA:
infoXml << " <Binary>" << xmlSafeString(binary, true) << "</Binary>\n";
infoXml << " <Label>" << xmlSafeString(label, true) << "</Label>\n";
infoXml << " <UniqueID>" << juce::int64(uniqueId) << "</UniqueID>\n";
infoXml << " <UniqueID>" << juce2::int64(uniqueId) << "</UniqueID>\n";
break;
case PLUGIN_DSSI:
infoXml << " <Binary>" << xmlSafeString(binary, true) << "</Binary>\n";
@@ -520,7 +520,7 @@ void CarlaStateSave::dumpToMemoryStream(MemoryOutputStream& content) const
break;
case PLUGIN_VST2:
infoXml << " <Binary>" << xmlSafeString(binary, true) << "</Binary>\n";
infoXml << " <UniqueID>" << juce::int64(uniqueId) << "</UniqueID>\n";
infoXml << " <UniqueID>" << juce2::int64(uniqueId) << "</UniqueID>\n";
break;
case PLUGIN_GIG:
case PLUGIN_SF2:


+ 7
- 8
source/utils/CarlaStateUtils.hpp View File

@@ -21,8 +21,7 @@
#include "CarlaBackend.h"
#include "LinkedList.hpp"

#include "AppConfig.h"
#include "juce_core/juce_core.h"
#include "juce_audio_graph/juce_audio_graph.h"

CARLA_BACKEND_START_NAMESPACE

@@ -94,16 +93,16 @@ struct CarlaStateSave {
~CarlaStateSave() 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)
};

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)
return newString.replace("&","&amp;").replace("<","&lt;").replace(">","&gt;").replace("'","&apos;").replace("\"","&quot;");
@@ -112,9 +111,9 @@ juce::String xmlSafeString(const char* const cstring, const bool toXml)
}

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)
return newString.replace("&","&amp;").replace("<","&lt;").replace(">","&gt;").replace("'","&apos;").replace("\"","&quot;");


+ 1
- 1
source/utils/CarlaString.hpp View File

@@ -18,8 +18,8 @@
#ifndef CARLA_STRING_HPP_INCLUDED
#define CARLA_STRING_HPP_INCLUDED

#include "CarlaJuceUtils.hpp"
#include "CarlaMathUtils.hpp"
#include "CarlaJuceUtils.hpp"

#include <algorithm>



Loading…
Cancel
Save