From b22074cb98088c559414af0bf56412dee56a6d91 Mon Sep 17 00:00:00 2001 From: Leandro Bolivar Date: Tue, 5 Apr 2022 15:15:25 -0500 Subject: [PATCH] Improved harmonik functionality by adding an additional harmonic oscillator --- README.md | 4 +- builds/nts-1/osc/harmon/manifest.json | 4 +- builds/nts-1/osc/kord/manifest.json | 2 +- oscillators/nts-1/harmonikv1.0.ntkdigunit | Bin 1640 -> 0 bytes .../nts-1/subharmonikorgv1.1.ntkdigunit | Bin 1846 -> 0 bytes src/nts-1/osc/harmon/harmon.cpp | 35 ++++++++---------- src/nts-1/osc/harmon/harmon.hpp | 5 +-- 7 files changed, 21 insertions(+), 29 deletions(-) delete mode 100644 oscillators/nts-1/harmonikv1.0.ntkdigunit delete mode 100644 oscillators/nts-1/subharmonikorgv1.1.ntkdigunit diff --git a/README.md b/README.md index 048017f..1dfb1ba 100644 --- a/README.md +++ b/README.md @@ -20,9 +20,7 @@ In order to run user units built with SDK version 1.1-0, the following firmware ## Compiled Oscillators -The compiled oscillators are found in the oscillators folder under its respective platform name: -- nts-1. -- minilogue-xd. +The compiled oscillators are found in the releases section of this repo. ## Prerequisites diff --git a/builds/nts-1/osc/harmon/manifest.json b/builds/nts-1/osc/harmon/manifest.json index 95169ce..3162ea4 100644 --- a/builds/nts-1/osc/harmon/manifest.json +++ b/builds/nts-1/osc/harmon/manifest.json @@ -6,15 +6,15 @@ "api" : "1.1-0", "dev_id" : 0, "prg_id" : 0, - "version" : "0.1-0", + "version" : "1.0-0", "name" : "harm", "num_param" : 6, "params" : [ - ["ROOT", 0, 100, "%"], ["P1", 0, 100, "%"], ["P2", 0, 100, "%"], ["P3", 0, 100, "%"], ["P4", 0, 100, "%"], + ["P5", 0, 100, "%"], ["SPRD", 0, 2, "%"] ] } diff --git a/builds/nts-1/osc/kord/manifest.json b/builds/nts-1/osc/kord/manifest.json index f65c410..d6add60 100644 --- a/builds/nts-1/osc/kord/manifest.json +++ b/builds/nts-1/osc/kord/manifest.json @@ -6,7 +6,7 @@ "api" : "1.1-0", "dev_id" : 0, "prg_id" : 0, - "version" : "0.1-0", + "version" : "1.0-0", "name" : "kord", "num_param" : 6, "params" : [ diff --git a/oscillators/nts-1/harmonikv1.0.ntkdigunit b/oscillators/nts-1/harmonikv1.0.ntkdigunit deleted file mode 100644 index 094bdee681bfa6b519750ed9ccf21a134c0b12a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1640 zcmWIWW@h1H0D&_JpMt;)D8b1f!;q0!l$)QInXMlh!pXqgAO9r*gi9;985mi(a#HWIz2!<@vMqlujJ3{!q97dwv%~1F!Ow zOpbHgX5>UHiAtIm#Ldn4hV5{i+QL20+O`_l5ttuq4w`!aKtNz_Z}}98B}#Py&-2#FZ`Za29Xe4TZ>_jbU!dRc(Q4NgL%YTm zhiCjbU(S1c^27FeOD*?r|I@alh_pMsYIAm)ICD$c-Zx#ll1`h3r(SvxYR7Z4Yx&tW z^@x9O4QgM-?R2e-QamPBTy<1JA<9W*U%BA9a!qWYE zFrN-0#{Qj1pKQcW>c{5g5YPb6*94eXg%S0Zdv z(^cQ@SAP68=^w}T`Y%7Fp2oNSx^VFCPL`Sj|J#KAiyr5jCM$e7`;hCJEngh8zVaxp zyf%OK3KuPxO|M=Zv7dZu<4pg)sI9r7#`mhucD#EUHZ|hv!yDxliJ7eui=Irfwf=7Q zw&&anvw1xE?%R~BC&-?-JwY{ZZ=2*^u9;?Du8DCOTSO;6)V+8%YF(Go=@m_@=j_np zf7Hfxcwcw)R=uA=XQ%1^Y*T*rakAC@W7d|LdoJF)>iBAX$)8Js_itX+^pDP-G(WaL z<7jZ4P=@9`Edy7L(yHn9Up0RGI~P+nqgbaR;bYjtAMdxZl?&W{yjv{NRqUI_C&TZJ z6Ex@Z&eUsZ5jf9f@%i|n(44<*(E_~NHRO{HzS_37JMQTEj8D{e-59 z6}x;*W=Nc=kH2xZt*Sqc^RMOfIfs4+%=qLxGvhx~fHxzP95b%sR03MC3NXBN1Tm2c zS5`>jidGOpjKfv5LW~2JvJ6Waoso@0D`v;yu_lmZNw Tt6AAV-eU$rR-j&ARuB&WeuS~F diff --git a/oscillators/nts-1/subharmonikorgv1.1.ntkdigunit b/oscillators/nts-1/subharmonikorgv1.1.ntkdigunit deleted file mode 100644 index 0f013c65c5069b6d03f43fc985c6e5c0f788523d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1846 zcmWIWW@h1H00HKe(}TbaD8bJl!%$qBl#y7Jo1d4NonMr$9~#2Rz}#BfoB+b572FJr zEMFNJ7+6GrS^|IufoKkfpDU&Z?TTOTbqUD(36z$>G$=PQFEcH*xI{0jI6n_;Y8lYP zPn8&^w)Q!4GbswRzW=Swws7{*sDKN)R$?V9`~(v-RoAXwaa;A*`?otn#H7zAO5Feb zVQ)0s*9n`SI9V|zcf60jb8#apzx!j8swHch_Oz@EP#3Lmd?9_=Eu^()!pHV255rt% zevL5q=T%&9t$N|K@YP+x-BnZ1X$Nns4=K8<@;j^kpMloi&38UV)XivH@FMW;9+x@1 zkzQ+?G*uS{h%;PU?r>sSU0}A0gb_o}p%rab_ACC`XFcR!-PUvbMg~Y^pY|mp@bvs zr-sD)M2AY)KacY|Eqgh8PG4O66z^?c`*lQ<59r-)NR-~8BEhL9ByZ)T^KE5kr<%If z+T2S~6$;HhRq+)UIu-L0Et1@G^lr+{v6-4Pi+9=-iOJ_mzCSTLSKz$t$6T=q?D2cd z@9%tG^ZfhYb0@$5-e+xMP$8GtQxQ_jCRh~naKhq^Y?kL5SQGAYo3Rvskv}iWUF5>V z9v>+9JF4D%S5Vz*c~k$=;>vqRd~YAETDtGQ`Acm<+4_t1J8w^_KW+2w>H4!QA67>n z)vIrpmux?C$62|}gxBIf!|Rsf>I1JtRUW5lTF8VnGaoyi?JJ-EH&WI-Aa05$A_lI2eW4>9cioZ-hhWKs#{4#B_y0^Tn`9)qJvaN6 z%WdAwMc4iws`Z;D6cHw@^U3hY#@b5W#^ssv`3!P9znY3A?ln)H=kUn%j+$zn?x(!d zwQnX1dGyUzmwD~Vvue}L^9GZJc!l5G^YISLes(F~{~9}&C_CFX{Y!sbGS-#uo^Ip* zcXhY%th?u@8}8qjv2^mgDc@X+>+h@b*F^iAkUK3L-t|zxcT!la#Qdf?YhP;E=AOD& zX62Rj*L9YU_!qq$^@eBPoi-9+IxlJD_570jor-dqirV--<82~yXQ!{e`?Kiovvb!z z@Kv_e#zKzOQ#QeZ6QUD!Ki8!D{wG*)4W+8SZR37rNoZj=Xtn zHSDfThpksEKQw#s_RBo=KLy!rmZx>^bU(CXX7bNo*Tu^NC2v-hZ~C`+`?_t;yV$ct zU#!n7Wid6@H4=?obvN|t61T)vl?&gm+F`r@s%6#s4+4^=VGlRFsC_(lx@fhH&-EhVl?Q7IPV(JZqb8xAyhUAN`I?4!miZE#CYllVVh`$a z{W4?{+opZut88u84U-imOkN&7oY#U`|Ni_Cr+?;^JICsV{R_SGUbcIv9GI}V%64V& zsvjypvcLV^+G77;`-E5atydSG75u8`5|>^XwMd(3^^7UUc3s~#<;zo zIo3>1x4VDy)IZTBe2&b%a_^6ENJmedrx_M@{oyyq#;;idd%P1I6J{;;JUDIjv#Iwl zJICEW|J6Rgn~_P58CO*x0j(4S7~VR9m>3lUE2Lt;s1!hk;;I%Ph5~B{h9!-jn1-TN t5{CeFbhhY{UQJW diff --git a/src/nts-1/osc/harmon/harmon.cpp b/src/nts-1/osc/harmon/harmon.cpp index 09b1302..0f58838 100644 --- a/src/nts-1/osc/harmon/harmon.cpp +++ b/src/nts-1/osc/harmon/harmon.cpp @@ -10,7 +10,6 @@ static Oscillator osc; void OSC_INIT(uint32_t platform, uint32_t api) { osc.drive = 0.f; osc.spread = harmonic; - } static inline float fold(float x) { @@ -47,34 +46,25 @@ void OSC_CYCLE( int32_t *yn, const uint32_t frames ) { - float signals[5] = { 0 }; const float w0 = osc_w0f_for_note((params->pitch)>>8, params->pitch & 0xFF); - const float drive = osc.drive; const float lfo = q31_to_f32(params->shape_lfo); q31_t * __restrict y = (q31_t *)yn; const q31_t * y_e = y + frames; for (; y != y_e; ) { - for (int i = 0; i < 5; i++) { + float sig = 0.f; + for (int i = 0; i < 6; i++) { float p = osc.phases[i]; - float g = osc.gains[i]; int div = spread(i); float w = w0 * div; p = (p < 0.f) ? 1.f - p : p - (uint32_t)p; - float folded = 0.75f * (drive + lfo) * fold(osc_sinf(p)); + float folded = 0.75f * (osc.drive + lfo) * fold(osc_sinf(p)); p = p + folded; - signals[i] = (osc_sinf(p)) * g; + sig += osc_sinf(p) * osc.gains[i]; osc.phases[i] += w; osc.phases[i] -= (uint32_t)osc.phases[i]; } - - // Main signal - float sig = 0.f; - for (int i = 0; i < 5 ; i++) { - sig += signals[i]; - } - sig *= osc.total_gain; *(y++) = f32_to_q31(sig); } @@ -88,24 +78,29 @@ void OSC_NOTEOFF(const user_osc_param_t * const params) { (void)params; } +float scale_input(int value) { + float ratio = (float)value / 100.f; + return ratio / 6.f; +} + void OSC_PARAM(uint16_t index, uint16_t value) { const float valf = param_val_to_f32(value); switch (index) { case k_user_osc_param_id1: - osc.gains[0] = valf; + osc.gains[1] = scale_input(value); break; case k_user_osc_param_id2: - osc.gains[1] = valf; + osc.gains[2] = scale_input(value); break; case k_user_osc_param_id3: - osc.gains[2] = valf; + osc.gains[3] = scale_input(value); break; case k_user_osc_param_id4: - osc.gains[3] = valf; + osc.gains[4] = scale_input(value); break; case k_user_osc_param_id5: - osc.gains[4] = valf; + osc.gains[5] = scale_input(value); break; case k_user_osc_param_id6: switch (value) { @@ -124,7 +119,7 @@ void OSC_PARAM(uint16_t index, uint16_t value) { osc.drive = valf; break; case k_user_osc_param_shiftshape: - osc.total_gain = valf * 5.f; + osc.gains[0] = valf / 6.f; break; default: break; diff --git a/src/nts-1/osc/harmon/harmon.hpp b/src/nts-1/osc/harmon/harmon.hpp index af689ff..13bda90 100644 --- a/src/nts-1/osc/harmon/harmon.hpp +++ b/src/nts-1/osc/harmon/harmon.hpp @@ -12,9 +12,8 @@ typedef enum { } Spread; typedef struct Oscillator { - float phases[5] = { 0 }; - float gains[5]= { 1.f, 0.f, 0.f, 0.f, 0.f }; + float phases[6] = { 0 }; + float gains[6]= { 0.17, 0.f, 0.f, 0.f, 0.f, 0.f }; float drive; Spread spread; - float total_gain; } Oscillator;