Subversion Repositories svn.mios32

Rev

Rev 1836 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1352 lee 1
// $Id: app.c 1169 2011-04-09 23:31:28Z tk $
2
/*
3
 * MIOS32 SD card polyphonic sample player
4
 *
5
 * ==========================================================================
6
 *
7
 *  Copyright (C) 2011 Lee O'Donnell (lee@bassmaker.co.uk)
8
 *  Base software Copyright (C) 2009 Thorsten Klose (tk@midibox.org)
9
 *  Licensed for personal non-commercial use only.
10
 *  All other rights reserved.
11
 *
12
 * ==========================================================================
13
 */
14
 
15
 
16
/////////////////////////////////////////////////////////////////////////////
17
// Include files
18
/////////////////////////////////////////////////////////////////////////////
19
 
20
#include <mios32.h>
21
#include "app.h"
22
#include <file.h>
23
#include <string.h>
24
 
1366 lee 25
// Task stuff - the bank switch scanning is lower priority than the voice processing
26
#define PRIORITY_VOICE_TASK ( tskIDLE_PRIORITY + 3 )
27
#define PRIORITY_BANKSWITCH_TASK    ( tskIDLE_PRIORITY + 2 )
28
static void TASK_VOICE_SCAN(void *pvParameters);
29
static void TASK_BANKSWITCH_SCAN(void *pvParameters);
30
 
1352 lee 31
/////////////////////////////////////////////////////////////////////////////
32
// Local definitions
33
/////////////////////////////////////////////////////////////////////////////
34
 
35
#define NUM_SAMPLES_TO_OPEN 64  // Maximum number of file handles to use, and how many samples to open
36
#define POLYPHONY 8             // Max voices to sound simultaneously
1363 lee 37
 
38
// Following accounts for: 7 bits (envelope decay) + 7 bits (velocity related volume) + 1-3 bits (mixing up to 8 samples but depends how hot your samples are)
1486 lee 39
#define SAMPLE_SCALING 15        // Number of bits to scale samples down by in order to not distort - added 7 bits for midi volume now
1363 lee 40
 
1357 lee 41
#define MAX_TIME_IN_DMA 45      // Time (*0.1ms) to read sample data for, e.g. 40 = 4.0 mS
1352 lee 42
 
43
#define SAMPLE_BUFFER_SIZE 512  // -> 512 L/R samples, 80 Hz refill rate (11.6~ mS period). DMA refill routine called every 5.8mS.
44
// NB sample rate and SPI prescaler set in mios32_config file - at 44.1kHz, reading 2 bytes per sample is SD card average rate of 86.13kB/s for a single sample
45
 
46
#define DEBUG_VERBOSE_LEVEL 10
47
#define DEBUG_MSG MIOS32_MIDI_SendDebugMessage
48
 
1357 lee 49
// Now mandatory to have this set as legacy read code removed
50
#define CLUSTER_CACHE_SIZE 32 // typically for 32 * 64*512 bytes = max sample file length of 1 MB !!!
1356 tk 51
 
1357 lee 52
// set to 1 to perform right channel inversion for PCM1725 DAC
53
#define DAC_FIX 0
54
 
1371 lee 55
// name of config file on SD card to read
56
#define CONFIG_FNAME "player.cfg"
57
 
1352 lee 58
/////////////////////////////////////////////////////////////////////////////
59
// Local Variables
60
/////////////////////////////////////////////////////////////////////////////
61
 
62
/////////////////////////////////////////////////////////////////////////////
63
// Global Variables
64
/////////////////////////////////////////////////////////////////////////////
65
 
66
// All filenames are supported in 8.3 format
67
 
1371 lee 68
u8 lee_hw=0; // set to enable scanning of Lee's temporary bank switch on J10
1975 tk 69
u8 midichannel=0;   // MIDI channel to respond to
1371 lee 70
 
1366 lee 71
static  u8 voice_no=0;  // used to count number of voices to play
72
static  u8 voice_samples[POLYPHONY];    // Store which sample numbers are playing in which voice
73
static  s16 voice_velocity[POLYPHONY];  // Store the velocity for each sample
1486 lee 74
static s16 midi_volume=127; // 7 bit value to scale the volume of all samples by - needs to be s16 to make multiplies work
1366 lee 75
 
1355 lee 76
char bankprefix[13]="bank.";    // Default sample bank filename prefix on the SD card, needs to have Unix style line feeds
1352 lee 77
static file_t bank_fileinfo;    // Create the file descriptor for bank file
78
 
79
int sample_to_midinote[NUM_SAMPLES_TO_OPEN];        // Stores midi note mappings from bank file
80
u8 no_samples_loaded;                               // Stores number of samples we read in from bank file (and will scan for activity)
81
 
82
static u32 sample_buffer[SAMPLE_BUFFER_SIZE]; // sample buffer used for DMA
83
 
84
static u32 samplefile_pos[NUM_SAMPLES_TO_OPEN]; // Current position in the sample file
85
static u32 samplefile_len[NUM_SAMPLES_TO_OPEN]; // Length of the sample file
1363 lee 86
static s16 sample_on[NUM_SAMPLES_TO_OPEN];  // To track whether each sample should be on or not
87
static s8 sample_vel[NUM_SAMPLES_TO_OPEN];  // Sample velocity
88
static u8 sample_decay[NUM_SAMPLES_TO_OPEN];    // Sample decay parameter (used to calculate per sample, based on velocity the decrement value)
89
static u8 sample_decval[NUM_SAMPLES_TO_OPEN];   // Decay time read in from bank file
90
static u8 no_decay;                             // Used to speed up decay routine if this bank has no decay time
91
static u8 hold_sample[NUM_SAMPLES_TO_OPEN];     // Used to hold sample (for drums)
1352 lee 92
static file_t samplefile_fileinfo[NUM_SAMPLES_TO_OPEN]; // Create the right number of file descriptors
93
static u8 samplebyte_buf[POLYPHONY][SAMPLE_BUFFER_SIZE];    // Create a buffer for each voice
1357 lee 94
static u32 sample_cluster_cache[NUM_SAMPLES_TO_OPEN][CLUSTER_CACHE_SIZE];   // Array of sample cluster positions on SD card
1352 lee 95
 
1366 lee 96
static u8 sample_bank_no=1; // The sample bank number being played
1550 lee 97
static u8 switch_bank_no=1; // The sample bank selected via switch for J10 
1370 lee 98
static u8 damper_pedal=0;   // Damper pedal on channel 1
1356 tk 99
 
1352 lee 100
volatile u8 print_msg;
101
 
1358 lee 102
static u8 sdcard_access_allowed=0; // allow SD Card access for SYNTH_ReloadSampleBuffer
1353 tk 103
 
1362 lee 104
// Curve to map velocity to volume of samples
105
static const u8 velocity_curve[128] = {
106
 
107
36 ,37 ,39 ,41 ,43 ,45 ,46 ,48 ,50 ,51 ,53 ,55 ,56 ,58 ,59 ,61 ,
108
62 ,63 ,65 ,66 ,68 ,69 ,70 ,71 ,73 ,74 ,75 ,76 ,78 ,79 ,80 ,81 ,
109
82 ,83 ,84 ,85 ,86 ,87 ,88 ,89 ,90 ,91 ,92 ,93 ,93 ,94 ,94 ,95 ,
110
96 ,97 ,98 ,99 ,100,101,101,102,103,103,104,105,105,106,107,107,
111
108,109,109,110,110,111,111,112,112,113,113,114,114,115,115,116,
112
116,117,117,118,118,118,119,119,120,120,120,121,121,121,122,122,
113
122,123,123,123,124,124,124,125,125,125,126,126,126,127,127,127
114
};
1353 tk 115
 
1362 lee 116
 
1352 lee 117
// Call this routine with the sample array number to reference, and the filename to open
118
s32 SAMP_FILE_open(u8 sample_n, char fname[])
119
{
1409 lee 120
  DEBUG_MSG("Filename is %s.",fname);
1352 lee 121
  s32 status = FILE_ReadOpen(&samplefile_fileinfo[sample_n], fname);
122
  FILE_ReadClose(&samplefile_fileinfo[sample_n]); // close again - file will be reopened by read handler
123
 
124
  if( status < 0 ) {
125
    DEBUG_MSG("[APP] failed to open file, status: %d\n", status);
126
  } else {
127
 
128
    // got it
129
    samplefile_pos[sample_n] = 0;
130
    samplefile_len[sample_n] = samplefile_fileinfo[sample_n].fsize;
131
 
132
    DEBUG_MSG("[APP] Sample no %d filename %s opened of length %u\n", sample_n,fname,samplefile_len[sample_n]);
133
  }
134
 
135
  return status;
136
}
137
 
138
/////////////////////////////////////////////////////////////////////////////
139
// reads <len> bytes from the .mid file into <buffer>
140
// returns number of read bytes
141
/////////////////////////////////////////////////////////////////////////////
1366 lee 142
int SAMP_FILE_read(void *buffer, u32 len, u8 sample_n)
1352 lee 143
{
1356 tk 144
  // determine sector based on sample position
145
  u32 pos = samplefile_pos[sample_n];
146
  u32 sector_ix = pos / 512;
147
  u32 sectors_per_cluster = FILE_VolumeSectorsPerCluster();
148
  u32 cluster_ix = sector_ix / sectors_per_cluster;
149
  if( cluster_ix >= CLUSTER_CACHE_SIZE )
150
    return -1;
1366 lee 151
 
1356 tk 152
  u32 cluster = sample_cluster_cache[sample_n][cluster_ix];
153
  u32 phys_sector = FILE_VolumeCluster2Sector(cluster) + (sector_ix % sectors_per_cluster);
154
  if( MIOS32_SDCARD_SectorRead(phys_sector, buffer) < 0 )
155
    return -2;
156
  return len;
1352 lee 157
}
158
 
1357 lee 159
void Open_Bank(u8 b_num)    // Open the bank number passed and parse the bank information, load samples, set midi notes, number of samples and cache cluster positions
1352 lee 160
{
161
  u8 samp_no;
1409 lee 162
  u8 f_line[63];                // 0..3=0xXX (hex midi note) 4=space 5=sample hold (0 or 1) 6=space 7..10=decay (4 digit decimal) 11=space 12..23=8.3 filename 24=null
1355 lee 163
  char b_file[13];              // Overall bank name to generate
164
  char b_num_char[4];           // Up to 3 digit bank string plus terminator
1409 lee 165
  static char sample_filenames[NUM_SAMPLES_TO_OPEN][30];        // Stores sample mappings from bank file, needs to be static to avoid crash
1355 lee 166
 
1486 lee 167
  midi_volume=127;      // Reset midi volume to default value
168
 
1355 lee 169
  strcpy(b_file,bankprefix);        // Get prefix in
170
  sprintf(b_num_char,"%d",b_num);   // get bank number as string
171
  strcat(b_file,b_num_char);        // Create the final filename
172
 
1358 lee 173
  MIOS32_BOARD_LED_Set(0x1, 0x1);   // Turn on LED during bank load
1355 lee 174
 
1358 lee 175
  no_samples_loaded=0;
1363 lee 176
  no_decay=1;                       // Default to no decay for bank
1358 lee 177
 
1352 lee 178
  DEBUG_MSG("Opening bank file %s",b_file);
179
  if(FILE_ReadOpen(&bank_fileinfo, b_file)<0) { DEBUG_MSG("Failed to open bank file."); }
1409 lee 180
   else
1352 lee 181
  {
1409 lee 182
          for(samp_no=0;samp_no<NUM_SAMPLES_TO_OPEN;samp_no++)  // Check for up to the defined maximum of sample mappings (one per line)
183
          {
184
            if(FILE_ReadLine(f_line, 63)) // Read line up to 63 chars long
185
            {
186
               //DEBUG_MSG("Sample no %d, Line is: %s",samp_no,f_line);
187
               sample_to_midinote[samp_no]=(int)strtol((char *)(f_line+2),NULL,16); // Convert hex string values to a real number (pos 2 on line, base 16)
188
               hold_sample[samp_no]=(int)strtol((char *)(f_line+5),NULL,10); // Convert sample hold digit
189
               sample_decval[samp_no]=(int)strtol((char *)(f_line+7),NULL,10); // Convert decay number (pos 5 on line, base 10)
190
               if(sample_decval[samp_no]>0) { no_decay=0; } // At least one of the samples requires decay processing
191
               (void) strncpy(sample_filenames[samp_no],(char *)(f_line+12),30);    // Put name into array of sample names (pos 10 on line), up to 12 chars (8.3)   
192
               DEBUG_MSG("Sample no %d, filename is: %s, midi note value=0x%x, decay value %d, hold=%d",samp_no,sample_filenames[samp_no],sample_to_midinote[samp_no],sample_decval[samp_no],hold_sample[samp_no]);
193
               no_samples_loaded++; // increment global number of samples we will read in and scan for in play
194
            }
195
           }
196
          FILE_ReadClose(&bank_fileinfo);
197
 
198
         for(samp_no=0;samp_no<no_samples_loaded;samp_no++) // Open all sample files and mark all samples as off
199
         {
200
           if(SAMP_FILE_open(samp_no,sample_filenames[samp_no])) {
201
           DEBUG_MSG("Open sample file failed.");
202
           } else {
203
             // Pre-read all the cluster positions for all samples to open
204
             u32 num_sectors_per_cluster = FILE_VolumeSectorsPerCluster();
205
             u32 cluster_ix;
206
             for(cluster_ix=0; cluster_ix < CLUSTER_CACHE_SIZE; ++cluster_ix) {
207
               u32 pos = cluster_ix*num_sectors_per_cluster*SAMPLE_BUFFER_SIZE;
1356 tk 208
 
1409 lee 209
               if( pos >= samplefile_len[samp_no] )
210
             break; // end of file reached
211
               else {
212
             s32 status;
213
             if( (status=FILE_ReadReOpen(&samplefile_fileinfo[samp_no])) >= 0 ) {
214
               status = FILE_ReadSeek(pos);
215
               if( status >= 0 ) {
216
                 u8 dummy; // dummy read to update cluster
217
                 status = FILE_ReadBuffer(&dummy, 1);
218
               }
219
               FILE_ReadClose(&samplefile_fileinfo[samp_no]);
220
             }
221
             if( status < 0 )
222
               break;
223
               }
1356 tk 224
 
1409 lee 225
               sample_cluster_cache[samp_no][cluster_ix] = samplefile_fileinfo[samp_no].curr_clust;
226
               DEBUG_MSG("Cluster %d: %d ", cluster_ix, sample_cluster_cache[samp_no][cluster_ix]);
227
             }
228
           }
1356 tk 229
 
1409 lee 230
           sample_on[samp_no]=0;    // Set sample to off
231
         }
232
    }
233
    MIOS32_BOARD_LED_Set(0x1, 0x0); // Turn off LED after bank load
1352 lee 234
}
235
 
1409 lee 236
u8 Read_Switch(void) // Lee's temp hardware: Set up inputs for bank switch as input with pullups, and find if any lines pulled low to select bank 
1355 lee 237
{
1409 lee 238
     u8 pin_no;
239
     u8 bank_val;
1355 lee 240
 
1409 lee 241
     for(pin_no=0;pin_no<8;pin_no++)
242
     {
243
      MIOS32_BOARD_J10_PinInit(pin_no, MIOS32_BOARD_PIN_MODE_INPUT_PU);
244
     }
1355 lee 245
 
1409 lee 246
     bank_val=(u8)MIOS32_BOARD_J10_Get(); // Read all pins, if all pins high, val=0 meaning bank 1, otherwise one pin should be pulled low eg bank_index 0 = bank_val=1 so bank 2
247
     if(bank_val==127) { return 9; }    // D7 = 128 low
248
     if(bank_val==191) { return 8; }    // D6 = 64 low
249
     if(bank_val==223) { return 7; }    // D5 = 32 low
250
     if(bank_val==239) { return 6; }    // D4 = 16 low
251
     if(bank_val==247) { return 5; }    // D3 = 8 low
252
     if(bank_val==251) { return 4; }    // D2 = 4 low
253
     if(bank_val==253) { return 3; }    // D1 = 2 low
254
     if(bank_val==254) { return 2; }    // D0 = 1 low
255
     return 1;      // default to bank 1 (bank val 255)
1355 lee 256
 }
257
 
1371 lee 258
void Read_Config()  // Open the config file on the SD card and (re)set various settings for the player
259
{
260
  u8 f_line[25];                    // parameter and value space separated
261
  char *param_name, *param_value;   //
262
  static file_t config_fileinfo;    // Create the file descriptor for config file
263
 
264
  DEBUG_MSG("Opening config file %s",CONFIG_FNAME);
265
  if(FILE_ReadOpen(&config_fileinfo, CONFIG_FNAME)<0) { DEBUG_MSG("Failed to open config file."); return; }
266
 
267
  while(1)  // keep going until we get an EOF
268
  {
269
    if(FILE_ReadLine(f_line, 25)) // Read line up to 24 chars long
270
    {
271
       //DEBUG_MSG("Config Line is: %s",f_line);
272
       param_name=strtok((char *)f_line, " ");  // find param name up to the space
273
       param_value=strtok(NULL,"\n");   // find value
274
       DEBUG_MSG("Found param %s and value %s",param_name,param_value);
275
       if(!strcmp(param_name,"lee_hw")) { lee_hw=(int)strtol((char *)(param_value),NULL,10); } // Set lee_hw param
276
       if(!strcmp(param_name,"midichannel")) { midichannel=((int)strtol((char *)(param_value),NULL,10)-1); } // Set midichannel (midi receive routines need -1 from decimal value)
277
    }
278
    else { break; } // Hit EOF
279
   }
280
  FILE_ReadClose(&config_fileinfo);
281
}
282
 
1352 lee 283
/////////////////////////////////////////////////////////////////////////////
284
// This hook is called after startup to initialize the application
285
/////////////////////////////////////////////////////////////////////////////
286
void APP_Init(void)
287
{
288
 // initialize all LEDs
289
  MIOS32_BOARD_LED_Init(0xffffffff);
290
 
291
   // print first message
292
  print_msg = PRINT_MSG_INIT;
293
  DEBUG_MSG(MIOS32_LCD_BOOT_MSG_LINE1);
294
  DEBUG_MSG(MIOS32_LCD_BOOT_MSG_LINE2);  
295
  DEBUG_MSG("Initialising SD card..");
296
 
297
  if(FILE_Init(0)<0) { DEBUG_MSG("Error initialising SD card"); } // initialise SD card
298
 
1376 tk 299
  // wait until SD Card available
300
  int timeout_ctr;
301
  for(timeout_ctr=0; timeout_ctr<1000; ++timeout_ctr)
302
    if( MIOS32_SDCARD_CheckAvailable(0) >= 1 )
303
      break;
304
 
305
  if( timeout_ctr == 1000 ) {
306
    DEBUG_MSG("SD Card error: connection failed!");
307
  }
308
 
1352 lee 309
  //s32 status=FILE_PrintSDCardInfos(); // Print SD card info
1371 lee 310
 
311
  // Read config file from SD card
312
  Read_Config();
1352 lee 313
 
314
  // Open bank file
315
 
1371 lee 316
  if (lee_hw)   // If we have non standard bank switch connected
317
  {
318
      DEBUG_MSG("Reading J10 switch");
319
      sample_bank_no=Read_Switch(); // For Lee's temporary bank physical switch on J10 - read first bank to load on boot
320
  }
321
 
1357 lee 322
  Open_Bank(sample_bank_no);    // Open default bank on boot (1 if Lee's switch not read)
323
 
1352 lee 324
  DEBUG_MSG("Initialising synth...");
1357 lee 325
 
326
  // allow SD Card access
327
  sdcard_access_allowed = 1;  
328
 
329
  // init Synth
1352 lee 330
  SYNTH_Init(0);
331
  DEBUG_MSG("Synth init done.");
1353 tk 332
 
1352 lee 333
  MIOS32_STOPWATCH_Init(100);       // Use stopwatch in 100uS accuracy
1366 lee 334
 
335
  // Start tasks for voice processing and bank switch scanning
336
  xTaskCreate(TASK_VOICE_SCAN, (signed portCHAR *)"VOICE_SCAN", configMINIMAL_STACK_SIZE, NULL, PRIORITY_VOICE_TASK, NULL);
337
  xTaskCreate(TASK_BANKSWITCH_SCAN, (signed portCHAR *)"BANKSWITCH_SCAN", configMINIMAL_STACK_SIZE, NULL, PRIORITY_BANKSWITCH_TASK, NULL);
1352 lee 338
}
339
 
340
/////////////////////////////////////////////////////////////////////////////
341
// This hook is called when a MIDI package has been received
342
/////////////////////////////////////////////////////////////////////////////
343
void APP_MIDI_NotifyPackage(mios32_midi_port_t port, mios32_midi_package_t midi_package)
344
{
345
  u8 samp_no;
346
 
1975 tk 347
  if( midi_package.chn == midichannel && (midi_package.type == NoteOn || midi_package.type == NoteOff) )    // Only interested in note on/off on chn1
1352 lee 348
  {
349
    if( midi_package.event == NoteOn && midi_package.velocity > 0 )
350
    {
351
                for(samp_no=0;samp_no<no_samples_loaded;samp_no++)  // go through array looking for mapped notes
352
                {
353
                 if(midi_package.note==sample_to_midinote[samp_no])     // Midi note on matches a note mapped to this sample samp_no
354
                    {
1363 lee 355
                         sample_on[samp_no]=-1;     // Retrigger the sample
1362 lee 356
                         sample_vel[samp_no]=velocity_curve[midi_package.velocity];
1363 lee 357
                            // Mark it as want to play unless it's already on
1352 lee 358
                    //DEBUG_MSG("Turning sample %d on , midi note %x hex",samp_no,midi_package.note);
359
                    }
360
                }
361
            //}
362
    }
363
    else    // We have a note off
364
    {
1363 lee 365
        for(samp_no=0;samp_no<no_samples_loaded;samp_no++)  // go through array looking for mapped notes
1352 lee 366
        {
1370 lee 367
            if (!hold_sample[samp_no] && !damper_pedal) // if not holding sample or damper pedal not pressed, turn the note off, otherwise do nothing
1352 lee 368
            {
1363 lee 369
                if(midi_package.note==sample_to_midinote[samp_no])      // Midi note on matches a note mapped to this sample samp_no
370
                {
1671 lee 371
                    if(no_decay || sample_decval[samp_no]==0 || sample_on[samp_no]==0) { sample_on[samp_no]=0; }        // Turn off immediately if no decay for bank or this sample or the sample finished
1363 lee 372
                    else
373
                    {
374
                        sample_on[samp_no]=sample_decval[samp_no];                          // Mark it as decaying with the appropriate time for this sample
375
                        sample_decay[samp_no]=1+sample_vel[samp_no]/((sample_decval[samp_no]>>3)+1);        // Amount to decay by each 8th time around the DMA routine (big = fast decay)
376
                    }
377
                    //DEBUG_MSG("Turning sample %d off, midi note %x hex",samp_no,midi_package.note);
378
                }
1352 lee 379
            }
380
        }
381
    }
382
  }
1975 tk 383
  else if (midi_package.chn==midichannel && midi_package.type==ProgramChange)
1370 lee 384
    {
385
        sample_bank_no=midi_package.evnt1;  // Set new bank
386
        DEBUG_MSG("MIDI Program Change received - Changing bank to %d",sample_bank_no);
387
        sdcard_access_allowed=0;
388
        DEBUG_MSG("Opening new sample bank");
389
        Open_Bank(sample_bank_no);  // Load relevant bank
390
        sdcard_access_allowed=1;
391
    }
1975 tk 392
  else if (midi_package.chn==midichannel && midi_package.type==CC && midi_package.evnt1==7) // Volume message
1486 lee 393
  {
394
   midi_volume=midi_package.evnt2;  // Set new global midi volume
395
   //DEBUG_MSG("Midi volume set to %d\n", midi_volume);
396
  }
1352 lee 397
  else
398
  {
1370 lee 399
  //DEBUG_MSG("Other MIDI message received, channel %d, event %X, type %X, cc number %d, value %d... ignoring.",midi_package.chn,midi_package.event,midi_package.type,midi_package.cc_number,midi_package.value);
1352 lee 400
  }
401
}
402
 
403
/////////////////////////////////////////////////////////////////////////////
404
// This hook is called before the shift register chain is scanned
405
/////////////////////////////////////////////////////////////////////////////
406
void APP_SRIO_ServicePrepare(void)
407
{
408
}
409
 
410
/////////////////////////////////////////////////////////////////////////////
411
// This hook is called after the shift register chain has been scanned
412
/////////////////////////////////////////////////////////////////////////////
413
void APP_SRIO_ServiceFinish(void)
414
{
415
}
416
 
417
/////////////////////////////////////////////////////////////////////////////
418
// This hook is called when a button has been toggled
419
// pin_value is 1 when button released, and 0 when button pressed
420
/////////////////////////////////////////////////////////////////////////////
421
void APP_DIN_NotifyToggle(u32 pin, u32 pin_value)
422
{
423
}
424
 
425
/////////////////////////////////////////////////////////////////////////////
426
// This function is called by MIOS32_I2S when the lower (state == 0) or 
427
// upper (state == 1) range of the sample buffer has been transfered, so 
428
// that it can be updated
429
/////////////////////////////////////////////////////////////////////////////
430
void SYNTH_ReloadSampleBuffer(u32 state)
431
{
1360 lee 432
  // transfer new samples to the lower/upper sample buffer range
433
  int i;
434
  u32 *buffer = (u32 *)&sample_buffer[state ? (SAMPLE_BUFFER_SIZE/2) : 0];  // point at either 0 or the upper half of buffer
1352 lee 435
 
1360 lee 436
  if( !sdcard_access_allowed )  // no access allowed by main thread
437
    {
438
     for(i=0; i<SAMPLE_BUFFER_SIZE; i+=2) { // Fill half the sample buffer with silence
439
       *buffer++ = 0;   // Muted output
440
     }
441
     return;    
442
    }
1353 tk 443
 
1352 lee 444
  // Each sample buffer entry contains the L/R 32 bit values
445
  // Each call of this routine will need to read in SAMPLE_BUFFER_SIZE/2 samples, each of which requires 16 bits
446
  // Therefore for mono samples, we'll need to read in SAMPLE_BUFFER_SIZE bytes
447
 
1366 lee 448
  u8 voice;
449
 
1352 lee 450
  s16 OutWavs16;    // 16 bit output to DAC
451
  s32 OutWavs32;    // 32 bit accumulator to mix samples into
452
  u32 ms_so_far;        // used to measure time of DMA routine
453
 
454
  MIOS32_STOPWATCH_Reset();         // Reset the stopwatch at start of DMA routine
455
  MIOS32_BOARD_LED_Set(0x1, 0x1);   // Turn on LED at start of DMA routine
456
 
457
 
458
    // Here we have voice_no samples to play simultaneously, and the samples contained in voice_samples array
459
 
460
    if(voice_no)    // if there's anything to play, read the samples and mix otherwise output silence
461
    {
462
        for(voice=0;voice<voice_no;voice++)     // read up to SAMPLE_BUFFER_SIZE characters into buffer for each voice
463
        {
1363 lee 464
            if(SAMP_FILE_read(samplebyte_buf[voice],SAMPLE_BUFFER_SIZE,voice_samples[voice])<0) // Read in the appropriate number of sectors for each sample thats on
465
            {   // if <0 then there was an error reading, so turn this sample off and mute it
466
             sample_on[voice_samples[voice]]=0; // Turn sample off
1366 lee 467
             voice_velocity[voice]=0;           // Silence it in the mix as we don't have a complete buffer
1363 lee 468
            }
469
 
1352 lee 470
            samplefile_pos[voice_samples[voice]]+=SAMPLE_BUFFER_SIZE;   // Move along the file position by the read buffer size
1357 lee 471
            if(samplefile_pos[voice_samples[voice]] >= samplefile_len[voice_samples[voice]]) // We've reached EOF - don't play this sample next time and also free up the voice
1352 lee 472
            {
1363 lee 473
                sample_on[voice_samples[voice]]=0; // Turn sample off
474
                //DEBUG_MSG("Reached EOF on sample %d",voice_samples[voice]);
1357 lee 475
            }
1352 lee 476
             ms_so_far= MIOS32_STOPWATCH_ValueGet();    // Check how long we've been in the routine up until this point
477
            if(ms_so_far>MAX_TIME_IN_DMA)              
478
                {
479
                 DEBUG_MSG("Abandoning DMA routine after %d.%d ms, after %d voices out of %d",ms_so_far/10,ms_so_far%10,voice+1,voice_no);
480
                 voice_no=voice+1;  // don't mix un-read voices (eg if break after 1st voice, voice_no should =1)
481
                 break; // go straight to sample mixing
482
                }
483
        }
484
 
485
        for(i=0; i<SAMPLE_BUFFER_SIZE; i+=2) // Fill half the sample buffer
486
            {  
487
                OutWavs32=0;    // zero the voice accumulator for this sample output
488
                for(voice=0;voice<voice_no;voice++)
489
                {
1354 lee 490
                        OutWavs32+=voice_velocity[voice]*(s16)((samplebyte_buf[voice][i+1] << 8) + samplebyte_buf[voice][i]);       // else mix it in
1352 lee 491
                }
1357 lee 492
                OutWavs32 = (OutWavs32>>SAMPLE_SCALING);    // Round down the wave to prevent distortion, and factor in the velocity multiply
493
                if(OutWavs32>32767) { OutWavs32=32767; }    // Saturate positive
494
                if(OutWavs32<-32768) { OutWavs32=-32768; }  // Saturate negative            
495
                OutWavs16 = (s16)OutWavs32;                 // Required to make following bit shift work correctly including sign bit
496
#if DAC_FIX
497
                *buffer++ = (OutWavs16 << 16) | (-OutWavs16 & 0xffff);  // make up the 32 bit word for L and R and write into buffer with fix for PCM1725 DAC
498
#else
1352 lee 499
                *buffer++ = (OutWavs16 << 16) | (OutWavs16 & 0xffff);   // make up the 32 bit word for L and R and write into buffer
1357 lee 500
#endif
501
                }
1352 lee 502
    }
503
    else    // There were no voices on
504
     { 
505
       for(i=0; i<SAMPLE_BUFFER_SIZE; i+=2) {   // Fill half the sample buffer with silence
506
       *buffer++ = 0;   // Muted output
507
        }
508
     }
509
 
510
     MIOS32_BOARD_LED_Set(0x1, 0x0);    // Turn off LED at end of DMA routine
1357 lee 511
    //ms_so_far= MIOS32_STOPWATCH_ValueGet();   // Check how long we've been in the routine up until this point
1366 lee 512
    //DEBUG_MSG("%d.%d ms,%d.%d ms,%d.%d ms, %d voices",ms2_so_far/10,ms2_so_far%10,ms3_so_far/10,ms3_so_far%10,ms_so_far/10,ms_so_far%10,voice_no);
1352 lee 513
}
514
 
515
/////////////////////////////////////////////////////////////////////////////
516
// initializes the synth
517
/////////////////////////////////////////////////////////////////////////////
518
s32 SYNTH_Init(u32 mode)
519
{
520
  // start I2S DMA transfers
521
  return MIOS32_I2S_Start((u32 *)&sample_buffer[0], SAMPLE_BUFFER_SIZE, &SYNTH_ReloadSampleBuffer);
522
}
523
 
524
/////////////////////////////////////////////////////////////////////////////
1357 lee 525
// This task is running endless in background
526
/////////////////////////////////////////////////////////////////////////////
527
void APP_Background(void)
528
{
529
}
530
 
531
/////////////////////////////////////////////////////////////////////////////
1352 lee 532
// This hook is called when an encoder has been moved
533
// incrementer is positive when encoder has been turned clockwise, else
534
// it is negative
535
/////////////////////////////////////////////////////////////////////////////
536
void APP_ENC_NotifyChange(u32 encoder, s32 incrementer)
537
{
538
}
539
 
540
/////////////////////////////////////////////////////////////////////////////
541
// This hook is called when a pot has been moved
542
/////////////////////////////////////////////////////////////////////////////
543
void APP_AIN_NotifyChange(u32 pin, u32 pin_value)
544
{
1353 tk 545
}
1366 lee 546
 
547
static void TASK_VOICE_SCAN(void *pvParameters)
548
{
549
  u8 samp_no;
1368 lee 550
  u8 new_voice_no;
551
 
1366 lee 552
  portTickType xLastExecutionTime;
553
 
554
  // Initialise the xLastExecutionTime variable on task entry
555
  xLastExecutionTime = xTaskGetTickCount();
556
 
557
  while( 1 )
558
  {
559
    vTaskDelayUntil(&xLastExecutionTime, 1 / portTICK_RATE_MS);     // Run this every 1 ms, this WILL be interrupted every now and again by the DMA fill interrupt
560
 
561
        // toggle Status LED to as a sign of live
562
        //MIOS32_BOARD_LED_Set(1, ~MIOS32_BOARD_LED_Get());
563
 
1368 lee 564
        new_voice_no=0;
1366 lee 565
 
566
        // Work out which voices need to play which sample, this has lowest sample number priority
567
        for(samp_no=0;samp_no<no_samples_loaded;samp_no++)
568
        {
1368 lee 569
            if(new_voice_no<POLYPHONY)  // As long as not already at max voices, otherwise don't trigger/play
1366 lee 570
                {
571
                 if(sample_on[samp_no]<0)   // We want to play this voice (either newly triggered =1 or continue playing =2)
572
                    {
1368 lee 573
                        voice_samples[new_voice_no]=samp_no;    // Assign the next available voice to this sample number
1486 lee 574
                        //voice_velocity[new_voice_no]=(s16)(sample_vel[samp_no]);  // Assign velocity to voice - cast required to ensure the voice accumulation multiply is fast signed 16 bit
575
                        voice_velocity[new_voice_no]=(s16)(sample_vel[samp_no]*midi_volume);    // Assign velocity to voice - cast required to ensure the voice accumulation multiply is fast signed 16 bit
1368 lee 576
                        new_voice_no++;                         // And increment number of voices in use
1366 lee 577
                        if(sample_on[samp_no]==-1)                  // Newly triggered sample (set to -1 by midi receive routine)
578
                        {
579
                         samplefile_pos[samp_no]=0; // Mark at position zero (used for sector reads and EOF calculations)
580
                         sample_on[samp_no]=-2;     // Mark as on and don't retrigger on next loop
581
                         }
582
                    }
583
 
584
                }
585
                else
586
                { break; }      // stop looking if we're full!
587
        }
588
 
1368 lee 589
        if(!no_decay || new_voice_no<POLYPHONY) // Only process decaying notes if decay is enabled or we have any voices left
1366 lee 590
        {
591
            // now new notes allocated, fill up any remaining voices with decaying ones
592
            for(samp_no=0;samp_no<no_samples_loaded;samp_no++)
593
            {
1368 lee 594
                if(new_voice_no<POLYPHONY)  // As long as not already at max voices, otherwise don't trigger/play
1366 lee 595
                    {
596
                    if(sample_on[samp_no]>0)    // positive number = decaying
597
                        {
1368 lee 598
                            voice_samples[new_voice_no]=samp_no;    // Assign the next available voice to this sample number
1549 lee 599
                            voice_velocity[new_voice_no]=(s16)(sample_vel[samp_no]*midi_volume);                   
1368 lee 600
                            new_voice_no++;                         // And increment number of voices in use                
1366 lee 601
                            sample_on[samp_no]--;               // Decrement decay time
602
                            if(sample_on[samp_no]<0) { sample_vel[samp_no]=0; sample_on[samp_no]=0;}    // If finished decaying mark as off
603
                            else
604
                            {
605
                                if((sample_on[samp_no]%8)==0) {
606
                                    sample_vel[samp_no]-=sample_decay[samp_no];     // decrement volume by appropriate amount 
607
                                    //DEBUG_MSG("vel is %d, sample on is %d, sample_decay is %d",sample_vel[samp_no],sample_on[samp_no],sample_decay[samp_no]);
608
                                   }
609
                            }
610
                            if(sample_vel[samp_no]<=0) { sample_vel[samp_no]=0; sample_on[samp_no]=0; }
611
                        }
612
 
613
                    }
614
                    else
615
                    { break;}   // stop looking if we're full
616
            }
617
        }
618
 
1368 lee 619
    voice_no=new_voice_no;  // Set the global voice count now we're done
1366 lee 620
 
621
    }
622
}
623
 
624
static void TASK_BANKSWITCH_SCAN(void *pvParameters)
625
{
626
 u8 this_bank;
627
  portTickType xLastExecutionTime;
628
 
629
  // Initialise the xLastExecutionTime variable on task entry
630
  xLastExecutionTime = xTaskGetTickCount();
631
 
632
  while( 1 )
633
  {
1486 lee 634
    vTaskDelayUntil(&xLastExecutionTime, 100 / portTICK_RATE_MS); // Run this every 0.1s, this WILL be interrupted every now and again by the DMA fill interrupt
1371 lee 635
    if(lee_hw)  // non standard bank switch connected and enabled in config file
636
    {  
637
            // Now check for bank switch change  
638
            this_bank=Read_Switch();    // Get bank value
1550 lee 639
            if(this_bank!=switch_bank_no) {
640
                switch_bank_no=this_bank;   // Set new bank to compare on switch - this is now separate to not interfere with MIDI program changes
1371 lee 641
                sample_bank_no=this_bank;   // Set new bank
642
                DEBUG_MSG("Changing bank to %d",sample_bank_no);
643
                sdcard_access_allowed=0;
644
                DEBUG_MSG("Opening new sample bank");
645
                Open_Bank(sample_bank_no);  // Load relevant bank
646
                sdcard_access_allowed=1;
647
            }
1366 lee 648
    }
649
  }
650
}