Jump to content

store 16bit variable to 8bit FILE_Writebuffer


Phatline
 Share

Recommended Posts

hi

save my patches with FILE_WriteBuffer like this:

            // 16Bit Pitchbend-value to 2x8Bit value - to get a saveable format
            PB8[0] = * ((unsigned char *)&PB[track]);       //low byte
            PB8[1] = * ((unsigned char *)((&PB[track])+1)); //hi byte
                 
            //Fill CC-Array of Clip                
            CC_SD[0] = clip_is_virgin;
            CC_SD[1] = Rythm;
            CC_SD[2] = Loop_Length[track];
            CC_SD[3] = BPM;
            CC_SD[4] = SetDecayTime[track];   
                              
            //Note-Data of Clip
            sprintf(filepathS, "sq/%d-%d.sq", track, clip);             //First Pattern --- will be later copied 511 times! 	sq/8-512.pb
                            FILE_WriteOpen	(filepathS,                     1);               
                            FILE_WriteBuffer((u8  *)file_typeBank,          4); //"SQ01" = 4 Positons      
                            FILE_WriteBuffer((u8  *)CC_SD,                 32); //Track Variables like Looplenght 
                            FILE_WriteBuffer((u8  *)PB8,                  512); //2x8Bit Pitchbendvalue x 256 Steps     = 512 Blocks                        
                            FILE_WriteBuffer((u8  *)Sequence[track],     2048); //Track, 256Steps, 8NotePolyphony 1x256x8 = 2048 Blocks
                            FILE_WriteClose	();                        
                     

 

i want to save the Pitchband also, i but this is 16bit, and that cant be Written, i need 8Bit Values, so my my 16Bit Pitchband-Variable is named PB[track]

it is done by:

            // 16Bit Pitchbend-value to 2x8Bit value - to get a saveable format
            PB8[0] = * ((unsigned char *)&PB[track]);       //low byte
            PB8[1] = * ((unsigned char *)((&PB[track])+1)); //hi byte

so far ok, QUESTION is: how to combine low and hi byte back to the 16bit Variable PB[track]? (after FILE_ReadBuffer is done)

next question is how to split a multiy-array in low and hi bytes variables: for example PB[track][256]    --- which is the Pitchbend-Information - over 256 Steps in a Sequence.

 

 thx 4 helpß

Edited by Phatline
Link to comment
Share on other sites

Hi Phatline,

I don't remember, sorry, just try.

memcpy(PB[track], &PB8, sizeof(PB8));

memcpy is copying a given length of data from an address to an other address
PB is already a Pointer then this code may work.
Tell me back I want to be sure.

You can try to write your 256 16bit values directly.
 

#define STEP_NUM 256
u16 PB[STEP_NUM];
//populate PB
//...
//write PB
for(i=0; i<STEP_NUM ; i++)FILE_WriteHWord(PB[i]); 

 

4 hours ago, Phatline said:

next question is how to split a multiy-array in low and hi bytes variables: for example PB[track][256]    --- which is the Pitchbend-Information - over 256 Steps in a Sequence.


By using structures union?

//Definitions
#define TRACK_NUM 16
#define STEP_NUM 256 
//Type
typedef union {
  struct {
    u16 data;
  };
   struct {
    u8 datas[2];
  };
  struct {
    u8 data_l;
    u8 data_h;
  };
} data_t;

.....
//Vaiable
data_t PB[TRACK_NUM][STEP_NUM];

.....
//Using
PB[track][step].data = (u16)pitchbend;
//or
PB[track][step].datas[0] = (u8)(pitchbend & 0xff);
PB[track][step].datas[1] = (u8)(pitchbend >> 8);
//or
PB[track][step].data_l = (u8)(pitchbend & 0xff);
PB[track][step].data_h = (u8)(pitchbend >> 8);

Best

Edited by Antichambre
  • Like 1
Link to comment
Share on other sites

4 hours ago, Antichambre said:

You can try to write your 256 16bit values directly.


#define STEP_NUM 256
u16 PB[STEP_NUM];
//populate PB
//...
//write PB
for(i=0; i<STEP_NUM ; i++)FILE_WriteHWord(PB[i]); 

 

hm having troubles by Reading the HWORD - compiler error:

make (im Verzeichnis: /home/...)
rm -f project.hex
Creating object file for app.c
app.c: In function 'SD':
app.c:857:40: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
-------------------------------------------------------------------------------
Application successfully built for:....

app.c:857:40 isthis line:

  for(i=0; i<256; i++){FILE_ReadHWord ((u16  *)PB[track][i]);}  //read Pitchbend u16 values directly    ??

 

u16* and u16

by using this code

//STORE
    if((job == 2) && (track == 8)) {//Store all Data- whole Program-Change-Patterns            
                        MUTEX_SDCARD_TAKE;
                        for (track=0; track<8; track++){ //count thru all tracks
                                               
                    //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,                 32); //Track Variables like Looplenght                      
                                    FILE_WriteBuffer((u8  *)Sequence[track],     2048); //8Tracks, 256Steps, 8NotePolyphony
               for(i=0; i<256; i++){FILE_WriteHWord(PB[track][i]);}  //write Pitchbend u16 values directly
                                    //FILE_WriteBuffer((u8  *)PB8,                 1024); //2x8Bit Pitchbendvalue...2 x 512 Steps= 1024 Blocks                               
                                    FILE_WriteClose	();                         
                    }        
                     MUTEX_SDCARD_GIVE;     
        }
        
    //LOAD
    if((job == 1) && (track == 8)) {//Load all Data- whole Program-Change-Patterns
                  MUTEX_SDCARD_TAKE;     
                    for (track=0; track<8; track++){ 
                        //NOTE-Data of Clip
                       sprintf(filepathL, "sq/%d-%d.sq", track, clip);
                       FILE_ReadOpen  (&midifile_fi, filepathL);
                       FILE_ReadBuffer((u8  *)file_typeBank,       4); 	
                       FILE_ReadBuffer((u8  *)CC_SD,              32); // ALL OTHER VARIABLES are saved in this ARRAY (CC_SD[128])  
                       FILE_ReadBuffer((u8  *)Sequence[track],  2048); ////8Tracks, 256Steps, 8NotePolyphony             
                       u16 i = 0;
  for(i=0; i<256; i++){FILE_ReadHWord ((u16  *)PB[track][i]);}  //write Pitchbend u16 values directly                                    
                       FILE_ReadClose	(&midifile_fi); 

            } 
            MUTEX_SDCARD_GIVE;
        }
    }

 

Edited by Phatline
Link to comment
Share on other sites

this line stops my lcd from reacting and nothing will be written:


                           for(i=0; i<256; i++){ //16bit  pitchbend to 2x8bit -saveable with Writebuffer
                                              PB8[0][i] = PB[track][i] & 0xff;
                                              PB8[1][i] = PB[track][i] >> 8;}  
                                               

 

when used in:

 

                        for (track=0; track<8; track++){ //count thru all tracks

                           for(i=0; i<256; i++){ //16bit  pitchbend to 2x8bit -saveable with Writebuffer
                                              PB8[0][i] = PB[track][i] & 0xff;
                                              PB8[1][i] = PB[track][i] >> 8;}  
                                               
                            MUTEX_SDCARD_TAKE;
                                //Write to File
                                sprintf(filepathS, "sq/%d-%d.sq", track, SongNrStor*4);             
                                            FILE_WriteOpen	(filepathS,                        1);               
                                            FILE_WriteBuffer((u8  *)file_typeBank,             4); //"SQ01" = 4 Positons      
                                            FILE_WriteBuffer((u8  *)CC_SD,                    32); //Track Variables like Looplenght                      
                                            FILE_WriteBuffer((u8  *)Sequence[track],        2048); //u8 Sequence[8][256][8]
                                            FILE_WriteBuffer((u8  *)PB8,                     512); //2x256
                                            FILE_WriteClose	(); 
                            MUTEX_SDCARD_GIVE;  //SD-Card is now free 4 apbess
                    }

, if i delete this lines: all files are written/loadet fine, 

maybe the bitshift takes to long... or sd access is to slow... or code is just waste...

Edited by Phatline
Link to comment
Share on other sites

5 hours ago, Phatline said:

for(i=0; i<256; i++){FILE_ReadHWord ((u16 *)PB[track]);} //read Pitchbend u16 values directly ??

How do you init PB as aray of int or pointer?
If array of int:

for(i=0; i<256; i++)FILE_WriteHWord (PB[track][i]); //write Pitchbend u16 values directly    
for(i=0; i<256; i++)FILE_ReadHWord (&PB[track][i]); //read Pitchbend u16 values directly    

 

Link to comment
Share on other sites

7 hours ago, Antichambre said:

How do you init PB as aray of int or pointer?
If array of int:


for(i=0; i<256; i++)FILE_WriteHWord (PB[track][i]); //write Pitchbend u16 values directly    
for(i=0; i<256; i++)FILE_ReadHWord (&PB[track][i]); //read Pitchbend u16 values directly    

 

    u16 PB[8][256] = {{}};

dont working, LCD hangs.... by just sending a ... SD(0,0,2 or 1) .... i decoppelt already the Load/Store button to directly act on the SD-Function (with counters in milliseconds) which solved issues but not the pitchbend thing...

static void SD(u8 track, u16 clip, u16 job){ 
    
	//STORE
    if(job == 2) {             
                    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,                    32); //Track Variables like Looplenght                      
                                    FILE_WriteBuffer((u8  *)Sequence[track],        2048); //u8 Sequence[8][256][8]={{{}}};     /

                                    for(i=0; i<256; i++)FILE_WriteHWord (PB[track][i]); //write Pitchbend u16 values directly 
                                    FILE_WriteClose	(); 
                    MUTEX_SDCARD_GIVE;  //SD-Card is now free
                    
                    SD_Done_StoreFlag = 1;}

                                                    
    //LOAD
    if(job == 1) {
                        MUTEX_SDCARD_TAKE;  
                            //READ FILE
                           sprintf(filepathL, "sq/%d-%d.sq", track, clip);
                           FILE_ReadOpen  (&midifile_fi, filepathL);
                           FILE_ReadBuffer((u8  *)file_typeBank,        4); 	
                           FILE_ReadBuffer((u8  *)CC_SD,               32); 
                           FILE_ReadBuffer((u8  *)Sequence[track],   2048); //u8 Sequence[8][256][8]             
                                                    
                           for(i=0; i<256; i++)FILE_ReadHWord (&PB[track][i]); //read Pitchbend u16 values directly                  
                           FILE_ReadClose	(&midifile_fi);
                         MUTEX_SDCARD_GIVE;      
    
           SD_Done_Load_Flag = 1;}

 

Link to comment
Share on other sites

On 13.12.2017 at 5:57 PM, Antichambre said:

What is the calling procedure? can you send me (PM) the project? I need a bigger view.
I think structure can resolve write and read but I need to know how it is called.
I'm not at home, nothing to do in the night in my hotel room, I can write something even if I haven't got any hardware to test it...

Best

file is up to date in wiki: http://www.midibox.org/dokuwiki/lib/exe/fetch.php?media=phatline:seq-melody-footboard.zip

when cleaned up this are the Functions involved >

1.APP_DIN_NotifyToggle >>> set a Flag to 1 (Hi)

2.TASK_Blink_Decay >>> wait 250ms, then send a Call to: SD(SaveNextFlag, SongNrStor, 2) = TRACK0, Song-PC0, store command

3.SD(u8 track, u16 clip, u16 job) >>> writing, reading, or initalizing files...

// local prototype of the task function
static void TASK_Blink_Decay(void *pvParameters);
static void SD(u8 track, u16 clip, u16 job);

void APP_DIN_NotifyToggle(u32 pin, u32 pin_value){ //1.STORE-LOAD-BUTTON-ACTION
    if(pin_value == 0) {
        switch(pin) {                 
            case 6:     StoreFlag = 1; break;        
            case 14:    LoadFlag  = 1;  break;         
}}}   


static void SD(u8 track, u16 clip, u16 job){         //3.Job1=load all, Job2=store all, Job3=initalize card
    
	//STORE
    if(job == 2) {
                    //Fill CC-Array of Clip                
                    CC_SD[0] = clip_is_virgin;
                    CC_SD[1] = Rythm;
                    CC_SD[2] = Loop_Length[track];
                    CC_SD[3] = BPM;
                    CC_SD[4] = 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,                    32); //Track Variables like Looplenght                      
                                    FILE_WriteBuffer((u8  *)Sequence[track],        2048); //u8 Sequence[8][256][8]={{{}}};     //8Tracks, 256Steps, 8NotePolyphony
                                    
                                    for(i=0; i<256; i++)FILE_WriteHWord (PB[track][i]); //write Pitchbend u16 values directly 
                                    FILE_WriteClose	(); 
                    MUTEX_SDCARD_GIVE;  //SD-Card is now free 4 apbess
                    
                    SongNrLoad = SongNrStor; //transfair load nr 2 store nr.
                    SD_Done_StoreFlag = 1;}
    
        
        
        
    //LOAD
    if(job == 1) {//Load all Data- whole Program-Change-Patterns

                        MUTEX_SDCARD_TAKE;  
                            //NOTE-Data of Clip
                           sprintf(filepathL, "sq/%d-%d.sq", track, clip);
                           FILE_ReadOpen  (&midifile_fi, filepathL);
                           FILE_ReadBuffer((u8  *)file_typeBank,        4); 	
                           FILE_ReadBuffer((u8  *)CC_SD,               32); 
                           FILE_ReadBuffer((u8  *)Sequence[track],   2048); //u8 Sequence[8][256][8]                 
                           for(i=0; i<256; i++)FILE_ReadHWord (&PB[track][i]); //read Pitchbend u16 values directly                  
                           FILE_ReadClose	(&midifile_fi);
                         MUTEX_SDCARD_GIVE;      
                        
                            //Paste  Variables from Array           
                            clip_is_virgin      = CC_SD[0];
                            Rythm               = CC_SD[1];
                            Loop_Length[track]  = CC_SD[2];
                            BPM                 = CC_SD[3];
                            SetDecayTime[track] = CC_SD[4];


                           //SEQ_BPM_Set(BPM);
           NeedSync = 1; //update ClockCounter when ready...
           
           SongNrStor = SongNrLoad; //transfair load nr 2 store nr.
           SD_Done_Load_Flag = 1;}
    
    
    //SD-Card Initalize - Files
  if((job == 3) && (clip < 8)){//CHECK SD-Card/Initalize Card
....
....                                      
}//End While
}//End TICK 0 >>> 1ms Task...

 

Edited by Phatline
Link to comment
Share on other sites

how ever the endgoal is:

128 Program-Change/Songs a 4clips = 512clips

8tracks a 512 clips

fileformat: [track]-[clip].sq   >>> each clip is a single file which can be called

 

when i Programchange, it loads the first row of clips >>> clip = PC*4 >>>

to load a other clip i need to built a 8x8 blm first: the plan is:

----------------tr0 tr1 tr2 tr3 tr4 tr5 tr6 tr7

last PC                                                x       -       Play-Clip from last Song

empty grid   x    x   x    x    x   x    x   x       -       Indicate that there is no Song to choose

clip.row0      x    x               x                     -         Play Clips[tr0][cliprow0] of actual song....

clip.row1                 x                                 -         

clip.row2                      x

clip.row3                                     

empty grid   x    x   x    x    x   x    x   x

next PC                                         x             -   Play Clips from next song....

 

so its a bit of ableton like... but more song structured.

Link to comment
Share on other sites

//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

Edited by Antichambre
  • Like 1
Link to comment
Share on other sites

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

 

Link to comment
Share on other sites

4 hours ago, Phatline said:

should it does it the same? incl(track) (step)

Yes it's exactly the same result for both.
The first uses your PB 16bits array directly, is elegant if it works.
Have a look on (root)/trunk/apps/processing/midibox_cv_v2/src/mbcv_file_b.cpp , you will find this line:

status |= FILE_ReadBuffer((u8 *)patch_buffer, 2*CV_PATCH_SIZE);

where patch_buffer is declared as an array of u16, you can see that the length is multiplied by two(sizeof will do it for you);
...
The second uses temporary and local u8 array PB8 (512 bytes size), must be slower and is ugly ;)
For this last you have to define STEP_NUM:

#define STEP_NUM 256

or replace it by 256 ;)

Edited by Antichambre
  • Like 1
Link to comment
Share on other sites

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...

Edited by Phatline
Link to comment
Share on other sites

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

Edited by Phatline
Link to comment
Share on other sites

Hi Phatline,

i don't know if i got all questions, but here are some generic answers :)

* 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 :)

Have a good time!
Many greets,
Peter

Link to comment
Share on other sites

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

 

Link to comment
Share on other sites

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;

 

 

 

Link to comment
Share on other sites

Try something like this:

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

and

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. 

Good luck and many greets,
Peter

 

Link to comment
Share on other sites

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

 

Link to comment
Share on other sites

It seems you solved it, just as Bruno recommended it, with the index loop[t] you can (and did) of course address only a single struct and can read/write that at any time, even when the app is running.

Quote

by the way, do i need that

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

for what platforms do i need a filetype?

A filetype generally helps you to reidentify which kind of revision a file has - as it is binary, structs may change and you may not be able to load old data in a new version, so in the loader you can compare the filetype to the expected version.

Quote

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

That happens for all non-array datastructures like plain integers. You need to take their address with the ampersand operator (that can then by typecasted to a u8 pointer) and write

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

Many greets!
Peter

Link to comment
Share on other sites

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...

 

Edited by Phatline
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

×
×
  • Create New...