diff --git a/.github/workflows/plugins_build.yml b/.github/workflows/plugins_build.yml index 82bf9c1f..dbbd6cc8 100644 --- a/.github/workflows/plugins_build.yml +++ b/.github/workflows/plugins_build.yml @@ -1,7 +1,7 @@ name: Csound plugins build env: - VCPKG_BINARY_SOURCES: "clear;nuget,GitHub,readwrite" + VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite" on: push: @@ -21,15 +21,11 @@ jobs: strategy: matrix: - os: [windows-latest] - version: ["6.17.0"] + os: [windows-latest, ubuntu-latest, "macos-13"] include: - os: "windows-latest" - mono: "" - # - os: "ubuntu-latest" - # mono: "mono" - # - os: "macos-latest" - # mono: "mono" + - os: "ubuntu-latest" + - os: "macos-13" steps: - name: Checkout Source Code @@ -45,55 +41,45 @@ jobs: run: | Invoke-WebRequest $env:FAUST_URL -OutFile faustInstaller.exe ./faustInstaller.exe /S + echo "C:/Program Files/Faust;C:/Program Files/Faust/lib" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append echo "C:/Program Files/csound/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append echo "OPCODE6DIR64=C:/Program Files/csound/plugins64" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append echo "PYTHONPATH=C:/Program Files/csound/bin" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append echo "RAWWAVE_PATH=C:/Program Files/csound/samples" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - .\6.x\vcpkg\bootstrap-vcpkg.bat - choco install csound --version=6.17.0 - echo $GITHUB_ENV - ls 'C:\Program Files\Faust\' - echo "C:\Program Files\Faust\;C:\Program Files\Faust\lib" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + .\vcpkg\bootstrap-vcpkg.bat - # - name: Setup platform (linux) - # if: startsWith(matrix.os, 'ubuntu') - # run: | - # ./vcpkg/bootstrap-vcpkg.sh - # sudo apt-get update - # sudo apt-get install libcsound64-dev + - name: Setup platform (linux) + if: startsWith(matrix.os, 'ubuntu') + run: ./vcpkg/bootstrap-vcpkg.sh - # - name: Setup platform (macos) - # if: startsWith(matrix.os, 'macos') - # run: | - # ./vcpkg/bootstrap-vcpkg.sh - # brew install csound - - - name: Setup VCPKG cache - shell: bash + - name: Setup platform (macos) + if: startsWith(matrix.os, 'macos') run: | - ${{ matrix.mono }} `./6.x/vcpkg/vcpkg fetch nuget | tail -n 1` \ - sources add \ - -source "https://nuget.pkg.github.com/csound/index.json" \ - -storepasswordincleartext \ - -name "GitHub" \ - -username "csound" \ - -password "${{ secrets.GITHUB_TOKEN }}" - ${{ matrix.mono }} `./6.x/vcpkg/vcpkg fetch nuget | tail -n 1` \ - setapikey "${{ secrets.GITHUB_TOKEN }}" \ - -source "https://nuget.pkg.github.com/csound/index.json" + ./vcpkg/bootstrap-vcpkg.sh + + - name: Export GitHub Actions cache environment variables + uses: actions/github-script@v6 + with: + script: | + core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || ''); + core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || ''); - name: Generate CMake build - run: cmake 6.x/. -B build -DUSE_VCPKG=1 + run: cmake -B build -DUSE_VCPKG=1 - name: Build plugins run: cmake --build build --config Release - - name: Build installer - run: iscc /o. .\installer\win64\Installer.iss + - name: Build installer (windows) + if: startsWith(matrix.os, 'windows') && github.ref == 'refs/heads/develop' + run: | + iscc /o. .\6.x\installer\win64\Installer.iss + # iscc /o. .\7.x\installer\win64\Installer.iss - - name: Upload installer - uses: actions/upload-artifact@v2 + - name: Upload installer (windows) + if: startsWith(matrix.os, 'windows') && github.ref == 'refs/heads/develop' + uses: actions/upload-artifact@v4 with: name: Csound_win_x64-${{env.CSOUND_VERSION}}.${{github.run_number}}-plugins-installer - path: ./csound6-plugins-win_x86_64-*.exe + path: ./6.x/csound6-plugins-win_x86_64-*.exe if-no-files-found: error diff --git a/.gitmodules b/.gitmodules index c309f612..a0a57f3d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "vcpkg"] - path = 6.x/vcpkg + path = vcpkg url = https://github.com/microsoft/vcpkg.git diff --git a/.vscode/settings.json b/.vscode/settings.json index bb9abbbd..9d16c437 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,7 @@ { "files.associations": { - "lame.h": "c" + "lame.h": "c", + "pythonopcodes.h": "c", + "csdl.h": "c" } } diff --git a/6.x/CMakeLists.txt b/6.x/CMakeLists.txt index ee24b690..69f7f259 100644 --- a/6.x/CMakeLists.txt +++ b/6.x/CMakeLists.txt @@ -1,48 +1,9 @@ -cmake_minimum_required(VERSION 3.5) -cmake_policy(SET CMP0077 NEW) - -option(USE_VCPKG "Use VCPKG to download and manage dependencies" OFF) - -if (USE_VCPKG) - # Detect correct triplet based on CMake env - if (WIN32) - set(VCPKG_HOST_TRIPLET "x64-windows-csound" CACHE STRING "") - set(VCPKG_TARGET_TRIPLET "x64-windows-csound") - set(CSOUND_INCLUDE_DIR_HINT "C:/Program Files/Csound6_x64") - elseif(APPLE) - set(VCPKG_HOST_TRIPLET "x64-osx" CACHE STRING "") - set(VCPKG_TARGET_TRIPLET "x64-osx") - elseif (UNIX) - set(VCPKG_HOST_TRIPLET "x64-linux" CACHE STRING "") - set(VCPKG_TARGET_TRIPLET "x64-linux") - endif() - - set(VCPKG_FEATURE_FLAGS versions) - set(X_VCPKG_APPLOCAL_DEPS_INSTALL ON) - set(VCPKG_OVERLAY_TRIPLETS ${CMAKE_CURRENT_SOURCE_DIR}/) - set(VCPKG_OVERLAY_PORTS ${CMAKE_CURRENT_SOURCE_DIR}/) - set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake - CACHE STRING "Vcpkg toolchain file") -endif() - -project(Csound-plugins) - -if (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") - set(CMAKE_COMPILER_IS_CLANG 1) -endif() - -set(APIVERSION "6.0") - set(CMAKE_CXX_STANDARD 11) set(CMAKE_MACOSX_RPATH 1) set(CMAKE_VERBOSE_MAKEFILE ON) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") -find_package(CSOUND) - -if(NOT CSOUND_INCLUDE_DIRS) - message(FATAL_ERROR "Csound header files are required") -endif() +set(APIVERSION "6.0") include(TestBigEndian) include(CheckFunctionExists) @@ -52,7 +13,7 @@ include(CheckCXXCompilerFlag) ### COMPILER OPTIMIZATION FLAGS option(USE_COMPILER_OPTIMIZATIONS "Use the default Csound compiler optimization flags" ON) if(USE_COMPILER_OPTIMIZATIONS) - include(${CMAKE_SOURCE_DIR}/cmake/CompilerOptimizations.cmake) + include("${CMAKE_SOURCE_DIR}/cmake/CompilerOptimizations.cmake") endif() ##/Library/Frameworks/CsoundLib64.framework/Versions/Current/Resources/Opcodes64 @@ -182,70 +143,11 @@ if(APPLE) endif() message("-- Plugins to be installed at: ${PLUGIN_INSTALL_DIR}") -# Checks if dependencies for an enabled target are fulfilled. -# If FAIL_MISSING is true and the dependencies are not fulfilled, -# it will abort the cmake run. -# If FAIL_MISSING is false, it will set the option to OFF. -# If the target is not enabled, it will do nothing. -# example: check_deps(BUILD_NEW_PARSER FLEX_EXECUTABLE BISON_EXECUTABLE) -function(check_deps option) - if(${option}) - set(i 1) - while( ${i} LESS ${ARGC} ) - set(dep ${ARGV${i}}) - if(NOT ${dep}) - if(FAIL_MISSING) - message(FATAL_ERROR - "${option} is enabled, but ${dep}=\"${${dep}}\"") - else() - message(STATUS "${dep}=\"${${dep}}\", so disabling ${option}") - set(${option} OFF PARENT_SCOPE) - # Set it in the local scope too - set(${option} OFF) - endif() - endif() - math(EXPR i "${i}+1") - endwhile() - endif() - if(${option}) - message(STATUS "${option} is enabled.") - else() - message(STATUS "${option} is disabled.") - endif() -endfunction(check_deps) - -# Utility function to make plugins. All plugin targets should use this as it -# sets up output directory set in top-level CmakeLists.txt -# and adds the appropriate install target -# -# libname - name of library to produce -# srcs - list of src files (must be quoted if a list) -# extralibs (OPTIONAL) - extra libraries to link the plugin to -# -# NB - this was moved here as it needs some VARS defined above -# for setting up the framework -function(make_plugin libname srcs) - if(APPLE) - add_library(${libname} SHARED ${srcs}) - else() - add_library(${libname} MODULE ${srcs}) - endif() - - set(i 2) - while( ${i} LESS ${ARGC} ) - target_link_libraries(${libname} PRIVATE ${ARGV${i}}) - math(EXPR i "${i}+1") - endwhile() +# Include utility functions for making plugins +include("${CMAKE_SOURCE_DIR}/cmake/utilities.cmake") - install(TARGETS ${libname} - LIBRARY DESTINATION "${PLUGIN_INSTALL_DIR}" - ARCHIVE DESTINATION "${PLUGIN_INSTALL_DIR}" ) -endfunction(make_plugin) - -#checking pthread functions +# Checking pthread functions if(REQUIRE_PTHREADS AND (PTHREAD_LIBRARY OR HAIKU)) - - #list(APPEND libcsound_CFLAGS -DHAVE_PTHREAD) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DHAVE_PTHREAD") check_function_exists(pthread_spin_lock PTHREAD_SPIN_LOCK_EXISTS) @@ -311,4 +213,4 @@ add_subdirectory(./src/mp3) add_subdirectory(./src/wiimote) add_subdirectory(./src/p5glove) add_subdirectory(./src/jackops) -add_subdirectory(./src/fluidOpcodes) \ No newline at end of file +add_subdirectory(./src/fluidOpcodes) diff --git a/6.x/csound/CppSound.hpp b/6.x/csound/CppSound.hpp new file mode 100644 index 00000000..0a75c9cc --- /dev/null +++ b/6.x/csound/CppSound.hpp @@ -0,0 +1,92 @@ +/* + * C S O U N D + * + * L I C E N S E + * + * This software is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef CSND_CPPSOUND_H +#define CSND_CPPSOUND_H + +#include "float-version.h" +#ifndef __MYFLT_DEF +#define __MYFLT_DEF +#ifdef USE_DOUBLE +#define MYFLT double +#else +#define MYFLT float +#endif +#endif + +#ifdef SWIG +%module csnd6 +%include "std_string.i" +%include "std_vector.i" +%{ +#include "csound.hpp" +#include "CsoundFile.hpp" +#include +#include + %} +%template(MyfltVector) std::vector; +#else +#include "csound.hpp" +#include "CsoundFile.hpp" +#include +#include +#endif + +class PUBLIC CppSound : public Csound, public CsoundFile +{ + bool go; + bool isCompiled; + bool isPerforming; + size_t spoutSize; + std::string renderedSoundfile; +public: + CppSound() : Csound(), + go(false), + isCompiled(false), + isPerforming(false), + spoutSize(0) +{ + + //SetHostData((CSOUND *)0); + +} + + virtual ~CppSound(); + virtual CSOUND *getCsound(); + virtual intptr_t getThis(); + virtual CsoundFile *getCsoundFile(); + virtual int compile(int argc, const char **argv); + virtual int compile(); + virtual size_t getSpoutSize() const; + virtual std::string getOutputSoundfileName() const; + virtual int perform(int argc, const char **argv); + virtual int perform(); + virtual int performKsmps(); + virtual void cleanup(); + virtual void inputMessage(const char *istatement); + virtual void write(const char *text); + virtual bool getIsCompiled() const; + virtual void setIsPerforming(bool isPerforming); + virtual bool getIsPerforming() const; + virtual bool getIsGo(); + virtual void stop(); +}; + +#endif + diff --git a/6.x/csound/CsoundFile.hpp b/6.x/csound/CsoundFile.hpp new file mode 100644 index 00000000..ff25e7e0 --- /dev/null +++ b/6.x/csound/CsoundFile.hpp @@ -0,0 +1,222 @@ +/* + * C S O U N D + * + * L I C E N S E + * + * This software is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef CSOUNDFILE_H +#define CSOUNDFILE_H + +#if 0 +#undef MYFLT +#ifdef USE_DOUBLE +#define MYFLT double +#else +#define MYFLT float +#endif +#endif + +#if defined(_MSC_VER) && !defined(__GNUC__) +#pragma warning(disable: 4786) +#endif +#ifdef SWIG +%module csnd6 +%include "std_string.i" +%include "std_vector.i" +#if !defined(SWIGLUA) +%include "std_map.i" +%template(IntToStringMap) std::map; +#endif +%{ +#include +#include +%} +#else +#include +#include +#include +#include +#include +#include +#include + +#ifndef PUBLIC +#if (defined(WIN32) || defined(_WIN32)) && !defined(SWIG) +# define PUBLIC __declspec(dllexport) +#elif defined(__GNUC__) && (__GNUC__ >= 4) /* && !defined(__MACH__) */ +# define PUBLIC __attribute__ ( (visibility("default")) ) +#else +# define PUBLIC +#endif +#endif + +#if defined(WIN32) +#include +#endif +#endif + +void PUBLIC gatherArgs(int argc, const char **argv, std::string &commandLine); + +void PUBLIC scatterArgs(const std::string commandLine, std::vector &args, std::vector &argv); + +std::string PUBLIC &trim(std::string &value); + +std::string PUBLIC &trimQuotes(std::string &value); + +/** + * Returns true if definition is a valid Csound instrument definition block. + * Also returns the part before the instr number, the instr number, + * the name (all text after the first comment on the same line as the instr number), + * and the part after the instr number, all by reference. + */ +bool PUBLIC parseInstrument(const std::string &definition, std::string &preNumber, std::string &id, std::string &name, std::string &postNumber); + +/** + * Manages a Csound Structured Data (CSD) file with facilities + * for creating an arrangement of selected instruments in the orchestra, + * and for programmatically building score files. + */ +class PUBLIC CsoundFile +{ +protected: + /** + * What are we storing, anyway? + */ + std::string filename; + /** + * CsOptions + */ + std::string command; + std::vector args; + std::vector argv; + /** + * CsInstruments + */ + std::string orchestra; + /** + * CsScore + */ + std::string score; + /** + * CsMidi + */ + std::vector midifile; +public: + /** + * Patch library and arrangement. + */ + std::string libraryFilename; + std::vector arrangement; + CsoundFile(); + virtual ~CsoundFile(){}; + virtual std::string generateFilename(); + virtual std::string getFilename() const; + virtual void setFilename(std::string name); + /** + * Clears all contents of this, + * then imports the indicated file, + * which can be a Csound unified file (.csd), + * Csound orchestra (.orc), Csound score (.sco), + * standard MIDI file (.mid), or MusicXML v2 (.xml) + * file. + * + * The MusicXML notes become instrument number + 1, + * time in seconds, duration in seconds, MIDI key + * number, and MIDI velocity number. + */ + virtual int load(std::string filename); + virtual int load(std::istream &stream); + virtual int save(std::string filename) const; + virtual int save(std::ostream &stream) const; + /** + * Imports the indicated file, + * which can be a Csound unified file (.csd), + * Csound orchestra (.orc), Csound score (.sco), + * standard MIDI file (.mid), or MusicXML v2 (.xml) + * file. The data that is read replaces existing + * data of that type, but leaves other types of data + * untouched. + * + * The MusicXML notes become instrument number + 1, + * time in seconds, duration in seconds, MIDI key + * number, and MIDI velocity number. + */ + virtual int importFile(std::string filename); + virtual int importFile(std::istream &stream); + virtual int importCommand(std::istream &stream); + virtual int exportCommand(std::ostream &stream) const; + virtual int importOrchestra(std::istream &stream); + virtual int exportOrchestra(std::ostream &stream) const; + virtual int importScore(std::istream &stream); + virtual int exportScore(std::ostream &stream) const; + virtual int importArrangement(std::istream &stream); + virtual int exportArrangement(std::ostream &stream) const; + virtual int exportArrangementForPerformance(std::string filename) const; + virtual int exportArrangementForPerformance(std::ostream &stream) const; + virtual int importMidifile(std::istream &stream); + virtual int exportMidifile(std::ostream &stream) const; + virtual std::string getCommand() const; + virtual void setCommand(std::string commandLine); + virtual std::string getOrcFilename() const; + virtual std::string getScoFilename() const; + virtual std::string getMidiFilename() const; + virtual std::string getOutputSoundfileName() const; + virtual std::string getOrchestra() const; + virtual void setOrchestra(std::string orchestra); + virtual int getInstrumentCount() const; + virtual std::string getOrchestraHeader() const; + virtual bool getInstrument(int number, std::string &definition) const; + //virtual bool getInstrumentNumber(int index, std::string &definition) const; + virtual bool getInstrument(std::string name, std::string &definition) const; + virtual std::string getInstrument(std::string name) const; + virtual std::string getInstrument(int number) const; + virtual std::string getInstrumentBody(std::string name) const; + virtual std::string getInstrumentBody(int number) const; + virtual std::map getInstrumentNames() const; + virtual double getInstrumentNumber(std::string name) const; + virtual std::string getScore() const; + virtual void setScore(std::string score); + virtual int getArrangementCount() const; + virtual std::string getArrangement(int index) const; + virtual void addArrangement(std::string instrument); + virtual void setArrangement(int index, std::string instrument); + virtual void insertArrangement(int index, std::string instrument); + virtual void removeArrangement(int index); + virtual void setCSD(std::string xml); + virtual std::string getCSD() const; + virtual void addScoreLine(const std::string line); + virtual void addNote(double p1, double p2, double p3, double p4, double p5, double p6, double p7, double p8, double p9, double p10, double p11); + virtual void addNote(double p1, double p2, double p3, double p4, double p5, double p6, double p7, double p8, double p9, double p10); + virtual void addNote(double p1, double p2, double p3, double p4, double p5, double p6, double p7, double p8, double p9); + virtual void addNote(double p1, double p2, double p3, double p4, double p5, double p6, double p7, double p8); + virtual void addNote(double p1, double p2, double p3, double p4, double p5, double p6, double p7); + virtual void addNote(double p1, double p2, double p3, double p4, double p5, double p6); + virtual void addNote(double p1, double p2, double p3, double p4, double p5); + virtual void addNote(double p1, double p2, double p3, double p4); + virtual void addNote(double p1, double p2, double p3); + virtual bool exportForPerformance() const; + virtual void removeAll(); + virtual void removeCommand(); + virtual void removeOrchestra(); + virtual void removeScore(); + virtual void removeArrangement(); + virtual void removeMidifile(); + //virtual void getInstrumentNames(std::vector &names) const; + virtual bool loadOrcLibrary(const char *filename = 0); +}; + +#endif // CSOUND_FILE_H + diff --git a/6.x/src/linear_algebra/OpcodeBase.hpp b/6.x/csound/OpcodeBase.hpp similarity index 95% rename from 6.x/src/linear_algebra/OpcodeBase.hpp rename to 6.x/csound/OpcodeBase.hpp index 21ca8a0c..143decd8 100644 --- a/6.x/src/linear_algebra/OpcodeBase.hpp +++ b/6.x/csound/OpcodeBase.hpp @@ -1,492 +1,489 @@ -/* - OpcodeBase.hpp: - - Copyright (C) 2005, 2009, 2017 by Istva Varga, Victor Lazzarini and - Michael Gogins - - This file is part of Csound. - - The Csound Library is free software; you can redistribute it - and/or modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - Csound is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with Csound; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - 02110-1301 USA -*/ -#pragma once - -/** - * There is a conflict between the preprocessor definition "_CR" in the - * standard C++ library and in Csound. To work around this, undefine "_CR" and - * include ALL standard library include files BEFORE including ANY Csound - * include files. - */ -#if defined(_CR) -#undef _CR -#endif - -#include -#include -#include -#if !(defined(__wasi__)) -#include -#endif -#include -#include -#include -#include - -/** - * Template base class, or pseudo-virtual base class, - * for writing Csound opcodes in C++. - * Derive opcode implementation classes like this: - * - * DerivedClass : public OpcodeBase - * { - * public: - * // All output fields must be declared first as MYFLT *: - * MYFLT *aret1; - * // All input fields must be declared next as MYFLT *: - * MYFLT *iarg1; - * MYFLT *karg2; - * MYFLT *aarg3; - * // All internal state variables must be declared after that: - * size_t state1; - * double state2; - * MYFLT state3; - * // If the opcode shares data protect it by creating one or more void - * // *mutex member pointers: - * void *mutex1; - * void *mutex2; - * // and create them usind csound->Create_Mutex() in csoundModuleCreate - * // and destroy them using csound->DeleteMutex(mutex) - * // csoundModuleDestroy, and lock them using LockGuard guard(mutex). - * int init(); - * int kontrol(); - * int audio; - * int noteoff(); - * void deinit(); - * }; - */ - -namespace csound { - -static bool diagnostics_enabled = false; - -/** - * Use this to guard against data races in opcode functions. The mutex should - * be created by csound->Create_Mutex() in csoundModuleCreate(), and should - * be destroyed by csound->DeleteMutex() in csoundModuleDestroy(). - * - * If data is shared between opcode instances, the mutex should be global to - * the opcode library; if data is shared between threads for a single instance, - * the mutex should belong to the opcode instance. - */ -struct LockGuard { - LockGuard(CSOUND *csound_, void *mutex_) : csound(csound_), mutex(mutex_) - { - csound->LockMutex(mutex); - } - ~LockGuard() - { - csound->UnlockMutex(mutex); - } - CSOUND *csound; - void *mutex; -}; - -/** - * Use this to store a pointer to a global heap-allocated object, e.g. one - * used to manage state between opcode instances. - */ - -template int CreateGlobalPointer(CSOUND *csound, const char *name, T *pointer) -{ - T **pointer_to_pointer = 0; - int result = csound->CreateGlobalVariable(csound, name, sizeof(pointer_to_pointer)); - pointer_to_pointer = static_cast(csound->QueryGlobalVariable(csound, name)); - *pointer_to_pointer = pointer; - return result; -} - -/** - * Retrieve a pointer to a global heap-allocated object, e.g. one - * used to manage state between opcode instances. - */ -template T *QueryGlobalPointer(CSOUND *csound, const char *name, T*& pointer) -{ - T **pointer_to_pointer = static_cast(csound->QueryGlobalVariableNoCheck(csound, name)); - if (pointer_to_pointer != 0) { - pointer = *pointer_to_pointer; - } else { - pointer = 0; - } - return pointer; -} - -template -class OpcodeBase -{ -public: - int init(CSOUND *csound) - { - return NOTOK; - } - static int init_(CSOUND *csound, void *opcode) - { - return reinterpret_cast(opcode)->init(csound); - } - int kontrol(CSOUND *csound) - { - return NOTOK; - } - static int kontrol_(CSOUND *csound, void *opcode) - { - return reinterpret_cast(opcode)->kontrol(csound); - } - int audio(CSOUND *csound) - { - return NOTOK; - } - static int audio_(CSOUND *csound, void *opcode) - { - return reinterpret_cast(opcode)->audio(csound); - } - /** - This is how to compute audio signals for normal opcodes: - (1) Zero all frames from 0 up to but not including Offset. - (2) Compute all frames from ksmps_offset up to but not including End. - (3) Zero all frames from End up to but not including ksmps. - Example from a C opcode: - uint32_t offset = p->h.insdshead->ksmps_offset; - uint32_t early = p->h.insdshead->ksmps_no_end; - uint32_t n, nsmps = CS_KSMPS; - if (UNLIKELY(offset)) memset(p->r, '\0', offset*sizeof(MYFLT)); - if (UNLIKELY(early)) { - nsmps -= early; - memset(&p->r[nsmps], '\0', early*sizeof(MYFLT)); - } - for (n = offset; n < nsmps; n++) { - input1 = MYFLT2LRND(p->a[n]); - p->r[n] = (MYFLT) (input1 >> input2); - } - So in C++ it should look like this (which is much easier to understand): - int frameIndex = 0; - for( ; frameIndex < kperiodOffset(); ++frameIndex) { - asignal[frameIndex] = 0; - } - for( ; frameIndex < kperiodEnd(); ++frameIndex) { - asignal[frameIndex] = compute(); - } - for( ; frameIndex < ksmps(); ++frameIndex) { - asignal[frameIndex] = 0; - } - */ - uint32_t kperiodOffset() const - { - return opds.insdshead->ksmps_offset; - } - uint32_t kperiodEnd() const - { - uint32_t end = opds.insdshead->ksmps_no_end; - if (end) { - return end; - } else { - return ksmps(); - } - } - uint32_t ksmps() const - { - return opds.insdshead->ksmps; - } - uint32_t output_arg_count() - { - return (uint32_t)opds.optext->t.outArgCount; - } - uint32_t input_arg_count() - { - return (uint32_t)opds.optext->t.inArgCount; - } - void log(CSOUND *csound, const char *format,...) - { - va_list args; - va_start(args, format); - if(csound) { - csound->MessageV(csound, 0, format, args); - } else { - vfprintf(stdout, format, args); - } - va_end(args); - } - void warn(CSOUND *csound, const char *format,...) - { - if(csound) { - if(csound->GetMessageLevel(csound) & CS_WARNMSG) { - va_list args; - va_start(args, format); - csound->MessageV(csound, CSOUNDMSG_WARNING, format, args); - va_end(args); - } - } else { - va_list args; - va_start(args, format); - vfprintf(stdout, format, args); - va_end(args); - } - } - OPDS opds; -}; - -template -class OpcodeNoteoffBase -{ -public: - int init(CSOUND *csound) - { - IGN(csound); - return NOTOK; - } - static int init_(CSOUND *csound, void *opcode) - { - if (!csound->GetReinitFlag(csound) && !csound->GetTieFlag(csound)) { - csound->RegisterDeinitCallback(csound, opcode, - &OpcodeNoteoffBase::noteoff_); - } - return reinterpret_cast(opcode)->init(csound); - } - int kontrol(CSOUND *csound) - { - IGN(csound); - return NOTOK; - } - static int kontrol_(CSOUND *csound, void *opcode) - { - return reinterpret_cast(opcode)->kontrol(csound); - } - int audio(CSOUND *csound) - { - IGN(csound); - return NOTOK; - } - static int audio_(CSOUND *csound, void *opcode) - { - return reinterpret_cast(opcode)->audio(csound); - } - /** - This is how to compute audio signals for normal opcodes: - (1) Zero all frames from 0 up to but not including Offset. - (2) Compute all frames from ksmps_offset up to but not including End. - (3) Zero all frames from End up to but not including ksmps. - Example from a C opcode: - uint32_t offset = p->h.insdshead->ksmps_offset; - uint32_t early = p->h.insdshead->ksmps_no_end; - uint32_t n, nsmps = CS_KSMPS; - if (UNLIKELY(offset)) memset(p->r, '\0', offset*sizeof(MYFLT)); - if (UNLIKELY(early)) { - nsmps -= early; - memset(&p->r[nsmps], '\0', early*sizeof(MYFLT)); - } - for (n = offset; n < nsmps; n++) { - input1 = MYFLT2LRND(p->a[n]); - p->r[n] = (MYFLT) (input1 >> input2); - } - So in C++ it should look like this (which is much easier to understand): - int frameIndex = 0; - for( ; frameIndex < kperiodOffset(); ++frameIndex) { - asignal[frameIndex] = 0; - } - for( ; frameIndex < kperiodEnd(); ++frameIndex) { - asignal[frameIndex] = compute(); - } - for( ; frameIndex < ksmps(); ++frameIndex) { - asignal[frameIndex] = 0; - } - */ - uint32_t kperiodOffset() const - { - return opds.insdshead->ksmps_offset; - } - uint32_t kperiodEnd() const - { - uint32_t end = opds.insdshead->ksmps_no_end; - if (end) { - return end; - } else { - return ksmps(); - } - } - uint32_t ksmps() const - { - return opds.insdshead->ksmps; - } - uint32_t output_arg_count() - { - return (uint32_t)opds.optext->t.outArgCount; - } - uint32_t input_arg_count() - { - return (uint32_t)opds.optext->t.inArgCount; - } - void log(CSOUND *csound, const char *format,...) - { - va_list args; - va_start(args, format); - if(csound) { - csound->MessageV(csound, 0, format, args); - } else { - vfprintf(stdout, format, args); - } - va_end(args); - } - void warn(CSOUND *csound, const char *format,...) - { - if(csound) { - if(csound->GetMessageLevel(csound) & CS_WARNMSG) { - va_list args; - va_start(args, format); - csound->MessageV(csound, CSOUNDMSG_WARNING, format, args); - va_end(args); - } - } else { - va_list args; - va_start(args, format); - vfprintf(stdout, format, args); - va_end(args); - } - } - int noteoff(CSOUND *csound) - { - return OK; - } - static int noteoff_(CSOUND *csound, void *opcode) - { - return reinterpret_cast(opcode)->noteoff(csound); - } - OPDS opds; -}; - -#if (__cplusplus >= 201103L) && !(defined(__wasi__)) -#pragma message("Defining heap_object_manager_t.") - -/** - * The memory of non-POD C++ or C objects allocated on the heap by Csound - * plugins is managed not by Csound, but by the plugin module. This class - * performs that function. - * - * As long as all memory is allocated in or after csoundModuleCreate and - * de-allocated in csoundModuleDestroy, all will be well. The danger however - * is that memory leaks will occur if allocations are not matched with - * de-allocations, or worse, that crashes will occur if any objects are - * deleted twice or de-referenced after deletion. - * - * So, the plugin should manage a collection of all heap-allocated objects, - * keyed first off the Csound instance, and second off an object handle; and - * all such objects must be accessed only by handle, from this collection. - * - * In csoundModuleDestroy, all objects for the calling instance of Csound - * should be de-allocated, and the sub-collection for that instance should - * also be de-allocated. - * - * If then there are no more sub-collections for other instances of Csound, - * the entire contents of the collection should be de-allocated. - * - * This should be done as a singleton, and in a thread-safe way. - * - * There might still be a problem if any of the heap-allocated objects, - * themselves, have global static members, perhaps created by some external - * dependency. - * - * Please note, objects O in the declaration below must not be std::shared_ptr - * objects. Deletion of objects herein must be unconditional. Rather, the - * objects passed are raw pointers to instances of class O. - */ - template class heap_object_manager_t { - private: - std::map> objects_; - std::recursive_mutex mutex; - heap_object_manager_t(){}; - ~heap_object_manager_t(){}; - public: - static heap_object_manager_t &instance() { - static heap_object_manager_t singleton; - return singleton; - } - std::map> &objects() { - std::lock_guard lock(mutex); - return objects_; - } - /** - * Returns a list of pointers to all objects allocated for this - * instance of Csound. - */ - std::vector &objects_for_csound(CSOUND *csound) { - std::lock_guard lock(mutex); - auto &objects_for_csound_ = objects()[csound]; - return objects_for_csound_; - } - /** - * Returns the handle for the object; if the object has not yet been - * stored, inserts it into the list of object pointers for this - * instance of Csound; otherwise, returns the handle of the stored - * object pointer. - */ - int handle_for_object(CSOUND *csound, O *object) { - std::lock_guard lock(mutex); - auto &objects_for_csound_ = objects_for_csound(csound); - auto iterator = std::find(objects_for_csound_.begin(), objects_for_csound_.end(), object); - if (iterator == objects_for_csound_.end()) { - int handle = objects_for_csound_.size(); - objects_for_csound_.push_back(object); - if (diagnostics_enabled) std::fprintf(stderr, "heap_object_manager_t::handle_for_object %p: new object handle: %d (of %ld)\n", object, handle, objects_for_csound_.size()); - return handle; - } else { - int handle = static_cast(iterator - objects_for_csound_.begin()); - if (diagnostics_enabled) std::fprintf(stderr, "heap_object_manager_t::handle_for_object: existing object handle: %d\n", handle); - return handle; - } - } - /** - * Returns the object pointer for the handle; - * if the object pointer has not been stored by - * handle, returns a null pointer. - */ - O *object_for_handle(CSOUND *csound, int handle) { - std::lock_guard lock(mutex); - auto &objects_for_csound_ = objects_for_csound(csound); - if (handle >= objects_for_csound_.size()) { - return nullptr; - } - O *object = objects_for_csound_[handle]; - if (diagnostics_enabled) std::fprintf(stderr, "heap_object_manager_t::object_for_handle: %p %d (of %ld)\n", object, handle, objects_for_csound_.size()); - return object; - } - /** - * First destroys all objects created by the calling - * instance of Csound, then destroys the list of - * object pointers for this instance of Csound. - */ - void module_destroy(CSOUND *csound) { - std::lock_guard lock(mutex); - auto &objects_for_csound_ = objects_for_csound(csound); - for (int i = 0, n = objects_for_csound_.size(); i < n; ++i) { - delete objects_for_csound_[i]; - objects_for_csound_[i] = nullptr; - } - objects_for_csound_.clear(); - objects().erase(csound); - } -}; - -#else -#pragma message("Not defining heap_manager_t.") -#endif - -} +/* + OpcodeBase.hpp: + + Copyright (C) 2005, 2009, 2017 by Istva Varga, Victor Lazzarini and + Michael Gogins + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ +#pragma once + +/** + * There is a conflict between the preprocessor definition "_CR" in the + * standard C++ library and in Csound. To work around this, undefine "_CR" and + * include ALL standard library include files BEFORE including ANY Csound + * include files. + */ +#if defined(_CR) +#undef _CR +#endif + +#include +#include +#include +#if !(defined(__wasi__)) +#include +#endif +#include +#include +#include +#include + +/** + * Template base class, or pseudo-virtual base class, + * for writing Csound opcodes in C++. + * Derive opcode implementation classes like this: + * + * DerivedClass : public OpcodeBase + * { + * public: + * // All output fields must be declared first as MYFLT *: + * MYFLT *aret1; + * // All input fields must be declared next as MYFLT *: + * MYFLT *iarg1; + * MYFLT *karg2; + * MYFLT *aarg3; + * // All internal state variables must be declared after that: + * size_t state1; + * double state2; + * MYFLT state3; + * // If the opcode shares data protect it by creating one or more void + * // *mutex member pointers: + * void *mutex1; + * void *mutex2; + * // and create them usind csound->Create_Mutex() in csoundModuleCreate + * // and destroy them using csound->DeleteMutex(mutex) + * // csoundModuleDestroy, and lock them using LockGuard guard(mutex). + * int init(); + * int kontrol(); + * int audio; + * int noteoff(); + * void deinit(); + * }; + */ + +namespace csound { + +static bool diagnostics_enabled = false; + +/** + * Use this to guard against data races in opcode functions. The mutex should + * be created by csound->Create_Mutex() in csoundModuleCreate(), and should + * be destroyed by csound->DeleteMutex() in csoundModuleDestroy(). + * + * If data is shared between opcode instances, the mutex should be global to + * the opcode library; if data is shared between threads for a single instance, + * the mutex should belong to the opcode instance. + */ +struct LockGuard { + LockGuard(CSOUND *csound_, void *mutex_) : csound(csound_), mutex(mutex_) + { + csound->LockMutex(mutex); + } + ~LockGuard() + { + csound->UnlockMutex(mutex); + } + CSOUND *csound; + void *mutex; +}; + +/** + * Use this to store a pointer to a global heap-allocated object, e.g. one + * used to manage state between opcode instances. + */ + +template int CreateGlobalPointer(CSOUND *csound, const char *name, T *pointer) +{ + T **pointer_to_pointer = 0; + int result = csound->CreateGlobalVariable(csound, name, sizeof(pointer_to_pointer)); + pointer_to_pointer = static_cast(csound->QueryGlobalVariable(csound, name)); + *pointer_to_pointer = pointer; + return result; +} + +/** + * Retrieve a pointer to a global heap-allocated object, e.g. one + * used to manage state between opcode instances. + */ +template T *QueryGlobalPointer(CSOUND *csound, const char *name, T*& pointer) +{ + T **pointer_to_pointer = static_cast(csound->QueryGlobalVariableNoCheck(csound, name)); + if (pointer_to_pointer != 0) { + pointer = *pointer_to_pointer; + } else { + pointer = 0; + } + return pointer; +} + +template +class OpcodeBase +{ +public: + int init(CSOUND *csound) + { + return NOTOK; + } + static int init_(CSOUND *csound, void *opcode) + { + return reinterpret_cast(opcode)->init(csound); + } + int kontrol(CSOUND *csound) + { + return NOTOK; + } + static int kontrol_(CSOUND *csound, void *opcode) + { + return reinterpret_cast(opcode)->kontrol(csound); + } + int audio(CSOUND *csound) + { + return NOTOK; + } + static int audio_(CSOUND *csound, void *opcode) + { + return reinterpret_cast(opcode)->audio(csound); + } + /** + This is how to compute audio signals for normal opcodes: + (1) Zero all frames from 0 up to but not including Offset. + (2) Compute all frames from ksmps_offset up to but not including End. + (3) Zero all frames from End up to but not including ksmps. + Example from a C opcode: + uint32_t offset = p->h.insdshead->ksmps_offset; + uint32_t early = p->h.insdshead->ksmps_no_end; + uint32_t n, nsmps = CS_KSMPS; + if (UNLIKELY(offset)) memset(p->r, '\0', offset*sizeof(MYFLT)); + if (UNLIKELY(early)) { + nsmps -= early; + memset(&p->r[nsmps], '\0', early*sizeof(MYFLT)); + } + for (n = offset; n < nsmps; n++) { + input1 = MYFLT2LRND(p->a[n]); + p->r[n] = (MYFLT) (input1 >> input2); + } + So in C++ it should look like this (which is much easier to understand): + int frameIndex = 0; + for( ; frameIndex < kperiodOffset(); ++frameIndex) { + asignal[frameIndex] = 0; + } + for( ; frameIndex < kperiodEnd(); ++frameIndex) { + asignal[frameIndex] = compute(); + } + for( ; frameIndex < ksmps(); ++frameIndex) { + asignal[frameIndex] = 0; + } + */ + uint32_t kperiodOffset() const + { + return opds.insdshead->ksmps_offset; + } + uint32_t kperiodEnd() const + { + uint32_t end = opds.insdshead->ksmps_no_end; + if (end) { + return end; + } else { + return ksmps(); + } + } + uint32_t ksmps() const + { + return opds.insdshead->ksmps; + } + uint32_t output_arg_count() + { + return (uint32_t)opds.optext->t.outArgCount; + } + uint32_t input_arg_count() + { + return (uint32_t)opds.optext->t.inArgCount; + } + void log(CSOUND *csound, const char *format,...) + { + va_list args; + va_start(args, format); + if(csound) { + csound->MessageV(csound, 0, format, args); + } else { + vfprintf(stdout, format, args); + } + va_end(args); + } + void warn(CSOUND *csound, const char *format,...) + { + if(csound) { + if(csound->GetMessageLevel(csound) & CS_WARNMSG) { + va_list args; + va_start(args, format); + csound->MessageV(csound, CSOUNDMSG_WARNING, format, args); + va_end(args); + } + } else { + va_list args; + va_start(args, format); + vfprintf(stdout, format, args); + va_end(args); + } + } + OPDS opds; +}; + +template +class OpcodeNoteoffBase +{ +public: + int init(CSOUND *csound) + { + IGN(csound); + return NOTOK; + } + static int init_(CSOUND *csound, void *opcode) + { + if (!csound->GetReinitFlag(csound) && !csound->GetTieFlag(csound)) { + csound->RegisterDeinitCallback(csound, opcode, + &OpcodeNoteoffBase::noteoff_); + } + return reinterpret_cast(opcode)->init(csound); + } + int kontrol(CSOUND *csound) + { + IGN(csound); + return NOTOK; + } + static int kontrol_(CSOUND *csound, void *opcode) + { + return reinterpret_cast(opcode)->kontrol(csound); + } + int audio(CSOUND *csound) + { + IGN(csound); + return NOTOK; + } + static int audio_(CSOUND *csound, void *opcode) + { + return reinterpret_cast(opcode)->audio(csound); + } + /** + This is how to compute audio signals for normal opcodes: + (1) Zero all frames from 0 up to but not including Offset. + (2) Compute all frames from ksmps_offset up to but not including End. + (3) Zero all frames from End up to but not including ksmps. + Example from a C opcode: + uint32_t offset = p->h.insdshead->ksmps_offset; + uint32_t early = p->h.insdshead->ksmps_no_end; + uint32_t n, nsmps = CS_KSMPS; + if (UNLIKELY(offset)) memset(p->r, '\0', offset*sizeof(MYFLT)); + if (UNLIKELY(early)) { + nsmps -= early; + memset(&p->r[nsmps], '\0', early*sizeof(MYFLT)); + } + for (n = offset; n < nsmps; n++) { + input1 = MYFLT2LRND(p->a[n]); + p->r[n] = (MYFLT) (input1 >> input2); + } + So in C++ it should look like this (which is much easier to understand): + int frameIndex = 0; + for( ; frameIndex < kperiodOffset(); ++frameIndex) { + asignal[frameIndex] = 0; + } + for( ; frameIndex < kperiodEnd(); ++frameIndex) { + asignal[frameIndex] = compute(); + } + for( ; frameIndex < ksmps(); ++frameIndex) { + asignal[frameIndex] = 0; + } + */ + uint32_t kperiodOffset() const + { + return opds.insdshead->ksmps_offset; + } + uint32_t kperiodEnd() const + { + uint32_t end = opds.insdshead->ksmps_no_end; + if (end) { + return end; + } else { + return ksmps(); + } + } + uint32_t ksmps() const + { + return opds.insdshead->ksmps; + } + uint32_t output_arg_count() + { + return (uint32_t)opds.optext->t.outArgCount; + } + uint32_t input_arg_count() + { + return (uint32_t)opds.optext->t.inArgCount; + } + void log(CSOUND *csound, const char *format,...) + { + va_list args; + va_start(args, format); + if(csound) { + csound->MessageV(csound, 0, format, args); + } else { + vfprintf(stdout, format, args); + } + va_end(args); + } + void warn(CSOUND *csound, const char *format,...) + { + if(csound) { + if(csound->GetMessageLevel(csound) & CS_WARNMSG) { + va_list args; + va_start(args, format); + csound->MessageV(csound, CSOUNDMSG_WARNING, format, args); + va_end(args); + } + } else { + va_list args; + va_start(args, format); + vfprintf(stdout, format, args); + va_end(args); + } + } + int noteoff(CSOUND *csound) + { + return OK; + } + static int noteoff_(CSOUND *csound, void *opcode) + { + return reinterpret_cast(opcode)->noteoff(csound); + } + OPDS opds; +}; + +#if (__cplusplus >= 201103L) && !(defined(__wasi__)) + +/** + * The memory of non-POD C++ or C objects allocated on the heap by Csound + * plugins is managed not by Csound, but by the plugin module. This class + * performs that function. + * + * As long as all memory is allocated in or after csoundModuleCreate and + * de-allocated in csoundModuleDestroy, all will be well. The danger however + * is that memory leaks will occur if allocations are not matched with + * de-allocations, or worse, that crashes will occur if any objects are + * deleted twice or de-referenced after deletion. + * + * So, the plugin should manage a collection of all heap-allocated objects, + * keyed first off the Csound instance, and second off an object handle; and + * all such objects must be accessed only by handle, from this collection. + * + * In csoundModuleDestroy, all objects for the calling instance of Csound + * should be de-allocated, and the sub-collection for that instance should + * also be de-allocated. + * + * If then there are no more sub-collections for other instances of Csound, + * the entire contents of the collection should be de-allocated. + * + * This should be done as a singleton, and in a thread-safe way. + * + * There might still be a problem if any of the heap-allocated objects, + * themselves, have global static members, perhaps created by some external + * dependency. + * + * Please note, objects O in the declaration below must not be std::shared_ptr + * objects. Deletion of objects herein must be unconditional. Rather, the + * objects passed are raw pointers to instances of class O. + */ + template class heap_object_manager_t { + private: + std::map> objects_; + std::recursive_mutex mutex; + heap_object_manager_t(){}; + ~heap_object_manager_t(){}; + public: + static heap_object_manager_t &instance() { + static heap_object_manager_t singleton; + return singleton; + } + std::map> &objects() { + std::lock_guard lock(mutex); + return objects_; + } + /** + * Returns a list of pointers to all objects allocated for this + * instance of Csound. + */ + std::vector &objects_for_csound(CSOUND *csound) { + std::lock_guard lock(mutex); + auto &objects_for_csound_ = objects()[csound]; + return objects_for_csound_; + } + /** + * Returns the handle for the object; if the object has not yet been + * stored, inserts it into the list of object pointers for this + * instance of Csound; otherwise, returns the handle of the stored + * object pointer. + */ + int handle_for_object(CSOUND *csound, O *object) { + std::lock_guard lock(mutex); + auto &objects_for_csound_ = objects_for_csound(csound); + auto iterator = std::find(objects_for_csound_.begin(), objects_for_csound_.end(), object); + if (iterator == objects_for_csound_.end()) { + int handle = objects_for_csound_.size(); + objects_for_csound_.push_back(object); + if (diagnostics_enabled) std::fprintf(stderr, "heap_object_manager_t::handle_for_object %p: new object handle: %d (of %d)\n", object, handle, objects_for_csound_.size()); + return handle; + } else { + int handle = static_cast(iterator - objects_for_csound_.begin()); + if (diagnostics_enabled) std::fprintf(stderr, "heap_object_manager_t::handle_for_object: existing object handle: %d\n", handle); + return handle; + } + } + /** + * Returns the object pointer for the handle; + * if the object pointer has not been stored by + * handle, returns a null pointer. + */ + O *object_for_handle(CSOUND *csound, int handle) { + std::lock_guard lock(mutex); + auto &objects_for_csound_ = objects_for_csound(csound); + if (handle >= objects_for_csound_.size()) { + return nullptr; + } + O *object = objects_for_csound_[handle]; + if (diagnostics_enabled) std::fprintf(stderr, "heap_object_manager_t::object_for_handle: %p %d (of %d)\n", object, handle, objects_for_csound_.size()); + return object; + } + /** + * First destroys all objects created by the calling + * instance of Csound, then destroys the list of + * object pointers for this instance of Csound. + */ + void module_destroy(CSOUND *csound) { + std::lock_guard lock(mutex); + auto &objects_for_csound_ = objects_for_csound(csound); + for (int i = 0, n = objects_for_csound_.size(); i < n; ++i) { + delete objects_for_csound_[i]; + objects_for_csound_[i] == nullptr; + } + objects_for_csound_.clear(); + objects().erase(csound); + } +}; + +#endif + +} diff --git a/6.x/csound/README.md b/6.x/csound/README.md new file mode 100644 index 00000000..139a1762 --- /dev/null +++ b/6.x/csound/README.md @@ -0,0 +1 @@ +This folder just contains the latest headers from the csound engine. They are required by the plugins to build against this API. diff --git a/6.x/csound/Soundfile.hpp b/6.x/csound/Soundfile.hpp new file mode 100644 index 00000000..dbd285ff --- /dev/null +++ b/6.x/csound/Soundfile.hpp @@ -0,0 +1,190 @@ +/* + * C S O U N D + * + * L I C E N S E + * + * This software is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef CSOUND_SOUNDFILE_H +#define CSOUND_SOUNDFILE_H + +#ifdef SWIG +%module csnd6 +%{ +#include +#include +#include +#include +#include + %} +%include "std_string.i" +#ifdef SWIGPYTHON +%typemap(in) double *outputFrame { + static double buffer[16]; + $1 = &buffer[0]; + for (int i = 0, n = PySequence_Size($input); i < n; i++) { + PyObject *o = PyFloat_FromDouble($1[i]); + PySequence_SetItem($input, i, o); + } +} +%typemap(in) double *inputFrame { + static double buffer[16]; + $1 = &buffer[0]; + for (int i = 0, n = PySequence_Size($input); i < n; i++) { + PyObject *o = PySequence_ITEM($input, i); + $1[i] = PyFloat_AS_DOUBLE(o); + } +} +%typemap(in) (double *outputFrames, int samples) { + $1 = (double *) PyString_AsString($input); + $2 = PyString_Size($input) / sizeof(double); +} +%typemap(in) (double *inputFrames, int samples) { + $1 = (double *) PyString_AsString($input); + $2 = PyString_Size($input) / sizeof(double); +} +%typemap(in) double *mixedFrames { + $1 = (double *) PyString_AsString($input); +} + +#endif +#else +#include +#include +#include +#include +#include +#endif + +#if defined(WIN32) +#define SILENCE_PUBLIC __declspec(dllexport) +#elif defined(__GNUC__) +#define SILENCE_PUBLIC __attribute__ ( (visibility("default")) ) +#else +#define SILENCE_PUBLIC +#endif + +namespace csound +{ + /** + * Simple, basic read/write access, in sample frames, to PCM soundfiles. + * Reads and writes any format, but write defaults to WAV float format. + * This class is designed for Python wrapping with SWIG. + * See http://www.mega-nerd.com/libsndfile for more information + * on the underlying libsndfile library. + */ +#ifdef SWIG + class Soundfile +#else + class SILENCE_PUBLIC Soundfile +#endif + { + SNDFILE *sndfile; + SF_INFO sf_info; + protected: + virtual void initialize() ; + public: + Soundfile(); + virtual ~Soundfile() ; + virtual int getFramesPerSecond() const; + virtual void setFramesPerSecond(int framesPerSecond); + virtual int getChannelsPerFrame() const; + virtual void setChannelsPerFrame(int channelsPerFrame); + /** + * See sndfile.h for a descriptive list of format numbers. + */ + virtual int getFormat() const; + /** + * See sndfile.h for a descriptive list of format numbers. + */ + virtual void setFormat(int format); + /** + * Return the number of sample frames in a just opened file, + * or just after calling updateHeader. + */ + virtual int getFrames() const; + /** + * Open an existing soundfile for reading and/or writing. + */ + virtual int open(std::string filename); + /** + * Create a new soundfile for writing and/or reading. + * The default soundfile format is WAV PCM float samples at 44100 frames per second, stereo. + */ + virtual int create(std::string filename, int framesPerSecond = 44100, int channelsPerFrame = 2, int format = SF_FORMAT_WAV | SF_FORMAT_FLOAT); + /** + * Position the soundfile read/write pointer at the indicated sample frame. + * Set whence to 0 for SEEK_SET, 1 for SEEK_CUR, 2 for SEEK_END. + * Calling with whence = SEEK_CUR and frames = 0 returns the current read/write pointer. + */ + virtual int seek(int frames, int whence = 0); + virtual double seekSeconds(double seconds, int whence = 0); + /** + * Read one sample frame, and return it in a double array (in C++) or a sequence (in Python). + * The array or the sequence must already contain as many elements as there are channels. + * For efficiency, there is no bounds checking. + */ + virtual int readFrame(double *outputFrame); + /** + * Write one sample frame, from a double array (in C++) or a sequence (in Python). + * The array or the sequence must contain as many elements as there are channels. + * For efficiency, there is no checking of bounds or type in Python; the string must contain Floats. + * In Python this function is not thread-safe, as a static buffer is used internally. + */ + virtual int writeFrame(double *inputFrame); + /** + * Read one or more samples, and return them in a double array (in C++) or a binary string (in Python). + * The array or the string must already contain as many elements as there are samples (channels times frames). + * Channels are interleaved within frames. + * For efficiency, there is no bounds checking; on return the string will contain binary Float64. + * In Python this function is not thread-safe, as a static buffer is used internally. + */ + virtual int readFrames(double *outputFrames, int samples); + /** + * Write one or more samples, from a double array (in C++) or a binary string (in Python). + * The array or the string must contain as many elements as there are samples (channels times frames) + * Channels are interleaved within frames. + * For efficiency, there is no checking of bounds or type in Python; the string must contain binary Float64. + */ + virtual int writeFrames(double *inputFrames, int samples); + /** + * Mix one or more samples, from a double array (in C++) or a binary string (in Python), + * into the existing signal in the soundfile. + * The arrays or the strings must contain as many elements as there are samples (channels times frames) + * Channels are interleaved within frames. + * For efficiency, there is no checking of bounds or type in Python; the string must contain binary Float64. + */ + virtual int mixFrames(double *inputFrames, int samples, double *mixedFrames); + /** + * Update the soundfile header with the current file size, + * RIFF chunks, and so on. + */ + virtual void updateHeader(); + /** + * Close the soundfile. Should be called once for every opened or created soundfile, + * although the class destructor will automatically close an open soundfile. + */ + virtual int close() ; + /** + * Print to stderr any current error status message. + */ + virtual void error() const; + /** + * Make the soundfile be so many seconds of silence. + */ + virtual void blank(double duration); + }; +} +#endif diff --git a/6.x/csound/arrays.h b/6.x/csound/arrays.h new file mode 100644 index 00000000..563609a2 --- /dev/null +++ b/6.x/csound/arrays.h @@ -0,0 +1,124 @@ +/* + array.h: + + Copyright (C) 2011, 2017 John ffitch and Stephen Kyne + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef __ARRAY_H__ +#define __ARRAY_H__ + +static inline void tabinit(CSOUND *csound, ARRAYDAT *p, int size) +{ + size_t ss; + if (p->dimensions==0) { + p->dimensions = 1; + p->sizes = (int32_t*)csound->Calloc(csound, sizeof(int32_t)); + } + if (p->data == NULL) { + CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL); + p->arrayMemberSize = var->memBlockSize; + ss = p->arrayMemberSize*size; + p->data = (MYFLT*)csound->Calloc(csound, ss); + p->allocated = ss; + } else if( (ss = p->arrayMemberSize*size) > p->allocated) { + p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss); + memset((char*)(p->data)+p->allocated, '\0', ss-p->allocated); + p->allocated = ss; + } + if (p->dimensions==1) p->sizes[0] = size; + //p->dimensions = 1; +} + +static inline void tabinit_like(CSOUND *csound, ARRAYDAT *p, ARRAYDAT *tp) +{ + uint32_t ss = 1; + if(p->data == tp->data) { + return; + } + if (p->dimensions != tp->dimensions) { + p->sizes = (int32_t*)csound->ReAlloc(csound, p->sizes, + sizeof(int32_t)*tp->dimensions); + p->dimensions = tp->dimensions; + } + + for (int i=0; idimensions; i++) { + p->sizes[i] = tp->sizes[i]; + ss *= tp->sizes[i]; + } + + if (p->data == NULL) { + CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL); + p->arrayMemberSize = var->memBlockSize; + ss = p->arrayMemberSize*ss; + p->data = (MYFLT*)csound->Calloc(csound, ss); + p->allocated = ss; + } else if( (ss = p->arrayMemberSize*ss) > p->allocated) { + p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss); + p->allocated = ss; + } +} + +static inline int tabcheck(CSOUND *csound, ARRAYDAT *p, int size, OPDS *q) +{ + if (p->data==NULL || p->dimensions == 0) { + return csound->PerfError(csound, q, "%s", Str("Array not initialised")); + } + size_t s = p->arrayMemberSize*size; + if (s > p->allocated) { /* was arr->allocate */ + return csound->PerfError(csound, q, + Str("Array too small (allocated %zu < needed %zu), but cannot " + "allocate during performance pass. Allocate a bigger array at init time"), + p->allocated, s); + return NOTOK; + } + p->sizes[0] = size; + return OK; +} + +#if 0 +static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size) +{ + if (p->data==NULL || p->dimensions == 0 || + (p->dimensions==1 && p->sizes[0] < size)) { + size_t ss; + if (p->data == NULL) { + CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL); + p->arrayMemberSize = var->memBlockSize; + } + ss = p->arrayMemberSize*size; + if (p->data==NULL) { + p->data = (MYFLT*)csound->Calloc(csound, ss); + p->allocated = ss; + } + else if (ss > p->allocated) { + p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss); + p->allocated = ss; + } + if (p->dimensions==0) { + p->dimensions = 1; + p->sizes = (int32_t*)csound->Malloc(csound, sizeof(int32_t)); + } + p->sizes[0] = size; + } + //p->sizes[0] = size; +} +#endif + +#endif /* end of include guard: __ARRAY_H__ */ diff --git a/6.x/csound/cfgvar.h b/6.x/csound/cfgvar.h new file mode 100644 index 00000000..235312ae --- /dev/null +++ b/6.x/csound/cfgvar.h @@ -0,0 +1,249 @@ +/* + cfgvar.h: + + Copyright (C) 2005 Istvan Varga + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef CSOUND_CFGVAR_H +#define CSOUND_CFGVAR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* generic header structure */ + +typedef struct csCfgVariableHead_s { + union csCfgVariable_u *nxt; /* pointer to next structure in chain */ + unsigned char *name; /* name of the variable */ + void *p; /* pointer to value */ + int type; /* type (e.g. CSOUNDCFG_INTEGER) */ + int flags; /* bitwise OR of flags */ + unsigned char *shortDesc; /* short description (NULL if none) */ + unsigned char *longDesc; /* long description (NULL if none) */ +} csCfgVariableHead_t; + +/* int type */ + +typedef struct csCfgVariableInt_s { + union csCfgVariable_u *nxt; /* pointer to next structure in chain */ + unsigned char *name; /* name of the variable */ + int *p; /* pointer to value */ + int type; /* type (CSOUNDCFG_INTEGER) */ + int flags; /* bitwise OR of flags */ + unsigned char *shortDesc; /* short description (NULL if none) */ + unsigned char *longDesc; /* long description (NULL if none) */ + int min; /* minimum allowed value */ + int max; /* maximum allowed value */ +} csCfgVariableInt_t; + +/* boolean type (int with a value of 0 or 1) */ + +typedef struct csCfgVariableBoolean_s { + union csCfgVariable_u *nxt; /* pointer to next structure in chain */ + unsigned char *name; /* name of the variable */ + int *p; /* pointer to value */ + int type; /* type (CSOUNDCFG_BOOLEAN) */ + int flags; /* bitwise OR of flags */ + unsigned char *shortDesc; /* short description (NULL if none) */ + unsigned char *longDesc; /* long description (NULL if none) */ +} csCfgVariableBoolean_t; + +/* float type */ + +typedef struct csCfgVariableFloat_s { + union csCfgVariable_u *nxt; /* pointer to next structure in chain */ + unsigned char *name; /* name of the variable */ + float *p; /* pointer to value */ + int type; /* type (CSOUNDCFG_FLOAT) */ + int flags; /* bitwise OR of flags */ + unsigned char *shortDesc; /* short description (NULL if none) */ + unsigned char *longDesc; /* long description (NULL if none) */ + float min; /* minimum allowed value */ + float max; /* maximum allowed value */ +} csCfgVariableFloat_t; + +/* double type */ + +typedef struct csCfgVariableDouble_s { + union csCfgVariable_u *nxt; /* pointer to next structure in chain */ + unsigned char *name; /* name of the variable */ + double *p; /* pointer to value */ + int type; /* type (CSOUNDCFG_DOUBLE) */ + int flags; /* bitwise OR of flags */ + unsigned char *shortDesc; /* short description (NULL if none) */ + unsigned char *longDesc; /* long description (NULL if none) */ + double min; /* minimum allowed value */ + double max; /* maximum allowed value */ +} csCfgVariableDouble_t; + +/* MYFLT (float or double) type */ + +typedef struct csCfgVariableMYFLT_s { + union csCfgVariable_u *nxt; /* pointer to next structure in chain */ + unsigned char *name; /* name of the variable */ + MYFLT *p; /* pointer to value */ + int type; /* type (CSOUNDCFG_MYFLT) */ + int flags; /* bitwise OR of flags */ + unsigned char *shortDesc; /* short description (NULL if none) */ + unsigned char *longDesc; /* long description (NULL if none) */ + MYFLT min; /* minimum allowed value */ + MYFLT max; /* maximum allowed value */ +} csCfgVariableMYFLT_t; + +/* string type */ + +typedef struct csCfgVariableString_s { + union csCfgVariable_u *nxt; /* pointer to next structure in chain */ + unsigned char *name; /* name of the variable */ + char *p; /* value: array of 'maxlen' chars */ + int type; /* type (CSOUNDCFG_STRING) */ + int flags; /* bitwise OR of flags */ + unsigned char *shortDesc; /* short description (NULL if none) */ + unsigned char *longDesc; /* long description (NULL if none) */ + int maxlen; /* maximum length + 1 */ +} csCfgVariableString_t; + +/* union of all variable types */ + +typedef union csCfgVariable_u { + csCfgVariableHead_t h; + csCfgVariableInt_t i; + csCfgVariableBoolean_t b; + csCfgVariableFloat_t f; + csCfgVariableDouble_t d; + csCfgVariableMYFLT_t m; + csCfgVariableString_t s; +} csCfgVariable_t; + +/* types */ + +#define CSOUNDCFG_INTEGER 1 +#define CSOUNDCFG_BOOLEAN 2 +#define CSOUNDCFG_FLOAT 3 +#define CSOUNDCFG_DOUBLE 4 +#define CSOUNDCFG_MYFLT 5 +#define CSOUNDCFG_STRING 6 + +/* flags */ + +#define CSOUNDCFG_POWOFTWO 0x00000001 + +/* error codes */ + +#define CSOUNDCFG_SUCCESS 0 +#define CSOUNDCFG_INVALID_NAME -1 +#define CSOUNDCFG_INVALID_TYPE -2 +#define CSOUNDCFG_INVALID_FLAG -3 +#define CSOUNDCFG_NULL_POINTER -4 +#define CSOUNDCFG_TOO_HIGH -5 +#define CSOUNDCFG_TOO_LOW -6 +#define CSOUNDCFG_NOT_POWOFTWO -7 +#define CSOUNDCFG_INVALID_BOOLEAN -8 +#define CSOUNDCFG_MEMORY -9 +#define CSOUNDCFG_STRING_LENGTH -10 + +#define CSOUNDCFG_LASTERROR -10 + +/* -------- interface functions -------- */ + +/* This pragma must come before all public function declarations */ + + /** + * This function is similar to csoundCreateGlobalConfigurationVariable(), + * except it creates a configuration variable specific to Csound instance + * 'csound', and is suitable for calling from the Csound library + * (in csoundPreCompile()) or plugins (in csoundModuleCreate()). + * The other parameters and return value are the same as in the case of + * csoundCreateGlobalConfigurationVariable(). + */ + PUBLIC int + csoundCreateConfigurationVariable(CSOUND *csound, const char *name, + void *p, int type, int flags, + void *min, void *max, + const char *shortDesc, + const char *longDesc); + + /** + * Set the value of a configuration variable of Csound instance 'csound'. + * The 'name' and 'value' parameters, and return value are the same as + * in the case of csoundSetGlobalConfigurationVariable(). + */ + PUBLIC int csoundSetConfigurationVariable(CSOUND *csound, const char *name, + void *value); + + /** + * Set the value of a configuration variable of Csound instance 'csound', + * by parsing a string. + * The 'name' and 'value' parameters, and return value are the same as + * in the case of csoundParseGlobalConfigurationVariable(). + */ + PUBLIC int csoundParseConfigurationVariable(CSOUND *csound, const char *name, + const char *value); + + /** + * Return pointer to the configuration variable of Csound instace 'csound' + * with the specified name. + * The return value may be NULL if the variable is not found in the database. + */ + PUBLIC csCfgVariable_t + *csoundQueryConfigurationVariable(CSOUND *csound, const char *name); + + /** + * Create an alphabetically sorted list of all configuration variables + * of Csound instance 'csound'. + * Returns a pointer to a NULL terminated array of configuration variable + * pointers, or NULL on error. + * The caller is responsible for freeing the returned list with + * csoundDeleteCfgVarList(), however, the variable pointers in the list + * should not be freed. + */ + PUBLIC csCfgVariable_t **csoundListConfigurationVariables(CSOUND *csound); + + /** + * Release a configuration variable list previously returned + * by csoundListGlobalConfigurationVariables() or + * csoundListConfigurationVariables(). + */ + PUBLIC void csoundDeleteCfgVarList(CSOUND* csound, csCfgVariable_t **lst); + + /** + * Remove the configuration variable of Csound instance 'csound' with the + * specified name from the database. Plugins need not call this, as all + * configuration variables are automatically deleted by csoundReset(). + * Return value is CSOUNDCFG_SUCCESS in case of success, or + * CSOUNDCFG_INVALID_NAME if the variable was not found. + */ + PUBLIC int csoundDeleteConfigurationVariable(CSOUND *csound, + const char *name); + /** + * Returns pointer to an error string constant for the specified + * CSOUNDCFG error code. The string is not translated. + */ + PUBLIC const char *csoundCfgErrorCodeToString(int errcode); + +/* This pragma must come after all public function declarations */ + +#ifdef __cplusplus +} +#endif + +#endif /* CSOUND_CFGVAR_H */ + diff --git a/6.x/csound/csPerfThread.cpp b/6.x/csound/csPerfThread.cpp new file mode 100644 index 00000000..582404c8 --- /dev/null +++ b/6.x/csound/csPerfThread.cpp @@ -0,0 +1,888 @@ +/* + csPerfThread.cpp: + + Copyright (C) 2005 Istvan Varga + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include +#include + +#include "csound.hpp" +#include "csPerfThread.hpp" +#include + +// ---------------------------------------------------------------------------- + +/** + * Base class for event messages. + */ + +class CsoundPerformanceThreadMessage { + protected: + CsoundPerformanceThread *pt_; + void SetPaused(int state) + { + pt_->paused = state; + } + int GetPaused() + { + return pt_->paused; + } + recordData_t * getRecordData() + { + return &(pt_->recordData); + } + void lockRecord() + { + csoundLockMutex(pt_->recordLock); + } + void unlockRecord() + { + csoundUnlockMutex(pt_->recordLock); + } + + void QueueMessage(CsoundPerformanceThreadMessage *msg) + { + pt_->QueueMessage(msg); + } + + public: + CsoundPerformanceThreadMessage *nxt; + virtual int run() = 0; + CsoundPerformanceThreadMessage(CsoundPerformanceThread *pt) + { + pt_ = pt; + nxt = (CsoundPerformanceThreadMessage*) 0; + } + virtual ~CsoundPerformanceThreadMessage() {} +}; + +/** + * Unpause performance + */ + +class CsPerfThreadMsg_Play : public CsoundPerformanceThreadMessage { + public: + CsPerfThreadMsg_Play(CsoundPerformanceThread *pt) + : CsoundPerformanceThreadMessage(pt) {} + int run() + { + SetPaused(0); + return 0; + } + ~CsPerfThreadMsg_Play() {} +}; + +/** + * Pause performance + */ + +class CsPerfThreadMsg_Pause : public CsoundPerformanceThreadMessage { + public: + CsPerfThreadMsg_Pause(CsoundPerformanceThread *pt) + : CsoundPerformanceThreadMessage(pt) {} + int run() + { + SetPaused(1); + return 0; + } + ~CsPerfThreadMsg_Pause() {} +}; + +/** + * Toggle pause mode + */ + +class CsPerfThreadMsg_TogglePause : public CsoundPerformanceThreadMessage { + public: + CsPerfThreadMsg_TogglePause(CsoundPerformanceThread *pt) + : CsoundPerformanceThreadMessage(pt) {} + int run() + { + SetPaused(GetPaused() ? 0 : 1); + return 0; + } + ~CsPerfThreadMsg_TogglePause() {} +}; + +extern "C" { + static uintptr_t recordThread_(void *recordData_) + { + recordData_t *recordData = (recordData_t *)recordData_; + int retval = 0; + const int bufsize = 4096; + MYFLT buf[bufsize]; + _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON); + while (recordData->running) { + csoundLockMutex (recordData->mutex); + csoundCondWait(recordData->condvar, recordData->mutex); + int sampsread; + do { + sampsread = csoundReadCircularBuffer(NULL, recordData->cbuf, + buf, bufsize); +#ifdef USE_DOUBLE + sf_write_double((SNDFILE *) recordData->sfile, + buf, sampsread); +#else + sf_write_float((SNDFILE *) recordData->sfile, + buf, sampsread); +#endif + } while(sampsread != 0); + csoundUnlockMutex (recordData->mutex); + } + return (uintptr_t) ((unsigned int) retval); + } +} + +class CsPerfThreadMsg_Record: public CsoundPerformanceThreadMessage { +public: + CsPerfThreadMsg_Record(CsoundPerformanceThread *pt, + std::string filename, + int samplebits = 16, + int numbufs = 4) + : CsoundPerformanceThreadMessage(pt) + { + this->filename = filename; + CsoundPerformanceThreadMessage::lockRecord(); + recordData_t *recordData = CsoundPerformanceThreadMessage::getRecordData(); + if (recordData->running) { + CsoundPerformanceThreadMessage::unlockRecord(); + return; + } + CSOUND * csound = pt_->GetCsound(); + if (!csound) { + return; + } + int bufsize = csoundGetOutputBufferSize(csound) + * csoundGetNchnls(csound) * numbufs; + recordData->cbuf = csoundCreateCircularBuffer(csound, + bufsize, + sizeof(MYFLT)); + + if (!recordData->cbuf) { + csoundMessage(csound, "Could create recording buffer."); + return; + } + + SF_INFO sf_info; + sf_info.samplerate = csoundGetSr(csound); + sf_info.channels = csoundGetNchnls(csound); + switch (samplebits) { + case 32: + sf_info.format = SF_FORMAT_FLOAT; + break; + case 24: + sf_info.format = SF_FORMAT_PCM_24; + break; + case 16: + default: + sf_info.format = SF_FORMAT_PCM_16; + break; + } + + sf_info.format |= SF_FORMAT_WAV; + + recordData->sfile = (void *) sf_open(filename.c_str(), + SFM_WRITE, + &sf_info); + if (!recordData->sfile) { + csoundMessage(csound, "Could not open file for recording."); + csoundDestroyCircularBuffer(csound, recordData->cbuf); + return; + } + sf_command((SNDFILE *) recordData->sfile, SFC_SET_CLIPPING, + NULL, SF_TRUE); + + recordData->running = true; + recordData->thread = csoundCreateThread(recordThread_, (void*) recordData); + + + CsoundPerformanceThreadMessage::unlockRecord(); + } + int run() + { + return 0; + } + ~CsPerfThreadMsg_Record() { + /* VL: This appears to break the recording process + needs to be investigated. + */ + /* + CsoundPerformanceThreadMessage::lockRecord(); + recordData_t *recordData = CsoundPerformanceThreadMessage::getRecordData(); + if (recordData->sfile) { + sf_close((SNDFILE *) recordData->sfile); + recordData->sfile = NULL; + } + CsoundPerformanceThreadMessage::unlockRecord(); + */ + } +private: + std::string filename; + +}; + +class CsPerfThreadMsg_StopRecord: public CsoundPerformanceThreadMessage { +public: + CsPerfThreadMsg_StopRecord(CsoundPerformanceThread *pt) + : CsoundPerformanceThreadMessage(pt) {} + int run() + { + + CsoundPerformanceThreadMessage::lockRecord(); + recordData_t *recordData = CsoundPerformanceThreadMessage::getRecordData(); + if (recordData->running) { + recordData->running = false; + csoundJoinThread(recordData->thread); + /* VL: This appears to break the recording process + needs to be investigated. I'm reverting the old code for now. + */ + sf_close((SNDFILE *) recordData->sfile); + /* + if (recordData->sfile) { + sf_close((SNDFILE *) recordData->sfile); + recordData->sfile = NULL; + } + */ + } + + CsoundPerformanceThreadMessage::unlockRecord(); + + return 0; + } + ~CsPerfThreadMsg_StopRecord(){} +private: + // bool start; +}; + + +/** + * Stop performance (cannot be continued) + */ + +class CsPerfThreadMsg_Stop : public CsoundPerformanceThreadMessage { + public: + CsPerfThreadMsg_Stop(CsoundPerformanceThread *pt) + : CsoundPerformanceThreadMessage(pt) + { + CsoundPerformanceThreadMessage::QueueMessage( + new CsPerfThreadMsg_StopRecord(pt)); + } + int run() + { + return 1; + } + ~CsPerfThreadMsg_Stop() {} +}; + +/** + * Score event message + * + * absp2mode: if non-zero, start times are measured from the beginning of + * performance, instead of the current time + * opcod: score opcode (e.g. 'i' for a note event) + * pcnt: number of p-fields + * *p: array of p-fields, p[0] is p1 + */ + +class CsPerfThreadMsg_ScoreEvent : public CsoundPerformanceThreadMessage { + private: + char opcod; + int absp2mode; + int pcnt; + MYFLT *pp; + MYFLT p[10]; + public: + CsPerfThreadMsg_ScoreEvent(CsoundPerformanceThread *pt, + int absp2mode, char opcod, + int pcnt, const MYFLT *p) + : CsoundPerformanceThreadMessage(pt) + { + this->opcod = opcod; + this->absp2mode = absp2mode; + this->pcnt = pcnt; + if (pcnt <= 10) + this->pp = &(this->p[0]); + else + this->pp = new MYFLT[(unsigned int) pcnt]; + for (int i = 0; i < pcnt; i++) + this->pp[i] = p[i]; + } + int run() { + CSOUND *csound = pt_->GetCsound(); + if (absp2mode && pcnt > 1) { + double p2 = (double) pp[1] - csoundGetScoreTime(csound); + if (p2 < 0.0) { + if (pcnt > 2 && pp[2] >= (MYFLT) 0 && + (opcod == 'a' || opcod == 'i')) { + pp[2] = (MYFLT) ((double) pp[2] + p2); + if (pp[2] <= (MYFLT) 0) + return 0; + } + p2 = 0.0; + } + pp[1] = (MYFLT) p2; + } + if (csoundScoreEvent(csound, opcod, pp, (long) pcnt) != 0) + csoundMessageS(csound, CSOUNDMSG_WARNING, + "WARNING: could not create score event\n"); + return 0; + } + ~CsPerfThreadMsg_ScoreEvent() + { + if (pcnt > 10) + delete[] pp; + } +}; + +/** + * Score event message as a string + */ + +class CsPerfThreadMsg_InputMessage : public CsoundPerformanceThreadMessage { + private: + int len; + char *sp; + char s[128]; + public: + CsPerfThreadMsg_InputMessage(CsoundPerformanceThread *pt, const char *s) + : CsoundPerformanceThreadMessage(pt) + { + len = (int) strlen(s); + if (len < 128) + this->sp = &(this->s[0]); + else + this->sp = new char[(unsigned int) (len + 1)]; + strcpy(this->sp, s); + } + int run() + { + csoundInputMessage(pt_->GetCsound(), sp); + return 0; + } + ~CsPerfThreadMsg_InputMessage() + { + if (len >= 128) + delete[] sp; + } +}; + +/** + * Seek to the specified score time + */ + +class CsPerfThreadMsg_SetScoreOffsetSeconds + : public CsoundPerformanceThreadMessage { +private: + double timeVal; +public: + CsPerfThreadMsg_SetScoreOffsetSeconds(CsoundPerformanceThread *pt, + double timeVal) + : CsoundPerformanceThreadMessage(pt) + { + this->timeVal = timeVal; + } + int run() + { + csoundSetScoreOffsetSeconds(pt_->GetCsound(), (MYFLT) timeVal); + return 0; + } + ~CsPerfThreadMsg_SetScoreOffsetSeconds() {} +}; + +// ---------------------------------------------------------------------------- + +/** + * Performs the score until end of score, error, or receiving a stop event. + * Returns a negative value on error. + */ + +int CsoundPerformanceThread::Perform() +{ + int retval = 0; + do { + while (firstMessage) { + csoundLockMutex(queueLock); + do { + CsoundPerformanceThreadMessage *msg; + // get oldest message + msg = (CsoundPerformanceThreadMessage*) firstMessage; + if (!msg) + break; + // unlink from FIFO + firstMessage = msg->nxt; + if (!msg->nxt) + lastMessage = (CsoundPerformanceThreadMessage*) 0; + // process and destroy message + retval = msg->run(); + delete msg; // TODO: This should be moved out of the Perform function + } while (!retval); + if (paused) + csoundWaitThreadLock(pauseLock, (size_t) 0); + // mark queue as empty + csoundNotifyThreadLock(flushLock); + csoundUnlockMutex(queueLock); + // if error or end of score, return now + if (retval) + goto endOfPerf; + // fprintf(stderr, "Error or end of score, returning now."); + // if paused, wait until a new message is received, then loop back + if (!paused) + break; + // VL: if this is paused, then it will double lock. + csoundWaitThreadLockNoTimeout(pauseLock); + csoundNotifyThreadLock(pauseLock); + } + if(processcallback != NULL) + processcallback(cdata); + retval = csoundPerformKsmps(csound); + if (recordData.running) { + MYFLT *spout = csoundGetSpout(csound); + int len = csoundGetKsmps(csound) * csoundGetNchnls(csound); + if (csoundGet0dBFS(csound) != 1.0) { + MYFLT zdbfs = csoundGet0dBFS(csound); + MYFLT *modspout = spout; + for (int i = 0; i < len; i++) { + *modspout /= zdbfs; + modspout++; + } + } + int written = csoundWriteCircularBuffer(NULL, recordData.cbuf, + spout, len); + if (written != len) { + csoundMessage(csound, "perfThread record buffer overrun.\n"); + } + } + csoundCondSignal(recordData.condvar); // Needs to be outside the if + // for the case where stop record was requested + } while (!retval); + endOfPerf: + status = retval; + csoundCleanup(csound); + // delete any pending messages + csoundLockMutex(queueLock); + { + CsoundPerformanceThreadMessage *msg; + msg = (CsoundPerformanceThreadMessage*) firstMessage; + firstMessage = (CsoundPerformanceThreadMessage*) 0; + lastMessage = (CsoundPerformanceThreadMessage*) 0; + while (msg) { + CsoundPerformanceThreadMessage *nxt = msg->nxt; + delete msg; + msg = nxt; + } + } + csoundNotifyThreadLock(flushLock); + csoundUnlockMutex(queueLock); + //running = 0; + return retval; +} + +class CsPerfThread_PerformScore { + private: + CsoundPerformanceThread *pt; + public: + int Perform() + { + return pt->Perform(); + } + CsPerfThread_PerformScore(void *p) + { + pt = (CsoundPerformanceThread*) p; + } + ~CsPerfThread_PerformScore() + { + } +}; + +extern "C" { + static uintptr_t csoundPerformanceThread_(void *userData) + { + CsPerfThread_PerformScore p(userData); + _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON); + // perform the score + int retval = p.Perform(); + // return positive value if stopped or end of score, and negative on error + return (uintptr_t) ((unsigned int) retval); + } +} + +void CsoundPerformanceThread::csPerfThread_constructor(CSOUND *csound_) +{ + csound = csound_; + firstMessage = (CsoundPerformanceThreadMessage*) 0; + lastMessage = (CsoundPerformanceThreadMessage*) 0; + queueLock = (void*) 0; + pauseLock = (void*) 0; + flushLock = (void*) 0; + recordLock = (void *) 0; + perfThread = (void*) 0; + paused = 1; + status = CSOUND_MEMORY; + cdata = 0; + processcallback = 0; + running = 0; + queueLock = csoundCreateMutex(0); + if (!queueLock) + return; + pauseLock = csoundCreateThreadLock(); + if (!pauseLock) + return; + flushLock = csoundCreateThreadLock(); + if (!flushLock) + return; + recordLock = csoundCreateMutex(0); + if (!recordLock) + return; + try { + lastMessage = new CsPerfThreadMsg_Pause(this); + } + catch (std::bad_alloc&) { + return; + } + firstMessage = lastMessage; + recordData.cbuf = NULL; + recordData.sfile = NULL; + recordData.thread = NULL; + recordData.running = false; + + recordData.mutex = csoundCreateMutex (0); + recordData.condvar = csoundCreateCondVar(); + + perfThread = csoundCreateThread(csoundPerformanceThread_, (void*) this); + if (perfThread) { + status = 0; + running = 1; + } +} + +// ---------------------------------------------------------------------------- + +/** + * CsoundPerformanceThread(Csound *) + * CsoundPerformanceThread(CSOUND *) + * + * Performs a score in a separate thread until the end of score is reached, + * the playback (which is paused by default) is stopped by calling + * CsoundPerformanceThread::Stop(), or an error occurs. + * The constructor takes a Csound instance pointer as argument; it assumes + * that csoundCompile() was called successfully before creating the + * performance thread. Once the playback is stopped for one of the above + * mentioned reasons, the performance thread calls csoundCleanup() and + * returns. + */ + +CsoundPerformanceThread::CsoundPerformanceThread(Csound *csound) +{ + csPerfThread_constructor(csound->GetCsound()); +} + +CsoundPerformanceThread::CsoundPerformanceThread(CSOUND *csound) +{ + csPerfThread_constructor(csound); +} + +CsoundPerformanceThread::~CsoundPerformanceThread() +{ + // stop performance if it is still running + if (!status) + this->Stop(); // FIXME: should handle memory errors here + this->Join(); + if (queueLock) { + csoundDestroyMutex(queueLock); + } + if (pauseLock) { + csoundDestroyMutex(pauseLock); + } + if (flushLock) { + csoundDestroyMutex(flushLock); + } + if (recordLock) { + csoundDestroyMutex(recordLock); + } + if (recordData.mutex) { + csoundDestroyMutex(recordData.mutex); + } + if (recordData.condvar) { + csoundDestroyCondVar(recordData.condvar); + } +} + +// ---------------------------------------------------------------------------- + +void CsoundPerformanceThread::QueueMessage(CsoundPerformanceThreadMessage *msg) +{ + if (status) { + delete msg; + return; + } + csoundLockMutex(queueLock); + // link message into FIFO + if (!lastMessage) + firstMessage = msg; + else + lastMessage->nxt = msg; + lastMessage = msg; + // mark queue as non-empty + csoundWaitThreadLock(flushLock, (size_t) 0); + // wake up from pause + csoundNotifyThreadLock(pauseLock); + csoundUnlockMutex(queueLock); +} + +void CsoundPerformanceThread::Play() +{ + QueueMessage(new CsPerfThreadMsg_Play(this)); +} + +void CsoundPerformanceThread::Pause() +{ + QueueMessage(new CsPerfThreadMsg_Pause(this)); +} + +void CsoundPerformanceThread::TogglePause() +{ + QueueMessage(new CsPerfThreadMsg_TogglePause(this)); +} + +void CsoundPerformanceThread::Stop() +{ + QueueMessage(new CsPerfThreadMsg_Stop(this)); +} + +void CsoundPerformanceThread::Record(std::string filename, + int samplebits, + int numbufs) +{ + QueueMessage(new CsPerfThreadMsg_Record(this, filename, + samplebits, numbufs)); +} + +void CsoundPerformanceThread::StopRecord() +{ + QueueMessage(new CsPerfThreadMsg_StopRecord(this)); +} + +void CsoundPerformanceThread::ScoreEvent(int absp2mode, char opcod, + int pcnt, const MYFLT *p) +{ + QueueMessage(new CsPerfThreadMsg_ScoreEvent(this, + absp2mode, opcod, pcnt, p)); +} + +void CsoundPerformanceThread::InputMessage(const char *s) +{ + QueueMessage(new CsPerfThreadMsg_InputMessage(this, s)); +} + +void CsoundPerformanceThread::SetScoreOffsetSeconds(double timeVal) +{ + QueueMessage(new CsPerfThreadMsg_SetScoreOffsetSeconds(this, timeVal)); +} + +int CsoundPerformanceThread::Join() +{ + int retval; + retval = status; + + if (recordData.running) { + recordData.running = false; + csoundCondSignal(recordData.condvar); + csoundJoinThread(recordData.thread); + } + if (perfThread) { + retval = csoundJoinThread(perfThread); + perfThread = (void*) 0; + } + + // delete any pending messages + { + CsoundPerformanceThreadMessage *msg; + msg = (CsoundPerformanceThreadMessage*) firstMessage; + firstMessage = (CsoundPerformanceThreadMessage*) 0; + lastMessage = (CsoundPerformanceThreadMessage*) 0; + while (msg) { + CsoundPerformanceThreadMessage *nxt = msg->nxt; + delete msg; + msg = nxt; + } + } + // delete all thread locks + if (queueLock) { + csoundDestroyMutex(queueLock); + queueLock = (void*) 0; + } + if (pauseLock) { + csoundNotifyThreadLock(pauseLock); + csoundDestroyThreadLock(pauseLock); + pauseLock = (void*) 0; + } + if (flushLock) { + csoundNotifyThreadLock(flushLock); + csoundDestroyThreadLock(flushLock); + flushLock = (void*) 0; + } + + running = 0; + return retval; +} + +/** + * Waits until all pending messages (pause, send score event, etc.) + * are actually received by the performance thread. + */ + +void CsoundPerformanceThread::FlushMessageQueue() +{ + if (firstMessage) { + csoundWaitThreadLockNoTimeout(flushLock); + csoundNotifyThreadLock(flushLock); + } +} + + +// This section has been added to have a C layer exposing +// CsoundPerformanceThread, to facilitate the wrapping of +// CsoundPerformanceThread through FFI libraries. +extern "C" { + +#ifndef PUBLIK +#if (defined(WIN32) || defined(_WIN32)) +# define PUBLIK __declspec(dllexport) +#elif defined(__GNUC__) //&& !defined(__MACH__) +# define PUBLIK __attribute__ ( (visibility("default")) ) +#else +# define PUBLIK +#endif +#endif + +typedef void* Cpt; + +PUBLIK Cpt NewCsoundPT(CSOUND *csound) +{ + CsoundPerformanceThread *pt = new CsoundPerformanceThread(csound); + return (void *)pt; +} + +PUBLIK void DeleteCsoundPT(Cpt pt) +{ + CsoundPerformanceThread *cpt = (CsoundPerformanceThread *)pt; + delete cpt; +} + +PUBLIK int CsoundPTisRunning(Cpt pt) +{ + CsoundPerformanceThread *cpt = (CsoundPerformanceThread *)pt; + return cpt->isRunning(); +} + +PUBLIK void *CsoundPTgetProcessCB(Cpt pt) +{ + CsoundPerformanceThread *cpt = (CsoundPerformanceThread *)pt; + return cpt->GetProcessCallback(); +} + +PUBLIK void CsoundPTsetProcessCB(Cpt pt, void (*callback)(void *), void *cbData) +{ + CsoundPerformanceThread *cpt = (CsoundPerformanceThread *)pt; + cpt->SetProcessCallback(callback, cbData); +} + +PUBLIK CSOUND *CsoundPTgetCsound(Cpt pt) +{ + CsoundPerformanceThread *cpt = (CsoundPerformanceThread *)pt; + return cpt->GetCsound(); +} + +PUBLIK int CsoundPTgetStatus(Cpt pt) +{ + CsoundPerformanceThread *cpt = (CsoundPerformanceThread *)pt; + return cpt->GetStatus(); +} + +PUBLIK void CsoundPTplay(Cpt pt) +{ + CsoundPerformanceThread *cpt = (CsoundPerformanceThread *)pt; + cpt->Play(); +} + +PUBLIK void CsoundPTpause(Cpt pt) +{ + CsoundPerformanceThread *cpt = (CsoundPerformanceThread *)pt; + cpt->Pause(); +} + +PUBLIK void CsoundPTtogglePause(Cpt pt) +{ + CsoundPerformanceThread *cpt = (CsoundPerformanceThread *)pt; + cpt->TogglePause(); +} + +PUBLIK void CsoundPTstop(Cpt pt) +{ + CsoundPerformanceThread *cpt = (CsoundPerformanceThread *)pt; + cpt->Stop(); +} + +PUBLIK void CsoundPTrecord(Cpt pt, const char *filename, int samplebits, int numbufs) +{ + CsoundPerformanceThread *cpt = (CsoundPerformanceThread *)pt; + std::string fname(filename); + cpt->Record(fname, samplebits, numbufs); +} + +PUBLIK void CsoundPTstopRecord(Cpt pt) +{ + CsoundPerformanceThread *cpt = (CsoundPerformanceThread *)pt; + cpt->StopRecord(); +} + +PUBLIK void CsoundPTscoreEvent(Cpt pt, int absp2mode, char opcod, int pcnt, MYFLT *p) +{ + CsoundPerformanceThread *cpt = (CsoundPerformanceThread *)pt; + cpt->ScoreEvent(absp2mode, opcod, pcnt, p); +} + +PUBLIK void CsoundPTinputMessage(Cpt pt, const char *s) +{ + CsoundPerformanceThread *cpt = (CsoundPerformanceThread *)pt; + cpt->InputMessage(s); +} + +PUBLIK void CsoundPTsetScoreOffsetSeconds(Cpt pt, double timeVal) +{ + CsoundPerformanceThread *cpt = (CsoundPerformanceThread *)pt; + cpt->SetScoreOffsetSeconds(timeVal); +} + +PUBLIK int CsoundPTjoin(Cpt pt) +{ + CsoundPerformanceThread *cpt = (CsoundPerformanceThread *)pt; + return cpt->Join(); +} + +PUBLIK void CsoundPTflushMessageQueue(Cpt pt) +{ + CsoundPerformanceThread *cpt = (CsoundPerformanceThread *)pt; + cpt->FlushMessageQueue(); +} + +} // extern "C" + diff --git a/6.x/csound/csPerfThread.hpp b/6.x/csound/csPerfThread.hpp new file mode 100644 index 00000000..d0802826 --- /dev/null +++ b/6.x/csound/csPerfThread.hpp @@ -0,0 +1,239 @@ +/* + csPerfThread.hpp: + + Copyright (C) 2005 Istvan Varga + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef CSOUND_CSPERFTHREAD_HPP +#define CSOUND_CSPERFTHREAD_HPP + +class CsoundPerformanceThreadMessage; +class CsPerfThread_PerformScore; + +#ifdef SWIG +%include +#else +#include +#endif + +/** + * CsoundPerformanceThread(Csound *) + * CsoundPerformanceThread(CSOUND *) + * + * Performs a score in a separate thread until the end of score is reached, + * the playback (which is paused by default) is stopped by calling + * CsoundPerformanceThread::Stop(), or an error occurs. + * The constructor takes a Csound instance pointer as argument; it assumes + * that csoundCompile() was called successfully before creating the + * performance thread. Once the playback is stopped for one of the above + * mentioned reasons, the performance thread calls csoundCleanup() and + * returns. + + An example program using the CsoundPerformanceThread class + +#include +#include "csound.hpp" +#include "csPerfThread.hpp" + +int main(int argc, char *argv[]) +{ + int result=0; + Csound cs; + result = cs.Compile(argc,argv); + + if(!result) + { + CsoundPerformanceThread perfThread(cs.GetCsound()); + perfThread.Play(); // Starts performance + while(perfThread.GetStatus() == 0); + // nothing to do here... + // but you could process input events, graphics etc + perfThread.Stop(); // Stops performance. In fact, performance should have + // already finished, so this is just an example of how + //to stop if you need + perfThread.Join(); // always call Join() after Stop() as a rule of thumb. + } + else{ + printf("csoundCompile returned an error\n"); + return 1; + } + + return 0; +} +*/ + +#ifdef __SSE__ + #include +#ifndef _MM_DENORMALS_ZERO_ON + #define _MM_DENORMALS_ZERO_MASK 0x0040 + #define _MM_DENORMALS_ZERO_ON 0x0040 + #define _MM_DENORMALS_ZERO_OFF 0x0000 + #define _MM_SET_DENORMALS_ZERO_MODE(mode) \ + _mm_setcsr((_mm_getcsr() & ~_MM_DENORMALS_ZERO_MASK) | (mode)) + #define _MM_GET_DENORMALS_ZERO_MODE() \ + (_mm_getcsr() & _MM_DENORMALS_ZERO_MASK) + #endif +#else +#if !defined(_MM_SET_DENORMALS_ZERO_MODE) + #define _MM_DENORMALS_ZERO_MASK 0 + #define _MM_DENORMALS_ZERO_ON 0 + #define _MM_DENORMALS_ZERO_OFF 0 + #define _MM_SET_DENORMALS_ZERO_MODE(mode) +#endif +#endif + + +#ifdef SWIGPYTHON +struct PUBLIC pycallbackdata { + PyObject *func; + PyObject *data; +}; +#endif + +typedef struct { + void *cbuf; + void *sfile; + void *thread; + bool running; + void* condvar; + void* mutex; +} recordData_t; + +class PUBLIC CsoundPerformanceThread { + private: + CSOUND *csound; + volatile CsoundPerformanceThreadMessage *firstMessage; + CsoundPerformanceThreadMessage *lastMessage; + void *queueLock; // this is actually a mutex + void *pauseLock; + void *flushLock; + void *recordLock; + void *perfThread; + int paused; + int status; + void *cdata; + recordData_t recordData; + int running; + void (*processcallback)(void *cdata); + int Perform(); + void csPerfThread_constructor(CSOUND *); + void QueueMessage(CsoundPerformanceThreadMessage *); + public: +#ifdef SWIGPYTHON + PyThreadState *_tstate; + pycallbackdata pydata; +#endif + /** + * Returns 1 if the performance thread is running, 0 otherwise + */ + int isRunning() { return running;} + + /** + * Returns the process callback as a void pointer + */ + void *GetProcessCallback() { return (void *)processcallback; } + + /** + * Sets the process callback. + */ + void SetProcessCallback(void (*Callback)(void *), void *cbdata){ + processcallback = Callback; + cdata = cbdata; + } + /** + * Returns the Csound instance pointer. + */ + CSOUND *GetCsound() + { + return csound; + } + /** + * Returns the current status, zero if still playing, positive if + * the end of score was reached or performance was stopped, and + * negative if an error occured. + */ + int GetStatus() + { + return status; + } + /** + * Continues performance if it was paused. + */ + void Play(); + /** + * Pauses performance (can be continued by calling Play()). + */ + void Pause(); + /** + * Pauses performance unless it is already paused, in which case + * it is continued. + */ + void TogglePause(); + /** + * Stops performance (cannot be continued). + */ + void Stop(); + /** + * Starts recording the output from Csound. The sample rate and number + * of channels are taken directly from the running Csound instance. + */ + void Record(std::string filename, int samplebits = 16, int numbufs = 4); + /** + * Stops recording and closes audio file. + */ + void StopRecord(); + /** + * Sends a score event of type 'opcod' (e.g. 'i' for a note event), with + * 'pcnt' p-fields in array 'p' (p[0] is p1). If absp2mode is non-zero, + * the start time of the event is measured from the beginning of + * performance, instead of the default of relative to the current time. + */ + void ScoreEvent(int absp2mode, char opcod, int pcnt, const MYFLT *p); + /** + * Sends a score event as a string, similarly to line events (-L). + */ + void InputMessage(const char *s); + /** + * Sets the playback time pointer to the specified value (in seconds). + */ + void SetScoreOffsetSeconds(double timeVal); + /** + * Waits until the performance is finished or fails, and returns a + * positive value if the end of score was reached or Stop() was called, + * and a negative value if an error occured. Also releases any resources + * associated with the performance thread object. + */ + int Join(); + /** + * Waits until all pending messages (pause, send score event, etc.) + * are actually received by the performance thread. + */ + void FlushMessageQueue(); + // -------- + CsoundPerformanceThread(Csound *); + CsoundPerformanceThread(CSOUND *); + ~CsoundPerformanceThread(); + // -------- + friend class CsoundPerformanceThreadMessage; + friend class CsPerfThread_PerformScore; +}; + + +#endif // CSOUND_CSPERFTHREAD_HPP diff --git a/6.x/csound/cs_glue.hpp b/6.x/csound/cs_glue.hpp new file mode 100644 index 00000000..1b4613f2 --- /dev/null +++ b/6.x/csound/cs_glue.hpp @@ -0,0 +1,707 @@ +/* + cs_glue.hpp: + + Copyright (C) 2005, 2006 Istvan Varga + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef CSOUND_CS_GLUE_HPP +#define CSOUND_CS_GLUE_HPP + +/** + * CsoundOpcodeList(CSOUND *) + * CsoundOpcodeList(Csound *) + * + * Creates an alphabetically sorted opcode list for a Csound instance. + * Should be called after csoundCompile() or Csound::Compile(). + */ + +class PUBLIC CsoundOpcodeList { + private: + opcodeListEntry *lst; + int cnt; + public: + /** + * Returns the number of opcodes, or -1 if there is no list. + */ + int Count(); + /** + * Returns the name of the opcode at index 'ndx' (counting from zero), + * or NULL if the index is out of range. + */ + const char *Name(int ndx); + /** + * Returns the output types of the opcode at index 'ndx' (counting from + * zero), or NULL if the index is out of range. + */ + const char *OutTypes(int ndx); + /** + * Returns the input types of the opcode at index 'ndx' (counting from + * zero), or NULL if the index is out of range. + */ + const char *InTypes(int ndx); + /** + * Releases the memory used by the opcode list. Should be called + * before the Csound instance is destroyed or reset. + */ + void Clear(); + // -------- + CsoundOpcodeList(CSOUND *csound); + CsoundOpcodeList(Csound *csound); + ~CsoundOpcodeList(); +}; + +/** + * CsoundChannelList(CSOUND *) + * CsoundChannelList(Csound *) + * + * Creates an alphabetically sorted list of named channels of a Csound + * instance. Should be called after csoundCompile() or Csound::Compile(). + */ + +class PUBLIC CsoundChannelList { + private: + controlChannelInfo_t *lst; + int cnt; + CSOUND *csound; + void ResetVariables(); + int GetChannelMetaData(int ndx, controlChannelHints_t *hints); + public: + /** + * Returns the number of channels (-1 if there is no list). + */ + int Count(); + /** + * Returns the name of the channel at index 'ndx' (counting from zero), + * or NULL if the index is out of range. + */ + const char *Name(int ndx); + /** + * Returns the type of the channel at index 'ndx' (counting from zero), + * or -1 if the index is out of range. + */ + int Type(int ndx); + /** + * Returns 1 if the channel at index 'ndx' (counting from zero) exists + * and is a control channel, and 0 otherwise. + */ + int IsControlChannel(int ndx); + /** + * Returns 1 if the channel at index 'ndx' (counting from zero) exists + * and is an audio channel, and 0 otherwise. + */ + int IsAudioChannel(int ndx); + /** + * Returns 1 if the channel at index 'ndx' (counting from zero) exists + * and is a string channel, and 0 otherwise. + */ + int IsStringChannel(int ndx); + /** + * Returns 1 if the channel at index 'ndx' (counting from zero) exists + * and the input bit is set, and 0 otherwise. + */ + int IsInputChannel(int ndx); + /** + * Returns 1 if the channel at index 'ndx' (counting from zero) exists + * and the output bit is set, and 0 otherwise. + */ + int IsOutputChannel(int ndx); + /** + * Returns the sub-type (0: normal, 1: integer, 2: linear, 3: exponential) + * of the control channel at index 'ndx' (counting from zero), or -1 if + * the channel does not exist or is not a control channel. + */ + int SubType(int ndx); + /** + * Returns the default value set for the control channel at index 'ndx' + * (counting from zero), or 0.0 if the channel does not exist, is not a + * control channel, or has no default value. + */ + double DefaultValue(int ndx); + /** + * Returns the minimum value set for the control channel at index 'ndx' + * (counting from zero), or 0.0 if the channel does not exist, is not a + * control channel, or has no minimum value. + */ + double MinValue(int ndx); + /** + * Returns the maximum value set for the control channel at index 'ndx' + * (counting from zero), or 0.0 if the channel does not exist, is not a + * control channel, or has no maximum value. + */ + double MaxValue(int ndx); + /** + * Releases the memory used by the channel list. Should be called + * before the Csound instance is destroyed or reset. + */ + void Clear(); + // -------- + CsoundChannelList(CSOUND *csound); + CsoundChannelList(Csound *csound); + ~CsoundChannelList(); +}; + +/** + * CsoundUtilityList(CSOUND *) + * CsoundUtilityList(Csound *) + * + * Creates an alphabetically sorted list of utilities registered + * for a Csound instance. Should be called after csoundPreCompile() + * or Csound::PreCompile(). + */ + +class PUBLIC CsoundUtilityList { + private: + char **lst; + int cnt; + public: + /** + * Returns the number of utilities, or -1 if there is no list. + */ + int Count(); + /** + * Returns the name of the utility at index 'ndx' (counting from zero), + * or NULL if the index is out of range. + */ + const char *Name(int ndx); + /** + * Releases the memory used by the utility list. Should be called + * before the Csound instance is destroyed or reset. + */ + void Clear(); + // -------- + CsoundUtilityList(CSOUND *csound); + CsoundUtilityList(Csound *csound); + ~CsoundUtilityList(); +}; + +/** + * CsoundMYFLTArray() + * + * Creates a pointer for use with csoundGetChannelPtr(), + * csoundGetOutputBuffer(), or other functions that return a + * pointer to an array of floating point values. + * + * CsoundMYFLTArray(int cnt) + * + * Allocates an array of 'cnt' floating point values, for use + * with Csound API functions that take a MYFLT* pointer. + */ + +class PUBLIC CsoundMYFLTArray { + private: + MYFLT *p; + void *pp; + public: + /** + * Returns a MYFLT** pointer for use with csoundGetChannelPtr(). + */ + MYFLT **GetPtr() + { + return (&p); + } + /** + * Returns the address of the element at index 'ndx' (counting from + * zero) as a MYFLT* pointer, or NULL if there is no array. Does not + * check if 'ndx' is valid. + */ + MYFLT *GetPtr(int ndx) + { + if (p) + return &(p[ndx]); + return (MYFLT*) 0; + } + /** + * Sets the array pointer to a MYFLT* value returned by a Csound + * API function (e.g. csoundGetSpin() or csoundGetSpout()). + */ + void SetPtr(MYFLT *ptr) + { + p = ptr; + } + /** + * Stores a floating point value at index 'ndx' (counting from zero). + * No error checking is done, the array is assumed to exist and the + * index is assumed to be valid. + */ + void SetValue(int ndx, double value) + { + p[ndx] = (MYFLT) value; + } + /** + * Sets two floating point values starting at index 'ndx' (counting + * from zero). No error checking is done, the array is assumed to exist + * and the index is assumed to be valid. + */ + void SetValues(int ndx, double v0, double v1) + { + p[ndx] = (MYFLT) v0; p[ndx + 1] = (MYFLT) v1; + } + /** + * Sets three floating point values starting at index 'ndx' (counting + * from zero). No error checking is done, the array is assumed to exist + * and the index is assumed to be valid. + */ + void SetValues(int ndx, double v0, double v1, double v2) + { + p[ndx] = (MYFLT) v0; p[ndx + 1] = (MYFLT) v1; + p[ndx + 2] = (MYFLT) v2; + } + /** + * Sets four floating point values starting at index 'ndx' (counting + * from zero). No error checking is done, the array is assumed to exist + * and the index is assumed to be valid. + */ + void SetValues(int ndx, double v0, double v1, double v2, double v3) + { + p[ndx] = (MYFLT) v0; p[ndx + 1] = (MYFLT) v1; + p[ndx + 2] = (MYFLT) v2; p[ndx + 3] = (MYFLT) v3; + } + /** + * Sets five floating point values starting at index 'ndx' (counting + * from zero). No error checking is done, the array is assumed to exist + * and the index is assumed to be valid. + */ + void SetValues(int ndx, + double v0, double v1, double v2, double v3, double v4) + { + p[ndx] = (MYFLT) v0; p[ndx + 1] = (MYFLT) v1; + p[ndx + 2] = (MYFLT) v2; p[ndx + 3] = (MYFLT) v3; + p[ndx + 4] = (MYFLT) v4; + } + /** + * Sets six floating point values starting at index 'ndx' (counting + * from zero). No error checking is done, the array is assumed to exist + * and the index is assumed to be valid. + */ + void SetValues(int ndx, + double v0, double v1, double v2, double v3, double v4, + double v5) + { + p[ndx] = (MYFLT) v0; p[ndx + 1] = (MYFLT) v1; + p[ndx + 2] = (MYFLT) v2; p[ndx + 3] = (MYFLT) v3; + p[ndx + 4] = (MYFLT) v4; p[ndx + 5] = (MYFLT) v5; + } + /** + * Sets seven floating point values starting at index 'ndx' (counting + * from zero). No error checking is done, the array is assumed to exist + * and the index is assumed to be valid. + */ + void SetValues(int ndx, + double v0, double v1, double v2, double v3, double v4, + double v5, double v6) + { + p[ndx] = (MYFLT) v0; p[ndx + 1] = (MYFLT) v1; + p[ndx + 2] = (MYFLT) v2; p[ndx + 3] = (MYFLT) v3; + p[ndx + 4] = (MYFLT) v4; p[ndx + 5] = (MYFLT) v5; + p[ndx + 6] = (MYFLT) v6; + } + /** + * Sets eight floating point values starting at index 'ndx' (counting + * from zero). No error checking is done, the array is assumed to exist + * and the index is assumed to be valid. + */ + void SetValues(int ndx, + double v0, double v1, double v2, double v3, double v4, + double v5, double v6, double v7) + { + p[ndx] = (MYFLT) v0; p[ndx + 1] = (MYFLT) v1; + p[ndx + 2] = (MYFLT) v2; p[ndx + 3] = (MYFLT) v3; + p[ndx + 4] = (MYFLT) v4; p[ndx + 5] = (MYFLT) v5; + p[ndx + 6] = (MYFLT) v6; p[ndx + 7] = (MYFLT) v7; + } + /** + * Sets nine floating point values starting at index 'ndx' (counting + * from zero). No error checking is done, the array is assumed to exist + * and the index is assumed to be valid. + */ + void SetValues(int ndx, + double v0, double v1, double v2, double v3, double v4, + double v5, double v6, double v7, double v8) + { + p[ndx] = (MYFLT) v0; p[ndx + 1] = (MYFLT) v1; + p[ndx + 2] = (MYFLT) v2; p[ndx + 3] = (MYFLT) v3; + p[ndx + 4] = (MYFLT) v4; p[ndx + 5] = (MYFLT) v5; + p[ndx + 6] = (MYFLT) v6; p[ndx + 7] = (MYFLT) v7; + p[ndx + 8] = (MYFLT) v8; + } + /** + * Sets ten floating point values starting at index 'ndx' (counting + * from zero). No error checking is done, the array is assumed to exist + * and the index is assumed to be valid. + */ + void SetValues(int ndx, + double v0, double v1, double v2, double v3, double v4, + double v5, double v6, double v7, double v8, double v9) + { + p[ndx] = (MYFLT) v0; p[ndx + 1] = (MYFLT) v1; + p[ndx + 2] = (MYFLT) v2; p[ndx + 3] = (MYFLT) v3; + p[ndx + 4] = (MYFLT) v4; p[ndx + 5] = (MYFLT) v5; + p[ndx + 6] = (MYFLT) v6; p[ndx + 7] = (MYFLT) v7; + p[ndx + 8] = (MYFLT) v8; p[ndx + 9] = (MYFLT) v9; + } + /** + * Returns the floating point value at index 'ndx' (counting from zero). + * No error checking is done, the array is assumed to exist and the + * index is assumed to be valid. + */ + double GetValue(int ndx) + { + return (double) p[ndx]; + } + /** + * Copies 'n' values to the array from a source pointer, starting at + * index 'ndx' (counting from zero). No error checking is done. + */ + void SetValues(int ndx, int n, const MYFLT *src) + { + for (int i = 0; i < n; i++) + p[ndx + i] = src[i]; + } + /** + * Copies 'n' values from the array to 'dst', starting at index 'ndx' + * (counting from zero). No error checking is done. + */ + void GetValues(MYFLT *dst, int ndx, int n) + { + for (int i = 0; i < n; i++) + dst[i] = p[ndx + i]; + } + /** + * Stores a string in the array (note: only do this with a pointer + * returned by csoundGetChannelPtr()), optionally limiting the length to + * maxLen - 1 characters. + */ + void SetStringValue(const char *s, int maxLen); + /** + * Returns a string from the array (note: only do this with a pointer + * returned by csoundGetChannelPtr()), or NULL if there is no array. + */ + const char *GetStringValue(); + /** + * Clears the array pointer, and releases any memory that was allocated + * by calling the constructor with a positive number of elements. + */ + void Clear(); + // -------- + CsoundMYFLTArray(); + CsoundMYFLTArray(int n); + ~CsoundMYFLTArray(); +}; + +/** + * A simple class for creating argv[] lists for use with + * functions like csoundCompile(). + */ + +class PUBLIC CsoundArgVList { + private: + char **ArgV_; + int cnt; + void destroy_argv(); + public: + /** + * Returns the count of arguments in the list, zero if there are + * none, and -1 if the list could not be allocated. + */ + int argc(); + /** + * Returns a char** pointer for use with csoundCompile() etc. + */ + char **argv(); + /** + * Returns the argument at the specified index (counting from zero), + * or NULL if the index is out of range. + */ + const char *argv(int ndx); + /** + * Inserts a new value to the argument list at the specified index + * (counting from zero). If there is not enough memory, the list is + * not changed. + */ + void Insert(int ndx, const char *s); + /** + * Appends a new value at the end of the argument list. + * If there is not enough memory, the list is not changed. + */ + void Append(const char *s); + /** + * Removes all elements of the list. + */ + void Clear(); + // -------- + CsoundArgVList(); + ~CsoundArgVList(); +}; + +/** + * Experimental class for wrapping callbacks using SWIG directors. + */ + +class CsoundMidiInputBuffer; +class CsoundMidiOutputBuffer; + +class PUBLIC CsoundCallbackWrapper { + private: + CSOUND *csound_; + public: + virtual void MessageCallback(int attr, char *msg) + { + (void) attr; + (void) msg; + } + virtual double InputValueCallback(const char *chnName) + { + (void) chnName; + return 0.0; + } + virtual void OutputValueCallback(const char *chnName, double value) + { + (void) chnName; + (void) value; + } + virtual int YieldCallback() + { + return 1; + } + virtual void MidiInputCallback(CsoundMidiInputBuffer *p) + { + (void) p; + } + virtual void MidiOutputCallback(CsoundMidiOutputBuffer *p) + { + (void) p; + } + + void SetMessageCallback(); + // void SetInputValueCallback(); + // void SetOutputValueCallback(); + void SetYieldCallback(); + void SetMidiInputCallback(CsoundArgVList *argv); + void SetMidiOutputCallback(CsoundArgVList *argv); + // void SetChannelIOCallbacks(); + CSOUND *GetCsound() + { + return csound_; + } + // for converting SWIG char* type to a Python string + static const char *CharPtrToString(const char *s) + { + return s; + } + // -------- + CsoundCallbackWrapper(Csound *csound); + CsoundCallbackWrapper(CSOUND *csound); + virtual ~CsoundCallbackWrapper() + { + } + private: + static int midiInOpenCallback(CSOUND *, void **, const char *); + static int midiInReadCallback(CSOUND *, void *, unsigned char *, int); + static int midiInCloseCallback(CSOUND *, void *); + static int midiOutOpenCallback(CSOUND *, void **, const char *); + static int midiOutWriteCallback(CSOUND *, void *, + const unsigned char *, int); + static int midiOutCloseCallback(CSOUND *, void *); +}; + +// ---------------------------- MIDI INPUT ---------------------------- + +class PUBLIC CsoundMidiInputBuffer { + private: + unsigned char *buf; + void *mutex_; + int bufReadPos; + int bufWritePos; + int bufBytes; + int bufSize; + public: + CsoundMidiInputBuffer(unsigned char *buf, int bufSize); + ~CsoundMidiInputBuffer(); + /** + * Sends a MIDI message, 'msg' is calculated as follows: + * STATUS + DATA1 * 256 + DATA2 * 65536 + */ + void SendMidiMessage(int msg); + /** + * Sends a MIDI message; 'channel' should be in the range 1 to 16, + * and data1 and data2 should be in the range 0 to 127. + */ + void SendMidiMessage(int status, int channel, int data1, int data2); + /** + * Sends a note-on message on 'channel' (1 to 16) for 'key' (0 to 127) + * with 'velocity' (0 to 127). + */ + void SendNoteOn(int channel, int key, int velocity); + /** + * Sends a note-off message on 'channel' (1 to 16) for 'key' (0 to 127) + * with 'velocity' (0 to 127). + */ + void SendNoteOff(int channel, int key, int velocity); + /** + * Sends a note-off message on 'channel' (1 to 16) for 'key', + * using a 0x90 status with zero velocity. + */ + void SendNoteOff(int channel, int key); + /** + * Sets polyphonic pressure on 'channel' (1 to 16) to 'value' (0 to 127) + * for 'key' (0 to 127). + */ + void SendPolyphonicPressure(int channel, int key, int value); + /** + * Sets controller 'ctl' (0 to 127) to 'value' (0 to 127) + * on 'channel' (1 to 16). + */ + void SendControlChange(int channel, int ctl, int value); + /** + * Sends program change to 'pgm' (1 to 128) on 'channel' (1 to 16). + */ + void SendProgramChange(int channel, int pgm); + /** + * Sets channel pressure to 'value' (0 to 127) on 'channel' (1 to 16). + */ + void SendChannelPressure(int channel, int value); + /** + * Sets pitch bend to 'value' (-8192 to 8191) on 'channel' (1 to 16). + */ + void SendPitchBend(int channel, int value); + // ----------------------------------------------------------------- + friend class CsoundCallbackWrapper; + protected: + /** + * Copies at most 'nBytes' bytes of MIDI data from the buffer to 'buf'. + * Returns the number of bytes copied. + */ + int GetMidiData(unsigned char *buf, int nBytes); +}; + +/** + * The following class allows sending MIDI input messages to a Csound + * instance. + */ + +class PUBLIC CsoundMidiInputStream : public CsoundMidiInputBuffer { + private: + unsigned char buf_[4096]; + CSOUND *csound; + public: + CsoundMidiInputStream(CSOUND *csound); + CsoundMidiInputStream(Csound *csound); + //~CsoundMidiInputStream() + //{ + //} + /** + * Enables MIDI input for the associated Csound instance. + * Should be called between csoundPreCompile() and csoundCompile(). + * If 'argv' is not NULL, the command line arguments required for + * MIDI input are appended. + */ + void EnableMidiInput(CsoundArgVList *argv); + private: + static int midiInOpenCallback(CSOUND *, void **, const char *); + static int midiInReadCallback(CSOUND *, void *, unsigned char *, int); + static int midiInCloseCallback(CSOUND *, void *); +}; + +// ---------------------------- MIDI OUTPUT --------------------------- + +class PUBLIC CsoundMidiOutputBuffer { + private: + unsigned char *buf; + void *mutex_; + int bufReadPos; + int bufWritePos; + int bufBytes; + int bufSize; + public: + CsoundMidiOutputBuffer(unsigned char *buf, int bufSize); + ~CsoundMidiOutputBuffer(); + /** + * Pops and returns the first message from the buffer, in the following + * format: + * STATUS + DATA1 * 256 + DATA2 * 65536 + * where STATUS also includes the channel number (0 to 15), if any. + * The return value is zero if there are no messages. + */ + int PopMessage(); + /** + * Returns the status byte for the first message in the buffer, not + * including the channel number in the case of channel messages. + * The return value is zero if there are no messages. + */ + int GetStatus(); + /** + * Returns the channel number (1 to 16) for the first message in the + * buffer. The return value is zero if there are no messages, or the + * first message is not a channel message. + */ + int GetChannel(); + /** + * Returns the first data byte (0 to 127) for the first message in the + * buffer. The return value is zero if there are no messages, or the + * first message does not have any data bytes. + */ + int GetData1(); + /** + * Returns the second data byte (0 to 127) for the first message in the + * buffer. The return value is zero if there are no messages, or the + * first message has less than two data bytes. + */ + int GetData2(); + // ----------------------------------------------------------------- + friend class CsoundCallbackWrapper; + protected: + /** + * Copies at most 'nBytes' bytes of MIDI data to the buffer from 'buf'. + * Returns the number of bytes copied. + */ + int SendMidiData(const unsigned char *buf, int nBytes); +}; + +/** + * The following class allows receiving MIDI output messages + * from a Csound instance. + */ + +class PUBLIC CsoundMidiOutputStream : public CsoundMidiOutputBuffer { + private: + unsigned char buf_[4096]; + CSOUND *csound; + public: + CsoundMidiOutputStream(CSOUND *csound); + CsoundMidiOutputStream(Csound *csound); + //~CsoundMidiOutputStream() + //{ + //} + /** + * Enables MIDI output for the associated Csound instance. + * Should be called between csoundPreCompile() and csoundCompile(). + * If 'argv' is not NULL, the command line arguments required for + * MIDI output are appended. + */ + void EnableMidiOutput(CsoundArgVList *argv); + private: + static int midiOutOpenCallback(CSOUND *, void **, const char *); + static int midiOutWriteCallback(CSOUND *, void *, + const unsigned char *, int); + static int midiOutCloseCallback(CSOUND *, void *); +}; + +#endif // CSOUND_CS_GLUE_HPP + diff --git a/6.x/csound/cs_par_structs.h b/6.x/csound/cs_par_structs.h new file mode 100644 index 00000000..77b13072 --- /dev/null +++ b/6.x/csound/cs_par_structs.h @@ -0,0 +1,70 @@ +/* + cs_par_structs.h: + + Copyright (C) 2011 John ffitch and Chris Wilson + 2013 John ffitch and Martin Brain + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef __CS_PAR_DISPATCH_H +#define __CS_PAR_DISPATCH_H + +/* global variables lock support */ +struct global_var_lock_t; + +struct instr_semantics_t; + +/* New model */ + +/* Current memory subsystems work at the granularity of cache lines. + * Thus concurrent accesses to multiple objects within a cache line + * can cause additional conflicts and memory subsystem traffic. + * The best way to avoid this is to pad the structures so that they don't + * share a cache line. 64 bytes seems to be becoming the usual cache line + * size. If the actual line is smaller, it will waste a little memory but + * shouldn't affect the sharing. If the actual line is larger then it may + * cause a few conflicts and thus a performance hit. Unless you are + * using a very unusual machine and you happen to know it's cache line size + * then leave this as 64, although you can try 32 or maybe even 16. + */ +#define CONCURRENTPADDING 64 + +typedef int taskID; + +/* Each task has a status */ +enum state { WAITING = 3, /* Dependencies have not been finished */ + AVAILABLE = 2, /* Dependencies met, ready to be run */ + INPROGRESS = 1, /* Has been started */ + DONE = 0 }; /* Has been completed */ + +typedef struct _stateWithPadding { + enum state s; + uint8_t padding [(CONCURRENTPADDING - sizeof(enum state)) / sizeof(uint8_t)]; +} stateWithPadding; + +/* Sets of prerequiste tasks for each task */ +typedef struct _watchList { + taskID id; + struct _watchList *next; + uint8_t padding [(CONCURRENTPADDING - + (sizeof(taskID) + + sizeof(struct _watchList *))) / sizeof(uint8_t)]; +} watchList; + +#endif diff --git a/6.x/csound/cscore.h b/6.x/csound/cscore.h new file mode 100644 index 00000000..dab6d559 --- /dev/null +++ b/6.x/csound/cscore.h @@ -0,0 +1,126 @@ +/* + cscore.h: + + Copyright (C) 1991 Barry Vercoe, John ffitch + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef CSCORE_H +#define CSCORE_H +/** +* \file csound.h +* \section section_api_cscore Cscore +* +* Beginning with Csound 5, all of the Cscore functions described in the +* manual are now part of the Csound API, and they can be called from a program +* that calls the Csound library. +* +* All of the CScore functions are renamed in the Csound API. For +* example, createv() is now cscoreCreateEvent(), and lcopy() is now +* cscoreListCopy(). In addition, each function takes an additional +* first parameter that is a pointer to a CSOUND instance. You can +* find the details in the header file, cscore.h, which may be +* included with your Csound distribution, or if not, can be found in +* Csound CVS `on SourceForge. +* +* Before you can use any of the Cscore API functions, you must create a CSOUND +* instance and initialize Cscore by calling csoundInitializeCscore() -- see +* csound.h for an explanation. An example main program that does all of this +* Top/cscormai.c. You should add a function called cscore() with your own +* score-processing code. An example that does nothing except write the score +* back out unchanged can be found in the file Top/cscore_internal.c. +* +* To create your own standalone Cscore program, you must compile cscormai.c +* (or your own main program) and the file containing your +* cscore() function, and link them with the Csound API library. +*/ + +#include + +#ifndef MYFLT +#include "sysdep.h" +#endif +#include "csound.h" + +typedef struct cshdr { + struct cshdr *prvblk; + struct cshdr *nxtblk; + int16 type; + int16 size; +} CSHDR; + +/* Single score event structure */ +typedef struct { + CSHDR h; + char *strarg; + char op; + int16 pcnt; + MYFLT p2orig; + MYFLT p3orig; + MYFLT p[1]; +} EVENT; + +/* Event list structure */ +typedef struct { + CSHDR h; + int nslots; + int nevents; + EVENT *e[1]; +} EVLIST; + +/* Functions for working with single events */ +PUBLIC EVENT *cscoreCreateEvent(CSOUND*, int); +PUBLIC EVENT *cscoreDefineEvent(CSOUND*, char*); +PUBLIC EVENT *cscoreCopyEvent(CSOUND*, EVENT*); +PUBLIC EVENT *cscoreGetEvent(CSOUND*); +PUBLIC void cscorePutEvent(CSOUND*, EVENT*); +PUBLIC void cscorePutString(CSOUND*, char*); + +/* Functions for working with event lists */ +PUBLIC EVLIST *cscoreListCreate(CSOUND*, int); +PUBLIC EVLIST *cscoreListAppendEvent(CSOUND*, EVLIST*, EVENT*); +PUBLIC EVLIST *cscoreListAppendStringEvent(CSOUND*, EVLIST*, char*); +PUBLIC EVLIST *cscoreListGetSection(CSOUND*); +PUBLIC EVLIST *cscoreListGetNext(CSOUND *, MYFLT); +PUBLIC EVLIST *cscoreListGetUntil(CSOUND*, MYFLT); +PUBLIC EVLIST *cscoreListCopy(CSOUND*, EVLIST*); +PUBLIC EVLIST *cscoreListCopyEvents(CSOUND*, EVLIST*); +PUBLIC EVLIST *cscoreListExtractInstruments(CSOUND*, EVLIST*, char*); +PUBLIC EVLIST *cscoreListExtractTime(CSOUND*, EVLIST*, MYFLT, MYFLT); +PUBLIC EVLIST *cscoreListSeparateF(CSOUND*, EVLIST*); +PUBLIC EVLIST *cscoreListSeparateTWF(CSOUND*, EVLIST*); +PUBLIC EVLIST *cscoreListAppendList(CSOUND*, EVLIST*, EVLIST*); +PUBLIC EVLIST *cscoreListConcatenate(CSOUND*, EVLIST*, EVLIST*); +PUBLIC void cscoreListPut(CSOUND*, EVLIST*); +PUBLIC int cscoreListPlay(CSOUND*, EVLIST*); +PUBLIC void cscoreListSort(CSOUND*, EVLIST*); +PUBLIC int cscoreListCount(CSOUND*, EVLIST *); + +/* Functions for reclaiming memory */ +PUBLIC void cscoreFreeEvent(CSOUND*, EVENT*); +PUBLIC void cscoreListFree(CSOUND*, EVLIST*); +PUBLIC void cscoreListFreeEvents(CSOUND*, EVLIST*); + +/* Functions for working with multiple input score files */ +PUBLIC FILE *cscoreFileOpen(CSOUND*, char*); +PUBLIC void cscoreFileClose(CSOUND*, FILE*); +PUBLIC FILE *cscoreFileGetCurrent(CSOUND*); +PUBLIC void cscoreFileSetCurrent(CSOUND*, FILE*); + +#endif diff --git a/6.x/csound/csdebug.h b/6.x/csound/csdebug.h new file mode 100644 index 00000000..a650b96d --- /dev/null +++ b/6.x/csound/csdebug.h @@ -0,0 +1,311 @@ +/* + csdebug.h: + + Copyright (C) 2014 Andres Cabrera + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef CSDEBUG_H +#define CSDEBUG_H + +/** +* \file csdebug.h +* +* This header provides the debugger API which is part of libcsound. +* +* Basic usage of the debugger is this: +* +* \code + CSOUND* csound = csoundCreate(NULL); + csoundCompileOrc(csound, " "); + csoundStart(csound); + csoundDebuggerInit(csound); + csoundSetBreakpointCallback(csound, brkpt_cb, &userdata); + csoundSetInstrumentBreakpoint(csound, 1, 5); + + // Run Csound Performance here + // The breakpoint callback will be called when instrument 1 has been + // instantiated and 5 control blocks have been processed. + + csoundDebuggerClean(csound); + csoundDestroy(csound); +* \endcode +* +*/ + +#ifdef __BUILDING_LIBCSOUND +#include "csoundCore.h" +#else +#include "csound.h" +#endif + +#include "csound_type_system.h" + + +/** @defgroup DEBUGGER Debugger + * + * @{ */ + +typedef struct debug_instr_s { + CS_VARIABLE *varPoolHead; + MYFLT *lclbas; + void *instrptr; + MYFLT p1, p2, p3; + uint64_t kcounter; + int line; + struct debug_instr_s *next; +} debug_instr_t; + +typedef struct debug_opcode_s { + char opname[16]; + int line; + // TODO: Fill opcode linked list + struct debug_opcode_s *next; + struct debug_opcode_s *prev; +} debug_opcode_t; + +typedef struct debug_variable_s { + const char *name; + const char *typeName; + void *data; + struct debug_variable_s *next; +} debug_variable_t; + +typedef struct { + debug_instr_t *breakpointInstr; + debug_variable_t *instrVarList; + debug_instr_t *instrListHead; + debug_opcode_t *currentOpcode; +} debug_bkpt_info_t; + + +/** \cond DOXYGEN_HIDDEN + * These types should not appear in the Doxygen docs */ + + +typedef enum { + CSDEBUG_BKPT_LINE, + CSDEBUG_BKPT_INSTR, + CSDEBUG_BKPT_DELETE, + CSDEBUG_BKPT_CLEAR_ALL +} bkpt_mode_t; + +typedef enum { + CSDEBUG_STATUS_RUNNING, + CSDEBUG_STATUS_STOPPED, + CSDEBUG_STATUS_NEXT +} debug_status_t; + +typedef struct bkpt_node_s { + int line; /* if line is < 0 breakpoint is for instrument instances */ + MYFLT instr; /* instrument number (including fractional part */ + int skip; /* number of times to skip when arriving at the breakpoint */ + int count; /* current backwards count for skip, when 0 break */ + bkpt_mode_t mode; + struct bkpt_node_s *next; +} bkpt_node_t; + +typedef enum { + CSDEBUG_CMD_NONE, + CSDEBUG_CMD_STEPOVER, + CSDEBUG_CMD_STEPINTO, + CSDEBUG_CMD_NEXT, + CSDEBUG_CMD_CONTINUE, + CSDEBUG_CMD_STOP +} debug_command_t; + +typedef enum { + CSDEBUG_OFF = 0x0, + CSDEBUG_K = 0x01, + CSDEBUG_INIT = 0x02 +} debug_mode_t; + +#ifdef __BUILD_LIBCSOUND + +void csoundDebuggerBreakpointReached(CSOUND *csound); + +#endif + +/** @endcond */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/** Breakpoint callback function type + * + * When a breakpoint is reached, the debugger will call a function of this type + * see csoundSetBreakpointCallback() */ +typedef void (*breakpoint_cb_t) (CSOUND *, debug_bkpt_info_t *, void *userdata); + +typedef struct csdebug_data_s { + void *bkpt_buffer; /* for passing breakpoints to the running engine */ + void *cmd_buffer; /* for passing commands to the running engine */ + debug_status_t status; + bkpt_node_t *bkpt_anchor; /* linked list for breakpoints */ + bkpt_node_t *cur_bkpt; /* current breakpoint where we are stopped */ + breakpoint_cb_t bkpt_cb; + void *cb_data; + void *debug_instr_ptr; /* != NULL when stopped at a breakpoint. + Holds INSDS * */ + void *debug_opcode_ptr; /* != NULL when stopped at a line breakpoint. + Holds OPDS * */ +} csdebug_data_t; + +/** Intialize debugger facilities + * + * This function allocates debugger structures, and enables its usage. + * There is a small performance penalty when using the debugger, so + * be sure to call csoundDebuggerClean() after use. + * + * This call is not thread safe and must be called before performance starts. + * + * @param csound A Csound instance +*/ +PUBLIC void csoundDebuggerInit(CSOUND *csound); + +/** Cleanup debugger facilities + * + * @param csound A Csound instance +*/ +PUBLIC void csoundDebuggerClean(CSOUND *csound); + +/** Set a breakpoint on a particular line + * + * @param csound A Csound instance @param line The line on which to + * set a breakpoint + * @param instr When set to 0, the line number refers + * to the line number in the score. When a number is given, it should + * refer to an instrument that has been compiled on the fly using + * csoundParseOrc(). + * @param skip number of control blocks to skip + * +*/ +PUBLIC void csoundSetBreakpoint(CSOUND *csound, int line, int instr, int skip); + +/** Remove a previously set line breakpoint + * +*/ +PUBLIC void csoundRemoveBreakpoint(CSOUND *csound, int line, int instr); + +/** Set a breakpoint for an instrument number + * + * Sets a breakpoint for an instrument number with optional number of skip + * control blocks. You can specify a fractional instrument number to identify + * particular instances. Specifying a value greater than 1 will result in that + * number of control blocks being skipped before this breakpoint is called + * again. A value of 0 and 1 has the same effect. + * + * This call is thread safe, as the breakpoint will be put in a lock free queue + * that is processed as soon as possible in the kperf function. + * + * @param csound a Csound instance + * @param instr instrument number + * @param skip number of control blocks to skip + */ +PUBLIC void csoundSetInstrumentBreakpoint(CSOUND *csound, MYFLT instr, int skip); + +/** Remove instrument breakpoint + * + * Removes an instrument breakpoint from the breakpoint list. Csound will no + * longer break at that instrument + * + * This call is thread safe, as the breakpoint will be put in a lock free queue + * that is processed as soon as possible in the kperf function. + */ +PUBLIC void csoundRemoveInstrumentBreakpoint(CSOUND *csound, MYFLT instr); + +/** Clear all breakpoints + * + * Removes all breakpoints. This call is thread safe, as it will be processed + * as soon as possible in the kperf function. + */ +PUBLIC void csoundClearBreakpoints(CSOUND *csound); + +/** Sets the breakpoint callback function + * + * Sets the function that will be called when a breakpoint is reached. + * + * @param csound Csound instance pointer + * @param bkpt_cb pointer to breakpoint callback function + * @param userdata pointer to user data that will be passed to the callback + * function + */ +PUBLIC void csoundSetBreakpointCallback(CSOUND *csound, + breakpoint_cb_t bkpt_cb, void *userdata); + +/* Not implemented yet, so not exposed in the API +PUBLIC void csoundDebugStepOver(CSOUND *csound); +PUBLIC void csoundDebugStepInto(CSOUND *csound); +*/ + +/** Continue execution and break at next instrument instance + * + * Call this function to continue execution but automatically stop at + * next instrument instance. + */ +PUBLIC void csoundDebugNext(CSOUND *csound); + +/** Continue execution from breakpoint + * + * Call this function to continue execution of a Csound instance which is + * stopped because a breakpoint has been reached. This function will continue + * traversing the instrument chain from the instrument instance that + * triggered the break. + */ +PUBLIC void csoundDebugContinue(CSOUND *csound); + +/** Stop Csound rendering and enter the debugger + * + * Calling this function will enter the debugger at the soonest possible point + * as if a breakpoint had been reached. + */ +PUBLIC void csoundDebugStop(CSOUND *csound); + +/** Get a list of active instrument instances + * Returns a linked list of allocated instrument instances + * csoundDebugFreeInstrInstances() must be called on the list once it is no + * longer needed. + * This function is not thread safe and should only be called while the csound + * engine is stopped at a breakpoint. + */ +PUBLIC debug_instr_t *csoundDebugGetInstrInstances(CSOUND *csound); + +/** Free list created by csoundDebugGetCurrentInstrInstance() or + * csoundDebugGetInstrInstances() + */ +PUBLIC void csoundDebugFreeInstrInstances(CSOUND *csound, debug_instr_t *instr); + +/** Get list of variables for instrument */ +PUBLIC debug_variable_t *csoundDebugGetVariables(CSOUND *csound, + debug_instr_t *instr); + +/** Free variable list generated by csoundDebugGetVariables() */ +PUBLIC void csoundDebugFreeVariables(CSOUND *csound, + debug_variable_t *varHead); + + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/6.x/csound/csdl.h b/6.x/csound/csdl.h new file mode 100644 index 00000000..8defda09 --- /dev/null +++ b/6.x/csound/csdl.h @@ -0,0 +1,184 @@ +/* + csdl.h: + + Copyright (C) 2002 John ffitch + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef CSOUND_CSDL_H +#define CSOUND_CSDL_H +/** +* \file csdl.h +* +* \brief Declares the Csound plugin opcode interface. +* \author John P. ffitch, Michael Gogins, Matt Ingalls, John D. Ramsdell, +* Istvan Varga, Victor Lazzarini. +* +* Plugin opcodes can extend the functionality of Csound, providing new +* functionality that is exposed as opcodes in the Csound language. +* Plugins need to include this header file only, as it will bring all necessary +* data structures to interact with Csound. It is not necessary for plugins +* to link to the libcsound library, as plugin opcodes will always receive a +* CSOUND* pointer (to the CSOUND_ struct) which contains all the API functions +* inside. +* +* This is the basic template for a plugin opcode. See the manual for further +* details on accepted types and function call rates. The use of the LINKAGE +* macro is highly recommended, rather than calling the functions directly. +* +* \code +#include "csdl.h" + +typedef struct { + OPDS h; + MYFLT *out; + MYFLT *in1, *in2; +} OPCODE; + +static int op_init(CSOUND *csound, OPCODE *p) +{ +// Intialization code goes here + return OK; +} + +static int op_k(CSOUND *csound, OPCODE *p) +{ +// code called at k-rate goes here + return OK; +} + +// You can use these functions if you need to prepare and cleanup things on +// loading/unloading the library, but they can be absent if you don't need them + +PUBLIC int csoundModuleCreate(CSOUND *csound) +{ + return 0; +} + +PUBLIC int csoundModuleInit(CSOUND *csound) +{ + OENTRY *ep = (OENTRY *) &(localops[0]); + int err = 0; + while (ep->opname != NULL) { + err |= csound->AppendOpcode(csound, + ep->opname, ep->dsblksiz, ep->thread, + ep->outypes, ep->intypes, + (int (*)(CSOUND *, void *)) ep->iopadr, + (int (*)(CSOUND *, void *)) ep->kopadr, + (int (*)(CSOUND *, void *)) ep->aopadr); + ep++; + } + return err; +} + +PUBLIC int csoundModuleDestroy(CSOUND *csound) +{ + // Called when the plugin opcode is unloaded, usually when Csound terminates. + return 0; +} + +static OENTRY localops[] = +{ + { "opcode", sizeof(OPCODE), 0, 3, "i", "ii", (SUBR)op_init, (SUBR)op_k }} +}; + +LINKAGE(localops) + +* +* \endcode +**/ + +#ifdef __BUILDING_LIBCSOUND +#undef __BUILDING_LIBCSOUND +#endif +#include "interlocks.h" +#include "csoundCore.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__wasi__) + #undef PUBLIC + #define PUBLIC extern +#endif + +/* Use the Str() macro for translations of strings */ +#undef Str + + /* VL commenting this out so ALL uses of Str(x) + call LocalizeString() [which might be a stub] + This would allows us to keep an eye on + -Wformat-security warnings + */ +//#ifndef GNU_GETTEXT +//#define Str(x) (x) +//#else +#define Str(x) (csound->LocalizeString(x)) +//#endif + +PUBLIC int64_t csound_opcode_init(CSOUND *, OENTRY **); +PUBLIC NGFENS *csound_fgen_init(CSOUND *); + +PUBLIC int csoundModuleCreate(CSOUND *); +PUBLIC int csoundModuleInit(CSOUND *); +PUBLIC int csoundModuleDestroy(CSOUND *); +PUBLIC const char *csoundModuleErrorCodeToString(int); + +PUBLIC int csoundModuleInfo(void); + +/** The LINKAGE macro sets up linking of opcode list*/ + +#define LINKAGE \ +PUBLIC int64_t csound_opcode_init(CSOUND *csound, OENTRY **ep) \ +{ (void) csound; *ep = localops; return (int64_t) sizeof(localops); } \ +PUBLIC int csoundModuleInfo(void) \ +{ return ((CS_APIVERSION << 16) + (CS_APISUBVER << 8) + (int) sizeof(MYFLT)); } + +/** The LINKAGE_BUILTIN macro sets up linking of opcode list for builtin opcodes + * which must have unique function names */ + +#undef LINKAGE_BUILTIN +#define LINKAGE_BUILTIN(name) \ +PUBLIC int64_t csound_opcode_init(CSOUND *csound, OENTRY **ep) \ +{ (void) csound; *ep = name; return (int64_t) (sizeof(name)); } \ +PUBLIC int csoundModuleInfo(void) \ +{ return ((CS_APIVERSION << 16) + (CS_APISUBVER << 8) + (int) sizeof(MYFLT)); } + +/** LINKAGE for f-table plugins */ + +#define FLINKAGE \ +PUBLIC NGFENS *csound_fgen_init(CSOUND *csound) \ +{ (void) csound; return localfgens; } \ +PUBLIC int csoundModuleInfo(void) \ +{ return ((CS_APIVERSION << 16) + (CS_APISUBVER << 8) + (int) sizeof(MYFLT)); } + +#undef FLINKAGE_BUILTIN +#define FLINKAGE_BUILTIN(name) \ +PUBLIC NGFENS *csound_fgen_init(CSOUND *csound) \ +{ (void) csound; return name; } \ +PUBLIC int csoundModuleInfo(void) \ +{ return ((CS_APIVERSION << 16) + (CS_APISUBVER << 8) + (int) sizeof(MYFLT)); } + +#ifdef __cplusplus +} +#endif + +#endif /* CSOUND_CSDL_H */ diff --git a/6.x/csound/csound.h b/6.x/csound/csound.h new file mode 100644 index 00000000..778a99ed --- /dev/null +++ b/6.x/csound/csound.h @@ -0,0 +1,2672 @@ +/* + csound.h: + + Copyright (C) 2003 2005 2008 2013 by John ffitch, Istvan Varga, + Mike Gogins, Victor Lazzarini, + Andres Cabrera, Steven Yi + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef CSOUND_H +#define CSOUND_H +/*! \mainpage + * + * Csound is a sound and music computing system. It was originally written + * by Barry Vercoe at the Massachusetts Institute of Technology in + * 1984 as the first C language version of this type of + * software. Since then Csound has received numerous contributions + * from researchers, programmers, and musicians from around the world. + * + * \section section_api_outline Outline of the API + * + * \subsection section_api_apilist The Csound Application Programming Interfaces + * + * The Csound Application Programming Interface (API) reference is contained + * herein. + * The Csound API actually consists of several APIs: + * + * - The basic Csound C API. Include csound.h and link with libcsound.a. + * This also includes the Cscore API (see below). + * - The basic Csound C++ API. Include csound.hpp and link with libcsound.a. + * - The interfaces API, includes a number of auxiliary C++ classes, which + * add functionality and support the wrapping of the Csound API by various + * languages (e.g. Python, Java, Lua). + * + * \b Purposes + * + * The purposes of the Csound API are as follows: + * + * \li Declare a stable public application programming interface (API) + * for Csound in csound.h. This is the only header file that needs + * to be \#included by users of the Csound API. + * + * \li Hide the internal implementation details of Csound from users of + * the API, so that development of Csound can proceed without affecting + * code that uses the API. + * + * \b Users + * + * Users of the Csound API fall into two main categories: hosts and plugins. + * + * \li Hosts are applications that use Csound as a software synthesis engine. + * Hosts can link with the Csound API either statically or dynamically. + * + * \li Plugins are shared libraries loaded by Csound at run time to implement + * external opcodes and/or drivers for audio or MIDI input and output. + * Plugin opcodes need only include the csdl.h header which brings all + * necessary functions and data structures. + * Plugins can be written in C or C++. For C++, OOP support is given through + * `include/plugin.h` (using the Csound allocator, for opcodes + * that do not involve standard C++ library collections) or + * `include/OpcodeBase.hpp` (using the standard ++ allocator, for opcodes + * that do use standard C++ library collections). + * + * \section section_api_c_example Examples Using the Csound (host) API + * + * The Csound command--line program is itself built using the Csound API. + * Its code reads (in outline) as follows: + * + * \code + * #include "csound.h" + * + * int main(int argc, char **argv) + * { + * void *csound = csoundCreate(0); + * int result = csoundCompile(csound, argc, argv); + * if(!result) { + * while(csoundPerformKsmps(csound) == 0){} + * csoundCleanup(csound); + * } + * csoundDestroy(csound); + * return result; + * } + * \endcode + * + * Csound code can also be supplied directly using strings, either as + * a multi-section CSD (with the same format as CSD files) or + * directly as a string. It can be compiled any number of times + * before or during performance. + * + * \subsection s1 Using a CSD text + * + * System options can be passed via the CSD text before the engine + * is started. These are ignored in subsequent compilations. + * + * \code + * #include "csound.h" + * + * const char *csd_text = + * " \n" + * " -odac \n" + * " \n" + * "instr 1 \n" + * " out(linen(oscili(p4,p5),0.1,p3,0.1)) \n" + * "endin \n" + * " \n" + * " \n" + * "i1 0 5 1000 440 \n" + * " \n" + * " \n"; + * + * int main(int argc, char **argv) + * { + * void *csound = csoundCreate(0); + * int result = csoundCompileCsdText(csound, csd_text); + * result = csoundStart(csound); + * while (1) { + * result = csoundPerformKsmps(csound); + * if (result != 0) { + * break; + * } + * } + * result = csoundCleanup(csound); + * csoundReset(csound); + * csoundDestroy(csound); + * return result; + * } + * \endcode + * + * \subsection s2 Using Csound code directly. + * + * Options can be passed via csoundSetOption() before the engine starts. + * + * \code + * #include "csound.h" + * + * const char *orc_text = + * "instr 1 \n" + * " out(linen(oscili(p4,p5),0.1,p3,0.1)) \n" + * "endin \n"; + * + * const char *sco_text = "i1 0 5 1000 440 \n"; + * + * int main(int argc, char **argv) + * { + * void *csound = csoundCreate(0); + * int result = csoundSetOption(csound, "-d"); + * result = csoundSetOption(csound, "-odac"); + * result = csoundStart(csound); + * result = csoundCompileOrc(csound, orc_text); + * result = csoundReadScore(csound, sco_text); + * while (1) { + * result = csoundPerformKsmps(csound); + * if (result != 0) { + * break; + * } + * } + * result = csoundCleanup(csound); + * csoundReset(csound); + * csoundDestroy(csound); + * return result; + * } + * \endcode + + * + * Everything that can be done using C as in the above examples can also be done + * in a similar manner in Python or any of the other Csound API languages. + * + * \file csound.h + * + * \brief Declares the public Csound application programming interface (API). + * \author John P. ffitch, Michael Gogins, Matt Ingalls, John D. Ramsdell, + * Istvan Varga, Victor Lazzarini, Andres Cabrera and Steven Yi. + * + * Hosts using the Csound API must \#include , and link with the + * Csound API library. Plugin libraries should \#include to get + * access to the API function pointers in the CSOUND structure, and do not + * need to link with the Csound API library. + * Only one of csound.h and csdl.h may be included by a compilation unit. + * + * Hosts must first create an instance of Csound using the \c csoundCreate + * API function. When hosts are finished using Csound, they must destroy the + * instance of csound using the \c csoundDestroy API function. + * Most of the other Csound API functions take the Csound instance as their + * first argument. + * Hosts can only call the standalone API functions declared in csound.h. + * + * Here is the complete code for the simplest possible Csound API host, + * a command-line Csound application: + * + * \code + * + * #include + * + * int main(int argc, char **argv) + * { + * CSOUND *csound = csoundCreate(NULL); + * int result = csoundCompile(csound, argc, argv); + * if (!result) + * result = csoundPerform(csound); + * csoundDestroy(csound); + * return (result >= 0 ? 0 : result); + * } + * + * \endcode + * + * All opcodes, including plugins, receive a pointer to their host + * instance of Csound as the first argument. Therefore, plugins MUST NOT + * compile, perform, or destroy the host instance of Csound, and MUST call + * the Csound API function pointers off the Csound instance pointer. + * + * \code + * MYFLT sr = csound->GetSr(csound); + * \endcode + * + * In general, plugins should ONLY access Csound functionality through the + * API function pointers and public members of the #CSOUND_ structure. + * + * \section section_licenses License + * + * \subsection section_csound_license Csound + * + * Copyright (C) 2001-2013 John ffitch, Michael Gogins, Victor Lazzarini, + * Steven Yi, Istvan Varga, Andres Cabrera + * + * This software is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * Platform-dependent definitions and declarations. + */ + +#if (defined(WIN32) || defined(_WIN32)) && !defined(SWIG) +# if defined(__BUILDING_LIBCSOUND) +# define PUBLIC __declspec(dllexport) +# define PUBLIC_DATA __declspec(dllexport) +# else +# define PUBLIC __declspec(dllexport) +# define PUBLIC_DATA __declspec(dllimport) +# endif +#elif defined(__wasi__) +# define PUBLIC __attribute__((used)) +# if !defined(PUBLIC_DATA) +# define PUBLIC_DATA +# endif +#elif defined(__GNUC__) && (__GNUC__ >= 4) /* && !defined(__MACH__) */ +# define PUBLIC __attribute__ ( (visibility("default")) ) +# define PUBLIC_DATA __attribute__ ( (visibility("default")) ) +#else +# define PUBLIC +# define PUBLIC_DATA +#endif + +#if defined(MSVC) +# include /* for _InterlockedExchange */ +#endif + +#if defined(__MACH__) +// on OSX 10.6 i386 does not have all builtins +#if defined(MAC_OS_X_VERSION_10_6) +#ifdef HAVE_ATOMIC_BUILTIN +#ifndef __x86_64__ +#undef HAVE_ATOMIC_BUILTIN +#endif +#endif +#endif +#endif + +/** + * Enables Python interface. + */ + +#ifdef SWIG +#define CS_PRINTF2 +#define CS_PRINTF3 +#include "float-version.h" +#ifndef __MYFLT_DEF +#define __MYFLT_DEF +#ifndef USE_DOUBLE +#define MYFLT float +#else +#define MYFLT double +#endif +#endif + %module csnd6 + %{ +# include "sysdep.h" +# include "text.h" +# include +# include + %} +#else +# include "sysdep.h" +# include "text.h" +# include +# include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + /** + * ERROR DEFINITIONS + */ + + typedef enum + { + /* Completed successfully. */ + CSOUND_SUCCESS = 0, + /* Unspecified failure. */ + CSOUND_ERROR = -1, + /* Failed during initialization. */ + CSOUND_INITIALIZATION = -2, + /* Failed during performance. */ + CSOUND_PERFORMANCE = -3, + /* Failed to allocate requested memory. */ + CSOUND_MEMORY = -4, + /* Termination requested by SIGINT or SIGTERM. */ + CSOUND_SIGNAL = -5 + } CSOUND_STATUS; + + /* Compilation or performance aborted, but not as a result of an error + (e.g. --help, or running an utility with -U). */ +#define CSOUND_EXITJMP_SUCCESS (256) + + /** + * Flags for csoundInitialize(). + */ + +#define CSOUNDINIT_NO_SIGNAL_HANDLER 1 +#define CSOUNDINIT_NO_ATEXIT 2 + + /** + * Types for keyboard callbacks set in csoundRegisterKeyboardCallback() + */ + +#define CSOUND_CALLBACK_KBD_EVENT (0x00000001U) +#define CSOUND_CALLBACK_KBD_TEXT (0x00000002U) + + /** + * The following constants are used with csound->FileOpen2() and + * csound->ldmemfile2() to specify the format of a file that is being + * opened. This information is passed by Csound to a host's FileOpen + * callback and does not influence the opening operation in any other + * way. Conversion from Csound's TYP_XXX macros for audio formats to + * CSOUND_FILETYPES values can be done with csound->type2csfiletype(). + */ + typedef enum { + CSFTYPE_UNIFIED_CSD = 1, /* Unified Csound document */ + CSFTYPE_ORCHESTRA, /* the primary orc file (may be temporary) */ + CSFTYPE_SCORE, /* the primary sco file (may be temporary) + or any additional score opened by Cscore */ + CSFTYPE_ORC_INCLUDE, /* a file #included by the orchestra */ + CSFTYPE_SCO_INCLUDE, /* a file #included by the score */ + CSFTYPE_SCORE_OUT, /* used for score.srt, score.xtr, cscore.out */ + CSFTYPE_SCOT, /* Scot score input format */ + CSFTYPE_OPTIONS, /* for .csoundrc and -@ flag */ + CSFTYPE_EXTRACT_PARMS, /* extraction file specified by -x */ + + /* audio file types that Csound can write (10-19) or read */ + CSFTYPE_RAW_AUDIO, + CSFTYPE_IRCAM, + CSFTYPE_AIFF, + CSFTYPE_AIFC, + CSFTYPE_WAVE, + CSFTYPE_AU, + CSFTYPE_SD2, + CSFTYPE_W64, + CSFTYPE_WAVEX, + CSFTYPE_FLAC, + CSFTYPE_CAF, + CSFTYPE_WVE, + CSFTYPE_OGG, + CSFTYPE_MPC2K, + CSFTYPE_RF64, + CSFTYPE_AVR, + CSFTYPE_HTK, + CSFTYPE_MAT4, + CSFTYPE_MAT5, + CSFTYPE_NIST, + CSFTYPE_PAF, + CSFTYPE_PVF, + CSFTYPE_SDS, + CSFTYPE_SVX, + CSFTYPE_VOC, + CSFTYPE_XI, + CSFTYPE_UNKNOWN_AUDIO, /* used when opening audio file for reading + or temp file written with */ + + /* miscellaneous music formats */ + CSFTYPE_SOUNDFONT, + CSFTYPE_STD_MIDI, /* Standard MIDI file */ + CSFTYPE_MIDI_SYSEX, /* Raw MIDI codes, eg. SysEx dump */ + + /* analysis formats */ + CSFTYPE_HETRO, + CSFTYPE_HETROT, + CSFTYPE_PVC, /* original PVOC format */ + CSFTYPE_PVCEX, /* PVOC-EX format */ + CSFTYPE_CVANAL, + CSFTYPE_LPC, + CSFTYPE_ATS, + CSFTYPE_LORIS, + CSFTYPE_SDIF, + CSFTYPE_HRTF, + + /* Types for plugins and the files they read/write */ + CSFTYPE_UNUSED, + CSFTYPE_LADSPA_PLUGIN, + CSFTYPE_SNAPSHOT, + + /* Special formats for Csound ftables or scanned synthesis + matrices with header info */ + CSFTYPE_FTABLES_TEXT, /* for ftsave and ftload */ + CSFTYPE_FTABLES_BINARY, /* for ftsave and ftload */ + CSFTYPE_XSCANU_MATRIX, /* for xscanu opcode */ + + /* These are for raw lists of numbers without header info */ + CSFTYPE_FLOATS_TEXT, /* used by GEN23, GEN28, dumpk, readk */ + CSFTYPE_FLOATS_BINARY, /* used by dumpk, readk, etc. */ + CSFTYPE_INTEGER_TEXT, /* used by dumpk, readk, etc. */ + CSFTYPE_INTEGER_BINARY, /* used by dumpk, readk, etc. */ + + /* image file formats */ + CSFTYPE_IMAGE_PNG, + + /* For files that don't match any of the above */ + CSFTYPE_POSTSCRIPT, /* EPS format used by graphs */ + CSFTYPE_SCRIPT_TEXT, /* executable script files (eg. Python) */ + CSFTYPE_OTHER_TEXT, + CSFTYPE_OTHER_BINARY, + + /* This should only be used internally by the original FileOpen() + API call or for temp files written with */ + CSFTYPE_UNKNOWN = 0 + } CSOUND_FILETYPES; + + /* + * TYPE DEFINITIONS + */ + + /* + * Forward declarations. + */ + + typedef struct CSOUND_ CSOUND; + typedef struct windat_ WINDAT; + typedef struct xyindat_ XYINDAT; + + + /** + * csound configuration structure, mirrors part of + * OPARMS, uses more meaningful names + */ + + typedef struct { + int debug_mode; /* debug mode, 0 or 1 */ + int buffer_frames; /* number of frames in in/out buffers */ + int hardware_buffer_frames; /* ibid. hardware */ + int displays; /* graph displays, 0 or 1 */ + int ascii_graphs; /* use ASCII graphs, 0 or 1 */ + int postscript_graphs; /* use postscript graphs, 0 or 1 */ + int message_level; /* message printout control */ + int tempo; /* tempo (sets Beatmode) */ + int ring_bell; /* bell, 0 or 1 */ + int use_cscore; /* use cscore for processing */ + int terminate_on_midi; /* terminate performance at the end + of midifile, 0 or 1 */ + int heartbeat; /* print heart beat, 0 or 1 */ + int defer_gen01_load ; /* defer GEN01 load, 0 or 1 */ + int midi_key; /* pfield to map midi key no */ + int midi_key_cps; /* pfield to map midi key no as cps */ + int midi_key_oct; /* pfield to map midi key no as oct */ + int midi_key_pch; /* pfield to map midi key no as pch */ + int midi_velocity; /* pfield to map midi velocity */ + int midi_velocity_amp; /* pfield to map midi velocity as amplitude */ + int no_default_paths; /* disable relative paths from files, 0 or 1 */ + int number_of_threads; /* number of threads for multicore performance */ + int syntax_check_only; /* do not compile, only check syntax */ + int csd_line_counts; /* csd line error reporting */ + int compute_weights; /* deprecated, kept for backwards comp. */ + int realtime_mode; /* use realtime priority mode, 0 or 1 */ + int sample_accurate; /* use sample-level score event accuracy */ + MYFLT sample_rate_override; /* overriding sample rate */ + MYFLT control_rate_override; /* overriding control rate */ + int nchnls_override; /* overriding number of out channels */ + int nchnls_i_override; /* overriding number of in channels */ + MYFLT e0dbfs_override; /* overriding 0dbfs */ + int daemon; /* daemon mode */ + int ksmps_override; /* ksmps override */ + int FFT_library; /* fft_lib */ + } CSOUND_PARAMS; + + /** + * Device information + */ + + typedef struct { + char device_name[128]; + char device_id[128]; + char rt_module[128]; + int max_nchnls; + int isOutput; + } CS_AUDIODEVICE; + + typedef struct { + char device_name[128]; + char interface_name[128]; + char device_id[128]; + char midi_module[128]; + int isOutput; + } CS_MIDIDEVICE; + + + /** + * Real-time audio parameters structure + */ + typedef struct { + /** device name (NULL/empty: default) */ + char *devName; + /** device number (0-1023), 1024: default */ + int devNum; + /** buffer fragment size (-b) in sample frames */ + unsigned int bufSamp_SW; + /** total buffer size (-B) in sample frames */ + int bufSamp_HW; + /** number of channels */ + int nChannels; + /** sample format (AE_SHORT etc.) */ + int sampleFormat; + /** sample rate in Hz */ + float sampleRate; + } csRtAudioParams; + + typedef struct RTCLOCK_S { + int_least64_t starttime_real; + int_least64_t starttime_CPU; + } RTCLOCK; + + typedef struct { + char *opname; + char *outypes; + char *intypes; + int flags; + } opcodeListEntry; + + typedef struct CsoundRandMTState_ { + int mti; + uint32_t mt[624]; + } CsoundRandMTState; + + /* PVSDATEXT is a variation on PVSDAT used in + the pvs bus interface */ + typedef struct pvsdat_ext { + int32 N; + int sliding; /* Flag to indicate sliding case */ + int32 NB; + int32 overlap; + int32 winsize; + int wintype; + int32 format; + uint32 framecount; + float* frame; + } PVSDATEXT; + + typedef struct ORCTOKEN { + int type; + char *lexeme; + int value; + double fvalue; + char *optype; + struct ORCTOKEN *next; + } ORCTOKEN; + + typedef struct TREE { + int type; + ORCTOKEN *value; + int rate; + int len; + int line; + uint64_t locn; + struct TREE *left; + struct TREE *right; + struct TREE *next; + void *markup; // TEMPORARY - used by semantic checker to + // markup node adds OENTRY or synthetic var + // names to expression nodes should be moved + // to TYPE_TABLE + } TREE; + + + /** + * Constants used by the bus interface (csoundGetChannelPtr() etc.). + */ + typedef enum { + CSOUND_CONTROL_CHANNEL = 1, + CSOUND_AUDIO_CHANNEL = 2, + CSOUND_STRING_CHANNEL = 3, + CSOUND_PVS_CHANNEL = 4, + CSOUND_VAR_CHANNEL = 5, + + CSOUND_CHANNEL_TYPE_MASK = 15, + + CSOUND_INPUT_CHANNEL = 16, + CSOUND_OUTPUT_CHANNEL = 32 + } controlChannelType; + + typedef enum { + CSOUND_CONTROL_CHANNEL_NO_HINTS = 0, + CSOUND_CONTROL_CHANNEL_INT = 1, + CSOUND_CONTROL_CHANNEL_LIN = 2, + CSOUND_CONTROL_CHANNEL_EXP = 3 + } controlChannelBehavior; + + /** + * This structure holds the parameter hints for control channels + * + */ + typedef struct controlChannelHints_s { + controlChannelBehavior behav; + + MYFLT dflt; + MYFLT min; + MYFLT max; + int x; + int y; + int width; + int height; + /** This member must be set explicitly to NULL if not used */ + char *attributes; + } controlChannelHints_t; + + typedef struct controlChannelInfo_s { + char *name; + int type; + controlChannelHints_t hints; + } controlChannelInfo_t; + + typedef void (*channelCallback_t)(CSOUND *csound, + const char *channelName, + void *channelValuePtr, + const void *channelType); + +#ifndef CSOUND_CSDL_H + + /** @defgroup INSTANTIATION Instantiation + * + * @{ */ + /** + * Initialise Csound library with specific flags. This function is called + * internally by csoundCreate(), so there is generally no need to use it + * explicitly unless you need to avoid default initilization that sets + * signal handlers and atexit() callbacks. + * Return value is zero on success, positive if initialisation was + * done already, and negative on error. + */ + PUBLIC int csoundInitialize(int flags); + + /** + * Sets an opcodedir override for csoundCreate() + */ + PUBLIC void csoundSetOpcodedir(const char *s); + + /** + * Creates an instance of Csound. Returns an opaque pointer that + * must be passed to most Csound API functions. The hostData + * parameter can be NULL, or it can be a pointer to any sort of + * data; this pointer can be accessed from the Csound instance + * that is passed to callback routines. + */ + PUBLIC CSOUND *csoundCreate(void *hostData); + + /** + * Loads all plugins from a given directory + */ + PUBLIC int csoundLoadPlugins(CSOUND *csound, const char *dir); + + /** + * Destroys an instance of Csound. + */ + PUBLIC void csoundDestroy(CSOUND *); + + /** + * Returns the version number times 1000 (5.00.0 = 5000). + */ + PUBLIC int csoundGetVersion(void); + + /** + * Returns the API version number times 100 (1.00 = 100). + */ + PUBLIC int csoundGetAPIVersion(void); + + + /** @}*/ + + /** @defgroup PERFORMANCE Performance + * + * @{ */ + /** + * Parse the given orchestra from an ASCII string into a TREE. + * This can be called during performance to parse new code. + */ + PUBLIC TREE *csoundParseOrc(CSOUND *csound, const char *str); + + /** + * Compile the given TREE node into structs for Csound to use + * this can be called during performance to compile a new TREE + */ + PUBLIC int csoundCompileTree(CSOUND *csound, TREE *root); + + /** + * Asynchronous version of csoundCompileTree() + */ + PUBLIC int csoundCompileTreeAsync(CSOUND *csound, TREE *root); + + + /** + * Free the resources associated with the TREE *tree + * This function should be called whenever the TREE was + * created with csoundParseOrc and memory can be deallocated. + **/ + PUBLIC void csoundDeleteTree(CSOUND *csound, TREE *tree); + + /** + * Parse, and compile the given orchestra from an ASCII string, + * also evaluating any global space code (i-time only) + * this can be called during performance to compile a new orchestra. + * /code + * char *orc = "instr 1 \n a1 rand 0dbfs/4 \n out a1 \n"; + * csoundCompileOrc(csound, orc); + * /endcode + */ + PUBLIC int csoundCompileOrc(CSOUND *csound, const char *str); + + /** + * Async version of csoundCompileOrc(). The code is parsed and + * compiled, then placed on a queue for + * asynchronous merge into the running engine, and evaluation. + * The function returns following parsing and compilation. + */ + PUBLIC int csoundCompileOrcAsync(CSOUND *csound, const char *str); + + /** + * Parse and compile an orchestra given on an string, + * evaluating any global space code (i-time only). + * On SUCCESS it returns a value passed to the + * 'return' opcode in global space + * /code + * char *code = "i1 = 2 + 2 \n return i1 \n"; + * MYFLT retval = csoundEvalCode(csound, code); + * /endcode + */ + PUBLIC MYFLT csoundEvalCode(CSOUND *csound, const char *str); + + /** + * Prepares an instance of Csound for Cscore + * processing outside of running an orchestra (i.e. "standalone Cscore"). + * It is an alternative to csoundCompile(), and + * csoundPerform*() and should not be used with these functions. + * You must call this function before using the interface in "cscore.h" + * when you do not wish to compile an orchestra. + * Pass it the already open FILE* pointers to the input and + * output score files. + * It returns CSOUND_SUCCESS on success and CSOUND_INITIALIZATION or other + * error code if it fails. + */ + PUBLIC int csoundInitializeCscore(CSOUND *, FILE *insco, FILE *outsco); + + /** + * Read arguments, parse and compile an orchestra, read, process and + * load a score. + */ + PUBLIC int csoundCompileArgs(CSOUND *, int argc, const char **argv); + + /** + * Prepares Csound for performance. Normally called after compiling + * a csd file or an orc file, in which case score preprocessing is + * performed and performance terminates when the score terminates. + * + * However, if called before compiling a csd file or an orc file, + * score preprocessing is not performed and "i" statements are dispatched + * as real-time events, the tag is ignored, and performance + * continues indefinitely or until ended using the API. + */ + PUBLIC int csoundStart(CSOUND *csound); + + /** + * Compiles Csound input files (such as an orchestra and score, or CSD) + * as directed by the supplied command-line arguments, + * but does not perform them. Returns a non-zero error code on failure. + * This function cannot be called during performance, and before a + * repeated call, csoundReset() needs to be called. + * In this (host-driven) mode, the sequence of calls should be as follows: + * /code + * csoundCompile(csound, argc, argv); + * while (!csoundPerformBuffer(csound)); + * csoundCleanup(csound); + * csoundReset(csound); + * /endcode + * Calls csoundStart() internally. + * Can only be called again after reset (see csoundReset()) + */ + PUBLIC int csoundCompile(CSOUND *, int argc, const char **argv); + + /** + * Compiles a Csound input file (CSD, .csd file), but does not perform it. + * Returns a non-zero error code on failure. + * + * If csoundStart is called before csoundCompileCsd, the + * element is ignored (but csoundSetOption can be called any number of + * times), the element is not pre-processed, but dispatched as + * real-time events; and performance continues indefinitely, or until + * ended by calling csoundStop or some other logic. In this "real-time" + * mode, the sequence of calls should be: + * + * \code + * + * csoundSetOption("-an_option"); + * csoundSetOption("-another_option"); + * csoundStart(csound); + * csoundCompileCsd(csound, csd_filename); + * while (1) { + * csoundPerformBuffer(csound); + * // Something to break out of the loop + * // when finished here... + * } + * csoundCleanup(csound); + * csoundReset(csound); + * + * \endcode + * + * NB: this function can be called repeatedly during performance to + * replace or add new instruments and events. + * + * But if csoundCompileCsd is called before csoundStart, the + * element is used, the section is pre-processed and dispatched + * normally, and performance terminates when the score terminates, or + * csoundStop is called. In this "non-real-time" mode (which can still + * output real-time audio and handle real-time events), the sequence of + * calls should be: + * + * \code + * + * csoundCompileCsd(csound, csd_filename); + * csoundStart(csound); + * while (1) { + * int finished = csoundPerformBuffer(csound); + * if (finished) break; + * } + * csoundCleanup(csound); + * csoundReset(csound); + * + * \endcode + * + */ + PUBLIC int csoundCompileCsd(CSOUND *csound, const char *csd_filename); + + /** + * Behaves the same way as csoundCompileCsd, except that the content + * of the CSD is read from the csd_text string rather than from a file. + * This is convenient when it is desirable to package the csd as part of + * an application or a multi-language piece. + */ + PUBLIC int csoundCompileCsdText(CSOUND *csound, const char *csd_text); + + /** + * Senses input events and performs audio output until the end of score + * is reached (positive return value), an error occurs (negative return + * value), or performance is stopped by calling csoundStop() from another + * thread (zero return value). + * Note that csoundCompile() or csoundCompileOrc(), csoundReadScore(), + * csoundStart() must be called first. + * In the case of zero return value, csoundPerform() can be called again + * to continue the stopped performance. Otherwise, csoundReset() should be + * called to clean up after the finished or failed performance. + */ + PUBLIC int csoundPerform(CSOUND *); + + /** + * Senses input events, and performs one control sample worth (ksmps) of + * audio output. + * Note that csoundCompile() or csoundCompileOrc(), csoundReadScore(), + * csoundStart() must be called first. + * Returns false during performance, and true when performance is finished. + * If called until it returns true, will perform an entire score. + * Enables external software to control the execution of Csound, + * and to synchronize performance with audio input and output. + */ + PUBLIC int csoundPerformKsmps(CSOUND *); + + /** + * Performs Csound, sensing real-time and score events + * and processing one buffer's worth (-b frames) of interleaved audio. + * Note that csoundCompile must be called first, then call + * csoundGetOutputBuffer() and csoundGetInputBuffer() to get the pointer + * to csound's I/O buffers. + * Returns false during performance, and true when performance is finished. + */ + PUBLIC int csoundPerformBuffer(CSOUND *); + + /** + * Stops a csoundPerform() running in another thread. Note that it is + * not guaranteed that csoundPerform() has already stopped when this + * function returns. + */ + PUBLIC void csoundStop(CSOUND *); + + /** + * Prints information about the end of a performance, and closes audio + * and MIDI devices. + * Note: after calling csoundCleanup(), the operation of the perform + * functions is undefined. + */ + PUBLIC int csoundCleanup(CSOUND *); + + /** + * Resets all internal memory and state in preparation for a new performance. + * Enables external software to run successive Csound performances + * without reloading Csound. Implies csoundCleanup(), unless already called. + */ + PUBLIC void csoundReset(CSOUND *); + + /** @}*/ + /** @defgroup SERVER UDP server + * + * @{ */ + + /** + * Starts the UDP server on a supplied port number + * returns CSOUND_SUCCESS if server has been started successfully, + * otherwise, CSOUND_ERROR. + */ + PUBLIC int csoundUDPServerStart(CSOUND *csound, unsigned int port); + + /** returns the port number on which the server is running, or + * CSOUND_ERROR if the server is not running. + */ + PUBLIC int csoundUDPServerStatus(CSOUND *csound); + + /** + * Closes the UDP server, returning CSOUND_SUCCESS if the + * running server was successfully closed, CSOUND_ERROR otherwise. + */ + PUBLIC int csoundUDPServerClose(CSOUND *csound); + + /** + * Turns on the transmission of console messages to UDP on address addr + * port port. If mirror is one, the messages will continue to be + * sent to the usual destination (see csoundSetMessaggeCallback()) + * as well as to UDP. + * returns CSOUND_SUCCESS or CSOUND_ERROR if the UDP transmission + * could not be set up. + */ + PUBLIC int csoundUDPConsole(CSOUND *csound, const char *addr, + int port, int mirror); + + /** + * Stop transmitting console messages via UDP + */ + PUBLIC void csoundStopUDPConsole(CSOUND *csound); + + /** @}*/ + /** @defgroup ATTRIBUTES Attributes + * + * @{ */ + + /** + * Returns the number of audio sample frames per second. + */ + PUBLIC MYFLT csoundGetSr(CSOUND *) ; + + /** + * Returns the number of control samples per second. + */ + PUBLIC MYFLT csoundGetKr(CSOUND *); + + /** + * Returns the number of audio sample frames per control sample. + */ + PUBLIC uint32_t csoundGetKsmps(CSOUND *); + + /** + * Returns the number of audio output channels. Set through the nchnls + * header variable in the csd file. + */ + PUBLIC uint32_t csoundGetNchnls(CSOUND *); + + /** + * Returns the number of audio input channels. Set through the + * nchnls_i header variable in the csd file. If this variable is + * not set, the value is taken from nchnls. + */ + PUBLIC uint32_t csoundGetNchnlsInput(CSOUND *csound); + + /** + * Returns the 0dBFS level of the spin/spout buffers. + */ + PUBLIC MYFLT csoundGet0dBFS(CSOUND *); + + /** + * Returns the A4 frequency reference + */ + PUBLIC MYFLT csoundGetA4(CSOUND *); + + /** + * Return the current performance time in samples + */ + PUBLIC int64_t csoundGetCurrentTimeSamples(CSOUND *csound); + + /** + * Return the size of MYFLT in bytes. + */ + PUBLIC int csoundGetSizeOfMYFLT(void); + + /** + * Returns host data. + */ + PUBLIC void *csoundGetHostData(CSOUND *); + + /** + * Sets host data. + */ + PUBLIC void csoundSetHostData(CSOUND *, void *hostData); + + /** + * Set a single csound option (flag). Returns CSOUND_SUCCESS on success. + * NB: blank spaces are not allowed + */ + PUBLIC int csoundSetOption(CSOUND *csound, const char *option); + + /** + * Configure Csound with a given set of parameters defined in + * the CSOUND_PARAMS structure. These parameters are the part of the + * OPARMS struct that are configurable through command line flags. + * The CSOUND_PARAMS structure can be obtained using csoundGetParams(). + * These options should only be changed before performance has started. + */ + PUBLIC void csoundSetParams(CSOUND *csound, CSOUND_PARAMS *p); + + /** + * Get the current set of parameters from a CSOUND instance in + * a CSOUND_PARAMS structure. See csoundSetParams(). + */ + PUBLIC void csoundGetParams(CSOUND *csound, CSOUND_PARAMS *p); + + /** + * Returns whether Csound is set to print debug messages sent through the + * DebugMsg() internal API function. Anything different to 0 means true. + */ + PUBLIC int csoundGetDebug(CSOUND *); + + /** + * Sets whether Csound prints debug messages from the DebugMsg() internal + * API function. Anything different to 0 means true. + */ + PUBLIC void csoundSetDebug(CSOUND *, int debug); + + /** + * If val > 0, sets the internal variable holding the system HW sr. + * Returns the stored value containing the system HW sr. + */ + PUBLIC MYFLT csoundSystemSr(CSOUND *csound, MYFLT val); + + + /** @}*/ + /** @defgroup FILEIO General Input/Output + * Setting the device or filename name for Csound input and output. These + * functions are used to set the input and output command line flags that + * apply to both input and output of audio and MIDI. See command line flags + * -o, -i, -M and -Q in the Csound Reference Manual. + * @{ */ + + /** + * Returns the audio output name (-o). + */ + PUBLIC const char *csoundGetOutputName(CSOUND *); + + /** + * Returns the audio input name (-i). + */ + PUBLIC const char *csoundGetInputName(CSOUND *); + + /** + * Set output destination, type and format + * type can be one of "wav","aiff", "au","raw", "paf", "svx", "nist", "voc", + * "ircam","w64","mat4", "mat5", "pvf","xi", "htk","sds","avr","wavex","sd2", + * "flac", "caf","wve","ogg","mpc2k","rf64", or NULL (use default or + * realtime IO). + * format can be one of "alaw", "schar", "uchar", "float", "double", "long", + * "short", "ulaw", "24bit", "vorbis", or NULL (use default or realtime IO). + * For RT audio, use device_id from CS_AUDIODEVICE for a given audio device. + * + */ + PUBLIC void csoundSetOutput(CSOUND *csound, const char *name, + const char *type, const char *format); + + /** + * Get output type and format. + * type should have space for at least 5 chars excluding termination, + * and format should have space for at least 7 chars. + * On return, these will hold the current values for + * these parameters. + */ + PUBLIC void csoundGetOutputFormat(CSOUND *csound,char *type, + char *format); + + /** + * Set input source + */ + PUBLIC void csoundSetInput(CSOUND *csound, const char *name); + + /** + * Set MIDI input device name/number + */ + PUBLIC void csoundSetMIDIInput(CSOUND *csound, const char *name); + + /** + * Set MIDI file input name + */ + PUBLIC void csoundSetMIDIFileInput(CSOUND *csound, const char *name); + + /** + * Set MIDI output device name/number + */ + PUBLIC void csoundSetMIDIOutput(CSOUND *csound, const char *name); + + /** + * Set MIDI file utput name + */ + PUBLIC void csoundSetMIDIFileOutput(CSOUND *csound, const char *name); + +#if !defined(SWIG) + /** + * Sets an external callback for receiving notices whenever Csound opens + * a file. The callback is made after the file is successfully opened. + * The following information is passed to the callback: + * char* pathname of the file; either full or relative to current dir + * int a file type code from the enumeration CSOUND_FILETYPES + * int 1 if Csound is writing the file, 0 if reading + * int 1 if a temporary file that Csound will delete; 0 if not + * + * Pass NULL to disable the callback. + * This callback is retained after a csoundReset() call. + */ + PUBLIC void csoundSetFileOpenCallback(CSOUND *p, + void (*func)(CSOUND*, const char*, + int, int, int)); +#endif + + /** @}*/ + /** @defgroup RTAUDIOIO Realtime Audio I/O + * + * @{ */ + + /** + * Sets the current RT audio module + */ + PUBLIC void csoundSetRTAudioModule(CSOUND *csound, const char *module); + + /** + * retrieves a module name and type ("audio" or "midi") given a + * number Modules are added to list as csound loads them returns + * CSOUND_SUCCESS on success and CSOUND_ERROR if module number + * was not found + * + * \code + * char *name, *type; + * int n = 0; + * while(!csoundGetModule(csound, n++, &name, &type)) + * printf("Module %d: %s (%s) \n", n, name, type); + * \endcode + */ + PUBLIC int csoundGetModule(CSOUND *csound, int number, + char **name, char **type); + + /** + * Returns the number of samples in Csound's input buffer. + */ + PUBLIC long csoundGetInputBufferSize(CSOUND *); + + /** + * Returns the number of samples in Csound's output buffer. + */ + PUBLIC long csoundGetOutputBufferSize(CSOUND *); + + /** + * Returns the address of the Csound audio input buffer. + * Enables external software to write audio into Csound before calling + * csoundPerformBuffer. + */ + PUBLIC MYFLT *csoundGetInputBuffer(CSOUND *); + + /** + * Returns the address of the Csound audio output buffer. + * Enables external software to read audio from Csound after calling + * csoundPerformBuffer. + */ + PUBLIC MYFLT *csoundGetOutputBuffer(CSOUND *); + + /** + * Returns the address of the Csound audio input working buffer (spin). + * Enables external software to write audio into Csound before calling + * csoundPerformKsmps. + */ + PUBLIC MYFLT *csoundGetSpin(CSOUND *); + + /** + * Clears the input buffer (spin). + */ + PUBLIC void csoundClearSpin(CSOUND *); + + /** + * Adds the indicated sample into the audio input working buffer (spin); + * this only ever makes sense before calling csoundPerformKsmps(). + * The frame and channel must be in bounds relative to ksmps and nchnls. + * NB: the spin buffer needs to be cleared at every k-cycle by calling + * csoundClearSpinBuffer(). + */ + PUBLIC void csoundAddSpinSample(CSOUND *csound, + int frame, int channel, MYFLT sample); + + /** + * Sets the audio input working buffer (spin) to the indicated sample + * this only ever makes sense before calling csoundPerformKsmps(). + * The frame and channel must be in bounds relative to ksmps and nchnls. + */ + PUBLIC void csoundSetSpinSample(CSOUND *csound, + int frame, int channel, MYFLT sample); + + /** + * Returns the address of the Csound audio output working buffer (spout). + * Enables external software to read audio from Csound after calling + * csoundPerformKsmps. + */ + PUBLIC MYFLT *csoundGetSpout(CSOUND *csound); + + /** + * Returns the indicated sample from the Csound audio output + * working buffer (spout); only ever makes sense after calling + * csoundPerformKsmps(). The frame and channel must be in bounds + * relative to ksmps and nchnls. + */ + PUBLIC MYFLT csoundGetSpoutSample(CSOUND *csound, int frame, int channel); + + /** + * Return pointer to user data pointer for real time audio input. + */ + PUBLIC void **csoundGetRtRecordUserData(CSOUND *); + + /** + * Return pointer to user data pointer for real time audio output. + */ + PUBLIC void **csoundGetRtPlayUserData(CSOUND *); + + /** + * Calling this function with a non-zero 'state' value between + * csoundCreate() and the start of performance will disable all default + * handling of sound I/O by the Csound library, allowing the host + * application to use the spin/spout/input/output buffers directly. + * For applications using spin/spout, bufSize should be set to 0. + * If 'bufSize' is greater than zero, the buffer size (-b) in frames will be + * set to the integer multiple of ksmps that is nearest to the value + * specified. + */ + PUBLIC void csoundSetHostImplementedAudioIO(CSOUND *, + int state, int bufSize); + + + /** + * This function can be called to obtain a list of available + * input or output audio devices. If list is NULL, the function + * will only return the number of devices (isOutput=1 for out + * devices, 0 for in devices). + * If list is non-NULL, then it should contain enough memory for + * one CS_AUDIODEVICE structure per device. + * Hosts will typically call this function twice: first to obtain + * a number of devices, then, after allocating space for each + * device information structure, pass an array of CS_AUDIODEVICE + * structs to be filled: + * + * \code + * int i,n = csoundGetAudioDevList(csound,NULL,1); + * CS_AUDIODEVICE *devs = (CS_AUDIODEVICE *) + * malloc(n*sizeof(CS_AUDIODEVICE)); + * csoundGetAudioDevList(csound,devs,1); + * for(i=0; i < n; i++) + * csound->Message(csound, " %d: %s (%s)\n", + * i, devs[i].device_id, devs[i].device_name); + * free(devs); + * \endcode + */ + PUBLIC int csoundGetAudioDevList(CSOUND *csound, + CS_AUDIODEVICE *list, int isOutput); + + /** + * Sets a function to be called by Csound for opening real-time + * audio playback. + */ + PUBLIC void + csoundSetPlayopenCallback(CSOUND *, + int (*playopen__)(CSOUND *, + const csRtAudioParams *parm)); + + /** + * Sets a function to be called by Csound for performing real-time + * audio playback. + */ + PUBLIC void csoundSetRtplayCallback(CSOUND *, + void (*rtplay__)(CSOUND *, + const MYFLT *outBuf, + int nbytes)); + + /** + * Sets a function to be called by Csound for opening real-time + * audio recording. + */ + PUBLIC void csoundSetRecopenCallback(CSOUND *, + int (*recopen_)(CSOUND *, + const csRtAudioParams *parm)); + + /** + * Sets a function to be called by Csound for performing real-time + * audio recording. + */ + PUBLIC void csoundSetRtrecordCallback(CSOUND *, + int (*rtrecord__)(CSOUND *, + MYFLT *inBuf, + int nbytes)); + + /** + * Sets a function to be called by Csound for closing real-time + * audio playback and recording. + */ + PUBLIC void csoundSetRtcloseCallback(CSOUND *, void (*rtclose__)(CSOUND *)); + + /** + * Sets a function that is called to obtain a list of audio devices. + * This should be set by rtaudio modules and should not be set by hosts. + * (See csoundGetAudioDevList()) + */ + PUBLIC void csoundSetAudioDeviceListCallback(CSOUND *csound, + int (*audiodevlist__)(CSOUND *, + CS_AUDIODEVICE *list, + int isOutput)); + + /** @}*/ + /** @defgroup RTMIDI Realtime Midi I/O + * + * @{ */ + + /** + * Sets the current MIDI IO module + */ + PUBLIC void csoundSetMIDIModule(CSOUND *csound, const char *module); + + /** + * call this function with state 1 if the host is implementing + * MIDI via the callbacks below. + */ + PUBLIC void csoundSetHostImplementedMIDIIO(CSOUND *csound, + int state); + + /** + * This function can be called to obtain a list of available + * input or output midi devices. If list is NULL, the function + * will only return the number of devices (isOutput=1 for out + * devices, 0 for in devices). + * If list is non-NULL, then it should contain enough memory for + * one CS_MIDIDEVICE structure per device. + * Hosts will typically call this function twice: first to obtain + * a number of devices, then, after allocating space for each + * device information structure, pass an array of CS_MIDIDEVICE + * structs to be filled. (see also csoundGetAudioDevList()) + */ + PUBLIC int csoundGetMIDIDevList(CSOUND *csound, + CS_MIDIDEVICE *list, int isOutput); + + /** + * Sets callback for opening real time MIDI input. + */ + PUBLIC void csoundSetExternalMidiInOpenCallback(CSOUND *, + int (*func)(CSOUND *, + void **userData, + const char *devName)); + + /** + * Sets callback for reading from real time MIDI input. + */ + PUBLIC void csoundSetExternalMidiReadCallback(CSOUND *, + int (*func)(CSOUND *, + void *userData, + unsigned char *buf, + int nBytes)); + + /** + * Sets callback for closing real time MIDI input. + */ + PUBLIC void csoundSetExternalMidiInCloseCallback(CSOUND *, + int (*func)(CSOUND *, + void *userData)); + + /** + * Sets callback for opening real time MIDI output. + */ + PUBLIC void csoundSetExternalMidiOutOpenCallback(CSOUND *, + int (*func)(CSOUND *, + void **userData, + const char *devName)); + + /** + * Sets callback for writing to real time MIDI output. + */ + PUBLIC void csoundSetExternalMidiWriteCallback(CSOUND *, + int (*func)(CSOUND *, + void *userData, + const unsigned char *buf, + int nBytes)); + + /** + * Sets callback for closing real time MIDI output. + */ + PUBLIC void csoundSetExternalMidiOutCloseCallback(CSOUND *, + int (*func)(CSOUND *, + void *userData)); + + /** + * Sets callback for converting MIDI error codes to strings. + */ + PUBLIC void csoundSetExternalMidiErrorStringCallback(CSOUND *, + const char *(*func)(int)); + + + /** + * Sets a function that is called to obtain a list of MIDI devices. + * This should be set by IO plugins, and should not be used by hosts. + * (See csoundGetMIDIDevList()) + */ + PUBLIC void csoundSetMIDIDeviceListCallback(CSOUND *csound, + int (*mididevlist__)(CSOUND *, + CS_MIDIDEVICE *list, + int isOutput)); + + /** @}*/ + /** @defgroup SCOREHANDLING Score Handling + * + * @{ */ + + /** + * Read, preprocess, and load a score from an ASCII string + * It can be called repeatedly, with the new score events + * being added to the currently scheduled ones. + */ + PUBLIC int csoundReadScore(CSOUND *csound, const char *str); + + /** + * Asynchronous version of csoundReadScore(). + */ + PUBLIC void csoundReadScoreAsync(CSOUND *csound, const char *str); + + /** + * Returns the current score time in seconds + * since the beginning of performance. + */ + PUBLIC double csoundGetScoreTime(CSOUND *); + + /** + * Sets whether Csound score events are performed or not, independently + * of real-time MIDI events (see csoundSetScorePending()). + */ + PUBLIC int csoundIsScorePending(CSOUND *); + + /** + * Sets whether Csound score events are performed or not (real-time + * events will continue to be performed). Can be used by external software, + * such as a VST host, to turn off performance of score events (while + * continuing to perform real-time events), for example to + * mute a Csound score while working on other tracks of a piece, or + * to play the Csound instruments live. + */ + PUBLIC void csoundSetScorePending(CSOUND *, int pending); + + /** + * Returns the score time beginning at which score events will + * actually immediately be performed (see csoundSetScoreOffsetSeconds()). + */ + PUBLIC MYFLT csoundGetScoreOffsetSeconds(CSOUND *); + + /** + * Csound score events prior to the specified time are not performed, and + * performance begins immediately at the specified time (real-time events + * will continue to be performed as they are received). + * Can be used by external software, such as a VST host, + * to begin score performance midway through a Csound score, + * for example to repeat a loop in a sequencer, or to synchronize + * other events with the Csound score. + */ + PUBLIC void csoundSetScoreOffsetSeconds(CSOUND *, MYFLT time); + + /** + * Rewinds a compiled Csound score to the time specified with + * csoundSetScoreOffsetSeconds(). + */ + PUBLIC void csoundRewindScore(CSOUND *); + + /** + * Sets an external callback for Cscore processing. + * Pass NULL to reset to the internal cscore() function + * (which does nothing). + * This callback is retained after a csoundReset() call. + */ + PUBLIC void csoundSetCscoreCallback(CSOUND *, + void (*cscoreCallback_)(CSOUND *)); + + /** + * Sorts score file 'inFile' and writes the result to 'outFile'. + * The Csound instance should be initialised + * before calling this function, and csoundReset() should be called + * after sorting the score to clean up. On success, zero is returned. + */ + PUBLIC int csoundScoreSort(CSOUND *, FILE *inFile, FILE *outFile); + + /** + * Extracts from 'inFile', controlled by 'extractFile', and writes + * the result to 'outFile'. The Csound instance should be initialised + * before calling this function, and csoundReset() + * should be called after score extraction to clean up. + * The return value is zero on success. + */ + PUBLIC int csoundScoreExtract(CSOUND *, + FILE *inFile, FILE *outFile, FILE *extractFile); + + /** @}*/ + /** @defgroup MESSAGES Messages and Text + * + * @{ */ + + /** + * Displays an informational message. + */ + PUBLIC CS_PRINTF2 void csoundMessage(CSOUND *, const char *format, ...); + + /** + * Print message with special attributes (see msg_attr.h for the list of + * available attributes). With attr=0, csoundMessageS() is identical to + * csoundMessage(). + */ + PUBLIC CS_PRINTF3 void csoundMessageS(CSOUND *, + int attr, const char *format, ...); + + PUBLIC void csoundMessageV(CSOUND *, + int attr, const char *format, va_list args); + + PUBLIC void csoundSetDefaultMessageCallback(void (*csoundMessageCallback_)( + CSOUND *, + int attr, + const char *format, + va_list valist)); + + /** + * Sets a function to be called by Csound to print an informational message. + * This callback is never called on --realtime mode + */ + PUBLIC void csoundSetMessageCallback(CSOUND *, + void (*csoundMessageCallback_)(CSOUND *, + int attr, + const char *format, + va_list valist)); + + /** + * Sets an alternative function to be called by Csound to print an + * informational message, using a less granular signature. + * This callback can be set for --realtime mode. + * This callback is cleared after csoundReset + */ + PUBLIC void csoundSetMessageStringCallback(CSOUND *csound, + void (*csoundMessageStrCallback)(CSOUND *csound, + int attr, + const char *str)); + + /** + * Returns the Csound message level (from 0 to 231). + */ + PUBLIC int csoundGetMessageLevel(CSOUND *); + + /** + * Sets the Csound message level (from 0 to 231). + */ + PUBLIC void csoundSetMessageLevel(CSOUND *, int messageLevel); + + /** + * Creates a buffer for storing messages printed by Csound. + * Should be called after creating a Csound instance andthe buffer + * can be freed by calling csoundDestroyMessageBuffer() before + * deleting the Csound instance. You will generally want to call + * csoundCleanup() to make sure the last messages are flushed to + * the message buffer before destroying Csound. + * If 'toStdOut' is non-zero, the messages are also printed to + * stdout and stderr (depending on the type of the message), + * in addition to being stored in the buffer. + * Using the message buffer ties up the internal message callback, so + * csoundSetMessageCallback should not be called after creating the + * message buffer. + */ + PUBLIC void csoundCreateMessageBuffer(CSOUND *csound, int toStdOut); + + /** + * Returns the first message from the buffer. + */ + PUBLIC const char* csoundGetFirstMessage(CSOUND *csound); + + /** + * Returns the attribute parameter (see msg_attr.h) of the first message + * in the buffer. + */ + PUBLIC int csoundGetFirstMessageAttr(CSOUND *csound); + + /** + * Removes the first message from the buffer. + */ + PUBLIC void csoundPopFirstMessage(CSOUND *csound); + + /** + * Returns the number of pending messages in the buffer. + */ + PUBLIC int csoundGetMessageCnt(CSOUND *csound); + + /** + * Releases all memory used by the message buffer. + */ + void PUBLIC csoundDestroyMessageBuffer(CSOUND *csound); + + /** @}*/ + /** @defgroup CONTROLEVENTS Channels, Control and Events + * + * @{ */ + + /** + * Stores a pointer to the specified channel of the bus in *p, + * creating the channel first if it does not exist yet. + * 'type' must be the bitwise OR of exactly one of the following values, + * CSOUND_CONTROL_CHANNEL + * control data (one MYFLT value) + * CSOUND_AUDIO_CHANNEL + * audio data (csoundGetKsmps(csound) MYFLT values) + * CSOUND_STRING_CHANNEL + * string data (MYFLT values with enough space to store + * csoundGetChannelDatasize() characters, including the + * NULL character at the end of the string) + * and at least one of these: + * CSOUND_INPUT_CHANNEL + * CSOUND_OUTPUT_CHANNEL + * If the channel already exists, it must match the data type + * (control, audio, or string), however, the input/output bits are + * OR'd with the new value. Note that audio and string channels + * can only be created after calling csoundCompile(), because the + * storage size is not known until then. + + * Return value is zero on success, or a negative error code, + * CSOUND_MEMORY there is not enough memory for allocating the channel + * CSOUND_ERROR the specified name or type is invalid + * or, if a channel with the same name but incompatible type + * already exists, the type of the existing channel. In the case + * of any non-zero return value, *p is set to NULL. + * Note: to find out the type of a channel without actually + * creating or changing it, set 'type' to zero, so that the return + * value will be either the type of the channel, or CSOUND_ERROR + * if it does not exist. + * + * Operations on **p are not thread-safe by default. The host is required + * to take care of threadsafety by + * 1) with control channels use __atomic_load() or + * __atomic_store() gcc atomic builtins to get or set a channel, + * if available. + * 2) For string and audio channels (and controls if option 1 is not + * available), retrieve the channel lock with csoundGetChannelLock() + * and use csoundSpinLock() and csoundSpinUnLock() to protect access + * to **p. + * See Top/threadsafe.c in the Csound library sources for + * examples. Optionally, use the channel get/set functions + * provided below, which are threadsafe by default. + */ + PUBLIC int csoundGetChannelPtr(CSOUND *, + MYFLT **p, const char *name, int type); + + /** + * Returns a list of allocated channels in *lst. A controlChannelInfo_t + * structure contains the channel characteristics. + * The return value is the number of channels, which may be zero if there + * are none, or CSOUND_MEMORY if there is not enough memory for allocating + * the list. In the case of no channels or an error, *lst is set to NULL. + * Notes: the caller is responsible for freeing the list returned in *lst + * with csoundDeleteChannelList(). The name pointers may become invalid + * after calling csoundReset(). + */ + PUBLIC int csoundListChannels(CSOUND *, controlChannelInfo_t **lst); + + /** + * Releases a channel list previously returned by csoundListChannels(). + */ + PUBLIC void csoundDeleteChannelList(CSOUND *, controlChannelInfo_t *lst); + + /** + * Set parameters hints for a control channel. These hints have no internal + * function but can be used by front ends to construct GUIs or to constrain + * values. See the controlChannelHints_t structure for details. + * Returns zero on success, or a non-zero error code on failure: + * CSOUND_ERROR: the channel does not exist, is not a control channel, + * or the specified parameters are invalid + * CSOUND_MEMORY: could not allocate memory + */ + PUBLIC int csoundSetControlChannelHints(CSOUND *, const char *name, + controlChannelHints_t hints); + + /** + * Returns special parameters (assuming there are any) of a control channel, + * previously set with csoundSetControlChannelHints() or the chnparams + * opcode. + * If the channel exists, is a control channel, the channel hints + * are stored in the preallocated controlChannelHints_t structure. The + * attributes member of the structure will be allocated inside this function + * so it is necessary to free it explicitly in the host. + * + * The return value is zero if the channel exists and is a control + * channel, otherwise, an error code is returned. + */ + PUBLIC int csoundGetControlChannelHints(CSOUND *, const char *name, + controlChannelHints_t *hints); + + /** + * Recovers a pointer to a lock for the specified channel called 'name'. + * The returned lock can be locked/unlocked with the csoundSpinLock() + * and csoundSpinUnLock() functions. + * @returns the address of the lock or NULL if the channel does not exist + */ + PUBLIC int *csoundGetChannelLock(CSOUND *, const char *name); + + /** + * retrieves the value of control channel identified by *name. + * If the err argument is not NULL, the error (or success) code + * finding or accessing the channel is stored in it. + */ + PUBLIC MYFLT csoundGetControlChannel(CSOUND *csound, const char *name, + int *err); + + /** + * sets the value of control channel identified by *name + */ + PUBLIC void csoundSetControlChannel(CSOUND *csound, + const char *name, MYFLT val); + + /** + * copies the audio channel identified by *name into array + * *samples which should contain enough memory for ksmps MYFLTs + */ + PUBLIC void csoundGetAudioChannel(CSOUND *csound, + const char *name, MYFLT *samples); + + /** + * sets the audio channel identified by *name with data from array + * *samples which should contain at least ksmps MYFLTs + */ + PUBLIC void csoundSetAudioChannel(CSOUND *csound, + const char *name, MYFLT *samples); + + /** + * copies the string channel identified by *name into *string + * which should contain enough memory for the string + * (see csoundGetChannelDatasize() below) + */ + PUBLIC void csoundGetStringChannel(CSOUND *csound, + const char *name, char *string); + + /** + * sets the string channel identified by *name with *string + */ + PUBLIC void csoundSetStringChannel(CSOUND *csound, + const char *name, char *string); + + /** + * returns the size of data stored in a channel; for string channels + * this might change if the channel space gets reallocated + * Since string variables use dynamic memory allocation in Csound6, + * this function can be called to get the space required for + * csoundGetStringChannel() + */ + PUBLIC int csoundGetChannelDatasize(CSOUND *csound, const char *name); + + /** Sets the function which will be called whenever the invalue opcode + * is used. */ + PUBLIC void + csoundSetInputChannelCallback(CSOUND *csound, + channelCallback_t inputChannelCalback); + + /** Sets the function which will be called whenever the outvalue opcode + * is used. */ + PUBLIC void + csoundSetOutputChannelCallback(CSOUND *csound, + channelCallback_t outputChannelCalback); + + /** + * Sends a PVSDATEX fin to the pvsin opcode (f-rate) for channel 'name'. + * Returns zero on success, CSOUND_ERROR if the index is invalid or + * fsig framesizes are incompatible. + * CSOUND_MEMORY if there is not enough memory to extend the bus. + */ + PUBLIC int csoundSetPvsChannel(CSOUND *, const PVSDATEXT *fin, + const char *name); + + /** + * Receives a PVSDAT fout from the pvsout opcode (f-rate) at channel 'name' + * Returns zero on success, CSOUND_ERROR if the index is invalid or + * if fsig framesizes are incompatible. + * CSOUND_MEMORY if there is not enough memory to extend the bus + */ + PUBLIC int csoundGetPvsChannel(CSOUND *csound, PVSDATEXT *fout, + const char *name); + + /** + * Send a new score event. 'type' is the score event type ('a', 'i', 'q', + * 'f', or 'e'). + * 'numFields' is the size of the pFields array. 'pFields' is an array of + * floats with all the pfields for this event, starting with the p1 value + * specified in pFields[0]. + */ + PUBLIC int csoundScoreEvent(CSOUND *, + char type, const MYFLT *pFields, long numFields); + + /** + * Asynchronous version of csoundScoreEvent(). + */ + PUBLIC void csoundScoreEventAsync(CSOUND *, + char type, const MYFLT *pFields, long numFields); + + /** + * Like csoundScoreEvent(), this function inserts a score event, but + * at absolute time with respect to the start of performance, or from an + * offset set with time_ofs + */ + PUBLIC int csoundScoreEventAbsolute(CSOUND *, + char type, const MYFLT *pfields, long numFields, double time_ofs); + + /** + * Asynchronous version of csoundScoreEventAbsolute(). + */ + PUBLIC void csoundScoreEventAbsoluteAsync(CSOUND *, + char type, const MYFLT *pfields, long numFields, double time_ofs); + /** + * Input a NULL-terminated string (as if from a console), + * used for line events. + */ + PUBLIC void csoundInputMessage(CSOUND *, const char *message); + + /** + * Asynchronous version of csoundInputMessage(). + */ + PUBLIC void csoundInputMessageAsync(CSOUND *, const char *message); + + /** + * Kills off one or more running instances of an instrument identified + * by instr (number) or instrName (name). If instrName is NULL, the + * instrument number is used. + * Mode is a sum of the following values: + * 0,1,2: kill all instances (1), oldest only (1), or newest (2) + * 4: only turnoff notes with exactly matching (fractional) instr number + * 8: only turnoff notes with indefinite duration (p3 < 0 or MIDI) + * allow_release, if non-zero, the killed instances are allowed to release. + */ + PUBLIC int csoundKillInstance(CSOUND *csound, MYFLT instr, + char *instrName, int mode, int allow_release); + + + /** + * Register a function to be called once in every control period + * by sensevents(). Any number of functions may be registered, + * and will be called in the order of registration. + * The callback function takes two arguments: the Csound instance + * pointer, and the userData pointer as passed to this function. + * This facility can be used to ensure a function is called synchronously + * before every csound control buffer processing. It is important + * to make sure no blocking operations are performed in the callback. + * The callbacks are cleared on csoundCleanup(). + * Returns zero on success. + */ + PUBLIC int csoundRegisterSenseEventCallback(CSOUND *, + void (*func)(CSOUND *, void *), + void *userData); + + /** + * Set the ASCII code of the most recent key pressed. + * This value is used by the 'sensekey' opcode if a callback + * for returning keyboard events is not set (see + * csoundRegisterKeyboardCallback()). + */ + PUBLIC void csoundKeyPress(CSOUND *, char c); + + /** + * Registers general purpose callback functions that will be called to query + * keyboard events. These callbacks are called on every control period by + * the sensekey opcode. + * The callback is preserved on csoundReset(), and multiple + * callbacks may be set and will be called in reverse order of + * registration. If the same function is set again, it is only moved + * in the list of callbacks so that it will be called first, and the + * user data and type mask parameters are updated. 'typeMask' can be the + * bitwise OR of callback types for which the function should be called, + * or zero for all types. + * Returns zero on success, CSOUND_ERROR if the specified function + * pointer or type mask is invalid, and CSOUND_MEMORY if there is not + * enough memory. + * + * The callback function takes the following arguments: + * void *userData + * the "user data" pointer, as specified when setting the callback + * void *p + * data pointer, depending on the callback type + * unsigned int type + * callback type, can be one of the following (more may be added in + * future versions of Csound): + * CSOUND_CALLBACK_KBD_EVENT + * CSOUND_CALLBACK_KBD_TEXT + * called by the sensekey opcode to fetch key codes. The data + * pointer is a pointer to a single value of type 'int', for + * returning the key code, which can be in the range 1 to 65535, + * or 0 if there is no keyboard event. + * For CSOUND_CALLBACK_KBD_EVENT, both key press and release + * events should be returned (with 65536 (0x10000) added to the + * key code in the latter case) as unshifted ASCII codes. + * CSOUND_CALLBACK_KBD_TEXT expects key press events only as the + * actual text that is typed. + * The return value should be zero on success, negative on error, and + * positive if the callback was ignored (for example because the type is + * not known). + */ + PUBLIC int csoundRegisterKeyboardCallback(CSOUND *, + int (*func)(void *userData, void *p, + unsigned int type), + void *userData, unsigned int type); + + /** + * Removes a callback previously set with csoundRegisterKeyboardCallback(). + */ + PUBLIC void csoundRemoveKeyboardCallback(CSOUND *csound, + int (*func)(void *, void *, unsigned int)); + + /** @}*/ + /** @defgroup TABLE Tables + * + * @{ */ + /** + * Returns the length of a function table (not including the guard point), + * or -1 if the table does not exist. + */ + PUBLIC int csoundTableLength(CSOUND *, int table); + + /** + * Returns the value of a slot in a function table. + * The table number and index are assumed to be valid. + */ + PUBLIC MYFLT csoundTableGet(CSOUND *, int table, int index); + + /** + * Sets the value of a slot in a function table. + * The table number and index are assumed to be valid. + */ + PUBLIC void csoundTableSet(CSOUND *, int table, int index, MYFLT value); + + + /** + * Copy the contents of a function table into a supplied array *dest + * The table number is assumed to be valid, and the destination needs to + * have sufficient space to receive all the function table contents. + */ + PUBLIC void csoundTableCopyOut(CSOUND *csound, int table, MYFLT *dest); + + /** + * Asynchronous version of csoundTableCopyOut() + */ + PUBLIC void csoundTableCopyOutAsync(CSOUND *csound, int table, MYFLT *dest); + /** + * Copy the contents of an array *src into a given function table + * The table number is assumed to be valid, and the table needs to + * have sufficient space to receive all the array contents. + */ + PUBLIC void csoundTableCopyIn(CSOUND *csound, int table, MYFLT *src); + + /** + * Asynchronous version of csoundTableCopyIn() + */ + PUBLIC void csoundTableCopyInAsync(CSOUND *csound, int table, MYFLT *src); + + /** + * Stores pointer to function table 'tableNum' in *tablePtr, + * and returns the table length (not including the guard point). + * If the table does not exist, *tablePtr is set to NULL and + * -1 is returned. + */ + PUBLIC int csoundGetTable(CSOUND *, MYFLT **tablePtr, int tableNum); + + /** + * Stores pointer to the arguments used to generate + * function table 'tableNum' in *argsPtr, + * and returns the number of arguments used. + * If the table does not exist, *argsPtr is set to NULL and + * -1 is returned. + * NB: the argument list starts with the GEN number and is followed by + * its parameters. eg. f 1 0 1024 10 1 0.5 yields the list {10.0,1.0,0.5} + */ + PUBLIC int csoundGetTableArgs(CSOUND *csound, MYFLT **argsPtr, int tableNum); + + /** + * Checks if a given GEN number num is a named GEN + * if so, it returns the string length (excluding terminating NULL char) + * Otherwise it returns 0. + */ + PUBLIC int csoundIsNamedGEN(CSOUND *csound, int num); + + /** + * Gets the GEN name from a number num, if this is a named GEN + * The final parameter is the max len of the string (excluding termination) + */ + PUBLIC void csoundGetNamedGEN(CSOUND *csound, int num, char *name, int len); + + /** @}*/ + /** @defgroup TABLEDISPLAY Function table display + * + * @{ */ + /** + * Tells Csound whether external graphic table display is supported. + * Returns the previously set value (initially zero). + */ + PUBLIC int csoundSetIsGraphable(CSOUND *, int isGraphable); + + /** + * Called by external software to set Csound's MakeGraph function. + */ + PUBLIC void csoundSetMakeGraphCallback(CSOUND *, + void (*makeGraphCallback_)(CSOUND *, + WINDAT *windat, + const char *name)); + + /** + * Called by external software to set Csound's DrawGraph function. + */ + PUBLIC void csoundSetDrawGraphCallback(CSOUND *, + void (*drawGraphCallback_)(CSOUND *, + WINDAT *windat)); + + /** + * Called by external software to set Csound's KillGraph function. + */ + PUBLIC void csoundSetKillGraphCallback(CSOUND *, + void (*killGraphCallback_)(CSOUND *, + WINDAT *windat)); + + /** + * Called by external software to set Csound's ExitGraph function. + */ + PUBLIC void csoundSetExitGraphCallback(CSOUND *, + int (*exitGraphCallback_)(CSOUND *)); + + /** @}*/ + /** @defgroup OPCODES Opcodes + * + * @{ */ + + /** + * Finds the list of named gens + */ + PUBLIC void *csoundGetNamedGens(CSOUND *); + + /** + * Gets an alphabetically sorted list of all opcodes. + * Should be called after externals are loaded by csoundCompile(). + * Returns the number of opcodes, or a negative error code on failure. + * Make sure to call csoundDisposeOpcodeList() when done with the list. + */ + PUBLIC int csoundNewOpcodeList(CSOUND *, opcodeListEntry **opcodelist); + + /** + * Releases an opcode list. + */ + PUBLIC void csoundDisposeOpcodeList(CSOUND *, opcodeListEntry *opcodelist); + + /** + * Appends an opcode implemented by external software + * to Csound's internal opcode list. + * The opcode list is extended by one slot, + * and the parameters are copied into the new slot. + * Returns zero on success. + */ + PUBLIC int csoundAppendOpcode(CSOUND *, const char *opname, + int dsblksiz, int flags, int thread, + const char *outypes, const char *intypes, + int (*iopadr)(CSOUND *, void *), + int (*kopadr)(CSOUND *, void *), + int (*aopadr)(CSOUND *, void *)); + + /** @}*/ + /** @defgroup THREADING Threading and concurrency + * + * @{ */ + + /** + * Called by external software to set a function for checking system + * events, yielding cpu time for coopertative multitasking, etc. + * This function is optional. It is often used as a way to 'turn off' + * Csound, allowing it to exit gracefully. In addition, some operations + * like utility analysis routines are not reentrant and you should use + * this function to do any kind of updating during the operation. + * Returns an 'OK to continue' boolean. + */ + PUBLIC void csoundSetYieldCallback(CSOUND *, int (*yieldCallback_)(CSOUND *)); + + /** + * Creates and starts a new thread of execution. + * Returns an opaque pointer that represents the thread on success, + * or NULL for failure. + * The userdata pointer is passed to the thread routine. + */ + PUBLIC void *csoundCreateThread(uintptr_t (*threadRoutine)(void *), + void *userdata); + + /** + * Creates and starts a new thread of execution + * with a user-defined stack size. + * Returns an opaque pointer that represents the thread on success, + * or NULL for failure. + * The userdata pointer is passed to the thread routine. + */ + PUBLIC void *csoundCreateThread2(uintptr_t (*threadRoutine)(void *), + unsigned int stack, + void *userdata); + + /** + * Returns the ID of the currently executing thread, + * or NULL for failure. + * + * NOTE: The return value can be used as a pointer + * to a thread object, but it should not be compared + * as a pointer. The pointed to values should be compared, + * and the user must free the pointer after use. + */ + PUBLIC void *csoundGetCurrentThreadId(void); + + /** + * Waits until the indicated thread's routine has finished. + * Returns the value returned by the thread routine. + */ + PUBLIC uintptr_t csoundJoinThread(void *thread); + /** + * Creates and returns a monitor object, or NULL if not successful. + * The object is initially in signaled (notified) state. + */ + PUBLIC void *csoundCreateThreadLock(void); + + /** + * Waits on the indicated monitor object for the indicated period. + * The function returns either when the monitor object is notified, + * or when the period has elapsed, whichever is sooner; in the first case, + * zero is returned. + * If 'milliseconds' is zero and the object is not notified, the function + * will return immediately with a non-zero status. + */ + PUBLIC int csoundWaitThreadLock(void *lock, size_t milliseconds); + + /** + * Waits on the indicated monitor object until it is notified. + * This function is similar to csoundWaitThreadLock() with an infinite + * wait time, but may be more efficient. + */ + PUBLIC void csoundWaitThreadLockNoTimeout(void *lock); + + /** + * Notifies the indicated monitor object. + */ + PUBLIC void csoundNotifyThreadLock(void *lock); + + /** + * Destroys the indicated monitor object. + */ + PUBLIC void csoundDestroyThreadLock(void *lock); + + /** + * Creates and returns a mutex object, or NULL if not successful. + * Mutexes can be faster than the more general purpose monitor objects + * returned by csoundCreateThreadLock() on some platforms, and can also + * be recursive, but the result of unlocking a mutex that is owned by + * another thread or is not locked is undefined. + * If 'isRecursive' is non-zero, the mutex can be re-locked multiple + * times by the same thread, requiring an equal number of unlock calls; + * otherwise, attempting to re-lock the mutex results in undefined + * behavior. + * Note: the handles returned by csoundCreateThreadLock() and + * csoundCreateMutex() are not compatible. + */ + PUBLIC void *csoundCreateMutex(int isRecursive); + + /** + * Acquires the indicated mutex object; if it is already in use by + * another thread, the function waits until the mutex is released by + * the other thread. + */ + PUBLIC void csoundLockMutex(void *mutex_); + + /** + * Acquires the indicated mutex object and returns zero, unless it is + * already in use by another thread, in which case a non-zero value is + * returned immediately, rather than waiting until the mutex becomes + * available. + * Note: this function may be unimplemented on Windows. + */ + PUBLIC int csoundLockMutexNoWait(void *mutex_); + + /** + * Releases the indicated mutex object, which should be owned by + * the current thread, otherwise the operation of this function is + * undefined. A recursive mutex needs to be unlocked as many times + * as it was locked previously. + */ + PUBLIC void csoundUnlockMutex(void *mutex_); + + /** + * Destroys the indicated mutex object. Destroying a mutex that + * is currently owned by a thread results in undefined behavior. + */ + PUBLIC void csoundDestroyMutex(void *mutex_); + + + /** + * Create a Thread Barrier. Max value parameter should be equal to + * number of child threads using the barrier plus one for the + * master thread */ + + PUBLIC void *csoundCreateBarrier(unsigned int max); + + /** + * Destroy a Thread Barrier. + */ + PUBLIC int csoundDestroyBarrier(void *barrier); + + /** + * Wait on the thread barrier. + */ + PUBLIC int csoundWaitBarrier(void *barrier); + + + /** Creates a conditional variable */ + PUBLIC void* csoundCreateCondVar(); + + /** Waits up on a conditional variable and mutex */ + PUBLIC void csoundCondWait(void* condVar, void* mutex); + + /** Signals a conditional variable */ + PUBLIC void csoundCondSignal(void* condVar); + + /** Destroys a conditional variable */ + PUBLIC void csoundDestroyCondVar(void* condVar); + + /** + * Waits for at least the specified number of milliseconds, + * yielding the CPU to other threads. + */ + PUBLIC void csoundSleep(size_t milliseconds); + + /** + * If the spinlock is not locked, lock it and return; + * if is is locked, wait until it is unlocked, then lock it and return. + * Uses atomic compare and swap operations that are safe across processors + * and safe for out of order operations, + * and which are more efficient than operating system locks. + * Use spinlocks to protect access to shared data, especially in functions + * that do little more than read or write such data, for example: + * + * @code + * static spin_lock_t lock = SPINLOCK_INIT; + * csoundSpinLockInit(&lock); + * void write(size_t frames, int* signal) + * { + * csoundSpinLock(&lock); + * for (size_t frame = 0; i < frames; frame++) { + * global_buffer[frame] += signal[frame]; + * } + * csoundSpinUnlock(&lock); + * } + * @endcode + */ + PUBLIC int csoundSpinLockInit(spin_lock_t *spinlock); + + /** + * Locks the spinlock + */ + PUBLIC void csoundSpinLock(spin_lock_t *spinlock); + + /** + * Tries the lock, returns CSOUND_SUCCESS if lock could be acquired, + CSOUND_ERROR, otherwise. + */ + PUBLIC int csoundSpinTryLock(spin_lock_t *spinlock); + + /** + * Unlocks the spinlock + */ + PUBLIC void csoundSpinUnLock(spin_lock_t *spinlock); + + + /** @}*/ + /** @defgroup MISCELLANEOUS Miscellaneous functions + * + * @{ */ + + /** + * Runs an external command with the arguments specified in 'argv'. + * argv[0] is the name of the program to execute (if not a full path + * file name, it is searched in the directories defined by the PATH + * environment variable). The list of arguments should be terminated + * by a NULL pointer. + * If 'noWait' is zero, the function waits until the external program + * finishes, otherwise it returns immediately. In the first case, a + * non-negative return value is the exit status of the command (0 to + * 255), otherwise it is the PID of the newly created process. + * On error, a negative value is returned. + */ + PUBLIC long csoundRunCommand(const char * const *argv, int noWait); + + /** + * Initialise a timer structure. + */ + PUBLIC void csoundInitTimerStruct(RTCLOCK *); + + /** + * Return the elapsed real time (in seconds) since the specified timer + * structure was initialised. + */ + PUBLIC double csoundGetRealTime(RTCLOCK *); + + /** + * Return the elapsed CPU time (in seconds) since the specified timer + * structure was initialised. + */ + PUBLIC double csoundGetCPUTime(RTCLOCK *); + + /** + * Return a 32-bit unsigned integer to be used as seed from current time. + */ + PUBLIC uint32_t csoundGetRandomSeedFromTime(void); + + /** + * Set language to 'lang_code' (lang_code can be for example + * CSLANGUAGE_ENGLISH_UK or CSLANGUAGE_FRENCH or many others, + * see n_getstr.h for the list of languages). This affects all + * Csound instances running in the address space of the current + * process. The special language code CSLANGUAGE_DEFAULT can be + * used to disable translation of messages and free all memory + * allocated by a previous call to csoundSetLanguage(). + * csoundSetLanguage() loads all files for the selected language + * from the directory specified by the CSSTRNGS environment + * variable. + */ + PUBLIC void csoundSetLanguage(cslanguage_t lang_code); + + /** + * Get pointer to the value of environment variable 'name', searching + * in this order: local environment of 'csound' (if not NULL), variables + * set with csoundSetGlobalEnv(), and system environment variables. + * If 'csound' is not NULL, should be called after csoundCompile(). + * Return value is NULL if the variable is not set. + */ + PUBLIC const char *csoundGetEnv(CSOUND *csound, const char *name); + + /** + * Set the global value of environment variable 'name' to 'value', + * or delete variable if 'value' is NULL. + * It is not safe to call this function while any Csound instances + * are active. + * Returns zero on success. + */ + PUBLIC int csoundSetGlobalEnv(const char *name, const char *value); + + /** + * Allocate nbytes bytes of memory that can be accessed later by calling + * csoundQueryGlobalVariable() with the specified name; the space is + * cleared to zero. + * Returns CSOUND_SUCCESS on success, CSOUND_ERROR in case of invalid + * parameters (zero nbytes, invalid or already used name), or + * CSOUND_MEMORY if there is not enough memory. + */ + PUBLIC int csoundCreateGlobalVariable(CSOUND *, + const char *name, size_t nbytes); + + /** + * Get pointer to space allocated with the name "name". + * Returns NULL if the specified name is not defined. + */ + PUBLIC void *csoundQueryGlobalVariable(CSOUND *, const char *name); + + /** + * This function is the same as csoundQueryGlobalVariable(), except the + * variable is assumed to exist and no error checking is done. + * Faster, but may crash or return an invalid pointer if 'name' is + * not defined. + */ + PUBLIC void *csoundQueryGlobalVariableNoCheck(CSOUND *, const char *name); + + /** + * Free memory allocated for "name" and remove "name" from the database. + * Return value is CSOUND_SUCCESS on success, or CSOUND_ERROR if the name is + * not defined. + */ + PUBLIC int csoundDestroyGlobalVariable(CSOUND *, const char *name); + + /** + * Run utility with the specified name and command line arguments. + * Should be called after loading utility plugins. + * Use csoundReset() to clean up after calling this function. + * Returns zero if the utility was run successfully. + */ + PUBLIC int csoundRunUtility(CSOUND *, const char *name, + int argc, char **argv); + + /** + * Returns a NULL terminated list of registered utility names. + * The caller is responsible for freeing the returned array with + * csoundDeleteUtilityList(), however, the names should not be + * changed or freed. + * The return value may be NULL in case of an error. + */ + PUBLIC char **csoundListUtilities(CSOUND *); + + /** + * Releases an utility list previously returned by csoundListUtilities(). + */ + PUBLIC void csoundDeleteUtilityList(CSOUND *, char **lst); + + /** + * Get utility description. + * Returns NULL if the utility was not found, or it has no description, + * or an error occured. + */ + PUBLIC const char *csoundGetUtilityDescription(CSOUND *, + const char *utilName); + + /** + * Simple linear congruential random number generator: + * (*seedVal) = (*seedVal) * 742938285 % 2147483647 + * the initial value of *seedVal must be in the range 1 to 2147483646. + * Returns the next number from the pseudo-random sequence, + * in the range 1 to 2147483646. + */ + PUBLIC int csoundRand31(int *seedVal); + + /** + * Initialise Mersenne Twister (MT19937) random number generator, + * using 'keyLength' unsigned 32 bit values from 'initKey' as seed. + * If the array is NULL, the length parameter is used for seeding. + */ + PUBLIC void csoundSeedRandMT(CsoundRandMTState *p, + const uint32_t *initKey, uint32_t keyLength); + + /** + * Returns next random number from MT19937 generator. + * The PRNG must be initialised first by calling csoundSeedRandMT(). + */ + PUBLIC uint32_t csoundRandMT(CsoundRandMTState *p); + +#endif /* !CSOUND_CSDL_H */ + + /* typedefs, macros, and interface functions for configuration variables */ +#include "cfgvar.h" + /* message attribute definitions for csoundMessageS() and csoundMessageV() */ +#include "msg_attr.h" + /* macro definitions for Csound release, and API version */ +#include "version.h" + + /** + * Create circular buffer with numelem number of elements. The + * element's size is set from elemsize. It should be used like: + *@code + * void *rb = csoundCreateCircularBuffer(csound, 1024, sizeof(MYFLT)); + *@endcode + */ + PUBLIC void *csoundCreateCircularBuffer(CSOUND *csound, + int numelem, int elemsize); + + /** + * Read from circular buffer + * @param csound This value is currently ignored. + * @param circular_buffer pointer to an existing circular buffer + * @param out preallocated buffer with at least items number of elements, where + * buffer contents will be read into + * @param items number of samples to be read + * @returns the actual number of items read (0 <= n <= items) + */ + PUBLIC int csoundReadCircularBuffer(CSOUND *csound, void *circular_buffer, + void *out, int items); + + /** + * Read from circular buffer without removing them from the buffer. + * @param circular_buffer pointer to an existing circular buffer + * @param out preallocated buffer with at least items number of elements, where + * buffer contents will be read into + * @param items number of samples to be read + * @returns the actual number of items read (0 <= n <= items) + */ + PUBLIC int csoundPeekCircularBuffer(CSOUND *csound, void *circular_buffer, + void *out, int items); + + /** + * Write to circular buffer + * @param csound This value is currently ignored. + * @param p pointer to an existing circular buffer + * @param inp buffer with at least items number of elements to be written into + * circular buffer + * @param items number of samples to write + * @returns the actual number of items written (0 <= n <= items) + */ + PUBLIC int csoundWriteCircularBuffer(CSOUND *csound, void *p, + const void *inp, int items); + /** + * Empty circular buffer of any remaining data. This function should only be + * used if there is no reader actively getting data from the buffer. + * @param csound This value is currently ignored. + * @param p pointer to an existing circular buffer + */ + PUBLIC void csoundFlushCircularBuffer(CSOUND *csound, void *p); + + /** + * Free circular buffer + */ + PUBLIC void csoundDestroyCircularBuffer(CSOUND *csound, void *circularbuffer); + + /** + * Platform-independent function to load a shared library. + */ + PUBLIC int csoundOpenLibrary(void **library, const char *libraryPath); + + /** + * Platform-independent function to unload a shared library. + */ + PUBLIC int csoundCloseLibrary(void *library); + + /** + * Platform-independent function to get a symbol address in a shared library. + */ + PUBLIC void *csoundGetLibrarySymbol(void *library, const char *symbolName); + + + /** @}*/ + +#ifdef SWIGPYTHON + + PUBLIC CSOUND *csoundGetInstance(int64_t obj){ return (CSOUND *)obj; } + +#endif + + +#ifdef SOME_FINE_DAY /* these functions are now deprecated */ + + /** + * Returns a pointer to the requested interface, if available, in the + * interface argument, and its version number, in the version argument. + * Returns 0 for success. + */ + + PUBLIC int csoundQueryInterface(const char *name, + void **iface, int *version); + + + /** + * Control values are specified by a 'channelName' string. + * Note that the 'invalue' & 'outvalue' channels can be specified by + * either a string or a number. If a number is specified, it will be + * converted to a string before making the callbacks to the external + * software. + */ + + /** + * Called by external software to set a function for Csound to + * fetch input control values. The 'invalue' opcodes will + * directly call this function. If 'channelName' starts with a + * '$', then 'invalue' opcode is expecting a C string, to be copied + * to 'value', with maximum size csoundGetChannelDatasize(). + */ + PUBLIC void csoundSetInputValueCallback(CSOUND *, + void (*inputValueCalback_)(CSOUND *, + const char *channelName, + MYFLT *value)); + + /** + * Called by external software to set a function for Csound to + * send output control values. The 'outvalue' opcodes will + * directly call this function. If 'channelName' starts with a + * '$', then the 'outvalue' opcode is sending a string appended + * to channelName in the format: "$channelName$stringOutput". + * and 'value' will be the index number into 'channelName' where + * the stringOutput begins. + */ + PUBLIC void csoundSetOutputValueCallback(CSOUND *, + void (*outputValueCalback_)(CSOUND *, + const char *channelName, + MYFLT value)); + + /** + * Sets callback function to be called by the opcodes 'chnsend' and + * 'chnrecv'. Should be called before csoundCompile(). + * The callback function takes the following arguments: + * CSOUND *csound + * Csound instance pointer + * const char *channelName + * the channel name + * MYFLT *channelValuePtr + * pointer to the channel value. Control channels are a single MYFLT + * value, while audio channels are an array of csoundGetKsmps(csound) + * MYFLT values. In the case of string channels, the pointer should be + * cast to char *, and points to a buffer of + * csoundGetChannelDatasize() bytes + * int channelType + * bitwise OR of the channel type (CSOUND_CONTROL_CHANNEL, + * CSOUND_AUDIO_CHANNEL, or CSOUND_STRING_CHANNEL; use + * channelType & CSOUND_CHANNEL_TYPE_MASK to extract the channel + * type), and either CSOUND_INPUT_CHANNEL or CSOUND_OUTPUT_CHANNEL + * to indicate the direction of the data transfer + * The callback is not preserved on csoundReset(). + */ + PUBLIC void csoundSetChannelIOCallback(CSOUND *, + CsoundChannelIOCallback_t func); + + /** + * Senses input events, and performs one control sample worth (ksmps) of + * audio output. + * Note that csoundCompile() or csoundCompileOrc(), + * csoundReadScore(), csoundStart() must be called first. + * Performs audio whether or not the Csound score has finished. + * Enables external software to control the execution of Csound, + * and to synchronize performance with audio input and output. + */ + PUBLIC int csoundPerformKsmpsAbsolute(CSOUND *); +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* CSOUND_H */ diff --git a/6.x/csound/csound.hpp b/6.x/csound/csound.hpp new file mode 100644 index 00000000..cf6b2d30 --- /dev/null +++ b/6.x/csound/csound.hpp @@ -0,0 +1,1080 @@ +/* + csound.hpp: + + Copyright (C) 2005 Istvan Varga, Michael Gogins + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA + + As a special exception, if other files instantiate templates or + use macros or inline functions from this file, this file does not + by itself cause the resulting executable or library to be covered + by the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the library or executable + file might be covered by the GNU Lesser General Public License. +*/ + +#ifndef __CSOUND_HPP__ +#define __CSOUND_HPP__ + +#ifdef SWIG +%module csnd6 +%{ +#include "csound.h" +%} +#else +#include "csound.h" +#if defined(HAVE_PTHREAD_SPIN_LOCK) && !defined(SWIG) +#include +#endif +#ifdef __BUILDING_CSOUND_INTERFACES +#endif +#endif + +#ifdef SWIGPYTHON +#define MESSAGE_BUFFER_LENGTH 8192 +struct PUBLIC pycbdata { + PyObject *mfunc,*invalfunc,*outvalfunc; + PyObject *midiinopenfunc, *midireadfunc, *midiinclosefunc; + PyObject *hostdata; + char messageBuffer[MESSAGE_BUFFER_LENGTH]; + int messageBufferIndex; +}; +#endif + +#if defined(__cplusplus) + +#if defined(HAVE_PTHREAD_SPIN_LOCK) && !defined(SWIG) +struct Spinlock +{ + pthread_spinlock_t lock_; + Spinlock() + { + pthread_spin_init(&lock_, PTHREAD_PROCESS_PRIVATE); + } + ~Spinlock() + { + pthread_spin_destroy(&lock_); + } + void lock() + { + pthread_spin_lock(&lock_); + } + void unlock() + { + pthread_spin_unlock(&lock_); + } +}; + +struct Spinlocker +{ + Spinlock &spinlock; + #if (__cplusplus >= 201103L) + explicit + #endif + Spinlocker(Spinlock &spinlock_) : spinlock(spinlock_) + { + spinlock.lock(); + } + ~Spinlocker() + { + spinlock.unlock(); + } +}; +#endif + + +/** + * C++ interface to the "C" Csound API. + */ +class PUBLIC Csound +{ +protected: + CSOUND *csound; +public: + void *pydata; +public: + virtual CSOUND *GetCsound() + { + return csound; + } + virtual void SetCsound(CSOUND *csound_) + { + csound = csound_; + } + virtual int InitializeCscore(FILE *insco, FILE *outsco) + { + return csoundInitializeCscore(csound, insco, outsco); + } + virtual int LoadPlugins(const char *dir){ + return csoundLoadPlugins(csound, dir); + } + virtual int GetVersion() + { + return csoundGetVersion(); + } + virtual int GetAPIVersion() + { + return csoundGetAPIVersion(); + } + virtual void *GetHostData() + { + return csoundGetHostData(csound); + } + virtual void SetHostData(void *hostData) + { + csoundSetHostData(csound, hostData); + } + virtual const char *GetEnv(const char *name) + { + return csoundGetEnv(csound, name); + } + virtual int SetGlobalEnv(const char *name,const char *value) + { + return csoundSetGlobalEnv(name, value); + } + virtual int SetOption(const char *option) + { + return csoundSetOption(csound, option); + } + virtual void SetParams(CSOUND_PARAMS *p){ + csoundSetParams(csound, p); + } + virtual void GetParams(CSOUND_PARAMS *p){ + csoundGetParams(csound, p); + } + virtual void SetOutput(const char *name,const char *type,const char *format){ + csoundSetOutput(csound, name, type, format); + } + virtual void SetInput(const char *name){ + csoundSetInput(csound, name); + } + virtual void SetMIDIInput(const char *name){ + csoundSetMIDIInput(csound,name); + } + virtual void SetMIDIFileInput(const char *name){ + csoundSetMIDIFileInput(csound,name); + } + virtual void SetMIDIOutput(const char *name){ + csoundSetMIDIOutput(csound,name); + } + virtual void SetMIDIFileOutput(const char *name){ + csoundSetMIDIFileOutput(csound,name); + } + virtual TREE *ParseOrc(const char *str) + { + return csoundParseOrc(csound, str); + } + virtual int CompileTree(TREE *root) + { + return csoundCompileTree(csound, root); + } + virtual void DeleteTree(TREE *root) + { + csoundDeleteTree(csound, root); + } + virtual int CompileOrc(const char *str) + { + return csoundCompileOrc(csound, str); + } + virtual MYFLT EvalCode(const char *str) + { + return csoundEvalCode(csound, str); + } + virtual int ReadScore(const char *str) + { + return csoundReadScore(csound, str); + } + virtual int CompileArgs(int argc,const char **argv) + { + return csoundCompileArgs(csound, argc, argv); + } + virtual int Compile(int argc,const char **argv) + { + return csoundCompile(csound, argc, argv); + } + virtual int Compile(const char *csdName) + { + const char *argv[3]; + argv[0] = (char*)"csound"; + argv[1] = csdName; + argv[2] = (char*) 0; + return csoundCompile(csound, 2, &(argv[0])); + } + virtual int Compile(const char *orcName,const char *scoName) + { + const char *argv[4]; + argv[0] = (char*)"csound"; + argv[1] = orcName; + argv[2] = scoName; + argv[3] = (char*) 0; + return csoundCompile(csound, 3, &(argv[0])); + } + virtual int Compile(const char *arg1,const char *arg2,const char *arg3) + { + const char *argv[5]; + argv[0] = (char*)"csound"; + argv[1] = arg1; + argv[2] = arg2; + argv[3] = arg3; + argv[4] = (char*) 0; + return csoundCompile(csound, 4, &(argv[0])); + } + virtual int Compile(const char *arg1,const char *arg2,const char *arg3,const char *arg4) + { + const char *argv[6]; + argv[0] = (char*)"csound"; + argv[1] = arg1; + argv[2] = arg2; + argv[3] = arg3; + argv[4] = arg4; + argv[5] = (char*) 0; + return csoundCompile(csound, 5, &(argv[0])); + } + virtual int Compile(const char *arg1,const char *arg2,const char *arg3, + const char *arg4,const char *arg5) + { + const char *argv[7]; + argv[0] = (char*)"csound"; + argv[1] = arg1; + argv[2] = arg2; + argv[3] = arg3; + argv[4] = arg4; + argv[5] = arg5; + argv[6] = (char*) 0; + return csoundCompile(csound, 6, &(argv[0])); + } + virtual int CompileCsd(const char *csd) + { + return csoundCompileCsd(csound, csd); + } + virtual int CompileCsdText(const char *csd_text) + { + return csoundCompileCsdText(csound, csd_text); + } + virtual int Start() + { + return csoundStart(csound); + } + virtual int Perform() + { + return csoundPerform(csound); + } + virtual int Perform(int argc, const char **argv) + { + int result = csoundCompile(csound, argc, argv); + if (result == 0) { + result = csoundPerform(csound); + } + csoundCleanup(csound); + return (result >= 0 ? 0 : result); + } + virtual int Perform(const char *csdName) + { + const char *argv[3]; + int result; + argv[0] = (char*)"csound"; + argv[1] = csdName; + argv[2] = (char*) 0; + result = csoundCompile(csound, 2, &(argv[0])); + if (result == 0) { + result = csoundPerform(csound); + } + csoundCleanup(csound); + return (result >= 0 ? 0 : result); + } + virtual int Perform(const char *orcName, const char *scoName) + { + const char *argv[4]; + int result; + argv[0] = (char*)"csound"; + argv[1] = orcName; + argv[2] = scoName; + argv[3] = (char*) 0; + result = csoundCompile(csound, 3, &(argv[0])); + if (result == 0) { + result = csoundPerform(csound); + } + csoundCleanup(csound); + return (result >= 0 ? 0 : result); + } + virtual int Perform(const char *arg1, const char *arg2, const char *arg3) + { + const char *argv[5]; + int result; + argv[0] = (char*)"csound"; + argv[1] = arg1; + argv[2] = arg2; + argv[3] = arg3; + argv[4] = (char*) 0; + result = csoundCompile(csound, 4, &(argv[0])); + if (result == 0) { + result = csoundPerform(csound); + } + csoundCleanup(csound); + return (result >= 0 ? 0 : result); + } + virtual int Perform(const char *arg1, const char *arg2, const char *arg3, const char *arg4) + { + const char *argv[6]; + int result; + argv[0] = (char*)"csound"; + argv[1] = arg1; + argv[2] = arg2; + argv[3] = arg3; + argv[4] = arg4; + argv[5] = (char*) 0; + result = csoundCompile(csound, 5, &(argv[0])); + if (result == 0) { + result = csoundPerform(csound); + } + csoundCleanup(csound); + return (result >= 0 ? 0 : result); + } + virtual int Perform(const char *arg1, const char *arg2, const char *arg3, + const char *arg4, const char *arg5) + { + const char *argv[7]; + int result; + argv[0] = (char*)"csound"; + argv[1] = arg1; + argv[2] = arg2; + argv[3] = arg3; + argv[4] = arg4; + argv[5] = arg5; + argv[6] = (char*) 0; + result = csoundCompile(csound, 6, &(argv[0])); + if (result == 0) { + result = csoundPerform(csound); + } + csoundCleanup(csound); + return (result >= 0 ? 0 : result); + } + virtual int PerformKsmps() + { + return csoundPerformKsmps(csound); + } + virtual int PerformBuffer() + { + return csoundPerformBuffer(csound); + } + virtual void Stop() + { + csoundStop(csound); + } + virtual int Cleanup() + { + return csoundCleanup(csound); + } + virtual void Reset() + { + csoundReset(csound); + } + virtual MYFLT GetSr() + { + return csoundGetSr(csound); + } + virtual MYFLT GetKr() + { + return csoundGetKr(csound); + } + virtual int GetKsmps() + { + return csoundGetKsmps(csound); + } + virtual int GetNchnls() + { + return csoundGetNchnls(csound); + } + virtual int GetNchnlsInput() + { + return csoundGetNchnlsInput(csound); + } + virtual MYFLT Get0dBFS() + { + return csoundGet0dBFS(csound); + } + virtual long GetInputBufferSize() + { + return csoundGetInputBufferSize(csound); + } + virtual long GetOutputBufferSize() + { + return csoundGetOutputBufferSize(csound); + } + virtual MYFLT *GetInputBuffer() + { + return csoundGetInputBuffer(csound); + } + virtual MYFLT *GetOutputBuffer() + { + return csoundGetOutputBuffer(csound); + } + virtual MYFLT *GetSpin() + { + return csoundGetSpin(csound); + } + virtual MYFLT *GetSpout() + { + return csoundGetSpout(csound); + } + virtual const char *GetOutputName() + { + return csoundGetOutputName(csound); + } + virtual long GetCurrentTimeSamples(){ + return csoundGetCurrentTimeSamples(csound); + } + virtual void SetHostImplementedAudioIO(int state, int bufSize) + { + csoundSetHostImplementedAudioIO(csound, state, bufSize); + } + virtual void SetHostImplementedMIDIIO(int state) + { + csoundSetHostImplementedMIDIIO(csound, state); + } + virtual double GetScoreTime() + { + return csoundGetScoreTime(csound); + } + virtual int IsScorePending() + { + return csoundIsScorePending(csound); + } + virtual void SetScorePending(int pending) + { + csoundSetScorePending(csound, pending); + } + virtual MYFLT GetScoreOffsetSeconds() + { + return csoundGetScoreOffsetSeconds(csound); + } + virtual void SetScoreOffsetSeconds(double time) + { + csoundSetScoreOffsetSeconds(csound, (MYFLT) time); + } + virtual void RewindScore() + { + csoundRewindScore(csound); + } + virtual void SetCscoreCallback(void (*cscoreCallback_)(CSOUND *)) + { + csoundSetCscoreCallback(csound, cscoreCallback_); + } + virtual int ScoreSort(FILE *inFile, FILE *outFile) + { + return csoundScoreSort(csound, inFile, outFile); + } + virtual int ScoreExtract(FILE *inFile, FILE *outFile, FILE *extractFile) + { + return csoundScoreExtract(csound, inFile, outFile, extractFile); + } + virtual void Message(const char *format, ...) + { + va_list args; + va_start(args, format); + csoundMessageV(csound, 0, format, args); + va_end(args); + } + virtual void MessageS(int attr, const char *format, ...) + { + va_list args; + va_start(args, format); + csoundMessageV(csound, attr, format, args); + va_end(args); + } + virtual void MessageV(int attr, const char *format, va_list args) + { + csoundMessageV(csound, attr, format, args); + } + virtual void SetMessageCallback( + void (*csoundMessageCallback_)(CSOUND *, int attr, + const char *format, va_list valist)) + { + csoundSetMessageCallback(csound, csoundMessageCallback_); + } + virtual int GetMessageLevel() + { + return csoundGetMessageLevel(csound); + } + virtual void SetMessageLevel(int messageLevel) + { + csoundSetMessageLevel(csound, messageLevel); + } + virtual void InputMessage(const char *message) + { + csoundInputMessage(csound, message); + } + virtual void KeyPressed(char c) + { + csoundKeyPress(csound, c); + } + virtual int ScoreEvent(char type, const MYFLT *pFields, long numFields) + { + return csoundScoreEvent(csound, type, pFields, numFields); + } + virtual int ScoreEventAbsolute(char type, const MYFLT *pFields, + long numFields, double time_ofs) + { + return csoundScoreEventAbsolute(csound, type, pFields, numFields, time_ofs); + } + virtual void SetExternalMidiInOpenCallback( + int (*func)(CSOUND *, void **, const char *)) + { + csoundSetExternalMidiInOpenCallback(csound, func); + } + virtual void SetExternalMidiReadCallback( + int (*func)(CSOUND *, void *, unsigned char *, int)) + { + csoundSetExternalMidiReadCallback(csound, func); + } + virtual void SetExternalMidiInCloseCallback( + int (*func)(CSOUND *, void *)) + { + csoundSetExternalMidiInCloseCallback(csound, func); + } + virtual void SetExternalMidiOutOpenCallback( + int (*func)(CSOUND *, void **, const char *)) + { + csoundSetExternalMidiOutOpenCallback(csound, func); + } + virtual void SetExternalMidiWriteCallback( + int (*func)(CSOUND *, void *, const unsigned char *, int)) + { + csoundSetExternalMidiWriteCallback(csound, func); + } + virtual void SetExternalMidiOutCloseCallback( + int (*func)(CSOUND *, void *)) + { + csoundSetExternalMidiOutCloseCallback(csound, func); + } + virtual void SetExternalMidiErrorStringCallback( + const char *(*func)(int)) + { + csoundSetExternalMidiErrorStringCallback(csound, func); + } + virtual int SetIsGraphable(int isGraphable) + { + return csoundSetIsGraphable(csound, isGraphable); + } + virtual void SetMakeGraphCallback( + void (*makeGraphCallback_)(CSOUND *, WINDAT *windat, const char *name)) + { + csoundSetMakeGraphCallback(csound, makeGraphCallback_); + } + virtual void SetDrawGraphCallback( + void (*drawGraphCallback_)(CSOUND *, WINDAT *windat)) + { + csoundSetDrawGraphCallback(csound, drawGraphCallback_); + } + virtual void SetKillGraphCallback( + void (*killGraphCallback_)(CSOUND *, WINDAT *windat)) + { + csoundSetKillGraphCallback(csound, killGraphCallback_); + } + virtual void SetExitGraphCallback( + int (*exitGraphCallback_)(CSOUND *)) + { + csoundSetExitGraphCallback(csound, exitGraphCallback_); + } + virtual int NewOpcodeList(opcodeListEntry* &opcodelist) + { + opcodeListEntry *tmp = (opcodeListEntry*) 0; + int retval; + retval = csoundNewOpcodeList(csound, &tmp); + opcodelist = tmp; + return retval; + } + virtual void DisposeOpcodeList(opcodeListEntry *opcodelist) + { + csoundDisposeOpcodeList(csound, opcodelist); + } + virtual int AppendOpcode(const char *opname, int dsblksiz, int flags, + int thread, + const char *outypes, const char *intypes, + int (*iopadr)(CSOUND *, void *), + int (*kopadr)(CSOUND *, void *), + int (*aopadr)(CSOUND *, void *)) + { + return csoundAppendOpcode(csound, opname, dsblksiz, flags, thread, + outypes, intypes, iopadr, kopadr, aopadr); + } + virtual void SetYieldCallback(int (*yieldCallback_)(CSOUND *)) + { + csoundSetYieldCallback(csound, yieldCallback_); + } + virtual void SetPlayopenCallback( + int (*playopen__)(CSOUND *, const csRtAudioParams *parm)) + { + csoundSetPlayopenCallback(csound, playopen__); + } + virtual void SetRtplayCallback( + void (*rtplay__)(CSOUND *, const MYFLT *outBuf, int nbytes)) + { + csoundSetRtplayCallback(csound, rtplay__); + } + virtual void SetRecopenCallback( + int (*recopen_)(CSOUND *, const csRtAudioParams *parm)) + { + csoundSetRecopenCallback(csound, recopen_); + } + virtual void SetRtrecordCallback( + int (*rtrecord__)(CSOUND *, MYFLT *inBuf, int nbytes)) + { + csoundSetRtrecordCallback(csound, rtrecord__); + } + virtual void SetRtcloseCallback( + void (*rtclose__)(CSOUND *)) + { + csoundSetRtcloseCallback(csound, rtclose__); + } + virtual int GetDebug() + { + return csoundGetDebug(csound); + } + virtual void SetDebug(int debug) + { + csoundSetDebug(csound, debug); + } + virtual int TableLength(int table) + { + return csoundTableLength(csound, table); + } + virtual MYFLT TableGet(int table, int index) + { + return csoundTableGet(csound, table, index); + } + virtual void TableSet(int table, int index, double value) + { + csoundTableSet(csound, table, index, (MYFLT) value); + } + virtual int GetTable(MYFLT* &tablePtr, int tableNum) + { + MYFLT *ftable; + int tmp; + tmp = csoundGetTable(csound, &ftable, tableNum); + tablePtr = ftable; + return tmp; + } + virtual void TableCopyOut(int table, MYFLT *dest){ + csoundTableCopyOut(csound,table,dest); + } + virtual void TableCopyIn(int table, MYFLT *src){ + csoundTableCopyIn(csound,table,src); + } + virtual int CreateGlobalVariable(const char *name, size_t nbytes) + { + return csoundCreateGlobalVariable(csound, name, nbytes); + } + virtual void *QueryGlobalVariable(const char *name) + { + return csoundQueryGlobalVariable(csound, name); + } + virtual void *QueryGlobalVariableNoCheck(const char *name) + { + return csoundQueryGlobalVariableNoCheck(csound, name); + } + virtual int DestroyGlobalVariable(const char *name) + { + return csoundDestroyGlobalVariable(csound, name); + } + virtual void **GetRtRecordUserData() + { + return csoundGetRtRecordUserData(csound); + } + virtual void **GetRtPlayUserData() + { + return csoundGetRtPlayUserData(csound); + } + virtual int RegisterSenseEventCallback(void (*func)(CSOUND *, void *), + void *userData) + { + return csoundRegisterSenseEventCallback(csound, func, userData); + } + virtual int RunUtility(const char *name, int argc, char **argv) + { + return csoundRunUtility(csound, name, argc, argv); + } + virtual char **ListUtilities() + { + return csoundListUtilities(csound); + } + virtual void DeleteUtilityList(char **lst) + { + csoundDeleteUtilityList(csound, lst); + } + virtual const char *GetUtilityDescription(const char *utilName) + { + return csoundGetUtilityDescription(csound, utilName); + } + virtual int GetChannelPtr(MYFLT* &p, const char *name, int type) + { + MYFLT *tmp; + int retval; + if(strlen(name) == 0) return CSOUND_ERROR; + retval = csoundGetChannelPtr(csound, &tmp, name, type); + p = tmp; + return retval; + } + virtual int ListChannels(controlChannelInfo_t* &lst) + { + controlChannelInfo_t *tmp; + int retval; + retval = csoundListChannels(csound, &tmp); + lst = tmp; + return retval; + } + virtual void DeleteChannelList(controlChannelInfo_t *lst) + { + csoundDeleteChannelList(csound, lst); + } + virtual int SetControlChannelHints(const char *name, + controlChannelHints_t hints) + { + return csoundSetControlChannelHints(csound, name, hints); + } + virtual int GetControlChannelHints(const char *name, controlChannelHints_t *hints) + { + return csoundGetControlChannelHints(csound, name, hints); + } + virtual void SetChannel(const char *name, double value) + { + csoundSetControlChannel(csound,name,value); + } + virtual void SetControlChannel(const char *name, double value) + { + csoundSetControlChannel(csound,name,value); + } + virtual void SetChannel(const char *name, char *string) + { + csoundSetStringChannel(csound,name,string); + } + virtual void SetStringChannel(const char *name, char *string) + { + csoundSetStringChannel(csound,name,string); + } + virtual void SetChannel(const char *name, MYFLT *samples) + { + csoundSetAudioChannel(csound,name,samples); + } + virtual MYFLT GetChannel(const char *name, int *err = NULL) + { + return csoundGetControlChannel(csound,name, err); + } + virtual MYFLT GetControlChannel(const char *name, int *err = NULL) + { + return csoundGetControlChannel(csound,name, err); + } + virtual void GetStringChannel(const char *name, char *string) + { + csoundGetStringChannel(csound,name,string); + } + virtual void GetAudioChannel(const char *name, MYFLT *samples) + { + csoundGetAudioChannel(csound,name,samples); + } + virtual int PvsinSet(const PVSDATEXT* value, const char *name) + { + return csoundSetPvsChannel(csound, value, name); + } + + virtual int PvsoutGet(PVSDATEXT* value, const char *name) + { + return csoundGetPvsChannel(csound, value, name); + } + + virtual void SetInputChannelCallback(channelCallback_t inputChannelCalback){ + csoundSetInputChannelCallback(csound, inputChannelCalback); + } + + virtual void SetOutputChannelCallback(channelCallback_t outputChannelCalback){ + csoundSetOutputChannelCallback(csound, outputChannelCalback); + } + + // cfgvar.h interface + virtual int CreateConfigurationVariable(const char *name, void *p, + int type, int flags, + void *min, void *max, + const char *shortDesc, + const char *longDesc) + { + return csoundCreateConfigurationVariable(csound, name, p, type, flags, + min, max, shortDesc, longDesc); + } + virtual int SetConfigurationVariable(const char *name, void *value) + { + return csoundSetConfigurationVariable(csound, name, value); + } + virtual int ParseConfigurationVariable(const char *name, const char *value) + { + return csoundParseConfigurationVariable(csound, name, value); + } + virtual csCfgVariable_t *QueryConfigurationVariable(const char *name) + { + return csoundQueryConfigurationVariable(csound, name); + } + virtual csCfgVariable_t **ListConfigurationVariables() + { + return csoundListConfigurationVariables(csound); + } + virtual int DeleteConfigurationVariable(const char *name) + { + return csoundDeleteConfigurationVariable(csound, name); + } + Csound() + { + csound = csoundCreate((CSOUND*) 0); + #ifdef SWIGPYTHON + pydata =(pycbdata *) new pycbdata; + memset(pydata, 0, sizeof(pycbdata)); + ((pycbdata *)pydata)->mfunc = NULL; + ((pycbdata *)pydata)->messageBufferIndex = 0; + csoundSetHostData(csound, this); + #else + pydata = NULL; + #endif + } + #if (__cplusplus >= 201103L) + Csound(const Csound &other) = delete; + explicit + #endif + Csound(CSOUND *csound_) : csound(csound_) + { + #ifdef SWIGPYTHON + pydata =(pycbdata *) new pycbdata; + ((pycbdata *)pydata)->mfunc = NULL; + ((pycbdata *)pydata)->messageBufferIndex = 0; + csoundSetHostData(csound, this); + #else + pydata = NULL; + #endif + + } + #if (__cplusplus >= 201103L) + explicit + #endif + Csound(void *hostData) + { + csound = csoundCreate(hostData); + #ifdef SWIGPYTHON + pydata =(pycbdata *) new pycbdata; + ((pycbdata *)pydata)->mfunc = NULL; + ((pycbdata *)pydata)->messageBufferIndex = 0; + csoundSetHostData(csound, this); + #else + pydata = NULL; + #endif + } + virtual ~Csound() + { + csoundDestroy(csound); + #ifdef SWIGPYTHON + ((pycbdata *)pydata)->mfunc = NULL; + delete (pycbdata *)pydata; + #endif + + } + virtual void CreateMessageBuffer(int toStdOut) + { + csoundCreateMessageBuffer(csound, toStdOut); + } + virtual const char *GetFirstMessage() + { + return csoundGetFirstMessage(csound); + } + virtual int GetFirstMessageAttr() + { + return csoundGetFirstMessageAttr(csound); + } + virtual void PopFirstMessage() + { + csoundPopFirstMessage(csound); + } + virtual int GetMessageCnt() + { + return csoundGetMessageCnt(csound); + } + virtual void DestroyMessageBuffer() + { + csoundDestroyMessageBuffer(csound); + } + virtual void AddSpinSample(int frame, int channel, MYFLT sample) + { + csoundAddSpinSample(csound, frame, channel, sample); + } + virtual void SetSpinSample(int frame, int channel, MYFLT sample) + { + csoundSetSpinSample(csound, frame, channel, sample); + } + virtual MYFLT GetSpoutSample(int frame, int channel) const + { + return csoundGetSpoutSample(csound, frame, channel); + } + virtual const char *GetInputName() + { + return csoundGetInputName(csound); + } + virtual void SetAudioChannel(const char *name, MYFLT *samples) { + csoundSetAudioChannel(csound, name, samples); + } + virtual MYFLT SystemSr(MYFLT value) { + return csoundSystemSr(csound, value); + } +}; + +class CsoundThreadLock { +protected: + void *threadLock; +public: + int Lock(size_t milliseconds) + { + return csoundWaitThreadLock(threadLock, milliseconds); + } + void Lock() + { + csoundWaitThreadLockNoTimeout(threadLock); + } + int TryLock() + { + return csoundWaitThreadLock(threadLock, (size_t) 0); + } + void Unlock() + { + csoundNotifyThreadLock(threadLock); + } + // constructors + // FIXME: should throw exception on failure ? + CsoundThreadLock() + { + threadLock = csoundCreateThreadLock(); + } + CsoundThreadLock(int locked) + { + threadLock = csoundCreateThreadLock(); + if (locked) + csoundWaitThreadLock(threadLock, (size_t) 0); + } + // destructor + ~CsoundThreadLock() + { + csoundDestroyThreadLock(threadLock); + } +}; + +class CsoundMutex { +protected: + void *mutex_; +public: + void Lock() + { + csoundLockMutex(mutex_); + } + // FIXME: this may be unimplemented on Windows + int TryLock() + { + return csoundLockMutexNoWait(mutex_); + } + void Unlock() + { + csoundUnlockMutex(mutex_); + } + CsoundMutex() + { + mutex_ = csoundCreateMutex(1); + } + #if (__cplusplus >= 201103L) + explicit + #endif + CsoundMutex(int isRecursive) + { + mutex_ = csoundCreateMutex(isRecursive); + } + ~CsoundMutex() + { + csoundDestroyMutex(mutex_); + } +}; + +// Mersenne Twister (MT19937) pseudo-random number generator + +class CsoundRandMT { +protected: + CsoundRandMTState mt; +public: + uint32_t Random() + { + return csoundRandMT(&mt); + } + void Seed(uint32_t seedVal) + { + csoundSeedRandMT(&mt, (uint32_t*) 0, seedVal); + } + void Seed(const uint32_t *initKey, int keyLength) + { + csoundSeedRandMT(&mt, initKey, (uint32_t) keyLength); + } + CsoundRandMT() + { + csoundSeedRandMT(&mt, (uint32_t*) 0, csoundGetRandomSeedFromTime()); + } + #if (__cplusplus >= 201103L) + explicit + #endif + CsoundRandMT(uint32_t seedVal) + { + csoundSeedRandMT(&mt, (uint32_t*) 0, seedVal); + } + CsoundRandMT(const uint32_t *initKey, int keyLength) + { + csoundSeedRandMT(&mt, initKey, (uint32_t) keyLength); + } + ~CsoundRandMT() + { + } +}; + +// timer (csoundInitialize() should be called before using this) + +class CsoundTimer { +protected: + RTCLOCK rt; +public: + double GetRealTime() + { + return csoundGetRealTime(&rt); + } + double GetCPUTime() + { + return csoundGetCPUTime(&rt); + } + void Reset() + { + csoundInitTimerStruct(&rt); + } + // constructor + CsoundTimer() + { + csoundInitTimerStruct(&rt); + } + ~CsoundTimer() + { + } +}; + +#endif // __cplusplus + +#endif // __CSOUND_HPP__ diff --git a/6.x/csound/csoundCore.h b/6.x/csound/csoundCore.h new file mode 100644 index 00000000..45a45a7b --- /dev/null +++ b/6.x/csound/csoundCore.h @@ -0,0 +1,1863 @@ +/* + csoundCore.h: + + Copyright (C) 1991-2006 Barry Vercoe, John ffitch, Istvan Varga + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#if !defined(__BUILDING_LIBCSOUND) && !defined(CSOUND_CSDL_H) +# error "Csound plugins and host applications should not include csoundCore.h" +#endif + +#ifndef CSOUNDCORE_H +#define CSOUNDCORE_H + +#if defined(__EMSCRIPTEN__) && !defined(EMSCRIPTEN) +#define EMSCRIPTEN +#endif + +#include "sysdep.h" +#if !defined(EMSCRIPTEN) && !defined(CABBAGE) +#if defined(HAVE_PTHREAD) +#include +#endif +#endif +#include "cs_par_structs.h" +#include +#include +#include "csound_type_system.h" +#include "csound.h" +#include "cscore.h" +#include "csound_data_structures.h" +#include "csound_standard_types.h" +#include "pools.h" + +#ifndef CSOUND_CSDL_H +/* VL not sure if we need to check for SSE */ +#if defined(__SSE__) && !defined(EMSCRIPTEN) +#include +#ifndef _MM_DENORMALS_ZERO_ON +#define _MM_DENORMALS_ZERO_MASK 0x0040 +#define _MM_DENORMALS_ZERO_ON 0x0040 +#define _MM_DENORMALS_ZERO_OFF 0x0000 +#define _MM_SET_DENORMALS_ZERO_MODE(mode) \ + _mm_setcsr((_mm_getcsr() & ~_MM_DENORMALS_ZERO_MASK) | (mode)) +#define _MM_GET_DENORMALS_ZERO_MODE() \ + (_mm_getcsr() & _MM_DENORMALS_ZERO_MASK) +#endif +#else +#ifndef _MM_DENORMALS_ZERO_ON +#define _MM_DENORMALS_ZERO_MASK 0 +#define _MM_DENORMALS_ZERO_ON 0 +#define _MM_DENORMALS_ZERO_OFF 0 +#define _MM_SET_DENORMALS_ZERO_MODE(mode) +#endif +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#if defined(__MACH__) || defined(__FreeBSD__) || defined(__DragonFly__) +#include +#endif + +#if (defined(__MACH__) || defined(ANDROID) || defined(NACL) || defined(__CYGWIN__) || defined(__HAIKU__)) +#include +#define BARRIER_SERIAL_THREAD (-1) +typedef struct { + pthread_mutex_t mut; + pthread_cond_t cond; + unsigned int count, max, iteration; +} barrier_t; + +#ifndef PTHREAD_BARRIER_SERIAL_THREAD +#define pthread_barrier_t barrier_t +#endif /* PTHREAD_BARRIER_SERIAL_THREAd */ +#endif /* __MACH__ */ + +#define OK (0) +#define NOTOK (-1) + +#define CSFILE_FD_R 1 +#define CSFILE_FD_W 2 +#define CSFILE_STD 3 +#define CSFILE_SND_R 4 +#define CSFILE_SND_W 5 + +#define MAXINSNO (200) +#define PMAX (1998) +#define VARGMAX (1999) +#define NOT_AN_INSTRUMENT INT32_MAX + +#define ORTXT h.optext->t +#define INCOUNT ORTXT.inlist->count +#define OUTCOUNT ORTXT.outlist->count /* Not used */ +//#define INOCOUNT ORTXT.inoffs->count +//#define OUTOCOUNT ORTXT.outoffs->count +#define INOCOUNT ORTXT.inArgCount +#define OUTOCOUNT ORTXT.outArgCount +#define IS_ASIG_ARG(x) (csoundGetTypeForArg(x) == &CS_VAR_TYPE_A) +#define IS_STR_ARG(x) (csoundGetTypeForArg(x) == &CS_VAR_TYPE_S) + +#define CURTIME (((double)csound->icurTime)/((double)csound->esr)) +#define CURTIME_inc (((double)csound->ksmps)/((double)csound->esr)) + +#ifdef B64BIT +#define MAXLEN 0x40000000 +#define FMAXLEN ((MYFLT)(MAXLEN)) +#define PHMASK 0x3fffffff +#else +#define MAXLEN 0x1000000L +#define FMAXLEN ((MYFLT)(MAXLEN)) +#define PHMASK 0x0FFFFFFL +#endif + +#define MAX_STRING_CHANNEL_DATASIZE 16384 + +#define PFRAC(x) ((MYFLT)((x) & ftp->lomask) * ftp->lodiv) +#define MAXPOS 0x7FFFFFFFL + +#define BYTREVS(n) ((n>>8 & 0xFF) | (n<<8 & 0xFF00)) +#define BYTREVL(n) ((n>>24 & 0xFF) | (n>>8 & 0xFF00L) | \ + (n<<8 & 0xFF0000L) | (n<<24 & 0xFF000000L)) + +#define OCTRES 8192 +#define CPSOCTL(n) ((MYFLT)(1<<((int)(n)>>13))*csound->cpsocfrc[(int)(n)&8191]) + +#define LOBITS 10 +#define LOFACT 1024 + /* LOSCAL is 1/LOFACT as MYFLT */ +#define LOSCAL FL(0.0009765625) + +#define LOMASK 1023 + +#ifdef USE_DOUBLE + extern int64_t MYNAN; + //#define SSTRCOD (nan("0")) +#define SSTRCOD (double)NAN +#else + extern int32 MYNAN; +#define SSTRCOD (float)NAN + //#define SSTRCOD (nanf("0")) +#endif + //#define ISSTRCOD(X) isnan(X) + //#ifndef __MACH__ +extern int ISSTRCOD(MYFLT); + //#else +//#define ISSTRCOD(X) isnan(X) +//#endif + +#define SSTRSIZ 1024 +#define ALLCHNLS 0x7fff +#define DFLT_SR FL(44100.0) +#define DFLT_KR FL(4410.0) +#define DFLT_KSMPS 10 +#define DFLT_NCHNLS 1 +#define MAXCHNLS 256 + +#define MAXNAME (256) + +#define DFLT_DBFS (FL(32768.0)) + +#define MAXOCTS 8 +#define MAXCHAN 16 /* 16 MIDI channels; only one port for now */ + + /* A440 tuning factor */ +#define ONEPT (csound->A4/430.5389646099018460319362438314060262605) +#define LOG10D20 0.11512925 /* for db to ampfac */ +#define DV32768 FL(0.000030517578125) + +#ifndef PI +#define PI (3.141592653589793238462643383279502884197) +#endif /* pi */ +#define TWOPI (6.283185307179586476925286766559005768394) +#define HALFPI (1.570796326794896619231321691639751442099) +#define PI_F ((MYFLT) PI) +#define TWOPI_F ((MYFLT) TWOPI) +#define HALFPI_F ((MYFLT) HALFPI) +#define INF (2147483647.0) +#define ROOT2 (1.414213562373095048801688724209698078569) + +/* CONSTANTS FOR USE IN MSGLEVEL */ +#define CS_AMPLMSG 01 +#define CS_RNGEMSG 02 +#define CS_WARNMSG 04 + //#define CS_UNUSED1 08 +#define CS_NOMSG 0x10 + //#define CS_UNUSED2 0x20 +#define CS_RAWMSG 0x40 +#define CS_TIMEMSG 0x80 +#define CS_NOQQ 0x400 + +#define IGN(X) (void) X + +#define ARG_CONSTANT 0 +#define ARG_STRING 1 +#define ARG_PFIELD 2 +#define ARG_GLOBAL 3 +#define ARG_LOCAL 4 +#define ARG_LABEL 5 + +#define ASYNC_GLOBAL 1 +#define ASYNC_LOCAL 2 + +enum {FFT_LIB=0, PFFT_LIB, VDSP_LIB}; +enum {FFT_FWD=0, FFT_INV}; + +/* advance declaration for + API message queue struct +*/ +struct _message_queue; + +typedef struct CORFIL { + char *body; + unsigned int len; + unsigned int p; + } CORFIL; + + typedef struct { + int odebug; + int sfread, sfwrite, sfheader, filetyp; + int inbufsamps, outbufsamps; + int informat, outformat; + int sfsampsize; + int displays, graphsoff, postscript, msglevel; + int Beatmode, oMaxLag; + int usingcscore, Linein; + int RTevents, Midiin, FMidiin, RMidiin; + int ringbell, termifend; + int rewrt_hdr, heartbeat, gen01defer; + double cmdTempo; + float sr_override, kr_override; + int nchnls_override, nchnls_i_override; + char *infilename, *outfilename; + CORFIL *playscore; + char *Linename, *Midiname, *FMidiname; + char *Midioutname; /* jjk 09252000 - MIDI output device, -Q option */ + char *FMidioutname; + int midiKey, midiKeyCps, midiKeyOct, midiKeyPch; + int midiVelocity, midiVelocityAmp; + int noDefaultPaths; /* syy - Oct 25, 2006: for disabling relative paths + from files */ + int numThreads; + int syntaxCheckOnly; + int useCsdLineCounts; + int sampleAccurate; /* switch for score events sample accuracy */ + int realtime; /* realtime priority mode */ + MYFLT e0dbfs_override; + int daemon; + double quality; /* for ogg encoding */ + int ksmps_override; + int fft_lib; + int echo; + MYFLT limiter; + float sr_default, kr_default; + } OPARMS; + + typedef struct arglst { + int count; + char *arg[1]; + } ARGLST; + + typedef struct arg { + int type; + void* argPtr; + int index; + struct arg* next; + } ARG; +// typedef struct argoffs { +// int count; +// int indx[1]; +// } ARGOFFS; + + typedef struct oentry { + char *opname; + uint16 dsblksiz; + uint16 flags; + uint8_t thread; + char *outypes; + char *intypes; + int (*iopadr)(CSOUND *, void *p); + int (*kopadr)(CSOUND *, void *p); + int (*aopadr)(CSOUND *, void *p); + void *useropinfo; /* user opcode parameters */ + } OENTRY; + + /** + * Storage for parsed orchestra code, for each opcode in an INSTRTXT. + */ + typedef struct text { + uint16_t linenum; /* Line num in orch file (currently buggy!) */ + uint64_t locn; /* and location */ + OENTRY *oentry; + char *opcod; /* Pointer to opcode name in global pool */ + ARGLST *inlist; /* Input args (pointer to item in name list) */ + ARGLST *outlist; + ARG *inArgs; /* Input args (index into list of values) */ + unsigned int inArgCount; + ARG *outArgs; + unsigned int outArgCount; + char intype; /* Type of first input argument (g,k,a,w etc) */ + char pftype; /* Type of output argument (k,a etc) */ + } TEXT; + + + /** + * This struct is filled out by otran() at orch parse time. + * It is used as a template for instrument events. + */ + typedef struct instr { + struct op * nxtop; /* Linked list of instr opcodes */ + TEXT t; /* Text of instrument (same in nxtop) */ + int pmax, vmax, pextrab; /* Arg count, size of data for all + opcodes in instr */ + //int mdepends; /* Opcode type (i/k/a) */ + CS_VAR_POOL* varPool; + + // int optxtcount; + int16 muted; +// int32 localen; + int32 opdstot; /* Total size of opds structs in instr */ +// int32 *inslist; /* Only used in parsing (?) */ + MYFLT *psetdata; /* Used for pset opcode */ + struct insds * instance; /* Chain of allocated instances of + this instrument */ + struct insds * lst_instance; /* last allocated instance */ + struct insds * act_instance; /* Chain of free (inactive) instances */ + /* (pointer to next one is INSDS.nxtact) */ + struct instr * nxtinstxt; /* Next instrument in orch (num order) */ + int active; /* To count activations for control */ + int pending_release; /* To count instruments in release phase */ + int maxalloc; + MYFLT cpuload; /* % load this instrumemnt makes */ + struct opcodinfo *opcode_info; /* UDO info (when instrs are UDOs) */ + char *insname; /* instrument name */ + int instcnt; /* Count number of instances ever */ + int isNew; /* is this a new definition */ + int nocheckpcnt; /* Control checks on pcnt */ + } INSTRTXT; + + typedef struct namedInstr { + int32 instno; + char *name; + INSTRTXT *ip; + struct namedInstr *next; + } INSTRNAME; + + /** + * A chain of TEXT structs. Note that this is identical with the first two + * members of struct INSTRTEXT, and is so typecast at various points in code. + */ + typedef struct op { + struct op *nxtop; + TEXT t; + } OPTXT; + + typedef struct fdch { + struct fdch *nxtchp; + /** handle returned by csound->FileOpen() */ + void *fd; + } FDCH; + + typedef struct auxch { + struct auxch *nxtchp; + size_t size; + void *auxp, *endp; + } AUXCH; + + /** this callback is used to notify the + availability of new storage in AUXCH *. + It can be used to swap the old storage + for the new one and return it for deallocation. + */ + typedef AUXCH* (*aux_cb)(CSOUND *, void *, AUXCH *); + + /** + * AuxAllocAsync data + */ + typedef struct { + CSOUND *csound; + size_t nbytes; + AUXCH *auxchp; + void *userData; + aux_cb notify; + } AUXASYNC; + + typedef struct { + int dimensions; + int* sizes; /* size of each dimensions */ + int arrayMemberSize; + CS_TYPE* arrayType; + MYFLT* data; + size_t allocated; +// AUXCH aux; + } ARRAYDAT; + + typedef struct { + int size; /* 0...size-1 */ + MYFLT *data; + AUXCH aux; + } TABDAT; + + typedef struct { + char *data; + int size; + } STRINGDAT; + + typedef struct monblk { + int16 pch; + struct monblk *prv; + } MONPCH; + + typedef struct { + int notnum[4]; + } DPEXCL; + + typedef struct { + DPEXCL dpexcl[8]; + /** for keys 25-99 */ + int exclset[75]; + } DPARM; + + typedef struct dklst { + struct dklst *nxtlst; + int32 pgmno; + /** cnt + keynos */ + MYFLT keylst[1]; + } DKLST; + + typedef struct mchnblk { + /** most recently received program change */ + int16 pgmno; + /** instrument number assigned to this channel */ + int16 insno; + int16 RegParNo; + int16 mono; + MONPCH *monobas; + MONPCH *monocur; + /** list of active notes (NULL: not active) */ + struct insds *kinsptr[128]; + /** polyphonic pressure indexed by note number */ + MYFLT polyaft[128]; + /** ... with GS vib_rate, stored in c128-c135 */ + MYFLT ctl_val[136]; + /** program change to instr number (<=0: ignore) */ + int16 pgm2ins[128]; + /** channel pressure (0-127) */ + MYFLT aftouch; + /** pitch bend (-1 to 1) */ + MYFLT pchbend; + /** pitch bend sensitivity in semitones */ + MYFLT pbensens; + /** number of held (sustaining) notes */ + int16 ksuscnt; + /** current state of sustain pedal (0: off) */ + int16 sustaining; + int dpmsb; + int dplsb; + int datenabl; + /** chain of dpgm keylists */ + DKLST *klists; + /** drumset params */ + DPARM *dparms; + } MCHNBLK; + + /** + * This struct holds the data for one score event. + */ + typedef struct event { + /** String argument(s) (NULL if none) */ + int scnt; + char *strarg; + /* instance pointer */ + void *pinstance; /* used in nstance opcode */ + /** Event type */ + char opcod; + /** Number of p-fields */ + int16 pcnt; + /** Event start time */ + MYFLT p2orig; + /** Length */ + MYFLT p3orig; + /** All p-fields for this event (SSTRCOD: string argument) */ + MYFLT p[PMAX + 1]; + union { /* To ensure size is same as earlier */ + MYFLT *extra; + MYFLT p[2]; + } c; + } EVTBLK; + /** + * This struct holds the info for a concrete instrument event + * instance in performance. + */ + typedef struct insds { + /* Chain of init-time opcodes */ + struct opds * nxti; + /* Chain of performance-time opcodes */ + struct opds * nxtp; + /* Next allocated instance */ + struct insds * nxtinstance; + /* Previous allocated instance */ + struct insds * prvinstance; + /* Next in list of active instruments */ + struct insds * nxtact; + /* Previous in list of active instruments */ + struct insds * prvact; + /* Next instrument to terminate */ + struct insds * nxtoff; + /* Chain of files used by opcodes in this instr */ + FDCH *fdchp; + /* Extra memory used by opcodes in this instr */ + AUXCH *auxchp; + /* Extra release time requested with xtratim opcode */ + int xtratim; + /* MIDI note info block if event started from MIDI */ + MCHNBLK *m_chnbp; + /* ptr to next overlapping MIDI voice */ + struct insds * nxtolap; + /* Instrument number */ + int16 insno; + /* Instrument def address */ + INSTRTXT *instr; + /* non-zero for sustaining MIDI note */ + int16 m_sust; + /* MIDI pitch, for simple access */ + unsigned char m_pitch; + /* ...ditto velocity */ + unsigned char m_veloc; + /* Flag to indicate we are releasing, test with release opcode */ + char relesing; + /* Set if instr instance is active (perfing) */ + char actflg; + /* Time to turn off event, in score beats */ + double offbet; + /* Time to turn off event, in seconds (negative on indef/tie) */ + double offtim; + /* Python namespace for just this instance. */ + void *pylocal; + /* pointer to Csound engine and API for externals */ + CSOUND *csound; + uint64_t kcounter; + unsigned int ksmps; /* Instrument copy of ksmps */ + MYFLT ekr; /* and of rates */ + MYFLT onedksmps, onedkr, kicvt; + struct opds *pds; /* Used for jumping */ + MYFLT scratchpad[4]; /* Persistent data */ + + /* user defined opcode I/O buffers */ + void *opcod_iobufs; + void *opcod_deact, *subins_deact; + /* opcodes to be run at note deactivation */ + void *nxtd; + uint32_t ksmps_offset; /* ksmps offset for sample accuracy */ + uint32_t no_end; /* samps left at the end for sample accuracy + (calculated) */ + uint32_t ksmps_no_end; /* samps left at the end for sample accuracy + (used by opcodes) */ + MYFLT *spin; /* offset into csound->spin */ + MYFLT *spout; /* offset into csound->spout, or local spout */ + int init_done; + int tieflag; + int reinitflag; + MYFLT retval; + MYFLT *lclbas; /* base for variable memory pool */ + char *strarg; /* string argument */ + /* Copy of required p-field values for quick access */ + CS_VAR_MEM p0; + CS_VAR_MEM p1; + CS_VAR_MEM p2; + CS_VAR_MEM p3; + } INSDS; + +#define CS_KSMPS (p->h.insdshead->ksmps) +#define CS_KCNT (p->h.insdshead->kcounter) +#define CS_EKR (p->h.insdshead->ekr) +#define CS_ONEDKSMPS (p->h.insdshead->onedksmps) +#define CS_ONEDKR (p->h.insdshead->onedkr) +#define CS_KICVT (p->h.insdshead->kicvt) +#define CS_ESR (csound->esr) +#define CS_PDS (p->h.insdshead->pds) +#define CS_SPIN (p->h.insdshead->spin) +#define CS_SPOUT (p->h.insdshead->spout) + typedef int (*SUBR)(CSOUND *, void *); + + /** + * This struct holds the info for one opcode in a concrete + * instrument instance in performance. + */ + typedef struct opds { + /** Next opcode in init-time chain */ + struct opds * nxti; + /** Next opcode in perf-time chain */ + struct opds * nxtp; + /** Initialization (i-time) function pointer */ + SUBR iopadr; + /** Perf-time (k- or a-rate) function pointer */ + SUBR opadr; + /** Orch file template part for this opcode */ + OPTXT *optext; + /** Owner instrument instance data structure */ + INSDS *insdshead; + } OPDS; + + typedef struct lblblk { + OPDS h; + OPDS *prvi; + OPDS *prvp; + } LBLBLK; + + typedef struct { + MYFLT *begp, *curp, *endp, feedback[6]; + int32 scount; + } OCTDAT; + + typedef struct { + int32 npts, nocts, nsamps; + MYFLT lofrq, hifrq, looct, srate; + OCTDAT octdata[MAXOCTS]; + AUXCH auxch; + } DOWNDAT; + + typedef struct { + uint32_t ktimstamp, ktimprd; + int32 npts, nfreqs, dbout; + DOWNDAT *downsrcp; + AUXCH auxch; + } SPECDAT; + + + + typedef struct { + MYFLT gen01; + MYFLT ifilno; + MYFLT iskptim; + MYFLT iformat; + MYFLT channel; + MYFLT sample_rate; + char strarg[SSTRSIZ]; + } GEN01ARGS; + + typedef struct { + /** table length, not including the guard point */ + uint32_t flen; + /** length mask ( = flen - 1) for power of two table size, 0 otherwise */ + int32 lenmask; + /** log2(MAXLEN / flen) for power of two table size, 0 otherwise */ + int32 lobits; + /** 2^lobits - 1 */ + int32 lomask; + /** 1 / 2^lobits */ + MYFLT lodiv; + /** LOFACT * (table_sr / orch_sr), cpscvt = cvtbas / base_freq */ + MYFLT cvtbas, cpscvt; + /** sustain loop mode (0: none, 1: forward, 2: forward and backward) */ + int16 loopmode1; + /** release loop mode (0: none, 1: forward, 2: forward and backward) */ + int16 loopmode2; + /** sustain loop start and end in sample frames */ + int32 begin1, end1; + /** release loop start and end in sample frames */ + int32 begin2, end2; + /** sound file length in sample frames (flenfrms = soundend - 1) */ + int32 soundend, flenfrms; + /** number of channels */ + int32 nchanls; + /** table number */ + int32 fno; + /** args */ + MYFLT args[PMAX - 4]; + /** arg count */ + int argcnt; + /** GEN01 parameters */ + GEN01ARGS gen01args; + /** table data (flen + 1 MYFLT values) */ + MYFLT *ftable; + } FUNC; + + typedef struct { + CSOUND *csound; + int32 flen; + int fno, guardreq; + EVTBLK e; + } FGDATA; + + typedef struct { + char *name; + int (*fn)(FGDATA *, FUNC *); + } NGFENS; + + typedef int (*GEN)(FGDATA *, FUNC *); + + typedef struct MEMFIL { + char filename[256]; /* Made larger RWD */ + char *beginp; + char *endp; + int32 length; + struct MEMFIL *next; + } MEMFIL; + + typedef struct { + int16 type; + int16 chan; + int16 dat1; + int16 dat2; + } MEVENT; + + typedef struct SNDMEMFILE_ { + /** file ID (short name) */ + char *name; + struct SNDMEMFILE_ *nxt; + /** full path filename */ + char *fullName; + /** file length in sample frames */ + size_t nFrames; + /** sample rate in Hz */ + double sampleRate; + /** number of channels */ + int nChannels; + /** AE_SHORT, AE_FLOAT, etc. */ + int sampleFormat; + /** TYP_WAV, TYP_AIFF, etc. */ + int fileType; + /** + * loop mode: + * 0: no loop information + * 1: off + * 2: forward + * 3: backward + * 4: bidirectional + */ + int loopMode; + /** playback start offset frames */ + double startOffs; + /** loop start (sample frames) */ + double loopStart; + /** loop end (sample frames) */ + double loopEnd; + /** base frequency (in Hz) */ + double baseFreq; + /** amplitude scale factor */ + double scaleFac; + /** interleaved sample data */ + float data[1]; + } SNDMEMFILE; + + typedef struct pvx_memfile_ { + char *filename; + struct pvx_memfile_ *nxt; + float *data; + uint32 nframes; + int format; + int fftsize; + int overlap; + int winsize; + int wintype; + int chans; + MYFLT srate; + } PVOCEX_MEMFILE; + +#ifdef __BUILDING_LIBCSOUND + +#define INSTR 1 +#define ENDIN 2 +#define OPCODE 3 +#define ENDOP 4 +#define LABEL 5 +#define SETBEG 6 +#define PSET 6 +#define USEROPCODE 7 +#define SETEND 8 + +#define TOKMAX 50L /* Should be 50 but bust */ + +/* max number of input/output args for user defined opcodes */ +#define OPCODENUMOUTS_LOW 16 +#define OPCODENUMOUTS_HIGH 64 +#define OPCODENUMOUTS_MAX 256 + +#define MBUFSIZ (4096) +#define MIDIINBUFMAX (1024) +#define MIDIINBUFMSK (MIDIINBUFMAX-1) + +#define MIDIMAXPORTS (64) + + typedef union { + uint32 dwData; + unsigned char bData[4]; + } MIDIMESSAGE; + + /* MIDI globals */ + + typedef struct midiglobals { + MEVENT *Midevtblk; + int sexp; + int MIDIoutDONE; + int MIDIINbufIndex; + MIDIMESSAGE MIDIINbuffer2[MIDIINBUFMAX]; + int (*MidiInOpenCallback)(CSOUND *, void **, const char *); + int (*MidiReadCallback)(CSOUND *, void *, unsigned char *, int); + int (*MidiInCloseCallback)(CSOUND *, void *); + int (*MidiOutOpenCallback)(CSOUND *, void **, const char *); + int (*MidiWriteCallback)(CSOUND *, void *, const unsigned char *, int); + int (*MidiOutCloseCallback)(CSOUND *, void *); + const char *(*MidiErrorStringCallback)(int); + void *midiInUserData; + void *midiOutUserData; + void *midiFileData; + void *midiOutFileData; + int rawControllerMode; + char muteTrackList[256]; + unsigned char mbuf[MBUFSIZ]; + unsigned char *bufp, *endatp; + int16 datreq, datcnt; + } MGLOBAL; + + typedef struct eventnode { + struct eventnode *nxt; + uint32 start_kcnt; + EVTBLK evt; + } EVTNODE; + + typedef struct { + OPDS h; + MYFLT *ktempo, *istartempo; + MYFLT prvtempo; + } TEMPO; + + /* typedef struct token { */ + /* char *str; */ + /* int16 prec; */ + /* } TOKEN; */ + + typedef struct names { + char *mac; + struct names *next; + } NAMES; + + typedef struct threadInfo { + struct threadInfo *next; + void * threadId; + } THREADINFO; + +#include "sort.h" +#include "text.h" +#include "prototyp.h" +#include "cwindow.h" +#include "envvar.h" +#include "remote.h" + +#define CS_STATE_PRE (1) +#define CS_STATE_COMP (2) +#define CS_STATE_UTIL (4) +#define CS_STATE_CLN (8) +#define CS_STATE_JMP (16) + +/* These are used to set/clear bits in csound->tempStatus. + If the bit is set, it indicates that the given file is + a temporary. */ + extern const uint32_t csOrcMask; + extern const uint32_t csScoInMask; + extern const uint32_t csScoSortMask; + extern const uint32_t csMidiScoMask; + extern const uint32_t csPlayScoMask; + +/* kperf function protoypes. Used by the debugger to switch between debug + * and nodebug kperf functions */ + int kperf_nodebug(CSOUND *csound); + int kperf_debug(CSOUND *csound); + +#endif /* __BUILDING_LIBCSOUND */ + +#define MARGS (3) +#define MAX_INCLUDE_DEPTH 100 +struct MACRO; + +typedef struct MACRON { + int n; + unsigned int line; + struct MACRO *s; + char *path; +} MACRON; + +typedef struct MACRO { /* To store active macros */ + char *name; /* Use is by name */ + int acnt; /* Count of arguments */ + char *body; /* The text of the macro */ + struct MACRO *next; /* Chain of active macros */ + int margs; /* amount of space for args */ + char *arg[MARGS]; /* With these arguments */ +} MACRO; + +typedef struct in_stack_s { /* Stack of active inputs */ + int16 is_marked_repeat; /* 1 if this input created by 'n' stmnt */ + int16 args; /* Argument count for macro */ + //CORFIL *cf; /* In core file */ + //void *fd; /* for closing stream */ + MACRO *mac; + int line; + int32 oposit; +} IN_STACK; + +typedef struct marked_sections { + char *name; + int32 posit; + int line; +} MARKED_SECTIONS; + +typedef struct namelst { + char *name; + struct namelst *next; +} NAMELST; + +typedef struct NAME__ { + char *namep; + struct NAME__ *nxt; + int type, count; +} NAME; + + /* Holds UDO information, when an instrument is + defined as a UDO + */ + typedef struct opcodinfo { + int32 instno; + char *name, *intypes, *outtypes; + int16 inchns, outchns; + CS_VAR_POOL* out_arg_pool; + CS_VAR_POOL* in_arg_pool; + INSTRTXT *ip; + struct opcodinfo *prv; + } OPCODINFO; + + /** + * This struct will hold the current engine state after compilation + */ + typedef struct engine_state { + CS_VAR_POOL *varPool; /* global variable pool */ + CS_HASH_TABLE *constantsPool; + CS_HASH_TABLE *stringPool; + int maxopcno; + INSTRTXT **instrtxtp; /* instrument list */ + INSTRTXT instxtanchor; + CS_HASH_TABLE *instrumentNames; /* instrument names */ + int maxinsno; + } ENGINE_STATE; + + + /** + * Nen FFT interface + */ + typedef struct _FFT_SETUP{ + int N, M; + void *setup; + MYFLT *buffer; + int lib; + int d; + int p2; + } CSOUND_FFT_SETUP; + + + /** + * plugin module info + */ + typedef struct { + char module[12]; + char type[12]; + } MODULE_INFO; + + +#define MAX_ALLOC_QUEUE 1024 + +typedef struct _alloc_data_ { + int type; + int insno; + EVTBLK blk; + MCHNBLK *chn; + MEVENT mep; + INSDS *ip; + OPDS *ids; +} ALLOC_DATA; + +#define MAX_MESSAGE_STR 1024 +typedef struct _message_queue_t_ { + int attr; + char str[MAX_MESSAGE_STR]; +} message_string_queue_t; + + +#include "find_opcode.h" + + /** + * Contains all function pointers, data, and data pointers required + * to run one instance of Csound. + * + * \b PUBLIC functions in CSOUND_ + * These are used by plugins to access the + * Csound library functionality without the requirement + * of compile-time linkage to the csound library + * New functions only need to be added here if + * they are required by plugins. + */ + struct CSOUND_ { + + /** @name Attributes */ + /**@{ */ + MYFLT (*GetSr)(CSOUND *); + MYFLT (*GetKr)(CSOUND *); + uint32_t (*GetKsmps)(CSOUND *); + /** Get number of output channels */ + uint32_t (*GetNchnls)(CSOUND *); + /** Get number of input channels */ + uint32_t (*GetNchnls_i)(CSOUND *); + MYFLT (*Get0dBFS) (CSOUND *); + /** Get number of control blocks elapsed */ + uint64_t (*GetKcounter)(CSOUND *); + int64_t (*GetCurrentTimeSamples)(CSOUND *); + long (*GetInputBufferSize)(CSOUND *); + long (*GetOutputBufferSize)(CSOUND *); + MYFLT *(*GetInputBuffer)(CSOUND *); + MYFLT *(*GetOutputBuffer)(CSOUND *); + /** Set internal debug mode */ + void (*SetDebug)(CSOUND *, int d); + int (*GetDebug)(CSOUND *); + int (*GetSizeOfMYFLT)(void); + void (*GetOParms)(CSOUND *, OPARMS *); + /** Get environment variable */ + const char *(*GetEnv)(CSOUND *, const char *name); + /**@}*/ + /** @name Message printout */ + /**@{ */ + CS_PRINTF2 void (*Message)(CSOUND *, const char *fmt, ...); + CS_PRINTF3 void (*MessageS)(CSOUND *, int attr, const char *fmt, ...); + void (*MessageV)(CSOUND *, int attr, const char *format, va_list args); + int (*GetMessageLevel)(CSOUND *); + void (*SetMessageLevel)(CSOUND *, int messageLevel); + void (*SetMessageCallback)(CSOUND *, + void (*csoundMessageCallback)(CSOUND *, + int attr, const char *format, + va_list valist)); + /**@}*/ + /** @name Event and MIDI functionality for opcodes */ + /**@{ */ + int (*SetReleaseLength)(void *p, int n); + MYFLT (*SetReleaseLengthSeconds)(void *p, MYFLT n); + int (*GetMidiChannelNumber)(void *p); + MCHNBLK *(*GetMidiChannel)(void *p); + int (*GetMidiNoteNumber)(void *p); + int (*GetMidiVelocity)(void *p); + int (*GetReleaseFlag)(void *p); + double (*GetOffTime)(void *p); + MYFLT *(*GetPFields)(void *p); + int (*GetInstrumentNumber)(void *p); + int (*GetZakBounds)(CSOUND *, MYFLT **); + int (*GetTieFlag)(CSOUND *); + int (*GetReinitFlag)(CSOUND *); + /** Current maximum number of strings, accessible through the strset + and strget opcodes */ + int (*GetStrsmax)(CSOUND *); + char *(*GetStrsets)(CSOUND *, long); + /* Fast power of two function from a precomputed table */ + MYFLT (*Pow2)(CSOUND *, MYFLT a); + /* Fast power function for positive integers */ + MYFLT (*intpow)(MYFLT, int32); + /* Returns a string name for the file type */ + char *(*type2string)(int type); + /**@}*/ + /** @name Arguments to opcodes */ + /**@{ */ + CS_TYPE *(*GetTypeForArg)(void *p); + int (*GetInputArgCnt)(void *p); + char *(*GetInputArgName)(void *p, int n); + int (*GetOutputArgCnt)(void *p); + char *(*GetOutputArgName)(void *p, int n); + char *(*GetString)(CSOUND *, MYFLT); + int32 (*strarg2insno)(CSOUND *, void *p, int is_string); + char *(*strarg2name)(CSOUND *, char *, void *, const char *, int); + + /**@}*/ + /** @name Memory allocation */ + /**@{ */ + void (*AuxAlloc)(CSOUND *, size_t nbytes, AUXCH *auxchp); + void *(*Malloc)(CSOUND *, size_t nbytes); + void *(*Calloc)(CSOUND *, size_t nbytes); + void *(*ReAlloc)(CSOUND *, void *oldp, size_t nbytes); + char *(*Strdup)(CSOUND *, char*); + void (*Free)(CSOUND *, void *ptr); + + /**@}*/ + /** @name Function tables */ + /**@{ */ + int (*hfgens)(CSOUND *, FUNC **, const EVTBLK *, int); + int (*FTAlloc)(CSOUND *, int tableNum, int len); + int (*FTDelete)(CSOUND *, int tableNum); + /** Find tables with power of two size. If table exists but is + not a power of 2, NULL is returned. */ + FUNC *(*FTFind)(CSOUND *, MYFLT *argp); + /** Find any table, except deferred load tables. */ + FUNC *(*FTFindP)(CSOUND *, MYFLT *argp); + /** Find any table. */ + FUNC *(*FTnp2Find)(CSOUND *, MYFLT *argp); + int (*GetTable)(CSOUND *, MYFLT **tablePtr, int tableNum); + int (*TableLength)(CSOUND *, int table); + MYFLT (*TableGet)(CSOUND *, int table, int index); + void (*TableSet)(CSOUND *, int table, int index, MYFLT value); + void *(*GetNamedGens)(CSOUND *); + + /**@}*/ + /** @name Global and config variable manipulation */ + /**@{ */ + int (*CreateGlobalVariable)(CSOUND *, const char *name, size_t nbytes); + void *(*QueryGlobalVariable)(CSOUND *, const char *name); + void *(*QueryGlobalVariableNoCheck)(CSOUND *, const char *name); + int (*DestroyGlobalVariable)(CSOUND *, const char *name); + int (*CreateConfigurationVariable)(CSOUND *, const char *name, + void *p, int type, int flags, + void *min, void *max, + const char *shortDesc, + const char *longDesc); + int (*SetConfigurationVariable)(CSOUND *, const char *name, void *value); + int (*ParseConfigurationVariable)(CSOUND *, + const char *name, const char *value); + csCfgVariable_t *(*QueryConfigurationVariable)(CSOUND *, const char *name); + csCfgVariable_t **(*ListConfigurationVariables)(CSOUND *); + int (*DeleteConfigurationVariable)(CSOUND *, const char *name); + const char *(*CfgErrorCodeToString)(int errcode); + + /**@}*/ + /** @name FFT support */ + /**@{ */ + MYFLT (*GetInverseComplexFFTScale)(CSOUND *, int FFTsize); + MYFLT (*GetInverseRealFFTScale)(CSOUND *, int FFTsize); + void (*ComplexFFT)(CSOUND *, MYFLT *buf, int FFTsize); + void (*InverseComplexFFT)(CSOUND *, MYFLT *buf, int FFTsize); + void (*RealFFT)(CSOUND *, MYFLT *buf, int FFTsize); + void (*InverseRealFFT)(CSOUND *, MYFLT *buf, int FFTsize); + void (*RealFFTMult)(CSOUND *, MYFLT *outbuf, MYFLT *buf1, MYFLT *buf2, + int FFTsize, MYFLT scaleFac); + void (*RealFFTnp2)(CSOUND *, MYFLT *buf, int FFTsize); + void (*InverseRealFFTnp2)(CSOUND *, MYFLT *buf, int FFTsize); + + /**@}*/ + /** @name PVOC-EX system */ + /**@{ */ + int (*PVOC_CreateFile)(CSOUND *, const char *, + uint32, uint32, uint32, + uint32, int32, int, int, + float, float *, uint32); + int (*PVOC_OpenFile)(CSOUND *, const char *, void *, void *); + int (*PVOC_CloseFile)(CSOUND *, int); + int (*PVOC_PutFrames)(CSOUND *, int, const float *, int32); + int (*PVOC_GetFrames)(CSOUND *, int, float *, uint32); + int (*PVOC_FrameCount)(CSOUND *, int); + int (*PVOC_fseek)(CSOUND *, int, int); + const char *(*PVOC_ErrorString)(CSOUND *); + int (*PVOCEX_LoadFile)(CSOUND *, const char *, PVOCEX_MEMFILE *); + + /**@}*/ + /** @name Error messages */ + /**@{ */ + CS_NORETURN CS_PRINTF2 void (*Die)(CSOUND *, const char *msg, ...); + CS_PRINTF2 int (*InitError)(CSOUND *, const char *msg, ...); + CS_PRINTF3 int (*PerfError)(CSOUND *, OPDS *h, const char *msg, ...); + CS_PRINTF2 void (*Warning)(CSOUND *, const char *msg, ...); + CS_PRINTF2 void (*DebugMsg)(CSOUND *, const char *msg, ...); + CS_NORETURN void (*LongJmp)(CSOUND *, int); + CS_PRINTF2 void (*ErrorMsg)(CSOUND *, const char *fmt, ...); + void (*ErrMsgV)(CSOUND *, const char *hdr, const char *fmt, va_list); + + /**@}*/ + /** @name Random numbers */ + /**@{ */ + uint32_t (*GetRandomSeedFromTime)(void); + void (*SeedRandMT)(CsoundRandMTState *p, + const uint32_t *initKey, uint32_t keyLength); + uint32_t (*RandMT)(CsoundRandMTState *p); + int (*Rand31)(int *seedVal); + int (*GetRandSeed)(CSOUND *, int which); + + /**@}*/ + /** @name Threads and locks */ + /**@{ */ + void *(*CreateThread)(uintptr_t (*threadRoutine)(void *), void *userdata); + uintptr_t (*JoinThread)(void *thread); + void *(*CreateThreadLock)(void); + void (*DestroyThreadLock)(void *lock); + int (*WaitThreadLock)(void *lock, size_t milliseconds); + void (*NotifyThreadLock)(void *lock); + void (*WaitThreadLockNoTimeout)(void *lock); + void *(*Create_Mutex)(int isRecursive); + int (*LockMutexNoWait)(void *mutex_); + void (*LockMutex)(void *mutex_); + void (*UnlockMutex)(void *mutex_); + void (*DestroyMutex)(void *mutex_); + void *(*CreateBarrier)(unsigned int max); + int (*DestroyBarrier)(void *); + int (*WaitBarrier)(void *); + void *(*GetCurrentThreadID)(void); + void (*Sleep)(size_t milliseconds); + void (*InitTimerStruct)(RTCLOCK *); + double (*GetRealTime)(RTCLOCK *); + double (*GetCPUTime)(RTCLOCK *); + + /**@}*/ + /** @name Circular lock-free buffer */ + /**@{ */ + void *(*CreateCircularBuffer)(CSOUND *, int, int); + int (*ReadCircularBuffer)(CSOUND *, void *, void *, int); + int (*WriteCircularBuffer)(CSOUND *, void *, const void *, int); + void (*FlushCircularBuffer)(CSOUND *, void *); + void (*DestroyCircularBuffer)(CSOUND *, void *); + + /**@}*/ + /** @name File access */ + /**@{ */ + char *(*FindInputFile)(CSOUND *, const char *filename, const char *envList); + char *(*FindOutputFile)(CSOUND *, + const char *filename, const char *envList); + void *(*SAsndgetset)(CSOUND *, + char *, void *, MYFLT *, MYFLT *, MYFLT *, int); + void *(*sndgetset)(CSOUND *, void *); + int (*getsndin)(CSOUND *, void *, MYFLT *, int, void *); + void (*rewriteheader)(void *ofd); + SNDMEMFILE *(*LoadSoundFile)(CSOUND *, const char *, void *); + void (*FDRecord)(CSOUND *, FDCH *fdchp); + void (*FDClose)(CSOUND *, FDCH *fdchp); + void *(*CreateFileHandle)(CSOUND *, void *, int, const char *); + char *(*GetFileName)(void *); + int (*FileClose)(CSOUND *, void *); + void *(*FileOpen2)(CSOUND *, void *, int, const char *, void *, + const char *, int, int); + int (*type2csfiletype)(int type, int encoding); + void (*NotifyFileOpened)(CSOUND*, const char*, int, int, int); + int (*sftype2csfiletype)(int type); + MEMFIL *(*ldmemfile2withCB)(CSOUND *, const char *, int, + int (*callback)(CSOUND *, MEMFIL *)); + void *(*FileOpenAsync)(CSOUND *, void *, int, const char *, void *, + const char *, int, int, int); + unsigned int (*ReadAsync)(CSOUND *, void *, MYFLT *, int); + unsigned int (*WriteAsync)(CSOUND *, void *, MYFLT *, int); + int (*FSeekAsync)(CSOUND *, void *, int, int); + char *(*getstrformat)(int format); + int (*sfsampsize)(int format); + + /**@}*/ + /** @name RT audio IO and callbacks */ + /**@{ */ + void (*SetPlayopenCallback)(CSOUND *, + int (*playopen__)(CSOUND *, const csRtAudioParams *parm)); + void (*SetRtplayCallback)(CSOUND *, + void (*rtplay__)(CSOUND *, const MYFLT *outBuf, int nbytes)); + void (*SetRecopenCallback)(CSOUND *, + int (*recopen__)(CSOUND *, const csRtAudioParams *parm)); + void (*SetRtrecordCallback)(CSOUND *, + int (*rtrecord__)(CSOUND *, MYFLT *inBuf, int nbytes)); + void (*SetRtcloseCallback)(CSOUND *, void (*rtclose__)(CSOUND *)); + void (*SetAudioDeviceListCallback)(CSOUND *csound, + int (*audiodevlist__)(CSOUND *, CS_AUDIODEVICE *list, int isOutput)); + void **(*GetRtRecordUserData)(CSOUND *); + void **(*GetRtPlayUserData)(CSOUND *); + int (*GetDitherMode)(CSOUND *); + /**@}*/ + /** @name RT MIDI and callbacks */ + /**@{ */ + void (*SetExternalMidiInOpenCallback)(CSOUND *, + int (*func)(CSOUND *, void **, const char *)); + void (*SetExternalMidiReadCallback)(CSOUND *, + int (*func)(CSOUND *, void *, unsigned char *, int)); + void (*SetExternalMidiInCloseCallback)(CSOUND *, + int (*func)(CSOUND *, void *)); + void (*SetExternalMidiOutOpenCallback)(CSOUND *, + int (*func)(CSOUND *, void **, const char *)); + void (*SetExternalMidiWriteCallback)(CSOUND *, + int (*func)(CSOUND *, void *, const unsigned char *, int)); + void (*SetExternalMidiOutCloseCallback)(CSOUND *, + int (*func)(CSOUND *, void *)); + void (*SetExternalMidiErrorStringCallback)(CSOUND *, + const char *(*func)(int)); + void (*SetMIDIDeviceListCallback)(CSOUND *csound, + int (*audiodevlist__)(CSOUND *, CS_MIDIDEVICE *list, int isOutput)); + void (*module_list_add)(CSOUND *, char *, char *); + /**@}*/ + /** @name Displays & graphs */ + /**@{ */ + void (*dispset)(CSOUND *, WINDAT *, MYFLT *, int32, char *, int, char *); + void (*display)(CSOUND *, WINDAT *); + int (*dispexit)(CSOUND *); + void (*dispinit)(CSOUND *); + int (*SetIsGraphable)(CSOUND *, int isGraphable); + void (*SetMakeGraphCallback)(CSOUND *, + void (*makeGraphCallback)(CSOUND *, WINDAT *p, + const char *name)); + void (*SetDrawGraphCallback)(CSOUND *, + void (*drawGraphCallback)(CSOUND *, WINDAT *p)); + void (*SetKillGraphCallback)(CSOUND *, + void (*killGraphCallback)(CSOUND *, WINDAT *p)); + void (*SetExitGraphCallback)(CSOUND *, int (*exitGraphCallback)(CSOUND *)); + /**@}*/ + /** @name Generic callbacks */ + /**@{ */ + void (*SetYieldCallback)(CSOUND *, int (*yieldCallback)(CSOUND *)); + int (*Set_KeyCallback)(CSOUND *, int (*func)(void *, void *, unsigned int), + void *userData, unsigned int typeMask); + void (*Remove_KeyCallback)(CSOUND *, + int (*func)(void *, void *, unsigned int)); + int (*RegisterSenseEventCallback)(CSOUND *, void (*func)(CSOUND *, void *), + void *userData); + int (*RegisterDeinitCallback)(CSOUND *, void *p, + int (*func)(CSOUND *, void *)); + int (*RegisterResetCallback)(CSOUND *, void *userData, + int (*func)(CSOUND *, void *)); + void (*SetInternalYieldCallback)(CSOUND *, + int (*yieldCallback)(CSOUND *)); + /**@}*/ + /** @name Opcodes and instruments */ + /**@{ */ + int (*AppendOpcode)(CSOUND *, const char *opname, int dsblksiz, int flags, + int thread, const char *outypes, const char *intypes, + int (*iopadr)(CSOUND *, void *), + int (*kopadr)(CSOUND *, void *), + int (*aopadr)(CSOUND *, void *)); + int (*AppendOpcodes)(CSOUND *, const OENTRY *opcodeList, int n); + char *(*GetOpcodeName)(void *p); + INSTRTXT **(*GetInstrumentList)(CSOUND *); + /**@}*/ + /** @name Events and performance */ + /**@{ */ + int (*CheckEvents)(CSOUND *); + int (*insert_score_event)(CSOUND *, EVTBLK *, double); + int (*insert_score_event_at_sample)(CSOUND *, EVTBLK *, int64_t); + int (*PerformKsmps)(CSOUND *); + /**@}*/ + /** @name Utilities */ + /**@{ */ + int (*AddUtility)(CSOUND *, const char *name, + int (*UtilFunc)(CSOUND *, int, char **)); + int (*RunUtility)(CSOUND *, const char *name, int argc, char **argv); + char **(*ListUtilities)(CSOUND *); + int (*SetUtilityDescription)(CSOUND *, const char *utilName, + const char *utilDesc); + const char *(*GetUtilityDescription)(CSOUND *, const char *utilName); + void (*SetUtilSr)(CSOUND *, MYFLT); + void (*SetUtilNchnls)(CSOUND *, int); + /**@}*/ + /** @name Miscellaneous */ + /**@{ */ + long (*RunCommand)(const char * const *argv, int noWait); + int (*OpenLibrary)(void **library, const char *libraryPath); + int (*CloseLibrary)(void *library); + void *(*GetLibrarySymbol)(void *library, const char *procedureName); +#if defined (__CUDACC__) || defined (__MACH__) + char *(*LocalizeString)(const char *); +#else + char *(*LocalizeString)(const char *) __attribute__ ((format_arg (1))); +#endif + char *(*strtok_r)(char*, char*, char**); + double (*strtod)(char*, char**); + int (*sprintf)(char *str, const char *format, ...); + int (*sscanf)(char *str, const char *format, ...); + MYFLT (*system_sr)(CSOUND *, MYFLT ); + /**@}*/ + /** @name Score Event s*/ + /**@{ */ + MYFLT (*GetScoreOffsetSeconds)(CSOUND *); + void (*SetScoreOffsetSeconds)(CSOUND *, MYFLT offset); + void (*RewindScore)(CSOUND *); + void (*InputMessage)(CSOUND *, const char *message__); + int (*ISSTRCOD)(MYFLT); + void *(*RealFFT2Setup)(CSOUND *csound, + int FFTsize, + int d); + void (*RealFFT2)(CSOUND *csound, + void *p, MYFLT *sig); + int (*ftError)(const FGDATA *, const char *, ...); + MYFLT (*GetA4)(CSOUND *csound); + int (*AuxAllocAsync)(CSOUND *, size_t, AUXCH *, + AUXASYNC *, aux_cb, void *); + void *(*GetHostData)(CSOUND *); + char *(*strNcpy)(char *dst, const char *src, size_t siz); + int (*GetZaBounds)(CSOUND *, MYFLT **); + OENTRY* (*find_opcode_new)(CSOUND*, char*, + char* , char*); + OENTRY* (*find_opcode_exact)(CSOUND*, char*, + char* , char*); + int (*GetChannelPtr)(CSOUND *,MYFLT **, const char *, int); + int (*ListChannels)(CSOUND *, controlChannelInfo_t **); + int (*GetErrorCnt)(CSOUND *); + FUNC* (*FTnp2Finde)(CSOUND*, MYFLT *); + INSTRTXT *(*GetInstrument)(CSOUND*, int, const char *); + MYFLT* (*AutoCorrelation)(CSOUND *, MYFLT*, MYFLT*, int, MYFLT*, int); + void * (*LPsetup)(CSOUND *csound, int N, int M); + void (*LPfree)(CSOUND *csound, void *); + MYFLT* (*LPred)(CSOUND *, void *, MYFLT *); + MYFLT* (*LPCeps)(CSOUND *, MYFLT *, MYFLT *, int, int); + MYFLT* (*CepsLP)(CSOUND *, MYFLT *, MYFLT *, int, int); + MYFLT (*LPrms)(CSOUND *, void *); + void *(*CreateThread2)(uintptr_t (*threadRoutine)(void *), unsigned int, void *userdata); + /**@}*/ + /** @name Placeholders + To allow the API to grow while maintining backward binary compatibility. */ + /**@{ */ + SUBR dummyfn_2[22]; + /**@}*/ +#ifdef __BUILDING_LIBCSOUND + /* ------- private data (not to be used by hosts or externals) ------- */ + /** @name Private Data + Private Data in the CSOUND struct to be used internally by the Csound + library and should be hidden from plugins. + If a new variable member is needed by the library, add it below, as a + private data member. If access is required solely by plugins (and not + internally by the library), use the CreateGlobalVariable() etc. interface, + instead of adding to CSOUND. + + If you find that a plugin needs to access existing private data, + first check above for an existing interface; if none is available, + add one. Please avoid giving full access, or allowing plugins to + change the values of private members, by using one of the two methods + below: + + 1) To get the data member value: + \code + returnType (*GetVar)(CSOUND *) + \endcode + 2) in case of pointers, data should be copied out to a supplied memory + slot, rather than the pointer being obtained: + \code + void (*GetData)(CSOUND *, dataType *) + + dataType var; + csound->GetData(csound, &var); + \endcode + */ + /**@{ */ + SUBR first_callback_; + channelCallback_t InputChannelCallback_; + channelCallback_t OutputChannelCallback_; + void (*csoundMessageCallback_)(CSOUND *, int attr, + const char *format, va_list args); + int (*csoundConfigureCallback_)(CSOUND *); + void (*csoundMakeGraphCallback_)(CSOUND *, WINDAT *windat, + const char *name); + void (*csoundDrawGraphCallback_)(CSOUND *, WINDAT *windat); + void (*csoundKillGraphCallback_)(CSOUND *, WINDAT *windat); + int (*csoundExitGraphCallback_)(CSOUND *); + int (*csoundYieldCallback_)(CSOUND *); + void (*cscoreCallback_)(CSOUND *); + void (*FileOpenCallback_)(CSOUND*, const char*, int, int, int); + SUBR last_callback_; + /* these are not saved on RESET */ + int (*playopen_callback)(CSOUND *, const csRtAudioParams *parm); + void (*rtplay_callback)(CSOUND *, const MYFLT *outBuf, int nbytes); + int (*recopen_callback)(CSOUND *, const csRtAudioParams *parm); + int (*rtrecord_callback)(CSOUND *, MYFLT *inBuf, int nbytes); + void (*rtclose_callback)(CSOUND *); + int (*audio_dev_list_callback)(CSOUND *, CS_AUDIODEVICE *, int); + int (*midi_dev_list_callback)(CSOUND *, CS_MIDIDEVICE *, int); + int (*doCsoundCallback)(CSOUND *, void *, unsigned int); + int (*csoundInternalYieldCallback_)(CSOUND *); + /* end of callbacks */ + void (*spinrecv)(CSOUND *); + void (*spoutran)(CSOUND *); + int (*audrecv)(CSOUND *, MYFLT *, int); + void (*audtran)(CSOUND *, const MYFLT *, int); + void *hostdata; + char *orchname, *scorename; + CORFIL *orchstr, *scorestr; + OPDS *ids; /* used by init loops */ + ENGINE_STATE engineState; /* current Engine State merged after + compilation */ + INSTRTXT *instr0; /* instr0 */ + INSTRTXT **dead_instr_pool; + int dead_instr_no; + TYPE_POOL* typePool; + unsigned int ksmps; + uint32_t nchnls; + int inchnls; + int spoutactive; + uint64_t kcounter, global_kcounter; + MYFLT esr; + MYFLT ekr; + /** current time in seconds, inc. per kprd */ + int64_t icurTime; /* Current time in samples */ + double curTime_inc; + /** start time of current section */ + double timeOffs, beatOffs; + /** current time in beats, inc per kprd */ + double curBeat, curBeat_inc; + /** beat time = 60 / tempo */ + int64_t ibeatTime; /* Beat time in samples */ + EVTBLK *currevent; + INSDS *curip; + MYFLT cpu_power_busy; + char *xfilename; + int peakchunks; + int keep_tmp; + CS_HASH_TABLE *opcodes; + int32 nrecs; + FILE* Linepipe; + int Linefd; + void *csoundCallbacks_; + FILE* scfp; + CORFIL *scstr; + FILE* oscfp; + MYFLT maxamp[MAXCHNLS]; + MYFLT smaxamp[MAXCHNLS]; + MYFLT omaxamp[MAXCHNLS]; + uint32 maxpos[MAXCHNLS], smaxpos[MAXCHNLS], omaxpos[MAXCHNLS]; + FILE* scorein; + FILE* scoreout; + int *argoffspace; + INSDS *frstoff; + /** reserved for std opcode library */ + void *stdOp_Env; + int holdrand; + int randSeed1; + int randSeed2; + CsoundRandMTState *csRandState; + RTCLOCK *csRtClock; + int strsmax; + char **strsets; + MYFLT *spin; + MYFLT *spout; + MYFLT *spraw; + int nspin; + int nspout; + MYFLT *auxspin; + OPARMS *oparms; + /** reserve space for up to MIDIMAXPORTS MIDI devices */ + MCHNBLK *m_chnbp[MIDIMAXPORTS*16]; + int dither_output; + MYFLT onedsr, sicvt; + MYFLT tpidsr, pidsr, mpidsr, mtpdsr; + MYFLT onedksmps; + MYFLT onedkr; + MYFLT kicvt; + int reinitflag; + int tieflag; + MYFLT e0dbfs, dbfs_to_float; + double A4; + void *rtRecord_userdata; + void *rtPlay_userdata; + jmp_buf exitjmp; + SRTBLK *frstbp; + int sectcnt; + int inerrcnt, synterrcnt, perferrcnt; + INSDS actanchor; + int32 rngcnt[MAXCHNLS]; + int16 rngflg, multichan; + void *evtFuncChain; + EVTNODE *OrcTrigEvts; /* List of events to be started */ + EVTNODE *freeEvtNodes; + int csoundIsScorePending_; + int64_t advanceCnt; + int initonly; + int evt_poll_cnt; + int evt_poll_maxcnt; + int Mforcdecs, Mxtroffs, MTrkend; + OPCODINFO *opcodeInfo; + FUNC** flist; + int maxfnum; + GEN *gensub; + int genmax; + CS_HASH_TABLE *namedGlobals; + CS_HASH_TABLE *cfgVariableDB; + double prvbt, curbt, nxtbt; + double curp2, nxtim; + int64_t cyclesRemaining; + EVTBLK evt; + void *memalloc_db; + MGLOBAL *midiGlobals; + CS_HASH_TABLE *envVarDB; + MEMFIL *memfiles; + PVOCEX_MEMFILE *pvx_memfiles; + int FFT_max_size; + void *FFT_table_1; + void *FFT_table_2; + /* statics from twarp.c should be TSEG* */ + void *tseg, *tpsave; + /* persistent macros */ + MACRO *orc_macros; + /* Statics from express.c */ + MYFLT *gbloffbas; /* was static in oload.c */ + void *file_io_thread; + int file_io_start; + void *file_io_threadlock; + int realtime_audio_flag; + void *event_insert_thread; + int event_insert_loop; + void *init_pass_threadlock; + void *API_lock; + spin_lock_t spoutlock, spinlock; + spin_lock_t memlock, spinlock1; + char *delayederrormessages; + void *printerrormessagesflag; + struct sread__ { + SRTBLK *bp, *prvibp; /* current srtblk, prev w/same int(p1) */ + char *sp, *nxp; /* string pntrs into srtblk text */ + int op; /* opcode of current event */ + int warpin; /* input format sensor */ + int linpos; /* line position sensor */ + int lincnt; /* count of lines/section in scorefile */ + MYFLT prvp2 /* = -FL(1.0) */; /* Last event time */ + MYFLT clock_base /* = FL(0.0) */; + MYFLT warp_factor /* = FL(1.0) */; + char *curmem; + char *memend; /* end of cur memblk */ + MACRO *unused_ptr2; + int last_name /* = -1 */; + IN_STACK *inputs, *str; + int input_size, input_cnt; + int unused_int3; + int unused_int2; + int linepos /* = -1 */; + MARKED_SECTIONS names[30]; +#define NAMELEN 40 /* array size of repeat macro names */ +#define RPTDEPTH 40 /* size of repeat_n arrays (39 loop levels) */ + char unused_char0[RPTDEPTH][NAMELEN]; + int unused_int4[RPTDEPTH]; + int32 unused_int7[RPTDEPTH]; + int unused_int5; + MACRO *unused_ptr0[RPTDEPTH]; + int unused_int6; + /* Variable for repeat sections */ + char unused_char1[NAMELEN]; + int unused_int8; + int32 unused_int9; + int unused_intA; + MACRO *unused_ptr1; + int nocarry; + } sread; + struct onefileStatics__ { + NAMELST *toremove; + char *orcname; + char *sconame; + char *midname; + int midiSet; + int csdlinecount; + } onefileStatics; +#define LBUFSIZ 32768 + struct lineventStatics__ { + char *Linep, *Linebufend; + int stdmode; + EVTBLK prve; + char *Linebuf; + int linebufsiz; + char *orchestra, *orchestrab; + int oflag; + } lineventStatics; + struct musmonStatics__ { + int32 srngcnt[MAXCHNLS], orngcnt[MAXCHNLS]; + int16 srngflg; + int16 sectno; + int lplayed; + int segamps, sormsg; + EVENT **ep, **epend; /* pointers for stepping through lplay list */ + EVENT *lsect; + } musmonStatics; + struct libsndStatics__ { + SNDFILE *outfile; + SNDFILE *infile; + char *sfoutname; /* soundout filename */ + MYFLT *inbuf; + MYFLT *outbuf; /* contin sndio buffers */ + MYFLT *outbufp; /* MYFLT pntr */ + uint32 inbufrem; + uint32 outbufrem; /* in monosamps */ + /* (see openin, iotranset) */ + unsigned int inbufsiz, outbufsiz; /* alloc in sfopenin/out */ + int isfopen; /* (real set in sfopenin) */ + int osfopen; /* (real set in sfopenout) */ + int pipdevin, pipdevout; /* 0: file, 1: pipe, 2: rtaudio */ + uint32 nframes /* = 1UL */; + FILE *pin, *pout; + int dither; + } libsndStatics; + + int warped; /* rdscor.c */ + int sstrlen; + char *sstrbuf; + int enableMsgAttr; /* csound.c */ + int sampsNeeded; + MYFLT csoundScoreOffsetSeconds_; + int inChar_; + int isGraphable_; + int delayr_stack_depth; /* ugens6.c */ + void *first_delayr; + void *last_delayr; + int32 revlpsiz[6]; + int32 revlpsum; + double rndfrac; /* aops.c */ + MYFLT *logbase2; + NAMES *omacros, *smacros; + void *namedgen; /* fgens.c */ + void *open_files; /* fileopen.c */ + void *searchPathCache; + CS_HASH_TABLE *sndmemfiles; + void *reset_list; + void *pvFileTable; /* pvfileio.c */ + int pvNumFiles; + int pvErrorCode; + /* database for deferred loading of opcode plugin libraries */ + // void *pluginOpcodeFiles; + int enableHostImplementedAudioIO; + int enableHostImplementedMIDIIO; + int hostRequestedBufferSize; + /* engineStatus is sum of: + * 1 (CS_STATE_PRE): csoundPreCompile was called + * 2 (CS_STATE_COMP): csoundCompile was called + * 4 (CS_STATE_UTIL): csoundRunUtility was called + * 8 (CS_STATE_CLN): csoundCleanup needs to be called + * 16 (CS_STATE_JMP): csoundLongJmp was called + */ + char engineStatus; + /* stdXX_assign_flags can be {1,2,4,8} */ + char stdin_assign_flg; + char stdout_assign_flg; + char orcname_mode; /* 0: normal, 1: ignore, 2: fail */ + int use_only_orchfile; + void *csmodule_db; + char *dl_opcodes_oplibs; + char *SF_csd_licence; + char *SF_id_title; + char *SF_id_copyright; + int SF_id_scopyright; + char *SF_id_software; + char *SF_id_artist; + char *SF_id_comment; + char *SF_id_date; + void *utility_db; + int16 *isintab; /* ugens3.c */ + void *lprdaddr; /* ugens5.c */ + int currentLPCSlot; + int max_lpc_slot; + CS_HASH_TABLE *chn_db; + int opcodedirWasOK; + int disable_csd_options; + CsoundRandMTState randState_; + int performState; + int ugens4_rand_16; + int ugens4_rand_15; + void *schedule_kicked; + MYFLT *disprep_fftcoefs; + void *winEPS_globals; + OPARMS oparms_; + REMOT_BUF SVrecvbuf; /* RM: rt_evt input Communications buffer */ + void *remoteGlobals; + /* VL: pvs bus */ + int nchanif, nchanof; + char *chanif, *chanof; + /* VL: internal yield callback */ + int multiThreadedComplete; + THREADINFO *multiThreadedThreadInfo; + struct dag_t *multiThreadedDag; + void *barrier1; + void *barrier2; + /* Statics from cs_par_dispatch; */ + /* ********These are no longer used******** */ + void *pointer1; //struct global_var_lock_t *global_var_lock_root; + void *pointer2; //struct global_var_lock_t **global_var_lock_cache; + int int1; //global_var_lock_count; + /* statics from cs_par_orc_semantic_analysis */ + struct instr_semantics_t *instCurr; + struct instr_semantics_t *instRoot; + int inInstr; + int dag_changed; + int dag_num_active; + INSDS **dag_task_map; + volatile stateWithPadding *dag_task_status; + watchList * volatile *dag_task_watch; + watchList *dag_wlmm; + char **dag_task_dep; + int dag_task_max_size; + uint32_t tempStatus; /* keeps track of which files are temps */ + int orcLineOffset; /* 1 less than 1st orch line in the CSD */ + int scoLineOffset; /* 1 less than 1st score line in the CSD */ + char* csdname; + /* original CSD name; do not free() */ + int parserUdoflag; + int parserNamedInstrFlag; + int tran_nchnlsi; + int scnt; /* Count of strings */ + int strsiz; /* length of current strings space */ + FUNC *sinetable; /* A useful table */ + int sinelength; /* Size of table */ + MYFLT *UNUSEDP; /* pow2 table */ + MYFLT *cpsocfrc; /* cps conv table */ + CORFIL* expanded_orc; /* output of preprocessor */ + CORFIL* expanded_sco; /* output of preprocessor */ + char *filedir[256];/* for location directory */ + void *message_buffer; + int jumpset; + int info_message_request; + int modules_loaded; + MYFLT _system_sr; + void* csdebug_data; /* debugger data */ + int (*kperf)(CSOUND *); /* kperf function pointer, to switch between debug + and nodebug function */ + int score_parser; + CS_HASH_TABLE* symbtab; + int print_version; + int inZero; /* flag compilation of instr0 */ + struct _message_queue **msg_queue; + volatile long msg_queue_wget; /* Writer - Get index */ + volatile long msg_queue_wput; /* Writer - Put Index */ + volatile long msg_queue_rstart; /* Reader - start index */ + volatile long msg_queue_items; + int aftouch; + void *directory; + ALLOC_DATA *alloc_queue; + volatile unsigned long alloc_queue_items; + unsigned long alloc_queue_wp; + spin_lock_t alloc_spinlock; + EVTBLK *init_event; + void (*csoundMessageStringCallback)(CSOUND *csound, + int attr, + const char *str); + char* message_string; + volatile unsigned long message_string_queue_items; + unsigned long message_string_queue_wp; + message_string_queue_t *message_string_queue; + int io_initialised; + char *op; + int mode; + char *opcodedir; + char *score_srt; + /*struct CSOUND_ **self;*/ + /**@}*/ +#endif /* __BUILDING_LIBCSOUND */ + }; + +/* + * Move the C++ guards to enclose the entire file, + * in order to enable C++ to #include this file. + */ + +#define LINKAGE_BUILTIN(name) \ +long name##_init(CSOUND *csound, OENTRY **ep) \ +{ (void) csound; *ep = name; return (long) (sizeof(name)); } + +#define FLINKAGE_BUILTIN(name) \ +NGFENS* name##_init(CSOUND *csound) \ +{ (void) csound; return name; } + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* CSOUNDCORE_H */ diff --git a/6.x/csound/csound_data_structures.h b/6.x/csound/csound_data_structures.h new file mode 100644 index 00000000..edaa13aa --- /dev/null +++ b/6.x/csound/csound_data_structures.h @@ -0,0 +1,133 @@ +/* + csound_data_structures.h: + + Copyright (C) 2013 Steven Yi + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA + */ + +#ifndef __CSOUND_DATA_STRUCTURES_H +#define __CSOUND_DATA_STRUCTURES_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _cons { + void* value; // should be car, but using value + struct _cons* next; // should be cdr, but to follow csound + // linked list conventions +} CONS_CELL; + +typedef struct _cs_hash_bucket_item { + char* key; + void* value; + struct _cs_hash_bucket_item* next; +} CS_HASH_TABLE_ITEM; + +typedef struct _cs_hash_table { + int table_size; + int count; + CS_HASH_TABLE_ITEM** buckets; +} CS_HASH_TABLE; + +/* FUNCTIONS FOR CONS CELL */ + +/** Given a value and CONS_CELL, create a new CONS_CELL that holds the + value, then set the ->next value to the passed-in cons cell. This + operation effectively appends a value to the head of cons list. The + function returns the head of the cons list. It is safe to pass in + a NULL for the cons argument; the returned value will be just the + newly generated cons cell. */ +PUBLIC CONS_CELL* cs_cons(CSOUND* csound, void* val, CONS_CELL* cons); + +/** Appends the cons2 CONS_CELL list to the tail of the cons1 */ +PUBLIC CONS_CELL* cs_cons_append(CONS_CELL* cons1, CONS_CELL* cons2); + +/** Returns length of CONS_CELL list */ +PUBLIC int cs_cons_length(CONS_CELL* head); + +/** Frees CONS_CELL list but does not free ->value pointers */ +PUBLIC void cs_cons_free(CSOUND* csound, CONS_CELL* head); + +/** Frees CONS_CELL list also frees ->value pointers */ +PUBLIC void cs_cons_free_complete(CSOUND* csound, CONS_CELL* head); + +/* FUNCTIONS FOR HASH SET */ + +/** Create CS_HASH_TABLE */ +PUBLIC CS_HASH_TABLE* cs_hash_table_create(CSOUND* csound); + +/** Retreive void* value for given char* key. Returns NULL if no + items founds for key. */ +PUBLIC void* cs_hash_table_get(CSOUND* csound, + CS_HASH_TABLE* hashTable, char* key); + +/** Retreive char* key from internal hash item for given char* key. + Useful when using CS_HASH_TABLE as a Set type. Returns + NULL if there is no entry for given key. */ +PUBLIC char* cs_hash_table_get_key(CSOUND* csound, + CS_HASH_TABLE* hashTable, char* key); + +/** Adds an entry into the hashtable using the given key and value. + If an existing entry is found, overwrites the value for that key with + the new value passed in. */ +PUBLIC void cs_hash_table_put(CSOUND* csound, + CS_HASH_TABLE* hashTable, char* key, void* value); + +/** Adds an entry into the hashtable using the given key and NULL + value. Returns the internal char* used for the hash item key. */ +PUBLIC char* cs_hash_table_put_key(CSOUND* csound, + CS_HASH_TABLE* hashTable, char* key); + +/** Removes an entry from the hashtable using the given key. If no + entry found for key, simply returns. Calls mfree on the table + item. */ +PUBLIC void cs_hash_table_remove(CSOUND* csound, + CS_HASH_TABLE* hashTable, char* key); + +/** Merges in all items from the the source table into the target + table. Entries with identical keys from the source table will + replace entries in the target table. Note: wipes out source table. */ +PUBLIC void cs_hash_table_merge(CSOUND* csound, + CS_HASH_TABLE* target, CS_HASH_TABLE* source); + +/** Returns char* keys as a cons list */ +PUBLIC CONS_CELL* cs_hash_table_keys(CSOUND* csound, CS_HASH_TABLE* hashTable); + +/** Returns void* values as a cons list */ +PUBLIC CONS_CELL* cs_hash_table_values(CSOUND* csound, CS_HASH_TABLE* hashTable); + +/** Frees hash table and hash table items using mfree. Does not call + free on ->value pointer. */ +PUBLIC void cs_hash_table_free(CSOUND* csound, CS_HASH_TABLE* hashTable); + +/** Frees hash table and hash table keys using mfree. Does call mfree + on ->value pointer. */ +PUBLIC void cs_hash_table_mfree_complete(CSOUND* csound, CS_HASH_TABLE* hashTable); + +/** Frees hash table hash table keys using mfree. Does call free on + ->value pointer. */ +PUBLIC void cs_hash_table_free_complete(CSOUND* csound, CS_HASH_TABLE* hashTable); + +char * cs_inverse_hash_get(CSOUND* csound, CS_HASH_TABLE* hashTable, int n); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/6.x/csound/csound_standard_types.h b/6.x/csound/csound_standard_types.h new file mode 100644 index 00000000..77c856e4 --- /dev/null +++ b/6.x/csound/csound_standard_types.h @@ -0,0 +1,70 @@ +/* + csound_standard_types.h: + + Copyright (C) 2012, 2013 Steven Yi + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA + */ + +#ifndef CSOUND_STANDARD_TYPES_H +#define CSOUND_STANDARD_TYPES_H + +#include "csound_type_system.h" +#include "csound.h" + +#ifdef __cplusplus +extern "C" { +#endif + + PUBLIC void csoundAddStandardTypes(CSOUND* csound, TYPE_POOL* pool); + + PUBLIC_DATA extern const CS_TYPE CS_VAR_TYPE_A; + PUBLIC_DATA extern const CS_TYPE CS_VAR_TYPE_K; + PUBLIC_DATA extern const CS_TYPE CS_VAR_TYPE_I; + PUBLIC_DATA extern const CS_TYPE CS_VAR_TYPE_S; + PUBLIC_DATA extern const CS_TYPE CS_VAR_TYPE_P; + PUBLIC_DATA extern const CS_TYPE CS_VAR_TYPE_R; + PUBLIC_DATA extern const CS_TYPE CS_VAR_TYPE_C; + PUBLIC_DATA extern const CS_TYPE CS_VAR_TYPE_W; + PUBLIC_DATA extern const CS_TYPE CS_VAR_TYPE_F; + PUBLIC_DATA extern const CS_TYPE CS_VAR_TYPE_B; + PUBLIC_DATA extern const CS_TYPE CS_VAR_TYPE_b; + PUBLIC_DATA extern const CS_TYPE CS_VAR_TYPE_ARRAY; + + typedef struct arrayVarInit { + int dimensions; + CS_TYPE* type; + } ARRAY_VAR_INIT; + + + /* Type maps for poly, optional, and var arg types + * format is in pairs of specified type and types it can resolve into, + * termintated by a NULL */ + extern const char* POLY_IN_TYPES[]; + extern const char* OPTIONAL_IN_TYPES[]; + extern const char* VAR_ARG_IN_TYPES[]; + extern const char* POLY_OUT_TYPES[]; + extern const char* VAR_ARG_OUT_TYPES[]; + + + +#ifdef __cplusplus +} +#endif + +#endif /* CSOUND_STANDARD_TYPES_H */ diff --git a/6.x/csound/csound_threaded.hpp b/6.x/csound/csound_threaded.hpp new file mode 100644 index 00000000..72af2d96 --- /dev/null +++ b/6.x/csound/csound_threaded.hpp @@ -0,0 +1,339 @@ +/* + csound_threaded.hpp: + + Copyright (C) 2017 Michael Gogins + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA + + As a special exception, if other files instantiate templates or + use macros or inline functions from this file, this file does not + by itself cause the resulting executable or library to be covered + by the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the library or executable + file might be covered by the GNU Lesser General Public License. +*/ + +#ifndef __CSOUND_THREADED_HPP__ +#define __CSOUND_THREADED_HPP__ + +#if defined(__GNUC__) +#if __cplusplus <= 199711L + #error To use csound_threaded.hpp you need at least a C++11 compliant compiler. +#endif +#endif + +#ifdef SWIG +%module csnd6 +%{ +#include "csound.hpp" +%} +#else +#include "csound.hpp" +#ifdef __BUILDING_CSOUND_INTERFACES +#endif + +#include +#include +#include +#include +#include +#include + +/** + * A thread-safe queue, or first-in first-out (FIFO) queue, implemented using + * only the standard C++11 library. The Data should be a simple type, such as + * a pointer. + */ +template +class concurrent_queue +{ +private: + std::queue queue_; + std::mutex mutex_; + std::condition_variable condition_variable_; +public: + void push(Data const& data) + { + std::unique_lock lock(mutex_); + queue_.push(data); + lock.unlock(); + condition_variable_.notify_one(); + } + bool empty() const + { + std::unique_lock lock(mutex_); + return queue_.empty(); + } + bool try_pop(Data& popped_value) + { + std::unique_lock lock(mutex_); + if (queue_.empty()) { + return false; + } + popped_value = queue_.front(); + queue_.pop(); + return true; + } + void wait_and_pop(Data& popped_value) + { + std::unique_lock lock(mutex_); + while (queue_.empty()) { + condition_variable_.wait(lock); + } + popped_value = queue_.front(); + queue_.pop(); + } +}; + +/** + * Abstract base class for Csound events to be enqueued + * for performance. + */ +struct CsoundEvent +{ + virtual ~CsoundEvent() {}; + /** + * Dispatches the event to Csound during performance. + */ + virtual int operator ()(CSOUND *csound_) = 0; +}; + +/** + * Specialization of CsoundEvent for low-level + * score events with raw pfields. + */ +struct CsoundScoreEvent : public CsoundEvent +{ + char opcode; + std::vector pfields; + CsoundScoreEvent(char opcode_, const MYFLT *pfields_, long pfield_count) + { + opcode = opcode_; + for (long i = 0; i < pfield_count; i++) { + pfields.push_back(pfields_[i]); + } + } + virtual int operator ()(CSOUND *csound_) { + return csoundScoreEvent(csound_, opcode, pfields.data(), pfields.size()); + } +}; + +/** + * Specialization of CsoundEvent for high-level textual score + * events, fragments of scores, or entire scores. + */ +struct CsoundTextEvent : public CsoundEvent +{ + std::string events; + CsoundTextEvent(const char *text) + { + events = text; + } + virtual int operator ()(CSOUND *csound_) { + return csoundReadScore(csound_, events.data()); + } +}; + +/** + * This class provides a multi-threaded C++ interface to the "C" Csound API. + * The interface is identical to the C++ interface of the Csound class in + * csound.hpp; however, the ::Perform() function runs in a separate thread of + * execution that is fed by a thread-safe FIFO of messages from ::ScoreEvent, + * ::InputMessage, and ::ReadScore. + * + * This is a header-file-only facility. The multi-threaded features of this + * class are minimalistic, but seem sufficient for most purposes. There are + * no external dependences apart from Csound and the standard C++ library. + */ +class PUBLIC CsoundThreaded : public Csound +{ +protected: + std::thread performance_thread; + std::atomic keep_running; + void (*kperiod_callback)(CSOUND *, void *); + void *kperiod_callback_user_data; + concurrent_queue input_queue; + void ClearQueue() + { + CsoundEvent *event = 0; + while (input_queue.try_pop(event)) { + delete event; + } + } +public: + CsoundThreaded() : Csound(), keep_running(false), kperiod_callback(nullptr), kperiod_callback_user_data(nullptr) {}; + CsoundThreaded(CSOUND *csound_) : Csound(csound_), keep_running(false), kperiod_callback(nullptr), kperiod_callback_user_data(nullptr) {}; + CsoundThreaded(void *host_data) : Csound(host_data), keep_running(false), kperiod_callback(nullptr), kperiod_callback_user_data(nullptr) {}; + virtual ~CsoundThreaded() + { + Stop(); + Join(); + ClearQueue(); + } + virtual void SetKperiodCallback(void (*kperiod_callback_)(CSOUND *, void *), void *kperiod_callback_user_data_) + { + kperiod_callback = kperiod_callback_; + kperiod_callback_user_data = kperiod_callback_user_data_; + } + virtual int PerformRoutine() + { + Message("Began CsoundThreaded::PerformRoutine()...\n"); + keep_running = true; + int result = 0; + while (true) { + if (keep_running == false) { + break; + } + CsoundEvent *event = 0; + while (input_queue.try_pop(event)) { + (*event)(csound); + delete event; + } + if (kperiod_callback != nullptr) { + kperiod_callback(csound, kperiod_callback_user_data); + } + result = Csound::PerformKsmps(); + if (result != 0) { + Message("CsoundThreaded::PerformRoutine(): CsoundThreaded::PerformKsmps() ended with %d...\n", result); + break; + } + } + keep_running = false; + ClearQueue(); + Message("CsoundThreaded::PerformRoutine(): Cleared performance queue...\n"); + Message("Ended CsoundThreaded::PerformRoutine() with %d.\n", result); + return result; + } + virtual int PerformAndResetRoutine() + { + Message("Began CsoundThreaded::PerformAndResetRoutine()...\n"); + keep_running = true; + int result = 0; + while (true) { + if (keep_running == false) { + break; + } + CsoundEvent *event = 0; + while (input_queue.try_pop(event)) { + (*event)(csound); + delete event; + } + if (kperiod_callback != nullptr) { + kperiod_callback(csound, kperiod_callback_user_data); + } + result = Csound::PerformKsmps(); + if (result != 0) { + Message("CsoundThreaded::PerformAndResetRoutine(): CsoundThreaded::PerformKsmps() ended with %d...\n", result); + break; + } + } + keep_running = false; + ClearQueue(); + Message("CsoundThreaded::PerformAndResetRoutine(): Cleared performance queue...\n"); + result = Cleanup(); + Message("CsoundThreaded::PerformAndResetRoutine(): Cleanup() returned %d...\n", result); + Reset(); + Message("CsoundThreaded::PerformAndResetRoutine(): Reset() returned...\n"); + Message("Ended CsoundThreaded::PerformAndResetRoutine() with %d.\n", result); + return result; + } + /** + * Overrides Csound::Perform to run in a separate thread of execution. + * The granularity of time is one kperiod. If a kperiod callback has been + * set, it is called with the CSOUND object and any user data on every + * kperiod. + */ + virtual int Perform() + { + performance_thread = std::thread(&CsoundThreaded::PerformRoutine, this); + return 0; + } + /** + * Like Perform, but calls Cleanup() and Reset() at the conclusion of the + * performance, so that this is done in the performance thread. + */ + virtual int PerformAndReset() + { + performance_thread = std::thread(&CsoundThreaded::PerformAndResetRoutine, this); + return 0; + } + /** + * Enqueues a low-level score event with raw pfields for dispatch from + * the performance thread routine. + */ + virtual int ScoreEvent(char opcode, const MYFLT *pfields, long pfield_count) + { + int result = 0; + CsoundScoreEvent *event = new CsoundScoreEvent(opcode, pfields, pfield_count); + input_queue.push(event); + return result; + } + /** + * Enqueues a textual score event or events for dispatch from the + * performance thread routine. + */ + virtual void InputMessage(const char *message) + { + CsoundTextEvent *event = new CsoundTextEvent(message); + input_queue.push(event); + } + /** + * Enqueues a textual score event, score fragment, or entire score for + * dispatch from the performance thread routine. + */ + virtual int ReadScore(const char *score) + { + int result = 0; + CsoundTextEvent *event = new CsoundTextEvent(score); + input_queue.push(event); + return result; + } + /** + * Signals the performance thread routine to stop and return. + */ + virtual void Stop() + { + Message("CsoundThreaded::Stop()...\n"); + keep_running = false; + Csound::Stop(); + Message("CsoundThreaded::Stop().\n"); + } + /** + * Causes the calling thread to wait for the end of the performance + * thread routine. + */ + virtual void Join() + { + Message("CsoundThreaded::Join()...\n"); + if (performance_thread.joinable()) { + performance_thread.join(); + } + Message("CsoundThreaded::Join().\n"); + } + /** + * Returns whether or not the performance thread routine is running. + */ + virtual bool IsPlaying() const + { + return keep_running; + } +}; + +#endif // __cplusplus + +#endif // __CSOUND_HPP__ diff --git a/6.x/csound/csound_type_system.h b/6.x/csound/csound_type_system.h new file mode 100644 index 00000000..a7ca6eff --- /dev/null +++ b/6.x/csound/csound_type_system.h @@ -0,0 +1,137 @@ +/* + csound_type_system.c: + + Copyright (C) 2012, 2013 Steven Yi + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA + */ + +#ifndef CSOUND_TYPE_SYSTEM_H +#define CSOUND_TYPE_SYSTEM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "csound.h" +#include "csound_data_structures.h" +#include + +#define CS_ARG_TYPE_BOTH 0 +#define CS_ARG_TYPE_IN 1 +#define CS_ARG_TYPE_OUT 2 + + struct csvariable; + + typedef struct cstype { + char* varTypeName; + char* varDescription; + int argtype; // used to denote if allowed as in-arg, out-arg, or both + struct csvariable* (*createVariable)(void*, void*); + void (*copyValue)(void* csound, void* dest, void* src); + struct cstype** unionTypes; + void (*freeVariableMemory)(void* csound, void* varMem); + } CS_TYPE; + + typedef struct csvarmem { + CS_TYPE* varType; + MYFLT value; + } CS_VAR_MEM; + +#if defined(UINTPTR_MAX) && defined(UINT64_MAX) && (UINTPTR_MAX == UINT64_MAX) +#define CS_VAR_TYPE_OFFSET (sizeof(CS_VAR_MEM) - sizeof(double)) +#else +#define CS_VAR_TYPE_OFFSET (sizeof(CS_VAR_MEM) - sizeof(MYFLT)) +#endif + + typedef struct csvariable { + char* varName; + CS_TYPE* varType; + int memBlockSize; /* Must be a multiple of sizeof(MYFLT), as + Csound uses MYFLT* and pointer arithmetic + to assign var locations */ + int memBlockIndex; + int dimensions; // used by arrays + int refCount; + struct csvariable* next; + CS_TYPE* subType; + void (*updateMemBlockSize)(void*, struct csvariable*); + void (*initializeVariableMemory)(void*,struct csvariable*, MYFLT*); + CS_VAR_MEM *memBlock; + } CS_VARIABLE; + + +// typedef struct cstypeinstance { +// CS_TYPE* varType; +// CS_VARIABLE* (*createVariable)(void*, void*); +// void* args ; +// struct cstypeinstance* next; +// } CS_TYPE_INSTANCE; + + typedef struct cstypeitem { + CS_TYPE* cstype; + struct cstypeitem* next; + } CS_TYPE_ITEM; + + typedef struct typepool { + CS_TYPE_ITEM* head; + } TYPE_POOL; + + /* Adds a new type to Csound's type table + Returns if variable type redefined */ + PUBLIC int csoundAddVariableType(CSOUND* csound, TYPE_POOL* pool, + CS_TYPE* typeInstance); + PUBLIC CS_VARIABLE* csoundCreateVariable(void* csound, TYPE_POOL* pool, + CS_TYPE* type, char* name, + void* typeArg); + PUBLIC CS_TYPE* csoundGetTypeWithVarTypeName(TYPE_POOL* pool, char* typeName); + PUBLIC CS_TYPE* csoundGetTypeForVarName(TYPE_POOL* pool, char* typeName); + + + /* Csound Variable Pool - essentially a map + CSOUND contains one for global memory, InstrDef and UDODef + contain a pool for local memory + */ + + typedef struct csvarpool { + CS_HASH_TABLE* table; + CS_VARIABLE* head; + CS_VARIABLE* tail; + int poolSize; + struct csvarpool* parent; + int varCount; + int synthArgCount; + } CS_VAR_POOL; + + PUBLIC CS_VAR_POOL* csoundCreateVarPool(CSOUND* csound); + PUBLIC void csoundFreeVarPool(CSOUND* csound, CS_VAR_POOL* pool); + PUBLIC char* getVarSimpleName(CSOUND* csound, const char* name); + PUBLIC CS_VARIABLE* csoundFindVariableWithName(CSOUND* csound, + CS_VAR_POOL* pool, + const char* name); + PUBLIC int csoundAddVariable(CSOUND* csound, CS_VAR_POOL* pool, + CS_VARIABLE* var); + PUBLIC void recalculateVarPoolMemory(void* csound, CS_VAR_POOL* pool); + PUBLIC void reallocateVarPoolMemory(void* csound, CS_VAR_POOL* pool); + PUBLIC void initializeVarPool(void *csound, MYFLT* memBlock, CS_VAR_POOL* pool); + +#ifdef __cplusplus +} +#endif + +#endif /* CSOUND_TYPE_SYSTEM_H */ diff --git a/6.x/csound/cwindow.h b/6.x/csound/cwindow.h new file mode 100644 index 00000000..4337a327 --- /dev/null +++ b/6.x/csound/cwindow.h @@ -0,0 +1,93 @@ +/* + cwindow.h: + + Copyright (C) 1990 Dan Ellis + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef CWINDOW_H +#define CWINDOW_H + +/*******************************************************\ +* cwindow.h * +* portable window graphs stolen from Csound * +* necessary header declarations * +* 08nov90 dpwe * +\*******************************************************/ + +#include "csound.h" + +#define CAPSIZE 60 + +struct windat_ { + uintptr_t windid; /* set by MakeGraph() */ + MYFLT *fdata; /* data passed to DrawGraph */ + int32 npts; /* size of above array */ + char caption[CAPSIZE]; /* caption string for graph */ + int16 waitflg; /* set =1 to wait for ms after Draw */ + int16 polarity; /* controls positioning of X axis */ + MYFLT max, min; /* workspace .. extrema this frame */ + MYFLT absmax; /* workspace .. largest of above */ + MYFLT oabsmax; /* Y axis scaling factor */ + int danflag; /* set to 1 for extra Yaxis mid span */ + int absflag; /* set to 1 to skip abs check */ +}; + +enum { /* symbols for WINDAT.polarity field */ + NOPOL, + NEGPOL, + POSPOL, + BIPOL +}; + +struct xyindat_ { /* for 'joystick' input window */ + uintptr_t windid; /* xwindow handle */ + int m_x,m_y; /* current crosshair pixel adr */ + MYFLT x,y; /* current proportions of fsd */ + int down; +}; + + /* ------------------------------------------------------------------------ */ + +#ifdef __BUILDING_LIBCSOUND + +void dispset(CSOUND *, WINDAT *, MYFLT *, int32, char *, int, char *); +int dispexit(CSOUND *); +void display(CSOUND *, WINDAT*); +#if 0 +/* create window for a graph */ +void MakeGraph(CSOUND *, WINDAT *, const char *); +/* create a mouse input window; init scale */ +void MakeXYin(CSOUND *, XYINDAT *, MYFLT, MYFLT); +/* update graph in existing window */ +void DrawGraph(CSOUND *, WINDAT *); +/* fetch latest value from mouse input window */ +void ReadXYin(CSOUND *, XYINDAT *); +/* remove a graph window */ +void KillGraph(CSOUND *, WINDAT *); +/* remove a mouse input window */ +void KillXYin(CSOUND *, XYINDAT *); +/* print click-Exit message in most recently active window */ +int ExitGraph(CSOUND *); +#endif + +#endif /* __BUILDING_LIBCSOUND */ + +#endif /* CWINDOW_H */ + diff --git a/6.x/csound/filebuilding.h b/6.x/csound/filebuilding.h new file mode 100644 index 00000000..5f04841a --- /dev/null +++ b/6.x/csound/filebuilding.h @@ -0,0 +1,211 @@ +/* + * C S O U N D + * + * An auto-extensible system for making music on computers + * by means of software alone. + * + * Copyright (C) 2001-2005 Michael Gogins, Matt Ingalls, John D. Ramsdell, + * John P. ffitch, Istvan Varga + * + * L I C E N S E + * + * This software is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef CSOUND_FILEBUILDING_H +#define CSOUND_FILEBUILDING_H + +#include "csound.h" +/** \file + * \brief Csound API functions to create, build up, and save CSD files. + * \author Michael Gogins + * + * \b Purpose + * + * The purpose of these functions is to make it easier for clients + * of the Csound API to programmatically build up CSD files, + * including set instrument definitions, set options, + * and especially append score statements. + * + * There are also convenience functions to compile and perform + * the saved CSD file. + */ +#ifndef PUBLIC +#if (defined(WIN32) || defined(_WIN32)) && !defined(SWIG) +# define PUBLIC __declspec(dllexport) +#elif defined(__GNUC__) && !defined(__MACH__) +# define PUBLIC __attribute__ ( (visibility("default")) ) +#else +# define PUBLIC +#endif +#endif + + /** + * Enables Python interface. + */ + +#ifdef SWIG +#define CS_PRINTF2 +#define CS_PRINTF3 +#include "float-version.h" +#ifndef __MYFLT_DEF +#define __MYFLT_DEF +#ifndef USE_DOUBLE +#define MYFLT float +#else +#define MYFLT double +#endif +#endif +%module filebuilding +%{ +# include "sysdep.h" +# include "text.h" +# include "csound.h" +# include +%} +#else +# include "sysdep.h" +# include "text.h" +# include "csound.h" +# include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + + +/** + * Initialize an internal CSD file. + */ + PUBLIC void csoundCsdCreate(CSOUND *csound); + +/** + * Set the CsOptions element of the internal CSD file. + */ +PUBLIC void csoundCsdSetOptions(CSOUND *csound, char *options); + +/** + * Return the CsOptions element of the internal CSD file. + */ +PUBLIC const char* csoundCsdGetOptions(CSOUND *csound); + +/** + * Set the CsInstruments element of the internal CSD file. + */ +PUBLIC void csoundCsdSetOrchestra(CSOUND *csound, char *orchestra); + +/** + * Return the CsInstruments element of the internal CSD file. + */ +PUBLIC const char* csoundCsdGetOrchestra(CSOUND *csound); + +/** + * Append a line of text to the CsScore element of the internal CSD file. + */ +PUBLIC void csoundCsdAddScoreLine(CSOUND *csound, char *line); + +/** + * Append an 'i' event to the CsScore element of the internal CSD file. + */ +PUBLIC void csoundCsdAddEvent11(CSOUND *csound, double p1, double p2, double p3, + double p4, double p5, double p6, double p7, + double p8, double p9, double p10, double p11); + +/** + * Append an 'i' event to the CsScore element of the internal CSD file. + */ +PUBLIC void csoundCsdAddEvent10(CSOUND *csound, double p1, double p2, double p3, + double p4, double p5, double p6, double p7, + double p8, double p9, double p10); + +/** + * Append an 'i' event to the CsScore element of the internal CSD file. + */ +PUBLIC void csoundCsdAddEvent9(CSOUND *csound, double p1, double p2, double p3, + double p4, double p5, double p6, double p7, + double p8, double p9); + +/** + * Append an 'i' event to the CsScore element of the internal CSD file. + */ +PUBLIC void csoundCsdAddEvent8(CSOUND *csound, double p1, double p2, double p3, + double p4, double p5, double p6, double p7, + double p8); + +/** + * Append an 'i' event to the CsScore element of the internal CSD file. + */ +PUBLIC void csoundCsdAddEvent7(CSOUND *csound, double p1, double p2, double p3, + double p4, double p5, double p6, double p7); + +/** + * Append an 'i' event to the CsScore element of the internal CSD file. + */ +PUBLIC void csoundCsdAddEvent6(CSOUND *csound, double p1, double p2, double p3, + double p4, double p5, double p6); + +/** + * Append an 'i' event to the CsScore element of the internal CSD file. + */ +PUBLIC void csoundCsdAddEvent5(CSOUND *csound, double p1, double p2, double p3, + double p4, double p5); + +/** + * Append an 'i' event to the CsScore element of the internal CSD file. + */ +PUBLIC void csoundCsdAddEvent4(CSOUND *csound, double p1, double p2, double p3, + double p4); + +/** + * Append an 'i' event to the CsScore element of the internal CSD file. + */ +PUBLIC void csoundCsdAddEvent3(CSOUND *csound, double p1, double p2, double p3); + +/** + * Save the internal CSD file to the indicated filename, which must end in '.csd'. + */ +PUBLIC int csoundCsdSave(CSOUND *csound, char *filename); + +/** + * Convenience function that saves the internal CSD file to the indicated filename, + * which must end in '.csd, then performs the file. + */ +PUBLIC int csoundCsdCompile(CSOUND *csound, char *filename); + +/** + * Convenience function that saves the internal CSD file to the indicated filename, + * which must end in '.csd, then compiles the file for later performance. + */ +PUBLIC int csoundCsdPerform(CSOUND *csound, char *filename); + + + /* VL: a new, more complete, version of this function has been added to the main + Csound library. + PUBLIC int csoundCompileCsd(CSOUND *, char *csdFilename); + */ + +/** + * Compiles and renders a Csound performance, + * as directed by the supplied CSD file, + * in one pass. Returns 0 for success. + */ +PUBLIC int csoundPerformCsd(CSOUND *, char *csdFilename); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/6.x/csound/find_opcode.h b/6.x/csound/find_opcode.h new file mode 100644 index 00000000..94d00c8a --- /dev/null +++ b/6.x/csound/find_opcode.h @@ -0,0 +1,35 @@ +/* + find_opcode.h: + + Copyright (C) 2016 by John ffitc + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ +#ifndef _FIND_OPCODE_H_ +#define _FIND_OPCODE_H_ + +char* get_opcode_short_name(CSOUND* csound, char* opname); + +PUBLIC OENTRY* find_opcode_new(CSOUND* csound, char* opname, + char* outArgsFound, char* inArgsFound); +PUBLIC OENTRY* find_opcode_exact(CSOUND* csound, char* opname, + char* outArgsFound, char* inArgsFound); +/* find OENTRY with the specified name in opcode list */ + +OENTRY* find_opcode(CSOUND *, char *); +#endif diff --git a/6.x/csound/float-version.h b/6.x/csound/float-version.h new file mode 100644 index 00000000..ebc595b1 --- /dev/null +++ b/6.x/csound/float-version.h @@ -0,0 +1,35 @@ +/* + float-version.h: + + Copyright (C) 1991-2010 Victor Lazzarini + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +/* this file can be copied as float-version.h in installers for double precision + currently implemented only for OSX +*/ + +#ifndef FLOAT_VERSION_H +#define FLOAT_VERSION_H + +#if !defined(USE_DOUBLE) +#define USE_DOUBLE +#endif + +#endif diff --git a/6.x/csound/interlocks.h b/6.x/csound/interlocks.h new file mode 100644 index 00000000..b636160d --- /dev/null +++ b/6.x/csound/interlocks.h @@ -0,0 +1,56 @@ +/* + interlocks.h: + + Copyright (C) 2011 John ffitch + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +// ZAK +#define ZR (0x0001) +#define ZW (0x0002) +#define ZB (0x0003) + +// Writes to inputs +#define WI (0x0004) + +//Tables +#define TR (0x0008) +#define TW (0x0010) +#define TB (0x0018) + +//Channels +#define _CR (0x0020) +#define _CW (0x0040) +#define _CB (0x0060) + +//Stack +#define SK (0x0080) + +//Printing +#define WR (0x0100) + +// Internal oddities -- SPOUT +#define IR (0x0200) +#define IW (0x0400) +#define IB (0x0600) + +//Deprecated +#define _QQ (0x8000) + + diff --git a/6.x/csound/modload.h b/6.x/csound/modload.h new file mode 100644 index 00000000..aa4cac2b --- /dev/null +++ b/6.x/csound/modload.h @@ -0,0 +1,56 @@ +/* + modload.h + CPOF Csound Plugin Opcode Framework + module load C functions and entry point + + (c) Victor Lazzarini, 2017 + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA + +*/ +#ifndef __MODLOAD__H +#define __MODLOAD__H + +#include + +#if defined(__wasi__) + #undef PUBLIC + #define PUBLIC extern __attribute__((used)) +#endif + +namespace csnd { +/** Plugin library entry point + */ +void on_load(Csound *); +} + +extern "C" { +PUBLIC int csoundModuleCreate(CSOUND *csound) { + IGN(csound); + return 0; +} +PUBLIC int csoundModuleDestroy(CSOUND *csound) { + IGN(csound); + return 0; +} +PUBLIC int csoundModuleInit(CSOUND *csound) { + csnd::on_load((csnd::Csound *)csound); + return 0; +} +} +#endif diff --git a/6.x/csound/msg_attr.h b/6.x/csound/msg_attr.h new file mode 100644 index 00000000..89d9aa3e --- /dev/null +++ b/6.x/csound/msg_attr.h @@ -0,0 +1,73 @@ +/* + msg_attr.h: + + Copyright (C) 2005 Istvan Varga + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef CSOUND_MSG_ATTR_H +#define CSOUND_MSG_ATTR_H + +/* message types (only one can be specified) */ + +/* standard message */ +#define CSOUNDMSG_DEFAULT (0x0000) +/* error message (initerror, perferror, etc.) */ +#define CSOUNDMSG_ERROR (0x1000) +/* orchestra opcodes (e.g. printks) */ +#define CSOUNDMSG_ORCH (0x2000) +/* for progress display and heartbeat characters */ +#define CSOUNDMSG_REALTIME (0x3000) +/* warning messages */ +#define CSOUNDMSG_WARNING (0x4000) +/* stdount messages */ +#define CSOUNDMSG_STDOUT (0x5000) + +/* format attributes (colors etc.), use the bitwise OR of any of these: */ + +#define CSOUNDMSG_FG_BLACK (0x0100) +#define CSOUNDMSG_FG_RED (0x0101) +#define CSOUNDMSG_FG_GREEN (0x0102) +#define CSOUNDMSG_FG_YELLOW (0x0103) +#define CSOUNDMSG_FG_BLUE (0x0104) +#define CSOUNDMSG_FG_MAGENTA (0x0105) +#define CSOUNDMSG_FG_CYAN (0x0106) +#define CSOUNDMSG_FG_WHITE (0x0107) + +#define CSOUNDMSG_FG_BOLD (0x0008) +#define CSOUNDMSG_FG_UNDERLINE (0x0080) + +#define CSOUNDMSG_BG_BLACK (0x0200) +#define CSOUNDMSG_BG_RED (0x0210) +#define CSOUNDMSG_BG_GREEN (0x0220) +#define CSOUNDMSG_BG_ORANGE (0x0230) +#define CSOUNDMSG_BG_BLUE (0x0240) +#define CSOUNDMSG_BG_MAGENTA (0x0250) +#define CSOUNDMSG_BG_CYAN (0x0260) +#define CSOUNDMSG_BG_GREY (0x0270) + + /* ------------------------------------------------------------------------ */ + +#define CSOUNDMSG_TYPE_MASK (0x7000) +#define CSOUNDMSG_FG_COLOR_MASK (0x0107) +#define CSOUNDMSG_FG_ATTR_MASK (0x0088) +#define CSOUNDMSG_BG_COLOR_MASK (0x0270) + +#endif /* CSOUND_MSG_ATTR_H */ + diff --git a/6.x/csound/pffft.h b/6.x/csound/pffft.h new file mode 100644 index 00000000..7e763e02 --- /dev/null +++ b/6.x/csound/pffft.h @@ -0,0 +1,183 @@ +/* Copyright (c) 2013 Julien Pommier ( pommier@modartt.com ) + + Based on original fortran 77 code from FFTPACKv4 from NETLIB, + authored by Dr Paul Swarztrauber of NCAR, in 1985. + + As confirmed by the NCAR fftpack software curators, the following + FFTPACKv5 license applies to FFTPACKv4 sources. My changes are + released under the same terms. + + FFTPACK license: + + http://www.cisl.ucar.edu/css/software/fftpack5/ftpk.html + + Copyright (c) 2004 the University Corporation for Atmospheric + Research ("UCAR"). All rights reserved. Developed by NCAR's + Computational and Information Systems Laboratory, UCAR, + www.cisl.ucar.edu. + + Redistribution and use of the Software in source and binary forms, + with or without modification, is permitted provided that the + following conditions are met: + + - Neither the names of NCAR's Computational and Information Systems + Laboratory, the University Corporation for Atmospheric Research, + nor the names of its sponsors or contributors may be used to + endorse or promote products derived from this Software without + specific prior written permission. + + - Redistributions of source code must retain the above copyright + notices, this list of conditions, and the disclaimer below. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions, and the disclaimer below in the + documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE + SOFTWARE. +*/ + +/* + PFFFT : a Pretty Fast FFT. + + This is basically an adaptation of the single precision fftpack + (v4) as found on netlib taking advantage of SIMD instruction found + on cpus such as intel x86 (SSE1), powerpc (Altivec), and arm (NEON). + + For architectures where no SIMD instruction is available, the code + falls back to a scalar version. + + Restrictions: + + - 1D transforms only, with 32-bit single precision. + + - supports only transforms for inputs of length N of the form + N=(2^a)*(3^b)*(5^c), a >= 5, b >=0, c >= 0 (32, 48, 64, 96, 128, + 144, 160, etc are all acceptable lengths). Performance is best for + 128<=N<=8192. + + - all (float*) pointers in the functions below are expected to + have an "simd-compatible" alignment, that is 16 bytes on x86 and + powerpc CPUs. + + You can allocate such buffers with the functions + pffft_aligned_malloc / pffft_aligned_free (or with stuff like + posix_memalign..) + +*/ + +#ifndef PFFFT_H +#define PFFFT_H + +#include // for size_t + +#ifdef __cplusplus +extern "C" { +#endif + + /* opaque struct holding internal stuff (precomputed twiddle factors) + this struct can be shared by many threads as it contains only + read-only data. + */ + typedef struct PFFFT_Setup PFFFT_Setup; + + /* direction of the transform */ + typedef enum { PFFFT_FORWARD, PFFFT_BACKWARD } pffft_direction_t; + + /* type of transform */ + typedef enum { PFFFT_REAL, PFFFT_COMPLEX } pffft_transform_t; + + /* + prepare for performing transforms of size N -- the returned + PFFFT_Setup structure is read-only so it can safely be shared by + multiple concurrent threads. + */ + PFFFT_Setup *pffft_new_setup(int N, pffft_transform_t transform); + void pffft_destroy_setup(PFFFT_Setup *); + /* + Perform a Fourier transform , The z-domain data is stored in the + most efficient order for transforming it back, or using it for + convolution. If you need to have its content sorted in the + "usual" way, that is as an array of interleaved complex numbers, + either use pffft_transform_ordered , or call pffft_zreorder after + the forward fft, and before the backward fft. + + Transforms are not scaled: PFFFT_BACKWARD(PFFFT_FORWARD(x)) = N*x. + Typically you will want to scale the backward transform by 1/N. + + The 'work' pointer should point to an area of N (2*N for complex + fft) floats, properly aligned. If 'work' is NULL, then stack will + be used instead (this is probably the best strategy for small + FFTs, say for N < 16384). + + input and output may alias. + */ + void pffft_transform(PFFFT_Setup *setup, const float *input, float *output, + float *work, pffft_direction_t direction); + + /* + Similar to pffft_transform, but makes sure that the output is + ordered as expected (interleaved complex numbers). This is + similar to calling pffft_transform and then pffft_zreorder. + + input and output may alias. + */ + void pffft_transform_ordered(PFFFT_Setup *setup, const float *input, + float *output, float *work, + pffft_direction_t direction); + + /* + call pffft_zreorder(.., PFFFT_FORWARD) after pffft_transform(..., + PFFFT_FORWARD) if you want to have the frequency components in + the correct "canonical" order, as interleaved complex numbers. + + (for real transforms, both 0-frequency and half frequency + components, which are real, are assembled in the first entry as + F(0)+i*F(n/2+1). Note that the original fftpack did place + F(n/2+1) at the end of the arrays). + + input and output should not alias. + */ + void pffft_zreorder(PFFFT_Setup *setup, const float *input, float *output, + pffft_direction_t direction); + + /* + Perform a multiplication of the frequency components of dft_a and + dft_b and accumulate them into dft_ab. The arrays should have + been obtained with pffft_transform(.., PFFFT_FORWARD) and should + *not* have been reordered with pffft_zreorder (otherwise just + perform the operation yourself as the dft coefs are stored as + interleaved complex numbers). + + the operation performed is: dft_ab += (dft_a * fdt_b)*scaling + + The dft_a, dft_b and dft_ab pointers may alias. + */ + void pffft_zconvolve_accumulate(PFFFT_Setup *setup, const float *dft_a, + const float *dft_b, float *dft_ab, float scaling); + + /* + the float buffers must have the correct alignment (16-byte boundary + on intel and powerpc). This function may be used to obtain such + correctly aligned buffers. + */ + void *pffft_aligned_malloc(size_t nb_bytes); + void pffft_aligned_free(void *); + + /* return 4 or 1 whether support SSE/Altivec instructions was enable when + building pffft.c */ + int pffft_simd_size(void); + +#ifdef __cplusplus +} +#endif + +#endif // PFFFT_H diff --git a/6.x/csound/plugin.h b/6.x/csound/plugin.h new file mode 100644 index 00000000..080db7bb --- /dev/null +++ b/6.x/csound/plugin.h @@ -0,0 +1,1230 @@ +/* + plugin.h + CPOF Csound Plugin Opcode Framework + C++ plugin opcode interface + + (c) Victor Lazzarini, 2017 + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA + +*/ + +#ifndef _PLUGIN_H_ +#define _PLUGIN_H_ +#include "csdl.h" +#include "pstream.h" +#include "arrays.h" +#include +#include +#include +#include +#include + +namespace csnd { + +/* constants */ +const double twopi = TWOPI; + +/** opcode threads: i-time, k-perf and/or a-perf +*/ +enum thread { i = 1, k = 2, ik = 3, a = 4, ia = 5 /*, ika = 3*/ }; + +/** fsig formats: phase vocoder, stft polar, stft complex, or + sinusoidal tracks +*/ +enum fsig_format { pvs = 0, polar, complex, tracks }; + +typedef CSOUND_FFT_SETUP *fftp; + +/** Csound Engine object. + */ +class Csound : CSOUND { + + /** Utility classes + */ + template friend class Vector; + friend class Fsig; + friend class Table; + template friend class AuxMem; + + /** + @private + opcode function template (deinit-time) + */ + template static int deinit(CSOUND *csound, void *p) { + return ((T *)p)->deinit(); + } + +public: + /** Host Data + */ + void *host_data() { return GetHostData(this); } + + /** init-time error message + */ + int init_error(const std::string &s) { + return InitError(this, "%s\n", LocalizeString(s.c_str())); + } + + /** perf-time error message + */ + int perf_error(const std::string &s, OPDS *inst) { + return PerfError(this, inst, "%s\n", LocalizeString(s.c_str())); + } + + /** warning message + */ + void warning(const std::string &s) { + Warning(this, "%s", LocalizeString(s.c_str())); + } + + /** console messages + */ + void message(const std::string &s) { + Message(this, "%s\n", LocalizeString(s.c_str())); + } + + /** system sampling rate + */ + MYFLT sr() { return GetSr(this); } + + /** system control rate + */ + MYFLT kr() { return GetKr(this); } + + /** system max amp reference + */ + MYFLT _0dbfs() { return Get0dBFS(this); } + + /** system A4 reference + */ + MYFLT _A4() { return GetA4(this); } + + /** number of audio channels (out) + */ + uint32_t nchnls() { return GetNchnls(this); } + + /** number of audio channels (in) + */ + uint32_t nchnls_i() { return GetNchnls_i(this); } + + /** time count (samples) + */ + int64_t current_time_samples() { return GetCurrentTimeSamples(this); } + + /** time count (seconds) + */ + double current_time_seconds() { + return GetCurrentTimeSamples(this) / GetSr(this); + } + + /** check for audio signal variable argument + */ + bool is_asig(void *arg) { + return !std::strcmp(GetTypeForArg(arg)->varTypeName, "a"); + } + + /** midi channel number for this instrument + */ + int midi_channel(OPDS *p) { return GetMidiChannelNumber(p); } + + /** midi note number for this instrument + */ + int midi_note_num(OPDS *p) { return GetMidiNoteNumber(p); } + + /** midi note velocity for this instrument + */ + int midi_note_vel(OPDS *p) { return GetMidiVelocity(p); } + + /** midi aftertouch for this channel + */ + MYFLT midi_chn_aftertouch(OPDS *p) { + return GetMidiChannel(p)->aftouch; } + + /** midi poly aftertouch for this channel + */ + MYFLT midi_chn_polytouch(OPDS *p, uint32_t note) { + return GetMidiChannel(p)->polyaft[note]; + } + + /** midi ctl change for this channel + */ + MYFLT midi_chn_ctl(OPDS *p, uint32_t ctl) { + return GetMidiChannel(p)->ctl_val[ctl]; + } + + /** midi pitchbend for this channel + */ + MYFLT midi_chn_pitchbend(OPDS *p) { + return GetMidiChannel(p)->pchbend; + } + + /** list of active instrument instances for this channel \n + returns an INSDS array with 128 items, one per + MIDI note number. Inactive instances are marked NULL. + */ + const INSDS *midi_chn_list(OPDS *p) { + return (const INSDS *) GetMidiChannel(p)->kinsptr; + } + + /** deinit registration for a given plugin class + */ + template void plugin_deinit(T *p) { + RegisterDeinitCallback(this, (void *)p, deinit); + } + + /** Csound memory allocation - malloc style + */ + void *malloc(size_t size) { return Malloc(this, size); } + + /** Csound memory allocation - calloc style + */ + void *calloc(size_t size) { return Calloc(this, size); } + + /** Csound memory re-allocation + */ + void *realloc(void *p, size_t size) { return ReAlloc(this, p, size); } + + /** Csound string duplication + */ + char *strdup(char *s) { return Strdup(this, s); } + + /** Csound memory de-allocation + */ + void free(void *p) { Free(this, p); } + + /** FFT setup: real-to-complex and complex-to-real \n + direction: FFT_FWD or FFT_INV \n + returns a handle to the FFT setup. + */ + fftp fft_setup(uint32_t size, uint32_t direction) { + return (fftp)RealFFT2Setup(this, size, direction); + } + + /** FFT operation, in-place, but also + returning a pointer to std::complex + to the transformed data memory. + */ + std::complex *rfft(fftp setup, MYFLT *data) { + if (!setup->p2) { + if (setup->d == FFT_FWD) + RealFFTnp2(this, data, setup->N); + else + InverseRealFFTnp2(this, data, setup->N); + } else + RealFFT2(this, setup, data); + return reinterpret_cast *>(data); + } + + /** FFT operation for complex data, in-place, but also + returning a pointer to std::complex + to the transformed data memory. + */ + std::complex *fft(fftp setup, std::complex *data) { + MYFLT *fdata = reinterpret_cast(data); + if (setup->d == FFT_FWD) + ComplexFFT(this, fdata, setup->N); + else + ComplexFFT(this, fdata, setup->N); + return reinterpret_cast *>(fdata); + } + + /** Creates a global variable in the current Csound object + */ + int create_global_variable(const char *name, size_t nbytes) { + return CreateGlobalVariable(this, name, nbytes); + } + + /** Retrieves a ptr for an existing named global variable + */ + void *query_global_variable(const char* name) { + return QueryGlobalVariable(this, name); + } + + /** Destroy an existing named global variable + */ + int destroy_global_variable(const char* name) { + return DestroyGlobalVariable(this, name); + } + + /** Access to the base CSOUND object + */ + CSOUND *get_csound() { + return this; + } + + /** Sleep + */ + void sleep(int ms) { Sleep(ms); } +}; + +/** + Thread pure virtual base class + */ +class Thread { + void *thread; + static uintptr_t thrdRun(void *t) { return ((Thread *)t)->run(); } + virtual uintptr_t run() = 0; + +protected: + Csound *csound; + +public: + Thread(Csound *cs) : csound(cs) { + CSOUND *p = (CSOUND *)csound; + thread = p->CreateThread(thrdRun, (void *)this); + } + + uintptr_t join() { + CSOUND *p = (CSOUND *)csound; + return p->JoinThread(thread); + } + void *get_thread() { return thread; } +}; + +/** Class AudioSig wraps an audio signal + */ +class AudioSig { + uint32_t early; + uint32_t offset; + uint32_t nsmps; + MYFLT *sig; + +public: + /** Constructor takes the plugin object and the + audio argument pointer, and a reset flag if + we need to clear an output buffer + */ + AudioSig(OPDS *p, MYFLT *s, bool res = false) + : early(p->insdshead->ksmps_no_end), offset(p->insdshead->ksmps_offset), + nsmps(p->insdshead->ksmps - p->insdshead->ksmps_no_end), sig(s) { + if (res) { + std::fill(sig, sig + p->insdshead->ksmps, 0); + } + }; + + /** iterator type + */ + typedef MYFLT *iterator; + + /** const_iterator type + */ + typedef const MYFLT *const_iterator; + + /** vector beginning + */ + iterator begin() { return sig + offset; } + + /** vector end + */ + iterator end() { return sig + nsmps; } + + /** vector beginning + */ + const_iterator begin() const { return sig + offset; } + + /** vector end + */ + const_iterator end() const { return sig + nsmps; } + + /** vector beginning + */ + const_iterator cbegin() const { return sig + offset; } + + /** vector end + */ + const_iterator cend() const { return sig + nsmps; } + + /** array subscript access (write) + */ + MYFLT &operator[](int n) { return sig[n]; } + + /** array subscript access (read) + */ + const MYFLT &operator[](int n) const { return sig[n]; } + + /** get early exit sample position + */ + uint32_t GetEarly() { return early; } + + /** get early exit sample offset + */ + uint32_t GetOffset() { return offset; } + + /** get number of samples to process + */ + uint32_t GetNsmps() { return nsmps; } +}; + +/** One-dimensional array container + template class + */ +template class Vector : ARRAYDAT { + +public: + /** Initialise the container + */ + void init(Csound *csound, int size) { + tabinit(csound, this, size); + } + + /** iterator type + */ + typedef T *iterator; + + /** const_iterator type + */ + typedef const T *const_iterator; + + /** vector beginning + */ + iterator begin() { return (T *)data; } + + /** vector end + */ + iterator end() { return (T *)((char *)data + sizes[0] * arrayMemberSize); } + + /** vector beginning + */ + const_iterator cbegin() const { return (const T *)data; } + + /** vector end + */ + const_iterator cend() const { + return (const T *)((char *)data + sizes[0] * arrayMemberSize); + } + + /** vector beginning + */ + const_iterator begin() const { return (const T *)data; } + + /** vector end + */ + const_iterator end() const { + return (const T *)((char *)data + sizes[0] * arrayMemberSize); + } + + /** array subscript access (write) + */ + T &operator[](int n) { return ((T *)data)[n]; } + + /** array subscript access (read) + */ + const T &operator[](int n) const { return ((T *)data)[n]; } + + /** array subscript access (read) + */ + uint32_t len() { return sizes[0]; } + + /** element offset + */ + uint32_t elem_offset() { return arrayMemberSize / sizeof(T); } + + /** array data + */ + T *data_array() { return (T *)data; } +}; + +typedef Vector myfltvec; +typedef std::complex pvscmplx; +typedef std::complex sldcmplx; + +/** Pvbin holds one Phase Vocoder bin + */ +template class Pvbin { + T am; + T fr; + +public: + /** constructor + */ + Pvbin() : am((T)0), fr((T)0){}; + + /** access amplitude + */ + T amp() { return am; } + + /** access frequency + */ + T freq() { return fr; } + + /** set amplitude + */ + T amp(T a) { return (am = a); } + + /** set frequency + */ + T freq(T f) { return (fr = f); } + + /** multiplication (unary) + */ + const Pvbin &operator*=(const Pvbin &bin) { + am *= bin.am; + fr = bin.fr; + return *this; + } + + /** multiplication (binary) + */ + Pvbin operator*(const Pvbin &a) { + Pvbin res = *this; + return (res *= a); + } + + /** multiplication by MYFLT (unary) + */ + const Pvbin &operator*=(MYFLT f) { + am *= f; + return *this; + } + + /** multiplication by MYFLT (binary) + */ + Pvbin operator*(MYFLT f) { + Pvbin res = *this; + return (res *= f); + } + + /** cast to std::complex& + */ + operator pvscmplx &() { return (pvscmplx &)reinterpret_cast(*this); } + + /** cast to std::complex* + */ + operator pvscmplx *() { return (pvscmplx *)reinterpret_cast(this); } +}; + +/** Phase Vocoder bin */ +typedef Pvbin pv_bin; + +/** Sliding Phase Vocoder bin */ +typedef Pvbin spv_bin; + +template class Pvframe; + +/** Phase Vocoder frame */ +typedef Pvframe pv_frame; + +/** Sliding Phase Vocoder frame */ +typedef Pvframe spv_frame; + +/** fsig base class, holds PVSDAT data + */ +class Fsig : protected PVSDAT { +public: + /** initialise the object, allocating memory + if necessary. + */ + void init(Csound *csound, int32_t n, int32_t h, int32_t w, int32_t t, + int32_t f, int32_t nb = 0, int32_t sl = 0, uint32_t nsmps = 1) { + N = n; + overlap = h; + winsize = w; + wintype = t; + format = f; + NB = nb; + sliding = sl; + if (!sliding) { + size_t bytes = (n + 2) * sizeof(float); + if (frame.auxp == nullptr || frame.size < bytes) { + csound->AuxAlloc(csound, bytes, &frame); + std::fill((float *)frame.auxp, (float *)frame.auxp + n + 2, 0); + } + } else { + size_t bytes = (n + 2) * sizeof(MYFLT) * nsmps; + if (frame.auxp == NULL || frame.size < bytes) + csound->AuxAlloc(csound, bytes, &frame); + } + framecount = 1; + } + void init(Csound *csound, const Fsig &f, uint32_t nsmps = 1) { + init(csound, f.N, f.overlap, f.winsize, f.wintype, f.format, f.NB, + f.sliding, nsmps); + } + + /** get the DFT size + */ + uint32_t dft_size() { return N; } + + /** get the analysis hop size + */ + uint32_t hop_size() { return overlap; } + + /** get the analysis window size + */ + uint32_t win_size() { return winsize; } + + /** get the window type + */ + int32_t win_type() { return wintype; } + + /** get the number of bins + */ + uint32_t nbins() { return N / 2 + 1; } + + /** get the framecount + */ + uint32_t count() const { return framecount; } + + /** set framecount + */ + uint32_t count(uint32_t cnt) { return (framecount = cnt); } + + /** check for sliding mode + */ + bool isSliding() { return (bool)sliding; } + + /** get fsig data format + */ + int fsig_format() { return format; } + + /** get data frame as floats + */ + float *data() { return (float *) frame.auxp; } + + /** convert to pv_frame ref + */ + operator pv_frame &() { return reinterpret_cast(*this); } + +#ifdef USE_DOUBLE + /** convert to spv_frame ref + */ + operator spv_frame &() { return reinterpret_cast(*this); } +#endif + +}; + +/** Container class for a Phase Vocoder + analysis frame +*/ +template class Pvframe : public Fsig { + +public: + /** iterator type + */ + typedef T *iterator; + + /** const_iterator type + */ + typedef const T *const_iterator; + + /** returns an iterator to the + beginning of the frame + */ + iterator begin() { return (T *)frame.auxp; } + + /** returns an iterator to the + end of the frame + */ + iterator end() { return (T *)frame.auxp + N / 2 + 1; } + + /** returns a const iterator to the + beginning of the frame + */ + const_iterator begin() const { return (const T *)frame.auxp; } + + /** returns a const iterator to the + end of the frame + */ + const_iterator end() const { return (const T *)(frame.auxp + N / 2 + 1); } + + /** returns a const iterator to the + beginning of the frame + */ + const_iterator cbegin() const { return (const T *)frame.auxp; } + + /** returns a const iterator to the + end of the frame + */ + const_iterator cend() const { return (const T *)(frame.auxp + N / 2 + 1); } + + /** array subscript access operator (write) + */ + T &operator[](int n) { return ((T *)frame.auxp)[n]; } + + /** array subscript access operator (read) + */ + const T &operator[](int n) const { return ((T *)frame.auxp)[n]; } + + /** frame data pointer + */ + T *data() const { return (T *)frame.auxp; } + + /** return the container length + */ + uint32_t len() { return nbins(); } +}; + +/** function table container class + */ +class Table : FUNC { + +public: + /** Initialise this object from an opcode + argument arg */ + int init(Csound *csound, MYFLT *arg) { + Table *f = (Table *)csound->FTnp2Finde(csound, arg); + if (f != nullptr) { + std::copy(f, f + 1, this); + return OK; + } + return NOTOK; + } + + /** iterator type + */ + typedef MYFLT *iterator; + + /** const_iterator type + */ + typedef const MYFLT *const_iterator; + + /** returns an iterator to the + beginning of the table + */ + iterator begin() { return ftable; } + + /** returns an iterator to the + end of the table + */ + iterator end() { return ftable + flen; } + + /** returns a const iterator to the + beginning of the table + */ + const_iterator begin() const { return ftable; } + + /** returns a const iterator to the + end of the table + */ + const_iterator end() const { return ftable + flen; } + + /** returns a const iterator to the + beginning of the table + */ + const_iterator cbegin() const { return ftable; } + + /** returns a const iterator to the + end of the table + */ + const_iterator cend() const { return ftable + flen; } + + /** array subscript access operator (write) + */ + MYFLT &operator[](int n) { return ftable[n]; } + + /** array subscript access operator (read) + */ + const MYFLT &operator[](int n) const { return ftable[n]; } + + /** function table data pointer + */ + MYFLT *data() const { return ftable; } + + /** function table length + */ + uint32_t len() { return flen; } +}; + +/** vector container template using Csound AuxAlloc + mechanism for dynamic memory allocation + */ +template class AuxMem : AUXCH { + +public: + /** allocate memory for the container + */ + void allocate(Csound *csound, int n) { + size_t bytes = n * sizeof(T); + if (auxp == nullptr || size != bytes) { + csound->AuxAlloc(csound, bytes, (AUXCH *)this); + std::fill((char *)auxp, (char *)endp, 0); + } + } + + /** iterator type + */ + typedef T *iterator; + + /** const_iterator type + */ + typedef const T *const_iterator; + + /** vector beginning + */ + iterator begin() { return (T *)auxp; } + + /** vector end + */ + iterator end() { return (T *)endp; } + + /** vector beginning (const iterator) + */ + const_iterator begin() const { return (const T *)auxp; } + + /** vector end (const iterator) + */ + const_iterator end() const { return (const T *)endp; } + + /** vector beginning (const iterator) + */ + const_iterator cbegin() const { return (const T *)auxp; } + + /** vector end (const iterator) + */ + const_iterator cend() const { return (const T *)endp; } + + /** array subscript access (write) + */ + T &operator[](int n) { return ((T *)auxp)[n]; } + + /** array subscript access (read) + */ + const T &operator[](int n) const { return ((T *)auxp)[n]; } + + /** returns a pointer to the vector data + */ + T *data() { return (T *)auxp; } + + /** returns the length of the vector + */ + uint32_t len() { return size / sizeof(T); } +}; + + + +/** Parameters template class + */ + template class Param { + std::array ptrs; + +public: + /** parameter access via array subscript (write) + */ + MYFLT &operator[](int n) { return *ptrs[n]; } + + /** parameter access via array subscript (read) + */ + const MYFLT &operator[](int n) const { return *ptrs[n]; } + + /** iterator type + */ + typedef MYFLT **iterator; + + /** const_iterator type + */ + typedef const MYFLT **const_iterator; + + /** vector beginning + */ + iterator begin() { return &ptrs[0]; } + + /** vector end + */ + iterator end() { return &ptrs[N]; } + + /** vector beginning + */ + const_iterator begin() const { return (const MYFLT **)&ptrs[0]; } + + /** vector end + */ + const_iterator end() const { return (const MYFLT **)&ptrs[N]; } + + /** vector beginning + */ + const_iterator cbegin() const { return (const MYFLT **)&ptrs[0]; } + + /** vector end + */ + const_iterator cend() const { return (const MYFLT **)&ptrs[N]; } + + /** parameter data (MYFLT pointer) at index n + */ + MYFLT *operator()(int n) { return ptrs[n]; } + + /** @private: + same as operator() + */ + MYFLT *data(int n) { return ptrs[n]; } + + /** parameter string data (STRINGDAT ref) at index n + */ + STRINGDAT &str_data(int n) { return (STRINGDAT &)*ptrs[n]; } + + /** parameter fsig data (Fsig ref) at index n + */ + Fsig &fsig_data(int n) { return (Fsig &)*ptrs[n]; } + + /** 1-D array data as Vector template ref + */ + template Vector &vector_data(int n) { + return (Vector &)*ptrs[n]; + } + + /** returns 1-D numeric array data + */ + myfltvec &myfltvec_data(int n) { return (myfltvec &)*ptrs[n]; } + +}; + +/** InPlug template base class: + for 0 outputs and N inputs + also for multiple outputs and/or inputs + */ +template struct InPlug : OPDS { + /** arguments */ + Param args; + /** Csound engine */ + Csound *csound; + /** sample-accurate offset */ + uint32_t offset; + /** vector samples to process */ + uint32_t nsmps; + + /** i-time function placeholder + */ + int init() { return OK; } + + /** k-rate function placeholder + */ + int kperf() { return OK; } + + /** a-rate function placeholder + */ + int aperf() { return OK; } + + /** @private + sample-accurate offset for + a-rate opcodes; updates offset + and nsmps. Called implicitly by + the aperf() method. + */ + void sa_offset() { + uint32_t early = insdshead->ksmps_no_end; + nsmps = insdshead->ksmps - early; + offset = insdshead->ksmps_offset; + } + + /** @private + set nsmps and offset value for kperf() + */ + void nsmps_set() { + nsmps = insdshead->ksmps - insdshead->ksmps_no_end; + offset = insdshead->ksmps_offset; + } + + /** returns the number of output arguments + used in the case of variable output count + */ + uint32_t out_count() { return (uint32_t)optext->t.outArgCount; } + + /** returns the number of input arguments + used in the case of variable input count + */ + uint32_t in_count() { return (uint32_t)optext->t.inArgCount; } + + /** local control rate + */ + MYFLT kr() { return insdshead->ekr; } + + /** local ksmps + */ + MYFLT ksmps() { return insdshead->ksmps; } + + /** sampling rate + */ + MYFLT sr() { return csound->sr(); } + + /** midi channel number for this instrument + */ + int midi_channel() { return ((CSOUND *)csound)->GetMidiChannelNumber(this); } + + /** midi note number for this instrument + */ + int midi_note_num() { return ((CSOUND *)csound)->GetMidiNoteNumber(this); } + + /** midi note velocity for this instrument + */ + int midi_note_vel() { return ((CSOUND *)csound)->GetMidiVelocity(this); } + + /** midi aftertouch for this channel + */ + MYFLT midi_chn_aftertouch() { + return ((CSOUND *)csound)->GetMidiChannel(this)->aftouch; } + + /** midi poly aftertouch for this channel + */ + MYFLT midi_chn_polytouch(uint32_t note) { + return ((CSOUND *)csound)->GetMidiChannel(this)->polyaft[note]; + } + + /** midi ctl change for this channel + */ + MYFLT midi_chn_ctl(uint32_t ctl) { + return ((CSOUND *)csound)->GetMidiChannel(this)->ctl_val[ctl]; + } + + /** midi pitchbend for this channel + */ + MYFLT midi_chn_pitchbend() { + return ((CSOUND *)csound)->GetMidiChannel(this)->pchbend; } + + /** list of active instrument instances for this channel \n + returns an INSDS array with 128 items, one per + MIDI note number. Inactive instances are marked NULL. + */ + const INSDS *midi_chn_list() { + return (const INSDS *) ((CSOUND *)csound)->GetMidiChannel(this)->kinsptr; + } + + /** check if this opcode runs at init time + */ + bool is_init() { + return this->iopadr ? true : false; + } + + /** check if this opcode runs at perf time + */ + bool is_perf() { + return this->opaddr ? true : false; + } + +}; + +/** Plugin template base class: + for N outputs and M inputs, N > 0 + */ +template struct Plugin : OPDS { + /** output arguments */ + Param outargs; + /** input arguments */ + Param inargs; + /** Csound engine */ + Csound *csound; + /** sample-accurate offset */ + uint32_t offset; + /** vector samples to process */ + uint32_t nsmps; + + /** i-time function placeholder + */ + int init() { return OK; } + + /** k-rate function placeholder + */ + int kperf() { return OK; } + + /** a-rate function placeholder + */ + int aperf() { return OK; } + + /** @private + sample-accurate offset for + a-rate opcodes; updates offset + and nsmps. Called implicitly by + the aperf() method. + */ + void sa_offset() { + uint32_t early = insdshead->ksmps_no_end; + nsmps = insdshead->ksmps - early; + offset = insdshead->ksmps_offset; + if (UNLIKELY(offset || early)) + for (auto &arg : outargs) { + if (csound->is_asig(arg)) { + std::fill(arg, arg + offset, 0); + std::fill(arg + nsmps, arg + nsmps + early, 0); + } + } + } + + /** @private + set nsmps and offset value for kperf() + */ + void nsmps_set() { + nsmps = insdshead->ksmps - insdshead->ksmps_no_end; + offset = insdshead->ksmps_offset; + } + + /** returns the number of output arguments + used in the case of variable output count + */ + uint32_t out_count() { return (uint32_t)optext->t.outArgCount; } + + /** returns the number of input arguments + used in the case of variable input count + */ + uint32_t in_count() { return (uint32_t)optext->t.inArgCount; } + + /** local control rate + */ + MYFLT kr() { return insdshead->ekr; } + + /** local ksmps + */ + MYFLT ksmps() { return insdshead->ksmps; } + + /** sampling rate + */ + MYFLT sr() { return csound->sr(); } + + /** midi channel number for this instrument + */ + int midi_channel() { return ((CSOUND *)csound)->GetMidiChannelNumber(this); } + + /** midi note number for this instrument + */ + int midi_note_num() { return ((CSOUND *)csound)->GetMidiNoteNumber(this); } + + /** midi note velocity for this instrument + */ + int midi_note_vel() { return ((CSOUND *)csound)->GetMidiVelocity(this); } + + /** midi aftertouch for this channel + */ + MYFLT midi_chn_aftertouch() { + return ((CSOUND *)csound)->GetMidiChannel(this)->aftouch; } + + /** midi poly aftertouch for this channel + */ + MYFLT midi_chn_polytouch(uint32_t note) { + return ((CSOUND *)csound)->GetMidiChannel(this)->polyaft[note]; + } + + /** midi ctl change for this channel + */ + MYFLT midi_chn_ctl(uint32_t ctl) { + return ((CSOUND *)csound)->GetMidiChannel(this)->ctl_val[ctl]; + } + + /** midi pitchbend for this channel + */ + MYFLT midi_chn_pitchbend() { + return ((CSOUND *)csound)->GetMidiChannel(this)->pchbend; } + + /** list of active instrument instances for this channel \n + returns an INSDS array with 128 items, one per + MIDI note number. Inactive instances are marked NULL. + */ + const INSDS *midi_chn_list() { + return (const INSDS *) ((CSOUND *)csound)->GetMidiChannel(this)->kinsptr; + } + + /** check if this opcode runs at init time + */ + bool is_init() { + return this->iopadr ? true : false; + } + + /** check if this opcode runs at perf time + */ + bool is_perf() { + return this->opadr ? true : false; + } + +}; + + +/** Fsig plugin template base class: + for N outputs and M inputs + */ +template struct FPlugin : Plugin { + /** current frame time index */ + uint32_t framecount; +}; + +/** + @private + opcode thread function template (i-time) +*/ +template int init(CSOUND *csound, T *p) { + p->csound = (Csound *)csound; + return p->init(); +} + +/** + @private + opcode thread function template (k-rate) +*/ +template int kperf(CSOUND *csound, T *p) { + p->csound = (Csound *)csound; + p->nsmps_set(); + return p->kperf(); +} + +/** + @private + opcode thread function template (a-rate) +*/ +template int aperf(CSOUND *csound, T *p) { + p->csound = (Csound *)csound; + p->sa_offset(); + return p->aperf(); +} + +/** plugin registration function template + */ +template +int plugin(Csound *csound, const char *name, const char *oargs, + const char *iargs, uint32_t thr, uint32_t flags = 0) { + CSOUND *cs = (CSOUND *)csound; + if(thr == thread::ia || thr == thread::a) { + thr = thr == thread::ia ? 3 : 2; + return cs->AppendOpcode(cs, (char *)name, sizeof(T), flags, thr, + (char *)oargs, (char *)iargs, (SUBR)init, + (SUBR)aperf, NULL); + } + else + return cs->AppendOpcode(cs, (char *)name, sizeof(T), flags, thr, + (char *)oargs, (char *)iargs, (SUBR)init, + (SUBR)kperf, NULL); +} + +/** plugin registration function template + for classes with self-defined opcode argument types + */ +template +int plugin(Csound *csound, const char *name, uint32_t thr, + uint32_t flags = 0) { + CSOUND *cs = (CSOUND *)csound; + if(thr == thread::ia || thr == thread::a) { + thr = thr == thread::ia ? 3 : 2; + return cs->AppendOpcode(cs, (char *)name, sizeof(T), flags, thr, + (char *)T::otypes, (char *)T::itypes, (SUBR)init, + (SUBR)aperf, NULL); + + } + else + return cs->AppendOpcode(cs, (char *)name, sizeof(T), flags, thr, + (char *)T::otypes, (char *)T::itypes, (SUBR)init, + (SUBR)kperf, NULL); + +} + +/** utility constructor function template for member classes: \n + takes the class and constructor types as arguments. \n + Function takes the allocated memory pointer and constructor + arguments.\n + */ +template T *constr(T *p, Types... args) { + return new (p) T(args...); +} + +template void destr(T *p) { p->T::~T(); } +} +#endif diff --git a/6.x/csound/pools.h b/6.x/csound/pools.h new file mode 100644 index 00000000..f1772f21 --- /dev/null +++ b/6.x/csound/pools.h @@ -0,0 +1,42 @@ +/* + pools.h: + + Copyright (C) 2013 by Victor Lazzarini + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef POOLS_H +#define POOLS_H + +#define POOL_SIZE 256 + +typedef struct myflt_pool { + CS_VAR_MEM* values; + int max; + int count; +} MYFLT_POOL; + +MYFLT_POOL* myflt_pool_create(CSOUND* csound); +int myflt_pool_indexof(MYFLT_POOL* pool, MYFLT value); +int myflt_pool_find_or_add(CSOUND* csound, MYFLT_POOL* pool, MYFLT value); +int myflt_pool_find_or_addc(CSOUND* csound, MYFLT_POOL* pool, char* s); +void myflt_pool_free(CSOUND *csound, MYFLT_POOL *pool); + +#endif + diff --git a/6.x/csound/pstream.h b/6.x/csound/pstream.h new file mode 100644 index 00000000..26f482f6 --- /dev/null +++ b/6.x/csound/pstream.h @@ -0,0 +1,293 @@ +/* + pstream.h: + + Copyright (C) 2001 Richard Dobson + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef __PSTREAM_H_INCLUDED +#define __PSTREAM_H_INCLUDED + +/* pstream.h. Implementation of PVOCEX streaming opcodes. + (c) Richard Dobson August 2001 + NB pvoc routines based on CARL distribution (Mark Dolson). + This file is licensed according to the terms of the GNU LGPL. + */ + +/* opcodes: PROVISIONAL DEFINITIONS + + fsig pvsanal ain,ifftsize,ioverlap,iwinsize,iwintype[,iformat,iinit] + + iwintype: 0 = HAMMING, 1 = VonHann, 2 = Kaiser(?) + iformat: only PVS_AMP_FREQ (0) supported at present + (TODO: add f-table support for custom window) + ( But: really need a param to associate with the window too, + or just use a standard default value...) + + fsig pvsfread ktimpt,ifn[,ichan] + + asig pvsynth fsig[,iinit] + + asig pvsadsyn fsig,inoscs,kfmod[,ibin,ibinoffset,iinit] + + ibin: starting bin (defualt 0) + ibinoffset: distance between successive bins (default 1) + kfmod: multiplier; 1 = no change, 2 = up one octave. + + fsig pvscross fsrc,fdest,kamp1,kamp2 + + fsig pvsmaska fsrc,ifn,kdepth + + ioverlap,inumbins,iwinsize,iformat pvsinfo fsig + + ( will need sndinfo supporting pvocex files anyway, + to know numchans, wintype, etc.) + + fdest = fsrc + + ( woo-hoo! operator overloading in Csound!) + ( NB an init statement for fsigs is not supported. One day....) + + kflag pvsftw fsig,ifna [,ifnf] + pvsftr fsig,ifna [,ifnf] + + ( this modifies an ~existing~ signal, does not create a new one, + hence no output) + + Re iinit: not implemented yet: and I still need to establish + if it's possible... + */ + +/* description of an fsig analysis frame*/ +enum PVS_WINTYPE { + PVS_WIN_HAMMING = 0, + PVS_WIN_HANN, + PVS_WIN_KAISER, + PVS_WIN_CUSTOM, + PVS_WIN_BLACKMAN, + PVS_WIN_BLACKMAN_EXACT, + PVS_WIN_NUTTALLC3, + PVS_WIN_BHARRIS_3, + PVS_WIN_BHARRIS_MIN, + PVS_WIN_RECT +}; + + +enum PVS_ANALFORMAT { + PVS_AMP_FREQ = 0, + PVS_AMP_PHASE, + PVS_COMPLEX, + PVS_TRACKS /* added VL, 24.06.2005 */ +}; + +typedef struct { + MYFLT re; + MYFLT im; +} CMPLX; + +typedef struct pvsdat { + int32 N; + int sliding; /* Flag to indicate sliding case */ + int32 NB; + int32 overlap; + int32 winsize; + int wintype; + int32 format; /* fixed for now to AMP:FREQ */ + uint32 framecount; + AUXCH frame; /* RWD MUST always be 32bit floats */ + /* But not in sliding case when MYFLT */ +} PVSDAT; + +/* may be no point supporting Kaiser in an opcode unless we can support + the param too but we can have kaiser in a PVOCEX file. */ + +typedef struct { + OPDS h; + PVSDAT *fsig; /* output signal is an analysis frame */ + MYFLT *ain; /* input sig is audio */ + MYFLT *fftsize; /* params */ + MYFLT *overlap; + MYFLT *winsize; + MYFLT *wintype; + MYFLT *format; /* always PVS_AMP_FREQ at present */ + MYFLT *init; /* not yet implemented */ + /* internal */ + int32 buflen; + float fund,arate; + float RoverTwoPi,TwoPioverR,Fexact; + MYFLT *nextIn; + int32 nI,Ii,IOi; /* need all these ?; double as N and NB */ + int32 inptr; + + AUXCH input; + AUXCH overlapbuf; + AUXCH analbuf; + AUXCH analwinbuf; /* prewin in SDFT case */ + AUXCH oldInPhase; + AUXCH trig; + double *cosine, *sine; + void *setup; +} PVSANAL; + +typedef struct { + OPDS h; + MYFLT *aout; /* audio output signal */ + PVSDAT *fsig; /* input signal is an analysis frame */ + MYFLT *init; /* not yet implemented */ + /* internal */ + /* check these against fsig vals */ + int32 overlap,winsize,fftsize,wintype,format; + /* can we allow variant window tpes? */ + int32 buflen; + MYFLT fund,arate; + MYFLT RoverTwoPi,TwoPioverR,Fexact; + MYFLT *nextOut; + int32 nO,Ii,IOi; /* need all these ?*/ + int32 outptr; + int32 bin_index; /* for phase normalization across frames */ + /* renderer gets all format info from fsig */ + + AUXCH output; + AUXCH overlapbuf; + AUXCH synbuf; + AUXCH analwinbuf; /* may get away with a local alloc and free */ + AUXCH synwinbuf; + AUXCH oldOutPhase; + + void *setup; +} PVSYNTH; + +/* for pvadsyn */ + +typedef struct { + OPDS h; + MYFLT *aout; + PVSDAT *fsig; + MYFLT *n_oscs; + MYFLT *kfmod; + MYFLT *ibin; /* default 0 */ + MYFLT *ibinoffset; /* default 1 */ + MYFLT *init; /* not yet implemented */ + /* internal */ + int32 outptr; + uint32 lastframe; + /* check these against fsig vals */ + int32 overlap,winsize,fftsize,wintype,format,noscs; + int32 maxosc; + float one_over_overlap,pi_over_sr, one_over_sr; + float fmod; + AUXCH a; + AUXCH x; + AUXCH y; + AUXCH amps; + AUXCH lastamps; + AUXCH freqs; + AUXCH outbuf; +} PVADS; + +/* for pvscross */ +typedef struct { + OPDS h; + PVSDAT *fout; + PVSDAT *fsrc; + PVSDAT *fdest; + MYFLT *kamp1; + MYFLT *kamp2; + /* internal */ + int32 overlap,winsize,fftsize,wintype,format; + uint32 lastframe; +} PVSCROSS; + +/* for pvsmaska */ +typedef struct { + OPDS h; + PVSDAT *fout; + PVSDAT *fsrc; + MYFLT *ifn; + MYFLT *kdepth; + /* internal*/ + int32 overlap,winsize,fftsize,wintype,format; + uint32 lastframe; + int nwarned,pwarned; /* range errors for kdepth */ + FUNC *maskfunc; +} PVSMASKA; + +/* for pvsftw, pvsftr */ + +typedef struct { + OPDS h; + MYFLT *kflag; + PVSDAT *fsrc; + MYFLT *ifna; /* amp, required */ + MYFLT *ifnf; /* freq: optional*/ + /* internal */ + int32 overlap,winsize,fftsize,wintype,format; + uint32 lastframe; + FUNC *outfna, *outfnf; +} PVSFTW; + +typedef struct { + OPDS h; + /* no output var*/ + PVSDAT *fdest; + MYFLT *ifna; /* amp, may be 0 */ + MYFLT *ifnf; /* freq: optional*/ + /* internal */ + int32 overlap,winsize,fftsize,wintype,format; + uint32 lastframe; + FUNC *infna, *infnf; + MYFLT *ftablea,*ftablef; +} PVSFTR; + +/* for pvsfread */ +/* wsig pvsread ktimpt,ifilcod */ +typedef struct { + OPDS h; + PVSDAT *fout; + MYFLT *kpos; + MYFLT *ifilno; + MYFLT *ichan; + /* internal */ + int ptr; + int32 overlap,winsize,fftsize,wintype,format; + uint32 chans, nframes,lastframe,chanoffset,blockalign; + MYFLT arate; + float *membase; /* RWD MUST be 32bit: reads file */ +} PVSFREAD; + +/* for pvsinfo */ + +typedef struct { + OPDS h; + MYFLT *ioverlap; + MYFLT *inumbins; + MYFLT *iwinsize; + MYFLT *iformat; + /* internal*/ + PVSDAT *fsrc; +} PVSINFO; + +typedef struct { + OPDS h; + PVSDAT *fout; + PVSDAT *fsrc; +} FASSIGN; + +#endif + diff --git a/6.x/csound/pvfileio.h b/6.x/csound/pvfileio.h new file mode 100644 index 00000000..58e11cc8 --- /dev/null +++ b/6.x/csound/pvfileio.h @@ -0,0 +1,167 @@ +/* + pvfileio.h: + + Copyright (C) 2000 Richard Dobson + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +/* pvfileio.h: header file for PVOC_EX file format */ +/* Initial Version 0.1 RWD 25:5:2000 all rights reserved: work in progress! */ + +#ifndef __PVFILEIO_H_INCLUDED +#define __PVFILEIO_H_INCLUDED + +#include "sysdep.h" + +#if defined(WIN32) || defined(_WIN32) || defined(_MSC_VER) + +#include + +#else + +typedef struct +{ + uint32_t Data1; + uint16_t Data2; + uint16_t Data3; + unsigned char Data4[8]; +} GUID; + +typedef struct /* waveformatex */ { + uint16_t wFormatTag; + uint16_t nChannels; + uint32_t nSamplesPerSec; + uint32_t nAvgBytesPerSec; + uint16_t nBlockAlign; + uint16_t wBitsPerSample; + uint16_t cbSize; +} WAVEFORMATEX; + +#endif + +/* NB no support provided for double format (yet) */ + +typedef enum pvoc_wordformat { + PVOC_IEEE_FLOAT, + PVOC_IEEE_DOUBLE +} pvoc_wordformat; + +/* include PVOC_COMPLEX for some parity with SDIF */ + +typedef enum pvoc_frametype { + PVOC_AMP_FREQ = 0, + PVOC_AMP_PHASE, + PVOC_COMPLEX +} pvoc_frametype; + +/* a minimal list */ + +typedef enum pvoc_windowtype { + PVOC_DEFAULT = 0, + PVOC_HAMMING = 0, + PVOC_HANN, + PVOC_KAISER, + PVOC_RECT, + PVOC_CUSTOM +} pv_wtype; + +/* Renderer information: source is presumed to be of this type */ + +typedef enum pvoc_sampletype { + STYPE_16, + STYPE_24, + STYPE_32, + STYPE_IEEE_FLOAT +} pv_stype; + +typedef struct pvoc_data { /* 32 bytes */ + uint16_t wWordFormat; /* pvoc_wordformat */ + uint16_t wAnalFormat; /* pvoc_frametype */ + uint16_t wSourceFormat; /* WAVE_FORMAT_PCM or WAVE_FORMAT_IEEE_FLOAT */ + uint16_t wWindowType; /* pvoc_windowtype */ + uint32_t nAnalysisBins; /* implicit FFT size = (nAnalysisBins-1) * 2 */ + uint32_t dwWinlen; /* analysis winlen, in samples */ + /* NB may be != FFT size */ + uint32_t dwOverlap; /* samples */ + uint32_t dwFrameAlign; /* usually nAnalysisBins * 2 * sizeof(float) */ + float fAnalysisRate; + float fWindowParam; /* default 0.0f unless needed */ +} PVOCDATA; + +typedef struct { + WAVEFORMATEX Format; /* 18 bytes: info for renderer */ + /* as well as for pvoc */ + union { /* 2 bytes */ + uint16_t wValidBitsPerSample; /* as per standard WAVE_EX: */ + /* applies to renderer */ + uint16_t wSamplesPerBlock; + uint16_t wReserved; + } Samples; + uint32_t dwChannelMask; /* 4 bytes: can be used as in */ + /* standrad WAVE_EX */ + GUID SubFormat; /* 16 bytes */ +} WAVEFORMATEXTENSIBLE, *PWAVEFORMATEXTENSIBLE; + +typedef struct { + WAVEFORMATEXTENSIBLE wxFormat; /* 40 bytes */ + uint32_t dwVersion; /* 4 bytes */ + uint32_t dwDataSize; /* 4 bytes: sizeof PVOCDATA data block */ + PVOCDATA data; /* 32 bytes */ +} WAVEFORMATPVOCEX; /* total 80 bytes */ + +/* at least VC++ will give 84 for sizeof(WAVEFORMATPVOCEX), */ +/* so we need our own version */ +#define SIZEOF_FMTPVOCEX (80) +/* for the same reason: */ +#define SIZEOF_WFMTEX (18) +#define PVX_VERSION (1) + +/******* the all-important PVOC GUID + + {8312B9C2-2E6E-11d4-A824-DE5B96C3AB21} + +**************/ + +#ifndef CSOUND_CSDL_H + +extern const GUID KSDATAFORMAT_SUBTYPE_PVOC; + +/* pvoc file handling functions */ + +const char *pvoc_errorstr(CSOUND *); +int init_pvsys(CSOUND *); +int pvoc_createfile(CSOUND *, const char *, + uint32, uint32, uint32, + uint32, int32, int, int, + float, float *, uint32); +int pvoc_openfile(CSOUND *, + const char *filename, void *data_, void *fmt_); +int pvoc_closefile(CSOUND *, int); +int pvoc_putframes(CSOUND *, + int ofd, const float *frame, int32 numframes); +int pvoc_getframes(CSOUND *, + int ifd, float *frames, uint32 nframes); +int pvoc_framecount(CSOUND *, int ifd); +int pvoc_fseek(CSOUND *, int ifd, int offset); +int pvsys_release(CSOUND *); + +#endif /* CSOUND_CSDL_H */ + +#endif /* __PVFILEIO_H_INCLUDED */ + diff --git a/6.x/csound/soundio.h b/6.x/csound/soundio.h new file mode 100644 index 00000000..e6320b08 --- /dev/null +++ b/6.x/csound/soundio.h @@ -0,0 +1,149 @@ +/* + soundio.h: + + Copyright (C) 1991, 2000 Barry Vercoe, Richard Dobson + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + /* SOUNDIO.H */ +#ifndef CSOUND_SOUNDIO_H +#define CSOUND_SOUNDIO_H + +#include + +#ifdef WIN32 +#define IOBUFSAMPS 4096 /* default sampframes in audio iobuf, -b settable */ +#define IODACSAMPS 16384 /* default samps in hardware buffer, -B settable */ +#elif defined(NeXT) || defined(__MACH__) +#define IOBUFSAMPS 1024 /* default sampframes in audio iobuf, -b settable */ +#define IODACSAMPS 4096 /* default samps in hardware buffer, -B settable */ +#elif defined(ANDROID) +#define IOBUFSAMPS 2048 /* default sampframes in audio iobuf, -b settable */ +#define IODACSAMPS 4096 /* default samps in hardware buffer, -B settable */ +#else +#define IOBUFSAMPS 256 /* default sampframes in audio iobuf, -b settable */ +#define IODACSAMPS 1024 /* default samps in hardware buffer, -B settable */ +#endif + +#define SNDINBUFSIZ 4096 /* soundin bufsize; must be > sizeof(SFHEADER), */ + /* but small is kind to net rexec */ +#define MAXSNDNAME 1024 +/* standard audio encoding types */ + +#define AE_CHAR SF_FORMAT_PCM_S8 +#define AE_SHORT SF_FORMAT_PCM_16 +#define AE_24INT SF_FORMAT_PCM_24 +#define AE_LONG SF_FORMAT_PCM_32 +#define AE_UNCH SF_FORMAT_PCM_U8 +#define AE_FLOAT SF_FORMAT_FLOAT +#define AE_DOUBLE SF_FORMAT_DOUBLE +#define AE_ULAW SF_FORMAT_ULAW +#define AE_ALAW SF_FORMAT_ALAW +#define AE_IMA_ADPCM SF_FORMAT_IMA_ADPCM +#define AE_MS_ADPCM SF_FORMAT_MS_ADPCM +#define AE_GSM610 SF_FORMAT_GSM610 +#define AE_VOX SF_FORMAT_VOX_ADPCM +#define AE_G721_32 SF_FORMAT_G721_32 +#define AE_G723_24 SF_FORMAT_G723_24 +#define AE_G723_40 SF_FORMAT_G723_40 +#define AE_DWVW_12 SF_FORMAT_DWVW_12 +#define AE_DWVW_16 SF_FORMAT_DWVW_16 +#define AE_DWVW_24 SF_FORMAT_DWVW_24 +#define AE_DWVW_N SF_FORMAT_DWVW_N +#define AE_DPCM_8 SF_FORMAT_DPCM_8 +#define AE_DPCM_16 SF_FORMAT_DPCM_16 +#define AE_VORBIS SF_FORMAT_VORBIS + +#define AE_LAST SF_FORMAT_DPCM_16 /* current last audio encoding value */ + +/* file types */ + +#define TYP_WAV (SF_FORMAT_WAV >> 16) +#define TYP_AIFF (SF_FORMAT_AIFF >> 16) +#define TYP_AU (SF_FORMAT_AU >> 16) +#define TYP_RAW (SF_FORMAT_RAW >> 16) +#define TYP_PAF (SF_FORMAT_PAF >> 16) +#define TYP_SVX (SF_FORMAT_SVX >> 16) +#define TYP_NIST (SF_FORMAT_NIST >> 16) +#define TYP_VOC (SF_FORMAT_VOC >> 16) +#define TYP_IRCAM (SF_FORMAT_IRCAM >> 16) +#define TYP_W64 (SF_FORMAT_W64 >> 16) +#define TYP_MAT4 (SF_FORMAT_MAT4 >> 16) +#define TYP_MAT5 (SF_FORMAT_MAT5 >> 16) +#define TYP_PVF (SF_FORMAT_PVF >> 16) +#define TYP_XI (SF_FORMAT_XI >> 16) +#define TYP_HTK (SF_FORMAT_HTK >> 16) +#define TYP_SDS (SF_FORMAT_SDS >> 16) +#define TYP_AVR (SF_FORMAT_AVR >> 16) +#define TYP_WAVEX (SF_FORMAT_WAVEX >> 16) +#define TYP_SD2 (SF_FORMAT_SD2 >> 16) +#define TYP_FLAC (SF_FORMAT_FLAC >> 16) +#define TYP_CAF (SF_FORMAT_CAF >> 16) +#define TYP_WVE (SF_FORMAT_WVE >> 16) +#define TYP_OGG (SF_FORMAT_OGG >> 16) +#define TYP_MPC2K (SF_FORMAT_MPC2K >> 16) +#define TYP_RF64 (SF_FORMAT_RF64 >> 16) + +#define FORMAT2SF(x) ((int) (x)) +#define SF2FORMAT(x) ((int) (x) & 0xFFFF) +#define TYPE2SF(x) ((int) (x) << 16) +#define SF2TYPE(x) ((int) (x& SF_FORMAT_TYPEMASK) >> 16) + +#ifdef USE_DOUBLE +#define sf_write_MYFLT sf_write_double +#define sf_writef_MYFLT sf_writef_double +#define sf_read_MYFLT sf_read_double +#else +#define sf_write_MYFLT sf_write_float +#define sf_writef_MYFLT sf_writef_float +#define sf_read_MYFLT sf_read_float +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* generic sound input structure */ + +typedef struct { + SNDFILE *sinfd; /* sound file handle */ + MYFLT *inbufp, *bufend; /* current buffer position, end of buf */ + void *fd; /* handle returned by csoundFileOpen() */ + int bufsmps; /* number of mono samples in buffer */ + int format; /* sample format (AE_SHORT, etc.) */ + int channel; /* requested channel (ALLCHNLS: all) */ + int nchanls; /* number of channels in file */ + int sampframsiz; /* sample frame size in bytes */ + int filetyp; /* file format (TYP_WAV, etc.) */ + int analonly; /* non-zero for analysis utilities */ + int endfile; /* end of file reached ? non-zero: yes */ + int sr; /* sample rate in Hz */ + int do_floatscaling; /* scale floats by fscalefac ? 0: no */ + int64_t audrem, framesrem, getframes; /* samples, frames, frames */ + MYFLT fscalefac; + MYFLT skiptime; + char sfname[MAXSNDNAME]; + MYFLT inbuf[SNDINBUFSIZ]; +} SOUNDIN; + +#ifdef __cplusplus +} +#endif + +#endif /* CSOUND_SOUNDIO_H */ + diff --git a/6.x/csound/sysdep.h b/6.x/csound/sysdep.h new file mode 100644 index 00000000..5707a585 --- /dev/null +++ b/6.x/csound/sysdep.h @@ -0,0 +1,575 @@ +/* + sysdep.h: + + Copyright (C) 1991 Barry Vercoe, John ffitch + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef CSOUND_SYSDEP_H +#define CSOUND_SYSDEP_H + +/* check for the presence of a modern compiler (for use of certain features) */ +#if defined(WIN32) +#if !defined(locale_t) +typedef void *locale_t; +#endif +#endif + +#include +/* this checks for 64BIT builds */ +#if defined(__MACH__) || defined(LINUX) +#if ( __WORDSIZE == 64 ) || defined(__x86_64__) || defined(__amd64__) +#define B64BIT +#endif +#endif + +#if defined(WIN32) +#if _WIN64 +#define B64BIT +#endif +#endif + + + +#ifdef HAVE_GCC3 +# undef HAVE_GCC3 +#endif +#ifdef HAVE_C99 +# undef HAVE_C99 +#endif +#if (defined(__GNUC__) && (__GNUC__ >= 3)) +# define HAVE_C99 1 +# if defined(__BUILDING_LIBCSOUND) || defined(CSOUND_CSDL_H) +# ifndef _ISOC99_SOURCE +# define _ISOC99_SOURCE 1 +# endif +# ifndef _ISOC9X_SOURCE +# define _ISOC9X_SOURCE 1 +# endif +# endif +# if !(defined(__MACH__) && (__GNUC__ == 3) && (__GNUC_MINOR__ < 2)) +# define HAVE_GCC3 1 +# endif +#elif (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) +# define HAVE_C99 1 +#endif + +#if defined(__GNUC__) +# if defined(__GNUC_PATCHLEVEL__) +# define __GNUC_VERSION__ (__GNUC__ * 10000 \ + + __GNUC_MINOR__ * 100 \ + + __GNUC_PATCHLEVEL__) +# else +# define __GNUC_VERSION__ (__GNUC__ * 10000 \ + + __GNUC_MINOR__ * 100) +# endif +#endif + +#ifndef CABBAGE +#ifdef MSVC +typedef __int32 int32; +typedef __int16 int16; +typedef unsigned __int32 uint32; +typedef unsigned __int16 uint16; +#else +#include +#if defined(__HAIKU__) && defined(__HAIKU_CONFLICT) + /* Haiku has different typedefs -- relevant to rthaiku and network*/ + #include +#else +typedef int_least32_t int32; +typedef int_least16_t int16; +typedef uint_least32_t uint32; +typedef uint_least16_t uint16; +#endif +#endif +#endif + +#if defined(HAVE_PTHREAD_SPIN_LOCK) +#include +#endif + +#ifdef __MACH__ +#include +#endif + +#if !defined(USE_DOUBLE) +#if !defined(_MSC_VER) +#include "float-version.h" +#else +#define USE_DOUBLE +#endif +#endif + +#ifdef USE_DOUBLE +/* Defined here as Android does not have log2 functions */ +#define MYRECIPLN2 1.442695040888963407359924681001892137426 /* 1.0/log(2) */ +#define LOG2(a) (MYRECIPLN2*log(a)) /* floating point logarithm base 2 */ + + #define ACOS acos + #define ASIN asin + #define ATAN atan + #define ATAN2 atan2 + #define COS cos + #define SIN sin + #define TAN tan + #define COSH cosh + #define SINH sinh + #define TANH tanh + #define ACOSH acosh + #define ASINH asinh + #define ATANH atanh + #define EXP exp + #define LOG log + #define LOG10 log10 + /* #define LOG2 log2 */ + #define POWER pow + #define SQRT sqrt + #define HYPOT hypot + #define FABS fabs + #define FLOOR floor + #define CEIL ceil + #define FMOD fmod + #define MODF modf +#else +/* Defined here as Android does not have log2 functions */ +#define MYRECIPLN2 1.442695040888963407359924681001892137426 /* 1.0/log(2) */ +#define LOG2(a) (MYRECIPLN2*logf(a)) /* floating point logarithm base 2 */ + + #define ACOS acosf + #define ASIN asinf + #define ATAN atanf + #define ATAN2 atan2f + #define COS cosf + #define SIN sinf + #define TAN tanf + #define COSH coshf + #define SINH sinhf + #define TANH tanhf + #define ACOSH acoshf + #define ASINH asinhf + #define ATANH atanhf + #define EXP expf + #define LOG logf + #define LOG10 log10f + /* #define LOG2 log2f */ + #define POWER powf + #define SQRT sqrtf + #define HYPOT hypotf + #define FABS(x) fabsf(FL(x)) + #define FLOOR floorf + #define CEIL ceilf + #define FMOD fmodf + #define MODF modff +#endif + +// #include +#include +#include +#include +#if defined(HAVE_FCNTL_H) || defined(__unix) || defined(__unix__) +#include +#endif +#if defined(HAVE_UNISTD_H) || defined(__unix) || defined(__unix__) +#include +#endif + +/* Experiment with doubles or floats */ + +#ifndef __MYFLT_DEF +# define __MYFLT_DEF +# ifndef USE_DOUBLE +# define MYFLT float +# else +# define MYFLT double +# endif +#endif + +/* Aligning to double boundaries, should work with MYFLT as float or double */ +#define CS_FLOAT_ALIGN(x) ((int)(x + sizeof(MYFLT)-1) & (~(sizeof(MYFLT)-1))) + +#if defined(__BUILDING_LIBCSOUND) || defined(CSOUND_CSDL_H) + +#define FL(x) ((MYFLT) (x)) + +/* find out operating system if not specified on the command line */ + +#if defined(_WIN32) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 1 +# endif +#elif (defined(linux) || defined(__linux)) && !defined(LINUX) +# define LINUX 1 +#endif + +#if defined(WIN32) && defined(_MSC_VER) && !defined(__GNUC__) +# ifndef MSVC +# define MSVC 1 +# endif +#elif defined(MSVC) +# undef MSVC +#endif + +/* inline keyword: always available in C++, C99, and GCC 3.x and above */ +/* add any other compiler that supports 'inline' */ + +#if !(defined(__cplusplus) || defined(inline)) +# if defined(HAVE_C99) || defined(HAVE_GCC3) +# if defined(__GNUC__) && defined(__STRICT_ANSI__) +# define inline __inline__ +# endif +# elif defined(MSVC) +# define inline __inline +# else +# define inline +# endif +#endif + +#define DIRSEP '/' +#ifdef WIN32 +# undef DIRSEP +# define DIRSEP '\\' +# if !defined(O_NDELAY) +# define O_NDELAY (0) +# endif +# include +#else +# ifdef DOSGCC +# if !defined(O_NDELAY) +# define O_NDELAY (0) +# endif +# endif +# ifdef HAVE_SYS_TYPES_H +# include +# endif +/* RWD for WIN32 on VC++ */ +#endif +#ifndef MSVC +# include +#endif +#include + +#endif /* __BUILDING_LIBCSOUND || CSOUND_CSDL_H */ + +#ifdef WIN32 +# define ENVSEP ';' +#else +# define ENVSEP ':' +#endif +/* standard integer types */ + +#if defined(USE_GUSI2) +/* When compiling with GUSI on MacOS 9 (for Python), */ +/* all of the other integer types are already defined */ +typedef int64_t int_least64_t; +typedef uint64_t uint_least64_t; +#elif defined(HAVE_STDINT_H) || defined(HAVE_C99) +# include + +# if defined(__CYGWIN__) +#define __int8 char +#define __int16 short +#define __int32 int +#define __int64 long long +# endif +#else +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef short int16_t; +typedef unsigned short uint16_t; +typedef int int32_t; +typedef unsigned int uint32_t; +# if defined(__GNUC__) || !defined(WIN32) +typedef long long int64_t; +typedef unsigned long long uint64_t; +typedef long long int_least64_t; +typedef unsigned long long uint_least64_t; +# else +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +typedef __int64 int_least64_t; +typedef unsigned __int64 uint_least64_t; +# endif +#if !defined(_MSC_VER) +typedef long intptr_t; +typedef unsigned long uintptr_t; +#endif +#endif /* !(USE_GUSI2 || HAVE_STDINT_H || HAVE_C99) */ + + + +/* function attributes */ + +#if defined(HAVE_GCC3) && !defined(SWIG) +/* deprecated function, variable, or type that is to be removed eventually */ +# define CS_DEPRECATED __attribute__ ((__deprecated__)) +/* a function that should not be inlined */ +# define CS_NOINLINE __attribute__ ((__noinline__)) +/* a function that never returns (e.g. csoundDie()) */ +# define CS_NORETURN __attribute__ ((__noreturn__)) +/* printf-style function with first argument as format string */ +# define CS_PRINTF1 __attribute__ ((__format__ (__printf__, 1, 2))) +/* printf-style function with second argument as format string */ +# define CS_PRINTF2 __attribute__ ((__format__ (__printf__, 2, 3))) +/* printf-style function with third argument as format string */ +# define CS_PRINTF3 __attribute__ ((__format__ (__printf__, 3, 4))) +/* a function with no side effects or dependencies on volatile data */ +# define CS_PURE __attribute__ ((__pure__)) +#else +# define CS_DEPRECATED +# define CS_NOINLINE +# define CS_NORETURN +# define CS_PRINTF1 +# define CS_PRINTF2 +# define CS_PRINTF3 +# define CS_PURE +#endif +#if defined(__clang__) || defined(HAVE_GCC3) +# define LIKELY(x) __builtin_expect(!!(x),1) +# define UNLIKELY(x) __builtin_expect(!!(x),0) +#else +# define LIKELY(x) x +# define UNLIKELY(x) x +#endif + +#if defined(__BUILDING_LIBCSOUND) || defined(CSOUND_CSDL_H) + +/* macros for converting floats to integers */ +/* MYFLT2LONG: converts with unspecified rounding */ +/* MYFLT2LRND: rounds to nearest integer */ + +#ifdef USE_LRINT +# ifndef USE_DOUBLE +# define MYFLT2LONG(x) (x > LONG_MIN && x < LONG_MAX ? \ + (int32) lrintf((float) (x)) : 0) +# define MYFLT2LRND(x) (x > LONG_MIN && x < LONG_MAX ? \ + (int32) lrintf((float) (x)) : 0) +# else +# define MYFLT2LONG(x) (x > LONG_MIN && x < LONG_MAX ? \ + (int32) lrint((double) (x)) : 0) +# define MYFLT2LRND(x) (x > LONG_MIN && x < LONG_MAX ? \ + (int32) lrint((double) (x)) : 0) +# endif +#elif defined(MSVC) +#include +# ifndef USE_DOUBLE +// From Agner Fog optimisation manuals p.144 +static inline int MYFLT2LONG (float const x) { + return _mm_cvtss_si32 (_mm_load_ss (&x)); +} + +static inline int MYFLT2LRND (float const x) { + return _mm_cvtss_si32 (_mm_load_ss (&x)); +} + +# else +static inline int MYFLT2LONG (double const x) { + return _mm_cvtsd_si32 (_mm_load_sd (&x)); +} + +static inline int MYFLT2LRND (double const x) { + return _mm_cvtsd_si32 (_mm_load_sd (&x)); +} +# endif +#else +# ifndef USE_DOUBLE +# define MYFLT2LONG(x) ((int32) (x)) +# if defined(HAVE_GCC3) && defined(__i386__) && !defined(__ICC) +# define MYFLT2LRND(x) ((int32) lrintf((float) (x))) +# else +static inline int32 MYFLT2LRND(float fval) +{ + return ((int32) (fval + (fval < 0.0f ? -0.5f : 0.5f))); +} +# endif +# else +# define MYFLT2LONG(x) ((int32) (x)) +# if defined(HAVE_GCC3) && defined(__i386__) && !defined(__ICC) +# define MYFLT2LRND(x) ((int32) lrint((double) (x))) +# else +static inline int32 MYFLT2LRND(double fval) +{ + return ((int32) (fval + (fval < 0.0 ? -0.5 : 0.5))); +} +# endif +# endif +#endif + +/* inline functions and macros for clamping denormals to zero */ + +#if defined(__i386__) || defined(MSVC) +static inline float csoundUndenormalizeFloat(float x) +{ + volatile float tmp = 1.0e-30f; + return ((x + 1.0e-30f) - tmp); +} + +static inline double csoundUndenormalizeDouble(double x) +{ + volatile double tmp = 1.0e-200; + return ((x + 1.0e-200) - tmp); +} +#else +# define csoundUndenormalizeFloat(x) x +# define csoundUndenormalizeDouble(x) x +#endif + +#ifndef USE_DOUBLE +# define csoundUndenormalizeMYFLT csoundUndenormalizeFloat +#else +# define csoundUndenormalizeMYFLT csoundUndenormalizeDouble +#endif + +#endif /* __BUILDING_LIBCSOUND || CSOUND_CSDL_H */ + +// This is wrong..... needs thought +/* #ifdef HAVE_SPRINTF_L */ +/* # define CS_SPRINTF sprintf_l */ +/* #elseif HAVE__SPRINT_L */ +/* /\* this would be the case for the Windows locale aware function *\/ */ +/* # define CS_SPRINTF _sprintf_l */ +/* #else */ +# define CS_SPRINTF cs_sprintf +# define CS_SSCANF cs_sscanf +/* #endif */ + +#if !defined(HAVE_STRLCAT) && !defined(strlcat) +size_t strlcat(char *dst, const char *src, size_t siz); +#endif +char *strNcpy(char *dst, const char *src, size_t siz); + +/* atomics */ +#if defined(MSVC) +#define ATOMIC_SET(var, val) InterlockedExchange(&var, val); +#elif defined(HAVE_ATOMIC_BUILTIN) +#define ATOMIC_SET(var, val) __atomic_store_n(&var, val, __ATOMIC_SEQ_CST); +#else +#define ATOMIC_SET(var, val) var = val; +#endif + +#if defined(MSVC) +#define ATOMIC_SET8(var, val) InterlockedExchange8(&var, val); +#elif defined(HAVE_ATOMIC_BUILTIN) +#define ATOMIC_SET8(var, val) __atomic_store_n(&var, val,__ATOMIC_SEQ_CST); +#else +#define ATOMIC_SET8(var, val) var = val; +#endif + +#ifdef MSVC +#define ATOMIC_GET(var) InterlockedExchangeAdd(&var, 0) +#elif defined(HAVE_ATOMIC_BUILTIN) +#define ATOMIC_GET(var) __atomic_load_n(&var, __ATOMIC_SEQ_CST) +#else +#define ATOMIC_GET(var) var +#endif + +#ifdef MSVC +#define ATOMIC_GET8(var) InterlockedExchangeAdd8(&var, 0) +#elif defined(HAVE_ATOMIC_BUILTIN) +#define ATOMIC_GET8(var) __atomic_load_n(&var, __ATOMIC_SEQ_CST) +#else +#define ATOMIC_GET8(var) var +#endif + +#ifdef MSVC +#define ATOMIC_DECR(var) InterlockedExchangeAdd(&var, -1) +#elif defined(HAVE_ATOMIC_BUILTIN) +#define ATOMIC_DECR(var) __atomic_sub_fetch(&var, 1, __ATOMIC_SEQ_CST) +#else +#define ATOMIC_DECR(var) var -= 1 +#endif + +#ifdef MSVC +#define ATOMIC_INCR(var) InterlockedExchangeAdd(&var, 1) +#elif defined(HAVE_ATOMIC_BUILTIN) +#define ATOMIC_INCR(var) __atomic_add_fetch(&var, 1, __ATOMIC_SEQ_CST) +#else +#define ATOMIC_INCR(var) var += 1 +#endif + +#ifdef MSVC +#define ATOMIC_SUB(var, val) InterlockedExchangeAdd(&var, -val) +#elif defined(HAVE_ATOMIC_BUILTIN) +#define ATOMIC_SUB(var, val) __atomic_sub_fetch(&var, val, __ATOMIC_SEQ_CST) +#else +#define ATOMIC_SUB(var, val) var -= val +#endif + +#ifdef MSVC +#define ATOMIC_ADD(var, val) InterlockedExchangeAdd(&var, val) +#elif defined(HAVE_ATOMIC_BUILTIN) +#define ATOMIC_ADD(var, val) __atomic_add_fetch(&var, val, __ATOMIC_SEQ_CST) +#else +#define ATOMIC_ADD(var, val) var += val +#endif + +#if defined(MSVC) +#define ATOMIC_CMP_XCH(val, newVal, oldVal) \ + (InterlockedCompareExchange(val, newVal, oldVal) != oldVal) +#elif defined(HAVE_ATOMIC_BUILTIN) +#define ATOMIC_CMP_XCH(val, newVal, oldVal) \ + !(__atomic_compare_exchange(val, (long *) &oldVal, &newVal, 0, \ + __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) +#else /* FIXME: no atomics, what to do? */ +#define ATOMIC_CMP_XCH(val, newVal, oldVal) (*val = newVal) != oldVal +#endif + +#if defined(WIN32) +typedef int32_t spin_lock_t; +#define SPINLOCK_INIT 0 + +#elif defined(MACOSX) +#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12 +#include +typedef struct os_unfair_lock_s spin_lock_t; +#define SPINLOCK_INIT {0} +#else +#include +typedef int32_t spin_lock_t; +#define SPINLOCK_INIT 0 +#endif // MAC_OS_X_VERSION_MIN_REQUIRED + +#elif defined(__GNUC__) && defined(HAVE_PTHREAD_SPIN_LOCK) +typedef pthread_spinlock_t spin_lock_t; +#define SPINLOCK_INIT PTHREAD_SPINLOCK_INITIALIZER +#elif defined(__GNUC__) && defined(HAVE_ATOMIC_BUILTIN) +typedef char spin_lock_t; +#define SPINLOCK_INIT 0 + +#else +typedef int32_t spin_lock_t; +#define SPINLOCK_INIT 0 +#endif + +/* The ignore_value() macro is taken from GNULIB ignore-value.h, + licensed under the terms of the LGPLv2+ + Normally casting an expression to void discards its value, but GCC + versions 3.4 and newer have __attribute__ ((__warn_unused_result__)) + which may cause unwanted diagnostics in that case. Use __typeof__ + and __extension__ to work around the problem, if the workaround is + known to be needed. */ +#if 3 < __GNUC__ + (4 <= __GNUC_MINOR__) +# define ignore_value(x) \ + (__extension__ ({ __typeof__ (x) __x = (x); (void) __x; })) +#else +# define ignore_value(x) ((void) (x)) +#endif + + +#endif /* CSOUND_SYSDEP_H */ diff --git a/6.x/csound/text.h b/6.x/csound/text.h new file mode 100644 index 00000000..2ae7c45e --- /dev/null +++ b/6.x/csound/text.h @@ -0,0 +1,140 @@ +/* + text.h: + + Copyright (C) 1999 John ffitch + Jan 27 2005: Replaced with new implementation by Istvan Varga + Dec 25 2007: Added gettext support by John ffitch + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef CSOUND_TEXT_H +#define CSOUND_TEXT_H +#ifndef __GNUC__ +# define __attribute__(x) /*NOTHING*/ +#endif + + +/* list of languages */ + + typedef enum { + CSLANGUAGE_DEFAULT = 0, + CSLANGUAGE_AFRIKAANS, + CSLANGUAGE_ALBANIAN, + CSLANGUAGE_ARABIC, + CSLANGUAGE_ARMENIAN, + CSLANGUAGE_ASSAMESE, + CSLANGUAGE_AZERI, + CSLANGUAGE_BASQUE, + CSLANGUAGE_BELARUSIAN, + CSLANGUAGE_BENGALI, + CSLANGUAGE_BULGARIAN, + CSLANGUAGE_CATALAN, + CSLANGUAGE_CHINESE, + CSLANGUAGE_CROATIAN, + CSLANGUAGE_CZECH, + CSLANGUAGE_DANISH, + CSLANGUAGE_DUTCH, + CSLANGUAGE_ENGLISH_UK, + CSLANGUAGE_ENGLISH_US, + CSLANGUAGE_ESTONIAN, + CSLANGUAGE_FAEROESE, + CSLANGUAGE_FARSI, + CSLANGUAGE_FINNISH, + CSLANGUAGE_FRENCH, + CSLANGUAGE_GEORGIAN, + CSLANGUAGE_GERMAN, + CSLANGUAGE_GREEK, + CSLANGUAGE_GUJARATI, + CSLANGUAGE_HEBREW, + CSLANGUAGE_HINDI, + CSLANGUAGE_HUNGARIAN, + CSLANGUAGE_ICELANDIC, + CSLANGUAGE_INDONESIAN, + CSLANGUAGE_ITALIAN, + CSLANGUAGE_JAPANESE, + CSLANGUAGE_KANNADA, + CSLANGUAGE_KASHMIRI, + CSLANGUAGE_KAZAK, + CSLANGUAGE_KONKANI, + CSLANGUAGE_KOREAN, + CSLANGUAGE_LATVIAN, + CSLANGUAGE_LITHUANIAN, + CSLANGUAGE_MACEDONIAN, + CSLANGUAGE_MALAY, + CSLANGUAGE_MALAYALAM, + CSLANGUAGE_MANIPURI, + CSLANGUAGE_MARATHI, + CSLANGUAGE_NEPALI, + CSLANGUAGE_NORWEGIAN, + CSLANGUAGE_ORIYA, + CSLANGUAGE_POLISH, + CSLANGUAGE_PORTUGUESE, + CSLANGUAGE_PUNJABI, + CSLANGUAGE_ROMANIAN, + CSLANGUAGE_RUSSIAN, + CSLANGUAGE_SANSKRIT, + CSLANGUAGE_SERBIAN, + CSLANGUAGE_SINDHI, + CSLANGUAGE_SLOVAK, + CSLANGUAGE_SLOVENIAN, + CSLANGUAGE_SPANISH, + CSLANGUAGE_SWAHILI, + CSLANGUAGE_SWEDISH, + CSLANGUAGE_TAMIL, + CSLANGUAGE_TATAR, + CSLANGUAGE_TELUGU, + CSLANGUAGE_THAI, + CSLANGUAGE_TURKISH, + CSLANGUAGE_UKRAINIAN, + CSLANGUAGE_URDU, + CSLANGUAGE_UZBEK, + CSLANGUAGE_VIETNAMESE, + CSLANGUAGE_COLUMBIAN +} cslanguage_t; + +#ifdef __cplusplus +extern "C" { +#endif + void init_getstring(void*); + PUBLIC char *csoundLocalizeString(const char *s) + __attribute__ ((format_arg (1))); + PUBLIC char* cs_strtok_r(char* str, char* sep, char** lasts); + PUBLIC double cs_strtod(char* nptr, char** endptr); + PUBLIC int cs_sprintf(char *str, const char *format, ...); + PUBLIC int cs_sscanf(char *str, const char *format, ...); +#ifdef __cplusplus +} +#endif + + + /* VL commenting this out so ALL uses of Str(x) + call LocalizeString() [which might be a stub] + This would allows us to keep an eye on + -Wformat-security warnings + */ +//#ifdef GNU_GETTEXT +# define Str(x) csoundLocalizeString(x) +//#else +//# define Str(x) (x) +//#endif + +#define Str_noop(x) x + + +#endif /* CSOUND_TEXT_H */ diff --git a/6.x/csound/version.h b/6.x/csound/version.h new file mode 100644 index 00000000..99f0af56 --- /dev/null +++ b/6.x/csound/version.h @@ -0,0 +1,59 @@ +/* + version.h: + + Copyright (C) 1995 John ffitch + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef CSOUND_VERSION_H +#define CSOUND_VERSION_H + +/* Version string generated from CMake variables */ +#define VERSION "6.17" + +/* Define to the full name of this package. */ +#define CS_PACKAGE_NAME "Csound" + +/* Define to the full name and version of this package. */ +#define CS_PACKAGE_STRING "Csound " VERSION + +/* Define to the one symbol short name of this package. */ +#define CS_PACKAGE_TARNAME "csound" + +/* Define to the version of this package. Generated from CMake variables */ +#define CS_PACKAGE_VERSION VERSION +#define CS_VERSION (6) +#define CS_SUBVER (17) +#define CS_PATCHLEVEL (0) + + +#define CS_APIVERSION 4 /* should be increased anytime a new version + contains changes that an older host will + not be able to handle -- most likely this + will be a change to an API function or + the CSOUND struct */ +#define CS_APISUBVER 0 /* for minor changes that will still allow + compatiblity with older hosts */ + +#ifndef CS_PACKAGE_DATE +#define CS_PACKAGE_DATE __DATE__ +#endif + +#endif /* CSOUND_VERSION_H */ + diff --git a/6.x/src/AbletonLinkOpcodes/CMakeLists.txt b/6.x/src/AbletonLinkOpcodes/CMakeLists.txt index fe2e8dba..ca4f08c7 100644 --- a/6.x/src/AbletonLinkOpcodes/CMakeLists.txt +++ b/6.x/src/AbletonLinkOpcodes/CMakeLists.txt @@ -1,53 +1,42 @@ # Build Ableton Link Opcodes option(BUILD_ABLETON_LINK_OPCODES "Build the Ableton link opcodes" OFF) -if(BUILD_ABLETON_LINK_OPCODES) - message(STATUS "Ableton Link home: ${ABLETON_LINK_HOME}") - - if(APPLE) - make_plugin(ableton_link_opcodes ableton_link_opcodes.cpp) - set_target_properties(ableton_link_opcodes - PROPERTIES - COMPILE_FLAGS "-std=c++11 -stdlib=libc++ -Wno-multichar -DLINK_PLATFORM_MACOSX=1" - LINK_FLAGS "-std=c++11 -stdlib=libc++" - ) - elseif(LINUX) - include(CheckCXXCompilerFlag) - CHECK_CXX_COMPILER_FLAG("-std=gnu++11" COMPILER_SUPPORTS_CXX11) - - if(COMPILER_SUPPORTS_CXX11) - make_plugin(ableton_link_opcodes ableton_link_opcodes.cpp) - set_target_properties(ableton_link_opcodes PROPERTIES COMPILE_FLAGS "-std=gnu++11 -Wno-multichar -DLINK_PLATFORM_LINUX=1") - else() - message(STATUS "Not building ableton_link_opcodes as no C++11 support found.") - endif() - else() - make_plugin(ableton_link_opcodes ableton_link_opcodes.cpp) - - if(WIN32) - if(USE_VCPKG) - find_package(AbletonLink CONFIG REQUIRED PATH_SUFFIXES share/ableton-link) - target_link_libraries(ableton_link_opcodes PRIVATE Ableton::Link) - else() - set_target_properties(ableton_link_opcodes - PROPERTIES - COMPILE_FLAGS "-std=gnu++11 -Wno-multichar -DLINK_PLATFORM_WINDOWS=1" - LINK_FLAGS "-std=gnu++11" - ) - target_link_libraries(ableton_link_opcodes wsock32 ws2_32 iphlpapi) - endif() - endif() +if(USE_VCPKG) + find_package(AbletonLink CONFIG REQUIRED) + + if(NOT TARGET Ableton::Link) + message(STATUS "Could not find Ableton::Link") + set(BUILD_ABLETON_LINK_OPCODES OFF) + endif() +else() + if(NOT "${ABLETON_LINK_HOME}" STREQUAL "") + include("${ABLETON_LINK_HOME}/AbletonLinkConfig.cmake") endif() +endif() + +if(BUILD_ABLETON_LINK_OPCODES) + make_plugin(ableton_link_opcodes "6x" ableton_link_opcodes.cpp Ableton::Link) target_include_directories(ableton_link_opcodes PRIVATE - ${CSOUND_INCLUDE_DIRS} - ${ABLETON_LINK_HOME}/include - ${ABLETON_LINK_HOME}/modules/asio-standalone/asio/include + "${ABLETON_LINK_HOME}/include" + "${ABLETON_LINK_HOME}/modules/asio-standalone/asio/include" ) + target_compile_features(ableton_link_opcodes PUBLIC cxx_std_11) + + if(UNIX) + target_compile_options(ableton_link_opcodes PRIVATE "-Wno-multichar") + endif() + + if(WIN32) + target_link_libraries(ableton_link_opcodes PRIVATE wsock32 ws2_32 iphlpapi) + endif() + install(TARGETS ableton_link_opcodes - LIBRARY DESTINATION ${PLUGIN_INSTALL_DIR} - ARCHIVE DESTINATION ${LIBRARY_INSTALL_DIR} + LIBRARY DESTINATION "${PLUGIN_INSTALL_DIR}" + ARCHIVE DESTINATION "${LIBRARY_INSTALL_DIR}" ) + + message(STATUS "Building Ableton opcodes") endif() diff --git a/6.x/src/AbletonLinkOpcodes/ableton_link_opcodes.cpp b/6.x/src/AbletonLinkOpcodes/ableton_link_opcodes.cpp index dd83d12f..e5b91614 100644 --- a/6.x/src/AbletonLinkOpcodes/ableton_link_opcodes.cpp +++ b/6.x/src/AbletonLinkOpcodes/ableton_link_opcodes.cpp @@ -309,7 +309,7 @@ void freeifaddrs(struct ifaddrs* addrs) { } #endif // defined(ANDROID) #include -#include +#include "OpcodeBase.hpp" /** * A B L E T O N L I N K O P C O D E S diff --git a/6.x/src/CUDA/CMakeLists.txt b/6.x/src/CUDA/CMakeLists.txt index 608f75f2..cd16596f 100644 --- a/6.x/src/CUDA/CMakeLists.txt +++ b/6.x/src/CUDA/CMakeLists.txt @@ -10,7 +10,7 @@ function(make_cuda_plugin libname srcs) math(EXPR i "${i}+1") endwhile() - target_include_directories(${libname} PRIVATE ${CSOUND_INCLUDE_DIRS}) + target_include_directories(${libname} PRIVATE "${CMAKE_SOURCE_DIR}/csound") # set_target_properties(${libname} PROPERTIES # RUNTIME_OUTPUT_DIRECTORY ${BUILD_PLUGINS_DIR} diff --git a/6.x/src/chua/CMakeLists.txt b/6.x/src/chua/CMakeLists.txt index 1946da33..2402725b 100644 --- a/6.x/src/chua/CMakeLists.txt +++ b/6.x/src/chua/CMakeLists.txt @@ -3,19 +3,23 @@ option(BUILD_CHUA_OPCODES "Build the chua opcodes" ON) if(USE_VCPKG) find_package(Eigen3 CONFIG REQUIRED) + + if(NOT TARGET Eigen3::Eigen) + message(STATUS "Could not find Eigen3::Eigen") + set(BUILD_CHUA_OPCODES OFF) + endif() else() find_package(EIGEN3) + check_deps(BUILD_CHUA_OPCODES EIGEN3_FOUND) endif() -check_deps(BUILD_CHUA_OPCODES EIGEN3_FOUND) - -if(BUILD_CHUA_OPCODES AND EIGEN3_FOUND) - make_plugin(chua ChuaOscillator.cpp) - target_include_directories(chua PRIVATE ${EIGEN3_INCLUDE_DIR} ${CSOUND_INCLUDE_DIRS}) +if(BUILD_CHUA_OPCODES) + make_plugin(chua "6x" ChuaOscillator.cpp) if(USE_VCPKG) target_link_libraries(chua PRIVATE Eigen3::Eigen) else() + target_include_directories(chua PRIVATE ${EIGEN3_INCLUDE_DIR}) target_link_libraries(chua PRIVATE ${EIGEN_LIBRARIES}) endif() @@ -24,4 +28,6 @@ if(BUILD_CHUA_OPCODES AND EIGEN3_FOUND) COMPILE_FLAGS "-Wno-unused-local-typedef" ) endif() + + message(STATUS "Building Chua opcodes") endif() diff --git a/6.x/src/chua/OpcodeBase.hpp b/6.x/src/chua/OpcodeBase.hpp deleted file mode 100644 index 21ca8a0c..00000000 --- a/6.x/src/chua/OpcodeBase.hpp +++ /dev/null @@ -1,492 +0,0 @@ -/* - OpcodeBase.hpp: - - Copyright (C) 2005, 2009, 2017 by Istva Varga, Victor Lazzarini and - Michael Gogins - - This file is part of Csound. - - The Csound Library is free software; you can redistribute it - and/or modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - Csound is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with Csound; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - 02110-1301 USA -*/ -#pragma once - -/** - * There is a conflict between the preprocessor definition "_CR" in the - * standard C++ library and in Csound. To work around this, undefine "_CR" and - * include ALL standard library include files BEFORE including ANY Csound - * include files. - */ -#if defined(_CR) -#undef _CR -#endif - -#include -#include -#include -#if !(defined(__wasi__)) -#include -#endif -#include -#include -#include -#include - -/** - * Template base class, or pseudo-virtual base class, - * for writing Csound opcodes in C++. - * Derive opcode implementation classes like this: - * - * DerivedClass : public OpcodeBase - * { - * public: - * // All output fields must be declared first as MYFLT *: - * MYFLT *aret1; - * // All input fields must be declared next as MYFLT *: - * MYFLT *iarg1; - * MYFLT *karg2; - * MYFLT *aarg3; - * // All internal state variables must be declared after that: - * size_t state1; - * double state2; - * MYFLT state3; - * // If the opcode shares data protect it by creating one or more void - * // *mutex member pointers: - * void *mutex1; - * void *mutex2; - * // and create them usind csound->Create_Mutex() in csoundModuleCreate - * // and destroy them using csound->DeleteMutex(mutex) - * // csoundModuleDestroy, and lock them using LockGuard guard(mutex). - * int init(); - * int kontrol(); - * int audio; - * int noteoff(); - * void deinit(); - * }; - */ - -namespace csound { - -static bool diagnostics_enabled = false; - -/** - * Use this to guard against data races in opcode functions. The mutex should - * be created by csound->Create_Mutex() in csoundModuleCreate(), and should - * be destroyed by csound->DeleteMutex() in csoundModuleDestroy(). - * - * If data is shared between opcode instances, the mutex should be global to - * the opcode library; if data is shared between threads for a single instance, - * the mutex should belong to the opcode instance. - */ -struct LockGuard { - LockGuard(CSOUND *csound_, void *mutex_) : csound(csound_), mutex(mutex_) - { - csound->LockMutex(mutex); - } - ~LockGuard() - { - csound->UnlockMutex(mutex); - } - CSOUND *csound; - void *mutex; -}; - -/** - * Use this to store a pointer to a global heap-allocated object, e.g. one - * used to manage state between opcode instances. - */ - -template int CreateGlobalPointer(CSOUND *csound, const char *name, T *pointer) -{ - T **pointer_to_pointer = 0; - int result = csound->CreateGlobalVariable(csound, name, sizeof(pointer_to_pointer)); - pointer_to_pointer = static_cast(csound->QueryGlobalVariable(csound, name)); - *pointer_to_pointer = pointer; - return result; -} - -/** - * Retrieve a pointer to a global heap-allocated object, e.g. one - * used to manage state between opcode instances. - */ -template T *QueryGlobalPointer(CSOUND *csound, const char *name, T*& pointer) -{ - T **pointer_to_pointer = static_cast(csound->QueryGlobalVariableNoCheck(csound, name)); - if (pointer_to_pointer != 0) { - pointer = *pointer_to_pointer; - } else { - pointer = 0; - } - return pointer; -} - -template -class OpcodeBase -{ -public: - int init(CSOUND *csound) - { - return NOTOK; - } - static int init_(CSOUND *csound, void *opcode) - { - return reinterpret_cast(opcode)->init(csound); - } - int kontrol(CSOUND *csound) - { - return NOTOK; - } - static int kontrol_(CSOUND *csound, void *opcode) - { - return reinterpret_cast(opcode)->kontrol(csound); - } - int audio(CSOUND *csound) - { - return NOTOK; - } - static int audio_(CSOUND *csound, void *opcode) - { - return reinterpret_cast(opcode)->audio(csound); - } - /** - This is how to compute audio signals for normal opcodes: - (1) Zero all frames from 0 up to but not including Offset. - (2) Compute all frames from ksmps_offset up to but not including End. - (3) Zero all frames from End up to but not including ksmps. - Example from a C opcode: - uint32_t offset = p->h.insdshead->ksmps_offset; - uint32_t early = p->h.insdshead->ksmps_no_end; - uint32_t n, nsmps = CS_KSMPS; - if (UNLIKELY(offset)) memset(p->r, '\0', offset*sizeof(MYFLT)); - if (UNLIKELY(early)) { - nsmps -= early; - memset(&p->r[nsmps], '\0', early*sizeof(MYFLT)); - } - for (n = offset; n < nsmps; n++) { - input1 = MYFLT2LRND(p->a[n]); - p->r[n] = (MYFLT) (input1 >> input2); - } - So in C++ it should look like this (which is much easier to understand): - int frameIndex = 0; - for( ; frameIndex < kperiodOffset(); ++frameIndex) { - asignal[frameIndex] = 0; - } - for( ; frameIndex < kperiodEnd(); ++frameIndex) { - asignal[frameIndex] = compute(); - } - for( ; frameIndex < ksmps(); ++frameIndex) { - asignal[frameIndex] = 0; - } - */ - uint32_t kperiodOffset() const - { - return opds.insdshead->ksmps_offset; - } - uint32_t kperiodEnd() const - { - uint32_t end = opds.insdshead->ksmps_no_end; - if (end) { - return end; - } else { - return ksmps(); - } - } - uint32_t ksmps() const - { - return opds.insdshead->ksmps; - } - uint32_t output_arg_count() - { - return (uint32_t)opds.optext->t.outArgCount; - } - uint32_t input_arg_count() - { - return (uint32_t)opds.optext->t.inArgCount; - } - void log(CSOUND *csound, const char *format,...) - { - va_list args; - va_start(args, format); - if(csound) { - csound->MessageV(csound, 0, format, args); - } else { - vfprintf(stdout, format, args); - } - va_end(args); - } - void warn(CSOUND *csound, const char *format,...) - { - if(csound) { - if(csound->GetMessageLevel(csound) & CS_WARNMSG) { - va_list args; - va_start(args, format); - csound->MessageV(csound, CSOUNDMSG_WARNING, format, args); - va_end(args); - } - } else { - va_list args; - va_start(args, format); - vfprintf(stdout, format, args); - va_end(args); - } - } - OPDS opds; -}; - -template -class OpcodeNoteoffBase -{ -public: - int init(CSOUND *csound) - { - IGN(csound); - return NOTOK; - } - static int init_(CSOUND *csound, void *opcode) - { - if (!csound->GetReinitFlag(csound) && !csound->GetTieFlag(csound)) { - csound->RegisterDeinitCallback(csound, opcode, - &OpcodeNoteoffBase::noteoff_); - } - return reinterpret_cast(opcode)->init(csound); - } - int kontrol(CSOUND *csound) - { - IGN(csound); - return NOTOK; - } - static int kontrol_(CSOUND *csound, void *opcode) - { - return reinterpret_cast(opcode)->kontrol(csound); - } - int audio(CSOUND *csound) - { - IGN(csound); - return NOTOK; - } - static int audio_(CSOUND *csound, void *opcode) - { - return reinterpret_cast(opcode)->audio(csound); - } - /** - This is how to compute audio signals for normal opcodes: - (1) Zero all frames from 0 up to but not including Offset. - (2) Compute all frames from ksmps_offset up to but not including End. - (3) Zero all frames from End up to but not including ksmps. - Example from a C opcode: - uint32_t offset = p->h.insdshead->ksmps_offset; - uint32_t early = p->h.insdshead->ksmps_no_end; - uint32_t n, nsmps = CS_KSMPS; - if (UNLIKELY(offset)) memset(p->r, '\0', offset*sizeof(MYFLT)); - if (UNLIKELY(early)) { - nsmps -= early; - memset(&p->r[nsmps], '\0', early*sizeof(MYFLT)); - } - for (n = offset; n < nsmps; n++) { - input1 = MYFLT2LRND(p->a[n]); - p->r[n] = (MYFLT) (input1 >> input2); - } - So in C++ it should look like this (which is much easier to understand): - int frameIndex = 0; - for( ; frameIndex < kperiodOffset(); ++frameIndex) { - asignal[frameIndex] = 0; - } - for( ; frameIndex < kperiodEnd(); ++frameIndex) { - asignal[frameIndex] = compute(); - } - for( ; frameIndex < ksmps(); ++frameIndex) { - asignal[frameIndex] = 0; - } - */ - uint32_t kperiodOffset() const - { - return opds.insdshead->ksmps_offset; - } - uint32_t kperiodEnd() const - { - uint32_t end = opds.insdshead->ksmps_no_end; - if (end) { - return end; - } else { - return ksmps(); - } - } - uint32_t ksmps() const - { - return opds.insdshead->ksmps; - } - uint32_t output_arg_count() - { - return (uint32_t)opds.optext->t.outArgCount; - } - uint32_t input_arg_count() - { - return (uint32_t)opds.optext->t.inArgCount; - } - void log(CSOUND *csound, const char *format,...) - { - va_list args; - va_start(args, format); - if(csound) { - csound->MessageV(csound, 0, format, args); - } else { - vfprintf(stdout, format, args); - } - va_end(args); - } - void warn(CSOUND *csound, const char *format,...) - { - if(csound) { - if(csound->GetMessageLevel(csound) & CS_WARNMSG) { - va_list args; - va_start(args, format); - csound->MessageV(csound, CSOUNDMSG_WARNING, format, args); - va_end(args); - } - } else { - va_list args; - va_start(args, format); - vfprintf(stdout, format, args); - va_end(args); - } - } - int noteoff(CSOUND *csound) - { - return OK; - } - static int noteoff_(CSOUND *csound, void *opcode) - { - return reinterpret_cast(opcode)->noteoff(csound); - } - OPDS opds; -}; - -#if (__cplusplus >= 201103L) && !(defined(__wasi__)) -#pragma message("Defining heap_object_manager_t.") - -/** - * The memory of non-POD C++ or C objects allocated on the heap by Csound - * plugins is managed not by Csound, but by the plugin module. This class - * performs that function. - * - * As long as all memory is allocated in or after csoundModuleCreate and - * de-allocated in csoundModuleDestroy, all will be well. The danger however - * is that memory leaks will occur if allocations are not matched with - * de-allocations, or worse, that crashes will occur if any objects are - * deleted twice or de-referenced after deletion. - * - * So, the plugin should manage a collection of all heap-allocated objects, - * keyed first off the Csound instance, and second off an object handle; and - * all such objects must be accessed only by handle, from this collection. - * - * In csoundModuleDestroy, all objects for the calling instance of Csound - * should be de-allocated, and the sub-collection for that instance should - * also be de-allocated. - * - * If then there are no more sub-collections for other instances of Csound, - * the entire contents of the collection should be de-allocated. - * - * This should be done as a singleton, and in a thread-safe way. - * - * There might still be a problem if any of the heap-allocated objects, - * themselves, have global static members, perhaps created by some external - * dependency. - * - * Please note, objects O in the declaration below must not be std::shared_ptr - * objects. Deletion of objects herein must be unconditional. Rather, the - * objects passed are raw pointers to instances of class O. - */ - template class heap_object_manager_t { - private: - std::map> objects_; - std::recursive_mutex mutex; - heap_object_manager_t(){}; - ~heap_object_manager_t(){}; - public: - static heap_object_manager_t &instance() { - static heap_object_manager_t singleton; - return singleton; - } - std::map> &objects() { - std::lock_guard lock(mutex); - return objects_; - } - /** - * Returns a list of pointers to all objects allocated for this - * instance of Csound. - */ - std::vector &objects_for_csound(CSOUND *csound) { - std::lock_guard lock(mutex); - auto &objects_for_csound_ = objects()[csound]; - return objects_for_csound_; - } - /** - * Returns the handle for the object; if the object has not yet been - * stored, inserts it into the list of object pointers for this - * instance of Csound; otherwise, returns the handle of the stored - * object pointer. - */ - int handle_for_object(CSOUND *csound, O *object) { - std::lock_guard lock(mutex); - auto &objects_for_csound_ = objects_for_csound(csound); - auto iterator = std::find(objects_for_csound_.begin(), objects_for_csound_.end(), object); - if (iterator == objects_for_csound_.end()) { - int handle = objects_for_csound_.size(); - objects_for_csound_.push_back(object); - if (diagnostics_enabled) std::fprintf(stderr, "heap_object_manager_t::handle_for_object %p: new object handle: %d (of %ld)\n", object, handle, objects_for_csound_.size()); - return handle; - } else { - int handle = static_cast(iterator - objects_for_csound_.begin()); - if (diagnostics_enabled) std::fprintf(stderr, "heap_object_manager_t::handle_for_object: existing object handle: %d\n", handle); - return handle; - } - } - /** - * Returns the object pointer for the handle; - * if the object pointer has not been stored by - * handle, returns a null pointer. - */ - O *object_for_handle(CSOUND *csound, int handle) { - std::lock_guard lock(mutex); - auto &objects_for_csound_ = objects_for_csound(csound); - if (handle >= objects_for_csound_.size()) { - return nullptr; - } - O *object = objects_for_csound_[handle]; - if (diagnostics_enabled) std::fprintf(stderr, "heap_object_manager_t::object_for_handle: %p %d (of %ld)\n", object, handle, objects_for_csound_.size()); - return object; - } - /** - * First destroys all objects created by the calling - * instance of Csound, then destroys the list of - * object pointers for this instance of Csound. - */ - void module_destroy(CSOUND *csound) { - std::lock_guard lock(mutex); - auto &objects_for_csound_ = objects_for_csound(csound); - for (int i = 0, n = objects_for_csound_.size(); i < n; ++i) { - delete objects_for_csound_[i]; - objects_for_csound_[i] = nullptr; - } - objects_for_csound_.clear(); - objects().erase(csound); - } -}; - -#else -#pragma message("Not defining heap_manager_t.") -#endif - -} diff --git a/6.x/src/faustcsound/CMakeLists.txt b/6.x/src/faustcsound/CMakeLists.txt index 45b9d3dd..17b0042c 100644 --- a/6.x/src/faustcsound/CMakeLists.txt +++ b/6.x/src/faustcsound/CMakeLists.txt @@ -1,11 +1,13 @@ # Build faustcsound opcodes option(BUILD_FAUST_OPCODES "Build the Faust opcodes" ON) +set(THREADS_PREFER_PTHREAD_FLAG ON) +find_package(Threads) find_package(FAUST) -check_deps(BUILD_FAUST_OPCODES FAUST_FOUND) -if(BUILD_FAUST_OPCODES AND FAUST_FOUND) - make_plugin(faustcsound faustgen.cpp) +check_deps(BUILD_FAUST_OPCODES FAUST_FOUND Threads_FOUND) +if(BUILD_FAUST_OPCODES) + make_plugin(faustcsound "6x" faustgen.cpp) if(APPLE) set_target_properties(faustcsound PROPERTIES @@ -13,25 +15,10 @@ if(BUILD_FAUST_OPCODES AND FAUST_FOUND) ) endif() - target_include_directories(faustcsound PRIVATE ${CSOUND_INCLUDE_DIRS}) - target_link_libraries(faustcsound ${PTHREAD_LIBRARY}) + target_include_directories(faustcsound PRIVATE ${FAUST_INCLUDE_DIR}) target_compile_definitions(faustcsound PRIVATE "-DFAUSTFLOAT=MYFLT") + target_compile_features(faustcsound PRIVATE cxx_std_11) + target_link_libraries(faustcsound PRIVATE Threads::Threads ${FAUST_LIBRARIES}) - if(PTHREAD_LIBRARY) - target_compile_definitions(faustcsound PRIVATE "-DHAVE_PTHREAD") - endif() - - if(APPLE) - if(${OSX_VERSION} STREQUAL "10.6") - target_link_libraries(faustcsound ${FAUST_LIBRARIES}) - else() - target_compile_options(faustcsound PRIVATE "-stdlib=libc++") - target_link_libraries(faustcsound ${FAUST_LIBRARIES} -stdlib=libc++) - endif() - else() - target_link_libraries(faustcsound ${FAUST_LIBRARIES}) - endif() - - target_include_directories(faustcsound PRIVATE ${FAUST_INCLUDE_DIR}) - message("-- FAUST INCLUDE DIR: ${FAUST_INCLUDE_DIR}") + message(STATUS "Building faust opcodes") endif() diff --git a/6.x/src/faustcsound/faustgen.cpp b/6.x/src/faustcsound/faustgen.cpp index bf885305..16b4be7e 100644 --- a/6.x/src/faustcsound/faustgen.cpp +++ b/6.x/src/faustcsound/faustgen.cpp @@ -276,7 +276,6 @@ void *init_faustcompile_thread(void *pp) { char *ccode = csound->Strdup(csound, p->code->data); char *extra; MYFLT test = *p->extra; - int32_t ret; strcpy(cmd, p->args->data); #ifdef USE_DOUBLE strcat(cmd, " -double"); @@ -305,7 +304,6 @@ void *init_faustcompile_thread(void *pp) { csound->Free(csound, cmd); csound->Free(csound, ccode); csound->Free(csound, pp); - ret = -1; return NULL; } @@ -348,7 +346,7 @@ int32_t init_faustcompile(CSOUND *csound, faustcompile *p) { data->p = p; *p->hptr = -1.0; p->lock = csound->Create_Mutex(0); - + /* New API function allows thread stack to be defined - new in Csound 6.17 */ thread = (uintptr_t) csound->CreateThread2((uintptr_t (*)(void *))init_faustcompile_thread, *p->stacksize * MBYTE, data); @@ -824,16 +822,14 @@ void *init_faustgen_thread(void *pp) { p->factory = createDSPFactoryFromString( "faustop", (const char *)p->code->data, argc, argv, "", err_msg, 3); if (p->factory == NULL) { - int32_t ret = csound->InitError(csound, Str("Faust compilation problem: %s\n"), - err_msg.c_str()); + csound->InitError(csound, Str("Faust compilation problem: %s\n"), err_msg.c_str()); csound->Free(csound, pp); return NULL; } dsp = p->factory->createDSPInstance(); if (dsp == NULL) { - int32_t ret = csound->InitError(csound, "%s", - Str("Faust instantiation problem\n")); + csound->InitError(csound, "%s", Str("Faust instantiation problem\n")); csound->Free(csound, pp); return NULL; } @@ -866,22 +862,20 @@ void *init_faustgen_thread(void *pp) { dsp->buildUserInterface(ctls); dsp->init(csound->GetSr(csound)); if (p->engine->getNumInputs() != p->INCOUNT - 1) { - int32_t ret; - ret = csound->InitError(csound, "%s", Str("wrong number of input args\n")); + csound->InitError(csound, "%s", Str("wrong number of input args\n")); delete p->engine; deleteDSPFactory(p->factory); p->factory = NULL; p->engine = NULL; csound->Free(csound, pp); - return NULL; + return NULL; } if (p->engine->getNumOutputs() != p->OUTCOUNT - 1) { - int32_t ret; - ret = csound->InitError(csound, - Str("wrong number of output args: need %d had %d\n"), - p->engine->getNumOutputs(), - p->OUTCOUNT - 1 - ); + csound->InitError(csound, + Str("wrong number of output args: need %d had %d\n"), + p->engine->getNumOutputs(), + p->OUTCOUNT - 1 + ); delete p->engine; deleteDSPFactory(p->factory); csound->Free(csound, pp); @@ -908,8 +902,7 @@ void *init_faustgen_thread(void *pp) { } int32_t init_faustgen(CSOUND *csound, faustgen *p) { - uintptr_t thread; - int32_t *ret; + uintptr_t thread; hdata2 *data = (hdata2 *)csound->Malloc(csound, sizeof(hdata2)); data->csound = csound; data->p = p; diff --git a/6.x/src/fluidOpcodes/CMakeLists.txt b/6.x/src/fluidOpcodes/CMakeLists.txt index 0e6caa37..3b7d0745 100644 --- a/6.x/src/fluidOpcodes/CMakeLists.txt +++ b/6.x/src/fluidOpcodes/CMakeLists.txt @@ -1,11 +1,26 @@ -option(BUILD_FLUID_OPCODES "Build the fluidsynth opcodes" ON) +option(BUILD_FLUID_OPCODES "Build the fluidsynth opcodes" OFF) -find_package(FLUIDSYNTH) -check_deps(BUILD_FLUID_OPCODES FLUIDSYNTH_FOUND) +if(USE_VCPKG) + find_package(FluidSynth CONFIG) -if(BUILD_FLUID_OPCODES AND FLUIDSYNTH_FOUND) - make_plugin(fluidOpcodes fluidOpcodes.cpp) - target_include_directories(fluidOpcodes PRIVATE ${FLUIDSYNTH_INCLUDE_DIR}) - target_include_directories(fluidOpcodes PRIVATE ${CSOUND_INCLUDE_DIR}) - target_link_libraries(fluidOpcodes ${FLUIDSYNTH_LIBRARIES}) + if(NOT TARGET FluidSynth::libfluidsynth) + message(STATUS "Could not find FluidSynth::libfluidsynth") + set(BUILD_FLUID_OPCODES OFF) + endif() +else() + find_package(FLUIDSYNTH) + check_deps(BUILD_FLUID_OPCODES FLUIDSYNTH_FOUND) +endif() + +if(BUILD_FLUID_OPCODES) + make_plugin(fluidOpcodes "6x" fluidOpcodes.cpp) + + if(USE_VCPKG) + target_link_libraries(fluidOpcodes PRIVATE FluidSynth::libfluidsynth) + else() + target_include_directories(fluidOpcodes PRIVATE ${FLUIDSYNTH_INCLUDE_DIR}) + target_link_libraries(fluidOpcodes ${FLUIDSYNTH_LIBRARIES}) + endif() + + message(STATUS "Building Fluid opcodes") endif() diff --git a/6.x/src/fluidOpcodes/OpcodeBase.hpp b/6.x/src/fluidOpcodes/OpcodeBase.hpp deleted file mode 100644 index 21ca8a0c..00000000 --- a/6.x/src/fluidOpcodes/OpcodeBase.hpp +++ /dev/null @@ -1,492 +0,0 @@ -/* - OpcodeBase.hpp: - - Copyright (C) 2005, 2009, 2017 by Istva Varga, Victor Lazzarini and - Michael Gogins - - This file is part of Csound. - - The Csound Library is free software; you can redistribute it - and/or modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - Csound is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with Csound; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - 02110-1301 USA -*/ -#pragma once - -/** - * There is a conflict between the preprocessor definition "_CR" in the - * standard C++ library and in Csound. To work around this, undefine "_CR" and - * include ALL standard library include files BEFORE including ANY Csound - * include files. - */ -#if defined(_CR) -#undef _CR -#endif - -#include -#include -#include -#if !(defined(__wasi__)) -#include -#endif -#include -#include -#include -#include - -/** - * Template base class, or pseudo-virtual base class, - * for writing Csound opcodes in C++. - * Derive opcode implementation classes like this: - * - * DerivedClass : public OpcodeBase - * { - * public: - * // All output fields must be declared first as MYFLT *: - * MYFLT *aret1; - * // All input fields must be declared next as MYFLT *: - * MYFLT *iarg1; - * MYFLT *karg2; - * MYFLT *aarg3; - * // All internal state variables must be declared after that: - * size_t state1; - * double state2; - * MYFLT state3; - * // If the opcode shares data protect it by creating one or more void - * // *mutex member pointers: - * void *mutex1; - * void *mutex2; - * // and create them usind csound->Create_Mutex() in csoundModuleCreate - * // and destroy them using csound->DeleteMutex(mutex) - * // csoundModuleDestroy, and lock them using LockGuard guard(mutex). - * int init(); - * int kontrol(); - * int audio; - * int noteoff(); - * void deinit(); - * }; - */ - -namespace csound { - -static bool diagnostics_enabled = false; - -/** - * Use this to guard against data races in opcode functions. The mutex should - * be created by csound->Create_Mutex() in csoundModuleCreate(), and should - * be destroyed by csound->DeleteMutex() in csoundModuleDestroy(). - * - * If data is shared between opcode instances, the mutex should be global to - * the opcode library; if data is shared between threads for a single instance, - * the mutex should belong to the opcode instance. - */ -struct LockGuard { - LockGuard(CSOUND *csound_, void *mutex_) : csound(csound_), mutex(mutex_) - { - csound->LockMutex(mutex); - } - ~LockGuard() - { - csound->UnlockMutex(mutex); - } - CSOUND *csound; - void *mutex; -}; - -/** - * Use this to store a pointer to a global heap-allocated object, e.g. one - * used to manage state between opcode instances. - */ - -template int CreateGlobalPointer(CSOUND *csound, const char *name, T *pointer) -{ - T **pointer_to_pointer = 0; - int result = csound->CreateGlobalVariable(csound, name, sizeof(pointer_to_pointer)); - pointer_to_pointer = static_cast(csound->QueryGlobalVariable(csound, name)); - *pointer_to_pointer = pointer; - return result; -} - -/** - * Retrieve a pointer to a global heap-allocated object, e.g. one - * used to manage state between opcode instances. - */ -template T *QueryGlobalPointer(CSOUND *csound, const char *name, T*& pointer) -{ - T **pointer_to_pointer = static_cast(csound->QueryGlobalVariableNoCheck(csound, name)); - if (pointer_to_pointer != 0) { - pointer = *pointer_to_pointer; - } else { - pointer = 0; - } - return pointer; -} - -template -class OpcodeBase -{ -public: - int init(CSOUND *csound) - { - return NOTOK; - } - static int init_(CSOUND *csound, void *opcode) - { - return reinterpret_cast(opcode)->init(csound); - } - int kontrol(CSOUND *csound) - { - return NOTOK; - } - static int kontrol_(CSOUND *csound, void *opcode) - { - return reinterpret_cast(opcode)->kontrol(csound); - } - int audio(CSOUND *csound) - { - return NOTOK; - } - static int audio_(CSOUND *csound, void *opcode) - { - return reinterpret_cast(opcode)->audio(csound); - } - /** - This is how to compute audio signals for normal opcodes: - (1) Zero all frames from 0 up to but not including Offset. - (2) Compute all frames from ksmps_offset up to but not including End. - (3) Zero all frames from End up to but not including ksmps. - Example from a C opcode: - uint32_t offset = p->h.insdshead->ksmps_offset; - uint32_t early = p->h.insdshead->ksmps_no_end; - uint32_t n, nsmps = CS_KSMPS; - if (UNLIKELY(offset)) memset(p->r, '\0', offset*sizeof(MYFLT)); - if (UNLIKELY(early)) { - nsmps -= early; - memset(&p->r[nsmps], '\0', early*sizeof(MYFLT)); - } - for (n = offset; n < nsmps; n++) { - input1 = MYFLT2LRND(p->a[n]); - p->r[n] = (MYFLT) (input1 >> input2); - } - So in C++ it should look like this (which is much easier to understand): - int frameIndex = 0; - for( ; frameIndex < kperiodOffset(); ++frameIndex) { - asignal[frameIndex] = 0; - } - for( ; frameIndex < kperiodEnd(); ++frameIndex) { - asignal[frameIndex] = compute(); - } - for( ; frameIndex < ksmps(); ++frameIndex) { - asignal[frameIndex] = 0; - } - */ - uint32_t kperiodOffset() const - { - return opds.insdshead->ksmps_offset; - } - uint32_t kperiodEnd() const - { - uint32_t end = opds.insdshead->ksmps_no_end; - if (end) { - return end; - } else { - return ksmps(); - } - } - uint32_t ksmps() const - { - return opds.insdshead->ksmps; - } - uint32_t output_arg_count() - { - return (uint32_t)opds.optext->t.outArgCount; - } - uint32_t input_arg_count() - { - return (uint32_t)opds.optext->t.inArgCount; - } - void log(CSOUND *csound, const char *format,...) - { - va_list args; - va_start(args, format); - if(csound) { - csound->MessageV(csound, 0, format, args); - } else { - vfprintf(stdout, format, args); - } - va_end(args); - } - void warn(CSOUND *csound, const char *format,...) - { - if(csound) { - if(csound->GetMessageLevel(csound) & CS_WARNMSG) { - va_list args; - va_start(args, format); - csound->MessageV(csound, CSOUNDMSG_WARNING, format, args); - va_end(args); - } - } else { - va_list args; - va_start(args, format); - vfprintf(stdout, format, args); - va_end(args); - } - } - OPDS opds; -}; - -template -class OpcodeNoteoffBase -{ -public: - int init(CSOUND *csound) - { - IGN(csound); - return NOTOK; - } - static int init_(CSOUND *csound, void *opcode) - { - if (!csound->GetReinitFlag(csound) && !csound->GetTieFlag(csound)) { - csound->RegisterDeinitCallback(csound, opcode, - &OpcodeNoteoffBase::noteoff_); - } - return reinterpret_cast(opcode)->init(csound); - } - int kontrol(CSOUND *csound) - { - IGN(csound); - return NOTOK; - } - static int kontrol_(CSOUND *csound, void *opcode) - { - return reinterpret_cast(opcode)->kontrol(csound); - } - int audio(CSOUND *csound) - { - IGN(csound); - return NOTOK; - } - static int audio_(CSOUND *csound, void *opcode) - { - return reinterpret_cast(opcode)->audio(csound); - } - /** - This is how to compute audio signals for normal opcodes: - (1) Zero all frames from 0 up to but not including Offset. - (2) Compute all frames from ksmps_offset up to but not including End. - (3) Zero all frames from End up to but not including ksmps. - Example from a C opcode: - uint32_t offset = p->h.insdshead->ksmps_offset; - uint32_t early = p->h.insdshead->ksmps_no_end; - uint32_t n, nsmps = CS_KSMPS; - if (UNLIKELY(offset)) memset(p->r, '\0', offset*sizeof(MYFLT)); - if (UNLIKELY(early)) { - nsmps -= early; - memset(&p->r[nsmps], '\0', early*sizeof(MYFLT)); - } - for (n = offset; n < nsmps; n++) { - input1 = MYFLT2LRND(p->a[n]); - p->r[n] = (MYFLT) (input1 >> input2); - } - So in C++ it should look like this (which is much easier to understand): - int frameIndex = 0; - for( ; frameIndex < kperiodOffset(); ++frameIndex) { - asignal[frameIndex] = 0; - } - for( ; frameIndex < kperiodEnd(); ++frameIndex) { - asignal[frameIndex] = compute(); - } - for( ; frameIndex < ksmps(); ++frameIndex) { - asignal[frameIndex] = 0; - } - */ - uint32_t kperiodOffset() const - { - return opds.insdshead->ksmps_offset; - } - uint32_t kperiodEnd() const - { - uint32_t end = opds.insdshead->ksmps_no_end; - if (end) { - return end; - } else { - return ksmps(); - } - } - uint32_t ksmps() const - { - return opds.insdshead->ksmps; - } - uint32_t output_arg_count() - { - return (uint32_t)opds.optext->t.outArgCount; - } - uint32_t input_arg_count() - { - return (uint32_t)opds.optext->t.inArgCount; - } - void log(CSOUND *csound, const char *format,...) - { - va_list args; - va_start(args, format); - if(csound) { - csound->MessageV(csound, 0, format, args); - } else { - vfprintf(stdout, format, args); - } - va_end(args); - } - void warn(CSOUND *csound, const char *format,...) - { - if(csound) { - if(csound->GetMessageLevel(csound) & CS_WARNMSG) { - va_list args; - va_start(args, format); - csound->MessageV(csound, CSOUNDMSG_WARNING, format, args); - va_end(args); - } - } else { - va_list args; - va_start(args, format); - vfprintf(stdout, format, args); - va_end(args); - } - } - int noteoff(CSOUND *csound) - { - return OK; - } - static int noteoff_(CSOUND *csound, void *opcode) - { - return reinterpret_cast(opcode)->noteoff(csound); - } - OPDS opds; -}; - -#if (__cplusplus >= 201103L) && !(defined(__wasi__)) -#pragma message("Defining heap_object_manager_t.") - -/** - * The memory of non-POD C++ or C objects allocated on the heap by Csound - * plugins is managed not by Csound, but by the plugin module. This class - * performs that function. - * - * As long as all memory is allocated in or after csoundModuleCreate and - * de-allocated in csoundModuleDestroy, all will be well. The danger however - * is that memory leaks will occur if allocations are not matched with - * de-allocations, or worse, that crashes will occur if any objects are - * deleted twice or de-referenced after deletion. - * - * So, the plugin should manage a collection of all heap-allocated objects, - * keyed first off the Csound instance, and second off an object handle; and - * all such objects must be accessed only by handle, from this collection. - * - * In csoundModuleDestroy, all objects for the calling instance of Csound - * should be de-allocated, and the sub-collection for that instance should - * also be de-allocated. - * - * If then there are no more sub-collections for other instances of Csound, - * the entire contents of the collection should be de-allocated. - * - * This should be done as a singleton, and in a thread-safe way. - * - * There might still be a problem if any of the heap-allocated objects, - * themselves, have global static members, perhaps created by some external - * dependency. - * - * Please note, objects O in the declaration below must not be std::shared_ptr - * objects. Deletion of objects herein must be unconditional. Rather, the - * objects passed are raw pointers to instances of class O. - */ - template class heap_object_manager_t { - private: - std::map> objects_; - std::recursive_mutex mutex; - heap_object_manager_t(){}; - ~heap_object_manager_t(){}; - public: - static heap_object_manager_t &instance() { - static heap_object_manager_t singleton; - return singleton; - } - std::map> &objects() { - std::lock_guard lock(mutex); - return objects_; - } - /** - * Returns a list of pointers to all objects allocated for this - * instance of Csound. - */ - std::vector &objects_for_csound(CSOUND *csound) { - std::lock_guard lock(mutex); - auto &objects_for_csound_ = objects()[csound]; - return objects_for_csound_; - } - /** - * Returns the handle for the object; if the object has not yet been - * stored, inserts it into the list of object pointers for this - * instance of Csound; otherwise, returns the handle of the stored - * object pointer. - */ - int handle_for_object(CSOUND *csound, O *object) { - std::lock_guard lock(mutex); - auto &objects_for_csound_ = objects_for_csound(csound); - auto iterator = std::find(objects_for_csound_.begin(), objects_for_csound_.end(), object); - if (iterator == objects_for_csound_.end()) { - int handle = objects_for_csound_.size(); - objects_for_csound_.push_back(object); - if (diagnostics_enabled) std::fprintf(stderr, "heap_object_manager_t::handle_for_object %p: new object handle: %d (of %ld)\n", object, handle, objects_for_csound_.size()); - return handle; - } else { - int handle = static_cast(iterator - objects_for_csound_.begin()); - if (diagnostics_enabled) std::fprintf(stderr, "heap_object_manager_t::handle_for_object: existing object handle: %d\n", handle); - return handle; - } - } - /** - * Returns the object pointer for the handle; - * if the object pointer has not been stored by - * handle, returns a null pointer. - */ - O *object_for_handle(CSOUND *csound, int handle) { - std::lock_guard lock(mutex); - auto &objects_for_csound_ = objects_for_csound(csound); - if (handle >= objects_for_csound_.size()) { - return nullptr; - } - O *object = objects_for_csound_[handle]; - if (diagnostics_enabled) std::fprintf(stderr, "heap_object_manager_t::object_for_handle: %p %d (of %ld)\n", object, handle, objects_for_csound_.size()); - return object; - } - /** - * First destroys all objects created by the calling - * instance of Csound, then destroys the list of - * object pointers for this instance of Csound. - */ - void module_destroy(CSOUND *csound) { - std::lock_guard lock(mutex); - auto &objects_for_csound_ = objects_for_csound(csound); - for (int i = 0, n = objects_for_csound_.size(); i < n; ++i) { - delete objects_for_csound_[i]; - objects_for_csound_[i] = nullptr; - } - objects_for_csound_.clear(); - objects().erase(csound); - } -}; - -#else -#pragma message("Not defining heap_manager_t.") -#endif - -} diff --git a/6.x/src/hdf5/CMakeLists.txt b/6.x/src/hdf5/CMakeLists.txt index 7ea0f1a9..15a09283 100644 --- a/6.x/src/hdf5/CMakeLists.txt +++ b/6.x/src/hdf5/CMakeLists.txt @@ -1,16 +1,26 @@ option(BUILD_HDF5_OPCODES "Build the hdf5 read/write opcodes" ON) -find_package(HDF5) -check_deps(BUILD_HDF5_OPCODES HDF5_FOUND) +if(USE_VCPKG) + find_package(HDF5 CONFIG REQUIRED) -if(BUILD_HDF5_OPCODES AND HDF5_FOUND) + if(NOT TARGET hdf5::hdf5-static AND NOT TARGET hdf5::hdf5-shared) + message(STATUS "Could not find hdf5") + set(BUILD_HDF5_OPCODES OFF) + endif() +else() + find_package(HDF5) + check_deps(BUILD_HDF5_OPCODES HDF5_FOUND) +endif() + +if(BUILD_HDF5_OPCODES) # split version string, as cmake doesn't do this automatically string(REPLACE "." ";" VERSION_LIST ${HDF5_VERSION}) + list(GET VERSION_LIST 0 HDF5_VERSION_MAJOR) list(GET VERSION_LIST 1 HDF5_VERSION_MINOR) list(GET VERSION_LIST 2 HDF5_VERSION_PATCH) - make_plugin(hdf5ops HDF5IO.c) + make_plugin(hdf5ops "6x" HDF5IO.c) target_compile_definitions(hdf5ops PRIVATE -DHDF5_VERSION_MAJOR=${HDF5_VERSION_MAJOR} @@ -19,13 +29,17 @@ if(BUILD_HDF5_OPCODES AND HDF5_FOUND) ) if(USE_VCPKG) - target_include_directories(hdf5ops PRIVATE ${HDF5_INCLUDE_DIRS} ${CSOUND_INCLUDE_DIRS}) - target_link_libraries(hdf5ops PRIVATE hdf5::hdf5-static hdf5::hdf5_hl-static) + target_link_libraries(hdf5ops PRIVATE + $,hdf5::hdf5-static,hdf5::hdf5-shared> + $,hdf5::hdf5_hl-static,hdf5::hdf5_hl-shared> + ) else() message(STATUS "HDF5_INCLUDE_DIRS: ${HDF5_INCLUDE_DIRS}") message(STATUS "HDF5_LIBRARIES: ${HDF5_LIBRARIES}") - target_include_directories(hdf5ops PRIVATE ${HDF5_INCLUDE_DIRS} ${CSOUND_INCLUDE_DIRS}) + target_include_directories(hdf5ops PRIVATE ${HDF5_INCLUDE_DIRS}) target_link_libraries(hdf5ops ${HDF5_LIBRARIES}) endif() + + message(STATUS "Building HDF5 opcodes") endif() diff --git a/6.x/src/hdf5/HDF5IO.c b/6.x/src/hdf5/HDF5IO.c index 8d45ef5f..720ee001 100644 --- a/6.x/src/hdf5/HDF5IO.c +++ b/6.x/src/hdf5/HDF5IO.c @@ -230,7 +230,7 @@ void HDF5IO_readStringAttribute(CSOUND *csound, HDF5File *self, hid_t dataSetID = H5Dopen2(self->fileHandle, datasetName, H5P_DEFAULT); H5O_info_t oinfo; #if HDF5_VERSION_MAJOR == 1 && HDF5_VERSION_MINOR >= 12 - HDF5ERROR(H5Oget_info1(dataSetID, &oinfo)); + HDF5ERROR(H5Oget_info(dataSetID, &oinfo, 0)); #else HDF5ERROR(H5Oget_info(dataSetID, &oinfo)); #endif diff --git a/6.x/src/image/CMakeLists.txt b/6.x/src/image/CMakeLists.txt index 76123b24..366de61b 100644 --- a/6.x/src/image/CMakeLists.txt +++ b/6.x/src/image/CMakeLists.txt @@ -1,15 +1,28 @@ # Build image opcodes option(BUILD_IMAGE_OPCODES "Build the image opcodes" ON) -if(${BUILD_IMAGE_OPCODES}) - find_package(PNG) - check_deps(BUILD_IMAGE_OPCODES PNG_FOUND) - - if(BUILD_IMAGE_OPCODES) - make_plugin(image imageOpcodes.c) - target_include_directories(image PRIVATE ${CSOUND_INCLUDE_DIRS}) - target_include_directories(image PRIVATE ${PNG_INCLUDE_DIR}) - target_link_libraries(image ${PNG_LIBRARIES}) - target_compile_definitions(image PRIVATE ${PNG_DEFINITIONS}) - endif() +if(USE_VCPKG) + find_package(PNG REQUIRED) + + if(NOT TARGET PNG::PNG) + message(STATUS "Could not find libpng") + set(BUILD_IMAGE_OPCODES OFF) + endif() +else() + find_package(PNG) + check_deps(BUILD_IMAGE_OPCODES PNG_FOUND) +endif() + +if(BUILD_IMAGE_OPCODES) + make_plugin(image "6x" imageOpcodes.c) + + if(USE_VCPKG) + target_link_libraries(image PRIVATE PNG::PNG) + else() + target_compile_definitions(image PRIVATE ${PNG_DEFINITIONS}) + target_include_directories(image PRIVATE ${PNG_INCLUDE_DIR}) + target_link_libraries(image ${PNG_LIBRARIES}) + endif() + + message(STATUS "Building Image opcodes") endif() diff --git a/6.x/src/jackops/CMakeLists.txt b/6.x/src/jackops/CMakeLists.txt index c5ff8411..c8b23df8 100644 --- a/6.x/src/jackops/CMakeLists.txt +++ b/6.x/src/jackops/CMakeLists.txt @@ -6,18 +6,14 @@ find_path (JACK_INCLUDE_DIR jack/jack.h HINTS /usr/local/include) check_deps(BUILD_JACK_OPCODES JACK_LIB) if(BUILD_JACK_OPCODES AND JACK_LIB) - list(APPEND jack_LIBS ${JACK_LIB}) - - make_plugin(jacko jacko.cpp "${jack_LIBS}") - target_include_directories(jacko PRIVATE ${CSOUND_INCLUDE_DIRS}) + + make_plugin(jacko "6x" jacko.cpp "${jack_LIBS}") target_include_directories(jacko PRIVATE ${JACK_INCLUDE_DIR}) set_property(TARGET jacko PROPERTY CXX_STANDARD 20) set_property(TARGET jacko PROPERTY CXX_STANDARD_REQUIRED On) set_property(TARGET jacko PROPERTY CXX_EXTENSIONS Off) - - make_plugin(jackTransport jackTransport.c "${jack_LIBS}") - target_include_directories(jackTransport PRIVATE ${CSOUND_INCLUDE_DIRS}) + + make_plugin(jackTransport "6x" jackTransport.c "${jack_LIBS}") target_include_directories(jackTransport PRIVATE ${JACK_INCLUDE_DIR}) - endif() diff --git a/6.x/src/jackops/OpcodeBase.hpp b/6.x/src/jackops/OpcodeBase.hpp deleted file mode 100644 index 21ca8a0c..00000000 --- a/6.x/src/jackops/OpcodeBase.hpp +++ /dev/null @@ -1,492 +0,0 @@ -/* - OpcodeBase.hpp: - - Copyright (C) 2005, 2009, 2017 by Istva Varga, Victor Lazzarini and - Michael Gogins - - This file is part of Csound. - - The Csound Library is free software; you can redistribute it - and/or modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - Csound is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with Csound; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - 02110-1301 USA -*/ -#pragma once - -/** - * There is a conflict between the preprocessor definition "_CR" in the - * standard C++ library and in Csound. To work around this, undefine "_CR" and - * include ALL standard library include files BEFORE including ANY Csound - * include files. - */ -#if defined(_CR) -#undef _CR -#endif - -#include -#include -#include -#if !(defined(__wasi__)) -#include -#endif -#include -#include -#include -#include - -/** - * Template base class, or pseudo-virtual base class, - * for writing Csound opcodes in C++. - * Derive opcode implementation classes like this: - * - * DerivedClass : public OpcodeBase - * { - * public: - * // All output fields must be declared first as MYFLT *: - * MYFLT *aret1; - * // All input fields must be declared next as MYFLT *: - * MYFLT *iarg1; - * MYFLT *karg2; - * MYFLT *aarg3; - * // All internal state variables must be declared after that: - * size_t state1; - * double state2; - * MYFLT state3; - * // If the opcode shares data protect it by creating one or more void - * // *mutex member pointers: - * void *mutex1; - * void *mutex2; - * // and create them usind csound->Create_Mutex() in csoundModuleCreate - * // and destroy them using csound->DeleteMutex(mutex) - * // csoundModuleDestroy, and lock them using LockGuard guard(mutex). - * int init(); - * int kontrol(); - * int audio; - * int noteoff(); - * void deinit(); - * }; - */ - -namespace csound { - -static bool diagnostics_enabled = false; - -/** - * Use this to guard against data races in opcode functions. The mutex should - * be created by csound->Create_Mutex() in csoundModuleCreate(), and should - * be destroyed by csound->DeleteMutex() in csoundModuleDestroy(). - * - * If data is shared between opcode instances, the mutex should be global to - * the opcode library; if data is shared between threads for a single instance, - * the mutex should belong to the opcode instance. - */ -struct LockGuard { - LockGuard(CSOUND *csound_, void *mutex_) : csound(csound_), mutex(mutex_) - { - csound->LockMutex(mutex); - } - ~LockGuard() - { - csound->UnlockMutex(mutex); - } - CSOUND *csound; - void *mutex; -}; - -/** - * Use this to store a pointer to a global heap-allocated object, e.g. one - * used to manage state between opcode instances. - */ - -template int CreateGlobalPointer(CSOUND *csound, const char *name, T *pointer) -{ - T **pointer_to_pointer = 0; - int result = csound->CreateGlobalVariable(csound, name, sizeof(pointer_to_pointer)); - pointer_to_pointer = static_cast(csound->QueryGlobalVariable(csound, name)); - *pointer_to_pointer = pointer; - return result; -} - -/** - * Retrieve a pointer to a global heap-allocated object, e.g. one - * used to manage state between opcode instances. - */ -template T *QueryGlobalPointer(CSOUND *csound, const char *name, T*& pointer) -{ - T **pointer_to_pointer = static_cast(csound->QueryGlobalVariableNoCheck(csound, name)); - if (pointer_to_pointer != 0) { - pointer = *pointer_to_pointer; - } else { - pointer = 0; - } - return pointer; -} - -template -class OpcodeBase -{ -public: - int init(CSOUND *csound) - { - return NOTOK; - } - static int init_(CSOUND *csound, void *opcode) - { - return reinterpret_cast(opcode)->init(csound); - } - int kontrol(CSOUND *csound) - { - return NOTOK; - } - static int kontrol_(CSOUND *csound, void *opcode) - { - return reinterpret_cast(opcode)->kontrol(csound); - } - int audio(CSOUND *csound) - { - return NOTOK; - } - static int audio_(CSOUND *csound, void *opcode) - { - return reinterpret_cast(opcode)->audio(csound); - } - /** - This is how to compute audio signals for normal opcodes: - (1) Zero all frames from 0 up to but not including Offset. - (2) Compute all frames from ksmps_offset up to but not including End. - (3) Zero all frames from End up to but not including ksmps. - Example from a C opcode: - uint32_t offset = p->h.insdshead->ksmps_offset; - uint32_t early = p->h.insdshead->ksmps_no_end; - uint32_t n, nsmps = CS_KSMPS; - if (UNLIKELY(offset)) memset(p->r, '\0', offset*sizeof(MYFLT)); - if (UNLIKELY(early)) { - nsmps -= early; - memset(&p->r[nsmps], '\0', early*sizeof(MYFLT)); - } - for (n = offset; n < nsmps; n++) { - input1 = MYFLT2LRND(p->a[n]); - p->r[n] = (MYFLT) (input1 >> input2); - } - So in C++ it should look like this (which is much easier to understand): - int frameIndex = 0; - for( ; frameIndex < kperiodOffset(); ++frameIndex) { - asignal[frameIndex] = 0; - } - for( ; frameIndex < kperiodEnd(); ++frameIndex) { - asignal[frameIndex] = compute(); - } - for( ; frameIndex < ksmps(); ++frameIndex) { - asignal[frameIndex] = 0; - } - */ - uint32_t kperiodOffset() const - { - return opds.insdshead->ksmps_offset; - } - uint32_t kperiodEnd() const - { - uint32_t end = opds.insdshead->ksmps_no_end; - if (end) { - return end; - } else { - return ksmps(); - } - } - uint32_t ksmps() const - { - return opds.insdshead->ksmps; - } - uint32_t output_arg_count() - { - return (uint32_t)opds.optext->t.outArgCount; - } - uint32_t input_arg_count() - { - return (uint32_t)opds.optext->t.inArgCount; - } - void log(CSOUND *csound, const char *format,...) - { - va_list args; - va_start(args, format); - if(csound) { - csound->MessageV(csound, 0, format, args); - } else { - vfprintf(stdout, format, args); - } - va_end(args); - } - void warn(CSOUND *csound, const char *format,...) - { - if(csound) { - if(csound->GetMessageLevel(csound) & CS_WARNMSG) { - va_list args; - va_start(args, format); - csound->MessageV(csound, CSOUNDMSG_WARNING, format, args); - va_end(args); - } - } else { - va_list args; - va_start(args, format); - vfprintf(stdout, format, args); - va_end(args); - } - } - OPDS opds; -}; - -template -class OpcodeNoteoffBase -{ -public: - int init(CSOUND *csound) - { - IGN(csound); - return NOTOK; - } - static int init_(CSOUND *csound, void *opcode) - { - if (!csound->GetReinitFlag(csound) && !csound->GetTieFlag(csound)) { - csound->RegisterDeinitCallback(csound, opcode, - &OpcodeNoteoffBase::noteoff_); - } - return reinterpret_cast(opcode)->init(csound); - } - int kontrol(CSOUND *csound) - { - IGN(csound); - return NOTOK; - } - static int kontrol_(CSOUND *csound, void *opcode) - { - return reinterpret_cast(opcode)->kontrol(csound); - } - int audio(CSOUND *csound) - { - IGN(csound); - return NOTOK; - } - static int audio_(CSOUND *csound, void *opcode) - { - return reinterpret_cast(opcode)->audio(csound); - } - /** - This is how to compute audio signals for normal opcodes: - (1) Zero all frames from 0 up to but not including Offset. - (2) Compute all frames from ksmps_offset up to but not including End. - (3) Zero all frames from End up to but not including ksmps. - Example from a C opcode: - uint32_t offset = p->h.insdshead->ksmps_offset; - uint32_t early = p->h.insdshead->ksmps_no_end; - uint32_t n, nsmps = CS_KSMPS; - if (UNLIKELY(offset)) memset(p->r, '\0', offset*sizeof(MYFLT)); - if (UNLIKELY(early)) { - nsmps -= early; - memset(&p->r[nsmps], '\0', early*sizeof(MYFLT)); - } - for (n = offset; n < nsmps; n++) { - input1 = MYFLT2LRND(p->a[n]); - p->r[n] = (MYFLT) (input1 >> input2); - } - So in C++ it should look like this (which is much easier to understand): - int frameIndex = 0; - for( ; frameIndex < kperiodOffset(); ++frameIndex) { - asignal[frameIndex] = 0; - } - for( ; frameIndex < kperiodEnd(); ++frameIndex) { - asignal[frameIndex] = compute(); - } - for( ; frameIndex < ksmps(); ++frameIndex) { - asignal[frameIndex] = 0; - } - */ - uint32_t kperiodOffset() const - { - return opds.insdshead->ksmps_offset; - } - uint32_t kperiodEnd() const - { - uint32_t end = opds.insdshead->ksmps_no_end; - if (end) { - return end; - } else { - return ksmps(); - } - } - uint32_t ksmps() const - { - return opds.insdshead->ksmps; - } - uint32_t output_arg_count() - { - return (uint32_t)opds.optext->t.outArgCount; - } - uint32_t input_arg_count() - { - return (uint32_t)opds.optext->t.inArgCount; - } - void log(CSOUND *csound, const char *format,...) - { - va_list args; - va_start(args, format); - if(csound) { - csound->MessageV(csound, 0, format, args); - } else { - vfprintf(stdout, format, args); - } - va_end(args); - } - void warn(CSOUND *csound, const char *format,...) - { - if(csound) { - if(csound->GetMessageLevel(csound) & CS_WARNMSG) { - va_list args; - va_start(args, format); - csound->MessageV(csound, CSOUNDMSG_WARNING, format, args); - va_end(args); - } - } else { - va_list args; - va_start(args, format); - vfprintf(stdout, format, args); - va_end(args); - } - } - int noteoff(CSOUND *csound) - { - return OK; - } - static int noteoff_(CSOUND *csound, void *opcode) - { - return reinterpret_cast(opcode)->noteoff(csound); - } - OPDS opds; -}; - -#if (__cplusplus >= 201103L) && !(defined(__wasi__)) -#pragma message("Defining heap_object_manager_t.") - -/** - * The memory of non-POD C++ or C objects allocated on the heap by Csound - * plugins is managed not by Csound, but by the plugin module. This class - * performs that function. - * - * As long as all memory is allocated in or after csoundModuleCreate and - * de-allocated in csoundModuleDestroy, all will be well. The danger however - * is that memory leaks will occur if allocations are not matched with - * de-allocations, or worse, that crashes will occur if any objects are - * deleted twice or de-referenced after deletion. - * - * So, the plugin should manage a collection of all heap-allocated objects, - * keyed first off the Csound instance, and second off an object handle; and - * all such objects must be accessed only by handle, from this collection. - * - * In csoundModuleDestroy, all objects for the calling instance of Csound - * should be de-allocated, and the sub-collection for that instance should - * also be de-allocated. - * - * If then there are no more sub-collections for other instances of Csound, - * the entire contents of the collection should be de-allocated. - * - * This should be done as a singleton, and in a thread-safe way. - * - * There might still be a problem if any of the heap-allocated objects, - * themselves, have global static members, perhaps created by some external - * dependency. - * - * Please note, objects O in the declaration below must not be std::shared_ptr - * objects. Deletion of objects herein must be unconditional. Rather, the - * objects passed are raw pointers to instances of class O. - */ - template class heap_object_manager_t { - private: - std::map> objects_; - std::recursive_mutex mutex; - heap_object_manager_t(){}; - ~heap_object_manager_t(){}; - public: - static heap_object_manager_t &instance() { - static heap_object_manager_t singleton; - return singleton; - } - std::map> &objects() { - std::lock_guard lock(mutex); - return objects_; - } - /** - * Returns a list of pointers to all objects allocated for this - * instance of Csound. - */ - std::vector &objects_for_csound(CSOUND *csound) { - std::lock_guard lock(mutex); - auto &objects_for_csound_ = objects()[csound]; - return objects_for_csound_; - } - /** - * Returns the handle for the object; if the object has not yet been - * stored, inserts it into the list of object pointers for this - * instance of Csound; otherwise, returns the handle of the stored - * object pointer. - */ - int handle_for_object(CSOUND *csound, O *object) { - std::lock_guard lock(mutex); - auto &objects_for_csound_ = objects_for_csound(csound); - auto iterator = std::find(objects_for_csound_.begin(), objects_for_csound_.end(), object); - if (iterator == objects_for_csound_.end()) { - int handle = objects_for_csound_.size(); - objects_for_csound_.push_back(object); - if (diagnostics_enabled) std::fprintf(stderr, "heap_object_manager_t::handle_for_object %p: new object handle: %d (of %ld)\n", object, handle, objects_for_csound_.size()); - return handle; - } else { - int handle = static_cast(iterator - objects_for_csound_.begin()); - if (diagnostics_enabled) std::fprintf(stderr, "heap_object_manager_t::handle_for_object: existing object handle: %d\n", handle); - return handle; - } - } - /** - * Returns the object pointer for the handle; - * if the object pointer has not been stored by - * handle, returns a null pointer. - */ - O *object_for_handle(CSOUND *csound, int handle) { - std::lock_guard lock(mutex); - auto &objects_for_csound_ = objects_for_csound(csound); - if (handle >= objects_for_csound_.size()) { - return nullptr; - } - O *object = objects_for_csound_[handle]; - if (diagnostics_enabled) std::fprintf(stderr, "heap_object_manager_t::object_for_handle: %p %d (of %ld)\n", object, handle, objects_for_csound_.size()); - return object; - } - /** - * First destroys all objects created by the calling - * instance of Csound, then destroys the list of - * object pointers for this instance of Csound. - */ - void module_destroy(CSOUND *csound) { - std::lock_guard lock(mutex); - auto &objects_for_csound_ = objects_for_csound(csound); - for (int i = 0, n = objects_for_csound_.size(); i < n; ++i) { - delete objects_for_csound_[i]; - objects_for_csound_[i] = nullptr; - } - objects_for_csound_.clear(); - objects().erase(csound); - } -}; - -#else -#pragma message("Not defining heap_manager_t.") -#endif - -} diff --git a/6.x/src/jackops/jacko.cpp b/6.x/src/jackops/jacko.cpp index 14021b43..fa666fa3 100644 --- a/6.x/src/jackops/jacko.cpp +++ b/6.x/src/jackops/jacko.cpp @@ -549,7 +549,7 @@ struct JackoState { status); if (!jackClient) { csound->Message(csound, - "Could not create Jack client \"%s\" -- is Jack server \"%s\" running? Status: %d\n", + "Could not create Jack client \"%s\" -- is Jack server \"%s\" running? Status: %d\n", clientName, serverName, status); csound->LongJmp(csound, 1); } else { diff --git a/6.x/src/linear_algebra/CMakeLists.txt b/6.x/src/linear_algebra/CMakeLists.txt index 355d4369..f3cfb248 100644 --- a/6.x/src/linear_algebra/CMakeLists.txt +++ b/6.x/src/linear_algebra/CMakeLists.txt @@ -4,8 +4,8 @@ find_package(GMM) check_deps(BUILD_LINEAR_ALGEBRA_OPCODES GMM_FOUND) if(BUILD_LINEAR_ALGEBRA_OPCODES AND GMM_FOUND) - make_plugin(linear_algebra linear_algebra.cpp) - target_include_directories(linear_algebra PRIVATE ${GMM_INCLUDE_DIR} ${CSOUND_INCLUDE_DIR}) + make_plugin(linear_algebra "6x" linear_algebra.cpp) + target_include_directories(linear_algebra PRIVATE ${GMM_INCLUDE_DIR}) target_compile_options(linear_algebra PRIVATE "-DGMM_VERSION") if (MSVC) diff --git a/6.x/src/mp3/CMakeLists.txt b/6.x/src/mp3/CMakeLists.txt index 64f5b074..563c70e2 100644 --- a/6.x/src/mp3/CMakeLists.txt +++ b/6.x/src/mp3/CMakeLists.txt @@ -2,17 +2,22 @@ option(BUILD_MP3OUT_OPCODE "Build the mp3out opcode" ON) if(USE_VCPKG) find_package(mp3lame CONFIG REQUIRED) + + if(NOT TARGET mp3lame::mp3lame) + message(STATUS "Could not find mp3lame") + set(BUILD_MP3OUT_OPCODE OFF) + endif() else() find_package(LAME) + check_deps(BUILD_MP3OUT_OPCODE mp3lame_FOUND) endif() if(BUILD_MP3OUT_OPCODE) - if(LAME_FOUND) - make_plugin(mp3out mp3out.c ${LAME_LIBRARY}) - target_include_directories(mp3out PRIVATE ${LAME_INCLUDE_DIR} ${CSOUND_INCLUDE_DIR}) - elseif(mp3lame_FOUND AND USE_VCPKG) - make_plugin(mp3out mp3out.c mp3lame::mp3lame) - target_include_directories(mp3out PRIVATE ${CSOUND_INCLUDE_DIR}) + if(USE_VCPKG) + make_plugin(mp3out "6x" mp3out.c mp3lame::mp3lame) + else() + make_plugin(mp3out "6x" mp3out.c ${LAME_LIBRARY}) + target_include_directories(mp3out PRIVATE ${LAME_INCLUDE_DIR}) endif() message(STATUS "Building MP3 opcodes") diff --git a/6.x/src/mp3/mp3out.c b/6.x/src/mp3/mp3out.c index f11e4f67..08c0a1c4 100644 --- a/6.x/src/mp3/mp3out.c +++ b/6.x/src/mp3/mp3out.c @@ -98,7 +98,7 @@ int mp3out_init(CSOUND *csound, MP3OUT* p) &p->auxch); p->mp3buffer = p->auxch.auxp; - p->leftpcm = (char*)p->auxch.auxp + p->mp3buffer_size; + p->leftpcm = (double*)p->auxch.auxp + p->mp3buffer_size; p->rightpcm = p->leftpcm + nsmps; csound->RegisterDeinitCallback(csound, p, diff --git a/6.x/src/opencl/CMakeLists.txt b/6.x/src/opencl/CMakeLists.txt index 16c73b54..e4b0c1b7 100644 --- a/6.x/src/opencl/CMakeLists.txt +++ b/6.x/src/opencl/CMakeLists.txt @@ -4,7 +4,6 @@ find_library (OpenCL_library NAMES OpenCL) check_deps(BUILD_OPENCL_OPCODES OpenCL_FOUND) if(BUILD_OPENCL_OPCODES AND OpenCL_FOUND) - function(make_opencl_plugin libname srcs) if(APPLE) add_library(${libname} SHARED ${srcs}) @@ -18,12 +17,13 @@ if(BUILD_OPENCL_OPCODES AND OpenCL_FOUND) math(EXPR i "${i}+1") endwhile() - target_include_directories(${libname} PRIVATE ${CSOUND_INCLUDE_DIRS}) + target_include_directories(${libname} PRIVATE "${CMAKE_SOURCE_DIR}/csound") install(TARGETS ${libname} - LIBRARY DESTINATION "${PLUGIN_INSTALL_DIR}" ) + LIBRARY DESTINATION "${PLUGIN_INSTALL_DIR}" + ) endfunction() make_opencl_plugin(clop cladsynth.c) - target_link_libraries(clop ${OpenCL_library}) + target_link_libraries(clop PRIVATE ${OpenCL_library}) endif() diff --git a/6.x/src/p5glove/CMakeLists.txt b/6.x/src/p5glove/CMakeLists.txt index 8e6dcc49..15888d1b 100644 --- a/6.x/src/p5glove/CMakeLists.txt +++ b/6.x/src/p5glove/CMakeLists.txt @@ -6,14 +6,14 @@ if (NOT APPLE) check_deps(BUILD_P5GLOVE_OPCODES P5GLOVE_LIB) if(BUILD_P5GLOVE_OPCODES) - make_plugin(p5g p5glove.c ${P5GLOVE_LIB}) + make_plugin(p5g "6x" p5glove.c ${P5GLOVE_LIB}) target_include_directories(p5g PRIVATE ${P5GLOVE_INCLUDE_DIR}) target_include_directories(p5g PRIVATE ${CSOUND_INCLUDE_DIR}) endif() else() if(BUILD_P5GLOVE_OPCODES) - make_plugin(p5g "p5glove.c;libp5glove/p5glove.c;libp5glove/usb_hid_macosx.c") - target_link_libraries(p5g "-framework IOKit" "-framework CoreFoundation") + make_plugin(p5g "6x" "p5glove.c;libp5glove/p5glove.c;libp5glove/usb_hid_macosx.c") + target_link_libraries(p5g PRIVATE "-framework IOKit" "-framework CoreFoundation") target_include_directories(p5g PRIVATE ./libp5glove ${CSOUND_INCLUDE_DIR}) endif() endif() diff --git a/6.x/src/p5glove/libp5glove/p5glove.c b/6.x/src/p5glove/libp5glove/p5glove.c index 5abc3111..46fbbcce 100644 --- a/6.x/src/p5glove/libp5glove/p5glove.c +++ b/6.x/src/p5glove/libp5glove/p5glove.c @@ -11,19 +11,19 @@ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or + * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -74,7 +74,7 @@ struct p5glove { int v1,v2,h; } ir[8]; /* IR Sensors values. (-511 - 511) */ - /* Computed from p5g_process_sample + /* Computed from p5g_process_sample */ double position[3]; /* Position */ @@ -121,7 +121,7 @@ static int32_t get_bits_signed(uint8_t *data,int pos,int len) static void p5g_unpack_sample(struct p5glove *p5, uint8_t data[24]) { - unsigned char tmp[24]; + // unsigned char tmp[24]; int visible=1; int i; @@ -141,21 +141,21 @@ static void p5g_unpack_sample(struct p5glove *p5, uint8_t data[24]) */ if (data[0] != 1) { -printf("Odd. Sample [0]=%d\n",data[0]); + printf("Odd. Sample [0]=%d\n",data[0]); return; } for (i=0; i < 5; i++) { - int value; - - switch (i) { - case 0: value = data[1] >> 2; break; - case 1: value = ((data[1] & 0x3) << 4) | (data[2] >> 4); break; - case 2: value = ((data[2] & 0xF) << 2) | (data[3] >> 6); break; - case 3: value = (data[3] & 0x3F); break; - case 4: value = data[4] >> 2; break; - default: value = 0; break; - } + // int value; + + // switch (i) { + // case 0: value = data[1] >> 2; break; + // case 1: value = ((data[1] & 0x3) << 4) | (data[2] >> 4); break; + // case 2: value = ((data[2] & 0xF) << 2) | (data[3] >> 6); break; + // case 3: value = (data[3] & 0x3F); break; + // case 4: value = data[4] >> 2; break; + // default: value = 0; break; + // } p5->data.finger[i]=get_bits(data,8+6*i,6); } @@ -168,7 +168,7 @@ printf("Odd. Sample [0]=%d\n",data[0]); for (i=0; i < 4; i++) { int axis; - int value; + // int value; axis = get_bits(data,44+4*i,4); if (axis & 0x8) @@ -212,7 +212,7 @@ static int p5glove_check_triangle(P5Glove p5,int led1,int led2,int led3) double c; int led[3]; int i; - + led[0]=led1; led[1]=led2; led[2]=led3; @@ -220,7 +220,7 @@ static int p5glove_check_triangle(P5Glove p5,int led1,int led2,int led3) for (i=0; i < 3; i++) { c=p5glove_angle(p5->cal.led[led[i]], p5->cal.led[led[(i+1)%3]], - p5->cal.led[led[(i+2)%3]])*180.0/M_PI; + p5->cal.led[led[(i+2)%3]])*180.0/M_PI; /* At too acute/obtune an angle? */ DPRINTF("Angle %d-%d-%d is %.4lf\n",led[i],led[(i+1)%3],led[(i+2)%3],c); @@ -249,7 +249,7 @@ static int p5g_best_leds(P5Glove p5,int led[4],double pos[4][3]) if (p5->data.ir[i].visible) led[p5->data.ir[i].visible-1]=i; - /* Hmm. No 'best' led. + /* Hmm. No 'best' led. */ if (led[0] < 0) return -ENOENT; @@ -266,7 +266,7 @@ static int p5g_best_leds(P5Glove p5,int led[4],double pos[4][3]) /* If we have more than 2, we need to verify the data */ if (led[3] < 0) - leds=3; + leds=3; else { p5g_process_led(p5,led[3],pos[3]); leds=4; @@ -282,8 +282,8 @@ static int p5g_best_leds(P5Glove p5,int led[4],double pos[4][3]) double dist = p5glove_dist(pos[i],pos[j]); double err = fabs(dist-ref_dist)/ref_dist; - DPRINTF("%d - %d: %.4lf ",led[i],led[j],ref_dist); - DPRINTF("(%.4lf) [%.4lf]\n",led[i],led[j],dist,err); + DPRINTF("%d - %d: %.4lf ", led[i], led[j], ref_dist); + DPRINTF("(%d - %d) dist[%.4lf] err[%.4lf]\n", led[i], led[j], dist, err); /* Max 9% error margin on distance */ if (err > 0.20) { @@ -390,7 +390,7 @@ static int p5g_delta(P5Glove p5,int have_pos, int have_rot) have_rot=0; memcpy(&p5->prev,&p5->data,sizeof(p5->data)); - return mask | + return mask | (have_pos ? P5GLOVE_DELTA_POSITION : 0) | (have_rot ? P5GLOVE_DELTA_ROTATION : 0); } @@ -398,7 +398,7 @@ static int p5g_delta(P5Glove p5,int have_pos, int have_rot) static int p5g_process_sample(P5Glove p5) { - int i,j,leds; + int i, leds; int led[4] = {-1,-1,-1,-1}; double pos[4][3]; double pos_plane[3],ref_plane[3]; @@ -479,7 +479,7 @@ DPRINTF("Rotation axis : [%.4lf, %.4lf, %.4lf]\n",p5->data.rotation.axis[0],p5 /* Now, apply the rotation angle to the position */ p5glove_vec_mat(p5->cal.led[led[0]],rot_matrix,pos[1]); - /* Then simply subtract the difference from the + /* Then simply subtract the difference from the * reference position to get the *real* point */ for (i=0; i<3; i++) p5->data.position[i] = pos[0][i] - pos[1][i]; @@ -547,19 +547,19 @@ static int p5glove_calibrate(struct p5glove *p5) int8_t report12_buff[255]; int err; - memset(&p5->cal,0,sizeof(p5->cal)); - report12_buff[0]=12; - err=GetUSBHIDFeature(p5->usb,report12_buff,sizeof(report12_buff)); + memset(&p5->cal, 0, sizeof(p5->cal)); + report12_buff[0] = 12; + err = GetUSBHIDFeature(p5->usb, (char*)report12_buff, sizeof(report12_buff)); if (err < 0) goto end; - err=p5g_parse_report12(p5,report12_buff); + err = p5g_parse_report12(p5, report12_buff); if (err < 0) goto end; - report6_buff[0]=6; - err=GetUSBHIDFeature(p5->usb,report6_buff,sizeof(report6_buff)); + report6_buff[0] = 6; + err = GetUSBHIDFeature(p5->usb, (char*)report6_buff, sizeof(report6_buff)); if (err < 0) goto end; - err=p5g_parse_report6(p5,report6_buff); + err = p5g_parse_report6(p5, report6_buff); #ifdef DEBUG_CALIB DPRINTF("Cal results:\n"); @@ -580,7 +580,7 @@ P5Glove p5glove_open(int glove_number) struct p5glove *p5 = NULL; USBHID usb; int err; - + usb = OpenUSBHID ( glove_number, /* nth matching device */ 0x0d7f, /* vendor id */ @@ -619,7 +619,7 @@ int p5glove_sample(P5Glove p5,int timeout) { int err; uint8_t data[24]; - + if ( ReadUSBHID( p5->usb, data, 24 ) == 24 && data[0]==1) { p5g_unpack_sample(p5, data); err=p5g_process_sample(p5); @@ -627,7 +627,7 @@ int p5glove_sample(P5Glove p5,int timeout) errno = EACCES; err = -1; } - + return err; } diff --git a/6.x/src/py/CMakeLists.txt b/6.x/src/py/CMakeLists.txt index ab90376b..303b7747 100644 --- a/6.x/src/py/CMakeLists.txt +++ b/6.x/src/py/CMakeLists.txt @@ -11,8 +11,7 @@ if(BUILD_PYTHON_OPCODES) message("-- Python include dirs: ${Python3_INCLUDE_DIRS}") message("-- Python libraries: ${PYTHON_LIBRARIES}") - make_plugin(py src/pythonopcodes.c) - target_include_directories(py PRIVATE ${CSOUND_INCLUDE_DIRS}) + make_plugin(py "6x" src/pythonopcodes.c) target_include_directories(py PRIVATE ${PYTHON_INCLUDE_DIRS}) - target_link_libraries(py ${PYTHON_LIBRARIES}) + target_link_libraries(py PRIVATE ${PYTHON_LIBRARIES}) endif() diff --git a/6.x/src/py/src/pyx.auto.c b/6.x/src/py/src/pyx.auto.c index 7080bca3..a8b62ab4 100644 --- a/6.x/src/py/src/pyx.auto.c +++ b/6.x/src/py/src/pyx.auto.c @@ -64,25 +64,25 @@ static int pyexec_krate(CSOUND *csound, PYEXEC *p) return OK; } -static int pyexeci_irate(CSOUND *csound, PYEXEC *p) -{ - char source[1024]; - PyObject *result; - int *py_initialize_done; - if ((py_initialize_done = csound->QueryGlobalVariable(csound,"PY_INITIALIZE")) == NULL || - *py_initialize_done == 0) { - return NOTOK; - } - - strNcpy(source, (char*) p->string->data, 1024); // source[1023] = '\0' - - result = exec_file_in_given_context(csound, source, 0); - if (result == NULL) { - return pyErrMsg(p, "python exception"); - } - Py_DECREF(result); - return OK; -} +// static int pyexeci_irate(CSOUND *csound, PYEXEC *p) +// { +// char source[1024]; +// PyObject *result; +// int *py_initialize_done; +// if ((py_initialize_done = csound->QueryGlobalVariable(csound,"PY_INITIALIZE")) == NULL || +// *py_initialize_done == 0) { +// return NOTOK; +// } + +// strNcpy(source, (char*) p->string->data, 1024); // source[1023] = '\0' + +// result = exec_file_in_given_context(csound, source, 0); +// if (result == NULL) { +// return pyErrMsg(p, "python exception"); +// } +// Py_DECREF(result); +// return OK; +// } static int pylexec_irate(CSOUND *csound, PYEXEC *p) { @@ -370,31 +370,31 @@ static int pyeval_krate(CSOUND *csound, PYEVAL *p) return OK; } -static int pyevali_irate(CSOUND *csound, PYEVAL *p) -{ - char source[1024]; - PyObject *result; - int *py_initialize_done; - if ((py_initialize_done = csound->QueryGlobalVariable(csound,"PY_INITIALIZE")) == NULL || - *py_initialize_done == 0) { - return NOTOK; - } - - strNcpy(source, (char*) p->string->data, 1024); // source[1023] = '\0' - - result = eval_string_in_given_context(source, 0); - if (result == NULL) { - return pyErrMsg(p, "python exception"); - } - else if (!PyFloat_Check(result)) { - errMsg(p, "expression must evaluate in a float"); - } - else { - *p->result = PyFloat_AsDouble(result); - } - Py_DECREF(result); - return OK; -} +// static int pyevali_irate(CSOUND *csound, PYEVAL *p) +// { +// char source[1024]; +// PyObject *result; +// int *py_initialize_done; +// if ((py_initialize_done = csound->QueryGlobalVariable(csound,"PY_INITIALIZE")) == NULL || +// *py_initialize_done == 0) { +// return NOTOK; +// } + +// strNcpy(source, (char*) p->string->data, 1024); // source[1023] = '\0' + +// result = eval_string_in_given_context(source, 0); +// if (result == NULL) { +// return pyErrMsg(p, "python exception"); +// } +// else if (!PyFloat_Check(result)) { +// errMsg(p, "expression must evaluate in a float"); +// } +// else { +// *p->result = PyFloat_AsDouble(result); +// } +// Py_DECREF(result); +// return OK; +// } static int pyleval_irate(CSOUND *csound, PYEVAL *p) { @@ -553,24 +553,24 @@ static int pyassign_krate(CSOUND *csound, PYASSIGN *p) return OK; } -static int pyassigni_irate(CSOUND *csound, PYASSIGN *p) -{ - char source[1024]; - PyObject *result; - int *py_initialize_done; - if ((py_initialize_done = csound->QueryGlobalVariable(csound,"PY_INITIALIZE")) == NULL || - *py_initialize_done == 0) { - return NOTOK; - } - - snprintf(source, 1024, "%s = %f", (char*) p->string->data, *p->value); - result = run_statement_in_given_context(source, 0); - if (result == NULL) { - return pyErrMsg(p, "python exception"); - } - Py_DECREF(result); - return OK; -} +// static int pyassigni_irate(CSOUND *csound, PYASSIGN *p) +// { +// char source[1024]; +// PyObject *result; +// int *py_initialize_done; +// if ((py_initialize_done = csound->QueryGlobalVariable(csound,"PY_INITIALIZE")) == NULL || +// *py_initialize_done == 0) { +// return NOTOK; +// } + +// snprintf(source, 1024, "%s = %f", (char*) p->string->data, *p->value); +// result = run_statement_in_given_context(source, 0); +// if (result == NULL) { +// return pyErrMsg(p, "python exception"); +// } +// Py_DECREF(result); +// return OK; +// } static int pylassign_irate(CSOUND *csound, PYASSIGN *p) { diff --git a/6.x/src/stk/CMakeLists.txt b/6.x/src/stk/CMakeLists.txt index 24d006db..8c8541bb 100644 --- a/6.x/src/stk/CMakeLists.txt +++ b/6.x/src/stk/CMakeLists.txt @@ -6,11 +6,11 @@ if(BUILD_STK_OPCODES) endif() if(USE_VCPKG) - make_plugin(stkops stkOpcodes.cpp) + make_plugin(stkops "6x" stkOpcodes.cpp) find_package(unofficial-libstk CONFIG REQUIRED) target_link_libraries(stkops PRIVATE unofficial::libstk::libstk) - target_include_directories(stkops PRIVATE ${CSOUND_INCLUDE_DIRS}) - message(STATUS "Building STK opcodes for MSVC") + + message(STATUS "Building STK opcodes with VCPKG") else() find_package(STK) @@ -22,8 +22,8 @@ if(BUILD_STK_OPCODES) check_deps(BUILD_STK_OPCODES STK_INCLUDE_DIR) if(STK_INCLUDE_DIR) - make_plugin(stkops stkOpcodes.cpp) - target_include_directories(stkops PRIVATE ${CSOUND_INCLUDE_DIRS} ${STK_INCLUDE_DIR}) + make_plugin(stkops "6x" stkOpcodes.cpp) + target_include_directories(stkops PRIVATE ${STK_INCLUDE_DIR}) message(STATUS "Building STK opcodes.") if(BUILD_STATIC_LIBRARY) @@ -64,12 +64,11 @@ if(BUILD_STK_OPCODES) find_path(STK_INCLUDE_DIR Stk.h ./include) check_deps(BUILD_STK_OPCODES STK_FOUND STK_INCLUDE_DIR) - make_plugin(stkops "${stk_srcs}") + make_plugin(stkops "6x" "${stk_srcs}") target_include_directories(stkops PRIVATE - ${CSOUND_INCLUDE_DIRS} - ${CMAKE_CURRENT_SOURCE_DIR}/include - ${CMAKE_CURRENT_SOURCE_DIR}/include/stk - ${CMAKE_CURRENT_SOURCE_DIR}/src + "${CMAKE_CURRENT_SOURCE_DIR}/include" + "${CMAKE_CURRENT_SOURCE_DIR}/include/stk" + "${CMAKE_CURRENT_SOURCE_DIR}/src" ) set(stkdefs "-D__STK_REALTIME__") diff --git a/6.x/src/stk/stkOpcodes.cpp b/6.x/src/stk/stkOpcodes.cpp index f244969b..480c1e48 100644 --- a/6.x/src/stk/stkOpcodes.cpp +++ b/6.x/src/stk/stkOpcodes.cpp @@ -48,71 +48,40 @@ * See the STK class documentation to determine the controller numbers * used by each instrument. */ -#if defined(_MSC_VER) -#include "stk\BandedWG.h" -#include "stk\BeeThree.h" -#include "stk\BlowBotl.h" -#include "stk\BlowHole.h" -#include "stk\Bowed.h" -#include "stk\Brass.h" -#include "stk\Clarinet.h" -#include "stk\Drummer.h" -#include "stk\FMVoices.h" -#include "stk\Flute.h" -#include "stk\HevyMetl.h" -#include "stk\Mandolin.h" -#include "stk\Stk.h" - //#include "stk\Mesh2D.h" -#include "stk\ModalBar.h" -#include "stk\Moog.h" -#include "stk\PercFlut.h" -#include "stk\Plucked.h" -#include "stk\Resonate.h" -#include "stk\Rhodey.h" -#include "stk\Saxofony.h" -#include "stk\Shakers.h" -#include "stk\Simple.h" -#include "stk\Sitar.h" -#include "stk\StifKarp.h" -#include "stk\TubeBell.h" -#include "stk\VoicForm.h" -#include "stk\Whistle.h" -#include "stk\Wurley.h" -#else -#include "BandedWG.h" -#include "BeeThree.h" -#include "BlowBotl.h" -#include "BlowHole.h" -#include "Bowed.h" -#include "Brass.h" -#include "Clarinet.h" -#include "Drummer.h" -#include "FMVoices.h" -#include "Flute.h" -#include "HevyMetl.h" -#include "Mandolin.h" -#include "Stk.h" -//#include "Mesh2D.h" -#include "ModalBar.h" -#include "Moog.h" -#include "PercFlut.h" -#include "Plucked.h" -#include "Resonate.h" -#include "Rhodey.h" -#include "Saxofony.h" -#include "Shakers.h" -#include "Simple.h" -#include "Sitar.h" -#include "StifKarp.h" -#include "TubeBell.h" -#include "VoicForm.h" -#include "Whistle.h" -#include "Wurley.h" -#endif + +#include "stk/BandedWG.h" +#include "stk/BeeThree.h" +#include "stk/BlowBotl.h" +#include "stk/BlowHole.h" +#include "stk/Bowed.h" +#include "stk/Brass.h" +#include "stk/Clarinet.h" +#include "stk/Drummer.h" +#include "stk/FMVoices.h" +#include "stk/Flute.h" +#include "stk/HevyMetl.h" +#include "stk/Mandolin.h" +#include "stk/Stk.h" +#include "stk/ModalBar.h" +#include "stk/Moog.h" +#include "stk/PercFlut.h" +#include "stk/Plucked.h" +#include "stk/Resonate.h" +#include "stk/Rhodey.h" +#include "stk/Saxofony.h" +#include "stk/Shakers.h" +#include "stk/Simple.h" +#include "stk/Sitar.h" +#include "stk/StifKarp.h" +#include "stk/TubeBell.h" +#include "stk/VoicForm.h" +#include "stk/Whistle.h" +#include "stk/Wurley.h" + using namespace stk; #define __BUILDING_LIBCSOUND -#include +#include "OpcodeBase.hpp" #include using namespace csound; diff --git a/6.x/src/websockets/CMakeLists.txt b/6.x/src/websockets/CMakeLists.txt index 2438a8c3..ad67d138 100644 --- a/6.x/src/websockets/CMakeLists.txt +++ b/6.x/src/websockets/CMakeLists.txt @@ -1,26 +1,30 @@ option(BUILD_WEBSOCKET_OPCODE "Build the websocket opcode" ON) if(USE_VCPKG) - find_package(libuv CONFIG) - find_package(libwebsockets CONFIG) + find_package(libuv CONFIG REQUIRED) + find_package(libwebsockets CONFIG REQUIRED) + + check_deps(BUILD_WEBSOCKET_OPCODE libuv libwebsockets) +elseif(APPLE) + find_library(ssl_library NAMES ssl) + find_library(crypto_library NAMES crypto) + + check_deps(BUILD_WEBSOCKET_OPCODE ssl_library crypto_library) else() find_path(WEBSOCKETS_H libwebsockets.h /usr/local/include /usr/include) find_library(websockets_library NAMES websockets) -endif() - -if(APPLE) - find_library(ssl_library NAMES ssl) - find_library(crypto_library NAMES crypto) - check_deps(BUILD_WEBSOCKET_OPCODE websockets_library ssl_library crypto_library WEBSOCKETS_H) + check_deps(BUILD_WEBSOCKET_OPCODE WEBSOCKETS_H websockets_library) endif() if(BUILD_WEBSOCKET_OPCODE) - make_plugin(websocketIO WebSocketOpcode.c) - target_include_directories(websocketIO PRIVATE ${CSOUND_INCLUDE_DIRS}) + make_plugin(websocketIO "6x" WebSocketOpcode.c) if(USE_VCPKG) - target_link_libraries(websocketIO websockets uv_a) + target_link_libraries(websocketIO + websockets + $,libuv::uv_a,libuv::uv> + ) else() target_link_libraries(websocketIO ${websockets_library}) target_include_directories(websocketIO PRIVATE ${WEBSOCKETS_H}) diff --git a/6.x/src/widgets/CMakeLists.txt b/6.x/src/widgets/CMakeLists.txt index 7d441cfb..686f4c90 100644 --- a/6.x/src/widgets/CMakeLists.txt +++ b/6.x/src/widgets/CMakeLists.txt @@ -13,8 +13,8 @@ check_deps(USE_FLTK FLTK_FOUND) if(USE_FLTK) set(widgets_SRCS FL_graph.cpp winFLTK.c widgets.cpp) - make_plugin(widgets "${widgets_SRCS}" "${FLTK_LIBRARIES}") - target_include_directories(widgets PRIVATE ${CSOUND_INCLUDE_DIRS} ${FLTK_INCLUDE_DIR}) + make_plugin(widgets "6x" "${widgets_SRCS}" "${FLTK_LIBRARIES}") + target_include_directories(widgets PRIVATE ${FLTK_INCLUDE_DIR}) if(USE_VCPKG) target_link_libraries(widgets PRIVATE fltk fltk_gl fltk_forms fltk_images) @@ -37,8 +37,8 @@ if(USE_FLTK) virtual_keyboard/SliderBank.cpp virtual_keyboard/SliderData.cpp) - make_plugin(virtual "${virtual_SRCS}" "${FLTK_LIBRARIES}") - target_include_directories(virtual PRIVATE ${CSOUND_INCLUDE_DIRS} ${FLTK_INCLUDE_DIR} ".") + make_plugin(virtual "6x" "${virtual_SRCS}" "${FLTK_LIBRARIES}") + target_include_directories(virtual PRIVATE ${FLTK_INCLUDE_DIR} ".") if (USE_VCPKG) target_link_libraries(virtual PRIVATE fltk fltk_gl fltk_forms fltk_images) diff --git a/6.x/src/widgets/FL_graph.cpp b/6.x/src/widgets/FL_graph.cpp index a2674ec3..15e4f04a 100644 --- a/6.x/src/widgets/FL_graph.cpp +++ b/6.x/src/widgets/FL_graph.cpp @@ -205,9 +205,9 @@ void graph_box::draw() fl_line(win_x+w()/2, win_y, win_x+w()/2, win_y+win_h); } if (pol != NEGPOL) - sprintf(string, "%s %" PRIi32 " points, max %5.3f", msg, npts, win->oabsmax); + snprintf(string, 400, "%s %" PRIi32 " points, max %5.3f", msg, npts, win->oabsmax); else - sprintf(string, "%s %" PRIi32 " points, max %5.3f", msg, npts, win->max); + snprintf(string, 400, "%s %" PRIi32 " points, max %5.3f", msg, npts, win->max); ST(form)->label(string); } diff --git a/6.x/src/widgets/virtual_keyboard/KeyboardMapping.cpp b/6.x/src/widgets/virtual_keyboard/KeyboardMapping.cpp index a188da72..553a080b 100644 --- a/6.x/src/widgets/virtual_keyboard/KeyboardMapping.cpp +++ b/6.x/src/widgets/virtual_keyboard/KeyboardMapping.cpp @@ -173,16 +173,13 @@ void KeyboardMapping::initializeMap(CSOUND * csound, FILE *file) { void KeyboardMapping::initializeDefaults(CSOUND *csound) { for(int i = 0; i < 128; i++) { - char * name = (char *)csound->Calloc(csound, 9); - - sprintf(name, "Bank %d", i + 1); + snprintf(name, 9, "Bank %d", i + 1); Bank *temp = new Bank(csound, name); temp->initializeGM(); banks.push_back(temp); - } } diff --git a/6.x/src/widgets/widgets.cpp b/6.x/src/widgets/widgets.cpp index 4e5b001c..2c19f501 100644 --- a/6.x/src/widgets/widgets.cpp +++ b/6.x/src/widgets/widgets.cpp @@ -2228,7 +2228,7 @@ static inline void displ(MYFLT val, MYFLT index, CSOUND *csound) (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS"); if (index >= 0) { // display current value of valuator char valString[MAXNAME]; - sprintf(valString, "%.5g", val); + snprintf(valString, MAXNAME, "%.5g", val); ((Fl_Output*) (widgetGlobals->AddrSetValue[(long) index]).WidgAddress)-> value(valString); } @@ -2259,8 +2259,7 @@ static void fl_callbackExecButton(Fl_Button* w, void *a) #if defined(LINUX) || defined (MACOSX) - - pid_t pId = vfork(); + pid_t pId = fork(); if (pId == 0) { char *th; char *v[40]; @@ -3664,7 +3663,7 @@ extern "C" { string stemp; if (tempname == " ") { char s[40]; - sprintf(s, "%d", j); + snprintf(s, 40, "%d", j); stemp = s; } else @@ -4257,7 +4256,7 @@ extern "C" { Fl_Button *w; char *btName = new char[30]; widgetGlobals->allocatedStrings.push_back(btName); - sprintf(btName, "%d", z); + snprintf(btName, 30, "%d", z); switch (type) { case 1: w = new Fl_Button(x, y, 10, 10, btName); @@ -4475,7 +4474,7 @@ extern "C" { if (p->cysofar < cycles) { p->cysofar = cycles; char valString[MAXNAME]; - sprintf(valString,"%.5g", *p->val); + snprintf(valString, MAXNAME, "%.5g", *p->val); ((Fl_Output*) (widgetGlobals->AddrSetValue[(long) *p->idisp]).WidgAddress)-> value(valString ); } @@ -4496,7 +4495,7 @@ extern "C" { (WIDGET_GLOBALS *)csound->QueryGlobalVariable(csound, "WIDGET_GLOBALS"); if (p->oldvalue != value) { char valString[MAXNAME]; - sprintf(valString,"%.5g", *p->val); + snprintf(valString, MAXNAME, "%.5g", *p->val); ((Fl_Output*) (widgetGlobals->AddrSetValue[(long) *p->idisp]).WidgAddress)-> value(valString ); p->oldvalue = value; @@ -4806,7 +4805,7 @@ extern "C" { string stemp; if (tempname == " ") { char s[40]; - sprintf(s, "%d", j); + snprintf(s, 40, "%d", j); stemp = s; } else @@ -5020,7 +5019,7 @@ extern "C" { string stemp; if (tempname == " ") { char s[40]; - sprintf(s, "%d", j); + snprintf(s, 40, "%d", j); stemp = s; } else @@ -5213,7 +5212,7 @@ extern "C" { string stemp; if (tempname == " ") { char s[40]; - sprintf(s, "%d", j); + snprintf(s, 40, "%d", j); stemp = s; } else diff --git a/6.x/src/widgets/winFLTK.c b/6.x/src/widgets/winFLTK.c index 237037d5..f5e1295f 100644 --- a/6.x/src/widgets/winFLTK.c +++ b/6.x/src/widgets/winFLTK.c @@ -69,8 +69,9 @@ PUBLIC int csoundModuleInit(CSOUND *csound) int initFlags = 0; int *fltkFlags; int enableDisplays = 0; - OPARMS oparms; - csound->GetOParms(csound, &oparms); + OPARMS oparms; + + csound->GetOParms(csound, &oparms); if (csound->QueryGlobalVariable(csound, "FLTK_Flags") == (void*) 0) { @@ -89,7 +90,7 @@ PUBLIC int csoundModuleInit(CSOUND *csound) XCloseDisplay(dpy); #endif if (csound->SetIsGraphable(csound, 1) == 0) { - enableDisplays = 1; + enableDisplays = 1; (*fltkFlags) |= 64; if (!((*fltkFlags) & 256)) diff --git a/6.x/src/wiimote/CMakeLists.txt b/6.x/src/wiimote/CMakeLists.txt index cb4997c0..e4bad819 100644 --- a/6.x/src/wiimote/CMakeLists.txt +++ b/6.x/src/wiimote/CMakeLists.txt @@ -5,6 +5,6 @@ find_library(WIIUSE_LIB wiiuse) check_deps(BUILD_WIIMOTE_OPCODES WIIUSE_LIB) if(BUILD_WIIMOTE_OPCODES) - make_plugin(wiimote wiimote.c ${WIIUSE_LIB}) + make_plugin(wiimote "6x" wiimote.c ${WIIUSE_LIB}) target_include_directories(wiimote PRIVATE ${WIIUSE_INCLUDE_DIR} ${CSOUND_INCLUDE_DIR}) endif() diff --git a/6.x/vcpkg b/6.x/vcpkg deleted file mode 160000 index f6a5d4e8..00000000 --- a/6.x/vcpkg +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f6a5d4e8eb7476b8d7fc12a56dff300c1c986131 diff --git a/6.x/x64-windows-csound.cmake b/6.x/x64-windows-csound.cmake deleted file mode 100644 index dc862f9a..00000000 --- a/6.x/x64-windows-csound.cmake +++ /dev/null @@ -1,8 +0,0 @@ -set(VCPKG_TARGET_ARCHITECTURE x64) -set(VCPKG_CRT_LINKAGE dynamic) - -if(${PORT} MATCHES "fluidsynth|glib|zlib|pcre|libffi|gettext|libiconv|portmidi|portaudio|liblo") - set(VCPKG_LIBRARY_LINKAGE dynamic) -else() - set(VCPKG_LIBRARY_LINKAGE static) -endif() diff --git a/7.x/CMakeLists.txt b/7.x/CMakeLists.txt new file mode 100644 index 00000000..d42aed3b --- /dev/null +++ b/7.x/CMakeLists.txt @@ -0,0 +1,202 @@ +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_MACOSX_RPATH 1) +set(CMAKE_VERBOSE_MAKEFILE ON) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") + +set(APIVERSION "7.0") + +include(TestBigEndian) +include(CheckFunctionExists) +include(CheckCCompilerFlag) +include(CheckCXXCompilerFlag) + +message(STATUS "Building Csound 7 plugins") + +### COMPILER OPTIMIZATION FLAGS +option(USE_COMPILER_OPTIMIZATIONS "Use the default Csound compiler optimization flags" ON) +if(USE_COMPILER_OPTIMIZATIONS) + include("${CMAKE_SOURCE_DIR}/cmake/CompilerOptimizations.cmake") +endif() + +##/Library/Frameworks/CsoundLib64.framework/Versions/Current/Resources/Opcodes64 + +if(APPLE) + message(STATUS "Building on OSX") + set(OSX_VERSION " ") +endif() + +## USER OPTIONS ## +# Optional targets, they should all default to ON (check_deps will disable them if not possible to build) +option(USE_DOUBLE "Set to use double-precision floating point for audio samples." ON) +option(USE_LRINT "Use lrint/lrintf for converting floating point values to integers." ON) +option(BUILD_RELEASE "Build for release" ON) +option(USE_GIT_COMMIT "Show the git commit in version information" ON) +option(REQUIRE_PTHREADS "For non-Windows systems, set whether Csound will use threads or not" ON) + +# in Release configuration, set NDEBUG +if(${CMAKE_BUILD_TYPE} MATCHES "Release") + message("-----> Release mode") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNDEBUG") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DNDEBUG") +elseif(${CMAKE_BUILD_TYPE} MATCHES "Debug") + message("-----> Debug mode") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBETA") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DBETA") +endif() + +# set -Werror if in Debug configuration +if(NOT MSVC AND NOT WASM) + set(CMAKE_CXX_FLAGS_RELEASE "-O3 ") + set(CMAKE_C_FLAGS_RELEASE "-O3 ") + if(${CMAKE_BUILD_TYPE} MATCHES "Debug") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -Wno-missing-field-initializers") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -Wno-missing-field-initializers") + endif() +endif() + +if(NOT MSVC AND REQUIRE_PTHREADS) + # Use ladder of if's to support older CMake versions (i.e., travis) + find_library(PTHREAD_LIBRARY winpthread-1) + + if(NOT PTHREAD_LIBRARY) + find_library(PTHREAD_LIBRARY pthread) + endif() + + if(NOT PTHREAD_LIBRARY) + find_library(PTHREAD_LIBRARY pthreadGC2) + endif() + + if(NOT (PTHREAD_LIBRARY OR HAIKU)) + # pthreads are built in to Haiku + message(STATUS "Csound requires the pthread library") + endif() + + #FIXME this variable is for required include directories, possible bug + list(APPEND CMAKE_REQUIRED_INCLUDES pthread.h) + if (NOT HAIKU) + set(CMAKE_REQUIRED_LIBRARIES pthread) + endif() +endif() + +if(CMAKE_SYSTEM_NAME MATCHES "Linux") + set(LINUX YES) +else() + set(LINUX NO) +endif() + +set(BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}) +check_c_compiler_flag(-fvisibility=hidden HAS_VISIBILITY_HIDDEN) +check_cxx_compiler_flag(-fvisibility=hidden HAS_CXX_VISIBILITY_HIDDEN) + +if (HAS_VISIBILITY_HIDDEN) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden") +endif() + +if (HAS_CXX_VISIBILITY_HIDDEN) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden") +endif() + +check_c_compiler_flag(-std=gnu99 HAS_GNU99) +if (HAS_GNU99) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99") +endif() + +if (HAS_CXX_VISIBILITY_HIDDEN) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden") +endif() + +if(LINUX) + option(USE_LIB64 "Set to on to set installation directory for libraries to lib64" OFF) + + if(USE_LIB64) + set(LIBRARY_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib64") + add_definitions("-DLIB64") + else() + set(LIBRARY_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib") + endif() + + message(STATUS "LIBRARY INSTALL DIR: ${LIBRARY_INSTALL_DIR}") +endif() + +# plugin install directories (CS_USER_PLUGIN on MacOs/Windows) +if(USE_DOUBLE) + message(STATUS "Building with 64-bit floats") + if(APPLE) + set(PLUGIN_INSTALL_DIR "$ENV{HOME}/Library/csound/${APIVERSION}/plugins64") + elseif(LINUX) + set(PLUGIN_INSTALL_DIR "${LIBRARY_INSTALL_DIR}/csound/plugins64-${APIVERSION}") + elseif(MSVC) + set(PLUGIN_INSTALL_DIR "$ENV{LOCALAPPDATA}/csound/${APIVERSION}/plugins64") + endif() +else() + message(STATUS "Building with 32-bit floats") + if(APPLE) + set(PLUGIN_INSTALL_DIR "$ENV{HOME}/Library/csound/${APIVERSION}/plugins") + elseif(LINUX) + set(PLUGIN_INSTALL_DIR "${LIBRARY_INSTALL_DIR}/csound/plugins-${APIVERSION}") + elseif(MSVC) + set(PLUGIN_INSTALL_DIR "$ENV{LOCALAPPDATA}/csound/${APIVERSION}/plugins") + endif() +endif() + +message("-- Csound headers: ${CSOUND_INCLUDE_DIR}") +if(APPLE) + message("-- Csound framework: ${CSOUND_FRAMEWORK}") +endif() +message("-- Plugins to be installed at: ${PLUGIN_INSTALL_DIR}") + +# Include utility functions for making plugins +include("${CMAKE_SOURCE_DIR}/cmake/utilities.cmake") + +# Checking pthread functions +if(REQUIRE_PTHREADS AND (PTHREAD_LIBRARY OR HAIKU)) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DHAVE_PTHREAD") + + check_function_exists(pthread_spin_lock PTHREAD_SPIN_LOCK_EXISTS) + check_function_exists(pthread_barrier_init PTHREAD_BARRIER_INIT_EXISTS) + + if(PTHREAD_SPIN_LOCK_EXISTS) + list(APPEND libcsound_CFLAGS -DHAVE_PTHREAD_SPIN_LOCK) + endif() + + if(PTHREAD_BARRIER_INIT_EXISTS) + list(APPEND libcsound_CFLAGS -DHAVE_PTHREAD_BARRIER_INIT) + endif() +endif() + +# Linux does not have a separate libintl, it is part of libc +set(LIBINTL_AVAIL (LIBINTL_LIBRARY OR LINUX)) + +if(LINUX) + message(STATUS "Building on Linux.") + add_definitions(-DLINUX -DPIPES -DNO_FLTK_THREADS -D_GNU_SOURCE -DHAVE_SOCKETS) + list(APPEND libcsound_LIBS ${MATH_LIBRARY} dl) + + find_library(LIBRT_LIBRARY rt) + + if(LIBRT_LIBRARY) + list(APPEND libcsound_LIBS ${LIBRT_LIBRARY}) + message(STATUS " ADDING LIBRT LIBRARY: ${LIBRT_LIBRARY}.") + endif() + + find_library(LIBEXECINFO_LIBRARY execinfo) + + if(LIBEXECINFO_LIBRARY) + list(APPEND libcsound_LIBS ${LIBEXECINFO_LIBRARY}) + message(STATUS " ADDING LIBEXECINFO LIBRARY: ${LIBEXECINFO_LIBRARY}.") + endif() +endif() + +if(APPLE AND NOT IOS) + add_definitions(-DMACOSX -DPIPES -DNO_FLTK_THREADS -DHAVE_SOCKETS) + find_library(ACCELERATE_LIBRARY Accelerate) + find_path(VECLIB_PATH "Accelerate/Accelerate.h") + include_directories(${VECLIB_PATH}) + list(APPEND libcsound_LIBS ${MATH_LIBRARY} dl ${ACCELERATE_LIBRARY}) +endif() + +if(WIN32) + add_definitions(-DWIN32) +endif() + +add_subdirectory(./src/py) diff --git a/7.x/cmake/CompilerOptimizations.cmake b/7.x/cmake/CompilerOptimizations.cmake deleted file mode 100644 index 5888c36b..00000000 --- a/7.x/cmake/CompilerOptimizations.cmake +++ /dev/null @@ -1,53 +0,0 @@ - -check_c_compiler_flag(-ftree-vectorize HAS_TREE_VECTORIZE) -check_cxx_compiler_flag(-ftree-vectorize HAS_CXX_TREE_VECTORIZE) -if (HAS_TREE_VECTORISE) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ftree-vectorize") -endif() -if (HAS_CXX_TREE_VECTORISE) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftree-vectorize") -endif() - - -check_c_compiler_flag(-ffast-math HAS_FAST_MATH) -check_cxx_compiler_flag(-ffast-math HAS_CXX_FAST_MATH) -if (HAS_FAST_MATH AND NOT MINGW) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffast-math") -endif() -if (HAS_CXX_FAST_MATH AND NOT MINGW) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffast-math") -endif() - - - -if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang") -check_c_compiler_flag(-mfpmath=sse HAS_FPMATH_SSE) -check_cxx_compiler_flag(-mfpmath=sse HAS_CXX_FPMATH_SSE) - if (HAS_FPMATH_SSE) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpmath=sse") -endif() -if (HAS_CXX_FPMATH_SSE) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpmath=sse") -endif() - -endif() - - -check_c_compiler_flag(-msse2 HAS_SSE2) -check_cxx_compiler_flag(-msse2 HAS_CXX_SSE2) - if (HAS_SSE2 AND NOT IOS AND NOT WASM) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse2") -endif() -if (HAS_CXX_SSE2 AND NOT IOS AND NOT WASM) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse2") -endif() - - -check_c_compiler_flag(-fomit-frame-pointer HAS_OMIT_FRAME_POINTER) -check_cxx_compiler_flag(-fomit-frame-pointer HAS_CXX_OMIT_FRAME_POINTER) -if (HAS_OMIT_FRAME_POINTER) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fomit-frame-pointer") -endif() -if (HAS_CXX_OMIT_FRAME_POINTER) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fomit-frame-pointer") -endif() diff --git a/7.x/cmake/Modules/FindCSOUND.cmake b/7.x/cmake/Modules/FindCSOUND.cmake deleted file mode 100644 index d83c0c05..00000000 --- a/7.x/cmake/Modules/FindCSOUND.cmake +++ /dev/null @@ -1,65 +0,0 @@ -# Try to find the Csound library. -# Once done this will define: -# CSOUND_FOUND - System has the Csound library -# CSOUND_INCLUDE_DIRS - The Csound include directories. -# CSOUND_LIBRARIES - The libraries needed to use the Csound library. - -if(APPLE) - find_path(CSOUND_INCLUDE_DIR csound.h - HINTS - "$ENV{HOME}/Library/Frameworks/CsoundLib64.framework/Headers" - "$ENV{HOME}/Library/Frameworks/CsoundLib.framework/Headers" - /Library/Frameworks/CsoundLib64.framework/Headers - /Library/Frameworks/CsoundLib.framework/Headers - ${CSOUND_INCLUDE_DIR_HINT} - ) - - find_path(CSOUND_FRAMEWORK CsoundLib64 - HINTS - "$ENV{HOME}/Library/Frameworks/CsoundLib64.framework" - /Library/Frameworks/CsoundLib64.framework - ${CSOUND_FRAMEWORK_DIR_HINT} - ) - - find_path(CSOUND_FRAMEWORK32 CsoundLib - HINTS - "$ENV{HOME}/Library/Frameworks/CsoundLib64.framework" - "$ENV{HOME}/Library/Frameworks/CsoundLib.framework" - /Library/Frameworks/CsoundLib64.framework - /Library/Frameworks/CsoundLib.framework - ${CSOUND_FRAMEWORK32_DIR_HINT} - ) -else() - find_path(CSOUND_INCLUDE_DIR csound.h - PATH_SUFFIXES csound - HINTS ${CSOUND_INCLUDE_DIR_HINT} - ) -endif() - -if(APPLE) - find_library(CSOUND_LIBRARY - NAMES CsoundLib64 - HINTS - /Library/Frameworks/CsoundLib64.framework/ - "$ENV{HOME}/Library/Frameworks/CsoundLib64.framework" - ${CSOUND_LIBRARY_DIR_HINT} - ) -else() - find_library(CSOUND_LIBRARY - NAMES csound64 csound - HINTS ${CSOUND_LIBRARY_DIR_HINT} - ) -endif() - -include(FindPackageHandleStandardArgs) - -# handle the QUIETLY and REQUIRED arguments and set CSOUND_FOUND to TRUE -# if all listed variables are TRUE -find_package_handle_standard_args(CSOUND - CSOUND_LIBRARY CSOUND_INCLUDE_DIR -) - -mark_as_advanced(CSOUND_INCLUDE_DIR CSOUND_LIBRARY) - -set(CSOUND_INCLUDE_DIRS ${CSOUND_INCLUDE_DIR}) -set(CSOUND_LIBRARIES ${CSOUND_LIBRARY}) diff --git a/7.x/cmake/Modules/FindEIGEN3.cmake b/7.x/cmake/Modules/FindEIGEN3.cmake deleted file mode 100644 index e4e2ed8d..00000000 --- a/7.x/cmake/Modules/FindEIGEN3.cmake +++ /dev/null @@ -1,100 +0,0 @@ -# - Try to find Eigen3 lib -# -# This module supports requiring a minimum version, e.g. you can do -# find_package(Eigen3 3.1.2) -# to require version 3.1.2 or newer of Eigen3. -# -# Once done this will define -# -# EIGEN3_FOUND - system has eigen lib with correct version -# EIGEN3_INCLUDE_DIR - the eigen include directory -# EIGEN3_VERSION - eigen version -# -# This module reads hints about search locations from -# the following enviroment variables: -# -# EIGEN3_ROOT -# EIGEN3_ROOT_DIR - -# Copyright (c) 2006, 2007 Montel Laurent, -# Copyright (c) 2008, 2009 Gael Guennebaud, -# Copyright (c) 2009 Benoit Jacob -# Redistribution and use is allowed according to the terms of the 2-clause BSD license. - -if(NOT Eigen3_FIND_VERSION) - if(NOT Eigen3_FIND_VERSION_MAJOR) - set(Eigen3_FIND_VERSION_MAJOR 2) - endif(NOT Eigen3_FIND_VERSION_MAJOR) - if(NOT Eigen3_FIND_VERSION_MINOR) - set(Eigen3_FIND_VERSION_MINOR 91) - endif(NOT Eigen3_FIND_VERSION_MINOR) - if(NOT Eigen3_FIND_VERSION_PATCH) - set(Eigen3_FIND_VERSION_PATCH 0) - endif(NOT Eigen3_FIND_VERSION_PATCH) - - set(Eigen3_FIND_VERSION "${Eigen3_FIND_VERSION_MAJOR}.${Eigen3_FIND_VERSION_MINOR}.${Eigen3_FIND_VERSION_PATCH}") -endif(NOT Eigen3_FIND_VERSION) - -macro(_eigen3_check_version) - file(READ "${EIGEN3_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen3_version_header) - - string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen3_world_version_match "${_eigen3_version_header}") - set(EIGEN3_WORLD_VERSION "${CMAKE_MATCH_1}") - string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen3_major_version_match "${_eigen3_version_header}") - set(EIGEN3_MAJOR_VERSION "${CMAKE_MATCH_1}") - string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen3_minor_version_match "${_eigen3_version_header}") - set(EIGEN3_MINOR_VERSION "${CMAKE_MATCH_1}") - - set(EIGEN3_VERSION ${EIGEN3_WORLD_VERSION}.${EIGEN3_MAJOR_VERSION}.${EIGEN3_MINOR_VERSION}) - if(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION}) - set(EIGEN3_VERSION_OK FALSE) - else(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION}) - set(EIGEN3_VERSION_OK TRUE) - endif(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION}) - - if(NOT EIGEN3_VERSION_OK) - - message(STATUS "Eigen3 version ${EIGEN3_VERSION} found in ${EIGEN3_INCLUDE_DIR}, " - "but at least version ${Eigen3_FIND_VERSION} is required") - endif(NOT EIGEN3_VERSION_OK) -endmacro(_eigen3_check_version) - -if (EIGEN3_INCLUDE_DIR) - - # in cache already - _eigen3_check_version() - set(EIGEN3_FOUND ${EIGEN3_VERSION_OK}) - -else (EIGEN3_INCLUDE_DIR) - - # search first if an Eigen3Config.cmake is available in the system, - # if successful this would set EIGEN3_INCLUDE_DIR and the rest of - # the script will work as usual - find_package(Eigen3 ${Eigen3_FIND_VERSION} NO_MODULE QUIET) - - - if(NOT EIGEN3_INCLUDE_DIR) - find_path(EIGEN3_INCLUDE_DIR NAMES signature_of_eigen3_matrix_library - HINTS - ENV EIGEN3_ROOT - ENV EIGEN3_ROOT_DIR - PATHS - ${CMAKE_INSTALL_PREFIX}/include - /usr/local/include - ${CMAKE_INSTALL_PREFIX} - $ENV{HOME}/include/ - PATH_SUFFIXES eigen3 eigen Eigen - ) - endif(NOT EIGEN3_INCLUDE_DIR) - - if(EIGEN3_INCLUDE_DIR) - _eigen3_check_version() - endif(EIGEN3_INCLUDE_DIR) - - include(FindPackageHandleStandardArgs) - find_package_handle_standard_args(Eigen3 DEFAULT_MSG EIGEN3_INCLUDE_DIR EIGEN3_VERSION_OK) - - mark_as_advanced(EIGEN3_INCLUDE_DIR) - -endif(EIGEN3_INCLUDE_DIR) - diff --git a/7.x/cmake/Modules/FindFAUST.cmake b/7.x/cmake/Modules/FindFAUST.cmake deleted file mode 100644 index d1d329e5..00000000 --- a/7.x/cmake/Modules/FindFAUST.cmake +++ /dev/null @@ -1,59 +0,0 @@ -# Find Faust2 -include(FindPackageHandleStandardArgs) - -find_path(FAUST_INCLUDE_DIR faust/dsp/llvm-dsp.h - HINTS - C:/Program Files/Faust/include/ - /opt/lib/faust/architecture/ - /usr/lib/faust/architecture/ - /usr/local/lib/faust/architecture/ - "${FAUST_INCLUDE_DIR_HINT}" -) - -find_library(FAUST_LIBRARY - NAMES - libfaust.so - libfaust.dylib - faust.dll - faust - libfaust - HINTS - "${FAUST_LIB_DIR_HINT}" -) - -find_package_handle_standard_args(FAUST FAUST_INCLUDE_DIR FAUST_LIBRARY) - -if(FAUST_FOUND) - set(FAUST_LIBRARIES ${FAUST_LIBRARY}) - set(FAUST_INCLUDE_DIRS ${FAUST_INCLUDE_DIR}) - - if("${FAUST_LIBRARY}" MATCHES ".*\\.a") - # This is a static build of faust, hence - # we have to add all the LLVM flags... - - find_program(LLVM_CONFIG llvm-config - HINTS - /usr/bin - /usr/local/bin - /usr/local/opt/llvm/bin - ) - - if(NOT LLVM_CONFIG) - message(WARNING "Using a static Faust library requires LLVM tooling to be present in the path.") - UNSET(FAUST_FOUND) - else() - exec_program(${LLVM_CONFIG} ARGS --includedir OUTPUT_VARIABLE LLVM_DIR) - exec_program(${LLVM_CONFIG} ARGS --libs OUTPUT_VARIABLE LLVM_LIBS) - exec_program(${LLVM_CONFIG} ARGS --version OUTPUT_VARIABLE LLVM_VERSION) - exec_program(${LLVM_CONFIG} ARGS --ldflags OUTPUT_VARIABLE LLVM_LDFLAGS) - - set(LLVM_VERSION LLVM_${LLVM_VERSION_MAJOR}${LLVM_VERSION_MINOR}) - - find_package(OpenSSL REQUIRED) - set(FAUST_LIBRARIES ${FAUST_LIBRARIES} dl ${OPENSSL_LIBRARIES} ncurses z ${LLVM_LDFLAGS} ${LLVM_LIBS} ) - endif() - endif() -else() - set(FAUST_LIBRARIES) - set(FAUST_INCLUDE_DIRS) -endif() diff --git a/7.x/cmake/Modules/FindFLUIDSYNTH.cmake b/7.x/cmake/Modules/FindFLUIDSYNTH.cmake deleted file mode 100644 index 152604de..00000000 --- a/7.x/cmake/Modules/FindFLUIDSYNTH.cmake +++ /dev/null @@ -1,34 +0,0 @@ -# - Find fluidsynth -# Find the native fluidsynth includes and library -# -# FLUIDSYNTH_INCLUDE_DIR - where to find fluidsynth.h -# FLUIDSYNTH_LIBRARIES - List of libraries when using fluidsynth. -# FLUIDSYNTH_FOUND - True if fluidsynth found. - -if (FLUIDSYNTH_INCLUDE_DIR AND FLUIDSYNTH_LIBRARIES) - # Already in cache, be silent - set (FLUIDSYNTH_FIND_QUIETLY TRUE) -endif () - -if(APPLE) - find_path(FLUIDSYNTH_INCLUDE_DIR fluidsynth.h HINTS - /Library/Frameworks/FluidSynth.framework/Headers - ${FLUIDSYNTH_INCLUDE_DIR_HINT}) -else() - find_path (FLUIDSYNTH_INCLUDE_DIR fluidsynth.h) -endif() - -if(APPLE) - find_library(FLUIDSYNTH_LIBRARIES NAMES FluidSynth HINTS - /Library/Frameworks/FluidSynth.framework/ - ${FLUIDSYNTH_LIBRARY_DIR_HINT}) -else() - find_library (FLUIDSYNTH_LIBRARIES NAMES fluidsynth libfluidsynth) -endif() - -mark_as_advanced (FLUIDSYNTH_LIBRARIES FLUIDSYNTH_INCLUDE_DIR) - -# handle the QUIETLY and REQUIRED arguments and set FLUIDSYNTH_FOUND to TRUE if -# all listed variables are TRUE -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(FLUIDSYNTH DEFAULT_MSG FLUIDSYNTH_LIBRARIES FLUIDSYNTH_INCLUDE_DIR) diff --git a/7.x/cmake/Modules/FindGMM.cmake b/7.x/cmake/Modules/FindGMM.cmake deleted file mode 100644 index 1b4d3596..00000000 --- a/7.x/cmake/Modules/FindGMM.cmake +++ /dev/null @@ -1,20 +0,0 @@ -# Try to find the GMM library. -# Once done this will define: -# GMM_FOUND - System has the GMM library. -# GMM_VERSION -# GMM_INCLUDE_DIR - The GMM include directories. -# GMM_HAS_VECTOR_OSTREAM - Wether GMM defines operator<< for std::vector - -if (GMM_INCLUDE_DIR) - # in cache already - set(GMM_FOUND TRUE) -else (GMM_INCLUDE_DIR) - find_path(GMM_INCLUDE_DIR NAMES gmm/gmm.h - PATHS - ${INCLUDE_INSTALL_DIR} - ${GMM_INCLUDE_PATH} - ) - include(FindPackageHandleStandardArgs) - find_package_handle_standard_args(GMM DEFAULT_MSG GMM_INCLUDE_DIR) - mark_as_advanced(GMM_INCLUDE_DIR) -endif(GMM_INCLUDE_DIR) \ No newline at end of file diff --git a/7.x/cmake/Modules/FindLAME.cmake b/7.x/cmake/Modules/FindLAME.cmake deleted file mode 100644 index 9a637529..00000000 --- a/7.x/cmake/Modules/FindLAME.cmake +++ /dev/null @@ -1,20 +0,0 @@ -# - Find LAME -# Find the native LAME includes and library -# -# LAME_INCLUDE_DIR - where to find lame.h -# LAME_LIBRARY - lame library -# LAME_FOUND - lame found - -if (LAME_INCLUDE_DIR AND LAME_LIBRARY) - # Already in cache, be silent - set (LAME_FIND_QUIETLY TRUE) -endif () - -find_path (LAME_INCLUDE_DIR lame/lame.h HINTS /usr/local/include) -find_library (LAME_LIBRARY NAMES mp3lame libmp3lame HINTS /usr/local/lib) -mark_as_advanced (LAME_LIBRARIES LAME_INCLUDE_DIR) - -# handle the QUIETLY and REQUIRED arguments and set LAME_FOUND to TRUE if -# all listed variables are TRUE -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(LAME DEFAULT_MSG LAME_LIBRARY LAME_INCLUDE_DIR) diff --git a/7.x/cmake/Modules/FindSTK.cmake b/7.x/cmake/Modules/FindSTK.cmake deleted file mode 100644 index 1d889b01..00000000 --- a/7.x/cmake/Modules/FindSTK.cmake +++ /dev/null @@ -1,19 +0,0 @@ -# Try to find the STK library. -# Once done this will define: -# STK_FOUND - System has the STK library. -# STK_INCLUDE_DIRS - The STK include directories. -# STK_LIBRARIES - The libraries needed to use the STK. - -find_path(STK_INCLUDE_DIR Stk.h PATH_SUFFIXES stk HINTS "${STK_INCLUDE_DIR_HINT}") -find_library(STK_LIBRARY NAMES stk HINTS "${STK_LIBRARY_DIR_HINT}") - -set(STK_INCLUDE_DIRS ${STK_INCLUDE_DIR}) -set(STK_LIBRARIES ${STK_LIBRARY} ) - -include(FindPackageHandleStandardArgs) -# handle the QUIETLY and REQUIRED arguments and set STK_FOUND to TRUE -# if all listed variables are TRUE -find_package_handle_standard_args(STK DEFAULT_MSG - STK_LIBRARY STK_INCLUDE_DIR) - -mark_as_advanced(STK_INCLUDE_DIR STK_LIBRARY) diff --git a/7.x/csound/arrays.h b/7.x/csound/arrays.h new file mode 100644 index 00000000..aae4d4ab --- /dev/null +++ b/7.x/csound/arrays.h @@ -0,0 +1,129 @@ +/* + array.h: + + Copyright (C) 2011, 2017 John ffitch and Stephen Kyne + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef __ARRAY_H__ +#define __ARRAY_H__ + +typedef struct { + OPDS h; + MYFLT *r, *a; +} AEVAL; + +static inline void tabinit(CSOUND *csound, ARRAYDAT *p, int size, OPDS *ctx) +{ + size_t ss; + if (p->dimensions==0) { + p->dimensions = 1; + p->sizes = (int32_t*)csound->Calloc(csound, sizeof(int32_t)); + } + if (p->data == NULL) { + CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL, ctx); + p->arrayMemberSize = var->memBlockSize; + ss = p->arrayMemberSize*size; + p->data = (MYFLT*)csound->Calloc(csound, ss); + p->allocated = ss; + } else if( (ss = p->arrayMemberSize*size) > p->allocated) { + p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss); + memset((char*)(p->data)+p->allocated, '\0', ss-p->allocated); + p->allocated = ss; + } + if (p->dimensions==1) p->sizes[0] = size; + //p->dimensions = 1; +} + +static inline void tabinit_like(CSOUND *csound, ARRAYDAT *p, const ARRAYDAT *tp) +{ + uint32_t ss = 1; + if(p->data == tp->data) { + return; + } + if (p->dimensions != tp->dimensions) { + p->sizes = (int32_t*)csound->ReAlloc(csound, p->sizes, + sizeof(int32_t)*tp->dimensions); + p->dimensions = tp->dimensions; + } + + for (int i=0; idimensions; i++) { + p->sizes[i] = tp->sizes[i]; + ss *= tp->sizes[i]; + } + if(p->arrayType == NULL) p->arrayType = tp->arrayType; + if (p->data == NULL) { + CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL, NULL); + p->arrayMemberSize = var->memBlockSize; + ss = p->arrayMemberSize*ss; + p->data = (MYFLT*)csound->Calloc(csound, ss); + p->allocated = ss; + } else if( (ss = p->arrayMemberSize*ss) > p->allocated) { + p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss); + p->allocated = ss; + } +} + +static inline int tabcheck(CSOUND *csound, ARRAYDAT *p, int size, OPDS *q) +{ + if (p->data==NULL || p->dimensions == 0) { + return csound->PerfError(csound, q, "%s", Str("Array not initialised")); + } + size_t s = p->arrayMemberSize*size; + if (s > p->allocated) { /* was arr->allocate */ + return csound->PerfError(csound, q, + Str("Array too small (allocated %zu < needed %zu), but cannot " + "allocate during performance pass. Allocate a bigger array at init time"), + p->allocated, s); + return NOTOK; + } + p->sizes[0] = size; + return OK; +} + +#if 0 +static inline void tabensure(CSOUND *csound, ARRAYDAT *p, int size) +{ + if (p->data==NULL || p->dimensions == 0 || + (p->dimensions==1 && p->sizes[0] < size)) { + size_t ss; + if (p->data == NULL) { + CS_VARIABLE* var = p->arrayType->createVariable(csound, NULL); + p->arrayMemberSize = var->memBlockSize; + } + ss = p->arrayMemberSize*size; + if (p->data==NULL) { + p->data = (MYFLT*)csound->Calloc(csound, ss); + p->allocated = ss; + } + else if (ss > p->allocated) { + p->data = (MYFLT*) csound->ReAlloc(csound, p->data, ss); + p->allocated = ss; + } + if (p->dimensions==0) { + p->dimensions = 1; + p->sizes = (int32_t*)csound->Malloc(csound, sizeof(int32_t)); + } + p->sizes[0] = size; + } + //p->sizes[0] = size; +} +#endif + +#endif /* end of include guard: __ARRAY_H__ */ diff --git a/7.x/csound/cfgvar.h b/7.x/csound/cfgvar.h new file mode 100644 index 00000000..6cd7791b --- /dev/null +++ b/7.x/csound/cfgvar.h @@ -0,0 +1,249 @@ +/* + cfgvar.h: + + Copyright (C) 2005 Istvan Varga + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef CSOUND_CFGVAR_H +#define CSOUND_CFGVAR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* generic header structure */ + +typedef struct csCfgVariableHead_s { + union csCfgVariable_u *nxt; /* pointer to next structure in chain */ + unsigned char *name; /* name of the variable */ + void *p; /* pointer to value */ + int type; /* type (e.g. CSOUNDCFG_INTEGER) */ + int flags; /* bitwise OR of flags */ + unsigned char *shortDesc; /* short description (NULL if none) */ + unsigned char *longDesc; /* long description (NULL if none) */ +} csCfgVariableHead_t; + +/* int type */ + +typedef struct csCfgVariableInt_s { + union csCfgVariable_u *nxt; /* pointer to next structure in chain */ + unsigned char *name; /* name of the variable */ + int *p; /* pointer to value */ + int type; /* type (CSOUNDCFG_INTEGER) */ + int flags; /* bitwise OR of flags */ + unsigned char *shortDesc; /* short description (NULL if none) */ + unsigned char *longDesc; /* long description (NULL if none) */ + int min; /* minimum allowed value */ + int max; /* maximum allowed value */ +} csCfgVariableInt_t; + +/* boolean type (int with a value of 0 or 1) */ + +typedef struct csCfgVariableBoolean_s { + union csCfgVariable_u *nxt; /* pointer to next structure in chain */ + unsigned char *name; /* name of the variable */ + int *p; /* pointer to value */ + int type; /* type (CSOUNDCFG_BOOLEAN) */ + int flags; /* bitwise OR of flags */ + unsigned char *shortDesc; /* short description (NULL if none) */ + unsigned char *longDesc; /* long description (NULL if none) */ +} csCfgVariableBoolean_t; + +/* float type */ + +typedef struct csCfgVariableFloat_s { + union csCfgVariable_u *nxt; /* pointer to next structure in chain */ + unsigned char *name; /* name of the variable */ + float *p; /* pointer to value */ + int type; /* type (CSOUNDCFG_FLOAT) */ + int flags; /* bitwise OR of flags */ + unsigned char *shortDesc; /* short description (NULL if none) */ + unsigned char *longDesc; /* long description (NULL if none) */ + float min; /* minimum allowed value */ + float max; /* maximum allowed value */ +} csCfgVariableFloat_t; + +/* double type */ + +typedef struct csCfgVariableDouble_s { + union csCfgVariable_u *nxt; /* pointer to next structure in chain */ + unsigned char *name; /* name of the variable */ + double *p; /* pointer to value */ + int type; /* type (CSOUNDCFG_DOUBLE) */ + int flags; /* bitwise OR of flags */ + unsigned char *shortDesc; /* short description (NULL if none) */ + unsigned char *longDesc; /* long description (NULL if none) */ + double min; /* minimum allowed value */ + double max; /* maximum allowed value */ +} csCfgVariableDouble_t; + +/* MYFLT (float or double) type */ + +typedef struct csCfgVariableMYFLT_s { + union csCfgVariable_u *nxt; /* pointer to next structure in chain */ + unsigned char *name; /* name of the variable */ + MYFLT *p; /* pointer to value */ + int type; /* type (CSOUNDCFG_MYFLT) */ + int flags; /* bitwise OR of flags */ + unsigned char *shortDesc; /* short description (NULL if none) */ + unsigned char *longDesc; /* long description (NULL if none) */ + MYFLT min; /* minimum allowed value */ + MYFLT max; /* maximum allowed value */ +} csCfgVariableMYFLT_t; + +/* string type */ + +typedef struct csCfgVariableString_s { + union csCfgVariable_u *nxt; /* pointer to next structure in chain */ + unsigned char *name; /* name of the variable */ + char *p; /* value: array of 'maxlen' chars */ + int type; /* type (CSOUNDCFG_STRING) */ + int flags; /* bitwise OR of flags */ + unsigned char *shortDesc; /* short description (NULL if none) */ + unsigned char *longDesc; /* long description (NULL if none) */ + int maxlen; /* maximum length + 1 */ +} csCfgVariableString_t; + +/* union of all variable types */ + +typedef union csCfgVariable_u { + csCfgVariableHead_t h; + csCfgVariableInt_t i; + csCfgVariableBoolean_t b; + csCfgVariableFloat_t f; + csCfgVariableDouble_t d; + csCfgVariableMYFLT_t m; + csCfgVariableString_t s; +} csCfgVariable_t; + +/* types */ + +#define CSOUNDCFG_INTEGER 1 +#define CSOUNDCFG_BOOLEAN 2 +#define CSOUNDCFG_FLOAT 3 +#define CSOUNDCFG_DOUBLE 4 +#define CSOUNDCFG_MYFLT 5 +#define CSOUNDCFG_STRING 6 + +/* flags */ + +#define CSOUNDCFG_POWOFTWO 0x00000001 + +/* error codes */ + +#define CSOUNDCFG_SUCCESS 0 +#define CSOUNDCFG_INVALID_NAME -1 +#define CSOUNDCFG_INVALID_TYPE -2 +#define CSOUNDCFG_INVALID_FLAG -3 +#define CSOUNDCFG_NULL_POINTER -4 +#define CSOUNDCFG_TOO_HIGH -5 +#define CSOUNDCFG_TOO_LOW -6 +#define CSOUNDCFG_NOT_POWOFTWO -7 +#define CSOUNDCFG_INVALID_BOOLEAN -8 +#define CSOUNDCFG_MEMORY -9 +#define CSOUNDCFG_STRING_LENGTH -10 + +#define CSOUNDCFG_LASTERROR -10 + +/* -------- interface functions -------- */ + +/* This pragma must come before all public function declarations */ + + /** + * This function is similar to csoundCreateGlobalConfigurationVariable(), + * except it creates a configuration variable specific to Csound instance + * 'csound', and is suitable for calling from the Csound library + * (in csoundPreCompile()) or plugins (in csoundModuleCreate()). + * The other parameters and return value are the same as in the case of + * csoundCreateGlobalConfigurationVariable(). + */ + PUBLIC int + csoundCreateConfigurationVariable(CSOUND *csound, const char *name, + void *p, int type, int flags, + void *min, void *max, + const char *shortDesc, + const char *longDesc); + + /** + * Set the value of a configuration variable of Csound instance 'csound'. + * The 'name' and 'value' parameters, and return value are the same as + * in the case of csoundSetGlobalConfigurationVariable(). + */ + PUBLIC int csoundSetConfigurationVariable(CSOUND *csound, const char *name, + void *value); + + /** + * Set the value of a configuration variable of Csound instance 'csound', + * by parsing a string. + * The 'name' and 'value' parameters, and return value are the same as + * in the case of csoundParseGlobalConfigurationVariable(). + */ + PUBLIC int csoundParseConfigurationVariable(CSOUND *csound, const char *name, + const char *value); + + /** + * Return pointer to the configuration variable of Csound instace 'csound' + * with the specified name. + * The return value may be NULL if the variable is not found in the database. + */ + PUBLIC csCfgVariable_t + *csoundQueryConfigurationVariable(CSOUND *csound, const char *name); + + /** + * Create an alphabetically sorted list of all configuration variables + * of Csound instance 'csound'. + * Returns a pointer to a NULL terminated array of configuration variable + * pointers, or NULL on error. + * The caller is responsible for freeing the returned list with + * csoundDeleteCfgVarList(), however, the variable pointers in the list + * should not be freed. + */ + PUBLIC csCfgVariable_t **csoundListConfigurationVariables(CSOUND *csound); + + /** + * Release a configuration variable list previously returned + * by csoundListGlobalConfigurationVariables() or + * csoundListConfigurationVariables(). + */ + PUBLIC void csoundDeleteCfgVarList(CSOUND* csound, csCfgVariable_t **lst); + + /** + * Remove the configuration variable of Csound instance 'csound' with the + * specified name from the database. Plugins need not call this, as all + * configuration variables are automatically deleted by csoundReset(). + * Return value is CSOUNDCFG_SUCCESS in case of success, or + * CSOUNDCFG_INVALID_NAME if the variable was not found. + */ + PUBLIC int csoundDeleteConfigurationVariable(CSOUND *csound, + const char *name); + /** + * Returns pointer to an error string constant for the specified + * CSOUNDCFG error code. The string is not translated. + */ + PUBLIC const char *csoundCfgErrorCodeToString(int errcode); + +/* This pragma must come after all public function declarations */ + +#ifdef __cplusplus +} +#endif + +#endif /* CSOUND_CFGVAR_H */ + diff --git a/7.x/csound/csPerfThread.h b/7.x/csound/csPerfThread.h new file mode 100644 index 00000000..3b61acba --- /dev/null +++ b/7.x/csound/csPerfThread.h @@ -0,0 +1,156 @@ +/* + csPerfThread.h: C API interface to Csound PerformanceThread + + Copyright François Pinot (C) 2024 + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef CSOUND_CSPERFTHREAD_H +#define CSOUND_CSPERFTHREAD_H + +#ifdef __cplusplus +extern "C" { +#endif + typedef void CS_PERF_THREAD; + + /** + Runs Csound in a separate thread. + The playback (which is paused by default) is stopped by calling + stop(), or if an error occurs. + The constructor takes a Csound instance pointer as argument; it assumes + that ctcsound.compile_() was called successfully before creating + the performance thread. Once the playback is stopped for one of the above + mentioned reasons, the performance thread return + */ + PUBLIC CS_PERF_THREAD* csoundCreatePerformanceThread(CSOUND *csound); + + /** + Destroys a Csound perfomance thread object + */ + PUBLIC void csoundDestroyPerformanceThread(CS_PERF_THREAD* pt); + + /** + Returns true if the performance thread is running, false otherwise. + */ + PUBLIC int csoundPerformanceThreadIsRunning(CS_PERF_THREAD* pt); + + /** + Returns the process callback. + */ + PUBLIC void *csoundPerformanceThreadGetProcessCB(CS_PERF_THREAD* pt); + + /** + Sets the process callback. + */ + PUBLIC void csoundPerformanceThreadSetProcessCB(CS_PERF_THREAD* pt, + void (*callback)(void *), + void *cbData); + + /** + Returns the Csound instance pointer + */ + PUBLIC CSOUND *csoundPerformanceThreadGetCsound(CS_PERF_THREAD* pt); + + /** + Returns the current status. + Zero if still playing, positive if the end of score was reached or + performance was stopped, and negative if an error occured. + */ + PUBLIC int csoundPerformanceThreadGetStatus(CS_PERF_THREAD* pt); + + /** + Starts/Continues performance if it was paused + */ + PUBLIC void csoundPerformanceThreadPlay(CS_PERF_THREAD* pt); + + /** + Pauses performance + */ + PUBLIC void csoundPerformanceThreadPause(CS_PERF_THREAD* pt); + + /** + Toggles performance depending on its state (playing, paused) + */ + PUBLIC void csoundPerformanceThreadTogglePause(CS_PERF_THREAD* pt); + + /** + Stops performance fully. + */ + PUBLIC void csoundPerformanceThreadStop(CS_PERF_THREAD* pt); + + /** + Starts recording the output from Csound. + The sample rate and number of channels are taken directly from the + running Csound instance. + */ + PUBLIC void csoundPerformanceThreadRecord(CS_PERF_THREAD* pt, + const char *filename, + int samplebits, int numbufs); + + /** + Stops recording and closes audio file. + */ + PUBLIC void csoundPerformanceThreadStopRecord(CS_PERF_THREAD* pt); + + /** + Sends an event. + The event has type opcod (e.g. 'i' for a note event). + pFields is tuple, a list, or an ndarray of MYFLTs with all the pfields + for this event, starting with the p1 value specified in pFields[0]. + If absp2mode is non-zero, the start time of the event is measured + from the beginning of performance, instead of the default of relative + to the current time. + */ + PUBLIC void csoundPerformanceThreadScoreEvent(CS_PERF_THREAD* pt, + int absp2mode, char opcod, + int pcnt, MYFLT *p); + + /** + Sends an event as a string + */ + PUBLIC void csoundPerformanceThreadInputMessage(CS_PERF_THREAD* pt, + const char *s); + + /** + Sets the playback time pointer to the specified value (in seconds) + */ + PUBLIC void csoundPerformanceThreadSetScoreOffsetSeconds(CS_PERF_THREAD* pt, + double timeVal); + + /** + Waits until the performance is finished or fails. + Returns a positive value if the end of score was reached or + stop() was called, and a negative value if an error occured. + Also releases any resources associated with the performance thread + object. + + */ + PUBLIC int csoundPerformanceThreadJoin(CS_PERF_THREAD* pt); + + /** + Waits until all pending messages are actually received. + (pause, send score event, etc.) + */ + PUBLIC void csoundPerformanceThreadFlushMessageQueue(CS_PERF_THREAD* pt); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/7.x/csound/csPerfThread.hpp b/7.x/csound/csPerfThread.hpp new file mode 100644 index 00000000..5d705ce7 --- /dev/null +++ b/7.x/csound/csPerfThread.hpp @@ -0,0 +1,232 @@ +/* + csPerfThread.hpp: + + Copyright (C) 2005 Istvan Varga + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef CSOUND_CSPERFTHREAD_HPP +#define CSOUND_CSPERFTHREAD_HPP + +class CsoundPerformanceThreadMessage; +class CsPerfThread_PerformScore; + +#ifdef SWIG +%include +#else +#include +#endif + +/** + * CsoundPerformanceThread(Csound *) + * CsoundPerformanceThread(CSOUND *) + * + * Performs a score in a separate thread until the end of score is reached, + * the playback (which is paused by default) is stopped by calling + * CsoundPerformanceThread::Stop(), or an error occurs. + * The constructor takes a Csound instance pointer as argument; it assumes + * that csoundCompile() was called successfully before creating the + * performance thread. Once the playback is stopped for one of the above + * mentioned reasons, the performance thread calls csoundCleanup() and + * returns. + + An example program using the CsoundPerformanceThread class + +#include +#include "csound.hpp" +#include "csPerfThread.hpp" + +int main(int argc, char *argv[]) +{ + int result=0; + Csound cs; + result = cs.Compile(argc,argv); + + if(!result) + { + CsoundPerformanceThread perfThread(cs.GetCsound()); + perfThread.Play(); // Starts performance + while(perfThread.GetStatus() == 0); + // nothing to do here... + // but you could process input events, graphics etc + perfThread.Stop(); // Stops performance. In fact, performance should have + // already finished, so this is just an example of how + //to stop if you need + perfThread.Join(); // always call Join() after Stop() as a rule of thumb. + } + else{ + printf("csoundCompile returned an error\n"); + return 1; + } + + return 0; +} +*/ + +#ifdef __SSE__ + #include +#ifndef _MM_DENORMALS_ZERO_ON + #define _MM_DENORMALS_ZERO_MASK 0x0040 + #define _MM_DENORMALS_ZERO_ON 0x0040 + #define _MM_DENORMALS_ZERO_OFF 0x0000 + #define _MM_SET_DENORMALS_ZERO_MODE(mode) \ + _mm_setcsr((_mm_getcsr() & ~_MM_DENORMALS_ZERO_MASK) | (mode)) + #define _MM_GET_DENORMALS_ZERO_MODE() \ + (_mm_getcsr() & _MM_DENORMALS_ZERO_MASK) + #endif +#else +#if !defined(_MM_SET_DENORMALS_ZERO_MODE) + #define _MM_DENORMALS_ZERO_MASK 0 + #define _MM_DENORMALS_ZERO_ON 0 + #define _MM_DENORMALS_ZERO_OFF 0 + #define _MM_SET_DENORMALS_ZERO_MODE(mode) +#endif +#endif + +typedef struct { + void *cbuf; + void *sfile; + void *thread; + bool running; + void* condvar; + void* mutex; +} recordData_t; + +class PUBLIC CsoundPerformanceThread { + private: + CSOUND *csound; + volatile CsoundPerformanceThreadMessage *firstMessage; + CsoundPerformanceThreadMessage *lastMessage; + void *queueLock; // this is actually a mutex + void *pauseLock; + void *flushLock; + void *recordLock; + void *perfThread; + int paused; + int status; + void *cdata; + recordData_t recordData; + int running; + void (*processcallback)(void *cdata); + int Perform(); + void csPerfThread_constructor(CSOUND *); + void QueueMessage(CsoundPerformanceThreadMessage *); + public: +#ifdef SWIGPYTHON + PyThreadState *_tstate; + pycallbackdata pydata; +#endif + /** + * Returns 1 if the performance thread is running, 0 otherwise + */ + int IsRunning() { return running;} + + /** + * Returns the process callback as a void pointer + */ + void *GetProcessCallback() { return (void *)processcallback; } + + /** + * Sets the process callback. + */ + void SetProcessCallback(void (*Callback)(void *), void *cbdata){ + processcallback = Callback; + cdata = cbdata; + } + /** + * Returns the Csound instance pointer. + */ + CSOUND *GetCsound() + { + return csound; + } + /** + * Returns the current status, zero if still playing, positive if + * the end of score was reached or performance was stopped, and + * negative if an error occured. + */ + int GetStatus() + { + return status; + } + /** + * Continues performance if it was paused. + */ + void Play(); + /** + * Pauses performance (can be continued by calling Play()). + */ + void Pause(); + /** + * Pauses performance unless it is already paused, in which case + * it is continued. + */ + void TogglePause(); + /** + * Stops performance (cannot be continued). + */ + void Stop(); + /** + * Starts recording the output from Csound. The sample rate and number + * of channels are taken directly from the running Csound instance. + */ + void Record(std::string filename, int samplebits = 16, int numbufs = 4); + /** + * Stops recording and closes audio file. + */ + void StopRecord(); + /** + * Sends a score event of type 'opcod' (e.g. 'i' for a note event), with + * 'pcnt' p-fields in array 'p' (p[0] is p1). If absp2mode is non-zero, + * the start time of the event is measured from the beginning of + * performance, instead of the default of relative to the current time. + */ + void ScoreEvent(int absp2mode, char opcod, int pcnt, const MYFLT *p); + /** + * Sends a score event as a string, similarly to line events (-L). + */ + void InputMessage(const char *s); + /** + * Sets the playback time pointer to the specified value (in seconds). + */ + void SetScoreOffsetSeconds(double timeVal); + /** + * Waits until the performance is finished or fails, and returns a + * positive value if the end of score was reached or Stop() was called, + * and a negative value if an error occured. Also releases any resources + * associated with the performance thread object. + */ + int Join(); + /** + * Waits until all pending messages (pause, send score event, etc.) + * are actually received by the performance thread. + */ + void FlushMessageQueue(); + // -------- + CsoundPerformanceThread(Csound *); + CsoundPerformanceThread(Csound &); + CsoundPerformanceThread(CSOUND *); + ~CsoundPerformanceThread(); + // -------- + friend class CsoundPerformanceThreadMessage; + friend class CsPerfThread_PerformScore; +}; + + +#endif // CSOUND_CSPERFTHREAD_HPP diff --git a/7.x/csound/cs_par_structs.h b/7.x/csound/cs_par_structs.h new file mode 100644 index 00000000..508a4dc8 --- /dev/null +++ b/7.x/csound/cs_par_structs.h @@ -0,0 +1,70 @@ +/* + cs_par_structs.h: + + Copyright (C) 2011 John ffitch and Chris Wilson + 2013 John ffitch and Martin Brain + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef __CS_PAR_DISPATCH_H +#define __CS_PAR_DISPATCH_H + +/* global variables lock support */ +struct global_var_lock_t; + +struct instr_semantics_t; + +/* New model */ + +/* Current memory subsystems work at the granularity of cache lines. + * Thus concurrent accesses to multiple objects within a cache line + * can cause additional conflicts and memory subsystem traffic. + * The best way to avoid this is to pad the structures so that they don't + * share a cache line. 64 bytes seems to be becoming the usual cache line + * size. If the actual line is smaller, it will waste a little memory but + * shouldn't affect the sharing. If the actual line is larger then it may + * cause a few conflicts and thus a performance hit. Unless you are + * using a very unusual machine and you happen to know it's cache line size + * then leave this as 64, although you can try 32 or maybe even 16. + */ +#define CONCURRENTPADDING 64 + +typedef int taskID; + +/* Each task has a status */ +enum state { WAITING = 3, /* Dependencies have not been finished */ + AVAILABLE = 2, /* Dependencies met, ready to be run */ + INPROGRESS = 1, /* Has been started */ + DONE = 0 }; /* Has been completed */ + +typedef struct _stateWithPadding { + enum state s; + uint8_t padding [(CONCURRENTPADDING - sizeof(enum state)) / sizeof(uint8_t)]; +} stateWithPadding; + +/* Sets of prerequiste tasks for each task */ +typedef struct _watchList { + taskID id; + struct _watchList *next; + uint8_t padding [(CONCURRENTPADDING - + (sizeof(taskID) + + sizeof(struct _watchList *))) / sizeof(uint8_t)]; +} watchList; + +#endif diff --git a/7.x/csound/cscore.h b/7.x/csound/cscore.h new file mode 100644 index 00000000..7f74e606 --- /dev/null +++ b/7.x/csound/cscore.h @@ -0,0 +1,126 @@ +/* + cscore.h: + + Copyright (C) 1991 Barry Vercoe, John ffitch + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef CSCORE_H +#define CSCORE_H +/** +* \file csound.h +* \section section_api_cscore Cscore +* +* Beginning with Csound 5, all of the Cscore functions described in the +* manual are now part of the Csound API, and they can be called from a program +* that calls the Csound library. +* +* All of the CScore functions are renamed in the Csound API. For +* example, createv() is now cscoreCreateEvent(), and lcopy() is now +* cscoreListCopy(). In addition, each function takes an additional +* first parameter that is a pointer to a CSOUND instance. You can +* find the details in the header file, cscore.h, which may be +* included with your Csound distribution, or if not, can be found in +* Csound CVS `on SourceForge. +* +* Before you can use any of the Cscore API functions, you must create a CSOUND +* instance and initialize Cscore by calling csoundInitializeCscore() -- see +* csound.h for an explanation. An example main program that does all of this +* Top/cscormai.c. You should add a function called cscore() with your own +* score-processing code. An example that does nothing except write the score +* back out unchanged can be found in the file Top/cscore_internal.c. +* +* To create your own standalone Cscore program, you must compile cscormai.c +* (or your own main program) and the file containing your +* cscore() function, and link them with the Csound API library. +*/ + +#include + +#ifndef MYFLT +#include "sysdep.h" +#endif +#include "csound.h" + +typedef struct cshdr { + struct cshdr *prvblk; + struct cshdr *nxtblk; + int16 type; + int16 size; +} CSHDR; + +/* Single score event structure */ +typedef struct { + CSHDR h; + char *strarg; + char op; + int16 pcnt; + MYFLT p2orig; + MYFLT p3orig; + MYFLT p[1]; +} EVENT; + +/* Event list structure */ +typedef struct { + CSHDR h; + int nslots; + int nevents; + EVENT *e[1]; +} EVLIST; + +/* Functions for working with single events */ +PUBLIC EVENT *cscoreCreateEvent(CSOUND*, int); +PUBLIC EVENT *cscoreDefineEvent(CSOUND*, char*); +PUBLIC EVENT *cscoreCopyEvent(CSOUND*, EVENT*); +PUBLIC EVENT *cscoreGetEvent(CSOUND*); +PUBLIC void cscorePutEvent(CSOUND*, EVENT*); +PUBLIC void cscorePutString(CSOUND*, char*); + +/* Functions for working with event lists */ +PUBLIC EVLIST *cscoreListCreate(CSOUND*, int); +PUBLIC EVLIST *cscoreListAppendEvent(CSOUND*, EVLIST*, EVENT*); +PUBLIC EVLIST *cscoreListAppendStringEvent(CSOUND*, EVLIST*, char*); +PUBLIC EVLIST *cscoreListGetSection(CSOUND*); +PUBLIC EVLIST *cscoreListGetNext(CSOUND *, MYFLT); +PUBLIC EVLIST *cscoreListGetUntil(CSOUND*, MYFLT); +PUBLIC EVLIST *cscoreListCopy(CSOUND*, EVLIST*); +PUBLIC EVLIST *cscoreListCopyEvents(CSOUND*, EVLIST*); +PUBLIC EVLIST *cscoreListExtractInstruments(CSOUND*, EVLIST*, char*); +PUBLIC EVLIST *cscoreListExtractTime(CSOUND*, EVLIST*, MYFLT, MYFLT); +PUBLIC EVLIST *cscoreListSeparateF(CSOUND*, EVLIST*); +PUBLIC EVLIST *cscoreListSeparateTWF(CSOUND*, EVLIST*); +PUBLIC EVLIST *cscoreListAppendList(CSOUND*, EVLIST*, EVLIST*); +PUBLIC EVLIST *cscoreListConcatenate(CSOUND*, EVLIST*, EVLIST*); +PUBLIC void cscoreListPut(CSOUND*, EVLIST*); +PUBLIC int cscoreListPlay(CSOUND*, EVLIST*); +PUBLIC void cscoreListSort(CSOUND*, EVLIST*); +PUBLIC int cscoreListCount(CSOUND*, EVLIST *); + +/* Functions for reclaiming memory */ +PUBLIC void cscoreFreeEvent(CSOUND*, EVENT*); +PUBLIC void cscoreListFree(CSOUND*, EVLIST*); +PUBLIC void cscoreListFreeEvents(CSOUND*, EVLIST*); + +/* Functions for working with multiple input score files */ +PUBLIC FILE *cscoreFileOpen(CSOUND*, char*); +PUBLIC void cscoreFileClose(CSOUND*, FILE*); +PUBLIC FILE *cscoreFileGetCurrent(CSOUND*); +PUBLIC void cscoreFileSetCurrent(CSOUND*, FILE*); + +#endif diff --git a/7.x/csound/csdebug.h b/7.x/csound/csdebug.h new file mode 100644 index 00000000..d601bc84 --- /dev/null +++ b/7.x/csound/csdebug.h @@ -0,0 +1,311 @@ +/* + csdebug.h: + + Copyright (C) 2014 Andres Cabrera + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef CSDEBUG_H +#define CSDEBUG_H + +/** +* \file csdebug.h +* +* This header provides the debugger API which is part of libcsound. +* +* Basic usage of the debugger is this: +* +* \code + CSOUND* csound = csoundCreate(NULL); + csoundCompileOrc(csound, " "); + csoundStart(csound); + csoundDebuggerInit(csound); + csoundSetBreakpointCallback(csound, brkpt_cb, &userdata); + csoundSetInstrumentBreakpoint(csound, 1, 5); + + // Run Csound Performance here + // The breakpoint callback will be called when instrument 1 has been + // instantiated and 5 control blocks have been processed. + + csoundDebuggerClean(csound); + csoundDestroy(csound); +* \endcode +* +*/ + +#ifdef __BUILDING_LIBCSOUND +#include "csoundCore.h" +#else +#include "csound.h" +#endif + +#include "csound_type_system.h" + + +/** @defgroup DEBUGGER Debugger + * + * @{ */ + +typedef struct debug_instr_s { + CS_VARIABLE *varPoolHead; + MYFLT *lclbas; + void *instrptr; + MYFLT p1, p2, p3; + uint64_t kcounter; + int line; + struct debug_instr_s *next; +} debug_instr_t; + +typedef struct debug_opcode_s { + char opname[16]; + int line; + // TODO: Fill opcode linked list + struct debug_opcode_s *next; + struct debug_opcode_s *prev; +} debug_opcode_t; + +typedef struct debug_variable_s { + const char *name; + const char *typeName; + void *data; + struct debug_variable_s *next; +} debug_variable_t; + +typedef struct { + debug_instr_t *breakpointInstr; + debug_variable_t *instrVarList; + debug_instr_t *instrListHead; + debug_opcode_t *currentOpcode; +} debug_bkpt_info_t; + + +/** \cond DOXYGEN_HIDDEN + * These types should not appear in the Doxygen docs */ + + +typedef enum { + CSDEBUG_BKPT_LINE, + CSDEBUG_BKPT_INSTR, + CSDEBUG_BKPT_DELETE, + CSDEBUG_BKPT_CLEAR_ALL +} bkpt_mode_t; + +typedef enum { + CSDEBUG_STATUS_RUNNING, + CSDEBUG_STATUS_STOPPED, + CSDEBUG_STATUS_NEXT +} debug_status_t; + +typedef struct bkpt_node_s { + int line; /* if line is < 0 breakpoint is for instrument instances */ + MYFLT instr; /* instrument number (including fractional part */ + int skip; /* number of times to skip when arriving at the breakpoint */ + int count; /* current backwards count for skip, when 0 break */ + bkpt_mode_t mode; + struct bkpt_node_s *next; +} bkpt_node_t; + +typedef enum { + CSDEBUG_CMD_NONE, + CSDEBUG_CMD_STEPOVER, + CSDEBUG_CMD_STEPINTO, + CSDEBUG_CMD_NEXT, + CSDEBUG_CMD_CONTINUE, + CSDEBUG_CMD_STOP +} debug_command_t; + +typedef enum { + CSDEBUG_OFF = 0x0, + CSDEBUG_K = 0x01, + CSDEBUG_INIT = 0x02 +} debug_mode_t; + +#ifdef __BUILD_LIBCSOUND + +void csoundDebuggerBreakpointReached(CSOUND *csound); + +#endif + +/** @endcond */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/** Breakpoint callback function type + * + * When a breakpoint is reached, the debugger will call a function of this type + * see csoundSetBreakpointCallback() */ +typedef void (*breakpoint_cb_t) (CSOUND *, debug_bkpt_info_t *, void *userdata); + +typedef struct csdebug_data_s { + void *bkpt_buffer; /* for passing breakpoints to the running engine */ + void *cmd_buffer; /* for passing commands to the running engine */ + debug_status_t status; + bkpt_node_t *bkpt_anchor; /* linked list for breakpoints */ + bkpt_node_t *cur_bkpt; /* current breakpoint where we are stopped */ + breakpoint_cb_t bkpt_cb; + void *cb_data; + void *debug_instr_ptr; /* != NULL when stopped at a breakpoint. + Holds INSDS * */ + void *debug_opcode_ptr; /* != NULL when stopped at a line breakpoint. + Holds OPDS * */ +} csdebug_data_t; + +/** Intialize debugger facilities + * + * This function allocates debugger structures, and enables its usage. + * There is a small performance penalty when using the debugger, so + * be sure to call csoundDebuggerClean() after use. + * + * This call is not thread safe and must be called before performance starts. + * + * @param csound A Csound instance +*/ +PUBLIC void csoundDebuggerInit(CSOUND *csound); + +/** Cleanup debugger facilities + * + * @param csound A Csound instance +*/ +PUBLIC void csoundDebuggerClean(CSOUND *csound); + +/** Set a breakpoint on a particular line + * + * @param csound A Csound instance @param line The line on which to + * set a breakpoint + * @param instr When set to 0, the line number refers + * to the line number in the score. When a number is given, it should + * refer to an instrument that has been compiled on the fly using + * csoundParseOrc(). + * @param skip number of control blocks to skip + * +*/ +PUBLIC void csoundSetBreakpoint(CSOUND *csound, int line, int instr, int skip); + +/** Remove a previously set line breakpoint + * +*/ +PUBLIC void csoundRemoveBreakpoint(CSOUND *csound, int line, int instr); + +/** Set a breakpoint for an instrument number + * + * Sets a breakpoint for an instrument number with optional number of skip + * control blocks. You can specify a fractional instrument number to identify + * particular instances. Specifying a value greater than 1 will result in that + * number of control blocks being skipped before this breakpoint is called + * again. A value of 0 and 1 has the same effect. + * + * This call is thread safe, as the breakpoint will be put in a lock free queue + * that is processed as soon as possible in the kperf function. + * + * @param csound a Csound instance + * @param instr instrument number + * @param skip number of control blocks to skip + */ +PUBLIC void csoundSetInstrumentBreakpoint(CSOUND *csound, MYFLT instr, int skip); + +/** Remove instrument breakpoint + * + * Removes an instrument breakpoint from the breakpoint list. Csound will no + * longer break at that instrument + * + * This call is thread safe, as the breakpoint will be put in a lock free queue + * that is processed as soon as possible in the kperf function. + */ +PUBLIC void csoundRemoveInstrumentBreakpoint(CSOUND *csound, MYFLT instr); + +/** Clear all breakpoints + * + * Removes all breakpoints. This call is thread safe, as it will be processed + * as soon as possible in the kperf function. + */ +PUBLIC void csoundClearBreakpoints(CSOUND *csound); + +/** Sets the breakpoint callback function + * + * Sets the function that will be called when a breakpoint is reached. + * + * @param csound Csound instance pointer + * @param bkpt_cb pointer to breakpoint callback function + * @param userdata pointer to user data that will be passed to the callback + * function + */ +PUBLIC void csoundSetBreakpointCallback(CSOUND *csound, + breakpoint_cb_t bkpt_cb, void *userdata); + +/* Not implemented yet, so not exposed in the API +PUBLIC void csoundDebugStepOver(CSOUND *csound); +PUBLIC void csoundDebugStepInto(CSOUND *csound); +*/ + +/** Continue execution and break at next instrument instance + * + * Call this function to continue execution but automatically stop at + * next instrument instance. + */ +PUBLIC void csoundDebugNext(CSOUND *csound); + +/** Continue execution from breakpoint + * + * Call this function to continue execution of a Csound instance which is + * stopped because a breakpoint has been reached. This function will continue + * traversing the instrument chain from the instrument instance that + * triggered the break. + */ +PUBLIC void csoundDebugContinue(CSOUND *csound); + +/** Stop Csound rendering and enter the debugger + * + * Calling this function will enter the debugger at the soonest possible point + * as if a breakpoint had been reached. + */ +PUBLIC void csoundDebugStop(CSOUND *csound); + +/** Get a list of active instrument instances + * Returns a linked list of allocated instrument instances + * csoundDebugFreeInstrInstances() must be called on the list once it is no + * longer needed. + * This function is not thread safe and should only be called while the csound + * engine is stopped at a breakpoint. + */ +PUBLIC debug_instr_t *csoundDebugGetInstrInstances(CSOUND *csound); + +/** Free list created by csoundDebugGetCurrentInstrInstance() or + * csoundDebugGetInstrInstances() + */ +PUBLIC void csoundDebugFreeInstrInstances(CSOUND *csound, debug_instr_t *instr); + +/** Get list of variables for instrument */ +PUBLIC debug_variable_t *csoundDebugGetVariables(CSOUND *csound, + debug_instr_t *instr); + +/** Free variable list generated by csoundDebugGetVariables() */ +PUBLIC void csoundDebugFreeVariables(CSOUND *csound, + debug_variable_t *varHead); + + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/7.x/csound/csdl.h b/7.x/csound/csdl.h new file mode 100644 index 00000000..87aa64e9 --- /dev/null +++ b/7.x/csound/csdl.h @@ -0,0 +1,184 @@ +/* + csdl.h: + + Copyright (C) 2002 John ffitch + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef CSOUND_CSDL_H +#define CSOUND_CSDL_H +/** +* \file csdl.h +* +* \brief Declares the Csound plugin opcode interface. +* \author John P. ffitch, Michael Gogins, Matt Ingalls, John D. Ramsdell, +* Istvan Varga, Victor Lazzarini. +* +* Plugin opcodes can extend the functionality of Csound, providing new +* functionality that is exposed as opcodes in the Csound language. +* Plugins need to include this header file only, as it will bring all necessary +* data structures to interact with Csound. It is not necessary for plugins +* to link to the libcsound library, as plugin opcodes will always receive a +* CSOUND* pointer (to the CSOUND_ struct) which contains all the API functions +* inside. +* +* This is the basic template for a plugin opcode. See the manual for further +* details on accepted types and function call rates. The use of the LINKAGE +* macro is highly recommended, rather than calling the functions directly. +* +* \code +#include "csdl.h" + +typedef struct { + OPDS h; + MYFLT *out; + MYFLT *in1, *in2; +} OPCODE; + +static int op_init(CSOUND *csound, OPCODE *p) +{ +// Intialization code goes here + return OK; +} + +static int op_k(CSOUND *csound, OPCODE *p) +{ +// code called at k-rate goes here + return OK; +} + +// You can use these functions if you need to prepare and cleanup things on +// loading/unloading the library, but they can be absent if you don't need them + +PUBLIC int csoundModuleCreate(CSOUND *csound) +{ + return 0; +} + +PUBLIC int csoundModuleInit(CSOUND *csound) +{ + OENTRY *ep = (OENTRY *) &(localops[0]); + int err = 0; + while (ep->opname != NULL) { + err |= csound->AppendOpcode(csound, + ep->opname, ep->dsblksiz, ep->thread, + ep->outypes, ep->intypes, + (int (*)(CSOUND *, void *)) ep->init, + (int (*)(CSOUND *, void *)) ep->perf, + (int (*)(CSOUND *, void *)) ep->deinit); + ep++; + } + return err; +} + +PUBLIC int csoundModuleDestroy(CSOUND *csound) +{ + // Called when the plugin opcode is unloaded, usually when Csound terminates. + return 0; +} + +static OENTRY localops[] = +{ + { "opcode", sizeof(OPCODE), 0, 3, "i", "ii", (SUBR)op_init, (SUBR)op_k }} +}; + +LINKAGE(localops) + +* +* \endcode +**/ + +#ifdef __BUILDING_LIBCSOUND +#undef __BUILDING_LIBCSOUND +#endif +#include "interlocks.h" +#include "csoundCore.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__wasi__) + #undef PUBLIC + #define PUBLIC extern +#endif + +/* Use the Str() macro for translations of strings */ +#undef Str + + /* VL commenting this out so ALL uses of Str(x) + call LocalizeString() [which might be a stub] + This would allows us to keep an eye on + -Wformat-security warnings + */ +//#ifndef GNU_GETTEXT +//#define Str(x) (x) +//#else +#define Str(x) (csound->LocalizeString(x)) +//#endif + +PUBLIC int64_t csound_opcode_init(CSOUND *, OENTRY **); +PUBLIC NGFENS *csound_fgen_init(CSOUND *); + +PUBLIC int csoundModuleCreate(CSOUND *); +PUBLIC int csoundModuleInit(CSOUND *); +PUBLIC int csoundModuleDestroy(CSOUND *); +PUBLIC const char *csoundModuleErrorCodeToString(int); + +PUBLIC int csoundModuleInfo(void); + +/** The LINKAGE macro sets up linking of opcode list*/ + +#define LINKAGE \ +PUBLIC int64_t csound_opcode_init(CSOUND *csound, OENTRY **ep) \ +{ (void) csound; *ep = localops; return (int64_t) sizeof(localops); } \ +PUBLIC int csoundModuleInfo(void) \ +{ return ((CS_APIVERSION << 16) + (CS_APISUBVER << 8) + (int) sizeof(MYFLT)); } + +/** The LINKAGE_BUILTIN macro sets up linking of opcode list for builtin opcodes + * which must have unique function names */ + +#undef LINKAGE_BUILTIN +#define LINKAGE_BUILTIN(name) \ +PUBLIC int64_t csound_opcode_init(CSOUND *csound, OENTRY **ep) \ +{ (void) csound; *ep = name; return (int64_t) (sizeof(name)); } \ +PUBLIC int csoundModuleInfo(void) \ +{ return ((CS_APIVERSION << 16) + (CS_APISUBVER << 8) + (int) sizeof(MYFLT)); } + +/** LINKAGE for f-table plugins */ + +#define FLINKAGE \ +PUBLIC NGFENS *csound_fgen_init(CSOUND *csound) \ +{ (void) csound; return localfgens; } \ +PUBLIC int csoundModuleInfo(void) \ +{ return ((CS_APIVERSION << 16) + (CS_APISUBVER << 8) + (int) sizeof(MYFLT)); } + +#undef FLINKAGE_BUILTIN +#define FLINKAGE_BUILTIN(name) \ +PUBLIC NGFENS *csound_fgen_init(CSOUND *csound) \ +{ (void) csound; return name; } \ +PUBLIC int csoundModuleInfo(void) \ +{ return ((CS_APIVERSION << 16) + (CS_APISUBVER << 8) + (int) sizeof(MYFLT)); } + +#ifdef __cplusplus +} +#endif + +#endif /* CSOUND_CSDL_H */ diff --git a/7.x/csound/csound.h b/7.x/csound/csound.h new file mode 100644 index 00000000..772bd7db --- /dev/null +++ b/7.x/csound/csound.h @@ -0,0 +1,1378 @@ +/* + csound.h: Csound Host API + + Copyright (C) Csound Developers 2024 + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef CSOUND_H +#define CSOUND_H + +#if (defined(WIN32) || defined(_WIN32)) && !defined(SWIG) +# if defined(__BUILDING_LIBCSOUND) +# define PUBLIC __declspec(dllexport) +# define PUBLIC_DATA __declspec(dllexport) +# else +# define PUBLIC __declspec(dllexport) +# define PUBLIC_DATA __declspec(dllimport) +# endif +#elif defined(__wasi__) +# define PUBLIC __attribute__((used)) +# if !defined(PUBLIC_DATA) +# define PUBLIC_DATA +# endif +#elif defined(__GNUC__) && (__GNUC__ >= 4) /* && !defined(__MACH__) */ +# define PUBLIC __attribute__ ( (visibility("default")) ) +# define PUBLIC_DATA __attribute__ ( (visibility("default")) ) +#else +# define PUBLIC +# define PUBLIC_DATA +#endif + +#if defined(MSVC) +# include /* for _InterlockedExchange */ +#endif + +#if defined(__MACH__) +// on OSX 10.6 i386 does not have all builtins +#if defined(MAC_OS_X_VERSION_10_6) +#ifdef HAVE_ATOMIC_BUILTIN +#ifndef __x86_64__ +#undef HAVE_ATOMIC_BUILTIN +#endif +#endif +#endif +#endif + +// FOR ANDROID +#ifdef SWIG +#define CS_PRINTF2 +#define CS_PRINTF3 +#include "float-version.h" +#ifndef __MYFLT_DEF +#define __MYFLT_DEF +#ifndef USE_DOUBLE +#define MYFLT float +#else +#define MYFLT double +#endif +#endif +#else +# include "sysdep.h" +# include "text.h" +# include +# include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + /** + * ERROR DEFINITIONS + */ + typedef enum + { + /* Completed successfully. */ + CSOUND_SUCCESS = 0, + /* Unspecified failure. */ + CSOUND_ERROR = -1, + /* Failed during initialization. */ + CSOUND_INITIALIZATION = -2, + /* Failed during performance. */ + CSOUND_PERFORMANCE = -3, + /* Failed to allocate requested memory. */ + CSOUND_MEMORY = -4, + /* Termination requested by SIGINT or SIGTERM. */ + CSOUND_SIGNAL = -5 + } CSOUND_STATUS; + + /* Compilation or performance aborted, but not as a result of an error + (e.g. --help, or running an utility with -U). */ +#define CSOUND_EXITJMP_SUCCESS (256) + + /** + * Flags for csoundInitialize(). + */ + +#define CSOUNDINIT_NO_SIGNAL_HANDLER 1 +#define CSOUNDINIT_NO_ATEXIT 2 + + /** + * Types for keyboard callbacks set in csoundRegisterKeyboardCallback() + */ + +#define CSOUND_CALLBACK_KBD_EVENT (0x00000001U) +#define CSOUND_CALLBACK_KBD_TEXT (0x00000002U) + + /** + * Forward declarations. + */ + typedef struct CSOUND_ CSOUND; + typedef struct stringdat STRINGDAT; + typedef struct arraydat ARRAYDAT; + typedef struct pvsdat PVSDAT; + + /** + * csound configuration structure, mirrors part of + * OPARMS, uses more meaningful names + */ + typedef struct { + int debug_mode; /* debug mode, 0 or 1 */ + int buffer_frames; /* number of frames in in/out buffers */ + int hardware_buffer_frames; /* ibid. hardware */ + int displays; /* graph displays, 0 or 1 */ + int ascii_graphs; /* use ASCII graphs, 0 or 1 */ + int postscript_graphs; /* use postscript graphs, 0 or 1 */ + int message_level; /* message printout control */ + int tempo; /* tempo (sets Beatmode) */ + int ring_bell; /* bell, 0 or 1 */ + int use_cscore; /* use cscore for processing */ + int terminate_on_midi; /* terminate performance at the end + of midifile, 0 or 1 */ + int heartbeat; /* print heart beat, 0 or 1 */ + int defer_gen01_load ; /* defer GEN01 load, 0 or 1 */ + int midi_key; /* pfield to map midi key no */ + int midi_key_cps; /* pfield to map midi key no as cps */ + int midi_key_oct; /* pfield to map midi key no as oct */ + int midi_key_pch; /* pfield to map midi key no as pch */ + int midi_velocity; /* pfield to map midi velocity */ + int midi_velocity_amp; /* pfield to map midi velocity as amplitude */ + int no_default_paths; /* disable relative paths from files, 0 or 1 */ + int number_of_threads; /* number of threads for multicore performance */ + int syntax_check_only; /* do not compile, only check syntax */ + int csd_line_counts; /* csd line error reporting */ + int compute_weights; /* deprecated, kept for backwards comp. */ + int realtime_mode; /* use realtime priority mode, 0 or 1 */ + int sample_accurate; /* use sample-level score event accuracy */ + MYFLT sample_rate_override; /* overriding sample rate */ + MYFLT control_rate_override; /* overriding control rate */ + int nchnls_override; /* overriding number of out channels */ + int nchnls_i_override; /* overriding number of in channels */ + MYFLT e0dbfs_override; /* overriding 0dbfs */ + int daemon; /* daemon mode */ + int ksmps_override; /* ksmps override */ + int FFT_library; /* fft_lib */ + } CSOUND_PARAMS; + + /** + * Device information + */ + typedef struct { + char device_name[128]; + char device_id[128]; + char rt_module[128]; + int max_nchnls; + int isOutput; + } CS_AUDIODEVICE; + + typedef struct { + char device_name[128]; + char interface_name[128]; + char device_id[128]; + char midi_module[128]; + int isOutput; + } CS_MIDIDEVICE; + + /** + PVSDAT window types + */ + enum PVS_WINTYPE { + PVS_WIN_HAMMING = 0, + PVS_WIN_HANN, + PVS_WIN_KAISER, + PVS_WIN_CUSTOM, + PVS_WIN_BLACKMAN, + PVS_WIN_BLACKMAN_EXACT, + PVS_WIN_NUTTALLC3, + PVS_WIN_BHARRIS_3, + PVS_WIN_BHARRIS_MIN, + PVS_WIN_RECT + }; + + + /* + * PVSDAT formats + */ + enum PVS_ANALFORMAT { + PVS_AMP_FREQ = 0, /* phase vocoder */ + PVS_AMP_PHASE, /* polar DFT */ + PVS_COMPLEX, /* rectangular DFT */ + PVS_TRACKS /* amp, freq, phase, ID tracks */ + }; + + /** + * Constants used by the bus interface (csoundGetChannelPtr() etc.). + */ + typedef enum { + CSOUND_CONTROL_CHANNEL = 1, + CSOUND_AUDIO_CHANNEL = 2, + CSOUND_STRING_CHANNEL = 3, + CSOUND_PVS_CHANNEL = 4, + CSOUND_VAR_CHANNEL = 5, + CSOUND_ARRAY_CHANNEL = 6, + + CSOUND_CHANNEL_TYPE_MASK = 15, + + CSOUND_INPUT_CHANNEL = 16, + CSOUND_OUTPUT_CHANNEL = 32 + } controlChannelType; + + typedef enum { + CSOUND_CONTROL_CHANNEL_NO_HINTS = 0, + CSOUND_CONTROL_CHANNEL_INT = 1, + CSOUND_CONTROL_CHANNEL_LIN = 2, + CSOUND_CONTROL_CHANNEL_EXP = 3 + } controlChannelBehavior; + + /** + * This structure holds the parameter hints for control channels + * + */ + typedef struct controlChannelHints_s { + controlChannelBehavior behav; + MYFLT dflt; + MYFLT min; + MYFLT max; + int x; + int y; + int width; + int height; + /** This member must be set explicitly to NULL if not used */ + char *attributes; + } controlChannelHints_t; + + typedef struct controlChannelInfo_s { + char *name; + int type; + controlChannelHints_t hints; + } controlChannelInfo_t; + + typedef void (*channelCallback_t)(CSOUND *csound, + const char *channelName, + void *channelValuePtr, + const void *channelType); + /** + Event Types + */ + enum { + CS_INSTR_EVENT = 0, + CS_TABLE_EVENT, + CS_END_EVENT + }; + +#ifndef CSOUND_CSDL_H + /** @defgroup INSTANTIATION Instantiation + * + * @{ */ + + /** + * Initialise Csound library with specific flags. This function is called + * internally by csoundCreate(), so there is generally no need to use it + * explicitly unless you need to avoid default initilization that sets + * signal handlers and atexit() callbacks. + * Return value is zero on success, positive if initialisation was + * done already, and negative on error. + */ + PUBLIC int csoundInitialize(int flags); + + /** + * Creates an instance of Csound. Returns an opaque pointer that + * must be passed to most Csound API functions. The hostData + * parameter can be NULL, or it can be a pointer to any sort of + * data; this pointer can be accessed from the Csound instance + * that is passed to callback routines. + * If not NULL the opcodedir parameter sets an override for the + * plugin module/opcode directory search + */ + PUBLIC CSOUND *csoundCreate(void *hostData, const char *opcodedir); + + /** + * Destroys an instance of Csound. + */ + PUBLIC void csoundDestroy(CSOUND *); + + + /** @}*/ + /** @defgroup ATTRIBUTES Attributes + * + * @{ */ + /** + * Returns the version number times 1000 (5.00.0 = 5000). + */ + PUBLIC int csoundGetVersion(void); + + /** + * Returns the API version number times 100 (1.00 = 100). + */ + PUBLIC int csoundGetAPIVersion(void); + + /** + * Returns the number of audio sample frames per second. + */ + PUBLIC MYFLT csoundGetSr(CSOUND *) ; + + /** + * Returns the number of control samples per second. + */ + PUBLIC MYFLT csoundGetKr(CSOUND *); + + /** + * Returns the number of audio sample frames per control sample. + */ + PUBLIC uint32_t csoundGetKsmps(CSOUND *); + + /** + * Returns the number of audio channels in the Csound instance. + * If isInput = 0, the value of nchnls is returned, + * otherwise nchnls_i. If this variable is + * not set, the value is always taken from nchnls. + */ + PUBLIC uint32_t csoundGetChannels(CSOUND *, int isInput); + + /** + * Returns the 0dBFS level of the spin/spout buffers. + */ + PUBLIC MYFLT csoundGet0dBFS(CSOUND *); + + /** + * Returns the A4 frequency reference + */ + PUBLIC MYFLT csoundGetA4(CSOUND *); + + /** + * Return the current performance time in samples + */ + PUBLIC int64_t csoundGetCurrentTimeSamples(CSOUND *csound); + + /** + * Return the size of MYFLT in bytes. + */ + PUBLIC int csoundGetSizeOfMYFLT(void); + + /** + * Returns host data. + */ + PUBLIC void *csoundGetHostData(CSOUND *); + + /** + * Sets host data. + */ + PUBLIC void csoundSetHostData(CSOUND *, void *hostData); + + /** + * Get pointer to the value of environment variable 'name', searching + * in this order: local environment of 'csound' (if not NULL), variables + * set with csoundSetGlobalEnv(), and system environment variables. + * If 'csound' is not NULL, should be called after csoundCompile(). + * Return value is NULL if the variable is not set. + */ + PUBLIC const char *csoundGetEnv(CSOUND *csound, const char *name); + + /** + * Set the global value of environment variable 'name' to 'value', + * or delete variable if 'value' is NULL. + * It is not safe to call this function while any Csound instances + * are active. + * Returns zero on success. + */ + PUBLIC int csoundSetGlobalEnv(const char *name, const char *value); + + /** + * Set csound options (flag). Returns CSOUND_SUCCESS on success. + * This needs to be called after csoundCreate() and before any code is + * compiled. Multiple options are allowed in one string. + * Returns zero on success. + */ + PUBLIC int csoundSetOption(CSOUND *csound, const char *option); + + /** + * Configure Csound with a given set of parameters defined in + * the CSOUND_PARAMS structure. These parameters are the part of the + * OPARMS struct that are configurable through command line flags. + * The CSOUND_PARAMS structure can be obtained using csoundGetParams(). + * These options should only be changed before performance has started. + */ + PUBLIC void csoundSetParams(CSOUND *csound, CSOUND_PARAMS *p); + + /** + * Get the current set of parameters from a CSOUND instance in + * a CSOUND_PARAMS structure. See csoundSetParams(). + */ + PUBLIC void csoundGetParams(CSOUND *csound, CSOUND_PARAMS *p); + + /** + * Returns whether Csound is set to print debug messages sent through the + * DebugMsg() internal API function. Anything different to 0 means true. + */ + PUBLIC int csoundGetDebug(CSOUND *); + + /** + * Sets whether Csound prints debug messages from the DebugMsg() internal + * API function. Anything different to 0 means true. + */ + PUBLIC void csoundSetDebug(CSOUND *, int debug); + + /** + * If val > 0, sets the internal variable holding the system HW sr. + * Returns the stored value containing the system HW sr. + */ + PUBLIC MYFLT csoundSystemSr(CSOUND *csound, MYFLT val); + + + /** + * retrieves a module name and type ("audio" or "midi") given a + * number Modules are added to list as csound loads them returns + * CSOUND_SUCCESS on success and CSOUND_ERROR if module number + * was not found + * + * \code + * char *name, *type; + * int n = 0; + * while(!csoundGetModule(csound, n++, &name, &type)) + * printf("Module %d: %s (%s) \n", n, name, type); + * \endcode + */ + PUBLIC int csoundGetModule(CSOUND *csound, int number, + char **name, char **type); + + /** + * This function can be called to obtain a list of available + * input or output audio devices available (depending on the backend + * module used *). + * If list is NULL, the function returns the number of devices + * (isOutput=1 for out devices, 0 for in devices). + * If list is non-NULL, then it should contain enough memory for + * one CS_AUDIODEVICE structure per device. + * Hosts will typically call this function twice: first to obtain + * a number of devices, then, after allocating space for each + * device information structure, pass an array of CS_AUDIODEVICE + * structs to be filled: + * + * \code + * int i,n = csoundGetAudioDevList(csound,NULL,1); + * CS_AUDIODEVICE *devs = (CS_AUDIODEVICE *) + * malloc(n*sizeof(CS_AUDIODEVICE)); + * csoundGetAudioDevList(csound,devs,1); + * for(i=0; i < n; i++) + * csound->Message(csound, " %d: %s (%s)\n", + * i, devs[i].device_id, devs[i].device_name); + * free(devs); + * \endcode + */ + PUBLIC int csoundGetAudioDevList(CSOUND *csound, + CS_AUDIODEVICE *list, int isOutput); + + /** + * This function can be called to obtain a list of available + * input or output midi devices. If list is NULL, the function + * will only return the number of devices (isOutput=1 for out + * devices, 0 for in devices). + * If list is non-NULL, then it should contain enough memory for + * one CS_MIDIDEVICE structure per device. + * Hosts will typically call this function twice: first to obtain + * a number of devices, then, after allocating space for each + * device information structure, pass an array of CS_MIDIDEVICE + * structs to be filled. (see also csoundGetAudioDevList()) + */ + PUBLIC int csoundGetMIDIDevList(CSOUND *csound, + CS_MIDIDEVICE *list, int isOutput); + + /** + * Returns the Csound message level (from 0 to 231). + */ + PUBLIC int csoundGetMessageLevel(CSOUND *); + + /** + * Sets the Csound message level (from 0 to 231). + */ + PUBLIC void csoundSetMessageLevel(CSOUND *, int messageLevel); + + /** @}*/ + /** @defgroup PERFORMANCE Compilation and performance + * + * @{ */ + + /** + * Compiles Csound input files (such as an orchestra and score, or CSD) + * as directed by the supplied command-line arguments, + * but does not perform them. Returns a non-zero error code on failure. + * In this mode, the sequence of calls should be as follows: + * /code + * csoundCompile(csound, argc, argv); + * csoundStart(csound); + * while (!csoundPerformKsmps(csound)); + * csoundReset(csound); + * /endcode + */ + PUBLIC int csoundCompile(CSOUND *, int argc, const char **argv); + + /** + * Parse, and compile the given orchestra from an ASCII string, + * also evaluating any global space code (i-time only) + * in synchronous or asynchronous (async = 1) mode. + * /code + * char *orc = "instr 1 \n a1 rand 0dbfs/4 \n out a1 \n"; + * csoundCompileOrc(csound, orc, 0); + * /endcode + */ + PUBLIC int csoundCompileOrc(CSOUND *csound, const char *str, int async); + + /** + * Parse and compile an orchestra given on a string, synchronously, + * evaluating any global space code (i-time only). + * On SUCCESS it returns a value passed to the + * 'return' opcode in global space + * /code + * char *code = + * "i1 = 2 + 2 \n" + * "return i1 \n"; + * MYFLT retval = csoundEvalCode(csound, code); + * /endcode + */ + PUBLIC MYFLT csoundEvalCode(CSOUND *csound, const char *str); + + /** + * Compiles a Csound input file (CSD, .csd file) or a tx string + * containing the CSD code. + * Returns a non-zero error code on failure. + * + * If csoundStart is called before csoundCompileCsd, the + * element is ignored (but csoundSetOption can be called any number of + * times), the element is not pre-processed, but dispatched as + * real-time events; and performance continues indefinitely, or until + * ended by calling csoundStop or some other logic. In this "real-time" + * mode, the sequence of calls should be: + * + * \code + * + * csoundSetOption("-an_option"); + * csoundSetOption("-another_option"); + * csoundStart(csound); + * csoundCompileCSD(csound, csd_filename, 0); + * while (1) { + * csoundPerformBuffer(csound); + * // Something to break out of the loop + * // when finished here... + * } + * csoundReset(csound); + * + * \endcode + * + * NB: this function can be called repeatedly during performance to + * replace or add new instruments and events. + * + * But if csoundCompileCsd is called before csoundStart, the + * element is used, the section is pre-processed and dispatched + * normally, and performance terminates when the score terminates, or + * csoundStop is called. In this "non-real-time" mode (which can still + * output real-time audio and handle real-time events), the sequence of + * calls should be: + * + * \code + * + * csoundCompileCsd(csound, csd_filename, 0); + * csoundStart(csound); + * while (1) { + * int finished = csoundPerformBuffer(csound); + * if (finished) break; + * } + * csoundCleanup(csound); + * csoundReset(csound); + * + * \endcode + * + * if mode = 1, csd contains a full CSD code (rather than a filename). + * This is convenient when it is desirable to package the csd as part of + * an application or a multi-language piece. + * + */ + PUBLIC int csoundCompileCSD(CSOUND *csound, const char *csd, int mode); + + /** + * Prepares Csound for performance. Normally called after compiling + * a csd file or an orc file, in which case score preprocessing is + * performed and performance terminates when the score terminates. + * + * However, if called before compiling a csd file or an orc file, + * score preprocessing is not performed and "i" statements are dispatched + * as real-time events, the tag is ignored, and performance + * continues indefinitely or until ended using the API. + */ + PUBLIC int csoundStart(CSOUND *csound); + + /** + * Senses input events, and performs one control sample worth (ksmps) of + * audio output. csoundStart() must be called first. + * Returns false during performance, and true when performance is finished. + * If called until it returns true, will perform an entire score. + * Enables external software to control the execution of Csound, + * and to synchronize performance with audio input and output. + */ + PUBLIC int csoundPerformKsmps(CSOUND *); + + /** + * Run utility with the specified name and command line arguments. + * Should be called after loading utility plugins. + * Use csoundReset() to clean up after calling this function. + * Returns zero if the utility was run successfully. + */ + PUBLIC int csoundRunUtility(CSOUND *, const char *name, + int argc, char **argv); + + /** + * Resets all internal memory and state in preparation for a new performance. + * Enables external software to run successive Csound performances + * without reloading Csound. + */ + PUBLIC void csoundReset(CSOUND *); + /** @}*/ + + /** @defgroup RTAUDIOIO Realtime Audio I/O + * + * @{ */ + + /** + * Calling this function after csoundCreate() + * and before the start of performance will disable all default + * handling of sound I/O by the Csound library via its audio backend module. + * Host application should in this case use the spin/spout buffers directly. + */ + PUBLIC void csoundSetHostAudioIO(CSOUND *); + + /** + * Sets the current RT audio module + */ + PUBLIC void csoundSetRTAudioModule(CSOUND *csound, const char *module); + + /** + * retrieves a module name and type ("audio" or "midi") given a + * number Modules are added to list as csound loads them returns + * CSOUND_SUCCESS on success and CSOUND_ERROR if module number + * was not found + * + * \code + * char *name, *type; + * int n = 0; + * while(!csoundGetModule(csound, n++, &name, &type)) + * printf("Module %d: %s (%s) \n", n, name, type); + * \endcode + */ + + + /** + * Returns the address of the Csound audio input working buffer (spin). + * Enables external software to write audio into Csound before calling + * csoundPerformKsmps. + */ + PUBLIC MYFLT *csoundGetSpin(CSOUND *); + + /** + * Returns the address of the Csound audio output working buffer (spout). + * Enables external software to read audio from Csound after calling + * csoundPerformKsmps. + */ + PUBLIC const MYFLT *csoundGetSpout(CSOUND *csound); + + /** @}*/ + /** @defgroup RTMIDI Realtime Midi I/O + * + * @{ */ + + /** + * Calling this function after csoundCreate() + * and before the start of performance to implement + * MIDI via the callbacks below. + */ + PUBLIC void csoundSetHostMIDIIO(CSOUND *csound); + + /** + * Sets the current MIDI IO module + */ + PUBLIC void csoundSetMIDIModule(CSOUND *csound, const char *module); + + + /** + * Sets callback for opening real time MIDI input. + */ + PUBLIC void csoundSetExternalMidiInOpenCallback(CSOUND *,int (*func) + (CSOUND *,void **userData, + const char *devName)); + + /** + * Sets callback for reading from real time MIDI input. + */ + PUBLIC void csoundSetExternalMidiReadCallback(CSOUND *,int (*func) + (CSOUND *, void *userData, + unsigned char *buf, + int nBytes)); + + /** + * Sets callback for closing real time MIDI input. + */ + PUBLIC void csoundSetExternalMidiInCloseCallback(CSOUND *,int (*func) + (CSOUND *,void *userData)); + + /** + * Sets callback for opening real time MIDI output. + */ + PUBLIC void csoundSetExternalMidiOutOpenCallback(CSOUND *,int (*func) + (CSOUND *,void **userData, + const char *devName)); + + /** + * Sets callback for writing to real time MIDI output. + */ + PUBLIC void csoundSetExternalMidiWriteCallback(CSOUND *, int (*func) + (CSOUND *,void *userData, + const unsigned char *buf, + int nBytes)); + + /** + * Sets callback for closing real time MIDI output. + */ + PUBLIC void csoundSetExternalMidiOutCloseCallback(CSOUND *, + int (*func)(CSOUND *, + void *userData)); + + /** + * Sets callback for converting MIDI error codes to strings. + */ + PUBLIC void csoundSetExternalMidiErrorStringCallback(CSOUND *, + const char *(*func)(int)); + + + /** + * Sets a function that is called to obtain a list of MIDI devices. + * This should be set by IO plugins, and should not be used by hosts. + * (See csoundGetMIDIDevList()) + */ + PUBLIC void csoundSetMIDIDeviceListCallback(CSOUND *csound, + int (*mididevlist__) + (CSOUND *,CS_MIDIDEVICE *list, + int isOutput)); + + /** @}*/ + + /** @defgroup MESSAGES Csound Messages and Text + * + * @{ */ + /** + * Displays an informational message. + */ + PUBLIC CS_PRINTF2 void csoundMessage(CSOUND *, const char *format, ...); + + /** + * Print message with special attributes (see msg_attr.h for the list of + * available attributes). With attr=0, csoundMessageS() is identical to + * csoundMessage(). + */ + PUBLIC CS_PRINTF3 void csoundMessageS(CSOUND *,int attr, const char *format, + ...); + + PUBLIC void csoundMessageV(CSOUND *, int attr, const char *format, + va_list args); + + PUBLIC void csoundSetDefaultMessageCallback(void (*csoundMessageCallback_) + (CSOUND *,int attr, + const char *format, + va_list valist)); + + /** + * Sets a function to be called by Csound to print an informational message. + * This callback is never called on --realtime mode + */ + PUBLIC void csoundSetMessageCallback(CSOUND *, + void (*csoundMessageCallback_) + (CSOUND *, int attr,const char *format, + va_list valist)); + + /** + * Sets an alternative function to be called by Csound to print an + * informational message, using a less granular signature. + * This callback can be set for --realtime mode. + * This callback is cleared after csoundReset + */ + PUBLIC void csoundSetMessageStringCallback(CSOUND *csound, + void (*csoundMessageStrCallback) + (CSOUND *csound,int attr, + const char *str)); + /** + * Creates a buffer for storing messages printed by Csound. + * Should be called after creating a Csound instance andthe buffer + * can be freed by calling csoundDestroyMessageBuffer() before + * deleting the Csound instance. You will generally want to call + * csoundCleanup() to make sure the last messages are flushed to + * the message buffer before destroying Csound. + * If 'toStdOut' is non-zero, the messages are also printed to + * stdout and stderr (depending on the type of the message), + * in addition to being stored in the buffer. + * Using the message buffer ties up the internal message callback, so + * csoundSetMessageCallback should not be called after creating the + * message buffer. + */ + PUBLIC void csoundCreateMessageBuffer(CSOUND *csound, int toStdOut); + + /** + * Returns the first message from the buffer. + */ + PUBLIC const char* csoundGetFirstMessage(CSOUND *csound); + + /** + * Returns the attribute parameter (see msg_attr.h) of the first message + * in the buffer. + */ + PUBLIC int csoundGetFirstMessageAttr(CSOUND *csound); + + /** + * Removes the first message from the buffer. + */ + PUBLIC void csoundPopFirstMessage(CSOUND *csound); + + /** + * Returns the number of pending messages in the buffer. + */ + PUBLIC int csoundGetMessageCnt(CSOUND *csound); + + /** + * Releases all memory used by the message buffer. + */ + void PUBLIC csoundDestroyMessageBuffer(CSOUND *csound); + + /** @}*/ + /** @defgroup CONTROLEVENTS Channels, Control and Events + * + * @{ */ + + /** + * Stores a pointer to the specified channel of the bus in *p, + * creating the channel first if it does not exist yet. + * 'type' must be the bitwise OR of exactly one of the following values, + * CSOUND_CONTROL_CHANNEL + * control data (one MYFLT value) - (MYFLYT **) pp + * CSOUND_AUDIO_CHANNEL + * audio data (csoundGetKsmps(csound) MYFLT values) -(MYFLYT **) pp + * CSOUND_STRING_CHANNEL + * string data as a STRINGDAT structure - (STRINGDAT **) pp + * (see csoundGetStringData() and csoundSetStringData()) + * CSOUND_ARRAY_CHANNEL + * array data as an ARRAYDAT structure - (ARRAYDAT **) pp + * (see csoundArrayData***(), csoundSetArrayData(), + * csoundGetArrayData(), and csoundInitArrayData()) + * CSOUND_PVS_CHANNEL + * pvs data as a PVSDATEXT structure - (PVSDAT **) pp + * (see csoundPvsData***(), csoundSetPvsData(), + * csoundGetPvsData(), and csoundInitPvsData()) + * and at least one of these: + * CSOUND_INPUT_CHANNEL + * CSOUND_OUTPUT_CHANNEL + * If the channel already exists, it must match the data type + * (control, string, audio, pvs or array), however, the input/output bits are + * OR'd with the new value. Note that audio and string channels + * can only be created after calling csoundCompile(), because the + * storage size is not known until then. + * Return value is zero on success, or a negative error code, + * CSOUND_MEMORY there is not enough memory for allocating the channel + * CSOUND_ERROR the specified name or type is invalid + * or, if a channel with the same name but incompatible type + * already exists, the type of the existing channel. In the case + * of any non-zero return value, *p is set to NULL. + * Note: to find out the type of a channel without actually + * creating or changing it, set 'type' to zero, so that the return + * value will be either the type of the channel, or CSOUND_ERROR + * if it does not exist. + * + * Operations on **p are not thread-safe by default. The host is required + * to take care of threadsafety by + * 1) with control channels use __atomic_load() or + * __atomic_store() gcc atomic builtins to get or set a channel, + * if available. + * 2) For string and audio channels (and controls if option 1 is not + * available), use csoundLockChannel() and csoundUnlockChannel() + * when accessing/modifying channel data at **p. + * See Top/threadsafe.c in the Csound library sources for + * examples. Optionally, use the channel get/set functions + * provided below, which are threadsafe by default. + */ + PUBLIC int csoundGetChannelPtr(CSOUND *, + void **p, const char *name, int type); + + /** + * Returns the var type for a channel name or NULL if the channel + * was not found. + * Currently supported channel var types are 'k' (control), 'a' (audio), + * 'S' (string), 'f' (pvs), and '[' (array). + */ + PUBLIC const char *csoundGetChannelVarTypeName(CSOUND *csound, + const char *name); + + /** + * Returns a list of allocated channels in *lst. A controlChannelInfo_t + * structure contains the channel characteristics. + * The return value is the number of channels, which may be zero if there + * are none, or CSOUND_MEMORY if there is not enough memory for allocating + * the list. In the case of no channels or an error, *lst is set to NULL. + * Notes: the caller is responsible for freeing the list returned in *lst + * with csoundDeleteChannelList(). The name pointers may become invalid + * after calling csoundReset(). + */ + PUBLIC int csoundListChannels(CSOUND *, controlChannelInfo_t **lst); + + /** + * Releases a channel list previously returned by csoundListChannels(). + */ + PUBLIC void csoundDeleteChannelList(CSOUND *, controlChannelInfo_t *lst); + + /** + * Set parameters hints for a control channel. These hints have no internal + * function but can be used by front ends to construct GUIs or to constrain + * values. See the controlChannelHints_t structure for details. + * Returns zero on success, or a non-zero error code on failure: + * CSOUND_ERROR: the channel does not exist, is not a control channel, + * or the specified parameters are invalid + * CSOUND_MEMORY: could not allocate memory + */ + PUBLIC int csoundSetControlChannelHints(CSOUND *, const char *name, + controlChannelHints_t hints); + + /** + * Returns special parameters (assuming there are any) of a control channel, + * previously set with csoundSetControlChannelHints() or the chnparams + * opcode. + * If the channel exists, is a control channel, the channel hints + * are stored in the preallocated controlChannelHints_t structure. The + * attributes member of the structure will be allocated inside this function + * so it is necessary to free it explicitly in the host. + * + * The return value is zero if the channel exists and is a control + * channel, otherwise, an error code is returned. + */ + PUBLIC int csoundGetControlChannelHints(CSOUND *, const char *name, + controlChannelHints_t *hints); + + /** + * locks access to the channel allowing access to data in + * a threadsafe manner + **/ + PUBLIC void csoundLockChannel(CSOUND *csound, const char *channel); + + /** + * unlocks access to the channel, allowing access to data from + * elsewhere. + **/ + PUBLIC void csoundUnlockChannel(CSOUND *csound, const char *channel); + + /** + * retrieves the value of control channel identified by *name. + * If the err argument is not NULL, the error (or success) code + * finding or accessing the channel is stored in it. + */ + PUBLIC MYFLT csoundGetControlChannel(CSOUND *csound, const char *name, + int *err); + + /** + * sets the value of control channel identified by *name + */ + PUBLIC void csoundSetControlChannel(CSOUND *csound, + const char *name, MYFLT val); + + /** + * copies the audio channel identified by *name into array + * *samples which should contain enough memory for ksmps MYFLTs + */ + PUBLIC void csoundGetAudioChannel(CSOUND *csound, + const char *name, MYFLT *samples); + + /** + * sets the audio channel identified by *name with data from array + * *samples which should contain at least ksmps MYFLTs + */ + PUBLIC void csoundSetAudioChannel(CSOUND *csound, const char *name, + const MYFLT *samples); + + /** + * copies the string channel identified by *name into *string + * which should contain enough memory for the string + * (see csoundGetChannelDatasize() below) + */ + PUBLIC void csoundGetStringChannel(CSOUND *csound, + const char *name, char *string); + + /** + * sets the string channel identified by *name with *string + */ + PUBLIC void csoundSetStringChannel(CSOUND *csound, + const char *name, const char *string); + + /** + * Create and initialise an array channel with a given array type + * - "a" (audio sigs): each item is a ksmps-size MYFLT array + * - "i" (init vars): each item is a MYFLT + * - "S" (strings): each item is a STRINGDAT (see csoundGetStringData() and + * csoundSetStringData()) + * - "k" (control sigs): each item is a MYFLT + * dimensions - number of array dimensions + * sizes - sizes for each dimension + * returns the ARRAYDAT for the requested channel or NULL on error + * NB: if the channel exists and has already been initialised, + * this function is a non-op. + */ + PUBLIC ARRAYDAT *csoundInitArrayChannel(CSOUND *csound, const char *name, + const char *type, int dimensions, + const int *sizes); + + + /** + * Get the type of data the ARRAYDAT adat, returning + * - "a" (audio sigs): each item is a ksmps-size MYFLT array + * - "i" (init vars): each item is a MYFLT + * - "S" (strings): each item is a STRINGDAT (see csoundGetStringData() and + * csoundSetStringData()) + * - "k" (control sigs): each item is a MYFLT + */ + PUBLIC const char *csoundArrayDataType(const ARRAYDAT *adat); + + /** + * Get the dimensions of the ARRAYDAT adat. + **/ + PUBLIC int csoundArrayDataDimensions(const ARRAYDAT *adat); + + /** + * Get the sizes of each dimension of the ARRAYDAT adat; + **/ + PUBLIC const int* csoundArrayDataSizes(const ARRAYDAT *adat); + + + /** + * Set the data in the ARRAYDAT adat + **/ + PUBLIC void csoundSetArrayData(ARRAYDAT *adat, const void* data); + + /** + * Get the data from the ARRAYDAT adat + **/ + PUBLIC const void *csoundGetArrayData(const ARRAYDAT *adat); + + + /** + * Get a null-terminated string from a STRINGDAT structure + **/ + PUBLIC const char* csoundGetStringData(CSOUND *csound, STRINGDAT *sdata); + + /** + * Set a STRINGDAT structure with a null-terminated string + */ + PUBLIC void csoundSetStringData(CSOUND *csound, STRINGDAT *sdata, + const char *str); + + /** + * Create/initialise an Fsig channel with + * size - FFT analysis size + * overlap - analysis overlap size + * winsize - analysis window size + * wintype - analysis window type (see pvsdat types enumeration) + * format - analysis data format (see pvsdat format enumeration) + * returns the PVSDAT for the requested channel or NULL on error + * NB: if the channel exists and has already been initialised, + * this function is a non-op. + */ + PUBLIC PVSDAT *csoundInitPvsChannel(CSOUND *csound, const char* name, + int size, int overlap, int winsize, + int wintype, int format); + + /** + * Get the analysis FFT size used by the PVSDAT pvsdat + */ + PUBLIC int csoundPvsDataFFTSize(const PVSDAT *pvsdat); + + /** + * Get the analysis overlap size used by the PVSDAT pvsdat + */ + PUBLIC int csoundPvsDataOverlap(const PVSDAT *pvsdat); + + /** + * Get the analysis window size used by the PVSDAT pvsdat + */ + PUBLIC int csoundPvsDataWindowSize(const PVSDAT *pvsdat); + + /** + * Get the analysis data format used by the PVSDAT pvsdat + */ + PUBLIC int csoundPvsDataFormat(const PVSDAT *pvsdat); + + /** + * Get the current framecount from PVSDAT pvsdat + */ + PUBLIC unsigned int csoundPvsDataFramecount(const PVSDAT *pvsdat); + + /** + * Get the analysis data frame from the PVSDAT pvsdat + */ + PUBLIC const float *csoundGetPvsData(const PVSDAT *pvsdat); + + /** + * Set the analysis data frame in the PVSDAT pvsdat + */ + PUBLIC void csoundSetPvsData(PVSDAT *pvsdat, const float *frame); + + /** + * returns the size of data stored in a channel; for string channels + * this might change if the channel space gets reallocated + * Since string variables use dynamic memory allocation + * this function can be called to get the space required for + * csoundGetStringChannel() + */ + PUBLIC int csoundGetChannelDatasize(CSOUND *csound, const char *name); + + /** Sets the function which will be called whenever the invalue opcode + * is used. */ + PUBLIC void + csoundSetInputChannelCallback(CSOUND *csound, + channelCallback_t inputChannelCalback); + + /** Sets the function which will be called whenever the outvalue opcode + * is used. */ + PUBLIC void + csoundSetOutputChannelCallback(CSOUND *csound, + channelCallback_t outputChannelCalback); + + /** + * Send a new event. 'type' is the event type + * type 0 - instrument instance CS_INSTR_EVENT + * type 1 - function table instance CS_TABLE_EVENT + * type 2 - end event CS_END_EVENT + * event parameters is nparams MYFLT array with the event parameters (p-fields) + * optionally run asynchronously (async = 1) + */ + PUBLIC void csoundEvent(CSOUND *, int type, MYFLT *params, int nparams, int async); + + /** + * Send a new event as a NULL-terminated string + * Multiple events separated by newlines are possible + * and score preprocessing (carry, etc) is applied. + * optionally run asynchronously (async = 1) + */ + PUBLIC void csoundEventString(CSOUND *, const char *message, int async); + + /** + * Set the ASCII code of the most recent key pressed. + * This value is used by the 'sensekey' opcode if a callback + * for returning keyboard events is not set (see + * csoundRegisterKeyboardCallback()). + */ + PUBLIC void csoundKeyPress(CSOUND *, char c); + + /** + * Registers general purpose callback functions that will be called to query + * keyboard events. These callbacks are called on every control period by + * the sensekey opcode. + * The callback is preserved on csoundReset(), and multiple + * callbacks may be set and will be called in reverse order of + * registration. If the same function is set again, it is only moved + * in the list of callbacks so that it will be called first, and the + * user data and type mask parameters are updated. 'typeMask' can be the + * bitwise OR of callback types for which the function should be called, + * or zero for all types. + * Returns zero on success, CSOUND_ERROR if the specified function + * pointer or type mask is invalid, and CSOUND_MEMORY if there is not + * enough memory. + * + * The callback function takes the following arguments: + * void *userData + * the "user data" pointer, as specified when setting the callback + * void *p + * data pointer, depending on the callback type + * unsigned int type + * callback type, can be one of the following (more may be added in + * future versions of Csound): + * CSOUND_CALLBACK_KBD_EVENT + * CSOUND_CALLBACK_KBD_TEXT + * called by the sensekey opcode to fetch key codes. The data + * pointer is a pointer to a single value of type 'int', for + * returning the key code, which can be in the range 1 to 65535, + * or 0 if there is no keyboard event. + * For CSOUND_CALLBACK_KBD_EVENT, both key press and release + * events should be returned (with 65536 (0x10000) added to the + * key code in the latter case) as unshifted ASCII codes. + * CSOUND_CALLBACK_KBD_TEXT expects key press events only as the + * actual text that is typed. + * The return value should be zero on success, negative on error, and + * positive if the callback was ignored (for example because the type is + * not known). + */ + PUBLIC int csoundRegisterKeyboardCallback(CSOUND *, + int (*func)(void *userData, void *p, + unsigned int type), + void *userData, unsigned int type); + + /** + * Removes a callback previously set with csoundRegisterKeyboardCallback(). + */ + PUBLIC void csoundRemoveKeyboardCallback(CSOUND *csound, + int (*func)(void *, void *, unsigned int)); + + + /** @}*/ + /** @defgroup TABLE Tables + * + * @{ */ + + /** + * Returns the length of a function table (not including the guard point), + * or -1 if the table does not exist. + */ + PUBLIC int csoundTableLength(CSOUND *, int table); + + /** + * Stores pointer to function table 'tableNum' in *tablePtr, + * and returns the table length (not including the guard point). + * If the table does not exist, *tablePtr is set to NULL and + * -1 is returned. + */ + PUBLIC int csoundGetTable(CSOUND *, MYFLT **tablePtr, int tableNum); + + /** + * Stores pointer to the arguments used to generate + * function table 'tableNum' in *argsPtr, + * and returns the number of arguments used. + * If the table does not exist, *argsPtr is set to NULL and + * -1 is returned. + * NB: the argument list starts with the GEN number and is followed by + * its parameters. eg. f 1 0 1024 10 1 0.5 yields the list {10.0,1.0,0.5} + */ + PUBLIC int csoundGetTableArgs(CSOUND *csound, MYFLT **argsPtr, int tableNum); + + /** @}*/ + /** @defgroup SCOREHANDLING Score Handling + * + * @{ */ + + /** + * Returns the current score time in seconds + * since the beginning of performance. + */ + PUBLIC double csoundGetScoreTime(CSOUND *); + + /** + * Sets whether Csound score events are performed or not, independently + * of real-time MIDI events (see csoundSetScorePending()). + */ + PUBLIC int csoundIsScorePending(CSOUND *); + + /** + * Sets whether Csound score events are performed or not (real-time + * events will continue to be performed). Can be used by external software, + * such as a VST host, to turn off performance of score events (while + * continuing to perform real-time events), for example to + * mute a Csound score while working on other tracks of a piece, or + * to play the Csound instruments live. + */ + PUBLIC void csoundSetScorePending(CSOUND *, int pending); + + /** + * Returns the score time beginning at which score events will + * actually immediately be performed (see csoundSetScoreOffsetSeconds()). + */ + PUBLIC MYFLT csoundGetScoreOffsetSeconds(CSOUND *); + + /** + * Csound score events prior to the specified time are not performed, and + * performance begins immediately at the specified time (real-time events + * will continue to be performed as they are received). + * Can be used by external software, such as a VST host, + * to begin score performance midway through a Csound score, + * for example to repeat a loop in a sequencer, or to synchronize + * other events with the Csound score. + */ + PUBLIC void csoundSetScoreOffsetSeconds(CSOUND *, MYFLT time); + + /** + * Rewinds a compiled Csound score to the time specified with + * csoundSetScoreOffsetSeconds(). + */ + PUBLIC void csoundRewindScore(CSOUND *); + + /** + * Sorts score file 'inFile' and writes the result to 'outFile'. + * The Csound instance should be initialised + * before calling this function, and csoundReset() should be called + * after sorting the score to clean up. On success, zero is returned. + */ + PUBLIC int csoundScoreSort(CSOUND *, FILE *inFile, FILE *outFile); + + /** + * Extracts from 'inFile', controlled by 'extractFile', and writes + * the result to 'outFile'. The Csound instance should be initialised + * before calling this function, and csoundReset() + * should be called after score extraction to clean up. + * The return value is zero on success. + */ + PUBLIC int csoundScoreExtract(CSOUND *, + FILE *inFile, FILE *outFile, FILE *extractFile); + + + /** + * Waits for at least the specified number of milliseconds, + * yielding the CPU to other threads. + */ + PUBLIC void csoundSleep(size_t milliseconds); + + + /** @}*/ + /** @defgroup OPCODES Opcodes + * + * @{ */ + + /** + * Loads all plugins from a given directory. Generally called + * immediately after csoundCreate() + * to make new opcodes/modules available for compilation and performance. + */ + PUBLIC int csoundLoadPlugins(CSOUND *csound, const char *dir); + + + /** + * Appends an opcode implemented by external software + * to Csound's internal opcode list. + * The opcode list is extended by one slot, + * and the parameters are copied into the new slot. + * Returns zero on success. + */ + PUBLIC int csoundAppendOpcode (CSOUND *, const char *opname, + int dsblksiz, int flags, + const char *outypes, const char *intypes, + int(*init)(CSOUND *, void *), + int(*perf)(CSOUND *, void *), + int(*deinit)(CSOUND *, void *)); + + /** @}*/ + +#endif /* !CSOUND_CSDL_H */ + /* typedefs, macros, and interface functions for configuration variables */ +#include "cfgvar.h" + /* message attribute definitions for csoundMessageS() and csoundMessageV() */ +#include "msg_attr.h" + /* macro definitions for Csound release, and API version */ +#include "version.h" + +#ifdef __cplusplus +} +#endif + +#endif /* CSOUND_H */ diff --git a/7.x/csound/csound.hpp b/7.x/csound/csound.hpp new file mode 100644 index 00000000..e783641d --- /dev/null +++ b/7.x/csound/csound.hpp @@ -0,0 +1,535 @@ +/* + csound.hpp: + + Copyright (C) 2005 Istvan Varga, Michael Gogins + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA + + As a special exception, if other files instantiate templates or + use macros or inline functions from this file, this file does not + by itself cause the resulting executable or library to be covered + by the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the library or executable + file might be covered by the GNU Lesser General Public License. +*/ + +#ifndef __CSOUND_HPP__ +#define __CSOUND_HPP__ + +#ifdef SWIG +%module csnd6 +%{ +#include "csound.h" + %} +#else +#include "csound.h" +#if defined(HAVE_PTHREAD_SPIN_LOCK) && !defined(SWIG) +#include +#endif +#ifdef __BUILDING_CSOUND_INTERFACES +#endif +#endif + +#ifdef SWIGPYTHON +#define MESSAGE_BUFFER_LENGTH 8192 +struct PUBLIC pycbdata { + PyObject *mfunc,*invalfunc,*outvalfunc; + PyObject *midiinopenfunc, *midireadfunc, *midiinclosefunc; + PyObject *hostdata; + char messageBuffer[MESSAGE_BUFFER_LENGTH]; + int messageBufferIndex; +}; +#endif + +#if defined(__cplusplus) + +#if defined(HAVE_PTHREAD_SPIN_LOCK) && !defined(SWIG) +struct Spinlock +{ + pthread_spinlock_t lock_; + Spinlock() + { + pthread_spin_init(&lock_, PTHREAD_PROCESS_PRIVATE); + } + ~Spinlock() + { + pthread_spin_destroy(&lock_); + } + void lock() + { + pthread_spin_lock(&lock_); + } + void unlock() + { + pthread_spin_unlock(&lock_); + } +}; + +struct Spinlocker +{ + Spinlock &spinlock; +#if (__cplusplus >= 201103L) + explicit +#endif + Spinlocker(Spinlock &spinlock_) : spinlock(spinlock_) + { + spinlock.lock(); + } + ~Spinlocker() + { + spinlock.unlock(); + } +}; +#endif + + +/** + * C++ interface to the "C" Csound API. + */ +class PUBLIC Csound +{ + protected: + CSOUND *csound; + public: + void *pydata; + public: + virtual CSOUND *GetCsound() + { + return csound; + } + virtual void SetCsound(CSOUND *csound_) + { + csound = csound_; + } + virtual int LoadPlugins(const char *dir){ + return csoundLoadPlugins(csound, dir); + } + virtual int GetVersion() + { + return csoundGetVersion(); + } + virtual int GetAPIVersion() + { + return csoundGetAPIVersion(); + } + virtual void *GetHostData() + { + return csoundGetHostData(csound); + } + virtual void SetHostData(void *hostData) + { + csoundSetHostData(csound, hostData); + } + virtual const char *GetEnv(const char *name) + { + return csoundGetEnv(csound, name); + } + virtual int SetOption(const char *option) + { + return csoundSetOption(csound, option); + } + virtual void SetParams(CSOUND_PARAMS *p){ + csoundSetParams(csound, p); + } + virtual void GetParams(CSOUND_PARAMS *p){ + csoundGetParams(csound, p); + } + virtual int CompileOrc(const char *str, int async = 0) { + return csoundCompileOrc(csound, str, async); + } + virtual MYFLT EvalCode(const char *str) + { + return csoundEvalCode(csound, str); + } + virtual int Compile(int argc,const char **argv) + { + return csoundCompile(csound, argc, argv); + } + + virtual int Compile(const char *csdName) + { + const char *argv[3]; + argv[0] = (char*)"csound"; + argv[1] = csdName; + argv[2] = (char*) 0; + return csoundCompile(csound, 2, &(argv[0])); + } + virtual int Compile(const char *orcName, const char *scoName) + { + const char *argv[4]; + argv[0] = (char*)"csound"; + argv[1] = orcName; + argv[2] = scoName; + argv[3] = (char*) 0; + return csoundCompile(csound, 3, &(argv[0])); + } + virtual int Compile(const char *arg1,const char *arg2,const char *arg3) + { + const char *argv[5]; + argv[0] = (char*)"csound"; + argv[1] = arg1; + argv[2] = arg2; + argv[3] = arg3; + argv[4] = (char*) 0; + return csoundCompile(csound, 4, &(argv[0])); + } + virtual int Compile(const char *arg1,const char *arg2,const char *arg3,const char *arg4) + { + const char *argv[6]; + argv[0] = (char*)"csound"; + argv[1] = arg1; + argv[2] = arg2; + argv[3] = arg3; + argv[4] = arg4; + argv[5] = (char*) 0; + return csoundCompile(csound, 5, &(argv[0])); + } + virtual int Compile(const char *arg1,const char *arg2,const char *arg3, + const char *arg4,const char *arg5) + { + const char *argv[7]; + argv[0] = (char*)"csound"; + argv[1] = arg1; + argv[2] = arg2; + argv[3] = arg3; + argv[4] = arg4; + argv[5] = arg5; + argv[6] = (char*) 0; + return csoundCompile(csound, 6, &(argv[0])); + } + virtual int CompileCSD(const char *csd, int mode) + { + return csoundCompileCSD(csound, csd, mode); + } + virtual int Start() + { + return csoundStart(csound); + } + virtual int PerformKsmps() + { + return csoundPerformKsmps(csound); + } + virtual void Reset() + { + csoundReset(csound); + } + virtual MYFLT GetSr() + { + return csoundGetSr(csound); + } + virtual MYFLT GetKr() + { + return csoundGetKr(csound); + } + virtual int GetKsmps() + { + return csoundGetKsmps(csound); + } + virtual int GetChannels(int isInput = 0) + { + return csoundGetChannels(csound,isInput); + } + virtual MYFLT Get0dBFS() + { + return csoundGet0dBFS(csound); + } + virtual MYFLT *GetSpin() + { + return csoundGetSpin(csound); + } + virtual const MYFLT *GetSpout() + { + return csoundGetSpout(csound); + } + virtual long GetCurrentTimeSamples(){ + return csoundGetCurrentTimeSamples(csound); + } + virtual void SetHostAudioIO() + { + csoundSetHostAudioIO(csound); + } + virtual void SetHostMIDIIO() + { + csoundSetHostMIDIIO(csound); + } + virtual double GetScoreTime() + { + return csoundGetScoreTime(csound); + } + virtual int IsScorePending() + { + return csoundIsScorePending(csound); + } + virtual void SetScorePending(int pending) + { + csoundSetScorePending(csound, pending); + } + virtual MYFLT GetScoreOffsetSeconds() + { + return csoundGetScoreOffsetSeconds(csound); + } + virtual void SetScoreOffsetSeconds(double time) + { + csoundSetScoreOffsetSeconds(csound, (MYFLT) time); + } + virtual void RewindScore() + { + csoundRewindScore(csound); + } + virtual void Message(const char *format, ...) + { + va_list args; + va_start(args, format); + csoundMessageV(csound, 0, format, args); + va_end(args); + } + virtual void MessageS(int attr, const char *format, ...) + { + va_list args; + va_start(args, format); + csoundMessageV(csound, attr, format, args); + va_end(args); + } + virtual void MessageV(int attr, const char *format, va_list args) + { + csoundMessageV(csound, attr, format, args); + } + virtual void SetMessageCallback( + void (*csoundMessageCallback_)(CSOUND *, int attr, + const char *format, va_list valist)) + { + csoundSetMessageCallback(csound, csoundMessageCallback_); + } + virtual int GetMessageLevel() + { + return csoundGetMessageLevel(csound); + } + virtual void SetMessageLevel(int messageLevel) + { + csoundSetMessageLevel(csound, messageLevel); + } + virtual void KeyPressed(char c) + { + csoundKeyPress(csound, c); + } + virtual void Event(int type, MYFLT *pFields, long numFields, int async = 0) + { + csoundEvent(csound, type, pFields, numFields, async); + } + virtual void EventString(const char *s, int async = 0) + { + csoundEventString(csound, s, async); + } + virtual void SetExternalMidiInOpenCallback( + int (*func)(CSOUND *, void **, const char *)) + { + csoundSetExternalMidiInOpenCallback(csound, func); + } + virtual void SetExternalMidiReadCallback( + int (*func)(CSOUND *, void *, unsigned char *, int)) + { + csoundSetExternalMidiReadCallback(csound, func); + } + virtual void SetExternalMidiInCloseCallback( + int (*func)(CSOUND *, void *)) + { + csoundSetExternalMidiInCloseCallback(csound, func); + } + virtual void SetExternalMidiOutOpenCallback( + int (*func)(CSOUND *, void **, const char *)) + { + csoundSetExternalMidiOutOpenCallback(csound, func); + } + virtual void SetExternalMidiWriteCallback( + int (*func)(CSOUND *, void *, const unsigned char *, int)) + { + csoundSetExternalMidiWriteCallback(csound, func); + } + virtual void SetExternalMidiOutCloseCallback( + int (*func)(CSOUND *, void *)) + { + csoundSetExternalMidiOutCloseCallback(csound, func); + } + virtual void SetExternalMidiErrorStringCallback( + const char *(*func)(int)) + { + csoundSetExternalMidiErrorStringCallback(csound, func); + } + virtual int AppendOpcode(const char *opname, int dsblksiz, int flags, + const char *outypes, const char *intypes, int(*init)(CSOUND *, void *), + int(*perf)(CSOUND *, void *), int(*deinit)(CSOUND *, void *)) + { + return csoundAppendOpcode(csound, opname, dsblksiz, flags, + outypes, intypes, init, perf, deinit); + } + virtual int GetDebug() + { + return csoundGetDebug(csound); + } + virtual void SetDebug(int debug) + { + csoundSetDebug(csound, debug); + } + virtual int TableLength(int table) + { + return csoundTableLength(csound, table); + } + virtual int GetTable(MYFLT **tablePtr, int tableNum){ + return csoundGetTable(csound, tablePtr, tableNum); + } + + virtual int GetTableArgs(MYFLT **argsPtr, int tableNum){ + return csoundGetTableArgs(csound, argsPtr, tableNum); + } + + virtual int GetChannelPtr(void* &p, const char *name, int type) + { + MYFLT *tmp; + int retval; + if(strlen(name) == 0) return CSOUND_ERROR; + retval = csoundGetChannelPtr(csound, (void **) &tmp, name, type); + p = tmp; + return retval; + } + + virtual int ListChannels(controlChannelInfo_t* &lst) + { + controlChannelInfo_t *tmp; + int retval; + retval = csoundListChannels(csound, &tmp); + lst = tmp; + return retval; + } + + virtual void DeleteChannelList(controlChannelInfo_t *lst) + { + csoundDeleteChannelList(csound, lst); + } + virtual int SetControlChannelHints(const char *name, + controlChannelHints_t hints) + { + return csoundSetControlChannelHints(csound, name, hints); + } + virtual int GetControlChannelHints(const char *name, controlChannelHints_t *hints) + { + return csoundGetControlChannelHints(csound, name, hints); + } + virtual void SetChannel(const char *name, double value) + { + csoundSetControlChannel(csound,name,value); + } + virtual void SetControlChannel(const char *name, double value) + { + csoundSetControlChannel(csound,name,value); + } + virtual void SetChannel(const char *name, const char *string) + { + csoundSetStringChannel(csound,name,string); + } + virtual void SetStringChannel(const char *name, const char *string) + { + csoundSetStringChannel(csound,name,string); + } + virtual void SetChannel(const char *name, const MYFLT *samples) + { + csoundSetAudioChannel(csound,name,samples); + } + virtual MYFLT GetChannel(const char *name, int *err = NULL) + { + return csoundGetControlChannel(csound,name,err); + } + virtual MYFLT GetControlChannel(const char *name, int *err = NULL) + { + return csoundGetControlChannel(csound,name, err); + } + virtual void GetStringChannel(const char *name, char *string) + { + csoundGetStringChannel(csound,name,string); + } + virtual void GetAudioChannel(const char *name, MYFLT *samples) + { + csoundGetAudioChannel(csound,name,samples); + } + virtual ARRAYDAT *InitArrayChannel(CSOUND *csound, const char *name, + const char *type, int dimensions, + const int *sizes) { + return csoundInitArrayChannel(csound, name, type, dimensions, sizes); + } + virtual PVSDAT *InitPvsChannel(const char* name, int size, int overlap, + int winsize, int wintype, int format) { + return csoundInitPvsChannel(csound, name, size, overlap, winsize, + wintype, format); + } + Csound() + { + csound = csoundCreate((CSOUND*) 0, NULL); + } +#if (__cplusplus >= 201103L) + Csound(const Csound &other) = delete; + explicit +#endif + Csound(CSOUND *csound_) : csound(csound_) + { + + } +#if (__cplusplus >= 201103L) + explicit +#endif + Csound(void *hostData, const char *opcodedir = NULL) + { + csound = csoundCreate(hostData, opcodedir); + } + virtual ~Csound() + { + csoundDestroy(csound); + } + virtual void CreateMessageBuffer(int toStdOut) + { + csoundCreateMessageBuffer(csound, toStdOut); + } + virtual const char *GetFirstMessage() + { + return csoundGetFirstMessage(csound); + } + virtual int GetFirstMessageAttr() + { + return csoundGetFirstMessageAttr(csound); + } + virtual void PopFirstMessage() + { + csoundPopFirstMessage(csound); + } + virtual int GetMessageCnt() + { + return csoundGetMessageCnt(csound); + } + virtual void DestroyMessageBuffer() + { + csoundDestroyMessageBuffer(csound); + } + virtual void SetAudioChannel(const char *name, MYFLT *samples) { + csoundSetAudioChannel(csound, name, samples); + } + virtual MYFLT SystemSr(MYFLT value) { + return csoundSystemSr(csound, value); + } +}; + +#endif // __cplusplus + +#endif // __CSOUND_HPP__ diff --git a/7.x/csound/csoundCore.h b/7.x/csound/csoundCore.h new file mode 100644 index 00000000..cdbe9ad1 --- /dev/null +++ b/7.x/csound/csoundCore.h @@ -0,0 +1,2206 @@ +/* + csoundCore.h: csound engine structures and module API + + Copyright (C) 1991-2024 Barry Vercoe, John ffitch, Istvan Varga, + V Lazzarini, S Yi + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#if !defined(__BUILDING_LIBCSOUND) && !defined(CSOUND_CSDL_H) +# error "Csound plugins and host applications should not include csoundCore.h" +#endif + +#ifndef CSOUNDCORE_H +#define CSOUNDCORE_H + +#if defined(__EMSCRIPTEN__) && !defined(EMSCRIPTEN) +#define EMSCRIPTEN +#endif + +#include "sysdep.h" +#if !defined(EMSCRIPTEN) && !defined(CABBAGE) +#if defined(HAVE_PTHREAD) +#include +#endif +#endif +#include "cs_par_structs.h" +#include +#include +#include "csound_type_system.h" +#include "csound.h" +#include "csound_server.h" +#include "cscore.h" +#include "csound_data_structures.h" +#include "pools.h" +#include "soundfile.h" + +#ifndef CSOUND_CSDL_H +/* VL not sure if we need to check for SSE */ +#if defined(__SSE__) && !defined(EMSCRIPTEN) +#include +#ifndef _MM_DENORMALS_ZERO_ON +#define _MM_DENORMALS_ZERO_MASK 0x0040 +#define _MM_DENORMALS_ZERO_ON 0x0040 +#define _MM_DENORMALS_ZERO_OFF 0x0000 +#define _MM_SET_DENORMALS_ZERO_MODE(mode) \ + _mm_setcsr((_mm_getcsr() & ~_MM_DENORMALS_ZERO_MASK) | (mode)) +#define _MM_GET_DENORMALS_ZERO_MODE() \ + (_mm_getcsr() & _MM_DENORMALS_ZERO_MASK) +#endif +#else +#ifndef _MM_DENORMALS_ZERO_ON +#define _MM_DENORMALS_ZERO_MASK 0 +#define _MM_DENORMALS_ZERO_ON 0 +#define _MM_DENORMALS_ZERO_OFF 0 +#define _MM_SET_DENORMALS_ZERO_MODE(mode) +#endif +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + + /* VL: these were moved here from csound.h + as they are not relevant to the new host API + */ + typedef struct xyindat_ XYINDAT; + + /** + * Real-time audio parameters structure + */ + typedef struct { + /** device name (NULL/empty: default) */ + char *devName; + /** device number (0-1023), 1024: default */ + int devNum; + /** buffer fragment size (-b) in sample frames */ + unsigned int bufSamp_SW; + /** total buffer size (-B) in sample frames */ + int bufSamp_HW; + /** number of channels */ + int nChannels; + /** sample format (AE_SHORT etc.) */ + int sampleFormat; + /** sample rate in Hz */ + float sampleRate; + /** ksmps */ + int ksmps; + } csRtAudioParams; + + uint32_t csoundGetNchnls(CSOUND *); + uint32_t csoundGetNchnlsInput(CSOUND *csound); + long csoundGetInputBufferSize(CSOUND *); + long csoundGetOutputBufferSize(CSOUND *); + void *csoundGetNamedGens(CSOUND *); + int *csoundGetChannelLock(CSOUND *csound, const char *name); + + void **csoundGetRtRecordUserData(CSOUND *); + void **csoundGetRtPlayUserData(CSOUND *); + + void + csoundSetPlayopenCallback(CSOUND *, + int (*playopen__)(CSOUND *, + const csRtAudioParams *parm)); + void csoundSetRtplayCallback(CSOUND *, + void (*rtplay__)(CSOUND *, + const MYFLT *outBuf, + int nbytes)); + void csoundSetRecopenCallback(CSOUND *, + int (*recopen_)(CSOUND *, + const csRtAudioParams *parm)); + void csoundSetRtrecordCallback(CSOUND *, + int (*rtrecord__)(CSOUND *, + MYFLT *inBuf, + int nbytes)); + void csoundSetRtcloseCallback(CSOUND *, void (*rtclose__)(CSOUND *)); + void csoundSetAudioDeviceListCallback(CSOUND *csound, + int (*audiodevlist__)(CSOUND *, + CS_AUDIODEVICE *list, + int isOutput)); + + int csoundCompileCsd(CSOUND *csound, const char *csd_filename); + int csoundCompileCsdText(CSOUND *csound, const char *csd_text); + int csoundCleanup(CSOUND *); + + void csoundInputMessage(CSOUND *csound, const char * sc); + int csoundScoreEvent(CSOUND *, char type, const MYFLT *pFields, + long numFields); + +#include "csound_files.h" +#include "csound_graph_display.h" +#include "csound_circular_buffer.h" +#include "csound_threads.h" +#include "csound_compiler.h" +#include "csound_misc.h" + +#if defined(__MACH__) || defined(__FreeBSD__) || defined(__DragonFly__) +#include +#endif + +#if (defined(__MACH__) || defined(ANDROID) || defined(NACL) || defined(__CYGWIN__) || defined(__HAIKU__)) +#include +#define BARRIER_SERIAL_THREAD (-1) + typedef struct { + pthread_mutex_t mut; + pthread_cond_t cond; + unsigned int count, max, iteration; + } barrier_t; + +#ifndef PTHREAD_BARRIER_SERIAL_THREAD +#define pthread_barrier_t barrier_t +#endif /* PTHREAD_BARRIER_SERIAL_THREAd */ +#endif /* __MACH__ */ + +#define OK (0) +#define NOTOK (-1) + +#define DEFAULT_STRING_SIZE 64 + +#define CSFILE_FD_R 1 +#define CSFILE_FD_W 2 +#define CSFILE_STD 3 +#define CSFILE_SND_R 4 +#define CSFILE_SND_W 5 + + /* check for power of two ftable sizes */ +#define IS_POW_TWO(N) ((N != 0) ? !(N & (N - 1)) : 0) + +#define MAXINSNO (200) +#define PMAX (1998) +#define VARGMAX (1999) +#define NOT_AN_INSTRUMENT INT32_MAX + +#define ORTXT h.optext->t +#define INCOUNT ORTXT.inlist->count +#define OUTCOUNT ORTXT.outlist->count /* Not used */ +#define INOCOUNT ORTXT.inArgCount +#define OUTOCOUNT ORTXT.outArgCount +#define IS_ASIG_ARG(x) (GetTypeForArg(x) == csound->GetType(csound, "a")) +#define IS_STR_ARG(x) (GetTypeForArg(x) == csound->GetType(csound, "S")) +#define IS_KSIG_ARG(x) (GetTypeForArg(x) == csound->GetType(csound, "k")) +#define IS_INIT_ARG(x) (GetTypeForArg(x) == csound->GetType(csound, "i")) +#define IS_FSIG_ARG(x) (GetTypeForArg(x) == csound->GetType(csound, "f")) +#define IS_ARRAY_ARG(x) (GetTypeForArg(x) == csound->GetType(csound, "[")) + +#define CURTIME (((double)csound->icurTime)/((double)csound->esr)) +#define CURTIME_inc (((double)csound->ksmps)/((double)csound->esr)) + +#ifdef B64BIT +#define MAXLEN 0x10000000 +#define FMAXLEN ((MYFLT)(MAXLEN)) +#define PHMASK 0x0fffffff +#else +#define MAXLEN 0x1000000L +#define FMAXLEN ((MYFLT)(MAXLEN)) +#define PHMASK 0x0FFFFFFL +#endif + +#define MAX_STRING_CHANNEL_DATASIZE 16384 + +#define PFRAC(x) ((MYFLT)((x) & ftp->lomask) * ftp->lodiv) +#define MAXPOS 0x7FFFFFFFL + +#define BYTREVS(n) ((n>>8 & 0xFF) | (n<<8 & 0xFF00)) +#define BYTREVL(n) ((n>>24 & 0xFF) | (n>>8 & 0xFF00L) | \ + (n<<8 & 0xFF0000L) | (n<<24 & 0xFF000000L)) + +#define OCTRES 8192 +#define CPSOCTL(n) ((MYFLT)(1<<((int)(n)>>13))*csound->cpsocfrc[(int)(n)&8191]) + +#define LOBITS 10 +#define LOFACT 1024 + /* LOSCAL is 1/LOFACT as MYFLT */ +#define LOSCAL FL(0.0009765625) +#define LOMASK 1023 + +#ifdef USE_DOUBLE + extern int64_t MYNAN; +#define SSTRCOD (double)NAN +#else + extern int32 MYNAN; +#define SSTRCOD (float)NAN +#endif + extern int ISSTRCOD(MYFLT); + +#define SSTRSIZ 1024 +#define ALLCHNLS 0x7fff +#define DFLT_SR FL(44100.0) +#define DFLT_KR FL(4410.0) +#define DFLT_KSMPS 10 +#define DFLT_NCHNLS 1 +#define MAXCHNLS 256 + +#define MAXNAME (256) + +#define DFLT_DBFS (FL(32768.0)) + +#define MAXOCTS 8 +#define MAXCHAN 16 /* 16 MIDI channels; only one port for now */ + + /* A440 tuning factor */ +#define ONEPT (csound->GetA4(csound)/430.5389646099018460319362438314060262605) +#define LOG10D20 0.11512925 /* for db to ampfac */ +#define DV32768 FL(0.000030517578125) + +#ifndef PI +#define PI (3.141592653589793238462643383279502884197) +#endif /* pi */ +#define TWOPI (6.283185307179586476925286766559005768394) +#define HALFPI (1.570796326794896619231321691639751442099) +#define PI_F ((MYFLT) PI) +#define TWOPI_F ((MYFLT) TWOPI) +#define HALFPI_F ((MYFLT) HALFPI) +#define INF (2147483647.0) +#define ROOT2 (1.414213562373095048801688724209698078569) + + /* CONSTANTS FOR USE IN MSGLEVEL */ +#define CS_AMPLMSG 01 +#define CS_RNGEMSG 02 +#define CS_WARNMSG 04 +#define CS_NOMSG 0x10 +#define CS_RAWMSG 0x40 +#define CS_TIMEMSG 0x80 +#define CS_NOQQ 0x400 + +#define IGN(X) (void) X + +#define ARG_CONSTANT 0 +#define ARG_STRING 1 +#define ARG_PFIELD 2 +#define ARG_GLOBAL 3 +#define ARG_LOCAL 4 +#define ARG_LABEL 5 + +#define ASYNC_GLOBAL 1 +#define ASYNC_LOCAL 2 + + enum {FFT_LIB=0, PFFT_LIB, VDSP_LIB}; + enum {FFT_FWD=0, FFT_INV}; + + /* advance declaration for + API message queue struct + */ + struct _message_queue; + + typedef struct CSFILE_ { + struct CSFILE_ *nxt; + struct CSFILE_ *prv; + int type; + int fd; + FILE *f; + SNDFILE *sf; + void *cb; + int async_flag; + int items; + int pos; + MYFLT *buf; + int bufsize; + char fullName[1]; + } CSFILE; + + + typedef struct CORFIL { + char *body; + unsigned int len; + unsigned int p; + } CORFIL; + + typedef struct { + int odebug; + int sfread, sfwrite, sfheader, filetyp; + int inbufsamps, outbufsamps; + int informat, outformat; + int sfsampsize; + int displays, graphsoff, postscript, msglevel; + int Beatmode, oMaxLag; + int usingcscore, Linein; + int RTevents, Midiin, FMidiin, RMidiin; + int ringbell, termifend; + int rewrt_hdr, heartbeat, gen01defer; + double cmdTempo; + float sr_override, kr_override; + int nchnls_override, nchnls_i_override; + char *infilename, *outfilename; + CORFIL *playscore; + char *Linename, *Midiname, *FMidiname; + char *Midioutname; + /* jjk 09252000 - MIDI output device, -Q option */ + char *FMidioutname; + int midiKey, midiKeyCps, midiKeyOct, midiKeyPch; + int midiVelocity, midiVelocityAmp; + int noDefaultPaths; + /* syy - Oct 25, 2006: for disabling relative paths + from files */ + int numThreads; + int syntaxCheckOnly; + int useCsdLineCounts; + int sampleAccurate; /* switch for score events sample accuracy */ + int realtime; /* realtime priority mode */ + MYFLT e0dbfs_override; + int daemon; + double quality; /* for ogg encoding */ + int ksmps_override; + int fft_lib; + int echo; + MYFLT limiter; + float sr_default, kr_default; + int mp3_mode; + } OPARMS; + + typedef struct arglst { + int count; + char *arg[1]; + } ARGLST; + + typedef struct arg { + int type; + void* argPtr; + int index; + char* structPath; + struct arg* next; + } ARG; + + typedef struct oentry { + char *opname; + uint16 dsblksiz; + uint16 flags; + char *outypes; + char *intypes; + int32_t (*init)(CSOUND *, void *p); + int32_t (*perf)(CSOUND *, void *p); + int32_t (*deinit)(CSOUND *, void *p); + void *useropinfo; /* user opcode parameters */ + } OENTRY; + + /** + * Storage for parsed orchestra code, for each opcode in an INSTRTXT. + */ + typedef struct text { + uint16_t linenum; /* Line num in orch file (currently buggy!) */ + uint64_t locn; /* and location */ + OENTRY *oentry; + char *opcod; /* Pointer to opcode name in global pool */ + ARGLST *inlist; /* Input args (pointer to item in name list) */ + ARGLST *outlist; + ARG *inArgs; /* Input args (index into list of values) */ + unsigned int inArgCount; + ARG *outArgs; + unsigned int outArgCount; + // char intype; /* Type of first input argument (g,k,a,w etc) */ + char pftype; /* Type of output argument (k,a etc) */ + } TEXT; + + + /** + * This struct is filled out by otran() at orch parse time. + * It is used as a template for instrument events. + */ + typedef struct instr { + struct op * nxtop; /* Linked list of instr opcodes */ + TEXT t; /* Text of instrument (same in nxtop) */ + int pmax, vmax, pextrab; /* Arg count, size of data for all + opcodes in instr */ + //int mdepends; /* Opcode type (i/k/a) */ + CS_VAR_POOL* varPool; + + // int optxtcount; + int16 muted; + // int32 localen; + int32 opdstot; /* Total size of opds structs in instr */ + // int32 *inslist; /* Only used in parsing (?) */ + MYFLT *psetdata; /* Used for pset opcode */ + struct insds * instance; /* Chain of allocated instances of + this instrument */ + struct insds * lst_instance; /* last allocated instance */ + struct insds * act_instance; /* Chain of free (inactive) instances */ + /* (pointer to next one is INSDS.nxtact) */ + struct instr * nxtinstxt; /* Next instrument in orch (num order) */ + int active; /* To count activations for control */ + int pending_release; /* To count instruments in release phase */ + int maxalloc; + MYFLT cpuload; /* % load this instrumemnt makes */ + struct opcodinfo *opcode_info; /* UDO info (when instrs are UDOs) */ + char *insname; /* instrument name */ + int instcnt; /* Count number of instances ever */ + int isNew; /* is this a new definition */ + int nocheckpcnt; /* Control checks on pcnt */ + } INSTRTXT; + + typedef struct namedInstr { + int32 instno; + char *name; + INSTRTXT *ip; + struct namedInstr *next; + } INSTRNAME; + + /** + * A chain of TEXT structs. Note that this is identical with the first two + * members of struct INSTRTEXT, and is so typecast at various points in code. + */ + typedef struct op { + struct op *nxtop; + TEXT t; + } OPTXT; + + typedef struct fdch { + struct fdch *nxtchp; + /** handle returned by csound->FileOpen() */ + void *fd; + } FDCH; + + typedef struct auxch { + struct auxch *nxtchp; + size_t size; + void *auxp, *endp; + } AUXCH; + + /** this callback is used to notify the + availability of new storage in AUXCH *. + It can be used to swap the old storage + for the new one and return it for deallocation. + */ + typedef AUXCH* (*aux_cb)(CSOUND *, void *, AUXCH *); + + /** + * AuxAllocAsync data + */ + typedef struct { + CSOUND *csound; + size_t nbytes; + AUXCH *auxchp; + void *userData; + aux_cb notify; + } AUXASYNC; + + typedef struct { + int size; /* 0...size-1 */ + MYFLT *data; + AUXCH aux; + } TABDAT; + + /* + * Type definition for array data + */ + struct arraydat { + int dimensions; /* number of array dimensions */ + int32_t* sizes; /* size of each dimensions */ + int arrayMemberSize; /* size of each item */ + const struct cstype* arrayType; /* type of array */ + MYFLT* data; /* data */ + size_t allocated; /* size of allocated data */ + }; + +#define MAX_STRINGDAT_SIZE 0xFFFFFFFF + /* + * Type definition for string data (string channels) + */ + struct stringdat { + char *data; // null-terminated string + size_t size; // total allocated size + int64_t timestamp; // used internally for updates + }; + + typedef struct monblk { + int16 pch; + struct monblk *prv; + } MONPCH; + + typedef struct { + int notnum[4]; + } DPEXCL; + + typedef struct { + DPEXCL dpexcl[8]; + /** for keys 25-99 */ + int exclset[75]; + } DPARM; + + typedef struct dklst { + struct dklst *nxtlst; + int32 pgmno; + /** cnt + keynos */ + MYFLT keylst[1]; + } DKLST; + + typedef struct mchnblk { + /** most recently received program change */ + int16 pgmno; + /** instrument number assigned to this channel */ + int16 insno; + int16 RegParNo; + int16 mono; + /** channel number */ + int16 channel; + MONPCH *monobas; + MONPCH *monocur; + /** list of active notes (NULL: not active) */ + struct insds *kinsptr[128]; + /** polyphonic pressure indexed by note number */ + MYFLT polyaft[128]; + /** ... with GS vib_rate, stored in c128-c135 */ + MYFLT ctl_val[136]; + /** program change to instr number (<=0: ignore) */ + int16 pgm2ins[128]; + /** channel pressure (0-127) */ + MYFLT aftouch; + /** pitch bend (-1 to 1) */ + MYFLT pchbend; + /** pitch bend sensitivity in semitones */ + MYFLT pbensens; + /** number of held (sustaining) notes */ + int16 ksuscnt; + /** current state of sustain pedal (0: off) */ + int16 sustaining; + int dpmsb; + int dplsb; + int datenabl; + /** chain of dpgm keylists */ + DKLST *klists; + /** drumset params */ + DPARM *dparms; + } MCHNBLK; + + /** + * This struct holds the data for one score event. + */ + typedef struct event { + /** String argument(s) (NULL if none) */ + int scnt; + char *strarg; + /* instance pointer */ + void *pinstance; /* used in nstance opcode */ + /** Event type */ + char opcod; + /** Number of p-fields */ + int16 pcnt; + /** Event start time */ + MYFLT p2orig; + /** Length */ + MYFLT p3orig; + /** All p-fields for this event (SSTRCOD: string argument) */ + MYFLT p[PMAX + 1]; + union { /* To ensure size is same as earlier */ + MYFLT *extra; + MYFLT p[2]; + } c; + } EVTBLK; + /** + * This struct holds the info for a concrete instrument event + * instance in performance. + */ + typedef struct insds { + /* Chain of init-time opcodes */ + struct opds * nxti; + /* Chain of performance-time opcodes */ + struct opds * nxtp; + /* Chain of deinit opcodes */ + struct opds * nxtd; + /* Next allocated instance */ + struct insds * nxtinstance; + /* Previous allocated instance */ + struct insds * prvinstance; + /* Next in list of active instruments */ + struct insds * nxtact; + /* Previous in list of active instruments */ + struct insds * prvact; + /* Next instrument to terminate */ + struct insds * nxtoff; + /* Chain of files used by opcodes in this instr */ + FDCH *fdchp; + /* Extra memory used by opcodes in this instr */ + AUXCH *auxchp; + /* Extra release time requested with xtratim opcode */ + int xtratim; + /* MIDI note info block if event started from MIDI */ + MCHNBLK *m_chnbp; + /* ptr to next overlapping MIDI voice */ + struct insds * nxtolap; + /* Instrument number */ + int16 insno; + /* Instrument def address */ + INSTRTXT *instr; + /* non-zero for sustaining MIDI note */ + int16 m_sust; + /* MIDI pitch, for simple access */ + unsigned char m_pitch; + /* ...ditto velocity */ + unsigned char m_veloc; + /* Flag to indicate we are releasing, test with release opcode */ + char relesing; + /* Set if instr instance is active (perfing) */ + char actflg; + /* Time to turn off event, in score beats */ + double offbet; + /* Time to turn off event, in seconds (negative on indef/tie) */ + double offtim; + /* pointer to Csound engine and API for externals */ + CSOUND *csound; + uint64_t kcounter; + MYFLT esr, sicvt, pidsr; /* local sr */ + MYFLT onedsr; + int in_cvt, out_cvt; /* resampling converter modes for in and out */ + unsigned int ksmps; /* Instrument copy of ksmps */ + MYFLT ekr; /* and of rates */ + + MYFLT onedksmps, onedkr, kicvt; + struct opds *pds; /* Used for jumping */ + MYFLT scratchpad[4]; /* Persistent data */ + + /* user defined opcode I/O buffers */ + void *opcod_iobufs; + void *opcod_deact, *subins_deact; + uint32_t ksmps_offset; /* ksmps offset for sample accuracy */ + uint32_t no_end; /* samps left at the end for sample accuracy + (calculated) */ + uint32_t ksmps_no_end; /* samps left at the end for sample accuracy + (used by opcodes) */ + MYFLT *spin; /* offset into csound->spin */ + MYFLT *spout; /* offset into csound->spout, or local spout */ + int init_done; + int tieflag; + int reinitflag; + MYFLT retval; + MYFLT *lclbas; /* base for variable memory pool */ + char *strarg; /* string argument */ + /* Copy of required p-field values for quick access */ + CS_VAR_MEM p0; + CS_VAR_MEM p1; + CS_VAR_MEM p2; + CS_VAR_MEM p3; + } INSDS; + +#define CS_KSMPS (p->h.insdshead->ksmps) +#define CS_KCNT (p->h.insdshead->kcounter) +#define CS_EKR (p->h.insdshead->ekr) +#define CS_ONEDKSMPS (p->h.insdshead->onedksmps) +#define CS_ONEDKR (p->h.insdshead->onedkr) +#define CS_KICVT (p->h.insdshead->kicvt) +#define CS_ONEDDBFS (FL(1.0/csound->Get0dBFS(csound))) +#define CS_ESR (p->h.insdshead->esr) +#define CS_ONEDSR (p->h.insdshead->onedsr) +#define CS_SICVT (p->h.insdshead->sicvt) +#define CS_TPIDSR (2.*p->h.insdshead->pidsr) +#define CS_PIDSR (p->h.insdshead->pidsr) +#define CS_MPIDSR (-p->h.insdshead->pidsr) +#define CS_MTPIDSR (-2.*p->h.insdshead->pidsr) +#define CS_PDS (p->h.insdshead->pds) +#define CS_SPIN (p->h.insdshead->spin) +#define CS_SPOUT (p->h.insdshead->spout) + +/* Phase modulo-1 for oscillators */ +static inline double PHMOD1(double p) { + return p < 0 ? -(1. - FLOOR(p)) : p - (uint64_t) p; +} + + typedef int32_t (*SUBR)(CSOUND *, void *); + + /** + * This struct holds the info for one opcode in a concrete + * instrument instance in performance. + */ + typedef struct opds { + /** Next opcode in init-time chain */ + struct opds * nxti; + /** Next opcode in perf-time chain */ + struct opds * nxtp; + /** Next opcode in deinit chain */ + struct opds * nxtd; + /** Initialization (i-time) function pointer */ + SUBR init; + /** Perf-time (k- or a-rate) function pointer */ + SUBR perf; + /** deinit function pointer */ + SUBR deinit; + /** Orch file template part for this opcode */ + OPTXT *optext; + /** Owner instrument instance data structure */ + INSDS *insdshead; + } OPDS; + + typedef struct { + char *opname; + char *outypes; + char *intypes; + int flags; + } opcodeListEntry; + + + typedef struct lblblk { + OPDS h; + OPDS *prvi; + OPDS *prvp; + OPDS *prvd; + } LBLBLK; + + typedef struct { + MYFLT *begp, *curp, *endp, feedback[6]; + int32 scount; + } OCTDAT; + + typedef struct { + int32 npts, nocts, nsamps; + MYFLT lofrq, hifrq, looct, srate; + OCTDAT octdata[MAXOCTS]; + AUXCH auxch; + } DOWNDAT; + + typedef struct { + uint32_t ktimstamp, ktimprd; + int32 npts, nfreqs, dbout; + DOWNDAT *downsrcp; + AUXCH auxch; + } SPECDAT; + + typedef struct { + MYFLT gen01; + MYFLT ifilno; + MYFLT iskptim; + MYFLT iformat; + MYFLT channel; + MYFLT sample_rate; + char strarg[SSTRSIZ]; + } GEN01ARGS; + + typedef struct { + /** table length, not including the guard point */ + uint32_t flen; + /** length mask ( = flen - 1) for power of two table size, 0 otherwise */ + int32 lenmask; + /** log2(MAXLEN / flen) for power of two table size, 0 otherwise */ + int32 lobits; + /** 2^lobits - 1 */ + int32 lomask; + /** 1 / 2^lobits */ + MYFLT lodiv; + /** LOFACT * (table_sr / orch_sr), cpscvt = cvtbas / base_freq */ + MYFLT cvtbas, cpscvt; + /** sustain loop mode (0: none, 1: forward, 2: forward and backward) */ + int16 loopmode1; + /** release loop mode (0: none, 1: forward, 2: forward and backward) */ + int16 loopmode2; + /** sustain loop start and end in sample frames */ + int32 begin1, end1; + /** release loop start and end in sample frames */ + int32 begin2, end2; + /** sound file length in sample frames (flenfrms = soundend - 1) */ + int32 soundend, flenfrms; + /** number of channels */ + int32 nchanls; + /** table number */ + int32 fno; + /** sampling rate */ + MYFLT sr; + /** args */ + MYFLT args[PMAX - 4]; + /** arg count */ + int argcnt; + /** GEN01 parameters */ + GEN01ARGS gen01args; + /** table data (flen + 1 MYFLT values) */ + MYFLT *ftable; + } FUNC; + + typedef struct { + CSOUND *csound; + int32 flen; + int fno, guardreq; + EVTBLK e; + } FGDATA; + + typedef struct { + char *name; + int (*fn)(FGDATA *, FUNC *); + } NGFENS; + + typedef int (*GEN)(FGDATA *, FUNC *); + + typedef struct MEMFIL { + char filename[256]; /* Made larger RWD */ + char *beginp; + char *endp; + int32 length; + struct MEMFIL *next; + } MEMFIL; + + typedef struct { + int16 type; + int16 chan; + int16 dat1; + int16 dat2; + } MEVENT; + + typedef struct SNDMEMFILE_ { + /** file ID (short name) */ + char *name; + struct SNDMEMFILE_ *nxt; + /** full path filename */ + char *fullName; + /** file length in sample frames */ + size_t nFrames; + /** sample rate in Hz */ + double sampleRate; + /** number of channels */ + int nChannels; + /** AE_SHORT, AE_FLOAT, etc. */ + int sampleFormat; + /** TYP_WAV, TYP_AIFF, etc. */ + int fileType; + /** + * loop mode: + * 0: no loop information + * 1: off + * 2: forward + * 3: backward + * 4: bidirectional + */ + int loopMode; + /** playback start offset frames */ + double startOffs; + /** loop start (sample frames) */ + double loopStart; + /** loop end (sample frames) */ + double loopEnd; + /** base frequency (in Hz) */ + double baseFreq; + /** amplitude scale factor */ + double scaleFac; + /** interleaved sample data */ + MYFLT data[1]; + } SNDMEMFILE; + + typedef struct pvx_memfile_ { + char *filename; + struct pvx_memfile_ *nxt; + float *data; + uint32 nframes; + int format; + int fftsize; + int overlap; + int winsize; + int wintype; + int chans; + MYFLT srate; + } PVOCEX_MEMFILE; + +#ifdef __BUILDING_LIBCSOUND + +#define INSTR 1 +#define ENDIN 2 +#define OPCODE 3 +#define ENDOP 4 +#define LABEL 5 +#define SETBEG 6 +#define PSET 6 +#define USEROPCODE 7 +#define SETEND 8 + +#define TOKMAX 50L /* Should be 50 but bust */ + + /* max number of input/output args for user defined opcodes */ +#define OPCODENUMOUTS_LOW 16 +#define OPCODENUMOUTS_HIGH 64 +#define OPCODENUMOUTS_MAX 256 + +#define MBUFSIZ (4096) +#define MIDIINBUFMAX (1024) +#define MIDIINBUFMSK (MIDIINBUFMAX-1) + +#define MIDIMAXPORTS (64) + + typedef union { + uint32 dwData; + unsigned char bData[4]; + } MIDIMESSAGE; + + /* MIDI globals */ + + typedef struct midiglobals { + MEVENT *Midevtblk; + int sexp; + int MIDIoutDONE; + int MIDIINbufIndex; + MIDIMESSAGE MIDIINbuffer2[MIDIINBUFMAX]; + int (*MidiInOpenCallback)(CSOUND *, void **, const char *); + int (*MidiReadCallback)(CSOUND *, void *, unsigned char *, int); + int (*MidiInCloseCallback)(CSOUND *, void *); + int (*MidiOutOpenCallback)(CSOUND *, void **, const char *); + int (*MidiWriteCallback)(CSOUND *, void *, const unsigned char *, int); + int (*MidiOutCloseCallback)(CSOUND *, void *); + const char *(*MidiErrorStringCallback)(int); + void *midiInUserData; + void *midiOutUserData; + void *midiFileData; + void *midiOutFileData; + int rawControllerMode; + char muteTrackList[256]; + unsigned char mbuf[MBUFSIZ]; + unsigned char *bufp, *endatp; + int16 datreq, datcnt; + } MGLOBAL; + + typedef struct osc_mess { + char *address; + char *type; + char *data; + int32_t size; + int32_t flag; + struct osc_mess *nxt; + } OSC_MESS; + + typedef struct eventnode { + struct eventnode *nxt; + uint32 start_kcnt; + EVTBLK evt; + } EVTNODE; + + typedef struct { + OPDS h; + MYFLT *ktempo, *istartempo; + MYFLT prvtempo; + } TEMPO; + + /* typedef struct token { */ + /* char *str; */ + /* int16 prec; */ + /* } TOKEN; */ + + typedef struct names { + char *mac; + struct names *next; + } NAMES; + + typedef struct threadInfo { + struct threadInfo *next; + void * threadId; + } THREADINFO; + +#include "sort.h" +#include "text.h" +#include "prototyp.h" +#include "cwindow.h" +#include "envvar.h" +#include "remote.h" + +#define CS_STATE_PRE (1) +#define CS_STATE_COMP (2) +#define CS_STATE_UTIL (4) +#define CS_STATE_CLN (8) +#define CS_STATE_JMP (16) + + /* These are used to set/clear bits in csound->tempStatus. + If the bit is set, it indicates that the given file is + a temporary. */ + extern const uint32_t csOrcMask; + extern const uint32_t csScoInMask; + extern const uint32_t csScoSortMask; + extern const uint32_t csMidiScoMask; + extern const uint32_t csPlayScoMask; + + /* kperf function protoypes. Used by the debugger to switch between debug + * and nodebug kperf functions */ + int kperf_nodebug(CSOUND *csound); + int kperf_debug(CSOUND *csound); + + /* + check if code is running at init time. + result may not be valid in realtime mode + */ + int csoundIsInitThread(CSOUND *csound); + +#endif /* __BUILDING_LIBCSOUND */ + +#define MARGS (3) +#define MAX_INCLUDE_DEPTH 100 + struct MACRO; + + typedef struct MACRON { + int n; + unsigned int line; + struct MACRO *s; + char *path; + int included; + } MACRON; + + typedef struct MACRO { /* To store active macros */ + char *name; /* Use is by name */ + int acnt; /* Count of arguments */ + char *body; /* The text of the macro */ + struct MACRO *next; /* Chain of active macros */ + int margs; /* amount of space for args */ + char *arg[MARGS]; /* With these arguments */ + } MACRO; + + typedef struct in_stack_s { /* Stack of active inputs */ + int16 is_marked_repeat; /* 1 if this input created by 'n' stmnt */ + int16 args; /* Argument count for macro */ + //CORFIL *cf; /* In core file */ + //void *fd; /* for closing stream */ + MACRO *mac; + int line; + int32 oposit; + } IN_STACK; + + typedef struct marked_sections { + char *name; + int32 posit; + int line; + } MARKED_SECTIONS; + + typedef struct namelst { + char *name; + struct namelst *next; + } NAMELST; + + typedef struct NAME__ { + char *namep; + struct NAME__ *nxt; + int type, count; + } NAME; + + /* Holds UDO information, when an instrument is + defined as a UDO + */ + typedef struct opcodinfo { + int32 instno; + char *name, *intypes, *outtypes; + int16 inchns, outchns; + CS_VAR_POOL* out_arg_pool; + CS_VAR_POOL* in_arg_pool; + INSTRTXT *ip; + struct opcodinfo *prv; + } OPCODINFO; + + /** + * This struct will hold the current engine state after compilation + */ + typedef struct engine_state { + CS_VAR_POOL *varPool; /* global variable pool */ + CS_HASH_TABLE *constantsPool; + CS_HASH_TABLE *stringPool; + int maxopcno; + INSTRTXT **instrtxtp; /* instrument list */ + INSTRTXT instxtanchor; + CS_HASH_TABLE *instrumentNames; /* instrument names */ + int maxinsno; + } ENGINE_STATE; + + + /** + * Nen FFT interface + */ + typedef struct _FFT_SETUP{ + int N, M; + void *setup; + MYFLT *buffer; + int lib; + int d; + int p2; + } CSOUND_FFT_SETUP; + + + /** + * plugin module info + */ + typedef struct { + char module[12]; + char type[12]; + } MODULE_INFO; + + +#define MAX_ALLOC_QUEUE 1024 + + typedef struct _alloc_data_ { + int type; + int insno; + EVTBLK blk; + MCHNBLK *chn; + MEVENT mep; + INSDS *ip; + OPDS *ids; + } ALLOC_DATA; + +#define MAX_MESSAGE_STR 1024 + typedef struct _message_queue_t_ { + int attr; + char str[MAX_MESSAGE_STR]; + } message_string_queue_t; + + /* Binary positive power function */ + static inline double intpow1(double x, int32_t n) + { + double ans = 1.; + while (n!=0) { + if (n&1) ans = ans * x; + n >>= 1; + x = x*x; + } + return ans; + } + + /* Binary power function */ + static inline double intpow(MYFLT x, int32_t n) + { + if (n<0) { + n = -n; + x = 1./x; + } + return intpow1(x, n); + } + + static inline int32_t byte_order(void){ + const int32_t one = 1; + return (!*((char*) &one)); + } + + static inline int isstrcod(MYFLT xx){ + int sel = (byte_order()+1)&1; +#ifdef USE_DOUBLE + union { + double d; + int32_t i[2]; + } z; + z.d = xx; + return ((z.i[sel]&0x7ff00000)==0x7ff00000); +#else + union { + float f; + int32_t j; + } z; + z.f = xx; + return ((z.j&0x7f800000) == 0x7f800000); +#endif + } + + /** @name Opcode attributes */ + /**@{ */ + /** + * Returns true if argument is a string code + */ + static inline int32_t IsStringCode(MYFLT f){ + return isstrcod(f); + } + + /** + * Returns the number of input arguments for opcode 'p'. + */ + static inline int32_t GetInputArgCnt(OPDS *p){ + return (int32_t) p->optext->t.inArgCount; + } + + /** + * Returns the name of input argument 'n' (counting from 0) for opcode 'p'. + */ + static inline char *GetInputArgName(OPDS *p, uint32_t n){ + if ( n >= + (uint32_t) p->optext->t.inArgCount) + return (char*) NULL; + return (char*) p->optext->t.inlist->arg[n]; + } + + /** + * Returns the number of output arguments for opcode 'p'. + */ + static inline int32_t GetOutputArgCnt(OPDS *p){ + return (int32_t) p->optext->t.outArgCount; + } + + /** + * Returns the name of output argument 'n' (counting from 0) for opcode 'p'. + */ + static inline char *GetOutputArgName(OPDS *p, uint32_t n){ + if (n >= (uint32_t) p->optext->t.outArgCount) + return (char*) NULL; + return (char*) p->optext->t.outlist->arg[n]; + } + + /** + * Returns the CS_TYPE for an opcode argument argPtr + */ + static inline CS_TYPE* GetTypeForArg(void* argPtr) { + char* ptr = (char*) argPtr; + CS_TYPE* varType = *(CS_TYPE**)(ptr - CS_VAR_TYPE_OFFSET); + return varType; + } + + /** + * Returns MIDI channel number (0 to 15) for the instrument instance + * that called opcode 'p'. + * In the case of score notes, -1 is returned. + */ + static inline int32_t GetMidiChannelNumber(OPDS *p){ + MCHNBLK *chn = p->insdshead->m_chnbp; + return chn != NULL ? chn->channel : -1; + } + + /** + * Returns MIDI note number (in the range 0 to 127) for opcode 'p'. + * If the opcode was not called from a MIDI activated instrument + * instance, the return value is undefined. + */ + static inline int32_t GetMidiNoteNumber(OPDS *p){ + return (int32_t) p->insdshead->m_pitch; + } + + /** + * Returns MIDI velocity (in the range 0 to 127) for opcode 'p'. + * If the opcode was not called from a MIDI activated instrument + * instance, the return value is undefined. + */ + static inline int32_t GetMidiVelocity(OPDS *p){ + return (int32_t) p->insdshead->m_veloc; + } + + /** + * Returns a pointer to the MIDI channel structure for the instrument + * instance that called opcode 'p'. + * In the case of score notes, NULL is returned. + */ + static inline MCHNBLK *GetMidiChannel(OPDS *p){ + return p->insdshead->m_chnbp; + } + + + /** + * Returns non-zero if the current note (owning opcode 'p') is releasing. + */ + static inline int32_t GetReleaseFlag(void *p){ + return (int32_t) ((OPDS*) p)->insdshead->relesing; + } + + /** + * Returns the note-off time in seconds (measured from the beginning of + * performance) of the current instrument instance, from which opcode 'p' + * was called. The return value may be negative if the note has indefinite + * duration. + */ + static inline double GetOffTime(OPDS *p){ + return (double) p->insdshead->offtim; + } + + /** + * Returns the array of p-fields passed to the instrument instance + * that owns opcode 'p', starting from p0. Only p1, p2, and p3 are + * guaranteed to be available. p2 is measured in seconds from the + * beginning of the current section. + */ + static inline CS_VAR_MEM *GetPFields(void *p){ + return &(((OPDS*) p)->insdshead->p0); + } + + /** + * Returns the instrument number (p1) for opcode 'p'. + */ + static inline int32_t GetInstrumentNumber(OPDS *p){ + return (int32_t) p->insdshead->p1.value; + } + + /** + * Returns the local ksmps of instrument/UDO containing opcode p. + * This is an alternative to the macro CS_KSMPS. + */ + static inline uint32_t GetLocalKsmps(OPDS *p){ + return (uint32_t) p->insdshead->ksmps; + } + + /** + * Returns the local sr of instrument/UDO containing opcode p. + * This is an alternative to the macro CS_ESR. + */ + static inline MYFLT GetLocalSr(OPDS *p){ + // FIXME: this needs to be adjusted once local sr is + // implemented + return p->insdshead->esr; + } + + + /** + * Returns the local kr of instrument/UDO containing opcode p. + * This is an alternative to the macro CS_EKR. + */ + static inline MYFLT GetLocalKr(OPDS *p){ + return p->insdshead->ekr; + } + + /** + * Returns the local kcount of instrument/UDO containing opcode p. + * This is an alternative to the macro CS_KCOUNTER. + */ + static inline uint64_t GetLocalKcounter(OPDS *p){ + return p->insdshead->kcounter; + } + + /** + * Returns the opcode name for p. + */ + static inline char *GetOpcodeName(OPDS *p){ + return p->optext->t.oentry->opname; + } + /**@}*/ + + static inline char le_test(){ + union _le { + char c[2]; + short s; + } le = {{0x0001}}; + return le.c[0]; + } + + static inline char *byteswap(char *p, int32_t N){ + if (le_test()) { + char tmp; + int32_t j ; + for(j = 0; j < N/2; j++) { + tmp = p[j]; + p[j] = p[N - j - 1]; + p[N - j - 1] = tmp; + } + } + return p; + } + + + +#include "find_opcode.h" + + /** + * Contains all function pointers, data, and data pointers required + * to run one instance of Csound. + * + * \b PUBLIC functions in CSOUND_ + * These are used by plugins to access the + * Csound library functionality without the requirement + * of compile-time linkage to the csound library + * New functions only need to be added here if + * they are required by plugins. + */ + struct CSOUND_ { + + /** @name Attributes */ + /**@{ */ + /** Get number of output channels */ + uint32_t (*GetNchnls)(CSOUND *); + /** Get number of input channels */ + uint32_t (*GetNchnls_i)(CSOUND *); + /** Get max peak amp */ + MYFLT (*Get0dBFS) (CSOUND *); + /** Get reference tuning */ + MYFLT (*GetA4)(CSOUND *); + /** Get current tie flag */ + int (*GetTieFlag)(CSOUND *); + /** Get current reinit flag */ + int (*GetReinitFlag)(CSOUND *); + /** Get current compiled instrument list */ + INSTRTXT **(*GetInstrumentList)(CSOUND *); + + void *(*GetHostData)(CSOUND *); + int64_t (*GetCurrentTimeSamples)(CSOUND *); + long (*GetInputBufferSize)(CSOUND *); + long (*GetOutputBufferSize)(CSOUND *); + int (*GetDebug)(CSOUND *); + int (*GetSizeOfMYFLT)(void); + void (*GetOParms)(CSOUND *, OPARMS *parms); + const char *(*GetEnv)(CSOUND *, const char *name); + MYFLT (*GetSystemSr)(CSOUND *, MYFLT ); + /**@}*/ + + /** @name Software bus */ + /**@{ */ + int (*GetChannelPtr)(CSOUND *, void **ptr, const char *name, int mode); + int (*ListChannels)(CSOUND *, controlChannelInfo_t **list); + /**@}*/ + + /** @name Events and Score */ + /**@{ */ + int (*CheckEvents)(CSOUND *); + int (*InsertScoreEvent)(CSOUND *, EVTBLK *, double); + MYFLT (*GetScoreOffsetSeconds)(CSOUND *); + void (*SetScoreOffsetSeconds)(CSOUND *, MYFLT); + void (*RewindScore)(CSOUND *); + void (*InputMessage)(CSOUND *, const char *message__); + int32_t (*ReadScore)(CSOUND *, const char*); + /**@}*/ + + /** @name Message printout */ + /**@{ */ + CS_PRINTF2 void (*Message)(CSOUND *, const char *fmt, ...); + CS_PRINTF3 void (*MessageS)(CSOUND *, int attr, const char *fmt, ...); + void (*MessageV)(CSOUND *, int attr, const char *format, va_list args); + int (*GetMessageLevel)(CSOUND *); + void (*SetMessageLevel)(CSOUND *, int messageLevel); + void (*SetMessageCallback)(CSOUND *, + void (*csoundMessageCallback) + (CSOUND *,int attr, const char *format, + va_list valist)); + /**@}*/ + + /** @name Arguments and Types */ + /**@{ */ + char *(*GetString)(CSOUND *, MYFLT); + int32 (*StringArg2Insno)(CSOUND *, void *p, int is_string); + char *(*StringArg2Name)(CSOUND *, char *, void *, const char *, int); + const CS_TYPE *(*GetType)(CSOUND *csound, const char *type); + + /**@}*/ + + /** @name Memory allocation */ + /**@{ */ + void (*AuxAlloc)(CSOUND *, size_t nbytes, AUXCH *auxchp); + int (*AuxAllocAsync)(CSOUND *, size_t, AUXCH *, + AUXASYNC *, aux_cb, void *); + void *(*Malloc)(CSOUND *, size_t nbytes); + void *(*Calloc)(CSOUND *, size_t nbytes); + void *(*ReAlloc)(CSOUND *, void *oldp, size_t nbytes); + char *(*Strdup)(CSOUND *, const char*); + void (*Free)(CSOUND *, void *ptr); + /**@}*/ + + /** @name Function tables */ + /**@{ */ + int (*FTCreate)(CSOUND *, FUNC **, const EVTBLK *, int); + int (*FTAlloc)(CSOUND *, int tableNum, int len); + int (*FTDelete)(CSOUND *, int tableNum); + FUNC *(*FTFind)(CSOUND *, MYFLT *argp); + void *(*GetNamedGens)(CSOUND *); + /**@}*/ + + /** @name Global and config variable manipulation */ + /**@{ */ + int (*CreateGlobalVariable)(CSOUND *, const char *name, size_t nbytes); + void *(*QueryGlobalVariable)(CSOUND *, const char *name); + void *(*QueryGlobalVariableNoCheck)(CSOUND *, const char *name); + int (*DestroyGlobalVariable)(CSOUND *, const char *name); + int (*CreateConfigurationVariable)(CSOUND *, const char *name, + void *p, int type, int flags, + void *min, void *max, + const char *shortDesc, + const char *longDesc); + int (*SetConfigurationVariable)(CSOUND *, const char *name, void *value); + int (*ParseConfigurationVariable)(CSOUND *, + const char *name, const char *value); + csCfgVariable_t *(*QueryConfigurationVariable)(CSOUND *, const char *name); + csCfgVariable_t **(*ListConfigurationVariables)(CSOUND *); + int (*DeleteConfigurationVariable)(CSOUND *, const char *name); + const char *(*CfgErrorCodeToString)(int errcode); + /**@}*/ + + /** @name FFT support */ + /**@{ */ + void *(*RealFFTSetup)(CSOUND *csound, int FFTsize, int d); + void (*RealFFT)(CSOUND *csound, + void *p, MYFLT *sig); + MYFLT (*GetInverseRealFFTScale)(CSOUND *, int FFTsize); + void (*ComplexFFT)(CSOUND *, MYFLT *buf, int FFTsize); + void (*InverseComplexFFT)(CSOUND *, MYFLT *buf, int FFTsize); + MYFLT (*GetInverseComplexFFTScale)(CSOUND *, int FFTsize); + void (*RealFFTMult)(CSOUND *, MYFLT *outbuf, MYFLT *buf1, MYFLT *buf2, + int FFTsize, MYFLT scaleFac); + void *(*DCTSetup)(CSOUND *csound,int FFTsize, int d); + void (*DCT)(CSOUND *csound, void *p, MYFLT *sig); + /**@}*/ + + /** @name LPC support */ + /**@{ */ + MYFLT* (*AutoCorrelation)(CSOUND *, MYFLT*, MYFLT*, int, MYFLT*, int); + void * (*LPsetup)(CSOUND *csound, int N, int M); + void (*LPfree)(CSOUND *csound, void *); + MYFLT* (*LPred)(CSOUND *, void *, MYFLT *); + MYFLT* (*LPCeps)(CSOUND *, MYFLT *, MYFLT *, int, int); + MYFLT* (*CepsLP)(CSOUND *, MYFLT *, MYFLT *, int, int); + MYFLT (*LPrms)(CSOUND *, void *); + /**@}*/ + + /** @name PVOC-EX system */ + /**@{ */ + int (*PVOC_CreateFile)(CSOUND *, const char *, + uint32, uint32, uint32, + uint32, int32, int, int, + float, float *, uint32); + int (*PVOC_OpenFile)(CSOUND *, const char *, void *, void *); + int (*PVOC_CloseFile)(CSOUND *, int); + int (*PVOC_PutFrames)(CSOUND *, int, const float *, int32); + int (*PVOC_GetFrames)(CSOUND *, int, float *, uint32); + int (*PVOC_FrameCount)(CSOUND *, int); + int (*PVOC_fseek)(CSOUND *, int, int); + const char *(*PVOC_ErrorString)(CSOUND *); + int (*PVOCEX_LoadFile)(CSOUND *, const char *, PVOCEX_MEMFILE *); + /**@}*/ + + /** @name Error messages */ + /**@{ */ + CS_NORETURN CS_PRINTF2 void (*Die)(CSOUND *, const char *msg, ...); + CS_PRINTF2 int (*InitError)(CSOUND *, const char *msg, ...); + CS_PRINTF3 int (*PerfError)(CSOUND *, OPDS *h, const char *msg, ...); + CS_PRINTF2 int (*FtError)(const FGDATA *, const char *, ...); + CS_PRINTF2 void (*Warning)(CSOUND *, const char *msg, ...); + CS_PRINTF2 void (*DebugMsg)(CSOUND *, const char *msg, ...); + CS_NORETURN void (*LongJmp)(CSOUND *, int); + CS_PRINTF2 void (*ErrorMsg)(CSOUND *, const char *fmt, ...); + void (*ErrMsgV)(CSOUND *, const char *hdr, const char *fmt, va_list); + /**@}*/ + + /** @name Random numbers */ + /**@{ */ + uint32_t (*GetRandomSeedFromTime)(void); + void (*SeedRandMT)(CsoundRandMTState *p, + const uint32_t *initKey, uint32_t keyLength); + uint32_t (*RandMT)(CsoundRandMTState *p); + int (*Rand31)(int *seedVal); + int32_t *(*RandSeed1)(CSOUND *); + int (*GetRandSeed)(CSOUND *, int which); + /**@}*/ + + /** @name Threads and locks */ + /**@{ */ + void *(*CreateThread)(uintptr_t (*threadRoutine)(void *), void *userdata); + uintptr_t (*JoinThread)(void *thread); + void *(*CreateThreadLock)(void); + void (*DestroyThreadLock)(void *lock); + int (*WaitThreadLock)(void *lock, size_t milliseconds); + void (*NotifyThreadLock)(void *lock); + void (*WaitThreadLockNoTimeout)(void *lock); + void *(*Create_Mutex)(int isRecursive); + int (*LockMutexNoWait)(void *mutex_); + void (*LockMutex)(void *mutex_); + void (*UnlockMutex)(void *mutex_); + void (*DestroyMutex)(void *mutex_); + void *(*CreateBarrier)(unsigned int max); + int (*DestroyBarrier)(void *); + int (*WaitBarrier)(void *); + void *(*GetCurrentThreadID)(void); + void (*Sleep)(size_t milliseconds); + void (*InitTimerStruct)(RTCLOCK *); + double (*GetRealTime)(RTCLOCK *); + double (*GetCPUTime)(RTCLOCK *); + /**@}*/ + + /** @name Circular lock-free buffer */ + /**@{ */ + void *(*CreateCircularBuffer)(CSOUND *, int, int); + int (*ReadCircularBuffer)(CSOUND *, void *, void *, int); + int (*WriteCircularBuffer)(CSOUND *, void *, const void *, int); + int (*PeekCircularBuffer)(CSOUND *, void *, void *, int); + void (*FlushCircularBuffer)(CSOUND *, void *); + void (*DestroyCircularBuffer)(CSOUND *, void *); + /**@}*/ + + /** @name File access */ + /**@{ */ + char *(*FindInputFile)(CSOUND *, const char *filename, const char *envList); + char *(*FindOutputFile)(CSOUND *, + const char *filename, const char *envList); + void *(*SndInputFileOpen)(CSOUND *, + char *, void *, MYFLT *, MYFLT *, MYFLT *, int); + void *(*SndInputOpen)(CSOUND *, void *); + int (*SndInputRead)(CSOUND *, void *, MYFLT *, int, void *); + void *(*FileOpen)(CSOUND *, void *, int, const char *, void *, + const char *, int, int); /* Rename FileOpen */ + void (*NotifyFileOpened)(CSOUND*, const char*, int, int, int); + int (*FileClose)(CSOUND *, void *); + int32_t (*SndfileWrite)(CSOUND *, void *, MYFLT *, int32_t); + int32_t (*SndfileRead)(CSOUND *, void *, MYFLT *, int32_t); + int32_t (*SndfileSeek)(CSOUND *, void *, int32_t, int32_t); + int32_t (*FileCommand)(CSOUND *, void *, int , void *, int ); + const char *(*FileError)(CSOUND *, void *); + void *(*FileOpenAsync)(CSOUND *, void *, int, const char *, void *, + const char *, int, int, int); + unsigned int (*ReadAsync)(CSOUND *, void *, MYFLT *, int); + unsigned int (*WriteAsync)(CSOUND *, void *, MYFLT *, int); + int (*FSeekAsync)(CSOUND *, void *, int, int); + void (*RewriteHeader)(void *ofd); + SNDMEMFILE *(*LoadSoundFile)(CSOUND *, const char *, void *); + MEMFIL *(*LoadMemoryFile)(CSOUND *, const char *, int, + int (*callback)(CSOUND *, MEMFIL *)); + void (*FDRecord)(CSOUND *, FDCH *fdchp); + void (*FDClose)(CSOUND *, FDCH *fdchp); + void *(*CreateFileHandle)(CSOUND *, void *, int, const char *); + char *(*GetFileName)(void *); + int (*Type2CsfileType)(int type, int encoding); + int (*SndfileType2CsfileType)(int type); + char *(*Type2String)(int type); + char *(*GetStrFormat)(int format); + int (*SndfileSampleSize)(int format); + /**@}*/ + + /** @name Generic callbacks */ + /**@{ */ + int (*Set_KeyCallback)(CSOUND *, int (*func)(void *, void *, unsigned int), + void *userData, unsigned int typeMask); + void (*Remove_KeyCallback)(CSOUND *, + int (*func)(void *, void *, unsigned int)); + int (*RegisterResetCallback)(CSOUND *, void *userData, + int (*func)(CSOUND *, void *)); + /**@}*/ + + /** @name Hash tables */ + /**@{ */ + CS_HASH_TABLE *(*CreateHashTable)(CSOUND *); + void *(*GetHashTableValue)(CSOUND *, CS_HASH_TABLE *, char *); + void (*SetHashTableValue)(CSOUND *, CS_HASH_TABLE *, char *, void *); + void (*RemoveHashTableKey)(CSOUND *, CS_HASH_TABLE *, char *); + void (*DestroyHashTable)(CSOUND *, CS_HASH_TABLE *); + char *(*GetHashTableKey)(CSOUND *, CS_HASH_TABLE *, char *); + CONS_CELL *(*GetHashTableKeys)(CSOUND *, CS_HASH_TABLE *); + CONS_CELL *(*GetHashTableValues)(CSOUND *, CS_HASH_TABLE *); + /**@}*/ + + /** @name Plugin opcodes and discovery support */ + /**@{ */ + int (*AppendOpcode)(CSOUND *, const char *opname, int dsblksiz, int flags, + const char *outypes, const char *intypes, + int (*init)(CSOUND *, void *), + int (*perf)(CSOUND *, void *), + int (*deinit)(CSOUND *, void *)); + int (*AppendOpcodes)(CSOUND *, const OENTRY *opcodeList, int n); + OENTRY* (*FindOpcode)(CSOUND*, char*, char* , char*); + /**@}*/ + + /** @name RT audio IO module support */ + /**@{ */ + void (*SetPlayopenCallback)(CSOUND *, + int (*playopen__)(CSOUND *, const csRtAudioParams *parm)); + void (*SetRtplayCallback)(CSOUND *, + void (*rtplay__)(CSOUND *, const MYFLT *outBuf, int nbytes)); + void (*SetRecopenCallback)(CSOUND *, + int (*recopen__)(CSOUND *, const csRtAudioParams *parm)); + void (*SetRtrecordCallback)(CSOUND *, + int (*rtrecord__)(CSOUND *, MYFLT *inBuf, int nbytes)); + void (*SetRtcloseCallback)(CSOUND *, void (*rtclose__)(CSOUND *)); + void (*SetAudioDeviceListCallback)(CSOUND *csound, + int (*audiodevlist__)(CSOUND *, CS_AUDIODEVICE *list, int isOutput)); + void **(*GetRtRecordUserData)(CSOUND *); + void **(*GetRtPlayUserData)(CSOUND *); + int (*GetDitherMode)(CSOUND *); + /**@}*/ + + /** @name RT MIDI module support */ + /**@{ */ + void (*SetExternalMidiInOpenCallback)(CSOUND *, + int (*func)(CSOUND *, void **, const char *)); + void (*SetExternalMidiReadCallback)(CSOUND *, + int (*func)(CSOUND *, void *, unsigned char *, int)); + void (*SetExternalMidiInCloseCallback)(CSOUND *, + int (*func)(CSOUND *, void *)); + void (*SetExternalMidiOutOpenCallback)(CSOUND *, + int (*func)(CSOUND *, void **, const char *)); + void (*SetExternalMidiWriteCallback)(CSOUND *, + int (*func)(CSOUND *, void *, const unsigned char *, int)); + void (*SetExternalMidiOutCloseCallback)(CSOUND *, + int (*func)(CSOUND *, void *)); + void (*SetExternalMidiErrorStringCallback)(CSOUND *, + const char *(*func)(int)); + void (*SetMIDIDeviceListCallback)(CSOUND *csound, + int (*audiodevlist__)(CSOUND *, CS_MIDIDEVICE *list, int isOutput)); + void (*module_list_add)(CSOUND *, char *, char *); + /**@}*/ + + /** @name Utility module support */ + /**@{ */ + int (*AddUtility)(CSOUND *, const char *name, + int (*UtilFunc)(CSOUND *, int, char **)); + int (*RunUtility)(CSOUND *, const char *name, int argc, char **argv); + char **(*ListUtilities)(CSOUND *); + int (*SetUtilityDescription)(CSOUND *, const char *utilName, + const char *utilDesc); + const char *(*GetUtilityDescription)(CSOUND *, const char *utilName); + void (*SetUtilSr)(CSOUND *, MYFLT); + void (*SetUtilNchnls)(CSOUND *, int); + /**@}*/ + + /** @name Displays & graphs support */ + /**@{ */ + void (*SetDisplay)(CSOUND *, WINDAT *, MYFLT *, int32, char *, int, char *); + void (*Display)(CSOUND *, WINDAT *); + int (*DeinitDisplay)(CSOUND *); + void (*InitDisplay)(CSOUND *); + int (*SetIsGraphable)(CSOUND *, int isGraphable); + void (*SetMakeGraphCallback)(CSOUND *, + void (*makeGraphCallback)(CSOUND *, WINDAT *p, + const char *name)); + void (*SetDrawGraphCallback)(CSOUND *, + void (*drawGraphCallback)(CSOUND *, WINDAT *p)); + void (*SetKillGraphCallback)(CSOUND *, + void (*killGraphCallback)(CSOUND *, WINDAT *p)); + void (*SetExitGraphCallback)(CSOUND *, int (*exitGraphCallback)(CSOUND *)); + /**@}*/ + + /** @name Miscellaneous */ + /**@{ */ + /* Fast power of two function from a precomputed table */ + MYFLT (*Pow2)(CSOUND *, MYFLT a); +#if defined (__CUDACC__) || defined (__MACH__) + char *(*LocalizeString)(const char *); +#else + char *(*LocalizeString)(const char *) __attribute__ ((format_arg (1))); +#endif + double (*Strtod)(char* nptr, char**); + int (*Sprintf)(char *str, const char *format, ...); + int (*Sscanf)(char *str, const char *format, ...); + /**@}*/ + + + /** @name Placeholders + To allow the API to grow while maintining backward binary compatibility. */ + /**@{ */ + SUBR dummyfn_2[13]; + /**@}*/ +#ifdef __BUILDING_LIBCSOUND + /* ------- private data (not to be used by hosts or externals) ------- */ + /** @name Private Data + Private Data in the CSOUND struct to be used internally by the Csound + library and should be hidden from plugins. + If a new variable member is needed by the library, add it below, as a + private data member. If access is required solely by plugins (and not + internally by the library), use the CreateGlobalVariable() etc. interface, + instead of adding to CSOUND. + + If you find that a plugin needs to access existing private data, + first check above for an existing interface; if none is available, + add one. Please avoid giving full access, or allowing plugins to + change the values of private members, by using one of the two methods + below: + + 1) To get the data member value: + \code + returnType (*GetVar)(CSOUND *) + \endcode + 2) in case of pointers, data should be copied out to a supplied memory + slot, rather than the pointer being obtained: + \code + void (*GetData)(CSOUND *, dataType *) + + dataType var; + csound->GetData(csound, &var); + \endcode + */ + /**@{ */ + SUBR first_callback_; + channelCallback_t InputChannelCallback_; + channelCallback_t OutputChannelCallback_; + void (*csoundMessageCallback_)(CSOUND *, int attr, + const char *format, va_list args); + int (*csoundConfigureCallback_)(CSOUND *); + void (*csoundMakeGraphCallback_)(CSOUND *, WINDAT *windat, + const char *name); + void (*csoundDrawGraphCallback_)(CSOUND *, WINDAT *windat); + void (*csoundKillGraphCallback_)(CSOUND *, WINDAT *windat); + int (*csoundExitGraphCallback_)(CSOUND *); + int (*csoundYieldCallback_)(CSOUND *); + void (*cscoreCallback_)(CSOUND *); + void* (*OpenSoundFileCallback_)(CSOUND*, const char*, int, void*); + FILE* (*OpenFileCallback_)(CSOUND*, const char*, const char*); + void (*FileOpenCallback_)(CSOUND*, const char*, int, int, int); + SUBR last_callback_; + /* these are not saved on RESET */ + int (*playopen_callback)(CSOUND *, const csRtAudioParams *parm); + void (*rtplay_callback)(CSOUND *, const MYFLT *outBuf, int nbytes); + int (*recopen_callback)(CSOUND *, const csRtAudioParams *parm); + int (*rtrecord_callback)(CSOUND *, MYFLT *inBuf, int nbytes); + void (*rtclose_callback)(CSOUND *); + int (*audio_dev_list_callback)(CSOUND *, CS_AUDIODEVICE *, int); + int (*midi_dev_list_callback)(CSOUND *, CS_MIDIDEVICE *, int); + int (*doCsoundCallback)(CSOUND *, void *, unsigned int); + int (*csoundInternalYieldCallback_)(CSOUND *); + /* end of callbacks */ + void (*spinrecv)(CSOUND *); + void (*spoutran)(CSOUND *); + int (*audrecv)(CSOUND *, MYFLT *, int); + void (*audtran)(CSOUND *, const MYFLT *, int); + void *hostdata; + char *orchname, *scorename; + CORFIL *orchstr, *scorestr; + OPDS *ids; /* used by init loops */ + ENGINE_STATE engineState; /* current Engine State merged after + compilation */ + INSTRTXT *instr0; /* instr0 */ + INSTRTXT **dead_instr_pool; + int dead_instr_no; + TYPE_POOL* typePool; + unsigned int ksmps; + uint32_t nchnls; + int inchnls; + uint64_t kcounter, global_kcounter; + MYFLT esr; + MYFLT ekr; + /** current time in seconds, inc. per kprd */ + int64_t icurTime; /* Current time in samples */ + double curTime_inc; + /** start time of current section */ + double timeOffs, beatOffs; + /** current time in beats, inc per kprd */ + double curBeat, curBeat_inc; + /** beat time = 60 / tempo */ + int64_t ibeatTime; /* Beat time in samples */ + EVTBLK *currevent; + INSDS *curip; + MYFLT cpu_power_busy; + char *xfilename; + int peakchunks; + int keep_tmp; + CS_HASH_TABLE *opcodes; + int32 nrecs; + FILE* Linepipe; + int Linefd; + void *csoundCallbacks_; + FILE* scfp; + CORFIL *scstr; + FILE* oscfp; + MYFLT maxamp[MAXCHNLS]; + MYFLT smaxamp[MAXCHNLS]; + MYFLT omaxamp[MAXCHNLS]; + uint32 maxpos[MAXCHNLS], smaxpos[MAXCHNLS], omaxpos[MAXCHNLS]; + FILE* scorein; + FILE* scoreout; + int *argoffspace; + INSDS *frstoff; + int randSeed1; + int randSeed2; + CsoundRandMTState *csRandState; + RTCLOCK *csRtClock; + int strsmax; + char **strsets; + MYFLT *spin; + MYFLT *spout; + MYFLT *spout_tmp; + int nspin; + int nspout; + MYFLT *auxspin; + OPARMS *oparms; + /** reserve space for up to MIDIMAXPORTS MIDI devices */ + MCHNBLK *m_chnbp[MIDIMAXPORTS*16]; + int dither_output; + MYFLT onedsr, sicvt; + MYFLT tpidsr, pidsr, mpidsr, mtpdsr; + MYFLT onedksmps; + MYFLT onedkr; + MYFLT kicvt; + int reinitflag; + int tieflag; + MYFLT e0dbfs, dbfs_to_float; + double A4; + void *rtRecord_userdata; + void *rtPlay_userdata; + jmp_buf exitjmp; + SRTBLK *frstbp; + int sectcnt; + int inerrcnt, synterrcnt, perferrcnt; + INSDS actanchor; + int32 rngcnt[MAXCHNLS]; + int16 rngflg, multichan; + void *evtFuncChain; + EVTNODE *OrcTrigEvts; /* List of events to be started */ + EVTNODE *freeEvtNodes; + int csoundIsScorePending_; + int64_t advanceCnt; + int initonly; + int evt_poll_cnt; + int evt_poll_maxcnt; + int Mforcdecs, Mxtroffs, MTrkend; + OPCODINFO *opcodeInfo; + FUNC** flist; + int maxfnum; + GEN *gensub; + int genmax; + CS_HASH_TABLE *namedGlobals; + CS_HASH_TABLE *cfgVariableDB; + double prvbt, curbt, nxtbt; + double curp2, nxtim; + int64_t cyclesRemaining; + EVTBLK evt; + void *memalloc_db; + MGLOBAL *midiGlobals; + CS_HASH_TABLE *envVarDB; + MEMFIL *memfiles; + PVOCEX_MEMFILE *pvx_memfiles; + int FFT_max_size; + void *FFT_table_1; + void *FFT_table_2; + /* statics from twarp.c should be TSEG* */ + void *tseg, *tpsave; + /* persistent macros */ + MACRO *orc_macros; + /* Statics from express.c */ + MYFLT *gbloffbas; /* was static in oload.c */ + void *file_io_thread; + int file_io_start; + void *file_io_threadlock; + int realtime_audio_flag; + void *event_insert_thread; + int event_insert_loop; + void *init_pass_threadlock; + void *API_lock; + spin_lock_t spoutlock, spinlock; + spin_lock_t memlock, spinlock1; + char *delayederrormessages; + void *printerrormessagesflag; + struct sread__ { + SRTBLK *bp, *prvibp; /* current srtblk, prev w/same int(p1) */ + char *sp, *nxp; /* string pntrs into srtblk text */ + int op; /* opcode of current event */ + int warpin; /* input format sensor */ + int linpos; /* line position sensor */ + int lincnt; /* count of lines/section in scorefile */ + MYFLT prvp2 /* = -FL(1.0) */; /* Last event time */ + MYFLT clock_base /* = FL(0.0) */; + MYFLT warp_factor /* = FL(1.0) */; + char *curmem; + char *memend; /* end of cur memblk */ + MACRO *unused_ptr2; + int last_name /* = -1 */; + IN_STACK *inputs, *str; + int input_size, input_cnt; + int unused_int3; + int unused_int2; + int linepos /* = -1 */; + MARKED_SECTIONS names[30]; +#define NAMELEN 40 /* array size of repeat macro names */ +#define RPTDEPTH 40 /* size of repeat_n arrays (39 loop levels) */ + char unused_char0[RPTDEPTH][NAMELEN]; + int unused_int4[RPTDEPTH]; + int32 unused_int7[RPTDEPTH]; + int unused_int5; + MACRO *unused_ptr0[RPTDEPTH]; + int unused_int6; + /* Variable for repeat sections */ + char unused_char1[NAMELEN]; + int unused_int8; + int32 unused_int9; + int unused_intA; + MACRO *unused_ptr1; + int nocarry; + } sread; + struct onefileStatics__ { + NAMELST *toremove; + char *orcname; + char *sconame; + char *midname; + int midiSet; + int csdlinecount; + } onefileStatics; +#define LBUFSIZ 32768 + struct lineventStatics__ { + char *Linep, *Linebufend; + int stdmode; + EVTBLK prve; + char *Linebuf; + int linebufsiz; + char *orchestra, *orchestrab; + int oflag; + } lineventStatics; + struct musmonStatics__ { + int32 srngcnt[MAXCHNLS], orngcnt[MAXCHNLS]; + int16 srngflg; + int16 sectno; + int lplayed; + int segamps, sormsg; + EVENT **ep, **epend; /* pointers for stepping through lplay list */ + EVENT *lsect; + } musmonStatics; + struct libsndStatics__ { + void *outfile; + void *infile; + char *sfoutname; /* soundout filename */ + MYFLT *inbuf; + MYFLT *outbuf; /* contin sndio buffers */ + MYFLT *outbufp; /* MYFLT pntr */ + uint32 inbufrem; + uint32 outbufrem; /* in monosamps */ + /* (see openin, iotranset) */ + unsigned int inbufsiz, outbufsiz; /* alloc in sfopenin/out */ + int isfopen; /* (real set in sfopenin) */ + int osfopen; /* (real set in sfopenout) */ + int pipdevin, pipdevout; /* 0: file, 1: pipe, 2: rtaudio */ + uint32 nframes /* = 1UL */; + FILE *pin, *pout; + int dither; + } libsndStatics; + + int warped; /* rdscor.c */ + int sstrlen; + char *sstrbuf; + int enableMsgAttr; /* csound.c */ + int sampsNeeded; + MYFLT csoundScoreOffsetSeconds_; + int inChar_; + int isGraphable_; + int delayr_stack_depth; /* ugens6.c */ + void *first_delayr; + void *last_delayr; + int32 revlpsiz[6]; + int32 revlpsum; + double rndfrac; /* aops.c */ + MYFLT *logbase2; + NAMES *omacros, *smacros; + void *namedgen; /* fgens.c */ + void *open_files; /* fileopen.c */ + void *searchPathCache; + CS_HASH_TABLE *sndmemfiles; + void *reset_list; + void *pvFileTable; /* pvfileio.c */ + int pvNumFiles; + int pvErrorCode; + /* database for deferred loading of opcode plugin libraries */ + // void *pluginOpcodeFiles; + int enableHostImplementedAudioIO; + int enableHostImplementedMIDIIO; + int hostRequestedBufferSize; + /* engineStatus is sum of: + * 1 (CS_STATE_PRE): csoundPreCompile was called + * 2 (CS_STATE_COMP): csoundCompile was called + * 4 (CS_STATE_UTIL): csoundRunUtility was called + * 8 (CS_STATE_CLN): csoundCleanup needs to be called + * 16 (CS_STATE_JMP): csoundLongJmp was called + */ + char engineStatus; + /* stdXX_assign_flags can be {1,2,4,8} */ + char stdin_assign_flg; + char stdout_assign_flg; + char orcname_mode; /* 0: normal, 1: ignore, 2: fail */ + int use_only_orchfile; + void *csmodule_db; + char *dl_opcodes_oplibs; + char *SF_csd_licence; + char *SF_id_title; + char *SF_id_copyright; + int SF_id_scopyright; + char *SF_id_software; + char *SF_id_artist; + char *SF_id_comment; + char *SF_id_date; + void *utility_db; + int16 *isintab; /* ugens3.c */ + void *lprdaddr; /* ugens5.c */ + int currentLPCSlot; + int max_lpc_slot; + CS_HASH_TABLE *chn_db; + int opcodedirWasOK; + int disable_csd_options; + CsoundRandMTState randState_; + int performState; + int ugens4_rand_16; + int ugens4_rand_15; + void *schedule_kicked; + MYFLT *disprep_fftcoefs; + void *winEPS_globals; + OPARMS oparms_; + REMOT_BUF SVrecvbuf; /* RM: rt_evt input Communications buffer */ + void *remoteGlobals; + /* VL: pvs bus */ + int nchanif, nchanof; + char *chanif, *chanof; + /* VL: internal yield callback */ + int multiThreadedComplete; + THREADINFO *multiThreadedThreadInfo; + struct dag_t *multiThreadedDag; + void *barrier1; + void *barrier2; + /* Statics from cs_par_dispatch; */ + /* ********These are no longer used******** */ + void *pointer1; //struct global_var_lock_t *global_var_lock_root; + void *pointer2; //struct global_var_lock_t **global_var_lock_cache; + int int1; //global_var_lock_count; + /* statics from cs_par_orc_semantic_analysis */ + struct instr_semantics_t *instCurr; + struct instr_semantics_t *instRoot; + int inInstr; + int dag_changed; + int dag_num_active; + INSDS **dag_task_map; + volatile stateWithPadding *dag_task_status; + watchList * volatile *dag_task_watch; + watchList *dag_wlmm; + char **dag_task_dep; + int dag_task_max_size; + uint32_t tempStatus; /* keeps track of which files are temps */ + int orcLineOffset; /* 1 less than 1st orch line in the CSD */ + int scoLineOffset; /* 1 less than 1st score line in the CSD */ + char* csdname; + /* original CSD name; do not free() */ + int parserNamedInstrFlag; + int tran_nchnlsi; + int scnt; /* Count of strings */ + int strsiz; /* length of current strings space */ + FUNC *sinetable; /* A useful table */ + int sinelength; /* Size of table */ + MYFLT *UNUSEDP; /* pow2 table */ + MYFLT *cpsocfrc; /* cps conv table */ + CORFIL* expanded_orc; /* output of preprocessor */ + CORFIL* expanded_sco; /* output of preprocessor */ + char *filedir[256];/* for location directory */ + void *message_buffer; + int jumpset; + int info_message_request; + int modules_loaded; + MYFLT _system_sr; + void* csdebug_data; /* debugger data */ + int (*kperf)(CSOUND *); /* kperf function pointer, to switch between debug + and nodebug function */ + int score_parser; + int print_version; + int inZero; /* flag compilation of instr0 */ + struct _message_queue **msg_queue; + volatile long msg_queue_wget; /* Writer - Get index */ + volatile long msg_queue_wput; /* Writer - Put Index */ + volatile long msg_queue_rstart; /* Reader - start index */ + volatile long msg_queue_items; + int aftouch; + void *directory; + ALLOC_DATA *alloc_queue; + volatile unsigned long alloc_queue_items; + unsigned long alloc_queue_wp; + spin_lock_t alloc_spinlock; + EVTBLK *init_event; + void (*csoundMessageStringCallback)(CSOUND *csound, + int attr, + const char *str); + char* message_string; + volatile unsigned long message_string_queue_items; + unsigned long message_string_queue_wp; + message_string_queue_t *message_string_queue; + int io_initialised; + char *op; + int mode; + char *opcodedir; + char *score_srt; + OSC_MESS osc_message_anchor; + spin_lock_t osc_spinlock; + /*struct CSOUND_ **self;*/ + /**@}*/ +#endif /* __BUILDING_LIBCSOUND */ + }; + + /* + * Move the C++ guards to enclose the entire file, + * in order to enable C++ to #include this file. + */ + +#define LINKAGE_BUILTIN(name) \ + int32_t name##_init(CSOUND *csound, OENTRY **ep) \ + { (void) csound; *ep = name; return (long) (sizeof(name)); } + +#define FLINKAGE_BUILTIN(name) \ + NGFENS* name##_init(CSOUND *csound) \ + { (void) csound; return name; } + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* CSOUNDCORE_H */ diff --git a/7.x/csound/csound_circular_buffer.h b/7.x/csound/csound_circular_buffer.h new file mode 100644 index 00000000..fb56e2ca --- /dev/null +++ b/7.x/csound/csound_circular_buffer.h @@ -0,0 +1,96 @@ +/* + csound_circular_buffer.h: utility circular buffer functions + + Copyright (C) 2024 V Lazzarini + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef CS_CIRCULAR_BUFFER_H +#define CS_CIRCULAR_BUFFER_H + +#ifdef __cplusplus +extern "C" { +#endif + + /** @}*/ + /** @defgroup CIRCULARBUFFER Circular buffer functions + * + * @{ */ + /** + * Create circular buffer with numelem number of elements. The + * element's size is set from elemsize. It should be used like: + *@code + * void *rb = csoundCreateCircularBuffer(csound, 1024, sizeof(MYFLT)); + *@endcode + */ + PUBLIC void *csoundCreateCircularBuffer(CSOUND *csound, + int numelem, int elemsize); + + /** + * Read from circular buffer + * @param csound This value is currently ignored. + * @param circular_buffer pointer to an existing circular buffer + * @param out preallocated buffer with at least items number of elements, where + * buffer contents will be read into + * @param items number of samples to be read + * @returns the actual number of items read (0 <= n <= items) + */ + PUBLIC int csoundReadCircularBuffer(CSOUND *csound, void *circular_buffer, + void *out, int items); + + /** + * Read from circular buffer without removing them from the buffer. + * @param circular_buffer pointer to an existing circular buffer + * @param out preallocated buffer with at least items number of elements, where + * buffer contents will be read into + * @param items number of samples to be read + * @returns the actual number of items read (0 <= n <= items) + */ + PUBLIC int csoundPeekCircularBuffer(CSOUND *csound, void *circular_buffer, + void *out, int items); + + /** + * Write to circular buffer + * @param csound This value is currently ignored. + * @param p pointer to an existing circular buffer + * @param inp buffer with at least items number of elements to be written into + * circular buffer + * @param items number of samples to write + * @returns the actual number of items written (0 <= n <= items) + */ + PUBLIC int csoundWriteCircularBuffer(CSOUND *csound, void *p, + const void *inp, int items); + /** + * Empty circular buffer of any remaining data. This function should only be + * used if there is no reader actively getting data from the buffer. + * @param csound This value is currently ignored. + * @param p pointer to an existing circular buffer + */ + PUBLIC void csoundFlushCircularBuffer(CSOUND *csound, void *p); + + /** + * Free circular buffer + */ + PUBLIC void csoundDestroyCircularBuffer(CSOUND *csound, void *circularbuffer); + /** @}*/ +#ifdef __cplusplus +} +#endif + +#endif diff --git a/7.x/csound/csound_compiler.h b/7.x/csound/csound_compiler.h new file mode 100644 index 00000000..6e9b629e --- /dev/null +++ b/7.x/csound/csound_compiler.h @@ -0,0 +1,92 @@ +/* + csound_compiler.h: lower-level parsing and compiling interface + + Copyright (C) 2024 + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef CSOUND_COMPILER_H +#define CSOUND_COMPILER_H + +#ifdef __cplusplus +extern "C" { +#endif + + + typedef struct ORCTOKEN { + int type; + char *lexeme; + int value; + double fvalue; + char *optype; + struct ORCTOKEN *next; + } ORCTOKEN; + + + typedef struct TREE { + int type; + ORCTOKEN *value; + int rate; + int len; + int line; + uint64_t locn; + struct TREE *left; + struct TREE *right; + struct TREE *next; + void *markup; // TEMPORARY - used by semantic checker to + // markup node adds OENTRY or synthetic var + // names to expression nodes should be moved + // to TYPE_TABLE + } TREE; + +#ifndef CSOUND_CSDL_H + + /** @}*/ + /** @defgroup COMPILATION Parsing and compilation + * + * @{ */ + /** + * Parse the given orchestra from an ASCII string into a TREE. + * This can be called during performance to parse new code. + */ + PUBLIC TREE *csoundParseOrc(CSOUND *csound, const char *str); + + /** + * Compile the given TREE node into structs for Csound to use + * in synchronous or asynchronous (async = 1) mode. + */ + PUBLIC int csoundCompileTree(CSOUND *csound, TREE *root, int async); + + /** + * Free the resources associated with the TREE *tree + * This function should be called whenever the TREE was + * created with csoundParseOrc and memory can be deallocated. + **/ + PUBLIC void csoundDeleteTree(CSOUND *csound, TREE *tree); + + + /** @}*/ + +#endif /* !CSOUND_CSDL_H */ + +#ifdef __cplusplus +} +#endif + +#endif /* CSOUND_COMPILER_H */ diff --git a/7.x/csound/csound_data_structures.h b/7.x/csound/csound_data_structures.h new file mode 100644 index 00000000..87b974e1 --- /dev/null +++ b/7.x/csound/csound_data_structures.h @@ -0,0 +1,133 @@ +/* + csound_data_structures.h: + + Copyright (C) 2013 Steven Yi + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA + */ + +#ifndef __CSOUND_DATA_STRUCTURES_H +#define __CSOUND_DATA_STRUCTURES_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _cons { + void* value; // should be car, but using value + struct _cons* next; // should be cdr, but to follow csound + // linked list conventions +} CONS_CELL; + +typedef struct _cs_hash_bucket_item { + char* key; + void* value; + struct _cs_hash_bucket_item* next; +} CS_HASH_TABLE_ITEM; + +typedef struct _cs_hash_table { + int table_size; + int count; + CS_HASH_TABLE_ITEM** buckets; +} CS_HASH_TABLE; + +/* FUNCTIONS FOR CONS CELL */ + +/** Given a value and CONS_CELL, create a new CONS_CELL that holds the + value, then set the ->next value to the passed-in cons cell. This + operation effectively appends a value to the head of cons list. The + function returns the head of the cons list. It is safe to pass in + a NULL for the cons argument; the returned value will be just the + newly generated cons cell. */ +PUBLIC CONS_CELL* cs_cons(CSOUND* csound, void* val, CONS_CELL* cons); + +/** Appends the cons2 CONS_CELL list to the tail of the cons1 */ +PUBLIC CONS_CELL* cs_cons_append(CONS_CELL* cons1, CONS_CELL* cons2); + +/** Returns length of CONS_CELL list */ +PUBLIC int cs_cons_length(CONS_CELL* head); + +/** Frees CONS_CELL list but does not free ->value pointers */ +PUBLIC void cs_cons_free(CSOUND* csound, CONS_CELL* head); + +/** Frees CONS_CELL list also frees ->value pointers */ +PUBLIC void cs_cons_free_complete(CSOUND* csound, CONS_CELL* head); + +/* FUNCTIONS FOR HASH SET */ + +/** Create CS_HASH_TABLE */ +PUBLIC CS_HASH_TABLE* cs_hash_table_create(CSOUND* csound); + +/** Retreive void* value for given char* key. Returns NULL if no + items founds for key. */ +PUBLIC void* cs_hash_table_get(CSOUND* csound, + CS_HASH_TABLE* hashTable, char* key); + +/** Retreive char* key from internal hash item for given char* key. + Useful when using CS_HASH_TABLE as a Set type. Returns + NULL if there is no entry for given key. */ +PUBLIC char* cs_hash_table_get_key(CSOUND* csound, + CS_HASH_TABLE* hashTable, char* key); + +/** Adds an entry into the hashtable using the given key and value. + If an existing entry is found, overwrites the value for that key with + the new value passed in. */ +PUBLIC void cs_hash_table_put(CSOUND* csound, + CS_HASH_TABLE* hashTable, char* key, void* value); + +/** Adds an entry into the hashtable using the given key and NULL + value. Returns the internal char* used for the hash item key. */ +PUBLIC char* cs_hash_table_put_key(CSOUND* csound, + CS_HASH_TABLE* hashTable, char* key); + +/** Removes an entry from the hashtable using the given key. If no + entry found for key, simply returns. Calls mfree on the table + item. */ +PUBLIC void cs_hash_table_remove(CSOUND* csound, + CS_HASH_TABLE* hashTable, char* key); + +/** Merges in all items from the the source table into the target + table. Entries with identical keys from the source table will + replace entries in the target table. Note: wipes out source table. */ +PUBLIC void cs_hash_table_merge(CSOUND* csound, + CS_HASH_TABLE* target, CS_HASH_TABLE* source); + +/** Returns char* keys as a cons list */ +PUBLIC CONS_CELL* cs_hash_table_keys(CSOUND* csound, CS_HASH_TABLE* hashTable); + +/** Returns void* values as a cons list */ +PUBLIC CONS_CELL* cs_hash_table_values(CSOUND* csound, CS_HASH_TABLE* hashTable); + +/** Frees hash table and hash table items using mfree. Does not call + free on ->value pointer. */ +PUBLIC void cs_hash_table_free(CSOUND* csound, CS_HASH_TABLE* hashTable); + +/** Frees hash table and hash table keys using mfree. Does call mfree + on ->value pointer. */ +PUBLIC void cs_hash_table_mfree_complete(CSOUND* csound, CS_HASH_TABLE* hashTable); + +/** Frees hash table hash table keys using mfree. Does call free on + ->value pointer. */ +PUBLIC void cs_hash_table_free_complete(CSOUND* csound, CS_HASH_TABLE* hashTable); + +char * cs_inverse_hash_get(CSOUND* csound, CS_HASH_TABLE* hashTable, int n); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/7.x/csound/csound_files.h b/7.x/csound/csound_files.h new file mode 100644 index 00000000..13442d35 --- /dev/null +++ b/7.x/csound/csound_files.h @@ -0,0 +1,185 @@ +/* + csound_files.h: file open utilities + + Copyright (C) 2024 V Lazzarini + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef CSOUND_FILES_H +#define CSOUND_FILES_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The following constants are used with csound->FileOpen() and + * csound->ldmemfile() to specify the format of a file that is being + * opened. This information is passed by Csound to a host's FileOpen + * callback and does not influence the opening operation in any other + * way. Conversion from Csound's TYP_XXX macros for audio formats to + * CSOUND_FILETYPES values can be done with csound->type2csfiletype(). + */ + typedef enum { + CSFTYPE_UNIFIED_CSD = 1, /* Unified Csound document */ + CSFTYPE_ORCHESTRA, /* the primary orc file (may be temporary) */ + CSFTYPE_SCORE, /* the primary sco file (may be temporary) + or any additional score opened by Cscore */ + CSFTYPE_ORC_INCLUDE, /* a file #included by the orchestra */ + CSFTYPE_SCO_INCLUDE, /* a file #included by the score */ + CSFTYPE_SCORE_OUT, /* used for score.srt, score.xtr, cscore.out */ + CSFTYPE_SCOT, /* Scot score input format */ + CSFTYPE_OPTIONS, /* for .csoundrc and -@ flag */ + CSFTYPE_EXTRACT_PARMS, /* extraction file specified by -x */ + + /* audio file types that Csound can write (10-19) or read */ + CSFTYPE_RAW_AUDIO, + CSFTYPE_IRCAM, + CSFTYPE_AIFF, + CSFTYPE_AIFC, + CSFTYPE_WAVE, + CSFTYPE_AU, + CSFTYPE_SD2, + CSFTYPE_W64, + CSFTYPE_WAVEX, + CSFTYPE_FLAC, + CSFTYPE_CAF, + CSFTYPE_WVE, + CSFTYPE_OGG, + CSFTYPE_MPC2K, + CSFTYPE_RF64, + CSFTYPE_AVR, + CSFTYPE_HTK, + CSFTYPE_MAT4, + CSFTYPE_MAT5, + CSFTYPE_NIST, + CSFTYPE_PAF, + CSFTYPE_PVF, + CSFTYPE_SDS, + CSFTYPE_SVX, + CSFTYPE_VOC, + CSFTYPE_XI, + CSFTYPE_MPEG, + CSFTYPE_UNKNOWN_AUDIO, /* used when opening audio file for reading + or temp file written with */ + + /* miscellaneous music formats */ + CSFTYPE_SOUNDFONT, + CSFTYPE_STD_MIDI, /* Standard MIDI file */ + CSFTYPE_MIDI_SYSEX, /* Raw MIDI codes, eg. SysEx dump */ + + /* analysis formats */ + CSFTYPE_HETRO, + CSFTYPE_HETROT, + CSFTYPE_PVC, /* original PVOC format */ + CSFTYPE_PVCEX, /* PVOC-EX format */ + CSFTYPE_CVANAL, + CSFTYPE_LPC, + CSFTYPE_ATS, + CSFTYPE_LORIS, + CSFTYPE_SDIF, + CSFTYPE_HRTF, + + /* Types for plugins and the files they read/write */ + CSFTYPE_UNUSED, + CSFTYPE_LADSPA_PLUGIN, + CSFTYPE_SNAPSHOT, + + /* Special formats for Csound ftables or scanned synthesis + matrices with header info */ + CSFTYPE_FTABLES_TEXT, /* for ftsave and ftload */ + CSFTYPE_FTABLES_BINARY, /* for ftsave and ftload */ + CSFTYPE_XSCANU_MATRIX, /* for xscanu opcode */ + + /* These are for raw lists of numbers without header info */ + CSFTYPE_FLOATS_TEXT, /* used by GEN23, GEN28, dumpk, readk */ + CSFTYPE_FLOATS_BINARY, /* used by dumpk, readk, etc. */ + CSFTYPE_INTEGER_TEXT, /* used by dumpk, readk, etc. */ + CSFTYPE_INTEGER_BINARY, /* used by dumpk, readk, etc. */ + + /* image file formats */ + CSFTYPE_IMAGE_PNG, + + /* For files that don't match any of the above */ + CSFTYPE_POSTSCRIPT, /* EPS format used by graphs */ + CSFTYPE_SCRIPT_TEXT, /* executable script files (eg. Python) */ + CSFTYPE_OTHER_TEXT, + CSFTYPE_OTHER_BINARY, + + /* This should only be used internally by the original FileOpen() + API call or for temp files written with */ + CSFTYPE_UNKNOWN = 0 + } CSOUND_FILETYPES; + + + /** + * Sets an external callback for opening a sound file. + * The callback is made when a sound file is going to be opened. + * The following information is passed to the callback: + * char* pathname of the file; either full or relative to current dir + * int flags of the file descriptor. + * SFLIB_INFO* sound file info of the sound file. + * + * Pass NULL to disable the callback. + * This callback is retained after a csoundReset() call. + */ + + PUBLIC void csoundSetOpenSoundFileCallback(CSOUND *p, + void *(*openSoundFileCallback)(CSOUND*, + const char*, + int, void*)); + + /** + * Sets an external callback for opening a file. + * The callback is made when a file is going to be opened. + * The following information is passed to the callback: + * char* pathname of the file; either full or relative to current dir + * char* access mode of the file. + * + * Pass NULL to disable the callback. + * This callback is retained after a csoundReset() call. + */ + PUBLIC void csoundSetOpenFileCallback(CSOUND *p, + FILE *(*openFileCallback)(CSOUND*, + const char*, + const char*)); + +#if !defined(SWIG) + /** + * Sets an external callback for receiving notices whenever Csound opens + * a file. The callback is made after the file is successfully opened. + * The following information is passed to the callback: + * char* pathname of the file; either full or relative to current dir + * int a file type code from the enumeration CSOUND_FILETYPES + * int 1 if Csound is writing the file, 0 if reading + * int 1 if a temporary file that Csound will delete; 0 if not + * + * Pass NULL to disable the callback. + * This callback is retained after a csoundReset() call. + */ + PUBLIC void csoundSetFileOpenCallback(CSOUND *p, + void (*func)(CSOUND*, const char*, + int, int, int)); +#endif + +#ifdef __cplusplus +} +#endif + +#endif // CSOUND_FILES_H diff --git a/7.x/csound/csound_graph_display.h b/7.x/csound/csound_graph_display.h new file mode 100644 index 00000000..13596eab --- /dev/null +++ b/7.x/csound/csound_graph_display.h @@ -0,0 +1,73 @@ +/* + graph_display.h: graphs and displays + + Copyright (C) 2024 + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef GRAPH_DISPLAY_H +#define GRAPH_DISPLAY_H + +#ifdef __cplusplus +extern "C" { +#endif + /** @defgroup TABLEDISPLAY Function table display + * + * @{ */ + typedef struct windat_ WINDAT; + + /** + * Tells Csound whether external graphic table display is supported. + * Returns the previously set value (initially zero). + */ + PUBLIC int csoundSetIsGraphable(CSOUND *, int isGraphable); + + /** + * Called by external software to set Csound's MakeGraph function. + */ + PUBLIC void csoundSetMakeGraphCallback(CSOUND *, + void (*makeGraphCallback_)(CSOUND *, + WINDAT *windat, + const char *name)); + + /** + * Called by external software to set Csound's DrawGraph function. + */ + PUBLIC void csoundSetDrawGraphCallback(CSOUND *, + void (*drawGraphCallback_)(CSOUND *, + WINDAT *windat)); + + /** + * Called by external software to set Csound's KillGraph function. + */ + PUBLIC void csoundSetKillGraphCallback(CSOUND *, + void (*killGraphCallback_)(CSOUND *, + WINDAT *windat)); + + /** + * Called by external software to set Csound's ExitGraph function. + */ + PUBLIC void csoundSetExitGraphCallback(CSOUND *, + int (*exitGraphCallback_)(CSOUND *)); +/** @}*/ + +#ifdef __cplusplus +} +#endif +#endif diff --git a/7.x/csound/csound_misc.h b/7.x/csound/csound_misc.h new file mode 100644 index 00000000..3cbbf328 --- /dev/null +++ b/7.x/csound/csound_misc.h @@ -0,0 +1,203 @@ +/* + csound_misc.h: miscellaneous utility functions + + Copyright (C) 2024 + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef CS_MISC_H +#define CS_MISC_H + +#ifdef __cplusplus +extern "C" { +#endif + + typedef struct RTCLOCK_S { + int_least64_t starttime_real; + int_least64_t starttime_CPU; + } RTCLOCK; + + typedef struct CsoundRandMTState_ { + int mti; + uint32_t mt[624]; + } CsoundRandMTState; + + /** @defgroup MISCELLANEOUS Miscellaneous functions + * + * @{ */ + + /** + * Runs an external command with the arguments specified in 'argv'. + * argv[0] is the name of the program to execute (if not a full path + * file name, it is searched in the directories defined by the PATH + * environment variable). The list of arguments should be terminated + * by a NULL pointer. + * If 'noWait' is zero, the function waits until the external program + * finishes, otherwise it returns immediately. In the first case, a + * non-negative return value is the exit status of the command (0 to + * 255), otherwise it is the PID of the newly created process. + * On error, a negative value is returned. + */ + PUBLIC long csoundRunCommand(const char * const *argv, int noWait); + + /** + * Initialise a timer structure. + */ + PUBLIC void csoundInitTimerStruct(RTCLOCK *); + + /** + * Return the elapsed real time (in seconds) since the specified timer + * structure was initialised. + */ + PUBLIC double csoundGetRealTime(RTCLOCK *); + + /** + * Return the elapsed CPU time (in seconds) since the specified timer + * structure was initialised. + */ + PUBLIC double csoundGetCPUTime(RTCLOCK *); + + /** + * Return a 32-bit unsigned integer to be used as seed from current time. + */ + PUBLIC uint32_t csoundGetRandomSeedFromTime(void); + + /** + * Set language to 'lang_code' (lang_code can be for example + * CSLANGUAGE_ENGLISH_UK or CSLANGUAGE_FRENCH or many others, + * see n_getstr.h for the list of languages). This affects all + * Csound instances running in the address space of the current + * process. The special language code CSLANGUAGE_DEFAULT can be + * used to disable translation of messages and free all memory + * allocated by a previous call to csoundSetLanguage(). + * csoundSetLanguage() loads all files for the selected language + * from the directory specified by the CSSTRNGS environment + * variable. + */ + PUBLIC void csoundSetLanguage(cslanguage_t lang_code); + + /** + * Get pointer to the value of environment variable 'name', searching + * in this order: local environment of 'csound' (if not NULL), variables + * set with csoundSetGlobalEnv(), and system environment variables. + * If 'csound' is not NULL, should be called after csoundCompile(). + * Return value is NULL if the variable is not set. + */ + PUBLIC const char *csoundGetEnv(CSOUND *csound, const char *name); + + /** + * Set the global value of environment variable 'name' to 'value', + * or delete variable if 'value' is NULL. + * It is not safe to call this function while any Csound instances + * are active. + * Returns zero on success. + */ + PUBLIC int csoundSetGlobalEnv(const char *name, const char *value); + + /** + * Allocate nbytes bytes of memory that can be accessed later by calling + * csoundQueryGlobalVariable() with the specified name; the space is + * cleared to zero. + * Returns CSOUND_SUCCESS on success, CSOUND_ERROR in case of invalid + * parameters (zero nbytes, invalid or already used name), or + * CSOUND_MEMORY if there is not enough memory. + */ + PUBLIC int csoundCreateGlobalVariable(CSOUND *, + const char *name, size_t nbytes); + + /** + * Get pointer to space allocated with the name "name". + * Returns NULL if the specified name is not defined. + */ + PUBLIC void *csoundQueryGlobalVariable(CSOUND *, const char *name); + + /** + * This function is the same as csoundQueryGlobalVariable(), except the + * variable is assumed to exist and no error checking is done. + * Faster, but may crash or return an invalid pointer if 'name' is + * not defined. + */ + PUBLIC void *csoundQueryGlobalVariableNoCheck(CSOUND *, const char *name); + + /** + * Free memory allocated for "name" and remove "name" from the database. + * Return value is CSOUND_SUCCESS on success, or CSOUND_ERROR if the name is + * not defined. + */ + PUBLIC int csoundDestroyGlobalVariable(CSOUND *, const char *name); + + /** + * Run utility with the specified name and command line arguments. + * Should be called after loading utility plugins. + * Use csoundReset() to clean up after calling this function. + * Returns zero if the utility was run successfully. + */ + PUBLIC int csoundRunUtility(CSOUND *, const char *name, + int argc, char **argv); + + /** + * Returns a NULL terminated list of registered utility names. + * The caller is responsible for freeing the returned array with + * csoundDeleteUtilityList(), however, the names should not be + * changed or freed. + * The return value may be NULL in case of an error. + */ + PUBLIC char **csoundListUtilities(CSOUND *); + + /** + * Releases an utility list previously returned by csoundListUtilities(). + */ + PUBLIC void csoundDeleteUtilityList(CSOUND *, char **lst); + + /** + * Get utility description. + * Returns NULL if the utility was not found, or it has no description, + * or an error occured. + */ + PUBLIC const char *csoundGetUtilityDescription(CSOUND *, + const char *utilName); + + /** + * Simple linear congruential random number generator: + * (*seedVal) = (*seedVal) * 742938285 % 2147483647 + * the initial value of *seedVal must be in the range 1 to 2147483646. + * Returns the next number from the pseudo-random sequence, + * in the range 1 to 2147483646. + */ + PUBLIC int csoundRand31(int *seedVal); + + /** + * Initialise Mersenne Twister (MT19937) random number generator, + * using 'keyLength' unsigned 32 bit values from 'initKey' as seed. + * If the array is NULL, the length parameter is used for seeding. + */ + PUBLIC void csoundSeedRandMT(CsoundRandMTState *p, + const uint32_t *initKey, uint32_t keyLength); + + /** + * Returns next random number from MT19937 generator. + * The PRNG must be initialised first by calling csoundSeedRandMT(). + */ + PUBLIC uint32_t csoundRandMT(CsoundRandMTState *p); + /** @}*/ +#ifdef __cplusplus +} +#endif + +#endif diff --git a/7.x/csound/csound_server.h b/7.x/csound/csound_server.h new file mode 100644 index 00000000..6019fa8f --- /dev/null +++ b/7.x/csound/csound_server.h @@ -0,0 +1,70 @@ +/* + csound_server.h: Csound UDP server API + + Copyright (C) 2024 V Lazzarini + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef UDP_SERVER_H +#define UDP_SERVER_H + + +#ifdef __cplusplus +extern "C" { +#endif + + /** + * Starts the UDP server on a supplied port number + * returns CSOUND_SUCCESS if server has been started successfully, + * otherwise, CSOUND_ERROR. + */ + PUBLIC int csoundUDPServerStart(CSOUND *csound, unsigned int port); + + /** returns the port number on which the server is running, or + * CSOUND_ERROR if the server is not running. + */ + PUBLIC int csoundUDPServerStatus(CSOUND *csound); + + /** + * Closes the UDP server, returning CSOUND_SUCCESS if the + * running server was successfully closed, CSOUND_ERROR otherwise. + */ + PUBLIC int csoundUDPServerClose(CSOUND *csound); + + /** + * Turns on the transmission of console messages to UDP on address addr + * port port. If mirror is one, the messages will continue to be + * sent to the usual destination (see csoundSetMessaggeCallback()) + * as well as to UDP. + * returns CSOUND_SUCCESS or CSOUND_ERROR if the UDP transmission + * could not be set up. + */ + PUBLIC int csoundUDPConsole(CSOUND *csound, const char *addr, + int port, int mirror); + + /** + * Stop transmitting console messages via UDP + */ + PUBLIC void csoundStopUDPConsole(CSOUND *csound); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/7.x/csound/csound_threads.h b/7.x/csound/csound_threads.h new file mode 100644 index 00000000..86496a82 --- /dev/null +++ b/7.x/csound/csound_threads.h @@ -0,0 +1,239 @@ +/* + cs_threads.h:cross-platform threads interface + + Copyright (C) 2024 + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef CS_THREADS_H +#define CS_THREADS_H + +#ifdef __cplusplus +extern "C" { +#endif + + + /** @defgroup THREADING Threading and concurrency + * + * @{ */ + + /** + * Called by external software to set a function for checking system + * events, yielding cpu time for coopertative multitasking, etc. + * This function is optional. It is often used as a way to 'turn off' + * Csound, allowing it to exit gracefully. In addition, some operations + * like utility analysis routines are not reentrant and you should use + * this function to do any kind of updating during the operation. + * Returns an 'OK to continue' boolean. + */ + PUBLIC void csoundSetYieldCallback(CSOUND *, int (*yieldCallback_)(CSOUND *)); + + /** + * Creates and starts a new thread of execution. + * Returns an opaque pointer that represents the thread on success, + * or NULL for failure. + * The userdata pointer is passed to the thread routine. + */ + PUBLIC void *csoundCreateThread(uintptr_t (*threadRoutine)(void *), + void *userdata); + + /** + * Creates and starts a new thread of execution + * with a user-defined stack size. + * Returns an opaque pointer that represents the thread on success, + * or NULL for failure. + * The userdata pointer is passed to the thread routine. + */ + PUBLIC void *csoundCreateThread2(uintptr_t (*threadRoutine)(void *), + unsigned int stack, + void *userdata); + + /** + * Returns the ID of the currently executing thread, + * or NULL for failure. + * + * NOTE: The return value can be used as a pointer + * to a thread object, but it should not be compared + * as a pointer. The pointed to values should be compared, + * and the user must free the pointer after use. + */ + PUBLIC void *csoundGetCurrentThreadId(void); + + /** + * Waits until the indicated thread's routine has finished. + * Returns the value returned by the thread routine. + */ + PUBLIC uintptr_t csoundJoinThread(void *thread); + /** + * Creates and returns a monitor object, or NULL if not successful. + * The object is initially in signaled (notified) state. + */ + PUBLIC void *csoundCreateThreadLock(void); + + /** + * Waits on the indicated monitor object for the indicated period. + * The function returns either when the monitor object is notified, + * or when the period has elapsed, whichever is sooner; in the first case, + * zero is returned. + * If 'milliseconds' is zero and the object is not notified, the function + * will return immediately with a non-zero status. + */ + PUBLIC int csoundWaitThreadLock(void *lock, size_t milliseconds); + + /** + * Waits on the indicated monitor object until it is notified. + * This function is similar to csoundWaitThreadLock() with an infinite + * wait time, but may be more efficient. + */ + PUBLIC void csoundWaitThreadLockNoTimeout(void *lock); + + /** + * Notifies the indicated monitor object. + */ + PUBLIC void csoundNotifyThreadLock(void *lock); + + /** + * Destroys the indicated monitor object. + */ + PUBLIC void csoundDestroyThreadLock(void *lock); + + /** + * Creates and returns a mutex object, or NULL if not successful. + * Mutexes can be faster than the more general purpose monitor objects + * returned by csoundCreateThreadLock() on some platforms, and can also + * be recursive, but the result of unlocking a mutex that is owned by + * another thread or is not locked is undefined. + * If 'isRecursive' is non-zero, the mutex can be re-locked multiple + * times by the same thread, requiring an equal number of unlock calls; + * otherwise, attempting to re-lock the mutex results in undefined + * behavior. + * Note: the handles returned by csoundCreateThreadLock() and + * csoundCreateMutex() are not compatible. + */ + PUBLIC void *csoundCreateMutex(int isRecursive); + + /** + * Acquires the indicated mutex object; if it is already in use by + * another thread, the function waits until the mutex is released by + * the other thread. + */ + PUBLIC void csoundLockMutex(void *mutex_); + + /** + * Acquires the indicated mutex object and returns zero, unless it is + * already in use by another thread, in which case a non-zero value is + * returned immediately, rather than waiting until the mutex becomes + * available. + * Note: this function may be unimplemented on Windows. + */ + PUBLIC int csoundLockMutexNoWait(void *mutex_); + + /** + * Releases the indicated mutex object, which should be owned by + * the current thread, otherwise the operation of this function is + * undefined. A recursive mutex needs to be unlocked as many times + * as it was locked previously. + */ + PUBLIC void csoundUnlockMutex(void *mutex_); + + /** + * Destroys the indicated mutex object. Destroying a mutex that + * is currently owned by a thread results in undefined behavior. + */ + PUBLIC void csoundDestroyMutex(void *mutex_); + + + /** + * Create a Thread Barrier. Max value parameter should be equal to + * number of child threads using the barrier plus one for the + * master thread */ + + PUBLIC void *csoundCreateBarrier(unsigned int max); + + /** + * Destroy a Thread Barrier. + */ + PUBLIC int csoundDestroyBarrier(void *barrier); + + /** + * Wait on the thread barrier. + */ + PUBLIC int csoundWaitBarrier(void *barrier); + + + /** Creates a conditional variable */ + PUBLIC void* csoundCreateCondVar(); + + /** Waits up on a conditional variable and mutex */ + PUBLIC void csoundCondWait(void* condVar, void* mutex); + + /** Signals a conditional variable */ + PUBLIC void csoundCondSignal(void* condVar); + + /** Destroys a conditional variable */ + PUBLIC void csoundDestroyCondVar(void* condVar); + + /** + * If the spinlock is not locked, lock it and return; + * if is is locked, wait until it is unlocked, then lock it and return. + * Uses atomic compare and swap operations that are safe across processors + * and safe for out of order operations, + * and which are more efficient than operating system locks. + * Use spinlocks to protect access to shared data, especially in functions + * that do little more than read or write such data, for example: + * + * @code + * static spin_lock_t lock = SPINLOCK_INIT; + * csoundSpinLockInit(&lock); + * void write(size_t frames, int* signal) + * { + * csoundSpinLock(&lock); + * for (size_t frame = 0; i < frames; frame++) { + * global_buffer[frame] += signal[frame]; + * } + * csoundSpinUnlock(&lock); + * } + * @endcode + */ + PUBLIC int csoundSpinLockInit(spin_lock_t *spinlock); + + + /** + * Locks the spinlock + */ + PUBLIC void csoundSpinLock(spin_lock_t *spinlock); + + /** + * Tries the lock, returns CSOUND_SUCCESS if lock could be acquired, + CSOUND_ERROR, otherwise. + */ + PUBLIC int csoundSpinTryLock(spin_lock_t *spinlock); + + /** + * Unlocks the spinlock + */ + PUBLIC void csoundSpinUnLock(spin_lock_t *spinlock); + + /** @}*/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/7.x/csound/csound_type_system.h b/7.x/csound/csound_type_system.h new file mode 100644 index 00000000..cea5f8ce --- /dev/null +++ b/7.x/csound/csound_type_system.h @@ -0,0 +1,155 @@ +/* + csound_type_system.c: + + Copyright (C) 2012, 2013 Steven Yi + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef CSOUND_TYPE_SYSTEM_H +#define CSOUND_TYPE_SYSTEM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "csound.h" +#include "csound_data_structures.h" +#include + +#define CS_ARG_TYPE_BOTH 0 +#define CS_ARG_TYPE_IN 1 +#define CS_ARG_TYPE_OUT 2 + + struct csvariable; + struct cstype; + struct opds; + + typedef struct cstype { + char* varTypeName; + char* varDescription; + int argtype; // used to denote if allowed as in-arg, out-arg, or both + struct csvariable* (*createVariable)(void *cs, void *p, struct opds *ctx); + void (*copyValue)(CSOUND* csound, const struct cstype* cstype, void* dest, const + void* src, struct opds *ctx); + void (*freeVariableMemory)(void* csound, void* varMem); + CONS_CELL* members; + int userDefinedType; + } CS_TYPE; + + typedef struct csvarmem { + const CS_TYPE* varType; + MYFLT value; + } CS_VAR_MEM; + +#if defined(UINTPTR_MAX) && defined(UINT64_MAX) && (UINTPTR_MAX == UINT64_MAX) +#define CS_VAR_TYPE_OFFSET (sizeof(CS_VAR_MEM) - sizeof(double)) +#else +#define CS_VAR_TYPE_OFFSET (sizeof(CS_VAR_MEM) - sizeof(MYFLT)) +#endif + + typedef struct csvariable { + char* varName; + const CS_TYPE* varType; + int memBlockSize; /* Must be a multiple of sizeof(MYFLT), as + Csound uses MYFLT* and pointer arithmetic + to assign var locations */ + int memBlockIndex; + int dimensions; // used by arrays + int refCount; + struct csvariable* next; + const CS_TYPE* subType; + void (*updateMemBlockSize)(CSOUND*, struct csvariable*); + void (*initializeVariableMemory)(CSOUND*, struct csvariable*, MYFLT*); + CS_VAR_MEM *memBlock; + } CS_VARIABLE; + + typedef struct cstypeitem { + CS_TYPE* cstype; + struct cstypeitem* next; + } CS_TYPE_ITEM; + + typedef struct typepool { + CS_TYPE_ITEM* head; + } TYPE_POOL; + + /** + * Returns Csound internal type pool + */ + PUBLIC TYPE_POOL *csoundGetTypePool(CSOUND* csound); + + /** + * Adds a new type to type table pool + * Returns if variable type redefined + */ + PUBLIC int csoundAddVariableType(CSOUND* csound, TYPE_POOL* pool, + CS_TYPE* typeInstance); + + /** + * Creates a new variable with a type from type table + * Returns new variable on success, NULL on failure + */ + PUBLIC CS_VARIABLE* csoundCreateVariable(CSOUND* csound, TYPE_POOL* pool, + const CS_TYPE* type, char* name, + void* typeArg); + /** + * Gets a type variable from a type name string + * Returns the CS_TYPE*, NULL on failure + */ + PUBLIC const CS_TYPE* csoundGetTypeWithVarTypeName(const TYPE_POOL* pool, + const char* typeName); + + /** + * Gets a type variable from a channek name + * Returns a const CS_TYPE*, NULL on failure + */ + PUBLIC const CS_TYPE *csoundGetChannelVarType(CSOUND *csound, const char *name); + + /** + * Csound Variable Pool - essentially a map + * CSOUND contains one for global memory, InstrDef and UDODef + * contain a pool for local memory + */ + typedef struct csvarpool { + CS_HASH_TABLE* table; + CS_VARIABLE* head; + CS_VARIABLE* tail; + int poolSize; + struct csvarpool* parent; + int varCount; + int synthArgCount; + } CS_VAR_POOL; + + /* Shsould we keep these in the API? */ + PUBLIC CS_VAR_POOL* csoundCreateVarPool(CSOUND* csound); + PUBLIC void csoundFreeVarPool(CSOUND* csound, CS_VAR_POOL* pool); + PUBLIC char* getVarSimpleName(CSOUND* csound, const char* name); + PUBLIC CS_VARIABLE* csoundFindVariableWithName(CSOUND* csound, + CS_VAR_POOL* pool, + const char* name); + PUBLIC int csoundAddVariable(CSOUND* csound, CS_VAR_POOL* pool, + CS_VARIABLE* var); + PUBLIC void recalculateVarPoolMemory(CSOUND* csound, CS_VAR_POOL* pool); + PUBLIC void reallocateVarPoolMemory(CSOUND* csound, CS_VAR_POOL* pool); + PUBLIC void initializeVarPool(CSOUND* csound, MYFLT* memBlock, CS_VAR_POOL* pool); + +#ifdef __cplusplus +} +#endif + +#endif /* CSOUND_TYPE_SYSTEM_H */ diff --git a/7.x/csound/cwindow.h b/7.x/csound/cwindow.h new file mode 100644 index 00000000..31c3cd3c --- /dev/null +++ b/7.x/csound/cwindow.h @@ -0,0 +1,93 @@ +/* + cwindow.h: + + Copyright (C) 1990 Dan Ellis + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef CWINDOW_H +#define CWINDOW_H + +/*******************************************************\ +* cwindow.h * +* portable window graphs stolen from Csound * +* necessary header declarations * +* 08nov90 dpwe * +\*******************************************************/ + +#include "csound.h" + +#define CAPSIZE 60 + +struct windat_ { + uintptr_t windid; /* set by MakeGraph() */ + MYFLT *fdata; /* data passed to DrawGraph */ + int32 npts; /* size of above array */ + char caption[CAPSIZE]; /* caption string for graph */ + int16 waitflg; /* set =1 to wait for ms after Draw */ + int16 polarity; /* controls positioning of X axis */ + MYFLT max, min; /* workspace .. extrema this frame */ + MYFLT absmax; /* workspace .. largest of above */ + MYFLT oabsmax; /* Y axis scaling factor */ + int danflag; /* set to 1 for extra Yaxis mid span */ + int absflag; /* set to 1 to skip abs check */ +}; + +enum { /* symbols for WINDAT.polarity field */ + NOPOL, + NEGPOL, + POSPOL, + BIPOL +}; + +struct xyindat_ { /* for 'joystick' input window */ + uintptr_t windid; /* xwindow handle */ + int m_x,m_y; /* current crosshair pixel adr */ + MYFLT x,y; /* current proportions of fsd */ + int down; +}; + + /* ------------------------------------------------------------------------ */ + +#ifdef __BUILDING_LIBCSOUND + +void dispset(CSOUND *, WINDAT *, MYFLT *, int32, char *, int, char *); +int dispexit(CSOUND *); +void display(CSOUND *, WINDAT*); +#if 0 +/* create window for a graph */ +void MakeGraph(CSOUND *, WINDAT *, const char *); +/* create a mouse input window; init scale */ +void MakeXYin(CSOUND *, XYINDAT *, MYFLT, MYFLT); +/* update graph in existing window */ +void DrawGraph(CSOUND *, WINDAT *); +/* fetch latest value from mouse input window */ +void ReadXYin(CSOUND *, XYINDAT *); +/* remove a graph window */ +void KillGraph(CSOUND *, WINDAT *); +/* remove a mouse input window */ +void KillXYin(CSOUND *, XYINDAT *); +/* print click-Exit message in most recently active window */ +int ExitGraph(CSOUND *); +#endif + +#endif /* __BUILDING_LIBCSOUND */ + +#endif /* CWINDOW_H */ + diff --git a/7.x/csound/find_opcode.h b/7.x/csound/find_opcode.h new file mode 100644 index 00000000..2f53059b --- /dev/null +++ b/7.x/csound/find_opcode.h @@ -0,0 +1,35 @@ +/* + find_opcode.h: + + Copyright (C) 2016 by John ffitc + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ +#ifndef _FIND_OPCODE_H_ +#define _FIND_OPCODE_H_ + +char* get_opcode_short_name(CSOUND* csound, char* opname); + +PUBLIC OENTRY* find_opcode_new(CSOUND* csound, char* opname, + char* outArgsFound, char* inArgsFound); +PUBLIC OENTRY* find_opcode_exact(CSOUND* csound, char* opname, + char* outArgsFound, char* inArgsFound); +/* find OENTRY with the specified name in opcode list */ + +OENTRY* find_opcode(CSOUND *, char *); +#endif diff --git a/7.x/csound/float-version.h b/7.x/csound/float-version.h new file mode 100644 index 00000000..4d5914b4 --- /dev/null +++ b/7.x/csound/float-version.h @@ -0,0 +1,35 @@ +/* + float-version.h: + + Copyright (C) 1991-2010 Victor Lazzarini + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +/* this file can be copied as float-version.h in installers for double precision + currently implemented only for OSX +*/ + +#ifndef FLOAT_VERSION_H +#define FLOAT_VERSION_H + +#if !defined(USE_DOUBLE) +#define USE_DOUBLE +#endif + +#endif diff --git a/7.x/csound/interlocks.h b/7.x/csound/interlocks.h new file mode 100644 index 00000000..05f634cf --- /dev/null +++ b/7.x/csound/interlocks.h @@ -0,0 +1,59 @@ +/* + interlocks.h: + + Copyright (C) 2011 John ffitch + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#pragma once + +// ZAK +#define ZR (0x0001) +#define ZW (0x0002) +#define ZB (0x0003) + +// Writes to inputs +#define WI (0x0004) + +//Tables +#define TR (0x0008) +#define TW (0x0010) +#define TB (0x0018) + +//Channels +#define _CR (0x0020) +#define _CW (0x0040) +#define _CB (0x0060) + +//Stack +#define SK (0x0080) + +//Printing +#define WR (0x0100) + +// Internal oddities -- SPOUT +#define IR (0x0200) +#define IW (0x0400) +#define IB (0x0600) + +// Declare but not defined +#define UNDEFINED (0x0800) + +//Deprecated +#define _QQ (0x8000) diff --git a/7.x/csound/modload.h b/7.x/csound/modload.h new file mode 100644 index 00000000..b3d1b447 --- /dev/null +++ b/7.x/csound/modload.h @@ -0,0 +1,56 @@ +/* + modload.h + CPOF Csound Plugin Opcode Framework + module load C functions and entry point + + (c) Victor Lazzarini, 2017 + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA + +*/ +#ifndef __MODLOAD__H +#define __MODLOAD__H + +#include + +#if defined(__wasi__) + #undef PUBLIC + #define PUBLIC extern __attribute__((used)) +#endif + +namespace csnd { +/** Plugin library entry point + */ +void on_load(Csound *); +} + +extern "C" { +PUBLIC int csoundModuleCreate(CSOUND *csound) { + IGN(csound); + return 0; +} +PUBLIC int csoundModuleDestroy(CSOUND *csound) { + IGN(csound); + return 0; +} +PUBLIC int csoundModuleInit(CSOUND *csound) { + csnd::on_load((csnd::Csound *)csound); + return 0; +} +} +#endif diff --git a/7.x/csound/msg_attr.h b/7.x/csound/msg_attr.h new file mode 100644 index 00000000..ca042858 --- /dev/null +++ b/7.x/csound/msg_attr.h @@ -0,0 +1,73 @@ +/* + msg_attr.h: + + Copyright (C) 2005 Istvan Varga + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef CSOUND_MSG_ATTR_H +#define CSOUND_MSG_ATTR_H + +/* message types (only one can be specified) */ + +/* standard message */ +#define CSOUNDMSG_DEFAULT (0x0000) +/* error message (initerror, perferror, etc.) */ +#define CSOUNDMSG_ERROR (0x1000) +/* orchestra opcodes (e.g. printks) */ +#define CSOUNDMSG_ORCH (0x2000) +/* for progress display and heartbeat characters */ +#define CSOUNDMSG_REALTIME (0x3000) +/* warning messages */ +#define CSOUNDMSG_WARNING (0x4000) +/* stdount messages */ +#define CSOUNDMSG_STDOUT (0x5000) + +/* format attributes (colors etc.), use the bitwise OR of any of these: */ + +#define CSOUNDMSG_FG_BLACK (0x0100) +#define CSOUNDMSG_FG_RED (0x0101) +#define CSOUNDMSG_FG_GREEN (0x0102) +#define CSOUNDMSG_FG_YELLOW (0x0103) +#define CSOUNDMSG_FG_BLUE (0x0104) +#define CSOUNDMSG_FG_MAGENTA (0x0105) +#define CSOUNDMSG_FG_CYAN (0x0106) +#define CSOUNDMSG_FG_WHITE (0x0107) + +#define CSOUNDMSG_FG_BOLD (0x0008) +#define CSOUNDMSG_FG_UNDERLINE (0x0080) + +#define CSOUNDMSG_BG_BLACK (0x0200) +#define CSOUNDMSG_BG_RED (0x0210) +#define CSOUNDMSG_BG_GREEN (0x0220) +#define CSOUNDMSG_BG_ORANGE (0x0230) +#define CSOUNDMSG_BG_BLUE (0x0240) +#define CSOUNDMSG_BG_MAGENTA (0x0250) +#define CSOUNDMSG_BG_CYAN (0x0260) +#define CSOUNDMSG_BG_GREY (0x0270) + + /* ------------------------------------------------------------------------ */ + +#define CSOUNDMSG_TYPE_MASK (0x7000) +#define CSOUNDMSG_FG_COLOR_MASK (0x0107) +#define CSOUNDMSG_FG_ATTR_MASK (0x0088) +#define CSOUNDMSG_BG_COLOR_MASK (0x0270) + +#endif /* CSOUND_MSG_ATTR_H */ + diff --git a/7.x/csound/plugin.h b/7.x/csound/plugin.h new file mode 100644 index 00000000..abe0f3f9 --- /dev/null +++ b/7.x/csound/plugin.h @@ -0,0 +1,1246 @@ +/* + plugin.h + CPOF Csound Plugin Opcode Framework + C++ plugin opcode interface + + (c) Victor Lazzarini, 2017 + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA + +*/ + +#ifndef _PLUGIN_H_ +#define _PLUGIN_H_ +#ifdef CS_INTERNAL +#include "csoundCore.h" +#else +#include "csdl.h" +#endif +#include "pstream.h" +#include "arrays.h" +#include +#include +#include +#include +#include + +namespace csnd { + +/* constants */ +const double twopi = TWOPI; + +/** opcode threads: i-time, k-perf and/or a-perf +*/ +enum thread { i = 1, k = 2, ik = 3, a = 4, ia = 5 /*, ika = 3*/ }; + +/** fsig formats: phase vocoder, stft polar, stft complex, or + sinusoidal tracks +*/ +enum fsig_format { pvs = 0, polar, complex, tracks }; + +typedef CSOUND_FFT_SETUP *fftp; + +/** Csound Engine object. + */ +class Csound : CSOUND { + + /** Utility classes + */ + template friend class Vector; + friend class Fsig; + friend class Table; + template friend class AuxMem; + + /** + @private + opcode function template (deinit-time) + */ + template static int deinit(CSOUND *csound, void *p) { + return ((T *)p)->deinit(); + } + +public: + /** Host Data + */ + void *host_data() { return GetHostData(this); } + + /** init-time error message + */ + int init_error(const std::string &s) { + return InitError(this, "%s\n", LocalizeString(s.c_str())); + } + + /** perf-time error message + */ + int perf_error(const std::string &s, OPDS *inst) { + return PerfError(this, inst, "%s\n", LocalizeString(s.c_str())); + } + + /** warning message + */ + void warning(const std::string &s) { + Warning(this, "%s", LocalizeString(s.c_str())); + } + + /** console messages + */ + void message(const std::string &s) { + Message(this, "%s\n", LocalizeString(s.c_str())); + } + + /** system sampling rate + */ + //MYFLT sr() { return GetSr(this); } + + /** system control rate + */ + //MYFLT kr() { return GetKr(this); } + + /** system max amp reference + */ + MYFLT _0dbfs() { return Get0dBFS(this); } + + /** system A4 reference + */ + MYFLT _A4() { return GetA4(this); } + + /** number of audio channels (out) + */ + uint32_t nchnls() { return GetNchnls(this); } + + /** number of audio channels (in) + */ + uint32_t nchnls_i() { return GetNchnls_i(this); } + + /** time count (samples) + */ + int64_t current_time_samples() { return GetCurrentTimeSamples(this); } + + /** time count (seconds) + */ + //double current_time_seconds() { + // return GetCurrentTimeSamples(this) / GetSr(this); + //} + + /** check for audio signal variable argument + */ + bool is_asig(void *arg) { + return !std::strcmp(GetTypeForArg(arg)->varTypeName, "a"); + } + + /** midi channel number for this instrument + */ + int midi_channel(OPDS *p) { return GetMidiChannelNumber(p); } + + /** midi note number for this instrument + */ + int midi_note_num(OPDS *p) { return GetMidiNoteNumber(p); } + + /** midi note velocity for this instrument + */ + int midi_note_vel(OPDS *p) { return GetMidiVelocity(p); } + + /** midi aftertouch for this channel + */ + MYFLT midi_chn_aftertouch(OPDS *p) { + return GetMidiChannel(p)->aftouch; } + + /** midi poly aftertouch for this channel + */ + MYFLT midi_chn_polytouch(OPDS *p, uint32_t note) { + return GetMidiChannel(p)->polyaft[note]; + } + + /** midi ctl change for this channel + */ + MYFLT midi_chn_ctl(OPDS *p, uint32_t ctl) { + return GetMidiChannel(p)->ctl_val[ctl]; + } + + /** midi pitchbend for this channel + */ + MYFLT midi_chn_pitchbend(OPDS *p) { + return GetMidiChannel(p)->pchbend; + } + + /** list of active instrument instances for this channel \n + returns an INSDS array with 128 items, one per + MIDI note number. Inactive instances are marked NULL. + */ + const INSDS *midi_chn_list(OPDS *p) { + return (const INSDS *) GetMidiChannel(p)->kinsptr; + } + + /** Csound memory allocation - malloc style + */ + void *malloc(size_t size) { return Malloc(this, size); } + + /** Csound memory allocation - calloc style + */ + void *calloc(size_t size) { return Calloc(this, size); } + + /** Csound memory re-allocation + */ + void *realloc(void *p, size_t size) { return ReAlloc(this, p, size); } + + /** Csound string duplication + */ + char *strdup(char *s) { return Strdup(this, s); } + + /** Csound memory de-allocation + */ + void free(void *p) { Free(this, p); } + + /** FFT setup: real-to-complex and complex-to-real \n + direction: FFT_FWD or FFT_INV \n + returns a handle to the FFT setup. + */ + fftp fft_setup(uint32_t size, uint32_t direction) { + return (fftp)RealFFTSetup(this, size, direction); + } + + /** FFT operation, in-place, but also + returning a pointer to std::complex + to the transformed data memory. + */ + std::complex *rfft(fftp setup, MYFLT *data) { + RealFFT(this, setup, data); + return reinterpret_cast *>(data); + } + + /** FFT operation for complex data, in-place, but also + returning a pointer to std::complex + to the transformed data memory. + */ + std::complex *fft(fftp setup, std::complex *data) { + MYFLT *fdata = reinterpret_cast(data); + if (setup->d == FFT_FWD) + ComplexFFT(this, fdata, setup->N); + else + ComplexFFT(this, fdata, setup->N); + return reinterpret_cast *>(fdata); + } + + /** Creates a global variable in the current Csound object + */ + int create_global_variable(const char *name, size_t nbytes) { + return CreateGlobalVariable(this, name, nbytes); + } + + /** Retrieves a ptr for an existing named global variable + */ + void *query_global_variable(const char* name) { + return QueryGlobalVariable(this, name); + } + + /** Destroy an existing named global variable + */ + int destroy_global_variable(const char* name) { + return DestroyGlobalVariable(this, name); + } + + /** Access to the base CSOUND object + */ + CSOUND *get_csound() { + return this; + } + + /** Sleep + */ + void sleep(int ms) { Sleep(ms); } +}; + +/** + Thread pure virtual base class + */ +class Thread { + void *thread; + static uintptr_t thrdRun(void *t) { return ((Thread *)t)->run(); } + virtual uintptr_t run() = 0; + +protected: + Csound *csound; + +public: + Thread(Csound *cs) : csound(cs) { + CSOUND *p = (CSOUND *)csound; + thread = p->CreateThread(thrdRun, (void *)this); + } + + uintptr_t join() { + CSOUND *p = (CSOUND *)csound; + return p->JoinThread(thread); + } + void *get_thread() { return thread; } +}; + +/** Class AudioSig wraps an audio signal + */ +class AudioSig { + uint32_t early; + uint32_t offset; + uint32_t nsmps; + MYFLT *sig; + +public: + /** Constructor takes the plugin object and the + audio argument pointer, and a reset flag if + we need to clear an output buffer + */ + AudioSig(OPDS *p, MYFLT *s, bool res = false) + : early(p->insdshead->ksmps_no_end), offset(p->insdshead->ksmps_offset), + nsmps(p->insdshead->ksmps - p->insdshead->ksmps_no_end), sig(s) { + if (res) { + std::fill(sig, sig + p->insdshead->ksmps, 0); + } + }; + + /** iterator type + */ + typedef MYFLT *iterator; + + /** const_iterator type + */ + typedef const MYFLT *const_iterator; + + /** vector beginning + */ + iterator begin() { return sig + offset; } + + /** vector end + */ + iterator end() { return sig + nsmps; } + + /** vector beginning + */ + const_iterator begin() const { return sig + offset; } + + /** vector end + */ + const_iterator end() const { return sig + nsmps; } + + /** vector beginning + */ + const_iterator cbegin() const { return sig + offset; } + + /** vector end + */ + const_iterator cend() const { return sig + nsmps; } + + /** array subscript access (write) + */ + MYFLT &operator[](int n) { return sig[n]; } + + /** array subscript access (read) + */ + const MYFLT &operator[](int n) const { return sig[n]; } + + /** get early exit sample position + */ + uint32_t GetEarly() { return early; } + + /** get early exit sample offset + */ + uint32_t GetOffset() { return offset; } + + /** get number of samples to process + */ + uint32_t GetNsmps() { return nsmps; } +}; + +/** One-dimensional array container + template class + */ +template class Vector : ARRAYDAT { + +public: + /** Initialise the container + */ + void init(Csound *csound, int size, OPDS *ctx) { + tabinit(csound, this, size, ctx); + } + + /** iterator type + */ + typedef T *iterator; + + /** const_iterator type + */ + typedef const T *const_iterator; + + /** vector beginning + */ + iterator begin() { return (T *)data; } + + /** vector end + */ + iterator end() { return (T *)((char *)data + sizes[0] * arrayMemberSize); } + + /** vector beginning + */ + const_iterator cbegin() const { return (const T *)data; } + + /** vector end + */ + const_iterator cend() const { + return (const T *)((char *)data + sizes[0] * arrayMemberSize); + } + + /** vector beginning + */ + const_iterator begin() const { return (const T *)data; } + + /** vector end + */ + const_iterator end() const { + return (const T *)((char *)data + sizes[0] * arrayMemberSize); + } + + /** array subscript access (write) + */ + T &operator[](int n) { return ((T *)data)[n]; } + + /** array subscript access (read) + */ + const T &operator[](int n) const { return ((T *)data)[n]; } + + /** array subscript access (read) + */ + uint32_t len() { return sizes[0]; } + + /** element offset + */ + uint32_t elem_offset() { return arrayMemberSize / sizeof(T); } + + /** array data + */ + T *data_array() { return (T *)data; } +}; + +typedef Vector myfltvec; +typedef std::complex pvscmplx; +typedef std::complex sldcmplx; + +/** Pvbin holds one Phase Vocoder bin + */ +template class Pvbin { + T am; + T fr; + +public: + /** constructor + */ + Pvbin() : am((T)0), fr((T)0){}; + + /** access amplitude + */ + T amp() { return am; } + + /** access frequency + */ + T freq() { return fr; } + + /** set amplitude + */ + T amp(T a) { return (am = a); } + + /** set frequency + */ + T freq(T f) { return (fr = f); } + + /** multiplication (unary) + */ + const Pvbin &operator*=(const Pvbin &bin) { + am *= bin.am; + fr = bin.fr; + return *this; + } + + /** multiplication (binary) + */ + Pvbin operator*(const Pvbin &a) { + Pvbin res = *this; + return (res *= a); + } + + /** multiplication by MYFLT (unary) + */ + const Pvbin &operator*=(MYFLT f) { + am *= f; + return *this; + } + + /** multiplication by MYFLT (binary) + */ + Pvbin operator*(MYFLT f) { + Pvbin res = *this; + return (res *= f); + } + + /** cast to std::complex& + */ + operator pvscmplx &() { return (pvscmplx &)reinterpret_cast(*this); } + + /** cast to std::complex* + */ + operator pvscmplx *() { return (pvscmplx *)reinterpret_cast(this); } +}; + +/** Phase Vocoder bin */ +typedef Pvbin pv_bin; + +/** Sliding Phase Vocoder bin */ +typedef Pvbin spv_bin; + +template class Pvframe; + +/** Phase Vocoder frame */ +typedef Pvframe pv_frame; + +/** Sliding Phase Vocoder frame */ +typedef Pvframe spv_frame; + +/** fsig base class, holds PVSDAT data + */ +class Fsig : protected PVSDAT { +public: + /** initialise the object, allocating memory + if necessary. + */ + void init(Csound *csound, int32_t n, int32_t h, int32_t w, int32_t t, + int32_t f, int32_t nb = 0, int32_t sl = 0, uint32_t nsmps = 1) { + N = n; + overlap = h; + winsize = w; + wintype = t; + format = f; + NB = nb; + sliding = sl; + if (!sliding) { + size_t bytes = (n + 2) * sizeof(float); + if (frame.auxp == nullptr || frame.size < bytes) { + csound->AuxAlloc(csound, bytes, &frame); + std::fill((float *)frame.auxp, (float *)frame.auxp + n + 2, 0.f); + } + } else { + size_t bytes = (n + 2) * sizeof(MYFLT) * nsmps; + if (frame.auxp == NULL || frame.size < bytes) + csound->AuxAlloc(csound, bytes, &frame); + } + framecount = 1; + } + void init(Csound *csound, const Fsig &f, uint32_t nsmps = 1) { + init(csound, f.N, f.overlap, f.winsize, f.wintype, f.format, f.NB, + f.sliding, nsmps); + } + + /** get the DFT size + */ + uint32_t dft_size() { return N; } + + /** get the analysis hop size + */ + uint32_t hop_size() { return overlap; } + + /** get the analysis window size + */ + uint32_t win_size() { return winsize; } + + /** get the window type + */ + int32_t win_type() { return wintype; } + + /** get the number of bins + */ + uint32_t nbins() { return N / 2 + 1; } + + /** get the framecount + */ + uint32_t count() const { return framecount; } + + /** set framecount + */ + uint32_t count(uint32_t cnt) { return (framecount = cnt); } + + /** check for sliding mode + */ + bool isSliding() { return (bool)sliding; } + + /** get fsig data format + */ + int fsig_format() { return format; } + + /** get data frame as floats + */ + float *data() { return (float *) frame.auxp; } + + /** convert to pv_frame ref + */ + operator pv_frame &() { return reinterpret_cast(*this); } + +#ifdef USE_DOUBLE + /** convert to spv_frame ref + */ + operator spv_frame &() { return reinterpret_cast(*this); } +#endif + +}; + +/** Container class for a Phase Vocoder + analysis frame +*/ +template class Pvframe : public Fsig { + +public: + /** iterator type + */ + typedef T *iterator; + + /** const_iterator type + */ + typedef const T *const_iterator; + + /** returns an iterator to the + beginning of the frame + */ + iterator begin() { return (T *)frame.auxp; } + + /** returns an iterator to the + end of the frame + */ + iterator end() { return (T *)frame.auxp + N / 2 + 1; } + + /** returns a const iterator to the + beginning of the frame + */ + const_iterator begin() const { return (const T *)frame.auxp; } + + /** returns a const iterator to the + end of the frame + */ + const_iterator end() const { return (const T *)(frame.auxp + N / 2 + 1); } + + /** returns a const iterator to the + beginning of the frame + */ + const_iterator cbegin() const { return (const T *)frame.auxp; } + + /** returns a const iterator to the + end of the frame + */ + const_iterator cend() const { return (const T *)(frame.auxp + N / 2 + 1); } + + /** array subscript access operator (write) + */ + T &operator[](int n) { return ((T *)frame.auxp)[n]; } + + /** array subscript access operator (read) + */ + const T &operator[](int n) const { return ((T *)frame.auxp)[n]; } + + /** frame data pointer + */ + T *data() const { return (T *)frame.auxp; } + + /** return the container length + */ + uint32_t len() { return nbins(); } +}; + +/** function table container class + */ +class Table : FUNC { + +public: + /** Initialise this object from an opcode + argument arg */ + int init(Csound *csound, MYFLT *arg) { + Table *f = (Table *)csound->FTFind(csound, arg); + if (f != nullptr) { + std::copy(f, f + 1, this); + return OK; + } + return NOTOK; + } + + /** iterator type + */ + typedef MYFLT *iterator; + + /** const_iterator type + */ + typedef const MYFLT *const_iterator; + + /** returns an iterator to the + beginning of the table + */ + iterator begin() { return ftable; } + + /** returns an iterator to the + end of the table + */ + iterator end() { return ftable + flen; } + + /** returns a const iterator to the + beginning of the table + */ + const_iterator begin() const { return ftable; } + + /** returns a const iterator to the + end of the table + */ + const_iterator end() const { return ftable + flen; } + + /** returns a const iterator to the + beginning of the table + */ + const_iterator cbegin() const { return ftable; } + + /** returns a const iterator to the + end of the table + */ + const_iterator cend() const { return ftable + flen; } + + /** array subscript access operator (write) + */ + MYFLT &operator[](int n) { return ftable[n]; } + + /** array subscript access operator (read) + */ + const MYFLT &operator[](int n) const { return ftable[n]; } + + /** function table data pointer + */ + MYFLT *data() const { return ftable; } + + /** function table length + */ + uint32_t len() { return flen; } +}; + +/** vector container template using Csound AuxAlloc + mechanism for dynamic memory allocation + */ +template class AuxMem : AUXCH { + +public: + /** allocate memory for the container + */ + void allocate(Csound *csound, int n) { + size_t bytes = n * sizeof(T); + if (auxp == nullptr || size != bytes) { + csound->AuxAlloc(csound, bytes, (AUXCH *)this); + std::fill((char *)auxp, (char *)endp, 0); + } + } + + /** iterator type + */ + typedef T *iterator; + + /** const_iterator type + */ + typedef const T *const_iterator; + + /** vector beginning + */ + iterator begin() { return (T *)auxp; } + + /** vector end + */ + iterator end() { return (T *)endp; } + + /** vector beginning (const iterator) + */ + const_iterator begin() const { return (const T *)auxp; } + + /** vector end (const iterator) + */ + const_iterator end() const { return (const T *)endp; } + + /** vector beginning (const iterator) + */ + const_iterator cbegin() const { return (const T *)auxp; } + + /** vector end (const iterator) + */ + const_iterator cend() const { return (const T *)endp; } + + /** array subscript access (write) + */ + T &operator[](int n) { return ((T *)auxp)[n]; } + + /** array subscript access (read) + */ + const T &operator[](int n) const { return ((T *)auxp)[n]; } + + /** returns a pointer to the vector data + */ + T *data() { return (T *)auxp; } + + /** returns the length of the vector + */ + uint32_t len() { return size / sizeof(T); } +}; + + + +/** Parameters template class + */ + template class Param { + std::array ptrs; + +public: + /** parameter access via array subscript (write) + */ + MYFLT &operator[](int n) { return *ptrs[n]; } + + /** parameter access via array subscript (read) + */ + const MYFLT &operator[](int n) const { return *ptrs[n]; } + + /** iterator type + */ + typedef MYFLT **iterator; + + /** const_iterator type + */ + typedef const MYFLT **const_iterator; + + /** vector beginning + */ + iterator begin() { return &ptrs[0]; } + + /** vector end + */ + iterator end() { return &ptrs[N]; } + + /** vector beginning + */ + const_iterator begin() const { return (const MYFLT **)&ptrs[0]; } + + /** vector end + */ + const_iterator end() const { return (const MYFLT **)&ptrs[N]; } + + /** vector beginning + */ + const_iterator cbegin() const { return (const MYFLT **)&ptrs[0]; } + + /** vector end + */ + const_iterator cend() const { return (const MYFLT **)&ptrs[N]; } + + /** parameter data (MYFLT pointer) at index n + */ + MYFLT *operator()(int n) { return ptrs[n]; } + + /** @private: + same as operator() + */ + MYFLT *data(int n) { return ptrs[n]; } + + /** parameter string data (STRINGDAT ref) at index n + */ + STRINGDAT &str_data(int n) { return (STRINGDAT &)*ptrs[n]; } + + /** parameter fsig data (Fsig ref) at index n + */ + Fsig &fsig_data(int n) { return (Fsig &)*ptrs[n]; } + + /** 1-D array data as Vector template ref + */ + template Vector &vector_data(int n) { + return (Vector &)*ptrs[n]; + } + + /** returns 1-D numeric array data + */ + myfltvec &myfltvec_data(int n) { return (myfltvec &)*ptrs[n]; } + +}; + +/** InPlug template base class: + for 0 outputs and N inputs + also for multiple outputs and/or inputs + */ +template struct InPlug : OPDS { + /** arguments */ + Param args; + /** Csound engine */ + Csound *csound; + /** sample-accurate offset */ + uint32_t offset; + /** vector samples to process */ + uint32_t nsmps; + + /** i-time function placeholder + */ + int init() { return OK; } + + /** deinit function placeholder + */ + int deinit() { return OK; } + + /** k-rate function placeholder + */ + int kperf() { return OK; } + + /** a-rate function placeholder + */ + int aperf() { return OK; } + + /** @private + sample-accurate offset for + a-rate opcodes; updates offset + and nsmps. Called implicitly by + the aperf() method. + */ + void sa_offset() { + uint32_t early = insdshead->ksmps_no_end; + nsmps = insdshead->ksmps - early; + offset = insdshead->ksmps_offset; + } + + /** @private + set nsmps and offset value for kperf() + */ + void nsmps_set() { + nsmps = insdshead->ksmps - insdshead->ksmps_no_end; + offset = insdshead->ksmps_offset; + } + + /** returns the number of output arguments + used in the case of variable output count + */ + uint32_t out_count() { return (uint32_t)optext->t.outArgCount; } + + /** returns the number of input arguments + used in the case of variable input count + */ + uint32_t in_count() { return (uint32_t)optext->t.inArgCount; } + + /** local control rate + */ + MYFLT kr() { return insdshead->ekr; } + + /** local ksmps + */ + MYFLT ksmps() { return insdshead->ksmps; } + + /** sampling rate + */ + MYFLT sr() { return insdshead->esr; } + + /** midi channel number for this instrument + */ + int midi_channel() { return GetMidiChannelNumber(this); } + + /** midi note number for this instrument + */ + int midi_note_num() { return GetMidiNoteNumber(this); } + + /** midi note velocity for this instrument + */ + int midi_note_vel() { return GetMidiVelocity(this); } + + /** midi aftertouch for this channel + */ + MYFLT midi_chn_aftertouch() { + return GetMidiChannel(this)->aftouch; } + + /** midi poly aftertouch for this channel + */ + MYFLT midi_chn_polytouch(uint32_t note) { + return GetMidiChannel(this)->polyaft[note]; + } + + /** midi ctl change for this channel + */ + MYFLT midi_chn_ctl(uint32_t ctl) { + return GetMidiChannel(this)->ctl_val[ctl]; + } + + /** midi pitchbend for this channel + */ + MYFLT midi_chn_pitchbend() { + return GetMidiChannel(this)->pchbend; } + + /** list of active instrument instances for this channel \n + returns an INSDS array with 128 items, one per + MIDI note number. Inactive instances are marked NULL. + */ + const INSDS *midi_chn_list() { + return (const INSDS *) GetMidiChannel(this)->kinsptr; + } + + /** check if this opcode runs at init time + */ + bool is_init() { + return this->init ? true : false; + } + + /** check if this opcode runs at perf time + */ + bool is_perf() { +#ifdef EMSCRIPTEN + return this->perf ? true : false; +#else + return this->opaddr ? true : false; +#endif + } + +}; + +/** Plugin template base class: + for N outputs and M inputs, N > 0 + */ +template struct Plugin : OPDS { + /** output arguments */ + Param outargs; + /** input arguments */ + Param inargs; + /** Csound engine */ + Csound *csound; + /** sample-accurate offset */ + uint32_t offset; + /** vector samples to process */ + uint32_t nsmps; + + /** i-time function placeholder + */ + int init() { return OK; } + + /** deinit function placeholder + */ + int deinit() { return OK; } + + /** k-rate function placeholder + */ + int kperf() { return OK; } + + /** a-rate function placeholder + */ + int aperf() { return OK; } + + /** @private + sample-accurate offset for + a-rate opcodes; updates offset + and nsmps. Called implicitly by + the aperf() method. + */ + void sa_offset() { + uint32_t early = insdshead->ksmps_no_end; + nsmps = insdshead->ksmps - early; + offset = insdshead->ksmps_offset; + if (UNLIKELY(offset || early)) + for (auto &arg : outargs) { + if (csound->is_asig(arg)) { + std::fill(arg, arg + offset, 0); + std::fill(arg + nsmps, arg + nsmps + early, 0); + } + } + } + + /** @private + set nsmps and offset value for kperf() + */ + void nsmps_set() { + nsmps = insdshead->ksmps - insdshead->ksmps_no_end; + offset = insdshead->ksmps_offset; + } + + /** returns the number of output arguments + used in the case of variable output count + */ + uint32_t out_count() { return (uint32_t)optext->t.outArgCount; } + + /** returns the number of input arguments + used in the case of variable input count + */ + uint32_t in_count() { return (uint32_t)optext->t.inArgCount; } + + /** local control rate + */ + MYFLT kr() { return insdshead->ekr; } + + /** local ksmps + */ + MYFLT ksmps() { return insdshead->ksmps; } + + /** sampling rate + */ + MYFLT sr() { return insdshead->esr; } + + /** midi channel number for this instrument + */ + int midi_channel() { return GetMidiChannelNumber(this); } + + /** midi note number for this instrument + */ + int midi_note_num() { return GetMidiNoteNumber(this); } + + /** midi note velocity for this instrument + */ + int midi_note_vel() { return GetMidiVelocity(this); } + + /** midi aftertouch for this channel + */ + MYFLT midi_chn_aftertouch() { + return GetMidiChannel(this)->aftouch; } + + /** midi poly aftertouch for this channel + */ + MYFLT midi_chn_polytouch(uint32_t note) { + return GetMidiChannel(this)->polyaft[note]; + } + + /** midi ctl change for this channel + */ + MYFLT midi_chn_ctl(uint32_t ctl) { + return GetMidiChannel(this)->ctl_val[ctl]; + } + + /** midi pitchbend for this channel + */ + MYFLT midi_chn_pitchbend() { + return GetMidiChannel(this)->pchbend; } + + /** list of active instrument instances for this channel \n + returns an INSDS array with 128 items, one per + MIDI note number. Inactive instances are marked NULL. + */ + const INSDS *midi_chn_list() { + return (const INSDS *) GetMidiChannel(this)->kinsptr; + } + + /** check if this opcode runs at init time + */ + bool is_init() { +#ifdef EMSCRIPTEN + return this->init ? true : false; +#else + return (this->init != NULL); +#endif + } + + /** check if this opcode runs at perf time + */ + bool is_perf() { + return (this->perf != NULL); + } + +}; + + +/** Fsig plugin template base class: + for N outputs and M inputs + */ +template struct FPlugin : Plugin { + /** current frame time index */ + uint32_t framecount; +}; + +/** + @private + opcode thread function template (i-time) +*/ +template int init(CSOUND *csound, T *p) { + p->csound = (Csound *)csound; + return p->init(); +} + +/** + @private + opcode thread function template (deinit) +*/ +template int deinit(CSOUND *csound, T *p) { + p->csound = (Csound *)csound; + return p->deinit(); +} + + +/** + @private + opcode thread function template (k-rate) +*/ +template int kperf(CSOUND *csound, T *p) { + p->csound = (Csound *)csound; + p->nsmps_set(); + return p->kperf(); +} + +/** + @private + opcode thread function template (a-rate) +*/ +template int aperf(CSOUND *csound, T *p) { + p->csound = (Csound *)csound; + p->sa_offset(); + return p->aperf(); +} + +/** plugin registration function template + */ +template +int plugin(Csound *csound, const char *name, const char *oargs, + const char *iargs, uint32_t thr, uint32_t flags = 0) { + CSOUND *cs = (CSOUND *)csound; + if(thr == thread::ia || thr == thread::a) { + return cs->AppendOpcode(cs, (char *)name, sizeof(T), flags, + (char *)oargs, (char *)iargs, (SUBR)init, + (SUBR)aperf, (SUBR)deinit); + } + else + return cs->AppendOpcode(cs, (char *)name, sizeof(T), flags, + (char *)oargs, (char *)iargs, (SUBR)init, + (SUBR)kperf, (SUBR)deinit); +} + +/** plugin registration function template + for classes with self-defined opcode argument types + */ +template +int plugin(Csound *csound, const char *name, uint32_t thr, + uint32_t flags = 0) { + CSOUND *cs = (CSOUND *)csound; + if(thr == thread::ia || thr == thread::a) { + return cs->AppendOpcode(cs, (char *)name, sizeof(T), flags, + (char *)T::otypes, (char *)T::itypes, (SUBR)init, + (SUBR)aperf, (SUBR)deinit); + + } + else + return cs->AppendOpcode(cs, (char *)name, sizeof(T), flags, + (char *)T::otypes, (char *)T::itypes, (SUBR)init, + (SUBR)kperf, (SUBR)deinit); + +} + +/** utility constructor function template for member classes: \n + takes the class and constructor types as arguments. \n + Function takes the allocated memory pointer and constructor + arguments.\n + */ +template T *constr(T *p, Types... args) { + return new (p) T(args...); +} + +template void destr(T *p) { p->T::~T(); } +} +#endif diff --git a/7.x/csound/pools.h b/7.x/csound/pools.h new file mode 100644 index 00000000..12c17922 --- /dev/null +++ b/7.x/csound/pools.h @@ -0,0 +1,42 @@ +/* + pools.h: + + Copyright (C) 2013 by Victor Lazzarini + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef POOLS_H +#define POOLS_H + +#define POOL_SIZE 256 + +typedef struct myflt_pool { + CS_VAR_MEM* values; + int max; + int count; +} MYFLT_POOL; + +MYFLT_POOL* myflt_pool_create(CSOUND* csound); +int myflt_pool_indexof(MYFLT_POOL* pool, MYFLT value); +int myflt_pool_find_or_add(CSOUND* csound, MYFLT_POOL* pool, MYFLT value); +int myflt_pool_find_or_addc(CSOUND* csound, MYFLT_POOL* pool, char* s); +void myflt_pool_free(CSOUND *csound, MYFLT_POOL *pool); + +#endif + diff --git a/7.x/csound/pstream.h b/7.x/csound/pstream.h new file mode 100644 index 00000000..b554d289 --- /dev/null +++ b/7.x/csound/pstream.h @@ -0,0 +1,271 @@ +/* + pstream.h: + + Copyright (C) 2001 Richard Dobson + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef __PSTREAM_H_INCLUDED +#define __PSTREAM_H_INCLUDED + +/* pstream.h. Implementation of PVOCEX streaming opcodes. + (c) Richard Dobson August 2001 + NB pvoc routines based on CARL distribution (Mark Dolson). + This file is licensed according to the terms of the GNU LGPL. + */ + +/* opcodes: PROVISIONAL DEFINITIONS + + fsig pvsanal ain,ifftsize,ioverlap,iwinsize,iwintype[,iformat,iinit] + + iwintype: 0 = HAMMING, 1 = VonHann, 2 = Kaiser(?) + iformat: only PVS_AMP_FREQ (0) supported at present + (TODO: add f-table support for custom window) + ( But: really need a param to associate with the window too, + or just use a standard default value...) + + fsig pvsfread ktimpt,ifn[,ichan] + + asig pvsynth fsig[,iinit] + + asig pvsadsyn fsig,inoscs,kfmod[,ibin,ibinoffset,iinit] + + ibin: starting bin (defualt 0) + ibinoffset: distance between successive bins (default 1) + kfmod: multiplier; 1 = no change, 2 = up one octave. + + fsig pvscross fsrc,fdest,kamp1,kamp2 + + fsig pvsmaska fsrc,ifn,kdepth + + ioverlap,inumbins,iwinsize,iformat pvsinfo fsig + + ( will need sndinfo supporting pvocex files anyway, + to know numchans, wintype, etc.) + + fdest = fsrc + + ( woo-hoo! operator overloading in Csound!) + ( NB an init statement for fsigs is not supported. One day....) + + kflag pvsftw fsig,ifna [,ifnf] + pvsftr fsig,ifna [,ifnf] + + ( this modifies an ~existing~ signal, does not create a new one, + hence no output) + + Re iinit: not implemented yet: and I still need to establish + if it's possible... + */ + +typedef struct { + MYFLT re; + MYFLT im; +} CMPLX; + +struct pvsdat { + int32 N; + int sliding; /* Flag to indicate sliding case */ + int32 NB; + int32 overlap; + int32 winsize; + int wintype; + int32 format; /* fixed for now to AMP:FREQ */ + uint32 framecount; + AUXCH frame; /* RWD MUST always be 32bit floats */ + /* But not in sliding case when MYFLT */ +}; + +/* may be no point supporting Kaiser in an opcode unless we can support + the param too but we can have kaiser in a PVOCEX file. */ + +typedef struct { + OPDS h; + PVSDAT *fsig; /* output signal is an analysis frame */ + MYFLT *ain; /* input sig is audio */ + MYFLT *fftsize; /* params */ + MYFLT *overlap; + MYFLT *winsize; + MYFLT *wintype; + MYFLT *format; /* always PVS_AMP_FREQ at present */ + MYFLT *init; /* not yet implemented */ + /* internal */ + int32 buflen; + float fund,arate; + float RoverTwoPi,TwoPioverR,Fexact; + MYFLT *nextIn; + int32 nI,Ii,IOi; /* need all these ?; double as N and NB */ + int32 inptr; + + AUXCH input; + AUXCH overlapbuf; + AUXCH analbuf; + AUXCH analwinbuf; /* prewin in SDFT case */ + AUXCH oldInPhase; + AUXCH trig; + double *cosine, *sine; + void *setup; +} PVSANAL; + +typedef struct { + OPDS h; + MYFLT *aout; /* audio output signal */ + PVSDAT *fsig; /* input signal is an analysis frame */ + MYFLT *init; /* not yet implemented */ + /* internal */ + /* check these against fsig vals */ + int32 overlap,winsize,fftsize,wintype,format; + /* can we allow variant window tpes? */ + int32 buflen; + MYFLT fund,arate; + MYFLT RoverTwoPi,TwoPioverR,Fexact; + MYFLT *nextOut; + int32 nO,Ii,IOi; /* need all these ?*/ + int32 outptr; + int32 bin_index; /* for phase normalization across frames */ + /* renderer gets all format info from fsig */ + + AUXCH output; + AUXCH overlapbuf; + AUXCH synbuf; + AUXCH analwinbuf; /* may get away with a local alloc and free */ + AUXCH synwinbuf; + AUXCH oldOutPhase; + + void *setup; +} PVSYNTH; + +/* for pvadsyn */ + +typedef struct { + OPDS h; + MYFLT *aout; + PVSDAT *fsig; + MYFLT *n_oscs; + MYFLT *kfmod; + MYFLT *ibin; /* default 0 */ + MYFLT *ibinoffset; /* default 1 */ + MYFLT *init; /* not yet implemented */ + /* internal */ + int32 outptr; + uint32 lastframe; + /* check these against fsig vals */ + int32 overlap,winsize,fftsize,wintype,format,noscs; + int32 maxosc; + float one_over_overlap,pi_over_sr, one_over_sr; + float fmod; + AUXCH a; + AUXCH x; + AUXCH y; + AUXCH amps; + AUXCH lastamps; + AUXCH freqs; + AUXCH outbuf; +} PVADS; + +/* for pvscross */ +typedef struct { + OPDS h; + PVSDAT *fout; + PVSDAT *fsrc; + PVSDAT *fdest; + MYFLT *kamp1; + MYFLT *kamp2; + /* internal */ + int32 overlap,winsize,fftsize,wintype,format; + uint32 lastframe; +} PVSCROSS; + +/* for pvsmaska */ +typedef struct { + OPDS h; + PVSDAT *fout; + PVSDAT *fsrc; + MYFLT *ifn; + MYFLT *kdepth; + /* internal*/ + int32 overlap,winsize,fftsize,wintype,format; + uint32 lastframe; + int nwarned,pwarned; /* range errors for kdepth */ + FUNC *maskfunc; +} PVSMASKA; + +/* for pvsftw, pvsftr */ + +typedef struct { + OPDS h; + MYFLT *kflag; + PVSDAT *fsrc; + MYFLT *ifna; /* amp, required */ + MYFLT *ifnf; /* freq: optional*/ + /* internal */ + int32 overlap,winsize,fftsize,wintype,format; + uint32 lastframe; + FUNC *outfna, *outfnf; +} PVSFTW; + +typedef struct { + OPDS h; + /* no output var*/ + PVSDAT *fdest; + MYFLT *ifna; /* amp, may be 0 */ + MYFLT *ifnf; /* freq: optional*/ + /* internal */ + int32 overlap,winsize,fftsize,wintype,format; + uint32 lastframe; + FUNC *infna, *infnf; + MYFLT *ftablea,*ftablef; +} PVSFTR; + +/* for pvsfread */ +/* wsig pvsread ktimpt,ifilcod */ +typedef struct { + OPDS h; + PVSDAT *fout; + MYFLT *kpos; + MYFLT *ifilno; + MYFLT *ichan; + /* internal */ + int ptr; + int32 overlap,winsize,fftsize,wintype,format; + uint32 chans, nframes,lastframe,chanoffset,blockalign; + MYFLT arate; + float *membase; /* RWD MUST be 32bit: reads file */ +} PVSFREAD; + +/* for pvsinfo */ + +typedef struct { + OPDS h; + MYFLT *ioverlap; + MYFLT *inumbins; + MYFLT *iwinsize; + MYFLT *iformat; + /* internal*/ + PVSDAT *fsrc; +} PVSINFO; + +typedef struct { + OPDS h; + PVSDAT *fout; + PVSDAT *fsrc; +} FASSIGN; + +#endif + diff --git a/7.x/csound/pvfileio.h b/7.x/csound/pvfileio.h new file mode 100644 index 00000000..b05c2277 --- /dev/null +++ b/7.x/csound/pvfileio.h @@ -0,0 +1,167 @@ +/* + pvfileio.h: + + Copyright (C) 2000 Richard Dobson + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +/* pvfileio.h: header file for PVOC_EX file format */ +/* Initial Version 0.1 RWD 25:5:2000 all rights reserved: work in progress! */ + +#ifndef __PVFILEIO_H_INCLUDED +#define __PVFILEIO_H_INCLUDED + +#include "sysdep.h" + +#if defined(WIN32) || defined(_WIN32) || defined(_MSC_VER) + +#include + +#else + +typedef struct +{ + uint32_t Data1; + uint16_t Data2; + uint16_t Data3; + unsigned char Data4[8]; +} GUID; + +typedef struct /* waveformatex */ { + uint16_t wFormatTag; + uint16_t nChannels; + uint32_t nSamplesPerSec; + uint32_t nAvgBytesPerSec; + uint16_t nBlockAlign; + uint16_t wBitsPerSample; + uint16_t cbSize; +} WAVEFORMATEX; + +#endif + +/* NB no support provided for double format (yet) */ + +typedef enum pvoc_wordformat { + PVOC_IEEE_FLOAT, + PVOC_IEEE_DOUBLE +} pvoc_wordformat; + +/* include PVOC_COMPLEX for some parity with SDIF */ + +typedef enum pvoc_frametype { + PVOC_AMP_FREQ = 0, + PVOC_AMP_PHASE, + PVOC_COMPLEX +} pvoc_frametype; + +/* a minimal list */ + +typedef enum pvoc_windowtype { + PVOC_DEFAULT = 0, + PVOC_HAMMING = 0, + PVOC_HANN, + PVOC_KAISER, + PVOC_RECT, + PVOC_CUSTOM +} pv_wtype; + +/* Renderer information: source is presumed to be of this type */ + +typedef enum pvoc_sampletype { + STYPE_16, + STYPE_24, + STYPE_32, + STYPE_IEEE_FLOAT +} pv_stype; + +typedef struct pvoc_data { /* 32 bytes */ + uint16_t wWordFormat; /* pvoc_wordformat */ + uint16_t wAnalFormat; /* pvoc_frametype */ + uint16_t wSourceFormat; /* WAVE_FORMAT_PCM or WAVE_FORMAT_IEEE_FLOAT */ + uint16_t wWindowType; /* pvoc_windowtype */ + uint32_t nAnalysisBins; /* implicit FFT size = (nAnalysisBins-1) * 2 */ + uint32_t dwWinlen; /* analysis winlen, in samples */ + /* NB may be != FFT size */ + uint32_t dwOverlap; /* samples */ + uint32_t dwFrameAlign; /* usually nAnalysisBins * 2 * sizeof(float) */ + float fAnalysisRate; + float fWindowParam; /* default 0.0f unless needed */ +} PVOCDATA; + +typedef struct { + WAVEFORMATEX Format; /* 18 bytes: info for renderer */ + /* as well as for pvoc */ + union { /* 2 bytes */ + uint16_t wValidBitsPerSample; /* as per standard WAVE_EX: */ + /* applies to renderer */ + uint16_t wSamplesPerBlock; + uint16_t wReserved; + } Samples; + uint32_t dwChannelMask; /* 4 bytes: can be used as in */ + /* standrad WAVE_EX */ + GUID SubFormat; /* 16 bytes */ +} WAVEFORMATEXTENSIBLE, *PWAVEFORMATEXTENSIBLE; + +typedef struct { + WAVEFORMATEXTENSIBLE wxFormat; /* 40 bytes */ + uint32_t dwVersion; /* 4 bytes */ + uint32_t dwDataSize; /* 4 bytes: sizeof PVOCDATA data block */ + PVOCDATA data; /* 32 bytes */ +} WAVEFORMATPVOCEX; /* total 80 bytes */ + +/* at least VC++ will give 84 for sizeof(WAVEFORMATPVOCEX), */ +/* so we need our own version */ +#define SIZEOF_FMTPVOCEX (80) +/* for the same reason: */ +#define SIZEOF_WFMTEX (18) +#define PVX_VERSION (1) + +/******* the all-important PVOC GUID + + {8312B9C2-2E6E-11d4-A824-DE5B96C3AB21} + +**************/ + +#ifndef CSOUND_CSDL_H + +extern const GUID KSDATAFORMAT_SUBTYPE_PVOC; + +/* pvoc file handling functions */ + +const char *pvoc_errorstr(CSOUND *); +int32_t init_pvsys(CSOUND *); +int32_t pvoc_createfile(CSOUND *, const char *, + uint32, uint32, uint32, + uint32, int32, int32_t, int32_t, + float, float *, uint32); +int32_t pvoc_openfile(CSOUND *, + const char *filename, void *data_, void *fmt_); +int32_t pvoc_closefile(CSOUND *, int32_t); +int32_t pvoc_putframes(CSOUND *, + int32_t ofd, const float *frame, int32 numframes); +int32_t pvoc_getframes(CSOUND *, + int32_t ifd, float *frames, uint32 nframes); +int32_t pvoc_framecount(CSOUND *, int32_t ifd); +int32_t pvoc_fseek(CSOUND *, int32_t ifd, int32_t offset); +int32_t pvsys_release(CSOUND *); + +#endif /* CSOUND_CSDL_H */ + +#endif /* __PVFILEIO_H_INCLUDED */ + diff --git a/7.x/csound/soundfile.h b/7.x/csound/soundfile.h new file mode 100644 index 00000000..2fb6afd8 --- /dev/null +++ b/7.x/csound/soundfile.h @@ -0,0 +1,279 @@ +/* + soundfile.h: Soundile IO interface + + Copyright (C) 2021 V Lazzarini + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef _SOUNDFILE_H_ +#define _SOUNDFILE_H_ + +#ifdef USE_LIBSNDFILE +#include + +#define SFLIB_FALSE SF_FALSE +#define SFLIB_TRUE SF_TRUE + +#define SFLIB_INSTRUMENT SF_INSTRUMENT + +#ifndef SNDFILE_MP3 +// set missing tokens +#define SF_FORMAT_MPEG 0x230000 /* MPEG-1/2 audio stream */ +#define SF_FORMAT_MPEG_LAYER_I 0x0080 /* MPEG-1 Audio Layer I */ +#define SF_FORMAT_MPEG_LAYER_II 0x0081, /* MPEG-1 Audio Layer II */ +#define SF_FORMAT_MPEG_LAYER_III 0x0082 /* MPEG-2 Audio Layer III */ +#endif + + +/* standard audio encoding types */ +#define AE_CHAR SF_FORMAT_PCM_S8 +#define AE_SHORT SF_FORMAT_PCM_16 +#define AE_24INT SF_FORMAT_PCM_24 +#define AE_LONG SF_FORMAT_PCM_32 +#define AE_UNCH SF_FORMAT_PCM_U8 +#define AE_FLOAT SF_FORMAT_FLOAT +#define AE_DOUBLE SF_FORMAT_DOUBLE +#define AE_ULAW SF_FORMAT_ULAW +#define AE_ALAW SF_FORMAT_ALAW +#define AE_IMA_ADPCM SF_FORMAT_IMA_ADPCM +#define AE_MS_ADPCM SF_FORMAT_MS_ADPCM +#define AE_GSM610 SF_FORMAT_GSM610 +#define AE_VOX SF_FORMAT_VOX_ADPCM +#define AE_G721_32 SF_FORMAT_G721_32 +#define AE_G723_24 SF_FORMAT_G723_24 +#define AE_G723_40 SF_FORMAT_G723_40 +#define AE_DWVW_12 SF_FORMAT_DWVW_12 +#define AE_DWVW_16 SF_FORMAT_DWVW_16 +#define AE_DWVW_24 SF_FORMAT_DWVW_24 +#define AE_DWVW_N SF_FORMAT_DWVW_N +#define AE_DPCM_8 SF_FORMAT_DPCM_8 +#define AE_DPCM_16 SF_FORMAT_DPCM_16 +#define AE_VORBIS SF_FORMAT_VORBIS +#define AE_MPEG SF_FORMAT_MPEG | SF_FORMAT_MPEG_LAYER_III + +#define AE_LAST SF_FORMAT_DPCM_16 /* current last audio encoding value */ + +/* file types */ +#define TYP_WAV (SF_FORMAT_WAV >> 16) +#define TYP_AIFF (SF_FORMAT_AIFF >> 16) +#define TYP_AU (SF_FORMAT_AU >> 16) +#define TYP_RAW (SF_FORMAT_RAW >> 16) +#define TYP_PAF (SF_FORMAT_PAF >> 16) +#define TYP_SVX (SF_FORMAT_SVX >> 16) +#define TYP_NIST (SF_FORMAT_NIST >> 16) +#define TYP_VOC (SF_FORMAT_VOC >> 16) +#define TYP_IRCAM (SF_FORMAT_IRCAM >> 16) +#define TYP_W64 (SF_FORMAT_W64 >> 16) +#define TYP_MAT4 (SF_FORMAT_MAT4 >> 16) +#define TYP_MAT5 (SF_FORMAT_MAT5 >> 16) +#define TYP_PVF (SF_FORMAT_PVF >> 16) +#define TYP_XI (SF_FORMAT_XI >> 16) +#define TYP_HTK (SF_FORMAT_HTK >> 16) +#define TYP_SDS (SF_FORMAT_SDS >> 16) +#define TYP_AVR (SF_FORMAT_AVR >> 16) +#define TYP_WAVEX (SF_FORMAT_WAVEX >> 16) +#define TYP_SD2 (SF_FORMAT_SD2 >> 16) +#define TYP_FLAC (SF_FORMAT_FLAC >> 16) +#define TYP_CAF (SF_FORMAT_CAF >> 16) +#define TYP_WVE (SF_FORMAT_WVE >> 16) +#define TYP_OGG (SF_FORMAT_OGG >> 16) +#define TYP_MPEG (SF_FORMAT_MPEG >> 16) +#define TYP_MPC2K (SF_FORMAT_MPC2K >> 16) +#define TYP_RF64 (SF_FORMAT_RF64 >> 16) + +#define FORMAT2SF(x) ((int) (x)) +#define SF2FORMAT(x) ((int) (x) & 0xFFFF) +#define TYPE2SF(x) ((int) (x) << 16) +#define TYP2SF(x) ((int) (x) << 16) +#define SF2TYPE(x) ((int) (x & SF_FORMAT_TYPEMASK) >> 16) +#define TYPE2ENC(x) ((int) (x & SF_FORMAT_SUBMASK)) +#define ENDIANESSBITS (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK) + +#else +#include + +#define AE_CHAR 10 +#define AE_SHORT 20 +#define AE_24INT 30 +#define AE_LONG 40 +#define AE_UNCH 50 +#define AE_FLOAT 60 +#define AE_DOUBLE 70 +#define AE_ULAW 80 +#define AE_ALAW 90 +#define AE_IMA_ADPCM 100 +#define AE_MS_ADPCM 110 +#define AE_GSM610 120 +#define AE_VOX 130 +#define AE_G721_32 140 +#define AE_G723_24 150 +#define AE_G723_40 160 +#define AE_DWVW_12 170 +#define AE_DWVW_16 180 +#define AE_DWVW_24 190 +#define AE_DWVW_N 200 +#define AE_DPCM_8 210 +#define AE_DPCM_16 220 +#define AE_VORBIS 230 +#define AE_MPEG 240 + +#define AE_LAST SF_FORMAT_DPCM_16 /* current last audio encoding value */ + +/* file types */ +#define TYP_WAV (0) +#define TYP_AIFF (1) +#define TYP_AU (2) +#define TYP_RAW (3) +#define TYP_PAF (4) +#define TYP_SVX (5) +#define TYP_NIST (6) +#define TYP_VOC (7) +#define TYP_IRCAM (8) +#define TYP_W64 (9) +#define TYP_MAT4 (10) +#define TYP_MAT5 (11) +#define TYP_PVF (12) +#define TYP_XI (13) +#define TYP_HTK (14) +#define TYP_SDS (15) +#define TYP_AVR (16) +#define TYP_WAVEX (17) +#define TYP_SD2 (18) +#define TYP_FLAC (19) +#define TYP_CAF (20) +#define TYP_WVE (21) +#define TYP_OGG (22) +#define TYP_MPC2K (23) +#define TYP_RF64 (24) +#define TYP_MPEG (25) + +#define FORMAT2SF(x) ((int) (x)) +#define SF2FORMAT(x) ((int) (x)) +#define TYPE2SF(x) ((int) (x)) +#define TYP2SF(x) ((int) (x)) +#define SF2TYPE(x) ((int) (x)) +#define TYPE2ENC(x) ((int) (x)) +#define ENDIANESSBITS 0 + +#define SNDFILE void +#define SFLIB_FALSE 0 +#define SFLIB_TRUE 1 +#define SFC_SET_CLIPPING 0 +#define SFC_SET_VBR_ENCODING_QUALITY 0 +#define SFC_SET_ADD_PEAK_CHUNK 0 +#define SFC_SET_DITHER_ON_WRITE 0 +#define SFC_SET_NORM_DOUBLE 0 +#define SFC_SET_NORM_FLOAT 0 +#define SFC_GET_SIGNAL_MAX 0 +#define SFC_CALC_NORM_SIGNAL_MAX 0 +#define SFC_GET_MAX_ALL_CHANNELS 0 +#define SFC_CALC_NORM_MAX_ALL_CHANNELS 0 +#define SFC_SET_UPDATE_HEADER_AUTO 0 +#define SFC_SET_ADD_PEAK_CHUNK 0 +#define SFC_UPDATE_HEADER_NOW 0 +#define SFC_GET_INSTRUMENT 0 + +enum + { SF_STR_TITLE, + SF_STR_COPYRIGHT, + SF_STR_SOFTWARE, + SF_STR_ARTIST, + SF_STR_COMMENT, + SF_STR_DATE, + SF_STR_ALBUM, + SF_STR_LICENSE, + SF_STR_TRACKNUMBER, + SF_STR_GENRE + } ; + + +enum { SFM_READ = 0, SFM_WRITE}; + +#define SFCLIB_GET_INSTRUMENT 0 +enum + { + SF_LOOP_NONE = 800, + SF_LOOP_FORWARD, + SF_LOOP_BACKWARD, + SF_LOOP_ALTERNATING + } ; + +typedef struct +{ + int gain ; + char basenote, detune ; + char velocity_lo, velocity_hi ; + char key_lo, key_hi ; + int loop_count ; + + struct + { + int mode ; + unsigned int start ; + unsigned int end ; + unsigned int count ; + } loops [16] ; +} SFLIB_INSTRUMENT ; + +typedef long sf_count_t; + +#endif // USE_LIBSNDFILE + +#ifdef USE_DOUBLE +#define sflib_write_MYFLT sflib_write_double +#define sflib_writef_MYFLT sflib_writef_double +#define sflib_read_MYFLT sflib_read_double +#define sflib_readf_MYFLT sflib_readf_double +#else +#define sflib_write_MYFLT sflib_write_float +#define sflib_writef_MYFLT sflib_writef_float +#define sflib_read_MYFLT sflib_read_float +#define sflib_readf_MYFLT sflib_readf_float +#endif + +typedef struct sflib_info { + long frames ; + int samplerate ; + int channels ; + int format ; +} SFLIB_INFO; + + +#ifdef __cplusplus +extern "C" { +#endif + int sflib_command (void *handle, int cmd, void *data, int datasize); + void *sflib_open(const char *path, int mode, SFLIB_INFO *sfinfo); + void *sflib_open_fd(int fd, int mode, SFLIB_INFO *sfinfo, int close_desc); + int sflib_close(void *sndfile); + long sflib_seek(void *handle, long frames, int whence); + long sflib_read_float(void *sndfile, float *ptr, long items); + long sflib_readf_float(void *handle, float *ptr, long frames); + long sflib_read_double(void *sndfile, double *ptr, long items); + long sflib_readf_double(void *handle, double *ptr, long frames); + long sflib_write_float(void *sndfile, float *ptr, long items); + long sflib_writef_float(void *handle, float *ptr, long frames); + long sflib_write_double(void *handle, double *ptr, long items); + long sflib_writef_double(void *handle, double *ptr, long frames); + int sflib_set_string(void *sndfile, int str_type, const char* str); + const char *sflib_strerror(void *); +#ifdef __cplusplus +} +#endif +#endif /* _SOUNDFILE_H_ */ diff --git a/7.x/csound/soundio.h b/7.x/csound/soundio.h new file mode 100644 index 00000000..5f96f9b6 --- /dev/null +++ b/7.x/csound/soundio.h @@ -0,0 +1,79 @@ +/* + soundio.h: + + Copyright (C) 1991, 2000 Barry Vercoe, Richard Dobson + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + /* SOUNDIO.H */ +#ifndef CSOUND_SOUNDIO_H +#define CSOUND_SOUNDIO_H + +#include "soundfile.h" + + +#ifdef WIN32 +#define IOBUFSAMPS 4096 /* default sampframes in audio iobuf, -b settable */ +#define IODACSAMPS 16384 /* default samps in hardware buffer, -B settable */ +#elif defined(NeXT) || defined(__MACH__) +#define IOBUFSAMPS 1024 /* default sampframes in audio iobuf, -b settable */ +#define IODACSAMPS 4096 /* default samps in hardware buffer, -B settable */ +#elif defined(ANDROID) +#define IOBUFSAMPS 2048 /* default sampframes in audio iobuf, -b settable */ +#define IODACSAMPS 4096 /* default samps in hardware buffer, -B settable */ +#else +#define IOBUFSAMPS 256 /* default sampframes in audio iobuf, -b settable */ +#define IODACSAMPS 1024 /* default samps in hardware buffer, -B settable */ +#endif + +#define SNDINBUFSIZ 4096 /* soundin bufsize; must be > sizeof(SFHEADER), */ + /* but small is kind to net rexec */ +#define MAXSNDNAME 1024 + +#ifdef __cplusplus +extern "C" { +#endif + +/* generic sound input structure */ + +typedef struct { + void *sinfd; /* sound file handle */ + MYFLT *inbufp, *bufend; /* current buffer position, end of buf */ + void *fd; /* handle returned by csoundFileOpen() */ + int bufsmps; /* number of mono samples in buffer */ + int format; /* sample format (AE_SHORT, etc.) */ + int channel; /* requested channel (ALLCHNLS: all) */ + int nchanls; /* number of channels in file */ + int sampframsiz; /* sample frame size in bytes */ + int filetyp; /* file format (TYP_WAV, etc.) */ + int analonly; /* non-zero for analysis utilities */ + int endfile; /* end of file reached ? non-zero: yes */ + int sr; /* sample rate in Hz */ + int do_floatscaling; /* scale floats by fscalefac ? 0: no */ + int64_t audrem, framesrem, getframes; /* samples, frames, frames */ + MYFLT fscalefac; + MYFLT skiptime; + char sfname[MAXSNDNAME]; + MYFLT inbuf[SNDINBUFSIZ]; +} SOUNDIN; + +#ifdef __cplusplus +} +#endif + +#endif /* CSOUND_SOUNDIO_H */ diff --git a/7.x/csound/sysdep.h b/7.x/csound/sysdep.h new file mode 100644 index 00000000..875350bb --- /dev/null +++ b/7.x/csound/sysdep.h @@ -0,0 +1,587 @@ +/* + sysdep.h: + + Copyright (C) 1991 Barry Vercoe, John ffitch + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef CSOUND_SYSDEP_H +#define CSOUND_SYSDEP_H + +/* check for the presence of a modern compiler (for use of certain features) */ +#if defined(WIN32) +#if !defined(locale_t) +typedef void *locale_t; +#endif +#endif + +#include +/* this checks for 64BIT builds */ +#if defined(__MACH__) || defined(LINUX) +#if ( __WORDSIZE == 64 ) || defined(__x86_64__) || defined(__amd64__) +#define B64BIT +#endif +#endif + +#if defined(WIN32) +#if _WIN64 +#define B64BIT +#endif +#endif + + + +#ifdef HAVE_GCC3 +# undef HAVE_GCC3 +#endif +#ifdef HAVE_C99 +# undef HAVE_C99 +#endif +#if (defined(__GNUC__) && (__GNUC__ >= 3)) +# define HAVE_C99 1 +# if defined(__BUILDING_LIBCSOUND) || defined(CSOUND_CSDL_H) +# ifndef _ISOC99_SOURCE +# define _ISOC99_SOURCE 1 +# endif +# ifndef _ISOC9X_SOURCE +# define _ISOC9X_SOURCE 1 +# endif +# endif +# if !(defined(__MACH__) && (__GNUC__ == 3) && (__GNUC_MINOR__ < 2)) +# define HAVE_GCC3 1 +# endif +#elif (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) +# define HAVE_C99 1 +#endif + +#if defined(__GNUC__) +# if defined(__GNUC_PATCHLEVEL__) +# define __GNUC_VERSION__ (__GNUC__ * 10000 \ + + __GNUC_MINOR__ * 100 \ + + __GNUC_PATCHLEVEL__) +# else +# define __GNUC_VERSION__ (__GNUC__ * 10000 \ + + __GNUC_MINOR__ * 100) +# endif +#endif + +#ifndef CABBAGE +#ifdef MSVC +typedef __int32 int32; +typedef __int16 int16; +typedef unsigned __int32 uint32; +typedef unsigned __int16 uint16; +#else +#include +#if defined(__HAIKU__) && defined(__HAIKU_CONFLICT) + /* Haiku has different typedefs -- relevant to rthaiku and network*/ + #include +#else +typedef int_least32_t int32; +typedef int_least64_t int64; +typedef int_least16_t int16; +typedef uint_least32_t uint32; +typedef uint_least16_t uint16; +#endif +#endif +#endif + +#if defined(HAVE_PTHREAD_SPIN_LOCK) +#include +#endif + +#ifdef __MACH__ +#include +#endif + +#if !defined(USE_DOUBLE) +#if !defined(_MSC_VER) +#include "float-version.h" +#else +#define USE_DOUBLE +#endif +#endif + +#ifdef USE_DOUBLE +/* Defined here as Android does not have log2 functions */ +#define MYRECIPLN2 1.442695040888963407359924681001892137426 /* 1.0/log(2) */ +#define LOG2(a) (MYRECIPLN2*log(a)) /* floating point logarithm base 2 */ + + #define ACOS acos + #define ASIN asin + #define ATAN atan + #define ATAN2 atan2 + #define COS cos + #define SIN sin + #define TAN tan + #define COSH cosh + #define SINH sinh + #define TANH tanh + #define ACOSH acosh + #define ASINH asinh + #define ATANH atanh + #define EXP exp + #define LOG log + #define LOG10 log10 + /* #define LOG2 log2 */ + #define POWER pow + #define SQRT sqrt + #define HYPOT hypot + #define FABS fabs + #define FLOOR floor + #define CEIL ceil + #define FMOD fmod + #define MODF modf +#else +/* Defined here as Android does not have log2 functions */ +#define MYRECIPLN2 1.442695040888963407359924681001892137426 /* 1.0/log(2) */ +#define LOG2(a) (MYRECIPLN2*logf(a)) /* floating point logarithm base 2 */ + + #define ACOS acosf + #define ASIN asinf + #define ATAN atanf + #define ATAN2 atan2f + #define COS cosf + #define SIN sinf + #define TAN tanf + #define COSH coshf + #define SINH sinhf + #define TANH tanhf + #define ACOSH acoshf + #define ASINH asinhf + #define ATANH atanhf + #define EXP expf + #define LOG logf + #define LOG10 log10f + /* #define LOG2 log2f */ + #define POWER powf + #define SQRT sqrtf + #define HYPOT hypotf + #define FABS(x) fabsf(FL(x)) + #define FLOOR floorf + #define CEIL ceilf + #define FMOD fmodf + #define MODF modff +#endif + +// #include +#include +#include +#include +#if defined(HAVE_FCNTL_H) || defined(__unix) || defined(__unix__) +#include +#endif +#if defined(HAVE_UNISTD_H) || defined(__unix) || defined(__unix__) +#include +#endif + +/* Experiment with doubles or floats */ + +#ifndef __MYFLT_DEF +# define __MYFLT_DEF +# ifndef USE_DOUBLE +# define MYFLT float +# else +# define MYFLT double +# endif +#endif + +/* Aligning to double boundaries, should work with MYFLT as float or double */ +#define CS_FLOAT_ALIGN(x) ((int)(x + sizeof(MYFLT)-1) & (~(sizeof(MYFLT)-1))) + +#if defined(__BUILDING_LIBCSOUND) || defined(CSOUND_CSDL_H) + +#define FL(x) ((MYFLT) (x)) + +/* find out operating system if not specified on the command line */ + +#if defined(_WIN32) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 1 +# endif +#elif (defined(linux) || defined(__linux)) && !defined(LINUX) +# define LINUX 1 +#endif + +#if defined(WIN32) && defined(_MSC_VER) && !defined(__GNUC__) +# ifndef MSVC +# define MSVC 1 +# endif +#elif defined(MSVC) +# undef MSVC +#endif + +/* inline keyword: always available in C++, C99, and GCC 3.x and above */ +/* add any other compiler that supports 'inline' */ + +#if !(defined(__cplusplus) || defined(inline)) +# if defined(HAVE_C99) || defined(HAVE_GCC3) +# if defined(__GNUC__) && defined(__STRICT_ANSI__) +# define inline __inline__ +# endif +# elif defined(MSVC) +# define inline __inline +# else +# define inline +# endif +#endif + +#define DIRSEP '/' +#ifdef WIN32 +# undef DIRSEP +# define DIRSEP '\\' +# if !defined(O_NDELAY) +# define O_NDELAY (0) +# endif +# include +#else +# ifdef DOSGCC +# if !defined(O_NDELAY) +# define O_NDELAY (0) +# endif +# endif +# ifdef HAVE_SYS_TYPES_H +# include +# endif +/* RWD for WIN32 on VC++ */ +#endif +#ifndef MSVC +# include +#endif +#include + +#endif /* __BUILDING_LIBCSOUND || CSOUND_CSDL_H */ + +#ifdef WIN32 +# define ENVSEP ';' +#else +# define ENVSEP ':' +#endif +/* standard integer types */ + +#if defined(USE_GUSI2) +/* When compiling with GUSI on MacOS 9 (for Python), */ +/* all of the other integer types are already defined */ +typedef int64_t int_least64_t; +typedef uint64_t uint_least64_t; +#elif defined(HAVE_STDINT_H) || defined(HAVE_C99) +# include + +# if defined(__CYGWIN__) +#define __int8 char +#define __int16 short +#define __int32 int +#define __int64 long long +# endif +#else +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef short int16_t; +typedef unsigned short uint16_t; +typedef int int32_t; +typedef unsigned int uint32_t; +# if defined(__GNUC__) || !defined(WIN32) +typedef long long int64_t; +typedef unsigned long long uint64_t; +typedef long long int_least64_t; +typedef unsigned long long uint_least64_t; +# else +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +typedef __int64 int_least64_t; +typedef unsigned __int64 uint_least64_t; +# endif +#if !defined(_MSC_VER) +typedef long intptr_t; +typedef unsigned long uintptr_t; +#endif +#endif /* !(USE_GUSI2 || HAVE_STDINT_H || HAVE_C99) */ + + + +/* function attributes */ + +#if defined(HAVE_GCC3) && !defined(SWIG) +/* deprecated function, variable, or type that is to be removed eventually */ +# define CS_DEPRECATED __attribute__ ((__deprecated__)) +/* a function that should not be inlined */ +# define CS_NOINLINE __attribute__ ((__noinline__)) +/* a function that never returns (e.g. csoundDie()) */ +# define CS_NORETURN __attribute__ ((__noreturn__)) +/* printf-style function with first argument as format string */ +# define CS_PRINTF1 __attribute__ ((__format__ (__printf__, 1, 2))) +/* printf-style function with second argument as format string */ +# define CS_PRINTF2 __attribute__ ((__format__ (__printf__, 2, 3))) +/* printf-style function with third argument as format string */ +# define CS_PRINTF3 __attribute__ ((__format__ (__printf__, 3, 4))) +/* a function with no side effects or dependencies on volatile data */ +# define CS_PURE __attribute__ ((__pure__)) +#else +# define CS_DEPRECATED +# define CS_NOINLINE +# define CS_NORETURN +# define CS_PRINTF1 +# define CS_PRINTF2 +# define CS_PRINTF3 +# define CS_PURE +#endif +#if defined(__clang__) || defined(HAVE_GCC3) +# define LIKELY(x) __builtin_expect(!!(x),1) +# define UNLIKELY(x) __builtin_expect(!!(x),0) +#else +# define LIKELY(x) x +# define UNLIKELY(x) x +#endif + +#if defined(__BUILDING_LIBCSOUND) || defined(CSOUND_CSDL_H) + +/* macros for converting floats to integers */ +/* MYFLT2LONG: converts with unspecified rounding */ +/* MYFLT2LRND: rounds to nearest integer */ + +#ifdef USE_LRINT +# ifndef USE_DOUBLE +# define MYFLT2LONG(x) (x > LONG_MIN && x < LONG_MAX ? \ + (int32) lrintf((float) (x)) : 0) +# define MYFLT2LRND(x) (x > LONG_MIN && x < LONG_MAX ? \ + (int32) lrintf((float) (x)) : 0) +# else +# define MYFLT2LONG(x) (x > LONG_MIN && x < LONG_MAX ? \ + (int32) lrint((double) (x)) : 0) +# define MYFLT2LRND(x) (x > LONG_MIN && x < LONG_MAX ? \ + (int32) lrint((double) (x)) : 0) +# define MYFLT2LONG64(x) (x > LONG_MIN && x < LONG_MAX ? \ + (int64_t) lrintl((double) (x)) : 0) +# define MYFLT2LRND64(x) (x > LONG_MIN && x < LONG_MAX ? \ + (int64_t) lrintl((double) (x)) : 0) +# endif +#elif defined(MSVC) +#include +# ifndef USE_DOUBLE +// From Agner Fog optimisation manuals p.144 +static inline int MYFLT2LONG (float const x) { + return _mm_cvtss_si32 (_mm_load_ss (&x)); +} + +static inline int MYFLT2LRND (float const x) { + return _mm_cvtss_si32 (_mm_load_ss (&x)); +} + +# else +static inline int MYFLT2LONG (double const x) { + return _mm_cvtsd_si32 (_mm_load_sd (&x)); +} + +static inline int MYFLT2LRND (double const x) { + return _mm_cvtsd_si32 (_mm_load_sd (&x)); +} +# endif +#else +# ifndef USE_DOUBLE +# define MYFLT2LONG(x) ((int32) (x)) +# if defined(HAVE_GCC3) && defined(__i386__) && !defined(__ICC) +# define MYFLT2LRND(x) ((int32) lrintf((float) (x))) +# else +static inline int32 MYFLT2LRND(float fval) +{ + return ((int32) (fval + (fval < 0.0f ? -0.5f : 0.5f))); +} +# endif +# else +# define MYFLT2LONG(x) ((int32) (x)) +# if defined(HAVE_GCC3) && defined(__i386__) && !defined(__ICC) +# define MYFLT2LRND(x) ((int32) lrint((double) (x))) +# else + +static inline int32 MYFLT2LRND(double fval) +{ + return ((int32) (fval + (fval < 0.0 ? -0.5 : 0.5))); +} + +static inline int64 MYFLT2LRND64(double fval) +{ + return ((int64) (fval + (fval < 0.0 ? -0.5 : 0.5))); +} + +# endif +# endif +#endif + +/* inline functions and macros for clamping denormals to zero */ + +#if defined(__i386__) || defined(MSVC) +static inline float csoundUndenormalizeFloat(float x) +{ + volatile float tmp = 1.0e-30f; + return ((x + 1.0e-30f) - tmp); +} + +static inline double csoundUndenormalizeDouble(double x) +{ + volatile double tmp = 1.0e-200; + return ((x + 1.0e-200) - tmp); +} +#else +# define csoundUndenormalizeFloat(x) x +# define csoundUndenormalizeDouble(x) x +#endif + +#ifndef USE_DOUBLE +# define csoundUndenormalizeMYFLT csoundUndenormalizeFloat +#else +# define csoundUndenormalizeMYFLT csoundUndenormalizeDouble +#endif + +#endif /* __BUILDING_LIBCSOUND || CSOUND_CSDL_H */ + +// This is wrong..... needs thought +/* #ifdef HAVE_SPRINTF_L */ +/* # define CS_SPRINTF sprintf_l */ +/* #elseif HAVE__SPRINT_L */ +/* /\* this would be the case for the Windows locale aware function *\/ */ +/* # define CS_SPRINTF _sprintf_l */ +/* #else */ +# define CS_SPRINTF cs_sprintf +# define CS_SSCANF cs_sscanf +/* #endif */ + +#if !defined(HAVE_STRLCAT) && !defined(strlcat) +size_t strlcat(char *dst, const char *src, size_t siz); +#endif +char *strNcpy(char *dst, const char *src, size_t siz); + +/* atomics */ +#if defined(MSVC) +#define ATOMIC_SET(var, val) InterlockedExchange(&var, val); +#elif defined(HAVE_ATOMIC_BUILTIN) +#define ATOMIC_SET(var, val) __atomic_store_n(&var, val, __ATOMIC_SEQ_CST); +#else +#define ATOMIC_SET(var, val) var = val; +#endif + +#if defined(MSVC) +#define ATOMIC_SET8(var, val) InterlockedExchange8(&var, val); +#elif defined(HAVE_ATOMIC_BUILTIN) +#define ATOMIC_SET8(var, val) __atomic_store_n(&var, val,__ATOMIC_SEQ_CST); +#else +#define ATOMIC_SET8(var, val) var = val; +#endif + +#ifdef MSVC +#define ATOMIC_GET(var) InterlockedExchangeAdd(&var, 0) +#elif defined(HAVE_ATOMIC_BUILTIN) +#define ATOMIC_GET(var) __atomic_load_n(&var, __ATOMIC_SEQ_CST) +#else +#define ATOMIC_GET(var) var +#endif + +#ifdef MSVC +#define ATOMIC_GET8(var) InterlockedExchangeAdd8(&var, 0) +#elif defined(HAVE_ATOMIC_BUILTIN) +#define ATOMIC_GET8(var) __atomic_load_n(&var, __ATOMIC_SEQ_CST) +#else +#define ATOMIC_GET8(var) var +#endif + +#ifdef MSVC +#define ATOMIC_DECR(var) InterlockedExchangeAdd(&var, -1) +#elif defined(HAVE_ATOMIC_BUILTIN) +#define ATOMIC_DECR(var) __atomic_sub_fetch(&var, 1, __ATOMIC_SEQ_CST) +#else +#define ATOMIC_DECR(var) var -= 1 +#endif + +#ifdef MSVC +#define ATOMIC_INCR(var) InterlockedExchangeAdd(&var, 1) +#elif defined(HAVE_ATOMIC_BUILTIN) +#define ATOMIC_INCR(var) __atomic_add_fetch(&var, 1, __ATOMIC_SEQ_CST) +#else +#define ATOMIC_INCR(var) var += 1 +#endif + +#ifdef MSVC +#define ATOMIC_SUB(var, val) InterlockedExchangeAdd(&var, -val) +#elif defined(HAVE_ATOMIC_BUILTIN) +#define ATOMIC_SUB(var, val) __atomic_sub_fetch(&var, val, __ATOMIC_SEQ_CST) +#else +#define ATOMIC_SUB(var, val) var -= val +#endif + +#ifdef MSVC +#define ATOMIC_ADD(var, val) InterlockedExchangeAdd(&var, val) +#elif defined(HAVE_ATOMIC_BUILTIN) +#define ATOMIC_ADD(var, val) __atomic_add_fetch(&var, val, __ATOMIC_SEQ_CST) +#else +#define ATOMIC_ADD(var, val) var += val +#endif + +#if defined(MSVC) +#define ATOMIC_CMP_XCH(val, newVal, oldVal) \ + (InterlockedCompareExchange(val, newVal, oldVal) != oldVal) +#elif defined(HAVE_ATOMIC_BUILTIN) +#define ATOMIC_CMP_XCH(val, newVal, oldVal) \ + !(__atomic_compare_exchange(val, (long *) &oldVal, &newVal, 0, \ + __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) +#else /* FIXME: no atomics, what to do? */ +#define ATOMIC_CMP_XCH(val, newVal, oldVal) (*val = newVal) != oldVal +#endif + +#if defined(WIN32) +typedef int32_t spin_lock_t; +#define SPINLOCK_INIT 0 + +#elif defined(MACOSX) +#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12 +#include +typedef struct os_unfair_lock_s spin_lock_t; +#define SPINLOCK_INIT {0} +#else +#include +typedef int32_t spin_lock_t; +#define SPINLOCK_INIT 0 +#endif // MAC_OS_X_VERSION_MIN_REQUIRED + +#elif defined(__GNUC__) && defined(HAVE_PTHREAD_SPIN_LOCK) +typedef pthread_spinlock_t spin_lock_t; +#define SPINLOCK_INIT PTHREAD_SPINLOCK_INITIALIZER +#elif defined(__GNUC__) && defined(HAVE_ATOMIC_BUILTIN) +typedef char spin_lock_t; +#define SPINLOCK_INIT 0 + +#else +typedef int32_t spin_lock_t; +#define SPINLOCK_INIT 0 +#endif + +/* The ignore_value() macro is taken from GNULIB ignore-value.h, + licensed under the terms of the LGPLv2+ + Normally casting an expression to void discards its value, but GCC + versions 3.4 and newer have __attribute__ ((__warn_unused_result__)) + which may cause unwanted diagnostics in that case. Use __typeof__ + and __extension__ to work around the problem, if the workaround is + known to be needed. */ +#if 3 < __GNUC__ + (4 <= __GNUC_MINOR__) +# define ignore_value(x) \ + (__extension__ ({ __typeof__ (x) __x = (x); (void) __x; })) +#else +# define ignore_value(x) ((void) (x)) +#endif + + +#endif /* CSOUND_SYSDEP_H */ diff --git a/7.x/csound/text.h b/7.x/csound/text.h new file mode 100644 index 00000000..ad24ca3a --- /dev/null +++ b/7.x/csound/text.h @@ -0,0 +1,140 @@ +/* + text.h: + + Copyright (C) 1999 John ffitch + Jan 27 2005: Replaced with new implementation by Istvan Varga + Dec 25 2007: Added gettext support by John ffitch + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef CSOUND_TEXT_H +#define CSOUND_TEXT_H +#ifndef __GNUC__ +# define __attribute__(x) /*NOTHING*/ +#endif + + +/* list of languages */ + + typedef enum { + CSLANGUAGE_DEFAULT = 0, + CSLANGUAGE_AFRIKAANS, + CSLANGUAGE_ALBANIAN, + CSLANGUAGE_ARABIC, + CSLANGUAGE_ARMENIAN, + CSLANGUAGE_ASSAMESE, + CSLANGUAGE_AZERI, + CSLANGUAGE_BASQUE, + CSLANGUAGE_BELARUSIAN, + CSLANGUAGE_BENGALI, + CSLANGUAGE_BULGARIAN, + CSLANGUAGE_CATALAN, + CSLANGUAGE_CHINESE, + CSLANGUAGE_CROATIAN, + CSLANGUAGE_CZECH, + CSLANGUAGE_DANISH, + CSLANGUAGE_DUTCH, + CSLANGUAGE_ENGLISH_UK, + CSLANGUAGE_ENGLISH_US, + CSLANGUAGE_ESTONIAN, + CSLANGUAGE_FAEROESE, + CSLANGUAGE_FARSI, + CSLANGUAGE_FINNISH, + CSLANGUAGE_FRENCH, + CSLANGUAGE_GEORGIAN, + CSLANGUAGE_GERMAN, + CSLANGUAGE_GREEK, + CSLANGUAGE_GUJARATI, + CSLANGUAGE_HEBREW, + CSLANGUAGE_HINDI, + CSLANGUAGE_HUNGARIAN, + CSLANGUAGE_ICELANDIC, + CSLANGUAGE_INDONESIAN, + CSLANGUAGE_ITALIAN, + CSLANGUAGE_JAPANESE, + CSLANGUAGE_KANNADA, + CSLANGUAGE_KASHMIRI, + CSLANGUAGE_KAZAK, + CSLANGUAGE_KONKANI, + CSLANGUAGE_KOREAN, + CSLANGUAGE_LATVIAN, + CSLANGUAGE_LITHUANIAN, + CSLANGUAGE_MACEDONIAN, + CSLANGUAGE_MALAY, + CSLANGUAGE_MALAYALAM, + CSLANGUAGE_MANIPURI, + CSLANGUAGE_MARATHI, + CSLANGUAGE_NEPALI, + CSLANGUAGE_NORWEGIAN, + CSLANGUAGE_ORIYA, + CSLANGUAGE_POLISH, + CSLANGUAGE_PORTUGUESE, + CSLANGUAGE_PUNJABI, + CSLANGUAGE_ROMANIAN, + CSLANGUAGE_RUSSIAN, + CSLANGUAGE_SANSKRIT, + CSLANGUAGE_SERBIAN, + CSLANGUAGE_SINDHI, + CSLANGUAGE_SLOVAK, + CSLANGUAGE_SLOVENIAN, + CSLANGUAGE_SPANISH, + CSLANGUAGE_SWAHILI, + CSLANGUAGE_SWEDISH, + CSLANGUAGE_TAMIL, + CSLANGUAGE_TATAR, + CSLANGUAGE_TELUGU, + CSLANGUAGE_THAI, + CSLANGUAGE_TURKISH, + CSLANGUAGE_UKRAINIAN, + CSLANGUAGE_URDU, + CSLANGUAGE_UZBEK, + CSLANGUAGE_VIETNAMESE, + CSLANGUAGE_COLUMBIAN +} cslanguage_t; + +#ifdef __cplusplus +extern "C" { +#endif + void init_getstring(void*); + PUBLIC char *csoundLocalizeString(const char *s) + __attribute__ ((format_arg (1))); + PUBLIC char* cs_strtok_r(char* str, char* sep, char** lasts); + PUBLIC double cs_strtod(char* nptr, char** endptr); + PUBLIC int cs_sprintf(char *str, const char *format, ...); + PUBLIC int cs_sscanf(char *str, const char *format, ...); +#ifdef __cplusplus +} +#endif + + + /* VL commenting this out so ALL uses of Str(x) + call LocalizeString() [which might be a stub] + This would allows us to keep an eye on + -Wformat-security warnings + */ +//#ifdef GNU_GETTEXT +# define Str(x) csoundLocalizeString(x) +//#else +//# define Str(x) (x) +//#endif + +#define Str_noop(x) x + + +#endif /* CSOUND_TEXT_H */ diff --git a/7.x/csound/ugen.h b/7.x/csound/ugen.h new file mode 100644 index 00000000..130e060c --- /dev/null +++ b/7.x/csound/ugen.h @@ -0,0 +1,101 @@ +/** API Functions for creating instances of Csound Opcodes as + * individual unit generators. UGEN's should also be extensible + * by host languages at runtime. + * + * Workflow: + * + * - User creates a CSOUND instance + * - User creates a UGEN_FACTORY + * - User lists OENTRYs + * - User uses OENTRY with UGEN_FACTORY to create UGEN instance. + * - User connects arguments together using ugen_set_input and ugen_set_output. + * This is the process to dynamically create a graph. + * - User uses graph of UGENs and schedule to run with a CSOUND instance. + * - User turns off graph. + * + * - context: required for things like hold, releasing, etc. + * */ + +#pragma once + +#include "csoundCore.h" +#include + +typedef struct { + CSOUND* csound; + INSDS* insds; + OENTRY* oentry; + void *opcodeMem; + MYFLT* data; + OPDS* opds; + CS_VAR_POOL* inPool; + CS_VAR_POOL* outPool; + int inPoolCount; + int outPoolCount; + int inocount; +} UGEN; + +typedef struct { + INSDS* insds; +} UGEN_CONTEXT; + +typedef struct { + CSOUND* csound; + INSDS* insds; +} UGEN_FACTORY; + +/** Creates a UGEN_FACTORY, used to list available UGENs (Csound Opcodes), + * as well as create instances of UGENs. User should configure the CSOUND + * instance for sr and ksmps before creating a factory. */ +PUBLIC UGEN_FACTORY* ugen_factory_new(CSOUND* csound); + +/* Delete a UGEN_FACTORY */ +PUBLIC bool ugen_factory_delete(CSOUND* csound, UGEN_FACTORY* factory); + +/* +PUBLIC UGEN_CONTEXT* ugen_context_new(UGEN_FACTORY* factory); + +PUBLIC UGEN_CONTEXT* ugen_context_delete(UGEN_FACTORY* factory); +*/ + +/** Create a new UGEN, using the given UGEN_FACTORY and OENTRY */ +PUBLIC UGEN* ugen_new(UGEN_FACTORY* factory, char* opName, char* outargTypes, char* inargTypes); + + +/** Set output argument pointer for opcode's data struct by index. + * TODO - consider using CS_VARIABLE instead of void* so that + * type check can happen here. + * */ +PUBLIC bool ugen_set_output(UGEN* ugen, int index, void* arg); + +/** Set input argument pointer for opcode's data struct by index. + * TODO - consider using CS_VARIABLE instead of void* so that + * type check can happen here. + * */ +PUBLIC bool ugen_set_input(UGEN* ugen, int index, void* arg); + +/** Set value for output argument for opcode's data struct by index. Assumes UGEN arguments are not set by reference. + * + * TODO - consider using CS_VARIABLE instead of void* so that + * type check can happen here. Also, would provide hook to use + * CS_TYPE's copyValue function. + */ +PUBLIC bool ugen_set_output_value(UGEN* ugen, int index, void* arg); + +/** Set value for input argument for opcode's data struct by index. Assumes UGEN arguments are not set by reference. + * + * TODO - consider using CS_VARIABLE instead of void* so that + * type check can happen here. + * */ +PUBLIC bool ugen_set_input_value(UGEN* ugen, int index, void* arg); + +/** Run the init-pass for the opcode instance held in UGEN. */ +PUBLIC int ugen_init(UGEN* ugen); + +/** Run the perf-pass for the opcode instance held in UGEN. */ +PUBLIC int ugen_perform(UGEN* ugen); + +/** Delets the opcode instance held in UGEN. */ +PUBLIC bool ugen_delete(UGEN* ugen); + + diff --git a/7.x/csound/version.h b/7.x/csound/version.h new file mode 100644 index 00000000..e43ab60a --- /dev/null +++ b/7.x/csound/version.h @@ -0,0 +1,59 @@ +/* + version.h: + + Copyright (C) 1995 John ffitch + + This file is part of Csound. + + The Csound Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + Csound is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Csound; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef CSOUND_VERSION_H +#define CSOUND_VERSION_H + +/* Version string generated from CMake variables */ +#define VERSION "7.0" + +/* Define to the full name of this package. */ +#define CS_PACKAGE_NAME "Csound" + +/* Define to the full name and version of this package. */ +#define CS_PACKAGE_STRING "Csound " VERSION + +/* Define to the one symbol short name of this package. */ +#define CS_PACKAGE_TARNAME "csound" + +/* Define to the version of this package. Generated from CMake variables */ +#define CS_PACKAGE_VERSION VERSION +#define CS_VERSION (7) +#define CS_SUBVER (0) +#define CS_PATCHLEVEL (0) + + +#define CS_APIVERSION 4 /* should be increased anytime a new version + contains changes that an older host will + not be able to handle -- most likely this + will be a change to an API function or + the CSOUND struct */ +#define CS_APISUBVER 0 /* for minor changes that will still allow + compatiblity with older hosts */ + +#ifndef CS_PACKAGE_DATE +#define CS_PACKAGE_DATE __DATE__ +#endif + +#endif /* CSOUND_VERSION_H */ + diff --git a/7.x/src/py/CMakeLists.txt b/7.x/src/py/CMakeLists.txt index ab90376b..793b8563 100644 --- a/7.x/src/py/CMakeLists.txt +++ b/7.x/src/py/CMakeLists.txt @@ -11,8 +11,8 @@ if(BUILD_PYTHON_OPCODES) message("-- Python include dirs: ${Python3_INCLUDE_DIRS}") message("-- Python libraries: ${PYTHON_LIBRARIES}") - make_plugin(py src/pythonopcodes.c) - target_include_directories(py PRIVATE ${CSOUND_INCLUDE_DIRS}) - target_include_directories(py PRIVATE ${PYTHON_INCLUDE_DIRS}) - target_link_libraries(py ${PYTHON_LIBRARIES}) + make_plugin(py7 "7x" src/pythonopcodes.c) + target_include_directories(py7 PRIVATE ${CSOUND_INCLUDE_DIRS}) + target_include_directories(py7 PRIVATE ${PYTHON_INCLUDE_DIRS}) + target_link_libraries(py7 PRIVATE ${PYTHON_LIBRARIES}) endif() diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..ca354bac --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,31 @@ +cmake_minimum_required(VERSION 3.13.4) +cmake_policy(SET CMP0077 NEW) +cmake_policy(SET CMP0091 NEW) + +option(USE_VCPKG "Use VCPKG to download and manage dependencies" OFF) + +if(USE_VCPKG) + # Detect correct triplet based on CMake env + if (WIN32) + set(VCPKG_HOST_TRIPLET "x64-windows-static" CACHE STRING "") + set(VCPKG_TARGET_TRIPLET "x64-windows-static") + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") + elseif(APPLE) + set(VCPKG_HOST_TRIPLET "x64-osx" CACHE STRING "") + set(VCPKG_TARGET_TRIPLET "x64-osx") + elseif (UNIX) + set(VCPKG_HOST_TRIPLET "x64-linux" CACHE STRING "") + set(VCPKG_TARGET_TRIPLET "x64-linux") + endif() + + set(VCPKG_FEATURE_FLAGS versions) + set(X_VCPKG_APPLOCAL_DEPS_INSTALL ON) + set(CMAKE_TOOLCHAIN_FILE + "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake" + CACHE STRING "Vcpkg toolchain file") +endif() + +project(Csound-plugins) + +add_subdirectory(./6.x) +add_subdirectory(./7.x) diff --git a/6.x/cmake/CompilerOptimizations.cmake b/cmake/CompilerOptimizations.cmake similarity index 100% rename from 6.x/cmake/CompilerOptimizations.cmake rename to cmake/CompilerOptimizations.cmake diff --git a/6.x/cmake/Modules/FindCSOUND.cmake b/cmake/Modules/FindCSOUND.cmake similarity index 100% rename from 6.x/cmake/Modules/FindCSOUND.cmake rename to cmake/Modules/FindCSOUND.cmake diff --git a/6.x/cmake/Modules/FindEIGEN3.cmake b/cmake/Modules/FindEIGEN3.cmake similarity index 100% rename from 6.x/cmake/Modules/FindEIGEN3.cmake rename to cmake/Modules/FindEIGEN3.cmake diff --git a/6.x/cmake/Modules/FindFAUST.cmake b/cmake/Modules/FindFAUST.cmake similarity index 97% rename from 6.x/cmake/Modules/FindFAUST.cmake rename to cmake/Modules/FindFAUST.cmake index d1d329e5..e08715a1 100644 --- a/6.x/cmake/Modules/FindFAUST.cmake +++ b/cmake/Modules/FindFAUST.cmake @@ -3,7 +3,7 @@ include(FindPackageHandleStandardArgs) find_path(FAUST_INCLUDE_DIR faust/dsp/llvm-dsp.h HINTS - C:/Program Files/Faust/include/ + "C:/Program Files/Faust/include/" /opt/lib/faust/architecture/ /usr/lib/faust/architecture/ /usr/local/lib/faust/architecture/ diff --git a/6.x/cmake/Modules/FindFLUIDSYNTH.cmake b/cmake/Modules/FindFLUIDSYNTH.cmake similarity index 100% rename from 6.x/cmake/Modules/FindFLUIDSYNTH.cmake rename to cmake/Modules/FindFLUIDSYNTH.cmake diff --git a/6.x/cmake/Modules/FindGMM.cmake b/cmake/Modules/FindGMM.cmake similarity index 100% rename from 6.x/cmake/Modules/FindGMM.cmake rename to cmake/Modules/FindGMM.cmake diff --git a/6.x/cmake/Modules/FindLAME.cmake b/cmake/Modules/FindLAME.cmake similarity index 100% rename from 6.x/cmake/Modules/FindLAME.cmake rename to cmake/Modules/FindLAME.cmake diff --git a/6.x/cmake/Modules/FindSTK.cmake b/cmake/Modules/FindSTK.cmake similarity index 100% rename from 6.x/cmake/Modules/FindSTK.cmake rename to cmake/Modules/FindSTK.cmake diff --git a/cmake/utilities.cmake b/cmake/utilities.cmake new file mode 100644 index 00000000..187f1819 --- /dev/null +++ b/cmake/utilities.cmake @@ -0,0 +1,70 @@ +# Checks if dependencies for an enabled target are fulfilled. +# If FAIL_MISSING is true and the dependencies are not fulfilled, +# it will abort the cmake run. +# If FAIL_MISSING is false, it will set the option to OFF. +# If the target is not enabled, it will do nothing. +# example: check_deps(BUILD_NEW_PARSER FLEX_EXECUTABLE BISON_EXECUTABLE) +function(check_deps option) + if(${option}) + set(i 1) + + while( ${i} LESS ${ARGC} ) + set(dep ${ARGV${i}}) + + if(NOT ${dep}) + if(FAIL_MISSING) + message(FATAL_ERROR "${option} is enabled, but ${dep}=\"${${dep}}\"") + else() + message(STATUS "${dep}=\"${${dep}}\", so disabling ${option}") + set(${option} OFF PARENT_SCOPE) + # Set it in the local scope too + set(${option} OFF) + endif() + endif() + + math(EXPR i "${i}+1") + endwhile() + endif() + + if(${option}) + message(STATUS "${option} is enabled.") + else() + message(STATUS "${option} is disabled.") + endif() +endfunction() + +# Utility function to make plugins. All plugin targets should use this as it +# sets up output directory set in top-level CmakeLists.txt +# and adds the appropriate install target +# +# libname - name of library to produce +# version - version of the plugin, valid values are 6x and 7x +# srcs - list of src files (must be quoted if a list) +# extralibs (OPTIONAL) - extra libraries to link the plugin to +# +# NB - this was moved here as it needs some VARS defined above +# for setting up the framework +function(make_plugin libname version srcs) + if(APPLE) + add_library(${libname} SHARED ${srcs}) + else() + add_library(${libname} MODULE ${srcs}) + endif() + + set(i 3) + while( ${i} LESS ${ARGC} ) + target_link_libraries(${libname} PRIVATE ${ARGV${i}}) + math(EXPR i "${i}+1") + endwhile() + + if (version STREQUAL "6x") + target_include_directories(${libname} PUBLIC "${CMAKE_SOURCE_DIR}/6.x/csound") + else() + target_include_directories(${libname} PUBLIC "${CMAKE_SOURCE_DIR}/7.x/csound") + endif() + + install(TARGETS ${libname} + LIBRARY DESTINATION "${PLUGIN_INSTALL_DIR}" + ARCHIVE DESTINATION "${PLUGIN_INSTALL_DIR}" + ) +endfunction() diff --git a/vcpkg b/vcpkg new file mode 160000 index 00000000..98aa6396 --- /dev/null +++ b/vcpkg @@ -0,0 +1 @@ +Subproject commit 98aa6396292d57e737a6ef999d4225ca488859d5 diff --git a/6.x/vcpkg.json b/vcpkg.json similarity index 57% rename from 6.x/vcpkg.json rename to vcpkg.json index 21ef94d8..91287c02 100644 --- a/6.x/vcpkg.json +++ b/vcpkg.json @@ -1,17 +1,21 @@ { "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json", "name": "csound-plugins", - "version-string": "6.16.2", - "builtin-baseline": "f6a5d4e8eb7476b8d7fc12a56dff300c1c986131", + "version-string": "1.0.0", + "builtin-baseline": "98aa6396292d57e737a6ef999d4225ca488859d5", "dependencies": [ "ableton-link", "eigen3", - "fltk", - "fluidsynth", + { + "name": "fltk", + "platform": "!linux" + }, "hdf5", + "libuv", + "libpng", "libstk", "libwebsockets", "mp3lame", "zlib" ] -} \ No newline at end of file +}