smf.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:18k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * smf.c : Standard MIDI File (.mid) demux module for vlc
  3.  *****************************************************************************
  4.  * Copyright © 2007 Rémi Denis-Courmont
  5.  * $Id: fb7eb892b6d3ea37a754c6a39c0a8440a59b83d5 $
  6.  *
  7.  * This program is free software; you can redistribute it and/or modify
  8.  * it under the terms of the GNU General Public License as published by
  9.  * the Free Software Foundation; either version 2 of the License, or
  10.  * (at your option) any later version.
  11.  *
  12.  * This program is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  * GNU General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU General Public License
  18.  * along with this program; if not, write to the Free Software
  19.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  20.  *****************************************************************************/
  21. #ifdef HAVE_CONFIG_H
  22. # include "config.h"
  23. #endif
  24. #include <vlc_common.h>
  25. #include <vlc_plugin.h>
  26. #include <vlc_demux.h>
  27. #include <vlc_aout.h>
  28. #include <vlc_codecs.h>
  29. #include <vlc_charset.h>
  30. #include <limits.h>
  31. #include <assert.h>
  32. #define TEMPO_MIN  20
  33. #define TEMPO_MAX 250 /* Beats per minute */
  34. static int  Open  (vlc_object_t *);
  35. static void Close (vlc_object_t *);
  36. vlc_module_begin ()
  37.     set_description (N_("SMF demuxer"))
  38.     set_category (CAT_INPUT)
  39.     set_subcategory (SUBCAT_INPUT_DEMUX)
  40.     set_capability ("demux", 20)
  41.     set_callbacks (Open, Close)
  42. vlc_module_end ()
  43. static int Demux   (demux_t *);
  44. static int Control (demux_t *, int i_query, va_list args);
  45. typedef struct smf_track_t
  46. {
  47.     int64_t  offset; /* Read offset in the file (stream_Tell) */
  48.     int64_t  end;    /* End offset in the file */
  49.     uint64_t next;   /* Time of next message (in term of pulses) */
  50.     uint8_t  running_event; /* Running (previous) event */
  51. } mtrk_t;
  52. static int ReadDeltaTime (stream_t *s, mtrk_t *track);
  53. struct demux_sys_t
  54. {
  55.     es_out_id_t *es;
  56.     date_t       pts;
  57.     uint64_t     pulse; /* Pulses counter */
  58.     unsigned     ppqn;   /* Pulses Per Quarter Note */
  59.     /* by the way, "quarter note" is "noire" in French */
  60.     unsigned     trackc; /* Number of tracks */
  61.     mtrk_t       trackv[0]; /* Track states */
  62. };
  63. /*****************************************************************************
  64.  * Open: check file and initializes structures
  65.  *****************************************************************************/
  66. static int Open (vlc_object_t * p_this)
  67. {
  68.     demux_t       *p_demux = (demux_t *)p_this;
  69.     stream_t      *stream = p_demux->s;
  70.     demux_sys_t   *p_sys;
  71.     const uint8_t *peek;
  72.     unsigned       tracks, ppqn;
  73.     bool     multitrack;
  74.     /* (Try to) parse the SMF header */
  75.     /* Header chunk always has 6 bytes payload */
  76.     if (stream_Peek (stream, &peek, 14) < 14)
  77.         return VLC_EGENERIC;
  78.     /* Skip RIFF MIDI header if present */
  79.     if (!memcmp (peek, "RIFF", 4) && !memcmp (peek + 8, "RMID", 4))
  80.     {
  81.         uint32_t riff_len = GetDWLE (peek + 4);
  82.         msg_Dbg (p_this, "detected RIFF MIDI file (%u bytes)",
  83.                  (unsigned)riff_len);
  84.         if ((stream_Read (stream, NULL, 12) < 12))
  85.             return VLC_EGENERIC;
  86.         /* Look for the RIFF data chunk */
  87.         for (;;)
  88.         {
  89.             char chnk_hdr[8];
  90.             uint32_t chnk_len;
  91.             if ((riff_len < 8)
  92.              || (stream_Read (stream, chnk_hdr, 8) < 8))
  93.                 return VLC_EGENERIC;
  94.             riff_len -= 8;
  95.             chnk_len = GetDWLE (chnk_hdr + 4);
  96.             if (riff_len < chnk_len)
  97.                 return VLC_EGENERIC;
  98.             riff_len -= chnk_len;
  99.             if (!memcmp (chnk_hdr, "data", 4))
  100.                 break; /* found! */
  101.             if (stream_Read (stream, NULL, chnk_len) < (ssize_t)chnk_len)
  102.                 return VLC_EGENERIC;
  103.         }
  104.         /* Read real SMF header. Assume RIFF data chunk length is proper. */
  105.         if (stream_Peek (stream, &peek, 14) < 14)
  106.             return VLC_EGENERIC;
  107.     }
  108.     if (memcmp (peek, "MThdx00x00x00x06", 8))
  109.         return VLC_EGENERIC;
  110.     peek += 8;
  111.     /* First word: SMF type */
  112.     switch (GetWBE (peek))
  113.     {
  114.         case 0:
  115.             multitrack = false;
  116.             break;
  117.         case 1:
  118.             multitrack = true;
  119.             break;
  120.         default:
  121.             /* We don't implement SMF2 (as do many) */
  122.             msg_Err (p_this, "unsupported SMF file type %u", GetWBE (peek));
  123.             return VLC_EGENERIC;
  124.     }
  125.     peek += 2;
  126.     /* Second word: number of tracks */
  127.     tracks = GetWBE (peek);
  128.     peek += 2;
  129.     if (!multitrack && (tracks != 1))
  130.     {
  131.         msg_Err (p_this, "invalid SMF type 0 file");
  132.         return VLC_EGENERIC;
  133.     }
  134.     msg_Dbg (p_this, "detected Standard MIDI File (type %u) with %u track(s)",
  135.              multitrack, tracks);
  136.     /* Third/last word: timing */
  137.     ppqn = GetWBE (peek);
  138.     if (ppqn & 0x8000)
  139.     {
  140.         /* FIXME */
  141.         msg_Err (p_this, "SMPTE timestamps not implemented");
  142.         return VLC_EGENERIC;
  143.     }
  144.     else
  145.     {
  146.         msg_Dbg (p_this, " %u pulses per quarter note", ppqn);
  147.     }
  148.     p_sys = malloc (sizeof (*p_sys) + (sizeof (mtrk_t) * tracks));
  149.     if (p_sys == NULL)
  150.         return VLC_ENOMEM;
  151.     /* We've had a valid SMF header - now skip it*/
  152.     if (stream_Read (stream, NULL, 14) < 14)
  153.         goto error;
  154.     p_demux->pf_demux   = Demux;
  155.     p_demux->pf_control = Control;
  156.     p_demux->p_sys      = p_sys;
  157.     /* Default SMF tempo is 120BPM, i.e. half a second per quarter note */
  158.     date_Init (&p_sys->pts, ppqn * 2, 1);
  159.     date_Set (&p_sys->pts, 1);
  160.     p_sys->pulse        = 0;
  161.     p_sys->ppqn         = ppqn;
  162.     p_sys->trackc       = tracks;
  163.     /* Prefetch track offsets */
  164.     for (unsigned i = 0; i < tracks; i++)
  165.     {
  166.         uint8_t head[8];
  167.         if (i > 0)
  168.         {
  169.             /* Seeking screws streaming up, but there is no way around this,
  170.              * as SMF1 tracks are performed simultaneously.
  171.              * Not a big deal as SMF1 are usually only a few kbytes anyway. */
  172.             if (stream_Seek (stream,  p_sys->trackv[i-1].end))
  173.             {
  174.                 msg_Err (p_this, "cannot build SMF index (corrupted file?)");
  175.                 goto error;
  176.             }
  177.         }
  178.         for (;;)
  179.         {
  180.             stream_Read (stream, head, 8);
  181.             if (memcmp (head, "MTrk", 4) == 0)
  182.                 break;
  183.             msg_Dbg (p_this, "skipping unknown SMF chunk");
  184.             stream_Read (stream, NULL, GetDWBE (head + 4));
  185.         }
  186.         p_sys->trackv[i].offset = stream_Tell (stream);
  187.         p_sys->trackv[i].end = p_sys->trackv[i].offset + GetDWBE (head + 4);
  188.         p_sys->trackv[i].next = 0;
  189.         ReadDeltaTime (stream, p_sys->trackv + i);
  190.         p_sys->trackv[i].running_event = 0xF6;
  191.         /* Why 0xF6 (Tuning Calibration)?
  192.          * Because it has zero bytes of data, so the parser will detect the
  193.          * error if the first event uses running status. */
  194.     }
  195.     es_format_t  fmt;
  196.     es_format_Init (&fmt, AUDIO_ES, VLC_FOURCC('M', 'I', 'D', 'I'));
  197.     fmt.audio.i_channels = 2;
  198.     fmt.audio.i_original_channels = fmt.audio.i_physical_channels =
  199.         AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
  200.     fmt.audio.i_rate = 44100; /* dummy value */
  201.     p_sys->es = es_out_Add (p_demux->out, &fmt);
  202.     return VLC_SUCCESS;
  203. error:
  204.     free (p_sys);
  205.     return VLC_EGENERIC;
  206. }
  207. /**
  208.  * Releases allocate resources.
  209.  */
  210. static void Close (vlc_object_t * p_this)
  211. {
  212.     demux_t *p_demux = (demux_t *)p_this;
  213.     demux_sys_t *p_sys = p_demux->p_sys;
  214.     free (p_sys);
  215. }
  216. /**
  217.  * Reads MIDI variable length (7, 14, 21 or 28 bits) integer.
  218.  * @return read value, or -1 on EOF/error.
  219.  */
  220. static int32_t ReadVarInt (stream_t *s)
  221. {
  222.     uint32_t val = 0;
  223.     uint8_t byte;
  224.     for (unsigned i = 0; i < 4; i++)
  225.     {
  226.         if (stream_Read (s, &byte, 1) < 1)
  227.             return -1;
  228.         val = (val << 7) | (byte & 0x7f);
  229.         if ((byte & 0x80) == 0)
  230.             return val;
  231.     }
  232.     return -1;
  233. }
  234. /**
  235.  * Reads (delta) time from the next event of a given track.
  236.  * @param s stream to read data from (must be positioned at the right offset)
  237.  */
  238. static int ReadDeltaTime (stream_t *s, mtrk_t *track)
  239. {
  240.     int32_t delta_time;
  241.     assert (stream_Tell (s) == track->offset);
  242.     if (track->offset >= track->end)
  243.     {
  244.         /* This track is done */
  245.         track->next = UINT64_MAX;
  246.         return 0;
  247.     }
  248.     delta_time = ReadVarInt (s);
  249.     if (delta_time < 0)
  250.         return -1;
  251.     track->next += delta_time;
  252.     track->offset = stream_Tell (s);
  253.     return 0;
  254. }
  255. /**
  256.  * Non-MIDI Meta events handler
  257.  */
  258. static
  259. int HandleMeta (demux_t *p_demux, mtrk_t *tr)
  260. {
  261.     stream_t *s = p_demux->s;
  262.     demux_sys_t *p_sys = p_demux->p_sys;
  263.     uint8_t *payload;
  264.     uint8_t type;
  265.     int32_t length;
  266.     int ret = 0;
  267.     if (stream_Read (s, &type, 1) != 1)
  268.         return -1;
  269.     length = ReadVarInt (s);
  270.     if (length < 0)
  271.         return -1;
  272.     payload = malloc (length + 1);
  273.     if ((payload == NULL)
  274.      || (stream_Read (s, payload, length) != length))
  275.     {
  276.         free (payload);
  277.         return -1;
  278.     }
  279.     payload[length] = '';
  280.     switch (type)
  281.     {
  282.         case 0x00: /* Sequence Number */
  283.             break;
  284.         case 0x01: /* Text (comment) */
  285.             EnsureUTF8 ((char *)payload);
  286.             msg_Info (p_demux, "Text      : %s", (char *)payload);
  287.             break;
  288.         case 0x02: /* Copyright */
  289.             EnsureUTF8 ((char *)payload);
  290.             msg_Info (p_demux, "Copyright : %s", (char *)payload);
  291.             break;
  292.         case 0x03: /* Track name */
  293.             EnsureUTF8 ((char *)payload);
  294.             msg_Info (p_demux, "Track name: %s", (char *)payload);
  295.             break;
  296.         case 0x04: /* Instrument name */
  297.             EnsureUTF8 ((char *)payload);
  298.             msg_Info (p_demux, "Instrument: %s", (char *)payload);
  299.             break;
  300.         case 0x05: /* Lyric (one syllable) */
  301.             /*EnsureUTF8 ((char *)payload);*/
  302.             break;
  303.         case 0x06: /* Marker text */
  304.             EnsureUTF8 ((char *)payload);
  305.             msg_Info (p_demux, "Marker    : %s", (char *)payload);
  306.         case 0x07: /* Cue point (WAVE filename) */
  307.             EnsureUTF8 ((char *)payload);
  308.             msg_Info (p_demux, "Cue point : %s", (char *)payload);
  309.             break;
  310.         case 0x08: /* Program/Patch name */
  311.             EnsureUTF8 ((char *)payload);
  312.             msg_Info (p_demux, "Patch name: %s", (char *)payload);
  313.             break;
  314.         case 0x09: /* MIDI port name */
  315.             EnsureUTF8 ((char *)payload);
  316.             msg_Dbg (p_demux, "MIDI port : %s", (char *)payload);
  317.             break;
  318.         case 0x2F: /* End of track */
  319.             if (tr->end != stream_Tell (s))
  320.             {
  321.                 msg_Err (p_demux, "misplaced end of track");
  322.                 ret = -1;
  323.             }
  324.             break;
  325.         case 0x51: /* Tempo */
  326.             if (length == 3)
  327.             {
  328.                 uint32_t uspqn = (payload[0] << 16)
  329.                                | (payload[1] << 8) | payload[2];
  330.                 unsigned tempo = 60 * 1000000 / (uspqn ? uspqn : 1);
  331.                 msg_Dbg (p_demux, "tempo: %uus/qn -> %u BPM",
  332.                          (unsigned)uspqn, tempo);
  333.                 if (tempo < TEMPO_MIN)
  334.                 {
  335.                     msg_Warn (p_demux, "tempo too slow -> %u BPM", TEMPO_MIN);
  336.                     tempo = TEMPO_MIN;
  337.                 }
  338.                 else
  339.                 if (tempo > TEMPO_MAX)
  340.                 {
  341.                     msg_Warn (p_demux, "tempo too fast -> %u BPM", TEMPO_MAX);
  342.                     tempo = TEMPO_MAX;
  343.                 }
  344.                 date_Change (&p_sys->pts, p_sys->ppqn * tempo, 60);
  345.             }
  346.             else
  347.                 ret = -1;
  348.             break;
  349.         case 0x54: /* SMPTE offset */
  350.             if (length == 5)
  351.                 msg_Warn (p_demux, "SMPTE offset not implemented");
  352.             else
  353.                 ret = -1;
  354.             break;
  355.         case 0x58: /* Time signature */
  356.             if (length == 4)
  357.                 ;
  358.             else
  359.                 ret = -1;
  360.             break;
  361.         case 0x59: /* Key signature */
  362.             if (length == 2)
  363.                 ;
  364.             else
  365.                 ret = -1;
  366.             break;
  367.         case 0x7f: /* Proprietary event */
  368.             msg_Dbg (p_demux, "ignored proprietary SMF Meta Event (%d bytes)",
  369.                      length);
  370.             break;
  371.         default:
  372.             msg_Warn (p_demux, "unknown SMF Meta Event type 0x%02X (%d bytes)",
  373.                       type, length);
  374.     }
  375.     free (payload);
  376.     return ret;
  377. }
  378. static
  379. int HandleMessage (demux_t *p_demux, mtrk_t *tr)
  380. {
  381.     stream_t *s = p_demux->s;
  382.     block_t *block;
  383.     uint8_t first, event;
  384.     unsigned datalen;
  385.     if (stream_Seek (s, tr->offset)
  386.      || (stream_Read (s, &first, 1) != 1))
  387.         return -1;
  388.     event = (first & 0x80) ? first : tr->running_event;
  389.     switch (event & 0xf0)
  390.     {
  391.         case 0xF0: /* System Exclusive */
  392.             switch (event)
  393.             {
  394.                 case 0xF0: /* System Specific */
  395.                 {
  396.                     /* TODO: don't skip these */
  397.                     stream_Read (s, NULL, 1); /* Manuf ID */
  398.                     for (;;)
  399.                     {
  400.                         uint8_t c;
  401.                         if (stream_Read (s, &c, 1) != 1)
  402.                             return -1;
  403.                         if (c == 0xF7)
  404.                             goto skip;
  405.                     }
  406.                     /* never reached */
  407.                 }
  408.                 case 0xFF: /* SMF Meta Event */
  409.                     if (HandleMeta (p_demux, tr))
  410.                         return -1;
  411.                     /* We MUST NOT pass this event forward. It would be
  412.                      * confused as a MIDI Reset real-time event. */
  413.                     goto skip;
  414.                 case 0xF1:
  415.                 case 0xF3:
  416.                     datalen = 1;
  417.                     break;
  418.                 case 0xF2:
  419.                     datalen = 2;
  420.                     break;
  421.                 case 0xF4:
  422.                 case 0xF5:
  423.                     /* We cannot handle undefined "common" (non-real-time)
  424.                      * events inside SMF, as we cannot differentiate a
  425.                      * one byte delta-time (< 0x80) from event data. */
  426.                 case 0xF7: /* End of sysex -> should never happen(?) */
  427.                     msg_Err (p_demux, "unknown MIDI event 0x%02X", event);
  428.                     return -1; /* undefined events */
  429.                 default:
  430.                     datalen = 0;
  431.                     break;
  432.             }
  433.             break;
  434.         case 0xC0:
  435.         case 0xD0:
  436.             datalen = 1;
  437.             break;
  438.         default:
  439.             datalen = 2;
  440.             break;
  441.     }
  442.     /* FIXME: one message per block is very inefficient */
  443.     block = block_New (p_demux, 1 + datalen);
  444.     if (block == NULL)
  445.         goto skip;
  446.     block->p_buffer[0] = event;
  447.     if (first & 0x80)
  448.     {
  449.         stream_Read (s, block->p_buffer + 1, datalen);
  450.     }
  451.     else
  452.     {
  453.         if (datalen == 0)
  454.         {
  455.             msg_Err (p_demux, "malformatted MIDI event");
  456.             return -1; /* can't use implicit running status with empty payload! */
  457.         }
  458.         block->p_buffer[1] = first;
  459.         if (datalen > 1)
  460.             stream_Read (s, block->p_buffer + 2, datalen - 1);
  461.     }
  462.     block->i_dts = block->i_pts = date_Get (&p_demux->p_sys->pts);
  463.     es_out_Send (p_demux->out, p_demux->p_sys->es, block);
  464. skip:
  465.     if (event < 0xF8)
  466.         /* If event is not real-time, update running status */
  467.         tr->running_event = event;
  468.     tr->offset = stream_Tell (s);
  469.     return 0;
  470. }
  471. /*****************************************************************************
  472.  * Demux: read chunks and send them to the synthetizer
  473.  *****************************************************************************
  474.  * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
  475.  *****************************************************************************/
  476. static int Demux (demux_t *p_demux)
  477. {
  478.     stream_t *s = p_demux->s;
  479.     demux_sys_t *p_sys = p_demux->p_sys;
  480.     uint64_t     pulse = p_sys->pulse, next_pulse = UINT64_MAX;
  481.     if (pulse == UINT64_MAX)
  482.         return 0; /* all tracks are done */
  483.     es_out_Control (p_demux->out, ES_OUT_SET_PCR, date_Get (&p_sys->pts));
  484.     for (unsigned i = 0; i < p_sys->trackc; i++)
  485.     {
  486.         mtrk_t *track = p_sys->trackv + i;
  487.         while (track->next == pulse)
  488.         {
  489.             if (HandleMessage (p_demux, track)
  490.              || ReadDeltaTime (s, track))
  491.             {
  492.                 msg_Err (p_demux, "fatal parsing error");
  493.                 return VLC_EGENERIC;
  494.             }
  495.         }
  496.         if (track->next < next_pulse)
  497.             next_pulse = track->next;
  498.     }
  499.     mtime_t cur_tick = (date_Get (&p_sys->pts) + 9999) / 10000, last_tick;
  500.     if (next_pulse != UINT64_MAX)
  501.         last_tick = date_Increment (&p_sys->pts, next_pulse - pulse) / 10000;
  502.     else
  503.         last_tick = cur_tick + 1;
  504.     /* MIDI Tick emulation (ping the decoder every 10ms) */
  505.     while (cur_tick < last_tick)
  506.     {
  507.         block_t *tick = block_New (p_demux, 1);
  508.         if (tick == NULL)
  509.             break;
  510.         tick->p_buffer[0] = 0xF9;
  511.         tick->i_dts = tick->i_pts = cur_tick++ * 10000;
  512.         es_out_Send (p_demux->out, p_sys->es, tick);
  513.     }
  514.     p_sys->pulse = next_pulse;
  515.     return 1;
  516. }
  517. /*****************************************************************************
  518.  * Control:
  519.  *****************************************************************************/
  520. static int Control (demux_t *p_demux, int i_query, va_list args)
  521. {
  522.     demux_sys_t *p_sys = p_demux->p_sys;
  523.     switch (i_query)
  524.     {
  525.         case DEMUX_GET_TIME:
  526.         {
  527.             *(va_arg (args, int64_t *)) = date_Get (&p_sys->pts);
  528.             return 0;
  529.         }
  530. #if 0
  531.         /* TODO: */
  532.         case DEMUX_SET_TIME:
  533.         case DEMUX_GET_POSITION:
  534.         case DEMUX_SET_POSITION:
  535.         case DEMUX_GET_LENGTH:
  536. #endif
  537.     }
  538.     return VLC_EGENERIC;
  539. }