From 7ac0a398134668f7802c56726d735eaca99739c2 Mon Sep 17 00:00:00 2001 From: Jeff Smith Date: Thu, 29 Nov 2018 01:57:10 -0600 Subject: [PATCH 01/13] Symbol spawn_miniedit_text needs to be defined --- src/common/gui/PopupEditorDialog.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/common/gui/PopupEditorDialog.cpp b/src/common/gui/PopupEditorDialog.cpp index cee6589914a..1904cd316b5 100644 --- a/src/common/gui/PopupEditorDialog.cpp +++ b/src/common/gui/PopupEditorDialog.cpp @@ -139,4 +139,14 @@ void spawn_miniedit_text(char* c, int maxchars) strncpy(c, me.textdata, maxchars); } } -#endif \ No newline at end of file +#elif __linux__ + +#include + +void spawn_miniedit_text(char* c, int maxchars) +{ + // FIXME: Implement text edit popup on Linux. + fprintf(stderr, "%s: text edit popup is not implemented.\n", __func__); +} + +#endif From 40b4fc5632382693ee3c7772699f9698a96235e1 Mon Sep 17 00:00:00 2001 From: Jeff Smith Date: Thu, 29 Nov 2018 01:58:11 -0600 Subject: [PATCH 02/13] Linux VST2 plugin needs soHandle defined This was previously fixed in 776c2e205d419b6f7ed28c616ba6c222ac3bb5ab, but was reverted in 04b1f1a7e6ff4ffb49ddb2434438fcfe4215fdb3. --- src/vst2/Vst2PluginInstance.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vst2/Vst2PluginInstance.cpp b/src/vst2/Vst2PluginInstance.cpp index 78ef450ce76..de3b3946e73 100644 --- a/src/vst2/Vst2PluginInstance.cpp +++ b/src/vst2/Vst2PluginInstance.cpp @@ -25,6 +25,10 @@ using namespace std; +#if __linux__ +namespace VSTGUI { void* soHandle = nullptr; } +#endif + //------------------------------------------------------------------------------------------------------- AudioEffect* createEffectInstance(audioMasterCallback audioMaster) From f2eb931de06b63e2925230a2153149b488a4f844 Mon Sep 17 00:00:00 2001 From: Jarkko Sakkinen Date: Wed, 28 Nov 2018 09:02:05 -0800 Subject: [PATCH 03/13] Flag SurgeStorage::load_vt_wav() only for Windows Right now SurgeStorage::load_vt_wav() is flagged ambiguously. This commit flags it consistently only for Windows. Without this change Renoise's plugin loader will complain about undefined symbol (i.e. load_vt_wav()). Print an error message to make this visible and add a FIXME comment. WAV file loading will be easy to implement for macOS and Linux once the plugin is otherwise running on those platforms because it only depends on Windows buffered IO functions. Signed-off-by: Jarkko Sakkinen --- src/common/SurgeStorage.cpp | 2 -- src/common/SurgeStorageLoadWavetable.cpp | 13 ++++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/common/SurgeStorage.cpp b/src/common/SurgeStorage.cpp index c8700f3fa2a..d4037ad688f 100644 --- a/src/common/SurgeStorage.cpp +++ b/src/common/SurgeStorage.cpp @@ -342,10 +342,8 @@ void SurgeStorage::load_wt(string filename, Wavetable* wt) extension[i] = tolower(extension[i]); if (extension.compare(".wt") == 0) load_wt_wt(filename, wt); -#if !MAC else if (extension.compare(".wav") == 0) load_wt_wav(filename, wt); -#endif } void SurgeStorage::load_wt_wt(string filename, Wavetable* wt) diff --git a/src/common/SurgeStorageLoadWavetable.cpp b/src/common/SurgeStorageLoadWavetable.cpp index 860c11a7d17..ec734a1fad5 100644 --- a/src/common/SurgeStorageLoadWavetable.cpp +++ b/src/common/SurgeStorageLoadWavetable.cpp @@ -3,11 +3,12 @@ //------------------------------------------------------------------------------------------------------- #include "SurgeStorage.h" #include "DspUtilities.h" -#if WINDOWS +#if WINDOWS #include #include #include +#endif void error_msg(char* c) {} // add messagebox? @@ -17,7 +18,7 @@ void error_msg(char* c) void SurgeStorage::load_wt_wav(string filename, Wavetable* wt) { - +#if WINDOWS uint32 wave_channels = 0; uint32 wave_samplerate = 0; uint32 wave_blockalignment = 0; @@ -291,7 +292,9 @@ void SurgeStorage::load_wt_wav(string filename, Wavetable* wt) /* Close the file */ mmioClose(hmmio, 0); - - return; +#else + // FIXME: Implement WAV file loading for macOS and Linux. + fprintf(stderr, "%s: WAV file loading is not implemented.\n", + __func__); +#endif } -#endif \ No newline at end of file From 31fd5a77660c8160b6140a0ed8e2188c77c3084b Mon Sep 17 00:00:00 2001 From: Jarkko Sakkinen Date: Tue, 4 Dec 2018 21:25:43 -0800 Subject: [PATCH 04/13] Fix CPU architecture code Implement the CPU architecture code for macOS and Linux. Instead of causing a name collision with SSE_VERSION, use the created bitmask to both detect CMOV instruction and SSE2 instruction set and use in various conditional statements. Clean up naming to align with https://webkit.org/code-style-guidelines/ as we do not have any naming conventions place in this project. Signed-off-by: Jarkko Sakkinen --- src/common/AbstractSynthesizer.cpp | 46 +++++++++++++---------------- src/common/CpuArchitecture.cpp | 37 ++++++++--------------- src/common/CpuArchitecture.h | 17 ++++++----- src/common/dsp/QuadFilterUnit.cpp | 11 +++---- src/common/dsp/WindowOscillator.cpp | 5 ++-- src/common/globals.h | 3 -- 6 files changed, 52 insertions(+), 67 deletions(-) diff --git a/src/common/AbstractSynthesizer.cpp b/src/common/AbstractSynthesizer.cpp index 95f147b6bc5..ba9def51847 100644 --- a/src/common/AbstractSynthesizer.cpp +++ b/src/common/AbstractSynthesizer.cpp @@ -2,41 +2,37 @@ // Copyright 2005 Claes Johanson & vember|audio //------------------------------------------------------------------------------------------------------- #include "AbstractSynthesizer.h" +#if WINDOWS +#include +#endif -#define SSE_STATE_FLAG 0x8040 - -#if !MAC && !__linux__ #include -int SSE_VERSION; - -#include -#endif +const char *SSE2ErrorText = + "This plugin requires a CPU supporting the SSE2 instruction set."; +const char *CMOVErrorText = + "This plugin requires a CPU supporting the CMOV instruction."; void initDllGlobals() { -#if !MAC && !__linux__ // intel macs always support SSE2 - unsigned int arch = determine_support(); - // detect - if (arch & ca_SSE3) - { - SSE_VERSION = 3; - } - else if (arch & ca_SSE2) - { - SSE_VERSION = 2; - } - else + initCpuArchitecture(); + + if (!(CpuArchitecture & CaSSE2)) { - SSE_VERSION = 0; - MessageBox(::GetActiveWindow(), - "This plugin requires a CPU supporting the SSE2 instruction set.", +#if WINDOWS + MessageBox(::GetActiveWindow(), SSE2ErrorText, "Surge: System requirements not met", MB_OK | MB_ICONERROR); +#else + fprintf(stderr, "%s: %s", __func__, SSE2ErrorText); +#endif } - if (!(arch & ca_CMOV)) + if (!(CpuArchitecture & CaCMOV)) { - MessageBox(::GetActiveWindow(), "This plugin requires a CPU supporting the CMOV instruction.", +#if WINDOWS + MessageBox(::GetActiveWindow(), CMOVErrorText, "Surge: System requirements not met", MB_OK | MB_ICONERROR); - } +#else + fprintf(stderr, "%s: %s", __func__, CMOVErrorText); #endif + } } diff --git a/src/common/CpuArchitecture.cpp b/src/common/CpuArchitecture.cpp index f2fa06e6658..e3ea386bde4 100644 --- a/src/common/CpuArchitecture.cpp +++ b/src/common/CpuArchitecture.cpp @@ -1,13 +1,14 @@ -#if !MAC #include "CpuArchitecture.h" #include +unsigned int CpuArchitecture; + extern "C" void __cpuid(int* CPUInfo, int InfoType); #pragma intrinsic(__cpuid) -unsigned int determine_support() +void initCpuArchitecture() { - unsigned int arch = 0; +#if WINDOWS int CPUInfo[4] = {-1}; __cpuid(CPUInfo, 0); char vendor[12]; @@ -19,26 +20,14 @@ unsigned int determine_support() __cpuid(CPUInfo, 1); if ((1 << 15) & CPUInfo[3]) - arch |= ca_CMOV; - if ((1 << 25) & CPUInfo[3]) - arch |= ca_SSE; + CpuArchitecture |= CaCMOV; if ((1 << 26) & CPUInfo[3]) - arch |= ca_SSE2; - if (CPUInfo[2] & 0x1) - arch |= ca_SSE3; - - // get number of extended pages - __cpuid(CPUInfo, 0x80000000); - unsigned int extendedpages = CPUInfo[0]; - - // determine 3DNow! support - if (!strncmp("AuthenticAMD", vendor, 12) && (extendedpages >= 0x80000001)) - { - __cpuid(CPUInfo, 0x80000001); - if (((1 << 30) & CPUInfo[3]) && ((1 << 31) & CPUInfo[3])) - arch |= ca_3DNOW; - } - - return arch; + CpuArchitecture |= CaSSE2; +#else + __builtin_cpu_init(); + if (__builtin_cpu_supports("sse2")) + CpuArchitecture |= CaSSE2; + if (__builtin_cpu_supports("cmov")) + CpuArchitecture |= CaCMOV; +#endif } -#endif \ No newline at end of file diff --git a/src/common/CpuArchitecture.h b/src/common/CpuArchitecture.h index 21f9d2669ea..d5b137ca29f 100644 --- a/src/common/CpuArchitecture.h +++ b/src/common/CpuArchitecture.h @@ -1,13 +1,14 @@ +#ifndef CPUARCHITECTURE_H +#define CPUARCHITECTURE_H enum CpuArchitecture { - ca_SSE = 0x1, - ca_SSE2 = 0x2, - ca_SSE3 = 0x4, - ca_3DNOW = 0x8, - ca_X64 = 0x10, - ca_PPC = 0x20, - ca_CMOV = 0x40, + CaSSE2 = 0x2, + CaCMOV = 0x40, }; -unsigned int determine_support(); \ No newline at end of file +extern unsigned int CpuArchitecture; + +void initCpuArchitecture(); + +#endif // CPUARCHITECTURE_H diff --git a/src/common/dsp/QuadFilterUnit.cpp b/src/common/dsp/QuadFilterUnit.cpp index 77032351291..a208f575c83 100644 --- a/src/common/dsp/QuadFilterUnit.cpp +++ b/src/common/dsp/QuadFilterUnit.cpp @@ -1,3 +1,4 @@ +#include "CpuArchitecture.h" #include "QuadFilterUnit.h" #include "SurgeStorage.h" #include @@ -1484,7 +1485,7 @@ FilterUnitQFPtr GetQFPtrFilterUnit(int type, int subtype) return COMBquad_PPC; #else #if !_M_X64 - if (SSE_VERSION < 2) + if (!(CpuArchitecture & CaSSE2)) return COMBquad_SSE1; #endif return COMBquad_SSE2; @@ -1514,7 +1515,7 @@ WaveshaperQFPtr GetQFPtrWaveshaper(int type) { case wst_digi: #if !_M_X64 - if (SSE_VERSION < 2) + if (!(CpuArchitecture & CaSSE2)) return DIGI_SSE1; #endif return DIGI_SSE2; @@ -1522,13 +1523,13 @@ WaveshaperQFPtr GetQFPtrWaveshaper(int type) return CLIP; case wst_sinus: #if !_M_X64 - if (SSE_VERSION < 2) + if (!(CpuArchitecture & CaSSE2)) return SINUS_SSE1; #endif return SINUS_SSE2; case wst_asym: #if !_M_X64 - if (SSE_VERSION < 2) + if (!(CpuArchitecture & CaSSE2)) return ASYM_SSE1; #endif return ASYM_SSE2; @@ -1537,4 +1538,4 @@ WaveshaperQFPtr GetQFPtrWaveshaper(int type) } #endif return 0; -} \ No newline at end of file +} diff --git a/src/common/dsp/WindowOscillator.cpp b/src/common/dsp/WindowOscillator.cpp index 95633fd904c..71e88b21698 100644 --- a/src/common/dsp/WindowOscillator.cpp +++ b/src/common/dsp/WindowOscillator.cpp @@ -1,6 +1,7 @@ //------------------------------------------------------------------------------------------------------- // Copyright 2006 Claes Johanson & Vember Audio //------------------------------------------------------------------------------------------------------- +#include "CpuArchitecture.h" #include "Oscillator.h" #if !MAC && !__linux__ #include @@ -212,7 +213,7 @@ void WindowOscillator::ProcessSubOscs(bool stereo) } #else #if (!_M_X64 && !MAC) - if (SSE_VERSION >= 2) + if (CpuArchitecture & CaSSE2) #endif { // SSE2 path @@ -427,7 +428,7 @@ void WindowOscillator::process_block(float pitch, float drift, bool stereo, bool #else __m128 scale = _mm_load1_ps(&OutAttenuation); #if (!_M_X64 && !MAC) - if (SSE_VERSION >= 2) + if (CpuArchitecture & CaSSE2) #endif { // SSE2 path diff --git a/src/common/globals.h b/src/common/globals.h index 8c2e868b282..8eebd59ae83 100644 --- a/src/common/globals.h +++ b/src/common/globals.h @@ -34,6 +34,3 @@ const int ob_length_quad = ob_length >> 2; const float block_size_inv = (1.f / block_size); const float block_size_os_inv = (1.f / block_size_os); const int max_fb_comb = 2048; // m�ste vara 2^n -#if !MAC && !__linux__ -extern int SSE_VERSION; -#endif From c99a65df6cfbaf86a466016405f273c27b4356cb Mon Sep 17 00:00:00 2001 From: Jarkko Sakkinen Date: Sun, 2 Dec 2018 10:47:30 -0800 Subject: [PATCH 05/13] Remove MemoryFile.h Remove the unused MemoryFile.h. It causes bunch of compiler warnings because multi-character character constants do not have any legit standard definition. Signed-off-by: Jarkko Sakkinen --- src/common/MemoryFile.h | 588 -------------------------------------- src/common/SurgePatch.cpp | 1 - 2 files changed, 589 deletions(-) delete mode 100644 src/common/MemoryFile.h diff --git a/src/common/MemoryFile.h b/src/common/MemoryFile.h deleted file mode 100644 index 315b5da52d0..00000000000 --- a/src/common/MemoryFile.h +++ /dev/null @@ -1,588 +0,0 @@ -#pragma once -#include - -struct riffheader -{ - unsigned long id; - unsigned long datasize; -}; - -enum mfseek -{ - mf_FromStart = 0, - mf_FromCurrent, - mf_FromEnd, -}; - -__forceinline unsigned short swap_endianW(unsigned short x) -{ - return ((x & 0xFF) << 8) | ((x & 0xFF00) >> 8); -} - -__forceinline unsigned int swap_endianDW(unsigned int x) -{ - return ((x & 0xFF) << 24) | ((x & 0xFF00) << 8) | ((x & 0xFF0000) >> 8) | - ((x & 0xFF000000) >> 24); -} - -// class intended to parse memory mapped RIFF-files -class MemoryFile -{ -public: - MemoryFile(void* data, int datasize) - { - assert(data); - assert(datasize); - this->data = (char*)data; - this->size = datasize; - loc = 0; - StartStack.push_front(0); - EndStack.push_front(datasize); - } - - virtual char Peek() - { - assert(data); - if ((loc < size) && (loc >= 0)) - return data[loc]; - return 0; - } - - bool Read(void* buffer, size_t s) - { - if ((s + loc) > size) - return false; - memcpy(buffer, data + loc, s); - loc += s; - return true; - } - - bool SkipPSTRING() - { - unsigned char length = (*(unsigned char*)(data + loc)) + 1; - if (length & 1) - length++; // IFF 16-bit alignment - if ((length + loc) > size) - return false; - loc += length; - return true; - } - - unsigned long ReadDWORD() - { - if ((4 + loc) > size) - return 0; - unsigned long val = *(unsigned long*)(data + loc); - loc += 4; - return val; - } - - unsigned long ReadDWORDBE() - { - if ((4 + loc) > size) - return 0; - unsigned long val = *(unsigned long*)(data + loc); - loc += 4; - return vt_read_int32BE(val); - } - - void WriteDWORD(unsigned long dw) - { - if ((4 + loc) > size) - return; - *(unsigned long*)(data + loc) = dw; - loc += 4; - } - - void WriteDWORDBE(unsigned long dw) - { - if ((4 + loc) > size) - return; - *(unsigned long*)(data + loc) = vt_write_int32BE(dw); - loc += 4; - } - - unsigned short ReadWORD() - { - if ((2 + loc) > size) - return 0; - unsigned short val = *(unsigned short*)(data + loc); - loc += 2; - return val; - } - - void* ReadPtr(size_t s) // moves loc like read, but it returns a pointer to the memory instead of - // copying it - { - if ((s + loc) > size) - return 0; - void* ptr = data + loc; - loc += s; - return ptr; - } - - void* GetPtr() - { - void* ptr = data + loc; - return ptr; - } - - size_t TellI() - { - return loc; - } - - size_t SeekI(size_t pos, int mode = mf_FromStart) - { - switch (mode) - { - case mf_FromStart: - loc = pos; - break; - - case mf_FromCurrent: - loc += pos; - break; - - case mf_FromEnd: - loc = size + pos; - break; - } - return loc; - } - - bool riff_descend_RIFF_or_LIST(int tag, size_t* datasize, unsigned int entry = 0) - { - char* cv = (char*)&tag; - int rtag = (cv[0] << 24) + (cv[1] << 16) + (cv[2] << 8) + cv[3]; - assert((loc & 1) == 0); // assure block unsigned short alignment (2-bytes) - riffheader rh; - while (!Eob()) - { - if (!Read(&rh, sizeof(riffheader))) - return false; - if ((rh.id == 'FFIR') || (rh.id == 'TSIL')) - { - int subtag; - if (!Read(&subtag, 4)) - return false; - if (subtag == rtag) - { - if (entry) - { - entry--; - SeekI(-4, mf_FromCurrent); - } - else - { - if (datasize) - *datasize = rh.datasize - 4; // don't include the subid - return true; - } - } - else - { - SeekI(-4, mf_FromCurrent); - } - } - - if (!SeekI(rh.datasize + (rh.datasize & 1), mf_FromCurrent)) - return false; - // +1 if odd to align on unsigned short - } - return false; - } - - bool iff_descend_FORM(int tag, int* datasize) - { - char* cv = (char*)&tag; - int rtag = (cv[0] << 24) + (cv[1] << 16) + (cv[2] << 8) + cv[3]; - - assert((loc & 1) == 0); // assure block unsigned short alignment (2-bytes) - riffheader rh; - while (!Eof()) - { - if (!Read(&rh, sizeof(riffheader))) - return false; - rh.datasize = swap_endianDW(rh.datasize); - if (rh.id == 'MROF') - { - unsigned long subtag; - if (!Read(&subtag, 4)) - return false; - if (subtag == rtag) - { - if (datasize) - *datasize = rh.datasize; // don't include the subid - return true; - } - else - { - SeekI(-4, mf_FromCurrent); - } - } - - if (!SeekI(rh.datasize + (rh.datasize & 1), mf_FromCurrent)) - return false; - // +1 if odd to align on unsigned short - } - return false; - } - - bool riff_descend(int tag, size_t* datasize) - { - char* cv = (char*)&tag; - unsigned int rtag = (cv[0] << 24) + (cv[1] << 16) + (cv[2] << 8) + cv[3]; - assert((loc & 1) == 0); // assure block unsigned short alignment (2-bytes) - riffheader rh; - while (!Eob()) - { - if (!Read(&rh, sizeof(riffheader))) - return false; - if (rh.id == rtag) - { - if (datasize) - *datasize = rh.datasize; - return true; - } - - if (!SeekI(rh.datasize + (rh.datasize & 1), mf_FromCurrent)) - return false; - // +1 if odd to align on unsigned short - } - return false; - } - - bool riff_descend(int* tag, size_t* datasize) - { - assert((loc & 1) == 0); // assure block unsigned short alignment (2-bytes) - riffheader rh; - - if (!Read(&rh, sizeof(riffheader))) - return false; - - if (tag) - *tag = vt_read_int32BE(rh.id); - if (datasize) - *datasize = rh.datasize; - return true; - } - - // NEW Start - - bool RIFFPeekChunk(int* Tag = 0, - size_t* DataSize = 0, - bool* HasSubchunks = 0, - int* LISTTag = 0) // Get the Tag & size without affecting the locator - { - assert((loc & 1) == 0); // assure block unsigned short alignment (2-bytes) - if ((loc + 8) > EndStack.front()) - return false; - int ChunkTag = vt_read_int32BE(*(int*)(data + loc)); - if (Tag) - *Tag = ChunkTag; - size_t dataSize = vt_read_int32LE(*(int*)(data + loc + 4)); - if (DataSize) - *DataSize = dataSize; - bool hasSubchunks = (ChunkTag == 'RIFF') || (ChunkTag == 'LIST'); - if (HasSubchunks) - *HasSubchunks = hasSubchunks; - if (LISTTag) - { - if (hasSubchunks) - *LISTTag = vt_read_int32BE(*(int*)(data + loc + 8)); - else - *LISTTag = 0; - } - - if ((loc + 8 + dataSize) > EndStack.front()) - { - invalid(); - return false; - } - - return true; - } - - void invalid() - { -#if !MAC && !__linux__ - char txt[1024]; - sprintf(txt, "Invalid RIFF-structure.\n\nOffset: 0x%X", loc); - MessageBox(::GetActiveWindow(), txt, "File I/O Error", MB_OK | MB_ICONERROR); -#endif - } - - bool RIFFIsContainer() // Returns true if the following Chunk is RIFF or LIST - { - assert((loc & 1) == 0); // assure block unsigned short alignment (2-bytes) - if ((loc + 8) > EndStack.front()) - return false; - int ChunkTag = vt_read_int32BE(*(int*)(data + loc)); - return (ChunkTag == 'RIFF') || (ChunkTag == 'LIST'); - } - - void* RIFFReadChunk(int* Tag = 0, size_t* DataSize = 0) // Read chunk & forward locator - { - assert((loc & 1) == 0); // assure block unsigned short alignment (2-bytes) - if ((loc + 8) > EndStack.front()) - return 0; - size_t chunksize = vt_read_int32LE(*(int*)(data + loc + 4)); - if (Tag) - *Tag = vt_read_int32BE(*(int*)(data + loc)); - if (DataSize) - *DataSize = size; - void* dataptr = data + loc + 8; - if ((loc + 8 + chunksize) > EndStack.front()) - { - invalid(); - return nullptr; - } - loc += 8 + chunksize; - if (loc & 1) - loc++; // Add 1 if odd - return dataptr; - } - - bool RIFFSkipChunk(int* Tag = 0, size_t* DataSize = 0) - { - assert((loc & 1) == 0); // assure block unsigned short alignment (2-bytes) - if ((loc + 8) > EndStack.front()) - return false; - size_t ChunkSize = vt_read_int32LE(*(int*)(data + loc + 4)); - if (Tag) - *Tag = vt_read_int32BE(*(int*)(data + loc)); - if (DataSize) - *DataSize = ChunkSize; - if ((loc + 8 + ChunkSize) > EndStack.front()) - { - invalid(); - return false; - } - loc += 8 + ChunkSize; - if (loc & 1) - loc++; // Add 1 if odd - return true; - } - - bool RIFFAscend(bool Rewind = false) - { - assert(!(StartStack.empty() || EndStack.empty())); - - if (!Rewind) - loc = EndStack.front(); - - StartStack.pop_front(); - EndStack.pop_front(); - - assert(!(StartStack.empty() || EndStack.empty())); - - if (Rewind) - loc = StartStack.front(); - - return true; - } - - bool RIFFDescend(int* LISTtag = 0, - size_t* datasize = 0) // Descend into the chunk at the current location - { - assert((loc & 1) == 0); // assure block unsigned short alignment (2-bytes) - if ((loc + 12) > EndStack.front()) - return false; - int Tag = vt_read_int32BE(*(int*)(data + loc)); - if ((Tag != 'LIST') && (Tag != 'RIFF')) - return false; - size_t chunksize = vt_read_int32LE(*(int*)(data + loc + 4)); - int LISTTag = vt_read_int32BE(*(int*)(data + loc + 8)); - loc += 12; - - StartStack.push_front(loc); - EndStack.push_front(loc + chunksize - 4); - - if (datasize) - *datasize = chunksize - 4; - if (LISTtag) - *LISTtag = LISTTag; - return true; - } - - bool RIFFDescendSearch( - int tag, - size_t* datasize = 0, - unsigned int entry = 0) // Descend into a chunk by searching for it (sequentially if desired) - { - assert((loc & 1) == 0); // assure block unsigned short alignment (2-bytes) - riffheader rh; - while (!Eob()) - { - if (!Read(&rh, sizeof(riffheader))) - return false; - rh.id = vt_read_int32BE(rh.id); - rh.datasize = vt_read_int32LE(rh.datasize); - if ((rh.id == 'RIFF') || (rh.id == 'LIST')) - { - unsigned int subtag; - if (!Read(&subtag, 4)) - return false; - subtag = vt_read_int32BE(subtag); - if (subtag == tag) - { - if (entry) - { - entry--; - SeekI(-4, mf_FromCurrent); - } - else - { - if (datasize) - *datasize = rh.datasize - 4; // don't include the subid - StartStack.push_front(loc); - EndStack.push_front(loc + rh.datasize - 4); - return true; - } - } - else - { - SeekI(-4, mf_FromCurrent); - } - } - - if (!SeekI(rh.datasize + (rh.datasize & 1), mf_FromCurrent)) - return false; - // +1 if odd to align on unsigned short - } - return false; - } - - unsigned int RIFFGetFileType() // Read the ID of the RIFF chunk - { - return vt_read_int32BE(*(unsigned int*)(data + 8)); - }; - - bool RIFFCreateChunk(unsigned long tag, void* indata, size_t datasize) - { - if ((8 + loc + datasize) > size) - { - invalid(); - return false; - } - *(unsigned long*)(data + loc) = vt_write_int32BE(tag); - loc += 4; - *(unsigned long*)(data + loc) = vt_write_int32LE(datasize); - loc += 4; - - memcpy(data + loc, indata, datasize); - loc += datasize; - - return true; - } - - bool RIFFCreateLISTHeader(unsigned long tag, size_t subsize) - { - if ((12 + loc + subsize) > size) - { - invalid(); - return false; - } - *(unsigned long*)(data + loc) = vt_write_int32BE('LIST'); - *(unsigned long*)(data + loc + 4) = vt_write_int32LE(subsize + 4); - *(unsigned long*)(data + loc + 8) = vt_write_int32BE(tag); - loc += 12; - return true; - } - - static size_t RIFFTextChunkSize(char* txt) - { - if (!txt) - return 0; - if (!txt[0]) - return 0; - size_t datasize = strlen(txt) + 1; - if (datasize & 1) - datasize++; - return datasize + 8; - } - - bool RIFFCreateTextChunk(unsigned long tag, char* txt) - { - // skip chunk if string is null/empty - if (!txt) - return true; - if (!txt[0]) - return true; - - size_t datasize = strlen(txt) + 1; // Make room for the terminating \0 - if (datasize & 1) - datasize++; // Force 2-byte alignment - - if ((8 + loc + datasize) > size) - { - invalid(); - return false; - } - *(unsigned long*)(data + loc) = vt_write_int32BE(tag); - *(unsigned long*)(data + loc + 4) = vt_write_int32LE(datasize); - loc += 8; - - memset(data + loc, 0, datasize); - strncpy(data + loc, txt, datasize); - loc += datasize; - - return true; - } - - // New End - - // File I/O - - bool LoadFile(wchar_t* FileName) - { - assert(0); - return false; - } - bool SaveFile(wchar_t* FileName) - { - assert(0); - return false; - } - - bool iff_descend(int tag, int* datasize) - { - char* cv = (char*)&tag; - int rtag = (cv[0] << 24) + (cv[1] << 16) + (cv[2] << 8) + cv[3]; - assert((loc & 1) == 0); // assure block unsigned short alignment (2-bytes) - riffheader rh; - while (!Eof()) - { - if (!Read(&rh, sizeof(riffheader))) - return false; - rh.datasize = swap_endianDW(rh.datasize); - if (rh.id == rtag) - { - if (datasize) - *datasize = rh.datasize; - return true; - } - - if (!SeekI(rh.datasize + (rh.datasize & 1), mf_FromCurrent)) - return false; - // +1 if odd to align on unsigned short - } - return false; - } - - bool Eof() - { - return (loc > size); - } - bool Eob() - { - return (loc > size) || (loc > EndStack.front()); - } - -private: - size_t loc, size; - std::list StartStack; - std::list EndStack; - char* data; -}; diff --git a/src/common/SurgePatch.cpp b/src/common/SurgePatch.cpp index 81ff0891ef6..3aa2ca5624b 100644 --- a/src/common/SurgePatch.cpp +++ b/src/common/SurgePatch.cpp @@ -6,7 +6,6 @@ #include "CSurgeSlider.h" #include "effect/Effect.h" #include -#include "MemoryFile.h" #include const int hmargin = 6; From 0f9af7cd84194564f9fb36bc0ea2a9962df06662 Mon Sep 17 00:00:00 2001 From: Jarkko Sakkinen Date: Tue, 4 Dec 2018 18:32:02 -0800 Subject: [PATCH 06/13] Fix compiler warnings for fread() calls in SurgeStorage.cpp Print an error message when fread() does read the required amount of data. Add FIXME's for implementing error handling as there is not yet project wide conventions how it should be done. Signed-off-by: Jarkko Sakkinen --- src/common/SurgeStorage.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/common/SurgeStorage.cpp b/src/common/SurgeStorage.cpp index d4037ad688f..d6b48083542 100644 --- a/src/common/SurgeStorage.cpp +++ b/src/common/SurgeStorage.cpp @@ -354,7 +354,12 @@ void SurgeStorage::load_wt_wt(string filename, Wavetable* wt) wt_header wh; memset(&wh, 0, sizeof(wt_header)); - fread(&wh, sizeof(wt_header), 1, f); + // FIXME: Implement error handling when there is a convention to implement + // the error handling (e.g. return code or exception). + if (fread(&wh, sizeof(wt_header), 1, f) != 1) + fprintf(stderr, "%s: reading the wavetable header failed.\n", + __func__); + if (wh.tag != vt_read_int32BE('vawt')) { fclose(f); @@ -369,7 +374,10 @@ void SurgeStorage::load_wt_wt(string filename, Wavetable* wt) ds = sizeof(float) * vt_read_int16LE(wh.n_tables) * vt_read_int32LE(wh.n_samples); data = malloc(ds); - fread(data, 1, ds, f); + // FIXME: Implement error handling when there is a convention to implement + // the error handling (e.g. return code or exception). + if (fread(data, 1, ds, f) != ds) + fprintf(stderr, "%s: reading the wavetable data failed.\n", __func__); CS_WaveTableData.enter(); wt->BuildWT(data, wh, false); CS_WaveTableData.leave(); From 4bd926d084567165735d3b1a677bbd4288698203 Mon Sep 17 00:00:00 2001 From: Jarkko Sakkinen Date: Tue, 4 Dec 2018 22:00:55 -0800 Subject: [PATCH 07/13] Fix compiler warnings in SurgePatch.cpp C++-standard does not define any legit semantics for multicharacter constants. Define tag as what it really is, a 4-character byte array, and use memcmp() to compare its value. Signed-off-by: Jarkko Sakkinen --- src/common/SurgePatch.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/common/SurgePatch.cpp b/src/common/SurgePatch.cpp index 3aa2ca5624b..8a2aa009c5a 100644 --- a/src/common/SurgePatch.cpp +++ b/src/common/SurgePatch.cpp @@ -725,7 +725,7 @@ void SurgePatch::do_morph() #pragma pack(push, 1) struct patch_header { - unsigned int tag; + char tag[4]; unsigned int xmlsize, wtsize[2][3]; }; #pragma pack(pop) @@ -740,7 +740,7 @@ void SurgePatch::load_patch(const void* data, int datasize, bool preset) patch_header* ph = (patch_header*)data; ph->xmlsize = vt_read_int32LE(ph->xmlsize); - if ((int)ph->tag == vt_read_int32BE('sub3')) + if (!memcmp(ph->tag, "sub3", 4)) { char* dr = (char*)data + sizeof(patch_header); load_xml(dr, ph->xmlsize, preset); @@ -784,7 +784,8 @@ unsigned int SurgePatch::save_patch(void** data) // void **xmldata = new void*(); void* xmldata = 0; patch_header header; - header.tag = vt_write_int32BE('sub3'); + + memcpy(header.tag, "sub3", 4); size_t xmlsize = save_xml(&xmldata); header.xmlsize = vt_write_int32LE(xmlsize); wt_header wth[2][n_oscs]; From f324357418fcbce26ee834fcf827bfa2c9522835 Mon Sep 17 00:00:00 2001 From: Jarkko Sakkinen Date: Wed, 5 Dec 2018 16:32:04 -0800 Subject: [PATCH 08/13] Fix compiler warnings in Parameter.cpp Set first byte of a string to zero instead of using the pattern sprintf(prefix, "") as this will cause compiler warning on gcc and clang and is also inefficient. Fix a possible buffer overflow by increasing the prefix buffer size in get_prefix() from 16 to 19 bytes so that it can fit the full integer value in all cases. Signed-off-by: Jarkko Sakkinen --- src/common/Parameter.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/common/Parameter.cpp b/src/common/Parameter.cpp index 3a8a8755da8..296b1007b50 100644 --- a/src/common/Parameter.cpp +++ b/src/common/Parameter.cpp @@ -15,7 +15,7 @@ Parameter::Parameter() void get_prefix(char* txt, ControlGroup ctrlgroup, int ctrlgroup_entry, int scene) { - char prefix[16]; + char prefix[19]; switch (ctrlgroup) { case cg_OSC: @@ -34,7 +34,7 @@ void get_prefix(char* txt, ControlGroup ctrlgroup, int ctrlgroup_entry, int scen sprintf(prefix, "fx%i_", ctrlgroup_entry + 1); break; default: - sprintf(prefix, ""); + prefix[0] = '\0'; break; }; if (scene == 2) @@ -76,7 +76,7 @@ void create_fullname(char* dn, char* fn, ControlGroup ctrlgroup, int ctrlgroup_e sprintf(prefix, "FX%i", ctrlgroup_entry + 1); break; default: - sprintf(prefix, ""); + prefix[0] = '\0'; useprefix = false; break; }; From a33b76b890a4ad25003c7b65b525b72910420e1d Mon Sep 17 00:00:00 2001 From: Jarkko Sakkinen Date: Wed, 5 Dec 2018 16:41:28 -0800 Subject: [PATCH 09/13] Return value in CPatchBrowser::onMouseDown() Return statement was missing from CPatchBrowser::onMouseDown(). Return kMouseEventHandled in the default case. Signed-off-by: Jarkko Sakkinen --- src/common/gui/CPatchBrowser.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/common/gui/CPatchBrowser.cpp b/src/common/gui/CPatchBrowser.cpp index edab1a74c03..97c96cb297c 100644 --- a/src/common/gui/CPatchBrowser.cpp +++ b/src/common/gui/CPatchBrowser.cpp @@ -128,6 +128,8 @@ CMouseEventResult CPatchBrowser::onMouseDown(CPoint& where, const CButtonState& contextMenu->setDirty(); contextMenu->popup(); getFrame()->removeView(contextMenu, true); // remove from frame and forget + + return kMouseEventHandled; } void CPatchBrowser::loadPatch(int id) From 96a7869986b1b268090f165476829f975f94df5d Mon Sep 17 00:00:00 2001 From: Jarkko Sakkinen Date: Thu, 6 Dec 2018 09:15:46 -0800 Subject: [PATCH 10/13] Adjust buffer sizes in SurgeGUIEditor.cpp Adjust the buffer sizes so that compiler can check that they don't overflow. Signed-off-by: Jarkko Sakkinen --- src/common/gui/SurgeGUIEditor.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/common/gui/SurgeGUIEditor.cpp b/src/common/gui/SurgeGUIEditor.cpp index 3566bda70ca..7f53d7ff01d 100644 --- a/src/common/gui/SurgeGUIEditor.cpp +++ b/src/common/gui/SurgeGUIEditor.cpp @@ -1422,7 +1422,7 @@ int32_t SurgeGUIEditor::controlModifierClicked(CControl* control, CButtonState b if (synth->storage.controllers[ccid] >= 0) { id_clearctrl = eid; - char txt4[256]; + char txt4[128]; decode_controllerid(txt4, synth->storage.controllers[ccid]); sprintf(txt, "Clear controller [currently %s]", txt4); contextMenu->addEntry(txt, eid++); @@ -1551,7 +1551,7 @@ int32_t SurgeGUIEditor::controlModifierClicked(CControl* control, CButtonState b id_clearctrl = -1, id_absolute = -1; contextMenu->addEntry((char*)p->get_name(), eid++); contextMenu->addEntry("-", eid++); - char txt[256], txt2[256]; + char txt[256], txt2[512]; p->get_display(txt); sprintf(txt2, "Value: %s", txt); contextMenu->addEntry(txt2, eid++); @@ -1590,7 +1590,7 @@ int32_t SurgeGUIEditor::controlModifierClicked(CControl* control, CButtonState b if (p->midictrl >= 0) { id_clearctrl = eid; - char txt4[256]; + char txt4[128]; decode_controllerid(txt4, p->midictrl); sprintf(txt, "Clear controller [currently %s]", txt4); contextMenu->addEntry(txt, eid++); @@ -1961,7 +1961,7 @@ void SurgeGUIEditor::valueChanged(CControl* control) { Parameter* p = synth->storage.getPatch().param_ptr[ptag]; - char pname[256], pdisp[256], txt[256]; + char pname[256], pdisp[128], txt[128]; bool modulate = false; if (modsource && mod_editor && synth->isValidModulation(p->id, modsource) && From 31ca779788a956b78cc7fdf19356a5f2e503e94b Mon Sep 17 00:00:00 2001 From: Jarkko Sakkinen Date: Thu, 6 Dec 2018 09:40:48 -0800 Subject: [PATCH 11/13] Change tag type from unsigned int to char [] in struct wt_header C++-standard does not define any legit semantics for multicharacter constants. Define tag as what it really is, a 4-character byte array, and use memcmp() to compare its value. Signed-off-by: Jarkko Sakkinen --- src/common/SurgePatch.cpp | 2 +- src/common/SurgeStorage.cpp | 2 +- src/common/dsp/Wavetable.h | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/common/SurgePatch.cpp b/src/common/SurgePatch.cpp index 8a2aa009c5a..a707336cf65 100644 --- a/src/common/SurgePatch.cpp +++ b/src/common/SurgePatch.cpp @@ -795,7 +795,7 @@ unsigned int SurgePatch::save_patch(void** data) { if (uses_wavetabledata(scene[sc].osc[osc].type.val.i)) { - wth[sc][osc].tag = 0; + memset(wth[sc][osc].tag, 0, 4); wth[sc][osc].n_samples = scene[sc].osc[osc].wt.size; wth[sc][osc].n_tables = scene[sc].osc[osc].wt.n_tables; wth[sc][osc].flags = scene[sc].osc[osc].wt.flags | wtf_int16; diff --git a/src/common/SurgeStorage.cpp b/src/common/SurgeStorage.cpp index d6b48083542..3b7c4e9dd00 100644 --- a/src/common/SurgeStorage.cpp +++ b/src/common/SurgeStorage.cpp @@ -360,7 +360,7 @@ void SurgeStorage::load_wt_wt(string filename, Wavetable* wt) fprintf(stderr, "%s: reading the wavetable header failed.\n", __func__); - if (wh.tag != vt_read_int32BE('vawt')) + if (memcmp(wh.tag, "vawt", 4)) { fclose(f); return; diff --git a/src/common/dsp/Wavetable.h b/src/common/dsp/Wavetable.h index 69c06633040..f6f4c4d8174 100644 --- a/src/common/dsp/Wavetable.h +++ b/src/common/dsp/Wavetable.h @@ -8,9 +8,10 @@ const int max_wtable_samples = 268000; // delay pops 4 uses the most #pragma pack(push, 1) struct wt_header { - unsigned int tag; + char tag[4]; unsigned int n_samples; - unsigned short n_tables, flags; + unsigned short n_tables; + unsigned short flags; }; #pragma pack(pop) From 0cf4d301eac009d4a6cb8281694fde6f25b29bc0 Mon Sep 17 00:00:00 2001 From: Jarkko Sakkinen Date: Thu, 6 Dec 2018 15:11:01 -0800 Subject: [PATCH 12/13] Added IRC channel to README.md Set up an IRC channel to irc.freenode.net called #surgesynth. Signed-off-by: Jarkko Sakkinen --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 897d8f89ede..d8803e34dc7 100644 --- a/README.md +++ b/README.md @@ -137,3 +137,7 @@ An example of setting the environment variable `VST2SDK_DIR` would be: ```export VST2SDK_DIR=~/programming/VST_SDK_2.4``` ***NOTE***: This environment variable needs to be set _before_ running `premake5 xcode4` - which generates projects / and is part of the `build-osx.sh` script. + +## References + +* IRC channel #surgesynth @ irc.freenode.net From d85b7aa84e3e636714a877a17d811d133576ad33 Mon Sep 17 00:00:00 2001 From: Claes Johanson Date: Thu, 13 Dec 2018 10:32:01 +0100 Subject: [PATCH 13/13] CpuArchitecture was never initialized and void initCpuArchitecture was returning int. --- src/common/CpuArchitecture.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/CpuArchitecture.cpp b/src/common/CpuArchitecture.cpp index e3ea386bde4..f24a7535ff7 100644 --- a/src/common/CpuArchitecture.cpp +++ b/src/common/CpuArchitecture.cpp @@ -1,7 +1,7 @@ #include "CpuArchitecture.h" #include -unsigned int CpuArchitecture; +unsigned int CpuArchitecture = 0; extern "C" void __cpuid(int* CPUInfo, int InfoType); #pragma intrinsic(__cpuid) @@ -16,7 +16,7 @@ void initCpuArchitecture() memcpy(&vendor[8], &CPUInfo[2], 4 * sizeof(char)); memcpy(&vendor[4], &CPUInfo[3], 4 * sizeof(char)); if (!CPUInfo[0]) - return 0; // no additional instructions supported + return; // no additional instructions supported __cpuid(CPUInfo, 1); if ((1 << 15) & CPUInfo[3])