aboutsummaryrefslogtreecommitdiff
path: root/chuck/patches/0009-revised-LiSa-performing-various-optimizations-and-fi.patch
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2012-09-14 04:30:44 +0200
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2012-09-14 04:30:44 +0200
commit058c024194c4ce612d6365337b4ef0d7fad016b3 (patch)
treedf75378489a2487feaf2938b8f97dc2fefe1a4d9 /chuck/patches/0009-revised-LiSa-performing-various-optimizations-and-fi.patch
parent0a95e15cdc87de0136734e784d487f9b03170bbb (diff)
downloadnanonote-ports-058c024194c4ce612d6365337b4ef0d7fad016b3.tar.gz
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
Diffstat (limited to 'chuck/patches/0009-revised-LiSa-performing-various-optimizations-and-fi.patch')
-rw-r--r--chuck/patches/0009-revised-LiSa-performing-various-optimizations-and-fi.patch308
1 files changed, 308 insertions, 0 deletions
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 <robin.haberkorn@googlemail.com>
+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; j<num_chans; j++) {
++ for(t_CKINT j=0; j<LiSa_channels; j++) {
+ channelGain[i][j] = 1.;
+ }
+- channelGain[i][0] = 0.707;
+- channelGain[i][1] = 0.707;
+ }
+
+ return true;
+@@ -3796,44 +3796,53 @@ struct LiSaMulti_data
+ //for simple stereo panning of a particular voice, and...
+ // l.channelGain(voice, channel, gain)
+ //to set the gain for a particular voice going to a particular channel; good for >2 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;i<num_chans;i++) outsamples[i] = 0.;
+-
+- if(!mdata) return outsamples;
+-
+- recordSamp(in);
+-
+- if(track==0) {
+- for (t_CKINT i=0; i<maxvoices; i++) {
+- if(play[i]) {
+- tempsample = getNextSamp(i);
+- for(t_CKINT j=0;j<num_chans;j++) {
+- //outsamples[j] += tempsample; //mono for now, testing...
+- outsamples[j] += tempsample * channelGain[i][j]; //channelGain should return gain for voice i in channel j
+- }
+- }
++ case 1:
++ if( in < 0. ) in = -in;
++ 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];
++ }
+ }
+- } else if(track==1) {
+- if(in<0.) in = -in;
+- for (t_CKINT i=0; i<maxvoices; i++) {
+- if(play[i]) tempsample += getSamp((t_CKDOUBLE)in * (loop_end[i] - loop_start[i]) + loop_start[i], i);
+- }
+- } else if(track==2 && play[0]) {
+- if(in<0.) in = -in; //only use voice 0 when tracking with durs.
+- tempsample = getSamp( (t_CKDOUBLE)in, 0 );
+- }
++ break;
+
+- return outsamples;
++ 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];
++ }
++ break;
++ }
+ }
+
+ inline void clear_buf()
+ {
+- for (t_CKINT i = 0; i < mdata_len; i++)
+- mdata[i] = 0.;
++ memset( mdata, 0, mdata_len*sizeof(SAMPLE) );
+ }
+
+ inline t_CKINT get_free_voice()
+@@ -3907,16 +3916,7 @@ CK_DLL_CTOR( LiSaMulti_ctor )
+ LiSaMulti_data * f = new LiSaMulti_data;
+ memset( f, 0, sizeof(LiSaMulti_data) );
+
+- Chuck_UGen * ugen = (Chuck_UGen *)SELF;
+- f->num_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; i<d->num_chans; i++) d->channelGain[which][i] = 0.;
++ for(i=0; i<LiSa_channels; i++) d->channelGain[which][i] = 0.;
+
+- for(i=0; i<d->num_chans; i++) {
++ for(i=0; i<LiSa_channels; i++) {
+ t_CKINT panTrunc = (t_CKINT)d->voicePan[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; i<d->num_chans; i++) d->channelGain[which][i] = 0.;
++ for(i=0; i<LiSa_channels; i++) d->channelGain[which][i] = 0.;
+
+- for(i=0; i<d->num_chans; i++) {
++ for(i=0; i<LiSa_channels; i++) {
+ t_CKINT panTrunc = (t_CKINT)d->voicePan[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
+