Phatline Posted April 28, 2018 Report Share Posted April 28, 2018 (edited) Problems Solution is: were we have to add this to the lokal makefile: Quote first point after adding Math lib, it seems the loading sequence of libraries is wrong. the `__errno' compilation error. To resolve it we have to set the loading sequence, just change this line in your Makefile: LIBS= to LIBS = -lm -lgcc -lc ORGINAL PROBLEM POST Hei. I have made now, a LFO (UP/DOWN Ramp & Triangle), now i need to add a logaritmic ammount to get CURVES/SINEs on the LFO Straight Lines, i want to do this with a Encoder. My LFO Values going from 0-65535 (16bit, AOUT-Ready) My Curve CC also goes from 0-65535 (Curve means Logaritmic) I have to execute this code every milli seconds, to change the AOUT, and every 75ms to update the SCOPE-Display I tryd around and this is code is working with stdi0 and math.h, outside of mios: (Working) #include <stdio.h> #include <math.h> double cc = 32000; double curve = 64000; int endresult; int main (void) { printf("exponential_input 0-65535: "); scanf("%lf", &curve); endresult = cc * (log(curve) / log(cc)); printf (" %d \n", endresult ); return 0; } now in mios my code it is also working when i fill in fixed values: (WORKING) //calculate Exponential double lfo = 65000; double curve = 32000; double lfo_result; lfo_result = lfo * (log(curve) / log(lfo)); if(lfo_result > 65535) { lfo_result = 65535;} if(lfo_result < 1) { lfo_result = 0;} but when i use my arrays instead of this fixed values, i become a error (NOT WORKING) //calculate Exponential double lfo = aout[channel_strip].lfo[y]; double curve = aout[channel_strip].v_cc[26+(y*8)]; double lfo_result; lfo_result = lfo * (log(curve) / log(lfo)); i also tryed: (NOT WORKING) double lfo_result = aout[channel_strip].lfo[y] * ( log(aout[channel_strip].v_cc[26+(y*8)]) / log(aout[channel_strip].lfo[y]) ); error is: (errno) Quote make (im Verzeichnis: /home/triggermatrix/c/Filterbox-V1) rm -f project.hex Creating object file for app.c app.c: In function 'APP_Init': app.c:218:5: warning: pointer targets in passing argument 2 of 'xTaskCreate' differ in signedness [-Wpointer-sign] In file included from app.c:11:0: /home/triggermatrix/mios32/trunk/FreeRTOS/Source/include/task.h:360:13: note: expected 'const char * const' but argument is of type 'signed char *' /home/triggermatrix/mios32_toolchain/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7e-m/libm.a(lib_a-w_log.o): In function `log': w_log.c:(.text.log+0xb8): undefined reference to `__errno' w_log.c:(.text.log+0xc2): undefined reference to `__errno' w_log.c:(.text.log+0xcc): undefined reference to `__errno' collect2: error: ld returned 1 exit status Kompilierung fehlgeschlagen. make: *** [project_build/project.elf] Fehler 1 dont know how to handle this, i need a cc-controlled logaritmic - any ideas? here a goodie: Edited April 29, 2018 by Phatline Quote Link to comment Share on other sites More sharing options...
Antichambre Posted April 28, 2018 Report Share Posted April 28, 2018 It may be better to prepare a log and antilog table then just use multiply, instead of heavy math processing. Best Bruno Quote Link to comment Share on other sites More sharing options...
Phatline Posted April 28, 2018 Author Report Share Posted April 28, 2018 (edited) hei. @ table, na a life-changeable log? table? or a table holds all 16bit possibilitys? [65536][65536] while [lfo_value][curve] - that ram i cant see in a µC (dont say i dont should use 16 bit values, the program doing it well, i have other reasons for that...) such table could calculate in a a background task - with the give CURVE-Parameter,, endlessly, and could be used then live... but in the end i have to ask which value should be which tablecell anyway. @ least i want to try do the math, - and i will see timing then. if there is a way for log with this compiler(gcc?) gcc and frtos/mios? what did i wrong. i tryd double floats... -mike Edited April 28, 2018 by Phatline Quote Link to comment Share on other sites More sharing options...
Phatline Posted April 28, 2018 Author Report Share Posted April 28, 2018 (edited) POST NOT WORKING hmm a workaround, that comes in my mind , while sitting here trinking vodka, set with collected raspberrys in it- i could (if there is no other solution): i could set my CURVE-Encoder (log setting encoder) to count from 0-20 ----curve= 0-19 (instead of 0-65525) then make a switch, not very nice, not very small switch (curve) { case 0: lfo_log = lfo_lin * log(0.1); break; case 1: lfo_log = lfo_lin * log(0.2); break; case 2: lfo_log = lfo_lin * log(0.3); break; case 3: lfo_log = lfo_lin * log(0.4); break; case 4: lfo_log = lfo_lin * log(0.5); break; case 5: lfo_log = lfo_lin * log(0.6); break; case 6: lfo_log = lfo_lin * log(0.7); break; case 7: lfo_log = lfo_lin * log(0.8); break; case 8: lfo_log = lfo_lin * log(0.9); break; case 9: lfo_log = lfo_lin * log(1.0); break; case 10: lfo_log = lfo_lin * log(1.1); break; case 11: lfo_log = lfo_lin * log(1.2); break; case 12: lfo_log = lfo_lin * log(1.3); break; case 13: lfo_log = lfo_lin * log(1.4); break; case 14: lfo_log = lfo_lin * log(1.5); break; case 15: lfo_log = lfo_lin * log(1.6); break; case 16: lfo_log = lfo_lin * log(1.7); break; case 17: lfo_log = lfo_lin * log(1.8); break; case 18: lfo_log = lfo_lin * log(1.9); break; case 19: lfo_log = lfo_lin * log(2.0); break; } (not testet yet, cause the lack of hardware here) - maybe there has to be that log(x)/log(y) thing... but somekind like this so i have this constants what the compiler crying out. for Edited April 29, 2018 by Phatline Quote Link to comment Share on other sites More sharing options...
Antichambre Posted April 29, 2018 Report Share Posted April 29, 2018 I did the same thing in MIOS32, applied to a 16bit linear function y=x: Is this what you want? Will explain tomorrow... have to get some sleep... 1 Quote Link to comment Share on other sites More sharing options...
Antichambre Posted April 29, 2018 Report Share Posted April 29, 2018 (edited) Good morning,First thing: the bitmap manipulation Declaration: ///////////////////////////////////////////////////////////////////////////// // Local variables ///////////////////////////////////////////////////////////////////////////// // You need 128*64 pixel, for SSD1306 a pixel is one bit // we will declare an u8 array, size is 128*64/8 = 1024 static u8 bitmap_array[1024]; // the bitmap mios32_lcd_bitmap_t bitmap; // some other variables for the example u32 line, column; const float a=1.0; Init: ///////////////////////////////////////////////////////////////////////////// // This hook is called after startup to initialize the application ///////////////////////////////////////////////////////////////////////////// void APP_Init(void) { MIOS32_BOARD_LED_Init(0xffffffff); // initialize all LEDs // initialize bitmap width=128, height=64, offset=128(!) and depth=1 bit bitmap = MIOS32_LCD_BitmapInit(bitmap_array,128,64,128,1); ... } Linear function exemple: I used the SRIO_ServicePrepare as 1ms timer ///////////////////////////////////////////////////////////////////////////// // This hook is called before the shift register chain is scanned ///////////////////////////////////////////////////////////////////////////// void APP_SRIO_ServicePrepare(void) { column +=128; //column increment(x axis) if( column > 0xffff){ // 65535 max column = 0; // this will clear/reset the bitmap ! memset(bitmap_array, 0, sizeof bitmap_array); } // this is just a linear function y=ax line = (u32)(a*column); u8 x= (u8)(column>>9); //reducing 16 bit to 128pixels(7bits) u8 y= (u8)(line>>10); //reducing 16 bit to 64pixels(6bits) // set the pixel MIOS32_LCD_BitmapPixelSet(bitmap, x, 63-y, 1); // 63-y is to invert the y axis } now we send it: ///////////////////////////////////////////////////////////////////////////// // This task is running endless in background ///////////////////////////////////////////////////////////////////////////// void APP_Background(void) { column = 0; line = 0; // clear LCD MIOS32_LCD_Clear(); // endless loop while( 1 ) { int i; MIOS32_LCD_GCursorSet(0, 0); MIOS32_LCD_BitmapPrint(bitmap); // done! } } result: Edited April 29, 2018 by Antichambre 1 Quote Link to comment Share on other sites More sharing options...
Antichambre Posted April 29, 2018 Report Share Posted April 29, 2018 For a partial bitmap(not full screen) e.g. 32x32 centered change declare // You need 32*32 pixel, for SSD1306 a pixel is one bit // we will declare an u8 array, size is 32*32/8 = 128 //static u8 bitmap_array[128]; //I don't know why this not work static u8 bitmap_array[1024]; //this is fine init: // initialize bitmap width=32, height=32, offset=128(!) and depth=1 bit bitmap = MIOS32_LCD_BitmapInit(bitmap_array,32,32,128,1); calc: u8 x= (u8)(column>>11); //reducing 16 bit to 32pixels(5bits) u8 y= (u8)(line>>11); //reducing 16 bit to 32pixels(5bits) // set the pixel MIOS32_LCD_BitmapPixelSet(bitmap, x, 31-y, 1); // 31-y is to invert the y axis positionning: MIOS32_LCD_GCursorSet(48, 16); MIOS32_LCD_BitmapPrint(bitmap); result: 1 Quote Link to comment Share on other sites More sharing options...
Antichambre Posted April 29, 2018 Report Share Posted April 29, 2018 Adding curve response Log and Antilog: first point after adding Math lib, it seems the loading sequence of libraries is wrong. the `__errno' compilation error. To resolve it we have to set the loading sequence, just change this line in your Makefile: LIBS= to LIBS = -lm -lgcc -lc works for me ;) Now the curve: in declaration add the curve variable, I use MIOS Studio to control it u8 curve = 64; in MIDI_Notify CC#1 is curve parameter ///////////////////////////////////////////////////////////////////////////// // This hook is called when a MIDI package has been received ///////////////////////////////////////////////////////////////////////////// void APP_MIDI_NotifyPackage(mios32_midi_port_t port, mios32_midi_package_t midi_package) { // store incoming ModWheel values to curve if( midi_package.type == CC && midi_package.cc_number == 1 ) curve = (u8)midi_package.value; } Ok now we will change the function to: ///////////////////////////////////////////////////////////////////////////// // This hook is called before the shift register chain is scanned ///////////////////////////////////////////////////////////////////////////// void APP_SRIO_ServicePrepare(void) { column +=128; //column increment(x axis) if( column > 0xffff){ // 65535 max column = 0; // this will clear/reset the bitmap ! memset(bitmap_array, 0, sizeof bitmap_array); } // log/antilog function if(curve<64){ // reducing curve to a float between 0 and 1 float curv_f=(float)(64-curve)/64.0; // reducing column to a float between 0 and 1 float column_f = (1.0-((float)(column/65536.0))); // line value is line = (u32)(column + ((log(column_f)*curv_f*column_f)*65536)); }else{ // reducing curve to a float between 0 and 1 float curv_f=(float)(curve-64)/64.0; // reducing column to a float between 0 and 1 float column_f = (float)(column/65536.0); // line value is line = (u32)(column - ((log(column_f)*curv_f*column_f)*65536)); } u8 x= (u8)(column>>9); //reducing 16 bit to 128pixels(7bits) u8 y= (u8)(line>>11); //reducing 16 bit to 64pixels(6bits) // set the pixel MIOS32_LCD_BitmapPixelSet(bitmap, x, 63-y, 1); // 63-y is to invert the y axis } result: Voilà! I hope it will help you ;) have a good sunday! Bruno 2 Quote Link to comment Share on other sites More sharing options...
Phatline Posted April 29, 2018 Author Report Share Posted April 29, 2018 (edited) cool device, for programing on the field? yes that curve behavior is what i was looking for... thx will try that @ evening --- special that library thing Quote LIBS= to LIBS = -lm -lgcc -lc yes also works me thx!!!!! --- i add this to the top of article! this solve allmost everything in the night i was thinking of a solution, how to DIY a log function special for this task, but it endet up to be exponential... my idea was: 1. make a linear LFO like bevore, call it LFO_LIN, this is only for calculations 2. calculate LFO_LOG, this will be mixed with other LFOs and will be sent out to AOUT_Channels 2a: calculate LFO_LOG: for example: LFO_length: 500ms, LFO_actual time Position: 250ms, LFO_LIN: 32768, cc_curve: variable from 0-65535 as example below calculation: LFO_LOG = LFO_LIN + LFO_LIN_ADD LFO_LIN_ADD = LFO_LIN * ( %time * %cc_curve) - - - - [0-65535] = [0-65535] * [%] * [%] ) 3750 = 15000 * ( ( (1/500ms) * 250ms)) * (1/65536) * 32768)) ) 3750 = 15000 * 0,5time * 0,5cc @ cc_curve: 32768 18750 = 15000 + 3750 example calculation of the LFO_LIN_ADD 15000 = 15000 + 0 = 15000 * 0,5time * 0,0cc @ cc_curve: 0 15000,2 = 15000 + 0,22 = 15000 * 0,5time * 0,00003cc @ cc_curve: 2 15000,4 = 15000 + 0,45 = 15000 * 0,5time * 0,00006cc @ cc_curve: 4 .... 15234 = 15000 + 234 = 15000 * 0,5time * 0,03125cc @ cc_curve: 2048 15468 = 15000 + 468 = 15000 * 0,5time * 0,06250cc @ cc_curve: 4096 15937 = 15000 + 937 = 15000 * 0,5time * 0,12500cc @ cc_curve: 8192 16875 = 15000 + 1875 = 15000 * 0,5time * 0,25000cc @ cc_curve:16384 18750 = 15000 + 3750 = 15000 * 0,5time * 0,50000cc @ cc_curve:32768 22250 = 15000 + 7500 = 15000 * 0,5time * 1.0000cc @ cc_curve:65536 now try half time and half lfo_lin to proof that this is not linear...: 7968,75 = 7500 + 468 = 7500 * 0,25time * 0,25000cc @ cc_curve:16384 15937,5 = 7968,75 * 2 where we had: 16875 = 15000 + 1875 = 15000 * 0,5time * 0,25000cc @ cc_curve:16384 15937,5 vs 16875 @ 1/4time @ 1/4curve_cc (positive log) so if that result is not a comma-loos result, then this is now not linear, have to proof if that make sense on the machine what happens when try a full cc_curve effect @ 65536 : 22250 = 15000 + 7500 = 15000 * 0,5time * 1.0000cc @ cc_curve:65536 vs half time 9375 = 7500 + 1875 = 7500 * 0,25time * 1.0000cc @ cc_curve:65536 18750 = 9375 * 2 18750 vs 22250 what happens @ end of time ( i guis it clips over 65536): 1310720 = 65536+ 65536 = 65536 * 1.0 time * 1.0000cc @ cc_curve:65536 oh that we have to clip if ( lfo_log > 65536 ) {lfo_log = 65536) so we have more a exponential then a logarithmic, depending on the cc_curve parameter i have a clipping expanding cc_curve to -65536 to + 65536 makes it +-(time)exponential, i just cant wait, to try my and brunos codes. Edited April 29, 2018 by Phatline Quote Link to comment Share on other sites More sharing options...
Antichambre Posted April 29, 2018 Report Share Posted April 29, 2018 Ahah. Mine is a true log/antilog, this is math! see the function applied to a triangle LFO with variable speed and amplitude 2 Quote Link to comment Share on other sites More sharing options...
Antichambre Posted April 29, 2018 Report Share Posted April 29, 2018 (edited) On 29/04/2018 at 3:42 PM, Phatline said: cool device, for programing on the field? This is something I made for a customer, it can convert all serial connection and a lot of protocol, RS232, 422, 485 MIDI LANC and some specials others... It's based on 2 SP338 IC around an LPC1769, so I can use it for MIOS32 too. When I did the boxes I made one for me too and I use it as a tool on field, it 'saved my life' 2 times already. Edited July 15, 2020 by Antichambre Quote Link to comment Share on other sites More sharing options...
Phatline Posted April 30, 2018 Author Report Share Posted April 30, 2018 how get you the tri-angle > sine conversion done, when i do, i get in the bottum part a arrowhead, and in the top i round (see video first display...3rd encoder sets curve parameter // T R I A N G L E if( aout[x].v_cc[24 + (8*y)] == 2 ) { if( (counter[x][y] * 2) > lfo_cycle[x][y] ) { lfo_lin[x][y] = lfo_lin[x][y] - ( 131072 / lfo_cycle[x][y] ) ;} else { lfo_lin[x][y] = lfo_lin[x][y] + ( 131072 / lfo_cycle[x][y] ) ;} // Reset - ms - Counter if( lfo_loop_step_pos[x][y] == 0 && flag.step0once[x][y] == 1) { flag.step0once[x][y] = 0; counter[x][y] = 0; lfo_lin[x][y] = 0; // init lfo internal lfo_log[x][y] = 1; // init CV Value update_lfo_scope[x][y] = 1; // wait for next 16th step of seq to restart LFO Cycle } } // end triangle i do the lin-log calculation right after the Waveform calculation, and save the result --- result will then printed on Screen, and dumped out to AOUT. for lin-log i used your code - mine have not done that, what i want... did you changed anything? i dont get the sinus you have in your video // L I N > L O G / A N T I L O G // lin > log if (curve < 32767){ // reducing curve to a float between 0 and 1 curv_f=(float)(32768-curve)/32768.0; // reducing column to a float between 0 and 1 lfo_f = (1.0-((float)(lfo_lin[x][y]/65536.0))); // lin > log lfo_log[x][y] = (u32)(lfo_lin[x][y] + ((log(lfo_f)*curv_f*lfo_f)*65536)); } // lin > antilog else{ // reducing curve to a float between 0 and 1 curv_f=(float)(aout[x].v_cc[26+(y*8)] - 32768) / 32768.0; // reducing column to a float between 0 and 1 lfo_f = (float)(lfo_lin[x][y]/65536.0); // lin > log lfo_log[x][y] = (u32)(lfo_lin[x][y] - ((log(lfo_f)*curv_f*lfo_f)*65536)); } }}// end x y loop Quote Link to comment Share on other sites More sharing options...
Antichambre Posted April 30, 2018 Report Share Posted April 30, 2018 (edited) Yes I just adapt it to a signed value, normally a lfo is bipolar. declare 2 new static function ///////////////////////////////////////////////////////////////////////////// // Local variables ///////////////////////////////////////////////////////////////////////////// u16 phase =0; u16 curve =32768; u16 amp_cc =65535: ///////////////////////////////////////////////////////////////////////////// // Local Prototypes ///////////////////////////////////////////////////////////////////////////// static s16 XXX_hlp_log_signed(u16 curv, s16 signed_amp); static u16 XXX_hlp_log_unsigned(u16 curv, u16 abs_amp); Add the function ///////////////////////////////////////////////////////////////////////////// // help func: return the Log/Antilog of a given signed value ///////////////////////////////////////////////////////////////////////////// static s16 XXX_hlp_log_signed(u16 curv, s16 signed_amp){ s16 log_amp; if(signed_amp<-32767)signed_amp=-32767; // limit signed to -32767 to -32767 if(signed_amp<0){ u16 abs_amp = (u16)((0-signed_amp) << 1); log_amp = (s16)(0-(XXX_hlp_log_unsigned(curv, abs_amp)>>1)); }else{ log_amp = (s16)(XXX_hlp_log_unsigned(curv, (u16)(signed_amp<<1))>>1); } return log_amp; } ///////////////////////////////////////////////////////////////////////////// // help func: return the Log/Antilog of a given unsugned value // note: math.h must be included ///////////////////////////////////////////////////////////////////////////// static u16 XXX_hlp_log_unsigned(u16 curv, u16 abs_amp){ u16 log_amp; float curv_f, amp_f; if (curv < 32768){ // reducing curve to a float between 0 and 1 curv_f=(float)(32767-curv)/32767.0; // reducing column to a float between 0 and 1 amp_f = (1.0-((float)(abs_amp/65535.0))); // lin > log log_amp = (u16)(abs_amp + ((log(amp_f)*curv_f*amp_f)*65535)); }else{ // reducing curve to a float between 0 and 1 curv_f=(float)(curv-32767)/32767.0; // reducing column to a float between 0 and 1 amp_f = (float)(abs_amp/65535.0); // lin > log log_amp = (u16)(abs_amp - ((log(amp_f)*curv_f*amp_f)*65535)); } return log_amp; } now you will be able to use it everywhere with signed or unsigned 16bit value A TRIANGLE LFO with amplitude, phase and curve parameters: // calc an unipolar triangle(0 to 65535) depending on x(time) between 0 and 65355 and phase between 0 and 65355 u16 time = (u16)(x + phase + 16384) ; // apply the phase u16 tri = (time < 32768) ? time << 1 : ((65535 - time) << 1)); // now we shift down the unipolar to get a bipolar one s16 signed_tri = (s16)(tri - 32768); // call log function, curve is unsigned 16bit value! signed_tri = XXX_hlp_log_signed(curve, signed_tri); // apply amplitude parameter, amp_cc between 0 and 65355 signed_tri = (s16)(signed_tri*amp_cc/65535); // we shift back the triangle to unsigned 16 bit value, for use with lcd and aout tri = (u16)(signed_tri + 32768); Result: More? ;) Edited April 30, 2018 by Antichambre some correction shifting is 32768 not 32758 ;) --- added amp_cc and phase parameter 1 Quote Link to comment Share on other sites More sharing options...
Antichambre Posted April 30, 2018 Report Share Posted April 30, 2018 ... Always More! ;)Width modulation added, with it you can achieve ramp down/up, pseudo sine(this is not true sine) and many more from a single triangle waveform: // calc an unipolar triangle(0 to 65535) depending on x(time) between 0 and 65355 and phase between 0 and 65355 // set the phase u16 time = (u16)(x + phase + (u16)(wide_mod/2)) ; // apply pos/neg width modulation, wide_mod is an unsigned 16bit ;) float wide_pos = 65535.0/wide_mod; float wide_neg = 65535.0/(65535-wide_mod); u16 tri = (time < wide_mod) ? ((u16)(time*wide_pos)) : ((u16)((65535 - time)*wide_neg)); // now we shift down the unipolar to get a bipolar one s16 signed_tri = (s16)(tri - 32768); // call log function, curve is unsigned 16bit value! signed_tri = XXX_hlp_log_signed(curve, signed_tri); // apply amplitude parameter, amp_cc between 0 and 65355 signed_tri = (s16)(signed_tri*amp_cc/65535); // we shift back the triangle to unsigned 16 bit value, for use with lcd and aout tri = (u16)(signed_tri + 32768); Quote Link to comment Share on other sites More sharing options...
Phatline Posted May 1, 2018 Author Report Share Posted May 1, 2018 thX great inspiration! special the bithshift to 128 und 64 > genial... or to scale time to u16, and then make more simple any offset possible (automation-assignment of this paremters is now also easy), also the log antilog logic.. i used your code as inspiration source to optimize code... not only because of you, because of RAM, i looked what happens when i let calculate all 4Channel-Strips & all 8 Scopes (8x4 OSCs, 88xVelo-, 88xOSC-,88xMotionSeuencer-Assignments...) had blackscreens, and ram debugger warnings usw, now i am a bit faster here - no problem with + - operation, and like you said, -heavy division and multiplication- the programm then is working ok with one screen, 8 with log and all that stuff just dont have a function... it will take me more time to experience that. i combine now ENV + LFO und let them share the same controlls, ENV is just a nother OSC/WAVEFORM, with Bendable paremeters. I addet 0: retrigger und 1: sustain to my RATE CC, the rest are typical LFO cycle rates encreasing... so i can use a envelope as LFO and a typical LFO-Wave as Envelope, so i am also more flexible, not every track needs 4 envelopse most of them only 2 or even 1, haveing on the other side more LFOs... and so on. Quote Link to comment Share on other sites More sharing options...
Antichambre Posted May 2, 2018 Report Share Posted May 2, 2018 (edited) You're welcome! I already planned to do something like that for the PIXI, then not a waste of time you just pushed me to do it now ;) But I will come back to this because it needs an accurate frequency too, exponential range something from 0.002Hz to 20Hz. I've already got the math just have to translate it in code: if note < note_Ref then freq = Freq_Ref / (2^((note_Ref/note)/12) else freq = Freq_Ref * (2^((note/note_Ref)/12) something like this #define LFO_FREQ_REF 1.0 //1Hz #define LFO_FREQ_REF_NOTE 0x45 // 69, A3 midi note //7bit #define LFO_FREQ_REF_VALUE (LFO_FREQ_REF_NOTE<<9) //16bit #define LFO_FREQ_TICK_RESO 1.0 //ms u8 coarse = LFO_REF_NOTE; // LFO Coarse Tune (7bit) u8 fine = 64; // LFO Fine Tune +/- 6bit(7bit) float target_period, last_period; // in millisecond float accumulator, accum_step; // in millisecond //with freq_val = (u16)(coase<<9 + (fine-64)<<2); if(freq_val<LFO_FREQ_REF_VALUE) target_period = (float)(1000.0 / (REF_FREQ / (2^(((LFO_FREQ_REF_VALUE-freq_val)/512.0)/12); else target_period = (float)(1000.0 / (REF_FREQ * (2^(((freq_val-LFO_FREQ_REF_VALUE)/512.0)/12); accum_step = target_period / LFO_FREQ_TICK_RESO; like a VCO is centered around 440Hz on A3 note, the LFO will be centered around 1Hz on A3 note which will give 0.01858Hz for the lowest note and 28.50876Hz for the higher one.ToDo! And I didn't check in the SVN if something like this was done before Best Bruno Edited May 2, 2018 by Antichambre Quote Link to comment Share on other sites More sharing options...
Antichambre Posted May 2, 2018 Report Share Posted May 2, 2018 (edited) 9 hours ago, Phatline said: no problem with + - operation, and like you said, -heavy division and multiplication- the programm then is working ok with one screen, 8 with log and all that stuff just dont have a function... it will take me more time to experience that. For process time, remember, by decreasing the parameters resolution to 7bit (CC resolution) you can prepare some tables at startup(RAM) OR write it in program memory(FLASH) and finally remove some calculation. e.g. this can be replaced by an array if curve is a 7bit On 30/04/2018 at 1:19 PM, Antichambre said: curv_f=(float)(32767-curv)/32767.0; We can also try to use the FPU of the STM32 for hardware floating point calculation, but I read in the forum people have some troubles to get it. Edited May 2, 2018 by Antichambre Quote Link to comment Share on other sites More sharing options...
Phatline Posted May 3, 2018 Author Report Share Posted May 3, 2018 (edited) 18 hours ago, Antichambre said: For process time, remember, by decreasing the parameters resolution to 7bit (CC resolution) you can prepare some tables at startup(RAM) OR write it in program memory(FLASH) and finally remove some calculation. e.g. this can be replaced by an array if curve is a 7bit We can also try to use the FPU of the STM32 for hardware floating point calculation, but I read in the forum people have some troubles to get it. i have tryed, but with the result, that i could use FPU, but not for my program because in order to use FPU i have to turn off optimize and frame pointer (as workaround), but i a am not expirienced enough to rewrite my code good enough to not need optimize and other stuff... @7bit, i want to automate everything possible (so all except Wave-Form, RATE and Programchange), because they are combined with Clock, resync...) The Automations are: MotionSequencer Velocity from trigger OSC (LFO) and they all get summed/combined together on each CC/aout/parameter ... i dont want to mix here, its better to leaf it u16, the program is already big, and it would lead to problems and headpain in the future. Edited May 3, 2018 by Phatline Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.