Subversion Repositories svn.mios32

Rev

Rev 1363 | Rev 1368 | Go to most recent revision | 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)
1354 lee 39
#define SAMPLE_SCALING 8        // Number of bits to scale samples down by in order to not distort
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 enable scanning of Lee's temporary bank switch on J10
53
#define LEE_HW 1
1356 tk 54
 
1357 lee 55
// set to 1 to perform right channel inversion for PCM1725 DAC
56
#define DAC_FIX 0
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
 
1366 lee 68
static  u8 voice_no=0;  // used to count number of voices to play
69
static  u8 voice_samples[POLYPHONY];    // Store which sample numbers are playing in which voice
70
static  s16 voice_velocity[POLYPHONY];  // Store the velocity for each sample
71
 
72
 
1355 lee 73
char bankprefix[13]="bank.";    // Default sample bank filename prefix on the SD card, needs to have Unix style line feeds
1352 lee 74
static file_t bank_fileinfo;    // Create the file descriptor for bank file
75
 
76
int sample_to_midinote[NUM_SAMPLES_TO_OPEN];        // Stores midi note mappings from bank file
77
u8 no_samples_loaded;                               // Stores number of samples we read in from bank file (and will scan for activity)
78
 
79
static u32 sample_buffer[SAMPLE_BUFFER_SIZE]; // sample buffer used for DMA
80
 
81
static u32 samplefile_pos[NUM_SAMPLES_TO_OPEN]; // Current position in the sample file
82
static u32 samplefile_len[NUM_SAMPLES_TO_OPEN]; // Length of the sample file
1363 lee 83
static s16 sample_on[NUM_SAMPLES_TO_OPEN];  // To track whether each sample should be on or not
84
static s8 sample_vel[NUM_SAMPLES_TO_OPEN];  // Sample velocity
85
static u8 sample_decay[NUM_SAMPLES_TO_OPEN];    // Sample decay parameter (used to calculate per sample, based on velocity the decrement value)
86
static u8 sample_decval[NUM_SAMPLES_TO_OPEN];   // Decay time read in from bank file
87
static u8 no_decay;                             // Used to speed up decay routine if this bank has no decay time
88
static u8 hold_sample[NUM_SAMPLES_TO_OPEN];     // Used to hold sample (for drums)
1352 lee 89
static file_t samplefile_fileinfo[NUM_SAMPLES_TO_OPEN]; // Create the right number of file descriptors
90
static u8 samplebyte_buf[POLYPHONY][SAMPLE_BUFFER_SIZE];    // Create a buffer for each voice
1357 lee 91
static u32 sample_cluster_cache[NUM_SAMPLES_TO_OPEN][CLUSTER_CACHE_SIZE];   // Array of sample cluster positions on SD card
1352 lee 92
 
1366 lee 93
static u8 sample_bank_no=1; // The sample bank number being played
1356 tk 94
 
1352 lee 95
volatile u8 print_msg;
96
 
1358 lee 97
static u8 sdcard_access_allowed=0; // allow SD Card access for SYNTH_ReloadSampleBuffer
1353 tk 98
 
1362 lee 99
// Curve to map velocity to volume of samples
100
static const u8 velocity_curve[128] = {
101
 
102
36 ,37 ,39 ,41 ,43 ,45 ,46 ,48 ,50 ,51 ,53 ,55 ,56 ,58 ,59 ,61 ,
103
62 ,63 ,65 ,66 ,68 ,69 ,70 ,71 ,73 ,74 ,75 ,76 ,78 ,79 ,80 ,81 ,
104
82 ,83 ,84 ,85 ,86 ,87 ,88 ,89 ,90 ,91 ,92 ,93 ,93 ,94 ,94 ,95 ,
105
96 ,97 ,98 ,99 ,100,101,101,102,103,103,104,105,105,106,107,107,
106
108,109,109,110,110,111,111,112,112,113,113,114,114,115,115,116,
107
116,117,117,118,118,118,119,119,120,120,120,121,121,121,122,122,
108
122,123,123,123,124,124,124,125,125,125,126,126,126,127,127,127
109
};
1353 tk 110
 
1362 lee 111
 
1352 lee 112
// Call this routine with the sample array number to reference, and the filename to open
113
s32 SAMP_FILE_open(u8 sample_n, char fname[])
114
{
115
  s32 status = FILE_ReadOpen(&samplefile_fileinfo[sample_n], fname);
116
  FILE_ReadClose(&samplefile_fileinfo[sample_n]); // close again - file will be reopened by read handler
117
 
118
  if( status < 0 ) {
119
    DEBUG_MSG("[APP] failed to open file, status: %d\n", status);
120
  } else {
121
 
122
    // got it
123
    samplefile_pos[sample_n] = 0;
124
    samplefile_len[sample_n] = samplefile_fileinfo[sample_n].fsize;
125
 
126
    DEBUG_MSG("[APP] Sample no %d filename %s opened of length %u\n", sample_n,fname,samplefile_len[sample_n]);
127
  }
128
 
129
  return status;
130
}
131
 
132
/////////////////////////////////////////////////////////////////////////////
133
// reads <len> bytes from the .mid file into <buffer>
134
// returns number of read bytes
135
/////////////////////////////////////////////////////////////////////////////
1366 lee 136
int SAMP_FILE_read(void *buffer, u32 len, u8 sample_n)
1352 lee 137
{
1356 tk 138
  // determine sector based on sample position
139
  u32 pos = samplefile_pos[sample_n];
140
  u32 sector_ix = pos / 512;
141
  u32 sectors_per_cluster = FILE_VolumeSectorsPerCluster();
142
  u32 cluster_ix = sector_ix / sectors_per_cluster;
143
  if( cluster_ix >= CLUSTER_CACHE_SIZE )
144
    return -1;
1366 lee 145
 
1356 tk 146
  u32 cluster = sample_cluster_cache[sample_n][cluster_ix];
147
  u32 phys_sector = FILE_VolumeCluster2Sector(cluster) + (sector_ix % sectors_per_cluster);
148
  if( MIOS32_SDCARD_SectorRead(phys_sector, buffer) < 0 )
149
    return -2;
150
  return len;
1352 lee 151
}
152
 
1357 lee 153
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 154
{
155
  u8 samp_no;
1363 lee 156
  u8 f_line[25];                // 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 157
  char b_file[13];              // Overall bank name to generate
158
  char b_num_char[4];           // Up to 3 digit bank string plus terminator
1358 lee 159
  static char sample_filenames[NUM_SAMPLES_TO_OPEN][13];        // Stores sample mappings from bank file, needs to be static to avoid crash
1355 lee 160
 
161
  strcpy(b_file,bankprefix);        // Get prefix in
162
  sprintf(b_num_char,"%d",b_num);   // get bank number as string
163
  strcat(b_file,b_num_char);        // Create the final filename
164
 
1358 lee 165
  MIOS32_BOARD_LED_Set(0x1, 0x1);   // Turn on LED during bank load
1355 lee 166
 
1358 lee 167
  no_samples_loaded=0;
1363 lee 168
  no_decay=1;                       // Default to no decay for bank
1358 lee 169
 
1352 lee 170
  DEBUG_MSG("Opening bank file %s",b_file);
171
  if(FILE_ReadOpen(&bank_fileinfo, b_file)<0) { DEBUG_MSG("Failed to open bank file."); }
172
 
173
  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)
174
  {
1363 lee 175
    if(FILE_ReadLine(f_line, 25)) // Read line up to 23 chars long
1352 lee 176
    {
1363 lee 177
       //DEBUG_MSG("Sample no %d, Line is: %s",samp_no,f_line);
178
       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)
179
       hold_sample[samp_no]=(int)strtol((char *)(f_line+5),NULL,10); // Convert sample hold digit
180
       sample_decval[samp_no]=(int)strtol((char *)(f_line+7),NULL,10); // Convert decay number (pos 5 on line, base 10)
181
       if(sample_decval[samp_no]>0) { no_decay=0; } // At least one of the samples requires decay processing
182
       (void) strncpy(sample_filenames[samp_no],(char *)(f_line+12),12);    // Put name into array of sample names (pos 10 on line), up to 12 chars (8.3)   
183
       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]);
1352 lee 184
       no_samples_loaded++; // increment global number of samples we will read in and scan for in play
185
    }
186
   }
187
  FILE_ReadClose(&bank_fileinfo);
1355 lee 188
 
189
 for(samp_no=0;samp_no<no_samples_loaded;samp_no++) // Open all sample files and mark all samples as off
190
 {
1356 tk 191
   if(SAMP_FILE_open(samp_no,sample_filenames[samp_no])) {
192
     DEBUG_MSG("Open sample file failed.");
193
   } else {
1357 lee 194
     // Pre-read all the cluster positions for all samples to open
1356 tk 195
     u32 num_sectors_per_cluster = FILE_VolumeSectorsPerCluster();
196
     u32 cluster_ix;
197
     for(cluster_ix=0; cluster_ix < CLUSTER_CACHE_SIZE; ++cluster_ix) {
198
       u32 pos = cluster_ix*num_sectors_per_cluster*SAMPLE_BUFFER_SIZE;
199
 
200
       if( pos >= samplefile_len[samp_no] )
201
     break; // end of file reached
202
       else {
203
     s32 status;
204
     if( (status=FILE_ReadReOpen(&samplefile_fileinfo[samp_no])) >= 0 ) {
205
       status = FILE_ReadSeek(pos);
206
       if( status >= 0 ) {
207
         u8 dummy; // dummy read to update cluster
208
         status = FILE_ReadBuffer(&dummy, 1);
209
       }
210
       FILE_ReadClose(&samplefile_fileinfo[samp_no]);
211
     }
212
     if( status < 0 )
213
       break;
214
       }
215
 
216
       sample_cluster_cache[samp_no][cluster_ix] = samplefile_fileinfo[samp_no].curr_clust;
217
       DEBUG_MSG("Cluster %d: %d ", cluster_ix, sample_cluster_cache[samp_no][cluster_ix]);
218
     }
219
   }
220
 
1357 lee 221
   sample_on[samp_no]=0;    // Set sample to off
1355 lee 222
 }
1358 lee 223
   MIOS32_BOARD_LED_Set(0x1, 0x0);  // Turn off LED after bank load
1352 lee 224
}
225
 
1357 lee 226
#if LEE_HW
1355 lee 227
u8 Read_Switch(void) // Lee's temp hardware: Set up inputs for bank switch as input with pullups, then read bank number (1,2,3,4) based on which of D0, D1 or D2 low
228
{
229
     u8 pin_no;
230
     u8 bank_val;
231
 
232
     for(pin_no=0;pin_no<8;pin_no++)
233
     {
234
      MIOS32_BOARD_J10_PinInit(pin_no, MIOS32_BOARD_PIN_MODE_INPUT_PU);
235
     }
236
 
237
     bank_val=(u8)(MIOS32_BOARD_J10_Get() & 0x07); // Read all pins, but only care about first 3, 7=1st pos (all high), 6=2nd pos (D0 low), 5=3rd pos (D1 low), 3=4th pos (D2 low)
238
     if(bank_val==3) { return 4; }
239
     if(bank_val==5) { return 3; }
240
     if(bank_val==6) { return 2; }   
241
     return 1;      // default to bank 1
242
 }
1357 lee 243
#endif
1355 lee 244
 
1352 lee 245
/////////////////////////////////////////////////////////////////////////////
246
// This hook is called after startup to initialize the application
247
/////////////////////////////////////////////////////////////////////////////
248
void APP_Init(void)
249
{
250
 // initialize all LEDs
251
  MIOS32_BOARD_LED_Init(0xffffffff);
252
 
253
   // print first message
254
  print_msg = PRINT_MSG_INIT;
255
  DEBUG_MSG(MIOS32_LCD_BOOT_MSG_LINE1);
256
  DEBUG_MSG(MIOS32_LCD_BOOT_MSG_LINE2);  
257
  DEBUG_MSG("Initialising SD card..");
258
  MIOS32_SDCARD_PowerOn();
259
 
260
  if(FILE_Init(0)<0) { DEBUG_MSG("Error initialising SD card"); } // initialise SD card
261
 
262
  //s32 status=FILE_PrintSDCardInfos(); // Print SD card info
263
 
264
  // Open bank file
265
 
1357 lee 266
#if LEE_HW
267
  DEBUG_MSG("Reading J10 switch");
268
  sample_bank_no=Read_Switch(); // For Lee's temporary bank physical switch on J10 - read first bank to load on boot
269
#endif
1355 lee 270
 
1357 lee 271
  Open_Bank(sample_bank_no);    // Open default bank on boot (1 if Lee's switch not read)
272
 
1352 lee 273
  DEBUG_MSG("Initialising synth...");
1357 lee 274
 
275
  // allow SD Card access
276
  sdcard_access_allowed = 1;  
277
 
278
  // init Synth
1352 lee 279
  SYNTH_Init(0);
280
  DEBUG_MSG("Synth init done.");
1353 tk 281
 
1352 lee 282
  MIOS32_STOPWATCH_Init(100);       // Use stopwatch in 100uS accuracy
1366 lee 283
 
284
  // Start tasks for voice processing and bank switch scanning
285
  xTaskCreate(TASK_VOICE_SCAN, (signed portCHAR *)"VOICE_SCAN", configMINIMAL_STACK_SIZE, NULL, PRIORITY_VOICE_TASK, NULL);
286
  xTaskCreate(TASK_BANKSWITCH_SCAN, (signed portCHAR *)"BANKSWITCH_SCAN", configMINIMAL_STACK_SIZE, NULL, PRIORITY_BANKSWITCH_TASK, NULL);
1352 lee 287
}
288
 
289
/////////////////////////////////////////////////////////////////////////////
290
// This hook is called when a MIDI package has been received
291
/////////////////////////////////////////////////////////////////////////////
292
void APP_MIDI_NotifyPackage(mios32_midi_port_t port, mios32_midi_package_t midi_package)
293
{
294
  u8 samp_no;
295
 
296
  if( midi_package.chn == Chn1 && (midi_package.type == NoteOn || midi_package.type == NoteOff) )   // Only interested in note on/off on chn1
297
  {
298
    if( midi_package.event == NoteOn && midi_package.velocity > 0 )
299
    {
300
                for(samp_no=0;samp_no<no_samples_loaded;samp_no++)  // go through array looking for mapped notes
301
                {
302
                 if(midi_package.note==sample_to_midinote[samp_no])     // Midi note on matches a note mapped to this sample samp_no
303
                    {
1363 lee 304
                         sample_on[samp_no]=-1;     // Retrigger the sample
1362 lee 305
                         sample_vel[samp_no]=velocity_curve[midi_package.velocity];
1363 lee 306
                            // Mark it as want to play unless it's already on
1352 lee 307
                    //DEBUG_MSG("Turning sample %d on , midi note %x hex",samp_no,midi_package.note);
308
                    }
309
                }
310
            //}
311
    }
312
    else    // We have a note off
313
    {
1363 lee 314
        for(samp_no=0;samp_no<no_samples_loaded;samp_no++)  // go through array looking for mapped notes
1352 lee 315
        {
1363 lee 316
            if (!hold_sample[samp_no])  // if not holding sample, turn the note off, otherwise do nothing
1352 lee 317
            {
1363 lee 318
                if(midi_package.note==sample_to_midinote[samp_no])      // Midi note on matches a note mapped to this sample samp_no
319
                {
320
                    if(no_decay || sample_decval[samp_no]==0) { sample_on[samp_no]=0; }     // Turn off immediately if no decay for bank or this sample
321
                    else
322
                    {
323
                        sample_on[samp_no]=sample_decval[samp_no];                          // Mark it as decaying with the appropriate time for this sample
324
                        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)
325
                    }
326
                    //DEBUG_MSG("Turning sample %d off, midi note %x hex",samp_no,midi_package.note);
327
                }
1352 lee 328
            }
329
        }
330
    }
331
  }
332
  else
333
  {
334
  // DEBUG_MSG("Other MIDI message received... ignoring.");
335
  }
336
}
337
 
338
/////////////////////////////////////////////////////////////////////////////
339
// This hook is called before the shift register chain is scanned
340
/////////////////////////////////////////////////////////////////////////////
341
void APP_SRIO_ServicePrepare(void)
342
{
343
}
344
 
345
/////////////////////////////////////////////////////////////////////////////
346
// This hook is called after the shift register chain has been scanned
347
/////////////////////////////////////////////////////////////////////////////
348
void APP_SRIO_ServiceFinish(void)
349
{
350
}
351
 
352
/////////////////////////////////////////////////////////////////////////////
353
// This hook is called when a button has been toggled
354
// pin_value is 1 when button released, and 0 when button pressed
355
/////////////////////////////////////////////////////////////////////////////
356
void APP_DIN_NotifyToggle(u32 pin, u32 pin_value)
357
{
358
}
359
 
360
/////////////////////////////////////////////////////////////////////////////
361
// This function is called by MIOS32_I2S when the lower (state == 0) or 
362
// upper (state == 1) range of the sample buffer has been transfered, so 
363
// that it can be updated
364
/////////////////////////////////////////////////////////////////////////////
365
void SYNTH_ReloadSampleBuffer(u32 state)
366
{
1360 lee 367
  // transfer new samples to the lower/upper sample buffer range
368
  int i;
369
  u32 *buffer = (u32 *)&sample_buffer[state ? (SAMPLE_BUFFER_SIZE/2) : 0];  // point at either 0 or the upper half of buffer
1352 lee 370
 
1360 lee 371
  if( !sdcard_access_allowed )  // no access allowed by main thread
372
    {
373
     for(i=0; i<SAMPLE_BUFFER_SIZE; i+=2) { // Fill half the sample buffer with silence
374
       *buffer++ = 0;   // Muted output
375
     }
376
     return;    
377
    }
1353 tk 378
 
1352 lee 379
  // Each sample buffer entry contains the L/R 32 bit values
380
  // Each call of this routine will need to read in SAMPLE_BUFFER_SIZE/2 samples, each of which requires 16 bits
381
  // Therefore for mono samples, we'll need to read in SAMPLE_BUFFER_SIZE bytes
382
 
1366 lee 383
  u8 voice;
384
 
1352 lee 385
  s16 OutWavs16;    // 16 bit output to DAC
386
  s32 OutWavs32;    // 32 bit accumulator to mix samples into
387
  u32 ms_so_far;        // used to measure time of DMA routine
388
 
389
  MIOS32_STOPWATCH_Reset();         // Reset the stopwatch at start of DMA routine
390
  MIOS32_BOARD_LED_Set(0x1, 0x1);   // Turn on LED at start of DMA routine
391
 
392
 
393
    // Here we have voice_no samples to play simultaneously, and the samples contained in voice_samples array
394
 
395
    if(voice_no)    // if there's anything to play, read the samples and mix otherwise output silence
396
    {
397
        for(voice=0;voice<voice_no;voice++)     // read up to SAMPLE_BUFFER_SIZE characters into buffer for each voice
398
        {
1363 lee 399
            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
400
            {   // if <0 then there was an error reading, so turn this sample off and mute it
401
             sample_on[voice_samples[voice]]=0; // Turn sample off
1366 lee 402
             voice_velocity[voice]=0;           // Silence it in the mix as we don't have a complete buffer
1363 lee 403
            }
404
 
1352 lee 405
            samplefile_pos[voice_samples[voice]]+=SAMPLE_BUFFER_SIZE;   // Move along the file position by the read buffer size
1357 lee 406
            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 407
            {
1363 lee 408
                sample_on[voice_samples[voice]]=0; // Turn sample off
409
                //DEBUG_MSG("Reached EOF on sample %d",voice_samples[voice]);
1357 lee 410
            }
1352 lee 411
             ms_so_far= MIOS32_STOPWATCH_ValueGet();    // Check how long we've been in the routine up until this point
412
            if(ms_so_far>MAX_TIME_IN_DMA)              
413
                {
414
                 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);
415
                 voice_no=voice+1;  // don't mix un-read voices (eg if break after 1st voice, voice_no should =1)
416
                 break; // go straight to sample mixing
417
                }
418
        }
419
 
420
        for(i=0; i<SAMPLE_BUFFER_SIZE; i+=2) // Fill half the sample buffer
421
            {  
422
                OutWavs32=0;    // zero the voice accumulator for this sample output
423
                for(voice=0;voice<voice_no;voice++)
424
                {
1354 lee 425
                        OutWavs32+=voice_velocity[voice]*(s16)((samplebyte_buf[voice][i+1] << 8) + samplebyte_buf[voice][i]);       // else mix it in
1352 lee 426
                }
1357 lee 427
                OutWavs32 = (OutWavs32>>SAMPLE_SCALING);    // Round down the wave to prevent distortion, and factor in the velocity multiply
428
                if(OutWavs32>32767) { OutWavs32=32767; }    // Saturate positive
429
                if(OutWavs32<-32768) { OutWavs32=-32768; }  // Saturate negative            
430
                OutWavs16 = (s16)OutWavs32;                 // Required to make following bit shift work correctly including sign bit
431
#if DAC_FIX
432
                *buffer++ = (OutWavs16 << 16) | (-OutWavs16 & 0xffff);  // make up the 32 bit word for L and R and write into buffer with fix for PCM1725 DAC
433
#else
1352 lee 434
                *buffer++ = (OutWavs16 << 16) | (OutWavs16 & 0xffff);   // make up the 32 bit word for L and R and write into buffer
1357 lee 435
#endif
436
                }
1352 lee 437
    }
438
    else    // There were no voices on
439
     { 
440
       for(i=0; i<SAMPLE_BUFFER_SIZE; i+=2) {   // Fill half the sample buffer with silence
441
       *buffer++ = 0;   // Muted output
442
        }
443
     }
444
 
445
     MIOS32_BOARD_LED_Set(0x1, 0x0);    // Turn off LED at end of DMA routine
1357 lee 446
    //ms_so_far= MIOS32_STOPWATCH_ValueGet();   // Check how long we've been in the routine up until this point
1366 lee 447
    //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 448
}
449
 
450
/////////////////////////////////////////////////////////////////////////////
451
// initializes the synth
452
/////////////////////////////////////////////////////////////////////////////
453
s32 SYNTH_Init(u32 mode)
454
{
455
  // start I2S DMA transfers
456
  return MIOS32_I2S_Start((u32 *)&sample_buffer[0], SAMPLE_BUFFER_SIZE, &SYNTH_ReloadSampleBuffer);
457
}
458
 
459
/////////////////////////////////////////////////////////////////////////////
1357 lee 460
// This task is running endless in background
461
/////////////////////////////////////////////////////////////////////////////
462
void APP_Background(void)
463
{
464
}
465
 
466
/////////////////////////////////////////////////////////////////////////////
1352 lee 467
// This hook is called when an encoder has been moved
468
// incrementer is positive when encoder has been turned clockwise, else
469
// it is negative
470
/////////////////////////////////////////////////////////////////////////////
471
void APP_ENC_NotifyChange(u32 encoder, s32 incrementer)
472
{
473
}
474
 
475
/////////////////////////////////////////////////////////////////////////////
476
// This hook is called when a pot has been moved
477
/////////////////////////////////////////////////////////////////////////////
478
void APP_AIN_NotifyChange(u32 pin, u32 pin_value)
479
{
1353 tk 480
}
1366 lee 481
 
482
static void TASK_VOICE_SCAN(void *pvParameters)
483
{
484
  u8 samp_no;
485
 
486
  portTickType xLastExecutionTime;
487
 
488
  // Initialise the xLastExecutionTime variable on task entry
489
  xLastExecutionTime = xTaskGetTickCount();
490
 
491
  while( 1 )
492
  {
493
    vTaskDelayUntil(&xLastExecutionTime, 1 / portTICK_RATE_MS);     // Run this every 1 ms, this WILL be interrupted every now and again by the DMA fill interrupt
494
 
495
        // toggle Status LED to as a sign of live
496
        //MIOS32_BOARD_LED_Set(1, ~MIOS32_BOARD_LED_Get());
497
 
498
        voice_no=0;
499
 
500
        // Work out which voices need to play which sample, this has lowest sample number priority
501
        for(samp_no=0;samp_no<no_samples_loaded;samp_no++)
502
        {
503
            if(voice_no<POLYPHONY)  // As long as not already at max voices, otherwise don't trigger/play
504
                {
505
                 if(sample_on[samp_no]<0)   // We want to play this voice (either newly triggered =1 or continue playing =2)
506
                    {
507
                        voice_samples[voice_no]=samp_no;    // Assign the next available voice to this sample number
508
                        voice_velocity[voice_no]=(s16)(sample_vel[samp_no]);    // Assign velocity to voice - cast required to ensure the voice accumulation multiply is fast signed 16 bit
509
                        voice_no++;                         // And increment number of voices in use
510
                        if(sample_on[samp_no]==-1)                  // Newly triggered sample (set to -1 by midi receive routine)
511
                        {
512
                         samplefile_pos[samp_no]=0; // Mark at position zero (used for sector reads and EOF calculations)
513
                         sample_on[samp_no]=-2;     // Mark as on and don't retrigger on next loop
514
                         }
515
                    }
516
 
517
                }
518
                else
519
                { break; }      // stop looking if we're full!
520
        }
521
 
522
        if(!no_decay || voice_no<POLYPHONY) // Only process decaying notes if decay is enabled or we have any voices left
523
        {
524
            // now new notes allocated, fill up any remaining voices with decaying ones
525
            for(samp_no=0;samp_no<no_samples_loaded;samp_no++)
526
            {
527
                if(voice_no<POLYPHONY)  // As long as not already at max voices, otherwise don't trigger/play
528
                    {
529
                    if(sample_on[samp_no]>0)    // positive number = decaying
530
                        {
531
                            voice_samples[voice_no]=samp_no;    // Assign the next available voice to this sample number
532
                            voice_velocity[voice_no]=(s16)(sample_vel[samp_no]);                   
533
                            voice_no++;                         // And increment number of voices in use                
534
                            sample_on[samp_no]--;               // Decrement decay time
535
                            if(sample_on[samp_no]<0) { sample_vel[samp_no]=0; sample_on[samp_no]=0;}    // If finished decaying mark as off
536
                            else
537
                            {
538
                                if((sample_on[samp_no]%8)==0) {
539
                                    sample_vel[samp_no]-=sample_decay[samp_no];     // decrement volume by appropriate amount 
540
                                    //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]);
541
                                   }
542
                            }
543
                            if(sample_vel[samp_no]<=0) { sample_vel[samp_no]=0; sample_on[samp_no]=0; }
544
                        }
545
 
546
                    }
547
                    else
548
                    { break;}   // stop looking if we're full
549
            }
550
        }
551
 
552
 
553
    }
554
}
555
 
556
static void TASK_BANKSWITCH_SCAN(void *pvParameters)
557
{
558
 u8 this_bank;
559
  portTickType xLastExecutionTime;
560
 
561
  // Initialise the xLastExecutionTime variable on task entry
562
  xLastExecutionTime = xTaskGetTickCount();
563
 
564
  while( 1 )
565
  {
566
    vTaskDelayUntil(&xLastExecutionTime, 500 / portTICK_RATE_MS); // Run this every 0.5s, this WILL be interrupted every now and again by the DMA fill interrupt
567
    #if LEE_HW
568
    // Now check for bank switch change  
569
    this_bank=Read_Switch();    // Get bank value
570
    if(this_bank!=sample_bank_no) {
571
        sample_bank_no=this_bank;   // Set new bank
572
        DEBUG_MSG("Changing bank to %d",sample_bank_no);
573
        sdcard_access_allowed=0;
574
        DEBUG_MSG("Opening new sample bank");
575
        Open_Bank(sample_bank_no);  // Load relevant bank
576
        sdcard_access_allowed=1;
577
    }
578
    #endif
579
 
580
  }
581
}