vlc | branch: master | Rémi Denis-Courmont <r...@remlab.net> | Thu Jul 10 19:05:05 2014 +0300| [ae4b8827a5f9104fce36a3fb9b10e3accb3a8f4d] | committer: Jean-Baptiste Kempf
smf: revector > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=ae4b8827a5f9104fce36a3fb9b10e3accb3a8f4d --- modules/demux/smf.c | 112 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 72 insertions(+), 40 deletions(-) diff --git a/modules/demux/smf.c b/modules/demux/smf.c index 2ac6349..eefbdcc 100644 --- a/modules/demux/smf.c +++ b/modules/demux/smf.c @@ -356,6 +356,68 @@ skip: return 0; } +static int SeekSet0 (demux_t *demux) +{ + stream_t *stream = demux->s; + demux_sys_t *sys = demux->p_sys; + + /* Default SMF tempo is 120BPM, i.e. half a second per quarter note */ + date_Init (&sys->pts, sys->ppqn * 2, 1); + date_Set (&sys->pts, VLC_TS_0); + sys->pulse = 0; + sys->tick = VLC_TS_0; + + for (unsigned i = 0; i < sys->trackc; i++) + { + mtrk_t *tr = sys->trackv + i; + + tr->offset = 0; + tr->next = 0; + /* Why 0xF6 (Tuning Calibration)? + * Because it has zero bytes of data, so the parser will detect the + * error if the first event uses running status. */ + tr->running_event = 0xF6; + + if (stream_Seek (stream, tr->start) + || ReadDeltaTime (stream, tr)) + { + msg_Err (demux, "fatal parsing error"); + return -1; + } + } + + return 0; +} + +static int ReadEvents (demux_t *demux, uint64_t *restrict pulse) +{ + uint64_t cur_pulse = *pulse, next_pulse = UINT64_MAX; + demux_sys_t *sys = demux->p_sys; + + for (unsigned i = 0; i < sys->trackc; i++) + { + mtrk_t *track = sys->trackv + i; + + while (track->next <= cur_pulse) + { + if (HandleMessage (demux, track) + || ReadDeltaTime (demux->s, track)) + { + msg_Err (demux, "fatal parsing error"); + return -1; + } + } + + if (next_pulse > track->next) + next_pulse = track->next; + } + + if (next_pulse != UINT64_MAX) + date_Increment (&sys->pts, next_pulse - cur_pulse); + *pulse = next_pulse; + return 0; +} + /***************************************************************************** * Demux: read chunks and send them to the synthesizer ***************************************************************************** @@ -383,31 +445,15 @@ static int Demux (demux_t *demux) } /* MIDI events in chronological order across all tracks */ - uint64_t cur_pulse = sys->pulse, next_pulse = UINT64_MAX; - - for (unsigned i = 0; i < sys->trackc; i++) - { - mtrk_t *track = sys->trackv + i; + uint64_t pulse = sys->pulse; - while (track->next == cur_pulse) - { - if (HandleMessage (demux, track) - || ReadDeltaTime (demux->s, track)) - { - msg_Err (demux, "fatal parsing error"); - return VLC_EGENERIC; - } - } - - if (next_pulse > track->next) - next_pulse = track->next; - } + if (ReadEvents (demux, &pulse)) + return VLC_EGENERIC; - if (next_pulse == UINT64_MAX) + if (pulse == UINT64_MAX) return 0; /* all tracks are done */ - date_Increment (&sys->pts, next_pulse - cur_pulse); - sys->pulse = next_pulse; + sys->pulse = pulse; return 1; } @@ -538,14 +584,10 @@ static int Open (vlc_object_t *obj) if (stream_Read (stream, NULL, 14) < 14) goto error; - /* Default SMF tempo is 120BPM, i.e. half a second per quarter note */ - date_Init (&sys->pts, ppqn * 2, 1); - date_Set (&sys->pts, VLC_TS_0); - sys->pulse = 0; - sys->tick = VLC_TS_0; + demux->p_sys = sys; sys->ppqn = ppqn; + sys->trackc = tracks; - sys->trackc = tracks; /* Prefetch track offsets */ for (unsigned i = 0; i < tracks; i++) { @@ -579,20 +621,11 @@ static int Open (vlc_object_t *obj) tr->start = stream_Tell (stream); tr->length = GetDWBE (head + 4); - tr->offset = 0; - tr->next = 0; - /* Why 0xF6 (Tuning Calibration)? - * Because it has zero bytes of data, so the parser will detect the - * error if the first event uses running status. */ - tr->running_event = 0xF6; - - if (ReadDeltaTime (stream, tr) < 0) - { - msg_Err (demux, "fatal parsing error"); - goto error; - } } + if (SeekSet0 (demux)) + goto error; + es_format_t fmt; es_format_Init (&fmt, AUDIO_ES, VLC_CODEC_MIDI); fmt.audio.i_channels = 2; @@ -601,7 +634,6 @@ static int Open (vlc_object_t *obj) demux->pf_demux = Demux; demux->pf_control = Control; - demux->p_sys = sys; return VLC_SUCCESS; error: _______________________________________________ vlc-commits mailing list vlc-commits@videolan.org https://mailman.videolan.org/listinfo/vlc-commits