Jump to content

Phatline

Members
  • Posts

    1,279
  • Joined

  • Last visited

  • Days Won

    71

Posts posted by Phatline

  1. i am offically a artist. i pay social insurance for that. my time is free for midibox making music for contest cd website or gig. have a girlfriend spending lot of time in love. cooking and houshold on my own... and midibox coding planing building consume the rest of it. since i need the devices for a gig end of february i dont have time for tutorials... but when i have some spare time i would make some video doku-to see what to have done BUT not a detailt tutorial for that it is to much information. but i think in german and for a mios based uset project so it would help only a small group anyway. so i have to rethink it i also dont have the best cam equipment nor mony for that..

    maybe this and others is a reason that there are no video tuts outthere ,;)

  2. This code: (app.c download@ http://wiki.midibox.org/lib/exe/fetch.php?media=phatline:tm_v3.zip)

    void APP_Init(void){ 
    
    xTaskCreate(TASK_SEQ, (signed portCHAR *)"SEQ", configMINIMAL_STACK_SIZE, NULL, PRIORITY_TASK_SEQ, NULL);}   // install sequencer task  
    

    compile with following warnings:

    Quote

    make (im Verzeichnis: /home/nixgibts/c/tm_V3)
    rm -f project.hex
    Creating object file for app.c
    app.c: In function 'APP_Init':
    app.c:386:3: 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 *'

    Creating object file for seq.c
    ....
    /home/triggermatrix/mios32/trunk/FreeRTOS/Source/portable/GCC/ARM_CM3/port.c: In function 'prvPortStartFirstTask':
    /home/triggermatrix/mios32/trunk/FreeRTOS/Source/portable/GCC/ARM_CM3/port.c:282:1: warning: stack usage computation not supported for this target [enabled by default]
    ...
    /home/triggermatrix/mios32/trunk/drivers/STM32F4xx/v1.1.0/STM32_USB_Device_Library/Core/src/usbd_req.c: In function 'USBD_GetString':
    /home/triggermatrix/mios32/trunk/drivers/STM32F4xx/v1.1.0/STM32_USB_Device_Library/Core/src/usbd_req.c:845:18: warning: comparison between pointer and integer [enabled by default]
    /home/triggermatrix/mios32/trunk/drivers/STM32F4xx/v1.1.0/STM32_USB_Device_Library/Core/src/usbd_req.c: In function 'USBD_GetLen':
    /home/triggermatrix/mios32/trunk/drivers/STM32F4xx/v1.1.0/STM32_USB_Device_Library/Core/src/usbd_req.c:863:17: warning: comparison between pointer and integer [enabled by default]
    ...
    Creating object file for freertos_heap.cpp
    -------------------------------------------------------------------------------
    Kompilierung erfolgreich beendet.
    Application successfully built for:
    Processor: STM32F407VG
    Family:    STM32F4xx
    Board:     MBHP_CORE_STM32F4
    LCD:       universal
    -------------------------------------------------------------------------------
    arm-none-eabi-size project_build/project.elf
       text       data        bss        dec        hex    filename
      98646       9184      56600     164430      2824e    project_build/project.elf
    20000000 D __ram_start
    200100f8 B __ram_end

    that task.h code - Warning by "xTaskCreate...":

    #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
    	BaseType_t xTaskCreate(	TaskFunction_t pxTaskCode,
    							const char * const pcName,
    							const uint16_t usStackDepth,
    							void * const pvParameters,
    							UBaseType_t uxPriority,
    							TaskHandle_t * const pxCreatedTask ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
    #endif

     

    do i have to fear?

  3. THX! without that i would have been lost! :cheers:

    worked at the first moment!

     

    i had enough to close and re-open the Mios-Studio every time when uploading new code... specially while programming over weeks daily :pout: deep into code...(and that rescan joke? not funny)

    my cores bootloader is setup ed, to show up as "MIOS32" (when not in bootload mode), so i hardcodet that in mios-studio to be set when press "Rescan mididevices", working under linux mint kernel 4.4.0-98

    no more closing MidiStudio, or have to close multiple-open-instances because of codeing and trying and uploading, then everytime the resize of the window, search and open hexfile and so on. Of course that is hardcodet, but in my case it is good this way, now i know how to compile anyway - thx

    open: svn/mios32/trunk/tools/mios_studio/src/gui/MiosStudio.cpp

    edit: i deleted all from"case rescanDevices" to "break;" and wrote this instead: (the line is about 955 or so)

     case rescanDevices:
            closeMidiPorts();
            initialMidiScanCounter = 1;
     
            getMidiInput();
            getMidiOutput();
            setMidiInput("MIOS32");
            setMidiOutput("MIOS32");
            break;
    

    dont really know exact what is going on there, but for me its working, and thats enough.

    also some colorchanging by searching the gui/....cpp filesvia

    g.fillAll(Colours::black);

    but the background of the main-fields are still white... to bad...

  4. after initialize:

     void APP_Init(void){
      int pin;   for(pin=0; pin<16; ++pin){     MIOS32_BOARD_J10_PinInit(pin, MIOS32_BOARD_PIN_MODE_INPUT_PU);}   }

    getting pin 0-7 is workin ok, but 8-15 give me no output:

    void APP_SRIO_ServicePrepare(void)  {
                // get GPIO-Pins
                u8 x = 0;
                for(x=0; x<16; x++) {
                     
                if(MIOS32_BOARD_J10_PinGet(x) != flag.j10PinState[x]) {
                     
                    MIOS32_MIDI_SendDebugMessage("pin: %d value: %d", x, MIOS32_BOARD_J10_PinGet(x));
                    flag.j10PinState[x] = MIOS32_BOARD_J10_PinGet(x);
                  } }

     

    why?

  5. Hi,

    i want to modify the blm_scalar app a bit

    http://svnmios.midiboxorg/filedetails.php?repname=svn.mios32&path=%2Ftrunk%2Fapps%2Fcontrollers%2Fblm_scalar%2FREADME.txt

    i want to use it in standalone and via midi/sysex...

    so my question: how to call the BLM internally? when i want to display a "array[16][16]=0 or 1 or 2;"

    i know i can call it like below

    but is there a more direct way to use it?

    thx. mike

    
    void APP_Background(void){
    
    u8 chn = 0;
    u8 note = 0;
    u8 velocity = 0;
    
    for(chn=0; chn<16; chn++){ 
    for(note=0; note<16; note++){ 
        velocity = Seq[chn][note];
        
        if( note <= 0x0f ) {                                    //note<=15?
          // BLM16x16 LEDs
          led_mod_ix = chn >> 2;
          led_row_ix = ((chn&3) << 1) + ((note >> 3) & 1);
          led_column_ix = note & 0x7; //7
          modify_led = 1;
        } else if( note == 0x40 ) {                             //note==64
          // extra column LEDs
          led_mod_ix = 4;
          led_row_ix = (chn&3) << 1;
          led_column_ix = chn >> 2;
          modify_led = 1;
        } else if( chn == 0 && note >= 0x60 && note <= 0x6f ) { //Chn0, note>=96, note>0111
          // extra row LEDs
          led_mod_ix = 4;
          led_row_ix = 1 + ((note >> 1) & 6);
          led_column_ix = note & 3;
          modify_led = 1;
        } else if( chn == 0xf && note >= 0x60 && note <= 0x6f ) { //Chn15, note>=96, note>0111
          // additional extra LEDs
          led_mod_ix = 4;
          led_row_ix = 1 + ((note >> 1) & 6);
          led_column_ix = 4 + (note & 3);
          modify_led = 1;
        }
    
    
        if( modify_led ) {
          u8 led_mask = 1 << led_column_ix;
    
          // 90 xx 00 is the same like a note off event!
          // (-> http://www.borg.com/~jglatt/tech/midispec.htm)
          if( velocity == 0x00 ) {
    	// Note Off or velocity == 0x00: clear both LEDs
    	blm_scalar_led[led_mod_ix][led_row_ix][0] &= ~led_mask;
    #if BLM_SCALAR_NUM_COLOURS >= 2
    	blm_scalar_led[led_mod_ix][led_row_ix][1] &= ~led_mask;
    #endif
          } else if( velocity < 0x40 ) {
    	// Velocity < 0x40: set green LED, clear red LED
    	blm_scalar_led[led_mod_ix][led_row_ix][0] |= led_mask;
    #if BLM_SCALAR_NUM_COLOURS >= 2
    	blm_scalar_led[led_mod_ix][led_row_ix][1] &= ~led_mask;
    #endif
          } else if( velocity < 0x60 ) {
    	// Velocity < 0x60: clear green LED, set red LED
    	blm_scalar_led[led_mod_ix][led_row_ix][0] &= ~led_mask;
    #if BLM_SCALAR_NUM_COLOURS >= 2
    	blm_scalar_led[led_mod_ix][led_row_ix][1] |= led_mask;
    #endif
          } else {
    	// Velocity >= 0x60: set both LEDs
    	blm_scalar_led[led_mod_ix][led_row_ix][0] |= led_mask;
    #if BLM_SCALAR_NUM_COLOURS >= 2
    	blm_scalar_led[led_mod_ix][led_row_ix][1] |= led_mask;
    #endif
          }
        }
      }
    
    
    
    }} // END - FOR - LOOPS
      

     

  6. hm i get a error:

    app.c:1094:13: warning: implicit declaration of function 'wmemset' [-Wimplicit-function-declaration]
    if(edit & (1<<0))wmemset(loop[track].PB, (u32)((8192<<16) + 8192), (sizeof (loop[track].PB))/4); // reset Pitch Bend

     

    when i then add:

    #include <wchar.h>    to app.c

    then error:

    Quote

    app.c:1169:13: warning: passing argument 1 of 'wmemset' from incompatible pointer type [enabled by default]

    In file included from app.c:23:0:

    /home/triggermatrix/mios32_toolchain/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/include/wchar.h:108:10: note: expected 'wchar_t *' but argument is of type 'u16 *'

     

     

    should i change this:

     typedef struct storage {  
            u16  PB [512];    
             u8  SEQ[512] [8];                                    
             u8  MSQ[512];      
    
            char  leader:1;   
            char  virgin:1;      
             u8   length;   
             u8   decay;        
             u8   rythm;    
            u16   bpm;   
    } store_t;

    to this:

     typedef struct storage {  
        wchar_t PB  PB [512];    
             u8  SEQ[512] [8];                                    
             u8  MSQ[512];      
    
            char  leader:1;   
            char  virgin:1;      
             u8   length;   
             u8   decay;        
             u8   rythm;    
            u16   bpm;   
    } store_t;

    hm what size has this wchar_t?

  7. if(edit & 0x0f)memcpy(&loop_copy, &loop[track], sizeof loop_copy);   

    clever i like that :happy:


    but i planned it more like:  check which things have to copyied, so i can copy PB+NOTES, but not CC+Loop-Information, (for default)

    if i get it right: in your thought i can always copy only one thing: PB, All, Notes or Loop-Info

    but i can still use memcpy with for example:

    if( (edit[0]==1) && (edit[1]==1) && (edit[1]==1) && (edit[1]==1) ) memcpy(&loop_copy, &loop[track], sizeof loop_copy);   

     

    THX for your help guys!

    for the rest i will take me time on 23.12... today we make fire in the snow, and celebrate the 21.12 to restart the sun-circle :cheers: happy new sun year, skol!

  8. :blush: aja        a < 8        of course, thx!

     

    Edit: read/write on SD-Card is working fine!

            MUTEX_SDCARD_TAKE;
                    //Write to File
                    sprintf(file_path, "msp/%d-%d.msp", track, clip);             
                    FILE_WriteOpen	( file_path,          16 );   
                    FILE_WriteBuffer( (u8  *)&file_type,   4 );                                                    
                    FILE_WriteBuffer( (u8  *)&loop[track], sizeof(store_t) );                                      
                    FILE_WriteClose	(); 
            MUTEX_SDCARD_GIVE;

     

    @ Background-tasks

    function example which make a hardfault when using 1024,  when calling it... i call it once a time  with a button press on the UI (DIN) > see code below

    but also will need such things for mooving sequencer data forward in loop, or backwards, or copy step 0-15 to all other 512 steps in a musically way > means could be a wild button orgie...

    in App.h:
     typedef struct storage {   // to optimize SD-Load-Time, each clips data is stored in this struct
            u16  PB [512];      //  Pitchband inital = 8192 = No Pitchbend! 
             u8  SEQ[512] [8];  //  512Steps, 8NotePolyphony                                      
             u8  MSQ[512];      //  Motion-SEQ of one CC ...eg.:Control-Wheel of Keyboard   
             
            char  leader;       // Programchange able? - only 1 of 4 Song-Clips can send Programchanges via BLMatrix
            char  virgin;       // is there any data in the clip? need to display on a ButtonLed Matrix-Launcher   
             u8   length;       // 1x16, 2x16...
             u8   decay;        // 60ms... could be set with Encoder, but I dont need a variable, since the melody out will be used by the Triggermatrix...
             u8   rythm;        // 4x4=16, 5x3=15 usw... to calculate maximal duration per UI-matrix page
            u16   bpm;   
    } store_t;
    
    extern store_t loop[8];
    
    
    in app.c:
    
    u16 SEQ_copy[512][8]  = {{}}; //Copy actual Track into ClipboardBuffer
      u16 MSQ_copy[512]     = {}; //Copy actual Track into ClipboardBuffer
      u16 PB_copy [512]     = {}; //Copy actual Track into ClipboardBuffer  
      u16 tact_info_copy[32] = {}; //Copy bpm, loop length, tact and so on 
    
    
    // E D I T   C L I P  D A T A
    static void Edit_Clip(u8 track, u16 clip, u16 job){
    u16 c = 0;
    u16 x = 0;
        
        switch(job) {
            
            // Clear
            case 0:     for( c=0; c<512; c++ ) {
                
                            if(edit[0] == 1) { loop[track].PB[c]  = 8192; } // = no Pitch Bend
                            
                            if(edit[1] == 1) {for( x=0; x<8; x++ ) { loop[track].SEQ[c][x] = 0; } } // = no Note
                            
                            if(edit[2] == 1) {loop[track].MSQ[c] = 0; }     // = no Control Change
                    }  break;                
        
        
            // Copy                
            case 1:     for( c=0; c<512; c++ ) {
                
                            if(edit[0] == 1) {  PB_copy[c] = loop[track].PB[c];}     // PB
                        
                            if(edit[1] == 1) {  for( x=0; x<8; x++ ) { SEQ_copy[c][x] = loop[track].SEQ[c][x]; } } // NOTE
                            
                            if(edit[2] == 1) {  MSQ_copy[c] = loop[track].MSQ[c];}   // MSQ
                            }
                            
                        if(edit[3] == 1) {  
                        tact_info_copy[0] = loop[track].leader;
                        tact_info_copy[1] = loop[track].virgin;
                        tact_info_copy[2] = loop[track].length;
                        tact_info_copy[3] = loop[track].decay;
                        tact_info_copy[4] = loop[track].rythm;  
                        tact_info_copy[5] = loop[track].bpm; }
                      break;
                            
      
            // Paste                
            case 2:     for( c=0; c<512; c++ ) {
                
                            if(edit[0] == 1) { loop[track].PB[c]  =  PB_copy[c];}    // PB
                        
                            if(edit[1] == 1) { for( x=0; x<8; x++ ) { loop[track].SEQ[c][x]  =  SEQ_copy[c][x]; } } // NOTE
                            
                            if(edit[2] == 1) { loop[track].MSQ[c]  =  MSQ_copy[c]; } // MSQ 
                        }
                        if(edit[3] == 1) {  
                            loop[track].leader = tact_info_copy[0];
                            loop[track].virgin = tact_info_copy[1];
                            loop[track].length = tact_info_copy[2];
                            loop[track].decay  = tact_info_copy[3];
                            loop[track].rythm  = tact_info_copy[4];  
                            loop[track].bpm    = tact_info_copy[5]; }    
                      break;
                 
    }
    }

    also the code above is working ifne ;)

  9. ok understand, i let the the file describtion in....

    oje...

    there is something wrong with the code,

    http://wiki.midibox.org/lib/exe/fetch.php?media=phatline:seq-melody-footboard-beta.zip

     

    when i make arrays with 8x512, or arrays with 8x1024, the Files on SD-Card is always 5,6kb size, also on 1024 i got hardfaults when copy those structs into arrays (copy paste clear clips), by 512 no hardfault

     typedef struct storage { 
            u16  PB [512];      
             u8  SEQ[512] [8];                                    
             u8  MSQ[512]; 
    
            char  leader;       
            char  virgin;          
             u8   length;       
             u8   decay;        
             u8   rythm;        
            u16   bpm;   
    } store_t;
    
    no difference in SD-File-Size!
    
     typedef struct storage {   
            u16  PB [1024];  
             u8  SEQ[1024] [8];                                 
             u8  MSQ[1024];      
       
            char  leader;      
            char  virgin;         
             u8   length;   
             u8   decay;       
             u8   rythm;   
            u16   bpm;   
    } store_t;

     

    also i initialize all Arrays, but actual most of them (all except the first member loop[0] in the program are 0-out

    void APP_Init(void){
    //initalize 8 Clips with standart values
        u8 a = 0;
        for ( a=0; a>8; a++ ) { 
            loop[a].leader =  0;   
            loop[a].virgin =  1;
            loop[a].length =  1;
            loop[a].decay =  60; 
            loop[a].rythm =   4;
            loop[a].bpm   = 120;
            
            //initiate Pitchbend
            u16 b; for(b=0; b<512; b++)   { loop[a].PB[b] = 8192; }
            };
    
            
        //Initiate Pitchbend - copy paste buffer
        u16 b; for(b=0; b<512; b++)   { PB_copy[b] = 8192; }
    }

     

    the 1024 thing i think is clear, it takes to long to calculate all the data, i would need something like a xtask... but i dont figured out how to make out of a

    Quote

    static void Edit_Clip(u8 track, u16 clip, u16 job);     a    static void Edit_Clip       (void *pvParameters);

    i know:

    Quote

        xTaskCreate(Edit_Clip,  (signed portCHAR *)"Edit_Clip", 256,  NULL, PRIORITY_Counter, NULL); 

    i use such things for counters in ms tact (decay-counters, blink blink...), but not for a function that gets called, work something out, and done...

    for example:

    static void Decay(void *pvParameters){  //Send Note OFFs after a while
       portTickType xLastExecutionTime;
       xLastExecutionTime = xTaskGetTickCount();       // Initialise the xLastExecutionTime variable on task entry
      while( 1 ) {
        vTaskDelayUntil(&xLastExecutionTime, 1 / portTICK_RATE_MS);
        
        for(DcyNteCount = 1;  DcyNteCount < 128; DcyNteCount++) {
                            for(DcyTrkCount = 0; DcyTrkCount < 8;   DcyTrkCount++) {
                                
                                       if   (MeloDecayTIMER[DcyTrkCount][DcyNteCount] != 0) {
                                             MeloDecayTIMER[DcyTrkCount][DcyNteCount]   --;
                                             
                                          if (MeloDecayTIMER[DcyTrkCount][DcyNteCount] == 0) {
                                               MIOS32_MIDI_SendNoteOff(MelPortOut, MeloOutCh[DcyTrkCount], DcyNteCount, 0);  
                                               MIOS32_MIDI_SendNoteOn (MelPortOut, MeloOutCh[DcyTrkCount], DcyNteCount, 0);}}  
                                        }}
    }//End While
    }//End TICK 0 >>> 1ms Task...

     

  10. 5 hours ago, Hawkeye said:

    FILE_ReadBuffer((u8*)loop, 8 * sizeof(store_t));

    FILE_WriteBuffer((u8*)loop, 8 * sizeof(store_t));

    the trick is to use "sizeof", that calculates the data size of the structure "store_t" in bytes. Multiplying it by 8 if you want to read/write 8 of these structures at once. Make sure, that the variable "loop" is big enough to hold the data.

    would assume that all my tracks saved in a single file, and thats not the case, since i need to load the clips independendly for launching via BLM, but also need to load the clips via Program-change also

    so it ends up with:

                case 2: //LOAD all Clips - FOR  P R O G R A M  C H A N G E
                              for( t=0; t<8; t++) { 
                                    MUTEX_SDCARD_TAKE;  
                                        sprintf         ( filepathL, "sq/%d-%d.sq", t, clip );
                                        FILE_ReadOpen   ( &midifile_fi, filepathL );
                                        FILE_ReadBuffer ( (u8  *)file_type,        4 ); 
                                        FILE_ReadBuffer ( (u8 *)loop[t], sizeof(store_t) );   
                                        FILE_ReadClose  ( &midifile_fi );
                                    MUTEX_SDCARD_GIVE;                        
                                    
                                    //Calculate new Loop Lengths
                                    Loop[t]         = loop[t].length * MainLoop;
                            }
    2 hours ago, Antichambre said:

    FILE_WriteBuffer((u8 *)loop[track], sizeof(store_t));

    for a single track...

    best!

     

    by the way, do i need that

    FILE_WriteBuffer( (u8  *)file_type,    4 ); //"SQ01" = 4 Positons  

    for what platforms do i need a filetype?

    compiler says for the line: FILE_WriteBuffer((u8 *)loop[track], sizeof(store_t));     :

    Quote

    app.c:839:1: error: cannot convert to a pointer type

     

  11. i am stucking @ the moment, while i know how to use it instead of my normal arrays, i dont know how to write the whole struct into file...

     

    ok here my struct:  store_t loop[8] ,

    how can i read/write them now into my FILE?

    a struct is not named in MIOS32  functions doku

    app.h (so all functions have access on it

     typedef struct storage { // to optimize SD-Load-Time, each clips data is stored in this struct
            u16  PB [512];      //  Pitchband inital = 8192 = No Pitchbend! 
             u8  SEQ[512] [8];  //  512Steps, 8NotePolyphony                                       //loop[c].SEQ bevore
             u8  MSQ[512];      //  Motion-loop[c].SEQ of one CC (Control-Wheel of Keyboard           //loop[c].MSQ bevore 
             u8  CC  [32];      //  Save all other Variables into this Array - for SD-Card...      //loop[c].CC bevore 
             
            char  leader;       // Programchange able? - only 1 of 4 Song-Clips can send Programchanges via BLMatrix
            char  virgin;       // is there any data in the clip? need to display on a ButtonLed Matrix-Launcher     //loop[c].virgin bevore
             u8   length;       // 1x16, 2x16...     //loop[c].length    bevore 
             u8   decay;        // 60ms... could be set with Encoder, but I dont need a variable, since the melody out will be used by the Triggermatrix... //loop[c].decay   bevore  
             u8   rythm;        // 4x4=16, 5x3=15 usw... to calculate maximal duration per UI-matrix page            //loop[c].rythm bevore
            u16   bpm;   
    } store_t;

     

    app.c , initalize data

    //Card-Clip-Container
     store_t loop[8];
    
    void APP_Init(void){
        
        //initalize 8 Clips with standart values
        u8 a = 0;
        for ( a=0; a>8; a++ ) {
            sprintf( loop[a].file_type, "SIGL" );  
            loop[a].leader =  0;   
            loop[a].virgin =  1;
            loop[a].length =  1;
            loop[a].decay =  60;
            loop[a].rythm =   4;
            loop[a].bpm   = 120;
            
            //initiate Pitchbend
            u16 b; for(b=0; b<512; b++)   { loop[a].PB[b] = 8192; }    // 8192: inital No Pitchbend! 
            };

     

    app.c , store data

    //S T O R E Single Clip
    
                                    MUTEX_SDCARD_TAKE;
                                            //Write to File
                                            sprintf(filepathS, "sq/%d-%d.sq", track, clip);             
                                            FILE_WriteOpen	(filepathS,                    1);               
                                            //write struct                                        
                                            FILE_WriteClose	(); 
                                    MUTEX_SDCARD_GIVE;  //SD-Card is now free 4 access
                        break;
    
    //L O A D single Clip
                            MUTEX_SDCARD_TAKE;  
                                   sprintf(filepathL, "sq/%d-%d.sq", track, clip);
                                   FILE_ReadOpen  (&midifile_fi, filepathL);
                                   FILE_ReadBuffer((u8  *)file_type,        4); 
                                    //write struct
                                   FILE_ReadClose	(&midifile_fi);
                            MUTEX_SDCARD_GIVE;      
                            
                            //Calculate new Loop Lengths
                            Loop[track]         = loop[track].length * MainLoop;
                        break;

     

     

     

  12. 2 hours ago, Hawkeye said:

    * Using structs to read in data, e.g. from SD card will speed up things massively, as every further read may block i/o.

    * Memory alignment should only be a problem, if you access data all the time, tens of thousands of times per second :), if you only frequently need some data, don't worry too much, these modern microcontrollers are orders of magnitude faster than old machines. Use the correct memory size for your data and you will be good.

    * What you need to worry about is the data size of your program, so use the smallest possible data type in arrays.

    In short, our core is very fast, but has only very limited ram. It can calculate like a boss, but can only store 3x more than your old C64 :)

    thx good to know!

    i will try them structs

    code is for MelodienSpeicher, where arrays[8][512] polophonic played in 16th (Pitchbend, NoteOn/Off), and also hope that dont hurts when using structs

    u16        PB[8][512] = {{}};    // 8192: inital No Pitchbend! 
     u8  Sequence[8][512][8]={{{}}};     //8Tracks, 512Steps, 8NotePolyphony
     u8    CC_MSQ[8][512] =  {};//Motion-Sequence of one CC (Control-Wheel of Keyboard
    
      s16 TrackClipboard[512][8]  = {{}}; //Copy actual Track into ClipboardBuffer
      u8  StepClipBoard[8][8] = {};   //Just a memory container to copy paste Sequencer Steps

     

  13. to be prepared, today read a lot about structs, and memory-save/performance/code-readable     much to optimize .... it seems that there are things to keep on eye, to avoid heavy bus-load

    ...like order variable by byte size, and others which i cant summize a "i understand"...

    importend for me is that the the program goes fast thru, i dont have memory problems, i think, since it is a sequencer timing is No1

     

    by using struct it will slow down program-process? a normal variable-array is slower? > time not so importend - in case of loading from SD-Card to RAM, but for RAM-Access-time in the Program, hope that question make sense?

     

    then there where people who said, that when i dont use 32bit types, the program have to calc my 1bit 8bit or 16bit into 32bit -memory-slots- and access time will go not so good, other saying that this is only for x86, arm a nother story... dont know: should i use "int" as standard (except for the big sequencer Arrys > memory to low i expirienced today more a 8 or 16bit...) or should i use u8 or u16 instead? i mean when i dont use structs for all those  "not clip related"-variables, just single u8 variables make it any differnce at all?

    -mike

  14. thx has worked:

    FILE_ReadBuffer((u8  *)Sequence[track],  sizeof(Sequence[track]));  //u8 Sequence[8][512][8] 

    FILE_WriteBuffer((u8  *)Sequence[track],  sizeof(Sequence[track]));    //u8 Sequence[8][512][8]

    call: SD(track, clip, job);

    for example: SD(6,1,2); //track 6 dont matter, ProgramChange 1, Load all Clips

                           SD(0,7,1);//track 0, ProgramChange 7, Load single Clip (clip 7-0.sq)

                          SD(0,1,3);//track 0 , ProgramChange 1, Store single Clip (clip 1-0.sq)

                          SD(2,1,4);//track 2 dont matter, ProgramChange 1, Store all Clips

                           SD(2,1,5);//track 2 dont matter, ProgramChange 1 dont matter, Copy track 0-0.sq 512x8 times on SD-Card = Make filestructure = initalize SD-Card > take 20 Minutes

    full code: http://wiki.midibox.org/lib/exe/fetch.php?media=phatline:seq-melody-footboard.zip

    relativly stripped down the SD-Management is done by:

      u8 clip_is_virgin = 1; 
     u16 BPM = 120;
      u8  Rythm = 4;      
      u8 SetDecayTime[8] = {60,60,60,60, 60,60,60,60}; us
      u8 Loop_Length[8] = {1,4,1,4, 1,4,1,4}; 
      u8 CC_SD[8][32] = {}; //Save all other Variables into this Array - for SD-Card...
    
      u8 CC_MSQ[8][512] = {};
      u8 Sequence[8][512][8]={{{}}};     
    
    
    xSemaphoreHandle xSDCardSemaphore; 	// take and give access to SD-Card
    xSemaphoreHandle xLCDSemaphore;		// take and give access to LCD
    
    static file_t midifile_fi; //used to read files from SD-Card
    
    #define MUTEX_LCD_TAKE { while( xSemaphoreTakeRecursive(xLCDSemaphore, (portTickType)0) != pdTRUE ); }  //a Mutex reserve LCD/SD for a task, until it is given away...
    #define MUTEX_LCD_GIVE { xSemaphoreGiveRecursive(xLCDSemaphore); }
    #define PRIORITY_SD                 ( tskIDLE_PRIORITY + 3 ) //3:Mios standart
    
    static void SD(u8 track, u16 clip, u16 job);
    
    void APP_Init(void){
      xLCDSemaphore = xSemaphoreCreateRecursiveMutex(); // create Mutex for LCD access
      xSDCardSemaphore 	= xSemaphoreCreateRecursiveMutex();	//create Mutex for SD-Card access
      FILE_Init(0);// initialize file functions  
    }
    void APP_Tick(void){ //@1mS rate
            SDCardCount++;   //CHECK SD-Car every 2sec.
            if(SDCardCount > 2000) { SDCardCount = 0; SD(0, 0, 5); } //2s Counter > send Check-SDCard-Commant to StoreLoad-Function (u8 track, u16 clip, u16 job)
    }  
    // S T O R A G E - SD - C A R D      ///  read write clips/programchanges
    static void SD(u8 track, u16 clip, u16 job){         //Job1=load all, Job2=store all, Job3=initalize card
        u8 t = 0; //track counter initation
        
        switch(job) {   
    
    // R E A D /////////////////////////////////////////////////////////////////////////////////////////////////////// 
              
                case 1: //LOAD single Clip
                            MUTEX_SDCARD_TAKE;  
                                   sprintf(filepathL, "sq/%d-%d.sq", track, clip);
                                   FILE_ReadOpen  (&midifile_fi, filepathL);
                                   FILE_ReadBuffer((u8  *)file_typeBank,        4); 	
                                   FILE_ReadBuffer((u8  *)CC_SD   [track],  sizeof(CC_SD    [track]));
                                   FILE_ReadBuffer((u8  *)CC_MSQ  [track],  sizeof(CC_MSQ   [track])); //Control-Change-Motion-Sequence
                                   FILE_ReadBuffer((u8  *)Sequence[track],  sizeof(Sequence [track])); //u8 Sequence[8][512][8]  
                                   FILE_ReadBuffer((u8  *)PB      [track],  sizeof(PB       [track]));                  
                                   FILE_ReadClose	(&midifile_fi);
                            MUTEX_SDCARD_GIVE;      
                                
                            //Paste  Variables from Array           
                            Rythm               = CC_SD[track][1];
                            Loop_Length[track]  = CC_SD[track][2];
                            BPM                 = CC_SD[track][4];
                            SetDecayTime[track] = CC_SD[track][5];
                            
                            //Calculate new Loop Lengths
                            Loop[track]         = Loop_Length[track] * MainLoop;
                            
        
                            //SEQ_BPM_Set(BPM);
                            NeedSync = 1; //update ClockCounter when ready...
                   
                            SongNrStor = SongNrLoad; //transfair load nr 2 store nr.
                        break;
                        
                case 2: //LOAD all Clips - FOR  P R O G R A M  C H A N G E
                              for( t=0; t<8; t++) { 
                                    MUTEX_SDCARD_TAKE;  
                                           sprintf(filepathL, "sq/%d-%d.sq", t, clip);
                                           FILE_ReadOpen  (&midifile_fi, filepathL);
                                           FILE_ReadBuffer((u8  *)file_typeBank,     4); 	
                                           FILE_ReadBuffer((u8  *)CC_SD   [t],  sizeof(  CC_SD [t]));
                                           FILE_ReadBuffer((u8  *)CC_MSQ  [t],  sizeof(  CC_MSQ[t])); //Control-Change-Motion-Sequence
                                           FILE_ReadBuffer((u8  *)Sequence[t],  sizeof(Sequence[t])); //u8 Sequence[8][512][8]  
                                           FILE_ReadBuffer((u8  *)PB      [t],  sizeof(      PB[t]));                  
                                           FILE_ReadClose	(&midifile_fi);
                                    MUTEX_SDCARD_GIVE;     
                                     
                                    //Paste  Variables from Array           
                                    Rythm               = CC_SD[t][1];
                                    Loop_Length[t]      = CC_SD[t][2];
                                    BPM                 = CC_SD[t][4];
                                    SetDecayTime[t]     = CC_SD[t][5];
                                    
                                    //Calculate new Loop Lengths
                                    Loop[t]         = Loop_Length[t] * MainLoop;
                            }
                                
    
    
                            //SEQ_BPM_Set(BPM);
                            NeedSync = 1; //update ClockCounter when ready...
                   
                            SongNrStor = SongNrLoad; //transfair load nr 2 store nr.
                            
                            MUTEX_LCD_TAKE; 
                                MIOS32_LCD_DeviceSet(2); MIOS32_LCD_Clear(); MIOS32_LCD_CursorSet(0, 0); 
                                MIOS32_LCD_PrintFormattedString	("%s", "PROGRAM LOAD - Finished");
                            MUTEX_LCD_GIVE; 
                            Update_LCD_s = 1; //normal LCD-Labeling in back again in a second
                        break;
                    	
                        
    // S T O R E /////////////////////////////////////////////////////////////////////////////////////////////////////               
      
                case 3: //S T O R E Single Clip
                
                        //Fill CC-Array of Clip                
                        CC_SD[track][0] = clip_is_virgin;
                        CC_SD[track][1] = Rythm;
                        CC_SD[track][2] = Loop_Length[track];
                        CC_SD[track][4] = BPM;
                        CC_SD[track][5] = SetDecayTime[track];
                
                                    MUTEX_SDCARD_TAKE;
                                            //Write to File
                                            sprintf(filepathS, "sq/%d-%d.sq", track, clip);             
                                            FILE_WriteOpen	(filepathS,                    1);               
                                            FILE_WriteBuffer((u8  *)file_typeBank,         4); //"SQ01" = 4 Positons      
                                            FILE_WriteBuffer((u8  *)CC_SD   [track],  sizeof(CC_SD   [track])); //Track Variables like Looplenght 
                                            FILE_WriteBuffer((u8  *)CC_MSQ  [track],  sizeof(CC_MSQ  [track])); //Control-Change-Motion-Sequence
                                            FILE_WriteBuffer((u8  *)Sequence[track],  sizeof(Sequence[track])); //u8 Sequence[8][512][8]  
                                            FILE_WriteBuffer((u8  *)PB      [track],  sizeof(PB      [track]));  
                                            FILE_WriteClose	(); 
                                    MUTEX_SDCARD_GIVE;  //SD-Card is now free 4 access
                                    Update_LCD_s = 1; //normal LCD-Labeling in back again in secunds
                                    
                                    SongNrLoad = SongNrStor; //transfair load nr 2 store nr.
                        break;
                                    
                case 4: //S T O R E all Clips - FOR  P R O G R A M  C H A N G E
                        
                            for( t=0; t<8; t++)     { // store file once  by once
                                    //Fill CC-Array of Clip                
                                    CC_SD[t][0] = clip_is_virgin;
                                    CC_SD[t][1] = Rythm;
                                    CC_SD[t][2] = Loop_Length[t];           
                                    CC_SD[t][4] = BPM;
                                    CC_SD[t][5] = SetDecayTime[t];
                                    
                                    MUTEX_SDCARD_TAKE;
                                            //Write to File
                                            sprintf(filepathS, "sq/%d-%d.sq", t, clip);             
                                            FILE_WriteOpen	(filepathS,                1);               
                                            FILE_WriteBuffer((u8  *)file_typeBank,     4);  //"SQ01" = 4 Positons      
                                            FILE_WriteBuffer((u8  *)CC_SD   [t],  sizeof(CC_SD   [t]));  //Track Variables like Looplenght 
                                            FILE_WriteBuffer((u8  *)CC_MSQ  [t],  sizeof(CC_MSQ  [t]));   //Control-Change-Motion-Sequence
                                            FILE_WriteBuffer((u8  *)Sequence[t],  sizeof(Sequence[t])); //u8 Sequence[8][512][8]  
                                            FILE_WriteBuffer((u8  *)PB      [t],  sizeof(PB      [t])); 
                                            FILE_WriteClose	(); 
                                    MUTEX_SDCARD_GIVE;  //SD-Card is now free 4 access
                                    }
                                    
                            SongNrLoad = SongNrStor; //transfair load nr 2 store nr.
                            
                            MUTEX_LCD_TAKE; 
                                MIOS32_LCD_DeviceSet(2); MIOS32_LCD_Clear(); MIOS32_LCD_CursorSet(0, 0); 
                                MIOS32_LCD_PrintFormattedString	("%s", "PROGRAM STORE - Finished");
                            MUTEX_LCD_GIVE;
                            Update_LCD_s = 1; //normal LCD-Labeling in back again in secunds
                                                           
                        break;
          
             
    
    //  I N I T - S D - CARD //////////////////////////////////////////////////////////////////////////////////7//////   
      
                case 5: //SD-Card Initalize
                        MUTEX_SDCARD_TAKE;					//SD-Card is now only for the following LINES reserved:
                          statusSD = FILE_CheckSDCard();
                          switch(statusSD) {
                              case 2: MUTEX_LCD_TAKE;  MIOS32_LCD_DeviceSet(2); MIOS32_LCD_Clear(); MIOS32_LCD_CursorSet(0, 0); MIOS32_LCD_PrintFormattedString	("%s", "NO SD-Card"); MUTEX_LCD_GIVE;  break; 
                              case 3:
                                 if	(!FILE_SDCardAvailable() ) {MUTEX_LCD_TAKE; MIOS32_LCD_DeviceSet(2); MIOS32_LCD_Clear(); MIOS32_LCD_CursorSet(0, 0); MIOS32_LCD_PrintFormattedString	("%s", "Insert-FAT-Formated-SD-Card"); MUTEX_LCD_GIVE; break;} 
                                 if	(!FILE_VolumeAvailable() ) {MUTEX_LCD_TAKE; MIOS32_LCD_DeviceSet(2); MIOS32_LCD_Clear(); MIOS32_LCD_CursorSet(0, 0); MIOS32_LCD_PrintFormattedString	("%s", "Format SD-Format to FAT first!"); MUTEX_LCD_GIVE; break;} break;
                              case 1: // YES CARD!  >>> next: check Card-content
                                 statusDir = FILE_DirExists("sq");																								//ask file.c: exist a folder "t/" on the CARD?
                                 if(statusDir == 1){MUTEX_LCD_TAKE; MIOS32_LCD_DeviceSet(2); MIOS32_LCD_Clear(); MIOS32_LCD_CursorSet(0, 0); MIOS32_LCD_PrintFormattedString	("%s", "good SD-file structure");MenueUpdateFlag = 0;MUTEX_LCD_GIVE; break;} 
                                 
                                 if(statusDir == 0){MUTEX_LCD_TAKE; MIOS32_LCD_DeviceSet(2); MIOS32_LCD_Clear(); MIOS32_LCD_CursorSet(0, 0); MIOS32_LCD_PrintFormattedString	("%s", "create 4096 Files on SDC it takes 20min - really!-wait!!! ");MUTEX_LCD_GIVE;
                                                               
                                            //Fill CC-Array of Clip                
                                            CC_SD[track][0] = clip_is_virgin;
                                            CC_SD[track][1] = Rythm;
                                            CC_SD[track][2] = Loop_Length[track];
                                            CC_SD[track][4] = BPM;
                                            CC_SD[track][5] = SetDecayTime[track]; 
                                    
                                            FILE_MakeDir("sq");                           
    
                                            //Write to File
                                            sprintf(filepathS, "sq/%d-%d.sq", track, clip);             
                                            FILE_WriteOpen	(filepathS,                     1);               
                                            FILE_WriteBuffer((u8  *)file_typeBank,          4); //"SQ01" = 4 Positons      
                                            FILE_WriteBuffer((u8  *)CC_SD[track],          32); //Track Variables like Looplenght 
                                            FILE_WriteBuffer((u8  *)CC_MSQ[track],    sizeof(CC_MSQ[track]));   //Control-Change-Motion-Sequence
                                            FILE_WriteBuffer((u8  *)Sequence[track],  sizeof(Sequence[track])); //u8 Sequence[8][512][8]  
                                            FILE_WriteBuffer((u8  *)PB[track],        sizeof(PB[track])); 
                                            FILE_WriteClose	(); 
                                                                
                                                //copy-prototype file to 512x8 clip files on SD-Card
                                                for(t=0; t<8; t++){ 
                                                    
                                                    s16 clipcount = 0; //declare and set the Bank Counter inital value to 0 
                                                    for(clipcount=0; clipcount<512; clipcount++){  //countes 2 511 and do following commandos 511 times in a loop:
                                                        char copyfilepath[16];
                                                        sprintf(copyfilepath, "sq/%d-%d.sq", t, clipcount); //make a new filename depending on the counter value 1.sq, 2.sq, 3.sq...511.sq
                                                        FILE_Copy ((char *)"sq/0-0.sq", (char *)copyfilepath);} //copy the File 0.tm to all other 511 files...
                                                }
                                            
                                    
                                                                        //SD-Card is now free 4 apbess
                            MUTEX_LCD_TAKE; MIOS32_LCD_DeviceSet(0); MIOS32_LCD_Clear(); MIOS32_LCD_CursorSet(0, 0); MIOS32_LCD_PrintFormattedString	("%s", "SD-CARD - INIT - FINISHED"); MUTEX_LCD_GIVE;MenueUpdateFlag = 0;} break;
                            }
                            MUTEX_SDCARD_GIVE;	
                            }
    }

    maybe that helps anyone, or me in the future...

  15. 15 hours ago, Antichambre said:

    Try:

    
    // write
    FILE_WriteBuffer((u8 *)PB[track], sizeof(PB[track]);
    // read
    FILE_ReadBuffer((u8 *)PB[track], sizeof(PB[track]);

    I did it and your project was compiled without error...

    should it does it the same? incl(track) (step) cant wait to try it at home.many thx.4that. mike.

    14 hours ago, Antichambre said:
    
    //write
    u8 PB8[STEP_NUM*2];
    for (i=0; i<STEP_NUM; i++){
      PB8[i*2] = (u8)(PB[track][i] & 0xff);
      PB8[i*2+1] = (u8)(PB[track][i] >> 8);
    }
    FILE_WriteBuffer((u8 *)PB8 , sizeof(PB8));
    //read
    u8 PB8[STEP_NUM*2];
    FILE_ReadBuffer((u8 *)PB8 , sizeof(PB8));
    for (i=0; i<STEP_NUM; i++){
      PB[track][i] = (u16)((PB8[i*2+1] << 8) + PB8[i*2]);
    }

    much less beautiful

     

×
×
  • Create New...