source: ext/midi/midi_file.c @ 651b97e

feature/autosinkfeature/cnnfeature/cnn_orgfeature/constantqfeature/crepefeature/crepe_orgfeature/pitchshiftfeature/pydocstringsfeature/timestretchfix/ffmpeg5pitchshiftsamplertimestretchyinfft+
Last change on this file since 651b97e was a4b089c, checked in by Paul Brossier <piem@altern.org>, 20 years ago

midi_file.c

by default, int is unsigned on powerpc. use signed int instead.

  • Property mode set to 100644
File size: 15.3 KB
Line 
1/*
2 *
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Library General Public License
5 * as published by the Free Software Foundation; either version 2 of
6 * the License, or (at your option) any later version.
7 *
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 * Library General Public License for more details.
12 * 
13 * You should have received a copy of the GNU Library General Public
14 * License along with this library; if not, write to the Free
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
16 * 02111-1307, USA
17 */
18
19/* this file originally taken from FluidSynth - A Software Synthesizer
20 * Copyright (C) 2003  Peter Hanappe and others.
21 *
22 *  \note fixed some track names causing segfault
23 */
24
25#include "aubio_priv.h"
26#include "midi.h"
27#include "midi_event.h"
28#include "midi_track.h"
29#include "midi_player.h"
30#include "midi_file.h"
31
32
33/** aubio_midi_file */
34struct  _aubio_midi_file_t{
35  //aubio_file_t fp;
36  FILE *fp;
37  int running_status;
38  int c;
39  int type;
40  int ntracks;
41  int uses_smpte;
42  unsigned int smpte_fps;
43  unsigned int smpte_res;
44  unsigned int division;       /* If uses_SMPTE == 0 then division is
45                                  ticks per beat (quarter-note) */
46  double tempo;                /* Beats per second (SI rules =) */
47  int tracklen;
48  int trackpos;
49  int eot;
50  int varlen;
51};
52
53/***************************************************************
54 *
55 *                      MIDIFILE
56 */
57
58/** new_aubio_midi_file */
59aubio_midi_file_t * new_aubio_midi_file(char* filename)
60{
61  aubio_midi_file_t* mf;
62
63  mf = AUBIO_NEW(aubio_midi_file_t);
64  if (mf == NULL) {
65    AUBIO_ERR( "Out of memory");
66    return NULL;
67  }
68  AUBIO_MEMSET(mf, 0, sizeof(aubio_midi_file_t));
69
70  mf->c = -1;
71  mf->running_status = -1;
72  mf->fp = AUBIO_FOPEN(filename, "rb");
73
74  if (mf->fp == NULL) {
75    AUBIO_ERR( "Couldn't open the MIDI file !\n");
76    AUBIO_FREE(mf);
77    return NULL;   
78  }
79
80  if (aubio_midi_file_read_mthd(mf) != AUBIO_OK) {
81    AUBIO_FREE(mf);
82    return NULL;
83  }
84  return mf;
85}
86
87/** del_aubio_midi_file */
88void del_aubio_midi_file(aubio_midi_file_t* mf)
89{
90  if (mf == NULL) {
91    return;
92  }
93  if (mf->fp != NULL) {
94    AUBIO_FCLOSE(mf->fp);
95  }
96  AUBIO_FREE(mf);
97  return;
98}
99
100/** aubio_midi_file_getc */
101int aubio_midi_file_getc(aubio_midi_file_t* mf)
102{
103  unsigned char c;
104  int n;
105  if (mf->c >= 0) {
106    c = mf->c;
107    mf->c = -1;
108  } else {
109    n = AUBIO_FREAD(&c, 1, 1, mf->fp);
110    mf->trackpos++;
111  }
112  return (int) c;
113}
114
115/** aubio_midi_file_push */
116int aubio_midi_file_push(aubio_midi_file_t* mf, int c)
117{
118  mf->c = c;
119  return AUBIO_OK;
120}
121
122/** aubio_midi_file_read */
123int aubio_midi_file_read(aubio_midi_file_t* mf, void* buf, int len)
124{
125  int num = AUBIO_FREAD(buf, 1, len, mf->fp);
126  mf->trackpos += num;
127#if DEBUG
128  if (num != len) {
129    AUBIO_DBG( "Coulnd't read the requested number of bytes");
130  }
131#endif
132  return (num != len)? AUBIO_FAIL : AUBIO_OK;
133}
134
135/** aubio_midi_file_skip */
136int aubio_midi_file_skip(aubio_midi_file_t* mf, int skip)
137{
138  int err = AUBIO_FSEEK(mf->fp, skip, SEEK_CUR);
139  if (err) {
140    AUBIO_ERR( "FAIL to seek position in file");
141    return AUBIO_FAIL;   
142  }
143  return AUBIO_OK;
144}
145
146/** aubio_midi_file_read_mthd */
147int aubio_midi_file_read_mthd(aubio_midi_file_t* mf)
148{
149  signed char mthd[15];
150  if (aubio_midi_file_read(mf, mthd, 14) != AUBIO_OK) {
151    return AUBIO_FAIL;
152  }
153  if ((AUBIO_STRNCMP(mthd, "MThd", 4) != 0) || (mthd[7] != 6) || (mthd[9] > 2)) {
154    AUBIO_ERR( "Doesn't look like a MIDI file: invalid MThd header");
155    return AUBIO_FAIL;
156  }
157  mf->type = mthd[9];
158  mf->ntracks = (unsigned) mthd[11];
159  mf->ntracks += (unsigned int) (mthd[10]) << 16;
160  /** \bug: smpte timing not yet implemented */ 
161  if((int)(mthd[12]) < 0){
162  /*if((mthd[12]) < 0){*/
163    mf->uses_smpte = 1;
164    mf->smpte_fps = -mthd[12];
165    mf->smpte_res = (unsigned) mthd[13];
166    AUBIO_ERR( "File uses SMPTE timing -- Not implemented yet");
167    return AUBIO_FAIL;
168  } else {
169    mf->uses_smpte = 0;
170    mf->division = (mthd[12] << 8) | (mthd[13] & 0xff);
171  }
172  return AUBIO_OK;
173}
174
175/** aubio_midi_file_load_tracks */
176int aubio_midi_file_load_tracks(aubio_midi_file_t* mf, aubio_midi_player_t* player)
177{
178  int i;
179  for (i = 0; i < mf->ntracks; i++) {
180    if (aubio_midi_file_read_track(mf, player, i) != AUBIO_OK) {
181      return AUBIO_FAIL;
182    }
183  }
184  return AUBIO_OK;
185}
186
187/** aubio_midi_file_read_tracklen */
188int aubio_midi_file_read_tracklen(aubio_midi_file_t* mf)
189{
190  unsigned char length[5];
191  if (aubio_midi_file_read(mf, length, 4) != AUBIO_OK) {
192    return AUBIO_FAIL;
193  }
194  mf->tracklen = aubio_getlength(length);
195  mf->trackpos = 0;
196  mf->eot = 0;
197  return AUBIO_OK;
198}
199
200/** aubio_midi_file_eot */
201int aubio_midi_file_eot(aubio_midi_file_t* mf)
202{
203#if DEBUG
204  if (mf->trackpos > mf->tracklen) {
205    printf("track overrun: %d > %d\n", mf->trackpos, mf->tracklen);
206  }
207#endif
208  return mf->eot || (mf->trackpos >= mf->tracklen);
209}
210
211/** aubio_midi_file_read_track */
212int aubio_midi_file_read_track(aubio_midi_file_t* mf, aubio_midi_player_t* player, int num)
213{
214  aubio_track_t* track;
215  unsigned char id[5], length[5];
216  int found_track = 0;
217  int skip;
218
219  AUBIO_DBG("Loading track %d\n",num);
220  if (aubio_midi_file_read(mf, id, 4) != AUBIO_OK) {
221    AUBIO_DBG("Failed loading track %d\n",num);
222    return AUBIO_FAIL;
223  }
224 
225  id[4]='\0';
226
227  while (!found_track){
228
229    if (aubio_isasciistring((char*) id) == 0) {
230      AUBIO_ERR( "An non-ascii track header found, currupt file");
231      return AUBIO_FAIL;
232
233    } else if (strcmp((char*) id, "MTrk") == 0) {
234
235      found_track = 1;
236
237      if (aubio_midi_file_read_tracklen(mf) != AUBIO_OK) {
238        return AUBIO_FAIL;
239      }
240
241      track = new_aubio_track(num);
242      if (track == NULL) {
243        AUBIO_ERR( "Out of memory");
244        return AUBIO_FAIL;
245      }
246
247      while (!aubio_midi_file_eot(mf)) {
248        if (aubio_midi_file_read_event(mf, track) != AUBIO_OK) {
249          return AUBIO_FAIL;     
250        }
251      }
252
253      aubio_midi_player_add_track(player, track);
254    } else {
255      found_track = 0;
256      if (aubio_midi_file_read(mf, length, 4) != AUBIO_OK) {
257        return AUBIO_FAIL;
258      }
259      skip = aubio_getlength(length);
260      /* fseek(mf->fp, skip, SEEK_CUR); */
261      if (aubio_midi_file_skip(mf, skip) != AUBIO_OK) {
262        return AUBIO_FAIL;
263      }
264    }
265  }
266
267  if (feof(mf->fp)) {
268    AUBIO_ERR( "Unexpected end of file");
269    return AUBIO_FAIL;
270  }
271  AUBIO_DBG("Loaded track %d\n",num);
272  return AUBIO_OK;
273}
274
275/** aubio_midi_file_read_varlen */
276int aubio_midi_file_read_varlen(aubio_midi_file_t* mf)
277{ 
278  int i;
279  int c;
280  mf->varlen = 0;
281  for (i = 0;;i++) {
282    if (i == 4) {
283      AUBIO_ERR( "Invalid variable length number");
284      return AUBIO_FAIL;
285    }
286    c = aubio_midi_file_getc(mf);
287    if (c < 0) {
288      AUBIO_ERR( "Unexpected end of file");
289      return AUBIO_FAIL;
290    }
291    if (c & 0x80){
292      mf->varlen |= (int) (c & 0x7F);
293      mf->varlen <<= 7;
294    } else {
295      mf->varlen += c;
296      break;
297    }   
298  }
299  return AUBIO_OK;
300}
301
302/** aubio_midi_file_read_event */
303int aubio_midi_file_read_event(aubio_midi_file_t* mf, aubio_track_t* track)
304{
305  int dtime;
306  int status;
307  int type;
308  int tempo;
309  unsigned char* metadata = NULL;
310  unsigned char* dyn_buf = NULL;
311  unsigned char static_buf[256];
312  int nominator, denominator, clocks, notes, sf, mi;
313  aubio_midi_event_t* evt;
314  int channel = 0;
315  int param1 = 0;
316  int param2 = 0;
317
318
319  /* read the delta-time of the event */
320  if (aubio_midi_file_read_varlen(mf) != AUBIO_OK) {
321    return AUBIO_FAIL;
322  }
323  dtime = mf->varlen;
324
325  /* read the status byte */
326  status = aubio_midi_file_getc(mf);
327  if (status < 0) {
328    AUBIO_ERR( "Unexpected end of file");
329    return AUBIO_FAIL;
330  }
331
332  /* not a valid status byte: use the running status instead */
333  if ((status & 0x80) == 0) {
334    if ((mf->running_status & 0x80) == 0) {
335      AUBIO_ERR( "Undefined status and invalid running status");
336      return AUBIO_FAIL;
337    }
338    aubio_midi_file_push(mf, status);
339    status = mf->running_status;
340  } 
341
342  /* check what message we have */
343  if (status & 0x80) {
344    mf->running_status = status;
345
346    if ((status == MIDI_SYSEX) || (status == MIDI_EOX)) {     /* system exclusif */
347      /** \bug Sysex messages are not handled yet */
348      /* read the length of the message */
349      if (aubio_midi_file_read_varlen(mf) != AUBIO_OK) {
350        return AUBIO_FAIL;
351      }
352
353      if (mf->varlen < 255) {
354        metadata = &static_buf[0];
355      } else {
356        AUBIO_DBG( "%s: %d: alloc metadata, len = %d", __FILE__, __LINE__, mf->varlen);
357        dyn_buf = AUBIO_MALLOC(mf->varlen + 1);
358        if (dyn_buf == NULL) {
359          //AUBIO_LOG(AUBIO_PANIC, "Out of memory");
360          AUBIO_ERR("Out of memory");
361          return AUBIO_FAIL;
362        }
363        metadata = dyn_buf;
364      }
365
366      /* read the data of the message */
367      if (mf->varlen) {
368
369        if (aubio_midi_file_read(mf, metadata, mf->varlen) != AUBIO_OK) {
370          if (dyn_buf) {
371            AUBIO_FREE(dyn_buf);
372          }
373          return AUBIO_FAIL;
374        }
375
376        if (dyn_buf) {
377          AUBIO_DBG( "%s: %d: free metadata", __FILE__, __LINE__);
378          AUBIO_FREE(dyn_buf);
379        }
380      }
381
382      return AUBIO_OK;
383
384    } else if (status == MIDI_META_EVENT) {             /* meta events */
385
386      int result = AUBIO_OK;
387
388      /* get the type of the meta message */
389      type = aubio_midi_file_getc(mf);
390      if (type < 0) {
391        AUBIO_ERR( "Unexpected end of file");
392        return AUBIO_FAIL;
393      }
394
395      /* get the length of the data part */
396      if (aubio_midi_file_read_varlen(mf) != AUBIO_OK) {
397        return AUBIO_FAIL;
398      }
399
400      if (mf->varlen) {
401
402        if (mf->varlen < 255) {
403          metadata = &static_buf[0];
404        } else {
405          AUBIO_DBG( "%s: %d: alloc metadata, len = %d", __FILE__, __LINE__, mf->varlen);
406          dyn_buf = AUBIO_MALLOC(mf->varlen + 1);
407          if (dyn_buf == NULL) {
408            AUBIO_ERR("Out of memory");
409            return AUBIO_FAIL;
410          }
411          metadata = dyn_buf;
412        }
413
414        /* read the data */
415        if (aubio_midi_file_read(mf, metadata, mf->varlen) != AUBIO_OK) {
416          if (dyn_buf) {
417            AUBIO_FREE(dyn_buf);
418          }
419          return AUBIO_FAIL;
420        }
421      }
422
423      /* handle meta data */
424      switch (type) {
425
426        case MIDI_COPYRIGHT:
427          metadata[mf->varlen] = 0;
428          break;
429
430        case MIDI_TRACK_NAME:
431          if (metadata != NULL) /* avoids crashes on empty tracks */
432            metadata[mf->varlen] = 0;
433          aubio_track_set_name(track, (char*) metadata);
434          break;
435
436        case MIDI_INST_NAME:
437          metadata[mf->varlen] = 0;
438          break;
439
440        case MIDI_LYRIC:
441          break;
442
443        case MIDI_MARKER:
444          break;
445
446        case MIDI_CUE_POINT:
447          break; /* don't care much for text events */
448
449        case MIDI_EOT:
450          if (mf->varlen != 0) {
451            AUBIO_ERR("Invalid length for EndOfTrack event");
452            result = AUBIO_FAIL;
453            break;
454          }
455          mf->eot = 1;
456          break; 
457
458        case MIDI_SET_TEMPO:
459          if (mf->varlen != 3) {
460            AUBIO_ERR("Invalid length for SetTempo meta event");
461            result = AUBIO_FAIL;
462            break;
463          }
464          tempo = (metadata[0] << 16) + (metadata[1] << 8) + metadata[2];
465          evt = new_aubio_midi_event();
466          if (evt == NULL) {
467            AUBIO_ERR( "Out of memory");
468            result = AUBIO_FAIL;
469            break;
470          }
471          evt->dtime = dtime;
472          evt->type = MIDI_SET_TEMPO;
473          evt->channel = 0;
474          evt->param1 = tempo;
475          evt->param2 = 0;
476          aubio_track_add_event(track, evt);
477          break; 
478
479        case MIDI_SMPTE_OFFSET:
480          if (mf->varlen != 5) {
481            AUBIO_ERR("Invalid length for SMPTE Offset meta event");
482            result = AUBIO_FAIL;
483            break;
484          }
485          break; /* we don't use smtp */       
486
487        case MIDI_TIME_SIGNATURE:
488          if (mf->varlen != 4) {
489            AUBIO_ERR("Invalid length for TimeSignature meta event");
490            result = AUBIO_FAIL;
491            break;
492          }
493          nominator = metadata[0];
494          denominator = pow(2.0, (double) metadata[1]);
495          clocks = metadata[2];
496          notes = metadata[3];
497
498          AUBIO_DBG("signature=%d/%d, metronome=%d, 32nd-notes=%d\n", 
499              nominator, denominator, clocks, notes);
500
501          break;
502
503        case MIDI_KEY_SIGNATURE:
504          if (mf->varlen != 2) {
505            AUBIO_ERR( "Invalid length for KeySignature meta event");
506            result = AUBIO_FAIL;
507            break;
508          }
509          sf = metadata[0];
510          mi = metadata[1];
511          break;
512
513        case MIDI_SEQUENCER_EVENT:
514          AUBIO_DBG("Sequencer event ignored\n");
515          break;
516
517        default:
518          break;
519      }
520
521      if (dyn_buf) {
522        AUBIO_DBG( "%s: %d: free metadata", __FILE__, __LINE__);
523        AUBIO_FREE(dyn_buf);
524      }
525
526      return result;
527
528    } else {                /* channel messages */
529
530      type = status & 0xf0;
531      channel = status & 0x0f;
532
533      /* all channel message have at least 1 byte of associated data */
534      if ((param1 = aubio_midi_file_getc(mf)) < 0) {
535        AUBIO_ERR( "Unexpected end of file");
536        return AUBIO_FAIL;
537      }
538
539      switch (type) {
540
541        case NOTE_ON:
542          if ((param2 = aubio_midi_file_getc(mf)) < 0) {
543            AUBIO_ERR( "Unexpected end of file");
544            return AUBIO_FAIL;
545          }
546          break;
547
548        case NOTE_OFF: 
549          if ((param2 = aubio_midi_file_getc(mf)) < 0) {
550            AUBIO_ERR( "Unexpected end of file");
551            return AUBIO_FAIL;
552          }
553          break;
554
555        case KEY_PRESSURE:
556          if ((param2 = aubio_midi_file_getc(mf)) < 0) {
557            AUBIO_ERR( "Unexpected end of file");
558            return AUBIO_FAIL;
559          }
560          break;
561
562        case CONTROL_CHANGE:
563          if ((param2 = aubio_midi_file_getc(mf)) < 0) {
564            AUBIO_ERR( "Unexpected end of file");
565            return AUBIO_FAIL;
566          }
567          break;
568
569        case PROGRAM_CHANGE:
570          break;
571
572        case CHANNEL_PRESSURE:
573          break;
574
575        case PITCH_BEND:
576          if ((param2 = aubio_midi_file_getc(mf)) < 0) {
577            AUBIO_ERR( "Unexpected end of file");
578            return AUBIO_FAIL;
579          }
580
581          param1 = ((param2 & 0x7f) << 7) | (param1 & 0x7f);
582          param2 = 0;
583          break;
584
585        default:
586          /* Can't possibly happen !? */
587          AUBIO_ERR( "Unrecognized MIDI event");
588          return AUBIO_FAIL;     
589      }
590      evt = new_aubio_midi_event();
591      if (evt == NULL) {
592        AUBIO_ERR( "Out of memory");
593        return AUBIO_FAIL;
594      }
595      evt->dtime = dtime;
596      evt->type = type;
597      evt->channel = channel;
598      evt->param1 = param1;
599      evt->param2 = param2;
600      aubio_track_add_event(track, evt);
601    }
602  }
603  return AUBIO_OK;
604}
605
606/** aubio_midi_file_get_division */
607int aubio_midi_file_get_division(aubio_midi_file_t* midifile)
608{
609  return midifile->division;
610}
611
612
613/** aubio_isasciistring */
614int aubio_isasciistring(char* s)
615{
616  int i;
617  int len = (int) AUBIO_STRLEN(s);
618  for (i = 0; i < len; i++) {
619    if (!aubio_isascii(s[i])) {
620      return 0;
621    }
622  }
623  return 1;
624}
625
626/** aubio_getlength */
627long aubio_getlength(unsigned char *s)
628{
629  long i = 0;
630  i = s[3] | (s[2]<<8) | (s[1]<<16) | (s[0]<<24);
631  return i;
632}
633
Note: See TracBrowser for help on using the repository browser.