/* Copyright (C) 2006-2011 Nasca Octavian Paul Author: Nasca Octavian Paul This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License (version 2) for more details. You should have received a copy of the GNU General Public License (version 2) along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #pragma once #include #include #include "../JuceLibraryCode/JuceHeader.h" using REALTYPE = float; using floatvector = std::vector; using float2dvector = std::vector>; using float3dvector = std::vector>>; template inline std::unique_ptr unique_from_raw(T* ptr) { return std::unique_ptr(ptr); } template inline String toString(const T& x) { return String(x); } inline String toString(double x) { return String(x,3); } template inline String formatted(Args... args) { String result; (result << ... << toString(args)); return result; } #ifndef USEOLDPLAYCURSOR #define USEOLDPLAYCURSOR #endif #ifndef NULL #define NULL 0 #endif #ifndef M_PI #define M_PI 3.14159265359 #endif const int g_maxnumoutchans = 32; #ifndef USE_LUA_SCRIPTING //#define USE_LUA_SCRIPTING #endif inline void storeToTreeProperties(ValueTree dest, UndoManager* uman, juce::Identifier varname, var val) { dest.setProperty(varname, val, uman); } template inline void storeToTreeProperties(ValueTree dest, UndoManager* uman, juce::Identifier varname, var val, Ts&&... args) { dest.setProperty(varname, val, uman); storeToTreeProperties(dest, uman, args...); } template inline void storeToTreeProperties(ValueTree dest, UndoManager* uman, juce::Identifier varname, Range x) { dest.setProperty(varname+"_start", x.getStart(), uman); dest.setProperty(varname+"_end", x.getEnd(), uman); } template inline void getFromTreeProperties(ValueTree src, juce::Identifier varname, T& val) { if (src.hasProperty(varname)) val = src.getProperty(varname); } template inline void getFromTreeProperties(ValueTree src, juce::Identifier varname, T& val, Ts&... args) { if (src.hasProperty(varname)) val = src.getProperty(varname); getFromTreeProperties(src, args...); } template inline void getFromTreeProperties(ValueTree src, juce::Identifier varname, Range& rng) { if (src.hasProperty(varname + "_start") && src.hasProperty(varname + "_end")) { rng.setStart(src.getProperty(varname + "_start")); rng.setEnd(src.getProperty(varname + "_end")); } } template inline void timeCall(String msgprefix,F&& f) { double t0 = Time::getMillisecondCounterHiRes(); f(); double t1 = Time::getMillisecondCounterHiRes(); Logger::writeToLog(formatted(msgprefix, " took " , t1 - t0 , " ms")); } template class CircularBuffer final { public: CircularBuffer(int size) { m_buf.resize(size); } void clear() { m_avail = 0; m_readpos = 0; m_writepos = 0; std::fill(m_buf.begin(), m_buf.end(), T()); } void push(T x) { m_buf[m_writepos] = x; ++m_writepos; ++m_avail; if (m_writepos >= m_buf.size()) m_writepos = 0; } T get() { jassert(m_avail > 0); T x = m_buf[m_readpos]; ++m_readpos; --m_avail; if (m_readpos >= m_buf.size()) m_readpos = 0; return x; } int available() { return m_avail; } int getToBuf(T* buf, int len) { jassert(m_avail > 0); if (len > m_avail) len = m_avail; for (int i = 0; i < len; ++i) buf[i] = get(); return len; } int getFromBuf(T* buf, int len) { for (int i = 0; i < len; ++i) push(buf[i]); return len; } int getSize() { return (int)m_buf.size(); } void resize(int size) { m_avail = 0; m_readpos = 0; m_writepos = 0; m_buf.resize(size); } private: int m_writepos = 0; int m_readpos = 0; int m_avail = 0; std::vector m_buf; }; template inline void fill_container(Cont& c, const T& x) { std::fill(std::begin(c), std::end(c), x); } template inline void callGUI(T* ap, F&& f, bool async) { auto ed = dynamic_cast(ap->getActiveEditor()); if (ed) { if (async == false) f(ed); else MessageManager::callAsync([ed, f]() { f(ed); }); } } inline String secondsToString2(double secs) { RelativeTime rt(secs); String result; result.preallocateBytes(32); bool empty = true; if ((int)rt.inHours()>0) result << String((int)rt.inHours() % 24).paddedLeft('0', empty ? 1 : 2) << ':'; result << String((int)rt.inMinutes() % 60).paddedLeft('0', 2) << ':'; result << String((int)rt.inSeconds() % 60).paddedLeft('0', 2); auto millis = (int)rt.inMilliseconds() % 1000; if (millis > 0) result << '.' << String(millis).paddedLeft('0', 3); return result.trimEnd(); } inline String secondsToString(double seconds) { int64_t durintseconds = seconds; int64_t durintminutes = seconds / 60.0; int64_t durinthours = seconds / 3600.0; int64_t durintdays = seconds / (3600 * 24.0); String timestring; if (durintminutes < 1) timestring = String(seconds, 3) + " seconds"; if (durintminutes >= 1 && durinthours < 1) timestring = String(durintminutes) + " mins " + String(durintseconds % 60) + " secs"; if (durinthours >= 1 && durintdays < 1) timestring = String(durinthours) + " hours " + String(durintminutes % 60) + " mins " + String(durintseconds % 60) + " secs"; if (durintdays >= 1) timestring = String(durintdays) + " days " + String(durinthours % 24) + " hours " + String(durintminutes % 60) + " mins "; return timestring; } inline void toggleBool(bool& b) { b = !b; } inline void toggleBool(AudioParameterBool* b) { *b = !(*b); } template inline bool is_in_range(T val, T start, T end) { return val >= start && val <= end; } //#define SOUNDRANGE_OFFSET_ENABLED