From 058c024194c4ce612d6365337b4ef0d7fad016b3 Mon Sep 17 00:00:00 2001 From: Robin Haberkorn Date: Fri, 14 Sep 2012 04:30:44 +0200 Subject: added package for ChucK programming language * doesn't work very well anyways. probably because of the lack of hardware float support, requiring software emulation (ChucK uses floats internally to represent sample data) * includes my own modifications as patches --- chuck/Makefile | 41 + ...andle-debug-flags-if-CHUCK_DEBUG-y-build-.patch | 158 +++ chuck/patches/0002-added-.gitignore.patch | 27 + ...ng-arbitrary-numbers-of-output-input-chan.patch | 91 ++ ...nstall-chuck-headers-for-building-Chugins.patch | 25 + .../0005-allow-declaring-string-references.patch | 27 + ...ing-types-consider-arrays-of-the-same-dep.patch | 32 + .../0007-prevent-unused-return-value-warning.patch | 35 + ...-chuck-is-linked-against-manually-built-l.patch | 25 + ...a-performing-various-optimizations-and-fi.patch | 308 ++++++ ...0010-LiSa-fixes-new-features-and-clean-up.patch | 1073 ++++++++++++++++++++ ...Sa-only-for-my-setup-no-need-to-submit-pa.patch | 25 + .../0012-allow-unary-minus-on-durations.patch | 43 + chuck/patches/0013-crosscompile.patch | 35 + 14 files changed, 1945 insertions(+) create mode 100644 chuck/Makefile create mode 100644 chuck/patches/0001-correctly-handle-debug-flags-if-CHUCK_DEBUG-y-build-.patch create mode 100644 chuck/patches/0002-added-.gitignore.patch create mode 100644 chuck/patches/0003-allow-opening-arbitrary-numbers-of-output-input-chan.patch create mode 100644 chuck/patches/0004-install-chuck-headers-for-building-Chugins.patch create mode 100644 chuck/patches/0005-allow-declaring-string-references.patch create mode 100644 chuck/patches/0006-when-comparing-types-consider-arrays-of-the-same-dep.patch create mode 100644 chuck/patches/0007-prevent-unused-return-value-warning.patch create mode 100644 chuck/patches/0008-ensure-that-chuck-is-linked-against-manually-built-l.patch create mode 100644 chuck/patches/0009-revised-LiSa-performing-various-optimizations-and-fi.patch create mode 100644 chuck/patches/0010-LiSa-fixes-new-features-and-clean-up.patch create mode 100644 chuck/patches/0011-use-mono-LiSa-only-for-my-setup-no-need-to-submit-pa.patch create mode 100644 chuck/patches/0012-allow-unary-minus-on-durations.patch create mode 100644 chuck/patches/0013-crosscompile.patch diff --git a/chuck/Makefile b/chuck/Makefile new file mode 100644 index 0000000..bd1993d --- /dev/null +++ b/chuck/Makefile @@ -0,0 +1,41 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=chuck +PKG_VERSION:=1.3.1.1 +PKG_RELEASE:=1 + +PKG_SOURCE:=chuck-$(PKG_VERSION).tgz +PKG_SOURCE_URL:=http://chuck.cs.princeton.edu/release/files +PKG_MD5SUM:=fb8e0c9f06a51dbec168982497bd2b07 + +PKG_BUILD_DIR=$(BUILD_DIR)/chuck-$(PKG_VERSION) + +include $(INCLUDE_DIR)/package.mk + +define Package/chuck + SECTION:=lang + CATEGORY:=Languages + DEPENDS:= +alsa-lib +libsndfile +libpthread + TITLE:=ChucK Programming Language + URL:=http://http://chuck.cs.princeton.edu/ +endef + +define Package/chuck/description +ChucK Programming Language +endef + +define Build/Configure +endef + +define Build/Compile + $(CONFIGURE_VARS) \ + $(MAKE) -C $(PKG_BUILD_DIR)/src \ + linux-alsa +endef + +define Package/chuck/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/chuck $(1)/usr/bin/ +endef + +$(eval $(call BuildPackage,chuck)) diff --git a/chuck/patches/0001-correctly-handle-debug-flags-if-CHUCK_DEBUG-y-build-.patch b/chuck/patches/0001-correctly-handle-debug-flags-if-CHUCK_DEBUG-y-build-.patch new file mode 100644 index 0000000..aab42a7 --- /dev/null +++ b/chuck/patches/0001-correctly-handle-debug-flags-if-CHUCK_DEBUG-y-build-.patch @@ -0,0 +1,158 @@ +From 1f8d875b53b36f6f0dd6599d70deea55eb17c19e Mon Sep 17 00:00:00 2001 +From: Robin Haberkorn +Date: Fri, 7 Sep 2012 17:11:42 +0200 +Subject: [PATCH 01/12] correctly handle debug flags (if CHUCK_DEBUG=y, build with -O0) + +did it for all makefiles so it can be submitted as a patch + * according to Makefile best-practices, such flags should normally not be touched my the build system but they should instead be +set by the package maintainer using the CFLAGS environment variable +--- + makefile | 2 +- + makefile.alsa | 2 +- + makefile.audicle | 6 ++++-- + makefile.jack | 2 +- + makefile.oss | 2 +- + makefile.rl | 6 ++++-- + makefile.skot | 2 +- + makefile.vicon | 6 ++++-- + makefile.win32 | 2 +- + 9 files changed, 18 insertions(+), 12 deletions(-) + +diff --git a/src/makefile b/src/makefile +index 8afb2db..aa87fe9 100644 +--- a/src/makefile ++++ b/src/makefile +@@ -33,7 +33,7 @@ CFLAGS+= -D__CHUCK_STAT_TRACK__ + endif + + ifneq ($(CHUCK_DEBUG),) +-CFLAGS+= -g ++CFLAGS+= -g -O0 + else + CFLAGS+= -O3 + endif +diff --git a/src/makefile.alsa b/src/makefile.alsa +index f267207..f66e3ac 100644 +--- a/src/makefile.alsa ++++ b/src/makefile.alsa +@@ -1,4 +1,4 @@ + +-CFLAGS+= -D__LINUX_ALSA__ -O3 -fno-strict-aliasing -D__CK_SNDFILE_NATIVE__ ++CFLAGS+= -D__LINUX_ALSA__ -fno-strict-aliasing -D__CK_SNDFILE_NATIVE__ + LDFLAGS+= -lasound -lstdc++ -ldl -lm -lsndfile -lpthread + +diff --git a/src/makefile.audicle b/src/makefile.audicle +index 7e26071..2cbe5cc 100644 +--- a/src/makefile.audicle ++++ b/src/makefile.audicle +@@ -3,12 +3,14 @@ CXX=gcc + LEX=flex + YACC=bison + INCLUDES= +-FLAGS=-D__MACOSX_CORE__ -D__CHUCK_STAT_TRACK__ -DAJAY -O3 -c ++FLAGS=-D__MACOSX_CORE__ -D__CHUCK_STAT_TRACK__ -DAJAY -c + LIBS=-framework CoreAudio -framework CoreMIDI -framework CoreFoundation -framework Carbon -framework IOKit -lstdc++ -lm + SF_OBJ=util_sndfile.o + + ifneq ($(CHUCK_DEBUG),) +-FLAGS+= -g ++FLAGS+= -g -O0 ++else ++FLAGS+= -O3 + endif + + ifneq ($(CHUCK_STRICT),) +diff --git a/src/makefile.jack b/src/makefile.jack +index 464c1b7..e09939a 100644 +--- a/src/makefile.jack ++++ b/src/makefile.jack +@@ -1,4 +1,4 @@ + +-CFLAGS+= -D__UNIX_JACK__ -D__LINUX_JACK__ -O3 -fno-strict-aliasing -D__CK_SNDFILE_NATIVE__ ++CFLAGS+= -D__UNIX_JACK__ -D__LINUX_JACK__ -fno-strict-aliasing -D__CK_SNDFILE_NATIVE__ + LDFLAGS+= -lasound -ljack -lstdc++ -ldl -lm -lsndfile -lpthread + +diff --git a/src/makefile.oss b/src/makefile.oss +index b25bb3a..f3edf10 100644 +--- a/src/makefile.oss ++++ b/src/makefile.oss +@@ -1,4 +1,4 @@ + +-CFLAGS+= -D__LINUX_OSS__ -O3 -fno-strict-aliasing -D__CK_SNDFILE_NATIVE__ ++CFLAGS+= -D__LINUX_OSS__ -fno-strict-aliasing -D__CK_SNDFILE_NATIVE__ + LDFLAGS+= -lpthread -lstdc++ -ldl -lm -lsndfile + +diff --git a/src/makefile.rl b/src/makefile.rl +index cc12f75..47bf543 100644 +--- a/src/makefile.rl ++++ b/src/makefile.rl +@@ -4,7 +4,7 @@ CXX_LINK=g++ + LEX=flex + YACC=bison + INCLUDES= +-FLAGS=-D__MACOSX_CORE__ -D__USE_READLINE__ -O3 -c ++FLAGS=-D__MACOSX_CORE__ -D__USE_READLINE__ -c + LIBS=-framework CoreAudio -framework CoreMIDI -framework CoreFoundation -lstdc++ -lm -lreadline + SF_OBJ=util_sndfile.o + +@@ -13,7 +13,9 @@ FLAGS+= -D__CHUCK_STAT_TRACK__ + endif + + ifneq ($(CHUCK_DEBUG),) +-FLAGS+= -g ++FLAGS+= -g -O0 ++else ++FLAGS+= -O3 + endif + + ifneq ($(CHUCK_STRICT),) +diff --git a/src/makefile.skot b/src/makefile.skot +index 23ac594..d1b7383 100644 +--- a/src/makefile.skot ++++ b/src/makefile.skot +@@ -16,7 +16,7 @@ FLAGS+= -D__CHUCK_STAT_TRACK__ + endif + + ifneq ($(CHUCK_DEBUG),) +-FLAGS+= -g ++FLAGS+= -g -O0 + else + FLAGS+= -O3 + endif +diff --git a/src/makefile.vicon b/src/makefile.vicon +index cf8bf97..d0b898c 100644 +--- a/src/makefile.vicon ++++ b/src/makefile.vicon +@@ -3,12 +3,14 @@ CXX=gcc + LEX=flex + YACC=bison + INCLUDES=-I/usr/include/directx/ +-FLAGS=-D__WINDOWS_DS__ -D__WINDOWS_PTHREAD__ -DAJAY $(INCLUDES) -O3 -c ++FLAGS=-D__WINDOWS_DS__ -D__WINDOWS_PTHREAD__ -DAJAY $(INCLUDES) -c + LIBS=-ldsound -ldxguid -lwinmm -lstdc++ -lm + SF_OBJ=util_sndfile.o + + ifneq ($(CHUCK_DEBUG),) +-FLAGS+= -g ++FLAGS+= -g -O0 ++else ++FLAGS+= -O3 + endif + + ifneq ($(CHUCK_STRICT),) +diff --git a/src/makefile.win32 b/src/makefile.win32 +index 148c81f..2f64c5d 100644 +--- a/src/makefile.win32 ++++ b/src/makefile.win32 +@@ -10,7 +10,7 @@ LDFLAGS=-ldsound -ldinput -ldxguid -lwinmm -lstdc++ -lm -lole32 + CSRCS+= util_sndfile.c + + ifneq ($(CHUCK_DEBUG),) +-CFLAGS+= -g ++CFLAGS+= -g -O0 + else + CFLAGS+= -O3 + endif +-- +1.7.1 + diff --git a/chuck/patches/0002-added-.gitignore.patch b/chuck/patches/0002-added-.gitignore.patch new file mode 100644 index 0000000..15e833d --- /dev/null +++ b/chuck/patches/0002-added-.gitignore.patch @@ -0,0 +1,27 @@ +From ced8afbafed3688b771a4a773c4a11bb72371a0b Mon Sep 17 00:00:00 2001 +From: Robin Haberkorn +Date: Fri, 7 Sep 2012 17:14:29 +0200 +Subject: [PATCH 02/12] added .gitignore + +--- + .gitignore | 8 ++++++++ + 1 files changed, 8 insertions(+), 0 deletions(-) + create mode 100644 .gitignore + +diff --git a/src/.gitignore b/src/.gitignore +new file mode 100644 +index 0000000..ffe77af +--- /dev/null ++++ b/src/.gitignore +@@ -0,0 +1,8 @@ ++*.o ++*.d ++chuck ++ ++chuck.output ++chuck.tab.c ++chuck.tab.h ++chuck.yy.c +-- +1.7.1 + diff --git a/chuck/patches/0003-allow-opening-arbitrary-numbers-of-output-input-chan.patch b/chuck/patches/0003-allow-opening-arbitrary-numbers-of-output-input-chan.patch new file mode 100644 index 0000000..101a499 --- /dev/null +++ b/chuck/patches/0003-allow-opening-arbitrary-numbers-of-output-input-chan.patch @@ -0,0 +1,91 @@ +From 20d64be2aa8ed346a337a78a68423c4a769c32ea Mon Sep 17 00:00:00 2001 +From: Robin Haberkorn +Date: Fri, 7 Sep 2012 17:15:52 +0200 +Subject: [PATCH 03/12] allow opening arbitrary numbers of output/input channels (jack backend) + +also don't connect them automatically (done by my Jack patchbay) +--- + RtAudio/RtAudio.cpp | 6 ++++++ + digiio_rtaudio.cpp | 4 ++++ + 2 files changed, 10 insertions(+), 0 deletions(-) + +diff --git a/src/RtAudio/RtAudio.cpp b/src/RtAudio/RtAudio.cpp +index 1dec41b..5aa2b8a 100644 +--- a/src/RtAudio/RtAudio.cpp ++++ b/src/RtAudio/RtAudio.cpp +@@ -2095,9 +2095,12 @@ bool RtApiJack :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne + + // Count the available ports containing the client name as device + // channels. Jack "input ports" equal RtAudio output channels. ++#if 0 + unsigned int nChannels = 0; ++#endif + unsigned long flag = JackPortIsInput; + if ( mode == INPUT ) flag = JackPortIsOutput; ++#if 0 + ports = jack_get_ports( client, deviceName.c_str(), NULL, flag ); + if ( ports ) { + while ( ports[ nChannels ] ) nChannels++; +@@ -2110,6 +2113,7 @@ bool RtApiJack :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne + errorText_ = errorStream_.str(); + return FAILURE; + } ++#endif + + // Check the jack server sample rate. + unsigned int jackRate = jack_get_sample_rate( client ); +@@ -2352,6 +2356,7 @@ void RtApiJack :: startStream( void ) + goto unlock; + } + ++#if 0 + const char **ports; + + // Get the list of available ports. +@@ -2400,6 +2405,7 @@ void RtApiJack :: startStream( void ) + } + free(ports); + } ++#endif + + handle->drainCounter = 0; + handle->internalDrain = false; +diff --git a/src/digiio_rtaudio.cpp b/src/digiio_rtaudio.cpp +index d509181..c0bd35c 100644 +--- a/src/digiio_rtaudio.cpp ++++ b/src/digiio_rtaudio.cpp +@@ -511,6 +511,7 @@ BOOL__ Digitalio::initialize( DWORD__ num_dac_channels, + { + // get the default + m_dac_n = m_rtaudio->getDefaultOutputDevice(); ++#if 0 + + // ensure correct channel count if default device is requested + RtAudio::DeviceInfo device_info = m_rtaudio->getDeviceInfo(m_dac_n); +@@ -538,6 +539,7 @@ BOOL__ Digitalio::initialize( DWORD__ num_dac_channels, + return m_init = FALSE; + } + } ++#endif + } + else + { +@@ -551,6 +553,7 @@ BOOL__ Digitalio::initialize( DWORD__ num_dac_channels, + if( m_adc_n == 0 ) + { + m_adc_n = m_rtaudio->getDefaultInputDevice(); ++#if 0 + + // ensure correct channel count if default device is requested + RtAudio::DeviceInfo device_info = m_rtaudio->getDeviceInfo(m_adc_n); +@@ -577,6 +580,7 @@ BOOL__ Digitalio::initialize( DWORD__ num_dac_channels, + return m_init = FALSE; + } + } ++#endif + } + else + { +-- +1.7.1 + diff --git a/chuck/patches/0004-install-chuck-headers-for-building-Chugins.patch b/chuck/patches/0004-install-chuck-headers-for-building-Chugins.patch new file mode 100644 index 0000000..69be6f9 --- /dev/null +++ b/chuck/patches/0004-install-chuck-headers-for-building-Chugins.patch @@ -0,0 +1,25 @@ +From 58a8dbd6ce4e548407c92be1dd392e7f437e3862 Mon Sep 17 00:00:00 2001 +From: Robin Haberkorn +Date: Fri, 7 Sep 2012 17:17:56 +0200 +Subject: [PATCH 04/12] install chuck headers (for building Chugins) + +--- + makefile | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +diff --git a/src/makefile b/src/makefile +index aa87fe9..077b879 100644 +--- a/src/makefile ++++ b/src/makefile +@@ -9,6 +9,8 @@ current: + install: + cp $(wildcard chuck chuck.exe) $(DESTDIR)/ + chmod 755 $(DESTDIR)/$(wildcard chuck chuck.exe) ++ mkdir -p /usr/include/chuck ++ cp *.h /usr/include/chuck + + ifneq ($(CK_TARGET),) + .DEFAULT_GOAL:=$(CK_TARGET) +-- +1.7.1 + diff --git a/chuck/patches/0005-allow-declaring-string-references.patch b/chuck/patches/0005-allow-declaring-string-references.patch new file mode 100644 index 0000000..3b2ab36 --- /dev/null +++ b/chuck/patches/0005-allow-declaring-string-references.patch @@ -0,0 +1,27 @@ +From 9a84ba63d847024bb045d7a6c5362b63310071a8 Mon Sep 17 00:00:00 2001 +From: Robin Haberkorn +Date: Fri, 7 Sep 2012 17:20:15 +0200 +Subject: [PATCH 05/12] allow declaring "string" references + +tested, didn't experience any issues +--- + chuck_scan.cpp | 3 ++- + 1 files changed, 2 insertions(+), 1 deletions(-) + +diff --git a/src/chuck_scan.cpp b/src/chuck_scan.cpp +index 916b579..b85b373 100644 +--- a/src/chuck_scan.cpp ++++ b/src/chuck_scan.cpp +@@ -2173,7 +2173,8 @@ t_CKBOOL type_engine_scan2_exp_decl( Chuck_Env * env, a_Exp_Decl decl ) + } + + // primitive +- if( (isprim( type ) || isa( type, &t_string )) && decl->type->ref ) // TODO: string ++ if( (isprim( type ) /*|| isa( type, &t_string )*/) ++ && decl->type->ref ) // TODO: string + { + EM_error2( decl->linepos, + "cannot declare references (@) of primitive type '%s'...", +-- +1.7.1 + diff --git a/chuck/patches/0006-when-comparing-types-consider-arrays-of-the-same-dep.patch b/chuck/patches/0006-when-comparing-types-consider-arrays-of-the-same-dep.patch new file mode 100644 index 0000000..f0f8a45 --- /dev/null +++ b/chuck/patches/0006-when-comparing-types-consider-arrays-of-the-same-dep.patch @@ -0,0 +1,32 @@ +From d143313380e55196b8d34500047ed52b6930c72d Mon Sep 17 00:00:00 2001 +From: Robin Haberkorn +Date: Fri, 7 Sep 2012 17:21:58 +0200 +Subject: [PATCH 06/12] when comparing types consider arrays of the same depth and descended type as compatible + +--- + chuck_type.cpp | 9 +++++++++ + 1 files changed, 9 insertions(+), 0 deletions(-) + +diff --git a/src/chuck_type.cpp b/src/chuck_type.cpp +index c1aa326..4f817b8 100644 +--- a/src/chuck_type.cpp ++++ b/src/chuck_type.cpp +@@ -4091,6 +4091,15 @@ t_CKBOOL operator <=( const Chuck_Type & lhs, const Chuck_Type & rhs ) + curr = curr->parent; + } + ++ // if both are arrays of the same depth ++ if( lhs.array_type && rhs.array_type && ++ lhs.array_depth == rhs.array_depth ) ++ { ++ // if lhs array type is a child of rhs array type ++ for( curr = lhs.array_type->parent; curr; curr = curr->parent ) ++ if( *curr == *rhs.array_type ) return TRUE; ++ } ++ + // if lhs is null and rhs is a object + if( lhs == t_null && (rhs <= t_object) ) return TRUE; + +-- +1.7.1 + diff --git a/chuck/patches/0007-prevent-unused-return-value-warning.patch b/chuck/patches/0007-prevent-unused-return-value-warning.patch new file mode 100644 index 0000000..dd5e94d --- /dev/null +++ b/chuck/patches/0007-prevent-unused-return-value-warning.patch @@ -0,0 +1,35 @@ +From 006521d0799aecc18f83b9fa22604169145c64ed Mon Sep 17 00:00:00 2001 +From: Robin Haberkorn +Date: Fri, 7 Sep 2012 17:43:56 +0200 +Subject: [PATCH 07/12] prevent unused-return-value warning + +ordinarily, the return value of every fseek/fwrite/fread should be checked +--- + ugen_stk.cpp | 4 +++- + 1 files changed, 3 insertions(+), 1 deletions(-) + +diff --git a/src/ugen_stk.cpp b/src/ugen_stk.cpp +index f63eb6e..3a92ca2 100644 +--- a/src/ugen_stk.cpp ++++ b/src/ugen_stk.cpp +@@ -17333,7 +17333,8 @@ void WvOut :: closeMatFile( void ) + + SINT32 headsize, temp; + fseek(fd, 132, SEEK_SET); // jump to header size +- fread(&headsize, 4, 1, fd); ++ if( fread(&headsize, 4, 1, fd) < 4 ) goto close; ++ + temp = headsize; + headsize += (SINT32) (totalCount * 8 * channels); + fseek(fd, 132, SEEK_SET); +@@ -17344,6 +17345,7 @@ void WvOut :: closeMatFile( void ) + temp = totalCount * 8 * channels; + fwrite(&temp, 4, 1, fd); + ++ close: + fclose(fd); + } + +-- +1.7.1 + diff --git a/chuck/patches/0008-ensure-that-chuck-is-linked-against-manually-built-l.patch b/chuck/patches/0008-ensure-that-chuck-is-linked-against-manually-built-l.patch new file mode 100644 index 0000000..6487149 --- /dev/null +++ b/chuck/patches/0008-ensure-that-chuck-is-linked-against-manually-built-l.patch @@ -0,0 +1,25 @@ +From 713870b2d28ad236481341c5714b325fa82fa038 Mon Sep 17 00:00:00 2001 +From: Robin Haberkorn +Date: Fri, 7 Sep 2012 20:43:43 +0200 +Subject: [PATCH 08/12] ensure that chuck is linked against manually built libjack + +previously the manually built libjack was found at runtime but not linked to at compile-time +--- + makefile.jack | 3 +++ + 1 files changed, 3 insertions(+), 0 deletions(-) + +diff --git a/src/makefile.jack b/src/makefile.jack +index e09939a..a64ef3b 100644 +--- a/src/makefile.jack ++++ b/src/makefile.jack +@@ -1,4 +1,7 @@ + ++CFLAGS+= -I/usr/local/include ++LDFLAGS+= -L/usr/local/lib ++ + CFLAGS+= -D__UNIX_JACK__ -D__LINUX_JACK__ -fno-strict-aliasing -D__CK_SNDFILE_NATIVE__ + LDFLAGS+= -lasound -ljack -lstdc++ -ldl -lm -lsndfile -lpthread + +-- +1.7.1 + diff --git a/chuck/patches/0009-revised-LiSa-performing-various-optimizations-and-fi.patch b/chuck/patches/0009-revised-LiSa-performing-various-optimizations-and-fi.patch new file mode 100644 index 0000000..7fcf507 --- /dev/null +++ b/chuck/patches/0009-revised-LiSa-performing-various-optimizations-and-fi.patch @@ -0,0 +1,308 @@ +From dad4ab47c2b008f6cf946e268d8b49702e017af3 Mon Sep 17 00:00:00 2001 +From: Robin Haberkorn +Date: Sat, 8 Sep 2012 02:43:38 +0200 +Subject: [PATCH 09/12] revised LiSa, performing various optimizations and fixing a lot of bugs introduced with v1.3.0.0 + + * properly support multi-channels by using tickf. fixes expressions like "LiSa => Gain g" which are now properly chucked + * prevent unnecessary copying of output samples + * prevent generating output samples if buffer is unitialized (size unset) + * use LiSa_channels macro instead of class attribute - should allow the compiler to perform loop unrolling in the time-critical tick/tickf functions + * allow mono LiSa as a compile time option (#define LiSa_channels 1). useful for increasing performance where absolutely necessary. + * initialize all voices' channel gain with 1 instead of setting the gain to 0.707 for the first two channels (resulted in lower gain for existing pre-v1.3.0.0 LiSa patches) + * fixed memleak on LiSa destruction and buffer resize + * initialize newly allocated buffers (don't know why this didn't cause any trouble) + * fixed tracking modes 1 and 2 which were completely broken beginning with v1.3.0.0!!!! +--- + ugen_xxx.cpp | 154 ++++++++++++++++++++++++++++++---------------------------- + ugen_xxx.h | 1 + + 2 files changed, 81 insertions(+), 74 deletions(-) + +diff --git a/src/ugen_xxx.cpp b/src/ugen_xxx.cpp +index c634473..dfb1bca 100644 +--- a/src/ugen_xxx.cpp ++++ b/src/ugen_xxx.cpp +@@ -857,17 +857,15 @@ error: + } + + +- ++#define LiSa_channels 8 //max channels for multichannel LiSa + + // LiSa (live sampling data offset) +-//static t_CKUINT LiSaBasic_offset_data = 0; + static t_CKUINT LiSaMulti_offset_data = 0; + + //----------------------------------------------------------------------------- + // name: lisa_query() + // desc: ... + //----------------------------------------------------------------------------- +-#define LiSa_channels 8 //max channels for multichannel LiSa + DLL_QUERY lisa_query( Chuck_DL_Query * QUERY ) + { + Chuck_Env * env = Chuck_Env::instance(); +@@ -878,21 +876,20 @@ DLL_QUERY lisa_query( Chuck_DL_Query * QUERY ) + // - probably don't need the others anymore.... + // author: Dan Trueman (dan /at/ music.princeton.edu) + //--------------------------------------------------------------------- +- +- +- if( !type_engine_import_ugen_begin( env, "LiSa", "UGen_Stereo", env->global(), ++ ++#if LiSa_channels == 1 ++ if( !type_engine_import_ugen_begin( env, "LiSa", "UGen", env->global(), + LiSaMulti_ctor, LiSaMulti_dtor, +- LiSaMulti_tick, LiSaMulti_pmsg, 1, LiSa_channels )) ++ LiSaMulti_tick, LiSaMulti_pmsg )) + return FALSE; +- +- +- /* +- if( !type_engine_import_ugen_begin( env, "LiSa", "UGen", env->global(), ++#else /* LiSa_channels > 1 */ ++ if( !type_engine_import_ugen_begin( env, "LiSa", "UGen_Stereo", env->global(), + LiSaMulti_ctor, LiSaMulti_dtor, +- LiSaMulti_tick, LiSaMulti_pmsg)) ++ NULL, LiSaMulti_tickf, ++ LiSaMulti_pmsg, 1, LiSa_channels )) + return FALSE; +- */ +- ++#endif ++ + // set/get buffer size + func = make_new_mfun( "dur", "duration", LiSaMulti_size ); + func->add_arg( "dur", "val" ); +@@ -3556,7 +3553,6 @@ LiSa updates/fixes: + struct LiSaMulti_data + { + SAMPLE * mdata; +- SAMPLE * outsamples; //samples by channel to send out + t_CKINT mdata_len; + t_CKINT maxvoices; + t_CKINT loop_start[LiSa_MAXVOICES], loop_end[LiSa_MAXVOICES], loop_end_rec; +@@ -3575,18 +3571,24 @@ struct LiSaMulti_data + t_CKBOOL rampup[LiSa_MAXVOICES], rampdown[LiSa_MAXVOICES]; + + t_CKINT track; +- +- t_CKINT num_chans; ++ ++ ~LiSaMulti_data() ++ { ++ SAFE_DELETE( mdata ); ++ } + + // allocate memory, length in samples + inline int buffer_alloc(t_CKINT length) + { +- mdata = (SAMPLE *)malloc((length + 1) * sizeof(SAMPLE)); //extra sample for safety.... ++ SAFE_DELETE( mdata ); ++ ++ mdata = new SAMPLE[length + 1]; //extra sample for safety.... + if(!mdata) { + fprintf(stderr, "LiSaBasic: unable to allocate memory!\n"); + return false; + } +- ++ clear_buf(); ++ + mdata_len = length; + maxvoices = 10; // default; user can set + rec_ramplen = 0.; +@@ -3614,11 +3616,9 @@ struct LiSaMulti_data + rampup_len_inv[i] = rampdown_len_inv[i] = 1.; + rampctr[i] = 0.; + +- for(t_CKINT j=2; j2 voices (like 6 channels!) +- inline SAMPLE * tick_multi( SAMPLE in) ++ inline void tick_multi(SAMPLE in, SAMPLE *out) + { ++ for( t_CKINT i = 0; i < LiSa_channels; i++ ) out[i] = SILENCE; + +- SAMPLE tempsample = 0.; ++ switch( track ) ++ { ++ case 0: ++ recordSamp( in ); ++ for( t_CKINT i = 0; i < maxvoices; i++ ) ++ { ++ if( play[i] ) ++ { ++ SAMPLE tempsample = getNextSamp( i ); ++ for( t_CKINT j = 0; j < LiSa_channels; j++ ) ++ out[j] += tempsample * channelGain[i][j]; //channelGain should return gain for voice i in channel j ++ } ++ } ++ break; + +- for(t_CKINT i=0;inum_chans = ugen->m_multi_chan_size; +- //fprintf(stderr, "LiSa: number of channels = %d\n", f->num_chans); +- f->outsamples = new SAMPLE[f->num_chans]; +- memset( f->outsamples, 0, (f->num_chans)*sizeof(SAMPLE) ); +- + OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data) = (t_CKUINT)f; +- +- +- + } + + +@@ -3941,18 +3941,24 @@ CK_DLL_DTOR( LiSaMulti_dtor ) + //----------------------------------------------------------------------------- + CK_DLL_TICK( LiSaMulti_tick ) + { +- Chuck_UGen * ugen = (Chuck_UGen *)SELF; +- + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); +- SAMPLE * temp_out_samples = d->tick_multi( in ); +- +- for( t_CKUINT i = 0; i < ugen->m_multi_chan_size; i++ ) +- ugen->m_multi_chan[i]->m_sum = ugen->m_multi_chan[i]->m_current = temp_out_samples[i]; //yay this works! +- //out[i] = temp_out_samples[i]; +- ++ if( !d->mdata ) return FALSE; ++ ++ d->tick_multi( in, out ); ++ + return TRUE; + } + ++CK_DLL_TICKF( LiSaMulti_tickf ) ++{ ++ LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); ++ if( !d->mdata ) return FALSE; ++ ++ for( t_CKUINT frame = 0; frame < nframes; frame++ ) ++ d->tick_multi( in[frame], out + frame*LiSa_channels ); ++ ++ return TRUE; ++} + + //----------------------------------------------------------------------------- + // name: LiSaMulti_size() +@@ -4462,14 +4468,14 @@ CK_DLL_CTRL( LiSaMulti_ctrl_voicepan ) + + t_CKINT i; + +- for(i=0; inum_chans; i++) d->channelGain[which][i] = 0.; ++ for(i=0; ichannelGain[which][i] = 0.; + +- for(i=0; inum_chans; i++) { ++ for(i=0; ivoicePan[which]; + //fprintf(stderr, "panTrunc = %d, panFloat = %f, i = %d\n", panTrunc, d->voicePan[which], i); + if(i == panTrunc) { + d->channelGain[which][i] = 1. - ( d->voicePan[which] - (t_CKFLOAT)i ); +- if(i == d->num_chans - 1) { ++ if(i == LiSa_channels - 1) { + d->channelGain[which][0] = 1. - d->channelGain[which][i]; + d->channelGain[which][0] = sqrt(d->channelGain[which][0]); + } +@@ -4510,14 +4516,14 @@ CK_DLL_CTRL( LiSaMulti_ctrl_voicepan0 ) + + t_CKINT i; + +- for(i=0; inum_chans; i++) d->channelGain[which][i] = 0.; ++ for(i=0; ichannelGain[which][i] = 0.; + +- for(i=0; inum_chans; i++) { ++ for(i=0; ivoicePan[which]; + //fprintf(stderr, "panTrunc = %d, panFloat = %f, i = %d\n", panTrunc, d->voicePan[which], i); + if(i == panTrunc) { + d->channelGain[which][i] = 1. - ( d->voicePan[which] - (t_CKFLOAT)i ); +- if(i == d->num_chans - 1) { ++ if(i == LiSa_channels - 1) { + d->channelGain[which][0] = 1. - d->channelGain[which][i]; + d->channelGain[which][0] = sqrt(d->channelGain[which][0]); + } +diff --git a/src/ugen_xxx.h b/src/ugen_xxx.h +index 8e18af6..e0663ee 100644 +--- a/src/ugen_xxx.h ++++ b/src/ugen_xxx.h +@@ -189,6 +189,7 @@ CK_DLL_CGET( sndbuf_cget_valueAt ); + CK_DLL_CTOR( LiSaMulti_ctor ); + CK_DLL_DTOR( LiSaMulti_dtor ); + CK_DLL_TICK( LiSaMulti_tick ); ++CK_DLL_TICKF( LiSaMulti_tickf ); + CK_DLL_PMSG( LiSaMulti_pmsg ); + CK_DLL_CTRL( LiSaMulti_size ); + CK_DLL_CTRL( LiSaMulti_cget_size ); +-- +1.7.1 + diff --git a/chuck/patches/0010-LiSa-fixes-new-features-and-clean-up.patch b/chuck/patches/0010-LiSa-fixes-new-features-and-clean-up.patch new file mode 100644 index 0000000..3adc120 --- /dev/null +++ b/chuck/patches/0010-LiSa-fixes-new-features-and-clean-up.patch @@ -0,0 +1,1073 @@ +From d77b79446964fca0149bbaadc0e8354d92d6fafa Mon Sep 17 00:00:00 2001 +From: Robin Haberkorn +Date: Thu, 13 Sep 2012 01:47:37 +0200 +Subject: [PATCH 10/12] LiSa fixes, new features and clean up + + * always check whether buffer is allocated (size set) if necessary fixing easy to provoke segfaults + * when configuring check values for validity (e.g. lisa.track()) + * for every configuration parameter accepting a duration: support negative durations (translate to "from the end of the buffer") and durations longer than the buffer (translate to "from the beginning of the buffer") + * might be arbitrarily large + * tracking mode 1/2: accept input data < 0, or longer than buffer + * tracking mode 1: fixed playing whithout loop-playing (and arbitrarily set loop points) + * tracking mode 2: use all voices + * support loop start > loop end: loop over end of buffer/beginning of buffer +etc. +--- + ugen_xxx.cpp | 668 ++++++++++++++++++++++++++++++++++------------------------ + 1 files changed, 391 insertions(+), 277 deletions(-) + +diff --git a/src/ugen_xxx.cpp b/src/ugen_xxx.cpp +index dfb1bca..17e39d6 100644 +--- a/src/ugen_xxx.cpp ++++ b/src/ugen_xxx.cpp +@@ -51,6 +51,7 @@ + #include "chuck_vm.h" + #include "chuck_globals.h" + #include "chuck_instr.h" ++#include "chuck_errmsg.h" + + #include + using namespace std; +@@ -3556,6 +3557,7 @@ struct LiSaMulti_data + t_CKINT mdata_len; + t_CKINT maxvoices; + t_CKINT loop_start[LiSa_MAXVOICES], loop_end[LiSa_MAXVOICES], loop_end_rec; ++ t_CKINT loop_len[LiSa_MAXVOICES]; // caching of frequently used values + t_CKINT rindex; // record and play indices + t_CKBOOL record, looprec, loopplay[LiSa_MAXVOICES], reset, append, play[LiSa_MAXVOICES], bi[LiSa_MAXVOICES]; + t_CKFLOAT coeff; // feedback coeff +@@ -3577,51 +3579,118 @@ struct LiSaMulti_data + SAFE_DELETE( mdata ); + } + ++ inline t_CKDOUBLE normalize_index(t_CKDOUBLE index) ++ { ++ while( index < 0 ) index += mdata_len; ++ while( index >= mdata_len ) index -= mdata_len; ++ ++ return index; ++ } ++ ++ inline t_CKINT get_safe_voice(t_CKINT voice) ++ { ++ if (voice < 0 || voice >= maxvoices) ++ { ++ EM_error2( 0, "LiSa: Requesting invalid voice number %d (MAXVOICES=%d)", ++ voice, LiSa_MAXVOICES); ++ return 0; ++ } ++ ++ return voice; ++ } ++ ++ void update_cache(t_CKINT which = 0) ++ { ++ if( loop_start[which] <= loop_end[which] ) ++ loop_len[which] = loop_end[which] - loop_start[which]; ++ else /* loop_start[which] > loop_end[which] */ ++ loop_len[which] = mdata_len - loop_start[which] + loop_end[which]; ++ ++ loop_len[which]++; ++ } ++ ++ inline t_CKDUR set_loop_start(t_CKDUR v, t_CKINT which = 0) ++ { ++ if( !mdata ) ++ { ++ EM_error2( 0, "LiSa: Trying to set loop start on uninitialized buffer; ignoring" ); ++ return 0.; ++ } ++ ++ loop_start[which] = (t_CKINT)normalize_index( (t_CKDOUBLE)v ); ++ update_cache( which ); ++ ++ return (t_CKDUR)loop_start[which]; ++ } ++ inline t_CKDUR set_loop_end(t_CKDUR v, t_CKINT which = 0) ++ { ++ if( !mdata ) ++ { ++ EM_error2( 0, "LiSa: Trying to set loop end on uninitialized buffer; ignoring" ); ++ return 0.; ++ } ++ ++ loop_end[which] = (t_CKINT)normalize_index( (t_CKDOUBLE)v ); ++ update_cache( which ); ++ ++ return (t_CKDUR)loop_end[which]; ++ } ++ + // allocate memory, length in samples +- inline int buffer_alloc(t_CKINT length) ++ inline t_CKDUR buffer_alloc(t_CKDUR length) + { ++ if( (t_CKINT)length > LiSa_MAXBUFSIZE ) ++ { ++ EM_error2( 0, "LiSa: Buffer size request too large, resizing to %d", ++ LiSa_MAXBUFSIZE ); ++ length = LiSa_MAXBUFSIZE; ++ } ++ + SAFE_DELETE( mdata ); ++ mdata_len = 0; + +- mdata = new SAMPLE[length + 1]; //extra sample for safety.... +- if(!mdata) { +- fprintf(stderr, "LiSaBasic: unable to allocate memory!\n"); +- return false; ++ mdata = new SAMPLE[(t_CKINT)length]; ++ if( !mdata ) ++ { ++ EM_error2( 0, "LiSa: Unable to allocate memory!"); ++ return 0.; + } ++ ++ mdata_len = (t_CKINT)length; + clear_buf(); + +- mdata_len = length; + maxvoices = 10; // default; user can set + rec_ramplen = 0.; + rec_ramplen_inv = 1.; +- ++ + track = 0; +- +- for (t_CKINT i=0; i < LiSa_MAXVOICES; i++) { ++ ++ for( t_CKINT i = 0; i < LiSa_MAXVOICES; i++ ) ++ { + loop_start[i] = 0; +- //loop_end[i] = length - 1; //no idea why i had this +- loop_end[i] = length; +- loop_end_rec = length; +- ++ loop_end[i] = mdata_len - 1; ++ loop_end_rec = mdata_len - 1; ++ + pindex[i] = rindex = 0; + play[i] = record = bi[i] = false; + looprec = loopplay[i] = true; + coeff = 0.; + p_inc[i] = 1.; +- voiceGain[i] = 1.; +- voicePan[i] = 0.5; +- ++ voiceGain[i] = 1.; ++ voicePan[i] = 0.5; ++ + // ramp stuff + rampup[i] = rampdown[i] = false; + rampup_len[i] = rampdown_len[i] = 0.; + rampup_len_inv[i] = rampdown_len_inv[i] = 1.; + rampctr[i] = 0.; +- +- for(t_CKINT j=0; j= loop_start[which] && where <= loop_end[which]; ++ else ++ return where >= loop_start[which] || where <= loop_end[which]; ++ } ++ + // grab a sample from the buffer, with linear interpolation (add prc's SINC interp later) + // increment play index +- // which specifies voice number +- inline SAMPLE getNextSamp(t_CKINT which) ++ // which specifies voice number ++ inline SAMPLE getNextSamp(t_CKINT which = 0) + { + // constrain +- if(loopplay[which]) { +- if(bi[which]) { // change direction if bidirectional mode +- if(pindex[which] >= loop_end[which] || pindex[which] < loop_start[which]) { //should be >= ? +- pindex[which] -= p_inc[which]; +- p_inc[which] = -p_inc[which]; +- } ++ if( loopplay[which] ) ++ { ++ bool wasOutsideLoop = false; ++ ++ if ( loop_start[which] == loop_end[which] ) ++ { ++ pindex[which] = loop_start[which]; ++ } ++ else if ( loop_start[which] < loop_end[which] ) ++ { ++ wasOutsideLoop = pindex[which] < loop_start[which] || ++ pindex[which] > loop_end[which]; ++ ++ while( pindex[which] > loop_end[which] ) ++ pindex[which] -= loop_len[which]; ++ while( pindex[which] < loop_start[which] ) ++ pindex[which] += loop_len[which]; + } +- if( loop_start[which] == loop_end[which] ) pindex[which] = loop_start[which]; //catch this condition to avoid infinite while loops +- else { +- while(pindex[which] >= loop_end[which]) pindex[which] = loop_start[which] + (pindex[which] - loop_end[which]); //again, >=? +- while(pindex[which] < loop_start[which]) pindex[which] = loop_end[which] - (loop_start[which] - pindex[which]); +- } +- +- } else if(pindex[which] >= mdata_len || pindex[which] < 0) { //should be >=, no? +- play[which] = 0; ++ else /* loop_start[which] > loop_end[which] */ ++ { ++ pindex[which] = normalize_index( pindex[which] ); ++ ++ wasOutsideLoop = pindex[which] < loop_start[which] && ++ pindex[which] > loop_end[which]; ++ ++ if( wasOutsideLoop ) ++ { ++ if( p_inc[which] > 0 ) ++ { ++ /* after loop end */ ++ while( pindex[which] > 0 ) ++ pindex[which] -= loop_len[which]; ++ pindex[which] += mdata_len; ++ } ++ else ++ { ++ /* before loop start */ ++ while( pindex[which] < mdata_len ) ++ pindex[which] += loop_len[which]; ++ pindex[which] -= mdata_len; ++ } ++ } ++ } ++ ++ // change direction if bidirectional mode ++ if( bi[which] && wasOutsideLoop ) p_inc[which] *= -1; ++ } ++ /* !loopplay[which] */ ++ else if( pindex[which] >= mdata_len || pindex[which] < 0 ) ++ { ++ play[which] = false; + //fprintf(stderr, "turning voice %d off!\n", which); +- return (SAMPLE) 0.; ++ return SILENCE; + } +- ++ + // interp +- t_CKINT whereTrunc = (t_CKINT) pindex[which]; ++ t_CKINT whereTrunc = (t_CKINT)pindex[which]; + t_CKDOUBLE whereFrac = pindex[which] - (t_CKDOUBLE)whereTrunc; + t_CKINT whereNext = whereTrunc + 1; +- +- if (loopplay[which]) { +- if((whereNext) >= loop_end[which]) { +- whereNext = loop_start[which]; +- } +- if((whereTrunc) >= loop_end[which]) { +- whereTrunc = loop_start[which]; +- } +- } else { +- if((whereTrunc) >= mdata_len) { +- whereTrunc = mdata_len - 1; //should correct this, in case we've overshot by more than 1 sample +- whereNext = 0; +- } +- if((whereNext) >= mdata_len) { +- whereNext = 0; +- } +- } +- ++ ++ if( whereNext == mdata_len ) whereNext = 0; ++ ++ if( loopplay[which] && !isInLoop( whereNext, which ) ) ++ whereNext = loop_start[which]; ++ + pindex[which] += p_inc[which]; +- ++ + t_CKDOUBLE outsample; +- outsample = (t_CKDOUBLE)mdata[whereTrunc] + (t_CKDOUBLE)(mdata[whereNext] - mdata[whereTrunc]) * whereFrac; +- ++ outsample = (t_CKDOUBLE)mdata[whereTrunc] + ++ (t_CKDOUBLE)(mdata[whereNext] - mdata[whereTrunc]) * whereFrac; ++ + // ramp stuff +- if(rampup[which]) { ++ if( rampup[which] ) ++ { + outsample *= rampctr[which]++ * rampup_len_inv[which]; //remove divide +- if(rampctr[which] >= rampup_len[which]) rampup[which] = false; ++ rampup[which] = rampctr[which] < rampup_len[which]; + } +- else if(rampdown[which]) { ++ else if( rampdown[which] ) ++ { + outsample *= (rampdown_len[which] - rampctr[which]++) * rampdown_len_inv[which]; +- if(rampctr[which] >= rampdown_len[which]) { +- rampdown[which] = false; +- play[which] = false; +- } ++ play[which] = rampdown[which] = rampctr[which] < rampdown_len[which]; + } +- +- outsample *= voiceGain[which]; +- +- return (SAMPLE)outsample; ++ ++ return (SAMPLE)(outsample * voiceGain[which]); + } + + // grab a sample from the buffer, with linear interpolation (add prc's SINC interp later) + // given a position within the buffer +- inline SAMPLE getSamp(t_CKDOUBLE where, t_CKINT which) ++ inline SAMPLE getSamp(t_CKDOUBLE where, t_CKINT which = 0) + { +- // constrain +- if(where > loop_end[which]) where = loop_end[which]; +- if(where < loop_start[which]) where = loop_start[which]; +- + // interp +- t_CKINT whereTrunc = (t_CKINT) where; ++ t_CKINT whereTrunc = (t_CKINT)where; + t_CKDOUBLE whereFrac = where - (t_CKDOUBLE)whereTrunc; + t_CKINT whereNext = whereTrunc + 1; +- +- if((whereNext) == loop_end[which]) whereNext = loop_start[which]; ++ ++ if( whereNext == mdata_len ) whereNext = 0; ++ ++ if( loopplay[which] && !isInLoop( whereNext, which ) ) ++ whereNext = loop_start[which]; + + t_CKDOUBLE outsample; +- outsample = (t_CKDOUBLE)mdata[whereTrunc] + (t_CKDOUBLE)(mdata[whereNext] - mdata[whereTrunc]) * whereFrac; +- outsample *= voiceGain[which]; +- +- //add voiceGain ctl here; return (SAMPLE)vgain[which]*outsample; +- return (SAMPLE)outsample; ++ outsample = (t_CKDOUBLE)mdata[whereTrunc] + ++ (t_CKDOUBLE)(mdata[whereNext] - mdata[whereTrunc]) * whereFrac; ++ ++ return (SAMPLE)(outsample * voiceGain[which]); + } + + // ramp stuff +@@ -3792,6 +3889,11 @@ struct LiSaMulti_data + //fprintf ( stderr, "rec_ramplen = %f, inv = %f \n", rec_ramplen, rec_ramplen_inv ); + } + ++ inline void mix_voice(SAMPLE sample, t_CKINT which, SAMPLE *out) ++ { ++ for( t_CKINT i = 0; i < LiSa_channels; i++ ) ++ out[i] += sample * channelGain[which][i]; ++ } + + //for simple stereo panning of a particular voice, and... + // l.channelGain(voice, channel, gain) +@@ -3805,44 +3907,39 @@ struct LiSaMulti_data + case 0: + recordSamp( in ); + for( t_CKINT i = 0; i < maxvoices; i++ ) +- { +- if( play[i] ) +- { +- SAMPLE tempsample = getNextSamp( i ); +- for( t_CKINT j = 0; j < LiSa_channels; j++ ) +- out[j] += tempsample * channelGain[i][j]; //channelGain should return gain for voice i in channel j +- } +- } ++ if( play[i] ) mix_voice( getNextSamp( i ), i, out ); + break; + + case 1: +- if( in < 0. ) in = -in; ++ case 2: + for( t_CKINT i = 0; i < maxvoices; i++ ) + { + if( play[i] ) + { +- SAMPLE tempsample = getSamp( (t_CKDOUBLE)in * (loop_end[i] - loop_start[i]) + loop_start[i], i ); +- for( t_CKINT j = 0; j < LiSa_channels; j++ ) +- out[j] += tempsample * channelGain[i][j]; ++ t_CKDOUBLE where; ++ ++ if( track == 2 ) ++ where = (t_CKDOUBLE)in; ++ else if( loopplay[i] ) ++ where = (t_CKDOUBLE)in*loop_len[i] + loop_start[i]; ++ else ++ where = (t_CKDOUBLE)in*mdata_len; ++ ++ mix_voice( getSamp( normalize_index( where ), i ), i, out ); + } + } + break; + +- case 2: +- if( in < 0. ) in = -in; //only use voice 0 when tracking with durs. +- if( play[0] ) +- { +- SAMPLE tempsample = getSamp( (t_CKDOUBLE)in, 0 ); +- for( t_CKINT j = 0; j < LiSa_channels; j++ ) +- out[j] = tempsample * channelGain[0][j]; +- } ++ default: ++ /* shouldn't happen */ + break; + } + } + + inline void clear_buf() + { +- memset( mdata, 0, mdata_len*sizeof(SAMPLE) ); ++ if( mdata ) ++ memset( mdata, 0, mdata_len*sizeof(SAMPLE) ); + } + + inline t_CKINT get_free_voice() +@@ -3856,40 +3953,59 @@ struct LiSaMulti_data + } + + //stick sample in record buffer +- inline void pokeSample( SAMPLE insample, t_CKINT index ) { +- +- if ( index >= mdata_len || index < 0 ) { +- index = 0; +- fprintf(stderr, "LiSa: trying to put sample out of buffer range; ignoring"); +- } else mdata[index] = insample; +- +- } ++ inline void pokeSample( SAMPLE insample, t_CKINT index ) ++ { ++ mdata[index] = insample; ++ } + + //grab sample directly from record buffer, with linear interpolation +- inline SAMPLE grabSample ( t_CKDOUBLE where ) { +- +- if ( where > mdata_len || where < 0 ) { +- where = 0; +- fprintf(stderr, "LiSa: trying to grab sample out of buffer range; ignoring"); +- return 0.; +- } else { +- +- // interp +- t_CKINT whereTrunc = (t_CKINT) where; +- t_CKDOUBLE whereFrac = where - (t_CKDOUBLE)whereTrunc; +- t_CKINT whereNext = whereTrunc + 1; +- +- if((whereNext) == mdata_len) whereNext = 0; ++ inline SAMPLE grabSample( t_CKDOUBLE where ) ++ { ++ // interp ++ t_CKINT whereTrunc = (t_CKINT) where; ++ t_CKDOUBLE whereFrac = where - (t_CKDOUBLE)whereTrunc; ++ t_CKINT whereNext = whereTrunc + 1; + +- t_CKDOUBLE outsample; +- outsample = (t_CKDOUBLE)mdata[whereTrunc] + (t_CKDOUBLE)(mdata[whereNext] - mdata[whereTrunc]) * whereFrac; +- +- //add voiceGain ctl here; return (SAMPLE)vgain[which]*outsample; +- return (SAMPLE)outsample; +- +- } +- } +- ++ if( whereNext == mdata_len ) whereNext = 0; ++ ++ t_CKDOUBLE outsample; ++ outsample = (t_CKDOUBLE)mdata[whereTrunc] + (t_CKDOUBLE)(mdata[whereNext] - mdata[whereTrunc]) * whereFrac; ++ ++ return (SAMPLE)outsample; ++ } ++ ++ t_CKFLOAT set_voice_pan(t_CKFLOAT pan, t_CKINT which = 0) ++ { ++ voicePan[which] = pan; ++ ++ for( t_CKINT i = 0; i < LiSa_channels; i++ ) channelGain[which][i] = 0.; ++ ++ for( t_CKINT i = 0; i < LiSa_channels; i++ ) ++ { ++ t_CKINT panTrunc = (t_CKINT)voicePan[which]; ++ //fprintf(stderr, "panTrunc = %d, panFloat = %f, i = %d\n", panTrunc, voicePan[which], i); ++ if( i == panTrunc ) ++ { ++ channelGain[which][i] = 1. - ( voicePan[which] - (t_CKFLOAT)i ); ++ if( i == LiSa_channels - 1 ) ++ { ++ channelGain[which][0] = 1. - channelGain[which][i]; ++ channelGain[which][0] = sqrt( channelGain[which][0] ); ++ } ++ else ++ { ++ channelGain[which][i+1] = 1. - channelGain[which][i]; ++ channelGain[which][i+1] = sqrt( channelGain[which][i+1] ); ++ } ++ ++ channelGain[which][i] = sqrt( channelGain[which][i] ); ++ } ++ ++ //fprintf(stderr, "gain for channel %d and voice %d = %f\n", i, which, channelGain[which][i]); ++ } ++ ++ return pan; ++ } + }; + + +@@ -3967,14 +4083,8 @@ CK_DLL_TICKF( LiSaMulti_tickf ) + CK_DLL_CTRL( LiSaMulti_size ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); +- t_CKDUR buflen = GET_NEXT_DUR(ARGS); +- if (buflen > LiSa_MAXBUFSIZE) { +- fprintf(stderr, "LiSa: buffer size request too large, resizing\n"); +- buflen = LiSa_MAXBUFSIZE; +- } +- d->buffer_alloc((t_CKINT)buflen); +- +- RETURN->v_dur = (t_CKDUR)buflen; ++ ++ RETURN->v_dur = d->buffer_alloc( GET_NEXT_DUR(ARGS) ); + } + + CK_DLL_CGET( LiSaMulti_cget_size ) +@@ -4005,7 +4115,7 @@ CK_DLL_CTRL( LiSaMulti_start_record ) + CK_DLL_CTRL( LiSaMulti_start_play ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); +- t_CKINT which = GET_NEXT_INT(ARGS); ++ t_CKINT which = d->get_safe_voice( GET_NEXT_INT(ARGS) ); + d->play[which] = GET_NEXT_INT(ARGS); + //fprintf(stderr, "voice %d playing = %d\n", which, d->play[which]); + +@@ -4044,7 +4154,7 @@ CK_DLL_CTRL( LiSaMulti_start_play0 ) + CK_DLL_CTRL( LiSaMulti_ctrl_rate ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); +- t_CKINT which = GET_NEXT_INT(ARGS); ++ t_CKINT which = d->get_safe_voice( GET_NEXT_INT(ARGS) ); + d->p_inc[which] = (t_CKDOUBLE)GET_NEXT_FLOAT(ARGS); + + //fprintf(stderr, "setting voice %d rate to %f\n", which, d->p_inc[which]); +@@ -4071,7 +4181,7 @@ CK_DLL_CTRL( LiSaMulti_ctrl_rate0 ) + CK_DLL_CTRL( LiSaMulti_cget_rate ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); +- t_CKINT which = GET_NEXT_INT(ARGS); ++ t_CKINT which = d->get_safe_voice( GET_NEXT_INT(ARGS) ); + //fprintf(stderr, "setting voice %d rate to %f\n", which, d->p_inc[which]); + + RETURN->v_float = d->p_inc[which]; +@@ -4093,8 +4203,8 @@ CK_DLL_CTRL( LiSaMulti_cget_rate0 ) + CK_DLL_CTRL( LiSaMulti_ctrl_pindex ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); +- t_CKINT which = GET_NEXT_INT(ARGS); +- d->pindex[which] = (t_CKDOUBLE)GET_NEXT_DUR(ARGS); ++ t_CKINT which = d->get_safe_voice( GET_NEXT_INT(ARGS) ); ++ d->pindex[which] = d->normalize_index( (t_CKDOUBLE)GET_NEXT_DUR(ARGS) ); + + RETURN->v_dur = (t_CKDUR)d->pindex[which]; + } +@@ -4103,7 +4213,7 @@ CK_DLL_CTRL( LiSaMulti_ctrl_pindex ) + CK_DLL_CTRL( LiSaMulti_ctrl_pindex0 ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); +- d->pindex[0] = (t_CKDOUBLE)GET_NEXT_DUR(ARGS); ++ d->pindex[0] = d->normalize_index( (t_CKDOUBLE)GET_NEXT_DUR(ARGS) ); + + RETURN->v_dur = (t_CKDUR)d->pindex[0]; + } +@@ -4116,7 +4226,7 @@ CK_DLL_CTRL( LiSaMulti_ctrl_pindex0 ) + CK_DLL_CGET( LiSaMulti_cget_pindex ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); +- t_CKINT which = GET_NEXT_INT(ARGS); ++ t_CKINT which = d->get_safe_voice( GET_NEXT_INT(ARGS) ); + + // return + RETURN->v_dur = (t_CKDUR)d->pindex[which]; +@@ -4139,7 +4249,7 @@ CK_DLL_CGET( LiSaMulti_cget_pindex0 ) + CK_DLL_CTRL( LiSaMulti_ctrl_rindex ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); +- d->rindex = /* gewang-> */(t_CKINT)GET_NEXT_DUR(ARGS); ++ d->rindex = (t_CKINT)d->normalize_index( (t_CKDOUBLE)GET_NEXT_DUR(ARGS) ); + + RETURN->v_dur = (t_CKDUR)d->rindex; + } +@@ -4165,23 +4275,17 @@ CK_DLL_CGET( LiSaMulti_cget_rindex ) + CK_DLL_CTRL( LiSaMulti_ctrl_lstart ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); +- t_CKINT which = GET_NEXT_INT(ARGS); +- d->loop_start[which] = /* gewang-> */(t_CKINT)GET_NEXT_DUR(ARGS); +- +- if (d->loop_start[which] < 0) d->loop_start[which] = 0; +- +- RETURN->v_dur = (t_CKDUR)d->loop_start[which]; ++ t_CKINT which = d->get_safe_voice( GET_NEXT_INT(ARGS) ); ++ ++ RETURN->v_dur = d->set_loop_start( GET_NEXT_DUR(ARGS), which ); + } + + + CK_DLL_CTRL( LiSaMulti_ctrl_lstart0 ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); +- d->loop_start[0] = /* gewang-> */(t_CKINT)GET_NEXT_DUR(ARGS); +- +- if (d->loop_start[0] < 0) d->loop_start[0] = 0; +- +- RETURN->v_dur = (t_CKDUR)d->loop_start[0]; ++ ++ RETURN->v_dur = d->set_loop_start( GET_NEXT_DUR(ARGS) ); + } + + +@@ -4193,7 +4297,7 @@ CK_DLL_CGET( LiSaMulti_cget_lstart ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); + +- t_CKINT which = GET_NEXT_INT(ARGS); ++ t_CKINT which = d->get_safe_voice( GET_NEXT_INT(ARGS) ); + // return + RETURN->v_dur = (t_CKDUR)d->loop_start[which]; + } +@@ -4215,25 +4319,17 @@ CK_DLL_CGET( LiSaMulti_cget_lstart0 ) + CK_DLL_CTRL( LiSaMulti_ctrl_lend ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); +- t_CKINT which = GET_NEXT_INT(ARGS); +- d->loop_end[which] = /* gewang-> */(t_CKINT)GET_NEXT_DUR(ARGS); +- +- //check to make sure loop_end is not too large +- if (d->loop_end[which] >= d->mdata_len) d->loop_end[which] = d->mdata_len - 1; +- +- RETURN->v_dur = (t_CKDUR)d->loop_end[which]; ++ t_CKINT which = d->get_safe_voice( GET_NEXT_INT(ARGS) ); ++ ++ RETURN->v_dur = d->set_loop_end( GET_NEXT_DUR(ARGS), which ); + } + + + CK_DLL_CTRL( LiSaMulti_ctrl_lend0 ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); +- d->loop_end[0] = /* gewang-> */(t_CKINT)GET_NEXT_DUR(ARGS); +- +- //check to make sure loop_end is not too large +- if (d->loop_end[0] >= d->mdata_len) d->loop_end[0] = d->mdata_len - 1; +- +- RETURN->v_dur = (t_CKDUR)d->loop_end[0]; ++ ++ RETURN->v_dur = d->set_loop_end( GET_NEXT_DUR(ARGS) ); + } + + +@@ -4244,7 +4340,7 @@ CK_DLL_CTRL( LiSaMulti_ctrl_lend0 ) + CK_DLL_CGET( LiSaMulti_cget_lend ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); +- t_CKINT which = GET_NEXT_INT(ARGS); ++ t_CKINT which = d->get_safe_voice( GET_NEXT_INT(ARGS) ); + + // return + RETURN->v_dur = (t_CKDUR)d->loop_end[which]; +@@ -4267,7 +4363,7 @@ CK_DLL_CGET( LiSaMulti_cget_lend0 ) + CK_DLL_CTRL( LiSaMulti_ctrl_loop ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); +- t_CKINT which = GET_NEXT_INT(ARGS); ++ t_CKINT which = d->get_safe_voice( GET_NEXT_INT(ARGS) ); + d->loopplay[which] = (t_CKBOOL)GET_NEXT_INT(ARGS); + } + +@@ -4288,7 +4384,7 @@ CK_DLL_CTRL( LiSaMulti_ctrl_loop0 ) + CK_DLL_CGET( LiSaMulti_cget_loop ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); +- t_CKINT which = GET_NEXT_INT(ARGS); ++ t_CKINT which = d->get_safe_voice( GET_NEXT_INT(ARGS) ); + + // return + RETURN->v_int = (t_CKINT)d->loopplay[which]; +@@ -4311,7 +4407,7 @@ CK_DLL_CGET( LiSaMulti_cget_loop0 ) + CK_DLL_CTRL( LiSaMulti_ctrl_bi ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); +- t_CKINT which = GET_NEXT_INT(ARGS); ++ t_CKINT which = d->get_safe_voice( GET_NEXT_INT(ARGS) ); + d->bi[which] = (t_CKBOOL)GET_NEXT_INT(ARGS); + + RETURN->v_int = (t_CKINT)d->bi[which]; +@@ -4334,7 +4430,7 @@ CK_DLL_CTRL( LiSaMulti_ctrl_bi0 ) + CK_DLL_CGET( LiSaMulti_cget_bi ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); +- t_CKINT which = GET_NEXT_INT(ARGS); ++ t_CKINT which = d->get_safe_voice( GET_NEXT_INT(ARGS) ); + + // return + RETURN->v_int = (t_CKINT)d->bi[which]; +@@ -4357,8 +4453,15 @@ CK_DLL_CGET( LiSaMulti_cget_bi0 ) + CK_DLL_CTRL( LiSaMulti_ctrl_loop_end_rec ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); +- d->loop_end_rec = /* gewang-> */(t_CKINT)GET_NEXT_DUR(ARGS); +- ++ if( !d->mdata ) ++ { ++ EM_error2( 0, "LiSa: Trying to set loop recording end on uninitialized buffer; ignoring" ); ++ RETURN->v_dur = 0.; ++ return; ++ } ++ ++ d->loop_end_rec = (t_CKINT)d->normalize_index( (t_CKDOUBLE)GET_NEXT_DUR(ARGS) ); ++ + RETURN->v_dur = (t_CKDUR)d->loop_end_rec; + } + +@@ -4408,11 +4511,18 @@ CK_DLL_CGET( LiSaMulti_cget_loop_rec ) + CK_DLL_CTRL( LiSaMulti_ctrl_sample ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); +- SAMPLE sample_in = (SAMPLE)GET_NEXT_FLOAT(ARGS); +- int index_in = (t_CKINT)GET_NEXT_DUR(ARGS); +- +- d->pokeSample( sample_in, index_in ); +- ++ if( !d->mdata ) ++ { ++ EM_error2( 0, "LiSa: Trying to put sample into uninitialized buffer; ignoring" ); ++ RETURN->v_float = 0.; ++ return; ++ } ++ ++ SAMPLE sample_in = (SAMPLE)GET_NEXT_FLOAT(ARGS); ++ t_CKINT index_in = (t_CKINT)d->normalize_index( (t_CKDOUBLE)GET_NEXT_DUR(ARGS) ); ++ ++ d->pokeSample( sample_in, index_in ); ++ + RETURN->v_float = (t_CKFLOAT)sample_in; //pass input through + } + +@@ -4423,7 +4533,14 @@ CK_DLL_CTRL( LiSaMulti_ctrl_sample ) + CK_DLL_CGET( LiSaMulti_cget_sample ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); +- double index_in = (t_CKDOUBLE)GET_NEXT_DUR(ARGS); ++ if( !d->mdata ) ++ { ++ EM_error2( 0, "LiSa: Trying to grab sample from uninitialized buffer; ignoring" ); ++ RETURN->v_float = 0.; ++ return; ++ } ++ ++ t_CKDOUBLE index_in = d->normalize_index( (t_CKDOUBLE)GET_NEXT_DUR(ARGS) ); + // return + RETURN->v_float = (t_CKFLOAT)d->grabSample( index_in ); //change this to getSamp for interpolation + } +@@ -4436,7 +4553,7 @@ CK_DLL_CGET( LiSaMulti_cget_sample ) + CK_DLL_CTRL( LiSaMulti_ctrl_voicegain ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); +- t_CKINT which = GET_NEXT_INT(ARGS); ++ t_CKINT which = d->get_safe_voice( GET_NEXT_INT(ARGS) ); + d->voiceGain[which] = (t_CKDOUBLE)GET_NEXT_FLOAT(ARGS); + + RETURN->v_float = (t_CKFLOAT)d->voiceGain[which]; +@@ -4450,7 +4567,7 @@ CK_DLL_CTRL( LiSaMulti_ctrl_voicegain ) + CK_DLL_CGET( LiSaMulti_cget_voicegain ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); +- t_CKINT which = GET_NEXT_INT(ARGS); ++ t_CKINT which = d->get_safe_voice( GET_NEXT_INT(ARGS) ); + + // return + RETURN->v_float = (t_CKFLOAT)d->voiceGain[which]; +@@ -4463,35 +4580,10 @@ CK_DLL_CGET( LiSaMulti_cget_voicegain ) + CK_DLL_CTRL( LiSaMulti_ctrl_voicepan ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); +- t_CKINT which = GET_NEXT_INT(ARGS); +- d->voicePan[which] = (t_CKFLOAT)GET_NEXT_FLOAT(ARGS); +- +- t_CKINT i; ++ t_CKINT which = d->get_safe_voice( GET_NEXT_INT(ARGS) ); ++ t_CKFLOAT pan = GET_NEXT_FLOAT(ARGS); + +- for(i=0; ichannelGain[which][i] = 0.; +- +- for(i=0; ivoicePan[which]; +- //fprintf(stderr, "panTrunc = %d, panFloat = %f, i = %d\n", panTrunc, d->voicePan[which], i); +- if(i == panTrunc) { +- d->channelGain[which][i] = 1. - ( d->voicePan[which] - (t_CKFLOAT)i ); +- if(i == LiSa_channels - 1) { +- d->channelGain[which][0] = 1. - d->channelGain[which][i]; +- d->channelGain[which][0] = sqrt(d->channelGain[which][0]); +- } +- else { +- d->channelGain[which][i+1] = 1. - d->channelGain[which][i]; +- d->channelGain[which][i+1] = sqrt(d->channelGain[which][i+1]); +- } +- +- d->channelGain[which][i] = sqrt(d->channelGain[which][i]); +- +- } +- +- //fprintf(stderr, "gain for channel %d and voice %d = %f\n", i, which, d->channelGain[which][i]); +- } +- +- RETURN->v_float = (t_CKFLOAT)d->voicePan[which]; ++ RETURN->v_float = d->set_voice_pan( pan, which ); + } + + +@@ -4502,44 +4594,18 @@ CK_DLL_CTRL( LiSaMulti_ctrl_voicepan ) + CK_DLL_CGET( LiSaMulti_cget_voicepan ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); +- t_CKINT which = GET_NEXT_INT(ARGS); ++ t_CKINT which = d->get_safe_voice( GET_NEXT_INT(ARGS) ); + + // return +- RETURN->v_float = (t_CKFLOAT)d->voicePan[which]; ++ RETURN->v_float = d->voicePan[which]; + } + + CK_DLL_CTRL( LiSaMulti_ctrl_voicepan0 ) + { +- LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); +- t_CKINT which = 0; //voice 0 for this one +- d->voicePan[which] = (t_CKFLOAT)GET_NEXT_FLOAT(ARGS); +- +- t_CKINT i; ++ LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); ++ t_CKFLOAT pan = GET_NEXT_FLOAT(ARGS); + +- for(i=0; ichannelGain[which][i] = 0.; +- +- for(i=0; ivoicePan[which]; +- //fprintf(stderr, "panTrunc = %d, panFloat = %f, i = %d\n", panTrunc, d->voicePan[which], i); +- if(i == panTrunc) { +- d->channelGain[which][i] = 1. - ( d->voicePan[which] - (t_CKFLOAT)i ); +- if(i == LiSa_channels - 1) { +- d->channelGain[which][0] = 1. - d->channelGain[which][i]; +- d->channelGain[which][0] = sqrt(d->channelGain[which][0]); +- } +- else { +- d->channelGain[which][i+1] = 1. - d->channelGain[which][i]; +- d->channelGain[which][i+1] = sqrt(d->channelGain[which][i+1]); +- } +- +- d->channelGain[which][i] = sqrt(d->channelGain[which][i]); +- +- } +- +- //fprintf(stderr, "gain for channel %d and voice %d = %f\n", i, which, d->channelGain[which][i]); +- } +- +- RETURN->v_float = (t_CKFLOAT)d->voicePan[which]; ++ RETURN->v_float = d->set_voice_pan( pan ); + } + + CK_DLL_CGET( LiSaMulti_cget_voicepan0 ) +@@ -4547,7 +4613,7 @@ CK_DLL_CGET( LiSaMulti_cget_voicepan0 ) + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); + + // return +- RETURN->v_float = (t_CKFLOAT)d->voicePan[0]; ++ RETURN->v_float = d->voicePan[0]; + } + + //----------------------------------------------------------------------------- +@@ -4608,8 +4674,15 @@ CK_DLL_CGET( LiSaMulti_cget_voice ) + CK_DLL_CTRL( LiSaMulti_ctrl_rampup ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); +- t_CKINT voice = GET_NEXT_INT(ARGS); +- t_CKDUR len = GET_NEXT_DUR(ARGS); ++ if( !d->mdata ) ++ { ++ EM_error2( 0, "LiSa: Trying to set ramp up length on uninitialized buffer; ignoring" ); ++ RETURN->v_dur = 0.; ++ return; ++ } ++ ++ t_CKINT voice = d->get_safe_voice( GET_NEXT_INT(ARGS) ); ++ t_CKDUR len = (t_CKDUR)d->normalize_index( (t_CKDOUBLE)GET_NEXT_DUR(ARGS) ); + + d->ramp_up(voice, len); + +@@ -4620,7 +4693,14 @@ CK_DLL_CTRL( LiSaMulti_ctrl_rampup ) + CK_DLL_CTRL( LiSaMulti_ctrl_rampup0 ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); +- t_CKDUR len = GET_NEXT_DUR(ARGS); ++ if( !d->mdata ) ++ { ++ EM_error2( 0, "LiSa: Trying to set ramp up length on uninitialized buffer; ignoring" ); ++ RETURN->v_dur = 0.; ++ return; ++ } ++ ++ t_CKDUR len = (t_CKDUR)d->normalize_index( (t_CKDOUBLE)GET_NEXT_DUR(ARGS) ); + + d->ramp_up(0, len); + +@@ -4635,19 +4715,33 @@ CK_DLL_CTRL( LiSaMulti_ctrl_rampup0 ) + CK_DLL_CTRL( LiSaMulti_ctrl_rampdown ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); +- t_CKINT voice = GET_NEXT_INT(ARGS); +- t_CKDUR len = GET_NEXT_DUR(ARGS); ++ if( !d->mdata ) ++ { ++ EM_error2( 0, "LiSa: Trying to set ramp down length on uninitialized buffer; ignoring" ); ++ RETURN->v_dur = 0.; ++ return; ++ } ++ ++ t_CKINT voice = d->get_safe_voice( GET_NEXT_INT(ARGS) ); ++ t_CKDUR len = (t_CKDUR)d->normalize_index( (t_CKDOUBLE)GET_NEXT_DUR(ARGS) ); + + d->ramp_down(voice, len); + +- RETURN->v_dur = (t_CKDUR)len; ++ RETURN->v_dur = (t_CKDUR)len; + } + + + CK_DLL_CTRL( LiSaMulti_ctrl_rampdown0 ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); +- t_CKDUR len = GET_NEXT_DUR(ARGS); ++ if( !d->mdata ) ++ { ++ EM_error2( 0, "LiSa: Trying to set ramp down length on uninitialized buffer; ignoring" ); ++ RETURN->v_dur = 0.; ++ return; ++ } ++ ++ t_CKDUR len = (t_CKDUR)d->normalize_index( (t_CKDOUBLE)GET_NEXT_DUR(ARGS) ); + + d->ramp_down(0, len); + +@@ -4662,7 +4756,14 @@ CK_DLL_CTRL( LiSaMulti_ctrl_rampdown0 ) + CK_DLL_CTRL( LiSaMulti_ctrl_rec_ramplen ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); +- t_CKDUR newramplen = GET_NEXT_DUR(ARGS); ++ if( !d->mdata ) ++ { ++ EM_error2( 0, "LiSa: Trying to set recording ramp length on uninitialized buffer; ignoring" ); ++ RETURN->v_dur = 0.; ++ return; ++ } ++ ++ t_CKDUR newramplen = (t_CKDUR)d->normalize_index( (t_CKDOUBLE)GET_NEXT_DUR(ARGS) ); + d->set_rec_ramplen(newramplen); + + RETURN->v_dur = (t_CKDUR)newramplen; +@@ -4679,7 +4780,7 @@ CK_DLL_CTRL( LiSaMulti_ctrl_maxvoices ) + d->maxvoices = GET_NEXT_INT(ARGS); + if( d->maxvoices > LiSa_MAXVOICES) { + d->maxvoices = LiSa_MAXVOICES; +- fprintf(stderr, "LiSa: MAXVOICES limited to %d.\n", LiSa_MAXVOICES); ++ EM_error2( 0, "LiSa: MAXVOICES limited to %d", LiSa_MAXVOICES ); + } + RETURN->v_int = d->maxvoices; + } +@@ -4705,21 +4806,33 @@ CK_DLL_CGET( LiSaMulti_cget_maxvoices ) + CK_DLL_CGET( LiSaMulti_cget_value ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); +- t_CKINT voice = GET_NEXT_INT(ARGS); +- t_CKDOUBLE where = (t_CKDOUBLE) GET_NEXT_DUR(ARGS); ++ if( !d->mdata ) ++ { ++ EM_error2( 0, "LiSa: Trying to grab value from uninitialized buffer; ignoring" ); ++ RETURN->v_dur = 0.; ++ return; ++ } + +- // return +- RETURN->v_dur = (t_CKDUR)d->getSamp(where, voice); ++ t_CKINT voice = d->get_safe_voice( GET_NEXT_INT(ARGS) ); ++ t_CKDOUBLE where = d->normalize_index( (t_CKDOUBLE)GET_NEXT_DUR(ARGS) ); ++ ++ RETURN->v_dur = (t_CKDUR)d->getSamp( where, voice ); + } + + + CK_DLL_CGET( LiSaMulti_cget_value0 ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); ++ if( !d->mdata ) ++ { ++ EM_error2( 0, "LiSa: Trying to grab value from uninitialized buffer; ignoring" ); ++ RETURN->v_dur = 0.; ++ return; ++ } + +- t_CKDOUBLE where = (t_CKDOUBLE) GET_NEXT_DUR(ARGS); +- // return +- RETURN->v_dur = (t_CKDUR)d->getSamp(where, 0); ++ t_CKDOUBLE where = d->normalize_index( (t_CKDOUBLE)GET_NEXT_DUR(ARGS) ); ++ ++ RETURN->v_dur = (t_CKDUR)d->getSamp( where ); + } + + +@@ -4731,6 +4844,11 @@ CK_DLL_CTRL( LiSaMulti_ctrl_track ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); + d->track = (t_CKINT)GET_NEXT_INT(ARGS); ++ if( d->track < 0 || d->track > 2 ) ++ { ++ EM_error2( 0, "LiSa: Invalid tracking mode %d; using 0", d->track ); ++ d->track = 0; ++ } + + RETURN->v_int = d->track; + } +@@ -4756,12 +4874,8 @@ CK_DLL_CGET( LiSaMulti_cget_track ) + CK_DLL_CGET( LiSaMulti_cget_playing ) + { + LiSaMulti_data * d = (LiSaMulti_data *)OBJ_MEMBER_UINT(SELF, LiSaMulti_offset_data); +- t_CKINT voice = GET_NEXT_INT(ARGS); +- if(voice >= d->maxvoices) { +- fprintf(stderr, "LiSa: requesting info greater than MAXVOICES %d.\n", LiSa_MAXVOICES); +- voice = 0; +- } +- ++ t_CKINT voice = d->get_safe_voice( GET_NEXT_INT(ARGS) ); ++ + // return + RETURN->v_int = d->play[voice]; + } +-- +1.7.1 + diff --git a/chuck/patches/0011-use-mono-LiSa-only-for-my-setup-no-need-to-submit-pa.patch b/chuck/patches/0011-use-mono-LiSa-only-for-my-setup-no-need-to-submit-pa.patch new file mode 100644 index 0000000..3073dbb --- /dev/null +++ b/chuck/patches/0011-use-mono-LiSa-only-for-my-setup-no-need-to-submit-pa.patch @@ -0,0 +1,25 @@ +From 2bec62a6c1053fd2007540b1028e991b1e539424 Mon Sep 17 00:00:00 2001 +From: Robin Haberkorn +Date: Sat, 8 Sep 2012 04:00:06 +0200 +Subject: [PATCH 11/12] use mono LiSa (only for my setup, no need to submit patch) + +--- + ugen_xxx.cpp | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/src/ugen_xxx.cpp b/src/ugen_xxx.cpp +index 17e39d6..f57bd9d 100644 +--- a/src/ugen_xxx.cpp ++++ b/src/ugen_xxx.cpp +@@ -858,7 +858,7 @@ error: + } + + +-#define LiSa_channels 8 //max channels for multichannel LiSa ++#define LiSa_channels 1 //max channels for multichannel LiSa + + // LiSa (live sampling data offset) + static t_CKUINT LiSaMulti_offset_data = 0; +-- +1.7.1 + diff --git a/chuck/patches/0012-allow-unary-minus-on-durations.patch b/chuck/patches/0012-allow-unary-minus-on-durations.patch new file mode 100644 index 0000000..5380e97 --- /dev/null +++ b/chuck/patches/0012-allow-unary-minus-on-durations.patch @@ -0,0 +1,43 @@ +From ab1269fde46f8a0c32e4ce5ba45de9e38442f6e3 Mon Sep 17 00:00:00 2001 +From: Robin Haberkorn +Date: Wed, 12 Sep 2012 22:58:07 +0200 +Subject: [PATCH 12/12] allow unary minus on durations + +there is no reason why "-1*samp" should works but not "-samp" +--- + chuck_emit.cpp | 3 ++- + chuck_type.cpp | 4 ++-- + 2 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/chuck_emit.cpp b/src/chuck_emit.cpp +index 60cacc5..fdc7d9b 100644 +--- a/src/chuck_emit.cpp ++++ b/src/chuck_emit.cpp +@@ -2590,7 +2590,8 @@ t_CKBOOL emit_engine_emit_exp_unary( Chuck_Emitter * emit, a_Exp_Unary unary ) + // negate + if( equals( unary->exp->type, &t_int ) ) + emit->append( new Chuck_Instr_Negate_int ); +- else if( equals( unary->exp->type, &t_float ) ) ++ else if( equals( unary->exp->type, &t_float ) || ++ equals( unary->exp->type, &t_dur ) ) + emit->append( new Chuck_Instr_Negate_double ); + else + { +diff --git a/src/chuck_type.cpp b/src/chuck_type.cpp +index 4f817b8..3b642d1 100644 +--- a/src/chuck_type.cpp ++++ b/src/chuck_type.cpp +@@ -2041,8 +2041,8 @@ t_CKTYPE type_engine_check_exp_unary( Chuck_Env * env, a_Exp_Unary unary ) + break; + + case ae_op_minus: +- // float +- if( isa( t, &t_float ) ) return t; ++ // duration, float ++ if( isa( t, &t_dur ) || isa( t, &t_float ) ) return t; + case ae_op_tilda: + case ae_op_exclamation: + // int +-- +1.7.1 + diff --git a/chuck/patches/0013-crosscompile.patch b/chuck/patches/0013-crosscompile.patch new file mode 100644 index 0000000..fed5a82 --- /dev/null +++ b/chuck/patches/0013-crosscompile.patch @@ -0,0 +1,35 @@ +diff --git a/makefile b/makefile +index 077b879..134b492 100644 +--- a/src/makefile ++++ b/src/makefile +@@ -24,11 +24,11 @@ osx linux-oss linux-jack linux-alsa win32 osx-rl: chuck + + CK_VERSION=1.3.1.1 + +-LEX=flex +-YACC=bison +-CC=gcc +-CXX=gcc +-LD=g++ ++LEX?=flex ++YACC?=bison ++CC?=gcc ++CXX?=g++ ++LD=$(CXX) + + ifneq ($(CHUCK_STAT),) + CFLAGS+= -D__CHUCK_STAT_TRACK__ +@@ -120,11 +120,11 @@ chuck.yy.c: chuck.lex + $(LEX) -ochuck.yy.c chuck.lex + + $(COBJS): %.o: %.c +- $(CC) $(CFLAGS) $(ARCHOPTS) -c $< -o $@ ++ $(CC) $(CFLAGS) $(CPPFLAGS) $(ARCHOPTS) -c $< -o $@ + @$(CC) -MM $(CFLAGSDEPEND) $< > $*.d + + $(CXXOBJS): %.o: %.cpp +- $(CXX) $(CFLAGS) $(ARCHOPTS) -c $< -o $@ ++ $(CXX) $(CFLAGS) $(CXXFLAGS) $(CPPFLAGS) $(ARCHOPTS) -c $< -o $@ + @$(CXX) -MM $(CFLAGSDEPEND) $< > $*.d + + clean: -- cgit v1.2.3