mirror of
https://github.com/thestk/stk
synced 2026-01-11 20:11:52 +00:00
Compare commits
323 Commits
3.2
...
6aacd357d7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6aacd357d7 | ||
|
|
0d4bb84732 | ||
|
|
270edc855f | ||
|
|
d7d6079f6b | ||
|
|
cea6f547d2 | ||
|
|
212950d364 | ||
|
|
aeaef391ef | ||
|
|
d0345712db | ||
|
|
1cb2c81d04 | ||
|
|
b671638f99 | ||
|
|
169b005a2d | ||
|
|
73008d02a1 | ||
|
|
e364d81c8f | ||
|
|
3675846c66 | ||
|
|
fd5e37863d | ||
|
|
7f97ab5f71 | ||
|
|
8b29e0ea6d | ||
|
|
2af2f1c816 | ||
|
|
f39c1fb06d | ||
|
|
35ca4abcb9 | ||
|
|
cc2dd22e97 | ||
|
|
e0279e305b | ||
|
|
ce765cc391 | ||
|
|
9bf39f53c6 | ||
|
|
4397e05158 | ||
|
|
70835eccb4 | ||
|
|
79334d2c8d | ||
|
|
16918b0914 | ||
|
|
3acb9502ae | ||
|
|
92d81d67c2 | ||
|
|
893ff3d954 | ||
|
|
b343913233 | ||
|
|
f3ce5f4d04 | ||
|
|
d4750edc66 | ||
|
|
6a6a9cdfbe | ||
|
|
dec667bab5 | ||
|
|
1fd900263b | ||
|
|
67d573b169 | ||
|
|
500d2972f9 | ||
|
|
ee7a1a31f8 | ||
|
|
feb123c9b8 | ||
|
|
509c6cf9e9 | ||
|
|
e5454b85c7 | ||
|
|
f0a22c463d | ||
|
|
ba6ea9f5db | ||
|
|
f00e38611c | ||
|
|
367893bf50 | ||
|
|
a6266131cb | ||
|
|
1fec6e0157 | ||
|
|
d308c8aeb7 | ||
|
|
deddcbaa3e | ||
|
|
76127ffc6c | ||
|
|
d77b093a9d | ||
|
|
c7d37545d3 | ||
|
|
15a1359671 | ||
|
|
51f9676229 | ||
|
|
7840967816 | ||
|
|
8132c90515 | ||
|
|
73004ac9c4 | ||
|
|
a49f6e71e7 | ||
|
|
926a9faca7 | ||
|
|
34192d9a63 | ||
|
|
fb2b0aa305 | ||
|
|
ba967ff851 | ||
|
|
109f0bd9a8 | ||
|
|
7b94384705 | ||
|
|
b379160f2b | ||
|
|
4b5b142531 | ||
|
|
f1a75a8691 | ||
|
|
e5cab23433 | ||
|
|
5a8b2234c7 | ||
|
|
314835cc70 | ||
|
|
700ff2c459 | ||
|
|
fb15f76d45 | ||
|
|
921493d4fe | ||
|
|
4cbdd0d3dc | ||
|
|
c97f5b4b3a | ||
|
|
809cb26e12 | ||
|
|
dbe725c40d | ||
|
|
f47fde31b0 | ||
|
|
5ec15d2043 | ||
|
|
33baf69d3e | ||
|
|
975c9a365f | ||
|
|
00ddf89798 | ||
|
|
a8b6affd8c | ||
|
|
444dab21fd | ||
|
|
7fc638ce32 | ||
|
|
f489451660 | ||
|
|
b6143915a9 | ||
|
|
38970124ec | ||
|
|
ae2bac1601 | ||
|
|
8de7543266 | ||
|
|
f8550110d6 | ||
|
|
e4d373b658 | ||
|
|
2fffa79174 | ||
|
|
448c12b0f4 | ||
|
|
f88fc8690b | ||
|
|
0591733bd7 | ||
|
|
7fe70c4223 | ||
|
|
3d455a4644 | ||
|
|
db79599c01 | ||
|
|
7f06bf46f3 | ||
|
|
03b4299af4 | ||
|
|
c531f68a56 | ||
|
|
0a5dbf59d2 | ||
|
|
493fb35b3f | ||
|
|
00f7424140 | ||
|
|
47822b8ce8 | ||
|
|
4a27274c0f | ||
|
|
d1f08072f9 | ||
|
|
3211b94abb | ||
|
|
5e28beb4db | ||
|
|
21d392dca7 | ||
|
|
f79d75037a | ||
|
|
3efa214fbd | ||
|
|
6acefc08a8 | ||
|
|
6ce3ac9e10 | ||
|
|
11d1dc54f3 | ||
|
|
d6c67cc479 | ||
|
|
6ed16eb806 | ||
|
|
05230b11d5 | ||
|
|
3e103671d9 | ||
|
|
071280a311 | ||
|
|
15a2c89f89 | ||
|
|
889328c3c1 | ||
|
|
62416d7e3f | ||
|
|
9627701d04 | ||
|
|
9966f06757 | ||
|
|
56bcdc32ed | ||
|
|
2ddc79e3bd | ||
|
|
96b1a72186 | ||
|
|
2a6ada02a7 | ||
|
|
488301223a | ||
|
|
08f71c8fa9 | ||
|
|
e03aa486dd | ||
|
|
5dd605ecfd | ||
|
|
77a5cfa4aa | ||
|
|
77bdb45575 | ||
|
|
ff52b9f0b0 | ||
|
|
fe0f5d7f96 | ||
|
|
e1aa259517 | ||
|
|
95fcd14213 | ||
|
|
a5bef56e76 | ||
|
|
fb50d69e08 | ||
|
|
126ff9d9e1 | ||
|
|
83b75ed339 | ||
|
|
f0f6668f25 | ||
|
|
a506acc708 | ||
|
|
3e42e3db3f | ||
|
|
852bdec0c9 | ||
|
|
9d8673a24e | ||
|
|
57344a11a9 | ||
|
|
00da5562cd | ||
|
|
b02298a9f4 | ||
|
|
d1b4dd485b | ||
|
|
6d5a779879 | ||
|
|
7ea8b10c6a | ||
|
|
0e69055579 | ||
|
|
c2833d356a | ||
|
|
0f16f683c9 | ||
|
|
f3b1f35a8c | ||
|
|
262fe5a2d1 | ||
|
|
5e79513e5a | ||
|
|
f13866e696 | ||
|
|
9533f2bc66 | ||
|
|
8c0ad97a25 | ||
|
|
87461b1471 | ||
|
|
58fc744ea4 | ||
|
|
35f66c806e | ||
|
|
0a7c541cdc | ||
|
|
0e55d2d2b1 | ||
|
|
c1c314e7d6 | ||
|
|
84d947c750 | ||
|
|
05560b102d | ||
|
|
759fc187bc | ||
|
|
46be0d56c3 | ||
|
|
032e76da70 | ||
|
|
aae7f609cf | ||
|
|
d959a1167d | ||
|
|
c9f8c017bc | ||
|
|
6094f40399 | ||
|
|
a2fb59f476 | ||
|
|
f905623d10 | ||
|
|
b196c58c75 | ||
|
|
20b9411a5a | ||
|
|
bc3cfa8fb5 | ||
|
|
d1acfb07ed | ||
|
|
b5f046871b | ||
|
|
1de1f1e63d | ||
|
|
4ce317a5a7 | ||
|
|
2e8a0cdd50 | ||
|
|
5f9f7f6f08 | ||
|
|
a2be4bc721 | ||
|
|
2437623d67 | ||
|
|
0063a57dcb | ||
|
|
cc568a58c1 | ||
|
|
1799064d6f | ||
|
|
540d45dbbd | ||
|
|
222f81c1c1 | ||
|
|
cbb2fea120 | ||
|
|
4e4e8053a5 | ||
|
|
dc2bfe01d0 | ||
|
|
ea52f1f1a8 | ||
|
|
1c5d42e64c | ||
|
|
f1c929a6c4 | ||
|
|
d6dba8859f | ||
|
|
069cc1c339 | ||
|
|
32574e97d6 | ||
|
|
a0638ad024 | ||
|
|
3ad1a59585 | ||
|
|
90c33cae06 | ||
|
|
1ce9b33ca3 | ||
|
|
3caee97842 | ||
|
|
887baf05f8 | ||
|
|
aec65bcb76 | ||
|
|
db6fc1f0df | ||
|
|
1a2509ead9 | ||
|
|
7388163b7c | ||
|
|
3d9bb4051b | ||
|
|
92ca28918f | ||
|
|
32a3b551d8 | ||
|
|
a9a654862f | ||
|
|
a239b58651 | ||
|
|
caf7d2f2eb | ||
|
|
3ee62e42d0 | ||
|
|
afa3069dea | ||
|
|
2c136e82ef | ||
|
|
17b45a1dad | ||
|
|
dbecf1f7f0 | ||
|
|
4c8e0dec43 | ||
|
|
914a76cae0 | ||
|
|
979c6877c9 | ||
|
|
fff3e0b887 | ||
|
|
a027a515af | ||
|
|
1f0cad64dd | ||
|
|
3d3ab8b86a | ||
|
|
e4146d6dae | ||
|
|
79cdf449b5 | ||
|
|
ce076784a4 | ||
|
|
0f6f1c4194 | ||
|
|
b2cefb3b53 | ||
|
|
1468ad7e12 | ||
|
|
eade52ff5c | ||
|
|
4e90d3ffd2 | ||
|
|
b2c4aa87bb | ||
|
|
85ca274a33 | ||
|
|
eccc38a093 | ||
|
|
3ebdbe6977 | ||
|
|
742cf6a202 | ||
|
|
b7cbce0ced | ||
|
|
b5e24dec52 | ||
|
|
8658acabee | ||
|
|
0e7077c0f3 | ||
|
|
e2f4193e1a | ||
|
|
f38bcceed7 | ||
|
|
9e2cad425a | ||
|
|
3e43d5e297 | ||
|
|
8055f1d040 | ||
|
|
5e145ff682 | ||
|
|
042dea6ff7 | ||
|
|
04ba9c694e | ||
|
|
40fe7dae1d | ||
|
|
cafad844ad | ||
|
|
5749dc1c55 | ||
|
|
8284487d4b | ||
|
|
193a8ebb2e | ||
|
|
84cf7c5344 | ||
|
|
11ff75339d | ||
|
|
96543e1b84 | ||
|
|
416c02c83c | ||
|
|
08af1a08b4 | ||
|
|
4c6e8aee76 | ||
|
|
b2fbc4f302 | ||
|
|
7aefe7caff | ||
|
|
00f822e00c | ||
|
|
c2ae82f200 | ||
|
|
72786d0b72 | ||
|
|
32f23f9538 | ||
|
|
b0e8953a6f | ||
|
|
586eeac02e | ||
|
|
1874c0efa9 | ||
|
|
9e6a25d046 | ||
|
|
8912a5c0af | ||
|
|
b017472cdf | ||
|
|
ed754183e3 | ||
|
|
add961c2f4 | ||
|
|
e619de2a65 | ||
|
|
5e68ce4eeb | ||
|
|
ae9e437ae8 | ||
|
|
4699f8ef59 | ||
|
|
80db57e79b | ||
|
|
4078d9309d | ||
|
|
18e210ea94 | ||
|
|
3369940892 | ||
|
|
c57c52c17e | ||
|
|
1bbd2c003a | ||
|
|
80561731fe | ||
|
|
4f0c39e7eb | ||
|
|
b089236578 | ||
|
|
deaabdd041 | ||
|
|
caeaa5778c | ||
|
|
c298839886 | ||
|
|
57e3fe7dae | ||
|
|
4c8691eb08 | ||
|
|
3d0db65b1c | ||
|
|
c8b7b67680 | ||
|
|
72095c0a3d | ||
|
|
e449ac3583 | ||
|
|
a117cd0bb1 | ||
|
|
fc877b87bf | ||
|
|
0aec39260a | ||
|
|
baca57040b | ||
|
|
b6a2202011 | ||
|
|
eccd8c9981 | ||
|
|
d199342e86 | ||
|
|
27d9b79dc7 | ||
|
|
2cbce2d8bd | ||
|
|
a6381b9d38 | ||
|
|
cf06b7598b | ||
|
|
586b0add5f | ||
|
|
6e0d1955a8 | ||
|
|
2f09fcd019 | ||
|
|
81475b04c5 |
199
.gitignore
vendored
Normal file
199
.gitignore
vendored
Normal file
@@ -0,0 +1,199 @@
|
||||
#####
|
||||
# OS X temporary files that should never be committed
|
||||
#
|
||||
# c.f. http://www.westwind.com/reference/os-x/invisibles.html
|
||||
|
||||
.DS_Store
|
||||
|
||||
# c.f. http://www.westwind.com/reference/os-x/invisibles.html
|
||||
|
||||
.Trashes
|
||||
|
||||
# c.f. http://www.westwind.com/reference/os-x/invisibles.html
|
||||
|
||||
*.swp
|
||||
|
||||
# *.lock - this is used and abused by many editors for many different things.
|
||||
# For the main ones I use (e.g. Eclipse), it should be excluded
|
||||
# from source-control, but YMMV
|
||||
|
||||
*.lock
|
||||
|
||||
#
|
||||
# profile - REMOVED temporarily (on double-checking, this seems incorrect; I can't find it in OS X docs?)
|
||||
#profile
|
||||
|
||||
|
||||
####
|
||||
# Xcode temporary files that should never be committed
|
||||
#
|
||||
# NB: NIB/XIB files still exist even on Storyboard projects, so we want this...
|
||||
|
||||
*~.nib
|
||||
|
||||
|
||||
####
|
||||
# Xcode build files -
|
||||
#
|
||||
# NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "DerivedData"
|
||||
|
||||
DerivedData/
|
||||
|
||||
# NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "build"
|
||||
|
||||
build/
|
||||
|
||||
|
||||
#####
|
||||
# Xcode private settings (window sizes, bookmarks, breakpoints, custom executables, smart groups)
|
||||
#
|
||||
# This is complicated:
|
||||
#
|
||||
# SOMETIMES you need to put this file in version control.
|
||||
# Apple designed it poorly - if you use "custom executables", they are
|
||||
# saved in this file.
|
||||
# 99% of projects do NOT use those, so they do NOT want to version control this file.
|
||||
# ..but if you're in the 1%, comment out the line "*.pbxuser"
|
||||
|
||||
# .pbxuser: http://lists.apple.com/archives/xcode-users/2004/Jan/msg00193.html
|
||||
|
||||
*.pbxuser
|
||||
|
||||
# .mode1v3: http://lists.apple.com/archives/xcode-users/2007/Oct/msg00465.html
|
||||
|
||||
*.mode1v3
|
||||
|
||||
# .mode2v3: http://lists.apple.com/archives/xcode-users/2007/Oct/msg00465.html
|
||||
|
||||
*.mode2v3
|
||||
|
||||
# .perspectivev3: http://stackoverflow.com/questions/5223297/xcode-projects-what-is-a-perspectivev3-file
|
||||
|
||||
*.perspectivev3
|
||||
|
||||
# NB: also, whitelist the default ones, some projects need to use these
|
||||
!default.pbxuser
|
||||
!default.mode1v3
|
||||
!default.mode2v3
|
||||
!default.perspectivev3
|
||||
|
||||
|
||||
####
|
||||
# Xcode 4 - semi-personal settings
|
||||
#
|
||||
#
|
||||
# OPTION 1: ---------------------------------
|
||||
# throw away ALL personal settings (including custom schemes!
|
||||
# - unless they are "shared")
|
||||
#
|
||||
# NB: this is exclusive with OPTION 2 below
|
||||
xcuserdata
|
||||
|
||||
# OPTION 2: ---------------------------------
|
||||
# get rid of ALL personal settings, but KEEP SOME OF THEM
|
||||
# - NB: you must manually uncomment the bits you want to keep
|
||||
#
|
||||
# NB: this *requires* git v1.8.2 or above; you may need to upgrade to latest OS X,
|
||||
# or manually install git over the top of the OS X version
|
||||
# NB: this is exclusive with OPTION 1 above
|
||||
#
|
||||
#xcuserdata/**/*
|
||||
|
||||
# (requires option 2 above): Personal Schemes
|
||||
#
|
||||
#!xcuserdata/**/xcschemes/*
|
||||
|
||||
####
|
||||
# Xcode 4 workspaces - more detailed
|
||||
#
|
||||
# Workspaces are important! They are a core feature of Xcode - don't exclude them :)
|
||||
#
|
||||
# Workspace layout is quite spammy. For reference:
|
||||
#
|
||||
# /(root)/
|
||||
# /(project-name).xcodeproj/
|
||||
# project.pbxproj
|
||||
# /project.xcworkspace/
|
||||
# contents.xcworkspacedata
|
||||
# /xcuserdata/
|
||||
# /(your name)/xcuserdatad/
|
||||
# UserInterfaceState.xcuserstate
|
||||
# /xcsshareddata/
|
||||
# /xcschemes/
|
||||
# (shared scheme name).xcscheme
|
||||
# /xcuserdata/
|
||||
# /(your name)/xcuserdatad/
|
||||
# (private scheme).xcscheme
|
||||
# xcschememanagement.plist
|
||||
#
|
||||
#
|
||||
|
||||
####
|
||||
# Xcode 4 - Deprecated classes
|
||||
#
|
||||
# Allegedly, if you manually "deprecate" your classes, they get moved here.
|
||||
#
|
||||
# We're using source-control, so this is a "feature" that we do not want!
|
||||
|
||||
*.moved-aside
|
||||
|
||||
####
|
||||
# Files generated by automake
|
||||
|
||||
Makefile
|
||||
autom4te.cache
|
||||
config.log
|
||||
config.status
|
||||
configure
|
||||
projects/demo/Makefile
|
||||
projects/demo/stk-demo
|
||||
projects/demo/Release
|
||||
projects/demo/Debug
|
||||
projects/effects/Makefile
|
||||
projects/effects/effects
|
||||
projects/effects/Release
|
||||
projects/effects/Debug
|
||||
projects/eguitar/Makefile
|
||||
projects/eguitar/eguitar
|
||||
projects/eguitar/Release
|
||||
projects/eguitar/Debug
|
||||
projects/examples/Makefile
|
||||
projects/examples/audioprobe
|
||||
projects/examples/bethree
|
||||
projects/examples/controlbee
|
||||
projects/examples/crtsine
|
||||
projects/examples/duplex
|
||||
projects/examples/foursine
|
||||
projects/examples/grains
|
||||
projects/examples/inetIn
|
||||
projects/examples/inetOut
|
||||
projects/examples/libMakefile
|
||||
projects/examples/midiprobe
|
||||
projects/examples/play
|
||||
projects/examples/playsmf
|
||||
projects/examples/record
|
||||
projects/examples/rtsine
|
||||
projects/examples/sine
|
||||
projects/examples/sineosc
|
||||
projects/examples/threebees
|
||||
projects/examples/Release
|
||||
projects/examples/Debug
|
||||
projects/ragamatic/Makefile
|
||||
projects/ragamatic/ragamat
|
||||
projects/ragamatic/Release
|
||||
projects/ragamatic/Debug
|
||||
src/libstk.a
|
||||
src/Release
|
||||
src/Debug
|
||||
src/Makefile
|
||||
|
||||
####
|
||||
# Files generated by Visual Studio
|
||||
|
||||
projects/*/.vs/
|
||||
projects/*/*.exe
|
||||
projects/*/*.ilk
|
||||
projects/*/*.pdb
|
||||
projects/*/*.vcxproj.user
|
||||
projects/*/Release/
|
||||
projects/*/Debug/
|
||||
207
CMakeLists.txt
Normal file
207
CMakeLists.txt
Normal file
@@ -0,0 +1,207 @@
|
||||
cmake_minimum_required(VERSION 3.1) ##TODO: which version is better
|
||||
|
||||
project(STK VERSION 4.6.1)
|
||||
set (CMAKE_CXX_STANDARD 11)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build." FORCE)
|
||||
endif()
|
||||
SET_PROPERTY(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Release" "Debug" "RelWithDebInfo" "MinSizeRel")
|
||||
message("Build type: " ${CMAKE_BUILD_TYPE})
|
||||
|
||||
if(MSVC)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /O2 /DNDEBUG")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Z7 /Ob0 /Od /RTC1 /D_ITERATOR_DEBUG_LEVEL=2 /D_STK_DEBUG_ /D__RTAUDIO_DEBUG__ /D__RTMIDI_DEBUG__")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -DNDEBUG")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -D_STK_DEBUG_ -D__RTAUDIO_DEBUG__ -D__RTMIDI_DEBUG__")
|
||||
endif()
|
||||
|
||||
if(${CMAKE_CXX_COMPILER_ID} STREQUAL GNU)
|
||||
message("GCC.")
|
||||
set(CMAKE_CXX_FLAGS "-Wall")
|
||||
endif()
|
||||
|
||||
option(BUILD_SHARED "Whether to build the shared library" ON)
|
||||
option(BUILD_STATIC "Whether to build the static library" ON)
|
||||
option(REALTIME "Realtime support" ON)
|
||||
option(ENABLE_JACK "Enable JACK" ON)
|
||||
option(ENABLE_ALSA "Enable ALSA API support (linux only)" ON)
|
||||
# option(ENABLE_OSS "Enable OSS API Support (unixes only)" ON)
|
||||
option(ENABLE_ASIO "Enable ASIO API support (windows only)" OFF)
|
||||
option(ENABLE_DS "Enable DirectSound API support (windows only)" ON)
|
||||
option(ENABLE_WASAPI "Enable Windows Audio Session API support (windows only)" OFF)
|
||||
# option(ENABLE_CORE "Enable CoreAudio API support (mac only)" ON)
|
||||
option(COMPILE_PROJECTS "Compile all the example projects" ON)
|
||||
option(INSTALL_HEADERS "Install headers" ON)
|
||||
|
||||
include_directories("./include")
|
||||
file(GLOB STK_SRC "./src/*.cpp") # GLOB instead of GLOB_RECURSE as the asio depends on system
|
||||
|
||||
#========================================#
|
||||
#========== Realtime Support ============#
|
||||
#========================================#
|
||||
if(REALTIME)
|
||||
if(ENABLE_JACK)
|
||||
# Try to find PkgConfig
|
||||
find_package(PkgConfig QUIET)
|
||||
|
||||
if(PkgConfig_FOUND)
|
||||
# PkgConfig is available, use it
|
||||
pkg_check_modules(JACK QUIET jack)
|
||||
endif()
|
||||
|
||||
if(NOT JACK_FOUND)
|
||||
# PkgConfig was not found or Jack was not found through it, try a fallback
|
||||
message(STATUS "PkgConfig not found or failed to find Jack, attempting fallback")
|
||||
|
||||
# Fallback: Search in common locations
|
||||
find_path(JACK_INCLUDE_DIR
|
||||
NAMES jack/jack.h
|
||||
HINTS
|
||||
ENV JACK_ROOT
|
||||
"$ENV{ProgramFiles}/Jack"
|
||||
/usr/local/include
|
||||
/usr/include
|
||||
)
|
||||
|
||||
find_library(JACK_LIBRARY
|
||||
NAMES jack
|
||||
HINTS
|
||||
ENV JACK_ROOT
|
||||
"$ENV{ProgramFiles}/Jack"
|
||||
/usr/local/lib
|
||||
/usr/lib
|
||||
)
|
||||
|
||||
# Check if the fallback was successful
|
||||
if(JACK_INCLUDE_DIR AND JACK_LIBRARY)
|
||||
set(JACK_FOUND TRUE)
|
||||
set(JACK_INCLUDE_DIRS ${JACK_INCLUDE_DIR})
|
||||
set(JACK_LIBRARIES ${JACK_LIBRARY})
|
||||
message(STATUS "Found Jack (fallback):")
|
||||
message(STATUS " Includes: ${JACK_INCLUDE_DIRS}")
|
||||
message(STATUS " Libraries: ${JACK_LIBRARIES}")
|
||||
else()
|
||||
message(WARNING "Failed to find Jack library even with fallback. Please install Jack development package or ensure it is in a standard location.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(JACK_FOUND)
|
||||
include_directories(${JACK_INCLUDE_DIRS})
|
||||
link_libraries(${JACK_LIBRARIES})
|
||||
add_definitions(-D__UNIX_JACK__)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
message("${CMAKE_SYSTEM_NAME}")
|
||||
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
|
||||
find_package(Threads REQUIRED)
|
||||
link_libraries(Threads::Threads)
|
||||
if(${CMAKE_SYSTEM_NAME} STREQUAL Linux)
|
||||
# TODO: Finish Linux configuration, include different audio API supports
|
||||
#============== LINUX ================#
|
||||
message("Linux DETECTED!")
|
||||
if(ENABLE_ALSA)
|
||||
find_package(ALSA REQUIRED)
|
||||
if(ALSA_FOUND)
|
||||
include_directories(${ALSA_INCLUDE_DIRS})
|
||||
link_libraries(${ALSA_LIBRARIES})
|
||||
add_definitions(-D__LINUX_ALSA__)
|
||||
endif()
|
||||
endif()
|
||||
elseif(${CMAKE_SYSTEM_NAME} STREQUAL Darwin)
|
||||
#============== MAC OS ================#
|
||||
message("Machintosh DETECTED!")
|
||||
find_package(CoreAudio REQUIRED)
|
||||
include_directories(${COREAUDIO_INCLUDE_DIRS})
|
||||
add_definitions(-D__MACOSX_CORE__)
|
||||
link_libraries(${COREAUDIO_LIBRARY} ${COREAUDIO_FOUNDATION} ${COREAUDIO_MIDI})
|
||||
elseif(${CMAKE_SYSTEM_NAME} STREQUAL Windows)
|
||||
# TODO: MORE SUPPORT (e.g., MSYS)?
|
||||
# Tested under MSYS2 with Mingw64 toolchain
|
||||
#============== WINDOWS ================#
|
||||
message("Windows DETECTED!")
|
||||
link_libraries(winmm ole32 wsock32)
|
||||
add_definitions(-D__WINDOWS_MM__)
|
||||
|
||||
# TODO: ASIO NOT WORKING YET
|
||||
if(ENABLE_ASIO)
|
||||
message("ENALBING ASIO")
|
||||
include_directories("./src/include")
|
||||
# target_sources(stk PUBLIC "${CMAKE_SOURCE_DIR}/src/include/asio.cpp" "${CMAKE_SOURCE_DIR}/src/include/asiodrivers.cpp"
|
||||
# "${CMAKE_SOURCE_DIR}/src/include/asiolist.cpp" "${CMAKE_SOURCE_DIR}/src/include/iasiothiscallresolver.cpp")
|
||||
add_definitions(-D__WINDOWS_ASIO__)
|
||||
endif()
|
||||
|
||||
if(ENABLE_WASAPI)
|
||||
message("ENALBING WASAPI")
|
||||
link_libraries(mfuuid mfplat wmcodecdspuuid ksuser)
|
||||
add_definitions(-D__WINDOWS_WASAPI__)
|
||||
endif()
|
||||
|
||||
if(ENABLE_DS)
|
||||
message("ENALBING Directsound")
|
||||
link_libraries(dsound)
|
||||
add_definitions(-D__WINDOWS_DS__)
|
||||
endif()
|
||||
else()
|
||||
message("CMAKE_SYSTEM_NAME:" ${CMAKE_SYSTEM_NAME})
|
||||
message(FATAL_ERROR "Unknown system type for realtime support.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include(TestBigEndian)
|
||||
TEST_BIG_ENDIAN(IS_BIG_ENDIAN)
|
||||
if(NOT IS_BIG_ENDIAN)
|
||||
add_definitions(-D__LITTLE_ENDIAN__)
|
||||
endif()
|
||||
add_definitions(-D_USE_MATH_DEFINES)
|
||||
if(INSTALL_HEADERS)
|
||||
file(GLOB STK_HEADERS "include/*.h")
|
||||
install(FILES ${STK_HEADERS} DESTINATION include/stk)
|
||||
endif()
|
||||
#========================================#
|
||||
#========== Build the Library ===========#
|
||||
#========================================#
|
||||
if(BUILD_STATIC)
|
||||
add_library(stk STATIC ${STK_SRC} )
|
||||
target_include_directories(stk PRIVATE include PUBLIC $<INSTALL_INTERFACE:include>)
|
||||
set_target_properties(stk PROPERTIES PUBLIC_HEADER "${LIBSTK_HEADERS}")
|
||||
list(APPEND STK_TARGETS stk)
|
||||
endif()
|
||||
|
||||
if(BUILD_SHARED)
|
||||
add_library(stk_SHARED SHARED ${STK_SRC})
|
||||
set_target_properties(stk_SHARED PROPERTIES OUTPUT_NAME stk) # rename the shared library name
|
||||
target_include_directories(stk_SHARED PRIVATE include PUBLIC $<INSTALL_INTERFACE:include>)
|
||||
set_target_properties(stk_SHARED PROPERTIES PUBLIC_HEADER "${LIBSTK_HEADERS}")
|
||||
list(APPEND STK_TARGETS stk_SHARED)
|
||||
endif()
|
||||
|
||||
#========================================#
|
||||
#========= Build the examples ===========#
|
||||
#========================================#
|
||||
if(COMPILE_PROJECTS)
|
||||
message("COMPILE PROJECTS!")
|
||||
add_subdirectory(projects/examples)
|
||||
add_subdirectory(projects/eguitar)
|
||||
add_subdirectory(projects/demo)
|
||||
add_subdirectory(projects/effects)
|
||||
add_subdirectory(projects/ragamatic)
|
||||
endif()
|
||||
|
||||
#========================================#
|
||||
#========= Install ======================#
|
||||
#========================================#
|
||||
|
||||
install(TARGETS ${STK_TARGETS} EXPORT stk-config
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib
|
||||
RUNTIME DESTINATION bin
|
||||
PUBLIC_HEADER DESTINATION include/stk)
|
||||
|
||||
install(EXPORT stk-config DESTINATION lib/cmake/stk)
|
||||
54
INSTALL.md
Normal file
54
INSTALL.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# The Synthesis ToolKit in C++ (STK)
|
||||
By Perry R. Cook and Gary P. Scavone, 1995-2023.
|
||||
|
||||
The Synthesis ToolKit in C++ can be used in a variety of ways, depending on your particular needs. Some people simply choose the classes they need for a particular project and copy those to their project directory. Others like to compile and link to a library of object files. STK was not designed with one particular style of use in mind.
|
||||
|
||||
## Unix systems and MinGW
|
||||
|
||||
1. If you downloaded the software from the git repository, first run autoconf,
|
||||
|
||||
autoconf
|
||||
|
||||
otherwise, if you downloaded the software from the STK source distribution, unpack the tar file,
|
||||
|
||||
tar -xzf stk-4.x.x.tar.gz
|
||||
|
||||
2. From within the directory containing this file, run configure:
|
||||
|
||||
./configure
|
||||
|
||||
3. From within each project directory, type `make`.
|
||||
|
||||
4. To compile a library of objects, type `make` from within the `src` directory.
|
||||
|
||||
Several options can be passed to configure, including:
|
||||
|
||||
--disable-realtime = only compile generic non-realtime classes
|
||||
--enable-debug = enable various debug output
|
||||
--with-alsa = choose native ALSA API support (default, linux only)
|
||||
--with-oss = choose native OSS API support (unixes only)
|
||||
--with-jack = choose native JACK server API support (linux and macintosh OS-X)
|
||||
--with-core = choose OS-X CoreAudio API (macintosh OS-X only)
|
||||
--with-asio = choose ASIO API support (windows only)
|
||||
--with-ds = choose DirectSound API support (windows only)
|
||||
--with-wasapi = choose Windows Audio Session API support (windows only)
|
||||
|
||||
It is now possible to specify more than one audio and MIDI API where supported. Note, however, that the ALSA library is required in order to compile the RtMidi class in Linux if the `--with-oss` option is provided (only the OSS audio API will be used, not the OSS MIDI API). Typing `./configure --help` will display all the available options. In addition, it is possible to specify the RAWWAVES and INCLUDE paths to configure as (e.g. to set to /home/me/rawwaves and /home/me/include):
|
||||
|
||||
./configure RAWWAVE_PATH='$(HOME)/rawwaves/'
|
||||
./configure INCLUDE_PATH='$(HOME)/include/'
|
||||
|
||||
The ending "/" is required for the RAWWAVES path. The default behavior will set a relative path that works for the project files included with the distribution (assuming they are not moved). You can also change the RAWWAVE_PATH dynamically via the static Stk::setRawwavePath() function.
|
||||
|
||||
If you wish to use a different compiler than that selected by configure, specify that compiler in the command line (e.g. to use CC):
|
||||
|
||||
./configure CXX=CC
|
||||
|
||||
|
||||
## Windows
|
||||
|
||||
MinGW support is provided in the configure script. In addition, Visual Studio 2017 project files are included for each of the example STK projects.
|
||||
|
||||
## iOS
|
||||
|
||||
You can integrate the STK in iOS projects either by using its iOS static library or CocoaPods. See the [iOS README file](iOS/README-iOS.md) for instructions.
|
||||
27
LICENSE
Normal file
27
LICENSE
Normal file
@@ -0,0 +1,27 @@
|
||||
The Synthesis ToolKit in C++ (STK)
|
||||
|
||||
Copyright (c) 1995-2023 Perry R. Cook and Gary P. Scavone
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
asked to send the modifications to the original developer so that they
|
||||
can be incorporated into the canonical version. This is, however, not
|
||||
a binding provision of this license.
|
||||
|
||||
THE 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
ANY CLAIM, 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 IN THE SOFTWARE.
|
||||
41
Makefile.in
Normal file
41
Makefile.in
Normal file
@@ -0,0 +1,41 @@
|
||||
### Do not edit -- Generated by 'configure --with-whatever' from Makefile.in
|
||||
|
||||
RM = /bin/rm
|
||||
|
||||
REALTIME = @realtime@
|
||||
|
||||
all :
|
||||
cd src && $(MAKE)
|
||||
cd projects/demo && $(MAKE) libdemo
|
||||
ifeq ($(REALTIME),yes)
|
||||
cd projects/effects && $(MAKE) libeffects
|
||||
cd projects/ragamatic && $(MAKE) libragamat
|
||||
cd projects/eguitar && $(MAKE) libeguitar
|
||||
endif
|
||||
cd projects/examples && $(MAKE) -f libMakefile
|
||||
|
||||
clean :
|
||||
$(RM) -f *~
|
||||
cd src && $(MAKE) clean
|
||||
cd projects/demo && $(MAKE) clean
|
||||
ifeq ($(REALTIME),yes)
|
||||
cd projects/effects && $(MAKE) clean
|
||||
cd projects/ragamatic && $(MAKE) clean
|
||||
cd projects/eguitar && $(MAKE) clean
|
||||
endif
|
||||
cd projects/examples && $(MAKE) clean
|
||||
|
||||
distclean: clean
|
||||
$(RM) -rf config.log config.status autom4te.cache Makefile
|
||||
cd src && $(MAKE) distclean
|
||||
cd projects/demo && $(MAKE) distclean
|
||||
ifeq ($(REALTIME),yes)
|
||||
cd projects/effects && $(MAKE) distclean
|
||||
cd projects/ragamatic && $(MAKE) distclean
|
||||
cd projects/eguitar && $(MAKE) distclean
|
||||
endif
|
||||
cd projects/examples && $(MAKE) distclean
|
||||
|
||||
install:
|
||||
$(MAKE) -C src install
|
||||
|
||||
194
README.md
Normal file
194
README.md
Normal file
@@ -0,0 +1,194 @@
|
||||
# The Synthesis ToolKit in C++ (STK)
|
||||
By Perry R. Cook and Gary P. Scavone, 1995--2023.
|
||||
|
||||
This distribution of the Synthesis ToolKit in C++ (STK) contains the following:
|
||||
|
||||
* [`include`](include/): STK class header files
|
||||
* [`src`](src/): STK class source files
|
||||
* [`rawwaves`](rawwaves): STK audio files (1-channel, 16-bit, big-endian)
|
||||
* [`doc`](doc): STK documentation
|
||||
* [`projects`](projects): example STK projects and programs
|
||||
|
||||
Please read the [Legal and Ethical notes](#legal-and-ethical) near the bottom of this document and the [License](LICENSE).
|
||||
|
||||
For compiling and installing STK, see the [INSTALL.md](INSTALL.md) file in this directory.
|
||||
|
||||
## Contents
|
||||
|
||||
* [Overview](#overview)
|
||||
* [System Requirements](#system-requirements)
|
||||
* [What's New (and not so new)](#whats-new-and-not-so-new)
|
||||
* [Disclaimer](#disclaimer)
|
||||
* [Legal and Ethical](#legal-and-ethical)
|
||||
* [Further Reading](#further-reading)
|
||||
* [Perry's Notes From the Original Distribution](#perrys-notes-from-the-original-distribution)
|
||||
|
||||
# OVERVIEW
|
||||
|
||||
The Synthesis ToolKit in C++ (STK) is a set of open source audio
|
||||
signal processing and algorithmic synthesis classes written in the C++
|
||||
programming language. STK was designed to facilitate rapid
|
||||
development of music synthesis and audio processing software, with an
|
||||
emphasis on cross-platform functionality, realtime control, ease of
|
||||
use, and educational example code. The Synthesis ToolKit is extremely
|
||||
portable (most classes are platform-independent C++ code), and it's
|
||||
completely user-extensible (all source included, no unusual libraries,
|
||||
and no hidden drivers). We like to think that this increases the
|
||||
chances that our programs will still work in another 5-10 years. STK
|
||||
currently runs with "realtime" support (audio and MIDI) on Linux,
|
||||
Macintosh OS X, and Windows computer platforms. Generic, non-realtime
|
||||
support has been tested under NeXTStep, Sun, and other platforms and
|
||||
should work with any standard C++ compiler.
|
||||
|
||||
The only classes of the Synthesis ToolKit that are platform-dependent
|
||||
concern sockets, threads, mutexes, and real-time audio and MIDI input
|
||||
and output. The interface for MIDI input and the simple Tcl/Tk
|
||||
graphical user interfaces (GUIs) provided is the same, so it's easy to
|
||||
experiment in real time using either the GUIs or MIDI. The Synthesis
|
||||
ToolKit can generate simultaneous SND (AU), WAV, AIFF, and MAT-file
|
||||
output soundfile formats (as well as realtime sound output), so you
|
||||
can view your results using one of a large variety of sound/signal
|
||||
analysis tools already available (e.g. Snd, Cool Edit, Matlab).
|
||||
|
||||
The Synthesis Toolkit is not one particular program. Rather, it is a
|
||||
set of C++ classes that you can use to create your own programs. A
|
||||
few example applications are provided to demonstrate some of the ways
|
||||
to use the classes. If you have specific needs, you will probably
|
||||
have to either modify the example programs or write a new program
|
||||
altogether. Further, the example programs don't have a fancy GUI
|
||||
wrapper. If you feel the need to have a "drag and drop" graphical
|
||||
patching GUI, you probably don't want to use the ToolKit. Spending
|
||||
hundreds of hours making platform-dependent graphics code would go
|
||||
against one of the fundamental design goals of the ToolKit - platform
|
||||
independence.
|
||||
|
||||
For those instances where a simple GUI with sliders and buttons is
|
||||
helpful, we use Tcl/Tk (https://www.tcl.tk/) which is freely
|
||||
distributed for all the supported ToolKit platforms. A number of
|
||||
Tcl/Tk GUI scripts are distributed with the ToolKit release. For
|
||||
control, the Synthesis Toolkit uses raw MIDI (on supported platforms),
|
||||
and SKINI (Synthesis ToolKit Instrument Network Interface, a MIDI-like
|
||||
text message synthesis control format).
|
||||
|
||||
|
||||
# SYSTEM REQUIREMENTS
|
||||
|
||||
See the individual README's (e.g. README-linux) in the /doc directory
|
||||
for platform specific information and system requirements. In
|
||||
general, you will use the configure script to create Makefiles on unix
|
||||
platforms (and MinGW) or the VS2017 workspace files to compile the
|
||||
example programs. To use the Tcl/Tk GUIs, you will need Tcl/Tk
|
||||
version 8.0 or higher.
|
||||
|
||||
|
||||
# WHAT'S NEW (AND NOT SO NEW)
|
||||
|
||||
Despite being available in one form or another since 1996, we still
|
||||
consider STK to be alpha software. We attempt to maintain backward
|
||||
compatability but changes are sometimes made in an effort to improve
|
||||
the overall design or performance of the software. Please read the
|
||||
"Release Notes" in the /doc directory to see what has changed since
|
||||
the last release.
|
||||
|
||||
A new StkFrames class has been created to facilitate the handling and
|
||||
passing of multichannel, vectorized audio data. All STK classes have
|
||||
been updated to include tick() functions that accept StkFrames
|
||||
arguments.
|
||||
|
||||
The control message handling scheme has been simplified greatly
|
||||
through the use of the Messager class. It is now possible to have
|
||||
access to simultaneous piped, socketed, and/or MIDI input control
|
||||
messages. In most cases, this should eliminate the use of the
|
||||
Md2Skini program.
|
||||
|
||||
Realtime audio input capabilities were added to STK with release 3.0,
|
||||
though the behavior of such is very hardware dependent. Under Linux
|
||||
and Macintosh OS-X, audio input and output are possible with very low
|
||||
latency. Using the Windows DirectSound API, minimum dependable output
|
||||
sound latency seems to be around 20 milliseconds or so, while input
|
||||
sound latency is generally higher. Performance with the ASIO audio
|
||||
API on Windows provides much better performance.
|
||||
|
||||
As mentioned above, it is possible to record the audio ouput of an STK
|
||||
program to .snd, .wav, .raw, .aif, and .mat (Matlab MAT-file) output
|
||||
file types. Though somewhat obsolete, the program Md2Skini can be
|
||||
used to write SKINI scorefiles from realtime MIDI input. Finally, STK
|
||||
should compile with non-realtime functionality on any platform with a
|
||||
generic C++ compiler.
|
||||
|
||||
For those who wish to make a library from the core STK classes, the
|
||||
configure script generates a Makefile in the src directory that will
|
||||
accomplish that.
|
||||
|
||||
|
||||
# DISCLAIMER
|
||||
|
||||
You probably already guessed this, but just to be sure, we don't
|
||||
guarantee anything works. :-) It's free ... what do you expect? If
|
||||
you find a bug, please let us know and we'll try to correct it. You
|
||||
can also make suggestions, but again, no guarantees. Send email to
|
||||
the mail list.
|
||||
|
||||
|
||||
# LEGAL AND ETHICAL
|
||||
|
||||
This software was designed and created to be made publicly available
|
||||
for free, primarily for academic purposes, so if you use it, pass it
|
||||
on with this documentation, and for free.
|
||||
|
||||
If you make a million dollars with it, it would be nice if you would
|
||||
share. If you make compositions with it, put us in the program notes.
|
||||
|
||||
Some of the concepts are covered by various patents, some known to us
|
||||
and likely others which are unknown. Many of the ones known to us are
|
||||
administered by the Stanford Office of Technology and Licensing.
|
||||
|
||||
The good news is that large hunks of the techniques used here are
|
||||
public domain. To avoid subtle legal issues, we'll not state what's
|
||||
freely useable here, but we'll try to note within the various classes
|
||||
where certain things are likely to be protected by patents.
|
||||
|
||||
|
||||
# FURTHER READING
|
||||
|
||||
For complete documentation on this ToolKit, the classes, etc., see the
|
||||
doc directory of the distribution or surf to
|
||||
http://ccrma.stanford.edu/software/stk/. Also check the platform
|
||||
specific README's for specific system requirements.
|
||||
|
||||
|
||||
# PERRY'S NOTES FROM THE ORIGINAL DISTRIBUTION
|
||||
|
||||
This whole world was created with no particular hardware in mind.
|
||||
These examples are intended to be tutorial in nature, as a platform
|
||||
for the continuation of my research, and as a possible starting point
|
||||
for a software synthesis system. The basic motivation was to create
|
||||
the necessary unit generators to do the synthesis, processing, and
|
||||
control that I want to do and teach about. Little thought for
|
||||
optimization was given and therefore improvements, especially speed
|
||||
enhancements, should be possible with these classes. It was written
|
||||
with some basic concepts in mind about how to let compilers optimize.
|
||||
|
||||
Your question at this point might be, "But Perry, with CMix, CMusic,
|
||||
CSound, CShells, CMonkeys, etc. already cluttering the landscape, why
|
||||
a new set of stupid C functions for music synthesis and processing?"
|
||||
The answers lie below.
|
||||
|
||||
1) I needed to port many of the things I've done into something which is generic enough to port further to different machines.
|
||||
|
||||
2) I really plan to document this stuff, so that you don't have to be me to figure out what's going on. (I'll probably be sorry I said this in a couple of years, when even I can't figure out what I was thinking.)
|
||||
|
||||
3) The classic difficulties most people have in trying to implement physical models are:
|
||||
|
||||
A) They have trouble understanding the papers, and/or in turning the theory into practice.
|
||||
|
||||
B) The Physical Model instruments are a pain to get to oscillate, and coming up with stable and meaningful parameter values is required to get the models to work at all.
|
||||
|
||||
This set of C++ unit generators and instruments might help to diminish the scores of emails I get asking what to do with those block diagrams I put in my papers.
|
||||
|
||||
4) I wanted to try some new stuff with modal synthesis, and implement some classic FM patches as well.
|
||||
|
||||
5) I wanted to reimplement, and newly implement more of the intelligent and physical performer models I've talked about in some of my papers. But I wanted to do it in a portable way, and in such a way that I can hook up modules quickly. I also wanted to make these instruments connectable to such player objects, so folks like Brad Garton who really think a lot about the players can connect them to my instruments, a lot about which I think.
|
||||
|
||||
6) More rationalizations to follow . . .
|
||||
|
||||
55
STK.podspec
Normal file
55
STK.podspec
Normal file
@@ -0,0 +1,55 @@
|
||||
# To lint the spec:
|
||||
# pod spec lint --skip-import-validation --allow-warnings
|
||||
# To publish:
|
||||
# pod trunk push STK.podspec --skip-import-validation --allow-warnings
|
||||
|
||||
Pod::Spec.new do |spec|
|
||||
spec.name = 'STK'
|
||||
spec.version = '4.6.2'
|
||||
spec.summary = 'The Synthesis ToolKit in C++ is a set of open source audio signal processing and algorithmic synthesis classes.'
|
||||
spec.homepage = 'https://ccrma.stanford.edu/software/stk/'
|
||||
spec.source = { :git => 'https://github.com/thestk/stk.git', :tag => spec.version }
|
||||
spec.license = { :type => 'MIT' }
|
||||
spec.author = { "Ariel Elkin" => "ariel@arivibes.com" }
|
||||
spec.platform = :ios
|
||||
spec.ios.deployment_target = "10.0"
|
||||
spec.source_files = [
|
||||
"src/*.cpp",
|
||||
"include/*.h"
|
||||
]
|
||||
spec.public_header_files = [
|
||||
"include/*.h",
|
||||
"include/SKINImsg.h",
|
||||
"include/SKINItbl.h"
|
||||
]
|
||||
spec.exclude_files = [
|
||||
"include/Thread.h",
|
||||
"src/Thread.cpp",
|
||||
"include/Mutex.h",
|
||||
"src/Mutex.cpp",
|
||||
"include/UdpSocket.h",
|
||||
"src/UdpSocket.cpp",
|
||||
"include/Socket.h",
|
||||
"src/Socket.cpp",
|
||||
"include/TcpClient.h",
|
||||
"src/TcpClient.cpp",
|
||||
"include/TcpServer.h",
|
||||
"src/TcpServer.cpp",
|
||||
"include/InetWvIn.h",
|
||||
"src/InetWvIn.cpp",
|
||||
"include/InetWvOut.h",
|
||||
"src/InetWvOut.cpp",
|
||||
"include/RtAudio.h",
|
||||
"src/RtAudio.cpp",
|
||||
"include/RtMidi.h",
|
||||
"src/RtMidi.cpp",
|
||||
"include/RtWvIn.h",
|
||||
"src/RtWvIn.cpp",
|
||||
"include/RtWvOut.h",
|
||||
"src/RtWvOut.cpp",
|
||||
"include/RtError.h"
|
||||
]
|
||||
spec.preserve_paths = "README.MD"
|
||||
spec.resource_bundles = { "rawwaves": "rawwaves/*.raw" }
|
||||
spec.libraries = 'c++'
|
||||
end
|
||||
189
bin/treesed
Executable file
189
bin/treesed
Executable file
@@ -0,0 +1,189 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
# treesed
|
||||
# Written January 1996 by Rick Jansen (rick@sara.nl)
|
||||
# URL: http://www.sara.nl/rick
|
||||
|
||||
# usage: treesed pattern1 pattern2 -tree
|
||||
# treesed pattern1 pattern2 -files file1 file2 ...
|
||||
|
||||
# example: treesed href HREF -files *.html
|
||||
|
||||
# Treesed searches for pattern1 and replaces pattern1 by pattern2
|
||||
# if pattern2 supplied. If only pattern1 given treesed just searches.
|
||||
# Treesed will search in all files and subdirectories of the current
|
||||
# directory
|
||||
|
||||
|
||||
|
||||
#--------------------------------------------------------
|
||||
# Parameters
|
||||
|
||||
$DoEdit=0;
|
||||
$search_pattern = $ARGV[0];
|
||||
$search_pattern =~ s/(\W)/\\$1/g; # escape regexp chars
|
||||
shift;
|
||||
|
||||
while ($#ARGV >= 0) {
|
||||
|
||||
if ($ARGV[0] eq '-files') {
|
||||
@temp_ls = @ARGV[1 .. $#ARGV];
|
||||
# Get list of files, skip dirs
|
||||
foreach $file (@ARGV[1 .. $#ARGV]) {
|
||||
if (-f $file) {
|
||||
push(@ls, $file);
|
||||
}
|
||||
}
|
||||
last;
|
||||
}
|
||||
elsif ($ARGV[0] eq '-tree') {
|
||||
&Get_LS;
|
||||
last;
|
||||
}
|
||||
|
||||
if (! -f $ARGV[0]) {
|
||||
if (defined($replacement_pattern)) {
|
||||
print "usage: treesed pattern1 <pattern2> -tree/-files <files>\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$replacement_pattern = $ARGV[0];
|
||||
#$replacement_pattern =~ s/(\W)/\\$1/g; # escape regexp chars
|
||||
$DoEdit=1;
|
||||
shift;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# No files?
|
||||
if ($#ls < 0) {
|
||||
print "xx No input files\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
print "search_pattern: $search_pattern\n";
|
||||
print "replacement_pattern: $replacement_pattern\n";
|
||||
if ($DoEdit) {
|
||||
print "\n** EDIT MODE!\n\n"; }
|
||||
else {
|
||||
print "\n** Search mode\n\n";
|
||||
}
|
||||
|
||||
#foreach $file (@ls) {
|
||||
# print "$file \n";
|
||||
#}
|
||||
|
||||
|
||||
#--------------------------------------------------------
|
||||
# Search list of files for pattern
|
||||
|
||||
$linepos=0;
|
||||
|
||||
$| = 1; # Force flush after every write
|
||||
foreach $file (@ls) {
|
||||
#print "$file\n";
|
||||
print '.';
|
||||
$linepos++;
|
||||
if ($linepos > 50) {
|
||||
$linepos=0;
|
||||
print "\n";
|
||||
}
|
||||
|
||||
if (!open(FILE, $file)) {
|
||||
print "\nCould not open $file\n";
|
||||
next;
|
||||
}
|
||||
|
||||
$Found = 0;
|
||||
$Count = 0;
|
||||
$lineno = 0;
|
||||
@lines = ();
|
||||
while (<FILE>) {
|
||||
$lineno++;
|
||||
if (/$search_pattern/i) {
|
||||
#print;
|
||||
$Count++;
|
||||
$Found = 1;
|
||||
push(@lines, $lineno);
|
||||
}
|
||||
}
|
||||
close(FILE);
|
||||
if ($Found) {
|
||||
print "\n$file: $Count lines on: @lines\n";
|
||||
}
|
||||
|
||||
if ($Found && $DoEdit) { &Edit($file); }
|
||||
|
||||
}
|
||||
$| = 0;
|
||||
print "\n";
|
||||
|
||||
|
||||
exit(0);
|
||||
|
||||
|
||||
#--------------------------------------------------------
|
||||
# Edit file
|
||||
|
||||
sub Edit {
|
||||
|
||||
# Replace $ARGV[0] with $ARGV[1] in $file
|
||||
|
||||
local($file) = @_;
|
||||
local($bakfile) = $file.'.'.$$;
|
||||
|
||||
# First create backup
|
||||
open(FILE, $file) || die "Could not open $file for read\n";
|
||||
open(BAKFILE, ">$bakfile") || die "Could not open $bakfile for backup\n";
|
||||
while (<FILE>) {
|
||||
print BAKFILE;
|
||||
}
|
||||
close(BAKFILE);
|
||||
close(FILE);
|
||||
|
||||
# Now replace $ARGV[0] by $ARGV[1] in the backupfile,
|
||||
# result into $file
|
||||
open(BAKFILE, $bakfile) || die "Could not open $bakfile for read\n";
|
||||
open(FILE,">$file") || die "Could not open $file for write\n";
|
||||
$Count=0;
|
||||
while (<BAKFILE>) {
|
||||
if (/$search_pattern/i) { $Count++; }
|
||||
s/$search_pattern/$replacement_pattern/gi;
|
||||
print FILE;
|
||||
}
|
||||
close(BAKFILE);
|
||||
close(FILE);
|
||||
|
||||
print
|
||||
"\nReplaced $search_pattern by $replacement_pattern on $Count lines in $file\n";
|
||||
|
||||
} #sub Edit
|
||||
|
||||
#--------------------------------------------------------
|
||||
|
||||
sub Get_LS {
|
||||
|
||||
# Get a list of full path names into array @ls
|
||||
|
||||
local(@localls)=`ls -R1`;
|
||||
local($item,$Dir);
|
||||
|
||||
#print "localls: @localls\n";
|
||||
$Dir='';
|
||||
foreach $item (@localls) {
|
||||
#print "$item\n";
|
||||
if ($item =~ /:$/) {
|
||||
$Dir=$item;
|
||||
chop($Dir);
|
||||
$Dir =~ s/:$/\//;
|
||||
}
|
||||
else {
|
||||
chop($item);
|
||||
$item = $Dir.$item;
|
||||
if ($item !~ /^\s*$/) { push(@ls, $item); }
|
||||
}
|
||||
}
|
||||
@localls=();
|
||||
|
||||
} # sub Get_LS
|
||||
|
||||
21
cmake/FindCoreAudio.cmake
Normal file
21
cmake/FindCoreAudio.cmake
Normal file
@@ -0,0 +1,21 @@
|
||||
find_library(COREAUDIO_LIBRARY CoreAudio)
|
||||
find_library(COREAUDIO_FOUNDATION CoreFoundation)
|
||||
find_library(COREAUDIO_MIDI CoreMIDI)
|
||||
find_path(COREAUDIO_INCLUDE_DIRS CoreAudio/CoreAudio.h)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(
|
||||
CoreAudio
|
||||
DEFAULT_MSG
|
||||
COREAUDIO_LIBRARY
|
||||
COREAUDIO_FOUNDATION
|
||||
COREAUDIO_MIDI
|
||||
COREAUDIO_INCLUDE_DIRS)
|
||||
|
||||
mark_as_advanced(
|
||||
COREAUDIO_LIBRARY
|
||||
COREAUDIO_FOUNDATION
|
||||
COREAUDIO_MIDI
|
||||
COREAUDIO_INCLUDE_DIRS)
|
||||
|
||||
|
||||
1441
config/config.guess
vendored
Executable file
1441
config/config.guess
vendored
Executable file
File diff suppressed because it is too large
Load Diff
1813
config/config.sub
vendored
Normal file
1813
config/config.sub
vendored
Normal file
File diff suppressed because it is too large
Load Diff
255
configure.ac
Normal file
255
configure.ac
Normal file
@@ -0,0 +1,255 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
AC_INIT([STK],[5.0.0],[gary.scavone@mcgill.ca],[stk])
|
||||
AC_CONFIG_AUX_DIR(config)
|
||||
AC_CONFIG_SRCDIR(src/Stk.cpp)
|
||||
AC_CONFIG_FILES(Makefile src/Makefile projects/demo/Makefile projects/effects/Makefile projects/ragamatic/Makefile projects/examples/Makefile projects/examples/libMakefile projects/eguitar/Makefile)
|
||||
|
||||
# Fill GXX with something before test.
|
||||
AC_SUBST( GXX, ["no"] )
|
||||
|
||||
# standards version
|
||||
m4_include([m4/ax_cxx_compile_stdcxx.m4])
|
||||
AX_CXX_COMPILE_STDCXX(11, noext, mandatory)
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CXX(g++ CC c++ cxx)
|
||||
AC_PROG_RANLIB
|
||||
AC_PATH_PROG(AR, ar, no)
|
||||
if [[ $AR = "no" ]] ; then
|
||||
AC_MSG_ERROR("Could not find ar - needed to create a library");
|
||||
fi
|
||||
|
||||
# Checks for header files.
|
||||
AC_CHECK_INCLUDES_DEFAULT
|
||||
AC_PROG_EGREP
|
||||
|
||||
AC_CHECK_HEADERS(fcntl.h sys/ioctl.h sys/time.h termio.h unistd.h)
|
||||
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
AC_TYPE_SIZE_T
|
||||
|
||||
AC_C_BIGENDIAN
|
||||
AC_EGREP_CPP(yes,
|
||||
[#ifndef WORDS_BIGENDIAN
|
||||
yes
|
||||
#endif
|
||||
], [AC_SUBST( byte_order, [-D__LITTLE_ENDIAN__] )] )
|
||||
|
||||
AC_MSG_CHECKING(for RAWWAVE_PATH argument)
|
||||
AC_SUBST( rawwaves, $RAWWAVE_PATH )
|
||||
AC_MSG_RESULT($RAWWAVE_PATH)
|
||||
|
||||
AC_MSG_CHECKING(for INCLUDE_PATH argument)
|
||||
AC_SUBST( include, $INCLUDE_PATH )
|
||||
AC_MSG_RESULT($INCLUDE_PATH)
|
||||
|
||||
# Check for realtime support disable
|
||||
AC_MSG_CHECKING(whether to compile realtime support)
|
||||
AC_ARG_ENABLE(realtime,
|
||||
[ --disable-realtime = only compile generic non-realtime classes],
|
||||
realtime=$enableval)
|
||||
if test "$realtime" = "no"; then
|
||||
AC_SUBST( sound_api, [] )
|
||||
else
|
||||
AC_SUBST( realtime, [yes] )
|
||||
fi
|
||||
AC_MSG_RESULT($realtime)
|
||||
|
||||
AC_MSG_CHECKING(whether to build the static library)
|
||||
AC_ARG_ENABLE(static,
|
||||
[ --disable-static = do not compile static library ],
|
||||
build_static=$enableval,
|
||||
build_static=yes)
|
||||
AC_SUBST(build_static)
|
||||
AC_MSG_RESULT($build_static)
|
||||
|
||||
AC_MSG_CHECKING(whether to build the shared library)
|
||||
AC_ARG_ENABLE(shared,
|
||||
[ --enable-shared = compile the shared library ],
|
||||
build_shared=$enableval,
|
||||
build_shared=no)
|
||||
AC_SUBST(build_shared)
|
||||
AC_MSG_RESULT($build_shared)
|
||||
|
||||
if test x$build_static = xno -a x$build_shared = xno ; then
|
||||
AC_MSG_ERROR([ both static and shared libraries are disabled], 1)
|
||||
fi
|
||||
|
||||
# Check for math library
|
||||
AC_CHECK_LIB(m, cos, , AC_MSG_ERROR(math library is needed!))
|
||||
|
||||
# Check for debug
|
||||
AC_MSG_CHECKING(whether to compile debug version)
|
||||
AC_ARG_ENABLE(debug,
|
||||
[ --enable-debug = enable various debug output],
|
||||
debug=$enableval)
|
||||
if test "$debug" = "yes"; then
|
||||
AC_SUBST( cppflag, ["-D_STK_DEBUG_ -D__RTAUDIO_DEBUG__ -D__RTMIDI_DEBUG__"] )
|
||||
AC_SUBST( cxxflag, ["-g"] )
|
||||
AC_SUBST( object_path, [Debug] )
|
||||
else
|
||||
AC_SUBST( debug, [no] )
|
||||
AC_SUBST( cppflag, [] )
|
||||
AC_SUBST( cxxflag, [-O3] )
|
||||
AC_SUBST( object_path, [Release] )
|
||||
fi
|
||||
AC_MSG_RESULT($debug)
|
||||
|
||||
# Checks for functions
|
||||
if test $realtime = yes; then
|
||||
AC_CHECK_FUNCS(select socket)
|
||||
AC_CHECK_FUNC(gettimeofday, [cppflag="$cppflag -DHAVE_GETTIMEOFDAY"], )
|
||||
fi
|
||||
|
||||
# For -I and -D flags
|
||||
CPPFLAGS="$CPPFLAGS $cppflag"
|
||||
|
||||
# For debugging and optimization ... overwrite default because it has both -g and -O2
|
||||
CXXFLAGS="$cxxflag"
|
||||
|
||||
# Check compiler and use -Wall if gnu.
|
||||
if [test $GXX = "yes" ;] then
|
||||
AC_SUBST( cxxflag, [-Wall] )
|
||||
fi
|
||||
|
||||
CXXFLAGS="$CXXFLAGS $cxxflag"
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
|
||||
basesharedname="libstk-\$(RELEASE)"
|
||||
|
||||
AC_SUBST( sharedlib, ["libstk.so"] )
|
||||
AC_SUBST( sharedname, [${basesharedname}.so] )
|
||||
AC_SUBST( libflags, ["-shared -Wl,-soname,${basesharedname}.so -o $sharedname"] )
|
||||
case $host in
|
||||
*-apple*)
|
||||
AC_SUBST( sharedlib, ["libstk.dylib"] )
|
||||
AC_SUBST( sharedname, ["${basesharedname}.dylib"] )
|
||||
AC_SUBST( libflags, ["-dynamiclib -install_name \$(libdir)/${basesharedname}.dylib -o ${basesharedname}.dylib"] )
|
||||
esac
|
||||
|
||||
if test $realtime = yes; then
|
||||
# Checks for package options and external software
|
||||
AC_MSG_CHECKING(for audio API)
|
||||
|
||||
AC_ARG_WITH(jack, [ --with-jack = choose JACK server support (mac and linux only)])
|
||||
AS_IF([test "x$with_jack" == "xyes"], [
|
||||
api="$api -D__UNIX_JACK__"
|
||||
AC_MSG_RESULT(using JACK)
|
||||
AC_CHECK_LIB(jack, jack_client_open, , AC_MSG_ERROR(JACK support requires the jack library!))])
|
||||
|
||||
case $host in
|
||||
*-*-netbsd*)
|
||||
AS_IF([test "$api" == ""], [
|
||||
AC_MSG_RESULT(using OSS)
|
||||
api="$api -D__LINUX_OSS__"
|
||||
LIBS="$LIBS -lossaudio"
|
||||
AC_CHECK_LIB(pthread, pthread_create, , AC_MSG_ERROR(RtAudio requires the pthread library!))])
|
||||
;;
|
||||
|
||||
*-*-freebsd*)
|
||||
AS_IF([test "$api" == ""], [
|
||||
AC_MSG_RESULT(using OSS)
|
||||
api="$api -D__LINUX_OSS__"
|
||||
LIBS="$LIBS -lossaudio"
|
||||
AC_CHECK_LIB(pthread, pthread_create, , AC_MSG_ERROR(RtAudio requires the pthread library!))])
|
||||
;;
|
||||
|
||||
*-*-linux*)
|
||||
# Look for ALSA flag
|
||||
AC_ARG_WITH(alsa, [ --with-alsa = choose native ALSA API support (linux only)])
|
||||
AS_IF([test "x$with_alsa" == "xyes"], [
|
||||
api="$api -D__LINUX_ALSA__"
|
||||
AC_MSG_RESULT(using ALSA)
|
||||
AC_CHECK_LIB(asound, snd_pcm_open, , AC_MSG_ERROR(ALSA support requires the asound library!))])
|
||||
|
||||
# Look for PulseAudio flag
|
||||
AC_ARG_WITH(pulse, [ --with-pulse = choose PulseAudio support (linux only)])
|
||||
AS_IF([test "x$with_pulse" == "xyes"], [
|
||||
api="$api -D__LINUX_PULSE__"
|
||||
AC_MSG_RESULT(using PulseAudio)
|
||||
AC_CHECK_LIB(pulse, pa_proplist_gets, , AC_MSG_ERROR(PulseAudio support requires the libpulse library!))
|
||||
AC_CHECK_LIB(pulse-simple, pa_simple_new, , AC_MSG_ERROR(PulseAudio support requires the libpulse-simple library!))])
|
||||
|
||||
# Look for OSS flag
|
||||
AC_ARG_WITH(oss, [ --with-oss = choose OSS API support (unixes only)])
|
||||
AS_IF([test "x$with_oss" == "xyes"], [
|
||||
api="$api -D__LINUX_OSS__ -D__LINUX_ALSA__"
|
||||
AC_MSG_RESULT(using OSS)
|
||||
AC_CHECK_LIB(asound, snd_pcm_open, , AC_MSG_ERROR(OSS support requires ALSA for RtMidi!))])
|
||||
|
||||
# If no audio api flags specified, use ALSA
|
||||
AS_IF([test "$api" == ""], [
|
||||
AC_MSG_RESULT(using ALSA)
|
||||
AC_SUBST( api, [-D__LINUX_ALSA__] )
|
||||
AC_CHECK_LIB(asound, snd_pcm_open, , AC_MSG_ERROR(ALSA support requires the asound library!))
|
||||
])
|
||||
|
||||
AC_CHECK_LIB(pthread, pthread_create, , AC_MSG_ERROR(RtAudio requires the pthread library!))
|
||||
;;
|
||||
|
||||
*-apple*)
|
||||
# Look for Core flag
|
||||
AC_ARG_WITH(core, [ --with-core = choose CoreAudio API support (mac only)])
|
||||
AS_IF([test "x$with_core" == "xyes"], [
|
||||
api="$api -D__MACOSX_CORE__"
|
||||
AC_MSG_RESULT(using CoreAudio)
|
||||
AC_CHECK_HEADER(CoreAudio/CoreAudio.h, [], [AC_MSG_ERROR(CoreAudio header files not found!)] )
|
||||
LIBS="$LIBS -framework CoreAudio -framework CoreFoundation -framework CoreMIDI" ])
|
||||
|
||||
# If no audio api flags specified, use CoreAudio
|
||||
AS_IF([test "$api" == ""], [
|
||||
AC_SUBST( api, [-D__MACOSX_CORE__] )
|
||||
AC_MSG_RESULT(using CoreAudio)
|
||||
AC_CHECK_HEADER(CoreAudio/CoreAudio.h,
|
||||
[],
|
||||
[AC_MSG_ERROR(CoreAudio header files not found!)] )
|
||||
AC_SUBST( LIBS, ["-framework CoreAudio -framework CoreFoundation -framework CoreMIDI"] )
|
||||
])
|
||||
|
||||
AC_CHECK_LIB(pthread, pthread_create, , AC_MSG_ERROR(RtAudio requires the pthread library!))
|
||||
;;
|
||||
|
||||
*-mingw32*)
|
||||
AC_ARG_WITH(asio, [ --with-asio = choose ASIO API support (windoze only)])
|
||||
AS_IF([test "x$with_asio" == "xyes"], [
|
||||
api="$api -D__WINDOWS_ASIO__"
|
||||
AC_MSG_RESULT(using ASIO)
|
||||
AC_SUBST( objects, ["asio.o asiodrivers.o asiolist.o iasiothiscallresolver.o"] ) ])
|
||||
|
||||
# Look for DirectSound flag
|
||||
AC_ARG_WITH(ds, [ --with-ds = choose DirectSound API support (windoze only)])
|
||||
AS_IF([test "x$with_ds" == "xyes"], [
|
||||
api="$api -D__WINDOWS_DS__"
|
||||
AC_MSG_RESULT(using DirectSound)
|
||||
LIBS="-ldsound $LIBS" ])
|
||||
|
||||
# Look for WASAPI flag
|
||||
AC_ARG_WITH(wasapi, [ --with-wasapi = choose Windows Audio Session API support (windoze only)])
|
||||
AS_IF([test "x$with_wasapi" == "xyes"], [
|
||||
api="$api -D__WINDOWS_WASAPI__"
|
||||
AC_MSG_RESULT(using WASAPI)
|
||||
LIBS="-luuid -lksuser $LIBS" ])
|
||||
|
||||
# If no audio api flags specified, use DirectSound
|
||||
AS_IF([test "$api" == ""], [
|
||||
AC_SUBST( api, [-D__WINDOWS_DS__] )
|
||||
AC_MSG_RESULT(using DirectSound)
|
||||
LIBS="-ldsound -lwinmm $LIBS"
|
||||
])
|
||||
|
||||
api="$api -D__WINDOWS_MM__"
|
||||
LIBS="-lole32 -lwinmm -lwsock32 $LIBS"
|
||||
;;
|
||||
|
||||
*)
|
||||
# Default case for unknown realtime systems.
|
||||
AC_MSG_ERROR(Unknown system type for realtime support ... try --disable-realtime argument!)
|
||||
;;
|
||||
esac
|
||||
|
||||
CPPFLAGS="$CPPFLAGS $api"
|
||||
fi
|
||||
|
||||
AC_OUTPUT
|
||||
@@ -1,156 +0,0 @@
|
||||
STK: A ToolKit of Audio Synthesis Classes and Instruments in C++
|
||||
Version 3.2
|
||||
|
||||
By Perry R. Cook, 1995-2000
|
||||
and Gary P. Scavone, 1997-2000.
|
||||
|
||||
STK Classes, Version 3.2
|
||||
Please read README.txt for more information.
|
||||
|
||||
<--------Building Blocks---------->|<----------------Instruments------------------>
|
||||
|
||||
SourcSink Filters Reverb Non-Lin Modal & FM Physical Sampling PhISM
|
||||
Formant
|
||||
|
||||
Object-----------------------------------Instrmnt----------.
|
||||
| | | | | | |
|
||||
Envelope| Filter Reverb BowTabl | .----------------------------------------.
|
||||
| | | | JetTabl | | | | | | | | |
|
||||
ADSR | OneZero PRCRev ReedTabl| Modal4 | FM4Op---.| | | | Shakers
|
||||
| OnePole JCRev | | | | || | | |
|
||||
._____| TwoZero NRev .____| ModalBar| FM4Alg3 || Plucked Sampler |
|
||||
| | TwoPole | | | || Clarinet | |
|
||||
Noise | DCBlock LipFilt | HeavyMtl|| Brass SamplFlt|
|
||||
| | BiQuad | || Flute | |
|
||||
SubNoise| DlineL .____| .____|| Bowed Moog1 |
|
||||
| DLineA | | || BowedBar |
|
||||
| DLineN VoicForm FM4Alg4 || BlowHole |
|
||||
| FormSwep | ||____. |
|
||||
| PoleZero PercFlut| | |
|
||||
.____| FIR | Plucked2 |
|
||||
| | .____| | .____|
|
||||
TablLook| | | Mandolin |
|
||||
| FM4Alg5 | DrumSynt
|
||||
|____. | |
|
||||
| | Rhodey |
|
||||
| WvIn Wurley |
|
||||
._____| | TubeBell |
|
||||
| | WavWvIn .____|
|
||||
Modulatr| SndWvIn | |
|
||||
| RawWvIn FM4Alg6 |
|
||||
._____| MatWvIn | |
|
||||
| | AifWvIn FMVoices|
|
||||
SingWave| StrmWvIn |
|
||||
| .____|
|
||||
._____|_____. |
|
||||
| | | FM4Alg8
|
||||
VoicMang| WvOut |
|
||||
| | BeeThree
|
||||
| WavWvOut
|
||||
._____| SndWvOut
|
||||
| | RawWvOut
|
||||
RtMidi | MatWvOut
|
||||
| AifWvOut
|
||||
._____| RtWvOut
|
||||
| StrmWvOut
|
||||
RtAudio
|
||||
|
||||
********** INSTRUMENTS AND ALGORITHMS **************
|
||||
|
||||
Each Class will be listed either with all UGs it uses,
|
||||
or the <<Algorithm>> of which it is a flavor.
|
||||
All inherit from Instrmnt, which inherits from Object.
|
||||
|
||||
Plucked.cpp Basic Plucked String DLineA,OneZero,OnePole,Noise
|
||||
Plucked2.cpp Not So Basic Pluck DLineL,DlineA,OneZero
|
||||
Mandolin.cpp My Own Mandolin <<flavor of Plucked2>>
|
||||
Bowed.cpp Not Hideous Bowed String DlineL,BowTabl,OnePole,BiQuad,RawWave,ADSR
|
||||
Brass.cpp Not So Bad Brass Inst. DLineA,LipFilt,DCBlock,ADSR,RawWvIn
|
||||
Clarinet.cpp Pretty Good Clarinet DLineL,ReedTabl,OneZero,Envelope,Noise,RawWvIn
|
||||
BlowHole.cpp Clarinet w/ tone/reghole DLineL,ReedTabl,OneZero,Envelope,Noise,RawWvIn,PoleZero
|
||||
Flute.cpp Pretty Good Flute JetTabl,DLineL,OnePole,DCBlock,Noise,ADSR,RawWvIn
|
||||
BowedBar.cpp Pretty Good Bowed Bar DLineN,BowTabl,ADSR,BiQuad
|
||||
Modal4.cpp 4 Resonances Envelope,RawWvIn,RawWvIn,BiQuad,OnePole
|
||||
ModalBar.cpp Various presets <<flavor of MODAL4>>
|
||||
FM4Op.cpp 4 Operator FM Master ADSR,RawWvIn,TwoZero
|
||||
FM4Alg3.cpp 3 Cascade w/ FB Mod. <<flavor of FM4OP>>
|
||||
FM4Alg4.cpp Like Alg3 but diff. <<flavor of FM4OP>>
|
||||
FM4Alg5.cpp 2 Parallel Simple FMs <<flavor of FM4OP>>
|
||||
FM4Alg6.cpp 3 Carr. with 1 Mod. <<flavor of FM4OP>>
|
||||
FM4Alg8.cpp 4 Osc. Additive <<flavor of FM4OP>>
|
||||
HeavyMtl.cpp Distorted Synth <<flavor of FM4Alg3>>
|
||||
PercFlut.cpp Perc. Flute <<flavor of FM4Alg4>>
|
||||
Rhodey.cpp Rhodes-Like Elec. Piano <<flavor of FM4Alg5>>
|
||||
Wurley.cpp Wurlitz. Elec. Piano <<flavor of FM4Alg5>>
|
||||
TubeBell.cpp Classic FM Bell <<flavor of FM4Alg5>>
|
||||
FMVoices.cpp 3-Formant Voice Synth. <<flavor of FM4Alg6>>
|
||||
BeeThree.cpp Cheezy Organ for Paul <<flavor of FM4Alg8>>
|
||||
Sampler.cpp Sampling Synth. 4 each ADSR, RawWvIn (att), RawWvIn (loop), OnePole
|
||||
SamplFlt.cpp Sampler with Swept Filter <<flavor of Sampler>>
|
||||
Moog1.cpp Swept filter flavor of <<flavor of SamplFlt>>
|
||||
VoicForm.cpp Source/Filter Voice Envelope,Noise,SingWave,FormSwep,OnePole,OneZero
|
||||
DrumSynt.cpp Drum Synthesizer bunch of RawWvIn, and OnePole
|
||||
Shakers.cpp Stochastic Event Models
|
||||
|
||||
*********** BASIC UNIT GENERATORS **************
|
||||
|
||||
Master Object: Object.cpp For compatibility with Objective C
|
||||
|
||||
Source&Sink: Envelope.cpp Linearly Goes to Target by Rate, + noteOn/Off
|
||||
ADSR.cpp ADSR Flavor of Envelope
|
||||
Noise.cpp Random Number Generator
|
||||
SubNoise.cpp Random Numbers each N samples
|
||||
|
||||
Inputs: TablLook.cpp Lookup Table (assumes given data in big-endian format)
|
||||
WvIn.cpp Input Master Class (Looping, One-Shot,
|
||||
Interpolating, Non-Interpolating)
|
||||
RawWvIn.cpp STK Raw-file Input
|
||||
SndWvIn.cpp .snd Input Class
|
||||
WavWvIn.cpp .wav Input Class
|
||||
MatWvIn.cpp Matlab MAT-file Input Class
|
||||
AifWvIn.cpp AIFF Input Class
|
||||
RtWvIn.cpp Realtime Input Class
|
||||
StrmWvIn.cpp Audio Streaming (socket server) Input Class
|
||||
|
||||
Outputs: WvOut.cpp Output Master Class
|
||||
RawWvOut.cpp STK Raw-file Output Class
|
||||
SndWvOut.cpp .snd Output Class
|
||||
WavWvOut.cpp .wav Output Class
|
||||
MatWvOut.cpp Matlab MaT-file Output Class
|
||||
AifWvOut.cpp AIFF Output Class
|
||||
RtWvOut.cpp Realtime Output Class
|
||||
StrmWvOut.cpp Audio Streaming (socket client) Output Class
|
||||
|
||||
Duplex: RtDuplex.cpp Realtime Input/Output Class
|
||||
|
||||
MIDI: RtMidi.cpp MIDI I/O Class
|
||||
|
||||
Audio I/O: RtAudio.cpp Multi-OS Audio I/O Routines
|
||||
|
||||
Filters: Filter.cpp Filter Master Class
|
||||
OneZero.cpp One Zero Filter
|
||||
OnePole.cpp One Pole Filter
|
||||
PoleZero.cpp One Pole/One Zero Filter
|
||||
DCBlock.cpp DC Blocking 1Pole/1Zero Filter
|
||||
TwoZero.cpp Two Zero Filter
|
||||
TwoPole.cpp Two Pole Filter
|
||||
BiQuad.cpp 2Pole/2Zero Filter
|
||||
FormSwep.cpp Sweepable 2Pole filter, go to target by rate
|
||||
DLineL.cpp Linearly Interpolating Delay Line
|
||||
DLineA.cpp AllPass Interpolating Delay Line
|
||||
DLineN.cpp Non Interpolating Delay Line
|
||||
|
||||
Reverb: Reverb.cpp Reverb Master Class
|
||||
PRCRev.cpp 2 series allpass units, 2 parallel comb filters
|
||||
JCRev.cpp 3 series allpass units, 4 parallel comb filters
|
||||
NRev.cpp 6 parallel comb filters, 3 series allpass units, ...
|
||||
|
||||
NonLin&Lookup: JetTabl.cpp Cubic Jet NonLinearity
|
||||
BowTabl.cpp 1/x^3-like Bow NonLinearity
|
||||
ReedTabl.cpp 1 break point Reed NonLinearity
|
||||
LipFilt.cpp Pressure Controlled BiQuad with NonLin
|
||||
|
||||
Derived: Modulatr.cpp Per. and Rnd. Vibrato: RawWave, SubNoise, OnePole
|
||||
SingWave.cpp Looping Wavetable with: Modulatr, Envelope
|
||||
|
||||
Control: Controller.cpp Pipe, Socket, and MIDI control message handling
|
||||
@@ -1,28 +1,13 @@
|
||||
STK: A ToolKit of Audio Synthesis Classes and Instruments in C++
|
||||
Version 3.2
|
||||
The Synthesis ToolKit in C++ (STK)
|
||||
|
||||
By Perry R. Cook, 1995-2000
|
||||
and Gary P. Scavone, 1997-2000.
|
||||
By Perry R. Cook and Gary P. Scavone, 1995--2023.
|
||||
|
||||
Please read the file README.txt for more general STK information.
|
||||
Please read the file README and INSTALL for more general STK information.
|
||||
|
||||
STK for Linux is currently using either the Open Sound System (OSS) or the Advanced Linux Sound Architecture (ALSA) sound and MIDI APIs. The free version of OSS works as well (and in some cases better than the commercial OSS version ... such as with my Maestro 2e chipset). In general, the ALSA drivers seem to perform well though we have had some problems with them at CCRMA. You can read more about ALSA at http://www.alsa-project.org/. ALSA is open source and holds great promise for audio under Linux. Select (uncomment) the proper API #define statement in Object.h.
|
||||
Realtime audio support for Linux currently includes the Advanced Linux Sound Architecture (ALSA), the JACK low-latency audio server, and/or Open Sound System (OSS version 4.0 and higher only) APIs. That said, the OSS API support has not been tested in several years and is not considered a high priority. One or more APIs are selected during compilation using the __LINUX_ALSA__, __UNIX_JACK__, and/or __LINUX_OSS__ definitions. Because the ALSA library is now integrated into the standard Linux kernel, it is the default audio/MIDI API with STK versions 4.2 and higher.
|
||||
|
||||
STK should compile without much trouble under Linux ... afterall, it is primarily developed on Linux platforms. Since all Linux distributions typically include the GNU makefile utilities, you should be able to use the default Makefile. Typing "make" will initiate the compilation process.
|
||||
Realtime MIDI support Linux currently includes the Jack and ALSA sequencer support. Native OSS MIDI support no longer exists in RtMidi. If the __LINUX_OSS__ preprocessor definition is specified, only OSS audio support will be compiled and RtMidi will still be compiled using the ALSA API. For this reason, STK now requires the asound library for realtime support (unless only using the Jack API). Realtime programs must also link with the pthread library.
|
||||
|
||||
MIDIATOR SERIAL PORT MIDI SUPPORT:
|
||||
|
||||
STK now has special support for the MIDIator serial port MIDI interface. This is of primary interest to us laptop users, whose computers usually don't have a gameport. If you want to buy one of these devices, make sure you get the MS-124w model (www.midiator.com). For it to work in STK, make sure you uncomment the MIDIATOR define statement in Object.h. This support currently only works within the OSS API framework, though I should be able to get it to work with ALSA in the future as well.
|
||||
|
||||
There are a few things that need to be done on your system to get the MIDIator working. Add the following lines to your bootup sequence in /etc/rc.d/rc.local:
|
||||
|
||||
setserial /dev/ttyS0 baud_base 57600
|
||||
setserial /dev/ttyS0 divisor 1
|
||||
|
||||
You may need to specify the full path to the setserial function, depending on how your PATH variable is set up. Also, you may need to modify the permissions of /dev/ttyS0 (chmod a+rwx). And finally, the MIDIator should be set for "single addresssed" mode (the S/A switch on S and the A/B switch on A), which puts identical output on all 4 MIDI output ports. It is possible to use the MIDIator in a "multi-port" mode, though I'm not currently supporting that in STK.
|
||||
|
||||
NOTE REGARDING PTHREADS:
|
||||
|
||||
There haven't been any problems with threads since the old days of RedHat Linux 5.0. STK uses the MIT pthreads API.
|
||||
STK should compile without much trouble under Linux. Since all Linux distributions typically include the GNU makefile utilities, you should be able to use the default Makefiles. Typing "make" in a project directory will initiate the compilation process (after initially running the configure script in the top-level directory).
|
||||
|
||||
|
||||
|
||||
16
doc/README-MacOSX.txt
Normal file
16
doc/README-MacOSX.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
The Synthesis ToolKit in C++ (STK)
|
||||
|
||||
By Perry R. Cook and Gary P. Scavone, 1995--2023.
|
||||
|
||||
Please read the file README and INSTALL for more general STK information.
|
||||
|
||||
The default realtime support for Macintosh OS X uses the CoreAudio HAL API and is specified during compilation using the __MACOSX_CORE__ preprocessor definition. There is also support for the JACK audio server using the __UNIX_JACK__ preprocessor definition.
|
||||
|
||||
It is necessary to install the OS X developer kit (or the command line tools) in order to compile STK. STK was successfully tested on the latest version of OS X.
|
||||
|
||||
Tcl/Tk on OS X:
|
||||
|
||||
The Tcl/Tk interpreter included in the Xcode package seems outdated. Try getting tcl-tk through HomeBrew for an updated version.
|
||||
|
||||
It appears that socket support in Tcl/Tk on OS X uses the Nagle algorithm, which produces poor response between changes made in the Tcl/Tk script and the resulting audio updates. Note that this is only a problem when using a socket connection from a Tcl/Tk script.
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
STK: A ToolKit of Audio Synthesis Classes and Instruments in C++
|
||||
Version 3.2
|
||||
|
||||
By Perry R. Cook, 1995-2000
|
||||
and Gary P. Scavone, 1997-2000.
|
||||
|
||||
Please read the file README.txt for more general STK information.
|
||||
|
||||
STK has always worked under NeXTStep without realtime audio or MIDI support. In general, STK should compile in this way using any generic C++ compiler. C++ exception handling was added to STK with release 3.2. I have had some difficulty testing this release under NeXTStep because our NeXTStep compilers at CCRMA are very old. We tried a newer version of gcc-2.7.2.2 and that mostly worked, though it died trying to compile the BowedBar class. Also, I was unable to locate the correct header for the random() function.
|
||||
|
||||
In summary, I _think_ STK will compile under NeXTStep with a fairly recent compiler, but you may have to do a little work to make it happen. If you do succeed, please let us know.
|
||||
|
||||
Just for clarification, "realtime" support and the use of the __STK_REALTIME_ define statement includes audio and MIDI input/output routines, as well as socket and thread routines for realtime message acquisition (Controller) and internet audio streaming (StrmWvIn, StrmWvOut).
|
||||
|
||||
@@ -1,15 +1,7 @@
|
||||
STK: A ToolKit of Audio Synthesis Classes and Instruments in C++
|
||||
Version 3.2
|
||||
The Synthesis ToolKit in C++ (STK)
|
||||
|
||||
By Perry R. Cook, 1995-2000
|
||||
and Gary P. Scavone, 1997-2000.
|
||||
By Perry R. Cook and Gary P. Scavone, 1995--2023.
|
||||
|
||||
Please read the file README.txt for more general STK information.
|
||||
Please read the file README and INSTALL for more general STK information.
|
||||
|
||||
It seems that SGI systems are not distributed with the GNU Makefile utilities. The default Make utility has very limited functionality, so your safest bet is to download the GNU Makefile utilities from the Internet and use STK's default Makefile. If this is not possible, try using Makefile.sgi (make -f Makefile.sgi).
|
||||
|
||||
Another issue that has crept up with this release is proper compiler support for C++ error handling. If you experience problems, you probably don't have a recent version of the C++ compiler. Otherwise, STK should compile and run on SGI platforms without any problems.
|
||||
|
||||
NOTE REGARDING PTHREADS:
|
||||
|
||||
Since release 3.1, STK has used the pthread API under Irix. It appears that pthread functionality is standard on SGI, so this change shouldn't cause any problems. If I'm wrong, let me know!
|
||||
Since STK version 4.3, realtime support for IRIX has been discontinued due to an inability to test it. If you need realtime support on an SGI, go back to version 4.2.1. Release 4.0 of STK is confirmed to compile (with various warnings) using CC version 7.30.
|
||||
|
||||
@@ -1,69 +1,26 @@
|
||||
STK: A ToolKit of Audio Synthesis Classes and Instruments in C++
|
||||
Version 3.2
|
||||
The Synthesis ToolKit in C++ (STK)
|
||||
|
||||
By Perry R. Cook, 1995-2000
|
||||
and Gary P. Scavone, 1997-2000.
|
||||
By Perry R. Cook and Gary P. Scavone, 1995--2023.
|
||||
|
||||
Please read the file README.txt for more general STK information.
|
||||
Please read the file README.md for more general STK information.
|
||||
|
||||
DirectX and WindowsNT Issues:
|
||||
-----------------------------
|
||||
The configure script supports MinGW.
|
||||
|
||||
STK is currently distributed with Visual C++ 6.0 project and workspace files.
|
||||
STK has been built and tested on Windows platforms using Visual Studio. It is assumed here that you're familiar with Visual C++ and its particular idiosyncrasies. The currently supported version is VS2017. You can download the free non-commercial community edition from the Microsoft website. The folders in the projects directory contain VS2017 solution files.
|
||||
If you are creating a new stk application, it's easiest to use the supplied template:
|
||||
- Copy stk\projects\stk-template.zip to C:\Users\<user>\Documents\Visual Studio 2017\Templates\ProjectTemplates\Visual C++ Project\
|
||||
- Start VS2017.
|
||||
- Select create new project...
|
||||
- Select Visual C++.
|
||||
- Select stk-template and enter your preferred project name and location. Note that if you do not put the project at the same level as stk\projects you will have to fix all paths in the project properties to match.
|
||||
- The template is based on one of the projects in the examples directory. Add/remove files as needed and edit main.cpp to taste.
|
||||
|
||||
The STK realtime sound input capabilities under Windoze are only supported using the DirectSoundCapture API. The latency is pretty horrendous, but what do you expect? Also, there is a chance you don't have DirectSoundCapture support on your computer. If not, you should download the DirectX 6.0 (or higher) runtime libraries from Microsoft's WWW site (http://www.microsoft.com/directx/download.asp) in order to run the pre-compiled STK executables for Windoze. The last time I checked, there was no DirectSoundCapture support for WindowsNT ... you'll have to switch to Windows 2000. I stopped supporting the WinMM audio output code with this release. So, if you wish to compile STK under WindowsNT (without realtime audio input support), you'll have to download an older version of STK, uncomment the __WINMM_API_ flag (and comment out the __WINDS_API flag) in Object.h and recompile the source code.
|
||||
To use the Tcl/Tk GUIs, you will have to install Tcl/Tk and build using MinGW.
|
||||
|
||||
Realtime sound output under Windoze is supported using the DirectSound (dsound.lib) API. All new versions of Win95/98/NT come with the DirectSound library, but early versions did not. If you have trouble running the distributed executables, then you probably don't have DirectSound installed on your system. You can download the necessary DirectSound stuff from Microsoft's WWW pages (http://www.microsoft.com/directx/download.asp).
|
||||
With Windows XP and later, piping works as under unix. Simply fire up the script files (e.g. StkDemo.bat) by either double-clicking on them or from within a shell.
|
||||
|
||||
Realtime MIDI input is supported using the winmm.lib API.
|
||||
The DirectSound, WASAPI and Steinberg ASIO audio APIs are supported for realtime audio input/output. The VS2017 project files included with this distribution are configured to use all supported APIs. The default (as in stk-template) is the DirectSound API (preprocessor definition __WINDOWS_DS__). In order to use the ASIO API, it is necessary to use the preprocessor definition __WINDOWS_ASIO__, as well as include most of the files in the /src/include/ directory (i.e. asio.h, asio.cpp, ...). If you have a good quality soundcard and a native ASIO driver (not emulated), you are likely to get much better input/output response using that.
|
||||
|
||||
Visual C++ 6.0 workspaces have been created for the various STK projects. Everything has already been configured for you. The intermediate .obj files will be written to either the "Release" or "Debug" directories, but the executable files will be written to the main project directories (where they need to be for proper execution). If you should somehow lose or hose the VC++ workspace file (STK.dsw), then you will have to do a LOT of configuring to recreate it ... it's probably easier just to download the distribution again from our WWW sites. Anyway, for your benefit and mine, here is a list of things that need to be added to the various "Project Settings":
|
||||
When using the DirectSound API for audio input, latency can be high. If you experience realtime audio "stuttering", you should experiment with different "buffer size" and "number of buffers" values.
|
||||
|
||||
1. Under General: Set "Output files:" to <blank> (this will put the executable in the main project directory.
|
||||
|
||||
2. Under C/C++ > Code Generation: Set "Use run-time library:" to Multithreaded (use "debug" versions for the debug configuration).
|
||||
|
||||
3. Under Link > General: Add winmm.lib, dsound.lib, and Wsock32.lib to the end of the Object/library modules list.
|
||||
|
||||
4. Under C/C++ > Preprocessor: Add "../../include" directory to the "extra include" field.
|
||||
|
||||
5. Add all the necessary files to the project.
|
||||
|
||||
Remember that items 1-3 above need to be done for each project and for each configuration. There might be an easy way to make global changes, but I couldn't figure it out.
|
||||
|
||||
To use the Tcl/Tk GUIs, you will have to install Tcl/Tk. I got version 8.0 and it works very well (and installed easily). The distribution is available on the WWW and is free.
|
||||
|
||||
In order for socketing to work, it is necessary to have the TCP protocol installed on your computer. This can be done from the "Network" control panel.
|
||||
|
||||
Finally, to use it all -
|
||||
|
||||
|
||||
PLAY SKINI SCOREFILES IN REALTIME:
|
||||
|
||||
syntmono Clarinet -or < scores/streetsf.ski
|
||||
|
||||
|
||||
USE TCL/TK GUIs FOR REALTIME CONTROL:
|
||||
|
||||
1. Open a DOS console window and start syntmono (eg. syntmono Clarinet -or -is).
|
||||
|
||||
2. Double click on a Tcl/Tk file in TCLSpecs (eg. TCLPhys.tcl) from the Windows Explorer to start the GUI. Select the "communications" menu item and "Socket" and make the connection.
|
||||
|
||||
3. Start moving the sliders to control the instrument.
|
||||
|
||||
|
||||
USE REALTIME MIDI INPUT FOR CONTROL:
|
||||
|
||||
1. Open a DOS console window and start syntmono with MIDI input (eg. syntmono Clarinet -or -im).
|
||||
|
||||
This assumes you already have MIDI setup correctly for your computer.
|
||||
|
||||
|
||||
WINDOWS NT ONLY:
|
||||
|
||||
Realtime piping seems to work under WindowsNT in much the same way as on Unix platforms. Thus, it is possible to pipe realtime control data to syntmono under WindowsNT as well.
|
||||
|
||||
|
||||
WINDOWS 2000:
|
||||
|
||||
I don't have Windows 2000 and I doubt I'll get it anytime soon. However, we briefly tested release 3.2 of STK on Perry's Win2000 machine and it worked fine. There is an advantage in using Windows 2000 over 95/98 in that piping works, just as under unix. Also, the scheduler in Win2000 seems to be much better, so socketed messages don't get clumped together like they do in Win 95/98. Since 2000 is supposed to ship with DirectX 7.0, the DirectSoundCapture functionality should work as well.
|
||||
Realtime MIDI input/output is supported by RtMidi using the winmm.lib API and requires the __WINDOWS_MM__ preprocessor definition.
|
||||
|
||||
128
doc/README.txt
128
doc/README.txt
@@ -1,128 +0,0 @@
|
||||
STK: A ToolKit of Audio Synthesis Classes and Instruments in C++
|
||||
Version 3.2
|
||||
|
||||
By Perry R. Cook, 1995-2000
|
||||
and Gary P. Scavone, 1997-2000.
|
||||
|
||||
Please read the Legal and Ethical notes near the bottom of this document.
|
||||
|
||||
|
||||
OVERVIEW:
|
||||
|
||||
STK is a set of audio signal processing C++ classes and instruments for music synthesis. You can use these classes to create programs which make cool sounds using a variety of synthesis techniques. This is not a terribly novel concept, except that STK is very portable (it's mostly platform-independent C and C++ code) AND it's completely user-extensible. So, the code you write using STK actually has some chance of working in another 5-10 years. STK currently runs with "realtime" support (audio and MIDI) on SGI (Irix), Linux, and Windows computer platforms. Generic, non-realtime support has been tested under NeXTStep, but should work with any standard C++ compiler. STK is free for non-commercial use. The only parts of STK that are platform-dependent concern real-time sound, MIDI, and control input and output ... but we've taken care of that for you. The interface for MIDI input and the simple Tcl/Tk graphical user interfaces (GUIs) provided is the same, so it's easy to voice and experiment in real time using either the GUIs or MIDI.
|
||||
|
||||
STK isn't one particular program. Rather, STK is a set of C++ classes that you can use to create your own programs. We've provided a few example applications that demonstrate some of the ways that you could use these classes. But if you have specific needs you will probably have to either modify the example programs or write a new program altogether. Further, the example programs don't have a fancy GUI wrapper. If you feel the need to have a "drag and drop" GUI, you probably don't want to use STK. Spending hundreds of hours making platform-dependent GUI code would go against one of the fundamental design goals of STK - platform independence. STK can generate simultaneous .snd, .wav, .aif, and .mat output soundfile formats (as well as realtime sound output), so you can view your results using one of the numerous sound/signal analysis tools already available over the WWW (e.g. Snd, Cool Edit, Matlab). For those instances where a simple GUI with sliders and buttons is helpful, we use Tcl/Tk (which is freely distributed for all the STK supported platforms). A number of Tcl/Tk GUI scripts are distributed with the STK release.
|
||||
|
||||
|
||||
SYSTEM REQUIREMENTS:
|
||||
|
||||
See the individual README's (eg. README-linux) for platform specific information and system requirements. In general, you will use either the provided Makefiles (Unix platforms) or the VC++ workspace files to compile the example programs. To use the Tcl/Tk GUIs, you will need Tcl/Tk version 8.0 or higher.
|
||||
|
||||
|
||||
WHAT'S NEW:
|
||||
|
||||
STK has undergone several key revisions, changes, and additions since its last release. Despite being available in one form or another since 1996, we still consider STK to be alpha software. Thus, backward compatability has not been a priority. Please read the ReleaseNotes to see what has changed since the last release.
|
||||
|
||||
The control message handling scheme has been simplified greatly with release 3.2 through the use of the Controller class. It is now possible to have access to simultaneous piped, socketed, and/or MIDI input control messages. In most cases, this should eliminate the use of the MD2SKINI program.
|
||||
|
||||
Realtime audio input capabilities were added to STK with release 3.0, though the behavior of such is very hardware dependent. Under Linux and Irix, audio input and output are possible with very low latency. Using the Windoze DirectSound API, minimum dependable output sound latency seems to be around 20 milliseconds or so, while input sound latency is on the order of a hundred milliseconds or more!
|
||||
|
||||
As mentioned above, it is possible to record the audio ouput of an STK program to .snd, .wav, .raw, .aif, and .mat (Matlab MAT-file) output file types. Though somewhat obsolete, the program MD2SKINI can be used to write SKINI scorefiles from realtime MIDI input. Finally, STK should compile with non-realtime functionality on any platform with a generic C++ compiler.
|
||||
|
||||
For those who wish to make a library from the core STK classes, there is a Makefile in the src directory that will accomplish that (Linux and SGI only).
|
||||
|
||||
GETTING STARTED:
|
||||
|
||||
A number of example "projects" are provided with this distribution. The effects directory contains a program that demonstrates realtime duplex mode (simultaneous audio input and output) operation, as well as several simple delay-line based effects algorithms. RagaMatic is a totally cool application for achieving inner peace. The examples directory contains several simple programs which demonstrate audio input/output, as well as the use of the audio internet streaming classes. The syntmono directory offers a program for monophonic STK instrument playback and manipulation. Syntmono is used to demonstrate most of the current STK instruments. Control data (in the form of MIDI or SKINI messages) is acquired by syntmono through pipe, socket, or MIDI connections. Tcl/Tk GUIs are provided which output SKINI formatted messages. A variety of SKINI scorefiles are distributed with STK and can be found in the "scores" directory of the syntmono project. MD2SKINI is an executable (currently compiles from the syntmono project) which takes raw MIDI input, converts it to SKINI format, and outputs the result to stdout or any socket host and port ID.
|
||||
|
||||
Unless you downloaded the distribution with precompiled Windoze binaries, it is necessary to first compile the sources. Under Linux or Irix, simply typing "make" in any of the particular project directories will begin the compilation process. If your Unix system does not have the GNU Makefile utilities, you will have to use one of the platform specific Makefiles (eg. make -f Makefile.sgi). To compile the projects under Windoze, you should use the VC++ 6.0 project files provided with the STK distribution.
|
||||
|
||||
|
||||
SYNTMONO:
|
||||
|
||||
Syntmono is used to demonstrate most of the current STK instruments. Syntmono can take realtime control input via MIDI and/or SKINI format via pipes or sockets, or it can be fed SKINI scorefile (non-realtime) input. Syntmono can output data in realtime, .wav, .snd, .aif, .mat (Matlab MAT-file), and/or .raw formats. Assuming you have successfully compiled the syntmono executable, a scorefile can be redirected to syntmono and the output heard in realtime in the following way:
|
||||
|
||||
syntmono Clarinet -or < scores/streetsf.ski
|
||||
|
||||
The "-or" flag specifies the realtime output option. Typing syntmono without arguments will provide a brief description of the instruments possible and the various input/output option flags. Tcl/Tk GUIs are provided in the "tcl" directory of each project, though you will have to install Tcl/Tk version 8.0 or higher on your system to use them (older versions of Tcl/Tk under Linux seem to be more forgiving than under IRIX). Realtime SKINI control data can be piped to syntmono from a Tcl/Tk GUI on Unix platforms and WinNT in the following way:
|
||||
|
||||
wish < TCLSpecs/TCLPhys.tcl | syntmono Clarinet -or -ip
|
||||
|
||||
The "-ip" flag specifies piped realtime input. It is not possible to use realtime pipes under Windoze95/98, so socket communication must be used instead. For socket communication, it is necessary to first start the syntmono socket server using the "-is" flag (socketed realtime input). For the time being, a default (hardwired) socket port of 2001 is being used by syntmono. After syntmono is running (and waiting for a socket client connection), a Tcl/Tk GUI can be started. When using the GUI, it is necessary to invoke the "communications" menu item and select "socket" to establish the connection. The same procedure is also possible on Unix platforms. Finally, realtime MIDI control input can be used to control syntmono by typing:
|
||||
|
||||
syntmono Clarinet -or -im
|
||||
|
||||
The "-im" flag specifies realtime MIDI input. It is possible to use piped, socketed, and/or MIDI control input simultaneously.
|
||||
|
||||
|
||||
DISCLAIMER:
|
||||
|
||||
You probably already guessed this, but just to be sure, we don't guarantee anything works. :-) It's free ... what do you expect? If you find a bug, please let us know and we'll try to correct it. You can also make suggestions, but again, no guarantees. Send email to prc@cs.princeton.edu and gary@ccrma.stanford.edu.
|
||||
|
||||
|
||||
LEGAL AND ETHICAL:
|
||||
|
||||
This software was designed and created to be made publicly available for free, primarily for academic purposes, so if you use it, pass it on with this documentation, and for free.
|
||||
|
||||
If you make a million dollars with it, give us some. If you make compositions with it, put us in the program notes.
|
||||
|
||||
Some of the concepts are covered by various patents, some known to us and likely others which are unknown. Many of the ones known to us are administered by the Stanford Office of Technology and Licensing.
|
||||
|
||||
The good news is that large hunks of the techniques used here are public domain. To avoid subtle legal issues, we'll not state what's freely useable here, but we'll try to note within the various classes where certain things are likely to be protected by patents.
|
||||
|
||||
|
||||
FURTHER READING:
|
||||
|
||||
For more documentation on this ToolKit, the classes, etc., read the file Hierarchy.txt and the individual class definitions. Also check the platform specific README's for specific system requirements.
|
||||
|
||||
|
||||
PERRY'S NOTES FROM THE ORIGINAL DISTRIBUTION:
|
||||
|
||||
This whole world was created with no particular hardware in mind. These examples are intended to be tutorial in nature, as a platform for the continuation of my research, and as a possible starting point for a software synthesis system. The basic motivation was to create the necessary unit generators to do the synthesis, processing, and control that I want to do and teach about. Little thought for optimization was given (see Object.cpp), and therefore improvements, especially speed enhancements, should be possible with these classes. It was written with some basic concepts in mind about how to let compilers optimize.
|
||||
|
||||
Your question at this point might be, "But Perry, with CMix, CMusic, CSound, CShells, CMonkeys, etc. already cluttering the landscape, why a new set of stupid C functions for music synthesis and processing?" The answers lie below.
|
||||
|
||||
1) I needed to port many of the things I've done
|
||||
into something which is generic enough to port
|
||||
further to different machines.
|
||||
|
||||
2) I really plan to document this stuff, so that
|
||||
you don't have to be me to figure out what's
|
||||
going on. (I'll probably be sorry I said this
|
||||
in a couple of years, when even I can't figure
|
||||
out what I was thinking.)
|
||||
|
||||
3) The classic difficulties most people have in
|
||||
trying to implement physical models are:
|
||||
|
||||
A) They have trouble understanding the papers,
|
||||
and/or in turning the theory into practice.
|
||||
|
||||
B) The Physical Model instruments are a pain to get
|
||||
to oscillate, and coming up with stable and
|
||||
meaningful parameter values is required to
|
||||
get the models to work at all.
|
||||
|
||||
This set of C++ unit generators and instruments
|
||||
might help to diminish the scores of emails I
|
||||
get asking what to do with those block diagrams
|
||||
I put in my papers.
|
||||
|
||||
4) I wanted to try some new stuff with modal synthesis,
|
||||
and implement some classic FM patches as well.
|
||||
|
||||
5) I wanted to reimplement, and newly implement
|
||||
more of the intelligent and physical performer
|
||||
models I've talked about in some of my papers.
|
||||
But I wanted to do it in a portable way, and in
|
||||
such a way that I can hook up modules quickly.
|
||||
I also wanted to make these instruments connectable
|
||||
to such player objects, so folks like Brad Garton
|
||||
who really think a lot about the players can connect
|
||||
them to my instruments, a lot about which I think.
|
||||
|
||||
6) More rationalizations to follow . . .
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,232 @@
|
||||
STK: A ToolKit of Audio Synthesis Classes and Instruments in C++
|
||||
Release 3.2
|
||||
The Synthesis ToolKit in C++ (STK)
|
||||
|
||||
By Perry R. Cook, 1995-2000
|
||||
and Gary P. Scavone, 1997-2000
|
||||
By Perry R. Cook and Gary P. Scavone, 1995--2023.
|
||||
|
||||
v.5.0.1 (10 August 2023)
|
||||
- see github site for complete details (github.com/thestk/stk)
|
||||
- cmake updates
|
||||
- fix for demo msvc project in Windows
|
||||
|
||||
v.5.0.0 (4 August 2023)
|
||||
- see github site for complete details (github.com/thestk/stk)
|
||||
- new filter design functionality in BiQuad (thanks to Navin Kumar!)
|
||||
- update to PitShift to use a single delay line
|
||||
- various updates for new RtAudio API
|
||||
|
||||
v.4.6.2 (17 November 2021)
|
||||
- see github site for complete details (github.com/thestk/stk)
|
||||
- bug fixes in LentPitShift and Granulate classes
|
||||
- Makefile fixes
|
||||
- miscellaneous bug fixes
|
||||
|
||||
v.4.6.1 (18 April 2019)
|
||||
- see github site for complete details (github.com/thestk/stk)
|
||||
- various documentation updates
|
||||
- new Recorder (flute a la Verge) class (thanks to Mathias Bredholt)
|
||||
- updated Modulate class to allow noise rate control
|
||||
- new VS2017 project files
|
||||
- fix in FileLoop::getSize() to return file size (not chunk size)
|
||||
|
||||
v.4.6.0 (31 August 2017)
|
||||
- see github site for complete details
|
||||
- various build system updates
|
||||
- fixes in FileWvIn / FileLoop for normalisation and scaling, as well as file opening
|
||||
- bug fix for MAT-files in FileWrite
|
||||
- bug fix in MidiFileIn.cpp for timing and time-code formats
|
||||
- updated versions of RtAudio and RtMidi
|
||||
|
||||
v4.5.1 (22 February 2017)
|
||||
- fix for FileWvIn / FileLoop classes to avoid keeping files open if not necessary
|
||||
- miscellaneous bug fixes, documented on GitHub site (github.com/thestk/stk)
|
||||
- update to play.cpp example to play mono files as stereo
|
||||
- bug fix in DelayL::setDelay() function
|
||||
- miscellanous build bug fixes
|
||||
|
||||
v4.5.0: (26 April 2014)
|
||||
- updated versions of RtAudio and RtMidi, with associated renaming of RtError class to either RtAudioError or RtMidiError and addition of WASAPI support in Windows
|
||||
- added support in FileRead for little-endian AIFC file format
|
||||
- new iOS project files (thanks to Ariel Elkin)
|
||||
- bug fix in FreeVerb that could cause crackling for stereo input
|
||||
- various bug fixes and updates to minimize compiler warnings
|
||||
- ADSR fix for decay/release time calculations
|
||||
- various updates to build system
|
||||
|
||||
v4.4.4: (24 August 2012)
|
||||
- new FreeVerb class (thanks to Greg Burlet)
|
||||
- new Guitar class
|
||||
- new electric guitar project
|
||||
- cleaned / revised Shakers class
|
||||
- updated versions of RtAudio and RtMidi
|
||||
- bug fix in LentPitShift
|
||||
- bug fix in Echo constructor
|
||||
- bug fix in FileWvIn (file size when chunking)
|
||||
- bug fix in StkFrames copy constructor
|
||||
|
||||
v4.4.3: (30 August 2011)
|
||||
- changed SINT24 to be lower 3 bytes of 32-bit word
|
||||
- bug fixes to vectorized tick functions in Effects classes
|
||||
- updated versions of RtAudio and RtMidi
|
||||
- fix to ADSR bugs
|
||||
- updates to the internal argument checking and reporting scheme
|
||||
- updates to Bowed class (thanks to Esteban Maestre!)
|
||||
- fixes for 24-bit support in FileRead and FileWrite
|
||||
- added WAVE_FORMAT_EXTENSIBLE support in FileWrite
|
||||
- added sample rate variable reading and writing for MAT-files in FileRead and FileWrite
|
||||
|
||||
v4.4.2: (4 February 2011)
|
||||
- added various header file includes for newer compilers
|
||||
- new LentPitShift class (thanks to Francois Germain)
|
||||
- added "addTo" function to Delay class
|
||||
- updates to RtAudio and RtMidi
|
||||
- bug fixes in Voicer class (thanks Richard Dobson!)
|
||||
- bug fixes in Granulate class
|
||||
- added Makefile.in to compile library and all projects, as well as clean and distclean all
|
||||
|
||||
v4.4.1: (3 June 2010)
|
||||
- added multi-channel/frame tick() virtual function to WvIn and WvOut abstract base classes (required update to RtWvOut class)
|
||||
- updated configure script to select g++ compiler by default
|
||||
- in demo.cpp: removed voicer grouping for messages, fixing polyphony when messages are on the same MIDI/SKINI channel
|
||||
- updates to RtAudio and RtMidi
|
||||
|
||||
v4.4: (30 April 2010)
|
||||
- all classes embedded in the "stk" namespace (except RtAudio, RtMidi, and RtError)
|
||||
- class WaveLoop renamed FileLoop
|
||||
- significant efficiency improvements via code restructuring and inlining
|
||||
- some class source (.cpp) files deleted as part of inlining (Generator, Filter, Function, WvIn, WvOut, Effect, Instrmnt, BowTable, ReedTable, JetTable, Vector3D)
|
||||
- updates to RtAudio and RtMidi
|
||||
- previous "tickFrame()" functions renamed "tick" for more consistent API
|
||||
- more consistent and scalable approach to multichannel data and computations
|
||||
- multichannel support added to Granulate class
|
||||
- Filter class made abstract. New Iir and Fir classes made for non-order-specific filtering.
|
||||
- new TapDelay class
|
||||
- SubNoise class deleted (same as sub-sampled "ticking" of Noise class)
|
||||
|
||||
|
||||
v4.3.1: (7 December 2007)
|
||||
- further headerless file support in FileRead
|
||||
- bug fix in RtWvOut.cpp
|
||||
- added configure support for MinGW
|
||||
- updates to RtAudio and RtMidi for MinGW
|
||||
- changes to channel assignment in demo.cpp
|
||||
|
||||
|
||||
v4.3.0: (13 August 2007)
|
||||
- an official MIT-like license
|
||||
- new functionality to automatically update class data when the STK sample rate changes (partly implemented)
|
||||
- updates for new RtAudio version 4.0
|
||||
- removed RtDuplex class, users should use RtAudio directly with a callback function
|
||||
- bug fix in interpolate() function in Stk.h for non-interleaved data
|
||||
- fixes / improvements to the Granulate class
|
||||
- fix in Whistle when doing animation
|
||||
- fixes in BlitSquare for frequency, harmonics, and dc offset
|
||||
- updates to Makefiles for non-realtime compile
|
||||
- fix in demo.cpp for voice channel assignment
|
||||
- updated versions of RtMidi and RtAudio
|
||||
- updated ASIO files for MinGW compiler
|
||||
- new FAQ in documentation
|
||||
- MAT-file bug fix in FileRead class
|
||||
|
||||
|
||||
v4.2.1: (14 October 2005)
|
||||
- greatly expanded StkFrames functionality (including interpolation and indexing by channel/frame)
|
||||
- new Granulate granular synthesis class
|
||||
- new Blit, BlitSaw, and BlitSquare bandlimited waveform classes (thanks to Robin Davies!)
|
||||
- removed Table class ... all functionality (including interpolation) now in StkFrames and FileRead classes
|
||||
- revised Socket class (now abstract) and added TcpServer, TcpClient, and UdpSocket subclasses
|
||||
- added Stk::showWarnings() and Stk::printErrors() functions to dis/enable warning and error printouts
|
||||
- extracted file I/O functionality to new FileRead and FileWrite classes
|
||||
- revised WvIn / WvOut class structure (WvIn / WvOut now abstract and file I/O functionality in new FileWvIn / FileWvOut subclasses)
|
||||
- new SineWave class which calculates its own static table of variable length (no rawwave dependency)
|
||||
- new sinewave.raw file of length 1024 samples (used to be 256)
|
||||
- TcpWvIn and TcpWvOut renamed InetWvIn and InetWvOut, with added support for UDP sockets
|
||||
- fixed bug in WvOut tickFrame( const StkFrames &frames ) function
|
||||
- fixed bug in demo.cpp when writing output soundfiles without realtime output
|
||||
- added "binary" open flag to MidiFileIn class for Windows
|
||||
- fixed oversized MAT-file header in WvOut.cpp
|
||||
- fixed case statement bug in MidiFileIn.cpp for sysex
|
||||
- added missing getDelay() function to DelayA.cpp
|
||||
- fixed modDepth omission in Chorus.cpp
|
||||
- fixed DC blocker initialization bug in Flute.cpp
|
||||
- changed Filter class behavior so no default clearing of state when changing coefficients
|
||||
- bug fixes to RtAudio, especially for Windows DirectSound and ASIO (thanks to Robin Davies)
|
||||
- bug fixes to RtMidi, especially for Linux (thanks to Pedro Pedro Lopez-Cabanillas)
|
||||
|
||||
|
||||
v4.2.0: (4 October 2004)
|
||||
- simultaneous multiple audio APIs supported at compile time
|
||||
- fixed hidden overloaded virtual functions
|
||||
- new Asymp exponential envelope class
|
||||
- various changes to better conform to standard C++ programming practices
|
||||
- MY_FLOAT type converted to StkFloat and changed throughout (use treesed utility to search/replace in old files)
|
||||
- most example programs rewritten to use an audio callback paradigm (which works better in OS-X)
|
||||
- new StkFrames class for vectorized multichannel data and associated new tick() functions making use of StkFrames
|
||||
- new RtMidi class with MIDI output capabilities (API changes)
|
||||
- new MidiFileIn class for reading MIDI files
|
||||
- revised Filter classes to use std::vectors for coefficients (API changes)
|
||||
- revised Messager class (now queues messages for retrieval) (API changes)
|
||||
- new abstract parent Effect class for various effects
|
||||
- added setT60 function to all reverbs
|
||||
- new abstract parent Generator class for various signal sources
|
||||
- new abstract parent Function class for tables and various non-linear functions
|
||||
- Skini class completely rewritten (simplified) using the C++ STL (API changes)
|
||||
- WvOut classes now clip to -1.0 to +1.0 and report out of range
|
||||
- new Mutex class
|
||||
- turned Nagle algorithm off by default in Socket class
|
||||
- error reporting standardized in all classes
|
||||
|
||||
v4.1.3: (22 March 2004)
|
||||
- bug fix in RtAudio for Windows DirectSound output only support
|
||||
|
||||
v4.1.2: (15 March 2004)
|
||||
- added Linux JACK support to RtAudio
|
||||
- added optional doNormalize argument to WvIn to allow specification of data normalization or not
|
||||
- added volume control to demo program and various Tcl scripts
|
||||
- added support for dynamic rawwavePath() setting
|
||||
- WaveLoop bug fix
|
||||
- fixed bug in ADSR::setReleaseTime() method
|
||||
- fixed missing initialization of apInput in non-default constructor of DelayA class
|
||||
- added time seeding of random number generator to Noise constructor
|
||||
- update to the contentsAt() method of Delay class
|
||||
- WAV file fixes (8-bit) in WvIn and WvOut classes
|
||||
- configure changes
|
||||
- updated <iostream> include statements and appended "std::" as necessary throughout for compatibility with gcc 3
|
||||
|
||||
v4.1.1: (24 October 2002)
|
||||
- bug fix in RtAudio for Macintosh OS X and Windows ASIO duplex operation
|
||||
- windows ASIO fix in Stk.h
|
||||
- documentation updates
|
||||
- expanded tutorial
|
||||
- fixed RtDuplex omission in src Makefile
|
||||
|
||||
v4.1: (8 October 2002)
|
||||
- Macintosh OS X support added
|
||||
- new Whistle class
|
||||
- added Voicer, SingWave, and VoicForm classes
|
||||
- improvements/fixes to the banded waveguide instruments
|
||||
- demo program now uses Voicer, allowing polyphony
|
||||
- demo Tcl/Tk scripts changed to use SKINI PitchChange instead of PitchBend
|
||||
- demo program response to PitchBend modified to octave up/down
|
||||
- several RtAudio fixes and improvements (OS X and Windows ASIO support added)
|
||||
- added nextOut() method to Delay classes
|
||||
- documentation fixes for Reverb classes
|
||||
- RAWWAVE_PATH changed to include the "rawwave" directory
|
||||
- "configure" support added for unix systems
|
||||
- multivoice flag (-n NUMBER) added as command line option to demo program
|
||||
- sample rate flag added as command line option to all example programs
|
||||
- socket port number added as command line option to all example programs
|
||||
|
||||
v4.0: (April 2002)
|
||||
- new documentation and tutorial
|
||||
- several new instruments, including Saxofony, BlowBotl, and StifKarp
|
||||
- new Stk base class, replacing Object class
|
||||
- new Filter class structure and methods
|
||||
- extensive modifications to WvIn and WvOut class structures and methods
|
||||
- looping functionality moved to WaveLoop (subclass of WvIn)
|
||||
- automatic file type detection in WvIn ... hosed WavWvIn, AifWvIn, RawWavIn, SndWavIn, and MatWvIn subclasses
|
||||
- new file type specifier argument in WvOut ... hosed WavWvOut, AifWvOut, RawWavOut, SndWavOut, and MatWvOut subclasses
|
||||
- some simplifications of Messager class (was Controller)
|
||||
- new independent RtAudio class
|
||||
- extensive revisions in code and a significant number of API changes
|
||||
|
||||
v3.2: (13 November 2000)
|
||||
- new control handling class (Controller)
|
||||
@@ -56,7 +280,7 @@ v3.0: (10 October 1999)
|
||||
- added RawWvOut class
|
||||
- new WvIn class with RawWvIn, SndWvIn, WavWvIn, MatWvIn, and RTWvIn subclasses
|
||||
- removed RawWave, RawShot, RawInterp, and RawLoop classes (supplanted by RawWvIn)
|
||||
- multi-channel data support in WvIn and WvOut classes using MY_MULTI data type (pointer to MY_FLOAT) and the methods mtick() and mlastOutput()
|
||||
- multi-channel data support in WvIn and WvOut classes using MY_MULTI data type (pointer to StkFloat) and the methods mtick() and mlastOutput()
|
||||
- now writing to primary buffer under Windoze when allowed by hardware
|
||||
- cleaned up Object.h a bit
|
||||
- pulled various utility and thread functions out of syntmono.cpp (to aid readability of the code)
|
||||
@@ -87,4 +311,4 @@ v1.0:
|
||||
|
||||
|
||||
v0.8:
|
||||
- One of (if not THE) original distributions for SGI, NeXTStep, and basic Win support. I think this came out in 1996.
|
||||
- One of (if not THE) original distributions for SGI, NeXTStep, and basic Win support. I think this came out in 1996.
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
This describes the 1.1 implementation of SKINI,
|
||||
updated for the 2.x release of STK:
|
||||
This describes the latest (version 1.1) implementation of SKINI.
|
||||
|
||||
Synthesis toolKit Instrument Network Interface
|
||||
|
||||
for the Synthesis Toolkit in C++ by Perry R. Cook
|
||||
and Gary Scavone, 1999.
|
||||
for the Synthesis Toolkit in C++ by Perry R. Cook.
|
||||
|
||||
*********************************
|
||||
* Too good to be true? *
|
||||
@@ -12,7 +10,7 @@ and Gary Scavone, 1999.
|
||||
* A SKINI Haiku. *
|
||||
*********************************
|
||||
|
||||
Profound thanks to Dan Trueman, Brad Garton, and
|
||||
Profound thanks to Dan trueman, Brad Garton, and
|
||||
Gary Scavone for input on this revision. Thanks
|
||||
also to MIDI, the NeXT MusicKit, ZIPI and all
|
||||
the creators and modifiers of these for good bases
|
||||
@@ -72,8 +70,8 @@ upon/from which to build and depart.
|
||||
I am basically a bottom-up designer with an awareness of top-
|
||||
down design ideas, so SKINI above all reflects the needs of my
|
||||
particular research and creative projects as they have arisen and
|
||||
developed. SKINI11 represents a profound advance beyond SKINI08
|
||||
and SKINI09 (the first versions), future SKINI's might
|
||||
developed. SKINI 1.1 represents a profound advance beyond
|
||||
versions 0.8 and 0.9 (the first versions), future SKINI's might
|
||||
reflect some changes. Compatibility with prior scorefiles
|
||||
will be attempted, but there aren't that many scorefiles out
|
||||
there yet.
|
||||
@@ -87,7 +85,7 @@ upon/from which to build and depart.
|
||||
the channel number is scanned as a long int. Channels could be socket
|
||||
numbers, machine IDs, serial numbers, or even unique tags for each
|
||||
event in a synthesis. Other fields might be used, as specified in the
|
||||
SKINI11.tbl file. This is described in more detail later.
|
||||
SKINItbl.h file. This is described in more detail later.
|
||||
|
||||
Fields in a SKINI line are delimited by spaces, commas, or
|
||||
tabs. The SKINI parser only operates on a line at a time,
|
||||
@@ -103,7 +101,7 @@ upon/from which to build and depart.
|
||||
NonMIDI message types include SetPath (sets a path for file
|
||||
use later), and OpenReadFile (for streaming, mixing, and applying
|
||||
effects to soundfiles along with synthesis, for example).
|
||||
Other NonMIDI message types include Trilling, HammerOn, etc. (these
|
||||
Other non-MIDI message types include Trilling, HammerOn, etc. (these
|
||||
translate to gestures, behaviors, and contexts for use by
|
||||
intellegent players and instruments using SKINI). Where possible
|
||||
I will still use these as MIDI extension messages, so foot
|
||||
@@ -111,31 +109,31 @@ upon/from which to build and depart.
|
||||
|
||||
All fields other than type, time, and channel are optional, and the
|
||||
types and useage of the additional fields is defined in the file
|
||||
SKINI11.tbl.
|
||||
SKINItbl.h.
|
||||
|
||||
The other important file used by SKINI is SKINI11.msg, which is a
|
||||
The other important file used by SKINI is SKINImsg.h, which is a
|
||||
set of #defines to make C code more readable, and to allow reasonably
|
||||
quick re-mapping of control numbers, etc.. All of these defined
|
||||
symbols are assigned integer values. For JAVA, the #defines could
|
||||
be replaced by declaration and assignment statements, preserving
|
||||
the look and behavior of the rest of the code.
|
||||
|
||||
4) C Files Used To Implement SKINI11
|
||||
4) C Files Used To Implement SKINI
|
||||
|
||||
SKINI11.cpp is an object which can either open a SKINI file, and
|
||||
Skini.cpp is an object which can either open a SKINI file, and
|
||||
successively read and parse lines of text as SKINI strings, or
|
||||
accept strings from another object and parse them. The latter
|
||||
functionality would be used by a socket, pipe, or other connection
|
||||
receiving SKINI messages a line at a time, usually in real time,
|
||||
but not restricted to real time.
|
||||
|
||||
SKINI11.msg should be included by anything wanting to use the
|
||||
SKINI11.cpp object. This is not mandatory, but use of the __SK_blah_
|
||||
SKINImsg.h should be included by anything wanting to use the
|
||||
Skini.cpp object. This is not mandatory, but use of the __SK_blah_
|
||||
symbols which are defined in the .msg file will help to ensure
|
||||
clarity and consistency when messages are added and changed.
|
||||
|
||||
SKINI11.tbl is used only by the SKINI parser object (SKINI11.cpp).
|
||||
In the file SKINI11.tbl, an array of structures is declared and
|
||||
SKINItbl.h is used only by the SKINI parser object (Skini.cpp).
|
||||
In the file SKINItbl.h, an array of structures is declared and
|
||||
assigned values which instruct the parser as to what the message
|
||||
types are, and what the fields mean for those message types.
|
||||
This table is compiled and linked into applications using SKINI, but
|
||||
@@ -159,29 +157,28 @@ upon/from which to build and depart.
|
||||
message line. (We might allow for multiple messages per
|
||||
line later using the semicolon, but probably not. A series
|
||||
of lines with deltaTimes of 0.0 denotes simultaneous events.
|
||||
For Readability, multiple messages per line doesn't help much,
|
||||
For read-ability, multiple messages per line doesn't help much,
|
||||
so it's unlikely to be supported later).
|
||||
|
||||
d) The first field must be a SKINI message name. (like NoteOn).
|
||||
These might become case-insensitive in SKINI11+, so don't plan
|
||||
on exciting clever overloading of names (like noTeOn being
|
||||
These might become case-insensitive in future versions, so don't
|
||||
plan on exciting clever overloading of names (like noTeOn being
|
||||
different from NoTeON). There can be a number of leading
|
||||
spaces or tabs, but don't exceed 32 or so.
|
||||
|
||||
e) The second field must be a time specification in seconds.
|
||||
For real-time applications, this field can be 0.0. A time
|
||||
field can be either delta-time (most common and the only one
|
||||
supported in SKINI0.8), or absolute time. Absolute time
|
||||
A time field can be either delta-time (most common and the only one
|
||||
supported in version 0.8), or absolute time. Absolute time
|
||||
messages have an '=' appended to the beginning of the floating
|
||||
point number with no space. So 0.10000 means delta time of
|
||||
100ms., while =0.10000 means absolute time of 100 ms. Absolute
|
||||
100 ms, while =0.10000 means absolute time of 100 ms. Absolute
|
||||
time messages make most sense in score files, but could also be
|
||||
used for (loose) synchronization in a real-time context. Real
|
||||
time messages should be time-ordered AND time-correct. That is,
|
||||
if you've sent 100 total delta-time messages of 1.0 seconds, and
|
||||
then send an absolute time message of =90.0 seconds, or if you
|
||||
send two absolute time messages of =100.0 and =90.0 in that
|
||||
order, things will get really fouled up. The SKINI1.1 parser
|
||||
order, things will get really fouled up. The SKINI parser
|
||||
doesn't know about time, however. The WvOut device is the
|
||||
master time keeper in the Synthesis Toolkit, so it should be
|
||||
queried to see if absolute time messages are making sense.
|
||||
@@ -198,7 +195,7 @@ upon/from which to build and depart.
|
||||
A -1 channel can be used as don't care, omni, or other functions
|
||||
depending on your needs and taste.
|
||||
|
||||
g) All remaining fields are specified in the SKINI11.tbl file.
|
||||
g) All remaining fields are specified in the SKINItbl.h file.
|
||||
In general, there are maximum two more fields, which are either
|
||||
SK_INT (long), SK_DBL (double float), or SK_STR (string). The
|
||||
latter is the mechanism by which more arguments can be specified
|
||||
@@ -208,7 +205,7 @@ upon/from which to build and depart.
|
||||
|
||||
6) A Short SKINI File:
|
||||
|
||||
/* Howdy!!! Welcome to SKINI11, by P. Cook 1999
|
||||
/* Howdy!!! Welcome to SKINI, by P. Cook 1999
|
||||
|
||||
NoteOn 0.000082 2 55 82
|
||||
NoteOff 1.000000 2 55 0
|
||||
@@ -240,10 +237,10 @@ upon/from which to build and depart.
|
||||
NoteOff 0.000000 2 71 82
|
||||
NoteOff 0.000000 2 79 82
|
||||
|
||||
7) The SKINI11.tbl File, How Messages are Parsed
|
||||
7) The SKINItbl.h File, How Messages are Parsed:
|
||||
|
||||
The SKINI11.tbl file contains an array of structures which
|
||||
are accessed by the parser object SKINI11.cpp. The struct is:
|
||||
The SKINItbl.h file contains an array of structures which
|
||||
are accessed by the parser object Skini.cpp. The struct is:
|
||||
|
||||
struct SKINISpec { char messageString[32];
|
||||
long type;
|
||||
@@ -261,9 +258,9 @@ upon/from which to build and depart.
|
||||
to be any more fields on this line. So if there
|
||||
is is NOPE in data2, data3 won't even be checked
|
||||
SK_INT : byte (actually scanned as 32 bit signed long int)
|
||||
If it's a MIDI data field which is required to
|
||||
be an integer, like a controller number, it's
|
||||
0-127. Otherwise) get creative with SK_INTs
|
||||
If it's a MIDI data field which is required to
|
||||
be an integer, like a controller number, it's
|
||||
0-127. Otherwise) get creative with SK_INTs
|
||||
SK_DBL : double precision floating point. SKINI uses these
|
||||
in the MIDI context for note numbers with micro
|
||||
tuning, velocities, controller values, etc.
|
||||
@@ -272,14 +269,14 @@ upon/from which to build and depart.
|
||||
scanning the string to EndOfLine and then passing
|
||||
it to a more intellegent handler. For example,
|
||||
MIDI SYSEX (system exclusive) messages of up to
|
||||
256bytes can be read as space-delimited integers
|
||||
256 bytes can be read as space-delimited integers
|
||||
into the 1K SK_STR buffer. Longer bulk dumps,
|
||||
soundfiles, etc. should be handled as a new
|
||||
message type pointing to a FileName, Socket, or
|
||||
something else stored in the SK_STR field, or
|
||||
as a new type of multi-line message.
|
||||
|
||||
Here's a couple of lines from the SKINI11.tbl file
|
||||
Here's a couple of lines from the SKINItbl.h file
|
||||
|
||||
{"NoteOff" , __SK_NoteOff_, SK_DBL, SK_DBL},
|
||||
{"NoteOn" , __SK_NoteOn_, SK_DBL, SK_DBL},
|
||||
@@ -287,13 +284,13 @@ upon/from which to build and depart.
|
||||
{"ControlChange" , __SK_ControlChange_, SK_INT, SK_DBL},
|
||||
{"Volume" , __SK_ControlChange_, __SK_Volume_ , SK_DBL},
|
||||
|
||||
{"StringDamping" , __SK_ControlChange_, __SK_StringDamping_ , SK_DBL},
|
||||
{"StringDetune" , __SK_ControlChange_, __SK_StringDetune_ , SK_DBL},
|
||||
{"StringDamping" , __SK_ControlChange_, __SK_StringDamping_, SK_DBL},
|
||||
{"StringDetune" , __SK_ControlChange_, __SK_StringDetune_, SK_DBL},
|
||||
|
||||
The first three are basic MIDI messages. The first two would cause the
|
||||
parser, after recognizing a match of the string "NoteOff" or "NoteOn",
|
||||
to set the message type to 128 or 144 (__SK_NoteOff_ and __SK_NoteOn_
|
||||
are #defined in the file SKINI11.msg to be the MIDI byte value, without
|
||||
are #defined in the file SKINImsg.h to be the MIDI byte value, without
|
||||
channel, of the actual MIDI messages for NoteOn and NoteOff). The parser
|
||||
would then set the time or delta time (this is always done and is
|
||||
therefore not described in the SKINI Message Struct). The next two
|
||||
@@ -325,71 +322,67 @@ upon/from which to build and depart.
|
||||
|
||||
8) Objects using SKINI
|
||||
|
||||
Here's a simple example of code which uses the SKINI object
|
||||
Here's a simple example of code which uses the Skini object
|
||||
to read a SKINI file and control a single instrument.
|
||||
|
||||
Skini score;
|
||||
Skini::Message message;
|
||||
instrument = new Mandolin(50.0);
|
||||
score = new SKINI11(argv[1]);
|
||||
while(score->getType() > 0) {
|
||||
tempDouble = score->getDelta();
|
||||
if (tempDouble < 0) {
|
||||
tempDouble = - tempDouble;
|
||||
tempDouble = tempDouble - output.getTime();
|
||||
if (tempDouble < 0) {
|
||||
printf("Bad News Here!!! Backward Absolute Time
|
||||
Required.\n");
|
||||
tempDouble = 0.0;
|
||||
}
|
||||
score.setFile( argv[1] );
|
||||
while ( score.nextMessage( message ) != 0 ) {
|
||||
tempDouble = message.time;
|
||||
if (tempDouble < 0) {
|
||||
tempDouble = - tempDouble;
|
||||
tempDouble = tempDouble - output.getTime();
|
||||
if (tempDouble < 0) {
|
||||
printf("Bad News Here!!! Backward Absolute Time Required.\n");
|
||||
tempDouble = 0.0;
|
||||
}
|
||||
tempLong = (long) (tempDouble * SRATE);
|
||||
for (i=0;i<tempLong;i++) {
|
||||
output.tick(instrument->tick());
|
||||
}
|
||||
tempLong = (long) ( tempDouble * Stk::sampleRate() );
|
||||
for ( i=0; i<tempLong; i++ ) {
|
||||
output.tick( instrument->tick() );
|
||||
}
|
||||
|
||||
tempDouble3 = message.floatValues[1] * NORM_MIDI;
|
||||
if ( message.type == __SK_NoteOn_ ) {
|
||||
if ( tempDouble3 == 0.0 ) {
|
||||
tempDouble3 = 0.5;
|
||||
instrument->noteOff( tempDouble3 );
|
||||
}
|
||||
tempDouble3 = score->getByteThree();
|
||||
if (score->getType()== __SK_NoteOn_ ) {
|
||||
tempDouble3 *= NORM_7;
|
||||
if (score->getByteThree() == 0) {
|
||||
tempDouble3 = 0.5;
|
||||
instrument->noteOff(tempDouble3);
|
||||
}
|
||||
else {
|
||||
tempLong = (int) score->getByteTwo();
|
||||
tempDouble2 = __MIDI_To_Pitch[tempLong];
|
||||
instrument->noteOn(tempDouble2,tempDouble3);
|
||||
}
|
||||
else {
|
||||
tempLong = message.intValues[0];
|
||||
tempDouble2 = Midi2Pitch[tempLong];
|
||||
instrument->noteOn( tempDouble2, tempDouble3 );
|
||||
}
|
||||
else if (score->getType() == __SK_NoteOff_) {
|
||||
tempDouble3 *= NORM_7;
|
||||
instrument->noteOff(tempDouble3);
|
||||
}
|
||||
else if (score->getType() == __SK_ControlChange_) {
|
||||
tempLong = score->getByteTwoInt();
|
||||
instrument->controlChange(tempLong,temp3.0);
|
||||
}
|
||||
score->nextMessage();
|
||||
}
|
||||
else if ( message.type == __SK_NoteOff_ ) {
|
||||
instrument->noteOff( tempDouble3 );
|
||||
}
|
||||
else if ( message.type == __SK_ControlChange_ ) {
|
||||
tempLong = message.intValues[0];
|
||||
instrument->controlChange( tempLong, tempDouble3 );
|
||||
}
|
||||
}
|
||||
|
||||
When the score (SKINI11 object) object is created from the
|
||||
filename in argv[1], the first valid command line is read
|
||||
from the file and parsed.
|
||||
When a SKINI score is passed to a Skini object using the
|
||||
Skini::setFile() function, valid messages are read from
|
||||
the file and returned using the Skini::nextMessage() function.
|
||||
|
||||
The score->getType() retrieves the messageType. If this is
|
||||
-1, there are no more valid messages in the file and the
|
||||
synthesis loop terminates. Otherwise, the message type is
|
||||
returned.
|
||||
A Skini::Message structure contains all the information parsed
|
||||
from a single SKINI message. A returned message type of zero
|
||||
indicates either an invalid message or the end of a scorefile.
|
||||
|
||||
getDelta() retrieves the deltaTime until the current message
|
||||
should occur. If this is greater than 0, synthesis occurs
|
||||
until the deltaTime has elapsed. If deltaTime is less than
|
||||
zero, the time is interpreted as absolute time and the output
|
||||
device is queried as to what time it is now. That is used to
|
||||
form a deltaTime, and if it's positive we synthesize. If
|
||||
it's negative, we print an error and pretend this never
|
||||
happened and we hang around hoping to eventually catch up.
|
||||
The "time" member of a Skini::Message is the deltaTime until the
|
||||
current message should occur. If this is greater than 0,
|
||||
synthesis occurs until the deltaTime has elapsed. If deltaTime is
|
||||
less than zero, the time is interpreted as absolute time and the
|
||||
output device is queried as to what time it is now. That is used
|
||||
to form a deltaTime, and if it's positive we synthesize. If it's
|
||||
negative, we print an error, pretend this never happened and we
|
||||
hang around hoping to eventually catch up.
|
||||
|
||||
The rest of the code sorts out message types NoteOn, NoteOff
|
||||
(including NoteOn with velocity 0), and ControlChange. The
|
||||
code implicitly takes into account the integer type of the
|
||||
control number, but all other data is treated as double float.
|
||||
|
||||
The last line reads and parses the next message in the file.
|
||||
2719
doc/doxygen/Doxyfile
Normal file
2719
doc/doxygen/Doxyfile
Normal file
File diff suppressed because it is too large
Load Diff
10
doc/doxygen/classes.txt
Normal file
10
doc/doxygen/classes.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
/*! \page classes Class Documentation
|
||||
|
||||
<UL>
|
||||
<LI><a class="qindex" href="hierarchy.html">Class Hierarchy</a></LI>
|
||||
<LI><a class="qindex" href="annotated.html">Class/Enum List</a></LI>
|
||||
<LI><a class="qindex" href="files.html">File List</a></LI>
|
||||
<LI><a class="qindex" href="functions.html">Compound Members</a></LI>
|
||||
</UL>
|
||||
|
||||
*/
|
||||
109
doc/doxygen/compile.txt
Normal file
109
doc/doxygen/compile.txt
Normal file
@@ -0,0 +1,109 @@
|
||||
/*! \page compile Compiling
|
||||
|
||||
The Synthesis ToolKit can be used in a variety of ways, depending on your particular needs. Some people choose the classes they need for a particular project and copy those to their working directory. Others create <TT>Makefiles</TT> that compile project-specific class objects from common <TT>src</TT> and <TT>include</TT> directories. And still others like to compile and link to a common library of object files. STK was not designed with one particular style of use in mind.
|
||||
|
||||
For specifics on creating Windows applications, see README-Win.txt.
|
||||
|
||||
\section rtvsnonrt "Realtime" vs. "Non-Realtime"
|
||||
|
||||
Most of the Synthesis ToolKit classes are platform independent. That
|
||||
means that they should compile on any reasonably current C++ compiler.
|
||||
The functionality needed for realtime audio and MIDI input/output, as
|
||||
well as realtime control message acquistion, is inherently platform
|
||||
and operating-system (OS) <I>dependent</I>. STK classes that require
|
||||
specific platform/OS support include RtAudio, RtWvOut, RtWvIn,
|
||||
RtDuplex, RtMidi, InetWvIn, InetWvOut, Socket, UdpSocket, TcpServer,
|
||||
TcpClient, Thread, and Mutex. These classes currently can only be
|
||||
compiled on Linux, Macintosh OS X, and Windows systems.
|
||||
|
||||
Without the "realtime" classes, it is still possible to read SKINI
|
||||
scorefiles for control input and to read and write to/from a variety
|
||||
of audio file formats (WAV, SND, AIFF, MAT-file, and RAW). If
|
||||
compiling for a "little-endian" host processor, the
|
||||
<TT>__LITTLE_ENDIAN__</TT> preprocessor definition should be provided.
|
||||
|
||||
|
||||
\section unix Unix Systems:
|
||||
|
||||
STK compiles with realtime support on the following flavors of the Unix operating system: Linux, Irix, and Macintosh OS X. Aside from differences in compilers, audio/MIDI APIs, and host endianness, the steps necessary to compile STK programs and classes on these platforms are the same. The following table summarizes these differences.
|
||||
|
||||
<CENTER>
|
||||
<TABLE BORDER=2 COLS=5 WIDTH="100%">
|
||||
<TR BGCOLOR="beige">
|
||||
<TD WIDTH="5%"><B>OS:</B></TD>
|
||||
<TD WIDTH="5%"><B>Realtime Audio/MIDI API:</B></TD>
|
||||
<TD WIDTH="5%"><B>Preprocessor Definition:</B></TD>
|
||||
<TD WIDTH="5%"><B>Library or Framework:</B></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>Linux</TD>
|
||||
<TD>ALSA</TD>
|
||||
<TD>__LINUX_ALSA__, \__LITTLE_ENDIAN__</TD>
|
||||
<TD><TT>asound, pthread</TT></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>Linux</TD>
|
||||
<TD>OSS (version 4.0 only, use ALSA for MIDI support)</TD>
|
||||
<TD>__LINUX_OSS__, \__LINUX_ALSA__, \__LITTLE_ENDIAN__</TD>
|
||||
<TD><TT>asound, pthread</TT></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>Linux and Macintosh OS-X</TD>
|
||||
<TD>Jack</TD>
|
||||
<TD>__UNIX_JACK__, \__LITTLE_ENDIAN__</TD>
|
||||
<TD><TT>asound, pthread, jack</TT></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>Macintosh OS X</TD>
|
||||
<TD>CoreAudio</TD>
|
||||
<TD>__MACOSX_CORE__</TD>
|
||||
<TD><TT>pthread, CoreAudio, CoreMIDI, CoreFoundation</TT></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</CENTER>
|
||||
|
||||
The available C++ compilers on any of these systems can vary.
|
||||
|
||||
One approach in using STK is to simply copy the class files needed for
|
||||
a particular program into a project directory. Taking the
|
||||
<TT>sineosc.cpp</TT> example from the previous tutorial chapter, it
|
||||
would be necessary to set up a directory that includes the files
|
||||
<TT>sineosc.cpp</TT>, the rawwave file <TT>sinewave.raw</TT> in a
|
||||
subdirectory called <TT>rawwaves</TT>, and the header and source files
|
||||
for the classes Stk, FileRead, FileWrite, FileWvIn, FileLoop, and
|
||||
FileWvOut. The program could then be compiled on a little-endian
|
||||
system, such as a PC running Linux, using the GNU g++ compiler as
|
||||
follows:
|
||||
\code g++ -Wall -D__LITTLE_ENDIAN__ -o sineosc Stk.cpp FileRead.cpp FileWrite.cpp FileWvIn.cpp FileLoop.cpp FileWvOut.cpp sineosc.cpp \endcode
|
||||
|
||||
Note that the <TT>sineosc.cpp</TT> example does not make use of realtime audio or MIDI input/output classes. For programs using any of the STK realtime classes mentioned above, it is necessary to specify an audio/MIDI API preprocessor definition and link with the appropriate libraries or frameworks.
|
||||
|
||||
When working with a number of different projects that make use of ToolKit classes, the above approach can become cumbersome (especially when trying to synchronize with new STK releases). Most of the STK projects (e.g., demo, effects, ...) contain <TT>Makefiles</TT> (built by the configure script) that compile project-specific class objects from the distribution <TT>src</TT> and <TT>include</TT> directories. This approach makes it relatively easy when upgrading to a new STK release (by making path substitutions in the <TT>Makefile</TT> or by moving the projects to a similar relative path within the new STK source tree). A <TT>Makefile</TT> is provided in the <TT>projects/examples</TT> directory for compiling all the tutorial programs, as well as other example programs. To compile the <TT>sineosc.cpp</TT> program, for example, one need only type <TT>make sineosc</TT> from within the <TT>projects/examples</TT> directory.
|
||||
|
||||
|
||||
\subsection library Library Use:
|
||||
|
||||
The STK distribution provides a <TT>Makefile</TT> that can be used on Unix systems to build a static library. After unpacking the distribution (<TT>tar -xzf stk-4.x.x.tar.gz</TT>), run the configure script by typing <TT>./configure</TT> from the top level distribution directory (see the INSTALL file in the same directory for more information). Then from within the <TT>src</TT> directory, type <TT>make</TT>. After a successful build, you may wish to move the library (<TT>libstk.a</TT>) and the contents of the <TT>include</TT> directory to standard library and include search paths on your system. For example, the linux RPM distribution of STK puts the library in <TT>/usr/lib/</TT> and the STK header files in <TT>/usr/include/stk/</TT>.
|
||||
|
||||
Assuming the library is located in a standard search path and the header files are located in <TT>/usr/include/stk/</TT>, the <TT>sineosc.cpp</TT> example from the previous tutorial chapter can be compiled on a little-endian system using the GNU g++ compiler as follows:
|
||||
|
||||
\code
|
||||
g++ -Wall -D__LITTLE_ENDIAN__ -I/usr/include/stk -o sineosc sineosc.cpp -lstk
|
||||
\endcode
|
||||
|
||||
With the header files in a standard search path, it is possible to modify the <TT>\#include</TT> statements in the <TT>sineosc.cpp</TT> program as follows:
|
||||
|
||||
\code
|
||||
#include "stk/FileLoop.h"
|
||||
#include "stk/FileWvOut.h"
|
||||
\endcode
|
||||
|
||||
and then compile without an explicit include path argument to the compiler:
|
||||
|
||||
\code
|
||||
g++ -Wall -D__LITTLE_ENDIAN__ -o sineosc sineosc.cpp -lstk
|
||||
\endcode
|
||||
|
||||
|
||||
[<A HREF="tutorial.html">Main tutorial page</A>] [<A HREF="filtering.html">Next tutorial</A>]
|
||||
*/
|
||||
54
doc/doxygen/control.txt
Normal file
54
doc/doxygen/control.txt
Normal file
@@ -0,0 +1,54 @@
|
||||
/*! \page controlin Control Input
|
||||
|
||||
Each Synthesis ToolKit instrument exposes its relevant control parameters via public functions such as setFrequency() and controlChange(). Programmers are free to implement the control scheme of their choice in exposing those parameters to the user.
|
||||
|
||||
A text-based control protocol called <A HREF="skini.html">SKINI</A> is provided with the Synthesis ToolKit. SKINI extends the MIDI protocol in incremental ways, providing a text-based messaging scheme in human-readable format and making use of floating-point numbers wherever possible. Each SKINI message consists of a message type (e.g., NoteOn, PitchBend), a time specification (absolute or delta), a channel number (scanned as a long integer), and a maximum of two subsequent message-specific field values. Knowing this, it should be relatively clear what the following SKINI "scorefile" specifies:
|
||||
|
||||
\code
|
||||
NoteOn 0.000082 2 55.0 82.3
|
||||
NoteOff 1.000000 2 55.0 64.0
|
||||
NoteOn 0.000082 2 69.0 82.8
|
||||
StringDetune 0.100000 2 10.0
|
||||
StringDetune 0.100000 2 30.0
|
||||
StringDetune 0.100000 2 50.0
|
||||
StringDetune 0.100000 2 40.0
|
||||
StringDetune 0.100000 2 22.0
|
||||
StringDetune 0.100000 2 12.0
|
||||
NoteOff 1.000000 2 69.0 64.0
|
||||
\endcode
|
||||
|
||||
MIDI messages are easily represented within the SKINI protocol.
|
||||
|
||||
The class stk::Messager can be used to acquire and parse MIDI messages
|
||||
from a MIDI device and SKINI messages from STDIN and socket
|
||||
connections. Incoming messages are acquired asynchronously and saved
|
||||
to an internal message queue of stk::Skini::Message types (MIDI
|
||||
messages are converted to the stk::Skini:Message format). The user
|
||||
then uses the stk::Messager:popMessage() function to retrieve incoming
|
||||
control messages. This function does not block, instead returning a
|
||||
message type of zero when no more messages are in the queue. Many of
|
||||
the example programs included with the ToolKit distribution use a
|
||||
stk::Messager instance to accept control input from the accompanying Tcl/Tk
|
||||
graphical user interfaces, from external MIDI devices, or from SKINI
|
||||
scorefiles.
|
||||
|
||||
In the following example, we'll modify the <TT>bethree.cpp</TT> program from the previous tutorial chapter and incorporate a stk::Messager class to allow control via SKINI messages read from a SKINI file.
|
||||
|
||||
\include controlbee.cpp
|
||||
|
||||
A realtime control message will usually have a delta time of zero, in which case it is processed as soon as possible. Non-realtime messages, normally from a scorefile, will usually have non-zero delta times. The scheme used in this example is designed to work for both scorefile and realtime input types. When no message is available from the queue, the instrument is "ticked" for DELTA_CONTROL_TICKS and then the queue is checked again. The value of DELTA_CONTROL_TICKS roughly defines the program "control rate" in a realtime context, though multiple available messages in the queue are processed in immediate succession when their delta time values are zero.
|
||||
|
||||
The \c processMessage() function centralizes the handling of control messages. Other control update schemes can be implemented, perhaps using a separate thread or in the \c main() function, and this function should work in any context.
|
||||
|
||||
Assuming the program is compiled as <TT>controlbee</TT> and the SKINI scorefile <A HREF="tutorial/bookert.ski"><TT>bookert.ski</TT></A> is in the <TT>scores</TT> directory, the program can be run as:
|
||||
|
||||
\code
|
||||
controlbee scores/bookert.ski
|
||||
\endcode
|
||||
|
||||
Only a few basic SKINI message type case statements are included in this example. It is easy to extend the program to support a much more elaborate set of instrument control parameters.
|
||||
|
||||
This example could also be easily extended to accept "realtime" control input messages via pipe, socket or MIDI connections. The stk::Messager class provides stk::Messager::startStdInput(), stk::Messager::startSocketInput(), and stk::Messager::startMidiInput() functions for this purpose.
|
||||
|
||||
[<A HREF="tutorial.html">Main tutorial page</A>] [<A HREF="multichannel.html">Next tutorial</A>]
|
||||
*/
|
||||
74
doc/doxygen/crealtime.txt
Normal file
74
doc/doxygen/crealtime.txt
Normal file
@@ -0,0 +1,74 @@
|
||||
/*! \page crealtime Realtime Audio (callback)
|
||||
|
||||
An alternative scheme for audio input/output is to define a specific
|
||||
function in which audio computations are performed and to let the
|
||||
audio system call this function when more input/output data can be
|
||||
accepted by the hardware (referred to as a callback scheme). In this
|
||||
section, we show how the previous <TT>rtsine.cpp</TT> program can be
|
||||
modified to work in a callback scenario. There is no "single-sample"
|
||||
interface for this functionality. The callback function will be
|
||||
invoked automatically by the audio system controller (RtAudio) when
|
||||
new data is needed and it is necessary to compute a full audio buffer
|
||||
of samples at that time (see \ref callback for further information).
|
||||
|
||||
The previous section described the use of the stk::RtWvOut class for
|
||||
realtime audio output. The stk::RtWvOut::tick() function writes data to a
|
||||
large ring-buffer, from which data is periodically written to the
|
||||
computer's audio hardware via an underlying callback routine.
|
||||
|
||||
\include crtsine.cpp
|
||||
|
||||
The sinusoidal oscillator is created as before. The instantiation of
|
||||
RtAudio requires quite a few more parameters, including output/input
|
||||
device and channel specifiers, the data format, and the desired buffer
|
||||
length (in frames). In this example, we request a single output
|
||||
channel using the default output device, zero channels of input, the
|
||||
RtAudio data format which corresponds to an <tt>StkFloat</tt>, and the
|
||||
RT_BUFFER_SIZE defined in Stk.h. The \c bufferFrames argument is an
|
||||
API-dependent buffering parameter (see RtAudio for further
|
||||
information).
|
||||
|
||||
We also provide the audio system controller with a pointer to our
|
||||
callback function and an optional pointer to data that will be made
|
||||
available in the callback. In this example, we need to pass only the
|
||||
pointer to the oscillator. In more complex programs, it is typically
|
||||
necessary to put all shared data in a <tt>struct</tt> (see the next
|
||||
tutorial program for an example) or make use of global variables.
|
||||
|
||||
Our callback routine is the \c tick() function. Function arguments
|
||||
include pointers to the audio input and output data buffers, the
|
||||
buffer size (in frames), a stream time argument, a status argument to
|
||||
test for over/underruns, and the data pointer passed in the
|
||||
openStream() function (if it exists). It is necessary to cast these
|
||||
pointers to their corresponding data types before use. Our tick()
|
||||
routine simply "ticks" the oscillator for \c nBufferFrames counts and
|
||||
writes the result into the audio data buffer before returning.
|
||||
|
||||
The \c main() function blocks at the std::cin.get() call until the
|
||||
user hits the "enter" key, after which the audio controller is shut
|
||||
down and program execution ends.
|
||||
|
||||
\section callback Blocking vs. Callbacks
|
||||
|
||||
Prior to version 4.2.0, all STK example projects and programs used
|
||||
blocking audio input/output functionality (typically with the RtWvIn,
|
||||
RtWvOut, or RtDuplex classes). In many instances, a blocking scheme
|
||||
results in a clearer and more straight-forward program structure.
|
||||
Within a graphical user interface (GUI) programming context, however,
|
||||
callback routines are often more natural.
|
||||
|
||||
In order to allow all STK programs to function with equal proficiency
|
||||
on all supported computer platforms, a decision was made to modify the
|
||||
example projects to use audio callback routines. The result is a more
|
||||
complicated code structure, which is unfortunate given that we
|
||||
generally strive to make STK code as clear as possible for educational
|
||||
purposes. This was especially an issue with the demo program because
|
||||
it is designed to function in both realtime and non-realtime contexts.
|
||||
The use of global variables has been avoided by defining data
|
||||
structures to hold all variables that must be accessible to the
|
||||
callback routine and other functions. Alternative schemes for making
|
||||
control updates could be designed depending on particular program
|
||||
needs and constraints.
|
||||
|
||||
[<A HREF="tutorial.html">Main tutorial page</A>] [<A HREF="instruments.html">Next tutorial</A>]
|
||||
*/
|
||||
299
doc/doxygen/download.txt
Normal file
299
doc/doxygen/download.txt
Normal file
@@ -0,0 +1,299 @@
|
||||
/*! \page download Download and Release Notes
|
||||
|
||||
\section down Download Version 5.0.1 (10 August 2023):
|
||||
|
||||
- <A HREF="http://ccrma.stanford.edu/software/stk/release/stk-5.0.1.tar.gz">Source distribution</A>
|
||||
|
||||
\section notes Release Notes:
|
||||
\subsection v5dot0dot1 Version 5.0.1
|
||||
- see github site for complete details (github.com/thestk/stk)
|
||||
- cmake updates
|
||||
- fix for demo msvc project in Windows
|
||||
|
||||
\subsection v5dot0dot0 Version 5.0.0
|
||||
- see github site for complete details (github.com/thestk/stk)
|
||||
- new filter design functionality in BiQuad (thanks to Navin Kumar!)
|
||||
- update to PitShift to use a single delay line
|
||||
- various updates for new RtAudio API
|
||||
|
||||
\subsection v4dot6dot2 Version 4.6.2
|
||||
- see github site for complete details (github.com/thestk/stk)
|
||||
- bug fixes in LentPitShift and Granulate classes
|
||||
- Makefile fixes
|
||||
- miscellaneous bug fixes
|
||||
|
||||
\subsection v4dot6dot1 Version 4.6.1
|
||||
- see github site for complete details (github.com/thestk/stk)
|
||||
- various documentation updates
|
||||
- new Recorder (flute a la Verge) class (thanks to Mathias Bredholt)
|
||||
- updated Modulate class to allow noise rate control
|
||||
- new VS2017 project files
|
||||
- fix in FileLoop::getSize() to return file size (not chunk size)
|
||||
|
||||
\subsection v4dot6dot0 Version 4.6.0
|
||||
- see github site for complete details (github.com/thestk/stk)
|
||||
- various build system updates
|
||||
- fixes in FileWvIn / FileLoop for normalisation and scaling, as well as file opening
|
||||
- bug fix for MAT-files in FileWrite
|
||||
- bug fix in MidiFileIn.cpp for timing and time-code formats
|
||||
- updated versions of RtAudio and RtMidi
|
||||
|
||||
\subsection v4dot5dot1 Version 4.5.1
|
||||
- fix for FileWvIn / FileLoop classes to avoid keeping files open if not necessary
|
||||
- miscellaneous bug fixes, documented on GitHub site (github.com/thestk/stk)
|
||||
- update to play.cpp example to play mono files as stereo
|
||||
- bug fix in DelayL::setDelay() function
|
||||
- miscellanous build bug fixes
|
||||
|
||||
\subsection v4dot5dot0 Version 4.5.0
|
||||
- Updated versions of RtAudio and RtMidi, with associated renaming of RtError class to either RtAudioError or RtMidiError
|
||||
- New iOS project files (thanks to Ariel Elkin)
|
||||
- Bug fix in FreeVerb that could cause crackling for stereo input
|
||||
- Various bug fixes and updates to minimize compiler warnings
|
||||
- ADSR fix for decay/release time calculations
|
||||
- Various updates to build system
|
||||
|
||||
\subsection v4dot4dot4 Version 4.4.4
|
||||
- New FreeVerb class (thanks to Greg Burlet)
|
||||
- New Guitar class
|
||||
- New electric guitar project
|
||||
- Updated versions of RtAudio and RtMidi
|
||||
- Cleaned / revised Shakers class
|
||||
- Bug fix in LentPitShift
|
||||
- Bug fix in Echo constructor
|
||||
- Bug fix in FileWvIn (file size when chunking)
|
||||
- Bug fix in StkFrames copy constructor
|
||||
|
||||
\subsection v4dot4dot3 Version 4.4.3
|
||||
- Changed SINT24 to be lower 3 bytes of 32-bit word.
|
||||
- Bug fixes to vectorized tick functions in Effects classes.
|
||||
- Updated versions of RtAudio and RtMidi.
|
||||
- Bug fixes in ADSR and Envelope classes.
|
||||
- Updates to the internal argument checking and reporting scheme.
|
||||
- Updates to Bowed class (thanks to Esteban Maestre!).
|
||||
- Fixes for 24-bit support in FileRead and FileWrite.
|
||||
- Added WAVE_FORMAT_EXTENSIBLE support in FileWrite.
|
||||
- Added sample rate variable reading and writing for MAT-files in FileRead and FileWrite.
|
||||
|
||||
\subsection v4dot4dot2 Version 4.4.2
|
||||
- Added various header file includes for newer compilers.
|
||||
- Updates to RtAudio and RtMidi.
|
||||
- New LentPitShift class (thanks to Francois Germain).
|
||||
- Bug fixes in Voicer class (thanks Richard Dobson!).
|
||||
- Added Makefile.in to compile library and all projects, as well as clean and distclean.
|
||||
|
||||
\subsection v4dot4dot1 Version 4.4.1
|
||||
- Added multi-channel/frame tick() virtual function to WvIn and WvOut abstract base classes (required update to RtWvOut class).
|
||||
- Updated configure script to select g++ compiler by default.
|
||||
- In demo.cpp: removed voicer grouping for messages, fixing polyphony when messages are on the same MIDI/SKINI channel.
|
||||
- Updates to RtAudio and RtMidi.
|
||||
|
||||
\subsection v4dot4dot0 Version 4.4.0
|
||||
- All classes embedded in the "stk" namespace (except RtAudio, RtMidi, and RtError).
|
||||
- Class WaveLoop renamed FileLoop.
|
||||
- Significant efficiency improvements via code restructuring and inlining.
|
||||
- Some class source (.cpp) files deleted as part of inlining (Generator, Filter, Function, WvIn, WvOut, Effect, Instrmnt, BowTable, ReedTable, JetTable, Vector3D).
|
||||
- Updates to RtAudio and RtMidi.
|
||||
- Previous "tickFrame()" functions renamed "tick" for more consistent API.
|
||||
- More consistent and scalable approach to multichannel data and computations.
|
||||
- Multichannel support added to Granulate class.
|
||||
- Filter class made abstract. New Iir and Fir classes made for non-order-specific filtering.
|
||||
- New TapDelay class.
|
||||
- SubNoise class deleted (same as sub-sampled "ticking" of Noise class).
|
||||
|
||||
\subsection v4dot3dot1 Version 4.3.1
|
||||
- Further headerless file support in FileRead.
|
||||
- Bug fix in RtWvOut.cpp.
|
||||
- Added configure support for MinGW.
|
||||
- Updates to RtAudio and RtMidi for MinGW.
|
||||
- Changes to channel assignment in demo.cpp.
|
||||
|
||||
\subsection v4dot3dot0 Version 4.3.0
|
||||
- An official MIT-like license.
|
||||
- New functionality to automatically update class data when the STK sample rate changes (partly implemented).
|
||||
- Updates for new RtAudio version 4.0.
|
||||
- Removed RtDuplex class, users should use RtAudio directly with a callback function.
|
||||
- Bug fix in interpolate() function in Stk.h for non-interleaved data.
|
||||
- Fixes / improvements to the Granulate class.
|
||||
- Fix in Whistle when doing animation.
|
||||
- Fixes in BlitSquare for frequency, harmonics, and dc offset.
|
||||
- Updates to Makefiles for non-realtime compile.
|
||||
- Fix in demo.cpp for voice channel assignment.
|
||||
- Updated versions of RtMidi and RtAudio.
|
||||
- Updated ASIO files for MinGW compiler.
|
||||
- New FAQ in documentation.
|
||||
- MAT-file bug fix in FileRead class.
|
||||
|
||||
\subsection v4dot2dot1 Version 4.2.1
|
||||
- Greatly expanded StkFrames functionality (including interpolation and indexing by channel/frame).
|
||||
- New Blit, BlitSaw, and BlitSquare bandlimited waveform classes (thanks to Robin Davies!).
|
||||
- New Granulate granular synthesis class.
|
||||
- Removed Table class ... all functionality (including interpolation) now in StkFrames and FileRead classes.
|
||||
- Revised Socket class (now abstract) and added TcpServer, TcpClient, and UdpSocket subclasses.
|
||||
- Added Stk::showWarnings() and Stk::printErrors() functions to dis/enable warning and error printouts.
|
||||
- Extracted file I/O functionality to FileRead and FileWrite classes.
|
||||
- Revised WvIn / WvOut class structure (WvIn / WvOut now abstract and file I/O functionality in new FileWvIn / FileWvOut subclasses).
|
||||
- New SineWave class which calculates its own static table of variable length (no rawwave dependency).
|
||||
- New sinewave.raw file of length 1024 samples (used to be 256).
|
||||
- TcpWvIn and TcpWvOut renamed InetWvIn and InetWvOut, with added support for UDP sockets.
|
||||
- Fixed bug in WvOut tickFrame( const StkFrames &frames ) function.
|
||||
- Fixed bug in demo.cpp when writing output soundfiles without realtime output.
|
||||
- Added "binary" open flag to MidiFileIn class for Windows.
|
||||
- Fixed oversized MAT-file header in WvOut.cpp
|
||||
- Fixed case statement bug in MidiFileIn.cpp for sysex.
|
||||
- Added missing getDelay() function to DelayA.cpp.
|
||||
- Fixed modDepth omission in Chorus.cpp.
|
||||
- Fixed DC blocker initialization bug in Flute.cpp.
|
||||
- Changed Filter class behavior so no default clearing of state when changing coefficients.
|
||||
- Fixes to RtAudio, especially for Windows DirectSound and ASIO (thanks to Robin Davies).
|
||||
|
||||
\subsection v4dot2dot0 Version 4.2.0
|
||||
- Simultaneous multiple audio APIs supported at compile time.
|
||||
- Various changes to better conform to standard C++ programming practices.
|
||||
- Fixed hidden overloaded virtual functions.
|
||||
- New Asymp exponential envelope class.
|
||||
- <tt>MY_FLOAT</tt> type converted to <tt>StkFloat</tt> and changed throughout (use \c treesed utility to search/replace in old files).
|
||||
- Most example programs rewritten to use an audio callback paradigm (which works better in OS-X).
|
||||
- New StkFrames class for vectorized multichannel data and associated new tick() functions making use of StkFrames.
|
||||
- New RtMidi class with MIDI output capabilities (API changes).
|
||||
- New MidiFileIn class for reading MIDI files.
|
||||
- Revised Filter classes to use std::vectors for coefficients (API changes).
|
||||
- Revised Messager class (API changes).
|
||||
- New abstract parent Effect class for various effects.
|
||||
- New abstract parent Generator class for various signal sources.
|
||||
- New abstract parent Function class for tables and various non-linear functions.
|
||||
- Skini class completely rewritten (simplified) using the C++ STL (API changes).
|
||||
- WvOut classes now clip to -1.0 to +1.0 and report out of range.
|
||||
- New Mutex class.
|
||||
- Turned Nagle algorithm off by default in Socket class.
|
||||
- Error reporting standardized in all classes.
|
||||
|
||||
\subsection v4dot1dot3 Version 4.1.3
|
||||
- Bug fix in RtAudio for Windows DirectSound output only support
|
||||
|
||||
\subsection v4dot1dot2 Version 4.1.2
|
||||
- Added Linux JACK support to RtAudio.
|
||||
- Added optional doNormalize argument to WvIn to allow specification of data normalization or not.
|
||||
- Added volume control to demo program and various Tcl scripts.
|
||||
- Added support for dynamic rawwavePath() setting.
|
||||
- WaveLoop bug fix.
|
||||
- Fixed bug in ADSR::setReleaseTime() method.
|
||||
- Fixed missing initialization of apInput in non-default constructor of DelayA class.
|
||||
- Added time seeding of random number generator to Noise constructor.
|
||||
- Update to the contentsAt() method of Delay class.
|
||||
- WAV file fixes (8-bit) in WvIn and WvOut classes.
|
||||
- Configure script changes.
|
||||
- Updated \<iostream\> include statements and appended "std::" as necessary throughout for compatibility with gcc 3.
|
||||
|
||||
\subsection v4dot1dot1 Version 4.1.1
|
||||
- Bug fix in RtAudio for Macintosh OS X and Windows ASIO duplex operation.
|
||||
- Windows ASIO fix in Stk.h.
|
||||
- Documentation updates.
|
||||
- Expanded tutorial.
|
||||
- Fixed RtDuplex omission in src Makefile.
|
||||
|
||||
\subsection v4dot1 Version 4.1
|
||||
- Macintosh OS X support added.
|
||||
- New Whistle class.
|
||||
- Added Voicer, SingWave, and VoicForm classes.
|
||||
- Improvements/fixes to the banded waveguide instruments.
|
||||
- Demo program now uses Voicer, allowing polyphony.
|
||||
- Demo Tcl/Tk scripts changed to use SKINI PitchChange instead of PitchBend.
|
||||
- Demo program response to PitchBend modified to octave up/down.
|
||||
- Several RtAudio fixes and improvements (OS X and Windows ASIO support added).
|
||||
- Added nextOut() method to Delay classes.
|
||||
- Documentation fixes for Reverb classes.
|
||||
- RAWWAVE_PATH changed to include the "rawwave" directory.
|
||||
- "configure" support added for unix systems.
|
||||
- Multivoice flag (-n NUMBER) added as command line option to demo program.
|
||||
- Sample rate flag added as command line option to example programs.
|
||||
- Socket port number added as command line option to example programs.
|
||||
|
||||
\subsection v4 Version 4.0
|
||||
- New documentation and tutorial.
|
||||
- Several new instruments, including Saxofony, BlowBotl, and StifKarp.
|
||||
- New Stk base class, replacing Object class.
|
||||
- New Filter class structure and methods.
|
||||
- Extensive modifications to WvIn and WvOut class structures and methods.
|
||||
- Looping functionality moved to WaveLoop (subclass of WvIn).
|
||||
- Automatic file type detection in WvIn ... hosed WavWvIn, AifWvIn, RawWavIn, SndWavIn, and MatWvIn subclasses.
|
||||
- New file type specifier argument in WvOut ... hosed WavWvOut, AifWvOut, RawWavOut, SndWavOut, and MatWvOut subclasses.
|
||||
- Some simplifications of Messager class (was Controller).
|
||||
- New independent RtAudio class.
|
||||
- Extensive revisions in code and a significant number of API changes.
|
||||
|
||||
\subsection v3dot2 Version 3.2
|
||||
- New input control handling class (Controller)
|
||||
- Added AIFF file input/output support.
|
||||
- New C++ error handling capabilities.
|
||||
- New input/output internet streaming support (StrmWvIn/StrmWvOut).
|
||||
- Added native ALSA support for linux.
|
||||
- Added optional "device" argument to all "Rt" classes (audio and MIDI) and printout of devices when argument is invalid.
|
||||
- WvIn classes rewritten to support very big files (incremental load from disk).
|
||||
- Changed WvIn/WvOut classes to work with sample frame buffers.
|
||||
- Fixed looping and negative rate calculations in WvIn classes.
|
||||
- Fixed interpolation bug in RtWvIn.
|
||||
- Windoze RtAudio code rewritten (thank Dave!).
|
||||
- Simplified byte-swapping functions (in-place swapping).
|
||||
- "Stereo-ized" RagaMatic.
|
||||
- Miscellaneous renamings.
|
||||
- Probably a bunch more fixes that I've long since forgotten about.
|
||||
|
||||
\subsection v3dot1 Version 3.1
|
||||
- New RagaMatic project ... very cool!!!
|
||||
- Less clipping in the Shakers class.
|
||||
- Added "microphone position" to Mandolin in STKdemo.
|
||||
- Fixed MIDI system message exclusion under Irix.
|
||||
- Added a few bitmaps for the Shaker instruments.
|
||||
- Made destructors virtual for Reverb.h, WvIn.h and Simple.h.
|
||||
- Fixed bug setting delay length in DLineA when value too big.
|
||||
- Fixed bug in WinMM realtime code (RTSoundIO).
|
||||
- Added tick() method to BowTabl, JetTabl, and ReedTabl (same as lookup).
|
||||
- Switched to pthread API on SGI platforms.
|
||||
- Added some defines to Object.h for random number generation, FPU overflow checking, etc....
|
||||
- A few minor changes, some bug fixes ... can't remember all of them.
|
||||
|
||||
\subsection v3 Version 3.0
|
||||
- New #define flags for OS and realtime dependencies (this will probably cause problems for old personal STK code, but it was necessary to make future ports easier).
|
||||
- Expanded and cleaned the Shakers class.
|
||||
- New BowedBar algorithm/class.
|
||||
- Fixed Linux MIDI input bug.
|
||||
- Fixed MIDI status masking problem in Windows.
|
||||
- OS type defines now in Makefile.
|
||||
- New RAWWAVE_PATH define in Object.h.
|
||||
- Syntmono project pulled out to separate directory and cleaned up.
|
||||
- Socketing capabilities under Unix, as well as Windoze.
|
||||
- Multiple simultaneous socket client connections to STK servers now possible.
|
||||
- MD2SKINI now can merge MIDI and piped messages under Irix and Linux (for TCL->MD2SKINI->syntmono control).
|
||||
- Defined INT16 and INT32 types and fixed various WvIn and WvOut classes.
|
||||
- Updated MatWvIn and MatWvOut for new MAT-file documentation from Matlab.
|
||||
- New demo Tcl/Tk GUI (TclDemo.tcl).
|
||||
- Minor fixes to FM behavior.
|
||||
- Added record/duplex capabilities to RTSoundIO (Linux, SGI, and Windoze).
|
||||
- Fixed bugs in WavWvOut and MatWvOut header specifications.
|
||||
- Added RawWvOut class.
|
||||
- New WvIn class with RawWvIn, SndWvIn, WavWvIn, MatWvIn, and RTWvIn subclasses.
|
||||
- Removed RawWave, RawShot, RawInterp, and RawLoop classes (supplanted by RawWvIn).
|
||||
- Multi-channel data support in WvIn and WvOut classes using MY_MULTI data type (pointer to StkFloat) and the methods mtick() and mlastOutput().
|
||||
- Now writing to primary buffer under Windoze when allowed by hardware.
|
||||
- Cleaned up Object.h a bit.
|
||||
- Pulled various utility and thread functions out of syntmono.cpp (to aid readability of the code).
|
||||
|
||||
\subsection v2dot02 Version 2.02
|
||||
- Created RawWave abstract class, with subclasses of RawLoop (looping rawwave oscillator), RawShot (non-looping, non-interpolating rawwave player ... used to be RawWvIn), and RawInterp (looping or non-looping, interpolating rawwave player ... used to be RawWave).
|
||||
- Modified DrumSynt to correctly handle sample rates different than 22050 Hz.
|
||||
- Modified syntmono parsing vs. tick routine so that some ticking occurs between each message. When multiple messages are waiting to be processed, the time between message updates is inversely proportional to the number of messages in the buffer.
|
||||
- Fixed DirectSound playback bug in WinXX distribution. Sound was being played at 8-bit, 22 kHz in all cases. Playback is now 16-bit and dependent on SRATE.
|
||||
- Fixed bug in MD2SKINI which prevented some NoteOff statements from being output.
|
||||
- This distribution includes an example STK project, mus151, which demonstrates a means for keeping a user's personal projects separate from the main distribution. This is highly recommended, in order to simplify upgrades to future STK releases.
|
||||
|
||||
\subsection v2 Version 2
|
||||
- Unification of the capabilities of STK across the various platforms. All of the previous SGI functionality has been ported to Linux and Windows, including realtime sound output and MIDI input.
|
||||
- MIDI input (with optional time-stamping) supported on SGI, Linux (OSS device drivers only), and Windows operating systems. Time stamping under IRIX and Windows is quantized to milliseconds and under Linux to hundredths of a second.
|
||||
- Various Sound Output Options - .wav, .snd, and .mat (Matlab MAT-file) soundfile outputs are supported on all operating systems. I hacked out the MAT-file structure, so you don't have to include any platform-specific libraries. Realtime sound output is provided as well, except under NeXTStep.
|
||||
- Multiple Reverberator Implementations - Reverb subclasses of JCRev and NRev (popular reverberator implementations from CCRMA) have been written. Perry's original reverb implementation still exists as PRCRev. All reverberators now take a T60 initializer argument.
|
||||
- MD2SKINI - A program which parses a MIDI input stream and spits out SKINI code. The output of MD2SKINI is typically piped into an STK instrument executable (e.g. <tt>MD2SKINI | syntmono Clarinet -r -i</tt>). In addition, you can supply a filename argument to MD2SKINI and have it simultaneously record a SKINI score file for future reuse.
|
||||
- Modifications to <I>Object.h</I> for OS_TYPE compilation dependencies. <I>Makefile</I> automatically determines OS_TYPE when invoked (if you have the GNU makefile utilities installed on your system).
|
||||
- A single distribution for all platforms. The Unix and Windows versions have been merged into a single set of classes. Makefiles and Visual C++ workspace/project files are provided for compiling.
|
||||
|
||||
*/
|
||||
81
doc/doxygen/faq.txt
Normal file
81
doc/doxygen/faq.txt
Normal file
@@ -0,0 +1,81 @@
|
||||
/*! \page faq Frequently Asked Questions
|
||||
|
||||
- \ref license
|
||||
- \ref filerate
|
||||
- \ref endianness
|
||||
- \ref xwindows
|
||||
|
||||
\section license Does STK have a license?
|
||||
|
||||
Yes, we finally made something official for release 4.3.0. It is listed in the Stk class and a few other places in the distribution, but I'll repeat it here for clarity:
|
||||
|
||||
\verbatim
|
||||
The Synthesis ToolKit in C++ (STK) is a set of open source audio
|
||||
signal processing and algorithmic synthesis classes written in the
|
||||
C++ programming language. STK was designed to facilitate rapid
|
||||
development of music synthesis and audio processing software, with
|
||||
an emphasis on cross-platform functionality, realtime control,
|
||||
ease of use, and educational example code. STK currently runs
|
||||
with realtime support (audio and MIDI) on Linux, Macintosh OS X,
|
||||
and Windows computer platforms. Generic, non-realtime support has
|
||||
been tested under NeXTStep, Sun, and other platforms and should
|
||||
work with any standard C++ compiler.
|
||||
|
||||
STK GitHub site: https://github.com/thestk/stk
|
||||
STK WWW site: http://ccrma.stanford.edu/software/stk/
|
||||
|
||||
The Synthesis ToolKit in C++ (STK)
|
||||
Copyright (c) 1995--2023 Perry R. Cook and Gary P. Scavone
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
asked to send the modifications to the original developer so that they
|
||||
can be incorporated into the canonical version. This is, however, not
|
||||
a binding provision of this license.
|
||||
|
||||
THE 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, 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 IN THE SOFTWARE.
|
||||
\endverbatim
|
||||
|
||||
\section filerate Why is my file sample rate wrong?
|
||||
|
||||
When the FileWvIn class loads a soundfile, it automatically sets its internal read increment based on the soundfile rate and the current STK sample rate. For example, if the current STK sample rate is 44100 Hz and the soundfile rate is 22050 Hz, the read increment, or rate, will be set to 0.5 and the file will be interpolated so that is sounds correct at 44100 Hz. For most cases, this works fine. However, consider the following example:
|
||||
|
||||
\code
|
||||
FileWvIn input( "infile" ); // read an input soundfile
|
||||
StkFloat sampleRate = input.getFileRate();
|
||||
Stk::setSampleRate( sampleRate ); // set a new STK sample rate based on the file rate
|
||||
\endcode
|
||||
|
||||
With version 4.3 and higher of STK, the FileWvIn class will be notified of a sample rate change and it will automatically adjust its read rate accordingly. Previous versions of STK did not perform this change and thus, the read rate could end up being incorrect. If you do not want FileWvIn to perform this automatic adjustment, you can call the \c ignoreSampleRateChange() function for a given class instance.
|
||||
|
||||
\section endianness Why does the sound I generated with STK sound like *&#@!?
|
||||
|
||||
If the resultant sound generated by an STK program sounds like noise (and you're not doing an MLS experiment), the problem is likely related to the byte "endianness" of your computer. By default, STK assumes "big endian" byte order. If you are working with STK classes on a PC (Windows or Linux), you \e must define the <TT>__LITTLE_ENDIAN__</TT> preprocessor definition \e before compiling. If after reading this you realize you need to make this change, do not forget to recompile all STK classes from scratch.
|
||||
|
||||
\section xwindows Why do I get a Tk display error message?
|
||||
|
||||
The following error may be printed to your terminal window (depending on the version of the Tcl/Tk interpreter you are running) if you attempt to start an STK Tcl/Tk interface without the X Server first running:
|
||||
|
||||
\code
|
||||
Application initialization failed: this isn't a Tk applicationcouldn't connect to display ":0.0"
|
||||
\endcode
|
||||
|
||||
Simply start your X server and then try the command again.
|
||||
|
||||
*/
|
||||
91
doc/doxygen/filtering.txt
Normal file
91
doc/doxygen/filtering.txt
Normal file
@@ -0,0 +1,91 @@
|
||||
/*! \page filtering Using Filters
|
||||
|
||||
In this section, we demonstrate the use of a few of the STK filter classes. The stk::Iir class provides functionality to implement a generalized infinite impulse response (IIR) digital filter, similar to the \c filter function in Matlab. In this example, we create an stk::Iir instance and initialize it with specific numerator and denominator coefficients. We then compute its impulse response for 20 samples.
|
||||
|
||||
\code
|
||||
#include "Iir.h"
|
||||
using namespace stk;
|
||||
|
||||
int main()
|
||||
{
|
||||
StkFrames output( 20, 1 ); // initialize StkFrames to 20 frames and 1 channel (default: interleaved)
|
||||
output[0] = 1.0;
|
||||
|
||||
std::vector<StkFloat> numerator( 5, 0.1 ); // create and initialize numerator coefficients
|
||||
std::vector<StkFloat> denominator; // create empty denominator coefficients
|
||||
denominator.push_back( 1.0 ); // populate our denomintor values
|
||||
denominator.push_back( 0.3 );
|
||||
denominator.push_back( -0.5 );
|
||||
|
||||
Iir filter( numerator, denominator );
|
||||
|
||||
filter.tick( output );
|
||||
for ( unsigned int i=0; i<output.size(); i++ ) {
|
||||
std::cout << "i = " << i << " : output = " << output[i] << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
\endcode
|
||||
|
||||
The stk::Iir class implements the standard difference equation
|
||||
\code
|
||||
a[0]*y[n] = b[0]*x[n] + ... + b[nb]*x[n-nb] - a[1]*y[n-1] - ... - a[na]*y[n-na],
|
||||
\endcode
|
||||
|
||||
where "b" values are numerator coefficients and "a" values are denominator coefficients. Note that if the first denominator coefficient is not 1.0, the Iir class automatically normalizes all filter coefficients by that value. The coefficient values are passed to the Iir class via a C++ <a href="http://www.cplusplus.com/reference/vector/vector/">vector</a>, a container object provided by the C++ Standard Library.
|
||||
|
||||
Most STK classes use more specific types of digital filters, such as the stk::OneZero, stk::OnePole, stk::TwoPole, or stk::BiQuad varieties. These classes inherit from the stk::Filter abstract base class and provide specific functionality particular to their use, as well as functions to independently control individual coefficient values.
|
||||
|
||||
\section reson Resonances:
|
||||
|
||||
The STK stk::BiQuad and stk::TwoPole classes provide functionality for creating resonance filters. The following example demonstrates how to create a resonance centered at 440 Hz that is used to filter the output of a stk::Noise generator.
|
||||
|
||||
\code
|
||||
#include "BiQuad.h"
|
||||
#include "Noise.h"
|
||||
using namespace stk;
|
||||
|
||||
int main()
|
||||
{
|
||||
StkFrames output( 20, 1 ); // initialize StkFrames to 20 frames and 1 channel (default: interleaved)
|
||||
Noise noise;
|
||||
|
||||
BiQuad biquad;
|
||||
biquad.setResonance( 440.0, 0.98, true ); // automatically normalize for unity peak gain
|
||||
|
||||
for ( unsigned int i=0; i<output.size(); i++ ) {
|
||||
output[i] = biquad.tick( noise.tick() ); // single-sample computations
|
||||
std::cout << "i = " << i << " : output = " << output[i] << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
\endcode
|
||||
|
||||
By passing a boolian value of \c true as the third argument to the stk::BiQuad::setResonance() function, the filter coefficients are automatically scaled to achieve unity gain at the resonance peak frequency. The previous code could be easily modified for "vector-based" calculations:
|
||||
|
||||
\code
|
||||
#include "BiQuad.h"
|
||||
#include "Noise.h"
|
||||
using namespace stk;
|
||||
|
||||
int main()
|
||||
{
|
||||
StkFrames output( 20, 1 ); // initialize StkFrames to 20 frames and 1 channel (default: interleaved)
|
||||
Noise noise;
|
||||
|
||||
BiQuad biquad;
|
||||
biquad.setResonance( 440.0, 0.98, true ); // automatically normalize for unity peak gain
|
||||
|
||||
biquad.tick( noise.tick( output ) ); // vector-based computations
|
||||
for ( unsigned int i=0; i<output.size(); i++ ) {
|
||||
std::cout << "i = " << i << " : output = " << output[i] << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
\endcode
|
||||
|
||||
[<A HREF="tutorial.html">Main tutorial page</A>] [<A HREF="realtime.html">Next tutorial</A>]
|
||||
*/
|
||||
9
doc/doxygen/footer.html
Normal file
9
doc/doxygen/footer.html
Normal file
@@ -0,0 +1,9 @@
|
||||
<HR>
|
||||
|
||||
<table>
|
||||
<tr><td><A HREF="http://ccrma.stanford.edu/software/stk/"><I>The Synthesis ToolKit in C++ (STK)</I></A></td></tr>
|
||||
<tr><td>©1995--2023 Perry R. Cook and Gary P. Scavone. All Rights Reserved.</td></tr>
|
||||
</table>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
65
doc/doxygen/fundamentals.txt
Normal file
65
doc/doxygen/fundamentals.txt
Normal file
@@ -0,0 +1,65 @@
|
||||
/*! \page fundamentals STK Fundamentals
|
||||
|
||||
The Synthesis ToolKit is implemented in the C++ programming language. STK does not attempt to provide a new programming environment or paradigm but rather provides a set of objects that can be used within a normal C++ programming framework. Therefore, it is expected that users of STK will have some familiarity with C/C++ programming concepts. That said, the STK classes do have some particular idiosyncrasies that we will mention here. Starting with STK version 4.4, all STK classes except RtAudio and RtMidi are defined within the stk namespace.
|
||||
|
||||
\section Signal Computations:
|
||||
|
||||
Audio and control signals throughout STK use a floating-point data type, <tt>StkFloat</tt>, the exact precision of which can be controlled via a typedef statement in Stk.h. By default, an StkFloat is a double-precision floating-point value. Thus, the ToolKit can use any normalization scheme desired. The base instruments and algorithms are implemented with a general audio sample dynamic maximum of +/-1.0.
|
||||
|
||||
In general, the computation and/or passing of values is performed on a "single-sample" basis. For example, the stk::Noise class outputs random floating-point numbers in the range +/-1.0. The computation of such values occurs in the stk::Noise::tick() function. The following program will generate 20 random floating-point (<tt>StkFloat</tt>) values in the range -1.0 to +1.0:
|
||||
|
||||
\code
|
||||
#include "Noise.h"
|
||||
using namespace stk;
|
||||
|
||||
int main()
|
||||
{
|
||||
StkFloat output;
|
||||
Noise noise;
|
||||
|
||||
for ( unsigned int i=0; i<20; i++ ) {
|
||||
output = noise.tick();
|
||||
std::cout << "i = " << i << " : output = " << output << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
\endcode
|
||||
|
||||
Nearly all STK classes implement <TT>tick()</TT> functions that take and/or return sample values. Within the <TT>tick()</TT> function, the fundamental sample calculations are performed for a given class. Most STK classes consume/generate a single sample per operation and their <TT>tick()</TT> method takes/returns each sample "by value". In addition, every class implementing a <TT>tick()</TT> function also provides one or more overloaded <TT>tick()</TT> functions that can be used for vectorized computations, as shown in the next example.
|
||||
|
||||
\code
|
||||
#include "Noise.h"
|
||||
using namespace stk;
|
||||
|
||||
int main()
|
||||
{
|
||||
StkFrames output(20, 1); // initialize StkFrames to 20 frames and 1 channel (default: interleaved)
|
||||
Noise noise;
|
||||
|
||||
noise.tick( output );
|
||||
for ( unsigned int i=0; i<output.size(); i++ ) {
|
||||
std::cout << "i = " << i << " : output = " << output[i] << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
\endcode
|
||||
|
||||
In this way, it might be possible to achieve improved processing efficiency using vectorized computations. The StkFrames class is a relatively new addition to the ToolKit to provide a general "mechanism" for handling and passing vectorized, multi-channel audio data. The StkFrames "type" provides functions to set and/or determine the number of audio channels and sample frames it holds. Further, the StkFrames class provides data interpolation and subscripting functionality by frame/channel values.
|
||||
|
||||
\section STK Inheritance:
|
||||
|
||||
Nearly all STK classes inherit from the Stk abstract base class, which provides common functionality related to error reporting, sample rate control, and byte swapping. Several other base classes exist that roughly group many of the classes according to function as follows:
|
||||
|
||||
- stk::Generator: source signal unit generator classes [stk::Envelope, stk::ADSR, stk::Asymp, stk::Noise, stk::SubNoise, stk::Modulate, stk::SingWave, stk::SineWave, stk::Blit, stk::BlitSaw, stk::BlitSquare, stk::Granulate]
|
||||
- stk::Filter: digital filtering classes [stk::OneZero, stk::OnePole, stk::PoleZero, stk::TwoZero, stk::TwoPole, stk::BiQuad, stk::FormSwep, stk::Delay, stk::DelayL, stk::DelayA, stk::TapDelay]
|
||||
- stk::Function: input to output function mappings [stk::BowTable, stk::JetTable, stk::ReedTable]
|
||||
- stk::Instrmnt: sound synthesis algorithms, including physical, FM, modal, and particle models
|
||||
- stk::Effect: sound processing effect classes [stk::Echo, stk::Chorus, stk::PitShift, stk::PRCRev, stk::JCRev, stk::NRev]
|
||||
- stk::WvOut: audio data output classes [stk::FileWvOut, stk::RtWvOut, stk::InetWvOut]
|
||||
- stk::WvIn: audio data input classes [stk::FileWvIn, stk::FileLoop, stk::RtWvIn, stk::InetWvIn]
|
||||
|
||||
|
||||
[<A HREF="tutorial.html">Main tutorial page</A>] [<A HREF="hello.html">Next tutorial</A>]
|
||||
*/
|
||||
10
doc/doxygen/header.html
Normal file
10
doc/doxygen/header.html
Normal file
@@ -0,0 +1,10 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>The Synthesis ToolKit in C++ (STK)</TITLE>
|
||||
<LINK HREF="doxygen.css" REL="stylesheet" TYPE="text/css">
|
||||
</HEAD>
|
||||
<BODY BGCOLOR="#FFFFFF">
|
||||
<CENTER>
|
||||
<img src="princeton.gif"> <img src="ccrma.gif"> <img src="mcgill.gif"><P>
|
||||
<a class="qindex" href="index.html">Home</a> <a class="qindex" href="information.html">Information</a> <a class="qindex" href="classes.html">Classes</a> <a class="qindex" href="download.html">Download</a> <a class="qindex" href="usage.html">Usage</a> <a class="qindex" href="maillist.html">Mail List</a> <a class="qindex" href="system.html">Requirements</a> <a class="qindex" href="links.html">Links</a> <a class="qindex" href="faq.html">FAQ</a> <a class="qindex" href="tutorial.html">Tutorial</a></CENTER>
|
||||
<HR>
|
||||
31
doc/doxygen/header.tex
Normal file
31
doc/doxygen/header.tex
Normal file
@@ -0,0 +1,31 @@
|
||||
\documentclass[letter]{book}
|
||||
\usepackage{makeidx}
|
||||
\usepackage{fancyhdr}
|
||||
\usepackage{graphicx}
|
||||
\usepackage{float}
|
||||
\usepackage{alltt}
|
||||
\usepackage{doxygen}
|
||||
\usepackage{hyperref}
|
||||
\makeindex
|
||||
\setcounter{tocdepth}{1}
|
||||
\setlength{\footrulewidth}{0.4pt}
|
||||
\begin{document}
|
||||
\begin{titlepage}
|
||||
\vspace*{7cm}
|
||||
\begin{center}
|
||||
{\Large User Manual}\\
|
||||
\vspace*{0.5cm}
|
||||
{\Large The Synthesis ToolKit in C++}\\
|
||||
\vspace*{1cm}
|
||||
{\large by Perry R. Cook and Gary P. Scavone}\\
|
||||
\vspace*{0.5cm}
|
||||
{\small \copyright 1995--2007}\\
|
||||
\end{center}
|
||||
\end{titlepage}
|
||||
\clearemptydoublepage
|
||||
\pagenumbering{roman}
|
||||
\rfoot[\fancyplain{}{\bfseries\scriptsize The Synthesis ToolKit in C++ by Perry R. Cook and Gary P. Scavone, \copyright~1995--2007}]{}
|
||||
\lfoot[]{\fancyplain{}{\bfseries\scriptsize The Synthesis ToolKit in C++ by Perry R. Cook and Gary P. Scavone, \copyright~1995--2007}}
|
||||
\tableofcontents
|
||||
\clearemptydoublepage
|
||||
\pagenumbering{arabic}
|
||||
94
doc/doxygen/hello.txt
Normal file
94
doc/doxygen/hello.txt
Normal file
@@ -0,0 +1,94 @@
|
||||
/*! \page hello Hello Sine!
|
||||
|
||||
We'll continue our introduction to the Synthesis ToolKit with a simple
|
||||
sine-wave oscillator program. STK provides two different classes for
|
||||
sine-wave generation. We will first look at a generic waveform
|
||||
oscillator class, stk::FileLoop, that can load a variety of common file
|
||||
types. In this example, we load a sine "table" from an STK RAW file
|
||||
(defined as monophonic, 16-bit, big-endian data). We use the class
|
||||
stk::FileWvOut to write the result to a 16-bit, WAV formatted audio file.
|
||||
|
||||
\code
|
||||
|
||||
// sineosc.cpp
|
||||
|
||||
#include "FileLoop.h"
|
||||
#include "FileWvOut.h"
|
||||
using namespace stk;
|
||||
|
||||
int main()
|
||||
{
|
||||
// Set the global sample rate before creating class instances.
|
||||
Stk::setSampleRate( 44100.0 );
|
||||
|
||||
FileLoop input;
|
||||
FileWvOut output;
|
||||
|
||||
// Load the sine wave file.
|
||||
input.openFile( "rawwaves/sinewave.raw", true );
|
||||
|
||||
// Open a 16-bit, one-channel WAV formatted output file
|
||||
output.openFile( "hellosine.wav", 1, FileWrite::FILE_WAV, Stk::STK_SINT16 );
|
||||
|
||||
input.setFrequency( 440.0 );
|
||||
|
||||
// Run the oscillator for 40000 samples, writing to the output file
|
||||
for ( int i=0; i<40000; i++ )
|
||||
output.tick( input.tick() );
|
||||
|
||||
return 0;
|
||||
}
|
||||
\endcode
|
||||
|
||||
stk::FileLoop is a subclass of stk::FileWvIn, which supports WAV, SND
|
||||
(AU), AIFF, MAT-file (Matlab), and RAW file formats with 8-, 16-, and
|
||||
32-bit integer and 32- and 64-bit floating-point data types.
|
||||
stk::FileWvIn provides interpolating, read-once ("oneshot")
|
||||
functionality, as well as methods for setting the read rate and read
|
||||
position.
|
||||
|
||||
stk::FileWvIn provides a "tick level" and interpolating interface to
|
||||
the stk::FileRead class. Likewise, stk::FileWvOut provides a "tick
|
||||
level" interface to the stk::FileWrite class. stk::FileRead and
|
||||
FileWrite both support WAV, SND(AU), AIFF, MAT-file (Matlab), and RAW
|
||||
file formats with 8-, 16-, and 32-bit integer and 32- and 64-bit
|
||||
floating-point data types. stk::FileWvOut does not currently offer
|
||||
data interpolation functionality.
|
||||
|
||||
A number of STK parent classes, including stk::WvIn, stk::WvOut,
|
||||
stk::Instrmnt, stk::Generator, and stk::Effect, (and some or all of
|
||||
their subclasses) support multi-channel sample frames. If a
|
||||
single-sample version of the <TT>tick()</TT> function is called for
|
||||
these classes, a full sample frame is computed but only a single value
|
||||
is either input and/or output. For example, if the single-sample
|
||||
<TT>tick()</TT> function is called for subclasses of stk::WvOut, the
|
||||
sample argument is written to all channels in the one computed frame.
|
||||
For classes returning values, an optional \c channel argument
|
||||
specifies which channel value is returned from the computed frame (the
|
||||
default is always channel 0). To input and/or output multichannel data
|
||||
to these classes, the overloaded <TT>tick()</TT> functions taking
|
||||
StkFrames reference arguments should be used.
|
||||
|
||||
Nearly all STK classes inherit from the stk::Stk base class. Stk
|
||||
provides a static sample rate that is queried by subclasses as needed.
|
||||
Because many classes use the current sample rate value during
|
||||
instantiation, it is important that the desired value be set at the
|
||||
beginning of a program. The default STK sample rate is 44100 Hz.
|
||||
|
||||
\section error Error Handling
|
||||
|
||||
The ToolKit has some basic C++ error handling functionality built in.
|
||||
Classes that access files and/or hardware are most prone to runtime
|
||||
errors. To properly "catch" such errors, the above example should be
|
||||
rewritten as shown below.
|
||||
|
||||
\include sineosc.cpp
|
||||
|
||||
In this particular case, we simply exit the program if an error occurs
|
||||
(an error message is automatically printed to stderr). A more refined
|
||||
program might attempt to recover from or fix a particular problem and,
|
||||
if successful, continue processing. See the \ref classes to determine
|
||||
which constructors and functions can throw an error.
|
||||
|
||||
[<A HREF="fundamentals.html">Main tutorial page</A>] [<A HREF="compile.html">Next tutorial</A>]
|
||||
*/
|
||||
BIN
doc/doxygen/images/ccrma.gif
Normal file
BIN
doc/doxygen/images/ccrma.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.1 KiB |
BIN
doc/doxygen/images/mcgill.gif
Normal file
BIN
doc/doxygen/images/mcgill.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.7 KiB |
BIN
doc/doxygen/images/princeton.gif
Normal file
BIN
doc/doxygen/images/princeton.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.3 KiB |
41
doc/doxygen/index.txt
Normal file
41
doc/doxygen/index.txt
Normal file
@@ -0,0 +1,41 @@
|
||||
/*! \mainpage The Synthesis ToolKit in C++ (STK)
|
||||
|
||||
\htmlonly
|
||||
<BODY BGCOLOR="white">
|
||||
<h3><center><a href="http://www.cs.princeton.edu/~prc/">Perry R. Cook</a> & <a href="http://music.mcgill.ca/~gary/">Gary P. Scavone</a></center></h3>
|
||||
\endhtmlonly
|
||||
|
||||
The <B>Synthesis ToolKit in C++ (STK)</B> is a set of open source
|
||||
audio signal processing and algorithmic synthesis classes written in
|
||||
the C++ programming language. STK was designed to facilitate rapid
|
||||
development of music synthesis and audio processing software, with an
|
||||
emphasis on cross-platform functionality, realtime control, ease of
|
||||
use, and educational example code. The Synthesis ToolKit is extremely
|
||||
portable (it's mostly platform-independent C and C++ code), and it's
|
||||
completely user-extensible (all source included, no unusual libraries,
|
||||
and no hidden drivers). We like to think that this increases the
|
||||
chances that our programs will still work in another 5-10 years. In
|
||||
fact, the ToolKit has been working continuously for nearly 20 years
|
||||
now. STK currently runs with realtime support (audio and MIDI) on
|
||||
Linux, Macintosh OS X, and Windows computer platforms. Generic,
|
||||
non-realtime support has been tested under NeXTStep, Sun, and other
|
||||
platforms and should work with any standard C++ compiler.
|
||||
|
||||
- \ref information
|
||||
- \ref classes
|
||||
- \ref download
|
||||
- \ref usage
|
||||
- \ref maillist
|
||||
- \ref system
|
||||
- \ref links
|
||||
- \ref faq
|
||||
- \ref tutorial
|
||||
- <A href="http://github.com/thestk/stk">Stk on GitHub</A>
|
||||
|
||||
*/
|
||||
|
||||
<P>
|
||||
<FONT SIZE=-1>
|
||||
STK is a registered trademark of Analytical Graphics, Inc., 40 General Warren Blvd., Malvern, PA 19355, the manufacturer of the Satellite Tool Kit<69> (STK<54>) family of satellite simulation software. Although the term "STK" is used in this website, the content of this site is in no way related to Analytical Graphics, Inc, or its registered STK mark. Nothing in this website should be construed to mean that a business relationship, either past or present, exists between Analytical Graphics, Inc. and the owners of this particular website.
|
||||
</FONT>
|
||||
|
||||
133
doc/doxygen/information.txt
Normal file
133
doc/doxygen/information.txt
Normal file
@@ -0,0 +1,133 @@
|
||||
/*! \page information General Information
|
||||
|
||||
<H3>References</H3>
|
||||
<UL>
|
||||
<LI><A HREF="papers/stkupdate.pdf">ICMC2005 Paper</A></LI>
|
||||
<BR>
|
||||
A paper by Gary and Perry detailing recent updates to the Synthesis ToolKit in C++.
|
||||
<P>
|
||||
<LI><A HREF="papers/stkicmc99.pdf">ICMC99 Paper</A></LI>
|
||||
<BR>
|
||||
A not-so-recent paper by Perry and Gary about the Synthesis ToolKit in C++.
|
||||
<P>
|
||||
<LI>Book Chapter: <A HREF="http://www.akpeters.com/product.asp?ProdCode=1047">Audio Anecdotes</A></LI>
|
||||
<BR>
|
||||
Here's a link to a book that includes an chapter on STK.
|
||||
</UL>
|
||||
|
||||
|
||||
<H4>What is the <I>Synthesis ToolKit</I>?</H4>
|
||||
|
||||
The Synthesis ToolKit in C++ (STK) is a set of open source audio signal processing and algorithmic synthesis classes written in the C++ programming language. STK was designed to facilitate rapid development of music synthesis and audio processing software, with an emphasis on cross-platform functionality, realtime control, ease of use, and educational example code. The Synthesis ToolKit is extremely portable (it's mostly platform-independent C and C++ code), and it's completely user-extensible (all source included, no unusual libraries, and no hidden drivers). We like to think that this increases the chances that our programs will still work in another 5-10 years. In fact, the ToolKit has been working continuously for nearly 20 years now. STK currently runs with realtime support (audio and MIDI) on Linux, Macintosh OS X, and Windows computer platforms. Generic, non-realtime support has been tested under NeXTStep, Sun, and other platforms and should work with any standard C++ compiler.
|
||||
|
||||
The Synthesis ToolKit is free. The only parts of the Synthesis ToolKit that are platform-dependent concern real-time audio and MIDI input and output, and that is taken care of with a few special classes. The interface for MIDI input and the simple <A HREF="https://www.tcl.tk/">Tcl/Tk</A> graphical user interfaces (GUIs) provided is the same, so it's easy to experiment in real time using either the GUIs or MIDI. The Synthesis ToolKit can generate simultaneous SND (AU), WAV, AIFF, and MAT-file output soundfile formats (as well as realtime sound output), so you can view your results using one of a large variety of sound/signal analysis tools already available (e.g. <A HREF="http://www-ccrma.stanford.edu/software/snd/">Snd</A>, Cool Edit, Matlab).
|
||||
|
||||
|
||||
<H4>What the <I>Synthesis ToolKit</I> is not.</H4>
|
||||
|
||||
The Synthesis Toolkit is not one particular program. Rather, it is a set of C++ classes that you can use to create your own programs. A few example applications are provided to demonstrate some of the ways to use the classes. If you have specific needs, you will probably have to either modify the example programs or write a new program altogether. Further, the example programs don't have a fancy GUI wrapper. It is easy to embed STK classes inside a GUI environment but we have chosen to focus our energy on the audio signal processing issues. Spending hundreds of hours making platform-dependent graphical user interfaces would go against one of the fundamental design goals of the ToolKit - platform independence.
|
||||
|
||||
For those instances where a simple GUI with sliders and buttons is helpful, we use <A HREF="https://www.tcl.tk/">Tcl/Tk</A> (that is freely distributed for all the supported ToolKit platforms). A number of Tcl/Tk GUI scripts are distributed with the ToolKit release. For control, the Synthesis Toolkit uses raw MIDI (on supported platforms), and SKINI (Synthesis ToolKit Instrument Network Interface, a MIDI-like text message synthesis control format).
|
||||
|
||||
<H4>A brief history of the <I>Synthesis ToolKit in C++.</I></H4>
|
||||
|
||||
Perry Cook began developing a pre-cursor to the Synthesis ToolKit
|
||||
(also called STK) under NeXTStep at the Center for Computer Research
|
||||
in Music and Acoustics (CCRMA) at Stanford University in the
|
||||
early-1990s. With his move to Princeton University in 1996, he ported
|
||||
everything to C++ on SGI hardware, added real-time capabilities, and
|
||||
greatly expanded the synthesis techniques available. With the help of
|
||||
Bill Putnam, Perry also made a port of STK to Windows95. Gary Scavone
|
||||
began using STK extensively in the summer of 1997 and completed a full
|
||||
port of STK to Linux early in 1998. He finished the fully compatible
|
||||
Windows port (using DirectSound API) in June 1998. Numerous
|
||||
improvements and extensions have been made since then.
|
||||
|
||||
The Toolkit has been distributed continuously since 1996 via the <A
|
||||
HREF="http://www.music.princeton.edu/psk">Princeton Sound Kitchen</A>,
|
||||
<A HREF="http://www.cs.princeton.edu/~prc">Perry Cook's home page</A>
|
||||
at Princeton, <A HREF="http://www.music.mcgill.ca/~gary/">Gary
|
||||
Scavone's home page</A> at McGill University, and the <A HREF="http://ccrma.stanford.edu/software/stk">Synthesis ToolKit
|
||||
home page</A>. The ToolKit has been included in various collections
|
||||
of software. Much of it has also been ported to Max/MSP on Macintosh
|
||||
computers by Dan Trueman and Luke Dubois of Columbia University, and
|
||||
is distributed as <A
|
||||
HREF="http://music.columbia.edu/PeRColate">PeRColate</A>. Help on
|
||||
real-time sound and MIDI has been provided over the years by Tim
|
||||
Stilson, Bill Putnam, and Gabriel Maldonado.
|
||||
|
||||
<H4>Legal and Ethical Notes</H4>
|
||||
|
||||
This software was designed and created to be made publicly available
|
||||
for free, primarily for academic purposes, so if you use it, pass it
|
||||
on with this documentation, and for free. If you make a million
|
||||
dollars with it, it would be nice if you would share. If you make
|
||||
compositions with it, put us in the program notes.
|
||||
|
||||
Some of the concepts are covered by various patents, some known to us
|
||||
and likely others that are unknown. Many of the ones known to us are
|
||||
administered by the Stanford Office of Technology and Licensing. The
|
||||
good news is that large hunks of the techniques used here are public
|
||||
domain. To avoid subtle legal issues, we will not state what's freely
|
||||
useable here, but we will try to note within the various classes where
|
||||
certain things are likely to be protected by patents.
|
||||
|
||||
<H4>License</H4>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
asked to send the modifications to the original developer so that they
|
||||
can be incorporated into the canonical version. This is, however, not
|
||||
a binding provision of this license.
|
||||
|
||||
THE 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
ANY CLAIM, 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 IN THE SOFTWARE.
|
||||
|
||||
<H4>Disclaimer</H4>
|
||||
|
||||
STK is free and we do not guarantee anything. We've been hacking on this code for a while now and most of it seems to work pretty well. But, there surely are some bugs floating around. Sometimes things work fine on one computer platform but not so fine on another. FPU overflows and underflows cause <I>very</I> weird behavior that also depends on the particular CPU and OS. Let us know about bugs you find and we'll do our best to correct them.
|
||||
|
||||
<H4>Perry's Notes From the Original Distribution of STK</H4>
|
||||
|
||||
This whole world was created with no particular hardware in mind. These examples are intended to be tutorial in nature, as a platform for the continuation of my research, and as a possible starting point for a software synthesis system. The basic motivation was to create the necessary unit generators to do the synthesis, processing, and control that I want to do and teach about. Little thought for optimization was given and therefore improvements, especially speed enhancements, should be possible with these classes. It was written with some basic concepts in mind about how to let compilers optimize.
|
||||
|
||||
Your question at this point might be, "But Perry, with CMix, CMusic, CSound, CShells, CMonkeys, etc. already cluttering the landscape, why a new set of stupid C functions for music synthesis and processing?" The answers lie below.
|
||||
|
||||
<ol>
|
||||
<li>I needed to port many of the things I've done into something that is generic enough to port further to different machines.</li>
|
||||
|
||||
<li>I really plan to document this stuff, so that you don't have to be me to figure out what's going on. (I'll probably be sorry I said this in a couple of years, when even I can't figure out what I was thinking.)</li>
|
||||
|
||||
<li>The classic difficulties most people have in trying to implement physical models are:
|
||||
|
||||
<ul>
|
||||
<li>They have trouble understanding the papers, and/or in turning the theory into practice.</li>
|
||||
|
||||
<li>The physical model instruments are a pain to get to oscillate, and coming up with stable and meaningful parameter values is required to get the models to work at all.</li>
|
||||
</ul>
|
||||
|
||||
This set of C++ unit generators and instruments might help to diminish the scores of emails I get asking what to do with those block diagrams I put in my papers.</li>
|
||||
|
||||
<li>I wanted to try some new stuff with modal synthesis, and implement some classic FM patches as well.</li>
|
||||
|
||||
<li>I wanted to reimplement, and newly implement more of the intelligent and physical performer models I've talked about in some of my papers. But I wanted to do it in a portable way, and in such a way that I can hook up modules quickly. I also wanted to make these instruments connectable to such player objects, so folks like Brad Garton who really think a lot about the players can connect them to my instruments, a lot about which I think.</li>
|
||||
|
||||
<li>More rationalizations to follow ...</li>
|
||||
</ol>
|
||||
|
||||
*/
|
||||
19
doc/doxygen/instruments.txt
Normal file
19
doc/doxygen/instruments.txt
Normal file
@@ -0,0 +1,19 @@
|
||||
/*! \page instruments Instruments
|
||||
|
||||
The ToolKit comes with a wide variety of synthesis algorithms, all of which inherit from the stk::Instrmnt class. In this example, we'll fire up an instance of the stk::BeeThree FM synthesis class and show how its frequency can be modified over time.
|
||||
|
||||
\include bethree.cpp
|
||||
|
||||
We have used an Instrmnt pointer when referencing the BeeThree
|
||||
instance above, so it would be simple to replace the BeeThree class
|
||||
with any other STK instrument class. It should be noted, however,
|
||||
that a few classes do not respond to the setFrequency() function
|
||||
(e.g., Shakers, Drummer).
|
||||
|
||||
The noteOn() function initiates an instrument attack. Instruments that are continuously excited (e.g., stk::Clarinet, stk::BeeThree) will continue to sound until stopped with a noteOff(). Impulsively excited instrument sounds (e.g., stk::Plucked, stk::Wurley) typically decay within a few seconds time, requiring subsequent noteOn() messages for re-attack.
|
||||
|
||||
Instrument parameters can be precisely controlled as demonstrated above. A more flexible approach to instrument control, allowing arbitrary scorefile or realtime updates, is described in the next tutorial chapter.
|
||||
|
||||
[<A HREF="tutorial.html">Main tutorial page</A>] [<A HREF="controlin.html">Next tutorial</A>]
|
||||
*/
|
||||
|
||||
25
doc/doxygen/links.txt
Normal file
25
doc/doxygen/links.txt
Normal file
@@ -0,0 +1,25 @@
|
||||
/*! \page links Miscellaneous Links
|
||||
|
||||
- <A HREF="http://www.music.mcgill.ca/~gary/rtaudio/">The %RtAudio WWW site</A>
|
||||
|
||||
- <A HREF="http://www.music.mcgill.ca/~gary/rtmidi/">The %RtMidi WWW site</A>
|
||||
|
||||
- <A HREF="http://momu.stanford.edu/stk/">MoMu-Stk: A lightly modified version of STK that supports the iPhone platform (iPhone, iPad, iPod Touches)</A>
|
||||
|
||||
- <A HREF="http://ccrma.stanford.edu/~woony/software/stkx/">StkX: A Cocoa STK Framework for Mac OS X by Woon Seung Yeo</A>
|
||||
|
||||
- <A HREF="http://sourceforge.net/projects/mobilestk">Mobile STK: A port of STK for mobile devices by Georg Essl and Michael Rohs</A>
|
||||
|
||||
- <A HREF="http://chuck.cs.princeton.edu/">ChucK: Concurrent, On-the-fly Audio Programming Language</A> using STK unit generators
|
||||
|
||||
- <A HREF="http://kern.ccarh.org">Kern Scores: A Library of Electronic Musical Scores</A> (with automatic conversion to SKINI format)
|
||||
|
||||
- <A HREF="http://stk.sapp.org/midi2skini">MIDI to SKINI file converter</A> by Craig Sapp
|
||||
|
||||
- <A HREF="http://extra.humdrum.org/example/kern2skini/">Kern Score to SKINI file converter</A> by Craig Sapp
|
||||
|
||||
- <A HREF="http://www.music.columbia.edu/PeRColate/">PeRColate: A Port of STK for Max/MSP</A>
|
||||
|
||||
- <a href="http://airy.andre.online.fr/AU/index.html">AUStk: a demo of integration of STK instruments into an AudioUnit</a> by Airy Andre
|
||||
|
||||
*/
|
||||
14
doc/doxygen/maillist.txt
Normal file
14
doc/doxygen/maillist.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
/*! \page maillist The Mail List
|
||||
|
||||
An <A HREF="mailto:stk-request@ccrma.stanford.edu">STK</A> mailing list has been set up to facilitate communication among STK users. Subscribing to this list is your best way of keeping on top of new releases, bug fixes, and various user developments.
|
||||
<P>
|
||||
For answers to frequently asked questions, check the list <A HREF="http://ccrma-mail.stanford.edu/pipermail/stk/">archives</A>.
|
||||
<P>
|
||||
To join send a message to <A HREF="mailto:stk-request@ccrma.stanford.edu"><stk-request@ccrma.stanford.edu></A>
|
||||
with the contents: <TT>subscribe</TT>
|
||||
|
||||
<P>
|
||||
To be removed from the list send a message to <A HREF="mailto:stk-request@ccrma.stanford.edu"><stk-request@ccrma.stanford.edu></A>
|
||||
with the contents: <TT>unsubscribe</TT>
|
||||
|
||||
*/
|
||||
30
doc/doxygen/multichannel.txt
Normal file
30
doc/doxygen/multichannel.txt
Normal file
@@ -0,0 +1,30 @@
|
||||
/*! \page multichannel Multi-Channel I/O
|
||||
|
||||
The ToolKit stk::WvIn and stk::WvOut classes (and their subclasses) support multi-channel audio data input and output. Several other abstract base classes, such as stk::Instrmnt, stk::Generator, and stk::Effect, also support multi-channel computations though not all of their subclasses produce or take multi-channel data. A set of interleaved audio samples representing a single time "slice" is referred to as a <I>sample frame</I>. At a sample rate of 44.1 kHz, a four-channel audio stream will have 44100 sample frames per second and a total of 176400 individual samples per second.
|
||||
|
||||
Most STK classes process single-sample data streams via their
|
||||
<TT>tick()</TT> function. For classes supporting multi-channel data,
|
||||
one must distinguish the <TT>tick()</TT> functions taking or producing
|
||||
single \c StkFloat arguments from those taking stk::StkFrames& arguments. If
|
||||
a single-sample version of the <TT>tick()</TT> function is called for
|
||||
these classes, a full sample frame is computed but only a single value
|
||||
is either input and/or output. For example, if the single-sample
|
||||
<TT>tick()</TT> function is called for subclasses of WvOut, the sample
|
||||
argument is written to all channels in the one computed frame. For
|
||||
classes returning values, an optional \c channel argument specifies
|
||||
which channel value is returned from the computed frame (the default
|
||||
is always channel 0). To input and/or output multichannel data to
|
||||
these classes, the overloaded <TT>tick()</TT> functions taking
|
||||
StkFrames reference arguments should be used.
|
||||
|
||||
Multi-channel support for realtime audio input and output is dependent on the audio device(s) available on your system.
|
||||
|
||||
The following example demonstrates the use of the stk::FileWvOut class for
|
||||
creating a four channel, 16-bit AIFF formatted audio file. We will
|
||||
use four sinewaves of different frequencies for the first two seconds
|
||||
and then a single sinewave for the last two seconds.
|
||||
|
||||
\include foursine.cpp
|
||||
|
||||
[<A HREF="tutorial.html">Main tutorial page</A>] [<A HREF="polyvoices.html">Next tutorial</A>]
|
||||
*/
|
||||
22
doc/doxygen/polyvoices.txt
Normal file
22
doc/doxygen/polyvoices.txt
Normal file
@@ -0,0 +1,22 @@
|
||||
/*! \page polyvoices Voice Management
|
||||
|
||||
The previous tutorial chapters were concerned only with monophonic ToolKit instrument playback and control. At this point, it should be relatively clear that one can instantiate multiple instruments and perhaps sum together their outputs or even direct their outputs to separate channels. It is less clear how one might go about controlling a group of instruments. The stk::Voicer class is designed to serve just this purpose.
|
||||
|
||||
The stk::Voicer class is a relatively simple voice manager. The user can dynamically add and delete instruments to/from its "control", with the option of controlling specific instruments via unique note tags and/or grouping sets of instruments via a "group" number. All sounding instrument outputs are summed and returned via the <TT>tick()</TT> function. The stk::Voicer class responds to noteOn, noteOff, setFrequency, pitchBend, and controlChange messages, automatically assigning incoming messages to the voices in its control. When all voices are sounding and a new noteOn is encountered, the stk::Voicer interrupts the oldest sounding voice. The user is responsible for creating and deleting all instrument instances.
|
||||
|
||||
In the following example, we modify the <TT>controlbee.cpp</TT> program to make use of three stk::BeeThree instruments, all controlled using a stk::Voicer.
|
||||
|
||||
\include threebees.cpp
|
||||
|
||||
We have written this program to accept control messages from \c STDIN. Assuming the program is compiled as <TT>threebees</TT>, the three-voice SKINI scorefile <A HREF="tutorial/bachfugue.ski"><TT>bachfugue.ski</TT></A> (located in the <tt>scores</tt> directory with the examples) can be redirected to the program as:
|
||||
|
||||
\code
|
||||
threebees < scores/bachfugue.ski
|
||||
\endcode
|
||||
|
||||
For more fun, surf to <A HREF="http://kern.ccarh.org/">Kern Scores</A> for a huge assortment of other scorefiles that can be downloaded in the SKINI format.
|
||||
|
||||
Another easy extension would be to add the \c stk::Messager::startMidiInput() function to the program and then play the instruments via a MIDI keyboard.
|
||||
|
||||
[<A HREF="tutorial.html">Main tutorial page</A>]
|
||||
*/
|
||||
49
doc/doxygen/realtime.txt
Normal file
49
doc/doxygen/realtime.txt
Normal file
@@ -0,0 +1,49 @@
|
||||
/*! \page realtime Realtime Audio (blocking)
|
||||
|
||||
In this section, we modify the <TT>sineosc.cpp</TT> program in order
|
||||
to send the output to the default audio playback device on your
|
||||
computer system. We also make use of the stk::SineWave class as a
|
||||
sine-wave oscillator. stk::SineWave computes an internal, static sine-wave
|
||||
table when its first instance is created. Subsequent instances make
|
||||
use of the same table. The default table length, specified in
|
||||
SineWave.h, is 2048 samples.
|
||||
|
||||
\include rtsine.cpp
|
||||
|
||||
The class stk::RtWvOut is a protected subclass of stk::WvOut. A number of
|
||||
optional constructor arguments can be used to fine tune its
|
||||
performance for a given system. stk::RtWvOut provides a "single-sample",
|
||||
blocking interface to the RtAudio class. Note that stk::RtWvOut (as well
|
||||
as the stk::RtWvIn class described below) makes use of RtAudio's callback
|
||||
input/output functionality by creating a large ring-buffer into which
|
||||
data is written. These classes should not be used when low-latency
|
||||
and robust performance is necessary
|
||||
|
||||
Though not used here, an stk::RtWvIn class exists as well that can be used
|
||||
to read realtime audio data from an input device. See the
|
||||
<TT>record.cpp</TT> example program in the <TT>examples</TT> project
|
||||
for more information.
|
||||
|
||||
It may be possible to use an instance of stk::RtWvOut and an instance of
|
||||
stk::RtWvIn to simultaneously read and write realtime audio to and from a
|
||||
hardware device or devices. However, it is recommended to instead use
|
||||
a single instance of RtAudio to achieve this behavior, as described in the next section.
|
||||
See the <TT>effects</TT> project or the <TT>duplex.cpp</TT> example
|
||||
program in the <TT>examples</TT> project for more information.
|
||||
|
||||
When using any realtime STK class (RtAudio, stk::RtWvOut, stk::RtWvIn, RtMidi, stk::InetWvIn, stk::InetWvOut, stk::Socket, stk::UdpSocket, stk::TcpServer, stk::TcpClient, and stk::Thread), it is necessary to specify an audio/MIDI API preprocessor definition and link with the appropriate libraries or frameworks. For example, the above program could be compiled on a Linux system using the GNU g++ compiler and the ALSA audio API as follows (assuming all necessary files exist in the project directory):
|
||||
|
||||
\code
|
||||
g++ -Wall -D__LINUX_ALSA__ -D__LITTLE_ENDIAN__ -o rtsine Stk.cpp Generator.cpp SineWave.cpp WvOut.cpp \
|
||||
RtWvOut.cpp RtAudio.cpp rtsine.cpp -lpthread -lasound
|
||||
\endcode
|
||||
|
||||
On a Macintosh OS X system, the syntax would be:
|
||||
|
||||
\code
|
||||
g++ -Wall -D__MACOSX_CORE__ -o rtsine Stk.cpp Generator.cpp SineWave.cpp WvOut.cpp RtWvOut.cpp RtAudio.cpp \
|
||||
rtsine.cpp -lpthread -framework CoreAudio -framework CoreMIDI -framework CoreFoundation
|
||||
\endcode
|
||||
|
||||
[<A HREF="tutorial.html">Main tutorial page</A>] [<A HREF="crealtime.html">Next tutorial</A>]
|
||||
*/
|
||||
226
doc/doxygen/skini.txt
Normal file
226
doc/doxygen/skini.txt
Normal file
@@ -0,0 +1,226 @@
|
||||
/*! \page skini Synthesis toolKit Instrument Network Interface (SKINI)
|
||||
|
||||
This describes the latest (version 1.1) implementation of SKINI for the Synthesis ToolKit in C++ (STK) by Perry R. Cook.
|
||||
|
||||
\code
|
||||
Too good to be true?
|
||||
Have control and read it too?
|
||||
A SKINI haiku.
|
||||
\endcode
|
||||
|
||||
Profound thanks to Dan trueman, Brad Garton, and Gary Scavone for input on this revision. Thanks also to MIDI, the NeXT MusicKit, ZIPI and all the creators and modifiers of these for good bases upon/from which to build and depart.
|
||||
|
||||
\section compatibility MIDI Compatibility
|
||||
|
||||
SKINI was designed to be MIDI compatible wherever possible, and extend MIDI in incremental, then maybe profound ways.
|
||||
|
||||
Differences from MIDI, and motivations, include:
|
||||
|
||||
- Text-based messages are used, with meaningful names wherever possible. This allows any language or system capable of formatted printing to generate SKINI. Similarly, any system capable of reading in a string and turning delimited fields into strings, floats, and ints can consume SKINI for control. More importantly, humans can actually read, and even write if they want, SKINI files and streams. Use an editor and search/replace or macros to change a channel or control number. Load a SKINI score into a spread sheet to apply transformations to time, control parameters, MIDI velocities, etc. Put a monkey on a special typewriter and get your next great work. Life's too short to debug bit/nybble packed variable length mumble messages. Disk space gets cheaper, available bandwidth increases, music takes up so little space and bandwidth compared to video and graphics. Live a little.
|
||||
|
||||
- Floating point numbers are used wherever possible. Note Numbers, Velocities, Controller Values, and Delta and Absolute Times are all represented and scanned as ASCII double-precision floats. MIDI byte values are preserved, so that incoming MIDI bytes from an interface can be put directly into SKINI messages. 60.0 or 60 is middle C, 127.0 or 127 is maximum velocity etc. But, unlike MIDI, 60.5 can cause a 50 cent sharp middle C to be played. As with MIDI byte values like velocity, use of the integer and SKINI-added fractional parts is up to the implementor of the algorithm being controlled by SKINI messages. But the extra precision is there to be used or ignored.
|
||||
|
||||
\section why Why SKINI?
|
||||
|
||||
SKINI was designed to be extensable and hackable for a number of applications: imbedded synthesis in a game or VR simulation, scoring and mixing tasks, real-time and non-real time applications which could benefit from controllable sound synthesis, JAVA controlled synthesis, or eventually maybe JAVA synthesis, etc. SKINI is not intended to be "the mother of scorefiles," but since the entire system is based on text representations of names, floats, and ints, converters from one scorefile language to SKINI, or back, should be easily created.
|
||||
|
||||
I am basically a bottom-up designer with an awareness of top-down design ideas, so SKINI above all reflects the needs of my particular research and creative projects as they have arisen and developed. SKINI 1.1 represents a profound advance beyond versions 0.8 and 0.9 (the first versions), future SKINI's might reflect some changes. Compatibility with prior scorefiles will be attempted, but there aren't that many scorefiles out there yet.
|
||||
|
||||
\section messages SKINI Messages
|
||||
|
||||
A basic SKINI message is a line of text. There are only three required fields, the message type (an ASCII name), the time (either delta or absolute), and the channel number. Don't freak out and think that this is MIDI channel 0-15 (which is supported), because the channel number is scanned as a long int. Channels could be socket numbers, machine IDs, serial numbers, or even unique tags for each event in a synthesis. Other fields might be used, as specified in the \c SKINI.tbl file. This is described in more detail later.
|
||||
|
||||
Fields in a SKINI line are delimited by spaces, commas, or tabs. The SKINI parser only operates on a line at a time, so a newline means the message is over. Multiple messages are NOT allowed directly on a single line (by use of the ; for example in C). This could be supported, but it isn't in version 1.1.
|
||||
|
||||
Message types include standard MIDI types like NoteOn, NoteOff, ControlChange, etc. MIDI extension message types (messages which look better than MIDI but actually get turned into MIDI-like messages) include LipTension, StringDamping, etc. Non-MIDI message types include SetPath (sets a path for file use later), and OpenReadFile (for streaming, mixing, and applying effects to soundfiles along with synthesis, for example). Other non-MIDI message types include Trilling, HammerOn, etc. (these translate to gestures, behaviors, and contexts for use by intelligent players and instruments using SKINI). Where possible I will still use these as MIDI extension messages, so foot switches, etc. can be used to control them in real time.
|
||||
|
||||
All fields other than type, time, and channel are optional, and the
|
||||
types and useage of the additional fields is defined in the file \c
|
||||
SKINI.tbl.
|
||||
|
||||
The other important file used by SKINI is \c SKINI.msg, which is a set of #defines to make C code more readable, and to allow reasonably quick re-mapping of control numbers, etc.. All of these defined symbols are assigned integer values. For Java, the #defines could be replaced by declaration and assignment statements, preserving the look and behavior of the rest of the code.
|
||||
|
||||
\section cfiles Files Used To Implement SKINI
|
||||
|
||||
Skini is a C++ class which can either open a SKINI file and successively read and parse lines of text as SKINI strings, or accept strings from another object and parse them. The latter functionality would be used by a socket, pipe, or other connection receiving SKINI messages a line at a time, usually in real time, but not restricted to real time.
|
||||
|
||||
\c SKINI.msg should be included by anything wanting to use the Skini object. This is not mandatory, but use of the __SK_blah_ symbols which are defined in the .msg file will help to ensure clarity and consistency when messages are added and changed.
|
||||
|
||||
\c SKINI.tbl is used only by the Skini parser object (Skini.cpp). In the file \c SKINI.tbl, an array of structures is declared and assigned values which instruct the parser as to what the message types are, and what the fields mean for those message types. This table is compiled and linked into applications using SKINI, but could be dynamically loaded and changed in a future version of SKINI.
|
||||
|
||||
\section parser SKINI Messages and the SKINI Parser:
|
||||
|
||||
The parser isn't all that smart, but neither am I. Here are the basic rules governing a valid SKINI message:
|
||||
|
||||
- If the first (non-delimiter ... see below) character in a SKINI string is '/' that line is treated as a comment and echoed to stdout.
|
||||
|
||||
- Spaces, commas, and tabs delimit the fields in a SKINI message line. (We might allow for multiple messages per line later using the semicolon, but probably not. A series of lines with deltaTimes of 0.0 denotes simultaneous events. For read-ability, multiple messages per line doesn't help much, so it's unlikely to be supported later).
|
||||
|
||||
- The first field must be a SKINI message name (like NoteOn). These might become case-insensitive in future versions, so don't plan on exciting clever overloading of names (like noTeOn being different from NoTeON). There can be a number of leading spaces or tabs, but don't exceed 32 or so.
|
||||
|
||||
- The second field must be a time specification in seconds. A time field can be either delta-time (most common and the only one supported in version 0.8), or absolute time. Absolute time messages have an '=' appended to the beginning of the floating point number with no space. So 0.10000 means delta time of 100 ms, while =0.10000 means absolute time of 100 ms. Absolute time messages make most sense in score files, but could also be used for (loose) synchronization in a real-time context. Real-time messages should be time-ordered AND time-correct. That is, if you've sent 100 total delta-time messages of 1.0 seconds, and then send an absolute time message of =90.0 seconds, or if you send two absolute time messages of =100.0 and =90.0 in that order, things will get really fouled up. The SKINI parser doesn't know about time, however. The WvOut device is the master time keeper in the Synthesis Toolkit, so it should be queried to see if absolute time messages are making sense. There's an example of how to do that later in this document. Absolute times are returned by the parser as negative numbers (since negative deltaTimes are not allowed).
|
||||
|
||||
- The third field must be an integer channel number. Don't go crazy and think that this is just MIDI channel 0-15 (which is supported). The channel number is scanned as a long int. Channels 0-15 are in general to be treated as MIDI channels. After that it's wide open. Channels could be socket numbers, machine IDs, serial numbers, or even unique tags for each event in a synthesis. A -1 channel can be used as don't care, omni, or other functions depending on your needs and taste.
|
||||
|
||||
- All remaining fields are specified in the \c SKINI.tbl file. In general, there are maximum two more fields, which are either SK_INT (long), SK_DBL (double float), or SK_STR (string). The latter is the mechanism by which more arguments can be specified on the line, but the object using SKINI must take that string apart (retrived by using getRemainderString()) and scan it. Any excess fields are stashed in remainderString.
|
||||
|
||||
\section file A Short SKINI File:
|
||||
|
||||
\code
|
||||
/* Howdy!!! Welcome to SKINI, by P. Cook 1999
|
||||
|
||||
NoteOn 0.000082 2 55 82
|
||||
NoteOff 1.000000 2 55 0
|
||||
NoteOn 0.000082 2 69 82
|
||||
StringDetune 0.100000 2 10
|
||||
StringDetune 0.100000 2 30
|
||||
StringDetune 0.100000 2 50
|
||||
NoteOn 0.000000 2 69 82
|
||||
StringDetune 0.100000 2 40
|
||||
StringDetune 0.100000 2 22
|
||||
StringDetune 0.100000 2 12
|
||||
//
|
||||
StringDamping 0.000100 2 0.0
|
||||
NoteOn 0.000082 2 55 82
|
||||
NoteOn 0.200000 2 62 82
|
||||
NoteOn 0.100000 2 71 82
|
||||
NoteOn 0.200000 2 79 82
|
||||
NoteOff 1.000000 2 55 82
|
||||
NoteOff 0.000000 2 62 82
|
||||
NoteOff 0.000000 2 71 82
|
||||
NoteOff 0.000000 2 79 82
|
||||
StringDamping =4.000000 2 0.0
|
||||
NoteOn 0.000082 2 55 82
|
||||
NoteOn 0.200000 2 62 82
|
||||
NoteOn 0.100000 2 71 82
|
||||
NoteOn 0.200000 2 79 82
|
||||
NoteOff 1.000000 2 55 82
|
||||
NoteOff 0.000000 2 62 82
|
||||
NoteOff 0.000000 2 71 82
|
||||
NoteOff 0.000000 2 79 82
|
||||
\endcode
|
||||
|
||||
\section table The SKINI.tbl File and Message Parsing:
|
||||
|
||||
The \c SKINI.tbl file contains an array of structures which are accessed by the parser object Skini.cpp. The struct is:
|
||||
|
||||
\code
|
||||
struct SKINISpec {
|
||||
char messageString[32];
|
||||
long type;
|
||||
long data2;
|
||||
long data3;
|
||||
};
|
||||
\endcode
|
||||
|
||||
so an assignment of one of these structs looks like:
|
||||
|
||||
\code
|
||||
MessageStr$ ,type, data2, data3,
|
||||
\endcode
|
||||
|
||||
<TT>type</TT> is the message type sent back from the SKINI line parser.
|
||||
|
||||
<TT>data<n></TT> is either:
|
||||
|
||||
- NOPE : field not used, specifically, there aren't going to be any more fields on this line. So if there is is NOPE in data2, data3 won't even be checked.
|
||||
|
||||
- SK_INT : byte (actually scanned as 32 bit signed long int). If it's a MIDI data field which is required to be an integer, like a controller number, it's 0-127. Otherwise, get creative with SK_INTs.
|
||||
|
||||
- SK_DBL : double precision floating point. SKINI uses these in the MIDI context for note numbers with micro tuning, velocities, controller values, etc.
|
||||
|
||||
- SK_STR : only valid in final field. This allows (nearly) arbitrary message types to be supported by simply scanning the string to EOL (End Of Line) and then passing it to a more intelligent handler. For example, MIDI SYSEX (system exclusive) messages can be read as space-delimited integers into the SK_STR buffer. Longer bulk dumps, soundfiles, etc. should be handled as a new message type pointing to a FileName, Socket, or something else stored in the SK_STR field, or as a new type of multi-line message.
|
||||
|
||||
Each individual SKINI message is parsed and saved to a Skini::Message structure of the form:
|
||||
\code
|
||||
struct Message {
|
||||
long type; /*!< The message type, as defined in SKINI.msg. */
|
||||
long channel; /*!< The message channel (not limited to 16!). */
|
||||
StkFloat time; /*!< The message time stamp in seconds (delta or absolute). */
|
||||
std::vector<StkFloat> floatValues; /*!< The message values read as floats (values are type-specific). */
|
||||
std::vector<long> intValues; /*!< The message values read as ints (number and values are type-specific). */
|
||||
std::string remainder; /*!< Any remaining message data, read as ascii text. */
|
||||
};
|
||||
\endcode
|
||||
|
||||
Here's a couple of lines from the \c SKINI.tbl file
|
||||
|
||||
\code
|
||||
{"NoteOff" , __SK_NoteOff_, SK_DBL, SK_DBL},
|
||||
{"NoteOn" , __SK_NoteOn_, SK_DBL, SK_DBL},
|
||||
|
||||
{"ControlChange" , __SK_ControlChange_, SK_INT, SK_DBL},
|
||||
{"Volume" , __SK_ControlChange_, __SK_Volume_ , SK_DBL},
|
||||
|
||||
{"StringDamping" , __SK_ControlChange_, __SK_StringDamping_, SK_DBL},
|
||||
{"StringDetune" , __SK_ControlChange_, __SK_StringDetune_, SK_DBL},
|
||||
\endcode
|
||||
|
||||
The first three are basic MIDI messages. The first two would cause the parser, after recognizing a match of the string "NoteOff" or "NoteOn", to set the message type to 128 or 144 (__SK_NoteOff_ and __SK_NoteOn_ are #defined in the file \c SKINI.msg to be the MIDI byte value, without channel, of the actual MIDI messages for NoteOn and NoteOff). The parser would then set the time or delta time (this is always done and is therefore not described in the SKINI Message Struct). The next two fields would be scanned either as double-precision \c floats or as <tt>long ints</tt>, depending on the format specified in \c SKINI.tbl, and saved to the corresponding C++ vector variables in the Skini::Message structure (either \c floatValues or \c intValues). Floating-point values are also cast to <tt>ints</tt> (and vice-versa) and stored to their respective variables. For example, an expected integer value of 64 will also be saved as 64.0 in the corresponding \c floatValues variable of the Skini::Message structure. The remainder of the line is stashed in the remainderString variable.
|
||||
|
||||
The ControlChange spec is basically the same as NoteOn and NoteOff, but the second data byte is set to an integer (for checking later as to what MIDI control is being changed).
|
||||
|
||||
The Volume spec is a MIDI Extension message, which behaves like a ControlChange message with the controller number set explicitly to the value for MIDI Volume (7). Thus the following two lines would accomplish the same changing of MIDI volume on channel 2:
|
||||
|
||||
\code
|
||||
ControlChange 0.000000 2 7 64.1
|
||||
Volume 0.000000 2 64.1
|
||||
\endcode
|
||||
|
||||
I like the second line better, thus my motivation for SKINI in the first place.
|
||||
|
||||
The StringDamping and StringDetune messages behave the same as the Volume message, but use Control Numbers which aren't specifically nailed-down in MIDI. Note that these Control Numbers are carried around as long ints, so we're not limited to 0-127. If, however, you want to use a MIDI controller to play an instrument, using controller numbers in the 0-127 range might make sense.
|
||||
|
||||
\section using Using SKINI:
|
||||
|
||||
Here's a simple example of code which uses the Skini object to read a SKINI file and control a single instrument.
|
||||
|
||||
\code
|
||||
Skini score;
|
||||
Skini::Message message;
|
||||
instrument = new Mandolin(50.0);
|
||||
score.setFile( argv[1] );
|
||||
while ( score.nextMessage( message ) != 0 ) {
|
||||
tempDouble = message.time;
|
||||
if (tempDouble < 0) {
|
||||
tempDouble = - tempDouble;
|
||||
tempDouble = tempDouble - output.getTime();
|
||||
if (tempDouble < 0) {
|
||||
printf("Bad News Here!!! Backward Absolute Time Required.\n");
|
||||
tempDouble = 0.0;
|
||||
}
|
||||
}
|
||||
tempLong = (long) ( tempDouble * Stk::sampleRate() );
|
||||
for ( i=0; i<tempLong; i++ ) {
|
||||
output.tick( instrument->tick() );
|
||||
}
|
||||
|
||||
tempDouble3 = message.floatValues[1] * NORM_MIDI;
|
||||
if ( message.type == __SK_NoteOn_ ) {
|
||||
if ( tempDouble3 == 0.0 ) {
|
||||
tempDouble3 = 0.5;
|
||||
instrument->noteOff( tempDouble3 );
|
||||
}
|
||||
else {
|
||||
tempLong = message.intValues[0];
|
||||
tempDouble2 = Midi2Pitch[tempLong];
|
||||
instrument->noteOn( tempDouble2, tempDouble3 );
|
||||
}
|
||||
}
|
||||
else if ( message.type == __SK_NoteOff_ ) {
|
||||
instrument->noteOff( tempDouble3 );
|
||||
}
|
||||
else if ( message.type == __SK_ControlChange_ ) {
|
||||
tempLong = message.intValues[0];
|
||||
instrument->controlChange( tempLong, tempDouble3 );
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
|
||||
When a SKINI score is passed to a Skini object using the Skini::setFile() function, valid messages are read from the file and returned using the Skini::nextMessage() function.
|
||||
|
||||
The "time" member of a Skini::Message is the deltaTime until the current message should occur. If this is greater than 0, synthesis occurs until the deltaTime has elapsed. If deltaTime is less than zero, the time is interpreted as absolute time and the output device is queried as to what time it is now. That is used to form a deltaTime, and if it's positive we synthesize. If it's negative, we print an error, pretend this never happened and we hang around hoping to eventually catch up.
|
||||
|
||||
The rest of the code sorts out message types NoteOn, NoteOff (including NoteOn with velocity 0), and ControlChange. The code implicitly takes into account the integer type of the control number, but all other data is treated as double float.
|
||||
|
||||
*/
|
||||
35
doc/doxygen/system.txt
Normal file
35
doc/doxygen/system.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
/*! \page system System Requirements
|
||||
|
||||
<B>General:</B>
|
||||
<UL>
|
||||
<LI>A MIDI interface to use MIDI input/output controls. (NOTE: This may be built into the soundcard on your computer.)</LI>
|
||||
<LI><A HREF="https://www.tcl.tk/">Tcl/Tk</A> version 8.0 or higher to use the simple Tcl/Tk GUIs provided with the STK distribution (available free over the WWW for all supported realtime platforms).</LI>
|
||||
</UL>
|
||||
|
||||
<B>Linux (specific):</B>
|
||||
<UL>
|
||||
<LI>A soundcard to use realtime audio input/output capabilities. In order to use the <I><B>effects</B></I> project, the soundcard and drivers must support full duplex mode.</LI>
|
||||
<LI><A HREF="http://www.alsa-project.org/">ALSA</A> device drivers and library for realtime sound and MIDI input/output.</LI>
|
||||
<LI><A HREF="http://www.opensound.com">OSS</A> device drivers (version 4.0 and higher only) can be used for audio input/output, but MIDI support requires the ALSA library to compile.</LI>
|
||||
</UL>
|
||||
|
||||
<B>Macintosh OS X (specific):</B>
|
||||
<UL>
|
||||
<LI>A C++ compiler is not installed by default with OS X. It is necessary to download the Developer Kit from the Apple WWW site in order to compile STK or load it from the installation CD-ROM.</LI>
|
||||
<LI>If you experience frequent audio input/output "glitches", try increasing the RT_BUFFER_SIZE specified in Stk.h.</LI>
|
||||
<LI>The Tcl/Tk interpreter does not ship by default with OS X and must be downloaded from the internet. The latest Tcl/Tk Aqua distribution (http://www.apple.com/downloads/macosx/unix_open_source/tcltk.html) has been successfully tested on 10.2 and 10.3 systems. The default installation will place a link to the wish interpretor at /usr/bin/wish.
|
||||
|
||||
It appears that socket support in Tcl/Tk uses the Nagle algorithm, which produces poor response between changes made in the Tcl/Tk script and the resulting audio updates. Note that this is only a problem when using a socket connection from a Tcl/Tk script.</LI>
|
||||
|
||||
</UL>
|
||||
|
||||
<B>Windows95 and later (specific):</B>
|
||||
<UL>
|
||||
<LI>A soundcard to use realtime audio input/output capabilities. In order to use the <I><B>effects</B></I> project, the soundcard and drivers must support full duplex mode.</LI>
|
||||
<LI><A HREF="http://www.microsoft.com/directx/">DirectX</A> 5.0 (or higher) runtime libraries.</LI>
|
||||
<LI>For compiling the source (if not already in your system): <UL><LI><A HREF="Misc/dsound.h">dsound.h</A> header file (DirectX 6.1) - put somewhere in your header search path</LI><LI><A HREF="Misc/dsound.lib">dsound.lib</A> library file (DirectX 6.1) - put somewhere in your library search path</LI></UL></LI>
|
||||
</UL>
|
||||
|
||||
<P>
|
||||
|
||||
*/
|
||||
24
doc/doxygen/tutorial.txt
Normal file
24
doc/doxygen/tutorial.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
/*! \page tutorial Tutorial
|
||||
|
||||
The Synthesis ToolKit is a set of C++ classes. In order to go beyond the simple example programs we provide, it is necessary to know some basics about programming in C and C++. STK's "target audience" includes people who:
|
||||
- want to create audio DSP and/or synthesis programs
|
||||
- want to use our unit generators and input/output routines rather than code their own
|
||||
- want to learn about synthesis and processing algorithms
|
||||
- wish to teach real-time synthesis and processing and wish to use some of our classes and examples
|
||||
|
||||
Most ToolKit programmers will likely end up writing a class or two for their own particular needs, but this task is typically simplified by making use of pre-existing STK classes (filters, oscillators, etc.).
|
||||
|
||||
The following tutorial chapters describe many of the fundamental ToolKit concepts and classes. All tutorial programs are included in the <TT>projects/examples</TT> directory.
|
||||
|
||||
-# \ref fundamentals
|
||||
-# \ref hello
|
||||
-# \ref compile
|
||||
-# \ref filtering
|
||||
-# \ref realtime
|
||||
-# \ref crealtime
|
||||
-# \ref instruments
|
||||
-# \ref controlin
|
||||
-# \ref multichannel
|
||||
-# \ref polyvoices
|
||||
|
||||
*/
|
||||
205
doc/doxygen/usage.txt
Normal file
205
doc/doxygen/usage.txt
Normal file
@@ -0,0 +1,205 @@
|
||||
/*! \page usage Usage Documentation
|
||||
|
||||
- \ref directory
|
||||
- \ref compiling
|
||||
- \ref debug
|
||||
- \ref control
|
||||
- \ref voices
|
||||
- \ref nort
|
||||
- \ref rt
|
||||
- \ref tcl
|
||||
- \ref midi
|
||||
- \ref polyphony
|
||||
|
||||
<HR>
|
||||
|
||||
\section directory Directory Structure:
|
||||
|
||||
The top level distribution contains the following directories:
|
||||
|
||||
<UL>
|
||||
<LI> The <I><B>src</B></I> directory contains the source .cpp files for all the STK unit generator and algorithm classes.</LI><P>
|
||||
|
||||
<LI> The <I><B>include</B></I> directory contains the header files for all the STK unit generator and algorithm classes.</LI><P>
|
||||
|
||||
<LI> The <I><B>rawwaves</B></I> directory contains various raw, monophonic, 16-bit, big-endian, 22050 Hz soundfiles used with the STK classes.</LI><P>
|
||||
|
||||
<LI> The <I><B>doc</B></I> directory contains documentation about STK.</LI><P>
|
||||
|
||||
<LI> The <I><B>projects</B></I> directory contains various demo and example STK programs.</LI><P>
|
||||
</UL>
|
||||
|
||||
This release of STK comes with four separate "project" directories:
|
||||
|
||||
<OL>
|
||||
<LI> The <I><B>demo</B></I> project is used to demonstrate nearly all of the STK instruments. The <I><B>stk-demo</B></I> program has been written to allow a variety of control input and sound data output options. Simple graphical user interfaces (GUIs) are also provided.<P></LI>
|
||||
|
||||
<LI> The <I><B>effects</B></I> project demonstrates realtime duplex mode (simultaneous audio input and output) operation, when available, as well as various delay-line based effects algorithms.<P></LI>
|
||||
|
||||
<LI> The <I><B>ragamatic</B></I> project is just cool. Fire it up and be enlightened.<P></LI>
|
||||
|
||||
<LI> The <I><B>eguitar</B></I> project demonstrates how to make an electric guitar with feedback and distortion.<P></LI>
|
||||
|
||||
<LI> The <I><B>examples</B></I> project contains several simple programs that demonstrate audio input/output, including the audio internet streaming classes, as well as most of the tutorial programs.</LI>
|
||||
</OL>
|
||||
|
||||
\section compiling Compiling:
|
||||
|
||||
<UL>
|
||||
<LI><B>Windows95 and later:</B> For specifics on creating Windows applications using Visual Studio, see README-Win.txt.</LI>
|
||||
|
||||
<LI><B>Unix (and MinGW) Systems:</B> A GNU <TT>configure</TT> shell script is included in the distribution for unix-based systems. From the top-level distribution directory, type <TT>'./configure'</TT> and the script will create <TT>Makefiles</TT> in each project directory specific to the characteristics of the host computer. Then from within any given project directory (example <TT>demo</TT>), type <TT>'make'</TT> to compile the project. In addition, an STK library can be compiled from within the <TT>src</TT> directory.
|
||||
|
||||
Several options can be supplied to the <TT>configure</TT> script to customize the build behavior:
|
||||
<UL>
|
||||
<LI><TT>--disable-realtime</TT> to only compile generic non-realtime classes</LI>
|
||||
<LI><TT>--enable-debug</TT> to enable various debug output</LI>
|
||||
<LI><TT>--with-alsa</TT> to choose native ALSA API support (default, linux only)</LI>
|
||||
<LI><TT>--with-oss</TT> to choose native OSS audio API support (linux only, no native OSS MIDI support)</LI>
|
||||
<LI><TT>--with-jack</TT> to choose native JACK API support (linux and Macintosh OS-X)</LI>
|
||||
<LI><TT>--with-core</TT> to choose CoreAudio API support (Macintosh OS-X)</LI>
|
||||
<LI><TT>--with-asio</TT> to choose ASIO Audio API support (Windows)</LI>
|
||||
<LI><TT>--with-ds</TT> to choose Windows DirectSound Audio API support (Windows)</LI>
|
||||
</UL>
|
||||
<P>
|
||||
Note that it is possible to specify as many of the "--with-" options as desired to compile multi-API support. In addition, it is possible to specify the location of the STK rawwaves and the STK include path as follows:
|
||||
\code
|
||||
./configure RAWWAVE_PATH="/home/gary/rawwaves/"
|
||||
./configure INCLUDE_PATH="/home/gary/include/"
|
||||
\endcode
|
||||
|
||||
For novice STK users, the default configuration should be adequate.
|
||||
</UL>
|
||||
|
||||
For those who wish to create their own system-specific <TT>Makefiles</TT>:
|
||||
<UL>
|
||||
<LI><B>Linux:</B> Realtime audio support is enabled with either the <TT>__LINUX_ALSA__</TT>, <TT>__UNIX_JACK__</TT>, and/or <TT>__LINUX_OSS__</TT> preprocessor definitions, which are used to select the underlying audio system API(s). Because the ALSA library is now integrated into the standard Linux kernel, it is the default audio/MIDI API with STK versions 4.2 and higher. The <TT>__LINUX_ALSASEQ__</TT> preprocessor definition must be included for MIDI support. Note that native OSS MIDI support no longer exists in RtMidi. If the <TT>__LINUX_OSS__</TT> preprocessor definition is specified, only OSS (version 4.0) audio support will be compiled and RtMidi will still be compiled using the ALSA API (assuming the <TT>__LINUX_ALSASEQ__</TT> definition is defined). For this reason, STK now requires the <TT>asound</TT> library for realtime support. Realtime programs must also link with the <TT>pthread</TT> library. In addition, the <TT>__LITTLE_ENDIAN__</TT> preprocessor definition is necessary if compiling on a little-endian system. See the README-Linux file for further system configuration information.</LI>
|
||||
|
||||
<LI><B>Macintosh OS X:</B> Realtime support is enabled with the <TT>__MACOSX_CORE__</TT> and <TT>__UNIX_JACK__</TT> preprocessor definitions, which incorporate the CoreAudio audio/MIDI API and/or the JACK API. Realtime programs must also link with the <TT>pthread</TT> library and the <TT>CoreAudio</TT>, <TT>CoreMIDI</TT>, and <TT>CoreFoundation</TT> frameworks (for CoreAudio support) and/or the JACK library. See the README-MacOSX file for further system configuration information.</LI>
|
||||
|
||||
<LI><B>Generic (non-realtime):</B> Most STK classes are operating system <I>independent</I> and can be compiled using any current C++ compiler. STK assumes big-endian host byte order by default, so if your system is little-endian (i.e. Intel processor), you must provide the <TT>__LITTLE_ENDIAN__</TT> preprocessor definition to your compiler. The <I><B>demo</B></I> project will compile without realtime support, allowing the use of SKINI scorefiles for input control and output to a variety of soundfile formats. The following classes <I>cannot</I> be used without realtime support: RtAudio, RtWvIn, RtWvOut, RtDuplex, RtMidi, Socket, Thread, Mutex, TcpWvIn, TcpWvOut. Because of this, it is not possible to compile the <I><B>effects</B></I>, <I><B>ragamatic</B></I>, and most of the <I><B>examples</B></I> projects for non-realtime use.</LI>
|
||||
</UL>
|
||||
|
||||
\section debug Debugging:
|
||||
|
||||
When developing applications with STK, it is recommended that you define the preprocessor definition <TT>_STK_DEBUG_</TT> when compiling (or specify the <TT>--enable-debug</TT> option to the <TT>configure</TT> script). This will enable all levels of function argument and error checking within the STK classes. Without this definition, argument checking does not occur in functions that are expected to be called frequently in an iterative manner.
|
||||
|
||||
\section control Control Data:
|
||||
|
||||
All STK programs in this distribution take input control data in the form of <A HREF="skini.html">SKINI</A> or MIDI messages only. The Messager class unifies the various means of acquiring control data under a single, easy to use set of functions. The way that SKINI messages can be sent to the programs is dependent upon the operating system in use, as well as whether the program is running in realtime or not. In general, it is possible to:
|
||||
|
||||
<OL>
|
||||
<LI>Redirect or pipe SKINI scorefiles to an executable.</LI>
|
||||
<LI>Pipe realtime SKINI input messages to an executable (not possible under Windows95/98).</LI>
|
||||
<LI>Acquire realtime MIDI messages from a MIDI port on your computer.</LI>
|
||||
</OL>
|
||||
|
||||
<A HREF="https://www.tcl.tk/">Tcl/Tk</A> graphical user interfaces (GUI) are provided with this distribution that can generate realtime SKINI messages. Note that the Messager class allows multiple simultaneous socket client connections, together with MIDI and/or piped input. The <I><B>Md2Skini</B></I> program (in the <I><B>demo</B></I> directory) is mostly obsolete but can be used to create SKINI scorefiles from realtime MIDI input.
|
||||
|
||||
|
||||
\section voices Demo: STK Instruments
|
||||
|
||||
The <I><B>demo</B></I> project demonstrates the behavior of all the distributed STK instruments. The instruments available with this release include:
|
||||
<UL>
|
||||
<LI>Clarinet: Pretty good physical model of the clarinet</LI>
|
||||
<LI>BlowHole: A clarinet physical model with one tonehole and one register vent</LI>
|
||||
<LI>Saxofony: A psuedo-conical bore reed instrument that sometimes sounds like a saxophone</LI>
|
||||
<LI>Flute: Pretty good physical model of the flute</LI>
|
||||
<LI>Brass: Not so bad physical model of a brass instrument</LI>
|
||||
<LI>BlowBotl: A basic helmholtz resonator and air jet model</LI>
|
||||
<LI>Bowed: Not hideous physical model of a bowed string instrument</LI>
|
||||
<LI>Plucked: Yer basic plucked string physical model</LI>
|
||||
<LI>StifKarp: A simple plucked, stiff string physical model</LI>
|
||||
<LI>Sitar: A simple sitar/plucked string physical model</LI>
|
||||
<LI>Mandolin: Two-string mandolin physical model</LI>
|
||||
<LI>Rhodey: Rhodes-like electric piano FM synthesis model</LI>
|
||||
<LI>Wurley: Wurlitzer-like electric piano FM synthesis model</LI>
|
||||
<LI>TubeBell: FM synthesis model</LI>
|
||||
<LI>HevyMetl: Distorted synthesizer FM synthesis model</LI>
|
||||
<LI>PercFlut: Percussive flute-like FM synthesis model</LI>
|
||||
<LI>BeeThree: Cheezy organ FM synthesis model</LI>
|
||||
<LI>Moog: Swept filter sampler</LI>
|
||||
<LI>FMVoices: Three-formant FM voice synthesis</LI>
|
||||
<LI>VoicForm: Four-formant resonance filter voice synthesis</LI>
|
||||
<LI>Resonate: Noise through a BiQuad filter</LI>
|
||||
<LI>Drummer: Sampling synthesis</LI>
|
||||
<LI>BandedWG: Banded waveguide meta-object for bowed bars, tibetan bowls, etc.</LI>
|
||||
<LI>Shakers: Various stochastic event models of shaker instruments</LI>
|
||||
<LI>ModalBar: Various four-resonance presets (marimba, vibraphone, etc...)</LI>
|
||||
<LI>Mesh2D: Two-dimensional, rectilinear digital waveguide mesh</LI>
|
||||
<LI>Whistle: Hybrid physical/spectral model of a police whistle</LI>
|
||||
</UL>
|
||||
|
||||
\section nort Demo: Non-Realtime Use
|
||||
|
||||
See the information above with respect to compiling STK for non-realtime use.
|
||||
|
||||
In non-realtime mode, it is assumed that input control messages are provided from a SKINI scorefile and that audio output is written to a soundfile (.snd, .wav, .aif, .mat, .raw). A number of SKINI scorefiles are provided in the <I>scores</I> directory of the <I><B>demo</B></I> project. Assuming a successful compilation of the <I><B>stk-demo</B></I> program, typing:
|
||||
|
||||
\code
|
||||
stk-demo BeeThree -ow myfile.wav -if scores/bookert.ski
|
||||
\endcode
|
||||
|
||||
from the <I><B>demo</B></I> directory will play the scorefile <I>bookert.ski</I> using the STK BeeThree instrument and write the resulting audio data to a WAV formatted soundfile called "myfile.wav" (note that you may need to append <TT>./</TT> to the program name if your default shell setup is not set to look in the current directory). Typing <TT>stk-demo</TT> without any arguments will provide a full program usage description.
|
||||
|
||||
|
||||
\section rt Demo: Realtime Use
|
||||
|
||||
STK realtime audio and MIDI input/output and realtime SKINI control input via socketing support is provided for Linux, Mac OS-X, and Windows95 and later operating systems. STK realtime SKINI control input via piping is possible under Linux, Mac OS X, and Windows2000 and later only.
|
||||
<P>
|
||||
Control input and audio output options are typically specified as command-line arguments to STK programs. For example, the <I><B>stk-demo</B></I> program is invoked as:
|
||||
|
||||
\code
|
||||
stk-demo instrument flags
|
||||
\endcode
|
||||
|
||||
where instruments include those described above and flags can be any or all of:
|
||||
<UL>
|
||||
<LI><I>-or</I> for realtime audio output,</LI>
|
||||
<LI><I>-ow \<file name\></I> for WAV soundfile output,</LI>
|
||||
<LI><I>-os \<file name\></I> for SND (AU) soundfile output,</LI>
|
||||
<LI><I>-om \<file name\></I> for MAT-file output,</LI>
|
||||
<LI><I>-if \<file name\></I> for a SKINI formatted control file,</LI>
|
||||
<LI><I>-ip</I> for realtime SKINI control input via piping,</LI>
|
||||
<LI><I>-im \<port\></I> for MIDI control input (with optional port, -1 = virtual port where possible),</LI>
|
||||
<LI><I>-s RATE</I> to specify a sample rate,</LI>
|
||||
<LI><I>-n NUMBER</I> to specify multivoice polyphony</LI>
|
||||
</UL>
|
||||
The <i>-ip</i> flag must be used when piping realtime SKINI control data to an STK program. The <i>-im</i> flag must be used to read MIDI control input from your MIDI port. Note that you can use both input types simultaneously.
|
||||
|
||||
Assuming a successful compilation of the <I><B>stk-demo</B></I> program, typing:
|
||||
|
||||
\code
|
||||
stk-demo BeeThree -or -if scores/bookert.ski
|
||||
\endcode
|
||||
|
||||
from the <I><B>demo</B></I> directory will play the scorefile <I>bookert.ski</I> using the STK BeeThree instrument and stream the resulting audio data in realtime to the audio output channel of your computer. Typing <TT>stk-demo</TT> without any arguments will provide a full program usage description.
|
||||
|
||||
|
||||
\section tcl Realtime Control Input using Tcl/Tk Graphical User Interfaces:
|
||||
|
||||
There are a number of <A HREF="https://www.tcl.tk/">Tcl/Tk</A> GUIs supplied with the STK projects. These scripts require Tcl/Tk version 8.0 or later, which can be downloaded for free over the WWW. On Unix and Windows2000 and later platforms, you can run the various executable scripts (e.g. StkDemo.bat) provided with each project to start everything up (you may need to symbolically link the wishXX executable to the name <I>wish</I>). The Physical.bat script just implements the following command-line sequence:
|
||||
|
||||
\code
|
||||
wish < tcl/Physical.tcl | stk-demo Clarinet -or -ip
|
||||
\endcode
|
||||
|
||||
\section midi Realtime MIDI Control Input:
|
||||
|
||||
On all supported realtime platforms, you can direct realtime MIDI input to the STK Clarinet by typing:
|
||||
|
||||
\code
|
||||
stk-demo Clarinet -or -im
|
||||
\endcode
|
||||
|
||||
This will attempt to use the default MIDI port for input. An optional MIDI port number can be specified after the <TT>-im</TT> flag. Valid MIDI ports are numbered from 0 (default) and higher. On Linux and Macintosh OS-X systems, it is possible to open a virtual MIDI input port (that other software applications can connect to) by specifying a port identifier of -1.
|
||||
|
||||
\section polyphony Polyphony:
|
||||
|
||||
The <I><B>stk-demo</B></I> program supports an arbitrary number of voices via the <TT>-n NUMBER</TT> command-line flag and argument. For example, you can play eight BeeThree instruments with realtime output and control them from a MIDI device by typing:
|
||||
|
||||
\code
|
||||
stk-demo BeeThree -n 8 -or -im
|
||||
\endcode
|
||||
|
||||
*/
|
||||
180
doc/hierarchy.txt
Normal file
180
doc/hierarchy.txt
Normal file
@@ -0,0 +1,180 @@
|
||||
STK: A ToolKit of Audio Synthesis Classes and Instruments in C++
|
||||
|
||||
By Perry R. Cook and Gary P. Scavone, 1995--2023.
|
||||
|
||||
STK Classes - See the HTML documentation in the html directory for complete information.
|
||||
|
||||
|
||||
.- Generator - (Modulate, Noise, SingWave, Envelope, ADSR, Asymp, SineWave, Blit, BlitSaw, BlitSquare, Granulate)
|
||||
|
|
||||
|- Function - (BowTable, JetTable, ReedTable)
|
||||
|
|
||||
|- FileRead, FileWrite
|
||||
|
|
||||
|- WvIn - (FileWvIn, RtWvIn, InetWvIn)
|
||||
| |
|
||||
| FileLoop
|
||||
|
|
||||
|- WvOut - (FileWvOut, RtWvOut, TcpWvOut)
|
||||
|
|
||||
|- Filter - (OnePole, OneZero, TwoPole, TwoZero, PoleZero, Biquad, FormSwep, Delay, DelayL, DelayA, TapDelay)
|
||||
|
|
||||
|- RtAudio, RtMidi, Socket, Thread, Mutex
|
||||
| |
|
||||
Stk -| UdpSocket
|
||||
| TcpServer
|
||||
| TcpClient
|
||||
|
|
||||
|- StkFrames
|
||||
|
|
||||
|- Effect - (Echo, Chorus, PitShift, LentPitShift, PRCRev, JCRev, NRev, FreeVerb)
|
||||
|
|
||||
|- Voicer, Message, Skini, MidiFileIn, Phonemes, Sphere, Vector3D
|
||||
|
|
||||
|- Messager
|
||||
|
|
||||
|- Twang, Guitar
|
||||
|
|
||||
| .- FM - (HevyMetl, PercFlut, Rhodey, Wurley, TubeBell, BeeThree, FMVoices)
|
||||
| |
|
||||
| |- Modal - ModalBar
|
||||
| |
|
||||
| |- VoicForm
|
||||
| |
|
||||
| |- Sampler - Moog
|
||||
| |
|
||||
| |- Resonate
|
||||
| |
|
||||
| |- Mandolin
|
||||
.- Instrmnt -|
|
||||
|- Drummer
|
||||
|
|
||||
|- Clarinet, BlowHole, Saxofony, Flute, Brass, BlowBotl, Bowed, Plucked, StifKarp, Sitar, Recorder
|
||||
|
|
||||
|- Shakers
|
||||
|
|
||||
|- BandedWG
|
||||
|
|
||||
|- Mesh2D
|
||||
|
|
||||
.- Whistle
|
||||
|
||||
|
||||
*********** UNIT GENERATORS **************
|
||||
|
||||
Master Class: Stk.cpp Sample rate, byte-swapping, error handling functionality
|
||||
|
||||
Sources: Generator.h Abstract base class for various source signal classes
|
||||
Function.h Abstract base class for various input/output mapping classes
|
||||
Envelope.cpp Linearly goes to target by rate
|
||||
ADSR.cpp ADSR envelope
|
||||
Asymp.cpp Exponentially approaches target
|
||||
Noise.cpp Random number generator
|
||||
SineWave.cpp Sinusoidal oscillator with internally computed static table
|
||||
Blit.cpp Bandlimited impulse train
|
||||
BlitSaw.cpp Bandlimited sawtooth generator
|
||||
BlitSquare.cpp Bandlimited square wave generator
|
||||
Granulate.cpp Granular synthesis class that processes a monophonic audio file
|
||||
FileRead.cpp Audio file input class (no internal data storage) for RAW, WAV, SND (AU), AIFF, MAT-file files
|
||||
WvIn.h Abstract base class for audio data input classes
|
||||
FileWvIn.cpp Audio file input interface class with interpolation
|
||||
FileLoop.cpp Wavetable looping (subclass of FileWvIn)
|
||||
RtWvIn.cpp Realtime audio input class (subclass of WvIn)
|
||||
InetWvIn.cpp Audio streaming (socket server) input class (subclass of WvIn)
|
||||
|
||||
Sinks: FileWrite.cpp Audio file output class (no internal data storage) for RAW, WAV, SND (AU), AIFF, MAT-file files
|
||||
WvOut.h Abstract base class for audio data output classes
|
||||
FileWvOut.cpp Audio file output interface class to FileWrite
|
||||
RtWvOut.cpp Realtime audio output class (subclass of WvOut)
|
||||
InetWvOut.cpp Audio streaming (socket client) output class (subclass of WvOut)
|
||||
|
||||
Filters: Filter.h Filter master class
|
||||
Iir.h General infinite-impulse response filter
|
||||
Fir.h General finite-impulse response filter
|
||||
OneZero.cpp One zero filter
|
||||
OnePole.cpp One pole filter
|
||||
PoleZero.cpp One pole/one zero filter
|
||||
TwoZero.cpp Two zero filter
|
||||
TwoPole.cpp Two pole filter
|
||||
BiQuad.cpp Two pole/two zero filter
|
||||
FormSwep.cpp Sweepable biquad filter (goes to target by rate)
|
||||
Delay.cpp Non-interpolating delay line class
|
||||
DelayL.cpp Linearly interpolating delay line
|
||||
DelayA.cpp Allpass interpolating delay line
|
||||
TapDelay.cpp Multi-tap non-interpolating delay line class
|
||||
|
||||
Non-Linear: JetTabl.h Cubic jet non-linearity
|
||||
BowTabl.h x^(-3) Bow non-linearity
|
||||
ReedTabl.h One breakpoint saturating reed non-linearity
|
||||
|
||||
Derived: Modulate.cpp Periodic and random vibrato: WvIn, Noise, OnePole
|
||||
SingWave.cpp Looping wave table with randomness: Modulate, FileLoop, Envelope
|
||||
|
||||
|
||||
********** INSTRUMENTS AND ALGORITHMS **************
|
||||
|
||||
Each class is listed either with some of the unit generators it uses,
|
||||
or in terms of the algorithm it implements. All inherit from Instrmnt,
|
||||
which inherits from Stk.
|
||||
|
||||
Simple.cpp Simple Instrument Pulse oscillator + resonant filtered noise
|
||||
Plucked.cpp Basic Plucked String DelayA, OneZero, OnePole, Noise
|
||||
Twang.cpp Not So Basic Pluck DelayL, DlineA, Fir, allows commuted synthesis
|
||||
Mandolin.cpp Commuted Mandolin 2 Twangs
|
||||
Guitar.cpp N-String Guitar N Twangs, bridge coupling, allows feedback and body filter
|
||||
StifKarp.cpp Plucked String with Stiffness DelayA, DelayL, OneZero, BiQuad, Noise
|
||||
Bowed.cpp So So Bowed String DelayL, BowTabl, OnePole, BiQuad, WaveLoop, ADSR
|
||||
Brass.cpp Not So Bad Brass Instrument DelayA, BiQuad, PoleZero, ADSR, WaveLoop
|
||||
Clarinet.cpp Pretty Good Clarinet DelayL, ReedTabl, OneZero, Envelope, Noise, WaveLoop
|
||||
BlowHole.cpp Clarinet w/ Tone & Vent Holes DelayL, ReedTabl, OneZero, Envelope, Noise, WaveLoop, PoleZero
|
||||
Saxofony.cpp A Faux Saxophone DelayL, ReedTabl, OneZero, Envelope, Noise, WaveLoop
|
||||
Flute.cpp Pretty Good Flute JetTabl, DelayL, OnePole, PoleZero, Noise, ADSR, WaveLoop
|
||||
Recorder.cpp A More Physical Flute DelayL, IIR, Noise, ADSR, SineWave
|
||||
BlowBotl.cpp Blown Bottle JetTabl, BiQuad, PoleZero, Noise, ADSR, WaveLoop
|
||||
BandedWG.cpp Banded Waveguide Meta-Object Delay, BowTabl, ADSR, BiQuad
|
||||
Modal.cpp N Resonances Envelope, WaveLoop, BiQuad, OnePole
|
||||
ModalBar.cpp Various presets 4 Resonance Models
|
||||
FM.cpp N Operator FM Master ADSR, WaveLoop, TwoZero
|
||||
HevyMetl.cpp Distorted FM Synthesizer 3 Cascade with FB Modulator
|
||||
PercFlut.cpp Percussive Flute 3 Cascade Operators
|
||||
Rhodey.cpp Rhodes-Like Electric Piano 2 Parallel Simple FMs
|
||||
Wurley.cpp Wurlitzer Electric Piano 2 Parallel Simple FMs
|
||||
TubeBell.cpp Classic FM Bell 2 Parallel Simple FMs
|
||||
FMVoices.cpp 3 Formant FM Voice 3 Carriers Share 1 Modulator
|
||||
VoicForm.cpp 4 Formant Voice Synthesis FormSwep, SingWave, OnePole, OneZero, Envelope, Noise
|
||||
BeeThree.cpp Cheezy Additive Organ 4 Oscillators Additive
|
||||
Sampler.cpp Sampling Synthesizer 5 each ADSR, WvIn, WaveLoop, OnePole
|
||||
Moog.cpp Swept Filter Sampler with Swept Filter
|
||||
Resonate.cpp Filtered Noise ADSR, BiQuad, Noise
|
||||
Drummer.cpp Drum Synthesizer Bunch of WvIns, and OnePole
|
||||
Shakers.cpp PhISM statistical model for shakers and real-world sound effects
|
||||
Mesh2D.cpp Two-dimensional, rectilinear digital waveguide mesh.
|
||||
Whistle.cpp Hybrid physical/spectral model of a police whistle.
|
||||
|
||||
Effect.h Effects Processor Base Class
|
||||
JCRev.cpp Chowning Reverberator 3 series allpass units, 4 parallel combs, 2 stereo delays
|
||||
NRev.cpp Another famous CCRMA Reverb 8 allpass, 6 parallel comb filters
|
||||
PRCRev.cpp Dirt Cheap Reverb by Cook 2 allpass, 2 comb filters
|
||||
FreeVerb.cpp Jezar at Dreampoint's FreeVerb 4 allpass, 8 lowpass comb filters
|
||||
Flanger.cpp Flanger Effects Processor DelayL, WaveLoop
|
||||
Chorus.cpp Chorus Effects Processor DelayL, WaveLoop
|
||||
PitShift.cpp Cheap Pitch Shifter DelayL
|
||||
LentPitShift.cpp Pitch Shifter based Lent Algorithm
|
||||
|
||||
|
||||
*********** OTHER SUPPORT CLASSES AND FILES **************
|
||||
|
||||
RtAudio.cpp Multi-OS/API audio I/O routines
|
||||
RtMidi.cpp Multi-OS/API MIDI I/O routines
|
||||
Messager.cpp Pipe, socket, and MIDI control message handling
|
||||
Voicer.cpp Multi-instrument voice manager
|
||||
|
||||
demo.cpp Demonstration program for most synthesis algorithms
|
||||
effects.cpp Effects demonstration program
|
||||
ragamatic.cpp Nirvana just waiting to happen
|
||||
|
||||
Skini.cpp SKINI file/message parser object
|
||||
SKINImsg.h #defines for often used and universal MIDI/SKINI symbols
|
||||
SKINItbl.h Table of SKINI messages
|
||||
|
||||
|
||||
BIN
doc/html/ccrma.gif
Normal file
BIN
doc/html/ccrma.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.1 KiB |
BIN
doc/html/mcgill.gif
Normal file
BIN
doc/html/mcgill.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.7 KiB |
BIN
doc/html/princeton.gif
Normal file
BIN
doc/html/princeton.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.3 KiB |
175
doc/treesed.html
Normal file
175
doc/treesed.html
Normal file
@@ -0,0 +1,175 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Treesed Usage</title>
|
||||
</head>
|
||||
<body>
|
||||
<table border="0" width="660" cellpadding="0" cellspacing="0">
|
||||
<tbody><tr valign="top"><td width="165">
|
||||
|
||||
<h3>How to Use Treesed</h3>
|
||||
|
||||
Go to the directory where you want to search or make changes.
|
||||
|
||||
<p>
|
||||
There are two choices you can make when using treesed:
|
||||
</p><ol>
|
||||
<li>Do I just want to search for a text, or do I want to search for a
|
||||
text and replace it with something else?
|
||||
<br>
|
||||
If you are just searching you are using Treesed in "search mode", otherwise it is in
|
||||
"replace mode."
|
||||
</li><li>Do I want to search/replace only in files in my current directory,
|
||||
or should files in all subdirectories (and all directories below that)
|
||||
also be done?
|
||||
</li></ol>
|
||||
Some examples will make this clear.
|
||||
|
||||
<h4>Searching</h4>
|
||||
Say you are faced with the situation that the author of a slew of web-pages, Nathan Brazil, has left and has been succeeded by Mavra Chang. First, let us see which files are affected by this (what you type in is shown in <b><tt>bold</tt></b>):
|
||||
<blockquote>
|
||||
<pre>[localhost] <b>treesed "Nathan Brazil" -files *.html</b>
|
||||
search_pattern: Nathan\ Brazil
|
||||
replacement_pattern:
|
||||
|
||||
** Search mode
|
||||
|
||||
.
|
||||
midnight.html: 1 lines on: 2
|
||||
..
|
||||
well.html: 1 lines on: 3
|
||||
</pre>
|
||||
</blockquote>
|
||||
We notice the following:
|
||||
<ul>
|
||||
<li>The search text <tt>"Nathan Brazil"</tt> is enclosed in
|
||||
double-quotes (<tt>"</tt>).
|
||||
</li><li>You specify which files to search with <tt>-files</tt> followed by a
|
||||
list of file names--in this case <tt>*.html</tt>.
|
||||
</li><li>Treesed reports the search pattern ("pattern" is just a fancy word
|
||||
for "text") you specified (you can ignore
|
||||
that \).
|
||||
</li><li>Treesed reports an empty <tt>replacement_pattern</tt>. This is
|
||||
correct, because you haven't entered one.
|
||||
</li><li>It therefore deduces that is is in search mode.
|
||||
</li><li>It finds two files containing "Nathan Brazil", and reports on which
|
||||
lines of these files it found it; it does not show the lines themselves.
|
||||
</li></ul>
|
||||
Because you used <tt>-files</tt>, Treesed will search in the files you
|
||||
specify <i>in the current directory</i>. You can also search files in
|
||||
the current directory <i>and</i> all directories below it. However, in
|
||||
that case you can not specify which file names to use, all files will be
|
||||
searched:
|
||||
<blockquote>
|
||||
<pre>[localhost] <b>treesed "Nathan Brazil" -tree</b>
|
||||
search_pattern: Nathan\ Brazil
|
||||
replacement_pattern:
|
||||
|
||||
** Search mode
|
||||
|
||||
.
|
||||
midnight.html: 1 lines on: 2
|
||||
...
|
||||
well.html: 1 lines on: 3
|
||||
.
|
||||
new/echoes.html: 1 lines on: 2
|
||||
</pre>
|
||||
</blockquote>
|
||||
We notice the following:
|
||||
<ul>
|
||||
<li>Instead of <tt>-files</tt> we now see <tt>-tree</tt>.
|
||||
</li><li>We do not see a specification of file names.
|
||||
</li><li>Treesed finds an occurence of "Nathan Brazil" in the file
|
||||
<tt>echoes.html</tt> in the subdirectory <tt>new</tt>; it did not
|
||||
find this file in the previous example (as it shouldn't).
|
||||
</li></ul>
|
||||
|
||||
<h4>Replacing</h4>
|
||||
To replace a text you simply add the replacement text right after the
|
||||
search text:
|
||||
<blockquote>
|
||||
<pre>[localhost] <b>treesed "Nathan Brazil" "Mavra Change" -files *.html</b>
|
||||
search_pattern: Nathan\ Brazil
|
||||
replacement_pattern: Mavra Chang
|
||||
|
||||
** EDIT MODE!
|
||||
|
||||
.
|
||||
midnight.html: 1 lines on: 2
|
||||
|
||||
Replaced Nathan\ Brazil by Mavra Chang on 1 lines in midnight.html
|
||||
..
|
||||
well.html: 1 lines on: 3
|
||||
|
||||
Replaced Nathan\ Brazil by Mavra Chang on 1 lines in well.html
|
||||
</pre>
|
||||
</blockquote>
|
||||
We notice the following:
|
||||
<ul>
|
||||
<li>Right after the search text "Nathan Brazil" you specify the
|
||||
replacement text "Mavra Chang".
|
||||
</li><li>As a result, Treesed now reports a non-empty
|
||||
<tt>replacement_pattern</tt>.
|
||||
</li><li>Hence it concludes it is in "edit mode", which means replacment mode.
|
||||
</li><li>Treesed dutifully reports on which lines in which files it did the
|
||||
replacement.
|
||||
</li></ul>
|
||||
To replace a text in all files in the current directory and the ones
|
||||
below it, we do the following:
|
||||
<blockquote>
|
||||
<pre>[localhost] <b>treesed "Nathan Brazil" "Mavra Chang" -tree</b>
|
||||
search_pattern: Nathan\ Brazil
|
||||
replacement_pattern: Mavra Chang
|
||||
|
||||
** EDIT MODE!
|
||||
|
||||
.
|
||||
midnight.html: 1 lines on: 2
|
||||
|
||||
Replaced Nathan\ Brazil by Mavra Chang on 1 lines in midnight.html
|
||||
|
||||
....
|
||||
well.html: 1 lines on: 3
|
||||
|
||||
Replaced Nathan\ Brazil by Mavra Chang on 1 lines in well.html
|
||||
.
|
||||
new/echoes.html: 1 lines on: 2
|
||||
|
||||
Replaced Nathan\ Brazil by Mavra Chang on 1 lines in new/echoes.html
|
||||
</pre>
|
||||
</blockquote>
|
||||
and we get the expected results, including the replace in
|
||||
<tt>new/echoes.html</tt>.
|
||||
|
||||
<h4>Old Versions</h4>
|
||||
Treesed leaves behind quite a mess of old versions of the files it
|
||||
changed (only in change-mode, of course). These old files have the same
|
||||
name as the original file, with <tt>.ddddd</tt> appended to it. For
|
||||
example, if treesed makes a change to <tt>midnight.html</tt> it will
|
||||
leave the original version as something like
|
||||
<tt>midnight.html.26299</tt>. You'll have to remove these files lest
|
||||
your disk area clutters up. Here is a command that does that, <b>but
|
||||
beware!</b> This command removes all files in the current directory and
|
||||
all below it, that end in a period followed by one or more
|
||||
digits:
|
||||
<blockquote>
|
||||
<pre>find . -name "*.[0-9]*" -exec rm {} \;
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
It is interesting to note that if you use treesed again without cleaning
|
||||
up, you may get files like <tt>midnight.html.26299.27654</tt>. These
|
||||
will also be cleaned up by the above slightly dangerous command.
|
||||
|
||||
|
||||
<h3>About Treesed</h3>
|
||||
<tt>treesed</tt> is public domain software developed
|
||||
and designed by Rick Jansen from Sara, Amsterdam, Netherlands, January
|
||||
1996.
|
||||
|
||||
<p>
|
||||
|
||||
<h3>About This Document</h3>
|
||||
This usage document was created by the Division of Information Technology Services at The
|
||||
University of Western Ontario.
|
||||
|
||||
</body></html>
|
||||
91
iOS/README-iOS.md
Normal file
91
iOS/README-iOS.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# Readme
|
||||
|
||||
* [Setup](#setup)
|
||||
* [Usage](#usage)
|
||||
* [Troubleshooting](#troubleshooting)
|
||||
|
||||
## Setup
|
||||
|
||||
### [CocoaPods](https://cocoapods.org) (Recommended)
|
||||
|
||||
1. Add `pod 'STK', '~> 4.6'` to your Podfile.
|
||||
|
||||
1. Run `pod install`
|
||||
|
||||
### Manual
|
||||
|
||||
1. Clone or [download][download_link] the STK into your project's directory.
|
||||
|
||||
1. Open the **STK for iOS** folder, and drag and drop **STK.xcodeproj** into your Xcode project.
|
||||
|
||||
1. Open your project's settings, open the *Build Phases* tab. In the *Link Binary with Libraries* section, add **libSTK.a**.
|
||||
![][linking_libSTK_screenshot]
|
||||
|
||||
1. In the *Dependencies* section, add "rawwaves"
|
||||
|
||||
1. In your project's settings, open the *Build Settings* tab. In the *Search Paths* section, double click on the field to the right of *Header Search Paths*, and add the path to the STK's **include** directory relative to your Xcode project's directory.
|
||||
![][header_search_paths_screenshot]
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
1. Import the STK classes you require in your Objective-C source files (Swift does not yet support importing C++ code)
|
||||
* E.g. `#import "SineWave.h"`
|
||||
|
||||
1. Change the extension of any Objective-C files that import STK files to **.mm**.
|
||||
* E.g. **ViewController.m** —> **ViewController.mm**
|
||||
|
||||
1. If you use a class that makes use of raw wave files (such as `Mandolin`), make sure you call `Stk::setRawwavePath` beforehand in your code.
|
||||
|
||||
See the [iOS Demo project](..projects/demo/iOS%20Demo) for a sample usage.
|
||||
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### 'FileName.h' file not found
|
||||
|
||||
If you get this error when `#import`ing an STK header, you have added the wrong header search path for the STK in your project's settings (see Step 4 in Setup)
|
||||
|
||||
The STK's header search path you need to add is the path to the STK's **include** directory relative to your project's directory (as if you were `cd`ing into it). For example, it is `stk/include/` if the stk directory is inside your project's directory, but it is `../stk/include/` if both share the same directory.
|
||||
|
||||
If this problem doesn't go away:
|
||||
|
||||
1. Delete **STK.xcodeproj** from your Xcode project
|
||||
1. Move the STK directory within your project's directory.
|
||||
1. Follow step 1 from **Setup**, add `stk/include` to the *Header Search Paths*.
|
||||
|
||||
If that doesn't solve it:
|
||||
Install CocoaPods and use it to install the STK. It takes one minute and will make your life easier. Visit the [CocoaPods website](https://cocoapods.org) for installation instructions.
|
||||
|
||||
### FileRead::open: could not open or find file (../../rawwaves/filename.raw)!
|
||||
|
||||
If you use a class that makes use of raw waves (such as `Mandolin`, `Wurley`, or `Rhodey`) you need to make sure that the STK's raw wave files are copied into your bundle and that the STK knows where they are. You'll know you need to if you get this runtime error:
|
||||
`FileRead::open: could not open or find file (../../rawwaves/filename.raw)!`
|
||||
|
||||
#### If you're using CocoaPods
|
||||
|
||||
Add this code before using a class that needs the raw waves:
|
||||
```objective-c
|
||||
stk::Stk::setRawwavePath([[[NSBundle mainBundle] pathForResource:@"rawwaves" ofType:@"bundle"] UTF8String]);
|
||||
```
|
||||
|
||||
#### If you're not using CocoaPods
|
||||
|
||||
1. Open your project's settings, open the *Build Phases* tab.
|
||||
1. In the *Copy Bundle Resources*, drag and drop **rawwaves.bundle** (it's located in **STK.xcodeproj**'s **Helpers** folder).
|
||||
1. Then add this code before using a class that needs the raw waves:
|
||||
|
||||
```objective-c
|
||||
NSBundle *rawwaveBundle = [NSBundle bundleWithURL:[[NSBundle mainBundle] URLForResource:@"rawwaves" withExtension:@"bundle"]];
|
||||
stk::Stk::setRawwavePath([[rawwaveBundle resourcePath] UTF8String]);
|
||||
```
|
||||
|
||||
### Apple Mach-O Linker Error
|
||||
|
||||
This means that **STKLib.a** isn't being linked to your binary. Follow step 2 above in [Setup](#setup).
|
||||
|
||||
|
||||
[download_link]: https://github.com/thestk/stk/archive/master.zip
|
||||
[linking_libSTK_screenshot]: http://i.imgur.com/cLbGrtq.png
|
||||
[header_search_paths_screenshot]: http://i.imgur.com/iBTC06h.png
|
||||
[rawwaves_scheme_screenshot]: http://i.imgur.com/PKd7epf.png
|
||||
1165
iOS/STK.xcodeproj/project.pbxproj
Normal file
1165
iOS/STK.xcodeproj/project.pbxproj
Normal file
File diff suppressed because it is too large
Load Diff
7
iOS/STK.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
7
iOS/STK.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:STK for iOS.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
10
iOS/demo/README.md
Normal file
10
iOS/demo/README.md
Normal file
@@ -0,0 +1,10 @@
|
||||
##iOS Demo Xcode project
|
||||
|
||||
This project briefly shows how to manually integrate the STK static library into an Xcode project. See the **README** file in the STK's `iOS` directory for precise instructions.
|
||||
|
||||
Currently, this project does not output sound, it only shows how to generate audio samples from the STK classes within an iOS project, and how to control STK objects via UI controls. These samples need to be fed into an audio engine for them to be heard.
|
||||
|
||||
Note the following:
|
||||
|
||||
* ViewController needs to be renamed with the **.mm** extension as it's importing STK files, which are C++.
|
||||
* The header search paths in the *Build Settings* of **iOS Demo.xcodeproj** point to `../../include/` because the STK's `include` directory is two directories up relative to it.
|
||||
571
iOS/demo/iOS Demo.xcodeproj/project.pbxproj
Normal file
571
iOS/demo/iOS Demo.xcodeproj/project.pbxproj
Normal file
@@ -0,0 +1,571 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
B02FD53618C520D60009ECA9 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B02FD53518C520D60009ECA9 /* Foundation.framework */; };
|
||||
B02FD53818C520D60009ECA9 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B02FD53718C520D60009ECA9 /* CoreGraphics.framework */; };
|
||||
B02FD53A18C520D60009ECA9 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B02FD53918C520D60009ECA9 /* UIKit.framework */; };
|
||||
B02FD54018C520D60009ECA9 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = B02FD53E18C520D60009ECA9 /* InfoPlist.strings */; };
|
||||
B02FD54218C520D60009ECA9 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = B02FD54118C520D60009ECA9 /* main.m */; };
|
||||
B02FD54618C520D60009ECA9 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = B02FD54518C520D60009ECA9 /* AppDelegate.m */; };
|
||||
B02FD54818C520D60009ECA9 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B02FD54718C520D60009ECA9 /* Images.xcassets */; };
|
||||
B02FD54F18C520D70009ECA9 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B02FD54E18C520D70009ECA9 /* XCTest.framework */; };
|
||||
B02FD55018C520D70009ECA9 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B02FD53518C520D60009ECA9 /* Foundation.framework */; };
|
||||
B02FD55118C520D70009ECA9 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B02FD53918C520D60009ECA9 /* UIKit.framework */; };
|
||||
B02FD55918C520D70009ECA9 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = B02FD55718C520D70009ECA9 /* InfoPlist.strings */; };
|
||||
B02FD55B18C520D70009ECA9 /* iOS_DemoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B02FD55A18C520D70009ECA9 /* iOS_DemoTests.m */; };
|
||||
B02FD57018C521560009ECA9 /* ViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = B02FD56F18C521560009ECA9 /* ViewController.mm */; };
|
||||
B0779A8718D376F5004DA9B7 /* libSTK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B0779A8418D376A6004DA9B7 /* libSTK.a */; };
|
||||
B0779A8B18D37C13004DA9B7 /* rawwaves.bundle in Resources */ = {isa = PBXBuildFile; fileRef = B0779A8618D376A6004DA9B7 /* rawwaves.bundle */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
834A47CB24435D350028575A /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = B0779A7E18D376A5004DA9B7 /* STK.xcodeproj */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = B0EC337B18CB73480005787B;
|
||||
remoteInfo = rawwaves;
|
||||
};
|
||||
B02FD55218C520D70009ECA9 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = B02FD52A18C520D60009ECA9 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = B02FD53118C520D60009ECA9;
|
||||
remoteInfo = "iOS Demo";
|
||||
};
|
||||
B0779A8318D376A6004DA9B7 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = B0779A7E18D376A5004DA9B7 /* STK.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = B0AC5BEE18CB31DE00D860C0;
|
||||
remoteInfo = STK;
|
||||
};
|
||||
B0779A8518D376A6004DA9B7 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = B0779A7E18D376A5004DA9B7 /* STK.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = B0EC33B718CB73A70005787B;
|
||||
remoteInfo = rawwaves;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
B02FD53218C520D60009ECA9 /* iOS Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "iOS Demo.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
B02FD53518C520D60009ECA9 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
B02FD53718C520D60009ECA9 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
|
||||
B02FD53918C520D60009ECA9 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
|
||||
B02FD53D18C520D60009ECA9 /* iOS Demo-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "iOS Demo-Info.plist"; sourceTree = "<group>"; };
|
||||
B02FD53F18C520D60009ECA9 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
B02FD54118C520D60009ECA9 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
B02FD54318C520D60009ECA9 /* iOS Demo-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "iOS Demo-Prefix.pch"; sourceTree = "<group>"; };
|
||||
B02FD54418C520D60009ECA9 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
|
||||
B02FD54518C520D60009ECA9 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
|
||||
B02FD54718C520D60009ECA9 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
|
||||
B02FD54D18C520D70009ECA9 /* iOS DemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "iOS DemoTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
B02FD54E18C520D70009ECA9 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
|
||||
B02FD55618C520D70009ECA9 /* iOS DemoTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "iOS DemoTests-Info.plist"; sourceTree = "<group>"; };
|
||||
B02FD55818C520D70009ECA9 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
B02FD55A18C520D70009ECA9 /* iOS_DemoTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = iOS_DemoTests.m; sourceTree = "<group>"; };
|
||||
B02FD56E18C521560009ECA9 /* ViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; };
|
||||
B02FD56F18C521560009ECA9 /* ViewController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ViewController.mm; sourceTree = "<group>"; };
|
||||
B0779A7E18D376A5004DA9B7 /* STK.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = STK.xcodeproj; path = ../STK.xcodeproj; sourceTree = "<group>"; };
|
||||
B0779A8918D37977004DA9B7 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.md; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
B02FD52F18C520D60009ECA9 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
B0779A8718D376F5004DA9B7 /* libSTK.a in Frameworks */,
|
||||
B02FD53818C520D60009ECA9 /* CoreGraphics.framework in Frameworks */,
|
||||
B02FD53A18C520D60009ECA9 /* UIKit.framework in Frameworks */,
|
||||
B02FD53618C520D60009ECA9 /* Foundation.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
B02FD54A18C520D70009ECA9 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
B02FD54F18C520D70009ECA9 /* XCTest.framework in Frameworks */,
|
||||
B02FD55118C520D70009ECA9 /* UIKit.framework in Frameworks */,
|
||||
B02FD55018C520D70009ECA9 /* Foundation.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
B02FD52918C520D60009ECA9 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B0779A8918D37977004DA9B7 /* README.md */,
|
||||
B0779A7E18D376A5004DA9B7 /* STK.xcodeproj */,
|
||||
B02FD53B18C520D60009ECA9 /* iOS Demo */,
|
||||
B02FD55418C520D70009ECA9 /* iOS DemoTests */,
|
||||
B02FD53418C520D60009ECA9 /* Frameworks */,
|
||||
B02FD53318C520D60009ECA9 /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B02FD53318C520D60009ECA9 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B02FD53218C520D60009ECA9 /* iOS Demo.app */,
|
||||
B02FD54D18C520D70009ECA9 /* iOS DemoTests.xctest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B02FD53418C520D60009ECA9 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B02FD53518C520D60009ECA9 /* Foundation.framework */,
|
||||
B02FD53718C520D60009ECA9 /* CoreGraphics.framework */,
|
||||
B02FD53918C520D60009ECA9 /* UIKit.framework */,
|
||||
B02FD54E18C520D70009ECA9 /* XCTest.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B02FD53B18C520D60009ECA9 /* iOS Demo */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B02FD54418C520D60009ECA9 /* AppDelegate.h */,
|
||||
B02FD54518C520D60009ECA9 /* AppDelegate.m */,
|
||||
B02FD56E18C521560009ECA9 /* ViewController.h */,
|
||||
B02FD56F18C521560009ECA9 /* ViewController.mm */,
|
||||
B02FD54718C520D60009ECA9 /* Images.xcassets */,
|
||||
B02FD53C18C520D60009ECA9 /* Supporting Files */,
|
||||
);
|
||||
path = "iOS Demo";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B02FD53C18C520D60009ECA9 /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B02FD53D18C520D60009ECA9 /* iOS Demo-Info.plist */,
|
||||
B02FD53E18C520D60009ECA9 /* InfoPlist.strings */,
|
||||
B02FD54118C520D60009ECA9 /* main.m */,
|
||||
B02FD54318C520D60009ECA9 /* iOS Demo-Prefix.pch */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B02FD55418C520D70009ECA9 /* iOS DemoTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B02FD55A18C520D70009ECA9 /* iOS_DemoTests.m */,
|
||||
B02FD55518C520D70009ECA9 /* Supporting Files */,
|
||||
);
|
||||
path = "iOS DemoTests";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B02FD55518C520D70009ECA9 /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B02FD55618C520D70009ECA9 /* iOS DemoTests-Info.plist */,
|
||||
B02FD55718C520D70009ECA9 /* InfoPlist.strings */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B0779A7F18D376A5004DA9B7 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B0779A8418D376A6004DA9B7 /* libSTK.a */,
|
||||
B0779A8618D376A6004DA9B7 /* rawwaves.bundle */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
B02FD53118C520D60009ECA9 /* iOS Demo */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = B02FD55E18C520D70009ECA9 /* Build configuration list for PBXNativeTarget "iOS Demo" */;
|
||||
buildPhases = (
|
||||
B02FD52E18C520D60009ECA9 /* Sources */,
|
||||
B02FD52F18C520D60009ECA9 /* Frameworks */,
|
||||
B02FD53018C520D60009ECA9 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
834A47CC24435D350028575A /* PBXTargetDependency */,
|
||||
);
|
||||
name = "iOS Demo";
|
||||
productName = "iOS Demo";
|
||||
productReference = B02FD53218C520D60009ECA9 /* iOS Demo.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
B02FD54C18C520D70009ECA9 /* iOS DemoTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = B02FD56118C520D70009ECA9 /* Build configuration list for PBXNativeTarget "iOS DemoTests" */;
|
||||
buildPhases = (
|
||||
B02FD54918C520D70009ECA9 /* Sources */,
|
||||
B02FD54A18C520D70009ECA9 /* Frameworks */,
|
||||
B02FD54B18C520D70009ECA9 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
B02FD55318C520D70009ECA9 /* PBXTargetDependency */,
|
||||
);
|
||||
name = "iOS DemoTests";
|
||||
productName = "iOS DemoTests";
|
||||
productReference = B02FD54D18C520D70009ECA9 /* iOS DemoTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
B02FD52A18C520D60009ECA9 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 1140;
|
||||
ORGANIZATIONNAME = "Ariel Elkin";
|
||||
TargetAttributes = {
|
||||
B02FD54C18C520D70009ECA9 = {
|
||||
TestTargetID = B02FD53118C520D60009ECA9;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = B02FD52D18C520D60009ECA9 /* Build configuration list for PBXProject "iOS Demo" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = B02FD52918C520D60009ECA9;
|
||||
productRefGroup = B02FD53318C520D60009ECA9 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectReferences = (
|
||||
{
|
||||
ProductGroup = B0779A7F18D376A5004DA9B7 /* Products */;
|
||||
ProjectRef = B0779A7E18D376A5004DA9B7 /* STK.xcodeproj */;
|
||||
},
|
||||
);
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
B02FD53118C520D60009ECA9 /* iOS Demo */,
|
||||
B02FD54C18C520D70009ECA9 /* iOS DemoTests */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXReferenceProxy section */
|
||||
B0779A8418D376A6004DA9B7 /* libSTK.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libSTK.a;
|
||||
remoteRef = B0779A8318D376A6004DA9B7 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
B0779A8618D376A6004DA9B7 /* rawwaves.bundle */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = wrapper.cfbundle;
|
||||
path = rawwaves.bundle;
|
||||
remoteRef = B0779A8518D376A6004DA9B7 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
/* End PBXReferenceProxy section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
B02FD53018C520D60009ECA9 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
B0779A8B18D37C13004DA9B7 /* rawwaves.bundle in Resources */,
|
||||
B02FD54018C520D60009ECA9 /* InfoPlist.strings in Resources */,
|
||||
B02FD54818C520D60009ECA9 /* Images.xcassets in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
B02FD54B18C520D70009ECA9 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
B02FD55918C520D70009ECA9 /* InfoPlist.strings in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
B02FD52E18C520D60009ECA9 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
B02FD57018C521560009ECA9 /* ViewController.mm in Sources */,
|
||||
B02FD54618C520D60009ECA9 /* AppDelegate.m in Sources */,
|
||||
B02FD54218C520D60009ECA9 /* main.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
B02FD54918C520D70009ECA9 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
B02FD55B18C520D70009ECA9 /* iOS_DemoTests.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
834A47CC24435D350028575A /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
name = rawwaves;
|
||||
targetProxy = 834A47CB24435D350028575A /* PBXContainerItemProxy */;
|
||||
};
|
||||
B02FD55318C520D70009ECA9 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = B02FD53118C520D60009ECA9 /* iOS Demo */;
|
||||
targetProxy = B02FD55218C520D70009ECA9 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
B02FD53E18C520D60009ECA9 /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
B02FD53F18C520D60009ECA9 /* en */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B02FD55718C520D70009ECA9 /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
B02FD55818C520D70009ECA9 /* en */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
B02FD55C18C520D70009ECA9 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
B02FD55D18C520D70009ECA9 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = YES;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
SDKROOT = iphoneos;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
B02FD55F18C520D70009ECA9 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "iOS Demo/iOS Demo-Prefix.pch";
|
||||
HEADER_SEARCH_PATHS = (
|
||||
../../include/,
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
);
|
||||
INFOPLIST_FILE = "iOS Demo/iOS Demo-Info.plist";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "stk.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
B02FD56018C520D70009ECA9 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "iOS Demo/iOS Demo-Prefix.pch";
|
||||
HEADER_SEARCH_PATHS = (
|
||||
../../include/,
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
);
|
||||
INFOPLIST_FILE = "iOS Demo/iOS Demo-Info.plist";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "stk.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
B02FD56218C520D70009ECA9 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/iOS Demo.app/iOS Demo";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(SDKROOT)/Developer/Library/Frameworks",
|
||||
"$(inherited)",
|
||||
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||
);
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "iOS Demo/iOS Demo-Prefix.pch";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
INFOPLIST_FILE = "iOS DemoTests/iOS DemoTests-Info.plist";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "stk.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUNDLE_LOADER)";
|
||||
WRAPPER_EXTENSION = xctest;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
B02FD56318C520D70009ECA9 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/iOS Demo.app/iOS Demo";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(SDKROOT)/Developer/Library/Frameworks",
|
||||
"$(inherited)",
|
||||
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||
);
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "iOS Demo/iOS Demo-Prefix.pch";
|
||||
INFOPLIST_FILE = "iOS DemoTests/iOS DemoTests-Info.plist";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "stk.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUNDLE_LOADER)";
|
||||
WRAPPER_EXTENSION = xctest;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
B02FD52D18C520D60009ECA9 /* Build configuration list for PBXProject "iOS Demo" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
B02FD55C18C520D70009ECA9 /* Debug */,
|
||||
B02FD55D18C520D70009ECA9 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
B02FD55E18C520D70009ECA9 /* Build configuration list for PBXNativeTarget "iOS Demo" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
B02FD55F18C520D70009ECA9 /* Debug */,
|
||||
B02FD56018C520D70009ECA9 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
B02FD56118C520D70009ECA9 /* Build configuration list for PBXNativeTarget "iOS DemoTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
B02FD56218C520D70009ECA9 /* Debug */,
|
||||
B02FD56318C520D70009ECA9 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = B02FD52A18C520D60009ECA9 /* Project object */;
|
||||
}
|
||||
7
iOS/demo/iOS Demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
7
iOS/demo/iOS Demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:iOS Demo.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDESourceControlProjectFavoriteDictionaryKey</key>
|
||||
<false/>
|
||||
<key>IDESourceControlProjectIdentifier</key>
|
||||
<string>4E1BA790-84C0-4F40-AECE-98269B537CE6</string>
|
||||
<key>IDESourceControlProjectName</key>
|
||||
<string>iOS Demo</string>
|
||||
<key>IDESourceControlProjectOriginsDictionary</key>
|
||||
<dict>
|
||||
<key>CB047168-D1C4-40BC-85A3-6EB0A20AD217</key>
|
||||
<string>ssh://github.com/arielelkin/stk.git</string>
|
||||
</dict>
|
||||
<key>IDESourceControlProjectPath</key>
|
||||
<string>iOS/Demo/iOS Demo.xcodeproj/project.xcworkspace</string>
|
||||
<key>IDESourceControlProjectRelativeInstallPathDictionary</key>
|
||||
<dict>
|
||||
<key>CB047168-D1C4-40BC-85A3-6EB0A20AD217</key>
|
||||
<string>../../../..</string>
|
||||
</dict>
|
||||
<key>IDESourceControlProjectURL</key>
|
||||
<string>ssh://github.com/arielelkin/stk.git</string>
|
||||
<key>IDESourceControlProjectVersion</key>
|
||||
<integer>110</integer>
|
||||
<key>IDESourceControlProjectWCCIdentifier</key>
|
||||
<string>CB047168-D1C4-40BC-85A3-6EB0A20AD217</string>
|
||||
<key>IDESourceControlProjectWCConfigurations</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
|
||||
<string>public.vcs.git</string>
|
||||
<key>IDESourceControlWCCIdentifierKey</key>
|
||||
<string>CB047168-D1C4-40BC-85A3-6EB0A20AD217</string>
|
||||
<key>IDESourceControlWCCName</key>
|
||||
<string>stk</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
14
iOS/demo/iOS Demo/AppDelegate.h
Normal file
14
iOS/demo/iOS Demo/AppDelegate.h
Normal file
@@ -0,0 +1,14 @@
|
||||
//
|
||||
// AppDelegate.h
|
||||
// iOS Demo
|
||||
//
|
||||
// Created by Ariel Elkin on 03/03/2014.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
||||
|
||||
@property (strong, nonatomic) UIWindow *window;
|
||||
|
||||
@end
|
||||
25
iOS/demo/iOS Demo/AppDelegate.m
Normal file
25
iOS/demo/iOS Demo/AppDelegate.m
Normal file
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// AppDelegate.m
|
||||
// iOS Demo
|
||||
//
|
||||
// Created by Ariel Elkin on 03/03/2014.
|
||||
//
|
||||
|
||||
#import "AppDelegate.h"
|
||||
#import "ViewController.h"
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
|
||||
|
||||
ViewController *vc = [[ViewController alloc] initWithNibName:nil bundle:nil];
|
||||
[self.window setRootViewController:vc];
|
||||
|
||||
[self.window makeKeyAndVisible];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"orientation" : "portrait",
|
||||
"idiom" : "iphone",
|
||||
"extent" : "full-screen",
|
||||
"minimum-system-version" : "7.0",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"orientation" : "portrait",
|
||||
"idiom" : "iphone",
|
||||
"subtype" : "retina4",
|
||||
"extent" : "full-screen",
|
||||
"minimum-system-version" : "7.0",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
12
iOS/demo/iOS Demo/ViewController.h
Normal file
12
iOS/demo/iOS Demo/ViewController.h
Normal file
@@ -0,0 +1,12 @@
|
||||
//
|
||||
// ViewController.h
|
||||
// iOS Demo
|
||||
//
|
||||
// Created by Ariel Elkin on 03/03/2014.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface ViewController : UIViewController
|
||||
|
||||
@end
|
||||
108
iOS/demo/iOS Demo/ViewController.mm
Normal file
108
iOS/demo/iOS Demo/ViewController.mm
Normal file
@@ -0,0 +1,108 @@
|
||||
//
|
||||
// ViewController.m
|
||||
// iOS Demo
|
||||
//
|
||||
// Created by Ariel Elkin on 03/03/2014.
|
||||
//
|
||||
|
||||
#import "ViewController.h"
|
||||
|
||||
#import "SineWave.h"
|
||||
#import "Brass.h"
|
||||
#import "Mandolin.h"
|
||||
|
||||
@implementation ViewController {
|
||||
stk::SineWave *sineWave;
|
||||
stk::Brass *brass;
|
||||
}
|
||||
|
||||
- (void)loadView {
|
||||
self.view = [UIView new];
|
||||
[self.view setBackgroundColor:[UIColor whiteColor]];
|
||||
[self setupUI];
|
||||
}
|
||||
|
||||
- (void)viewDidAppear:(BOOL)animated {
|
||||
[super viewDidAppear:animated];
|
||||
|
||||
NSUInteger samplesToGenerate = 1000;
|
||||
|
||||
//Test SineWave:
|
||||
sineWave = new stk::SineWave();
|
||||
|
||||
for (NSUInteger i = 0; i < samplesToGenerate; i ++) {
|
||||
float sample = sineWave->tick();
|
||||
NSLog(@"SineWave sample: %f", sample);
|
||||
}
|
||||
|
||||
//Test Brass:
|
||||
brass = new stk::Brass();
|
||||
|
||||
brass->noteOn(400, 1);
|
||||
|
||||
for (NSUInteger i = 0; i < samplesToGenerate; i ++) {
|
||||
float sample = brass->tick();
|
||||
NSLog(@"Brass sample: %f", sample);
|
||||
}
|
||||
|
||||
//We're going to be making use of a class that needs
|
||||
//raw wave files, we need to tell the STK where
|
||||
//the files are:
|
||||
stk::Stk::setRawwavePath([[[NSBundle mainBundle] pathForResource:@"rawwaves" ofType:@"bundle"] UTF8String]);
|
||||
|
||||
|
||||
//Test Mandolin:
|
||||
stk::Mandolin *mandolin = new stk::Mandolin(400);
|
||||
|
||||
mandolin->pluck(1);
|
||||
|
||||
for (NSUInteger i = 0; i < samplesToGenerate; i ++) {
|
||||
float sample = mandolin->tick();
|
||||
NSLog(@"Mandolin sample: %f", sample);
|
||||
}
|
||||
|
||||
|
||||
#pragma mark TODO - Audio playback
|
||||
}
|
||||
|
||||
|
||||
- (void)sineSliderMoved:(UISlider *)slider {
|
||||
sineWave->setFrequency(slider.value);
|
||||
NSLog(@"Setting SineWave frequency to %.2f", slider.value);
|
||||
}
|
||||
|
||||
- (void)brassSliderMoved:(UISlider *)slider {
|
||||
brass->setFrequency(slider.value);
|
||||
NSLog(@"Setting Brass frequency to %.2f", slider.value);
|
||||
}
|
||||
|
||||
- (void)setupUI {
|
||||
|
||||
//Add slider to control sine wave frequency:
|
||||
UISlider *sineSlider = [[UISlider alloc] init];
|
||||
[sineSlider addTarget:self action:@selector(sineSliderMoved:) forControlEvents:UIControlEventValueChanged];
|
||||
[sineSlider setMinimumValue:0];
|
||||
[sineSlider setMaximumValue:800];
|
||||
[sineSlider setTranslatesAutoresizingMaskIntoConstraints:NO];
|
||||
[self.view addSubview:sineSlider];
|
||||
|
||||
NSDictionary *metrics = @{@"sliderWidth": @200};
|
||||
|
||||
NSArray *sliderConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-40-[sineSlider(sliderWidth)]" options:0 metrics:metrics views:@{@"sineSlider": sineSlider}];
|
||||
[self.view addConstraints:sliderConstraints];
|
||||
|
||||
//Add slider to control brass's frequency:
|
||||
UISlider *brassSlider = [[UISlider alloc] init];
|
||||
[brassSlider addTarget:self action:@selector(brassSliderMoved:) forControlEvents:UIControlEventValueChanged];
|
||||
[brassSlider setMinimumValue:0];
|
||||
[brassSlider setMaximumValue:800];
|
||||
[brassSlider setTranslatesAutoresizingMaskIntoConstraints:NO];
|
||||
[self.view addSubview:brassSlider];
|
||||
|
||||
sliderConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-40-[brassSlider(sliderWidth)]" options:0 metrics:metrics views:@{@"brassSlider": brassSlider}];
|
||||
[self.view addConstraints:sliderConstraints];
|
||||
sliderConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-40-[sineSlider]-[brassSlider]" options:0 metrics:nil views:@{@"sineSlider": sineSlider, @"brassSlider": brassSlider}];
|
||||
[self.view addConstraints:sliderConstraints];
|
||||
}
|
||||
|
||||
@end
|
||||
2
iOS/demo/iOS Demo/en.lproj/InfoPlist.strings
Normal file
2
iOS/demo/iOS Demo/en.lproj/InfoPlist.strings
Normal file
@@ -0,0 +1,2 @@
|
||||
/* Localized versions of Info.plist keys */
|
||||
|
||||
38
iOS/demo/iOS Demo/iOS Demo-Info.plist
Normal file
38
iOS/demo/iOS Demo/iOS Demo-Info.plist
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
16
iOS/demo/iOS Demo/iOS Demo-Prefix.pch
Normal file
16
iOS/demo/iOS Demo/iOS Demo-Prefix.pch
Normal file
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// Prefix header
|
||||
//
|
||||
// The contents of this file are implicitly included at the beginning of every source file.
|
||||
//
|
||||
|
||||
#import <Availability.h>
|
||||
|
||||
#ifndef __IPHONE_3_0
|
||||
#warning "This project uses features only available in iOS SDK 3.0 and later."
|
||||
#endif
|
||||
|
||||
#ifdef __OBJC__
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
#endif
|
||||
18
iOS/demo/iOS Demo/main.m
Normal file
18
iOS/demo/iOS Demo/main.m
Normal file
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// main.m
|
||||
// iOS Demo
|
||||
//
|
||||
// Created by Ariel Elkin on 03/03/2014.
|
||||
// Copyright (c) 2014 Ariel Elkin. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
@autoreleasepool {
|
||||
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
|
||||
}
|
||||
}
|
||||
2
iOS/demo/iOS DemoTests/en.lproj/InfoPlist.strings
Normal file
2
iOS/demo/iOS DemoTests/en.lproj/InfoPlist.strings
Normal file
@@ -0,0 +1,2 @@
|
||||
/* Localized versions of Info.plist keys */
|
||||
|
||||
22
iOS/demo/iOS DemoTests/iOS DemoTests-Info.plist
Normal file
22
iOS/demo/iOS DemoTests/iOS DemoTests-Info.plist
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
||||
34
iOS/demo/iOS DemoTests/iOS_DemoTests.m
Normal file
34
iOS/demo/iOS DemoTests/iOS_DemoTests.m
Normal file
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// iOS_DemoTests.m
|
||||
// iOS DemoTests
|
||||
//
|
||||
// Created by Ariel Elkin on 03/03/2014.
|
||||
// Copyright (c) 2014 Ariel Elkin. All rights reserved.
|
||||
//
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
@interface iOS_DemoTests : XCTestCase
|
||||
|
||||
@end
|
||||
|
||||
@implementation iOS_DemoTests
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||
}
|
||||
|
||||
- (void)tearDown
|
||||
{
|
||||
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
- (void)testExample
|
||||
{
|
||||
XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
@end
|
||||
209
include/ADSR.h
209
include/ADSR.h
@@ -1,46 +1,179 @@
|
||||
/*******************************************/
|
||||
/* ADSR Subclass of the Envelope Class, */
|
||||
/* by Perry R. Cook, 1995-96 */
|
||||
/* This is the traditional ADSR (Attack */
|
||||
/* Decay, Sustain, Release) envelope. */
|
||||
/* It responds to simple KeyOn and KeyOff */
|
||||
/* messages, keeping track of it's state. */
|
||||
/* There are two tick (update value) */
|
||||
/* methods, one returns the value, and */
|
||||
/* other returns the state (0 = A, 1 = D, */
|
||||
/* 2 = S, 3 = R) */
|
||||
/*******************************************/
|
||||
#ifndef STK_ADSR_H
|
||||
#define STK_ADSR_H
|
||||
|
||||
#if !defined(__ADSR_h)
|
||||
#define __ADSR_h
|
||||
#include "Generator.h"
|
||||
|
||||
#include "Envelope.h"
|
||||
namespace stk {
|
||||
|
||||
class ADSR : public Envelope
|
||||
/***************************************************/
|
||||
/*! \class ADSR
|
||||
\brief STK ADSR envelope class.
|
||||
|
||||
This class implements a traditional ADSR (Attack, Decay, Sustain,
|
||||
Release) envelope. It responds to simple keyOn and keyOff
|
||||
messages, keeping track of its state. The \e state = ADSR::IDLE
|
||||
before being triggered and after the envelope value reaches 0.0 in
|
||||
the ADSR::RELEASE state. All rate, target and level settings must
|
||||
be non-negative. All time settings are in seconds and must be
|
||||
positive.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995--2023.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class ADSR : public Generator
|
||||
{
|
||||
protected:
|
||||
MY_FLOAT attackRate;
|
||||
MY_FLOAT decayRate;
|
||||
MY_FLOAT sustainLevel;
|
||||
MY_FLOAT releaseRate;
|
||||
public:
|
||||
ADSR();
|
||||
~ADSR();
|
||||
void keyOn();
|
||||
void keyOff();
|
||||
void setAttackRate(MY_FLOAT aRate);
|
||||
void setDecayRate(MY_FLOAT aRate);
|
||||
void setSustainLevel(MY_FLOAT aLevel);
|
||||
void setReleaseRate(MY_FLOAT aRate);
|
||||
void setAttackTime(MY_FLOAT aTime);
|
||||
void setDecayTime(MY_FLOAT aTime);
|
||||
void setReleaseTime(MY_FLOAT aTime);
|
||||
void setAllTimes(MY_FLOAT attTime, MY_FLOAT decTime, MY_FLOAT susLevel, MY_FLOAT relTime);
|
||||
void setTarget(MY_FLOAT aTarget);
|
||||
void setValue(MY_FLOAT aValue);
|
||||
MY_FLOAT tick();
|
||||
int informTick();
|
||||
MY_FLOAT lastOut();
|
||||
|
||||
//! ADSR envelope states.
|
||||
enum {
|
||||
ATTACK, /*!< Attack */
|
||||
DECAY, /*!< Decay */
|
||||
SUSTAIN, /*!< Sustain */
|
||||
RELEASE, /*!< Release */
|
||||
IDLE /*!< Before attack / after release */
|
||||
};
|
||||
|
||||
//! Default constructor.
|
||||
ADSR( void );
|
||||
|
||||
//! Class destructor.
|
||||
~ADSR( void );
|
||||
|
||||
//! Set target = 1, state = \e ADSR::ATTACK.
|
||||
void keyOn( void );
|
||||
|
||||
//! Set target = 0, state = \e ADSR::RELEASE.
|
||||
void keyOff( void );
|
||||
|
||||
//! Set the attack rate (gain / sample).
|
||||
void setAttackRate( StkFloat rate );
|
||||
|
||||
//! Set the target value for the attack (default = 1.0).
|
||||
void setAttackTarget( StkFloat target );
|
||||
|
||||
//! Set the decay rate (gain / sample).
|
||||
void setDecayRate( StkFloat rate );
|
||||
|
||||
//! Set the sustain level.
|
||||
void setSustainLevel( StkFloat level );
|
||||
|
||||
//! Set the release rate (gain / sample).
|
||||
void setReleaseRate( StkFloat rate );
|
||||
|
||||
//! Set the attack rate based on a time duration (seconds).
|
||||
void setAttackTime( StkFloat time );
|
||||
|
||||
//! Set the decay rate based on a time duration (seconds).
|
||||
void setDecayTime( StkFloat time );
|
||||
|
||||
//! Set the release rate based on a time duration (seconds).
|
||||
void setReleaseTime( StkFloat time );
|
||||
|
||||
//! Set sustain level and attack, decay, and release time durations (seconds).
|
||||
void setAllTimes( StkFloat aTime, StkFloat dTime, StkFloat sLevel, StkFloat rTime );
|
||||
|
||||
//! Set a sustain target value and attack or decay from current value to target.
|
||||
void setTarget( StkFloat target );
|
||||
|
||||
//! Return the current envelope \e state (ATTACK, DECAY, SUSTAIN, RELEASE, IDLE).
|
||||
int getState( void ) const { return state_; };
|
||||
|
||||
//! Set to state = ADSR::SUSTAIN with current and target values of \e value.
|
||||
void setValue( StkFloat value );
|
||||
|
||||
//! Return the last computed output value.
|
||||
StkFloat lastOut( void ) const { return lastFrame_[0]; };
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( void );
|
||||
|
||||
//! Fill a channel of the StkFrames object with computed outputs.
|
||||
/*!
|
||||
The \c channel argument must be less than the number of
|
||||
channels in the StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
|
||||
|
||||
int state_;
|
||||
StkFloat value_;
|
||||
StkFloat target_;
|
||||
StkFloat attackRate_;
|
||||
StkFloat decayRate_;
|
||||
StkFloat releaseRate_;
|
||||
StkFloat releaseTime_;
|
||||
StkFloat sustainLevel_;
|
||||
};
|
||||
|
||||
inline StkFloat ADSR :: tick( void )
|
||||
{
|
||||
switch ( state_ ) {
|
||||
|
||||
case ATTACK:
|
||||
value_ += attackRate_;
|
||||
if ( value_ >= target_ ) {
|
||||
value_ = target_;
|
||||
target_ = sustainLevel_;
|
||||
state_ = DECAY;
|
||||
}
|
||||
lastFrame_[0] = value_;
|
||||
break;
|
||||
|
||||
case DECAY:
|
||||
if ( value_ > sustainLevel_ ) {
|
||||
value_ -= decayRate_;
|
||||
if ( value_ <= sustainLevel_ ) {
|
||||
value_ = sustainLevel_;
|
||||
state_ = SUSTAIN;
|
||||
}
|
||||
}
|
||||
else {
|
||||
value_ += decayRate_; // attack target < sustain level
|
||||
if ( value_ >= sustainLevel_ ) {
|
||||
value_ = sustainLevel_;
|
||||
state_ = SUSTAIN;
|
||||
}
|
||||
}
|
||||
lastFrame_[0] = value_;
|
||||
break;
|
||||
|
||||
case RELEASE:
|
||||
value_ -= releaseRate_;
|
||||
if ( value_ <= 0.0 ) {
|
||||
value_ = 0.0;
|
||||
state_ = IDLE;
|
||||
}
|
||||
lastFrame_[0] = value_;
|
||||
|
||||
}
|
||||
|
||||
return value_;
|
||||
}
|
||||
|
||||
inline StkFrames& ADSR :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
oStream_ << "ADSR::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
|
||||
*samples = ADSR::tick();
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
/*******************************************/
|
||||
/*
|
||||
AifWvIn Input Class,
|
||||
by Gary P. Scavone, 2000
|
||||
|
||||
This object inherits from WvIn and is
|
||||
used to open Audio Interchange File
|
||||
Format files with 16-bit data (signed
|
||||
integer) for playback.
|
||||
|
||||
.aif files are always bif-endian.
|
||||
*/
|
||||
/*******************************************/
|
||||
|
||||
#if !defined(__AifWvIn_h)
|
||||
#define __AifWvIn_h
|
||||
|
||||
#include "Object.h"
|
||||
#include "WvIn.h"
|
||||
|
||||
class AifWvIn : public WvIn
|
||||
{
|
||||
public:
|
||||
AifWvIn(char *fileName, const char *mode);
|
||||
~AifWvIn();
|
||||
protected:
|
||||
void getData(long index);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,32 +0,0 @@
|
||||
/*******************************************/
|
||||
/*
|
||||
AifWvOut Output Class,
|
||||
by Gary P. Scavone, 2000
|
||||
|
||||
This object inherits from WvOut and is
|
||||
used to write Audio Interchange File
|
||||
Format files with 16-bit data (signed
|
||||
integer).
|
||||
|
||||
.aif files are always bif-endian.
|
||||
*/
|
||||
/*******************************************/
|
||||
|
||||
#if !defined(__AifWvOut_h)
|
||||
#define __AifWvOut_h
|
||||
|
||||
#include "Object.h"
|
||||
#include "WvOut.h"
|
||||
|
||||
class AifWvOut : public WvOut
|
||||
{
|
||||
protected:
|
||||
FILE *fd;
|
||||
public:
|
||||
AifWvOut(char *fileName, int chans = 1);
|
||||
~AifWvOut();
|
||||
void tick(MY_FLOAT sample);
|
||||
void mtick(MY_MULTI samples);
|
||||
};
|
||||
|
||||
#endif
|
||||
146
include/Asymp.h
Normal file
146
include/Asymp.h
Normal file
@@ -0,0 +1,146 @@
|
||||
#ifndef STK_ASYMP_H
|
||||
#define STK_ASYMP_H
|
||||
|
||||
#include "Generator.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Asymp
|
||||
\brief STK asymptotic curve envelope class
|
||||
|
||||
This class implements a simple envelope generator
|
||||
which asymptotically approaches a target value.
|
||||
The algorithm used is of the form:
|
||||
|
||||
y[n] = a y[n-1] + (1-a) target,
|
||||
|
||||
where a = exp(-T/tau), T is the sample period, and
|
||||
tau is a time constant. The user can set the time
|
||||
constant (default value = 0.3) and target value.
|
||||
Theoretically, this recursion never reaches its
|
||||
target, though the calculations in this class are
|
||||
stopped when the current value gets within a small
|
||||
threshold value of the target (at which time the
|
||||
current value is set to the target). It responds
|
||||
to \e keyOn and \e keyOff messages by ramping to
|
||||
1.0 on keyOn and to 0.0 on keyOff.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995--2023.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
const StkFloat TARGET_THRESHOLD = 0.000001;
|
||||
|
||||
class Asymp : public Generator
|
||||
{
|
||||
public:
|
||||
|
||||
//! Default constructor.
|
||||
Asymp( void );
|
||||
|
||||
//! Class destructor.
|
||||
~Asymp( void );
|
||||
|
||||
//! Set target = 1.
|
||||
void keyOn( void );
|
||||
|
||||
//! Set target = 0.
|
||||
void keyOff( void );
|
||||
|
||||
//! Set the asymptotic rate via the time factor \e tau (must be > 0).
|
||||
/*!
|
||||
The rate is computed as described above. The value of \e tau
|
||||
must be greater than zero. Values of \e tau close to zero produce
|
||||
fast approach rates, while values greater than 1.0 produce rather
|
||||
slow rates.
|
||||
*/
|
||||
void setTau( StkFloat tau );
|
||||
|
||||
//! Set the asymptotic rate based on a time duration (must be > 0).
|
||||
void setTime( StkFloat time );
|
||||
|
||||
//! Set the asymptotic rate such that the target value is perceptually reached (to within -60dB of the target) in \e t60 seconds.
|
||||
void setT60( StkFloat t60 );
|
||||
|
||||
//! Set the target value.
|
||||
void setTarget( StkFloat target );
|
||||
|
||||
//! Set current and target values to \e value.
|
||||
void setValue( StkFloat value );
|
||||
|
||||
//! Return the current envelope \e state (0 = at target, 1 otherwise).
|
||||
int getState( void ) const { return state_; };
|
||||
|
||||
//! Return the last computed output value.
|
||||
StkFloat lastOut( void ) const { return lastFrame_[0]; };
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( void );
|
||||
|
||||
//! Fill a channel of the StkFrames object with computed outputs.
|
||||
/*!
|
||||
The \c channel argument must be less than the number of
|
||||
channels in the StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
|
||||
|
||||
StkFloat value_;
|
||||
StkFloat target_;
|
||||
StkFloat factor_;
|
||||
StkFloat constant_;
|
||||
int state_;
|
||||
};
|
||||
|
||||
inline StkFloat Asymp :: tick( void )
|
||||
{
|
||||
if ( state_ ) {
|
||||
|
||||
value_ = factor_ * value_ + constant_;
|
||||
|
||||
// Check threshold.
|
||||
if ( target_ > value_ ) {
|
||||
if ( target_ - value_ <= TARGET_THRESHOLD ) {
|
||||
value_ = target_;
|
||||
state_ = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( value_ - target_ <= TARGET_THRESHOLD ) {
|
||||
value_ = target_;
|
||||
state_ = 0;
|
||||
}
|
||||
}
|
||||
lastFrame_[0] = value_;
|
||||
}
|
||||
|
||||
return value_;
|
||||
}
|
||||
|
||||
inline StkFrames& Asymp :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
oStream_ << "Asymp::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
|
||||
*samples = Asymp::tick();
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
153
include/BandedWG.h
Normal file
153
include/BandedWG.h
Normal file
@@ -0,0 +1,153 @@
|
||||
#ifndef STK_BANDEDWG_H
|
||||
#define STK_BANDEDWG_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "DelayL.h"
|
||||
#include "BowTable.h"
|
||||
#include "ADSR.h"
|
||||
#include "BiQuad.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class BandedWG
|
||||
\brief Banded waveguide modeling class.
|
||||
|
||||
This class uses banded waveguide techniques to
|
||||
model a variety of sounds, including bowed
|
||||
bars, glasses, and bowls. For more
|
||||
information, see Essl, G. and Cook, P. "Banded
|
||||
Waveguides: Towards Physical Modelling of Bar
|
||||
Percussion Instruments", Proceedings of the
|
||||
1999 International Computer Music Conference.
|
||||
|
||||
Control Change Numbers:
|
||||
- Bow Pressure = 2
|
||||
- Bow Motion = 4
|
||||
- Strike Position = 8 (not implemented)
|
||||
- Vibrato Frequency = 11
|
||||
- Gain = 1
|
||||
- Bow Velocity = 128
|
||||
- Set Striking = 64
|
||||
- Instrument Presets = 16
|
||||
- Uniform Bar = 0
|
||||
- Tuned Bar = 1
|
||||
- Glass Harmonica = 2
|
||||
- Tibetan Bowl = 3
|
||||
|
||||
by Georg Essl, 1999--2004.
|
||||
Modified for STK 4.0 by Gary Scavone.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
const int MAX_BANDED_MODES = 20;
|
||||
|
||||
class BandedWG : public Instrmnt
|
||||
{
|
||||
public:
|
||||
//! Class constructor.
|
||||
BandedWG( void );
|
||||
|
||||
//! Class destructor.
|
||||
~BandedWG( void );
|
||||
|
||||
//! Reset and clear all internal state.
|
||||
void clear( void );
|
||||
|
||||
//! Set strike position (0.0 - 1.0).
|
||||
void setStrikePosition( StkFloat position );
|
||||
|
||||
//! Select a preset.
|
||||
void setPreset( int preset );
|
||||
|
||||
//! Set instrument parameters for a particular frequency.
|
||||
void setFrequency( StkFloat frequency );
|
||||
|
||||
//! Apply bow velocity/pressure to instrument with given amplitude and rate of increase.
|
||||
void startBowing( StkFloat amplitude, StkFloat rate );
|
||||
|
||||
//! Decrease bow velocity/breath pressure with given rate of decrease.
|
||||
void stopBowing( StkFloat rate );
|
||||
|
||||
//! Pluck the instrument with given amplitude.
|
||||
void pluck( StkFloat amp );
|
||||
|
||||
//! Start a note with the given frequency and amplitude.
|
||||
void noteOn( StkFloat frequency, StkFloat amplitude );
|
||||
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
void noteOff( StkFloat amplitude );
|
||||
|
||||
//! Perform the control change specified by \e number and \e value (0.0 - 128.0).
|
||||
void controlChange( int number, StkFloat value );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
//! Fill a channel of the StkFrames object with computed outputs.
|
||||
/*!
|
||||
The \c channel argument must be less than the number of
|
||||
channels in the StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
bool doPluck_;
|
||||
bool trackVelocity_;
|
||||
int nModes_;
|
||||
int presetModes_;
|
||||
BowTable bowTable_;
|
||||
ADSR adsr_;
|
||||
BiQuad bandpass_[MAX_BANDED_MODES];
|
||||
DelayL delay_[MAX_BANDED_MODES];
|
||||
StkFloat maxVelocity_;
|
||||
StkFloat modes_[MAX_BANDED_MODES];
|
||||
StkFloat frequency_;
|
||||
StkFloat baseGain_;
|
||||
StkFloat gains_[MAX_BANDED_MODES];
|
||||
StkFloat basegains_[MAX_BANDED_MODES];
|
||||
StkFloat excitation_[MAX_BANDED_MODES];
|
||||
StkFloat integrationConstant_;
|
||||
StkFloat velocityInput_;
|
||||
StkFloat bowVelocity_;
|
||||
StkFloat bowTarget_;
|
||||
StkFloat bowPosition_;
|
||||
StkFloat strikeAmp_;
|
||||
int strikePosition_;
|
||||
|
||||
};
|
||||
|
||||
inline StkFrames& BandedWG :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
unsigned int nChannels = lastFrame_.channels();
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel > frames.channels() - nChannels ) {
|
||||
oStream_ << "BandedWG::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int j, hop = frames.channels() - nChannels;
|
||||
if ( nChannels == 1 ) {
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
|
||||
*samples++ = tick();
|
||||
}
|
||||
else {
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
|
||||
*samples++ = tick();
|
||||
for ( j=1; j<nChannels; j++ )
|
||||
*samples++ = lastFrame_[j];
|
||||
}
|
||||
}
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
@@ -1,23 +1,127 @@
|
||||
/******************************************/
|
||||
/* HammondOid Organ Subclass */
|
||||
/* of Algorithm 8 (TX81Z) Subclass of */
|
||||
/* 4 Operator FM Synth */
|
||||
/* by Perry R. Cook, 1995-96 */
|
||||
/******************************************/
|
||||
#ifndef STK_BEETHREE_H
|
||||
#define STK_BEETHREE_H
|
||||
|
||||
#if !defined(__BeeThree_h)
|
||||
#define __BeeThree_h
|
||||
#include "FM.h"
|
||||
|
||||
#include "FM4Alg8.h"
|
||||
namespace stk {
|
||||
|
||||
class BeeThree : public FM4Alg8
|
||||
/***************************************************/
|
||||
/*! \class BeeThree
|
||||
\brief STK Hammond-oid organ FM synthesis instrument.
|
||||
|
||||
This class implements a simple 4 operator
|
||||
topology, also referred to as algorithm 8 of
|
||||
the TX81Z.
|
||||
|
||||
\code
|
||||
Algorithm 8 is :
|
||||
1 --.
|
||||
2 -\|
|
||||
+-> Out
|
||||
3 -/|
|
||||
4 --
|
||||
\endcode
|
||||
|
||||
Control Change Numbers:
|
||||
- Operator 4 (feedback) Gain = 2
|
||||
- Operator 3 Gain = 4
|
||||
- LFO Speed = 11
|
||||
- LFO Depth = 1
|
||||
- ADSR 2 & 4 Target = 128
|
||||
|
||||
The basic Chowning/Stanford FM patent expired
|
||||
in 1995, but there exist follow-on patents,
|
||||
mostly assigned to Yamaha. If you are of the
|
||||
type who should worry about this (making
|
||||
money) worry away.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995--2023.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class BeeThree : public FM
|
||||
{
|
||||
public:
|
||||
BeeThree();
|
||||
~BeeThree();
|
||||
virtual void setFreq(MY_FLOAT frequency);
|
||||
MY_FLOAT tick();
|
||||
virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp);
|
||||
public:
|
||||
//! Class constructor.
|
||||
/*!
|
||||
An StkError will be thrown if the rawwave path is incorrectly set.
|
||||
*/
|
||||
BeeThree( void );
|
||||
|
||||
//! Class destructor.
|
||||
~BeeThree( void );
|
||||
|
||||
//! Start a note with the given frequency and amplitude.
|
||||
void noteOn( StkFloat frequency, StkFloat amplitude );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
//! Fill a channel of the StkFrames object with computed outputs.
|
||||
/*!
|
||||
The \c channel argument must be less than the number of
|
||||
channels in the StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat BeeThree :: tick( unsigned int )
|
||||
{
|
||||
StkFloat temp;
|
||||
|
||||
if ( modDepth_ > 0.0 ) {
|
||||
temp = 1.0 + ( modDepth_ * vibrato_.tick() * 0.1 );
|
||||
waves_[0]->setFrequency( baseFrequency_ * temp * ratios_[0] );
|
||||
waves_[1]->setFrequency( baseFrequency_ * temp * ratios_[1] );
|
||||
waves_[2]->setFrequency( baseFrequency_ * temp * ratios_[2] );
|
||||
waves_[3]->setFrequency( baseFrequency_ * temp * ratios_[3] );
|
||||
}
|
||||
|
||||
waves_[3]->addPhaseOffset( twozero_.lastOut() );
|
||||
temp = control1_ * 2.0 * gains_[3] * adsr_[3]->tick() * waves_[3]->tick();
|
||||
twozero_.tick( temp );
|
||||
|
||||
temp += control2_ * 2.0 * gains_[2] * adsr_[2]->tick() * waves_[2]->tick();
|
||||
temp += gains_[1] * adsr_[1]->tick() * waves_[1]->tick();
|
||||
temp += gains_[0] * adsr_[0]->tick() * waves_[0]->tick();
|
||||
|
||||
lastFrame_[0] = temp * 0.125;
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& BeeThree :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
unsigned int nChannels = lastFrame_.channels();
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel > frames.channels() - nChannels ) {
|
||||
oStream_ << "BeeThree::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int j, hop = frames.channels() - nChannels;
|
||||
if ( nChannels == 1 ) {
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
|
||||
*samples++ = tick();
|
||||
}
|
||||
else {
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
|
||||
*samples++ = tick();
|
||||
for ( j=1; j<nChannels; j++ )
|
||||
*samples++ = lastFrame_[j];
|
||||
}
|
||||
}
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
277
include/BiQuad.h
277
include/BiQuad.h
@@ -1,40 +1,259 @@
|
||||
/*******************************************/
|
||||
/*
|
||||
BiQuad (2-pole, 2-zero) Filter Class,
|
||||
by Perry R. Cook, 1995-96.
|
||||
Modified by Julius Smith, 2000:
|
||||
setA1,setA2,setB1,setB2
|
||||
|
||||
See books on filters to understand
|
||||
more about how this works. Nothing
|
||||
out of the ordinary in this version.
|
||||
*/
|
||||
/*******************************************/
|
||||
|
||||
#if !defined(__BiQuad_h)
|
||||
#define __BiQuad_h
|
||||
#ifndef STK_BIQUAD_H
|
||||
#define STK_BIQUAD_H
|
||||
|
||||
#include "Filter.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class BiQuad
|
||||
\brief STK biquad (two-pole, two-zero) filter class.
|
||||
|
||||
This class implements a two-pole, two-zero digital filter.
|
||||
Methods are provided for creating a resonance or notch in the
|
||||
frequency response while maintaining a constant filter gain.
|
||||
|
||||
Formulae used calculate coefficients for lowpass, highpass,
|
||||
bandpass, bandreject and allpass are found on pg. 55 of
|
||||
Udo Zölzer's "DAFX - Digital Audio Effects" (2011 2nd ed).
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995--2023.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
const StkFloat RECIP_SQRT_2 = static_cast<StkFloat>( M_SQRT1_2 );
|
||||
class BiQuad : public Filter
|
||||
{
|
||||
protected:
|
||||
MY_FLOAT poleCoeffs[2];
|
||||
MY_FLOAT zeroCoeffs[2];
|
||||
public:
|
||||
|
||||
//! Default constructor creates a second-order pass-through filter.
|
||||
BiQuad();
|
||||
|
||||
//! Class destructor.
|
||||
~BiQuad();
|
||||
void clear();
|
||||
void setA1(MY_FLOAT a1);
|
||||
void setA2(MY_FLOAT a2);
|
||||
void setB1(MY_FLOAT b1);
|
||||
void setB2(MY_FLOAT b2);
|
||||
void setPoleCoeffs(MY_FLOAT *coeffs);
|
||||
void setZeroCoeffs(MY_FLOAT *coeffs);
|
||||
void setGain(MY_FLOAT aValue);
|
||||
void setFreqAndReson(MY_FLOAT freq, MY_FLOAT reson);
|
||||
void setEqualGainZeroes();
|
||||
MY_FLOAT tick(MY_FLOAT sample);
|
||||
|
||||
//! A function to enable/disable the automatic updating of class data when the STK sample rate changes.
|
||||
void ignoreSampleRateChange( bool ignore = true ) { ignoreSampleRateChange_ = ignore; };
|
||||
|
||||
//! Set all filter coefficients.
|
||||
void setCoefficients( StkFloat b0, StkFloat b1, StkFloat b2, StkFloat a1, StkFloat a2, bool clearState = false );
|
||||
|
||||
//! Set the b[0] coefficient value.
|
||||
void setB0( StkFloat b0 ) { b_[0] = b0; };
|
||||
|
||||
//! Set the b[1] coefficient value.
|
||||
void setB1( StkFloat b1 ) { b_[1] = b1; };
|
||||
|
||||
//! Set the b[2] coefficient value.
|
||||
void setB2( StkFloat b2 ) { b_[2] = b2; };
|
||||
|
||||
//! Set the a[1] coefficient value.
|
||||
void setA1( StkFloat a1 ) { a_[1] = a1; };
|
||||
|
||||
//! Set the a[2] coefficient value.
|
||||
void setA2( StkFloat a2 ) { a_[2] = a2; };
|
||||
|
||||
//! Sets the filter coefficients for a resonance at \e frequency (in Hz).
|
||||
/*!
|
||||
This method determines the filter coefficients corresponding to
|
||||
two complex-conjugate poles with the given \e frequency (in Hz)
|
||||
and \e radius from the z-plane origin. If \e normalize is true,
|
||||
the filter zeros are placed at z = 1, z = -1, and the coefficients
|
||||
are then normalized to produce a constant unity peak gain
|
||||
(independent of the filter \e gain parameter). The resulting
|
||||
filter frequency response has a resonance at the given \e
|
||||
frequency. The closer the poles are to the unit-circle (\e radius
|
||||
close to one), the narrower the resulting resonance width.
|
||||
An unstable filter will result for \e radius >= 1.0. The
|
||||
\e frequency value should be between zero and half the sample rate.
|
||||
*/
|
||||
void setResonance( StkFloat frequency, StkFloat radius, bool normalize = false );
|
||||
|
||||
//! Set the filter coefficients for a notch at \e frequency (in Hz).
|
||||
/*!
|
||||
This method determines the filter coefficients corresponding to
|
||||
two complex-conjugate zeros with the given \e frequency (in Hz)
|
||||
and \e radius from the z-plane origin. No filter normalization is
|
||||
attempted. The \e frequency value should be between zero and half
|
||||
the sample rate. The \e radius value should be positive.
|
||||
*/
|
||||
void setNotch( StkFloat frequency, StkFloat radius );
|
||||
|
||||
//! Set the filter coefficients for a low-pass with cutoff frequency \e fc (in Hz) and Q-factor \e Q.
|
||||
/*!
|
||||
This method determines the filter coefficients corresponding to a
|
||||
low-pass filter with cutoff placed at \e fc, where sloping behaviour
|
||||
and resonance are determined by \e Q. The default value for \e Q is
|
||||
1/sqrt(2), resulting in a gradual attenuation of frequencies higher than
|
||||
\e fc without added resonance. Values greater than this will more
|
||||
aggressively attenuate frequencies above \e fc while also adding a
|
||||
resonance at \e fc. Values less than this will result in a more gradual
|
||||
attenuation of frequencies above \e fc, but will also attenuate
|
||||
frequencies below \e fc as well. Both \e fc and \e Q must be positive.
|
||||
*/
|
||||
void setLowPass( StkFloat fc, StkFloat Q=RECIP_SQRT_2 );
|
||||
|
||||
//! Set the filter coefficients for a high-pass with cutoff frequency \e fc (in Hz) and Q-factor \e Q.
|
||||
/*!
|
||||
This method determines the filter coefficients corresponding to a high-pass
|
||||
filter with cutoff placed at \e fc, where sloping behaviour and resonance
|
||||
are determined by \e Q. The default value for \e Q is 1/sqrt(2), resulting
|
||||
in a gradual attenuation of frequencies lower than \e fc without added
|
||||
resonance. Values greater than this will more aggressively attenuate
|
||||
frequencies below \e fc while also adding a resonance at \e fc. Values less
|
||||
than this will result in a more gradual attenuation of frequencies below
|
||||
\e fc, but will also attenuate frequencies above \e fc as well.
|
||||
Both \e fc and \e Q must be positive.
|
||||
*/
|
||||
void setHighPass( StkFloat fc, StkFloat Q=RECIP_SQRT_2 );
|
||||
|
||||
//! Set the filter coefficients for a band-pass centered at \e fc (in Hz) with Q-factor \e Q.
|
||||
/*!
|
||||
This method determines the filter coefficients corresponding to a band-pass
|
||||
filter with pass-band centered at \e fc, where band width and slope a
|
||||
determined by \e Q. Values for \e Q that are less than 1.0 will attenuate
|
||||
frequencies above and below \e fc more gradually, resulting in a convex
|
||||
slope and a wider band. Values for \e Q greater than 1.0 will attenuate
|
||||
frequencies above and below \e fc more aggressively, resulting in a
|
||||
concave slope and a narrower band. Both \e fc and \e Q must be positive.
|
||||
*/
|
||||
void setBandPass( StkFloat fc, StkFloat Q );
|
||||
|
||||
//! Set the filter coefficients for a band-reject centered at \e fc (in Hz) with Q-factor \e Q.
|
||||
/*!
|
||||
This method determines the filter coefficients corresponding to a
|
||||
band-reject filter with stop-band centered at \e fc, where band width
|
||||
and slope are determined by \e Q. Values for \e Q that are less than 1.0
|
||||
will yield a wider band with greater attenuation of \e fc. Values for \e Q
|
||||
greater than 1.0 will yield a narrower band with less attenuation of \e fc.
|
||||
Both \e fc and \e Q must be positive.
|
||||
*/
|
||||
void setBandReject( StkFloat fc, StkFloat Q );
|
||||
|
||||
//! Set the filter coefficients for an all-pass centered at \e fc (in Hz) with Q-factor \e Q.
|
||||
/*!
|
||||
This method determines the filter coefficients corresponding to
|
||||
an all-pass filter whose phase response crosses -pi radians at \e fc.
|
||||
High values for \e Q will result in a more instantaenous shift in phase
|
||||
response at \e fc. Lower values will result in a more gradual shift in
|
||||
phase response around \e fc. Both \e fc and \e Q must be positive.
|
||||
*/
|
||||
void setAllPass( StkFloat fc, StkFloat Q );
|
||||
|
||||
//! Sets the filter zeroes for equal resonance gain.
|
||||
/*!
|
||||
When using the filter as a resonator, zeroes places at z = 1, z
|
||||
= -1 will result in a constant gain at resonance of 1 / (1 - R),
|
||||
where R is the pole radius setting.
|
||||
*/
|
||||
void setEqualGainZeroes( void );
|
||||
|
||||
//! Return the last computed output value.
|
||||
StkFloat lastOut( void ) const { return lastFrame_[0]; };
|
||||
|
||||
//! Input one sample to the filter and return a reference to one output.
|
||||
StkFloat tick( StkFloat input );
|
||||
|
||||
//! Take a channel of the StkFrames object as inputs to the filter and replace with corresponding outputs.
|
||||
/*!
|
||||
The StkFrames argument reference is returned. The \c channel
|
||||
argument must be less than the number of channels in the
|
||||
StkFrames argument (the first channel is specified by 0).
|
||||
However, range checking is only performed if _STK_DEBUG_ is
|
||||
defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
//! Take a channel of the \c iFrames object as inputs to the filter and write outputs to the \c oFrames object.
|
||||
/*!
|
||||
The \c iFrames object reference is returned. Each channel
|
||||
argument must be less than the number of channels in the
|
||||
corresponding StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
virtual void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
|
||||
|
||||
// Helper function to update the three intermediate values for the predefined filter types
|
||||
// along with the feedback filter coefficients. Performs the debug check for fc and Q-factor arguments.
|
||||
void setCommonFilterValues( StkFloat fc, StkFloat Q );
|
||||
|
||||
StkFloat K_;
|
||||
StkFloat kSqr_;
|
||||
StkFloat denom_;
|
||||
};
|
||||
|
||||
inline StkFloat BiQuad :: tick( StkFloat input )
|
||||
{
|
||||
inputs_[0] = gain_ * input;
|
||||
lastFrame_[0] = b_[0] * inputs_[0] + b_[1] * inputs_[1] + b_[2] * inputs_[2];
|
||||
lastFrame_[0] -= a_[2] * outputs_[2] + a_[1] * outputs_[1];
|
||||
inputs_[2] = inputs_[1];
|
||||
inputs_[1] = inputs_[0];
|
||||
outputs_[2] = outputs_[1];
|
||||
outputs_[1] = lastFrame_[0];
|
||||
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& BiQuad :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
oStream_ << "BiQuad::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
|
||||
inputs_[0] = gain_ * *samples;
|
||||
*samples = b_[0] * inputs_[0] + b_[1] * inputs_[1] + b_[2] * inputs_[2];
|
||||
*samples -= a_[2] * outputs_[2] + a_[1] * outputs_[1];
|
||||
inputs_[2] = inputs_[1];
|
||||
inputs_[1] = inputs_[0];
|
||||
outputs_[2] = outputs_[1];
|
||||
outputs_[1] = *samples;
|
||||
}
|
||||
|
||||
lastFrame_[0] = outputs_[1];
|
||||
return frames;
|
||||
}
|
||||
|
||||
inline StkFrames& BiQuad :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
|
||||
oStream_ << "BiQuad::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *iSamples = &iFrames[iChannel];
|
||||
StkFloat *oSamples = &oFrames[oChannel];
|
||||
unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
|
||||
for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
|
||||
inputs_[0] = gain_ * *iSamples;
|
||||
*oSamples = b_[0] * inputs_[0] + b_[1] * inputs_[1] + b_[2] * inputs_[2];
|
||||
*oSamples -= a_[2] * outputs_[2] + a_[1] * outputs_[1];
|
||||
inputs_[2] = inputs_[1];
|
||||
inputs_[1] = inputs_[0];
|
||||
outputs_[2] = outputs_[1];
|
||||
outputs_[1] = *oSamples;
|
||||
}
|
||||
|
||||
lastFrame_[0] = outputs_[1];
|
||||
return iFrames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
151
include/Blit.h
Normal file
151
include/Blit.h
Normal file
@@ -0,0 +1,151 @@
|
||||
#ifndef STK_BLIT_H
|
||||
#define STK_BLIT_H
|
||||
|
||||
#include "Generator.h"
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Blit
|
||||
\brief STK band-limited impulse train class.
|
||||
|
||||
This class generates a band-limited impulse train using a
|
||||
closed-form algorithm reported by Stilson and Smith in "Alias-Free
|
||||
Digital Synthesis of Classic Analog Waveforms", 1996. The user
|
||||
can specify both the fundamental frequency of the impulse train
|
||||
and the number of harmonics contained in the resulting signal.
|
||||
|
||||
The signal is normalized so that the peak value is +/-1.0.
|
||||
|
||||
If nHarmonics is 0, then the signal will contain all harmonics up
|
||||
to half the sample rate. Note, however, that this setting may
|
||||
produce aliasing in the signal when the frequency is changing (no
|
||||
automatic modification of the number of harmonics is performed by
|
||||
the setFrequency() function).
|
||||
|
||||
Original code by Robin Davies, 2005.
|
||||
Revisions by Gary Scavone for STK, 2005.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class Blit: public Generator
|
||||
{
|
||||
public:
|
||||
//! Default constructor that initializes BLIT frequency to 220 Hz.
|
||||
Blit( StkFloat frequency = 220.0 );
|
||||
|
||||
//! Class destructor.
|
||||
~Blit();
|
||||
|
||||
//! Resets the oscillator state and phase to 0.
|
||||
void reset();
|
||||
|
||||
//! Set the phase of the signal.
|
||||
/*!
|
||||
Set the phase of the signal, in the range 0 to 1.
|
||||
*/
|
||||
void setPhase( StkFloat phase ) { phase_ = PI * phase; };
|
||||
|
||||
//! Get the current phase of the signal.
|
||||
/*!
|
||||
Get the phase of the signal, in the range [0 to 1.0).
|
||||
*/
|
||||
StkFloat getPhase() const { return phase_ / PI; };
|
||||
|
||||
//! Set the impulse train rate in terms of a frequency in Hz.
|
||||
void setFrequency( StkFloat frequency );
|
||||
|
||||
//! Set the number of harmonics generated in the signal.
|
||||
/*!
|
||||
This function sets the number of harmonics contained in the
|
||||
resulting signal. It is equivalent to (2 * M) + 1 in the BLIT
|
||||
algorithm. The default value of 0 sets the algorithm for maximum
|
||||
harmonic content (harmonics up to half the sample rate). This
|
||||
parameter is not checked against the current sample rate and
|
||||
fundamental frequency. Thus, aliasing can result if one or more
|
||||
harmonics for a given fundamental frequency exceeds fs / 2. This
|
||||
behavior was chosen over the potentially more problematic solution
|
||||
of automatically modifying the M parameter, which can produce
|
||||
audible clicks in the signal.
|
||||
*/
|
||||
void setHarmonics( unsigned int nHarmonics = 0 );
|
||||
|
||||
//! Return the last computed output value.
|
||||
StkFloat lastOut( void ) const { return lastFrame_[0]; };
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( void );
|
||||
|
||||
//! Fill a channel of the StkFrames object with computed outputs.
|
||||
/*!
|
||||
The \c channel argument must be less than the number of
|
||||
channels in the StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
void updateHarmonics( void );
|
||||
|
||||
unsigned int nHarmonics_;
|
||||
unsigned int m_;
|
||||
StkFloat rate_;
|
||||
StkFloat phase_;
|
||||
StkFloat p_;
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat Blit :: tick( void )
|
||||
{
|
||||
// The code below implements the SincM algorithm of Stilson and
|
||||
// Smith with an additional scale factor of P / M applied to
|
||||
// normalize the output.
|
||||
|
||||
// A fully optimized version of this code would replace the two sin
|
||||
// calls with a pair of fast sin oscillators, for which stable fast
|
||||
// two-multiply algorithms are well known. In the spirit of STK,
|
||||
// which favors clarity over performance, the optimization has not
|
||||
// been made here.
|
||||
|
||||
// Avoid a divide by zero at the sinc peak, which has a limiting
|
||||
// value of 1.0.
|
||||
StkFloat tmp, denominator = sin( phase_ );
|
||||
if ( denominator <= std::numeric_limits<StkFloat>::epsilon() )
|
||||
tmp = 1.0;
|
||||
else {
|
||||
tmp = sin( m_ * phase_ );
|
||||
tmp /= m_ * denominator;
|
||||
}
|
||||
|
||||
phase_ += rate_;
|
||||
if ( phase_ >= PI ) phase_ -= PI;
|
||||
|
||||
lastFrame_[0] = tmp;
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& Blit :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
oStream_ << "Blit::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
|
||||
*samples = Blit::tick();
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
148
include/BlitSaw.h
Normal file
148
include/BlitSaw.h
Normal file
@@ -0,0 +1,148 @@
|
||||
#ifndef STK_BLITSAW_H
|
||||
#define STK_BLITSAW_H
|
||||
|
||||
#include "Generator.h"
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class BlitSaw
|
||||
\brief STK band-limited sawtooth wave class.
|
||||
|
||||
This class generates a band-limited sawtooth waveform using a
|
||||
closed-form algorithm reported by Stilson and Smith in "Alias-Free
|
||||
Digital Synthesis of Classic Analog Waveforms", 1996. The user
|
||||
can specify both the fundamental frequency of the sawtooth and the
|
||||
number of harmonics contained in the resulting signal.
|
||||
|
||||
If nHarmonics is 0, then the signal will contain all harmonics up
|
||||
to half the sample rate. Note, however, that this setting may
|
||||
produce aliasing in the signal when the frequency is changing (no
|
||||
automatic modification of the number of harmonics is performed by
|
||||
the setFrequency() function).
|
||||
|
||||
Based on initial code of Robin Davies, 2005.
|
||||
Modified algorithm code by Gary Scavone, 2005.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class BlitSaw: public Generator
|
||||
{
|
||||
public:
|
||||
//! Class constructor.
|
||||
BlitSaw( StkFloat frequency = 220.0 );
|
||||
|
||||
//! Class destructor.
|
||||
~BlitSaw();
|
||||
|
||||
//! Resets the oscillator state and phase to 0.
|
||||
void reset();
|
||||
|
||||
//! Set the sawtooth oscillator rate in terms of a frequency in Hz.
|
||||
void setFrequency( StkFloat frequency );
|
||||
|
||||
//! Set the number of harmonics generated in the signal.
|
||||
/*!
|
||||
This function sets the number of harmonics contained in the
|
||||
resulting signal. It is equivalent to (2 * M) + 1 in the BLIT
|
||||
algorithm. The default value of 0 sets the algorithm for maximum
|
||||
harmonic content (harmonics up to half the sample rate). This
|
||||
parameter is not checked against the current sample rate and
|
||||
fundamental frequency. Thus, aliasing can result if one or more
|
||||
harmonics for a given fundamental frequency exceeds fs / 2. This
|
||||
behavior was chosen over the potentially more problematic solution
|
||||
of automatically modifying the M parameter, which can produce
|
||||
audible clicks in the signal.
|
||||
*/
|
||||
void setHarmonics( unsigned int nHarmonics = 0 );
|
||||
|
||||
//! Return the last computed output value.
|
||||
StkFloat lastOut( void ) const { return lastFrame_[0]; };
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( void );
|
||||
|
||||
//! Fill a channel of the StkFrames object with computed outputs.
|
||||
/*!
|
||||
The \c channel argument must be less than the number of
|
||||
channels in the StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
void updateHarmonics( void );
|
||||
|
||||
unsigned int nHarmonics_;
|
||||
unsigned int m_;
|
||||
StkFloat rate_;
|
||||
StkFloat phase_;
|
||||
StkFloat p_;
|
||||
StkFloat C2_;
|
||||
StkFloat a_;
|
||||
StkFloat state_;
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat BlitSaw :: tick( void )
|
||||
{
|
||||
// The code below implements the BLIT algorithm of Stilson and
|
||||
// Smith, followed by a summation and filtering operation to produce
|
||||
// a sawtooth waveform. After experimenting with various approaches
|
||||
// to calculate the average value of the BLIT over one period, I
|
||||
// found that an estimate of C2_ = 1.0 / period (in samples) worked
|
||||
// most consistently. A "leaky integrator" is then applied to the
|
||||
// difference of the BLIT output and C2_. (GPS - 1 October 2005)
|
||||
|
||||
// A fully optimized version of this code would replace the two sin
|
||||
// calls with a pair of fast sin oscillators, for which stable fast
|
||||
// two-multiply algorithms are well known. In the spirit of STK,
|
||||
// which favors clarity over performance, the optimization has
|
||||
// not been made here.
|
||||
|
||||
// Avoid a divide by zero, or use of a denormalized divisor
|
||||
// at the sinc peak, which has a limiting value of m_ / p_.
|
||||
StkFloat tmp, denominator = sin( phase_ );
|
||||
if ( fabs(denominator) <= std::numeric_limits<StkFloat>::epsilon() )
|
||||
tmp = a_;
|
||||
else {
|
||||
tmp = sin( m_ * phase_ );
|
||||
tmp /= p_ * denominator;
|
||||
}
|
||||
|
||||
tmp += state_ - C2_;
|
||||
state_ = tmp * 0.995;
|
||||
|
||||
phase_ += rate_;
|
||||
if ( phase_ >= PI ) phase_ -= PI;
|
||||
|
||||
lastFrame_[0] = tmp;
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& BlitSaw :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
oStream_ << "BlitSaw::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
|
||||
*samples = BlitSaw::tick();
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
170
include/BlitSquare.h
Normal file
170
include/BlitSquare.h
Normal file
@@ -0,0 +1,170 @@
|
||||
#ifndef STK_BLITSQUARE_H
|
||||
#define STK_BLITSQUARE_H
|
||||
|
||||
#include "Generator.h"
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class BlitSquare
|
||||
\brief STK band-limited square wave class.
|
||||
|
||||
This class generates a band-limited square wave signal. It is
|
||||
derived in part from the approach reported by Stilson and Smith in
|
||||
"Alias-Free Digital Synthesis of Classic Analog Waveforms", 1996.
|
||||
The algorithm implemented in this class uses a SincM function with
|
||||
an even M value to achieve a bipolar bandlimited impulse train.
|
||||
This signal is then integrated to achieve a square waveform. The
|
||||
integration process has an associated DC offset so a DC blocking
|
||||
filter is applied at the output.
|
||||
|
||||
The user can specify both the fundamental frequency of the
|
||||
waveform and the number of harmonics contained in the resulting
|
||||
signal.
|
||||
|
||||
If nHarmonics is 0, then the signal will contain all harmonics up
|
||||
to half the sample rate. Note, however, that this setting may
|
||||
produce aliasing in the signal when the frequency is changing (no
|
||||
automatic modification of the number of harmonics is performed by
|
||||
the setFrequency() function). Also note that the harmonics of a
|
||||
square wave fall at odd integer multiples of the fundamental, so
|
||||
aliasing will happen with a lower fundamental than with the other
|
||||
Blit waveforms. This class is not guaranteed to be well behaved
|
||||
in the presence of significant aliasing.
|
||||
|
||||
Based on initial code of Robin Davies, 2005.
|
||||
Modified algorithm code by Gary Scavone, 2005--2006.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class BlitSquare: public Generator
|
||||
{
|
||||
public:
|
||||
//! Default constructor that initializes BLIT frequency to 220 Hz.
|
||||
BlitSquare( StkFloat frequency = 220.0 );
|
||||
|
||||
//! Class destructor.
|
||||
~BlitSquare();
|
||||
|
||||
//! Resets the oscillator state and phase to 0.
|
||||
void reset();
|
||||
|
||||
//! Set the phase of the signal.
|
||||
/*!
|
||||
Set the phase of the signal, in the range 0 to 1.
|
||||
*/
|
||||
void setPhase( StkFloat phase ) { phase_ = PI * phase; };
|
||||
|
||||
//! Get the current phase of the signal.
|
||||
/*!
|
||||
Get the phase of the signal, in the range [0 to 1.0).
|
||||
*/
|
||||
StkFloat getPhase() const { return phase_ / PI; };
|
||||
|
||||
//! Set the impulse train rate in terms of a frequency in Hz.
|
||||
void setFrequency( StkFloat frequency );
|
||||
|
||||
//! Set the number of harmonics generated in the signal.
|
||||
/*!
|
||||
This function sets the number of harmonics contained in the
|
||||
resulting signal. It is equivalent to (2 * M) + 1 in the BLIT
|
||||
algorithm. The default value of 0 sets the algorithm for maximum
|
||||
harmonic content (harmonics up to half the sample rate). This
|
||||
parameter is not checked against the current sample rate and
|
||||
fundamental frequency. Thus, aliasing can result if one or more
|
||||
harmonics for a given fundamental frequency exceeds fs / 2. This
|
||||
behavior was chosen over the potentially more problematic solution
|
||||
of automatically modifying the M parameter, which can produce
|
||||
audible clicks in the signal.
|
||||
*/
|
||||
void setHarmonics( unsigned int nHarmonics = 0 );
|
||||
|
||||
//! Return the last computed output value.
|
||||
StkFloat lastOut( void ) const { return lastFrame_[0]; };
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( void );
|
||||
|
||||
//! Fill a channel of the StkFrames object with computed outputs.
|
||||
/*!
|
||||
The \c channel argument must be less than the number of
|
||||
channels in the StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
void updateHarmonics( void );
|
||||
|
||||
unsigned int nHarmonics_;
|
||||
unsigned int m_;
|
||||
StkFloat rate_;
|
||||
StkFloat phase_;
|
||||
StkFloat p_;
|
||||
StkFloat a_;
|
||||
StkFloat lastBlitOutput_;
|
||||
StkFloat dcbState_;
|
||||
};
|
||||
|
||||
inline StkFloat BlitSquare :: tick( void )
|
||||
{
|
||||
StkFloat temp = lastBlitOutput_;
|
||||
|
||||
// A fully optimized version of this would replace the two sin calls
|
||||
// with a pair of fast sin oscillators, for which stable fast
|
||||
// two-multiply algorithms are well known. In the spirit of STK,
|
||||
// which favors clarity over performance, the optimization has
|
||||
// not been made here.
|
||||
|
||||
// Avoid a divide by zero, or use of a denomralized divisor
|
||||
// at the sinc peak, which has a limiting value of 1.0.
|
||||
StkFloat denominator = sin( phase_ );
|
||||
if ( fabs( denominator ) < std::numeric_limits<StkFloat>::epsilon() ) {
|
||||
// Inexact comparison safely distinguishes betwen *close to zero*, and *close to PI*.
|
||||
if ( phase_ < 0.1f || phase_ > TWO_PI - 0.1f )
|
||||
lastBlitOutput_ = a_;
|
||||
else
|
||||
lastBlitOutput_ = -a_;
|
||||
}
|
||||
else {
|
||||
lastBlitOutput_ = sin( m_ * phase_ );
|
||||
lastBlitOutput_ /= p_ * denominator;
|
||||
}
|
||||
|
||||
lastBlitOutput_ += temp;
|
||||
|
||||
// Now apply DC blocker.
|
||||
lastFrame_[0] = lastBlitOutput_ - dcbState_ + 0.999 * lastFrame_[0];
|
||||
dcbState_ = lastBlitOutput_;
|
||||
|
||||
phase_ += rate_;
|
||||
if ( phase_ >= TWO_PI ) phase_ -= TWO_PI;
|
||||
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& BlitSquare :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
oStream_ << "BlitSquare::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
|
||||
*samples = BlitSquare::tick();
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
144
include/BlowBotl.h
Normal file
144
include/BlowBotl.h
Normal file
@@ -0,0 +1,144 @@
|
||||
#ifndef STK_BLOWBOTL_H
|
||||
#define STK_BLOWBOTL_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "JetTable.h"
|
||||
#include "BiQuad.h"
|
||||
#include "PoleZero.h"
|
||||
#include "Noise.h"
|
||||
#include "ADSR.h"
|
||||
#include "SineWave.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class BlowBotl
|
||||
\brief STK blown bottle instrument class.
|
||||
|
||||
This class implements a helmholtz resonator
|
||||
(biquad filter) with a polynomial jet
|
||||
excitation (a la Cook).
|
||||
|
||||
Control Change Numbers:
|
||||
- Noise Gain = 4
|
||||
- Vibrato Frequency = 11
|
||||
- Vibrato Gain = 1
|
||||
- Volume = 128
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995--2023.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class BlowBotl : public Instrmnt
|
||||
{
|
||||
public:
|
||||
//! Class constructor.
|
||||
/*!
|
||||
An StkError will be thrown if the rawwave path is incorrectly set.
|
||||
*/
|
||||
BlowBotl( void );
|
||||
|
||||
//! Class destructor.
|
||||
~BlowBotl( void );
|
||||
|
||||
//! Reset and clear all internal state.
|
||||
void clear( void );
|
||||
|
||||
//! Set instrument parameters for a particular frequency.
|
||||
void setFrequency( StkFloat frequency );
|
||||
|
||||
//! Apply breath velocity to instrument with given amplitude and rate of increase.
|
||||
void startBlowing( StkFloat amplitude, StkFloat rate );
|
||||
|
||||
//! Decrease breath velocity with given rate of decrease.
|
||||
void stopBlowing( StkFloat rate );
|
||||
|
||||
//! Start a note with the given frequency and amplitude.
|
||||
void noteOn( StkFloat frequency, StkFloat amplitude );
|
||||
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
void noteOff( StkFloat amplitude );
|
||||
|
||||
//! Perform the control change specified by \e number and \e value (0.0 - 128.0).
|
||||
void controlChange( int number, StkFloat value );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
//! Fill a channel of the StkFrames object with computed outputs.
|
||||
/*!
|
||||
The \c channel argument must be less than the number of
|
||||
channels in the StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
JetTable jetTable_;
|
||||
BiQuad resonator_;
|
||||
PoleZero dcBlock_;
|
||||
Noise noise_;
|
||||
ADSR adsr_;
|
||||
SineWave vibrato_;
|
||||
StkFloat maxPressure_;
|
||||
StkFloat noiseGain_;
|
||||
StkFloat vibratoGain_;
|
||||
StkFloat outputGain_;
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat BlowBotl :: tick( unsigned int )
|
||||
{
|
||||
StkFloat breathPressure;
|
||||
StkFloat randPressure;
|
||||
StkFloat pressureDiff;
|
||||
|
||||
// Calculate the breath pressure (envelope + vibrato)
|
||||
breathPressure = maxPressure_ * adsr_.tick();
|
||||
breathPressure += vibratoGain_ * vibrato_.tick();
|
||||
|
||||
pressureDiff = breathPressure - resonator_.lastOut();
|
||||
|
||||
randPressure = noiseGain_ * noise_.tick();
|
||||
randPressure *= breathPressure;
|
||||
randPressure *= (1.0 + pressureDiff);
|
||||
|
||||
resonator_.tick( breathPressure + randPressure - ( jetTable_.tick( pressureDiff ) * pressureDiff ) );
|
||||
lastFrame_[0] = 0.2 * outputGain_ * dcBlock_.tick( pressureDiff );
|
||||
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& BlowBotl :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
unsigned int nChannels = lastFrame_.channels();
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel > frames.channels() - nChannels ) {
|
||||
oStream_ << "BlowBotl::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int j, hop = frames.channels() - nChannels;
|
||||
if ( nChannels == 1 ) {
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
|
||||
*samples++ = tick();
|
||||
}
|
||||
else {
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
|
||||
*samples++ = tick();
|
||||
for ( j=1; j<nChannels; j++ )
|
||||
*samples++ = lastFrame_[j];
|
||||
}
|
||||
}
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
@@ -1,57 +1,185 @@
|
||||
/***********************************************/
|
||||
/*
|
||||
Waveguide reed model with a register hole
|
||||
and one tonehole
|
||||
|
||||
by Gary P. Scavone, 2000.
|
||||
*/
|
||||
/***********************************************/
|
||||
|
||||
#if !defined(__BlowHole_h)
|
||||
#define __BlowHole_h
|
||||
#ifndef STK_BLOWHOLE_H
|
||||
#define STK_BLOWHOLE_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "DLineL.h"
|
||||
#include "ReedTabl.h"
|
||||
#include "DelayL.h"
|
||||
#include "ReedTable.h"
|
||||
#include "OneZero.h"
|
||||
#include "PoleZero.h"
|
||||
#include "Envelope.h"
|
||||
#include "Noise.h"
|
||||
#include "RawWvIn.h"
|
||||
#include "SineWave.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class BlowHole
|
||||
\brief STK clarinet physical model with one
|
||||
register hole and one tonehole.
|
||||
|
||||
This class is based on the clarinet model,
|
||||
with the addition of a two-port register hole
|
||||
and a three-port dynamic tonehole
|
||||
implementation, as discussed by Scavone and
|
||||
Cook (1998).
|
||||
|
||||
In this implementation, the distances between
|
||||
the reed/register hole and tonehole/bell are
|
||||
fixed. As a result, both the tonehole and
|
||||
register hole will have variable influence on
|
||||
the playing frequency, which is dependent on
|
||||
the length of the air column. In addition,
|
||||
the highest playing freqeuency is limited by
|
||||
these fixed lengths.
|
||||
|
||||
This is a digital waveguide model, making its
|
||||
use possibly subject to patents held by Stanford
|
||||
University, Yamaha, and others.
|
||||
|
||||
Control Change Numbers:
|
||||
- Reed Stiffness = 2
|
||||
- Noise Gain = 4
|
||||
- Tonehole State = 11
|
||||
- Register State = 1
|
||||
- Breath Pressure = 128
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995--2023.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class BlowHole : public Instrmnt
|
||||
{
|
||||
protected:
|
||||
DLineL *delays;
|
||||
ReedTabl *reedTable;
|
||||
OneZero *filter;
|
||||
PoleZero *tonehole;
|
||||
PoleZero *vent;
|
||||
Envelope *envelope;
|
||||
Noise *noise;
|
||||
RawWvIn *vibr;
|
||||
long length;
|
||||
MY_FLOAT scatter;
|
||||
MY_FLOAT th_coeff;
|
||||
MY_FLOAT r_th;
|
||||
MY_FLOAT rh_coeff;
|
||||
MY_FLOAT rh_gain;
|
||||
MY_FLOAT outputGain;
|
||||
MY_FLOAT noiseGain;
|
||||
MY_FLOAT vibrGain;
|
||||
public:
|
||||
BlowHole(MY_FLOAT lowestFreq);
|
||||
~BlowHole();
|
||||
void clear();
|
||||
virtual void setFreq(MY_FLOAT frequency);
|
||||
void setTonehole(MY_FLOAT newValue);
|
||||
void setVent(MY_FLOAT newValue);
|
||||
void startBlowing(MY_FLOAT amplitude,MY_FLOAT rate);
|
||||
void stopBlowing(MY_FLOAT rate);
|
||||
virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp);
|
||||
virtual void noteOff(MY_FLOAT amp);
|
||||
virtual MY_FLOAT tick();
|
||||
virtual void controlChange(int number, MY_FLOAT value);
|
||||
//! Class constructor.
|
||||
/*!
|
||||
An StkError will be thrown if the rawwave path is incorrectly set.
|
||||
*/
|
||||
BlowHole( StkFloat lowestFrequency );
|
||||
|
||||
//! Class destructor.
|
||||
~BlowHole( void );
|
||||
|
||||
//! Reset and clear all internal state.
|
||||
void clear( void );
|
||||
|
||||
//! Set instrument parameters for a particular frequency.
|
||||
void setFrequency( StkFloat frequency );
|
||||
|
||||
//! Set the tonehole state (0.0 = closed, 1.0 = fully open).
|
||||
void setTonehole( StkFloat newValue );
|
||||
|
||||
//! Set the register hole state (0.0 = closed, 1.0 = fully open).
|
||||
void setVent( StkFloat newValue );
|
||||
|
||||
//! Apply breath pressure to instrument with given amplitude and rate of increase.
|
||||
void startBlowing( StkFloat amplitude, StkFloat rate );
|
||||
|
||||
//! Decrease breath pressure with given rate of decrease.
|
||||
void stopBlowing( StkFloat rate );
|
||||
|
||||
//! Start a note with the given frequency and amplitude.
|
||||
void noteOn( StkFloat frequency, StkFloat amplitude );
|
||||
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
void noteOff( StkFloat amplitude );
|
||||
|
||||
//! Perform the control change specified by \e number and \e value (0.0 - 128.0).
|
||||
void controlChange( int number, StkFloat value );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
//! Fill a channel of the StkFrames object with computed outputs.
|
||||
/*!
|
||||
The \c channel argument must be less than the number of
|
||||
channels in the StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
DelayL delays_[3];
|
||||
ReedTable reedTable_;
|
||||
OneZero filter_;
|
||||
PoleZero tonehole_;
|
||||
PoleZero vent_;
|
||||
Envelope envelope_;
|
||||
Noise noise_;
|
||||
SineWave vibrato_;
|
||||
|
||||
StkFloat scatter_;
|
||||
StkFloat thCoeff_;
|
||||
StkFloat rhGain_;
|
||||
StkFloat outputGain_;
|
||||
StkFloat noiseGain_;
|
||||
StkFloat vibratoGain_;
|
||||
};
|
||||
|
||||
inline StkFloat BlowHole :: tick( unsigned int )
|
||||
{
|
||||
StkFloat pressureDiff;
|
||||
StkFloat breathPressure;
|
||||
StkFloat temp;
|
||||
|
||||
// Calculate the breath pressure (envelope + noise + vibrato)
|
||||
breathPressure = envelope_.tick();
|
||||
breathPressure += breathPressure * noiseGain_ * noise_.tick();
|
||||
breathPressure += breathPressure * vibratoGain_ * vibrato_.tick();
|
||||
|
||||
// Calculate the differential pressure = reflected - mouthpiece pressures
|
||||
pressureDiff = delays_[0].lastOut() - breathPressure;
|
||||
|
||||
// Do two-port junction scattering for register vent
|
||||
StkFloat pa = breathPressure + pressureDiff * reedTable_.tick( pressureDiff );
|
||||
StkFloat pb = delays_[1].lastOut();
|
||||
vent_.tick( pa+pb );
|
||||
|
||||
lastFrame_[0] = delays_[0].tick( vent_.lastOut()+pb );
|
||||
lastFrame_[0] *= outputGain_;
|
||||
|
||||
// Do three-port junction scattering (under tonehole)
|
||||
pa += vent_.lastOut();
|
||||
pb = delays_[2].lastOut();
|
||||
StkFloat pth = tonehole_.lastOut();
|
||||
temp = scatter_ * (pa + pb - 2 * pth);
|
||||
|
||||
delays_[2].tick( filter_.tick(pa + temp) * -0.95 );
|
||||
delays_[1].tick( pb + temp );
|
||||
tonehole_.tick( pa + pb - pth + temp );
|
||||
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& BlowHole :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
unsigned int nChannels = lastFrame_.channels();
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel > frames.channels() - nChannels ) {
|
||||
oStream_ << "BlowHole::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int j, hop = frames.channels() - nChannels;
|
||||
if ( nChannels == 1 ) {
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
|
||||
*samples++ = tick();
|
||||
}
|
||||
else {
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
|
||||
*samples++ = tick();
|
||||
for ( j=1; j<nChannels; j++ )
|
||||
*samples++ = lastFrame_[j];
|
||||
}
|
||||
}
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
/***********************************************/
|
||||
/* Simple Bow Table Object, after Smith */
|
||||
/* by Perry R. Cook, 1995-96 */
|
||||
/***********************************************/
|
||||
|
||||
#if !defined(__BowTabl_h)
|
||||
#define __BowTabl_h
|
||||
|
||||
#include "Object.h"
|
||||
|
||||
class BowTabl : public Object
|
||||
{
|
||||
protected:
|
||||
MY_FLOAT offSet;
|
||||
MY_FLOAT slope;
|
||||
MY_FLOAT lastOutput;
|
||||
public:
|
||||
BowTabl();
|
||||
~BowTabl();
|
||||
void setOffset(MY_FLOAT aValue);
|
||||
void setSlope(MY_FLOAT aValue);
|
||||
MY_FLOAT lookup(MY_FLOAT sample);
|
||||
MY_FLOAT tick(MY_FLOAT sample);
|
||||
MY_FLOAT lastOut();
|
||||
};
|
||||
|
||||
#endif
|
||||
150
include/BowTable.h
Normal file
150
include/BowTable.h
Normal file
@@ -0,0 +1,150 @@
|
||||
#ifndef STK_BOWTABL_H
|
||||
#define STK_BOWTABL_H
|
||||
|
||||
#include "Function.h"
|
||||
#include <cmath>
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class BowTable
|
||||
\brief STK bowed string table class.
|
||||
|
||||
This class implements a simple bowed string
|
||||
non-linear function, as described by Smith
|
||||
(1986). The output is an instantaneous
|
||||
reflection coefficient value.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995--2023.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class BowTable : public Function
|
||||
{
|
||||
public:
|
||||
//! Default constructor.
|
||||
BowTable( void ) : offset_(0.0), slope_(0.1), minOutput_(0.01), maxOutput_(0.98) {};
|
||||
|
||||
//! Set the table offset value.
|
||||
/*!
|
||||
The table offset is a bias which controls the
|
||||
symmetry of the friction. If you want the
|
||||
friction to vary with direction, use a non-zero
|
||||
value for the offset. The default value is zero.
|
||||
*/
|
||||
void setOffset( StkFloat offset ) { offset_ = offset; };
|
||||
|
||||
//! Set the table slope value.
|
||||
/*!
|
||||
The table slope controls the width of the friction
|
||||
pulse, which is related to bow force.
|
||||
*/
|
||||
void setSlope( StkFloat slope ) { slope_ = slope; };
|
||||
|
||||
//! Set the minimum table output value (0.0 - 1.0).
|
||||
void setMinOutput( StkFloat minimum ) { minOutput_ = minimum; };
|
||||
|
||||
//! Set the maximum table output value (0.0 - 1.0).
|
||||
void setMaxOutput( StkFloat maximum ) { maxOutput_ = maximum; };
|
||||
|
||||
//! Take one sample input and map to one sample of output.
|
||||
StkFloat tick( StkFloat input );
|
||||
|
||||
//! Take a channel of the StkFrames object as inputs to the table and replace with corresponding outputs.
|
||||
/*!
|
||||
The StkFrames argument reference is returned. The \c channel
|
||||
argument must be less than the number of channels in the
|
||||
StkFrames argument (the first channel is specified by 0).
|
||||
However, range checking is only performed if _STK_DEBUG_ is
|
||||
defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
//! Take a channel of the \c iFrames object as inputs to the table and write outputs to the \c oFrames object.
|
||||
/*!
|
||||
The \c iFrames object reference is returned. Each channel
|
||||
argument must be less than the number of channels in the
|
||||
corresponding StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat offset_;
|
||||
StkFloat slope_;
|
||||
StkFloat minOutput_;
|
||||
StkFloat maxOutput_;
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat BowTable :: tick( StkFloat input )
|
||||
{
|
||||
// The input represents differential string vs. bow velocity.
|
||||
StkFloat sample = input + offset_; // add bias to input
|
||||
sample *= slope_; // then scale it
|
||||
lastFrame_[0] = (StkFloat) fabs( (double) sample ) + (StkFloat) 0.75;
|
||||
lastFrame_[0] = (StkFloat) pow( lastFrame_[0], (StkFloat) -4.0 );
|
||||
|
||||
// Set minimum threshold
|
||||
if ( lastFrame_[0] < minOutput_ ) lastFrame_[0] = minOutput_;
|
||||
|
||||
// Set maximum threshold
|
||||
if ( lastFrame_[0] > maxOutput_ ) lastFrame_[0] = maxOutput_;
|
||||
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& BowTable :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
oStream_ << "BowTable::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
|
||||
*samples = *samples + offset_;
|
||||
*samples *= slope_;
|
||||
*samples = (StkFloat) fabs( (double) *samples ) + 0.75;
|
||||
*samples = (StkFloat) pow( *samples, (StkFloat) -4.0 );
|
||||
if ( *samples > 1.0) *samples = 1.0;
|
||||
}
|
||||
|
||||
lastFrame_[0] = *(samples-hop);
|
||||
return frames;
|
||||
}
|
||||
|
||||
inline StkFrames& BowTable :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
|
||||
oStream_ << "BowTable::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *iSamples = &iFrames[iChannel];
|
||||
StkFloat *oSamples = &oFrames[oChannel];
|
||||
unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
|
||||
for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
|
||||
*oSamples = *iSamples + offset_;
|
||||
*oSamples *= slope_;
|
||||
*oSamples = (StkFloat) fabs( (double) *oSamples ) + 0.75;
|
||||
*oSamples = (StkFloat) pow( *oSamples, (StkFloat) -4.0 );
|
||||
if ( *oSamples > 1.0) *oSamples = 1.0;
|
||||
}
|
||||
|
||||
lastFrame_[0] = *(oSamples-oHop);
|
||||
return iFrames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
189
include/Bowed.h
189
include/Bowed.h
@@ -1,56 +1,157 @@
|
||||
/******************************************/
|
||||
/* Bowed String model ala Smith */
|
||||
/* after McIntyre, Schumacher, Woodhouse */
|
||||
/* by Perry Cook, 1995-96 */
|
||||
/* */
|
||||
/* This is a waveguide model, and thus */
|
||||
/* relates to various Stanford Univ. */
|
||||
/* and possibly Yamaha and other patents.*/
|
||||
/* */
|
||||
/* Controls: CONTROL1 = bowPressure */
|
||||
/* CONTROL2 = bowPosition */
|
||||
/* CONTROL3 = vibrFreq */
|
||||
/* MOD_WHEEL= vibrGain */
|
||||
/* */
|
||||
/******************************************/
|
||||
|
||||
#if !defined(__Bowed_h)
|
||||
#define __Bowed_h
|
||||
#ifndef STK_BOWED_H
|
||||
#define STK_BOWED_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "DLineL.h"
|
||||
#include "BowTabl.h"
|
||||
#include "DelayL.h"
|
||||
#include "BowTable.h"
|
||||
#include "OnePole.h"
|
||||
#include "BiQuad.h"
|
||||
#include "RawWvIn.h"
|
||||
#include "SineWave.h"
|
||||
#include "ADSR.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Bowed
|
||||
\brief STK bowed string instrument class.
|
||||
|
||||
This class implements a bowed string model, a
|
||||
la Smith (1986), after McIntyre, Schumacher,
|
||||
Woodhouse (1983).
|
||||
|
||||
This is a digital waveguide model, making its
|
||||
use possibly subject to patents held by
|
||||
Stanford University, Yamaha, and others.
|
||||
|
||||
Control Change Numbers:
|
||||
- Bow Pressure = 2
|
||||
- Bow Position = 4
|
||||
- Vibrato Frequency = 11
|
||||
- Vibrato Gain = 1
|
||||
- Bow Velocity = 100
|
||||
- Frequency = 101
|
||||
- Volume = 128
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995--2023.
|
||||
Contributions by Esteban Maestre, 2011.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class Bowed : public Instrmnt
|
||||
{
|
||||
protected:
|
||||
DLineL *neckDelay;
|
||||
DLineL *bridgeDelay;
|
||||
BowTabl *bowTabl;
|
||||
OnePole *reflFilt;
|
||||
BiQuad *bodyFilt;
|
||||
RawWvIn *vibr;
|
||||
ADSR *adsr;
|
||||
MY_FLOAT maxVelocity;
|
||||
MY_FLOAT baseDelay;
|
||||
MY_FLOAT vibrGain;
|
||||
MY_FLOAT betaRatio;
|
||||
public:
|
||||
Bowed(MY_FLOAT lowestFreq);
|
||||
~Bowed();
|
||||
void clear();
|
||||
void startBowing(MY_FLOAT amplitude,MY_FLOAT rate);
|
||||
void stopBowing(MY_FLOAT rate);
|
||||
virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp);
|
||||
virtual void noteOff(MY_FLOAT amp);
|
||||
virtual void setFreq(MY_FLOAT frequency);
|
||||
void setVibrato(MY_FLOAT amount);
|
||||
virtual void controlChange(int number, MY_FLOAT value);
|
||||
virtual MY_FLOAT tick();
|
||||
//! Class constructor, taking the lowest desired playing frequency.
|
||||
Bowed( StkFloat lowestFrequency = 8.0 );
|
||||
|
||||
//! Class destructor.
|
||||
~Bowed( void );
|
||||
|
||||
//! Reset and clear all internal state.
|
||||
void clear( void );
|
||||
|
||||
//! Set instrument parameters for a particular frequency.
|
||||
void setFrequency( StkFloat frequency );
|
||||
|
||||
//! Set vibrato gain.
|
||||
void setVibrato( StkFloat gain ) { vibratoGain_ = gain; };
|
||||
|
||||
//! Apply breath pressure to instrument with given amplitude and rate of increase.
|
||||
void startBowing( StkFloat amplitude, StkFloat rate );
|
||||
|
||||
//! Decrease breath pressure with given rate of decrease.
|
||||
void stopBowing( StkFloat rate );
|
||||
|
||||
//! Start a note with the given frequency and amplitude.
|
||||
void noteOn( StkFloat frequency, StkFloat amplitude );
|
||||
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
void noteOff( StkFloat amplitude );
|
||||
|
||||
//! Perform the control change specified by \e number and \e value (0.0 - 128.0).
|
||||
void controlChange( int number, StkFloat value );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
//! Fill a channel of the StkFrames object with computed outputs.
|
||||
/*!
|
||||
The \c channel argument must be less than the number of
|
||||
channels in the StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
DelayL neckDelay_;
|
||||
DelayL bridgeDelay_;
|
||||
BowTable bowTable_;
|
||||
OnePole stringFilter_;
|
||||
BiQuad bodyFilters_[6];
|
||||
SineWave vibrato_;
|
||||
ADSR adsr_;
|
||||
|
||||
bool bowDown_;
|
||||
StkFloat maxVelocity_;
|
||||
StkFloat baseDelay_;
|
||||
StkFloat vibratoGain_;
|
||||
StkFloat betaRatio_;
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat Bowed :: tick( unsigned int )
|
||||
{
|
||||
StkFloat bowVelocity = maxVelocity_ * adsr_.tick();
|
||||
StkFloat bridgeReflection = -stringFilter_.tick( bridgeDelay_.lastOut() );
|
||||
StkFloat nutReflection = -neckDelay_.lastOut();
|
||||
StkFloat stringVelocity = bridgeReflection + nutReflection;
|
||||
StkFloat deltaV = bowVelocity - stringVelocity; // Differential velocity
|
||||
|
||||
StkFloat newVelocity = 0.0;
|
||||
if ( bowDown_ )
|
||||
newVelocity = deltaV * bowTable_.tick( deltaV ); // Non-Linear bow function
|
||||
neckDelay_.tick( bridgeReflection + newVelocity); // Do string propagations
|
||||
bridgeDelay_.tick(nutReflection + newVelocity);
|
||||
|
||||
if ( vibratoGain_ > 0.0 ) {
|
||||
neckDelay_.setDelay( (baseDelay_ * (1.0 - betaRatio_) ) +
|
||||
(baseDelay_ * vibratoGain_ * vibrato_.tick()) );
|
||||
}
|
||||
|
||||
lastFrame_[0] = 0.1248 * bodyFilters_[5].tick( bodyFilters_[4].tick( bodyFilters_[3].tick( bodyFilters_[2].tick( bodyFilters_[1].tick( bodyFilters_[0].tick( bridgeDelay_.lastOut() ) ) ) ) ) );
|
||||
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& Bowed :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
unsigned int nChannels = lastFrame_.channels();
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel > frames.channels() - nChannels ) {
|
||||
oStream_ << "Bowed::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int j, hop = frames.channels() - nChannels;
|
||||
if ( nChannels == 1 ) {
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
|
||||
*samples++ = tick();
|
||||
}
|
||||
else {
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
|
||||
*samples++ = tick();
|
||||
for ( j=1; j<nChannels; j++ )
|
||||
*samples++ = lastFrame_[j];
|
||||
}
|
||||
}
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
/*********************************************/
|
||||
/* Bowed Bar model */
|
||||
/* by Georg Essl, 1999 */
|
||||
/* For details refer to: */
|
||||
/* G.Essl, P.R.Cook: "Banded Waveguides: */
|
||||
/* Towards Physical Modelling of Bar */
|
||||
/* Percussion Instruments", ICMC'99 */
|
||||
/*********************************************/
|
||||
|
||||
#if !defined(__BowedBar_h)
|
||||
#define __BowedBar_h
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "DLineN.h"
|
||||
#include "BowTabl.h"
|
||||
#include "ADSR.h"
|
||||
#include "BiQuad.h"
|
||||
|
||||
class BowedBar : public Instrmnt
|
||||
{
|
||||
protected:
|
||||
BowTabl *bowTabl;
|
||||
ADSR *adsr;
|
||||
BiQuad *bandpass;
|
||||
MY_FLOAT maxVelocity;
|
||||
MY_FLOAT modes[4];
|
||||
DLineN delay[4];
|
||||
int NR_MODES;
|
||||
float Zs[4][2];
|
||||
MY_FLOAT coeffs[4][2];
|
||||
float filtOut[4];
|
||||
float filtIn[4];
|
||||
MY_FLOAT filtGain[4];
|
||||
MY_FLOAT freq;
|
||||
int length;
|
||||
MY_FLOAT R;
|
||||
MY_FLOAT GAIN;
|
||||
MY_FLOAT gains[4];
|
||||
MY_FLOAT slope;
|
||||
MY_FLOAT velinput;
|
||||
MY_FLOAT integration_const;
|
||||
int trackVel;
|
||||
MY_FLOAT bowvel, bowTarg, bowPos, lastBowPos;
|
||||
int doPluck;
|
||||
|
||||
public:
|
||||
BowedBar();
|
||||
~BowedBar();
|
||||
void tuneBandPasses();
|
||||
void clear();
|
||||
void startBowing(MY_FLOAT amplitude,MY_FLOAT rate);
|
||||
void stopBowing(MY_FLOAT rate);
|
||||
void pluck(MY_FLOAT amp);
|
||||
void setStrikePosition(MY_FLOAT position);
|
||||
void noteOn(MY_FLOAT freq, MY_FLOAT amp);
|
||||
void noteOff(MY_FLOAT amp);
|
||||
void setFreq(MY_FLOAT frequency);
|
||||
void controlChange(int number, MY_FLOAT value);
|
||||
MY_FLOAT tick();
|
||||
};
|
||||
|
||||
#endif
|
||||
182
include/Brass.h
182
include/Brass.h
@@ -1,53 +1,147 @@
|
||||
/******************************************/
|
||||
/* Simple Brass Instrument Model ala */
|
||||
/* Cook (TBone, HosePlayer) */
|
||||
/* by Perry R. Cook, 1995-96 */
|
||||
/* */
|
||||
/* This is a waveguide model, and thus */
|
||||
/* relates to various Stanford Univ. */
|
||||
/* and possibly Yamaha and other patents.*/
|
||||
/* */
|
||||
/* Controls: CONTROL1 = lipTension */
|
||||
/* CONTROL2 = slideLength */
|
||||
/* CONTROL3 = vibFreq */
|
||||
/* MOD_WHEEL= vibAmt */
|
||||
/******************************************/
|
||||
|
||||
#if !defined(__Brass_h)
|
||||
#define __Brass_h
|
||||
#ifndef STK_BRASS_H
|
||||
#define STK_BRASS_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "DLineA.h"
|
||||
#include "LipFilt.h"
|
||||
#include "DCBlock.h"
|
||||
#include "DelayA.h"
|
||||
#include "BiQuad.h"
|
||||
#include "PoleZero.h"
|
||||
#include "ADSR.h"
|
||||
#include "RawWvIn.h"
|
||||
#include "SineWave.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Brass
|
||||
\brief STK simple brass instrument class.
|
||||
|
||||
This class implements a simple brass instrument
|
||||
waveguide model, a la Cook (TBone, HosePlayer).
|
||||
|
||||
This is a digital waveguide model, making its
|
||||
use possibly subject to patents held by
|
||||
Stanford University, Yamaha, and others.
|
||||
|
||||
Control Change Numbers:
|
||||
- Lip Tension = 2
|
||||
- Slide Length = 4
|
||||
- Vibrato Frequency = 11
|
||||
- Vibrato Gain = 1
|
||||
- Volume = 128
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995--2023.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class Brass: public Instrmnt
|
||||
{
|
||||
protected:
|
||||
DLineA *delayLine;
|
||||
LipFilt *lipFilter;
|
||||
DCBlock *dcBlock;
|
||||
ADSR *adsr;
|
||||
RawWvIn *vibr;
|
||||
long length;
|
||||
MY_FLOAT lipTarget;
|
||||
MY_FLOAT slideTarget;
|
||||
MY_FLOAT vibrGain;
|
||||
MY_FLOAT maxPressure;
|
||||
public:
|
||||
Brass(MY_FLOAT lowestFreq);
|
||||
~Brass();
|
||||
void clear();
|
||||
virtual void setFreq(MY_FLOAT frequency);
|
||||
void setLip(MY_FLOAT frequency);
|
||||
void startBlowing(MY_FLOAT amplitude,MY_FLOAT rate);
|
||||
void stopBlowing(MY_FLOAT rate);
|
||||
virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp);
|
||||
virtual void noteOff(MY_FLOAT amp);
|
||||
virtual void controlChange(int number, MY_FLOAT value);
|
||||
virtual MY_FLOAT tick();
|
||||
public:
|
||||
//! Class constructor, taking the lowest desired playing frequency.
|
||||
/*!
|
||||
An StkError will be thrown if the rawwave path is incorrectly set.
|
||||
*/
|
||||
Brass( StkFloat lowestFrequency = 8.0 );
|
||||
|
||||
//! Class destructor.
|
||||
~Brass( );
|
||||
|
||||
//! Reset and clear all internal state.
|
||||
void clear( );
|
||||
|
||||
//! Set instrument parameters for a particular frequency.
|
||||
void setFrequency( StkFloat frequency );
|
||||
|
||||
//! Set the lips frequency.
|
||||
void setLip( StkFloat frequency );
|
||||
|
||||
//! Apply breath pressure to instrument with given amplitude and rate of increase.
|
||||
void startBlowing( StkFloat amplitude, StkFloat rate );
|
||||
|
||||
//! Decrease breath pressure with given rate of decrease.
|
||||
void stopBlowing( StkFloat rate );
|
||||
|
||||
//! Start a note with the given frequency and amplitude.
|
||||
void noteOn( StkFloat frequency, StkFloat amplitude );
|
||||
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
void noteOff( StkFloat amplitude );
|
||||
|
||||
//! Perform the control change specified by \e number and \e value (0.0 - 128.0).
|
||||
void controlChange( int number, StkFloat value );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
//! Fill a channel of the StkFrames object with computed outputs.
|
||||
/*!
|
||||
The \c channel argument must be less than the number of
|
||||
channels in the StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
DelayA delayLine_;
|
||||
BiQuad lipFilter_;
|
||||
PoleZero dcBlock_;
|
||||
ADSR adsr_;
|
||||
SineWave vibrato_;
|
||||
|
||||
StkFloat lipTarget_;
|
||||
StkFloat slideTarget_;
|
||||
StkFloat vibratoGain_;
|
||||
StkFloat maxPressure_;
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat Brass :: tick( unsigned int )
|
||||
{
|
||||
StkFloat breathPressure = maxPressure_ * adsr_.tick();
|
||||
breathPressure += vibratoGain_ * vibrato_.tick();
|
||||
|
||||
StkFloat mouthPressure = 0.3 * breathPressure;
|
||||
StkFloat borePressure = 0.85 * delayLine_.lastOut();
|
||||
StkFloat deltaPressure = mouthPressure - borePressure; // Differential pressure.
|
||||
deltaPressure = lipFilter_.tick( deltaPressure ); // Force - > position.
|
||||
deltaPressure *= deltaPressure; // Basic position to area mapping.
|
||||
if ( deltaPressure > 1.0 ) deltaPressure = 1.0; // Non-linear saturation.
|
||||
|
||||
// The following input scattering assumes the mouthPressure = area.
|
||||
lastFrame_[0] = deltaPressure * mouthPressure + ( 1.0 - deltaPressure) * borePressure;
|
||||
lastFrame_[0] = delayLine_.tick( dcBlock_.tick( lastFrame_[0] ) );
|
||||
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& Brass :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
unsigned int nChannels = lastFrame_.channels();
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel > frames.channels() - nChannels ) {
|
||||
oStream_ << "Brass::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int j, hop = frames.channels() - nChannels;
|
||||
if ( nChannels == 1 ) {
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
|
||||
*samples++ = tick();
|
||||
}
|
||||
else {
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
|
||||
*samples++ = tick();
|
||||
for ( j=1; j<nChannels; j++ )
|
||||
*samples++ = lastFrame_[j];
|
||||
}
|
||||
}
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
#include "Object.h"
|
||||
|
||||
void swap16(unsigned char *ptr);
|
||||
void swap32(unsigned char *ptr);
|
||||
void swap64(unsigned char *ptr);
|
||||
172
include/Chorus.h
Normal file
172
include/Chorus.h
Normal file
@@ -0,0 +1,172 @@
|
||||
#ifndef STK_CHORUS_H
|
||||
#define STK_CHORUS_H
|
||||
|
||||
#include "Effect.h"
|
||||
#include "DelayL.h"
|
||||
#include "SineWave.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Chorus
|
||||
\brief STK chorus effect class.
|
||||
|
||||
This class implements a chorus effect. It takes a monophonic
|
||||
input signal and produces a stereo output signal.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995--2023.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class Chorus : public Effect
|
||||
{
|
||||
public:
|
||||
//! Class constructor, taking the median desired delay length.
|
||||
/*!
|
||||
An StkError can be thrown if the rawwave path is incorrect.
|
||||
*/
|
||||
Chorus( StkFloat baseDelay = 6000 );
|
||||
|
||||
//! Reset and clear all internal state.
|
||||
void clear( void );
|
||||
|
||||
//! Set modulation depth in range 0.0 - 1.0.
|
||||
void setModDepth( StkFloat depth );
|
||||
|
||||
//! Set modulation frequency.
|
||||
void setModFrequency( StkFloat frequency );
|
||||
|
||||
//! Return the specified channel value of the last computed stereo frame.
|
||||
/*!
|
||||
Use the lastFrame() function to get both values of the last
|
||||
computed stereo frame. The \c channel argument must be 0 or 1
|
||||
(the first channel is specified by 0). However, range checking is
|
||||
only performed if _STK_DEBUG_ is defined during compilation, in
|
||||
which case an out-of-range value will trigger an StkError
|
||||
exception.
|
||||
*/
|
||||
StkFloat lastOut( unsigned int channel = 0 );
|
||||
|
||||
//! Input one sample to the effect and return the specified \c channel value of the computed stereo frame.
|
||||
/*!
|
||||
Use the lastFrame() function to get both values of the computed
|
||||
stereo output frame. The \c channel argument must be 0 or 1 (the
|
||||
first channel is specified by 0). However, range checking is only
|
||||
performed if _STK_DEBUG_ is defined during compilation, in which
|
||||
case an out-of-range value will trigger an StkError exception.
|
||||
*/
|
||||
StkFloat tick( StkFloat input, unsigned int channel = 0 );
|
||||
|
||||
//! Take a channel of the StkFrames object as inputs to the effect and replace with stereo outputs.
|
||||
/*!
|
||||
The StkFrames argument reference is returned. The stereo
|
||||
outputs are written to the StkFrames argument starting at the
|
||||
specified \c channel. Therefore, the \c channel argument must be
|
||||
less than ( channels() - 1 ) of the StkFrames argument (the first
|
||||
channel is specified by 0). However, range checking is only
|
||||
performed if _STK_DEBUG_ is defined during compilation, in which
|
||||
case an out-of-range value will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
//! Take a channel of the \c iFrames object as inputs to the effect and write stereo outputs to the \c oFrames object.
|
||||
/*!
|
||||
The \c iFrames object reference is returned. The \c iChannel
|
||||
argument must be less than the number of channels in the \c
|
||||
iFrames argument (the first channel is specified by 0). The \c
|
||||
oChannel argument must be less than ( channels() - 1 ) of the \c
|
||||
oFrames argument. However, range checking is only performed if
|
||||
_STK_DEBUG_ is defined during compilation, in which case an
|
||||
out-of-range value will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
DelayL delayLine_[2];
|
||||
SineWave mods_[2];
|
||||
StkFloat baseLength_;
|
||||
StkFloat modDepth_;
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat Chorus :: lastOut( unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel > 1 ) {
|
||||
oStream_ << "Chorus::lastOut(): channel argument must be less than 2!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
return lastFrame_[channel];
|
||||
}
|
||||
|
||||
inline StkFloat Chorus :: tick( StkFloat input, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel > 1 ) {
|
||||
oStream_ << "Chorus::tick(): channel argument must be less than 2!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
delayLine_[0].setDelay( baseLength_ * 0.707 * ( 1.0 + modDepth_ * mods_[0].tick() ) );
|
||||
delayLine_[1].setDelay( baseLength_ * 0.5 * ( 1.0 - modDepth_ * mods_[1].tick() ) );
|
||||
lastFrame_[0] = effectMix_ * ( delayLine_[0].tick( input ) - input ) + input;
|
||||
lastFrame_[1] = effectMix_ * ( delayLine_[1].tick( input ) - input ) + input;
|
||||
return lastFrame_[channel];
|
||||
}
|
||||
|
||||
inline StkFrames& Chorus :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() - 1 ) {
|
||||
oStream_ << "Chorus::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int hop = frames.channels() - 1;
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
|
||||
delayLine_[0].setDelay( baseLength_ * 0.707 * ( 1.0 + modDepth_ * mods_[0].tick() ) );
|
||||
delayLine_[1].setDelay( baseLength_ * 0.5 * ( 1.0 - modDepth_ * mods_[1].tick() ) );
|
||||
*samples = effectMix_ * ( delayLine_[0].tick( *samples ) - *samples ) + *samples;
|
||||
samples++;
|
||||
*samples = effectMix_ * ( delayLine_[1].tick( *samples ) - *samples ) + *samples;
|
||||
}
|
||||
|
||||
lastFrame_[0] = *(samples-hop);
|
||||
lastFrame_[1] = *(samples-hop+1);
|
||||
return frames;
|
||||
}
|
||||
|
||||
inline StkFrames& Chorus :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() - 1 ) {
|
||||
oStream_ << "Chorus::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *iSamples = &iFrames[iChannel];
|
||||
StkFloat *oSamples = &oFrames[oChannel];
|
||||
unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
|
||||
for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
|
||||
delayLine_[0].setDelay( baseLength_ * 0.707 * ( 1.0 + modDepth_ * mods_[0].tick() ) );
|
||||
delayLine_[1].setDelay( baseLength_ * 0.5 * ( 1.0 - modDepth_ * mods_[1].tick() ) );
|
||||
*oSamples = effectMix_ * ( delayLine_[0].tick( *iSamples ) - *iSamples ) + *iSamples;
|
||||
*(oSamples+1) = effectMix_ * ( delayLine_[1].tick( *iSamples ) - *iSamples ) + *iSamples;
|
||||
}
|
||||
|
||||
lastFrame_[0] = *(oSamples-oHop);
|
||||
lastFrame_[1] = *(oSamples-oHop+1);
|
||||
return iFrames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,53 +1,152 @@
|
||||
/******************************************/
|
||||
/* Clarinet model ala Smith */
|
||||
/* after McIntyre, Schumacher, Woodhouse */
|
||||
/* by Perry Cook, 1995-96 */
|
||||
/* */
|
||||
/* This is a waveguide model, and thus */
|
||||
/* relates to various Stanford Univ. */
|
||||
/* and possibly Yamaha and other patents.*/
|
||||
/* */
|
||||
/* Controls: CONTROL1 = reedStiffns */
|
||||
/* CONTROL2 = noiseGain */
|
||||
/* CONTROL3 = vibFreq */
|
||||
/* MOD_WHEEL= vibAmt */
|
||||
/******************************************/
|
||||
|
||||
#if !defined(__Clarinet_h)
|
||||
#define __Clarinet_h
|
||||
#ifndef STK_CLARINET_H
|
||||
#define STK_CLARINET_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "DLineL.h"
|
||||
#include "ReedTabl.h"
|
||||
#include "DelayL.h"
|
||||
#include "ReedTable.h"
|
||||
#include "OneZero.h"
|
||||
#include "Envelope.h"
|
||||
#include "Noise.h"
|
||||
#include "RawWvIn.h"
|
||||
#include "SineWave.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Clarinet
|
||||
\brief STK clarinet physical model class.
|
||||
|
||||
This class implements a simple clarinet
|
||||
physical model, as discussed by Smith (1986),
|
||||
McIntyre, Schumacher, Woodhouse (1983), and
|
||||
others.
|
||||
|
||||
This is a digital waveguide model, making its
|
||||
use possibly subject to patents held by Stanford
|
||||
University, Yamaha, and others.
|
||||
|
||||
Control Change Numbers:
|
||||
- Reed Stiffness = 2
|
||||
- Noise Gain = 4
|
||||
- Vibrato Frequency = 11
|
||||
- Vibrato Gain = 1
|
||||
- Breath Pressure = 128
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995--2023.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class Clarinet : public Instrmnt
|
||||
{
|
||||
protected:
|
||||
DLineL *delayLine;
|
||||
ReedTabl *reedTable;
|
||||
OneZero *filter;
|
||||
Envelope *envelope;
|
||||
Noise *noise;
|
||||
RawWvIn *vibr;
|
||||
long length;
|
||||
MY_FLOAT outputGain;
|
||||
MY_FLOAT noiseGain;
|
||||
MY_FLOAT vibrGain;
|
||||
public:
|
||||
Clarinet(MY_FLOAT lowestFreq);
|
||||
~Clarinet();
|
||||
void clear();
|
||||
virtual void setFreq(MY_FLOAT frequency);
|
||||
void startBlowing(MY_FLOAT amplitude,MY_FLOAT rate);
|
||||
void stopBlowing(MY_FLOAT rate);
|
||||
virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp);
|
||||
virtual void noteOff(MY_FLOAT amp);
|
||||
virtual MY_FLOAT tick();
|
||||
virtual void controlChange(int number, MY_FLOAT value);
|
||||
//! Class constructor, taking the lowest desired playing frequency.
|
||||
/*!
|
||||
An StkError will be thrown if the rawwave path is incorrectly set.
|
||||
*/
|
||||
Clarinet( StkFloat lowestFrequency = 8.0 );
|
||||
|
||||
//! Class destructor.
|
||||
~Clarinet( void );
|
||||
|
||||
//! Reset and clear all internal state.
|
||||
void clear( void );
|
||||
|
||||
//! Set instrument parameters for a particular frequency.
|
||||
void setFrequency( StkFloat frequency );
|
||||
|
||||
//! Apply breath pressure to instrument with given amplitude and rate of increase.
|
||||
void startBlowing( StkFloat amplitude, StkFloat rate );
|
||||
|
||||
//! Decrease breath pressure with given rate of decrease.
|
||||
void stopBlowing( StkFloat rate );
|
||||
|
||||
//! Start a note with the given frequency and amplitude.
|
||||
void noteOn( StkFloat frequency, StkFloat amplitude );
|
||||
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
void noteOff( StkFloat amplitude );
|
||||
|
||||
//! Perform the control change specified by \e number and \e value (0.0 - 128.0).
|
||||
void controlChange( int number, StkFloat value );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
//! Fill a channel of the StkFrames object with computed outputs.
|
||||
/*!
|
||||
The \c channel argument must be less than the number of
|
||||
channels in the StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
DelayL delayLine_;
|
||||
ReedTable reedTable_;
|
||||
OneZero filter_;
|
||||
Envelope envelope_;
|
||||
Noise noise_;
|
||||
SineWave vibrato_;
|
||||
|
||||
StkFloat outputGain_;
|
||||
StkFloat noiseGain_;
|
||||
StkFloat vibratoGain_;
|
||||
};
|
||||
|
||||
inline StkFloat Clarinet :: tick( unsigned int )
|
||||
{
|
||||
StkFloat pressureDiff;
|
||||
StkFloat breathPressure;
|
||||
|
||||
// Calculate the breath pressure (envelope + noise + vibrato)
|
||||
breathPressure = envelope_.tick();
|
||||
breathPressure += breathPressure * noiseGain_ * noise_.tick();
|
||||
breathPressure += breathPressure * vibratoGain_ * vibrato_.tick();
|
||||
|
||||
// Perform commuted loss filtering.
|
||||
pressureDiff = -0.95 * filter_.tick( delayLine_.lastOut() );
|
||||
|
||||
// Calculate pressure difference of reflected and mouthpiece pressures.
|
||||
pressureDiff = pressureDiff - breathPressure;
|
||||
|
||||
// Perform non-linear scattering using pressure difference in reed function.
|
||||
lastFrame_[0] = delayLine_.tick(breathPressure + pressureDiff * reedTable_.tick(pressureDiff));
|
||||
|
||||
// Apply output gain.
|
||||
lastFrame_[0] *= outputGain_;
|
||||
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& Clarinet :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
unsigned int nChannels = lastFrame_.channels();
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel > frames.channels() - nChannels ) {
|
||||
oStream_ << "Clarinet::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int j, hop = frames.channels() - nChannels;
|
||||
if ( nChannels == 1 ) {
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
|
||||
*samples++ = tick();
|
||||
}
|
||||
else {
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
|
||||
*samples++ = tick();
|
||||
for ( j=1; j<nChannels; j++ )
|
||||
*samples++ = lastFrame_[j];
|
||||
}
|
||||
}
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
/******************************************/
|
||||
/*
|
||||
Controller Class,
|
||||
by Gary P. Scavone, 2000
|
||||
|
||||
This object will accept control messages
|
||||
from a variety of sources, such as a MIDI
|
||||
port, scorefile, socket connection, or
|
||||
pipe. MIDI messages are retrieved with
|
||||
the RtMidi class. All other input sources
|
||||
(scorefile, socket, or pipe) are assumed
|
||||
to provide SKINI formatted messages.
|
||||
|
||||
For each call of getNextMessage(), the
|
||||
active input devices are queried to see
|
||||
if a new control message is available.
|
||||
Only one message per call is returned, so
|
||||
a subsequent call begins querying the
|
||||
next available device "after" the previously
|
||||
handled one.
|
||||
|
||||
This class is primarily for use in STK
|
||||
main() event loops.
|
||||
|
||||
One of my original goals in creating this class
|
||||
was to simplify the message acquisition process
|
||||
by removing all threads. If the windoze
|
||||
select() function behaved just like the unix one,
|
||||
that would have been possible. Since it does not
|
||||
(it can't be used to poll STDIN), I am using a
|
||||
thread to acquire messages from STDIN, which are
|
||||
then sent via a socket connection to the message
|
||||
socket server. Perhaps in the future, I will be
|
||||
able to simplify things.
|
||||
*/
|
||||
/******************************************/
|
||||
|
||||
#if !defined(__Controller_h)
|
||||
#define __Controller_h
|
||||
|
||||
#include "Object.h"
|
||||
#include "SKINI11.h"
|
||||
|
||||
#if defined(__STK_REALTIME_)
|
||||
#include "RtMidi.h"
|
||||
#include "StkError.h"
|
||||
|
||||
#if (defined(__OS_IRIX_) || defined(__OS_Linux_))
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <pthread.h>
|
||||
#include <netdb.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
void *stdinHandler(void *);
|
||||
|
||||
#elif defined(__OS_Win_)
|
||||
#include <process.h>
|
||||
#include <winsock.h>
|
||||
|
||||
void stdinHandler(void *);
|
||||
|
||||
#endif
|
||||
|
||||
#endif // __STK_REALTIME
|
||||
|
||||
#define STK_MIDI 0x0001
|
||||
#define STK_PIPE 0x0002
|
||||
#define STK_SOCKET 0x0004
|
||||
#define STK_SCOREFILE 0x0008
|
||||
|
||||
#define MESSAGE_LENGTH 128
|
||||
#define MAX_MESSAGES 25
|
||||
#define STK_SOCKET_PORT 2001
|
||||
|
||||
class Controller : public Object
|
||||
{
|
||||
protected:
|
||||
int source;
|
||||
long default_ticks;
|
||||
int type;
|
||||
MY_FLOAT channel;
|
||||
MY_FLOAT byte2;
|
||||
MY_FLOAT byte3;
|
||||
char message[MAX_MESSAGES][MESSAGE_LENGTH];
|
||||
int msg_index;
|
||||
int num_messages;
|
||||
SKINI11 *score;
|
||||
|
||||
#if defined(__STK_REALTIME_)
|
||||
fd_set mask;
|
||||
int maxfd;
|
||||
int fd[16];
|
||||
int local_socket;
|
||||
RtMidi *midi_input;
|
||||
int parseSocketData(int fd);
|
||||
#if (defined(__OS_IRIX_) || defined(__OS_Linux_))
|
||||
pthread_t stdin_thread;
|
||||
#elif defined(__OS_Win_)
|
||||
unsigned long stdin_thread;
|
||||
#endif
|
||||
#endif // __STK_REALTIME
|
||||
|
||||
public:
|
||||
Controller(int inputMask);
|
||||
~Controller();
|
||||
void setDefaultTicks(long nSamples);
|
||||
int getNextMessage();
|
||||
int getType();
|
||||
MY_FLOAT getByte2();
|
||||
MY_FLOAT getByte3();
|
||||
MY_FLOAT getChannel();
|
||||
};
|
||||
|
||||
#endif // defined(__Controller_h)
|
||||
138
include/Cubic.h
Normal file
138
include/Cubic.h
Normal file
@@ -0,0 +1,138 @@
|
||||
#ifndef STK_CUBIC_H
|
||||
#define STK_CUBIC_H
|
||||
|
||||
#include "Function.h"
|
||||
#include <cmath>
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Cubic
|
||||
\brief STK cubic non-linearity class.
|
||||
|
||||
This class implements the cubic non-linearity
|
||||
that was used in SynthBuilder.
|
||||
|
||||
The formula implemented is:
|
||||
|
||||
\code
|
||||
output = gain * (a1 * input + a2 * input^2 + a3 * input^3)
|
||||
\endcode
|
||||
|
||||
followed by a limiter for values outside +-threshold.
|
||||
|
||||
Ported to STK by Nick Porcaro, 2007. Updated for inclusion
|
||||
in STK distribution by Gary Scavone, 2011.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class Cubic : public Function
|
||||
{
|
||||
public:
|
||||
//! Default constructor.
|
||||
Cubic( void ) : a1_(0.5), a2_(0.5), a3_(0.5), gain_(1.0), threshold_(1.0) {};
|
||||
|
||||
//! Set the a1 coefficient value.
|
||||
void setA1( StkFloat a1 ) { a1_ = a1; };
|
||||
|
||||
//! Set the a2 coefficient value.
|
||||
void setA2( StkFloat a2 ) { a2_ = a2; };
|
||||
|
||||
//! Set the a3 coefficient value.
|
||||
void setA3( StkFloat a3 ) { a3_ = a3; };
|
||||
|
||||
//! Set the gain value.
|
||||
void setGain( StkFloat gain ) { gain_ = gain; };
|
||||
|
||||
//! Set the threshold value.
|
||||
void setThreshold( StkFloat threshold ) { threshold_ = threshold; };
|
||||
|
||||
//! Input one sample to the function and return one output.
|
||||
StkFloat tick( StkFloat input );
|
||||
|
||||
//! Take a channel of the StkFrames object as inputs to the function and replace with corresponding outputs.
|
||||
/*!
|
||||
The StkFrames argument reference is returned. The \c channel
|
||||
argument must be less than the number of channels in the
|
||||
StkFrames argument (the first channel is specified by 0).
|
||||
However, range checking is only performed if _STK_DEBUG_ is
|
||||
defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
//! Take a channel of the \c iFrames object as inputs to the function and write outputs to the \c oFrames object.
|
||||
/*!
|
||||
The \c iFrames object reference is returned. Each channel
|
||||
argument must be less than the number of channels in the
|
||||
corresponding StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat a1_;
|
||||
StkFloat a2_;
|
||||
StkFloat a3_;
|
||||
StkFloat gain_;
|
||||
StkFloat threshold_;
|
||||
};
|
||||
|
||||
inline StkFloat Cubic :: tick( StkFloat input )
|
||||
{
|
||||
StkFloat inSquared = input * input;
|
||||
StkFloat inCubed = inSquared * input;
|
||||
|
||||
lastFrame_[0] = gain_ * (a1_ * input + a2_ * inSquared + a3_ * inCubed);
|
||||
|
||||
// Apply threshold if we are out of range.
|
||||
if ( fabs( lastFrame_[0] ) > threshold_ ) {
|
||||
lastFrame_[0] = ( lastFrame_[0] < 0 ? -threshold_ : threshold_ );
|
||||
}
|
||||
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& Cubic :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
oStream_ << "Cubic::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
|
||||
*samples = tick( *samples );
|
||||
|
||||
lastFrame_[0] = *(samples-hop);
|
||||
return frames;
|
||||
}
|
||||
|
||||
inline StkFrames& Cubic :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
|
||||
oStream_ << "Cubic::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *iSamples = &iFrames[iChannel];
|
||||
StkFloat *oSamples = &oFrames[oChannel];
|
||||
unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
|
||||
for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop )
|
||||
*oSamples = tick( *iSamples );
|
||||
|
||||
lastFrame_[0] = *(oSamples-oHop);
|
||||
return iFrames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
@@ -1,26 +0,0 @@
|
||||
/*******************************************/
|
||||
/* DC Blocking Filter */
|
||||
/* by Perry R. Cook, 1995-96 */
|
||||
/* */
|
||||
/* This guy is very helpful in, uh, */
|
||||
/* blocking DC. Needed because a simple */
|
||||
/* low-pass reflection filter allows DC */
|
||||
/* to build up inside recursive */
|
||||
/* structures. */
|
||||
/*******************************************/
|
||||
|
||||
#if !defined(__DCBlock_h)
|
||||
#define __DCBlock_h
|
||||
|
||||
#include "Filter.h"
|
||||
|
||||
class DCBlock : public Filter
|
||||
{
|
||||
public:
|
||||
DCBlock();
|
||||
~DCBlock();
|
||||
void clear();
|
||||
MY_FLOAT tick(MY_FLOAT sample);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,43 +0,0 @@
|
||||
/*******************************************/
|
||||
/* AllPass Interpolating Delay Line */
|
||||
/* Object by Perry R. Cook 1995-96. */
|
||||
/* Revised by Gary P. Scavone, 1999. */
|
||||
/* */
|
||||
/* This one uses a delay line of maximum */
|
||||
/* length specified on creation, and */
|
||||
/* interpolates fractional length using */
|
||||
/* an all-pass filter. This version is */
|
||||
/* more efficient for computing static */
|
||||
/* length delay lines (alpha and coeff */
|
||||
/* are computed only when the length */
|
||||
/* is set, there probably is a more */
|
||||
/* efficient computational form if alpha */
|
||||
/* is changed often (each sample)). */
|
||||
/* */
|
||||
/*******************************************/
|
||||
|
||||
|
||||
#if !defined(__DLineA_h)
|
||||
#define __DLineA_h
|
||||
|
||||
#include "Filter.h"
|
||||
|
||||
class DLineA : public Filter
|
||||
{
|
||||
protected:
|
||||
long inPoint;
|
||||
long outPoint;
|
||||
long length;
|
||||
MY_FLOAT alpha;
|
||||
MY_FLOAT coeff;
|
||||
MY_FLOAT lastIn;
|
||||
public:
|
||||
DLineA();
|
||||
DLineA(long max_length);
|
||||
~DLineA();
|
||||
void clear();
|
||||
void setDelay(MY_FLOAT length);
|
||||
MY_FLOAT tick(MY_FLOAT sample);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,45 +0,0 @@
|
||||
/*******************************************/
|
||||
/*
|
||||
Linearly Interpolating Delay Line
|
||||
Object by Perry R. Cook 1995-96.
|
||||
Added methods by Julius Smith, 2000.
|
||||
|
||||
This one uses a delay line of maximum
|
||||
length specified on creation, and
|
||||
linearly interpolates fractional
|
||||
length. It is designed to be more
|
||||
efficient if the delay length is not
|
||||
changed very often.
|
||||
*/
|
||||
/*******************************************/
|
||||
|
||||
#if !defined(__DLineL_h)
|
||||
#define __DLineL_h
|
||||
|
||||
#include "Filter.h"
|
||||
|
||||
class DLineL : public Filter
|
||||
{
|
||||
protected:
|
||||
long inPoint;
|
||||
long outPoint;
|
||||
long length;
|
||||
MY_FLOAT alpha;
|
||||
MY_FLOAT omAlpha;
|
||||
MY_FLOAT currentDelay;
|
||||
public:
|
||||
DLineL();
|
||||
DLineL(long max_length);
|
||||
~DLineL();
|
||||
void clear();
|
||||
void setDelay(MY_FLOAT length);
|
||||
MY_FLOAT delay(void);
|
||||
MY_FLOAT energy(void);
|
||||
long currentInPoint(void);
|
||||
long currentOutPoint(void);
|
||||
MY_FLOAT contentsAt(int n);
|
||||
MY_FLOAT contentsAtNowMinus(int n);
|
||||
MY_FLOAT tick(MY_FLOAT sample);
|
||||
};
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user