Subversion Repositories svn.mios32

Rev

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

Rev Author Line No. Line
758 tk 1
// $Id: seq_midimp.c 2635 2019-01-06 17:14:01Z tk $
2
/*
3
 * MIDI File Importer
4
 *
5
 * ==========================================================================
6
 *
7
 *  Copyright (C) 2009 Thorsten Klose (tk@midibox.org)
8
 *  Licensed for personal non-commercial use only.
9
 *  All other rights reserved.
10
 *
11
 * ==========================================================================
12
 */
13
 
14
/////////////////////////////////////////////////////////////////////////////
15
// Include files
16
/////////////////////////////////////////////////////////////////////////////
17
 
18
#include <mios32.h>
19
 
956 tk 20
#include <ff.h>
758 tk 21
#include <string.h>
22
 
23
#include "tasks.h"
24
 
25
#include <seq_midi_out.h>
26
#include <mid_parser.h>
27
 
1261 tk 28
#include "file.h"
29
#include "seq_file.h"
30
 
758 tk 31
#include "seq_midimp.h"
984 tk 32
#include "seq_midply.h"
758 tk 33
#include "seq_core.h"
34
#include "seq_ui.h"
984 tk 35
#include "seq_cc.h"
1117 tk 36
#include "seq_label.h"
984 tk 37
#include "seq_par.h"
38
#include "seq_trg.h"
39
#include "seq_layer.h"
758 tk 40
 
41
 
42
/////////////////////////////////////////////////////////////////////////////
43
// for optional debugging messages via DEBUG_MSG (defined in mios32_config.h)
44
/////////////////////////////////////////////////////////////////////////////
45
#define DEBUG_VERBOSE_LEVEL 0
46
 
47
 
48
/////////////////////////////////////////////////////////////////////////////
984 tk 49
// Local prototypes
50
/////////////////////////////////////////////////////////////////////////////
51
 
52
static u32 SEQ_MIDIMP_read(void *buffer, u32 len);
53
static s32 SEQ_MIDIMP_eof(void);
54
static s32 SEQ_MIDIMP_seek(u32 pos);
55
 
56
static s32 SEQ_MIDIMP_PlayEvent(u8 track, mios32_midi_package_t midi_package, u32 tick);
57
static s32 SEQ_MIDIMP_PlayMeta(u8 track, u8 meta, u32 len, u8 *buffer, u32 tick);
58
 
987 tk 59
static s32 SEQ_MIDIMP_PlayEventAnalyze(u8 track, mios32_midi_package_t midi_package, u32 tick);
60
static s32 SEQ_MIDIMP_PlayMetaAnalyze(u8 track, u8 meta, u32 len, u8 *buffer, u32 tick);
984 tk 61
 
62
 
987 tk 63
 
984 tk 64
/////////////////////////////////////////////////////////////////////////////
758 tk 65
// Local variables
66
/////////////////////////////////////////////////////////////////////////////
67
static seq_midimp_mode_t seq_midimp_mode;
68
 
984 tk 69
static u8 seq_midimp_resolution;
70
static u8 seq_midimp_num_layers;
758 tk 71
 
984 tk 72
// filename
73
#define MIDIFILE_PATH_LEN_MAX 20
1117 tk 74
static char midifile_path[MIDIFILE_PATH_LEN_MAX];
984 tk 75
 
76
static u32 midifile_pos;
77
static u32 midifile_len;
78
 
1261 tk 79
static file_t midifile_fi;
984 tk 80
 
81
static u16 last_step[SEQ_CORE_NUM_TRACKS];
82
static u32 last_tick[SEQ_CORE_NUM_TRACKS];
83
static u16 midi_channel_set;
84
 
987 tk 85
static s8 first_track_with_events;
86
static u8 track_offset;
984 tk 87
 
987 tk 88
 
758 tk 89
/////////////////////////////////////////////////////////////////////////////
90
// Initialisation
91
/////////////////////////////////////////////////////////////////////////////
92
s32 SEQ_MIDIMP_Init(u32 mode)
93
{
94
  // init default mode
984 tk 95
  seq_midimp_mode = SEQ_MIDIMP_MODE_AllNotes;
96
  seq_midimp_resolution = 0;
97
  seq_midimp_num_layers = 8;
758 tk 98
 
984 tk 99
  midifile_pos = 0;
100
  midifile_len = 0;
101
  midifile_path[0] = 0;
102
 
758 tk 103
  return 0; // no error
104
}
984 tk 105
 
106
 
107
/////////////////////////////////////////////////////////////////////////////
108
// get/set mode
109
/////////////////////////////////////////////////////////////////////////////
110
seq_midimp_mode_t SEQ_MIDIMP_ModeGet(void)
111
{
112
  return seq_midimp_mode;
113
}
114
 
115
s32 SEQ_MIDIMP_ModeSet(seq_midimp_mode_t mode)
116
{
117
  if( mode >= SEQ_MIDIMP_MODE_AllNotes && mode <= SEQ_MIDIMP_MODE_AllDrums ) {
118
    seq_midimp_mode = mode;
119
  }  else {
120
    return -1; // invalid mode
121
  }
122
 
123
  return 0; // no error
124
}
125
 
126
/////////////////////////////////////////////////////////////////////////////
127
// get/set resolution
128
// 0: 16th notes (default), 1: 32th notes, 2: 64th notes
129
/////////////////////////////////////////////////////////////////////////////
130
s32 SEQ_MIDIMP_ResolutionGet(void)
131
{
132
  return seq_midimp_resolution;
133
}
134
 
135
s32 SEQ_MIDIMP_ResolutionSet(u8 resolution)
136
{
137
  if( resolution >= 3 )
138
    return -1; // invalid setting
139
  seq_midimp_resolution = resolution;
140
  return 0; // no error
141
}
142
 
143
 
144
/////////////////////////////////////////////////////////////////////////////
145
// get/set number of layers (4, 8 or 16)
146
/////////////////////////////////////////////////////////////////////////////
147
s32 SEQ_MIDIMP_NumLayersGet(void)
148
{
149
  return seq_midimp_num_layers;
150
}
151
 
152
s32 SEQ_MIDIMP_NumLayersSet(u8 num_layers)
153
{
154
  if( num_layers > 16 )
155
    return -1; // invalid setting
156
  seq_midimp_num_layers = num_layers;
157
  return 0; // no error
158
}
159
 
160
 
161
 
162
/////////////////////////////////////////////////////////////////////////////
163
// returns max. number of bars depending on layers and resolution
164
/////////////////////////////////////////////////////////////////////////////
165
s32 SEQ_MIDIMP_MaxBarsGet(void)
166
{
167
  switch( seq_midimp_resolution ) {
168
  case 1: return 1024 / (16*2*seq_midimp_num_layers);
169
  case 2: return 1024 / (16*4*seq_midimp_num_layers);
170
  }
171
  return 1024 / (16*seq_midimp_num_layers);
172
}
173
 
174
 
175
/////////////////////////////////////////////////////////////////////////////
176
// Imports a MIDI file based on selected parameters
177
// returns 0 on success
178
// returns < 0 on misc error (see MIOS terminal)
179
/////////////////////////////////////////////////////////////////////////////
987 tk 180
s32 SEQ_MIDIMP_ReadFile(char *path)
984 tk 181
{
182
  // stop MIDI play function (if running)
183
  SEQ_MIDPLY_RunModeSet(0, 0);
184
 
185
  // install callback functions
186
  MIOS32_IRQ_Disable();
187
  MID_PARSER_InstallFileCallbacks(&SEQ_MIDIMP_read, &SEQ_MIDIMP_eof, &SEQ_MIDIMP_seek);
987 tk 188
  MID_PARSER_InstallEventCallbacks(&SEQ_MIDIMP_PlayEventAnalyze, &SEQ_MIDIMP_PlayMetaAnalyze);
984 tk 189
  MIOS32_IRQ_Enable();
190
 
191
  MUTEX_SDCARD_TAKE;
192
 
1261 tk 193
  s32 status = FILE_ReadOpen(&midifile_fi, path);
984 tk 194
 
195
  if( status < 0 ) {
196
#if DEBUG_VERBOSE_LEVEL >= 1
197
    DEBUG_MSG("[SEQ_MIDIMP_ReadFile] failed to open file, status: %d\n", status);
198
#endif
199
    midifile_path[0] = 0; // disable file
200
  } else {
201
 
202
    // got it
203
    midifile_pos = 0;
204
    midifile_len = midifile_fi.fsize;
205
 
206
    strncpy(midifile_path, path, MIDIFILE_PATH_LEN_MAX);
207
    midifile_path[MIDIFILE_PATH_LEN_MAX-1] = 0;
208
 
209
#if DEBUG_VERBOSE_LEVEL >= 1
210
    DEBUG_MSG("[SEQ_MIDIMP_ReadFile] opened '%s' of length %u\n", path, midifile_len);
211
#endif
212
 
213
    // initialize all mbseq tracks which should be overwritten
214
    // TODO: currently no dedicated track can be imported
215
    u8 track;
216
    int num_steps = 1024 / seq_midimp_num_layers;
217
    for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track) {
218
      if( seq_midimp_mode == SEQ_MIDIMP_MODE_AllDrums ) {
219
    SEQ_PAR_TrackInit(track, num_steps, 1, seq_midimp_num_layers);
220
    SEQ_TRG_TrackInit(track, num_steps, 1, seq_midimp_num_layers);
221
    SEQ_CC_Set(track, SEQ_CC_MIDI_EVENT_MODE, SEQ_EVENT_MODE_Drum);
222
 
223
    u8 only_layers = 0;
224
    u8 all_triggers_cleared = 1;
225
    u8 init_assignments = 1;
226
    SEQ_LAYER_CopyPreset(track, only_layers, all_triggers_cleared, init_assignments);
227
 
228
    SEQ_CC_Set(track, SEQ_CC_PAR_ASG_DRUM_LAYER_A, SEQ_PAR_Type_Velocity);
229
    int i, j;
230
    for(i=0; i<seq_midimp_num_layers; ++i)
231
      for(j=0; j<num_steps; ++j)
232
        SEQ_PAR_Set(track, j, 0, i, 100);
233
 
2635 tk 234
    for(i=0; i<16; ++i) {
235
      u8 note = 36;
236
      SEQ_LABEL_CopyPresetDrum(i, (char *)&seq_core_trk[track].name[5*i], &note);
237
      SEQ_LAYER_PresetDrumNoteSet(ui_edit_preset_num_drum, note); // define new default value for drum
238
    }
984 tk 239
      } else {
240
    SEQ_PAR_TrackInit(track, num_steps, seq_midimp_num_layers, 1);
241
    SEQ_TRG_TrackInit(track, num_steps, seq_midimp_num_layers, 1);
242
    SEQ_CC_Set(track, SEQ_CC_MIDI_EVENT_MODE, SEQ_EVENT_MODE_Note);
243
 
244
    u8 only_layers = 0;
245
    u8 all_triggers_cleared = 1;
246
    u8 init_assignments = 1;
247
    SEQ_LAYER_CopyPreset(track, only_layers, all_triggers_cleared, init_assignments);
248
 
249
    SEQ_CC_Set(track, SEQ_CC_LAY_CONST_A1, SEQ_PAR_Type_Note);
250
    SEQ_CC_Set(track, SEQ_CC_LAY_CONST_A2, SEQ_PAR_Type_Velocity);
251
    SEQ_CC_Set(track, SEQ_CC_LAY_CONST_A3, SEQ_PAR_Type_Length);
252
    int i;
253
    for(i=3; i<16; ++i)
254
      SEQ_CC_Set(track, SEQ_CC_LAY_CONST_A1+i, SEQ_PAR_Type_Note);
255
 
256
    memset((char *)seq_core_trk[track].name, ' ', 80);
257
      }
258
 
259
      SEQ_CC_Set(track, SEQ_CC_MIDI_CHANNEL, track); // will be changed once first note is played
260
      SEQ_CC_Set(track, SEQ_CC_MIDI_PORT, 0); // default port
261
 
262
      switch( seq_midimp_resolution ) {
263
      case 1: SEQ_CC_Set(track, SEQ_CC_CLK_DIVIDER, 7); break;
264
      case 2: SEQ_CC_Set(track, SEQ_CC_CLK_DIVIDER, 3); break;
265
      default: SEQ_CC_Set(track, SEQ_CC_CLK_DIVIDER, 15);
266
      }
267
    }
268
 
269
    for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track) {
270
      last_step[track] = 0;
271
      last_tick[track] = 0;
272
    }
273
    midi_channel_set = 0;
274
 
987 tk 275
    ////////////////////////////////////////////////////////////////////////////////////////////////
276
    // analyze file - check for first track
277
    MID_PARSER_InstallEventCallbacks(&SEQ_MIDIMP_PlayEventAnalyze, &SEQ_MIDIMP_PlayMetaAnalyze);
278
    track_offset = 0;
279
    first_track_with_events = -1;
280
 
984 tk 281
    // read midifile
282
    MID_PARSER_Read();
283
 
284
    // fetch all events
285
    u32 tick;
286
    s32 fetch_status;
287
    u32 max_ticks = ((1024 / seq_midimp_num_layers) * 96 * MIDI_PARSER_PPQN_Get()) / 384;
288
    for(tick=0, fetch_status=1; tick < max_ticks && fetch_status > 0; ++tick)
289
      fetch_status = MID_PARSER_FetchEvents(tick, 1);
987 tk 290
 
291
 
292
#if DEBUG_VERBOSE_LEVEL >= 1
293
    DEBUG_MSG("[SEQ_MIDIMP_ReadFile] analyze step determined first track with events: %d\n", first_track_with_events);
294
#endif
295
 
296
    ////////////////////////////////////////////////////////////////////////////////////////////////
297
    // now read again to import events
298
    MID_PARSER_InstallEventCallbacks(&SEQ_MIDIMP_PlayEvent, &SEQ_MIDIMP_PlayMeta);
299
    track_offset = (first_track_with_events >= 0) ? first_track_with_events : 0;
300
 
301
    // read midifile
302
    MID_PARSER_Read();
303
 
304
    // fetch all events
305
    for(tick=0, fetch_status=1; tick < max_ticks && fetch_status > 0; ++tick)
306
      fetch_status = MID_PARSER_FetchEvents(tick, 1);
984 tk 307
  }
308
 
1261 tk 309
  FILE_ReadClose(&midifile_fi);
984 tk 310
 
311
  MUTEX_SDCARD_GIVE;
312
 
313
  return status;
314
}
315
 
316
 
317
/////////////////////////////////////////////////////////////////////////////
318
// reads <len> bytes from the .mid file into <buffer>
319
// returns number of read bytes
320
/////////////////////////////////////////////////////////////////////////////
321
static u32 SEQ_MIDIMP_read(void *buffer, u32 len)
322
{
323
  s32 status;
324
 
325
  if( !midifile_path[0] )
1261 tk 326
    return FILE_ERR_NO_FILE;
984 tk 327
 
1261 tk 328
  status = FILE_ReadBuffer(buffer, len);
984 tk 329
 
330
  return (status >= 0) ? len : 0;
331
}
332
 
333
 
334
/////////////////////////////////////////////////////////////////////////////
335
// returns 1 if end of file reached
336
/////////////////////////////////////////////////////////////////////////////
337
static s32 SEQ_MIDIMP_eof(void)
338
{
339
  if( midifile_pos >= midifile_len )
340
    return 1; // end of file reached
341
 
342
  return 0;
343
}
344
 
345
 
346
/////////////////////////////////////////////////////////////////////////////
347
// sets file pointer to a specific position
348
// returns -1 if end of file reached
349
/////////////////////////////////////////////////////////////////////////////
350
static s32 SEQ_MIDIMP_seek(u32 pos)
351
{
352
  s32 status;
353
 
354
  if( !midifile_path[0] )
355
    return -1; // end of file reached
356
 
357
  midifile_pos = pos;
358
 
359
  if( midifile_pos >= midifile_len )
360
    status = -1; // end of file reached
361
  else {
1261 tk 362
    status = FILE_ReadSeek(pos);    
984 tk 363
  }
364
 
365
  return status;
366
}
367
 
368
 
369
/////////////////////////////////////////////////////////////////////////////
370
// called when a MIDI event should be played at a given tick
371
/////////////////////////////////////////////////////////////////////////////
372
static s32 SEQ_MIDIMP_PlayEvent(u8 track, mios32_midi_package_t midi_package, u32 tick)
373
{
987 tk 374
  // remove offset determined during analyze step
375
  if( track < track_offset )
376
    return 0;
377
  track-= track_offset;
378
 
984 tk 379
  // check for track selection (TODO: select dedicated track)
380
  if( track >= SEQ_CORE_NUM_TRACKS )
381
    return 0;
382
 
383
  u32 step64th = (16 * tick) / MIDI_PARSER_PPQN_Get();
384
  int step = step64th;
385
  if( seq_midimp_resolution == 0 )
386
    step /= 4;
387
  else if( seq_midimp_resolution == 1 )
388
    step /= 2;
389
 
390
#if DEBUG_VERBOSE_LEVEL >= 2
391
  DEBUG_MSG("[SEQ_MIDIMP_PlayEvent:%u] T%d S64th=%d S16th=%d: %02x %02x %02x\n",
392
        tick, track, step64th, step64th/4,
393
        midi_package.evnt0, midi_package.evnt1, midi_package.evnt2);
394
#endif
395
 
396
  // check for note on/off
397
  if( midi_package.type == NoteOn && midi_package.velocity > 0 ) {
398
    int num_steps = SEQ_PAR_NumStepsGet(track);
399
    int par_layer = 0;
400
    u8 instrument = 0;
401
    u8 take_note = 0;
402
 
403
    if( step < num_steps ) {
404
      if( seq_midimp_mode == SEQ_MIDIMP_MODE_AllDrums ) {
405
    int num_instruments = SEQ_TRG_NumInstrumentsGet(track);
406
    // search for instrument
407
    u8 *drum_notes = (u8 *)&seq_cc_trk[track].lay_const[0*16];
408
    for(instrument=0; instrument<num_instruments; ++instrument) {
409
      if( midi_package.note == drum_notes[instrument] ) {
410
        take_note = 1;
411
        break;
412
      }
413
    }
414
 
415
    if( take_note ) {
416
      SEQ_TRG_GateSet(track, step, instrument, 1);
417
      SEQ_PAR_Set(track, step, par_layer, instrument, midi_package.velocity);
418
    }
419
 
420
      } else {
421
    // determine free parameter layer
422
    if( !SEQ_TRG_GateGet(track, step, instrument) ) {
423
      SEQ_TRG_GateSet(track, step, instrument, 1);
424
      par_layer = 0;
425
      take_note = 1;
426
    } else {
427
      int num_par_layers = SEQ_PAR_NumLayersGet(track);
428
      for(par_layer=3; par_layer<num_par_layers; ++par_layer)
429
        if( !SEQ_PAR_Get(track, step, par_layer, instrument) ) {
430
          take_note = 1;
431
          break;
432
        }
433
    }
434
 
435
    if( take_note ) {
436
#if DEBUG_VERBOSE_LEVEL >= 1
437
      DEBUG_MSG("[SEQ_MIDIMP_PlayEvent:%u] T%d NoteOn %d %d @ step %d/layer %d\n",
438
            tick, track, midi_package.note, midi_package.velocity,
439
            step, par_layer);
440
#endif
441
      SEQ_PAR_Set(track, step, par_layer, instrument, midi_package.note);
442
      if( par_layer == 0 || midi_package.velocity > SEQ_PAR_Get(track, step, 1, instrument) )
443
        SEQ_PAR_Set(track, step, 1, instrument, midi_package.velocity);
444
    }
445
      }
446
    }
447
 
448
    if( take_note ) {
449
      if( last_step[track] != step )
450
    last_tick[track] = tick;
451
      last_step[track] = step;
452
 
453
      if( step > SEQ_CC_Get(track, SEQ_CC_LENGTH) ) {
454
    int length = 16 * (step / 16) + 16;
455
    if( length > num_steps )
456
      length = num_steps;
457
 
458
    // important: set same length for all tracks to avoid unexpected loops
459
    int track_local;
460
    for(track_local=0; track_local<SEQ_CORE_NUM_TRACKS; ++track_local)
461
      SEQ_CC_Set(track_local, SEQ_CC_LENGTH, length-1);
462
      }
463
 
464
      // set midi channel on first note
465
      if( (midi_channel_set & (1 << track)) == 0 ) {
466
    midi_channel_set |= (1 << track);
467
    SEQ_CC_Set(track, SEQ_CC_MIDI_CHANNEL, midi_package.chn);
468
      }
469
    }
470
  } else if( midi_package.type == NoteOff || (midi_package.type == NoteOn && midi_package.velocity == 0) ) {
471
    if( seq_midimp_mode != SEQ_MIDIMP_MODE_AllDrums ) {
472
      // search note in last step
473
      int num_par_layers = SEQ_PAR_NumLayersGet(track);
474
      int par_layer = 0;
475
      u8 instrument = 0;
476
      u8 found_note = 0;
477
 
478
      if( midi_package.note == SEQ_PAR_Get(track, last_step[track], par_layer, instrument) )
479
    found_note = 1;
480
      else {
481
    for(par_layer=3; par_layer<num_par_layers; ++par_layer)
482
      if( midi_package.note == SEQ_PAR_Get(track, last_step[track], par_layer, instrument) ) {
483
        found_note = 1;
484
        break;
485
      }
486
      }
487
 
488
      if( found_note ) {
489
    int num_steps = SEQ_PAR_NumStepsGet(track);
490
 
491
    if( step < num_steps ) {
492
      u32 ppqn = 384; // / (1 << seq_midimp_resolution);
493
      int len = ((tick-last_tick[track]) * ppqn) / MIDI_PARSER_PPQN_Get();
494
 
495
#if DEBUG_VERBOSE_LEVEL >= 1
496
      DEBUG_MSG("[SEQ_MIDIMP_PlayEvent:%u] T%d NoteOff %d @ step %d/layer %d -> len = %d\n",
497
            tick, track, midi_package.note,
498
            step, par_layer, len);
499
#endif
500
      int i;
501
      for(i=last_step[track]; i<step; ++i) {
502
        if( len < 0 )
503
          break;
504
        SEQ_PAR_Set(track, i, 2, instrument, 96);
505
        len -= 96;
506
      }
507
      if( len > 0 )
508
        SEQ_PAR_Set(track, step, 2, instrument, len);
509
    }
510
      }
511
    }
512
  }
513
 
514
  return 0; // no error
515
}
516
 
517
 
518
/////////////////////////////////////////////////////////////////////////////
519
// called when a Meta event should be played/processed at a given tick
520
/////////////////////////////////////////////////////////////////////////////
521
static s32 SEQ_MIDIMP_PlayMeta(u8 track, u8 meta, u32 len, u8 *buffer, u32 tick)
522
{
523
  if( meta == 0x03 ) { // Sequence/Track Name
524
#if DEBUG_VERBOSE_LEVEL >= 2
525
    DEBUG_MSG("[SEQ_MIDIMP:%d:%u] Meta - Track Name: %s\n", track, tick, buffer);
526
#endif
527
  } else if( meta == 0x2f ) { // End of Track
528
#if DEBUG_VERBOSE_LEVEL >= 2
529
    DEBUG_MSG("[SEQ_MIDIMP:%d:%u] Meta - End of Track\n", track, tick, meta);
530
#endif
531
  }
532
 
533
  return 0; // no error
534
}
987 tk 535
 
536
 
537
/////////////////////////////////////////////////////////////////////////////
538
// called when a MIDI event should be played at a given tick
539
/////////////////////////////////////////////////////////////////////////////
540
static s32 SEQ_MIDIMP_PlayEventAnalyze(u8 track, mios32_midi_package_t midi_package, u32 tick)
541
{
542
  // check for track selection (TODO: select dedicated track)
543
  if( track >= SEQ_CORE_NUM_TRACKS )
544
    return 0;
545
 
546
  if( first_track_with_events == -1 || track < first_track_with_events )
547
    first_track_with_events = track;
548
 
549
  return 0;
550
}
551
 
552
 
553
/////////////////////////////////////////////////////////////////////////////
554
// called when a Meta event should be played/processed at a given tick
555
/////////////////////////////////////////////////////////////////////////////
556
static s32 SEQ_MIDIMP_PlayMetaAnalyze(u8 track, u8 meta, u32 len, u8 *buffer, u32 tick)
557
{
558
  // nothing to do during analyze phase
559
  return 0;
560
}