├── clients └── oooooooo │ ├── src │ ├── Perlin.cpp │ ├── DisplayUtils.h │ ├── Window.cpp │ ├── Serializable.h │ ├── Window.h │ ├── HelpSystem.h │ ├── Commands.cpp │ ├── DisplayMessage.h │ ├── AudioFile.h │ ├── KeyboardHandler.h │ ├── AudioFile.cpp │ ├── DrawFunctions.h │ ├── Poll.h │ ├── VUMeter.h │ ├── DisplayRing.h │ ├── IntroAnimation.h │ ├── OscInterface.h │ ├── LFO.cpp │ ├── Display.h │ ├── Perlin.h │ ├── VUMeter.cpp │ ├── Commands.h │ ├── SessionRecorder.h │ ├── HelpSystem.cpp │ ├── DisplayMessage.cpp │ ├── LFO.h │ ├── Parameter.h │ ├── BufDiskWorker.h │ ├── main.cpp │ └── Parameters.h │ ├── third-party │ └── .DS_Store │ └── tests │ └── pulsefile.scd ├── oooooooo.png ├── softcut-lib ├── waf ├── include │ └── softcut │ │ ├── Types.h │ │ ├── Svf.h │ │ ├── Interpolate.h │ │ ├── FadeCurves.h │ │ ├── TestBuffers.h │ │ ├── SoftClip.h │ │ ├── SubHead.h │ │ ├── ReadWriteHead.h │ │ └── Voice.h ├── CMakeLists.txt ├── wscript └── src │ ├── Svf.cpp │ └── FadeCurves.cpp ├── .gitignore ├── external ├── windows │ ├── SDL2.dll │ ├── libFLAC.dll │ ├── liblo-7.dll │ ├── zlib1.dll │ ├── SDL2_ttf.dll │ ├── libbz2-1.dll │ ├── libintl-8.dll │ ├── libogg-0.dll │ ├── libopus-0.dll │ ├── libbrotlidec.dll │ ├── libgraphite2.dll │ ├── libiconv-2.dll │ ├── libmp3lame-0.dll │ ├── libmpg123-0.dll │ ├── libpcre2-8-0.dll │ ├── libpng16-16.dll │ ├── libsndfile-1.dll │ ├── libstdc++-6.dll │ ├── libvorbis-0.dll │ ├── libfreetype-6.dll │ ├── libgcc_s_seh-1.dll │ ├── libglib-2.0-0.dll │ ├── libharfbuzz-0.dll │ ├── libvorbisenc-2.dll │ ├── libbrotlicommon.dll │ ├── libwinpthread-1.dll │ ├── copy_dlls.py │ └── dlls.txt └── faust │ └── architecture │ └── faust │ ├── gui │ ├── Styles │ │ ├── Blue.qrc │ │ ├── Grey.qrc │ │ ├── Default.qrc │ │ ├── Salmon.qrc │ │ ├── Default.qss │ │ ├── Grey.qss │ │ └── Blue.qss │ ├── meta.h │ ├── JSONControl.h │ ├── JuceStateUI.h │ ├── UI.h │ ├── Esp32Reader.h │ └── JuceReader.h │ ├── dsp │ ├── cpp-dsp-adapter.h │ ├── faust-engine.h │ ├── dsp-multifun.h │ ├── proxy-dsp.h │ ├── dsp-checker.h │ └── proxy-osc-dsp.h │ ├── vst │ └── voice.h │ ├── export.h │ ├── misc.h │ ├── midi │ ├── teensy-midi.h │ ├── gramophone-midi.h │ └── daisy-midi.h │ ├── audio │ ├── audio.h │ ├── channels.h │ └── osc-dsp.h │ └── sound-file.h ├── CMakeLists.txt ├── dsp ├── CMakeLists.txt ├── tapefx │ ├── Follower.cpp │ ├── CMakeLists.txt │ ├── Follower.h │ ├── TapeFX.h │ └── TapeFX.cpp ├── utilities │ ├── CMakeLists.txt │ ├── Utilities.h │ └── Utilities.cpp └── fverb │ ├── CMakeLists.txt │ ├── FVerb.h │ └── FVerb.cpp ├── Makefile ├── readme-macos.md ├── readme-contributing.md ├── notes.md ├── tests └── test1.scd └── .github └── workflows ├── ci.yml └── release.yml /clients/oooooooo/src/Perlin.cpp: -------------------------------------------------------------------------------- 1 | #include "Perlin.h" -------------------------------------------------------------------------------- /oooooooo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schollz/oooooooo/HEAD/oooooooo.png -------------------------------------------------------------------------------- /softcut-lib/waf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schollz/oooooooo/HEAD/softcut-lib/waf -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.json 2 | build/* 3 | *.wav 4 | AppDir/* 5 | *.AppImage 6 | appimagetool* 7 | *.flac 8 | -------------------------------------------------------------------------------- /external/windows/SDL2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schollz/oooooooo/HEAD/external/windows/SDL2.dll -------------------------------------------------------------------------------- /external/windows/libFLAC.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schollz/oooooooo/HEAD/external/windows/libFLAC.dll -------------------------------------------------------------------------------- /external/windows/liblo-7.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schollz/oooooooo/HEAD/external/windows/liblo-7.dll -------------------------------------------------------------------------------- /external/windows/zlib1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schollz/oooooooo/HEAD/external/windows/zlib1.dll -------------------------------------------------------------------------------- /external/windows/SDL2_ttf.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schollz/oooooooo/HEAD/external/windows/SDL2_ttf.dll -------------------------------------------------------------------------------- /external/windows/libbz2-1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schollz/oooooooo/HEAD/external/windows/libbz2-1.dll -------------------------------------------------------------------------------- /external/windows/libintl-8.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schollz/oooooooo/HEAD/external/windows/libintl-8.dll -------------------------------------------------------------------------------- /external/windows/libogg-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schollz/oooooooo/HEAD/external/windows/libogg-0.dll -------------------------------------------------------------------------------- /external/windows/libopus-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schollz/oooooooo/HEAD/external/windows/libopus-0.dll -------------------------------------------------------------------------------- /external/windows/libbrotlidec.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schollz/oooooooo/HEAD/external/windows/libbrotlidec.dll -------------------------------------------------------------------------------- /external/windows/libgraphite2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schollz/oooooooo/HEAD/external/windows/libgraphite2.dll -------------------------------------------------------------------------------- /external/windows/libiconv-2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schollz/oooooooo/HEAD/external/windows/libiconv-2.dll -------------------------------------------------------------------------------- /external/windows/libmp3lame-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schollz/oooooooo/HEAD/external/windows/libmp3lame-0.dll -------------------------------------------------------------------------------- /external/windows/libmpg123-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schollz/oooooooo/HEAD/external/windows/libmpg123-0.dll -------------------------------------------------------------------------------- /external/windows/libpcre2-8-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schollz/oooooooo/HEAD/external/windows/libpcre2-8-0.dll -------------------------------------------------------------------------------- /external/windows/libpng16-16.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schollz/oooooooo/HEAD/external/windows/libpng16-16.dll -------------------------------------------------------------------------------- /external/windows/libsndfile-1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schollz/oooooooo/HEAD/external/windows/libsndfile-1.dll -------------------------------------------------------------------------------- /external/windows/libstdc++-6.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schollz/oooooooo/HEAD/external/windows/libstdc++-6.dll -------------------------------------------------------------------------------- /external/windows/libvorbis-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schollz/oooooooo/HEAD/external/windows/libvorbis-0.dll -------------------------------------------------------------------------------- /external/windows/libfreetype-6.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schollz/oooooooo/HEAD/external/windows/libfreetype-6.dll -------------------------------------------------------------------------------- /external/windows/libgcc_s_seh-1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schollz/oooooooo/HEAD/external/windows/libgcc_s_seh-1.dll -------------------------------------------------------------------------------- /external/windows/libglib-2.0-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schollz/oooooooo/HEAD/external/windows/libglib-2.0-0.dll -------------------------------------------------------------------------------- /external/windows/libharfbuzz-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schollz/oooooooo/HEAD/external/windows/libharfbuzz-0.dll -------------------------------------------------------------------------------- /external/windows/libvorbisenc-2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schollz/oooooooo/HEAD/external/windows/libvorbisenc-2.dll -------------------------------------------------------------------------------- /clients/oooooooo/third-party/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schollz/oooooooo/HEAD/clients/oooooooo/third-party/.DS_Store -------------------------------------------------------------------------------- /external/windows/libbrotlicommon.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schollz/oooooooo/HEAD/external/windows/libbrotlicommon.dll -------------------------------------------------------------------------------- /external/windows/libwinpthread-1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schollz/oooooooo/HEAD/external/windows/libwinpthread-1.dll -------------------------------------------------------------------------------- /external/faust/architecture/faust/gui/Styles/Blue.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | Blue.qss 4 | 5 | 6 | -------------------------------------------------------------------------------- /external/faust/architecture/faust/gui/Styles/Grey.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | Grey.qss 4 | 5 | 6 | -------------------------------------------------------------------------------- /external/faust/architecture/faust/gui/Styles/Default.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | Default.qss 4 | 5 | 6 | -------------------------------------------------------------------------------- /external/faust/architecture/faust/gui/Styles/Salmon.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | Salmon.qss 4 | 5 | 6 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.17) 2 | 3 | add_subdirectory(dsp) 4 | project(softcut) 5 | add_subdirectory(softcut-lib) 6 | add_subdirectory(clients/oooooooo) 7 | -------------------------------------------------------------------------------- /dsp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ./dsp/CMakeLists.txt 2 | cmake_minimum_required(VERSION 3.17) 3 | 4 | project(dsp) 5 | 6 | # Add the subdirectories 7 | add_subdirectory(utilities) 8 | add_subdirectory(fverb) 9 | add_subdirectory(tapefx) 10 | -------------------------------------------------------------------------------- /clients/oooooooo/src/DisplayUtils.h: -------------------------------------------------------------------------------- 1 | // DisplayUtils.h 2 | #ifndef DISPLAY_UTILS_H 3 | #define DISPLAY_UTILS_H 4 | 5 | // Functions to get current window dimensions 6 | int get_window_width(); 7 | int get_window_height(); 8 | 9 | #endif // DISPLAY_UTILS_H -------------------------------------------------------------------------------- /clients/oooooooo/src/Window.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by emb on 1/25/19. 3 | // 4 | 5 | #include "Window.h" 6 | 7 | using namespace softcut_jack_osc; 8 | 9 | const float Window::raisedCosShort[Window::raisedCosShortLen] = { 10 | #include "cos_win.inc" 11 | }; -------------------------------------------------------------------------------- /dsp/tapefx/Follower.cpp: -------------------------------------------------------------------------------- 1 | #include "Follower.h" 2 | 3 | float Follower::process(float x) { 4 | const auto abs_x = std::abs(x); 5 | if (abs_x > y_) { 6 | y_ = a_ * y_ + (1 - a_) * abs_x; 7 | } else { 8 | y_ = b_ * y_ + (1 - b_) * abs_x; 9 | } 10 | return y_; 11 | } -------------------------------------------------------------------------------- /softcut-lib/include/softcut/Types.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by ezra on 11/10/18. 3 | // 4 | 5 | #ifndef Softcut_TYPES_H 6 | #define Softcut_TYPES_H 7 | 8 | namespace softcut { 9 | typedef double sample_t; 10 | typedef double phase_t; 11 | typedef double rate_t; 12 | } // namespace softcut 13 | #endif // Softcut_TYPES_H 14 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | builder: build 3 | cd build && cmake --build . --config Release -- -j$(nproc) 4 | 5 | build: 6 | mkdir -p build 7 | cd build && cmake -DCMAKE_BUILD_TYPE=Release .. 8 | 9 | run: builder 10 | ./build/clients/oooooooo/oooooooo 11 | 12 | test: 13 | sclang tests/test1.scd 14 | 15 | clean: 16 | rm -rf build -------------------------------------------------------------------------------- /clients/oooooooo/src/Serializable.h: -------------------------------------------------------------------------------- 1 | // Add to a new file like "Serializable.h" 2 | #pragma once 3 | #include "JSON.hpp" 4 | using JSON = nlohmann::json; 5 | 6 | class Serializable { 7 | public: 8 | virtual ~Serializable() = default; 9 | virtual JSON toJSON() const = 0; 10 | virtual void fromJSON(const JSON& json) = 0; 11 | }; -------------------------------------------------------------------------------- /dsp/tapefx/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.17) 2 | set(CMAKE_CXX_STANDARD 17) 3 | 4 | project(tapefx) 5 | 6 | # Ensure the source file is included 7 | add_library(tapefx STATIC Follower.cpp TapeFX.cpp) 8 | 9 | # Make sure the headers are available 10 | target_include_directories(tapefx PUBLIC 11 | ${CMAKE_CURRENT_SOURCE_DIR} 12 | ) 13 | 14 | target_compile_options(tapefx PRIVATE -O3) -------------------------------------------------------------------------------- /dsp/utilities/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.17) 2 | set(CMAKE_CXX_STANDARD 17) 3 | 4 | project(utilities) 5 | 6 | # Ensure the source file is included 7 | add_library(utilities STATIC Utilities.cpp) 8 | 9 | # Make sure the headers are available 10 | target_include_directories(utilities PUBLIC 11 | ${CMAKE_CURRENT_SOURCE_DIR} 12 | ) 13 | 14 | target_compile_options(utilities PRIVATE -O3) -------------------------------------------------------------------------------- /clients/oooooooo/src/Window.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by emb on 1/25/19. 3 | // 4 | 5 | #ifndef CRONE_WINDOW_H 6 | #define CRONE_WINDOW_H 7 | 8 | #include 9 | 10 | namespace softcut_jack_osc { 11 | 12 | class Window { 13 | public: 14 | // raised-cosine window 15 | static constexpr size_t raisedCosShortLen = 48 * 50; 16 | static const float raisedCosShort[raisedCosShortLen]; 17 | }; 18 | 19 | } // namespace softcut_jack_osc 20 | 21 | #endif // CRONE_WINDOW_H 22 | -------------------------------------------------------------------------------- /dsp/fverb/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.17) 2 | set(CMAKE_CXX_STANDARD 17) 3 | 4 | project(fverb) 5 | 6 | 7 | # Add your own library 8 | add_library(fverb STATIC FVerb.cpp) 9 | 10 | # Include Faust headers and your own headers 11 | target_include_directories(fverb PUBLIC 12 | ${CMAKE_CURRENT_SOURCE_DIR} 13 | ${CMAKE_CURRENT_SOURCE_DIR}/.. 14 | ${CMAKE_CURRENT_SOURCE_DIR}/../../external/faust/architecture 15 | ) 16 | 17 | target_compile_options(fverb PRIVATE -O3) 18 | -------------------------------------------------------------------------------- /dsp/utilities/Utilities.h: -------------------------------------------------------------------------------- 1 | #ifndef UTILITIES_H 2 | #define UTILITIES_H 3 | #pragma once 4 | 5 | #include 6 | #include 7 | 8 | // Declaration of the FormatString function 9 | std::string FormatString(const char* format, ...); 10 | 11 | float MidiToFreq(float midi); 12 | 13 | float LinLin(float in, float inMin, float inMax, float outMin, float outMax); 14 | 15 | float FClamp(float x, float min, float max); 16 | 17 | float DBAmp(float db); 18 | 19 | float AmpDB(float amp); 20 | 21 | #endif -------------------------------------------------------------------------------- /readme-macos.md: -------------------------------------------------------------------------------- 1 | to build and use `softcut_jack_osc` on macOS, JACK must be installed and running. also some packages dependencies need to be installed via macports or homebrew: 2 | 3 | ``` 4 | sudo port install jack 5 | sudo port install libsndfile1-dev 6 | sudo port install liblo 7 | ``` 8 | 9 | to use the software, `jackd` must be running: 10 | 11 | ``` 12 | jackd -d coreaudio 13 | ``` 14 | 15 | and the selected audio device must have at least 2 channels of I/O. (i find it easiest to use an aggregate device on mac laptops.) -------------------------------------------------------------------------------- /softcut-lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.17) 2 | project(softcut) 3 | set(CMAKE_CXX_STANDARD 14) 4 | 5 | set(SRC 6 | src/Voice.cpp 7 | src/ReadWriteHead.cpp 8 | src/SubHead.cpp 9 | src/FadeCurves.cpp 10 | src/Svf.cpp) 11 | 12 | include_directories(include src) 13 | 14 | # tapefx 15 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../dsp) 16 | 17 | if(APPLE) 18 | include_directories(/usr/local/include) 19 | endif() 20 | 21 | add_library(softcut STATIC ${SRC}) 22 | 23 | target_link_libraries(softcut tapefx) 24 | 25 | target_compile_options(softcut PRIVATE -O3) -------------------------------------------------------------------------------- /softcut-lib/wscript: -------------------------------------------------------------------------------- 1 | def options(opt): 2 | opt.load('compiler_cxx') 3 | 4 | def configure(conf): 5 | conf.load('compiler_cxx') 6 | 7 | def build(bld): 8 | softcut_sources = [ 9 | 'src/FadeCurves.cpp', 10 | 'src/ReadWriteHead.cpp', 11 | 'src/SubHead.cpp', 12 | 'src/Svf.cpp', 13 | 'src/Voice.cpp', 14 | ] 15 | 16 | bld.stlib( 17 | target = 'softcut', 18 | features = 'cxx cxxstlib', 19 | source = softcut_sources, 20 | includes = ['include'], 21 | cflags = ['-O3', '-Wall', '-Wextra'], 22 | cxxflags = ['--std=c++14'] 23 | ) 24 | -------------------------------------------------------------------------------- /dsp/fverb/FVerb.h: -------------------------------------------------------------------------------- 1 | // src/effects/FVerb.h 2 | #pragma once 3 | 4 | #include // for size_t 5 | 6 | #include "../utilities/Utilities.h" // for FClamp 7 | 8 | class FVerbDSP; // Forward declaration for the Faust class 9 | 10 | class FVerb { 11 | public: 12 | FVerb() = default; 13 | ~FVerb(); 14 | 15 | void Init(float sample_rate); 16 | void Process(float** out, int numSamples); 17 | void SetDecay(float decay); 18 | void SetTailDensity(float x); 19 | void SetInputDiffision1(float x); 20 | void SetInputDiffision2(float x); 21 | 22 | private: 23 | FVerbDSP* dsp; 24 | float** inputs = nullptr; 25 | float** outputs = nullptr; 26 | }; -------------------------------------------------------------------------------- /dsp/tapefx/Follower.h: -------------------------------------------------------------------------------- 1 | #ifndef LIB_FOLLOWER_H 2 | #define LIB_FOLLOWER_H 3 | 4 | #include 5 | 6 | class Follower { 7 | public: 8 | Follower(){}; 9 | Follower(float sampleRate) 10 | : a_(std::exp(-1.0 / (0.001 * sampleRate))), // Attack time = 1ms 11 | b_(std::exp(-1.0 / (0.020 * sampleRate))), // Decay time = 20ms 12 | y_(0) {} 13 | Follower(float sampleRate, float attack, float decay) 14 | : a_(std::exp(-1.0 / (attack * sampleRate))), // Attack time = 1ms 15 | b_(std::exp(-1.0 / (decay * sampleRate))), // Decay time = 20ms 16 | y_(0) {} 17 | 18 | float process(float x); 19 | 20 | private: 21 | float a_, b_, y_; 22 | }; 23 | 24 | #endif -------------------------------------------------------------------------------- /dsp/tapefx/TapeFX.h: -------------------------------------------------------------------------------- 1 | #ifndef LIB_TAPEEMU_H 2 | #define LIB_TAPEEMU_H 3 | 4 | #include "Follower.h" 5 | 6 | typedef double sample_t; 7 | 8 | class TapeFX { 9 | public: 10 | TapeFX(); 11 | void Init(float sample_rate); 12 | void Process(sample_t **out, unsigned int numFrames); 13 | void ProcessMono(sample_t *out, unsigned int numFrames); 14 | void SetBias(float bias); 15 | void SetPregain(float pregain); 16 | float getFollowerValue() { return follow_; } 17 | float GetBias() { return bias_; } 18 | float GetPregain() { return pregain_; } 19 | 20 | private: 21 | sample_t dc_input_l_, dc_output_l_, dc_gain_; 22 | sample_t dc_input_r_, dc_output_r_; 23 | float bias_, pregain_; 24 | Follower follower; 25 | sample_t follow_; 26 | }; 27 | #endif 28 | -------------------------------------------------------------------------------- /clients/oooooooo/src/HelpSystem.h: -------------------------------------------------------------------------------- 1 | #ifndef HELP_SYSTEM_H 2 | #define HELP_SYSTEM_H 3 | #pragma once 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | class HelpSystem { 12 | public: 13 | HelpSystem(); 14 | ~HelpSystem(); 15 | 16 | void Init(TTF_Font* font); 17 | void Toggle(); 18 | void Render(SDL_Renderer* renderer, int windowWidth); 19 | 20 | bool isVisible() const { return helpVisible; } 21 | 22 | private: 23 | TTF_Font* font; 24 | bool helpVisible; 25 | float fadeAlpha; // 0.0 = fully transparent, 1.0 = fully opaque 26 | float fadeTarget; // Target alpha value 27 | float fadeStep; // Amount to change alpha per frame 28 | 29 | std::vector helpMessages; 30 | }; 31 | #endif -------------------------------------------------------------------------------- /clients/oooooooo/src/Commands.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by ezra on 11/3/18. 3 | // 4 | 5 | #include "Commands.h" 6 | 7 | #include 8 | 9 | #include "SoftcutClient.h" 10 | 11 | using namespace softcut_jack_osc; 12 | 13 | Commands Commands::softcutCommands; 14 | 15 | Commands::Commands() = default; 16 | 17 | void Commands::post(Commands::Id id, float f) { 18 | CommandPacket p(id, -1, f); 19 | q.enqueue(p); 20 | } 21 | 22 | void Commands::post(Commands::Id id, int i, float f) { 23 | CommandPacket p(id, i, f); 24 | q.enqueue(p); 25 | } 26 | 27 | void Commands::post(Commands::Id id, int i, int j) { 28 | CommandPacket p(id, i, j); 29 | q.enqueue(p); 30 | } 31 | 32 | void Commands::post(Commands::Id id, int i, int j, float f) { 33 | CommandPacket p(id, i, j, f); 34 | q.enqueue(p); 35 | } 36 | 37 | void Commands::handlePending(SoftcutClient *client) { 38 | CommandPacket p; 39 | while (q.try_dequeue(p)) { 40 | client->handleCommand(&p); 41 | } 42 | } -------------------------------------------------------------------------------- /clients/oooooooo/src/DisplayMessage.h: -------------------------------------------------------------------------------- 1 | #ifndef MESSAGE_H 2 | #define MESSAGE_H 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | class DisplayMessage { 11 | public: 12 | DisplayMessage(); 13 | 14 | void Init(TTF_Font* font); 15 | void SetMessage(const std::string& message, int displaySeconds); 16 | void Update(); 17 | void Render(SDL_Renderer* renderer, int windowWidth, int windowHeight); 18 | bool IsActive() const; 19 | 20 | private: 21 | enum class State { IDLE, FADING_IN, DISPLAYING, FADING_OUT }; 22 | 23 | TTF_Font* font_; 24 | std::string currentMessage_; 25 | State state_; 26 | float alpha_; 27 | 28 | std::chrono::steady_clock::time_point startTime_; 29 | std::chrono::steady_clock::time_point displayEndTime_; 30 | 31 | int displayDurationMs_; 32 | const int FADE_DURATION_MS = 500; // 500ms fade in/out 33 | 34 | SDL_Color textColor_; 35 | }; 36 | 37 | #endif // MESSAGE_H -------------------------------------------------------------------------------- /clients/oooooooo/src/AudioFile.h: -------------------------------------------------------------------------------- 1 | #ifndef AUDIO_FILE_H 2 | #define AUDIO_FILE_H 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | class AudioFile { 10 | public: 11 | // Constructor takes a file path 12 | AudioFile(const std::string& filePath); 13 | 14 | // Destructor to clean up resources 15 | ~AudioFile(); 16 | 17 | // Check if file loaded successfully 18 | bool isValid() const; 19 | 20 | // Get error message if loading failed 21 | std::string getError() const; 22 | 23 | // Get sample rate of the audio file 24 | int getSampleRate() const; 25 | 26 | // Get number of channels in the audio file 27 | int getChannelCount() const; 28 | 29 | // Get total number of frames 30 | sf_count_t getFrameCount() const; 31 | 32 | private: 33 | SNDFILE* file; // Handle to the sound file 34 | SF_INFO fileInfo; // File information structure 35 | std::string errorMsg; // Storage for error message 36 | }; 37 | 38 | #endif // AUDIO_FILE_H -------------------------------------------------------------------------------- /clients/oooooooo/src/KeyboardHandler.h: -------------------------------------------------------------------------------- 1 | #ifndef KEYBOARD_HANDLER_H 2 | #define KEYBOARD_HANDLER_H 3 | #pragma once 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include "Parameters.h" 12 | #include "SoftcutClient.h" 13 | 14 | class Display; 15 | 16 | class KeyboardHandler { 17 | public: 18 | KeyboardHandler() = default; 19 | ~KeyboardHandler() = default; 20 | 21 | void Init(SoftcutClient* sc, Parameters* params, int numVoices, 22 | Display* display) { 23 | softcut_ = sc; 24 | params_ = params; 25 | numVoices_ = numVoices; 26 | display_ = display; 27 | } 28 | 29 | void handleKeyDown(SDL_Keycode key, bool isRepeat, SDL_Keymod modifiers, 30 | int* selectedLoop); 31 | void handleKeyUp(SDL_Keycode key, int selectedLoop); 32 | 33 | private: 34 | SoftcutClient* softcut_; 35 | Parameters* params_; 36 | int numVoices_; 37 | int voiceToCopy_ = -1; 38 | Display* display_; 39 | 40 | std::unordered_map keysHeld_; 41 | }; 42 | 43 | #endif -------------------------------------------------------------------------------- /clients/oooooooo/src/AudioFile.cpp: -------------------------------------------------------------------------------- 1 | #include "AudioFile.h" 2 | 3 | AudioFile::AudioFile(const std::string& filePath) : file(nullptr) { 4 | // Initialize fileInfo structure 5 | memset(&fileInfo, 0, sizeof(fileInfo)); 6 | 7 | // Try to open the audio file 8 | file = sf_open(filePath.c_str(), SFM_READ, &fileInfo); 9 | 10 | // Check if file opened successfully 11 | if (!file) { 12 | // Store the error message 13 | errorMsg = sf_strerror(nullptr); 14 | } 15 | } 16 | 17 | AudioFile::~AudioFile() { 18 | // Close the file if it's open 19 | if (file) { 20 | sf_close(file); 21 | file = nullptr; 22 | } 23 | } 24 | 25 | bool AudioFile::isValid() const { return file != nullptr; } 26 | 27 | std::string AudioFile::getError() const { return errorMsg; } 28 | 29 | int AudioFile::getSampleRate() const { 30 | if (!isValid()) { 31 | return 0; 32 | } 33 | return fileInfo.samplerate; 34 | } 35 | 36 | int AudioFile::getChannelCount() const { 37 | if (!isValid()) { 38 | return 0; 39 | } 40 | return fileInfo.channels; 41 | } 42 | 43 | sf_count_t AudioFile::getFrameCount() const { 44 | if (!isValid()) { 45 | return 0; 46 | } 47 | return fileInfo.frames; 48 | } -------------------------------------------------------------------------------- /external/windows/copy_dlls.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shutil 3 | 4 | # C:\msys64\mingw64\bin 5 | mingw64_bin = os.path.join("C:\\", "msys64", "mingw64", "bin") 6 | print(mingw64_bin) 7 | 8 | total_size = 0 # Variable to track the total size of copied DLLs 9 | 10 | with open("dlls.txt", "r") as dlls_txt: 11 | for line in dlls_txt: 12 | fields = line.split() 13 | # get the field with mingw64/bin in it 14 | dll_name = "" 15 | for field in fields: 16 | if "/mingw64/bin" in field: 17 | dll_name = field.split("/")[-1] 18 | break 19 | dll_name = dll_name.replace("/mingw64/bin/", "") 20 | file_name = os.path.join(mingw64_bin, dll_name) 21 | file_name = os.path.normpath(os.path.join(mingw64_bin, dll_name)) 22 | try: 23 | shutil.copy(file_name, ".") 24 | file_size = os.path.getsize(file_name) # Get the size of the copied file 25 | total_size += file_size 26 | print(f"Copied {file_name} to current directory") 27 | except Exception as e: 28 | print(f"Error copying {file_name}: {e}") 29 | 30 | # Convert total size to MB and print it 31 | total_size_mb = total_size / (1024 * 1024) 32 | print(f"Total size of copied DLLs: {total_size_mb:.2f} MB") 33 | -------------------------------------------------------------------------------- /readme-contributing.md: -------------------------------------------------------------------------------- 1 | ## repository structure 2 | 3 | ### current branches: 4 | 5 | - `main`: currently active development branch. pretty much every PR should be opened against `main` (with possible exception of hotfixes for norns.) may have bugs. 6 | 7 | - `norns-latest`: this will attempt to track the commit pointed at by the `softcut` submodule in the main branch of `monome/norns` repo. 8 | 9 | - `v1.5`: current version branch. `main` should be merged into here whenever it's deemed stable enough for testing. 10 | 11 | - `wip/v2`: this branch contains "backlogged" changes intended for a v2 overhaul. involves extensive and complicated changes to the processing architecture. it's not yet working, hence the backlog, but it reopresents enough work to be worth saving. will be "salvaging" changes from here to release as v1.5. 12 | 13 | ### working branches: 14 | 15 | other working branches branches may exist, and should preferably be named using a prefix and a slash. we suggest: 16 | 17 | `fix/` - for bugfixes and (measurable!) performance improvements. 18 | 19 | `feature/`- for new user-facing features 20 | 21 | `dev/` for primarily developer-facing work, like refactoring 22 | 23 | (if you are part of the `monome` organization, you're welcome to make development branch in the monome repo instead of your personal fork.) 24 | -------------------------------------------------------------------------------- /clients/oooooooo/tests/pulsefile.scd: -------------------------------------------------------------------------------- 1 | n = NetAddr("localhost", 9999); 2 | 3 | ~setup = { 4 | 5 | // load file 6 | f = "/home/emb/code/softcut-lib/pulse.wav"; 7 | 8 | n.sendMsg("/softcut/buffer/clear"); 9 | n.sendMsg("/softcut/buffer/read_mono", f, 0, 0, 0.5, 0, 0); 10 | 11 | // n.sendMsg("/softcut/buffer/write_mono", "/home/emb/code/softcut-lib/pulse_cutloop.wav", 0, 1.0, 0); 12 | 13 | n.sendMsg("/set/enabled/cut", 0, 1); 14 | n.sendMsg("/set/level/cut", 0, 0.5); 15 | n.sendMsg("/set/pan/cut", 0, 0); 16 | 17 | n.sendMsg("/set/param/cut/buffer", 0, 0); 18 | 19 | n.sendMsg("/set/param/cut/loop_start", 0, 0); 20 | n.sendMsg("/set/param/cut/loop_end", 0, 1); 21 | n.sendMsg("/set/param/cut/loop_flag", 0, 0); 22 | 23 | n.sendMsg("/set/param/cut/fade_time", 0, 0); 24 | 25 | n.sendMsg("/set/param/cut/post_filter_lp", 0, 0); 26 | n.sendMsg("/set/param/cut/post_filter_hp", 0, 0); 27 | n.sendMsg("/set/param/cut/post_filter_bp", 0, 0); 28 | n.sendMsg("/set/param/cut/post_filter_br", 0, 0); 29 | n.sendMsg("/set/param/cut/post_filter_dry", 0, 1); 30 | n.sendMsg("/set/param/cut/play_flag", 0, 1); 31 | 32 | }; 33 | 34 | ~bang = { 35 | n.sendMsg("/set/param/cut/position", 0, 0); 36 | }; 37 | 38 | r = Routine { 39 | 40 | var delta = 0.5; 41 | ~setup.value; 42 | 0.2.wait; 43 | 44 | 20.do({ 45 | ~bang.value; 46 | delta = delta * 0.9; 47 | delta.wait; 48 | }); 49 | }.play; -------------------------------------------------------------------------------- /clients/oooooooo/src/DrawFunctions.h: -------------------------------------------------------------------------------- 1 | // DrawFunctions.h 2 | #ifndef DRAW_FUNCTIONS_H 3 | #define DRAW_FUNCTIONS_H 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | #include "Perlin.h" 11 | 12 | // Initialize font and perlin noise 13 | void initializeDrawingResources(TTF_Font** font, PerlinNoise* perlin); 14 | void cleanupDrawingResources(); 15 | 16 | // Text drawing function 17 | void drawText(SDL_Renderer* renderer, TTF_Font* font, const std::string& text, 18 | int x, int y, uint8_t color); 19 | 20 | // Draw a bar for the volume level with a text label 21 | void drawBar(SDL_Renderer* renderer, TTF_Font* font, int x, int y, int width, 22 | int height, float fill, float lfo, float lfo_min, float lfo_max, 23 | const std::string& label, bool selected); 24 | 25 | // Draw a ring with a position indicator 26 | void drawRing(SDL_Renderer* renderer, PerlinNoise* perlin, float id, float x, 27 | float y, int radius, float position, float thickness, 28 | float* noiseTimeValue, bool show_notch = true, 29 | bool sketchy = false); 30 | 31 | // Utility functions for hit testing 32 | bool isPointInBar(int x, int y, int bar_x, int bar_y, int bar_width, 33 | int bar_height); 34 | bool isPointInLoop(int x, int y, int loop_x, int loop_y, int radius); 35 | 36 | #endif // DRAW_FUNCTIONS_H -------------------------------------------------------------------------------- /softcut-lib/include/softcut/Svf.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by ezra on 11/8/18. 3 | // 4 | // state variable filter 5 | // after Hal Chamberlin, Andy Simper 6 | 7 | #ifndef Softcut_SVF_H 8 | #define Softcut_SVF_H 9 | 10 | #include 11 | 12 | class Svf { 13 | public: 14 | Svf(); 15 | float getNextSample(float x); 16 | void setSampleRate(float sr); 17 | void setFc(float fc); 18 | void setRq(float rq); 19 | void setLpMix(float mix); 20 | void setHpMix(float mix); 21 | void setBpMix(float mix); 22 | void setBrMix(float mix); 23 | void reset(); 24 | void update(float x); 25 | void calcWarp(); 26 | void calcCoeffs(); 27 | void clearState(); 28 | 29 | float getFc(); 30 | 31 | private: 32 | static const float MAX_NORM_FC; 33 | float lpMix; 34 | float hpMix; 35 | float bpMix; 36 | float brMix; 37 | float minFc; 38 | float maxFc; 39 | float pi_sr; 40 | 41 | // sample rate 42 | float sr; 43 | // corner frequency in hz 44 | float fc; 45 | // reciprocal of Q in [0,1] 46 | float rq; 47 | // intermediate coefficients 48 | float g; 49 | float g1; 50 | float g2; 51 | float g3; 52 | float g4; 53 | // state variables 54 | float v0; 55 | float v1; 56 | float v2; 57 | float v0z; 58 | float v1z; 59 | float v2z; 60 | float v3; 61 | // outputs 62 | float lp; // lowpass 63 | float hp; // highpass 64 | float bp; // bandpass 65 | float br; // bandreject 66 | }; 67 | 68 | #endif // Softcut_SVF_H 69 | -------------------------------------------------------------------------------- /notes.md: -------------------------------------------------------------------------------- 1 | idea for new voice computation structure, 2 | 3 | should allow "duck" and "follow" featurees without compromising performance. 4 | implementation complexity is reasonable; 5 | the cost is some extra RAM usage (perhaps several KB per voice.) 6 | 7 | 1. allocate a number of buffers at least as big as the largest expected blocksize. each buffer will contain the value of a parameter for a whole block: 8 | - active subhead index 9 | - each subhead state: 10 | - read phase 11 | - write phase 12 | - pre+fade level 13 | - rec+fade level 14 | 15 | 2. each process block can be decomposed without looping over all voices on each sample. 16 | 17 | ## normal mode: 18 | 19 | same as present operation, with some potential speed gain due to memory locality: 20 | 21 | - update positions 22 | - update fade levels 23 | - peek+poke, mix 24 | 25 | ## "follow" mode: 26 | 27 | here, one voice is always hard-synced to another, but with different buffer data and mix parameters. this allows stereo operation among other things. 28 | 29 | - copy positions 30 | - copy fade levels 31 | - peek+poke, mix 32 | 33 | ## duck mode: 34 | 35 | one voice uses another's write index as a reference; output level is attenuated when this voice's read position crosses that voice's record position. 36 | 37 | - update positions 38 | - update fade levels, comparing with reference position 39 | - peek+poke, mix 40 | 41 | 42 | ### details 43 | 44 | - can use `std::array` and `std::copy` for state buffers 45 | - 46 | -------------------------------------------------------------------------------- /softcut-lib/include/softcut/Interpolate.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by ezra on 12/8/17. 3 | // 4 | 5 | #ifndef Softcut_INTERPOLATE_H 6 | #define Softcut_INTERPOLATE_H 7 | 8 | namespace softcut { 9 | class Interpolate { 10 | public: 11 | template 12 | static inline T hermite(T x, T y0, T y1, T y2, T y3) { 13 | // 4-point, 3rd-order Hermite (x-form) 14 | #if 0 15 | T c0 = y1; 16 | T c1 = 0.5 * (y2 - y0); 17 | T c2 = y0 - 2.5 * y1 + 2. * y2 - 0.5 * y3; 18 | T c3 = 0.5 * (y3 - y0) + 1.5 * (y1 - y2); 19 | return ((c3 * x + c2) * x + c1) * x + c0; 20 | #else // inlined: 21 | return (((0.5 * (y3 - y0) + 1.5 * (y1 - y2)) * x + 22 | (y0 - 2.5 * y1 + 2. * y2 - 0.5 * y3)) * 23 | x + 24 | 0.5 * (y2 - y0)) * 25 | x + 26 | y1; 27 | #endif 28 | } 29 | 30 | // super-simple interpolation into a table. 31 | // this makes assumptions for speed: 32 | // - allocated table size is >= N+1 33 | // - index is in [0, 1] 34 | template 35 | static inline T tabLinear(T* buf, float x) { 36 | // FIXME: tidy/speed 37 | const float fi = x * (N - 2); 38 | auto i = static_cast(fi); 39 | const float a = buf[i]; 40 | const float b = buf[i + 1]; 41 | const float c = (fi - static_cast(i)); 42 | return a + c * (b - a); 43 | } 44 | }; 45 | } // namespace softcut 46 | 47 | #endif // Softcut_INTERPOLATE_H 48 | -------------------------------------------------------------------------------- /clients/oooooooo/src/Poll.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by emb on 11/30/18. 3 | // 4 | 5 | #ifndef CRONE_POLL_H 6 | #define CRONE_POLL_H 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | namespace softcut_jack_osc { 19 | class Poll { 20 | public: 21 | typedef std::function Callback; 22 | 23 | explicit Poll(std::string name) { 24 | std::ostringstream os; 25 | os << "/poll/" << name; 26 | path = os.str(); 27 | } 28 | 29 | void setCallback(Callback c) { cb = std::move(c); } 30 | 31 | void start() { 32 | shouldStop = false; 33 | th = std::make_unique(std::thread([this] { 34 | while (!shouldStop) { 35 | this->cb(path.c_str()); 36 | std::this_thread::sleep_for(std::chrono::milliseconds(period)); 37 | } 38 | })); 39 | th->detach(); 40 | } 41 | 42 | void stop() { 43 | // in c++ there's no way to safely and non-cooperatively interrupt a thread. 44 | shouldStop = true; 45 | // i am reasonably sure this won't leak... 46 | th.reset(); 47 | } 48 | 49 | void setPeriod(int ms) { period = ms; } 50 | 51 | private: 52 | Callback cb; 53 | std::atomic period; 54 | std::atomic shouldStop; 55 | std::unique_ptr th; 56 | std::string path; 57 | lo_address addr; 58 | }; 59 | 60 | } // namespace softcut_jack_osc 61 | 62 | #endif // CRONE_POLL_H 63 | -------------------------------------------------------------------------------- /softcut-lib/include/softcut/FadeCurves.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by ezra on 11/15/18. 3 | // 4 | // static class for producing curves in fade period 5 | // 6 | // FIXME: this should be an object owned by SoftcutHead, passed to child 7 | // SubHeads 8 | 9 | #ifndef Softcut_FADECURVES_H 10 | #define Softcut_FADECURVES_H 11 | 12 | namespace softcut { 13 | 14 | class FadeCurves { 15 | public: 16 | typedef enum { Linear = 0, Sine = 1, Raised = 2 } Shape; 17 | 18 | // initialize with defaults 19 | void init(); 20 | void setRecDelayRatio(float x); 21 | void setPreWindowRatio(float x); 22 | void setMinRecDelayFrames(unsigned int x); 23 | void setMinPreWindowFrames(unsigned int x); 24 | // set curve shape 25 | void setPreShape(Shape x); 26 | void setRecShape(Shape x); 27 | // x is assumed to be in [0,1] 28 | float getRecFadeValue(float x); 29 | 30 | float getPreFadeValue(float x); 31 | 32 | private: 33 | void calcPreFade(); 34 | void calcRecFade(); 35 | 36 | private: 37 | // xfade curve buffers 38 | static constexpr unsigned int fadeBufSize = 1001; 39 | 40 | // record delay and pre window in fade, as proportion of fade time 41 | float recDelayRatio; 42 | float preWindowRatio; 43 | // minimum record delay/pre window, in frames 44 | unsigned int recDelayMinFrames; 45 | unsigned int preWindowMinFrames; 46 | float recFadeBuf[fadeBufSize]; 47 | float preFadeBuf[fadeBufSize]; 48 | Shape recShape; 49 | Shape preShape; 50 | }; 51 | } // namespace softcut 52 | 53 | #endif // Softcut_FADECURVES_H 54 | -------------------------------------------------------------------------------- /dsp/utilities/Utilities.cpp: -------------------------------------------------------------------------------- 1 | #include "Utilities.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | float MidiToFreq(float midi) { 10 | return powf(2.0f, (midi - 69.0f) / 12.0f) * 440.0f; 11 | } 12 | 13 | float LinLin(float in, float inMin, float inMax, float outMin, float outMax) { 14 | return (in - inMin) / (inMax - inMin) * (outMax - outMin) + outMin; 15 | } 16 | 17 | float FClamp(float x, float min, float max) { 18 | return std::max(min, std::min(x, max)); 19 | } 20 | 21 | // Format a string similar to sprintf but returning a std::string 22 | std::string FormatString(const char* format, ...) { 23 | // First, determine the required buffer size 24 | va_list args; 25 | va_start(args, format); 26 | // Use vsnprintf with a null buffer and 0 size to calculate required size 27 | int size = vsnprintf(nullptr, 0, format, args) + 1; // +1 for null terminator 28 | va_end(args); 29 | 30 | // Allocate the buffer 31 | char* buffer = new char[size]; 32 | 33 | // Format the string into the buffer 34 | va_start(args, format); 35 | vsnprintf(buffer, size, format, args); 36 | va_end(args); 37 | 38 | // Create a string and clean up 39 | std::string result(buffer); 40 | delete[] buffer; 41 | 42 | return result; 43 | } 44 | 45 | float DBAmp(float db) { return powf(10.0f, db / 20.0f); } 46 | 47 | float AmpDB(float amp) { 48 | if (amp < 0.001) { 49 | return -64.0f; // Avoid log(0) which is undefined 50 | } 51 | return 20.0f * log10f(amp); 52 | } -------------------------------------------------------------------------------- /clients/oooooooo/src/VUMeter.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created on 05/07/2025. 3 | // 4 | 5 | #ifndef CRONE_VUMETER_H 6 | #define CRONE_VUMETER_H 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #include "softcut/Types.h" 14 | 15 | using namespace softcut; 16 | 17 | class VUMeter { 18 | public: 19 | VUMeter(); 20 | 21 | // Initialize with sample rate 22 | void setSampleRate(float sr); 23 | 24 | // Set attack time in seconds 25 | void setAttackTime(float timeInSeconds); 26 | 27 | // Set release/decay time in seconds 28 | void setDecayTime(float timeInSeconds); 29 | 30 | // Process a mono buffer and update the VU level 31 | void process(const sample_t* buffer, size_t numFrames); 32 | 33 | // Get the current VU level in dB (thread-safe) 34 | float getLevel() const; 35 | 36 | // Convert linear amplitude to dB 37 | static float ampToDB(float amp); 38 | 39 | // Convert dB to linear amplitude 40 | static float dBToAmp(float db); 41 | 42 | // Reset the meter 43 | void reset(); 44 | 45 | private: 46 | std::atomic 47 | currentLevelDB; // Current level in dB (atomic for thread safety) 48 | float attackCoeff; // Attack coefficient 49 | float decayCoeff; // Decay/release coefficient 50 | float currentPeak; // Current peak value in linear amplitude 51 | float sampleRate; // Current sample rate 52 | float attackTime; // Attack time in seconds 53 | float decayTime; // Decay time in seconds 54 | 55 | // Recalculate coefficients when times change 56 | void updateCoefficients(); 57 | }; 58 | 59 | #endif // CRONE_VUMETER_H -------------------------------------------------------------------------------- /clients/oooooooo/src/DisplayRing.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #include "DrawFunctions.h" 5 | #include "Parameters.h" 6 | #include "SoftcutClient.h" 7 | #include "Utilities.h" 8 | 9 | using namespace softcut_jack_osc; 10 | 11 | class DisplayRing { 12 | public: 13 | DisplayRing() = default; 14 | ~DisplayRing() = default; 15 | void Init(SoftcutClient *softCutClient, Parameters *p, int i); 16 | void Update(float width_, float height_); 17 | void RegisterClick(float mouseX, float mouseY); 18 | void HandleDrag(float mouseX, float mouseY, float width, float height); 19 | void StopDrag(); 20 | void Render(SDL_Renderer *renderer, PerlinNoise *perlinGenerator, 21 | float *noiseTimeValue, float mainContentFadeAlpha_, 22 | bool isSelected); 23 | bool ClickedRing(); 24 | bool ClickedRadius(); 25 | float GetClickedRadius() { return clicked_radius_angle_normalized_; } 26 | bool IsDragging() const { return dragging_; } 27 | int GetId() const { return id_; } 28 | float GetDistanceToCenter() const { return distance_to_center_; } 29 | 30 | private: 31 | SoftcutClient *softCutClient_ = nullptr; 32 | Parameters *params_ = nullptr; 33 | int id_; 34 | float pos_; 35 | float dur_; 36 | float pregain_; 37 | float start_; 38 | float end_; 39 | float pan_; 40 | float x_; 41 | float y_; 42 | float radius_; 43 | float position_; 44 | float thickness_; 45 | bool clicked_ring_ = false; 46 | float distance_to_center_ = 0; 47 | bool dragging_ = false; 48 | bool clicked_radius_ = false; 49 | float clicked_radius_angle_normalized_ = 0; 50 | float breath_time_ = 0.0f; // Track time for breathing animation 51 | }; -------------------------------------------------------------------------------- /external/faust/architecture/faust/dsp/cpp-dsp-adapter.h: -------------------------------------------------------------------------------- 1 | /************************** BEGIN cpp-dsp-adapter.h ********************** 2 | FAUST Architecture File 3 | Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale 4 | --------------------------------------------------------------------- 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation; either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | 19 | EXCEPTION : As a special exception, you may create a larger work 20 | that contains this FAUST architecture section and distribute 21 | that work under terms of your choice, so long as this FAUST 22 | architecture section is not modified. 23 | ************************************************************************/ 24 | 25 | #ifndef CPP_mydsp_adapter_H 26 | #define CPP_mydsp_adapter_H 27 | 28 | #if defined(SOUNDFILE) 29 | #include "faust/gui/SoundUI.h" 30 | #endif 31 | 32 | class dsp; 33 | 34 | // Factory API 35 | dsp* createmydsp(); 36 | 37 | #endif 38 | /************************** END cpp-dsp-adapter.h **************************/ 39 | -------------------------------------------------------------------------------- /softcut-lib/include/softcut/TestBuffers.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by ezra on 11/16/18. 3 | // 4 | 5 | #ifndef Softcut_TESTBUFFERS_H 6 | #define Softcut_TESTBUFFERS_H 7 | 8 | #include 9 | #include 10 | 11 | namespace softcut { 12 | class TestBuffers { 13 | public: 14 | typedef enum { Read, Write, Fade, State, Pre, Rec, numChannels } Channel; 15 | enum { numFrames = 131072, frameMask = 131071 }; 16 | 17 | float buf[numChannels][numFrames]{}; 18 | unsigned int idx = 0; 19 | 20 | void init() { 21 | for (int ch = 0; ch < numChannels; ++ch) { 22 | for (int fr = 0; fr < numFrames; ++fr) { 23 | buf[ch][fr] = 0.f; 24 | } 25 | } 26 | } 27 | 28 | void update(float readPhase, float writePhase, float fade, float state, 29 | float pre, float rec) { 30 | buf[Read][idx] = readPhase; 31 | buf[Write][idx] = writePhase; 32 | buf[Fade][idx] = fade; 33 | buf[State][idx] = state; 34 | buf[Pre][idx] = pre; 35 | buf[Rec][idx] = rec; 36 | idx = (idx + 1) & frameMask; 37 | } 38 | 39 | // print buffer contents in matlab format 40 | void print() { 41 | using std::endl; 42 | std::ofstream ofs("Softcut_test_buffers.m", std::ofstream::out); 43 | ofs << "function y = Softcut_test_buffers() " << endl; 44 | ofs << " y = [" << endl; 45 | for (int ch = 0; ch < numChannels; ++ch) { 46 | ofs << " [ "; 47 | for (int fr = 0; fr < numFrames; ++fr) { 48 | ofs << buf[ch][fr] << " "; 49 | } 50 | ofs << " ]," << endl << endl; 51 | } 52 | ofs << " ];" << endl; 53 | ofs << "end" << endl; 54 | 55 | ofs.close(); 56 | } 57 | }; 58 | } // namespace softcut 59 | 60 | #endif // Softcut_TESTBUFFERS_H 61 | -------------------------------------------------------------------------------- /clients/oooooooo/src/IntroAnimation.h: -------------------------------------------------------------------------------- 1 | // IntroAnimation.h 2 | #ifndef INTRO_ANIMATION_H 3 | #define INTRO_ANIMATION_H 4 | #pragma once 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | #ifndef M_PI 13 | #define M_PI 3.14159265358979323846 14 | #endif 15 | 16 | class IntroAnimation { 17 | public: 18 | IntroAnimation(); 19 | ~IntroAnimation(); 20 | 21 | void Init(TTF_Font* font); // Changed to accept font 22 | void Update(); 23 | void Render(SDL_Renderer* renderer, int windowWidth, int windowHeight); 24 | 25 | bool isComplete() const { return animationComplete; } 26 | void Start(); 27 | void Stop(); 28 | 29 | private: 30 | struct TrailPoint { 31 | float x, y; 32 | float alpha; 33 | int pixelSize; 34 | }; 35 | 36 | bool animationComplete; 37 | bool animationRunning; 38 | float animationTime; 39 | float animationDuration; 40 | 41 | // Circle animation properties 42 | float circleAngle; 43 | float circleRadius; 44 | float centerX, centerY; 45 | 46 | // Trailing effect 47 | std::vector trail; 48 | int maxTrailLength; 49 | 50 | // Visual parameters 51 | float rotationSpeed; 52 | SDL_Color dotColor; 53 | SDL_Color trailColor; 54 | int dotSize; 55 | 56 | // Font for text display 57 | TTF_Font* font; 58 | 59 | void updateTrail(float currentX, float currentY); 60 | void renderPixelatedDot(SDL_Renderer* renderer, float x, float y, int size, 61 | SDL_Color color, float alpha); 62 | void renderCenterText(SDL_Renderer* renderer, int windowWidth, 63 | int windowHeight, 64 | float globalAlpha); // Updated signature 65 | }; 66 | 67 | #endif -------------------------------------------------------------------------------- /external/faust/architecture/faust/gui/meta.h: -------------------------------------------------------------------------------- 1 | /************************** BEGIN meta.h ******************************* 2 | FAUST Architecture File 3 | Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale 4 | --------------------------------------------------------------------- 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation; either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | 19 | EXCEPTION : As a special exception, you may create a larger work 20 | that contains this FAUST architecture section and distribute 21 | that work under terms of your choice, so long as this FAUST 22 | architecture section is not modified. 23 | ************************************************************************/ 24 | 25 | #ifndef __meta__ 26 | #define __meta__ 27 | 28 | #include "faust/export.h" 29 | 30 | /** 31 | The base class of Meta handler to be used in dsp::metadata(Meta* m) method to retrieve (key, value) metadata. 32 | */ 33 | struct FAUST_API Meta { 34 | virtual ~Meta() {} 35 | virtual void declare(const char* key, const char* value) = 0; 36 | }; 37 | 38 | #endif 39 | /************************** END meta.h **************************/ 40 | -------------------------------------------------------------------------------- /external/faust/architecture/faust/vst/voice.h: -------------------------------------------------------------------------------- 1 | /************************** BEGIN voice.h ************************** 2 | FAUST Architecture File 3 | Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale 4 | --------------------------------------------------------------------- 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation; either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | 19 | EXCEPTION : As a special exception, you may create a larger work 20 | that contains this FAUST architecture section and distribute 21 | that work under terms of your choice, so long as this FAUST 22 | architecture section is not modified. 23 | *********************************************************************/ 24 | 25 | #ifndef __VST_VOICE_H__ 26 | #define __VST_VOICE_H__ 27 | 28 | class Voice : public vstUI { 29 | 30 | public: 31 | Voice(int sample_rate) 32 | : vstUI(), m_dsp() 33 | { 34 | m_dsp.init(sample_rate); 35 | m_dsp.buildUserInterface(this); 36 | } 37 | 38 | mydsp m_dsp; 39 | 40 | }; //end of Voice class 41 | 42 | #endif 43 | /************************** END voice.h **************************/ 44 | -------------------------------------------------------------------------------- /softcut-lib/include/softcut/SoftClip.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by ezra on 11/9/18. 3 | // 4 | 5 | #ifndef Softcut_SOFTCLIP_H 6 | #define Softcut_SOFTCLIP_H 7 | 8 | #include 9 | 10 | #include "softcut/Utilities.h" 11 | 12 | namespace softcut { 13 | 14 | // two-stage quadratic soft clipper with variable gain 15 | // nice odd harmonics, kinda carbon-mic sound 16 | class SoftClip { 17 | private: 18 | float t; // threshold (beginning of knee) 19 | float g; // gain multiplier 20 | float a; // parabolic coefficient 21 | float b; // parabolic offset ( = max level) 22 | // update quad multiplier from current settings 23 | void calcCoeffs() { 24 | // match derivative at knee point 25 | // FIXME: should be able to factor this such that b=1 always, user sets g 26 | // only 27 | float t_1 = t - 1.f; 28 | if (t_1 < 0.f) { 29 | a = g / (2.f * t_1); 30 | b = g * t - (a * t_1 * t_1); 31 | } else { 32 | a = 0.f; 33 | b = 1.f; 34 | } 35 | } 36 | 37 | public: 38 | SoftClip(float t_ = 0.68f, float g_ = 1.2f) : t(t_), g(g_) { calcCoeffs(); } 39 | 40 | float processSample(float x) { 41 | float ax = fabs(x); 42 | const float sx = fsign(x); 43 | 44 | if (ax > 1.f) { 45 | ax = 1.f; 46 | } 47 | 48 | if (ax < t) { 49 | return x * g; 50 | } else { 51 | const float q = ax - 1.f; 52 | const float y = (a * q * q) + b; 53 | return sx * y; 54 | } 55 | } 56 | 57 | void setGain(float r) { 58 | g = r; 59 | calcCoeffs(); 60 | } 61 | 62 | void setLowThresh(float amp) { 63 | t = amp; 64 | calcCoeffs(); 65 | } 66 | 67 | float getGain() { return g; } 68 | 69 | float getLowThresh() { return t; } 70 | 71 | float getHighThreshDb() { return b; } 72 | }; 73 | } // namespace softcut 74 | 75 | #endif // Softcut_SOFTCLIP_H 76 | -------------------------------------------------------------------------------- /softcut-lib/src/Svf.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by ezra on 11/8/18. 3 | // 4 | 5 | #include "softcut/Svf.h" 6 | 7 | #include 8 | 9 | const float Svf::MAX_NORM_FC = 0.4; 10 | 11 | Svf::Svf() = default; 12 | 13 | float Svf::getNextSample(float x) { 14 | update(x); 15 | return lp * lpMix + hp * hpMix + bp * bpMix + br * brMix; 16 | } 17 | 18 | void Svf::setSampleRate(float aSr) { 19 | sr = aSr; 20 | pi_sr = M_PI / sr; 21 | minFc = 10.f; 22 | maxFc = sr * MAX_NORM_FC; 23 | calcWarp(); 24 | calcCoeffs(); 25 | } 26 | 27 | void Svf::setFc(float aFc) { 28 | fc = (aFc > maxFc) ? maxFc : aFc; 29 | fc = (fc < minFc) ? minFc : fc; 30 | calcWarp(); 31 | calcCoeffs(); 32 | } 33 | 34 | void Svf::setRq(float aRq) { 35 | rq = aRq; 36 | calcCoeffs(); 37 | } 38 | 39 | void Svf::setLpMix(float mix) { lpMix = mix; } 40 | 41 | void Svf::setHpMix(float mix) { hpMix = mix; } 42 | 43 | void Svf::setBpMix(float mix) { bpMix = mix; } 44 | 45 | void Svf::setBrMix(float mix) { brMix = mix; } 46 | 47 | void Svf::reset() { clearState(); } 48 | 49 | void Svf::calcWarp() { 50 | // NB: wasn't actually able to beat `tan` for performance+accuracy sweet spot 51 | // on raspi with aggressive optimizations 52 | g = static_cast(tan(fc * pi_sr)); 53 | } 54 | 55 | void Svf::calcCoeffs() { 56 | g1 = g / (1.f + g * (g + rq)); 57 | g2 = 2.f * (g + rq) * g1; 58 | g3 = g * g1; 59 | g4 = 2.f * g1; 60 | } 61 | 62 | void Svf::clearState() { 63 | v0z = 0; 64 | v1 = 0; 65 | v2 = 0; 66 | } 67 | 68 | void Svf::update(float in) { 69 | // update 70 | v0 = in; 71 | v1z = v1; 72 | v2z = v2; 73 | v3 = v0 + v0z - 2.f * v2z; 74 | v1 += g1 * v3 - g2 * v1z; 75 | v2 += g3 * v3 + g4 * v1z; 76 | v0z = v0; 77 | // output 78 | lp = v2; 79 | bp = v1; 80 | hp = v0 - rq * v1 - v2; 81 | br = v0 - rq * v1; 82 | } 83 | 84 | float Svf::getFc() { return fc; } -------------------------------------------------------------------------------- /external/faust/architecture/faust/gui/JSONControl.h: -------------------------------------------------------------------------------- 1 | /************************** BEGIN JSONControl.h ************************** 2 | FAUST Architecture File 3 | Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale 4 | --------------------------------------------------------------------- 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation; either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | 19 | EXCEPTION : As a special exception, you may create a larger work 20 | that contains this FAUST architecture section and distribute 21 | that work under terms of your choice, so long as this FAUST 22 | architecture section is not modified. 23 | *************************************************************************/ 24 | 25 | #ifndef __JSON_CONTROL__ 26 | #define __JSON_CONTROL__ 27 | 28 | #include 29 | 30 | #ifndef FAUSTFLOAT 31 | #define FAUSTFLOAT float 32 | #endif 33 | 34 | struct FAUST_API JSONControl { 35 | 36 | virtual std::string getJSON() { return ""; } 37 | 38 | virtual void setParamValue(const std::string& path, FAUSTFLOAT value) {} 39 | 40 | virtual FAUSTFLOAT getParamValue(const std::string& path) { return 0; } 41 | 42 | virtual ~JSONControl() 43 | {} 44 | 45 | }; 46 | 47 | #endif 48 | /************************** END JSONControl.h **************************/ 49 | -------------------------------------------------------------------------------- /dsp/tapefx/TapeFX.cpp: -------------------------------------------------------------------------------- 1 | #include "TapeFX.h" 2 | 3 | #include 4 | 5 | TapeFX::TapeFX() {} 6 | 7 | namespace { 8 | inline float db2amp_(float db) { return powf(10.0f, db / 20.0f); } 9 | 10 | inline float amp2db_(float amp) { return 20.0f * log10(amp); } 11 | } // namespace 12 | 13 | void TapeFX::Init(float sample_rate) { 14 | follower = Follower(sample_rate); 15 | dc_input_l_ = 0; 16 | dc_output_l_ = 0; 17 | dc_input_r_ = 0; 18 | dc_output_r_ = 0; 19 | dc_gain_ = 0.99; 20 | bias_ = 0.0f; 21 | pregain_ = 1.0f; 22 | follow_ = 0; 23 | } 24 | 25 | void TapeFX::SetBias(float bias) { bias_ = bias; } 26 | 27 | void TapeFX::SetPregain(float pregain) { pregain_ = pregain; } 28 | 29 | void TapeFX::ProcessMono(sample_t *out, unsigned int numFrames) { 30 | for (size_t i = 0; i < numFrames; i++) { 31 | // pregain 32 | out[i] *= pregain_; 33 | follow_ = follower.process(out[i]); 34 | // dc bias with follower 35 | out[i] = tanhf(out[i] + (follow_ * bias_)); 36 | // DC blocking 37 | sample_t in = out[i]; 38 | out[i] = in - dc_input_l_ + (dc_gain_ * dc_output_l_); 39 | dc_output_l_ = out[i]; 40 | dc_input_l_ = in; 41 | // extra tanh 42 | out[i] = tanhf(out[i]); 43 | } 44 | } 45 | 46 | void TapeFX::Process(sample_t **out, unsigned int numFrames) { 47 | for (size_t i = 0; i < numFrames; i++) { 48 | // pregain 49 | out[0][i] *= pregain_; 50 | out[1][i] *= pregain_; 51 | 52 | follow_ = follower.process(out[0][i]); 53 | 54 | // dc bias with follower 55 | out[0][i] = tanhf(out[0][i] + (follow_ * bias_)); 56 | out[1][i] = tanhf(out[1][i] + (follow_ * bias_)); 57 | 58 | // DC blocking 59 | sample_t in = out[0][i]; 60 | out[0][i] = in - dc_input_l_ + (dc_gain_ * dc_output_l_); 61 | dc_output_l_ = out[0][i]; 62 | dc_input_l_ = in; 63 | in = out[1][i]; 64 | out[1][i] = in - dc_input_r_ + (dc_gain_ * dc_output_r_); 65 | dc_output_r_ = out[1][i]; 66 | dc_input_r_ = in; 67 | 68 | // extra tanh 69 | out[0][i] = tanhf(out[0][i]); 70 | out[1][i] = tanhf(out[1][i]); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /tests/test1.scd: -------------------------------------------------------------------------------- 1 | s.waitForBoot({ 2 | Routine { 3 | "running tests".postln; 4 | n = NetAddr("localhost", 9999); 5 | 6 | // Load audio file 7 | "load file".postln; 8 | n.sendMsg("/softcut/buffer/clear"); 9 | n.sendMsg("/softcut/buffer/read_mono", "/home/zns/Documents/oooooooo/amen_beats8_bpm172.wav", 0, 0, -1, 0, 0); 10 | n.sendMsg("/softcut/buffer/read_mono", "/home/zns/Documents/oooooooo/strega.wav", 0, 30, -1, 0, 0); 11 | 1.wait; 12 | 13 | // Configure and enable voice 0 14 | 2.do({ 15 | arg i; 16 | n.sendMsg("/set/enabled/cut", i, 1); 17 | n.sendMsg("/set/level/cut", i, 1.0 + (1.0 * i)); 18 | n.sendMsg("/set/param/cut/rate", i, 41000/48000); 19 | n.sendMsg("/set/pan/cut", i, 0); 20 | n.sendMsg("/set/param/cut/buffer", i, 0); 21 | n.sendMsg("/set/param/cut/loop_start", i, 30*i); 22 | n.sendMsg("/set/param/cut/loop_end", i, 60/172*4.0+(30*i)); 23 | n.sendMsg("/set/param/cut/loop_flag", i, 1); 24 | n.sendMsg("/set/param/cut/fade_time", i, 60/172); 25 | n.sendMsg("/set/param/cut/post_filter_dry", i, 1); 26 | n.sendMsg("/set/param/cut/play_flag", i, 1); 27 | n.sendMsg("/set/param/cut/position", i, 0); 28 | 29 | }); 30 | 31 | "play_flag".postln; 32 | 33 | // Reverb test settings 34 | 3.wait; 35 | "reverb on".postln; 36 | n.sendMsg("/set/reverb/enabled", 1.0); 37 | n.sendMsg("/set/reverb/mix", 1.0); 38 | n.sendMsg("/set/reverb/send", 1, 1.0); 39 | 3.wait; 40 | "reverb off".postln; 41 | n.sendMsg("/set/reverb/send", 1, 0.0); 42 | 3.wait; 43 | "tapefx on".postln; 44 | n.sendMsg("/set/param/cut/tape_pregain", 0, 8.0); 45 | n.sendMsg("/set/param/cut/tape_bias", 0, 1.0); 46 | 47 | // n.sendMsg("/set/reverb/param/decay", 2.0); 48 | // n.sendMsg("/set/reverb/param/tail_density", 0.75); 49 | // n.sendMsg("/set/reverb/param/input_diffusion1", 0.3); 50 | // n.sendMsg("/set/reverb/param/input_diffusion2", 0.4); 51 | }.play; 52 | }); 53 | -------------------------------------------------------------------------------- /softcut-lib/include/softcut/SubHead.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by ezra on 4/21/18. 3 | // 4 | 5 | /* 6 | * this class implements one half of a crossfaded read/write sch. 7 | */ 8 | 9 | #ifndef Softcut_SUBHEAD_H 10 | #define Softcut_SUBHEAD_H 11 | 12 | #include "FadeCurves.h" 13 | #include "Resampler.h" 14 | #include "SoftClip.h" 15 | #include "Types.h" 16 | 17 | namespace softcut { 18 | 19 | typedef enum { Playing = 0, Stopped = 1, FadeIn = 2, FadeOut = 3 } State; 20 | typedef enum { None, Stop, LoopPos, LoopNeg } Action; 21 | 22 | class SubHead { 23 | friend class ReadWriteHead; 24 | 25 | public: 26 | void init(FadeCurves *fc); 27 | void setSampleRate(float sr); 28 | 29 | private: 30 | sample_t peek4(); 31 | unsigned int wrapBufIndex(int x); 32 | 33 | protected: 34 | static constexpr int blockSize = 2048; 35 | sample_t peek(); 36 | //! poke 37 | //! @param in: input value 38 | //! @param pre: scaling level for previous buffer content 39 | //! @param rec: scaling level for new content 40 | void poke(sample_t in, float pre, float rec); 41 | Action updatePhase(phase_t start, phase_t end, bool loop); 42 | void updateFade(float inc); 43 | 44 | // getters 45 | phase_t phase() { return phase_; } 46 | float fade() { return fade_; } 47 | float trig() { return trig_; } 48 | State state() { return state_; } 49 | 50 | // setters 51 | void setState(State state); 52 | void setPhase(phase_t phase); 53 | 54 | // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 55 | // **NB** buffer size must be a power of two!!!! 56 | void setBuffer(sample_t *buf, unsigned int frames); 57 | void setRate(rate_t rate); 58 | FadeCurves *fadeCurves; 59 | 60 | private: 61 | Resampler resamp_; 62 | SoftClip clip_; 63 | 64 | sample_t *buf_; // output buffer 65 | unsigned int wrIdx_; // write index 66 | unsigned int bufFrames_; 67 | unsigned int bufMask_; 68 | 69 | State state_; 70 | rate_t rate_; 71 | int inc_dir_; 72 | phase_t phase_; 73 | float fade_; 74 | float trig_; // output trigger value 75 | bool active_; 76 | int recOffset_; 77 | 78 | float preFade_; 79 | float recFade_; 80 | 81 | void setRecOffsetSamples(int d); 82 | }; 83 | 84 | } // namespace softcut 85 | 86 | #endif // Softcut_SUBHEAD_H 87 | -------------------------------------------------------------------------------- /clients/oooooooo/src/OscInterface.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // 4 | // Created by ezra on 11/4/18. 5 | // 6 | 7 | #ifndef CRONE_OSCINTERFACE_H 8 | #define CRONE_OSCINTERFACE_H 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | #include "SoftcutClient.h" 18 | #include "Poll.h" 19 | 20 | // FIXME: didn't realize that liblo has a perfectly ok-looking cpp interface already. this could be cleaner. 21 | // having a custom method wrapper is probably fine, easier to refactor if we move to different IPC. 22 | 23 | namespace softcut_jack_osc { 24 | using std::string; 25 | 26 | class OscInterface { 27 | 28 | private: 29 | static lo_server_thread st; 30 | static lo_address clientAddress; 31 | 32 | static bool quitFlag; 33 | static string port; 34 | static unsigned int numMethods; 35 | enum { MaxNumMethods = 256 }; 36 | 37 | // OscMethod: thin wrapper for passing lambdas to OSC server thread 38 | class OscMethod { 39 | typedef void(*Handler)(lo_arg **argv, int argc); 40 | public: 41 | string path; 42 | string format; 43 | OscMethod() = default; 44 | OscMethod(string p, string f, Handler h); 45 | Handler handler{}; 46 | }; 47 | 48 | static std::array methods; 49 | static std::unique_ptr vuPoll; 50 | static std::unique_ptr phasePoll; 51 | static SoftcutClient *softCutClient; 52 | 53 | private: 54 | typedef void(*Handler)(lo_arg **argv, int argc); 55 | static void handleLoError(int num, const char *m, const char *path) { 56 | std::cerr << "liblo error: " << num << "; " << m << "; " << path << std::endl; 57 | } 58 | 59 | static void addServerMethod(const char* path, const char* format, Handler handler); 60 | 61 | static void addServerMethods(); 62 | 63 | 64 | public: 65 | static void init(SoftcutClient *sc); 66 | static void deinit(); 67 | static void printServerMethods(); 68 | 69 | static bool shouldQuit() { return quitFlag; } 70 | static std::string getPortNumber() { return port; } 71 | }; 72 | } 73 | 74 | #endif //CRONE_OSCINTERFACE_H 75 | -------------------------------------------------------------------------------- /clients/oooooooo/src/LFO.cpp: -------------------------------------------------------------------------------- 1 | #include "LFO.h" 2 | 3 | #include 4 | 5 | static inline float Polyblep(float phase_inc, float t); 6 | 7 | float LFO::Process() { 8 | float out, t; 9 | switch (waveform_) { 10 | case WAVE_SIN: 11 | out = sinf(phase_ * 3.1415927410125732421875f * 2.0f); 12 | break; 13 | case WAVE_TRI: 14 | t = -1.0f + (2.0f * phase_); 15 | out = 2.0f * (fabsf(t) - 0.5f); 16 | break; 17 | case WAVE_SAW: 18 | out = -1.0f * (((phase_ * 2.0f)) - 1.0f); 19 | break; 20 | case WAVE_RAMP: 21 | out = ((phase_ * 2.0f)) - 1.0f; 22 | break; 23 | case WAVE_SQUARE: 24 | out = phase_ < pw_ ? (1.0f) : -1.0f; 25 | break; 26 | case WAVE_POLYBLEP_TRI: 27 | t = phase_; 28 | out = phase_ < 0.5f ? 1.0f : -1.0f; 29 | out += Polyblep(phase_inc_, t); 30 | out -= Polyblep(phase_inc_, (t + 0.5f) - static_cast((t + 0.5f))); 31 | // Leaky Integrator: 32 | // y[n] = A + x[n] + (1 - A) * y[n-1] 33 | out = phase_inc_ * out + (1.0f - phase_inc_) * last_out_; 34 | last_out_ = out; 35 | out *= 4.f; // normalize amplitude after leaky integration 36 | break; 37 | case WAVE_POLYBLEP_SAW: 38 | t = phase_; 39 | out = (2.0f * t) - 1.0f; 40 | out -= Polyblep(phase_inc_, t); 41 | out *= -1.0f; 42 | break; 43 | case WAVE_POLYBLEP_SQUARE: 44 | t = phase_; 45 | out = phase_ < pw_ ? 1.0f : -1.0f; 46 | out += Polyblep(phase_inc_, t); 47 | out -= Polyblep(phase_inc_, (t + (1.0f - pw_)) - 48 | static_cast((t + (1.0f - pw_)))); 49 | out *= 0.707f; // ? 50 | break; 51 | default: 52 | out = 0.0f; 53 | break; 54 | } 55 | phase_ += phase_inc_; 56 | if (phase_ > 1.0f) { 57 | phase_ -= 1.0f; 58 | eoc_ = true; 59 | } else { 60 | eoc_ = false; 61 | } 62 | eor_ = (phase_ - phase_inc_ < 0.5f && phase_ >= 0.5f); 63 | 64 | out_ = out * amp_ + add_; 65 | return out_; 66 | } 67 | 68 | float LFO::CalcPhaseInc(float f) { return f * sr_recip_; } 69 | 70 | static float Polyblep(float phase_inc, float t) { 71 | float dt = phase_inc; 72 | if (t < dt) { 73 | t /= dt; 74 | return t + t - t * t - 1.0f; 75 | } else if (t > 1.0f - dt) { 76 | t = (t - 1.0f) / dt; 77 | return t * t + t + t + 1.0f; 78 | } else { 79 | return 0.0f; 80 | } 81 | } -------------------------------------------------------------------------------- /clients/oooooooo/src/Display.h: -------------------------------------------------------------------------------- 1 | #ifndef DISPLAY_H 2 | #define DISPLAY_H 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "DisplayMessage.h" 14 | #include "DisplayRing.h" 15 | #include "DrawFunctions.h" 16 | #include "HelpSystem.h" 17 | #include "IntroAnimation.h" 18 | #include "KeyboardHandler.h" 19 | #include "Parameters.h" 20 | #include "Perlin.h" 21 | #include "SoftcutClient.h" 22 | 23 | using namespace softcut_jack_osc; 24 | 25 | class Display { 26 | public: 27 | void requestShutdown() { running_ = false; } 28 | // Define a callback type for quit notification 29 | using QuitCallback = std::function; 30 | 31 | Display(int width = 1200, int height = 900); 32 | ~Display(); 33 | 34 | void init(SoftcutClient* sc, int numVoices); 35 | 36 | void start(); 37 | void stop(); 38 | bool isRunning() const { return running_; } 39 | void SetMessage(const std::string& message, int secondsToDisplay); 40 | 41 | // Set the callback to be called when window is closed 42 | void setQuitCallback(QuitCallback callback) { quitCallback_ = callback; } 43 | 44 | private: 45 | void renderLoop(); 46 | 47 | // Window properties 48 | int width_; 49 | int height_; 50 | 51 | // SDL components 52 | SDL_Window* window_; 53 | SDL_Renderer* renderer_; 54 | 55 | // State 56 | std::atomic running_; 57 | 58 | // Thread 59 | std::unique_ptr displayThread_; 60 | 61 | // Quit callback 62 | QuitCallback quitCallback_; 63 | 64 | // SofcutClient 65 | int numVoices_; 66 | SoftcutClient* softCutClient_ = nullptr; 67 | DisplayRing* displayRings_; 68 | 69 | // Keyboard 70 | KeyboardHandler keyboardHandler_; 71 | 72 | // Display 73 | TTF_Font* font = nullptr; 74 | PerlinNoise perlinGenerator; 75 | float noiseTimeValue = 0.0f; 76 | int selected_loop = 0; 77 | bool mouse_dragging = false; 78 | bool dragging_bar = false; 79 | int dragged_parameter = -1; 80 | 81 | // Parameters 82 | Parameters* params_ = nullptr; 83 | int param_count_ = Parameters::PARAM_COUNT; 84 | 85 | // Help System 86 | HelpSystem helpSystem_; 87 | 88 | // Intro Animation 89 | IntroAnimation introAnimation_; 90 | float mainContentFadeAlpha_; 91 | 92 | // Display Message 93 | DisplayMessage displayMessage_; 94 | }; 95 | 96 | #endif // DISPLAY_H -------------------------------------------------------------------------------- /external/faust/architecture/faust/export.h: -------------------------------------------------------------------------------- 1 | /************************************************************************ 2 | FAUST Architecture File 3 | Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale 4 | --------------------------------------------------------------------- 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation; either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | 19 | EXCEPTION : As a special exception, you may create a larger work 20 | that contains this FAUST architecture section and distribute 21 | that work under terms of your choice, so long as this FAUST 22 | architecture section is not modified. 23 | ***************************************************************************/ 24 | 25 | #ifndef __export__ 26 | #define __export__ 27 | 28 | // Version as a global string 29 | #define FAUSTVERSION "2.79.3" 30 | 31 | // Version as separated [major,minor,patch] values 32 | #define FAUSTMAJORVERSION 2 33 | #define FAUSTMINORVERSION 79 34 | #define FAUSTPATCHVERSION 3 35 | 36 | // Use FAUST_API for code that is part of the external API but is also compiled in faust and libfaust 37 | // Use LIBFAUST_API for code that is compiled in faust and libfaust 38 | 39 | #ifdef _WIN32 40 | #pragma warning (disable: 4251) 41 | #ifdef FAUST_EXE 42 | #define FAUST_API 43 | #define LIBFAUST_API 44 | #elif FAUST_LIB 45 | #define FAUST_API __declspec(dllexport) 46 | #define LIBFAUST_API __declspec(dllexport) 47 | #else 48 | #define FAUST_API 49 | #define LIBFAUST_API 50 | #endif 51 | #else 52 | #ifdef FAUST_EXE 53 | #define FAUST_API 54 | #define LIBFAUST_API 55 | #else 56 | #define FAUST_API __attribute__((visibility("default"))) 57 | #define LIBFAUST_API __attribute__((visibility("default"))) 58 | #endif 59 | #endif 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /clients/oooooooo/src/Perlin.h: -------------------------------------------------------------------------------- 1 | #ifndef PERLIN_H 2 | #define PERLIN_H 3 | #pragma once 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | // Perlin noise implementation 10 | class PerlinNoise { 11 | private: 12 | std::vector p; 13 | 14 | public: 15 | PerlinNoise() { 16 | // Initialize the permutation vector with values 0-255 17 | p.resize(256); 18 | std::iota(p.begin(), p.end(), 0); 19 | 20 | // Randomize the permutation vector using a seed 21 | std::random_device rd; 22 | std::mt19937 engine(rd()); 23 | std::shuffle(p.begin(), p.end(), engine); 24 | 25 | // Duplicate the permutation vector 26 | p.insert(p.end(), p.begin(), p.end()); 27 | } 28 | 29 | // Fade function as defined by Ken Perlin 30 | double fade(double t) const { return t * t * t * (t * (t * 6 - 15) + 10); } 31 | 32 | // Linear interpolation 33 | double lerp(double t, double a, double b) const { return a + t * (b - a); } 34 | 35 | // Gradient function 36 | double grad(int hash, double x, double y, double z) const { 37 | // Convert low 4 bits of hash into 12 gradient directions 38 | int h = hash & 15; 39 | double u = h < 8 ? x : y, v = h < 4 ? y : h == 12 || h == 14 ? x : z; 40 | return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v); 41 | } 42 | 43 | // Return a noise value in the range [-1, 1] 44 | double noise(double x, double y, double z = 0) const { 45 | // Find the unit cube that contains the point 46 | int X = static_cast(std::floor(x)) & 255; 47 | int Y = static_cast(std::floor(y)) & 255; 48 | int Z = static_cast(std::floor(z)) & 255; 49 | 50 | // Find relative x, y, z of point in cube 51 | x -= std::floor(x); 52 | y -= std::floor(y); 53 | z -= std::floor(z); 54 | 55 | // Compute fade curves for each of x, y, z 56 | double u = fade(x); 57 | double v = fade(y); 58 | double w = fade(z); 59 | 60 | // Hash coordinates of the 8 cube corners 61 | int A = p[X] + Y; 62 | int AA = p[A] + Z; 63 | int AB = p[A + 1] + Z; 64 | int B = p[X + 1] + Y; 65 | int BA = p[B] + Z; 66 | int BB = p[B + 1] + Z; 67 | 68 | // And add blended results from 8 corners of cube 69 | return lerp( 70 | w, 71 | lerp(v, lerp(u, grad(p[AA], x, y, z), grad(p[BA], x - 1, y, z)), 72 | lerp(u, grad(p[AB], x, y - 1, z), grad(p[BB], x - 1, y - 1, z))), 73 | lerp(v, 74 | lerp(u, grad(p[AA + 1], x, y, z - 1), 75 | grad(p[BA + 1], x - 1, y, z - 1)), 76 | lerp(u, grad(p[AB + 1], x, y - 1, z - 1), 77 | grad(p[BB + 1], x - 1, y - 1, z - 1)))); 78 | } 79 | }; 80 | 81 | #endif // PERLIN_H -------------------------------------------------------------------------------- /dsp/fverb/FVerb.cpp: -------------------------------------------------------------------------------- 1 | // src/effects/FVerb.cpp 2 | #include "FVerb.h" 3 | 4 | #include 5 | 6 | #include "../utilities/Utilities.h" // for FClamp 7 | #include "FVerbDSP.h" // Include the Faust-generated header 8 | #include "faust/gui/MapUI.h" // Include MapUI for parameter control 9 | 10 | void FVerb::Init(float sample_rate) { 11 | // Initialize the DSP with the sample rate 12 | dsp = new FVerbDSP(); 13 | 14 | // Initialize the DSP parameters 15 | dsp->init(sample_rate); 16 | dsp->SetParamValue(FVerbDSP::PREDELAY, 150); 17 | SetDecay(82); 18 | SetTailDensity(80); 19 | SetInputDiffision1(70); 20 | SetInputDiffision2(75); 21 | } 22 | 23 | void FVerb::SetDecay(float decay) { 24 | // Set the decay parameter in the DSP 25 | dsp->SetParamValue(FVerbDSP::DECAY, FClamp(decay, 0.0f, 100.0f)); 26 | } 27 | 28 | void FVerb::SetTailDensity(float x) { 29 | // Set the decay parameter in the DSP 30 | dsp->SetParamValue(FVerbDSP::TAIL_DENSITY, FClamp(x, 0.0f, 100.0f)); 31 | } 32 | 33 | void FVerb::SetInputDiffision1(float x) { 34 | // Set the decay parameter in the DSP 35 | dsp->SetParamValue(FVerbDSP::INPUT_DIFFUSION_1, FClamp(x, 0.0f, 100.0f)); 36 | } 37 | 38 | void FVerb::SetInputDiffision2(float x) { 39 | // Set the decay parameter in the DSP 40 | dsp->SetParamValue(FVerbDSP::INPUT_DIFFUSION_2, FClamp(x, 0.0f, 100.0f)); 41 | } 42 | 43 | FVerb::~FVerb() { 44 | // Properly clean up all memory 45 | if (dsp) { 46 | delete dsp; 47 | } 48 | 49 | if (inputs) { 50 | for (int i = 0; i < 2; i++) { 51 | if (inputs[i]) delete[] inputs[i]; 52 | } 53 | delete[] inputs; 54 | } 55 | 56 | if (outputs) { 57 | for (int i = 0; i < 2; i++) { 58 | if (outputs[i]) delete[] outputs[i]; 59 | } 60 | delete[] outputs; 61 | } 62 | } 63 | 64 | void FVerb::Process(float** out, int numSamples) { 65 | if (inputs == nullptr || outputs == nullptr) { 66 | // Allocate input/output buffers 67 | inputs = new float*[2]; // 2 channels 68 | outputs = new float*[2]; // 2 channels 69 | 70 | for (int i = 0; i < 2; i++) { 71 | inputs[i] = new float[numSamples]; 72 | outputs[i] = new float[numSamples]; 73 | } 74 | } 75 | 76 | // Copy input from out to inputs 77 | for (int i = 0; i < 2; i++) { 78 | for (int j = 0; j < numSamples; j++) { 79 | inputs[i][j] = out[i][j]; 80 | } 81 | } 82 | 83 | // Process through Faust DSP using its compute method 84 | dsp->compute(numSamples, inputs, outputs); 85 | 86 | // Copy outputs back to out (if needed) 87 | for (int i = 0; i < 2; i++) { 88 | for (int j = 0; j < numSamples; j++) { 89 | out[i][j] = outputs[i][j]; 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /external/faust/architecture/faust/gui/Styles/Default.qss: -------------------------------------------------------------------------------- 1 | QPushButton{ 2 | min-width : 80px; 3 | border: 2px solid grey; 4 | border-radius: 6px; 5 | margin-top: 1ex; 6 | border-color: #811453; 7 | background-color: transparent; 8 | } 9 | 10 | QPushButton:hover{ 11 | border: 2px; 12 | border-radius: 6px; 13 | border-color: #811453; 14 | background-color: #6A455D; 15 | } 16 | 17 | QPushButton:pressed{ 18 | background-color: #6A455D; 19 | border-radius: 6px; 20 | border-color: #811453; 21 | } 22 | 23 | QGroupBox{ 24 | subcontrol: .QGroupBox; 25 | margin-top: 3ex; 26 | font-size: 10pt; 27 | font-weight: bold; 28 | color: black; 29 | } 30 | 31 | QGroupBox::title { 32 | subcontrol-origin: margin; 33 | subcontrol-position: top center; 34 | padding: 0 5px; 35 | color: black; 36 | } 37 | 38 | QMainWindow { 39 | margin-top: 3ex; 40 | font-size:10pt; 41 | font-weight:bold; 42 | color: black; 43 | } 44 | 45 | QPlainTextEdit, QTextEdit{ 46 | background-color: transparent; 47 | border: 2px solid gray; 48 | border-radius: 5px; 49 | top: 3px; 50 | margin-top: 3ex; 51 | font-size:12pt; 52 | font-weight:bold; 53 | color: black; 54 | } 55 | 56 | QTextBrowser { 57 | color: black; 58 | } 59 | QTextBrowser:document{ 60 | text-decoration: underline; 61 | color: black; 62 | font: Menlo; 63 | font-size: 14px 64 | } 65 | 66 | QLabel{ 67 | color : black; 68 | background: transparent; 69 | } 70 | 71 | QSlider::groove:vertical { 72 | background: red; 73 | position: absolute; 74 | left: 13px; right: 13px; 75 | } 76 | 77 | QSlider::handle:vertical { 78 | height: 40px; 79 | width: 30px; 80 | background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #E67E30, stop : 0.05 #AD4F09, stop: 0.3 #E67E30, stop : 0.90 #AD4F09, stop: 0.91 #AD4F09); 81 | margin: 0 -5px; 82 | border-radius: 5px; 83 | } 84 | 85 | QSlider::add-page:vertical { 86 | background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, 87 | stop: 0 #6A455D, stop : 0.5 #6A455D); 88 | } 89 | 90 | QSlider::sub-page:vertical { 91 | background: grey; 92 | } 93 | 94 | QSlider::groove:horizontal { 95 | background: red; 96 | position: absolute; 97 | top: 14px; bottom: 14px; 98 | } 99 | 100 | QSlider::handle:horizontal { 101 | width: 40px; 102 | background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #E67E30, stop : 0.05 #AD4F09, stop: 0.3 #E67E30, stop : 0.90 #AD4F09, stop: 0.91 #AD4F09); 103 | margin: -5px 0; 104 | border-radius: 5px; 105 | } 106 | 107 | QSlider::sub-page:horizontal { 108 | background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #6A455D, stop : 0.5 #6A455D); 109 | } 110 | 111 | QSlider::add-page:horizontal { 112 | background: grey; 113 | } 114 | 115 | QListWidget{ 116 | background-color: transparent; 117 | } -------------------------------------------------------------------------------- /clients/oooooooo/src/VUMeter.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created on 05/07/2025. 3 | // 4 | 5 | #include "VUMeter.h" 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | VUMeter::VUMeter() 12 | : currentLevelDB(-100.0f) // Start at a very low level (effectively silent) 13 | , 14 | attackCoeff(0.0f), 15 | decayCoeff(0.0f), 16 | currentPeak(0.0f), 17 | sampleRate(48000.0f) // Default to common sample rate 18 | , 19 | attackTime(0.01f) // 10ms attack (fast) 20 | , 21 | decayTime(0.3f) // 300ms decay (slow) 22 | { 23 | updateCoefficients(); 24 | } 25 | 26 | void VUMeter::setSampleRate(float sr) { 27 | sampleRate = sr; 28 | updateCoefficients(); 29 | } 30 | 31 | void VUMeter::setAttackTime(float timeInSeconds) { 32 | attackTime = timeInSeconds; 33 | updateCoefficients(); 34 | } 35 | 36 | void VUMeter::setDecayTime(float timeInSeconds) { 37 | decayTime = timeInSeconds; 38 | updateCoefficients(); 39 | } 40 | 41 | void VUMeter::updateCoefficients() { 42 | // Calculate time constants as coefficients 43 | // Formula: coeff = exp(-1.0 / (time * sampleRate)) 44 | attackCoeff = std::exp(-1.0f / (attackTime * sampleRate)); 45 | decayCoeff = std::exp(-1.0f / (decayTime * sampleRate)); 46 | } 47 | 48 | float VUMeter::ampToDB(float amp) { 49 | // Avoid log of zero or negative values 50 | const float minAmp = 1.0e-6f; // -120dB 51 | if (amp < minAmp) { 52 | return -100.0f; // Return a very low dB value for near-silence 53 | } 54 | 55 | // Convert amplitude to dB, reference is 1.0 56 | return 20.0f * std::log10(amp); 57 | } 58 | 59 | float VUMeter::dBToAmp(float db) { return std::pow(10.0f, db / 20.0f); } 60 | 61 | void VUMeter::process(const sample_t* buffer, size_t numFrames) { 62 | if (numFrames == 0) return; 63 | 64 | // Find peak in this buffer 65 | float bufferPeak = 0.0f; 66 | for (size_t i = 0; i < numFrames; ++i) { 67 | float absValue = std::fabs(static_cast(buffer[i])); 68 | bufferPeak = std::max(bufferPeak, absValue); 69 | } 70 | 71 | // Apply envelope follower (fast attack, slow decay) 72 | if (bufferPeak > currentPeak) { 73 | // Attack phase - quick response to peaks 74 | currentPeak = attackCoeff * currentPeak + (1.0f - attackCoeff) * bufferPeak; 75 | } else { 76 | // Decay/release phase - slow fall-off 77 | currentPeak = decayCoeff * currentPeak + (1.0f - decayCoeff) * bufferPeak; 78 | } 79 | 80 | // Convert to dB and update the atomic value for thread-safe access 81 | currentLevelDB.store(ampToDB(currentPeak)); 82 | } 83 | 84 | float VUMeter::getLevel() const { return currentLevelDB.load(); } 85 | 86 | void VUMeter::reset() { 87 | currentPeak = 0.0f; 88 | currentLevelDB.store(-100.0f); 89 | } 90 | -------------------------------------------------------------------------------- /external/faust/architecture/faust/dsp/faust-engine.h: -------------------------------------------------------------------------------- 1 | /************************** BEGIN faust-engine.h *********************** 2 | FAUST Architecture File 3 | Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale 4 | --------------------------------------------------------------------- 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation; either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | 19 | EXCEPTION : As a special exception, you may create a larger work 20 | that contains this FAUST architecture section and distribute 21 | that work under terms of your choice, so long as this FAUST 22 | architecture section is not modified. 23 | ************************************************************************/ 24 | 25 | #ifndef __faust_engine__ 26 | #define __faust_engine__ 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | void* create(int, int); // To be implemented 33 | void destroy(void*); 34 | 35 | bool start(void*); 36 | void stop(void*); 37 | 38 | bool isRunning(void*); 39 | 40 | uintptr_t keyOn(void*, int, int); 41 | int keyOff(void*, int); 42 | 43 | void propagateMidi(void*, int, double, int, int, int, int); 44 | 45 | const char* getJSONUI(void*); 46 | const char* getJSONMeta(void*); 47 | 48 | int getParamsCount(void*); 49 | 50 | void setParamValue(void*, const char*, float); 51 | float getParamValue(void*, const char*); 52 | 53 | void setParamIdValue(void*, int, float); 54 | float getParamIdValue(void*, int); 55 | 56 | void setVoiceParamValue(void*, const char*, uintptr_t, float); 57 | float getVoiceParamValue(void*, const char*, uintptr_t); 58 | 59 | const char* getParamAddress(void*, int); 60 | 61 | void propagateAcc(void*, int, float); 62 | void setAccConverter(void*, int, int, int, float, float, float); 63 | 64 | void propagateGyr(void*, int, float); 65 | void setGyrConverter(void*, int, int, int, float, float, float); 66 | 67 | float getCPULoad(void*); 68 | int getScreenColor(void*); 69 | 70 | #ifdef __cplusplus 71 | } 72 | #endif 73 | 74 | #endif // __faust_engine__ 75 | /************************** END faust-engine.h **************************/ 76 | -------------------------------------------------------------------------------- /clients/oooooooo/src/Commands.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by ezra on 11/3/18. 3 | // 4 | 5 | #ifndef CRONE_COMMANDS_H 6 | #define CRONE_COMMANDS_H 7 | 8 | // #include 9 | #include "readerwriterqueue/readerwriterqueue.h" 10 | 11 | namespace softcut_jack_osc { 12 | 13 | class SoftcutClient; 14 | 15 | class Commands { 16 | public: 17 | typedef enum { 18 | //-- softcut commands 19 | 20 | // mix 21 | SET_ENABLED_CUT, 22 | SET_LEVEL_CUT, 23 | SET_PAN_CUT, 24 | // level of individual input channel -> cut voice 25 | // (separate commands just to avoid a 3rd parameter) 26 | SET_LEVEL_IN_CUT, 27 | SET_LEVEL_CUT_CUT, 28 | 29 | // params 30 | SET_CUT_REC_FLAG, 31 | SET_CUT_PLAY_FLAG, 32 | 33 | SET_CUT_RATE, 34 | SET_CUT_LOOP_START, 35 | SET_CUT_LOOP_END, 36 | SET_CUT_LOOP_FLAG, 37 | SET_CUT_POSITION, 38 | 39 | SET_CUT_FADE_TIME, 40 | SET_CUT_REC_LEVEL, 41 | SET_CUT_PRE_LEVEL, 42 | SET_CUT_REC_OFFSET, 43 | 44 | SET_CUT_PRE_FILTER_FC, 45 | SET_CUT_PRE_FILTER_FC_MOD, 46 | SET_CUT_PRE_FILTER_RQ, 47 | SET_CUT_PRE_FILTER_LP, 48 | SET_CUT_PRE_FILTER_HP, 49 | SET_CUT_PRE_FILTER_BP, 50 | SET_CUT_PRE_FILTER_BR, 51 | SET_CUT_PRE_FILTER_DRY, 52 | 53 | SET_CUT_POST_FILTER_FC, 54 | SET_CUT_POST_FILTER_RQ, 55 | SET_CUT_POST_FILTER_LP, 56 | SET_CUT_POST_FILTER_HP, 57 | SET_CUT_POST_FILTER_BP, 58 | SET_CUT_POST_FILTER_BR, 59 | SET_CUT_POST_FILTER_DRY, 60 | 61 | SET_CUT_LEVEL_SLEW_TIME, 62 | SET_CUT_PAN_SLEW_TIME, 63 | SET_CUT_RECPRE_SLEW_TIME, 64 | SET_CUT_RATE_SLEW_TIME, 65 | SET_CUT_VOICE_SYNC, 66 | SET_CUT_BUFFER, 67 | 68 | SET_CUT_REC_ONCE, 69 | SET_CUT_TAPE_BIAS, 70 | SET_CUT_TAPE_PREGAIN, 71 | NUM_COMMANDS, 72 | } Id; 73 | 74 | public: 75 | Commands(); 76 | void post(Commands::Id id, float f); 77 | void post(Commands::Id id, int i, float f); 78 | void post(Commands::Id id, int i, int j); 79 | void post(Commands::Id id, int i, int j, float f); 80 | 81 | void handlePending(SoftcutClient *client); 82 | 83 | struct CommandPacket { 84 | CommandPacket() = default; 85 | CommandPacket(Commands::Id i, int i0, float f) 86 | : id(i), idx_0(i0), idx_1(-1), value(f) {} 87 | CommandPacket(Commands::Id i, int i0, int i1) 88 | : id(i), idx_0(i0), idx_1(i1) {} 89 | CommandPacket(Commands::Id i, int i0, int i1, float f) 90 | : id(i), idx_0(i0), idx_1(i1), value(f) {} 91 | Id id; 92 | int idx_0{}; 93 | int idx_1{}; 94 | float value{}; 95 | }; 96 | 97 | static Commands softcutCommands; 98 | 99 | private: 100 | // boost::lockfree::spsc_queue > q; 102 | moodycamel::ReaderWriterQueue q; 103 | }; 104 | 105 | } // namespace softcut_jack_osc 106 | 107 | #endif // CRONE_COMMANDS_H 108 | -------------------------------------------------------------------------------- /clients/oooooooo/src/SessionRecorder.h: -------------------------------------------------------------------------------- 1 | #ifndef SESSION_RECORDER_H 2 | #define SESSION_RECORDER_H 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | // Use double as sample type to match softcut 13 | using sample_t = double; 14 | 15 | class SessionRecorder { 16 | public: 17 | SessionRecorder(); 18 | ~SessionRecorder(); 19 | 20 | // Start recording with timestamp-based filenames 21 | void startRecording(int numVoices, float sampleRate); 22 | 23 | // Stop recording and close files 24 | void stopRecording(); 25 | 26 | // Check if currently recording 27 | bool isRecording() const { return recording_.load(); } 28 | 29 | // Called from audio thread - captures audio frames 30 | void captureMainMix(const sample_t* left, const sample_t* right, 31 | size_t numFrames); 32 | void captureVoice(int voice, const sample_t* left, const sample_t* right, 33 | size_t numFrames); 34 | 35 | private: 36 | std::atomic recording_; 37 | std::string sessionTimestamp_; 38 | int numVoices_; 39 | float sampleRate_; 40 | 41 | // Ring buffers for thread-safe audio capture 42 | static const size_t RING_BUFFER_SIZE = 48000 * 10; // 10 seconds at 48kHz 43 | struct VoiceBuffer { 44 | std::vector buffer; 45 | std::atomic writePos; 46 | std::atomic readPos; 47 | std::unique_ptr file; 48 | std::atomic hasAudio; 49 | std::atomic hasLogged; 50 | std::string filename; 51 | 52 | VoiceBuffer() : writePos(0), readPos(0), hasAudio(false), hasLogged(false) {} 53 | VoiceBuffer(VoiceBuffer&& other) noexcept 54 | : buffer(std::move(other.buffer)), 55 | writePos(other.writePos.load()), 56 | readPos(other.readPos.load()), 57 | file(std::move(other.file)), 58 | hasAudio(other.hasAudio.load()), 59 | hasLogged(other.hasLogged.load()), 60 | filename(std::move(other.filename)) {} 61 | VoiceBuffer& operator=(VoiceBuffer&& other) noexcept { 62 | if (this != &other) { 63 | buffer = std::move(other.buffer); 64 | writePos.store(other.writePos.load()); 65 | readPos.store(other.readPos.load()); 66 | file = std::move(other.file); 67 | hasAudio.store(other.hasAudio.load()); 68 | hasLogged.store(other.hasLogged.load()); 69 | filename = std::move(other.filename); 70 | } 71 | return *this; 72 | } 73 | // Delete copy constructor and assignment 74 | VoiceBuffer(const VoiceBuffer&) = delete; 75 | VoiceBuffer& operator=(const VoiceBuffer&) = delete; 76 | }; 77 | 78 | VoiceBuffer mainMixBuffer_; 79 | std::vector voiceBuffers_; 80 | 81 | // Worker thread for writing to disk 82 | std::unique_ptr writerThread_; 83 | std::atomic writerRunning_; 84 | 85 | void writerThreadFunc(); 86 | std::string generateTimestamp(); 87 | std::string generateFilename(const std::string& voiceId); 88 | void initializeBuffer(VoiceBuffer& buffer, int channels); 89 | size_t writeAvailableData(VoiceBuffer& buffer); 90 | }; 91 | 92 | #endif // SESSION_RECORDER_H 93 | -------------------------------------------------------------------------------- /softcut-lib/include/softcut/ReadWriteHead.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by ezra on 12/6/17. 3 | // 4 | 5 | #ifndef CUTFADEVOICE_CUTFADEVOICELOGIC_H 6 | #define CUTFADEVOICE_CUTFADEVOICELOGIC_H 7 | 8 | #include 9 | 10 | #include "FadeCurves.h" 11 | #include "SubHead.h" 12 | #include "TestBuffers.h" 13 | #include "Types.h" 14 | 15 | namespace softcut { 16 | 17 | class ReadWriteHead { 18 | public: 19 | void init(FadeCurves *fc); 20 | 21 | // per-sample update functions 22 | void processSample(sample_t in, sample_t *out); 23 | void processSampleNoRead(sample_t in, sample_t *out); 24 | void processSampleNoWrite(sample_t in, sample_t *out); 25 | 26 | void setSampleRate(float sr); 27 | void setBuffer(sample_t *buf, uint32_t size); 28 | void setRate(rate_t x); 29 | 30 | // set loop (region) start point in seconds 31 | void setLoopStartSeconds(float x); 32 | // set loop (region) end point in seconds 33 | void setLoopEndSeconds(float x); 34 | void setFadeTime(float secs); 35 | void setLoopFlag(bool val); 36 | 37 | void setRecOnceFlag(bool val); 38 | bool getRecOnceDone(); 39 | bool getRecOnceActive(); 40 | 41 | // set amplitudes 42 | void setRec(float x); 43 | void setPre(float x); 44 | 45 | // enqueue a position change with crossfade 46 | void cutToPos(float seconds); 47 | 48 | // immediately put both subheads in stopped state 49 | void stop(); 50 | // immediately start playing from current position (no fadein) 51 | void run(); 52 | 53 | float getDuration() { return (end - start) / sr; } 54 | 55 | float getLoopStart() { return start / sr; } 56 | 57 | float getLoopEnd() { return end / sr; } 58 | 59 | void setRecOffsetSamples(int d); 60 | 61 | phase_t getActivePhase(); 62 | rate_t getRate(); 63 | 64 | protected: 65 | friend class SubHead; 66 | 67 | private: 68 | // fade in to new position (given in samples) 69 | // assumption: phase is in range! 70 | void cutToPhase(phase_t newPhase); 71 | void enqueueCrossfade(phase_t newPhase); 72 | void dequeueCrossfade(); 73 | void takeAction(Action act); 74 | 75 | sample_t mixFade(sample_t x, sample_t y, float a, 76 | float b); // mix two inputs with phases 77 | void calcFadeInc(); 78 | 79 | private: 80 | SubHead head[2]; 81 | 82 | sample_t *buf; // audio buffer (allocated elsewhere) 83 | float sr; // sample rate 84 | phase_t start; // start/end points 85 | phase_t end; 86 | phase_t queuedCrossfade; 87 | bool queuedCrossfadeFlag; 88 | float fadeTime; // fade time in seconds 89 | float fadeInc; // linear fade increment per sample 90 | 91 | int active; // current active play head index (0 or 1) 92 | bool loopFlag; // set to loop, unset for 1-shot 93 | float pre; // pre-record level 94 | float rec; // record level 95 | bool recOnceFlag; // set to record one full loop 96 | bool recOnceDone; // triggers done to tell voice to unset rec flag 97 | int recOnceHead; // keeps track of which subhead is writing 98 | 99 | rate_t rate; // current rate 100 | TestBuffers testBuf; 101 | }; 102 | } // namespace softcut 103 | #endif // CUTFADEVOICE_CUTFADEVOICELOGIC_H 104 | -------------------------------------------------------------------------------- /external/faust/architecture/faust/dsp/dsp-multifun.h: -------------------------------------------------------------------------------- 1 | /************************** BEGIN dsp-multifun.h ************************** 2 | FAUST Architecture File 3 | Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale 4 | --------------------------------------------------------------------- 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation; either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | 19 | EXCEPTION : As a special exception, you may create a larger work 20 | that contains this FAUST architecture section and distribute 21 | that work under terms of your choice, so long as this FAUST 22 | architecture section is not modified. 23 | ***************************************************************************/ 24 | 25 | #ifndef dsp_multifun_H 26 | #define dsp_multifun_H 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | #include "faust/dsp/dsp-adapter.h" 33 | #include "faust/gui/meta.h" 34 | #include "mydspgeneric.h" 35 | 36 | /* 37 | A DSP decorator that loads the CPU optimised version of the code and instantiate it. 38 | This file is used by the 'faust2object' tool to produce a single multi CPU aware .o file, 39 | to be compiled and linked with the mydspmulti class. 40 | 41 | To test: c++ -std=c++11 FOOmulti.cpp FOOgeneric.cpp -o FOOmulti 42 | */ 43 | class mydspmulti : public decorator_dsp { 44 | 45 | private: 46 | 47 | struct Meta1 : Meta 48 | { 49 | std::string fOptions; 50 | 51 | void declare(const char* key, const char* value) 52 | { 53 | if (strcmp("compile_options", key) == 0) { 54 | fOptions = value; 55 | } 56 | } 57 | }; 58 | 59 | public: 60 | 61 | // Create a DS/US + Filter adapted DSP 62 | mydspmulti():decorator_dsp() 63 | { 64 | std::string error; 65 | fDSP = createSRAdapter(createmydspgeneric(), error, DOWN_SAMPLING, UP_SAMPLING, FILTER_TYPE); 66 | Meta1 meta; 67 | fDSP->metadata(&meta); 68 | std::cout << "Faust compile options : " << meta.fOptions << std::endl; 69 | } 70 | 71 | virtual ~mydspmulti() 72 | {} 73 | 74 | }; 75 | 76 | // Factory API 77 | dsp* createmydspmulti() { return new mydspmulti(); } 78 | 79 | #endif 80 | 81 | #ifdef TEST 82 | int main() 83 | { 84 | mydspmulti multi; 85 | std::cout << multi.getNumInputs() << std::endl; 86 | std::cout << multi.getNumOutputs() << std::endl; 87 | } 88 | #endif 89 | 90 | /************************** END dsp-multifun.h **************************/ 91 | -------------------------------------------------------------------------------- /clients/oooooooo/src/HelpSystem.cpp: -------------------------------------------------------------------------------- 1 | #include "HelpSystem.h" 2 | 3 | #include 4 | 5 | HelpSystem::HelpSystem() 6 | : font(nullptr), 7 | helpVisible(false), 8 | fadeAlpha(0.0f), 9 | fadeTarget(0.0f), 10 | fadeStep(0.05f) { 11 | // Initialize help messages 12 | helpMessages = { 13 | "basics", 14 | "h toggles help", 15 | "tab toggles menu", 16 | "1-8 selects loop", 17 | "up/down selects parameter", 18 | "left/right adjusts parameter", 19 | "ctrl + a copies parameter to all", 20 | "click edge to cut to position", 21 | "click and drag middle to adjust", 22 | "and pan", 23 | "", 24 | "playing/recording", 25 | "p toggles play", 26 | "r toggles record", 27 | "ctl + r pirmes recording", 28 | "shift + r records once", 29 | "", 30 | "lfos", 31 | "l toggles lfo", 32 | "ctrl + l toggles lfo on all", 33 | "+/- adjusts lfo period", 34 | "ctrl+left/right adjusts min lfo", 35 | "alt+left/right adjusts max lfo", 36 | "", 37 | "saving/loading", 38 | "drag-and-drop audio file to load", 39 | "s saves parameters", 40 | "ctrl+s saves audio", 41 | "o loads parameters", 42 | "ctrl+o loads audio", 43 | "y toggles session recording", 44 | }; 45 | } 46 | 47 | HelpSystem::~HelpSystem() { font = nullptr; } 48 | 49 | void HelpSystem::Init(TTF_Font* font) { this->font = font; } 50 | 51 | void HelpSystem::Toggle() { 52 | helpVisible = !helpVisible; 53 | fadeTarget = helpVisible ? 1.0f : 0.0f; 54 | } 55 | 56 | void HelpSystem::Render(SDL_Renderer* renderer, int windowWidth) { 57 | // Update fade alpha based on target 58 | if (fadeAlpha < fadeTarget) { 59 | fadeAlpha += fadeStep; 60 | if (fadeAlpha > fadeTarget) fadeAlpha = fadeTarget; 61 | } else if (fadeAlpha > fadeTarget) { 62 | fadeAlpha -= fadeStep; 63 | if (fadeAlpha < fadeTarget) fadeAlpha = fadeTarget; 64 | } 65 | // Only proceed if we have a font and some alpha 66 | if (!font || fadeAlpha <= 0.01f) return; 67 | 68 | // Calculate the alpha value for SDL (0-255) 69 | uint8_t alpha = static_cast(fadeAlpha * 255); 70 | 71 | // Set up position for text on right side of screen 72 | int textX = windowWidth - 360; // 450 pixels from right edge 73 | int textY = 20; // Start 10 pixels from top 74 | int lineHeight = 20; // Spacing between lines 75 | 76 | // Ensure text position is always visible 77 | textX = std::max(10, textX); 78 | 79 | // Draw each help message 80 | for (const auto& message : helpMessages) { 81 | SDL_Color textColor = {255, 255, 255, alpha}; // Gray with current alpha 82 | SDL_Surface* textSurface = 83 | TTF_RenderText_Blended(font, message.c_str(), textColor); 84 | 85 | if (textSurface) { 86 | SDL_Texture* textTexture = 87 | SDL_CreateTextureFromSurface(renderer, textSurface); 88 | if (textTexture) { 89 | SDL_Rect textRect = {textX, textY, textSurface->w, textSurface->h}; 90 | SDL_RenderCopy(renderer, textTexture, nullptr, &textRect); 91 | SDL_DestroyTexture(textTexture); 92 | } 93 | SDL_FreeSurface(textSurface); 94 | } 95 | 96 | // Move down for next line 97 | textY += lineHeight; 98 | } 99 | } -------------------------------------------------------------------------------- /clients/oooooooo/src/DisplayMessage.cpp: -------------------------------------------------------------------------------- 1 | #include "DisplayMessage.h" 2 | 3 | #include 4 | 5 | DisplayMessage::DisplayMessage() 6 | : font_(nullptr), 7 | state_(State::IDLE), 8 | alpha_(0.0f), 9 | displayDurationMs_(0), 10 | textColor_({255, 255, 255, 255}) {} 11 | 12 | void DisplayMessage::Init(TTF_Font* font) { font_ = font; } 13 | 14 | void DisplayMessage::SetMessage(const std::string& message, 15 | int displaySeconds) { 16 | currentMessage_ = message; 17 | displayDurationMs_ = displaySeconds * 1000; 18 | state_ = State::FADING_IN; 19 | alpha_ = 0.0f; 20 | startTime_ = std::chrono::steady_clock::now(); 21 | displayEndTime_ = startTime_ + std::chrono::milliseconds(FADE_DURATION_MS + 22 | displayDurationMs_); 23 | } 24 | 25 | void DisplayMessage::Update() { 26 | if (state_ == State::IDLE) { 27 | return; 28 | } 29 | 30 | auto now = std::chrono::steady_clock::now(); 31 | auto elapsed = 32 | std::chrono::duration_cast(now - startTime_) 33 | .count(); 34 | 35 | switch (state_) { 36 | case State::FADING_IN: 37 | if (elapsed < FADE_DURATION_MS) { 38 | alpha_ = static_cast(elapsed) / FADE_DURATION_MS; 39 | } else { 40 | alpha_ = 1.0f; 41 | state_ = State::DISPLAYING; 42 | } 43 | break; 44 | 45 | case State::DISPLAYING: 46 | if (elapsed > FADE_DURATION_MS + displayDurationMs_) { 47 | state_ = State::FADING_OUT; 48 | } 49 | break; 50 | 51 | case State::FADING_OUT: 52 | if (elapsed < FADE_DURATION_MS + displayDurationMs_ + FADE_DURATION_MS) { 53 | float fadeOutProgress = static_cast(elapsed - FADE_DURATION_MS - 54 | displayDurationMs_) / 55 | FADE_DURATION_MS; 56 | alpha_ = 1.0f - fadeOutProgress; 57 | } else { 58 | alpha_ = 0.0f; 59 | state_ = State::IDLE; 60 | currentMessage_.clear(); 61 | } 62 | break; 63 | 64 | case State::IDLE: 65 | // Already handled above 66 | break; 67 | } 68 | } 69 | 70 | void DisplayMessage::Render(SDL_Renderer* renderer, 71 | int windowWidth [[maybe_unused]], 72 | int windowHeight [[maybe_unused]]) { 73 | if (state_ == State::IDLE || alpha_ <= 0.0f || currentMessage_.empty() || 74 | !font_) { 75 | return; 76 | } 77 | 78 | SDL_Color color = textColor_; 79 | color.a = static_cast(255 * alpha_); 80 | 81 | // Create surface and texture 82 | SDL_Surface* surface = 83 | TTF_RenderText_Blended(font_, currentMessage_.c_str(), color); 84 | if (!surface) { 85 | return; 86 | } 87 | 88 | SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface); 89 | if (!texture) { 90 | SDL_FreeSurface(surface); 91 | return; 92 | } 93 | // Position the message in the bottom-right corner with some padding 94 | int padding = 10; 95 | int x = padding; 96 | int y = windowHeight - surface->h - padding; 97 | 98 | SDL_Rect destRect = {x, y, surface->w, surface->h}; 99 | SDL_RenderCopy(renderer, texture, nullptr, &destRect); 100 | 101 | // Clean up 102 | SDL_DestroyTexture(texture); 103 | SDL_FreeSurface(surface); 104 | } 105 | 106 | bool DisplayMessage::IsActive() const { return state_ != State::IDLE; } -------------------------------------------------------------------------------- /external/faust/architecture/faust/gui/JuceStateUI.h: -------------------------------------------------------------------------------- 1 | /************************** BEGIN JuceStateUI.h ************************** 2 | FAUST Architecture File 3 | Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale 4 | --------------------------------------------------------------------- 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation; either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | 19 | EXCEPTION : As a special exception, you may create a larger work 20 | that contains this FAUST architecture section and distribute 21 | that work under terms of your choice, so long as this FAUST 22 | architecture section is not modified. 23 | ************************************************************************/ 24 | 25 | #ifndef JuceStateUI_H 26 | #define JuceStateUI_H 27 | 28 | #include "../JuceLibraryCode/JuceHeader.h" 29 | 30 | #include "faust/gui/MapUI.h" 31 | 32 | // A class to save/restore DSP state using JUCE, which also set default values at construction time. 33 | 34 | struct JuceStateUI : public MapUI { 35 | 36 | bool fRestored; 37 | 38 | JuceStateUI():fRestored(false) {} 39 | virtual ~JuceStateUI() {} 40 | 41 | void getStateInformation (juce::MemoryBlock& destData) 42 | { 43 | juce::MemoryOutputStream stream (destData, true); 44 | 45 | // Write path and values 46 | if (sizeof(FAUSTFLOAT) == sizeof(float)) { 47 | for (const auto& it : getFullpathMap()) { 48 | stream.writeString(it.first); 49 | stream.writeFloat(*it.second); 50 | } 51 | } else { 52 | for (const auto& it : getFullpathMap()) { 53 | stream.writeString(it.first); 54 | stream.writeDouble(*it.second); 55 | } 56 | } 57 | } 58 | 59 | void setStateInformation (const void* data, int sizeInBytes) 60 | { 61 | fRestored = true; 62 | juce::MemoryInputStream stream (data, static_cast (sizeInBytes), false); 63 | std::string path; 64 | 65 | // Read path then value and try to restore them 66 | if (sizeof(FAUSTFLOAT) == sizeof(float)) { 67 | while ((path = stream.readString().toStdString()) != "") { 68 | setParamValue(path, stream.readFloat()); 69 | } 70 | } else { 71 | while ((path = stream.readString().toStdString()) != "") { 72 | setParamValue(path, stream.readDouble()); 73 | } 74 | } 75 | } 76 | 77 | // -- active widgets 78 | // use MapUI derived methods 79 | 80 | // -- passive widgets 81 | // empty si we don't want to save/restore them 82 | void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT fmin, FAUSTFLOAT fmax) {} 83 | void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT fmin, FAUSTFLOAT fmax) {} 84 | 85 | }; 86 | 87 | #endif 88 | /************************** END JuceStateUI.h **************************/ 89 | -------------------------------------------------------------------------------- /external/faust/architecture/faust/gui/UI.h: -------------------------------------------------------------------------------- 1 | /************************** BEGIN UI.h ***************************** 2 | FAUST Architecture File 3 | Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale 4 | --------------------------------------------------------------------- 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation; either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | 19 | EXCEPTION : As a special exception, you may create a larger work 20 | that contains this FAUST architecture section and distribute 21 | that work under terms of your choice, so long as this FAUST 22 | architecture section is not modified. 23 | ********************************************************************/ 24 | 25 | #ifndef __UI_H__ 26 | #define __UI_H__ 27 | 28 | #include "faust/export.h" 29 | 30 | #ifndef FAUSTFLOAT 31 | #define FAUSTFLOAT float 32 | #endif 33 | 34 | /******************************************************************************* 35 | * UI : Faust DSP User Interface 36 | * User Interface as expected by the buildUserInterface() method of a DSP. 37 | * This abstract class contains only the method that the Faust compiler can 38 | * generate to describe a DSP user interface. 39 | ******************************************************************************/ 40 | 41 | struct Soundfile; 42 | 43 | template 44 | struct FAUST_API UIReal { 45 | 46 | UIReal() {} 47 | virtual ~UIReal() {} 48 | 49 | // -- widget's layouts 50 | 51 | virtual void openTabBox(const char* label) = 0; 52 | virtual void openHorizontalBox(const char* label) = 0; 53 | virtual void openVerticalBox(const char* label) = 0; 54 | virtual void closeBox() = 0; 55 | 56 | // -- active widgets 57 | 58 | virtual void addButton(const char* label, REAL* zone) = 0; 59 | virtual void addCheckButton(const char* label, REAL* zone) = 0; 60 | virtual void addVerticalSlider(const char* label, REAL* zone, REAL init, REAL min, REAL max, REAL step) = 0; 61 | virtual void addHorizontalSlider(const char* label, REAL* zone, REAL init, REAL min, REAL max, REAL step) = 0; 62 | virtual void addNumEntry(const char* label, REAL* zone, REAL init, REAL min, REAL max, REAL step) = 0; 63 | 64 | // -- passive widgets 65 | 66 | virtual void addHorizontalBargraph(const char* label, REAL* zone, REAL min, REAL max) = 0; 67 | virtual void addVerticalBargraph(const char* label, REAL* zone, REAL min, REAL max) = 0; 68 | 69 | // -- soundfiles 70 | 71 | virtual void addSoundfile(const char* label, const char* filename, Soundfile** sf_zone) = 0; 72 | 73 | // -- metadata declarations 74 | 75 | virtual void declare(REAL* /*zone*/, const char* /*key*/, const char* /*val*/) {} 76 | 77 | // To be used by LLVM client 78 | virtual int sizeOfFAUSTFLOAT() { return sizeof(FAUSTFLOAT); } 79 | }; 80 | 81 | struct FAUST_API UI : public UIReal { 82 | UI() {} 83 | virtual ~UI() {} 84 | #ifdef DAISY_NO_RTTI 85 | virtual bool isSoundUI() const { return false; } 86 | virtual bool isMidiInterface() const { return false; } 87 | #endif 88 | }; 89 | 90 | #endif 91 | /************************** END UI.h **************************/ 92 | -------------------------------------------------------------------------------- /external/faust/architecture/faust/misc.h: -------------------------------------------------------------------------------- 1 | /************************** BEGIN misc.h ******************************* 2 | FAUST Architecture File 3 | Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale 4 | --------------------------------------------------------------------- 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation; either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | 19 | EXCEPTION : As a special exception, you may create a larger work 20 | that contains this FAUST architecture section and distribute 21 | that work under terms of your choice, so long as this FAUST 22 | architecture section is not modified. 23 | ***************************************************************************/ 24 | 25 | #ifndef __misc__ 26 | #define __misc__ 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #include "faust/gui/meta.h" 36 | 37 | struct MY_Meta : Meta, std::map 38 | { 39 | void declare(const char* key, const char* value) { (*this)[key] = value; } 40 | }; 41 | 42 | static int lsr(int x, int n) { return int(((unsigned int)x) >> n); } 43 | 44 | static int int2pow2(int x) { int r = 0; while ((1< 9 | #include 10 | 11 | #include "FadeCurves.h" 12 | #include "ReadWriteHead.h" 13 | #include "Svf.h" 14 | #include "TapeFX.h" 15 | #include "Types.h" 16 | #include "Utilities.h" 17 | 18 | namespace softcut { 19 | class Voice { 20 | public: 21 | Voice(); 22 | 23 | void init(FadeCurves *fc); 24 | 25 | void setBuffer(sample_t *buf, unsigned int numFrames); 26 | 27 | void setSampleRate(float hz); 28 | 29 | void setRate(float rate); 30 | 31 | void setLoopStart(float sec); 32 | 33 | void setLoopEnd(float sec); 34 | 35 | void setLoopFlag(bool val); 36 | 37 | void setFadeTime(float sec); 38 | 39 | void setRecLevel(float amp); 40 | 41 | void setPreLevel(float amp); 42 | 43 | void setRecFlag(bool val); 44 | 45 | void setRecOnceFlag(bool val); 46 | 47 | void setPlayFlag(bool val); 48 | 49 | void setPreFilterFc(float); 50 | 51 | void setPreFilterRq(float); 52 | 53 | void setPreFilterLp(float); 54 | 55 | void setPreFilterHp(float); 56 | 57 | void setPreFilterBp(float); 58 | 59 | void setPreFilterBr(float); 60 | 61 | void setPreFilterDry(float); 62 | 63 | void setPreFilterFcMod(float x); 64 | 65 | void setPostFilterFc(float); 66 | 67 | void setPostFilterRq(float); 68 | 69 | void setPostFilterLp(float); 70 | 71 | void setPostFilterHp(float); 72 | 73 | void setPostFilterBp(float); 74 | 75 | void setPostFilterBr(float); 76 | 77 | void setPostFilterDry(float); 78 | 79 | void cutToPos(float sec); 80 | 81 | // process a single channel 82 | void processBlockMono(const sample_t *in, sample_t *out, int numFrames); 83 | 84 | void setRecOffset(float d); 85 | 86 | void setRecPreSlewTime(float d); 87 | 88 | void setRateSlewTime(float d); 89 | 90 | void setPhaseQuant(float x); 91 | 92 | void setPhaseOffset(float x); 93 | 94 | phase_t getQuantPhase(); 95 | 96 | bool getPlayFlag(); 97 | 98 | bool getRecFlag(); 99 | 100 | float getActivePosition(); 101 | 102 | // use this from non-audio threads 103 | float getSavedPosition(); 104 | 105 | float getDuration() { return sch.getDuration(); } 106 | 107 | float getLoopStart() { return sch.getLoopStart(); } 108 | 109 | float getLoopEnd() { return sch.getLoopEnd(); } 110 | 111 | void reset(); 112 | 113 | // immediately put both subheads in a stopped state 114 | void stop(); 115 | 116 | // tape fx 117 | TapeFX tapeFx; 118 | 119 | private: 120 | void updatePreSvfFc(); 121 | 122 | void updateQuantPhase(); 123 | 124 | private: 125 | sample_t *buf; 126 | int bufFrames; 127 | float sampleRate; 128 | 129 | // fade curve data 130 | FadeCurves fadeCurves; 131 | // xfaded read/write head 132 | ReadWriteHead sch; 133 | // input filter 134 | Svf svfPre; 135 | // output filter 136 | Svf svfPost; 137 | // rate ramp 138 | LogRamp rateRamp; 139 | // pre-level ramp 140 | LogRamp preRamp; 141 | // record-level ramp 142 | LogRamp recRamp; 143 | 144 | // default frequency for SVF 145 | // reduced automatically when setting rate 146 | float svfPreFcBase; 147 | // the amount by which SVF frequency is modulated by rate 148 | float svfPreFcMod = 1.0; 149 | float svfPreDryLevel = 1.0; 150 | float svfPostDryLevel = 1.0; 151 | // phase quantization unit, should be in [0,1] 152 | phase_t phaseQuant; 153 | // phase offset in sec 154 | float phaseOffset = 0; 155 | 156 | //-- these stored phases are for access from non-audio threads, 157 | // and are updated once per block: 158 | std::atomic rawPhase; 159 | std::atomic quantPhase; 160 | 161 | private: 162 | bool playFlag; 163 | bool recFlag; 164 | }; 165 | } // namespace softcut 166 | 167 | #endif // Softcut_SoftcutVOICE_H 168 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | pull_request: 7 | branches: [main] 8 | 9 | jobs: 10 | linux: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v4 14 | with: 15 | submodules: true 16 | 17 | - name: Install dependencies 18 | run: | 19 | sudo apt-get update 20 | sudo apt-get install -y libjack-jackd2-dev liblo-dev libsdl2-dev libsdl2-ttf-dev librtmidi-dev libsndfile1-dev libflac-dev patchelf libfuse-dev cmake 21 | 22 | - name: Build project 23 | run: make 24 | 25 | - name: Create release 26 | run: ./build-appimage.sh 27 | 28 | - name: Create release artifact 29 | run: | 30 | cp oooooooo.AppImage oooooooo_${{ github.event.release.name }}.AppImage 31 | ls -lSh oooooooo_${{ github.event.release.name }}.AppImage 32 | 33 | macos: 34 | runs-on: macos-latest 35 | steps: 36 | - uses: actions/checkout@v4 37 | with: 38 | submodules: true 39 | 40 | - name: Install dependencies 41 | run: | 42 | brew update 43 | brew install jack liblo sdl2 sdl2_ttf rtmidi libsndfile flac create-dmg fuse cmake 44 | 45 | - name: Set PKG_CONFIG_PATH 46 | run: echo "PKG_CONFIG_PATH=/opt/homebrew/lib/pkgconfig" >> $GITHUB_ENV 47 | 48 | - name: Build project 49 | run: | 50 | export PKG_CONFIG_PATH="/opt/homebrew/lib/pkgconfig:/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH" 51 | export CXXFLAGS="-I/opt/homebrew/include -I/usr/local/include" 52 | export LDFLAGS="-L/opt/homebrew/lib -L/usr/local/lib" 53 | export PATH="/opt/homebrew/bin:$PATH" 54 | make 55 | - name: Build macOS app 56 | run: | 57 | chmod +x build-macapp.sh 58 | ./build-macapp.sh 59 | - name: Create release artifact 60 | run: | 61 | ls -lSh 62 | windows: 63 | runs-on: windows-latest 64 | steps: 65 | - uses: actions/checkout@v4 66 | with: 67 | submodules: true 68 | - name: Setup MSYS2 69 | uses: msys2/setup-msys2@v2 70 | with: 71 | msystem: MINGW64 72 | update: true 73 | install: >- 74 | mingw-w64-x86_64-gcc 75 | mingw-w64-x86_64-pkg-config 76 | mingw-w64-x86_64-python 77 | mingw-w64-x86_64-jack2 78 | mingw-w64-x86_64-liblo 79 | mingw-w64-x86_64-SDL2 80 | mingw-w64-x86_64-SDL2_ttf 81 | mingw-w64-x86_64-rtmidi 82 | mingw-w64-x86_64-libsndfile 83 | mingw-w64-x86_64-flac 84 | mingw-w64-x86_64-make 85 | mingw-w64-x86_64-cmake 86 | zip 87 | - name: Check MSYS2 environment 88 | shell: msys2 {0} 89 | run: | 90 | which gcc 91 | which g++ 92 | echo $PATH 93 | cmake --version 94 | pkg-config --libs jack 95 | ls -la /mingw64/lib/*jack* 96 | - name: Build in MSYS2 environment 97 | shell: msys2 {0} 98 | run: | 99 | mkdir -p build 100 | cd build 101 | export PATH="/mingw64/bin:$PATH" 102 | export PKG_CONFIG_PATH="/mingw64/lib/pkgconfig:$PKG_CONFIG_PATH" 103 | export MINGW_PREFIX="/mingw64" 104 | cmake -DCMAKE_BUILD_TYPE=Release \ 105 | -DCMAKE_PREFIX_PATH=/mingw64 \ 106 | .. 107 | cmake --build . --config Release 108 | - name: Create release artifact 109 | shell: msys2 {0} 110 | run: | 111 | mkdir oooooooo 112 | cp build/clients/oooooooo/oooooooo.exe oooooooo/ 113 | cp external/windows/*.dll oooooooo/ 114 | zip -r oooooooo_${{ github.event.release.name }}.zip oooooooo 115 | ls -lSh oooooooo_${{ github.event.release.name }}.zip 116 | -------------------------------------------------------------------------------- /clients/oooooooo/src/LFO.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2020 Electrosmith, Corp 3 | 4 | Use of this source code is governed by an MIT-style 5 | license that can be found in the LICENSE file or at 6 | https://opensource.org/licenses/MIT. 7 | */ 8 | 9 | #pragma once 10 | #ifndef DSY_LFO_H 11 | #define DSY_LFO_H 12 | #include 13 | #include 14 | 15 | #ifdef __cplusplus 16 | 17 | /** Synthesis of several waveforms, including polyBLEP bandlimited waveforms. 18 | */ 19 | class LFO { 20 | public: 21 | LFO() {} 22 | ~LFO() {} 23 | /** Choices for output waveforms, POLYBLEP are appropriately labeled. Others 24 | * are naive forms. 25 | */ 26 | enum Waveform { 27 | WAVE_SIN, 28 | WAVE_TRI, 29 | WAVE_SAW, 30 | WAVE_RAMP, 31 | WAVE_SQUARE, 32 | WAVE_POLYBLEP_TRI, 33 | WAVE_POLYBLEP_SAW, 34 | WAVE_POLYBLEP_SQUARE, 35 | WAVE_LAST, 36 | }; 37 | 38 | /** Initializes the LFO 39 | 40 | \param sample_rate - sample rate of the audio engine being run, and the 41 | frequency that the Process function will be called. 42 | 43 | Defaults: 44 | - freq_ = 100 Hz 45 | - amp_ = 0.5 46 | - waveform_ = sine wave. 47 | */ 48 | void Init(float sample_rate) { 49 | sr_ = sample_rate; 50 | out_ = 0.0f; 51 | add_ = 0.0f; 52 | sr_recip_ = 1.0f / sample_rate; 53 | freq_ = 100.0f; 54 | amp_ = 1.0f; 55 | pw_ = 0.5f; 56 | // generate random number between 0 and 2pi 57 | phase_ = static_cast(rand()) / 58 | (static_cast(RAND_MAX / (2.0f * M_PI))); 59 | phase_inc_ = CalcPhaseInc(freq_); 60 | waveform_ = WAVE_SIN; 61 | 62 | eoc_ = true; 63 | eor_ = true; 64 | } 65 | 66 | /** Changes the frequency of the LFO, and recalculates phase 67 | * increment. 68 | */ 69 | inline void SetFreq(const float f) { 70 | freq_ = f; 71 | phase_inc_ = CalcPhaseInc(f); 72 | } 73 | 74 | /** Sets the amplitude of the waveform. 75 | */ 76 | inline void SetAmp(const float a) { amp_ = a; } 77 | 78 | float GetAmp() { return amp_; } 79 | 80 | float GetPeriod() { return 1.0f / freq_; } 81 | 82 | inline void SetAdd(float a) { add_ = a; } 83 | /** Sets the waveform to be synthesized by the Process() function. 84 | */ 85 | inline void SetWaveform(const Waveform wf) { 86 | waveform_ = wf < WAVE_LAST ? wf : WAVE_SIN; 87 | } 88 | /** Sets the pulse width for WAVE_SQUARE and WAVE_POLYBLEP_SQUARE (range 0 - 89 | * 1) 90 | */ 91 | inline void SetPw(const float pw) { 92 | pw_ = pw < 0.0f ? 0.0f : pw > 1.0f ? 1.0f : pw; 93 | } 94 | 95 | /** Returns true if cycle is at end of rise. Set during call to Process. 96 | */ 97 | inline bool IsEOR() { return eor_; } 98 | 99 | /** Returns true if cycle is at end of cycle. Set during call to Process. 100 | */ 101 | inline bool IsEOC() { return eoc_; } 102 | 103 | /** Returns true if cycle rising. 104 | */ 105 | inline bool IsRising() { return phase_ < 0.5f; } 106 | 107 | /** Returns true if cycle falling. 108 | */ 109 | inline bool IsFalling() { return phase_ >= 0.5f; } 110 | 111 | /** Processes the waveform to be generated, returning one sample. This should 112 | * be called once per sample period. 113 | */ 114 | float Process(); 115 | 116 | float Value() { return out_; } 117 | 118 | /** Adds a value 0.0-1.0 (equivalent to 0.0-TWO_PI) to the current phase. 119 | * Useful for PM and "FM" synthesis. 120 | */ 121 | void PhaseAdd(float _phase) { phase_ += _phase; } 122 | /** Resets the phase to the input argument. If no argumeNt is present, it will 123 | * reset phase to 0.0; 124 | */ 125 | void Reset(float _phase = 0.0f) { phase_ = _phase; } 126 | 127 | private: 128 | float CalcPhaseInc(float f); 129 | Waveform waveform_; 130 | float add_, amp_, freq_, pw_; 131 | float sr_, sr_recip_, phase_, phase_inc_; 132 | float last_out_, last_freq_; 133 | float out_; 134 | bool eor_, eoc_; 135 | }; 136 | 137 | #endif 138 | #endif -------------------------------------------------------------------------------- /external/faust/architecture/faust/midi/teensy-midi.h: -------------------------------------------------------------------------------- 1 | /************************** BEGIN teensy-midi.h *************************** 2 | FAUST Architecture File 3 | Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale 4 | --------------------------------------------------------------------- 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation; either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | 19 | EXCEPTION : As a special exception, you may create a larger work 20 | that contains this FAUST architecture section and distribute 21 | that work under terms of your choice, so long as this FAUST 22 | architecture section is not modified. 23 | ***************************************************************************/ 24 | 25 | #ifndef __teensy_midi__ 26 | #define __teensy_midi__ 27 | 28 | #include 29 | 30 | #include "Arduino.h" 31 | #include "faust/midi/midi.h" 32 | 33 | extern usb_midi_class gUSBMIDI; 34 | 35 | /** 36 | * MIDI input/output handling for the Teensy: https://www.pjrc.com/teensy/ 37 | */ 38 | class teensy_midi : public midi_handler { 39 | 40 | public: 41 | 42 | void processMidi() 43 | { 44 | while (gUSBMIDI.read()) { 45 | 46 | int type = gUSBMIDI.getType(); // which MIDI message, 128-255 47 | int channel = gUSBMIDI.getChannel(); // which MIDI channel, 0-15 48 | double time = (double)gUSBMIDI.Clock; 49 | 50 | switch(type) { 51 | case gUSBMIDI.Clock: 52 | handleClock(time); 53 | break; 54 | case usbMIDI.Start: 55 | // We can consider start and continue as identical messages 56 | case usbMIDI.Continue: 57 | handleStart(time); 58 | break; 59 | case gUSBMIDI.Stop: 60 | handleStop(time); 61 | break; 62 | case gUSBMIDI.ProgramChange: 63 | handleProgChange(time, channel, gUSBMIDI.getData1()); 64 | break; 65 | case gUSBMIDI.AfterTouchChannel: 66 | handleAfterTouch(time, channel, gUSBMIDI.getData1()); 67 | break; 68 | case gUSBMIDI.NoteOff: 69 | handleKeyOff(time, channel, gUSBMIDI.getData1(), gUSBMIDI.getData2()); 70 | break; 71 | case gUSBMIDI.NoteOn: 72 | handleKeyOn(time, channel, gUSBMIDI.getData1(), gUSBMIDI.getData2()); 73 | break; 74 | case gUSBMIDI.ControlChange: 75 | handleCtrlChange(time, channel, gUSBMIDI.getData1(), gUSBMIDI.getData2()); 76 | break; 77 | case gUSBMIDI.PitchBend: 78 | handlePitchWheel(time, channel, gUSBMIDI.getData1(), gUSBMIDI.getData2()); 79 | break; 80 | case gUSBMIDI.AfterTouchPoly: 81 | handlePolyAfterTouch(time, channel, gUSBMIDI.getData1(), gUSBMIDI.getData2()); 82 | break; 83 | } 84 | } 85 | } 86 | }; 87 | 88 | #endif 89 | /************************** END teensy-midi.h **************************/ 90 | -------------------------------------------------------------------------------- /clients/oooooooo/src/Parameter.h: -------------------------------------------------------------------------------- 1 | #ifndef LIB_PARAMETER_H 2 | #define LIB_PARAMETER_H 3 | #pragma once 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include "DrawFunctions.h" 10 | #include "LFO.h" 11 | #include "Serializable.h" 12 | #include "Utilities.h" 13 | 14 | using namespace softcut_jack_osc; 15 | 16 | class Parameter : public Serializable { 17 | public: 18 | Parameter(); 19 | ~Parameter(); 20 | JSON toJSON() const override; 21 | void fromJSON(const JSON& json) override; 22 | 23 | void Init(float sample_rate, float min, float max, float inc, 24 | float default_value, float lfo_min, float lfo_max, float lfo_inc, 25 | float lfo_period, std::string name, std::string unit, 26 | std::function set_callback); 27 | 28 | std::string String(); 29 | std::string Name() const { return name_; } 30 | void SetStringFunc(std::function string_func) { 31 | string_func_ = string_func; 32 | } 33 | void ValueDelta(float delta); 34 | void ValueSet(float value, bool quiet) { set_(value, quiet); } 35 | void ValueSetRaw(float value, bool quiet); 36 | bool RegisterClick(float mouseX, float mouseY, bool dragging); 37 | 38 | void DeltaLFOPeriod(float delta); 39 | 40 | void LFODelta(float min_delta, float max_delta); 41 | void Render(SDL_Renderer* renderer, TTF_Font* font, int x, int y, int width, 42 | int height, bool selected, float brightness = 1.0f); 43 | void Update(); 44 | void Bang(); 45 | void Toggle() { 46 | if (value_set_raw_ > 0.5f) { 47 | set_(min_, false); 48 | } else { 49 | set_(max_, false); 50 | } 51 | } 52 | bool IsHidden() { return hide_; } 53 | void Hide(bool hide) { hide_ = hide; } 54 | void SetMax(float max) { 55 | max_ = max; 56 | if (value_set_ > max_) { 57 | value_set_ = max_; 58 | set_(max_, false); 59 | } 60 | } 61 | void SetInc(float inc); 62 | void SetBPM(float bpm); 63 | void SetIsQuantizable(bool is_quantizable) { 64 | is_quantizable_ = is_quantizable; 65 | } 66 | bool IsQuantized() { return is_quantizable_ && bpm_quantize_ > 0.0f; } 67 | float GetSecPerBeat() { return bpm_quantize_; } 68 | 69 | float GetValue() { return value_compute_; } 70 | float GetRaw() { return value_compute_raw_; } 71 | float GetRawMin() { return lfo_min_raw_; } 72 | float GetRawMax() { return lfo_max_raw_; } 73 | 74 | void ToggleLFO() { 75 | lfo_active_ = !lfo_active_; 76 | Update(); 77 | Bang(); 78 | } 79 | 80 | // Add methods to share parameter data 81 | void ShareFrom(Parameter* shared) { shared_parameter_ = shared; } 82 | bool IsShared() const { return shared_parameter_ != nullptr; } 83 | float GetValue() const { return value_set_; } 84 | 85 | private: 86 | void set_(float value, bool quiet); 87 | bool hide_ = false; 88 | std::string name_; 89 | std::string unit_; 90 | 91 | Parameter* shared_parameter_ = nullptr; // Pointer to shared parameter 92 | 93 | float x_ = 0.0f; 94 | float y_ = 0.0f; 95 | float width_ = 0.0f; 96 | float height_ = 0.0f; 97 | float value_set_ = 0.0f; 98 | float value_set_raw_ = 0.0f; 99 | float value_compute_ = 0.0f; 100 | float value_compute_raw_ = 0.0f; 101 | float min_ = 0.0f; 102 | float max_ = 1.0f; 103 | float inc_ = 0.01f; 104 | float inc_raw_ = 0.01f; 105 | float lfo_min_delta_ = 0.0f; 106 | float lfo_max_delta_ = 0.0f; 107 | float lfo_min_set_ = 0.0f; 108 | float lfo_max_set_ = 1.0f; 109 | float lfo_min_raw_ = 0.0f; 110 | float lfo_max_raw_ = 1.0f; 111 | float lfo_inc_ = 0.01f; 112 | float lfo_period_ = 10.0f; 113 | uint8_t lfo_waveform_ = LFO::WAVE_SIN; 114 | bool lfo_active_ = false; 115 | void lfo_min_max_update(); 116 | std::function set_callback_ = nullptr; 117 | std::function string_func_ = nullptr; 118 | static float bpm_quantize_; 119 | bool is_quantizable_ = false; 120 | 121 | LFO lfo_; 122 | }; 123 | 124 | #endif -------------------------------------------------------------------------------- /clients/oooooooo/src/BufDiskWorker.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by emb on 11/30/19. 3 | // 4 | /* 5 | * BufDiskWorker is an Audio Buffer Disk Interface static class. 6 | * 7 | * it requires users to _register_ buffers (returns numerical index for 8 | * registered buf) disk read/write work can be requested for registered buffers, 9 | * executed in background thread 10 | * 11 | * TODO: 12 | * - callback for request completion? 13 | * - use condvar for signaling, instead of sleep+poll 14 | */ 15 | 16 | #ifndef CRONE_BUFMANAGER_H 17 | #define CRONE_BUFMANAGER_H 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "softcut/Types.h" 27 | using namespace softcut; 28 | 29 | namespace softcut_jack_osc { 30 | 31 | // class for asynchronous management of mono audio buffers 32 | class BufDiskWorker { 33 | enum class JobType { Clear, ReadMono, ReadStereo, WriteMono, WriteStereo }; 34 | struct Job { 35 | JobType type; 36 | size_t bufIdx[2]; 37 | std::string path; 38 | float startSrc; 39 | float startDst; 40 | float dur; 41 | int chan; 42 | }; 43 | struct BufDesc { 44 | sample_t *data; 45 | size_t frames; 46 | }; 47 | static std::queue jobQ; 48 | static std::mutex qMut; 49 | static std::unique_ptr worker; 50 | static constexpr size_t maxBufs = 16; 51 | static std::array bufs; 52 | static int numBufs; 53 | static bool shouldQuit; 54 | static constexpr int sleepPeriodMs = 100; 55 | static int sampleRate; 56 | static constexpr int ioBufFrames = 1024; 57 | 58 | static int secToFrame(float seconds); 59 | 60 | private: 61 | static void requestJob(Job &job); 62 | 63 | public: 64 | // initialize with sample rate 65 | static void init(int sr); 66 | 67 | // register a buffer to manage. 68 | // returns index to be used in work requests 69 | static int registerBuffer(sample_t *data, size_t frames); 70 | 71 | // clear a portion of a mono buffer 72 | static void requestClear(size_t idx, float start = 0, float dur = -1); 73 | 74 | // read mono soundfile to mono buffer 75 | static void requestReadMono(size_t idx, std::string path, float startSrc = 0, 76 | float startDst = 0, float dur = -1, 77 | int chanSrc = 0); 78 | 79 | // read and de-interleave stereo soundfile to 2x mono buffers 80 | static void requestReadStereo(size_t idx0, size_t idx1, std::string path, 81 | float startSrc = 0, float startDst = 0, 82 | float dur = -1); 83 | 84 | // write mono buf to mono soundfile 85 | static void requestWriteMono(size_t idx, std::string path, float start = 0, 86 | float dur = -1); 87 | 88 | // write and interleave two mono buffers to one stereo file 89 | static void requestWriteStereo(size_t idx0, size_t idx1, std::string path, 90 | float start = 0, float dur = -1); 91 | 92 | private: 93 | static void workLoop(); 94 | 95 | static void clearBuffer(BufDesc &buf, float start = 0, float dur = -1); 96 | 97 | static void readBufferMono(const std::string &path, BufDesc &buf, 98 | float startSrc = 0, float startDst = 0, 99 | float dur = -1, int chanSrc = 0) noexcept; 100 | 101 | static void readBufferStereo(const std::string &path, BufDesc &buf0, 102 | BufDesc &buf1, float startSrc = 0, 103 | float startDst = 0, float dur = -1) noexcept; 104 | 105 | static void writeBufferMono(const std::string &path, BufDesc &buf, 106 | float start = 0, float dur = -1) noexcept; 107 | 108 | static void writeBufferStereo(const std::string &path, BufDesc &buf0, 109 | BufDesc &buf1, float start = 0, 110 | float dur = -1) noexcept; 111 | }; 112 | 113 | } // namespace softcut_jack_osc 114 | 115 | #endif // CRONE_BUFMANAGER_H 116 | -------------------------------------------------------------------------------- /clients/oooooooo/src/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by emb on 1/20/20. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "BufDiskWorker.h" 13 | #include "Display.h" 14 | #include "OscInterface.h" 15 | #include "SoftcutClient.h" 16 | 17 | // Global variables for shutdown coordination 18 | static std::unique_ptr g_display; 19 | static std::unique_ptr g_sc; 20 | static bool g_shouldQuit = false; 21 | static std::mutex g_shutdownMutex; // To protect shutdown sequence 22 | 23 | static inline void sleep(int ms) { 24 | std::this_thread::sleep_for(std::chrono::milliseconds(ms)); 25 | } 26 | 27 | // Central signal handler 28 | static void signalHandler(int sig) { 29 | std::cout << "Received signal " << sig << ", initiating shutdown..." 30 | << std::endl; 31 | 32 | // Lock to ensure exclusive access during shutdown 33 | std::lock_guard lock(g_shutdownMutex); 34 | 35 | // Set quit flag to exit main loop 36 | g_shouldQuit = true; 37 | 38 | // Request display shutdown 39 | if (g_display) { 40 | g_display->requestShutdown(); 41 | } 42 | 43 | // create a thread timer to terminate everything in two seconds 44 | std::thread([&]() { 45 | sleep(1000); 46 | std::cout << "Force quitting..." << std::endl; 47 | exit(1); 48 | }).detach(); 49 | } 50 | 51 | // Function to set the quit flag when window is closed 52 | static void onDisplayQuit() { 53 | std::cout << "Display window closed, initiating shutdown..." << std::endl; 54 | 55 | // Lock to ensure exclusive access during shutdown 56 | std::lock_guard lock(g_shutdownMutex); 57 | 58 | // Set quit flag to exit main loop 59 | g_shouldQuit = true; 60 | } 61 | 62 | int main() { 63 | using namespace softcut_jack_osc; 64 | 65 | // Set up signal handling 66 | std::signal(SIGINT, signalHandler); 67 | std::signal(SIGTERM, signalHandler); 68 | 69 | try { 70 | // Initialize SoftcutClient 71 | g_sc = std::make_unique(); 72 | g_sc->setup(); 73 | BufDiskWorker::init(static_cast(g_sc->getSampleRate())); 74 | g_sc->start(); 75 | g_sc->init(); 76 | g_sc->connectAdcPorts(); 77 | g_sc->connectDacPorts(); 78 | 79 | // Initialize OSC Interface 80 | OscInterface::init(g_sc.get()); 81 | 82 | // Create and start the display 83 | g_display = std::make_unique(800, 600); 84 | g_display->init(g_sc.get(), SoftcutClient::NumVoices); 85 | g_display->setQuitCallback(onDisplayQuit); 86 | g_display->start(); 87 | 88 | std::cout << "Entering main loop..." << std::endl; 89 | 90 | // Setup loops 91 | 92 | // Main application loop 93 | while (true) { 94 | { 95 | // Check if we should quit with mutex protection 96 | std::lock_guard lock(g_shutdownMutex); 97 | if (g_shouldQuit || OscInterface::shouldQuit()) { 98 | break; 99 | } 100 | } 101 | sleep(100); 102 | } 103 | 104 | std::cout << "Exiting main loop..." << std::endl; 105 | 106 | // Critical cleanup order: 107 | // 1. First stop the display - make sure this happens BEFORE cleaning up 108 | // OscInterface 109 | std::cout << "Stopping display..." << std::endl; 110 | if (g_display) { 111 | g_display->stop(); 112 | g_display.reset(); 113 | } 114 | 115 | // 2. Deinitialize OSC Interface 116 | std::cout << "Cleaning up OSC Interface..." << std::endl; 117 | OscInterface::deinit(); 118 | 119 | // 3. Finally stop SoftcutClient 120 | std::cout << "Stopping SoftcutClient..." << std::endl; 121 | if (g_sc) { 122 | g_sc->stop(); 123 | g_sc->cleanup(); 124 | g_sc.reset(); 125 | } 126 | 127 | std::cout << "Cleanup complete" << std::endl; 128 | return 0; 129 | 130 | } catch (const std::exception& e) { 131 | std::cerr << "Exception: " << e.what() << std::endl; 132 | return 1; 133 | } catch (...) { 134 | std::cerr << "Unknown exception!" << std::endl; 135 | return 1; 136 | } 137 | } -------------------------------------------------------------------------------- /external/windows/dlls.txt: -------------------------------------------------------------------------------- 1 | zacks@ube MSYS /c/Users/zacks/Documents/oooooooo/build 2 | $ ldd clients/oooooooo/oooooooo.exe 3 | 4 | ntdll.dll => /c/WINDOWS/SYSTEM32/ntdll.dll (0x7ff902fc0000) 5 | KERNEL32.DLL => /c/WINDOWS/System32/KERNEL32.DLL (0x7ff9026f0000) 6 | KERNELBASE.dll => /c/WINDOWS/System32/KERNELBASE.dll (0x7ff900880000) 7 | msvcrt.dll => /c/WINDOWS/System32/msvcrt.dll (0x7ff901fd0000) 8 | libgcc_s_seh-1.dll => /mingw64/bin/libgcc_s_seh-1.dll (0x7ff8e6310000) 9 | liblo-7.dll => /mingw64/bin/liblo-7.dll (0x7ff8e0f20000) 10 | WS2_32.dll => /c/WINDOWS/System32/WS2_32.dll (0x7ff902880000) 11 | RPCRT4.dll => /c/WINDOWS/System32/RPCRT4.dll (0x7ff901da0000) 12 | libwinpthread-1.dll => /mingw64/bin/libwinpthread-1.dll (0x7ff8d90f0000) 13 | libsndfile-1.dll => /mingw64/bin/libsndfile-1.dll (0x7ff8a0820000) 14 | libstdc++-6.dll => /mingw64/bin/libstdc++-6.dll (0x7ff858bb0000) 15 | libjack64.dll => /c/WINDOWS/libjack64.dll (0x7ff8577a0000) 16 | ADVAPI32.dll => /c/WINDOWS/System32/ADVAPI32.dll (0x7ff902220000) 17 | sechost.dll => /c/WINDOWS/System32/sechost.dll (0x7ff901ed0000) 18 | PSAPI.DLL => /c/WINDOWS/System32/PSAPI.DLL (0x7ff901fb0000) 19 | SHELL32.dll => /c/WINDOWS/System32/SHELL32.dll (0x7ff900dc0000) 20 | msvcp_win.dll => /c/WINDOWS/System32/msvcp_win.dll (0x7ff900500000) 21 | ucrtbase.dll => /c/WINDOWS/System32/ucrtbase.dll (0x7ff9005b0000) 22 | USER32.dll => /c/WINDOWS/System32/USER32.dll (0x7ff9022e0000) 23 | win32u.dll => /c/WINDOWS/System32/win32u.dll (0x7ff9002d0000) 24 | GDI32.dll => /c/WINDOWS/System32/GDI32.dll (0x7ff902be0000) 25 | gdi32full.dll => /c/WINDOWS/System32/gdi32full.dll (0x7ff9003c0000) 26 | wintypes.dll => /c/WINDOWS/System32/wintypes.dll (0x7ff900c50000) 27 | combase.dll => /c/WINDOWS/System32/combase.dll (0x7ff901990000) 28 | SDL2.dll => /mingw64/bin/SDL2.dll (0x7ff855f70000) 29 | IMM32.dll => /c/WINDOWS/System32/IMM32.dll (0x7ff902840000) 30 | ole32.dll => /c/WINDOWS/System32/ole32.dll (0x7ff902dc0000) 31 | OLEAUT32.dll => /c/WINDOWS/System32/OLEAUT32.dll (0x7ff902510000) 32 | SETUPAPI.dll => /c/WINDOWS/System32/SETUPAPI.dll (0x7ff901500000) 33 | SDL2_ttf.dll => /mingw64/bin/SDL2_ttf.dll (0x7ff8d3170000) 34 | IPHLPAPI.DLL => /c/WINDOWS/SYSTEM32/IPHLPAPI.DLL (0x7ff8fe980000) 35 | libFLAC.dll => /mingw64/bin/libFLAC.dll (0x7ff8ca270000) 36 | libmp3lame-0.dll => /mingw64/bin/libmp3lame-0.dll (0x7ff8c9040000) 37 | libmpg123-0.dll => /mingw64/bin/libmpg123-0.dll (0x7ff8a58c0000) 38 | SHLWAPI.dll => /c/WINDOWS/System32/SHLWAPI.dll (0x7ff902900000) 39 | libogg-0.dll => /mingw64/bin/libogg-0.dll (0x7ff8cd3b0000) 40 | libopus-0.dll => /mingw64/bin/libopus-0.dll (0x7ff8a5670000) 41 | libvorbis-0.dll => /mingw64/bin/libvorbis-0.dll (0x7ff8cd370000) 42 | libvorbisenc-2.dll => /mingw64/bin/libvorbisenc-2.dll (0x7ff8a5470000) 43 | WINMM.dll => /c/WINDOWS/SYSTEM32/WINMM.dll (0x7ff8f0110000) 44 | VERSION.dll => /c/WINDOWS/SYSTEM32/VERSION.dll (0x7ff8f9280000) 45 | libfreetype-6.dll => /mingw64/bin/libfreetype-6.dll (0x7ff85cac0000) 46 | libharfbuzz-0.dll => /mingw64/bin/libharfbuzz-0.dll (0x7ff85aff0000) 47 | libbrotlidec.dll => /mingw64/bin/libbrotlidec.dll (0x7ff8c9d00000) 48 | libbz2-1.dll => /mingw64/bin/libbz2-1.dll (0x7ff8c9ce0000) 49 | libpng16-16.dll => /mingw64/bin/libpng16-16.dll (0x7ff8b3dd0000) 50 | zlib1.dll => /mingw64/bin/zlib1.dll (0x7ff8b3890000) 51 | libglib-2.0-0.dll => /mingw64/bin/libglib-2.0-0.dll (0x7ff8594d0000) 52 | libgraphite2.dll => /mingw64/bin/libgraphite2.dll (0x7ff8b01b0000) 53 | libintl-8.dll => /mingw64/bin/libintl-8.dll (0x7ff8a3960000) 54 | USP10.dll => /c/WINDOWS/SYSTEM32/USP10.dll (0x7ff891630000) 55 | cfgmgr32.DLL => /c/WINDOWS/SYSTEM32/cfgmgr32.DLL (0x7ff8ffe00000) 56 | libbrotlicommon.dll => /mingw64/bin/libbrotlicommon.dll (0x7ff8ae280000) 57 | libpcre2-8-0.dll => /mingw64/bin/libpcre2-8-0.dll (0x7ff85cbf0000) 58 | libiconv-2.dll => /mingw64/bin/libiconv-2.dll (0x7ff85a650000) 59 | -------------------------------------------------------------------------------- /external/faust/architecture/faust/dsp/proxy-dsp.h: -------------------------------------------------------------------------------- 1 | /************************** BEGIN proxy-dsp.h *************************** 2 | FAUST Architecture File 3 | Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale 4 | --------------------------------------------------------------------- 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation; either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | 19 | EXCEPTION : As a special exception, you may create a larger work 20 | that contains this FAUST architecture section and distribute 21 | that work under terms of your choice, so long as this FAUST 22 | architecture section is not modified. 23 | ***************************************************************************/ 24 | 25 | #ifndef __proxy_dsp__ 26 | #define __proxy_dsp__ 27 | 28 | #include 29 | #include 30 | 31 | #include "faust/dsp/dsp.h" 32 | #include "faust/gui/JSONUIDecoder.h" 33 | #include "faust/gui/JSONUI.h" 34 | 35 | /** 36 | * Proxy dsp definition created from the DSP JSON description. 37 | * This class allows a 'proxy' dsp to control a real dsp 38 | * possibly running somewhere else. 39 | */ 40 | class proxy_dsp : public ::dsp { 41 | 42 | protected: 43 | 44 | JSONUIDecoder* fDecoder; 45 | int fSampleRate; 46 | 47 | void init(const std::string& json) 48 | { 49 | fDecoder = new JSONUIDecoder(json); 50 | fSampleRate = -1; 51 | } 52 | 53 | public: 54 | 55 | proxy_dsp():fDecoder(nullptr), fSampleRate(-1) 56 | {} 57 | 58 | proxy_dsp(const std::string& json) 59 | { 60 | init(json); 61 | } 62 | 63 | proxy_dsp(dsp* dsp) 64 | { 65 | JSONUI builder(dsp->getNumInputs(), dsp->getNumOutputs()); 66 | dsp->metadata(&builder); 67 | dsp->buildUserInterface(&builder); 68 | fSampleRate = dsp->getSampleRate(); 69 | fDecoder = new JSONUIDecoder(builder.JSON()); 70 | } 71 | 72 | virtual ~proxy_dsp() 73 | { 74 | delete fDecoder; 75 | } 76 | 77 | virtual int getNumInputs() { return fDecoder->fNumInputs; } 78 | virtual int getNumOutputs() { return fDecoder->fNumOutputs; } 79 | 80 | virtual void buildUserInterface(UI* ui) { fDecoder->buildUserInterface(ui); } 81 | 82 | // To possibly implement in a concrete proxy dsp 83 | virtual void init(int sample_rate) 84 | { 85 | instanceInit(sample_rate); 86 | } 87 | virtual void instanceInit(int sample_rate) 88 | { 89 | instanceConstants(sample_rate); 90 | instanceResetUserInterface(); 91 | instanceClear(); 92 | } 93 | virtual void instanceConstants(int sample_rate) { fSampleRate = sample_rate; } 94 | virtual void instanceResetUserInterface() { fDecoder->resetUserInterface(); } 95 | virtual void instanceClear() {} 96 | 97 | virtual int getSampleRate() { return fSampleRate; } 98 | 99 | virtual proxy_dsp* clone() { return new proxy_dsp(fDecoder->fJSON); } 100 | virtual void metadata(Meta* m) { fDecoder->metadata(m); } 101 | 102 | virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) {} 103 | virtual void compute(double date_usec, int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) {} 104 | 105 | }; 106 | 107 | #endif 108 | /************************** END proxy-dsp.h **************************/ 109 | -------------------------------------------------------------------------------- /softcut-lib/src/FadeCurves.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by ezra on 11/15/18. 3 | // 4 | 5 | #include "softcut/FadeCurves.h" 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "softcut/Interpolate.h" 13 | 14 | using namespace softcut; 15 | 16 | static constexpr float fpi = 3.1415926535898f; 17 | 18 | void FadeCurves::init() { 19 | setPreShape(FadeCurves::Shape::Linear); 20 | setRecShape(FadeCurves::Shape::Raised); 21 | setMinPreWindowFrames(0); 22 | setMinRecDelayFrames(0); 23 | setPreWindowRatio(1.f / 8); 24 | setRecDelayRatio(1.f / (8 * 16)); 25 | } 26 | 27 | void FadeCurves::calcRecFade() { 28 | float buf[fadeBufSize]; 29 | unsigned int n = fadeBufSize - 1; 30 | // build rec-fade curve 31 | // this will be scaled by base rec level 32 | unsigned int ndr = 33 | std::max(recDelayMinFrames, 34 | static_cast(recDelayRatio * fadeBufSize)); 35 | unsigned int nr = n - ndr; 36 | 37 | unsigned int i = 0; 38 | if (recShape == Sine) { 39 | const float phi = fpi / nr; 40 | float x = fpi; 41 | float y = 0.f; 42 | while (i < ndr) { 43 | buf[i++] = y; 44 | } 45 | while (i < n) { 46 | y = cosf(x) * 0.5f + 0.5f; 47 | buf[i++] = y; 48 | x += phi; 49 | } 50 | buf[n] = 1.f; 51 | } else if (recShape == Linear) { 52 | const float phi = 1.f / nr; 53 | float x = 0.f; 54 | while (i < ndr) { 55 | buf[i++] = x; 56 | } 57 | while (i < n) { 58 | buf[i++] = x; 59 | x += phi; 60 | } 61 | buf[n] = 1.f; 62 | } else if (recShape == Raised) { 63 | const float phi = fpi / (nr * 2); 64 | float x = 0.f; 65 | float y = 0.f; 66 | while (i < ndr) { 67 | buf[i++] = y; 68 | } 69 | while (i < n) { 70 | y = sinf(x) * -1.f; 71 | buf[i++] = y; 72 | x += phi; 73 | } 74 | buf[n] = 1.f; 75 | } else { 76 | // undefined shape. oh well 77 | return; 78 | } 79 | 80 | memcpy(recFadeBuf, buf, fadeBufSize * sizeof(float)); 81 | } 82 | 83 | void FadeCurves::calcPreFade() { 84 | float buf[fadeBufSize]; 85 | // build pre-fade curve 86 | // this will be scaled and added to the base pre value (mapping [0, 1] -> 87 | // [pre, 1]) 88 | unsigned int nwp = 89 | std::max(preWindowMinFrames, 90 | static_cast(preWindowRatio * fadeBufSize)); 91 | 92 | unsigned int i = 0; 93 | float x = 0.f; 94 | if (preShape == Sine) { 95 | const float phi = fpi / static_cast(nwp); 96 | while (i < nwp) { 97 | buf[i++] = cosf(x) * 0.5f + 0.5f; 98 | x += phi; 99 | } 100 | } else if (preShape == Linear) { 101 | const float phi = 1.f / static_cast(nwp); 102 | while (i < nwp) { 103 | buf[i++] = 1.f - x; 104 | x += phi; 105 | } 106 | } else if (recShape == Raised) { 107 | assert(preShape == Raised); 108 | const float phi = fpi / (static_cast(nwp * 2)); 109 | while (i < nwp) { 110 | buf[i++] = cosf(x); 111 | x += phi; 112 | } 113 | } else { 114 | // undefined shape. oh well 115 | return; 116 | } 117 | while (i < fadeBufSize) { 118 | buf[i++] = 0.f; 119 | } 120 | memcpy(preFadeBuf, buf, fadeBufSize * sizeof(float)); 121 | } 122 | 123 | void FadeCurves::setRecDelayRatio(float x) { 124 | recDelayRatio = x; 125 | calcRecFade(); 126 | } 127 | 128 | void FadeCurves::setPreWindowRatio(float x) { 129 | preWindowRatio = x; 130 | calcPreFade(); 131 | } 132 | 133 | void FadeCurves::setMinRecDelayFrames(unsigned int x) { 134 | recDelayMinFrames = x; 135 | calcRecFade(); 136 | } 137 | 138 | void FadeCurves::setMinPreWindowFrames(unsigned int x) { 139 | preWindowMinFrames = x; 140 | calcPreFade(); 141 | } 142 | 143 | float FadeCurves::getRecFadeValue(float x) { 144 | return Interpolate::tabLinear(recFadeBuf, x); 145 | } 146 | 147 | float FadeCurves::getPreFadeValue(float x) { 148 | return Interpolate::tabLinear(preFadeBuf, x); 149 | } 150 | 151 | void FadeCurves::setPreShape(FadeCurves::Shape x) { 152 | preShape = x; 153 | calcPreFade(); 154 | } 155 | 156 | void FadeCurves::setRecShape(FadeCurves::Shape x) { 157 | recShape = x; 158 | calcRecFade(); 159 | } 160 | -------------------------------------------------------------------------------- /external/faust/architecture/faust/midi/gramophone-midi.h: -------------------------------------------------------------------------------- 1 | /************************** BEGIN gramophone-midi.h *********************** 2 | FAUST Architecture File 3 | Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale 4 | --------------------------------------------------------------------- 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation; either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | 19 | EXCEPTION : As a special exception, you may create a larger work 20 | that contains this FAUST architecture section and distribute 21 | that work under terms of your choice, so long as this FAUST 22 | architecture section is not modified. 23 | ***************************************************************************/ 24 | 25 | #ifndef __gramophone_midi__ 26 | #define __gramophone_midi__ 27 | 28 | #include "blemidi.h" 29 | #include "esp_log.h" 30 | #include "faust/gui/meta.h" 31 | 32 | struct bt_meta : Meta 33 | { 34 | // default values 35 | std::string localName = "Gramophone"; 36 | std::string remoteName = ""; 37 | void declare(const char* key, const char* value) 38 | { 39 | if (strstr(key,"btmidi_device_name") != NULL) { 40 | localName = value; 41 | } 42 | else if (strstr(key,"btmidi_remote_name") != NULL) { 43 | remoteName = value; 44 | } 45 | } 46 | }; 47 | 48 | #define GMH_TAG "GramoMidiHandler" 49 | 50 | class gramophone_midi : public midi_handler { 51 | 52 | private: 53 | 54 | bt_meta fBTMeta; 55 | 56 | static void callback_midi_message_received(uint8_t blemidi_port, 57 | uint16_t timestamp, 58 | uint8_t midi_status, 59 | uint8_t* remaining_message, 60 | size_t len, 61 | size_t continued_sysex_pos, 62 | void* arg) 63 | { 64 | gramophone_midi* midi = static_cast(arg); 65 | if (len == 1) { 66 | midi->handleData1(timestamp,(int)midi_status,0, 67 | (int)remaining_message[0]); 68 | } else if (len == 2) { 69 | midi->handleData2(timestamp,(int)midi_status,0, 70 | (int)remaining_message[0], 71 | (int)remaining_message[1]); 72 | } 73 | } 74 | 75 | public: 76 | 77 | gramophone_midi(bt_meta& btMeta) : midi_handler("gramophone") 78 | { 79 | fBTMeta = btMeta; 80 | } 81 | 82 | virtual ~gramophone_midi() 83 | { 84 | stopMidi(); 85 | } 86 | 87 | bool startMidi() 88 | { 89 | int status = blemidi_init((void*)callback_midi_message_received, fBTMeta.localName.c_str(), fBTMeta.remoteName.c_str(), (void*)this); 90 | if (status < 0) { 91 | ESP_LOGE(GMH_TAG, "BLE MIDI Driver returned status=%d", status); 92 | return false; 93 | } else { 94 | ESP_LOGI(GMH_TAG, "BLE MIDI Driver initialized successfully"); 95 | return true; 96 | } 97 | } 98 | 99 | void stopMidi() 100 | { 101 | // This should probably implemented eventually but it can remaind as is for now 102 | } 103 | 104 | }; 105 | 106 | #endif 107 | /************************** END gramophone-midi.h **************************/ 108 | -------------------------------------------------------------------------------- /external/faust/architecture/faust/audio/audio.h: -------------------------------------------------------------------------------- 1 | /************************** BEGIN audio.h ***************************** 2 | FAUST Architecture File 3 | Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale 4 | --------------------------------------------------------------------- 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation; either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | 19 | EXCEPTION : As a special exception, you may create a larger work 20 | that contains this FAUST architecture section and distribute 21 | that work under terms of your choice, so long as this FAUST 22 | architecture section is not modified. 23 | ***********************************************************************/ 24 | 25 | #ifndef __audio__ 26 | #define __audio__ 27 | 28 | #include 29 | #include 30 | 31 | class dsp; 32 | 33 | typedef void (* shutdown_callback)(const char* message, void* arg); 34 | 35 | typedef void (* compute_callback)(void* arg); 36 | 37 | class audio { 38 | 39 | protected: 40 | 41 | shutdown_callback fShutdown; // Shutdown callback 42 | void* fShutdownArg; // Shutdown callback data 43 | 44 | std::set > fComputeCallbackList; 45 | 46 | public: 47 | 48 | audio():fShutdown(nullptr), fShutdownArg(nullptr) {} 49 | virtual ~audio() {} 50 | 51 | /** 52 | * Init the DSP. 53 | * @param name - the DSP name to be given to the audio driven 54 | * (could appear as a JACK client for instance) 55 | * @param dsp - the dsp that will be initialized with the driver sample rate 56 | * 57 | * @return true is sucessful, false in case of driver failure. 58 | **/ 59 | virtual bool init(const char* name, ::dsp* dsp) = 0; 60 | 61 | /** 62 | * Start audio processing. 63 | * @return true is sucessful, false if case of driver failure. 64 | **/ 65 | virtual bool start() = 0; 66 | 67 | /** 68 | * Stop audio processing. 69 | **/ 70 | virtual void stop() = 0; 71 | 72 | void setShutdownCallback(shutdown_callback cb, void* arg) 73 | { 74 | fShutdown = cb; 75 | fShutdownArg = arg; 76 | } 77 | 78 | void addControlCallback(compute_callback cb, void* arg) 79 | { 80 | fComputeCallbackList.insert(std::make_pair(cb, arg)); 81 | } 82 | 83 | bool removeControlCallback(compute_callback cb, void* arg) 84 | { 85 | return (fComputeCallbackList.erase(std::make_pair(cb, arg)) == 1); 86 | } 87 | 88 | void runControlCallbacks() 89 | { 90 | for (const auto& it : fComputeCallbackList) { 91 | it.first(it.second); 92 | } 93 | } 94 | 95 | // Return buffer size in frames. 96 | virtual int getBufferSize() = 0; 97 | 98 | // Return the driver sample rate in Hz. 99 | virtual int getSampleRate() = 0; 100 | 101 | // Return the driver hardware inputs number. 102 | virtual int getNumInputs() = 0; 103 | 104 | // Return the driver hardware outputs number. 105 | virtual int getNumOutputs() = 0; 106 | 107 | /** 108 | * @return Returns the average proportion of available CPU 109 | * being spent inside the audio callbacks (between 0.0 and 1.0). 110 | **/ 111 | virtual float getCPULoad() { return 0.f; } 112 | }; 113 | 114 | #endif 115 | /************************** END audio.h **************************/ 116 | -------------------------------------------------------------------------------- /external/faust/architecture/faust/audio/channels.h: -------------------------------------------------------------------------------- 1 | /************************** BEGIN channels.h ************************** 2 | FAUST Architecture File 3 | Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale 4 | --------------------------------------------------------------------- 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation; either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | 19 | EXCEPTION : As a special exception, you may create a larger work 20 | that contains this FAUST architecture section and distribute 21 | that work under terms of your choice, so long as this FAUST 22 | architecture section is not modified. 23 | ************************************************************************/ 24 | 25 | #ifndef __audio_channels__ 26 | #define __audio_channels__ 27 | 28 | #include 29 | #include 30 | 31 | #ifndef FAUSTFLOAT 32 | #define FAUSTFLOAT float 33 | #endif 34 | 35 | template 36 | class real_channels 37 | { 38 | private: 39 | 40 | int fNumFrames; 41 | int fNumChannels; 42 | REAL** fBuffers; 43 | REAL** fSliceBuffers; 44 | 45 | public: 46 | 47 | real_channels(int nframes, int nchannels) 48 | { 49 | fBuffers = new REAL*[nchannels]; 50 | fSliceBuffers = new REAL*[nchannels]; 51 | fNumFrames = nframes; 52 | fNumChannels = nchannels; 53 | 54 | // allocate audio channels 55 | for (int chan = 0; chan < fNumChannels; chan++) { 56 | fBuffers[chan] = new FAUSTFLOAT[fNumFrames]; 57 | } 58 | 59 | zero(); 60 | } 61 | 62 | void zero() 63 | { 64 | // clear audio channels 65 | for (int chan = 0; chan < fNumChannels; chan++) { 66 | memset(fBuffers[chan], 0, sizeof(REAL) * fNumFrames); 67 | } 68 | } 69 | 70 | void impulse() 71 | { 72 | // set first sample to 1 for all channels 73 | for (int chan = 0; chan < fNumChannels; chan++) { 74 | fBuffers[chan][0] = FAUSTFLOAT(1.0); 75 | for (int frame = 1; frame < fNumFrames; frame++) { 76 | fBuffers[chan][frame] = REAL(0.0); 77 | } 78 | } 79 | } 80 | 81 | void display() 82 | { 83 | for (int chan = 0; chan < fNumChannels; chan++) { 84 | for (int frame = 0; frame < fNumFrames; frame++) { 85 | std::cout << "chan = " << chan << " frame = " << frame << " value = " << fBuffers[chan][frame] << std::endl; 86 | } 87 | } 88 | } 89 | 90 | virtual ~real_channels() 91 | { 92 | // free separate input channels 93 | for (int chan = 0; chan < fNumChannels; chan++) { 94 | delete [] fBuffers[chan]; 95 | } 96 | delete [] fBuffers; 97 | delete [] fSliceBuffers; 98 | } 99 | 100 | REAL** buffers() { return fBuffers; } 101 | 102 | REAL** buffers(int index) 103 | { 104 | assert(index < fNumFrames); 105 | for (int chan = 0; chan < fNumChannels; chan++) { 106 | fSliceBuffers[chan] = &fBuffers[chan][index]; 107 | } 108 | return fSliceBuffers; 109 | } 110 | 111 | }; 112 | 113 | class channels : public real_channels { 114 | 115 | public: 116 | 117 | channels(int nframes, int nchannels):real_channels(nframes, nchannels) {} 118 | }; 119 | 120 | #endif 121 | 122 | /************************** END channels.h **************************/ 123 | -------------------------------------------------------------------------------- /external/faust/architecture/faust/gui/Esp32Reader.h: -------------------------------------------------------------------------------- 1 | /************************** BEGIN Esp32Reader.h ************************** 2 | FAUST Architecture File 3 | Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale 4 | --------------------------------------------------------------------- 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation; either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | 19 | EXCEPTION : As a special exception, you may create a larger work 20 | that contains this FAUST architecture section and distribute 21 | that work under terms of your choice, so long as this FAUST 22 | architecture section is not modified. 23 | *************************************************************************/ 24 | 25 | #ifndef FAUST_ESP32READER_H 26 | #define FAUST_ESP32READER_H 27 | 28 | #include 29 | #include "esp_err.h" 30 | #include "esp_log.h" 31 | #include "esp_spi_flash.h" 32 | #include "esp_vfs_fat.h" 33 | #include "driver/sdspi_host.h" 34 | #include "sdmmc_cmd.h" 35 | 36 | #include "faust/gui/WaveReader.h" 37 | 38 | #define TAG "Esp32Reader" 39 | 40 | #define SD_PIN_NUM_MISO GPIO_NUM_2 41 | #define SD_PIN_NUM_MOSI GPIO_NUM_15 42 | #define SD_PIN_NUM_CLK GPIO_NUM_14 43 | #define SD_PIN_NUM_CS GPIO_NUM_13 44 | 45 | struct Esp32Reader : public WaveReader { 46 | 47 | void sdcard_init() 48 | { 49 | ESP_LOGI(TAG, "Initializing SD card"); 50 | ESP_LOGI(TAG, "Using SPI peripheral"); 51 | 52 | sdmmc_host_t host = SDSPI_HOST_DEFAULT(); 53 | sdspi_slot_config_t slot_config = SDSPI_SLOT_CONFIG_DEFAULT(); 54 | slot_config.gpio_miso = SD_PIN_NUM_MISO; 55 | slot_config.gpio_mosi = SD_PIN_NUM_MOSI; 56 | slot_config.gpio_sck = SD_PIN_NUM_CLK; 57 | slot_config.gpio_cs = SD_PIN_NUM_CS; 58 | // This initializes the slot without card detect (CD) and write protect (WP) signals. 59 | // Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals. 60 | 61 | // Options for mounting the filesystem. 62 | // If format_if_mount_failed is set to true, SD card will be partitioned and 63 | // formatted in case when mounting fails. 64 | esp_vfs_fat_sdmmc_mount_config_t mount_config = { 65 | .format_if_mount_failed = false, 66 | .max_files = 5, 67 | .allocation_unit_size = 16 * 1024 68 | }; 69 | 70 | // Use settings defined above to initialize SD card and mount FAT filesystem. 71 | // Note: esp_vfs_fat_sdmmc_mount is an all-in-one convenience function. 72 | // Please check its source code and implement error recovery when developing 73 | // production applications. 74 | sdmmc_card_t* card; 75 | esp_err_t ret = esp_vfs_fat_sdmmc_mount("/sdcard", &host, &slot_config, &mount_config, &card); 76 | 77 | if (ret != ESP_OK) { 78 | if (ret == ESP_FAIL) { 79 | ESP_LOGE(TAG, "Failed to mount filesystem. " 80 | "If you want the card to be formatted, set format_if_mount_failed = true."); 81 | } else { 82 | ESP_LOGE(TAG, "Failed to initialize the card (%s). " 83 | "Make sure SD card lines have pull-up resistors in place.", esp_err_to_name(ret)); 84 | } 85 | return; 86 | } 87 | 88 | // Card has been initialized, print its properties 89 | sdmmc_card_print_info(stdout, card); 90 | ESP_LOGI(TAG, "SD card initialized"); 91 | } 92 | 93 | Esp32Reader() 94 | { 95 | sdcard_init(); 96 | } 97 | 98 | // Access methods inherited from WaveReader 99 | }; 100 | 101 | #endif // FAUST_ESP32READER_H 102 | /************************** END Esp32Reader.h **************************/ 103 | -------------------------------------------------------------------------------- /clients/oooooooo/src/Parameters.h: -------------------------------------------------------------------------------- 1 | #ifndef LIB_PARAMETERS_H 2 | #define LIB_PARAMETERS_H 3 | #pragma once 4 | 5 | #include "DrawFunctions.h" 6 | #include "Parameter.h" 7 | #include "Serializable.h" 8 | #include "SoftcutClient.h" 9 | 10 | using namespace softcut_jack_osc; 11 | 12 | class Parameters : public Serializable { 13 | public: 14 | // Parameters 15 | enum ParameterName { 16 | PARAM_LEVEL, 17 | PARAM_PAN, 18 | PARAM_PREGAIN, 19 | PARAM_BIAS, 20 | PARAM_LPF, 21 | PARAM_REVERB, 22 | PARAM_REVERB_DECAY, 23 | PARAM_REVERB_DENSITY, 24 | PARAM_RATE, 25 | PARAM_DIRECTION, 26 | PARAM_START, 27 | PARAM_DURATION, 28 | PARAM_REC_LEVEL, 29 | PARAM_PRE_LEVEL, 30 | PARAM_REC_SLEW, 31 | PARAM_LEVEL_SLEW, 32 | PARAM_RATE_SLEW, 33 | PARAM_PAN_SLEW, 34 | PARAM_FADE_TIME, 35 | PARAM_MIC_INPUT, 36 | PARAM_LOOP1_FEEDBACK, 37 | PARAM_LOOP2_FEEDBACK, 38 | PARAM_LOOP3_FEEDBACK, 39 | PARAM_LOOP4_FEEDBACK, 40 | PARAM_LOOP5_FEEDBACK, 41 | PARAM_LOOP6_FEEDBACK, 42 | PARAM_LOOP7_FEEDBACK, 43 | PARAM_LOOP8_FEEDBACK, 44 | PARAM_PRIME_SENSITIVITY, 45 | PARAM_PRIME_QUANTIZE, 46 | PARAM_BASE_RATE, 47 | PARAM_COUNT // Holds the number of parameters 48 | }; 49 | Parameter param_[PARAM_COUNT]; 50 | 51 | Parameters() = default; 52 | ~Parameters() = default; 53 | JSON toJSON() const override { 54 | JSON json; 55 | for (int i = 0; i < PARAM_COUNT; i++) { 56 | json[param_[i].Name()] = param_[i].toJSON(); 57 | } 58 | return json; 59 | } 60 | void fromJSON(const JSON& json) override { 61 | for (int i = 0; i < PARAM_COUNT; i++) { 62 | param_[i].fromJSON(json[param_[i].Name()]); 63 | } 64 | } 65 | 66 | void Init(SoftcutClient* sc, int voice, float sample_rate); 67 | 68 | void ValueDelta(float delta) { param_[selected_].ValueDelta(delta); } 69 | void ValueToggle(ParameterName p) { param_[p].Toggle(); } 70 | 71 | void ValueSet(ParameterName p, float value, bool quiet) { 72 | param_[p].ValueSet(value, quiet); 73 | } 74 | void ValueSetRaw(ParameterName p, float value, bool quiet) { 75 | param_[p].ValueSetRaw(value, quiet); 76 | } 77 | 78 | void LFODelta(float min_delta, float max_delta) { 79 | param_[selected_].LFODelta(min_delta, max_delta); 80 | } 81 | 82 | void ToggleLFO() { param_[selected_].ToggleLFO(); } 83 | 84 | void ToggleView(); // Add this method 85 | 86 | void Render(SDL_Renderer* renderer, TTF_Font* font, int x, int y, int width, 87 | int height, float brightness = 1.0f); // Add brightness parameter 88 | 89 | void UpdateFade(); // Add this method to update fade animation 90 | 91 | void Update(); 92 | 93 | void Bang() { 94 | for (int i = 0; i < PARAM_COUNT; i++) { 95 | param_[i].Bang(); 96 | } 97 | } 98 | 99 | float GetRaw(ParameterName p) { return param_[p].GetRaw(); } 100 | float GetValue(ParameterName p) { return param_[p].GetValue(); } 101 | float GetRawMin(ParameterName p) { return param_[p].GetRawMin(); } 102 | float GetRawMax(ParameterName p) { return param_[p].GetRawMax(); } 103 | void SetMax(ParameterName p, float max) { param_[p].SetMax(max); } 104 | void DeltaLFOPeriod(float delta) { param_[selected_].DeltaLFOPeriod(delta); } 105 | 106 | void SetSelected(int selected) { selected_ = selected; } 107 | int GetSelected() const { return selected_; } 108 | void SelectedDelta_(int delta) { 109 | selected_ += delta; 110 | while (selected_ < 0) selected_ += PARAM_COUNT; 111 | while (selected_ >= PARAM_COUNT) selected_ -= PARAM_COUNT; 112 | } 113 | void SelectedDelta(int delta) { 114 | SelectedDelta_(delta); 115 | while (param_[selected_].IsHidden()) { 116 | SelectedDelta_(delta); 117 | } 118 | } 119 | 120 | bool RegisterClick(float mouseX, float mouseY, bool dragging) { 121 | if (!view_visible_) { 122 | return false; 123 | } 124 | for (int i = 0; i < PARAM_COUNT; i++) { 125 | if (param_[i].IsHidden() || (dragging && i != selected_)) { 126 | continue; 127 | } 128 | if (param_[i].RegisterClick(mouseX, mouseY, dragging)) { 129 | selected_ = i; 130 | return true; 131 | } 132 | } 133 | return false; 134 | } 135 | 136 | private: 137 | bool view_visible_ = false; 138 | int voice_ = 0; 139 | float fade_amount_ = 1.0f; 140 | float fade_target_ = 1.0f; 141 | float fade_speed_ = 0.05f; // Adjust this for faster/slower fade 142 | 143 | SoftcutClient* softCutClient_ = nullptr; 144 | static int selected_; 145 | float sample_rate_ = 0.0f; 146 | }; 147 | 148 | #endif -------------------------------------------------------------------------------- /external/faust/architecture/faust/audio/osc-dsp.h: -------------------------------------------------------------------------------- 1 | /************************** BEGIN osc-dsp.h ***************************** 2 | FAUST Architecture File 3 | Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale 4 | --------------------------------------------------------------------- 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation; either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | 19 | EXCEPTION : As a special exception, you may create a larger work 20 | that contains this FAUST architecture section and distribute 21 | that work under terms of your choice, so long as this FAUST 22 | architecture section is not modified. 23 | ************************************************************************/ 24 | 25 | #ifndef __osc_dsp__ 26 | #define __osc_dsp__ 27 | 28 | #include 29 | #include "faust/audio/audio.h" 30 | #include "faust/dsp/dsp.h" 31 | #include "OSCIO.h" 32 | 33 | /****************************************************************************** 34 | ******************************************************************************* 35 | 36 | OSC AUDIO INTERFACE 37 | 38 | ******************************************************************************* 39 | *******************************************************************************/ 40 | 41 | #define kMaxBuffer 4096 42 | 43 | class oscdsp : public audio, public oscfaust::OSCIO { 44 | 45 | private: 46 | 47 | ::dsp* fDSP; 48 | float **fInBuffers, **fOutBuffers; 49 | 50 | public: 51 | 52 | oscdsp(const char* dst, int argc, char* argv[]) 53 | : OSCIO(dst), fDSP(nullptr), fInBuffers(nullptr), fOutBuffers(nullptr) 54 | { 55 | for (int i = 1; i < argc-1; i++) { 56 | if (!strcmp(argv[i], "-iodst")) setDest (argv[i+1]); 57 | } 58 | } 59 | 60 | virtual ~oscdsp() 61 | { 62 | stop(); 63 | for (int i = 0; i < numInputs(); i++) { 64 | delete [] fInBuffers[i]; 65 | } 66 | for (int i = 0; i < numOutputs(); i++) { 67 | delete [] fOutBuffers[i]; 68 | } 69 | delete [] fInBuffers; 70 | delete [] fOutBuffers; 71 | } 72 | 73 | virtual bool init(const char* name, ::dsp* DSP) 74 | { 75 | fDSP = DSP; 76 | fDSP->init(44100); 77 | fInBuffers = new float*[numInputs()]; 78 | fOutBuffers = new float*[numOutputs()]; 79 | for (int i = 0; i < numInputs(); i++) { 80 | fInBuffers[i] = new float[kMaxBuffer]; 81 | } 82 | for (int i = 0; i < numOutputs(); i++) { 83 | fOutBuffers [i] = new float[kMaxBuffer]; 84 | } 85 | return true; 86 | } 87 | 88 | virtual bool start() { return true; } 89 | virtual void stop() {} 90 | 91 | void compute(int nframes) 92 | { 93 | fDSP->compute(nframes, fInBuffers, fOutBuffers); 94 | for (int i = 0; i < numOutputs(); i++) { 95 | send(nframes, fOutBuffers [i], i); 96 | } 97 | } 98 | 99 | void receive(int nvalues, float* val) 100 | { 101 | int inChans = numInputs(); 102 | if (!inChans) { 103 | compute(nvalues); 104 | return; 105 | } 106 | 107 | for (int i = 0; i < nvalues; i++) { 108 | int c = i % inChans; 109 | int frame = i / inChans; 110 | fInBuffers[c][frame] = val[i]; 111 | } 112 | compute(nvalues / inChans); 113 | } 114 | 115 | int getNumInputs() const { return fDSP ? fDSP->getNumInputs() : 0; } 116 | int getNumOutputs() const { return fDSP ? fDSP->getNumOutputs() : 0; } 117 | 118 | }; 119 | 120 | #endif 121 | /************************** END osc-dsp.h **************************/ 122 | -------------------------------------------------------------------------------- /external/faust/architecture/faust/midi/daisy-midi.h: -------------------------------------------------------------------------------- 1 | /************************** BEGIN daisy-midi.h **************************** 2 | FAUST Architecture File 3 | Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale 4 | --------------------------------------------------------------------- 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation; either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | 19 | EXCEPTION : As a special exception, you may create a larger work 20 | that contains this FAUST architecture section and distribute 21 | that work under terms of your choice, so long as this FAUST 22 | architecture section is not modified. 23 | ***************************************************************************/ 24 | 25 | #ifndef __daisy_midi__ 26 | #define __daisy_midi__ 27 | 28 | #include 29 | 30 | #include "daisysp.h" 31 | #include "faust/midi/midi.h" 32 | #include "faust/gui/GUI.h" 33 | 34 | class daisy_midi : public midi_handler { 35 | 36 | private: 37 | 38 | daisy::MidiHandler fMidi; 39 | daisy::MidiHandler::Config fConfig; 40 | 41 | public: 42 | 43 | daisy_midi():midi_handler("daisy") 44 | {} 45 | 46 | virtual ~daisy_midi() 47 | { 48 | stopMidi(); 49 | } 50 | 51 | bool startMidi() 52 | { 53 | fMidi.Init(fConfig); 54 | return true; 55 | } 56 | 57 | void stopMidi() 58 | {} 59 | 60 | void processMidi() 61 | { 62 | fMidi.Listen(); 63 | while (fMidi.HasEvents()) { 64 | 65 | double time = 0.; 66 | daisy::MidiEvent m = fMidi.PopEvent(); 67 | switch(m.type) { 68 | 69 | case daisy::MidiMessageType::NoteOff: { 70 | // TODO 71 | //NoteOff p = m.AsNoteOff(); 72 | //handleKeyOff(time, p.channel, p.note, p.velocity); 73 | break; 74 | } 75 | 76 | case daisy::MidiMessageType::NoteOn: { 77 | daisy::NoteOnEvent p = m.AsNoteOn(); 78 | handleKeyOn(time, p.channel, p.note, p.velocity); 79 | break; 80 | } 81 | 82 | case daisy::MidiMessageType::PolyphonicKeyPressure: { 83 | // TODO 84 | //handlePolyAfterTouch(time, m.channel, m.control_number, m.value); 85 | break; 86 | } 87 | 88 | case daisy::MidiMessageType::ControlChange: { 89 | daisy::ControlChangeEvent p = m.AsControlChange(); 90 | handleCtrlChange(time, p.channel, p.control_number, p.value); 91 | break; 92 | } 93 | 94 | case daisy::MidiMessageType::ProgramChange: { 95 | // TODO 96 | //handleProgChange(time, p.channel, p.control_number, p.value); 97 | break; 98 | } 99 | 100 | case daisy::MidiMessageType::PitchBend: { 101 | // TODO 102 | //handlePitchWheel(time, p.channel, p.control_number, p.value); 103 | break; 104 | } 105 | 106 | default: 107 | break; 108 | } 109 | } 110 | // Synchronize all GUI controllers 111 | GUI::updateAllGuis(); 112 | } 113 | 114 | }; 115 | 116 | #endif 117 | /************************** END daisy-midi.h **************************/ 118 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | release: 5 | types: [created] 6 | workflow_dispatch: 7 | 8 | 9 | jobs: 10 | linux: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v4 14 | with: 15 | submodules: true 16 | 17 | - name: Install dependencies 18 | run: | 19 | sudo apt-get update 20 | sudo apt-get install -y libjack-jackd2-dev liblo-dev libsdl2-dev libsdl2-ttf-dev librtmidi-dev libsndfile1-dev libflac-dev patchelf libfuse-dev cmake 21 | 22 | - name: Build project 23 | run: make 24 | 25 | - name: Create release 26 | run: ./build-appimage.sh 27 | 28 | - name: Create release artifact 29 | run: | 30 | cp oooooooo.AppImage oooooooo_${{ github.event.release.name }}.AppImage 31 | ls -lSh oooooooo_${{ github.event.release.name }}.AppImage 32 | 33 | - name: Release 34 | uses: softprops/action-gh-release@v2 35 | with: 36 | files: | 37 | oooooooo_${{ github.event.release.name }}.AppImage 38 | 39 | # macos: 40 | # runs-on: macos-latest 41 | # steps: 42 | # - uses: actions/checkout@v4 43 | # with: 44 | # submodules: true 45 | 46 | # - name: Install dependencies 47 | # run: | 48 | # brew update 49 | # brew install jack liblo sdl2 sdl2_ttf rtmidi libsndfile flac create-dmg fuse cmake 50 | 51 | # - name: Set PKG_CONFIG_PATH 52 | # run: echo "PKG_CONFIG_PATH=/opt/homebrew/lib/pkgconfig" >> $GITHUB_ENV 53 | 54 | # - name: Build project 55 | # run: | 56 | # export PKG_CONFIG_PATH="/opt/homebrew/lib/pkgconfig:/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH" 57 | # export CXXFLAGS="-I/opt/homebrew/include -I/usr/local/include" 58 | # export LDFLAGS="-L/opt/homebrew/lib -L/usr/local/lib" 59 | # export PATH="/opt/homebrew/bin:$PATH" 60 | # make 61 | # - name: Build macOS app 62 | # run: | 63 | # chmod +x build-macapp.sh 64 | # ./build-macapp.sh 65 | # - name: Create release artifact 66 | # run: | 67 | # ls -lSh 68 | # cp oooooooo.dmg oooooooo_${{ github.event.release.name }}.dmg 69 | 70 | # - name: Release 71 | # uses: softprops/action-gh-release@v2 72 | # with: 73 | # files: | 74 | # oooooooo_${{ github.event.release.name }}.dmg 75 | 76 | windows: 77 | runs-on: windows-latest 78 | steps: 79 | - uses: actions/checkout@v4 80 | with: 81 | submodules: true 82 | - name: Setup MSYS2 83 | uses: msys2/setup-msys2@v2 84 | with: 85 | msystem: MINGW64 86 | update: true 87 | install: >- 88 | mingw-w64-x86_64-gcc 89 | mingw-w64-x86_64-pkg-config 90 | mingw-w64-x86_64-python 91 | mingw-w64-x86_64-jack2 92 | mingw-w64-x86_64-liblo 93 | mingw-w64-x86_64-SDL2 94 | mingw-w64-x86_64-SDL2_ttf 95 | mingw-w64-x86_64-rtmidi 96 | mingw-w64-x86_64-libsndfile 97 | mingw-w64-x86_64-flac 98 | mingw-w64-x86_64-make 99 | mingw-w64-x86_64-cmake 100 | zip 101 | - name: Check MSYS2 environment 102 | shell: msys2 {0} 103 | run: | 104 | which gcc 105 | which g++ 106 | echo $PATH 107 | cmake --version 108 | pkg-config --libs jack 109 | ls -la /mingw64/lib/*jack* 110 | - name: Build in MSYS2 environment 111 | shell: msys2 {0} 112 | run: | 113 | mkdir -p build 114 | cd build 115 | export PATH="/mingw64/bin:$PATH" 116 | export PKG_CONFIG_PATH="/mingw64/lib/pkgconfig:$PKG_CONFIG_PATH" 117 | export MINGW_PREFIX="/mingw64" 118 | cmake -DCMAKE_BUILD_TYPE=Release \ 119 | -DCMAKE_PREFIX_PATH=/mingw64 \ 120 | .. 121 | cmake --build . --config Release 122 | - name: Create release artifact 123 | shell: msys2 {0} 124 | run: | 125 | mkdir oooooooo 126 | cp build/clients/oooooooo/oooooooo.exe oooooooo/ 127 | cp external/windows/*.dll oooooooo/ 128 | zip -r oooooooo_${{ github.event.release.name }}.zip oooooooo 129 | ls -lSh oooooooo_${{ github.event.release.name }}.zip 130 | 131 | - name: Release 132 | uses: softprops/action-gh-release@v2 133 | with: 134 | files: | 135 | oooooooo_${{ github.event.release.name }}.zip -------------------------------------------------------------------------------- /external/faust/architecture/faust/sound-file.h: -------------------------------------------------------------------------------- 1 | /************************** BEGIN sound-file.h ***************************** 2 | FAUST Architecture File 3 | Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale 4 | --------------------------------------------------------------------- 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation; either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | 19 | EXCEPTION : As a special exception, you may create a larger work 20 | that contains this FAUST architecture section and distribute 21 | that work under terms of your choice, so long as this FAUST 22 | architecture section is not modified. 23 | ***************************************************************************/ 24 | 25 | #ifndef __SoundFileReader__ 26 | #define __SoundFileReader__ 27 | 28 | #include 29 | #include 30 | 31 | #define BUFFER_SIZE 1024 32 | 33 | #ifndef FAUSTFLOAT 34 | #define READ_SAMPLE sf_readf_float 35 | #define FAUSTFLOAT float 36 | #else 37 | #define READ_SAMPLE sf_readf_double 38 | #define FAUSTFLOAT double 39 | #endif 40 | 41 | #ifdef __cplusplus 42 | extern "C" { 43 | #endif 44 | 45 | typedef struct SoundFileReader { 46 | FAUSTFLOAT** fBuffer; 47 | SNDFILE* fSoundFile; 48 | int fChannels; 49 | int fFramesNum; 50 | } SoundFileReader; 51 | 52 | inline static SoundFileReader* createSFR(const char* name) 53 | { 54 | SoundFileReader* reader = (SoundFileReader*)calloc(1, sizeof(SoundFileReader)); 55 | if (!reader) return NULL; 56 | 57 | { 58 | SF_INFO snd_info; 59 | snd_info.format = 0; 60 | reader->fSoundFile = sf_open(name, SFM_READ, &snd_info); 61 | 62 | if (!reader->fSoundFile) { 63 | printf("soundfile '%s' cannot be opened\n", name); 64 | goto error; 65 | } 66 | 67 | reader->fChannels = snd_info.channels; 68 | reader->fFramesNum = snd_info.frames; 69 | 70 | reader->fBuffer = (FAUSTFLOAT**)malloc(reader->fChannels * sizeof(FAUSTFLOAT*)); 71 | if (!reader) goto error; 72 | 73 | for (int i = 0; i < reader->fChannels; i++) { 74 | reader->fBuffer[i] = (FAUSTFLOAT*)malloc(reader->fFramesNum * sizeof(FAUSTFLOAT)); 75 | if (!reader->fBuffer[i]) goto error; 76 | } 77 | 78 | // Read file in memory 79 | int nbf, cur_index = 0; 80 | FAUSTFLOAT buffer[BUFFER_SIZE * reader->fChannels]; 81 | do { 82 | nbf = READ_SAMPLE(reader->fSoundFile, buffer, BUFFER_SIZE); 83 | for (int sample = 0; sample < nbf; sample++) { 84 | for (int chan = 0; chan < reader->fChannels; chan++) { 85 | reader->fBuffer[chan][cur_index + sample] = buffer[sample * reader->fChannels + chan]; 86 | } 87 | } 88 | cur_index += nbf; 89 | } while (nbf == BUFFER_SIZE); 90 | 91 | return reader; 92 | } 93 | 94 | error: 95 | if (reader->fBuffer) free(reader->fBuffer); 96 | if (reader) free(reader); 97 | return NULL; 98 | } 99 | 100 | inline static void destroySFR(SoundFileReader* reader) 101 | { 102 | if (reader) { 103 | sf_close(reader->fSoundFile); 104 | for (int i = 0; i < reader->fChannels; i++) { 105 | free(reader->fBuffer[i]); 106 | } 107 | free(reader->fBuffer); 108 | free(reader); 109 | } 110 | } 111 | 112 | inline static int sizeSFR(SoundFileReader* reader) 113 | { 114 | return (reader) ? reader->fFramesNum : 1; 115 | } 116 | 117 | inline static int channelsSFR(SoundFileReader* reader) 118 | { 119 | return (reader) ? reader->fChannels : 1; 120 | } 121 | 122 | inline static FAUSTFLOAT sampleSFR(SoundFileReader* reader, int channel, int index) 123 | { 124 | return (reader) ? reader->fBuffer[channel][index] : 0.f; 125 | } 126 | 127 | #ifdef __cplusplus 128 | } 129 | #endif 130 | 131 | #endif 132 | /************************** END sound-file.h **************************/ 133 | -------------------------------------------------------------------------------- /external/faust/architecture/faust/dsp/dsp-checker.h: -------------------------------------------------------------------------------- 1 | /************************** BEGIN dsp-checker.h ************************** 2 | FAUST Architecture File 3 | Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale 4 | --------------------------------------------------------------------- 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation; either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | 19 | EXCEPTION : As a special exception, you may create a larger work 20 | that contains this FAUST architecture section and distribute 21 | that work under terms of your choice, so long as this FAUST 22 | architecture section is not modified. 23 | ************************************************************************/ 24 | 25 | #ifndef __dsp_checker__ 26 | #define __dsp_checker__ 27 | 28 | #include 29 | #include 30 | 31 | #include "faust/dsp/dsp.h" 32 | #include "faust/audio/fpe.h" 33 | 34 | //------------------------------------------------------------------------------ 35 | // dsp_me_checker: a DSP decorator to check math Floating Point Exceptions (FPE) 36 | // - when 'runtime' is true FPE checking is done with signals/exceptions 37 | // and the program exit at first exception 38 | // - when 'runtime' is false FPE checking is done while running and 39 | // SUBNORMAL, INFINITE, NAN statistics can be displayed with printStats() 40 | //------------------------------------------------------------------------------ 41 | 42 | class dsp_me_checker : public decorator_dsp 43 | { 44 | 45 | private: 46 | 47 | long long fFP_SUBNORMAL; 48 | long long fFP_INFINITE; 49 | long long fFP_NAN; 50 | bool fRuntime; 51 | 52 | void getStats(int cout, FAUSTFLOAT** outputs) 53 | { 54 | for (int chan = 0; chan < fDSP->getNumOutputs(); chan++) { 55 | for (int frame = 0; frame < cout; frame++) { 56 | FAUSTFLOAT value = outputs[chan][frame]; 57 | if (std::isnan(value)) { 58 | fFP_NAN++; 59 | } else if (std::isinf(value)) { 60 | fFP_INFINITE++; 61 | } else if (std::fpclassify(value) == FP_SUBNORMAL) { 62 | fFP_SUBNORMAL++; 63 | } 64 | } 65 | } 66 | } 67 | 68 | public: 69 | 70 | dsp_me_checker(::dsp* dsp, bool runtime = false) 71 | :decorator_dsp(dsp), 72 | fFP_SUBNORMAL(0), 73 | fFP_INFINITE(0), 74 | fFP_NAN(0), 75 | fRuntime(runtime) 76 | {} 77 | 78 | virtual ~dsp_me_checker() {} 79 | 80 | void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) 81 | { 82 | if (fRuntime) { 83 | TRY_FPE 84 | fDSP->compute(count, inputs, outputs); 85 | CATCH_FPE 86 | } else { 87 | fDSP->compute(count, inputs, outputs); 88 | getStats(count, outputs); 89 | } 90 | } 91 | void compute(double date_usec, int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) 92 | { 93 | if (fRuntime) { 94 | TRY_FPE 95 | fDSP->compute(date_usec, count, inputs, outputs); 96 | CATCH_FPE 97 | } else { 98 | fDSP->compute(date_usec, count, inputs, outputs); 99 | getStats(count, outputs); 100 | } 101 | } 102 | 103 | void printStats() 104 | { 105 | std::cout << "-------------------------------" << std::endl; 106 | std::cout << "FP_SUBNORMAL: " << fFP_SUBNORMAL << std::endl; 107 | std::cout << "FP_INFINITE: " << fFP_INFINITE << std::endl; 108 | std::cout << "FP_NAN: " << fFP_NAN << std::endl; 109 | std::cout << "-------------------------------" << std::endl; 110 | } 111 | 112 | }; 113 | 114 | #endif 115 | /************************** END dsp-checker.h **************************/ 116 | -------------------------------------------------------------------------------- /external/faust/architecture/faust/gui/Styles/Grey.qss: -------------------------------------------------------------------------------- 1 | QPushButton { 2 | background-color: qlineargradient(x1: 0, y1: 0, x2: 0.8, y2: 0.8, 3 | stop: 0 #B0B0B0, stop: 1 #404040); 4 | min-width : 80px; 5 | border: 2px solid grey; 6 | border-radius: 6px; 7 | margin-top: 1ex; 8 | color:white 9 | } 10 | 11 | QPushButton:hover { 12 | border: 2px solid orange; 13 | } 14 | 15 | QPushButton:pressed { 16 | background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #404040, stop: 1 #B0B0B0); 17 | } 18 | 19 | QGroupBox { 20 | subcontrol: .QGroupBox 21 | background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 #A0A0A0, stop: 1 #202020); 22 | margin-top: 3ex; 23 | border-radius: 5px; 24 | font-size:10pt; 25 | font-weight:bold; 26 | color: white; 27 | } 28 | 29 | QGroupBox::title { 30 | subcontrol-origin: margin; 31 | subcontrol-position: top center; 32 | padding: 0 5px; 33 | color : white; 34 | } 35 | 36 | QMainWindow, QDialog { 37 | background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 #A0A0A0, stop: 1 #202020); 38 | border-radius: 5px; 39 | margin-top: 3ex; 40 | font-size:10pt; 41 | font-weight:bold; 42 | color: white; 43 | } 44 | 45 | QPlainTextEdit, QTextEdit{ 46 | background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 #A0A0A0, stop: 1 #202020); 47 | border-color: yellow; 48 | border-radius: 5px; 49 | top: 3px; 50 | margin-top: 3ex; 51 | font-size:12pt; 52 | font-weight:bold; 53 | color: white; 54 | } 55 | 56 | QTextBrowser { 57 | background-color: qlineargradient(x1: 0, y1: 0, x2: 0.8, y2: 0.8, stop: 0 #A0A0A0, stop: 1 #202020); 58 | color: white; 59 | } 60 | 61 | QTextDocument{ 62 | text-decoration: underline; 63 | color: white; 64 | font: Menlo; 65 | font-size: 14px 66 | } 67 | 68 | QLabel{ 69 | color : white; 70 | background: transparent; 71 | } 72 | 73 | QSlider::groove:vertical { 74 | background: red; 75 | position: absolute; 76 | left: 13px; right: 13px; 77 | } 78 | 79 | QSlider::handle:vertical { 80 | height: 40px; 81 | width: 30px; 82 | background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #AAAAAA, stop : 0.05 #0A0A0A, stop: 0.3 #101010, stop : 0.90 #AAAAAA, stop: 0.91 #000000); 83 | margin: 0 -5px; 84 | border-radius: 5px; 85 | } 86 | 87 | QSlider::add-page:vertical { 88 | background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 yellow, stop : 0.5 orange); 89 | } 90 | 91 | QSlider::sub-page:vertical { 92 | background: grey; 93 | } 94 | 95 | QSlider::groove:horizontal { 96 | background: red; 97 | position: absolute; 98 | top: 14px; bottom: 14px; 99 | } 100 | 101 | QSlider::handle:horizontal { 102 | width: 40px; 103 | background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #AAAAAA, stop : 0.05 #0A0A0A, stop: 0.3 #101010, stop : 0.90 #AAAAAA, stop: 0.91 #000000); 104 | margin: -5px 0; 105 | border-radius: 5px; 106 | } 107 | 108 | QSlider::sub-page:horizontal { 109 | background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 yellow, stop : 0.5 orange); 110 | } 111 | 112 | QSlider::add-page:horizontal { 113 | background: grey; 114 | } 115 | 116 | QTabWidget::pane { 117 | border-top: 2px solid orange; 118 | background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #A0A0A0, stop: 1 #202020); 119 | } 120 | 121 | QTabWidget::tab-bar { 122 | left: 5px; 123 | } 124 | 125 | QTabBar::tab { 126 | background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #909090, stop: 0.4 #888888, stop: 0.5 #808080, stop: 1.0 #909090); 127 | border: 2px solid #808080; 128 | border-bottom-color: orange; 129 | border-top-left-radius: 4px; 130 | border-top-right-radius: 4px; 131 | min-width: 8ex; 132 | padding: 2px; 133 | } 134 | 135 | QTabBar::tab:selected, QTabBar::tab:hover { 136 | background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #D0D0D0, stop: 0.4 #A0A0A0, stop: 0.5 #808080, stop: 1.0 #A0A0A0); 137 | } 138 | 139 | QTabBar::tab:selected { 140 | border-color: orange; 141 | border-bottom-color: #A0A0A0; 142 | } 143 | 144 | QTabBar::tab:!selected { 145 | margin-top: 2px; 146 | } 147 | 148 | QListWidget{ 149 | background-color: transparent; 150 | } 151 | 152 | 153 | QListWidget::item{ 154 | color: white; 155 | } 156 | 157 | QStatusBar{ 158 | background-color: transparent; 159 | border: 0px; 160 | padding:0px 0px 0px 0px; 161 | margin:0px; 162 | } 163 | 164 | QScrollArea > QWidget > QWidget{ 165 | background-color: qlineargradient(x1: 0, y1: 0, x2: 0.8, y2: 0.8, stop: 0 #A0A0A0, stop: 1 #202020); 166 | } 167 | 168 | QScrollArea > QWidget { 169 | background-color: qlineargradient(x1: 0, y1: 0, x2: 0.8, y2: 0.8, stop: 0 #A0A0A0, stop: 1 #202020); 170 | } 171 | 172 | QScrollArea { 173 | background-color: qlineargradient(x1: 0, y1: 0, x2: 0.8, y2: 0.8, stop: 0 #A0A0A0, stop: 1 #202020); 174 | } -------------------------------------------------------------------------------- /external/faust/architecture/faust/gui/Styles/Blue.qss: -------------------------------------------------------------------------------- 1 | QPushButton{ 2 | min-width : 80px; 3 | border: 2px solid grey; 4 | border-radius: 6px; 5 | margin-top: 1ex; 6 | background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 #811453, stop: 1 #702963); 7 | color: white; 8 | } 9 | 10 | QPushButton:hover{ 11 | border: 2px solid orange; 12 | } 13 | 14 | QPushButton:pressed{ 15 | background-color: orange; 16 | border-color: grey; 17 | } 18 | 19 | QGroupBox{ 20 | subcontrol: .QGroupBox; 21 | background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 #003366, stop: 1 #22427C); 22 | margin-top: 3ex; 23 | border-radius: 5px; 24 | font-size: 10pt; 25 | font-weight: bold; 26 | color: white; 27 | } 28 | 29 | QGroupBox::title { 30 | subcontrol-origin: margin; 31 | subcontrol-position: top center; 32 | padding: 0 5px; 33 | color: white; 34 | } 35 | 36 | QMainWindow, QDialog{ 37 | background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 #003366, stop: 1 #22427C); 38 | border-radius: 5px; 39 | margin-top: 3ex; 40 | font-size:10pt; 41 | font-weight:bold; 42 | color: white; 43 | } 44 | 45 | QPlainTextEdit, QTextEdit{ 46 | background-color: transparent; 47 | border: 2px solid #702963; 48 | border-radius: 5px; 49 | top: 3px; 50 | margin-top: 3ex; 51 | font-size:12pt; 52 | font-weight:bold; 53 | color: white; 54 | } 55 | 56 | QTextBrowser { 57 | background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 #003366, stop: 1 #22427C); 58 | color: white; 59 | } 60 | 61 | QTextBrowser:document{ 62 | text-decoration: underline; 63 | color: white; 64 | font: Menlo; 65 | font-size: 14px 66 | } 67 | 68 | QLabel{ 69 | color : white; 70 | background: transparent; 71 | } 72 | 73 | QSlider::groove:vertical { 74 | background: red; 75 | position: absolute; 76 | left: 13px; right: 13px; 77 | } 78 | 79 | QSlider::handle:vertical { 80 | height: 40px; 81 | width: 30px; 82 | background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #AAAAAA, stop : 0.05 #0A0A0A, stop: 0.3 #101010, stop : 0.90 #AAAAAA, stop: 0.91 #000000); 83 | margin: 0 -5px; 84 | border-radius: 5px; 85 | } 86 | 87 | QSlider::add-page:vertical { 88 | background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 yellow, stop : 0.5 orange); 89 | } 90 | 91 | QSlider::sub-page:vertical { 92 | background: grey; 93 | } 94 | 95 | QSlider::groove:horizontal { 96 | background: red; 97 | position: absolute; 98 | top: 14px; bottom: 14px; 99 | } 100 | 101 | QSlider::handle:horizontal { 102 | width: 40px; 103 | background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #6A455D, stop : 0.05 #811453, stop: 0.3 #811453, stop : 0.90 #6A455D, stop: 0.91 #702963); 104 | margin: -5px 0; 105 | border-radius: 5px; 106 | } 107 | 108 | QSlider::sub-page:horizontal { 109 | background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 yellow, stop : 0.5 orange); 110 | } 111 | 112 | QSlider::add-page:horizontal { 113 | background: grey; 114 | } 115 | 116 | QTabWidget::pane { 117 | color : white; 118 | border-top: 2px #702963; 119 | background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #003366, stop: 1.0 #22427C); 120 | } 121 | 122 | QTabWidget::tab-bar { 123 | left: 5px; 124 | } 125 | 126 | QTabBar::tab { 127 | background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #003366, stop: 0.4 #22427C, stop: 0.5 #003366, stop: 1.0 #22427C); 128 | border: 2px solid #808080; 129 | color : white; 130 | border-bottom-color: #702963; 131 | border-top-left-radius: 4px; 132 | border-top-right-radius: 4px; 133 | min-width: 8ex; 134 | padding: 2px; 135 | } 136 | 137 | QTabBar::tab:selected, QTabBar::tab:hover { 138 | background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #003366, stop: 0.4 #22427C, stop: 0.5 #003366, stop: 1.0 #22427C); 139 | color : white; 140 | } 141 | 142 | QTabBar::tab:selected { 143 | color : white; 144 | border-color: #702963; 145 | border-bottom-color: #22427C; 146 | } 147 | 148 | QTabBar::tab:!selected { 149 | margin-top: 2px; 150 | } 151 | 152 | QListWidget{ 153 | background-color: transparent; 154 | } 155 | 156 | QListWidget::item{ 157 | color: white; 158 | } 159 | 160 | QStatusBar{ 161 | background-color: transparent; 162 | border: 0px; 163 | padding:0px 0px 0px 0px; 164 | margin:0px; 165 | } 166 | 167 | QScrollArea > QWidget > QWidget{ 168 | background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #003366, stop: 0.4 #22427C, stop: 0.5 #003366, stop: 1.0 #22427C); 169 | } 170 | 171 | QScrollArea > QWidget { 172 | background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #003366, stop: 0.4 #22427C, stop: 0.5 #003366, stop: 1.0 #22427C); 173 | } 174 | 175 | QScrollArea { 176 | background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #003366, stop: 0.4 #22427C, stop: 0.5 #003366, stop: 1.0 #22427C); 177 | } -------------------------------------------------------------------------------- /external/faust/architecture/faust/dsp/proxy-osc-dsp.h: -------------------------------------------------------------------------------- 1 | /************************** BEGIN proxy-osc-dsp.h ************************** 2 | FAUST Architecture File 3 | Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale 4 | --------------------------------------------------------------------- 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation; either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | 19 | EXCEPTION : As a special exception, you may create a larger work 20 | that contains this FAUST architecture section and distribute 21 | that work under terms of your choice, so long as this FAUST 22 | architecture section is not modified. 23 | ***************************************************************************/ 24 | 25 | #ifndef __proxy_osc_dsp__ 26 | #define __proxy_osc_dsp__ 27 | 28 | #include 29 | 30 | #include "faust/dsp/proxy-dsp.h" 31 | 32 | //---------------------------------------------------------------- 33 | // Proxy OSC dsp tries to connect to an OSC aware application and 34 | // creates a proxy to control it. 35 | //---------------------------------------------------------------- 36 | 37 | class proxy_osc_dsp : public proxy_dsp { 38 | 39 | private: 40 | 41 | std::string fJSON; 42 | 43 | static void errorHandler(int num, const char* msg, const char* where) 44 | { 45 | std::cerr << "Server error " << num << " in path" << ((where) ? where : "") << " : " << ((msg) ? msg : "") << std::endl; 46 | } 47 | 48 | static int messageHandler(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg, void* user_data) 49 | { 50 | return static_cast(user_data)->messageHandler(argv, argc); 51 | } 52 | 53 | int messageHandler(lo_arg** argv, int argc) 54 | { 55 | if (argc == 2 && strcmp(&argv[0]->s, "json") == 0) { 56 | fJSON = &argv[1]->s; 57 | } 58 | return 0; 59 | } 60 | 61 | public: 62 | 63 | proxy_osc_dsp(const std::string& ip, const std::string& root, int int_port, int out_port, int time_out = 5) 64 | { 65 | lo_message message = nullptr; 66 | lo_address target = nullptr; 67 | 68 | // Create server 69 | lo_server server = lo_server_new(std::to_string(int_port).c_str(), errorHandler); 70 | if (!server) { 71 | std::cerr << "Could not start a server with port: " << int_port << std::endl; 72 | goto fail; 73 | } 74 | lo_server_add_method(server, NULL, NULL, messageHandler, this); 75 | 76 | // Send 'json' message 77 | target = lo_address_new(ip.c_str(), std::to_string(out_port).c_str()); 78 | message = lo_message_new(); 79 | lo_message_add_string(message, "json"); 80 | if (lo_send_message(target, root.c_str(), message) == -1) { 81 | std::cerr << "An error occured in lo_send_message: " << lo_address_errstr(target) << std::endl; 82 | goto fail; 83 | } 84 | 85 | // Wait for 'json' reply from the OSC application 86 | if (lo_server_recv_noblock(server, time_out * 1000) == 0) { 87 | std::cerr << "No '" << root << "' OSC application on input " << int_port << " and output " << out_port << std::endl; 88 | goto fail; 89 | } 90 | 91 | lo_address_free(target); 92 | lo_message_free(message); 93 | lo_server_free(server); 94 | 95 | // Creates the proxy from the retrieved JSON 96 | init(fJSON); 97 | return; 98 | 99 | fail: 100 | if (target) lo_address_free(target); 101 | if (message) lo_message_free(message); 102 | if (server) lo_server_free(server); 103 | throw std::bad_alloc(); 104 | } 105 | 106 | }; 107 | 108 | #endif 109 | /************************** END proxy-osc-dsp.h **************************/ 110 | -------------------------------------------------------------------------------- /external/faust/architecture/faust/gui/JuceReader.h: -------------------------------------------------------------------------------- 1 | /************************** BEGIN JuceReader.h ************************** 2 | FAUST Architecture File 3 | Copyright (C) 2003-2022 GRAME, Centre National de Creation Musicale 4 | --------------------------------------------------------------------- 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published by 7 | the Free Software Foundation; either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | 19 | EXCEPTION : As a special exception, you may create a larger work 20 | that contains this FAUST architecture section and distribute 21 | that work under terms of your choice, so long as this FAUST 22 | architecture section is not modified. 23 | ************************************************************************/ 24 | 25 | #ifndef __JuceReader__ 26 | #define __JuceReader__ 27 | 28 | #include 29 | 30 | #include "../JuceLibraryCode/JuceHeader.h" 31 | 32 | #include "faust/gui/Soundfile.h" 33 | 34 | struct JuceReader : public SoundfileReader { 35 | 36 | juce::AudioFormatManager fFormatManager; 37 | 38 | JuceReader() { fFormatManager.registerBasicFormats(); } 39 | virtual ~JuceReader() 40 | {} 41 | 42 | bool checkFile(const std::string& path_name) override 43 | { 44 | juce::File file = juce::File::getCurrentWorkingDirectory().getChildFile(path_name); 45 | if (file.existsAsFile()) { 46 | return true; 47 | } else { 48 | //std::cerr << "ERROR : cannot open '" << path_name << "'" << std::endl; 49 | return false; 50 | } 51 | } 52 | 53 | void getParamsFile(const std::string& path_name, int& channels, int& length) override 54 | { 55 | std::unique_ptr formatReader (fFormatManager.createReaderFor (juce::File::getCurrentWorkingDirectory().getChildFile(path_name))); 56 | channels = int(formatReader->numChannels); 57 | length = int(formatReader->lengthInSamples); 58 | } 59 | 60 | void readFile(Soundfile* soundfile, const std::string& path_name, int part, int& offset, int max_chan) override 61 | { 62 | std::unique_ptr formatReader (fFormatManager.createReaderFor (juce::File::getCurrentWorkingDirectory().getChildFile(path_name))); 63 | 64 | soundfile->fLength[part] = int(formatReader->lengthInSamples); 65 | soundfile->fSR[part] = int(formatReader->sampleRate); 66 | soundfile->fOffset[part] = offset; 67 | 68 | void* buffers; 69 | if (soundfile->fIsDouble) { 70 | buffers = alloca(soundfile->fChannels * sizeof(double*)); 71 | soundfile->getBuffersOffsetReal(buffers, offset); 72 | } else { 73 | buffers = alloca(soundfile->fChannels * sizeof(float*)); 74 | soundfile->getBuffersOffsetReal(buffers, offset); 75 | } 76 | 77 | if (formatReader->read(reinterpret_cast(buffers), int(formatReader->numChannels), 0, int(formatReader->lengthInSamples), false)) { 78 | 79 | // Possibly convert samples 80 | if (!formatReader->usesFloatingPointData) { 81 | for (int chan = 0; chan < int(formatReader->numChannels); ++chan) { 82 | if (soundfile->fIsDouble) { 83 | // TODO 84 | } else { 85 | float* buffer = &(static_cast(soundfile->fBuffers))[chan][soundfile->fOffset[part]]; 86 | juce::FloatVectorOperations::convertFixedToFloat(buffer, reinterpret_cast(buffer), 87 | 1.0f/0x7fffffff, int(formatReader->lengthInSamples)); 88 | } 89 | } 90 | } 91 | 92 | } else { 93 | std::cerr << "Error reading the file : " << path_name << std::endl; 94 | } 95 | 96 | // Update offset 97 | offset += soundfile->fLength[part]; 98 | } 99 | 100 | }; 101 | 102 | #endif 103 | /************************** END JuceReader.h **************************/ 104 | --------------------------------------------------------------------------------