diff --git a/lib/sfold.c b/lib/sfold.c index cfd55ac..9eb1733 100644 --- a/lib/sfold.c +++ b/lib/sfold.c @@ -5,10 +5,11 @@ static float fold, rotate, density, offset, id = 0; +static float rotated, iid = 0; // OPTIMIZATION static float _ch = 1.f; // total count of channels to span across +static float _ich = 1.f; // inverse of _ch inline static float _xfade( float a, float b, float c ); -static float _sin( float in ); static float folder(float in, float coeff); static float densify(float v, float density); @@ -16,6 +17,7 @@ static float densify(float v, float density); // setup data structures void sfold_init(int channels){ _ch = (float)channels; + _ich = 1.f / _ch; fold = 0.f; rotate = 0.f; @@ -36,6 +38,7 @@ void sfold_set_fold(float f){ // (0..1) void sfold_set_rotate(float r){ rotate = r; + rotated = (rotate - 0.5f) * _ch; // allows rotate to perform 360 } // (0..1) void sfold_set_density(float d){ @@ -48,6 +51,7 @@ void sfold_set_offset(float o){ // (0..1) void sfold_set_id(float i){ id = i; + iid = 1.f - id; } // separate run function per channel @@ -68,17 +72,19 @@ float sfold(int channel){ // ROTATE // create rotated_index by adding ROTATE to channel index - float rix = (float)channel + ((rotate - 0.5f) * _ch); // allows rotate to perform 360 + // float rix = (float)channel + ((rotate - 0.5f) * _ch); // allows rotate to perform 360 + float rix = (float)channel + rotated; // allows rotate to perform 360 // wrap into range of 0 to channel count while(rix < 0.f) rix += _ch; while(rix >= _ch) rix -= _ch; - rix /= _ch; // scale down to 0,1 + rix *= _ich; // scale down to 0,1 rix -= 0.5f; // centre around 0 (-0.5, 0.5) rix *= 6.f; // scale up to +/-3 // ID // apply "id" (modulo) to OFFSET by combining CV and rotated_index - retval += rix * (1.f-id); + // retval += rix * (1.f-id); + retval += rix * iid; while(retval < 0.f) retval += 1.f; while(retval >= 1.f) retval -= 1.f; @@ -96,39 +102,9 @@ float sfold(int channel){ return retval; } - - - - - -#define LUT_SIN_SIZE ((uint32_t)1024) -#define LUT_SIN_HALF (LUT_SIN_SIZE >> 1) -const float sine_lut[LUT_SIN_SIZE + 1]={ - 1,0.999981175282601,0.999924701839145,0.999830581795823,0.999698818696204,0.999529417501093,0.99932238458835,0.999077727752645,0.998795456205172,0.998475580573295,0.998118112900149,0.997723066644192,0.99729045667869,0.996820299291166,0.996312612182778,0.99576741446766,0.995184726672197,0.994564570734255,0.993906970002356,0.993211949234794,0.99247953459871,0.991709753669099,0.99090263542778,0.990058210262297,0.989176509964781,0.988257567730749,0.987301418157858,0.986308097244599,0.985277642388941,0.984210092386929,0.983105487431216,0.981963869109555,0.98078528040323,0.97956976568544,0.978317370719628,0.977028142657754,0.975702130038528,0.974339382785576,0.97293995220556,0.971503890986252,0.970031253194544,0.968522094274417,0.966976471044852,0.965394441697689,0.96377606579544,0.962121404269042,0.960430519415566,0.958703474895871,0.956940335732209,0.955141168305771,0.953306040354194,0.951435020969008,0.949528180593037,0.947585591017741,0.945607325380521,0.94359345816196,0.941544065183021,0.93945922360219,0.937339011912575,0.935183509938948,0.932992798834739,0.930766961078984,0.928506080473216,0.926210242138311,0.923879532511287,0.921514039342042,0.919113851690058,0.916679059921043,0.914209755703531,0.91170603200543,0.909167983090522,0.906595704514915,0.903989293123443,0.901348847046022,0.898674465693954,0.895966249756185,0.893224301195515,0.890448723244758,0.887639620402854,0.884797098430938,0.881921264348355,0.879012226428634,0.876070094195407,0.87309497841829,0.870086991108711,0.867046245515693,0.863972856121587,0.860866938637767,0.857728610000272,0.854557988365401,0.851355193105265,0.848120344803297,0.844853565249707,0.841554977436898,0.838224705554838,0.83486287498638,0.831469612302545,0.828045045257756,0.824589302785025,0.821102514991105,0.817584813151584,0.814036329705948,0.810457198252595,0.806847553543799,0.803207531480645,0.799537269107905,0.795836904608884,0.792106577300212,0.788346427626606,0.784556597155575,0.780737228572094,0.776888465673232,0.773010453362737,0.76910333764558,0.765167265622459,0.761202385484262,0.757208846506485,0.753186799043613,0.749136394523459,0.745057785441466,0.740951125354959,0.73681656887737,0.732654271672413,0.728464390448225,0.724247082951467,0.720002507961382,0.715730825283819,0.711432195745216,0.707106781186548,0.702754744457225,0.698376249408973,0.693971460889654,0.689540544737067,0.6850836677727,0.680600997795453,0.676092703575316,0.671558954847018,0.666999922303638,0.662415777590172,0.657806693297079,0.653172842953777,0.648514401022113,0.643831542889792,0.639124444863776,0.634393284163646,0.629638238914927,0.624859488142386,0.620057211763289,0.615231590580627,0.610382806276309,0.605511041404326,0.600616479383869,0.595699304492433,0.590759701858874,0.585797857456439,0.580813958095765,0.575808191417845,0.570780745886967,0.565731810783613,0.560661576197336,0.555570233019602,0.550457972936605,0.545324988422047,0.540171472729893,0.534997619887097,0.529803624686295,0.524589682678469,0.51935599016559,0.514102744193222,0.508830142543107,0.503538383725718,0.498227666972782,0.492898192229784,0.487550160148436,0.482183772079123,0.476799230063322,0.471396736825998,0.465976495767966,0.46053871095824,0.455083587126344,0.449611329654607,0.444122144570429,0.438616238538528,0.433093818853152,0.427555093430282,0.4220002707998,0.416429560097637,0.410843171057904,0.40524131400499,0.399624199845647,0.393992040061048,0.388345046698826,0.38268343236509,0.377007410216418,0.371317193951838,0.365612997804774,0.359895036534988,0.35416352542049,0.348418680249434,0.342660717311994,0.33688985339222,0.331106305759876,0.325310292162263,0.319502030816016,0.313681740398891,0.307849640041535,0.302005949319228,0.296150888243624,0.290284677254462,0.284407537211272,0.278519689385053,0.272621355449949,0.266712757474898,0.260794117915276,0.254865659604515,0.24892760574572,0.242980179903264,0.237023605994367,0.231058108280671,0.225083911359793,0.21910124015687,0.213110319916091,0.207111376192219,0.201104634842092,0.195090322016128,0.189068664149806,0.183039887955141,0.177004220412149,0.170961888760301,0.16491312048997,0.158858143333861,0.152797185258443,0.146730474455362,0.140658239332849,0.134580708507126,0.128498110793793,0.122410675199216,0.116318630911905,0.110222207293883,0.104121633872055,0.0980171403295608,0.0919089564971327,0.0857973123444399,0.0796824379714301,0.0735645635996675,0.0674439195636641,0.0613207363022087,0.05519524434969,0.0490676743274181,0.042938256934941,0.036807222941359,0.0306748031766366,0.0245412285229123,0.0184067299058048,0.0122715382857199,0.00613588464915452,6.12323399573677E-017,-0.00613588464915439,-0.0122715382857198,-0.0184067299058047,-0.0245412285229121,-0.0306748031766365,-0.0368072229413589,-0.0429382569349408,-0.049067674327418,-0.0551952443496899,-0.0613207363022085,-0.067443919563664,-0.0735645635996673,-0.07968243797143,-0.0857973123444398,-0.0919089564971326,-0.0980171403295607,-0.104121633872055,-0.110222207293883,-0.116318630911905,-0.122410675199216,-0.128498110793793,-0.134580708507126,-0.140658239332849,-0.146730474455362,-0.152797185258443,-0.158858143333861,-0.16491312048997,-0.170961888760301,-0.177004220412149,-0.183039887955141,-0.189068664149806,-0.195090322016128,-0.201104634842092,-0.207111376192218,-0.213110319916091,-0.21910124015687,-0.225083911359793,-0.231058108280671,-0.237023605994367,-0.242980179903264,-0.24892760574572,-0.254865659604514,-0.260794117915275,-0.266712757474898,-0.272621355449949,-0.278519689385053,-0.284407537211272,-0.290284677254462,-0.296150888243624,-0.302005949319228,-0.307849640041535,-0.313681740398891,-0.319502030816016,-0.325310292162263,-0.331106305759876,-0.33688985339222,-0.342660717311994,-0.348418680249434,-0.35416352542049,-0.359895036534988,-0.365612997804774,-0.371317193951837,-0.377007410216418,-0.38268343236509,-0.388345046698826,-0.393992040061048,-0.399624199845647,-0.40524131400499,-0.410843171057904,-0.416429560097637,-0.4220002707998,-0.427555093430282,-0.433093818853152,-0.438616238538527,-0.444122144570429,-0.449611329654607,-0.455083587126344,-0.46053871095824,-0.465976495767966,-0.471396736825998,-0.476799230063322,-0.482183772079123,-0.487550160148436,-0.492898192229784,-0.498227666972782,-0.503538383725717,-0.508830142543107,-0.514102744193222,-0.51935599016559,-0.524589682678469,-0.529803624686295,-0.534997619887097,-0.540171472729893,-0.545324988422046,-0.550457972936605,-0.555570233019602,-0.560661576197336,-0.565731810783613,-0.570780745886967,-0.575808191417845,-0.580813958095764,-0.585797857456439,-0.590759701858874,-0.595699304492433,-0.600616479383869,-0.605511041404325,-0.610382806276309,-0.615231590580627,-0.620057211763289,-0.624859488142386,-0.629638238914927,-0.634393284163645,-0.639124444863776,-0.643831542889791,-0.648514401022112,-0.653172842953776,-0.657806693297079,-0.662415777590172,-0.666999922303637,-0.671558954847018,-0.676092703575316,-0.680600997795453,-0.6850836677727,-0.689540544737067,-0.693971460889654,-0.698376249408973,-0.702754744457225,-0.707106781186547,-0.711432195745217,-0.715730825283819,-0.720002507961382,-0.724247082951467,-0.728464390448225,-0.732654271672413,-0.73681656887737,-0.740951125354959,-0.745057785441466,-0.749136394523459,-0.753186799043612,-0.757208846506485,-0.761202385484262,-0.765167265622459,-0.76910333764558,-0.773010453362737,-0.776888465673232,-0.780737228572094,-0.784556597155575,-0.788346427626606,-0.792106577300212,-0.795836904608883,-0.799537269107905,-0.803207531480645,-0.806847553543799,-0.810457198252595,-0.814036329705948,-0.817584813151584,-0.821102514991105,-0.824589302785025,-0.828045045257756,-0.831469612302545,-0.83486287498638,-0.838224705554838,-0.841554977436898,-0.844853565249707,-0.848120344803297,-0.851355193105265,-0.8545579883654,-0.857728610000272,-0.860866938637767,-0.863972856121587,-0.867046245515693,-0.870086991108711,-0.87309497841829,-0.876070094195407,-0.879012226428634,-0.881921264348355,-0.884797098430938,-0.887639620402854,-0.890448723244758,-0.893224301195515,-0.895966249756185,-0.898674465693954,-0.901348847046022,-0.903989293123443,-0.906595704514915,-0.909167983090522,-0.91170603200543,-0.914209755703531,-0.916679059921043,-0.919113851690058,-0.921514039342042,-0.923879532511287,-0.926210242138311,-0.928506080473215,-0.930766961078984,-0.932992798834739,-0.935183509938948,-0.937339011912575,-0.93945922360219,-0.941544065183021,-0.94359345816196,-0.945607325380521,-0.947585591017741,-0.949528180593037,-0.951435020969008,-0.953306040354194,-0.955141168305771,-0.956940335732209,-0.958703474895871,-0.960430519415566,-0.962121404269042,-0.96377606579544,-0.965394441697689,-0.966976471044852,-0.968522094274417,-0.970031253194544,-0.971503890986252,-0.97293995220556,-0.974339382785576,-0.975702130038528,-0.977028142657754,-0.978317370719627,-0.97956976568544,-0.98078528040323,-0.981963869109555,-0.983105487431216,-0.984210092386929,-0.985277642388941,-0.986308097244599,-0.987301418157858,-0.988257567730749,-0.989176509964781,-0.990058210262297,-0.99090263542778,-0.991709753669099,-0.99247953459871,-0.993211949234794,-0.993906970002356,-0.994564570734255,-0.995184726672197,-0.99576741446766,-0.996312612182778,-0.996820299291166,-0.99729045667869,-0.997723066644192,-0.998118112900149,-0.998475580573295,-0.998795456205172,-0.999077727752645,-0.99932238458835,-0.999529417501093,-0.999698818696204,-0.999830581795823,-0.999924701839145,-0.999981175282601,-1,-0.999981175282601,-0.999924701839145,-0.999830581795823,-0.999698818696204,-0.999529417501093,-0.99932238458835,-0.999077727752645,-0.998795456205172,-0.998475580573295,-0.998118112900149,-0.997723066644192,-0.99729045667869,-0.996820299291166,-0.996312612182778,-0.99576741446766,-0.995184726672197,-0.994564570734256,-0.993906970002356,-0.993211949234795,-0.99247953459871,-0.991709753669099,-0.99090263542778,-0.990058210262297,-0.989176509964781,-0.988257567730749,-0.987301418157858,-0.986308097244599,-0.985277642388941,-0.984210092386929,-0.983105487431216,-0.981963869109555,-0.98078528040323,-0.97956976568544,-0.978317370719628,-0.977028142657754,-0.975702130038528,-0.974339382785576,-0.97293995220556,-0.971503890986252,-0.970031253194544,-0.968522094274417,-0.966976471044852,-0.965394441697689,-0.96377606579544,-0.962121404269042,-0.960430519415566,-0.958703474895871,-0.956940335732209,-0.955141168305771,-0.953306040354194,-0.951435020969008,-0.949528180593037,-0.947585591017741,-0.945607325380521,-0.94359345816196,-0.941544065183021,-0.93945922360219,-0.937339011912575,-0.935183509938948,-0.932992798834739,-0.930766961078984,-0.928506080473216,-0.926210242138311,-0.923879532511287,-0.921514039342042,-0.919113851690058,-0.916679059921043,-0.914209755703531,-0.91170603200543,-0.909167983090523,-0.906595704514915,-0.903989293123443,-0.901348847046022,-0.898674465693954,-0.895966249756185,-0.893224301195515,-0.890448723244758,-0.887639620402854,-0.884797098430938,-0.881921264348355,-0.879012226428634,-0.876070094195407,-0.87309497841829,-0.870086991108711,-0.867046245515693,-0.863972856121587,-0.860866938637767,-0.857728610000272,-0.854557988365401,-0.851355193105265,-0.848120344803297,-0.844853565249707,-0.841554977436898,-0.838224705554838,-0.83486287498638,-0.831469612302545,-0.828045045257756,-0.824589302785025,-0.821102514991105,-0.817584813151584,-0.814036329705949,-0.810457198252595,-0.806847553543799,-0.803207531480645,-0.799537269107905,-0.795836904608884,-0.792106577300212,-0.788346427626606,-0.784556597155575,-0.780737228572095,-0.776888465673232,-0.773010453362737,-0.76910333764558,-0.765167265622459,-0.761202385484262,-0.757208846506485,-0.753186799043613,-0.749136394523459,-0.745057785441466,-0.740951125354959,-0.73681656887737,-0.732654271672413,-0.728464390448225,-0.724247082951467,-0.720002507961382,-0.715730825283819,-0.711432195745217,-0.707106781186548,-0.702754744457225,-0.698376249408973,-0.693971460889654,-0.689540544737067,-0.6850836677727,-0.680600997795453,-0.676092703575316,-0.671558954847019,-0.666999922303638,-0.662415777590172,-0.657806693297079,-0.653172842953777,-0.648514401022112,-0.643831542889792,-0.639124444863776,-0.634393284163646,-0.629638238914927,-0.624859488142386,-0.620057211763289,-0.615231590580627,-0.610382806276309,-0.605511041404326,-0.600616479383869,-0.595699304492433,-0.590759701858874,-0.585797857456439,-0.580813958095765,-0.575808191417845,-0.570780745886967,-0.565731810783614,-0.560661576197337,-0.555570233019602,-0.550457972936605,-0.545324988422047,-0.540171472729893,-0.534997619887097,-0.529803624686295,-0.524589682678469,-0.51935599016559,-0.514102744193222,-0.508830142543107,-0.503538383725718,-0.498227666972782,-0.492898192229784,-0.487550160148436,-0.482183772079123,-0.476799230063322,-0.471396736825998,-0.465976495767967,-0.46053871095824,-0.455083587126344,-0.449611329654607,-0.44412214457043,-0.438616238538528,-0.433093818853152,-0.427555093430282,-0.422000270799799,-0.416429560097637,-0.410843171057904,-0.40524131400499,-0.399624199845647,-0.393992040061048,-0.388345046698827,-0.38268343236509,-0.377007410216418,-0.371317193951838,-0.365612997804774,-0.359895036534988,-0.35416352542049,-0.348418680249435,-0.342660717311995,-0.33688985339222,-0.331106305759877,-0.325310292162263,-0.319502030816015,-0.313681740398891,-0.307849640041535,-0.302005949319228,-0.296150888243624,-0.290284677254462,-0.284407537211272,-0.278519689385054,-0.272621355449949,-0.266712757474898,-0.260794117915276,-0.254865659604514,-0.24892760574572,-0.242980179903264,-0.237023605994368,-0.231058108280671,-0.225083911359793,-0.21910124015687,-0.213110319916092,-0.207111376192218,-0.201104634842092,-0.195090322016129,-0.189068664149806,-0.183039887955141,-0.177004220412149,-0.170961888760302,-0.16491312048997,-0.158858143333862,-0.152797185258444,-0.146730474455362,-0.140658239332849,-0.134580708507126,-0.128498110793794,-0.122410675199216,-0.116318630911905,-0.110222207293883,-0.104121633872055,-0.0980171403295605,-0.0919089564971328,-0.0857973123444402,-0.0796824379714307,-0.0735645635996674,-0.0674439195636642,-0.061320736302209,-0.0551952443496897,-0.049067674327418,-0.0429382569349411,-0.0368072229413593,-0.0306748031766365,-0.0245412285229124,-0.0184067299058052,-0.0122715382857205,-0.00613588464915442,-1.83697019872103E-016,0.00613588464915405,0.0122715382857201,0.0184067299058048,0.024541228522912,0.0306748031766361,0.036807222941359,0.0429382569349407,0.0490676743274177,0.0551952443496894,0.0613207363022086,0.0674439195636639,0.073564563599667,0.0796824379714303,0.0857973123444399,0.0919089564971325,0.0980171403295601,0.104121633872055,0.110222207293883,0.116318630911904,0.122410675199216,0.128498110793793,0.134580708507126,0.140658239332849,0.146730474455362,0.152797185258443,0.158858143333861,0.164913120489969,0.170961888760301,0.177004220412149,0.183039887955141,0.189068664149806,0.195090322016128,0.201104634842092,0.207111376192218,0.213110319916092,0.21910124015687,0.225083911359793,0.231058108280671,0.237023605994367,0.242980179903264,0.24892760574572,0.254865659604514,0.260794117915276,0.266712757474898,0.272621355449948,0.278519689385053,0.284407537211272,0.290284677254462,0.296150888243623,0.302005949319228,0.307849640041535,0.313681740398891,0.319502030816015,0.325310292162263,0.331106305759876,0.33688985339222,0.342660717311995,0.348418680249434,0.35416352542049,0.359895036534988,0.365612997804774,0.371317193951837,0.377007410216418,0.38268343236509,0.388345046698826,0.393992040061048,0.399624199845646,0.40524131400499,0.410843171057904,0.416429560097637,0.422000270799799,0.427555093430282,0.433093818853152,0.438616238538527,0.444122144570429,0.449611329654607,0.455083587126344,0.46053871095824,0.465976495767966,0.471396736825998,0.476799230063322,0.482183772079122,0.487550160148436,0.492898192229784,0.498227666972781,0.503538383725718,0.508830142543107,0.514102744193221,0.519355990165589,0.524589682678469,0.529803624686295,0.534997619887097,0.540171472729892,0.545324988422046,0.550457972936605,0.555570233019602,0.560661576197336,0.565731810783613,0.570780745886967,0.575808191417845,0.580813958095765,0.585797857456439,0.590759701858874,0.595699304492433,0.600616479383869,0.605511041404325,0.610382806276309,0.615231590580627,0.620057211763289,0.624859488142386,0.629638238914927,0.634393284163646,0.639124444863776,0.643831542889791,0.648514401022112,0.653172842953777,0.657806693297079,0.662415777590171,0.666999922303638,0.671558954847018,0.676092703575316,0.680600997795453,0.6850836677727,0.689540544737067,0.693971460889654,0.698376249408972,0.702754744457225,0.707106781186547,0.711432195745216,0.715730825283819,0.720002507961382,0.724247082951467,0.728464390448225,0.732654271672413,0.73681656887737,0.740951125354959,0.745057785441465,0.749136394523459,0.753186799043612,0.757208846506484,0.761202385484262,0.765167265622459,0.769103337645579,0.773010453362737,0.776888465673233,0.780737228572094,0.784556597155575,0.788346427626606,0.792106577300212,0.795836904608883,0.799537269107905,0.803207531480645,0.806847553543799,0.810457198252595,0.814036329705948,0.817584813151584,0.821102514991105,0.824589302785025,0.828045045257755,0.831469612302545,0.83486287498638,0.838224705554838,0.841554977436899,0.844853565249707,0.848120344803297,0.851355193105265,0.854557988365401,0.857728610000272,0.860866938637767,0.863972856121587,0.867046245515693,0.870086991108711,0.87309497841829,0.876070094195407,0.879012226428633,0.881921264348355,0.884797098430937,0.887639620402854,0.890448723244758,0.893224301195515,0.895966249756185,0.898674465693954,0.901348847046022,0.903989293123443,0.906595704514916,0.909167983090522,0.91170603200543,0.914209755703531,0.916679059921043,0.919113851690058,0.921514039342042,0.923879532511286,0.926210242138311,0.928506080473215,0.930766961078984,0.932992798834739,0.935183509938947,0.937339011912575,0.93945922360219,0.941544065183021,0.94359345816196,0.945607325380521,0.947585591017741,0.949528180593037,0.951435020969008,0.953306040354194,0.955141168305771,0.956940335732209,0.958703474895871,0.960430519415566,0.962121404269042,0.96377606579544,0.965394441697689,0.966976471044852,0.968522094274417,0.970031253194544,0.971503890986252,0.97293995220556,0.974339382785576,0.975702130038528,0.977028142657754,0.978317370719628,0.97956976568544,0.98078528040323,0.981963869109555,0.983105487431216,0.984210092386929,0.985277642388941,0.986308097244599,0.987301418157858,0.988257567730749,0.989176509964781,0.990058210262297,0.99090263542778,0.991709753669099,0.99247953459871,0.993211949234794,0.993906970002356,0.994564570734255,0.995184726672197,0.99576741446766,0.996312612182778,0.996820299291166,0.99729045667869,0.997723066644192,0.998118112900149,0.998475580573295,0.998795456205172,0.999077727752645,0.999322384588349,0.999529417501093,0.999698818696204,0.999830581795823,0.999924701839145,0.999981175282601, - 1.0 -}; - -const float lut_sin_half_f = LUT_SIN_HALF; - -inline static float _xfade( float a, float b, float c ){ - return (a + c*(b-a)); -} - -static float _sin( float in ){ - float fix = (1.0 - in) * lut_sin_half_f; - uint32_t ix = (uint32_t)fix; - float* lut = (float*) &sine_lut[ix]; - return _xfade( *lut - , lut[1] - , (fix - (float)ix) - ); -} - // in (0 .. 1) if not using _sin // coeff (0 .. 2) static float folder(float in, float coeff){ - // in = _sin(in); // sin then back convert +/-1 to (0..1) - float gain = 1.2 * coeff * coeff; // exponential (^2) application // apply the scaled coeff as a gain constant @@ -156,16 +132,33 @@ static float folder(float in, float coeff){ // return (win2 & 1) ? (in - offset) : (offset - in) ; } +inline static float _xfade( float a, float b, float c ){ + return (a + c*(b-a)); +} + +// LUTs for shaping for easier customization & much faster operation +#include "lin2expo.h" +#include "lin2logo.h" // retval & density: 0 .. 1 // density is a crossfade from expo -> linear -> log // returns a 0..1 float which distorts the midpoint of the waveform up/down static float densify(float v, float density){ if(density<0.5f){ // less dense. use exponential - float expo = powf(2.f, 10.f * (v - 1.f)); + float vv = v * 255.f; // convert 0,1 to 0,255 + int left = (int)vv; + float c = vv - (float)left; + float expo = _xfade(lut_expo_256[left], lut_expo_256[left+1], c); + + // float expo = powf(2.f, 10.f * (v - 1.f)); return _xfade(expo, v, density * 2.f); // at 1, we want linear } else if(density > 0.5f){ // more dense. use logarithmic - float log = 1.f - powf(2.f, -10.f * v); - return _xfade(v, log, (density * 2.f)-1.f); // at 0, we want linear + float vv = v * 255.f; // convert 0,1 to 0,255 + int left = (int)vv; + float c = vv - (float)left; + float logo = _xfade(lut_logo_256[left], lut_logo_256[left+1], c); + + // float log = 1.f - powf(2.f, -10.f * v); + return _xfade(v, logo, (density * 2.f)-1.f); // at 0, we want linear } else { return v; } diff --git a/ll/adc.c b/ll/adc.c index 789a6ca..0b2eb72 100644 --- a/ll/adc.c +++ b/ll/adc.c @@ -1,7 +1,6 @@ #include "adc.h" #include -// #include // HAL_Delay() #include "interrupts.h" #include "../lib/caw.h" @@ -10,13 +9,9 @@ static ADC_HandleTypeDef AdcHandle; static ADC_HandleTypeDef AdcHandle2; static ADC_ChannelConfTypeDef sConfig; -#define ADC_CHANNELS 3 -#define ADC_BUFFERS 2 -static volatile uint16_t adc_raw[ADC_CHANNELS*ADC_BUFFERS*2]; // 6 channels, -static volatile uint16_t* adc_raw2 = &adc_raw[ADC_CHANNELS*ADC_BUFFERS*1]; // second 3 channels +static volatile uint16_t adc_direct[2][6]; - -static void start_conversion(void); +static void next_conversion(void); void ADC_Init(void){ AdcHandle.Instance = ADC1; @@ -25,15 +20,15 @@ void ADC_Init(void){ AdcHandle.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV4; AdcHandle.Init.Resolution = ADC_RESOLUTION_12B; AdcHandle.Init.ScanConvMode = ADC_SCAN_ENABLE; - AdcHandle.Init.ContinuousConvMode = ENABLE; // i think disable - AdcHandle.Init.NbrOfConversion = 3; // scan all 5 chans on ADC1 - AdcHandle.Init.DiscontinuousConvMode = DISABLE; // i think enable + AdcHandle.Init.ContinuousConvMode = ENABLE; + AdcHandle.Init.NbrOfConversion = 3; + AdcHandle.Init.DiscontinuousConvMode = DISABLE; AdcHandle.Init.NbrOfDiscConversion = 3; AdcHandle.Init.ExternalTrigConv = ADC_SOFTWARE_START; AdcHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; AdcHandle.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1; AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT; - AdcHandle.Init.DMAContinuousRequests = ENABLE; + AdcHandle.Init.DMAContinuousRequests = DISABLE; AdcHandle.Init.EOCSelection = ADC_EOC_SEQ_CONV; if( HAL_ADC_Init( &AdcHandle ) != HAL_OK ){ @@ -58,23 +53,21 @@ void ADC_Init(void){ if( HAL_ADC_ConfigChannel(&AdcHandle, &sConfig) != HAL_OK ) Caw_printf("HAL_ADC_ConfigChannel failed\n"); - - AdcHandle2.Instance = ADC2; HAL_ADC_DeInit(&AdcHandle2); AdcHandle2.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV4; AdcHandle2.Init.Resolution = ADC_RESOLUTION_12B; - AdcHandle2.Init.ScanConvMode = ADC_SCAN_ENABLE; - AdcHandle2.Init.ContinuousConvMode = ENABLE; // i think disable - AdcHandle2.Init.NbrOfConversion = 3; // scan all 5 chans on ADC1 - AdcHandle2.Init.DiscontinuousConvMode = DISABLE; // i think enable + AdcHandle2.Init.ScanConvMode = ADC_SCAN_ENABLE; // enable this to allow use of the internal MUX + AdcHandle2.Init.ContinuousConvMode = ENABLE; // enable means "one conversion" is the whole sequence + AdcHandle2.Init.NbrOfConversion = 3; // scan 3 chans on ADC + AdcHandle2.Init.DiscontinuousConvMode = DISABLE; // only used if doing a fancy irregular channel sequence AdcHandle2.Init.NbrOfDiscConversion = 3; AdcHandle2.Init.ExternalTrigConv = ADC_SOFTWARE_START; AdcHandle2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; AdcHandle2.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1; AdcHandle2.Init.DataAlign = ADC_DATAALIGN_RIGHT; - AdcHandle2.Init.DMAContinuousRequests = ENABLE; + AdcHandle2.Init.DMAContinuousRequests = DISABLE; // ENABLE this along with DMA circular buffer mode for continuous AdcHandle2.Init.EOCSelection = ADC_EOC_SEQ_CONV; if( HAL_ADC_Init( &AdcHandle2 ) != HAL_OK ){ @@ -95,19 +88,20 @@ void ADC_Init(void){ Caw_printf("HAL_ADC_ConfigChannel failed\n"); - start_conversion(); + next_conversion(); } -static void start_conversion(void){ +static int double_buffer = 0; +static void next_conversion(void){ if( HAL_ADC_Start_DMA( &AdcHandle - , (uint32_t*)adc_raw - , ADC_CHANNELS*ADC_BUFFERS + , (uint32_t*)&adc_direct[double_buffer][0] + , 3 ) != HAL_OK ){ Caw_printf("HAL_ADC_Start_DMA failed, retrying..\n"); // HAL_Delay(10); if( HAL_ADC_Start_DMA( &AdcHandle - , (uint32_t*)adc_raw - , ADC_CHANNELS*ADC_BUFFERS + , (uint32_t*)&adc_direct[double_buffer][0] + , 3 ) != HAL_OK ){ Caw_printf("HAL_ADC_Start_DMA failed again, ignoring\n"); return; @@ -115,14 +109,14 @@ static void start_conversion(void){ } if( HAL_ADC_Start_DMA( &AdcHandle2 - , (uint32_t*)adc_raw2 - , ADC_CHANNELS*ADC_BUFFERS + , (uint32_t*)&adc_direct[double_buffer][3] + , 3 ) != HAL_OK ){ Caw_printf("HAL_ADC_Start_DMA failed, retrying..\n"); // HAL_Delay(10); if( HAL_ADC_Start_DMA( &AdcHandle2 - , (uint32_t*)adc_raw2 - , ADC_CHANNELS*ADC_BUFFERS + , (uint32_t*)&adc_direct[double_buffer][3] + , 3 ) != HAL_OK ){ Caw_printf("HAL_ADC_Start_DMA failed again, ignoring\n"); return; @@ -159,7 +153,7 @@ void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc){ hdma_adc.Init.MemInc = DMA_MINC_ENABLE; hdma_adc.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; hdma_adc.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; - hdma_adc.Init.Mode = DMA_CIRCULAR; + hdma_adc.Init.Mode = DMA_NORMAL; hdma_adc.Init.Priority = DMA_PRIORITY_HIGH; hdma_adc.Init.FIFOMode = DMA_FIFOMODE_DISABLE; hdma_adc.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL; @@ -197,7 +191,7 @@ void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc){ hdma_adc2.Init.MemInc = DMA_MINC_ENABLE; hdma_adc2.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; hdma_adc2.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; - hdma_adc2.Init.Mode = DMA_CIRCULAR; + hdma_adc2.Init.Mode = DMA_NORMAL; hdma_adc2.Init.Priority = DMA_PRIORITY_HIGH; hdma_adc2.Init.FIFOMode = DMA_FIFOMODE_DISABLE; hdma_adc2.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL; @@ -214,17 +208,30 @@ void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc){ } } -static int read_half[2] = {0,0}; -uint16_t ADC_get(int chan){ // inversion & bipolar shaping - // 1,2,3,1,2,3,4,5,6,4,5,6 - if(chan<3){ - chan += read_half[0] * ADC_CHANNELS; - } else { - chan -= ADC_CHANNELS; // 3-5 down to 0-2 - chan += read_half[1] * ADC_CHANNELS; // +0 or +3 -> 0-2 / 3-5 - chan += ADC_CHANNELS * 2; // += 6 -> 6-8 / 9-11 +// return a pointer to an array that can be accesed directly with enum names +uint16_t* ADC_get_buffer(void){ + return (uint16_t*)adc_direct[double_buffer]; +} + +uint16_t ADC_get(int chan){ + return (uint16_t)adc_direct[double_buffer][chan]; +} + +// call this at the start of your tight audio callback +// this will setup the ADC_get() function to point to the valid data +static int completed = 0; +uint16_t* ADC_next_frame(void){ + // check we completed the last read (raise warning if not, help with configuring speeds) + if(completed==0){ + Caw_printf("ADC: dma wasn't done\n\r"); } - return adc_raw[chan]; + // flip read/write heads + double_buffer ^= 1; + + // start next cycle + next_conversion(); + + return ADC_get_buffer(); } @@ -237,30 +244,9 @@ void DMA2_Stream2_IRQHandler(void){ HAL_DMA_IRQHandler(AdcHandle2.DMA_Handle); } -static int counter = 0; -void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc){ - counter++; - if(hadc == &AdcHandle){ - read_half[0] = 0; - } else if(hadc == &AdcHandle2){ - read_half[1] = 0; - } -} void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc){ - counter++; - if(hadc == &AdcHandle){ - read_half[0] = 1; - } else if(hadc == &AdcHandle2){ - read_half[1] = 1; - } + completed++; } void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc){ Caw_printf("adc error\n\r"); } - -// debug / timing / optimization -int ADC_get_count(void){ - int c = counter; - counter = 0; - return c; -} diff --git a/ll/adc.h b/ll/adc.h index 8a2d7bd..14530f5 100644 --- a/ll/adc.h +++ b/ll/adc.h @@ -23,3 +23,6 @@ void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc); void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc); int ADC_get_count(void); + +// collect next frame, and return last received frame +uint16_t* ADC_next_frame(void); diff --git a/ll/adda.c b/ll/adda.c index b7b21b2..2f4d165 100644 --- a/ll/adda.c +++ b/ll/adda.c @@ -8,43 +8,47 @@ static uint32_t stepper[16] = {0}; static uint32_t vals[4] = {0}; // direct set values for non-folds -static void write_to_dac_buffer(uint32_t* dest, int channel, int sample, int src); +static void write_to_dac_buffer(uint32_t* dest, int channel, int src); +// single sample mode. assume bsize == 1 void ADDA_BlockProcess(uint32_t* dest, int bsize){ + uint16_t* adc = ADC_next_frame(); + uint32_t samp = 0; // smooth & stepped modulation - for(int i=0; i> 3; // 1 if an upper set. upper 8 are 1 step ahead of lower - int ix = sample * 16; // for each sample, step forward by 16 samples (there are 16 channels) - dest[jj+jx+ix] = (jj<<11) | (src & 0xfff); // hard cut values to 12bit range + dest[jj+jx] = (jj<<11) | (src & 0xfff); // hard cut values to 12bit range } diff --git a/main.c b/main.c index 28bcca3..c608ac6 100755 --- a/main.c +++ b/main.c @@ -72,7 +72,8 @@ int main(void){ stepped_init(); sfold_init(12); - DAC_Init(32, 16); // 32 samples per block, 16 channels + // DAC_Init(32, 16); // 32 samples per block, 16 channels + DAC_Init(1, 16); // DISABLE BLOCK PROCESSING, single sample! minimal latency DAC_Start(); uint32_t last_tick = HAL_GetTick(); @@ -103,7 +104,7 @@ int main(void){ a >>= 12; // divide by 4096 lights_xset(stepped_ix()); // Caw_printf("%i\n\r",a); - Caw_printf("%i\n\r",ADC_get_count()); + // Caw_printf("%i\n\r",ADC_get_count()); } for(int i=0; i<6; i++){ // ADDA_set_val(i, ADC_get(i)); diff --git a/util/lut_expo.lua b/util/lut_expo.lua new file mode 100644 index 0000000..5761b6f --- /dev/null +++ b/util/lut_expo.lua @@ -0,0 +1,55 @@ +header = [[ +// THIS FILE IS AUTOGENERATED // +// DO NOT EDIT THIS MANUALLY // + +#pragma once + +const float lut_expo_256[256] = { + ]] + +footer = "\n};\n" + +-- expects values 0..255 +-- outputs must be 0.f~1.f +function expo(i) + local c = i / 255 -- convert 0,255 into 0,1 + -- return 2 ^ (10 * (c-1)) -- expo approximation (obvs could do real expo if we want?) + return 1 - math.sqrt(1 - c^2) -- expo as a quarter circle for max smoothness +end + +function logo(i) + local c = i / 255 -- convert 0,255 into 0,1 + -- return 1 - (2 ^ (-10 * c)) -- log approximation (obvs could do real expo if we want?) + return math.sqrt(2*c - c^2) -- log as a quarter circle for max smoothness +end + +function build_table() + s = header + t = {} + for i=0,255 do + t[i+1] = expo(i) + end + print(t[1]) + print(t[2]) + print(t[3]) + print(t[4]) + print(t[127]) + print(t[128]) + print(t[255]) + print(t[256]) + s = s .. table.concat(t, ", ") + return s .. footer +end + +local out_file = arg[1] + +-- build_table() + +do + f = io.open(out_file, 'w') + f:write(build_table()) + f:close() +end + +-- example usage: +-- lua scripts/lin2exp.lua lib/lin2exp.h diff --git a/util/lut_logo.lua b/util/lut_logo.lua new file mode 100644 index 0000000..3d4e290 --- /dev/null +++ b/util/lut_logo.lua @@ -0,0 +1,50 @@ +header = [[ +// THIS FILE IS AUTOGENERATED // +// DO NOT EDIT THIS MANUALLY // + +#pragma once + +const float lut_logo_256[256] = { + ]] + +footer = "\n};\n" + +-- expects values 0..255 +-- outputs must be 0.f~1.f + +function logo(i) + local c = i / 255 -- convert 0,255 into 0,1 + -- return 1 - (2 ^ (-10 * c)) -- log approximation (obvs could do real log if we want?) + return math.sqrt(2*c - c^2) -- log as a quarter circle for max smoothness +end + +function build_table() + s = header + t = {} + for i=0,255 do + t[i+1] = logo(i) + end + print(t[1]) + print(t[2]) + print(t[3]) + print(t[4]) + print(t[127]) + print(t[128]) + print(t[255]) + print(t[256]) + s = s .. table.concat(t, ", ") + return s .. footer +end + +local out_file = arg[1] + +-- build_table() + +do + f = io.open(out_file, 'w') + f:write(build_table()) + f:close() +end + +-- example usage: +-- lua scripts/lin2exp.lua lib/lin2exp.h