]> git.sesse.net Git - vlc/blob - modules/demux/smf.c
demux: ts: adjust PTS based on PCR's (fix #13803)
[vlc] / modules / demux / smf.c
1 /*****************************************************************************
2  * smf.c : Standard MIDI File (.mid) demux module for vlc
3  *****************************************************************************
4  * Copyright © 2007 Rémi Denis-Courmont
5  * $Id$
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as published by
9  * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this program; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
20  *****************************************************************************/
21
22 #ifdef HAVE_CONFIG_H
23 # include "config.h"
24 #endif
25
26 #include <vlc_common.h>
27 #include <vlc_plugin.h>
28 #include <vlc_demux.h>
29 #include <vlc_charset.h>
30 #include <limits.h>
31
32 #include <assert.h>
33
34 #define TEMPO_MIN  20
35 #define TEMPO_MAX 250 /* Beats per minute */
36
37 /**
38  * Reads MIDI variable length (7, 14, 21 or 28 bits) integer.
39  * @return read value, or -1 on EOF/error.
40  */
41 static int32_t ReadVarInt (stream_t *s)
42 {
43     uint32_t val = 0;
44     uint8_t byte;
45
46     for (unsigned i = 0; i < 4; i++)
47     {
48         if (stream_Read (s, &byte, 1) < 1)
49             return -1;
50
51         val = (val << 7) | (byte & 0x7f);
52         if ((byte & 0x80) == 0)
53             return val;
54     }
55
56     return -1;
57 }
58
59 typedef struct smf_track_t
60 {
61     uint64_t next;   /*< Time of next message (in term of pulses) */
62     int64_t  start;  /*< Start offset in the file */
63     uint32_t length; /*< Bytes length */
64     uint32_t offset; /*< Read offset relative to the start offset */
65     uint8_t  running_event; /*< Running (previous) event */
66 } mtrk_t;
67
68 /**
69  * Reads (delta) time from the next event of a given track.
70  * @param s stream to read data from (must be positioned at the right offset)
71  */
72 static int ReadDeltaTime (stream_t *s, mtrk_t *track)
73 {
74     int32_t delta_time;
75
76     assert (stream_Tell (s) == track->start + track->offset);
77
78     if (track->offset >= track->length)
79     {
80         /* This track is done */
81         track->next = UINT64_MAX;
82         return 0;
83     }
84
85     delta_time = ReadVarInt (s);
86     if (delta_time < 0)
87         return -1;
88
89     track->next += delta_time;
90     track->offset = stream_Tell (s) - track->start;
91     return 0;
92 }
93
94 struct demux_sys_t
95 {
96     es_out_id_t *es;
97     date_t       pts; /*< Play timestamp */
98     uint64_t     pulse; /*< Pulses counter */
99     mtime_t      tick; /*< Last tick timestamp */
100
101     mtime_t      duration; /*< Total duration */
102     unsigned     ppqn;   /*< Pulses Per Quarter Note */
103     /* by the way, "quarter note" is "noire" in French */
104
105     unsigned     trackc; /*< Number of tracks */
106     mtrk_t       trackv[]; /*< Track states */
107 };
108
109 /**
110  * Non-MIDI Meta events handler
111  */
112 static
113 int HandleMeta (demux_t *p_demux, mtrk_t *tr)
114 {
115     stream_t *s = p_demux->s;
116     demux_sys_t *p_sys = p_demux->p_sys;
117     uint8_t *payload;
118     uint8_t type;
119     int32_t length;
120     int ret = 0;
121
122     if (stream_Read (s, &type, 1) != 1)
123         return -1;
124
125     length = ReadVarInt (s);
126     if (length < 0)
127         return -1;
128
129     payload = malloc (length + 1);
130     if ((payload == NULL)
131      || (stream_Read (s, payload, length) != length))
132     {
133         free (payload);
134         return -1;
135     }
136
137     payload[length] = '\0';
138
139     switch (type)
140     {
141         case 0x00: /* Sequence Number */
142             break;
143
144         case 0x01: /* Text (comment) */
145             EnsureUTF8 ((char *)payload);
146             msg_Info (p_demux, "Text      : %s", (char *)payload);
147             break;
148
149         case 0x02: /* Copyright */
150             EnsureUTF8 ((char *)payload);
151             msg_Info (p_demux, "Copyright : %s", (char *)payload);
152             break;
153
154         case 0x03: /* Track name */
155             EnsureUTF8 ((char *)payload);
156             msg_Info (p_demux, "Track name: %s", (char *)payload);
157             break;
158
159         case 0x04: /* Instrument name */
160             EnsureUTF8 ((char *)payload);
161             msg_Info (p_demux, "Instrument: %s", (char *)payload);
162             break;
163
164         case 0x05: /* Lyric (one syllable) */
165             /*EnsureUTF8 ((char *)payload);*/
166             break;
167
168         case 0x06: /* Marker text */
169             EnsureUTF8 ((char *)payload);
170             msg_Info (p_demux, "Marker    : %s", (char *)payload);
171
172         case 0x07: /* Cue point (WAVE filename) */
173             EnsureUTF8 ((char *)payload);
174             msg_Info (p_demux, "Cue point : %s", (char *)payload);
175             break;
176
177         case 0x08: /* Program/Patch name */
178             EnsureUTF8 ((char *)payload);
179             msg_Info (p_demux, "Patch name: %s", (char *)payload);
180             break;
181
182         case 0x09: /* MIDI port name */
183             EnsureUTF8 ((char *)payload);
184             msg_Dbg (p_demux, "MIDI port : %s", (char *)payload);
185             break;
186
187         case 0x2F: /* End of track */
188             if (tr->start + tr->length != stream_Tell (s))
189             {
190                 msg_Err (p_demux, "misplaced end of track");
191                 ret = -1;
192             }
193             break;
194
195         case 0x51: /* Tempo */
196             if (length == 3)
197             {
198                 uint32_t uspqn = (payload[0] << 16)
199                                | (payload[1] << 8) | payload[2];
200                 unsigned tempo = 60 * 1000000 / (uspqn ? uspqn : 1);
201                 msg_Dbg (p_demux, "tempo: %uus/qn -> %u BPM",
202                          (unsigned)uspqn, tempo);
203
204                 if (tempo < TEMPO_MIN)
205                 {
206                     msg_Warn (p_demux, "tempo too slow -> %u BPM", TEMPO_MIN);
207                     tempo = TEMPO_MIN;
208                 }
209                 else
210                 if (tempo > TEMPO_MAX)
211                 {
212                     msg_Warn (p_demux, "tempo too fast -> %u BPM", TEMPO_MAX);
213                     tempo = TEMPO_MAX;
214                 }
215                 date_Change (&p_sys->pts, p_sys->ppqn * tempo, 60);
216             }
217             else
218                 ret = -1;
219             break;
220
221         case 0x54: /* SMPTE offset */
222             if (length == 5)
223                 msg_Warn (p_demux, "SMPTE offset not implemented");
224             else
225                 ret = -1;
226             break;
227
228         case 0x58: /* Time signature */
229             if (length == 4)
230                 ;
231             else
232                 ret = -1;
233             break;
234
235         case 0x59: /* Key signature */
236             if (length == 2)
237                 ;
238             else
239                 ret = -1;
240             break;
241
242         case 0x7f: /* Proprietary event */
243             msg_Dbg (p_demux, "ignored proprietary SMF Meta Event (%d bytes)",
244                      length);
245             break;
246
247         default:
248             msg_Warn (p_demux, "unknown SMF Meta Event type 0x%02X (%d bytes)",
249                       type, length);
250     }
251
252     free (payload);
253     return ret;
254 }
255
256 static
257 int HandleMessage (demux_t *p_demux, mtrk_t *tr, es_out_t *out)
258 {
259     stream_t *s = p_demux->s;
260     block_t *block;
261     uint8_t first, event;
262     unsigned datalen;
263
264     if (stream_Seek (s, tr->start + tr->offset)
265      || (stream_Read (s, &first, 1) != 1))
266         return -1;
267
268     event = (first & 0x80) ? first : tr->running_event;
269
270     switch (event & 0xf0)
271     {
272         case 0xF0: /* System Exclusive */
273             switch (event)
274             {
275                 case 0xF0: /* System Specific start */
276                 case 0xF7: /* System Specific continuation */
277                 {
278                     /* Variable length followed by SysEx event data */
279                     int32_t len = ReadVarInt (s);
280                     if (len == -1)
281                         return -1;
282
283                     block = stream_Block (s, len);
284                     if (block == NULL)
285                         return -1;
286                     block = block_Realloc (block, 1, len);
287                     if (block == NULL)
288                         return -1;
289                     block->p_buffer[0] = event;
290                     goto send;
291                 }
292                 case 0xFF: /* SMF Meta Event */
293                     if (HandleMeta (p_demux, tr))
294                         return -1;
295                     /* We MUST NOT pass this event forward. It would be
296                      * confused as a MIDI Reset real-time event. */
297                     goto skip;
298                 case 0xF1:
299                 case 0xF3:
300                     datalen = 1;
301                     break;
302                 case 0xF2:
303                     datalen = 2;
304                     break;
305                 case 0xF4:
306                 case 0xF5:
307                     /* We cannot handle undefined "common" (non-real-time)
308                      * events inside SMF, as we cannot differentiate a
309                      * one byte delta-time (< 0x80) from event data. */
310                 default:
311                     datalen = 0;
312                     break;
313             }
314             break;
315         case 0xC0:
316         case 0xD0:
317             datalen = 1;
318             break;
319         default:
320             datalen = 2;
321             break;
322     }
323
324     /* FIXME: one message per block is very inefficient */
325     block = block_Alloc (1 + datalen);
326     if (block == NULL)
327         goto skip;
328
329     block->p_buffer[0] = event;
330     if (first & 0x80)
331     {
332         stream_Read (s, block->p_buffer + 1, datalen);
333     }
334     else
335     {
336         if (datalen == 0)
337         {
338             msg_Err (p_demux, "malformatted MIDI event");
339             return -1; /* implicit running status requires non-empty payload */
340         }
341
342         block->p_buffer[1] = first;
343         if (datalen > 1)
344             stream_Read (s, block->p_buffer + 2, datalen - 1);
345     }
346
347 send:
348     block->i_dts = block->i_pts = date_Get (&p_demux->p_sys->pts);
349     if (out != NULL)
350         es_out_Send (out, p_demux->p_sys->es, block);
351     else
352         block_Release (block);
353
354 skip:
355     if (event < 0xF8)
356         /* If event is not real-time, update running status */
357         tr->running_event = event;
358
359     tr->offset = stream_Tell (s) - tr->start;
360     return 0;
361 }
362
363 static int SeekSet0 (demux_t *demux)
364 {
365     stream_t *stream = demux->s;
366     demux_sys_t *sys = demux->p_sys;
367
368     /* Default SMF tempo is 120BPM, i.e. half a second per quarter note */
369     date_Init (&sys->pts, sys->ppqn * 2, 1);
370     date_Set (&sys->pts, VLC_TS_0);
371     sys->pulse = 0;
372     sys->tick = VLC_TS_0;
373
374     for (unsigned i = 0; i < sys->trackc; i++)
375     {
376         mtrk_t *tr = sys->trackv + i;
377
378         tr->offset = 0;
379         tr->next = 0;
380         /* Why 0xF6 (Tuning Calibration)?
381          * Because it has zero bytes of data, so the parser will detect the
382          * error if the first event uses running status. */
383         tr->running_event = 0xF6;
384
385         if (stream_Seek (stream, tr->start)
386          || ReadDeltaTime (stream, tr))
387         {
388             msg_Err (demux, "fatal parsing error");
389             return -1;
390         }
391     }
392
393     return 0;
394 }
395
396 static int ReadEvents (demux_t *demux, uint64_t *restrict pulse,
397                        es_out_t *out)
398 {
399     uint64_t cur_pulse = *pulse, next_pulse = UINT64_MAX;
400     demux_sys_t *sys = demux->p_sys;
401
402     for (unsigned i = 0; i < sys->trackc; i++)
403     {
404         mtrk_t *track = sys->trackv + i;
405
406         while (track->next <= cur_pulse)
407         {
408             if (HandleMessage (demux, track, out)
409              || ReadDeltaTime (demux->s, track))
410             {
411                 msg_Err (demux, "fatal parsing error");
412                 return -1;
413             }
414         }
415
416         if (next_pulse > track->next)
417             next_pulse = track->next;
418     }
419
420     if (next_pulse != UINT64_MAX)
421         date_Increment (&sys->pts, next_pulse - cur_pulse);
422     *pulse = next_pulse;
423     return 0;
424 }
425
426 #define TICK (CLOCK_FREQ / 100)
427
428 /*****************************************************************************
429  * Demux: read chunks and send them to the synthesizer
430  *****************************************************************************
431  * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
432  *****************************************************************************/
433 static int Demux (demux_t *demux)
434 {
435     demux_sys_t *sys = demux->p_sys;
436
437     /* MIDI Tick emulation (ping the decoder every 10ms) */
438     if (sys->tick <= date_Get (&sys->pts))
439     {
440         block_t *tick = block_Alloc (1);
441         if (unlikely(tick == NULL))
442             return VLC_ENOMEM;
443
444         tick->p_buffer[0] = 0xF9;
445         tick->i_dts = tick->i_pts = sys->tick;
446
447         es_out_Send (demux->out, sys->es, tick);
448         es_out_Control (demux->out, ES_OUT_SET_PCR, sys->tick);
449
450         sys->tick += TICK;
451         return 1;
452     }
453
454     /* MIDI events in chronological order across all tracks */
455     uint64_t pulse = sys->pulse;
456
457     if (ReadEvents (demux, &pulse, demux->out))
458         return VLC_EGENERIC;
459
460     if (pulse == UINT64_MAX)
461         return 0; /* all tracks are done */
462
463     sys->pulse = pulse;
464     return 1;
465 }
466
467 static int Seek (demux_t *demux, mtime_t pts)
468 {
469     demux_sys_t *sys = demux->p_sys;
470
471     /* Rewind if needed */
472     if (pts < date_Get (&sys->pts) && SeekSet0 (demux))
473         return VLC_EGENERIC;
474
475     /* Fast forward */
476     uint64_t pulse = sys->pulse;
477
478     while (pts > date_Get (&sys->pts))
479     {
480         if (pulse == UINT64_MAX)
481             return VLC_SUCCESS; /* premature end */
482         if (ReadEvents (demux, &pulse, NULL))
483             return VLC_EGENERIC;
484     }
485
486     sys->pulse = pulse;
487     sys->tick = ((date_Get (&sys->pts) - VLC_TS_0) / TICK) * TICK + VLC_TS_0;
488     return VLC_SUCCESS;
489 }
490
491 /*****************************************************************************
492  * Control:
493  *****************************************************************************/
494 static int Control (demux_t *demux, int i_query, va_list args)
495 {
496     demux_sys_t *sys = demux->p_sys;
497
498     switch (i_query)
499     {
500         case DEMUX_GET_POSITION:
501             if (!sys->duration)
502                 return VLC_EGENERIC;
503             *va_arg (args, double *) = (sys->tick - (double)VLC_TS_0)
504                                      / sys->duration;
505             break;
506         case DEMUX_SET_POSITION:
507             return Seek (demux, va_arg (args, double) * sys->duration);
508         case DEMUX_GET_LENGTH:
509             *va_arg (args, int64_t *) = sys->duration;
510             break;
511         case DEMUX_GET_TIME:
512             *va_arg (args, int64_t *) = sys->tick - VLC_TS_0;
513             break;
514         case DEMUX_SET_TIME:
515             return Seek (demux, va_arg (args, int64_t));
516         default:
517             return VLC_EGENERIC;
518     }
519     return VLC_SUCCESS;
520 }
521
522 /**
523  * Probes file format and starts demuxing.
524  */
525 static int Open (vlc_object_t *obj)
526 {
527     demux_t *demux = (demux_t *)obj;
528     stream_t *stream = demux->s;
529     const uint8_t *peek;
530     bool multitrack;
531
532     /* (Try to) parse the SMF header */
533     /* Header chunk always has 6 bytes payload */
534     if (stream_Peek (stream, &peek, 14) < 14)
535         return VLC_EGENERIC;
536
537     /* Skip RIFF MIDI header if present */
538     if (!memcmp (peek, "RIFF", 4) && !memcmp (peek + 8, "RMID", 4))
539     {
540         uint32_t riff_len = GetDWLE (peek + 4);
541
542         msg_Dbg (demux, "detected RIFF MIDI file (%"PRIu32" bytes)", riff_len);
543         if ((stream_Read (stream, NULL, 12) < 12))
544             return VLC_EGENERIC;
545
546         /* Look for the RIFF data chunk */
547         for (;;)
548         {
549             char chnk_hdr[8];
550             uint32_t chnk_len;
551
552             if ((riff_len < 8)
553              || (stream_Read (stream, chnk_hdr, 8) < 8))
554                 return VLC_EGENERIC;
555
556             riff_len -= 8;
557             chnk_len = GetDWLE (chnk_hdr + 4);
558             if (riff_len < chnk_len)
559                 return VLC_EGENERIC;
560             riff_len -= chnk_len;
561
562             if (!memcmp (chnk_hdr, "data", 4))
563                 break; /* found! */
564
565             if (stream_Read (stream, NULL, chnk_len) < (ssize_t)chnk_len)
566                 return VLC_EGENERIC;
567         }
568
569         /* Read real SMF header. Assume RIFF data chunk length is proper. */
570         if (stream_Peek (stream, &peek, 14) < 14)
571             return VLC_EGENERIC;
572     }
573
574     if (memcmp (peek, "MThd\x00\x00\x00\x06", 8))
575         return VLC_EGENERIC;
576     peek += 8;
577
578     /* First word: SMF type */
579     switch (GetWBE (peek))
580     {
581         case 0:
582             multitrack = false;
583             break;
584         case 1:
585             multitrack = true;
586             break;
587         default:
588             /* We don't implement SMF2 (as do many) */
589             msg_Err (demux, "unsupported SMF file type %u", GetWBE (peek));
590             return VLC_EGENERIC;
591     }
592     peek += 2;
593
594     /* Second word: number of tracks */
595     unsigned tracks = GetWBE (peek);
596     peek += 2;
597     if (!multitrack && (tracks != 1))
598     {
599         msg_Err (demux, "invalid SMF type 0 file");
600         return VLC_EGENERIC;
601     }
602
603     msg_Dbg (demux, "detected Standard MIDI File (type %u) with %u track(s)",
604              multitrack, tracks);
605
606     /* Third/last word: timing */
607     unsigned ppqn = GetWBE (peek);
608     if (ppqn & 0x8000)
609     {   /* FIXME */
610         msg_Err (demux, "SMPTE timestamps not implemented");
611         return VLC_EGENERIC;
612     }
613     else
614     {
615         msg_Dbg (demux, " %u pulses per quarter note", ppqn);
616     }
617
618     demux_sys_t *sys = malloc (sizeof (*sys) + (sizeof (mtrk_t) * tracks));
619     if (unlikely(sys == NULL))
620         return VLC_ENOMEM;
621
622     /* We've had a valid SMF header - now skip it*/
623     if (stream_Read (stream, NULL, 14) < 14)
624         goto error;
625
626     demux->p_sys = sys;
627     sys->duration = 0;
628     sys->ppqn = ppqn;
629     sys->trackc = tracks;
630
631     /* Prefetch track offsets */
632     for (unsigned i = 0; i < tracks; i++)
633     {
634         mtrk_t *tr = sys->trackv + i;
635         uint8_t head[8];
636
637         /* Seeking screws streaming up, but there is no way around this, as
638          * SMF1 tracks are performed simultaneously.
639          * Not a big deal as SMF1 are usually only a few kbytes anyway. */
640         if (i > 0 && stream_Seek (stream, tr[-1].start + tr[-1].length))
641         {
642             msg_Err (demux, "cannot build SMF index (corrupted file?)");
643             goto error;
644         }
645
646         for (;;)
647         {
648             if (stream_Read (stream, head, 8) < 8)
649             {
650                 /* FIXME: don't give up if we have at least one valid track */
651                 msg_Err (demux, "incomplete SMF chunk, file is corrupted");
652                 goto error;
653             }
654
655             if (memcmp (head, "MTrk", 4) == 0)
656                 break;
657
658             msg_Dbg (demux, "skipping unknown SMF chunk");
659             stream_Read (stream, NULL, GetDWBE (head + 4));
660         }
661
662         tr->start = stream_Tell (stream);
663         tr->length = GetDWBE (head + 4);
664     }
665
666     bool b;
667     if (stream_Control (stream, STREAM_CAN_FASTSEEK, &b) == 0 && b)
668     {
669         if (SeekSet0 (demux))
670             goto error;
671
672         for (uint64_t pulse = 0; pulse != UINT64_MAX;)
673              if (ReadEvents (demux, &pulse, NULL))
674                  break;
675
676         sys->duration = date_Get (&sys->pts);
677     }
678
679     if (SeekSet0 (demux))
680         goto error;
681
682     es_format_t  fmt;
683     es_format_Init (&fmt, AUDIO_ES, VLC_CODEC_MIDI);
684     fmt.audio.i_channels = 2;
685     fmt.audio.i_rate = 44100; /* dummy value */
686     sys->es = es_out_Add (demux->out, &fmt);
687
688     demux->pf_demux = Demux;
689     demux->pf_control = Control;
690     return VLC_SUCCESS;
691
692 error:
693     free (sys);
694     return VLC_EGENERIC;
695 }
696
697 /**
698  * Releases allocate resources.
699  */
700 static void Close (vlc_object_t * p_this)
701 {
702     demux_t *p_demux = (demux_t *)p_this;
703     demux_sys_t *p_sys = p_demux->p_sys;
704
705     free (p_sys);
706 }
707
708 vlc_module_begin ()
709     set_description (N_("SMF demuxer"))
710     set_category (CAT_INPUT)
711     set_subcategory (SUBCAT_INPUT_DEMUX)
712     set_capability ("demux", 20)
713     set_callbacks (Open, Close)
714 vlc_module_end ()