diff --git a/Builds/MacOSX/Dexed.xcodeproj/project.xcworkspace/xcuserdata/asb2m10.xcuserdatad/UserInterfaceState.xcuserstate b/Builds/MacOSX/Dexed.xcodeproj/project.xcworkspace/xcuserdata/asb2m10.xcuserdatad/UserInterfaceState.xcuserstate index 77d4c30..074c45a 100644 Binary files a/Builds/MacOSX/Dexed.xcodeproj/project.xcworkspace/xcuserdata/asb2m10.xcuserdatad/UserInterfaceState.xcuserstate and b/Builds/MacOSX/Dexed.xcodeproj/project.xcworkspace/xcuserdata/asb2m10.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm b/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm index 798a662..a38a2a0 100644 --- a/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm +++ b/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm @@ -342,7 +342,6 @@ public: void initialise (double rate, int blockSize) { - refreshParameterList(); updateNumChannels(); producesMidiMessages = canProduceMidiOutput(); setPluginCallbacks(); @@ -350,6 +349,8 @@ public: numOutputBusChannels * numOutputBusses, rate, blockSize); setLatencySamples (0); + initialiseAudioUnit(); + refreshParameterList(); } //============================================================================== diff --git a/JuceLibraryCode/modules/juce_core/javascript/juce_Javascript.cpp b/JuceLibraryCode/modules/juce_core/javascript/juce_Javascript.cpp index f86ce30..e78bb37 100644 --- a/JuceLibraryCode/modules/juce_core/javascript/juce_Javascript.cpp +++ b/JuceLibraryCode/modules/juce_core/javascript/juce_Javascript.cpp @@ -1659,7 +1659,7 @@ JavascriptEngine::JavascriptEngine() : maximumExecutionTime (15.0), root (new R JavascriptEngine::~JavascriptEngine() {} -void JavascriptEngine::prepareTimeout() const { root->timeout = Time::getCurrentTime() + maximumExecutionTime; } +void JavascriptEngine::prepareTimeout() const noexcept { root->timeout = Time::getCurrentTime() + maximumExecutionTime; } void JavascriptEngine::registerNativeObject (Identifier name, DynamicObject* object) { @@ -1715,6 +1715,11 @@ var JavascriptEngine::callFunction (Identifier function, const var::NativeFuncti return returnVal; } +const NamedValueSet& JavascriptEngine::getRootObjectProperties() const noexcept +{ + return root->getProperties(); +} + #if JUCE_MSVC #pragma warning (pop) #endif diff --git a/JuceLibraryCode/modules/juce_core/javascript/juce_Javascript.h b/JuceLibraryCode/modules/juce_core/javascript/juce_Javascript.h index 42368a4..eafc3cd 100644 --- a/JuceLibraryCode/modules/juce_core/javascript/juce_Javascript.h +++ b/JuceLibraryCode/modules/juce_core/javascript/juce_Javascript.h @@ -96,10 +96,13 @@ public: */ RelativeTime maximumExecutionTime; + /** Provides access to the set of properties of the root namespace object. */ + const NamedValueSet& getRootObjectProperties() const noexcept; + private: JUCE_PUBLIC_IN_DLL_BUILD (struct RootObject) - ReferenceCountedObjectPtr root; - void prepareTimeout() const; + const ReferenceCountedObjectPtr root; + void prepareTimeout() const noexcept; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JavascriptEngine) }; diff --git a/JuceLibraryCode/modules/juce_core/native/juce_win32_Network.cpp b/JuceLibraryCode/modules/juce_core/native/juce_win32_Network.cpp index 1b35453..f0b6061 100644 --- a/JuceLibraryCode/modules/juce_core/native/juce_win32_Network.cpp +++ b/JuceLibraryCode/modules/juce_core/native/juce_win32_Network.cpp @@ -45,13 +45,14 @@ public: address (address_), headers (headers_), postData (postData_), position (0), finished (false), isPost (isPost_), timeOutMs (timeOutMs_) { - createConnection (progressCallback, progressCallbackContext); - - if (! isError()) + for (int maxRedirects = 10; --maxRedirects >= 0;) { - if (responseHeaders != nullptr) + createConnection (progressCallback, progressCallbackContext); + + if (! isError()) { DWORD bufferSizeBytes = 4096; + StringPairArray headers (false); for (;;) { @@ -65,11 +66,10 @@ public: for (int i = 0; i < headersArray.size(); ++i) { const String& header = headersArray[i]; - const String key (header.upToFirstOccurrenceOf (": ", false, false)); + const String key (header.upToFirstOccurrenceOf (": ", false, false)); const String value (header.fromFirstOccurrenceOf (": ", false, false)); - const String previousValue ((*responseHeaders) [key]); - - responseHeaders->set (key, previousValue.isEmpty() ? value : (previousValue + "," + value)); + const String previousValue (headers[key]); + headers.set (key, previousValue.isEmpty() ? value : (previousValue + "," + value)); } break; @@ -77,14 +77,34 @@ public: if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) break; + + bufferSizeBytes += 4096; } - } - DWORD status = 0; - DWORD statusSize = sizeof (status); + DWORD status = 0; + DWORD statusSize = sizeof (status); + + if (HttpQueryInfo (request, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &status, &statusSize, 0)) + { + statusCode = (int) status; + + if (status == 301 || status == 302 || status == 303 || status == 307) + { + const String newLocation (headers["Location"]); + + if (newLocation.isNotEmpty() && newLocation != address) + { + address = newLocation; + continue; + } + } + } + + if (responseHeaders != nullptr) + responseHeaders->addArray (headers); + } - if (HttpQueryInfo (request, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &status, &statusSize, 0)) - statusCode = (int) status; + break; } } diff --git a/JuceLibraryCode/modules/juce_core/system/juce_PlatformDefs.h b/JuceLibraryCode/modules/juce_core/system/juce_PlatformDefs.h index 4086dfa..aadf388 100644 --- a/JuceLibraryCode/modules/juce_core/system/juce_PlatformDefs.h +++ b/JuceLibraryCode/modules/juce_core/system/juce_PlatformDefs.h @@ -337,6 +337,10 @@ namespace juce #if (__GNUC__ * 100 + __GNUC_MINOR__) >= 407 && ! defined (JUCE_DELETED_FUNCTION) #define JUCE_DELETED_FUNCTION = delete #endif + + #if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 && ! defined (JUCE_COMPILER_SUPPORTS_LAMBDAS) + #define JUCE_COMPILER_SUPPORTS_LAMBDAS 1 + #endif #endif #if JUCE_CLANG && defined (__has_feature) @@ -356,6 +360,10 @@ namespace juce #define JUCE_DELETED_FUNCTION = delete #endif + #if __has_feature (cxx_lambdas) && ((! JUCE_MAC) || (defined (MAC_OS_X_VERSION_10_8) && MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_8)) + #define JUCE_COMPILER_SUPPORTS_LAMBDAS 1 + #endif + #ifndef JUCE_COMPILER_SUPPORTS_OVERRIDE_AND_FINAL #define JUCE_COMPILER_SUPPORTS_OVERRIDE_AND_FINAL 1 #endif @@ -372,6 +380,7 @@ namespace juce #if defined (_MSC_VER) && _MSC_VER >= 1700 #define JUCE_COMPILER_SUPPORTS_OVERRIDE_AND_FINAL 1 + #define JUCE_COMPILER_SUPPORTS_LAMBDAS 1 #endif #ifndef JUCE_DELETED_FUNCTION diff --git a/JuceLibraryCode/modules/juce_events/messages/juce_MessageManager.cpp b/JuceLibraryCode/modules/juce_events/messages/juce_MessageManager.cpp index cfaf8cf..44c2adc 100644 --- a/JuceLibraryCode/modules/juce_events/messages/juce_MessageManager.cpp +++ b/JuceLibraryCode/modules/juce_events/messages/juce_MessageManager.cpp @@ -131,6 +131,7 @@ void MessageManager::stopDispatchLoop() #endif //============================================================================== +#if JUCE_COMPILER_SUPPORTS_LAMBDAS struct AsyncFunction : private MessageManager::MessageBase { AsyncFunction (std::function f) : fn (f) { post(); } @@ -146,7 +147,9 @@ void MessageManager::callAsync (std::function f) { new AsyncFunction (f); } +#endif +//============================================================================== class AsyncFunctionCallback : public MessageManager::MessageBase { public: diff --git a/JuceLibraryCode/modules/juce_events/messages/juce_MessageManager.h b/JuceLibraryCode/modules/juce_events/messages/juce_MessageManager.h index bd91977..0901b29 100644 --- a/JuceLibraryCode/modules/juce_events/messages/juce_MessageManager.h +++ b/JuceLibraryCode/modules/juce_events/messages/juce_MessageManager.h @@ -91,10 +91,12 @@ public: #endif //============================================================================== + #if JUCE_COMPILER_SUPPORTS_LAMBDAS /** Asynchronously invokes a function or C++11 lambda on the message thread. Internally this uses the CallbackMessage class to invoke the callback. */ static void callAsync (std::function); + #endif /** Calls a function using the message-thread. diff --git a/JuceLibraryCode/modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm b/JuceLibraryCode/modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm index b7e814d..4fd30aa 100644 --- a/JuceLibraryCode/modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm +++ b/JuceLibraryCode/modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm @@ -142,7 +142,6 @@ public: if (currentPeer != peer) { - removeFromParent(); currentPeer = peer; if (peer != nullptr) @@ -151,6 +150,10 @@ public: [peerView addSubview: view]; componentMovedOrResized (false, false); } + else + { + removeFromParent(); + } } [view setHidden: ! owner.isShowing()]; diff --git a/README.md b/README.md index a5157c7..39481fa 100644 --- a/README.md +++ b/README.md @@ -131,7 +131,7 @@ FAQ (possibly) Credits & thanks ---------------- * DX Synth engine : Raph Levien and the [msfa](https://code.google.com/p/music-synthesizer-for-android) team -* AZur Studio - Graphical design +* AZur Studio : Graphical design * LP Filter : Filatov Vadim (2DaT); taken from the excellent [Obxd](https://obxd.wordpress.com) project * PPPlay : Great [OPL3](http://sourceforge.net/projects/peepeeplayer) implementation, with documented code :D * DX7 program compilation : Jean-Marc Desprez (author of [SynprezFM](http://www.synprez.com/SynprezFM)) @@ -147,6 +147,7 @@ Planned milestones TODO - Dexed ------------ * Yamaha 4 operators (DX21/DX27/DX100) sysex import +* UI threaded messaging to avoid DAW automation 'clicks' * Various code cleanup * AU Version diff --git a/Resources/ui/GlobalEditor_864x144.png b/Resources/ui/GlobalEditor_864x144.png index 863b46c..a23f739 100644 Binary files a/Resources/ui/GlobalEditor_864x144.png and b/Resources/ui/GlobalEditor_864x144.png differ diff --git a/Source/AlgoDisplay.cpp b/Source/AlgoDisplay.cpp index 0f5b708..7a72b07 100644 --- a/Source/AlgoDisplay.cpp +++ b/Source/AlgoDisplay.cpp @@ -37,6 +37,7 @@ inline void displayOp(Graphics &g, char id, char x, char y, char link, char fb) g.setColour(Colours::white); g.drawText(t, x, y, 16, 12, Justification::centred, true); + g.setGradientFill(ColourGradient()); g.setColour(DXLookNFeel::fillColour); switch(link) { case 0 : // LINE DOWN @@ -44,11 +45,11 @@ inline void displayOp(Graphics &g, char id, char x, char y, char link, char fb) break; case 1: // ARROW TO RIGHT g.drawLine(x+8, y+12, x+8, y+18, LINE_SZ); - g.drawLine(x+7, y+18, x+32, y+18, LINE_SZ); + g.drawLine(x+7, y+18, x+34, y+18, LINE_SZ); break; - case 2: // ARROW TO LEFT - g.drawLine(x+8, y+12, x+8, y+18, LINE_SZ); - g.drawLine(x-16, y+18, x+10, y+18, LINE_SZ); + case 2: // ARROW TO RIGHT JOIN + g.drawLine(x+8, y+12, x+8, y+19, LINE_SZ); + //g.drawLine(x-17, y+18, x+9, y+18, LINE_SZ); break; case 3: // LINE g.drawLine(x+8, y+12, x+8, y+18, LINE_SZ); @@ -57,16 +58,51 @@ inline void displayOp(Graphics &g, char id, char x, char y, char link, char fb) case 4: // LEFT * 2 g.drawLine(x+8, y+12, x+8, y+18, LINE_SZ); g.drawLine(x-16, y+18, x+25, y+18, LINE_SZ); - default : + break; + case 5: // RIGHT DIAG + g.drawLine(x+8, y+12, x+25, y+18, LINE_SZ); + break; + case 6: + g.drawLine(x+8, y+12, x+8, y+18, LINE_SZ); + g.drawLine(x+7, y+18, x+58, y+18, LINE_SZ); + break; + case 7: // ARROW TO LEFT + g.drawLine(x+8, y+12, x+8, y+19, LINE_SZ); + g.drawLine(x-17, y+18, x+9, y+18, LINE_SZ); break; } - if ( fb ) { - g.drawLine(x+7, y, x+8, y-4, LINE_SZ); + switch(fb) { + case 0: + break; + case 1: + g.drawLine(x+7, y, x+8, y-5, LINE_SZ); g.drawLine(x+8, y-4, x+20, y-4, LINE_SZ); g.drawLine(x+19, y-4, x+19, y+15, LINE_SZ); g.drawLine(x+18, y+15, x+19, y+15, LINE_SZ); - g.drawLine(x+8, y+15, x+19, y+15, LINE_SZ); + g.drawLine(x+8, y+15, x+20, y+15, LINE_SZ); + break; + case 2: // ALGO 4 + g.drawLine(x+7, y, x+8, y-5, LINE_SZ); + g.drawLine(x+8, y-4, x+20, y-4, LINE_SZ); + g.drawLine(x+19, y-4, x+19, y+59, LINE_SZ); +// g.drawLine(x+19, y+57, x+19, y+59, LINE_SZ); + g.drawLine(x+8, y+58, x+19, y+58, LINE_SZ); + break; + case 3: // ALGO 6 + g.drawLine(x+7, y, x+8, y-5, LINE_SZ); + g.drawLine(x+8, y-4, x+20, y-4, LINE_SZ); + g.drawLine(x+19, y-4, x+19, y+37, LINE_SZ); + //g.drawLine(x+18, y+36, x+19, y+36, LINE_SZ); + g.drawLine(x+8, y+36, x+19, y+36, LINE_SZ); + break; + case 4: + g.drawLine(x+7, y, x+8, y-5, LINE_SZ); + g.drawLine(x+8, y-4, x-4, y-4, LINE_SZ); + g.drawLine(x-3, y-4, x-3, y+15, LINE_SZ); + g.drawLine(x-3, y+15, x+8, y+15, LINE_SZ); + g.drawLine(x+8, y+15, x+8, y+12, LINE_SZ); + break; } } @@ -90,7 +126,6 @@ void AlgoDisplay::paint(Graphics &g) { displayOp(g, 2, 2, 2, 0, 1); displayOp(g, 1, 2, 3, 1, 0); break; - case 2: displayOp(g, 6, 3, 1, 0, 1); displayOp(g, 5, 3, 2, 0, 0); @@ -100,34 +135,32 @@ void AlgoDisplay::paint(Graphics &g) { displayOp(g, 1, 2, 3, 1, 0); break; case 3: // - displayOp(g, 6, 3, 1, 0, 0); + displayOp(g, 6, 3, 1, 0, 2); displayOp(g, 5, 3, 2, 0, 0); displayOp(g, 4, 3, 3, 2, 0); displayOp(g, 3, 2, 1, 0, 0); displayOp(g, 2, 2, 2, 0, 0); displayOp(g, 1, 2, 3, 1, 0); break; - case 4: displayOp(g, 6, 3, 2, 0, 1); displayOp(g, 5, 3, 3, 2, 0); displayOp(g, 4, 2, 2, 0, 0); - displayOp(g, 3, 2, 3, 3, 0); + displayOp(g, 3, 2, 3, 1, 0); displayOp(g, 2, 1, 2, 0, 0); displayOp(g, 1, 1, 3, 1, 0); break; case 5: // - displayOp(g, 6, 3, 2, 0, 0); + displayOp(g, 6, 3, 2, 0, 3); displayOp(g, 5, 3, 3, 2, 0); displayOp(g, 4, 2, 2, 0, 0); - displayOp(g, 3, 2, 3, 3, 0); + displayOp(g, 3, 2, 3, 1, 0); displayOp(g, 2, 1, 2, 0, 0); displayOp(g, 1, 1, 3, 1, 0); break; - case 6: displayOp(g, 6, 3, 1, 0, 1); - displayOp(g, 5, 3, 2, 2, 0); + displayOp(g, 5, 3, 2, 7, 0); displayOp(g, 4, 2, 2, 0, 0); displayOp(g, 3, 2, 3, 2, 0); displayOp(g, 2, 1, 2, 0, 0); @@ -135,27 +168,26 @@ void AlgoDisplay::paint(Graphics &g) { break; case 7: displayOp(g, 6, 3, 1, 0, 0); - displayOp(g, 5, 3, 2, 2, 0); - displayOp(g, 4, 2, 2, 0, 1); + displayOp(g, 5, 3, 2, 7, 0); + displayOp(g, 4, 2, 2, 0, 4); displayOp(g, 3, 2, 3, 2, 0); displayOp(g, 2, 1, 2, 0, 0); displayOp(g, 1, 1, 3, 1, 0); break; case 8: displayOp(g, 6, 3, 1, 0, 0); - displayOp(g, 5, 3, 2, 2, 0); + displayOp(g, 5, 3, 2, 7, 0); displayOp(g, 4, 2, 2, 0, 0); displayOp(g, 3, 2, 3, 2, 0); displayOp(g, 2, 1, 2, 0, 1); displayOp(g, 1, 1, 3, 1, 0); break; - case 9: displayOp(g, 6, 2, 2, 0, 0); displayOp(g, 5, 1, 2, 1, 0); displayOp(g, 4, 2, 3, 1, 0); displayOp(g, 3, 3, 1, 0, 1); - displayOp(g, 2, 3, 2, 2, 0); + displayOp(g, 2, 3, 2, 0, 0); displayOp(g, 1, 3, 3, 2, 0); break; case 10: @@ -163,59 +195,175 @@ void AlgoDisplay::paint(Graphics &g) { displayOp(g, 5, 1, 2, 1, 0); displayOp(g, 4, 2, 3, 1, 0); displayOp(g, 3, 3, 1, 0, 0); - displayOp(g, 2, 3, 2, 2, 0); + displayOp(g, 2, 3, 2, 0, 0); displayOp(g, 1, 3, 3, 2, 0); break; - case 11: - displayOp(g, 6, 2, 2, 0, 1); - displayOp(g, 5, 1, 2, 1, 0); - displayOp(g, 4, 0, 2, 1, 0); - displayOp(g, 3, 1, 3, 1, 0); - displayOp(g, 2, 3, 2, 0, 0); - displayOp(g, 1, 3, 3, 2, 0); + displayOp(g, 6, 3, 2, 7, 0); + displayOp(g, 5, 2, 2, 0, 0); + displayOp(g, 4, 1, 2, 1, 0); + displayOp(g, 3, 2, 3, 6, 0); + displayOp(g, 2, 4, 2, 0, 1); + displayOp(g, 1, 4, 3, 2, 0); break; - case 12: - displayOp(g, 6, 2, 2, 0, 0); - displayOp(g, 5, 1, 2, 1, 0); - displayOp(g, 4, 0, 2, 1, 0); - displayOp(g, 3, 1, 3, 1, 0); - displayOp(g, 2, 3, 2, 0, 0); - displayOp(g, 1, 3, 3, 2, 0); + displayOp(g, 6, 3, 2, 7, 1); + displayOp(g, 5, 2, 2, 0, 0); + displayOp(g, 4, 1, 2, 1, 0); + displayOp(g, 3, 2, 3, 6, 0); + displayOp(g, 2, 4, 2, 0, 0); + displayOp(g, 1, 4, 3, 2, 0); break; - case 13: displayOp(g, 6, 3, 1, 0, 1); - displayOp(g, 5, 3, 2, 1, 0); - displayOp(g, 4, 3, 3, 2, 0); - displayOp(g, 3, 2, 1, 0, 0); + displayOp(g, 5, 2, 1, 1, 0); + displayOp(g, 4, 3, 2, 0, 0); + displayOp(g, 3, 3, 3, 2, 0); displayOp(g, 2, 2, 2, 0, 0); - displayOp(g, 1, 2, 3, 1, 0); + displayOp(g, 1, 2, 3, 1, 0); break; case 14: displayOp(g, 6, 3, 1, 0, 0); + displayOp(g, 5, 2, 1, 1, 0); + displayOp(g, 4, 3, 2, 0, 0); + displayOp(g, 3, 3, 3, 2, 0); + displayOp(g, 2, 2, 2, 0, 4); + displayOp(g, 1, 2, 3, 1, 0); + break; + case 15: + displayOp(g, 6, 3, 1, 0, 1); + displayOp(g, 5, 3, 2, 7, 0); + displayOp(g, 4, 2, 1, 0, 0); + displayOp(g, 3, 2, 2, 0, 0); + displayOp(g, 2, 1, 2, 1, 0); + displayOp(g, 1, 2, 3, 0, 0); + break; + case 16: + displayOp(g, 6, 3, 1, 0, 0); + displayOp(g, 5, 3, 2, 7, 0); + displayOp(g, 4, 2, 1, 0, 0); + displayOp(g, 3, 2, 2, 0, 0); + displayOp(g, 2, 1, 2, 1, 4); + displayOp(g, 1, 2, 3, 0, 0); + break; + case 17: + displayOp(g, 6, 3, 0, 0, 0); + displayOp(g, 5, 3, 1, 0, 0); + displayOp(g, 4, 3, 2, 7, 0); + displayOp(g, 3, 2, 2, 0, 4); + displayOp(g, 2, 1, 2, 1, 0); + displayOp(g, 1, 2, 3, 0, 0); + break; + case 18: + displayOp(g, 6, 2, 2, 0, 1); + displayOp(g, 5, 3, 3, 2, 0); + displayOp(g, 4, 2, 3, 1, 0); + displayOp(g, 3, 1, 1, 0, 0); + displayOp(g, 2, 1, 2, 0, 0); + displayOp(g, 1, 1, 3, 1, 0); + break; + case 19: + displayOp(g, 6, 4, 2, 0, 0); + displayOp(g, 5, 3, 2, 1, 0); + displayOp(g, 4, 4, 3, 2, 0); + displayOp(g, 3, 1, 2, 0, 1); + displayOp(g, 2, 2, 3, 6, 0); + displayOp(g, 1, 1, 3, 1, 0); + break; + case 20: + displayOp(g, 6, 3, 2, 0, 0); + displayOp(g, 5, 4, 3, 2, 0); + displayOp(g, 4, 3, 3, 1, 0); + displayOp(g, 3, 1, 2, 0, 1); + displayOp(g, 2, 2, 3, 1, 0); + displayOp(g, 1, 1, 3, 1, 0); + break; + case 21: + displayOp(g, 6, 3, 2, 0, 1); + displayOp(g, 5, 4, 3, 2, 0); + displayOp(g, 4, 3, 3, 1, 0); + displayOp(g, 3, 2, 3, 1, 0); + displayOp(g, 2, 1, 2, 0, 0); + displayOp(g, 1, 1, 3, 1, 0); + break; + case 22: // CC + displayOp(g, 6, 3, 2, 0, 1); + displayOp(g, 5, 4, 3, 2, 0); + displayOp(g, 4, 3, 3, 1, 0); + displayOp(g, 3, 2, 2, 0, 0); + displayOp(g, 2, 2, 3, 1, 0); + displayOp(g, 1, 1, 3, 1, 0); + break; + case 23: // CC + displayOp(g, 6, 3, 2, 0, 1); + displayOp(g, 5, 4, 3, 2, 0); + displayOp(g, 4, 3, 3, 1, 0); + displayOp(g, 3, 2, 3, 1, 0); + displayOp(g, 2, 1, 3, 1, 0); + displayOp(g, 1, 0, 3, 1, 0); + break; + case 24: // CC + displayOp(g, 6, 3, 2, 0, 1); + displayOp(g, 5, 4, 3, 2, 0); + displayOp(g, 4, 3, 3, 1, 0); + displayOp(g, 3, 2, 3, 1, 0); + displayOp(g, 2, 1, 3, 1, 0); + displayOp(g, 1, 0, 3, 1, 0); + break; + case 25: + displayOp(g, 6, 4, 2, 0, 1); displayOp(g, 5, 3, 2, 1, 0); - displayOp(g, 4, 3, 3, 2, 0); - displayOp(g, 3, 2, 1, 0, 0); - displayOp(g, 2, 2, 2, 0, 0); - displayOp(g, 1, 2, 3, 1, 0); + displayOp(g, 4, 4, 3, 2, 0); + displayOp(g, 3, 2, 2, 0, 0); + displayOp(g, 2, 2, 3, 6, 0); + displayOp(g, 1, 1, 3, 1, 0); + break; + case 26: + displayOp(g, 6, 4, 2, 0, 0); + displayOp(g, 5, 3, 2, 1, 0); + displayOp(g, 4, 4, 3, 2, 0); + displayOp(g, 3, 2, 2, 0, 1); + displayOp(g, 2, 2, 3, 6, 0); + displayOp(g, 1, 1, 3, 1, 0); + break; + case 27: + displayOp(g, 6, 3, 3, 2, 0); + displayOp(g, 5, 2, 1, 0, 1); + displayOp(g, 4, 2, 2, 0, 0); + displayOp(g, 3, 2, 3, 1, 0); + displayOp(g, 2, 1, 2, 0, 0); + displayOp(g, 1, 1, 3, 1, 0); + break; + case 28: + displayOp(g, 6, 4, 2, 0, 1); + displayOp(g, 5, 4, 3, 2, 0); + displayOp(g, 4, 3, 2, 0, 0); + displayOp(g, 3, 3, 3, 1, 0); + displayOp(g, 2, 2, 3, 1, 0); + displayOp(g, 1, 1, 3, 1, 0); + break; + case 29: + displayOp(g, 6, 4, 3, 2, 0); + displayOp(g, 5, 3, 1, 0, 1); + displayOp(g, 4, 3, 2, 0, 0); + displayOp(g, 3, 3, 3, 1, 0); + displayOp(g, 2, 2, 3, 1, 0); + displayOp(g, 1, 1, 3, 1, 0); break; - case 30: displayOp(g, 6, 4, 2, 0, 1); displayOp(g, 5, 4, 3, 2, 0); - displayOp(g, 4, 3, 3, 3, 0); - displayOp(g, 3, 2, 3, 3, 0); - displayOp(g, 2, 1, 3, 3, 0); + displayOp(g, 4, 3, 3, 1, 0); + displayOp(g, 3, 2, 3, 1, 0); + displayOp(g, 2, 1, 3, 1, 0); displayOp(g, 1, 0, 3, 1, 0); break; case 31: displayOp(g, 6, 5, 3, 2, 1); - displayOp(g, 5, 4, 3, 3, 0); - displayOp(g, 4, 3, 3, 3, 0); - displayOp(g, 3, 2, 3, 3, 0); - displayOp(g, 2, 1, 3, 3, 0); + displayOp(g, 5, 4, 3, 1, 0); + displayOp(g, 4, 3, 3, 1, 0); + displayOp(g, 3, 2, 3, 1, 0); + displayOp(g, 2, 1, 3, 1, 0); displayOp(g, 1, 0, 3, 1, 0); break; default: diff --git a/Source/DXComponents.cpp b/Source/DXComponents.cpp index 5792c9b..ef5ffaf 100644 --- a/Source/DXComponents.cpp +++ b/Source/DXComponents.cpp @@ -22,6 +22,7 @@ * */ +#include "Dexed.h" #include "DXComponents.h" #include "DXLookNFeel.h" #include "PluginProcessor.h" @@ -337,41 +338,15 @@ void VuMeter::paint(Graphics &g) { } LcdDisplay::LcdDisplay() { - systemMsg = "*** DEXED FM synthesizer ***"; - paramMsg = ""; -} - -void LcdDisplay::timerCallback() { - //systemMsg = "*** DEXED FM synthesizer ***"; - //repaint(); - //stopTimer(); + paramMsg = "DEXED " DEXED_VERSION; } void LcdDisplay::setSystemMsg(String msg) { - //systemMsg = msg; - //triggerAsyncUpdate(); -} - -void LcdDisplay::handleAsyncUpdate() { - repaint(); - startTimer(5000); + paramMsg = msg; } -#ifdef _WIN32 - const float LCD_FONTSIZE = 13.0f; -#else - const float LCD_FONTSIZE = 15.0f; -#endif - void LcdDisplay::paint(Graphics &g) { g.setColour (Colours::white); - /* - g.fillRoundedRectangle (0.0f, 0.0f, (float) getWidth(), (float) getHeight(), 1.0f); - - g.setFont (Font (Font::getDefaultMonospacedFontName(), LCD_FONTSIZE, Font::plain)); - g.drawText (systemMsg, - 7, 4, 300, 8, - Justification::centredLeft, true);*/ g.drawText (paramMsg, 0, 0, 140, 14, Justification::centred, true); diff --git a/Source/DXComponents.h b/Source/DXComponents.h index 6642eef..e67d60d 100644 --- a/Source/DXComponents.h +++ b/Source/DXComponents.h @@ -46,13 +46,10 @@ public : float v; }; -class LcdDisplay : public Component, public Timer, public AsyncUpdater { - void timerCallback(); - void handleAsyncUpdate(); +class LcdDisplay : public Component { public: LcdDisplay(); void setSystemMsg(String msg); - String systemMsg; String paramMsg; void paint(Graphics &g); }; diff --git a/Source/DXLookNFeel.cpp b/Source/DXLookNFeel.cpp index 78e1740..ed65b1d 100644 --- a/Source/DXLookNFeel.cpp +++ b/Source/DXLookNFeel.cpp @@ -30,17 +30,24 @@ Colour DXLookNFeel::comboBoxBackground = Colour(20,18,18); DXLookNFeel::DXLookNFeel() { setColour(TextButton::buttonColourId,Colour(0xFF0FC00F)); + setColour(TextButton::textColourOnId, Colours::white); + setColour(TextButton::textColourOffId, Colours::white); + setColour(Slider::rotarySliderOutlineColourId,Colour(0xFF0FC00F)); setColour(Slider::rotarySliderFillColourId,Colour(0xFFFFFFFF)); + setColour(AlertWindow::backgroundColourId,lightBackground); + setColour(AlertWindow::textColourId, Colours::white); + setColour(TextEditor::backgroundColourId,ctrlBackground); setColour(TextEditor::textColourId, Colours::white); + setColour(TextEditor::highlightColourId, fillColour); setColour(TextEditor::outlineColourId, Colours::transparentBlack); + setColour(ComboBox::backgroundColourId,ctrlBackground); setColour(ComboBox::textColourId, Colours::white); setColour(ComboBox::buttonColourId, Colours::white); - setColour(TextButton::textColourOnId, Colours::white); - setColour(TextButton::textColourOffId, Colours::white); + setColour(PopupMenu::backgroundColourId, background); setColour(PopupMenu::textColourId, Colours::white); setColour(PopupMenu::highlightedTextColourId, Colours::white); @@ -108,6 +115,7 @@ Font DXLookNFeel::getTextButtonFont(TextButton& button, int buttonHeight) { void DXLookNFeel::positionComboBoxText(ComboBox& box, Label& label) { ComboBox *src = &box; + // I'm not proud of this one, but really... it must be another way to do this.... ComboBoxImage* img = dynamic_cast(src); if(img != 0) { return; diff --git a/Source/Dexed.h b/Source/Dexed.h index 74722d4..0532721 100644 --- a/Source/Dexed.h +++ b/Source/Dexed.h @@ -24,14 +24,14 @@ void dexed_trace(const char *source, const char *fmt, ...); #ifdef DEBUG - #define DEXED_VERSION "0.8.0a DEBUG" + #define DEXED_VERSION "0.8.0b1 DEBUG" #ifdef _MSC_VER #define TRACE(fmt, ...) dexed_trace(__FUNCTION__,fmt,##__VA_ARGS__) #else #define TRACE(fmt, ...) dexed_trace(__PRETTY_FUNCTION__,fmt,##__VA_ARGS__) #endif #else - #define DEXED_VERSION "0.8.0a" + #define DEXED_VERSION "0.8.0b1" #define TRACE(fmt, ...) #endif diff --git a/Source/GlobalEditor.cpp b/Source/GlobalEditor.cpp index f36e08b..95ca368 100644 --- a/Source/GlobalEditor.cpp +++ b/Source/GlobalEditor.cpp @@ -19,12 +19,50 @@ //[Headers] You can add your own extra header files here... #include "PluginEditor.h" +#include "DXLookNFeel.h" //[/Headers] #include "GlobalEditor.h" //[MiscUserDefs] You can add your own user definitions and misc code here... + +/** + * Ugly but usefull midi monitor to know if you are really sending/receiving something from the DX7 + * If the midi is not configured this component wont show up + */ +class MidiMonitor : public Component { + SysexComm *midi; +public: + MidiMonitor(SysexComm *sysexComm) { + midi = sysexComm; + } + + void paint(Graphics &g) { + if ( ! (midi->isInputActive() || midi->isOutputActive() ) ) + return; + + /*g.setColour(DXLookNFeel::lightBackground); + g.fillRoundedRectangle(0, 0, getWidth(), getHeight(), 3); + */ + g.setColour(Colours::white); +// g.drawSingleLineText("DX7 ACT ", 0, 13); + + Image myStrip = ImageCache::getFromMemory(BinaryData::Light_14x14_png, BinaryData::Light_14x14_pngSize); + + if ( midi->isInputActive() ) { + g.drawSingleLineText("DX7 IN", 17,14); + g.drawImage(myStrip, 0, 3, 14, 14, 0, midi->inActivity ? 14 : 0, 14, 14); + midi->inActivity = false; + } + + if ( midi->isOutputActive() ) { + g.drawSingleLineText("DX7 OUT", 17, 28); + g.drawImage(myStrip, 0, 17, 14, 14, 0, midi->outActivity ? 14 : 0, 14, 14); + midi->outActivity = false; + } + } +}; //[/MiscUserDefs] //============================================================================== @@ -32,7 +70,7 @@ GlobalEditor::GlobalEditor () { addAndMakeVisible (lfoSpeed = new Slider ("lfoSpeed")); lfoSpeed->setRange (0, 99, 1); - lfoSpeed->setSliderStyle (Slider::Rotary); + lfoSpeed->setSliderStyle (Slider::RotaryVerticalDrag); lfoSpeed->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); lfoSpeed->addListener (this); @@ -122,6 +160,7 @@ GlobalEditor::GlobalEditor () addAndMakeVisible (oscSync = new ToggleButton ("oscSync")); oscSync->setButtonText (String::empty); + oscSync->addListener (this); addAndMakeVisible (pitchModSens = new Slider ("pitchModSens")); pitchModSens->setRange (0, 7, 0); @@ -131,6 +170,7 @@ GlobalEditor::GlobalEditor () addAndMakeVisible (lfoSync = new ToggleButton ("lfoSync")); lfoSync->setButtonText (String::empty); + lfoSync->addListener (this); addAndMakeVisible (pitchEnvDisplay = new PitchEnvDisplay()); pitchEnvDisplay->setName ("pitchEnvDisplay"); @@ -218,6 +258,7 @@ GlobalEditor::GlobalEditor () lfoType->setImage(ImageCache::getFromMemory(BinaryData::LFO_36_26_png, BinaryData::LFO_36_26_pngSize)); programs = programSelector; + //[/Constructor] } @@ -281,6 +322,9 @@ void GlobalEditor::paint (Graphics& g) //[UserPaint] Add your own custom painting code here.. Image myStrip = ImageCache::getFromMemory(BinaryData::Light_14x14_png, BinaryData::Light_14x14_pngSize); g.drawImage(myStrip, 300, 70, 14, 14, 0, monoMode->getToggleState() ? 14 : 0, 14, 14); + + g.drawImage(myStrip, 621, 102, 14, 14, 0, lfoSync->getToggleState() ? 14 : 0, 14, 14); + g.drawImage(myStrip, 705, 102, 14, 14, 0, oscSync->getToggleState() ? 14 : 0, 14, 14); //[/UserPaint] } @@ -301,12 +345,12 @@ void GlobalEditor::resized() pitchLevel4->setBounds (823, 56, 34, 34); pitchLevel1->setBounds (739, 57, 34, 34); transpose->setBounds (202, 60, 34, 34); - oscSync->setBounds (652, 95, 48, 26); + oscSync->setBounds (650, 96, 48, 26); pitchModSens->setBounds (666, 5, 34, 34); - lfoSync->setBounds (571, 96, 48, 26); + lfoSync->setBounds (567, 96, 48, 26); pitchEnvDisplay->setBounds (751, 10, 93, 30); algoDisplay->setBounds (338, 30, 146, 91); - feedback->setBounds (501, 80, 34, 34); + feedback->setBounds (501, 81, 34, 34); algo->setBounds (501, 22, 34, 34); lcdDisplay->setBounds (6, 87, 140, 13); output->setBounds (157, 60, 34, 34); @@ -318,7 +362,7 @@ void GlobalEditor::resized() loadButton->setBounds (50, 111, 50, 30); saveButton->setBounds (98, 111, 50, 30); storeButton->setBounds (270, 109, 50, 30); - monoMode->setBounds (248, 65, 48, 26); + monoMode->setBounds (249, 65, 48, 26); lfoType->setBounds (584, 8, 36, 26); programSelector->setBounds (153, 115, 112, 18); //[UserResized] Add your own custom resize handling here.. @@ -443,7 +487,19 @@ void GlobalEditor::buttonClicked (Button* buttonThatWasClicked) //[UserbuttonClicked_Pre] //[/UserbuttonClicked_Pre] - if (buttonThatWasClicked == initButton) + if (buttonThatWasClicked == oscSync) + { + //[UserButtonCode_oscSync] -- add your button handler code here.. + repaint(); + //[/UserButtonCode_oscSync] + } + else if (buttonThatWasClicked == lfoSync) + { + //[UserButtonCode_lfoSync] -- add your button handler code here.. + repaint(); + //[/UserButtonCode_lfoSync] + } + else if (buttonThatWasClicked == initButton) { //[UserButtonCode_initButton] -- add your button handler code here.. editor->initProgram(); @@ -527,6 +583,11 @@ void GlobalEditor::bind(DexedAudioProcessor *parent) { algoDisplay->algo = &(parent->data[134]); pitchEnvDisplay->pvalues = &(parent->data[126]); processor = parent; + + midiMonitor = new MidiMonitor(&(processor->sysexComm)); + addAndMakeVisible(midiMonitor); + midiMonitor->setBounds(155, 21, 80, 80); + repaint(); } @@ -579,8 +640,8 @@ BEGIN_JUCER_METADATA + style="RotaryVerticalDrag" textBoxPos="NoTextBox" textBoxEditable="1" + textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> + explicitFocusOrder="0" pos="650 96 48 26" buttonText="" connectedEdges="0" + needsCallback="1" radioGroupId="0" state="0"/> + explicitFocusOrder="0" pos="567 96 48 26" buttonText="" connectedEdges="0" + needsCallback="1" radioGroupId="0" state="0"/> @@ -654,7 +715,7 @@ BEGIN_JUCER_METADATA virtualName="" explicitFocusOrder="0" pos="338 30 146 91" class="AlgoDisplay" params=""/> midiMonitor; //[/UserMethods] void paint (Graphics& g); diff --git a/Source/OperatorEditor.cpp b/Source/OperatorEditor.cpp index 88f57f6..02d2296 100644 --- a/Source/OperatorEditor.cpp +++ b/Source/OperatorEditor.cpp @@ -244,14 +244,14 @@ void OperatorEditor::paint (Graphics& g) //[UserPaint] Add your own custom painting code here.. g.setColour (Colours::white); g.setFont(Font (30.00f, Font::plain)); - g.drawText(opNum, 242, 9, 30, 30, Justification::centred, true); + g.drawText(opNum, 242, 10, 30, 30, Justification::centred, true); Image myStrip = ImageCache::getFromMemory(BinaryData::Light_14x14_png, BinaryData::Light_14x14_pngSize); bool state = opMode->getToggleState(); // 129 x 24 - g.drawImage(myStrip, 128, 24, 14, 14, 0, state ? 0 : 14, 14, 14); + g.drawImage(myStrip, 127, 24, 14, 14, 0, state ? 0 : 14, 14, 14); // 199 x 24 g.drawImage(myStrip, 199, 24, 14, 14, 0, !state ? 0 : 14, 14, 14); diff --git a/Source/PluginEditor.cpp b/Source/PluginEditor.cpp index ea52791..14074aa 100644 --- a/Source/PluginEditor.cpp +++ b/Source/PluginEditor.cpp @@ -57,53 +57,6 @@ public: } }; -/** - * Ugly but usefull midi monitor to know if you are really sending/receiving something from the DX7 - * If the midi is not configured this component wont show up - */ -class MidiMonitor : public Component { - SysexComm *midi; -public: - MidiMonitor(SysexComm *sysexComm) { - midi = sysexComm; - } - - void paint(Graphics &g) { - if ( ! (midi->isInputActive() || midi->isOutputActive() ) ) - return; - - //g.setColour(DXLookNFeel::dxDarkBrown); - g.fillRect(0, 0, getWidth(), getHeight()); - g.setColour(Colours::black); - g.drawSingleLineText("DX7 ", 0, 13); - - if ( midi->isInputActive() ) { - g.drawSingleLineText("IN", 27,13); - if ( midi->inActivity ) { - g.setColour(Colours::red); - } else { - g.setColour(Colours::darkgrey); - } - g.fillRect(44, 4, 7, 9); - - midi->inActivity = false; - } - - if ( midi->isOutputActive() ) { - g.setColour(Colours::black); - g.drawSingleLineText("OUT", 55, 13); - if ( midi->outActivity ) { - g.setColour(Colours::red); - } else { - g.setColour(Colours::darkgrey); - } - g.fillRect(83, 4, 7, 9); - - midi->outActivity = false; - } - } -}; - //============================================================================== DexedAudioProcessorEditor::DexedAudioProcessorEditor (DexedAudioProcessor* ownerFilter) : AudioProcessorEditor (ownerFilter), @@ -111,12 +64,12 @@ DexedAudioProcessorEditor::DexedAudioProcessorEditor (DexedAudioProcessor* owner { LookAndFeel::setDefaultLookAndFeel(&dx_lnf); - setSize (866, 677); + setSize (866, ownerFilter->showKeyboard ? 677 : 583); processor = ownerFilter; - addAndMakeVisible(midiMonitor = new MidiMonitor(&processor->sysexComm)); - midiMonitor->setBounds(645, 6, 110, 18); + /*addAndMakeVisible(midiMonitor = new MidiMonitor(&processor->sysexComm)); + midiMonitor->setBounds(645, 6, 110, 18);*/ // OPERATORS addAndMakeVisible(&(operators[0])); @@ -149,8 +102,7 @@ DexedAudioProcessorEditor::DexedAudioProcessorEditor (DexedAudioProcessor* owner // The DX7 is a badass on the bass, keep it that way midiKeyboard.setLowestVisibleKey(24); - const int keyboardHeight = 90; - midiKeyboard.setBounds(4, getHeight() - keyboardHeight - 4, getWidth() - 8, keyboardHeight); + midiKeyboard.setBounds(4, 583, getWidth() - 8, 90); global.editor = this; addAndMakeVisible(&global); @@ -283,33 +235,18 @@ void DexedAudioProcessorEditor::parmShow() { processor->setEngineType(tp); processor->savePreference(); + setSize (866, processor->showKeyboard ? 677 : 583); + midiKeyboard.repaint(); + if ( ret == false ) { AlertWindow::showMessageBoxAsync(AlertWindow::WarningIcon, "Midi Interface", "Error opening midi ports"); } - - //sendButton->setVisible(processor->sysexComm.isOutputActive()); } void DexedAudioProcessorEditor::initProgram() { processor->resetToInitVoice(); } -/* - if (buttonThatWasClicked == monoButton ) { - processor->setMonoMode(monoButton->getToggleState()); - monoButton->setState(processor->isMonoMode() ? Button::ButtonState::buttonDown : Button::ButtonState::buttonNormal); - return; - } - - if (buttonThatWasClicked == aboutButton) { - AboutBox about(this); - about.runModalLoop(); - return; - } - - AlertWindow::showMessageBoxAsync(AlertWindow::WarningIcon, "Sorry", "Soon !"); -}*/ - void DexedAudioProcessorEditor::comboBoxChanged (ComboBox* comboBoxThatHasChanged) { processor->setCurrentProgram(global.programs->getSelectedId()-1); processor->updateHostDisplay(); @@ -330,7 +267,6 @@ void DexedAudioProcessorEditor::timerCallback() { } global.updatePitchPos(processor->voiceStatus.pitchStep); global.updateVu(processor->vuSignal); - midiMonitor->repaint(); } void DexedAudioProcessorEditor::updateUI() { diff --git a/Source/PluginEditor.h b/Source/PluginEditor.h index 3e9462d..b7ccd5d 100644 --- a/Source/PluginEditor.h +++ b/Source/PluginEditor.h @@ -39,7 +39,6 @@ class DexedAudioProcessorEditor : public AudioProcessorEditor, MidiKeyboardComponent midiKeyboard; DXLookNFeel dx_lnf; - ScopedPointer midiMonitor; OperatorEditor operators[6]; public: diff --git a/Source/msfa/env.cc b/Source/msfa/env.cc old mode 100755 new mode 100644 index 4c73705..63e44ac --- a/Source/msfa/env.cc +++ b/Source/msfa/env.cc @@ -1,132 +1,132 @@ -/* - * Copyright 2012 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#include "synth.h" -#include "env.h" - -#include "../Dexed.h" -//using namespace std; - -uint32_t Env::sr_multiplier = (1<<24); - -void Env::init_sr(double sampleRate) { - sr_multiplier = (44100.0 / sampleRate) * (1<<24); -} - -void Env::init(const int r[4], const int l[4], int32_t ol, int rate_scaling) { - for (int i = 0; i < 4; i++) { - rates_[i] = r[i]; - levels_[i] = l[i]; - } - outlevel_ = ol; - rate_scaling_ = rate_scaling; - level_ = 0; - down_ = true; - advance(0); -} - -int32_t Env::getsample() { - if (ix_ < 3 || ((ix_ < 4) && !down_)) { - if (rising_) { - const int jumptarget = 1716; - if (level_ < (jumptarget << 16)) { - level_ = jumptarget << 16; - } - level_ += (((17 << 24) - level_) >> 24) * inc_; - // TODO: should probably be more accurate when inc is large - if (level_ >= targetlevel_) { - level_ = targetlevel_; - advance(ix_ + 1); - } - } else { // !rising - level_ -= inc_; - if (level_ <= targetlevel_) { - level_ = targetlevel_; - advance(ix_ + 1); - } - } - } - // TODO: this would be a good place to set level to 0 when under threshold - return level_; -} - -void Env::keydown(bool d) { - if (down_ != d) { - down_ = d; - advance(d ? 0 : 3); - } -} - -void Env::setparam(int param, int value) { - if (param < 4) { - rates_[param] = value; - } else if (param < 8) { - levels_[param - 4] = value; - } - // Unknown parameter, ignore for now -} - -const int levellut[] = { - 0, 5, 9, 13, 17, 20, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 42, 43, 45, 46 -}; - -int Env::scaleoutlevel(int outlevel) { - return outlevel >= 20 ? 28 + outlevel : levellut[outlevel]; -} - -void Env::advance(int newix) { - ix_ = newix; - if (ix_ < 4) { - int newlevel = levels_[ix_]; - int actuallevel = scaleoutlevel(newlevel) >> 1; - actuallevel = (actuallevel << 6) + outlevel_ - 4256; - actuallevel = actuallevel < 16 ? 16 : actuallevel; - // level here is same as Java impl - targetlevel_ = actuallevel << 16; - rising_ = (targetlevel_ > level_); - - // rate - int qrate = (rates_[ix_] * 41) >> 6; - qrate += rate_scaling_; - qrate = min(qrate, 63); - inc_ = (4 + (qrate & 3)) << (2 + LG_N + (qrate >> 2)); - - // meh, this should be fixed elsewhere - inc_ = ((int64_t)inc_ * (int64_t)sr_multiplier) >> 24; - } -} - -void Env::getPosition(char *step) { - *step = ix_; -} - -void Env::transfer(Env &src) { - for(int i=0;i<4;i++) { - rates_[i] = src.rates_[i]; - levels_[i] = src.levels_[i]; - } - outlevel_ = src.outlevel_; - rate_scaling_ = src.rate_scaling_; - level_ = src.level_; - targetlevel_ = src.targetlevel_; - rising_= src.rising_; - ix_ = src.ix_; - inc_ = src.inc_; - down_ = src.down_; -} - +/* + * Copyright 2012 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "synth.h" +#include "env.h" + +#include "../Dexed.h" +//using namespace std; + +uint32_t Env::sr_multiplier = (1<<24); + +void Env::init_sr(double sampleRate) { + sr_multiplier = (44100.0 / sampleRate) * (1<<24); +} + +void Env::init(const int r[4], const int l[4], int32_t ol, int rate_scaling) { + for (int i = 0; i < 4; i++) { + rates_[i] = r[i]; + levels_[i] = l[i]; + } + outlevel_ = ol; + rate_scaling_ = rate_scaling; + level_ = 0; + down_ = true; + advance(0); +} + +int32_t Env::getsample() { + if (ix_ < 3 || ((ix_ < 4) && !down_)) { + if (rising_) { + const int jumptarget = 1716; + if (level_ < (jumptarget << 16)) { + level_ = jumptarget << 16; + } + level_ += (((17 << 24) - level_) >> 24) * inc_; + // TODO: should probably be more accurate when inc is large + if (level_ >= targetlevel_) { + level_ = targetlevel_; + advance(ix_ + 1); + } + } else { // !rising + level_ -= inc_; + if (level_ <= targetlevel_) { + level_ = targetlevel_; + advance(ix_ + 1); + } + } + } + // TODO: this would be a good place to set level to 0 when under threshold + return level_; +} + +void Env::keydown(bool d) { + if (down_ != d) { + down_ = d; + advance(d ? 0 : 3); + } +} + +void Env::setparam(int param, int value) { + if (param < 4) { + rates_[param] = value; + } else if (param < 8) { + levels_[param - 4] = value; + } + // Unknown parameter, ignore for now +} + +const int levellut[] = { + 0, 5, 9, 13, 17, 20, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 42, 43, 45, 46 +}; + +int Env::scaleoutlevel(int outlevel) { + return outlevel >= 20 ? 28 + outlevel : levellut[outlevel]; +} + +void Env::advance(int newix) { + ix_ = newix; + if (ix_ < 4) { + int newlevel = levels_[ix_]; + int actuallevel = scaleoutlevel(newlevel) >> 1; + actuallevel = (actuallevel << 6) + outlevel_ - 4256; + actuallevel = actuallevel < 16 ? 16 : actuallevel; + // level here is same as Java impl + targetlevel_ = actuallevel << 16; + rising_ = (targetlevel_ > level_); + + // rate + int qrate = (rates_[ix_] * 41) >> 6; + qrate += rate_scaling_; + qrate = min(qrate, 63); + inc_ = (4 + (qrate & 3)) << (2 + LG_N + (qrate >> 2)); + + // meh, this should be fixed elsewhere + inc_ = ((int64_t)inc_ * (int64_t)sr_multiplier) >> 24; + } +} + +void Env::getPosition(char *step) { + *step = ix_; +} + +void Env::transfer(Env &src) { + for(int i=0;i<4;i++) { + rates_[i] = src.rates_[i]; + levels_[i] = src.levels_[i]; + } + outlevel_ = src.outlevel_; + rate_scaling_ = src.rate_scaling_; + level_ = src.level_; + targetlevel_ = src.targetlevel_; + rising_= src.rising_; + ix_ = src.ix_; + inc_ = src.inc_; + down_ = src.down_; +} + diff --git a/Source/msfa/lfo.cc b/Source/msfa/lfo.cc old mode 100755 new mode 100644 index 6b86df5..a3836b8 --- a/Source/msfa/lfo.cc +++ b/Source/msfa/lfo.cc @@ -1,97 +1,97 @@ -/* - * Copyright 2013 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// Low frequency oscillator, compatible with DX7 - -#include "synth.h" - -#include "sin.h" -#include "lfo.h" - -uint32_t Lfo::unit_; - -void Lfo::init(double sample_rate) { - // constant is 1 << 32 / 15.5s / 11 - Lfo::unit_ = (int32_t)(N * 25190424 / sample_rate + 0.5); -} - -void Lfo::reset(const char params[6]) { - int rate = params[0]; // 0..99 - int sr = rate == 0 ? 1 : (165 * rate) >> 6; - sr *= sr < 160 ? 11 : (11 + ((sr - 160) >> 4)); - delta_ = unit_ * sr; - int a = 99 - params[1]; // LFO delay - if (a == 99) { - delayinc_ = ~0u; - delayinc2_ = ~0u; - } else { - a = (16 + (a & 15)) << (1 + (a >> 4)); - delayinc_ = unit_ * a; - a &= 0xff80; - a = max(0x80, a); - delayinc2_ = unit_ * a; - } - waveform_ = params[5]; - sync_ = params[4] != 0; -} - -int32_t Lfo::getsample() { - phase_ += delta_; - int32_t x; - switch (waveform_) { - case 0: // triangle - x = phase_ >> 7; - x ^= -(phase_ >> 31); - x &= (1 << 24) - 1; - return x; - case 1: // sawtooth down - return (~phase_ ^ (1U << 31)) >> 8; - case 2: // sawtooth up - return (phase_ ^ (1U << 31)) >> 8; - case 3: // square - return ((~phase_) >> 7) & (1 << 24); - case 4: // sine - return (1 << 23) + (Sin::lookup(phase_ >> 8) >> 1); - case 5: // s&h - if (phase_ < delta_) { - randstate_ = (randstate_ * 179 + 17) & 0xff; - } - x = randstate_ ^ 0x80; - return (x + 1) << 16; - } - return 1 << 23; -} - -int32_t Lfo::getdelay() { - uint32_t delta = delaystate_ < (1U << 31) ? delayinc_ : delayinc2_; - uint32_t d = delaystate_ + delta; - if (d < delayinc_) { - return 1 << 24; - } - delaystate_ = d; - if (d < (1U << 31)) { - return 0; - } else { - return (d >> 7) & ((1 << 24) - 1); - } -} - -void Lfo::keydown() { - if (sync_) { - phase_ = (1U << 31) - 1; - } - delaystate_ = 0; -} +/* + * Copyright 2013 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Low frequency oscillator, compatible with DX7 + +#include "synth.h" + +#include "sin.h" +#include "lfo.h" + +uint32_t Lfo::unit_; + +void Lfo::init(double sample_rate) { + // constant is 1 << 32 / 15.5s / 11 + Lfo::unit_ = (int32_t)(N * 25190424 / sample_rate + 0.5); +} + +void Lfo::reset(const char params[6]) { + int rate = params[0]; // 0..99 + int sr = rate == 0 ? 1 : (165 * rate) >> 6; + sr *= sr < 160 ? 11 : (11 + ((sr - 160) >> 4)); + delta_ = unit_ * sr; + int a = 99 - params[1]; // LFO delay + if (a == 99) { + delayinc_ = ~0u; + delayinc2_ = ~0u; + } else { + a = (16 + (a & 15)) << (1 + (a >> 4)); + delayinc_ = unit_ * a; + a &= 0xff80; + a = max(0x80, a); + delayinc2_ = unit_ * a; + } + waveform_ = params[5]; + sync_ = params[4] != 0; +} + +int32_t Lfo::getsample() { + phase_ += delta_; + int32_t x; + switch (waveform_) { + case 0: // triangle + x = phase_ >> 7; + x ^= -(phase_ >> 31); + x &= (1 << 24) - 1; + return x; + case 1: // sawtooth down + return (~phase_ ^ (1U << 31)) >> 8; + case 2: // sawtooth up + return (phase_ ^ (1U << 31)) >> 8; + case 3: // square + return ((~phase_) >> 7) & (1 << 24); + case 4: // sine + return (1 << 23) + (Sin::lookup(phase_ >> 8) >> 1); + case 5: // s&h + if (phase_ < delta_) { + randstate_ = (randstate_ * 179 + 17) & 0xff; + } + x = randstate_ ^ 0x80; + return (x + 1) << 16; + } + return 1 << 23; +} + +int32_t Lfo::getdelay() { + uint32_t delta = delaystate_ < (1U << 31) ? delayinc_ : delayinc2_; + uint32_t d = delaystate_ + delta; + if (d < delayinc_) { + return 1 << 24; + } + delaystate_ = d; + if (d < (1U << 31)) { + return 0; + } else { + return (d >> 7) & ((1 << 24) - 1); + } +} + +void Lfo::keydown() { + if (sync_) { + phase_ = (1U << 31) - 1; + } + delaystate_ = 0; +} diff --git a/Source/msfa/lfo.h b/Source/msfa/lfo.h old mode 100755 new mode 100644 index 809df1e..e769535 --- a/Source/msfa/lfo.h +++ b/Source/msfa/lfo.h @@ -1,43 +1,43 @@ -/* - * Copyright 2013 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// Low frequency oscillator, compatible with DX7 - -class Lfo { - public: - static void init(double sample_rate); - void reset(const char params[6]); - - // result is 0..1 in Q24 - int32_t getsample(); - - // result is 0..1 in Q24 - int32_t getdelay(); - - void keydown(); - private: - static uint32_t unit_; - - uint32_t phase_; // Q32 - uint32_t delta_; - uint8_t waveform_; - uint8_t randstate_; - bool sync_; - - uint32_t delaystate_; - uint32_t delayinc_; - uint32_t delayinc2_; -}; +/* + * Copyright 2013 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Low frequency oscillator, compatible with DX7 + +class Lfo { + public: + static void init(double sample_rate); + void reset(const char params[6]); + + // result is 0..1 in Q24 + int32_t getsample(); + + // result is 0..1 in Q24 + int32_t getdelay(); + + void keydown(); + private: + static uint32_t unit_; + + uint32_t phase_; // Q32 + uint32_t delta_; + uint8_t waveform_; + uint8_t randstate_; + bool sync_; + + uint32_t delaystate_; + uint32_t delayinc_; + uint32_t delayinc2_; +}; diff --git a/Source/msfa/sin.cc b/Source/msfa/sin.cc old mode 100755 new mode 100644 index 5b09de4..3257dcd --- a/Source/msfa/sin.cc +++ b/Source/msfa/sin.cc @@ -1,142 +1,142 @@ -/* - * Copyright 2012 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define _USE_MATH_DEFINES -#include - -#include "synth.h" -#include "sin.h" - -#define R (1 << 29) - -#ifdef SIN_DELTA -int32_t sintab[SIN_N_SAMPLES << 1]; -#else -int32_t sintab[SIN_N_SAMPLES + 1]; -#endif - -void Sin::init() { - double dphase = 2 * M_PI / SIN_N_SAMPLES; - int32_t c = (int32_t)floor(cos(dphase) * (1 << 30) + 0.5); - int32_t s = (int32_t)floor(sin(dphase) * (1 << 30) + 0.5); - int32_t u = 1 << 30; - int32_t v = 0; - for (int i = 0; i < SIN_N_SAMPLES / 2; i++) { -#ifdef SIN_DELTA - sintab[(i << 1) + 1] = (v + 32) >> 6; - sintab[((i + SIN_N_SAMPLES / 2) << 1) + 1] = -((v + 32) >> 6); -#else - sintab[i] = (v + 32) >> 6; - sintab[i + SIN_N_SAMPLES / 2] = -((v + 32) >> 6); -#endif - int32_t t = ((int64_t)u * (int64_t)s + (int64_t)v * (int64_t)c + R) >> 30; - u = ((int64_t)u * (int64_t)c - (int64_t)v * (int64_t)s + R) >> 30; - v = t; - } -#ifdef SIN_DELTA - for (int i = 0; i < SIN_N_SAMPLES - 1; i++) { - sintab[i << 1] = sintab[(i << 1) + 3] - sintab[(i << 1) + 1]; - } - sintab[(SIN_N_SAMPLES << 1) - 2] = -sintab[(SIN_N_SAMPLES << 1) - 1]; -#else - sintab[SIN_N_SAMPLES] = 0; -#endif -} - -#ifndef SIN_INLINE -int32_t Sin::lookup(int32_t phase) { - const int SHIFT = 24 - SIN_LG_N_SAMPLES; - int lowbits = phase & ((1 << SHIFT) - 1); -#ifdef SIN_DELTA - int phase_int = (phase >> (SHIFT - 1)) & ((SIN_N_SAMPLES - 1) << 1); - int dy = sintab[phase_int]; - int y0 = sintab[phase_int + 1]; - - return y0 + (((int64_t)dy * (int64_t)lowbits) >> SHIFT); -#else - int phase_int = (phase >> SHIFT) & (SIN_N_SAMPLES - 1); - int y0 = sintab[phase_int]; - int y1 = sintab[phase_int + 1]; - - return y0 + (((int64_t)(y1 - y0) * (int64_t)lowbits) >> SHIFT); -#endif -} -#endif - - -#if 0 -// The following is an implementation designed not to use any lookup tables, -// based on the following implementation by Basile Graf: -// http://www.rossbencina.com/static/code/sinusoids/even_polynomial_sin_approximation.txt - -#define C0 (1 << 24) -#define C1 (331121857 >> 2) -#define C2 (1084885537 >> 4) -#define C3 (1310449902 >> 6) - -int32_t Sin::compute(int32_t phase) { - int32_t x = (phase & ((1 << 23) - 1)) - (1 << 22); - int32_t x2 = ((int64_t)x * (int64_t)x) >> 22; - int32_t x4 = ((int64_t)x2 * (int64_t)x2) >> 24; - int32_t x6 = ((int64_t)x2 * (int64_t)x4) >> 24; - int32_t y = C0 - - (((int64_t)C1 * (int64_t)x2) >> 24) + - (((int64_t)C2 * (int64_t)x4) >> 24) - - (((int64_t)C3 * (int64_t)x6) >> 24); - y ^= -((phase >> 23) & 1); - return y; -} -#endif - -#if 1 -// coefficients are Chebyshev polynomial, computed by compute_cos_poly.py -#define C8_0 16777216 -#define C8_2 -331168742 -#define C8_4 1089453524 -#define C8_6 -1430910663 -#define C8_8 950108533 - -int32_t Sin::compute(int32_t phase) { - int32_t x = (phase & ((1 << 23) - 1)) - (1 << 22); - int32_t x2 = ((int64_t)x * (int64_t)x) >> 16; - int32_t y = (((((((((((((int64_t)C8_8 - * (int64_t)x2) >> 32) + C8_6) - * (int64_t)x2) >> 32) + C8_4) - * (int64_t)x2) >> 32) + C8_2) - * (int64_t)x2) >> 32) + C8_0); - y ^= -((phase >> 23) & 1); - return y; -} -#endif - -#define C10_0 (1 << 30) -#define C10_2 -1324675874 // scaled * 4 -#define C10_4 1089501821 -#define C10_6 -1433689867 -#define C10_8 1009356886 -#define C10_10 -421101352 -int32_t Sin::compute10(int32_t phase) { - int32_t x = (phase & ((1 << 29) - 1)) - (1 << 28); - int32_t x2 = ((int64_t)x * (int64_t)x) >> 26; - int32_t y = ((((((((((((((((int64_t)C10_10 - * (int64_t)x2) >> 34) + C10_8) - * (int64_t)x2) >> 34) + C10_6) - * (int64_t)x2) >> 34) + C10_4) - * (int64_t)x2) >> 32) + C10_2) - * (int64_t)x2) >> 30) + C10_0); - y ^= -((phase >> 29) & 1); - return y; -} +/* + * Copyright 2012 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define _USE_MATH_DEFINES +#include + +#include "synth.h" +#include "sin.h" + +#define R (1 << 29) + +#ifdef SIN_DELTA +int32_t sintab[SIN_N_SAMPLES << 1]; +#else +int32_t sintab[SIN_N_SAMPLES + 1]; +#endif + +void Sin::init() { + double dphase = 2 * M_PI / SIN_N_SAMPLES; + int32_t c = (int32_t)floor(cos(dphase) * (1 << 30) + 0.5); + int32_t s = (int32_t)floor(sin(dphase) * (1 << 30) + 0.5); + int32_t u = 1 << 30; + int32_t v = 0; + for (int i = 0; i < SIN_N_SAMPLES / 2; i++) { +#ifdef SIN_DELTA + sintab[(i << 1) + 1] = (v + 32) >> 6; + sintab[((i + SIN_N_SAMPLES / 2) << 1) + 1] = -((v + 32) >> 6); +#else + sintab[i] = (v + 32) >> 6; + sintab[i + SIN_N_SAMPLES / 2] = -((v + 32) >> 6); +#endif + int32_t t = ((int64_t)u * (int64_t)s + (int64_t)v * (int64_t)c + R) >> 30; + u = ((int64_t)u * (int64_t)c - (int64_t)v * (int64_t)s + R) >> 30; + v = t; + } +#ifdef SIN_DELTA + for (int i = 0; i < SIN_N_SAMPLES - 1; i++) { + sintab[i << 1] = sintab[(i << 1) + 3] - sintab[(i << 1) + 1]; + } + sintab[(SIN_N_SAMPLES << 1) - 2] = -sintab[(SIN_N_SAMPLES << 1) - 1]; +#else + sintab[SIN_N_SAMPLES] = 0; +#endif +} + +#ifndef SIN_INLINE +int32_t Sin::lookup(int32_t phase) { + const int SHIFT = 24 - SIN_LG_N_SAMPLES; + int lowbits = phase & ((1 << SHIFT) - 1); +#ifdef SIN_DELTA + int phase_int = (phase >> (SHIFT - 1)) & ((SIN_N_SAMPLES - 1) << 1); + int dy = sintab[phase_int]; + int y0 = sintab[phase_int + 1]; + + return y0 + (((int64_t)dy * (int64_t)lowbits) >> SHIFT); +#else + int phase_int = (phase >> SHIFT) & (SIN_N_SAMPLES - 1); + int y0 = sintab[phase_int]; + int y1 = sintab[phase_int + 1]; + + return y0 + (((int64_t)(y1 - y0) * (int64_t)lowbits) >> SHIFT); +#endif +} +#endif + + +#if 0 +// The following is an implementation designed not to use any lookup tables, +// based on the following implementation by Basile Graf: +// http://www.rossbencina.com/static/code/sinusoids/even_polynomial_sin_approximation.txt + +#define C0 (1 << 24) +#define C1 (331121857 >> 2) +#define C2 (1084885537 >> 4) +#define C3 (1310449902 >> 6) + +int32_t Sin::compute(int32_t phase) { + int32_t x = (phase & ((1 << 23) - 1)) - (1 << 22); + int32_t x2 = ((int64_t)x * (int64_t)x) >> 22; + int32_t x4 = ((int64_t)x2 * (int64_t)x2) >> 24; + int32_t x6 = ((int64_t)x2 * (int64_t)x4) >> 24; + int32_t y = C0 - + (((int64_t)C1 * (int64_t)x2) >> 24) + + (((int64_t)C2 * (int64_t)x4) >> 24) - + (((int64_t)C3 * (int64_t)x6) >> 24); + y ^= -((phase >> 23) & 1); + return y; +} +#endif + +#if 1 +// coefficients are Chebyshev polynomial, computed by compute_cos_poly.py +#define C8_0 16777216 +#define C8_2 -331168742 +#define C8_4 1089453524 +#define C8_6 -1430910663 +#define C8_8 950108533 + +int32_t Sin::compute(int32_t phase) { + int32_t x = (phase & ((1 << 23) - 1)) - (1 << 22); + int32_t x2 = ((int64_t)x * (int64_t)x) >> 16; + int32_t y = (((((((((((((int64_t)C8_8 + * (int64_t)x2) >> 32) + C8_6) + * (int64_t)x2) >> 32) + C8_4) + * (int64_t)x2) >> 32) + C8_2) + * (int64_t)x2) >> 32) + C8_0); + y ^= -((phase >> 23) & 1); + return y; +} +#endif + +#define C10_0 (1 << 30) +#define C10_2 -1324675874 // scaled * 4 +#define C10_4 1089501821 +#define C10_6 -1433689867 +#define C10_8 1009356886 +#define C10_10 -421101352 +int32_t Sin::compute10(int32_t phase) { + int32_t x = (phase & ((1 << 29) - 1)) - (1 << 28); + int32_t x2 = ((int64_t)x * (int64_t)x) >> 26; + int32_t y = ((((((((((((((((int64_t)C10_10 + * (int64_t)x2) >> 34) + C10_8) + * (int64_t)x2) >> 34) + C10_6) + * (int64_t)x2) >> 34) + C10_4) + * (int64_t)x2) >> 32) + C10_2) + * (int64_t)x2) >> 30) + C10_0); + y ^= -((phase >> 29) & 1); + return y; +} diff --git a/Source/msfa/sin.h b/Source/msfa/sin.h old mode 100755 new mode 100644 index d84a7d3..6605e99 --- a/Source/msfa/sin.h +++ b/Source/msfa/sin.h @@ -1,62 +1,62 @@ -/* - * Copyright 2012 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -class Sin { - public: - Sin(); - - static void init(); - static int32_t lookup(int32_t phase); - static int32_t compute(int32_t phase); - - // A more accurate sine, both input and output Q30 - static int32_t compute10(int32_t phase); -}; - -#define SIN_LG_N_SAMPLES 10 -#define SIN_N_SAMPLES (1 << SIN_LG_N_SAMPLES) - -#define SIN_INLINE - -// Use twice as much RAM for the LUT but avoid a little computation -#define SIN_DELTA - -#ifdef SIN_DELTA -extern int32_t sintab[SIN_N_SAMPLES << 1]; -#else -extern int32_t sintab[SIN_N_SAMPLES + 1]; -#endif - -#ifdef SIN_INLINE -inline -int32_t Sin::lookup(int32_t phase) { - const int SHIFT = 24 - SIN_LG_N_SAMPLES; - int lowbits = phase & ((1 << SHIFT) - 1); -#ifdef SIN_DELTA - int phase_int = (phase >> (SHIFT - 1)) & ((SIN_N_SAMPLES - 1) << 1); - int dy = sintab[phase_int]; - int y0 = sintab[phase_int + 1]; - - return y0 + (((int64_t)dy * (int64_t)lowbits) >> SHIFT); -#else - int phase_int = (phase >> SHIFT) & (SIN_N_SAMPLES - 1); - int y0 = sintab[phase_int]; - int y1 = sintab[phase_int + 1]; - - return y0 + (((int64_t)(y1 - y0) * (int64_t)lowbits) >> SHIFT); -#endif -} -#endif +/* + * Copyright 2012 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class Sin { + public: + Sin(); + + static void init(); + static int32_t lookup(int32_t phase); + static int32_t compute(int32_t phase); + + // A more accurate sine, both input and output Q30 + static int32_t compute10(int32_t phase); +}; + +#define SIN_LG_N_SAMPLES 10 +#define SIN_N_SAMPLES (1 << SIN_LG_N_SAMPLES) + +#define SIN_INLINE + +// Use twice as much RAM for the LUT but avoid a little computation +#define SIN_DELTA + +#ifdef SIN_DELTA +extern int32_t sintab[SIN_N_SAMPLES << 1]; +#else +extern int32_t sintab[SIN_N_SAMPLES + 1]; +#endif + +#ifdef SIN_INLINE +inline +int32_t Sin::lookup(int32_t phase) { + const int SHIFT = 24 - SIN_LG_N_SAMPLES; + int lowbits = phase & ((1 << SHIFT) - 1); +#ifdef SIN_DELTA + int phase_int = (phase >> (SHIFT - 1)) & ((SIN_N_SAMPLES - 1) << 1); + int dy = sintab[phase_int]; + int y0 = sintab[phase_int + 1]; + + return y0 + (((int64_t)dy * (int64_t)lowbits) >> SHIFT); +#else + int phase_int = (phase >> SHIFT) & (SIN_N_SAMPLES - 1); + int y0 = sintab[phase_int]; + int y1 = sintab[phase_int + 1]; + + return y0 + (((int64_t)(y1 - y0) * (int64_t)lowbits) >> SHIFT); +#endif +} +#endif diff --git a/Source/msfa/synth.h b/Source/msfa/synth.h old mode 100755 new mode 100644 index 68c1181..5275775 --- a/Source/msfa/synth.h +++ b/Source/msfa/synth.h @@ -1,72 +1,72 @@ -/* - * Copyright 2012 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __SYNTH_H -#define __SYNTH_H - -// This IS not be present on MSVC. -// See http://stackoverflow.com/questions/126279/c99-stdint-h-header-and-ms-visual-studio -#include -#ifdef _MSC_VER -typedef __int32 int32_t; -typedef unsigned __int32 uint32_t; -typedef __int16 SInt16; -#endif - -#define LG_N 6 -#define N (1 << LG_N) - -#if defined(__APPLE__) -#include -#define SynthMemoryBarrier() OSMemoryBarrier() -#elif defined(__GNUC__) -#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) -#define SynthMemoryBarrier() __sync_synchronize() -#endif -#endif - - -// #undef SynthMemoryBarrier() - -#ifndef SynthMemoryBarrier -// need to understand why this must be defined -// #warning Memory barrier is not enabled -#define SynthMemoryBarrier() -#endif - -template -inline static T min(const T& a, const T& b) { - return a < b ? a : b; -} - -template -inline static T max(const T& a, const T& b) { - return a > b ? a : b; -} - - -void dexed_trace(const char *source, const char *fmt, ...); - -#define QER(n,b) ( ((float)n)/(1< +#ifdef _MSC_VER +typedef __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef __int16 SInt16; +#endif + +#define LG_N 6 +#define N (1 << LG_N) + +#if defined(__APPLE__) +#include +#define SynthMemoryBarrier() OSMemoryBarrier() +#elif defined(__GNUC__) +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) +#define SynthMemoryBarrier() __sync_synchronize() +#endif +#endif + + +// #undef SynthMemoryBarrier() + +#ifndef SynthMemoryBarrier +// need to understand why this must be defined +// #warning Memory barrier is not enabled +#define SynthMemoryBarrier() +#endif + +template +inline static T min(const T& a, const T& b) { + return a < b ? a : b; +} + +template +inline static T max(const T& a, const T& b) { + return a > b ? a : b; +} + + +void dexed_trace(const char *source, const char *fmt, ...); + +#define QER(n,b) ( ((float)n)/(1<