Skip to content

Commit 7f13dfa

Browse files
committed
[timidity]
* When file wraps, do no free data and reload the file - reuse the already loaded data. * Remove double free() when attempting to load an invalid MIDI file.
1 parent 3880155 commit 7f13dfa

File tree

2 files changed

+114
-136
lines changed

2 files changed

+114
-136
lines changed

playtimidity/timidityplay.c

Lines changed: 113 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,9 @@ static void free_EventDelayed (CtlEventDelayed *self)
183183

184184
struct mchaninfo channelstat[16] = {{{0}}};
185185

186+
static int dump_rc(int rc);
187+
static void debug_events(MidiEvent *events);
188+
186189
OCP_INTERNAL void timidityGetChanInfo (uint8_t ch, struct mchaninfo *ci)
187190
{
188191
assert (ch < 16);
@@ -647,7 +650,7 @@ static void ocp_ctl_event(CtlEvent *event)
647650
PRINT ("ctl->event (event=CTLE_MUTE, v1=%"PRIdPTR" ch, v2=%"PRIdPTR" is_mute)\n", event->v1, event->v2);
648651
break;
649652
case CTLE_PROGRAM:
650-
PRINT ("ctl->event (event=CTLE_PROGRAM, v1=%"PRIdPTR" ch, v2=%"PRIdPTR" prog, v3=name \"%s\", v4=%"PRIdPTR" bank %dmsb.%dlsb)\n", event->v1, event->v2, (char *)event->v3, event->v4, (intptr_t)(event->v4>>8), (intptr_t)(event->v4&0xff));
653+
PRINT ("ctl->event (event=CTLE_PROGRAM, v1=%"PRIdPTR" ch, v2=%"PRIdPTR" prog, v3=name \"%s\", v4=%"PRIdPTR" bank %dmsb.%dlsb)\n", event->v1, event->v2, (char *)event->v3, event->v4, (int)(intptr_t)(event->v4>>8), (int)(intptr_t)(event->v4&0xff));
651654
break;
652655
case CTLE_VOLUME:
653656
PRINT ("ctl->event (event=CTLE_VOLUME, v1=%"PRIdPTR" ch, v2=%"PRIdPTR" value)\n", event->v1, event->v2);
@@ -922,6 +925,81 @@ PlayMode *play_mode_list[2] = {&ocp_playmode, 0}, *target_play_mode = &ocp_playm
922925

923926
ControlMode *ctl_list[2] = {&ocp_ctl, 0}, *ctl = &ocp_ctl;
924927

928+
struct lyric_t lyrics[2];
929+
930+
static void scan_lyrics (struct cpifaceSessionAPI_t *cpifaceSession, const MidiEvent *events)
931+
{
932+
const MidiEvent *event;
933+
934+
for (event = events; event->type != ME_EOT; event++)
935+
{
936+
if (event->type == ME_KARAOKE_LYRIC)
937+
{
938+
const char *t = event2string (&tc, event->a | (int)(event->b << 8));
939+
if (t && t[0] && ((event->time != 0) || (t[1] != '@')))
940+
{
941+
const char *e;
942+
for (t++; t[0]; t = e)
943+
{
944+
char *p, *n;
945+
e = t + strlen(t);
946+
if ((p = strchr (t, '/')) /* && (p < e) */)
947+
{
948+
e = p + 1;
949+
}
950+
if ((n = strchr (t, '\\')) && (n < e))
951+
{
952+
e = n + 1;
953+
}
954+
if (t[0] == '/')
955+
{
956+
karaoke_new_paragraph (&lyrics[0]);
957+
} else if (t[0] == '\\')
958+
{
959+
karaoke_new_line (&lyrics[0]);
960+
} else {
961+
karaoke_new_syllable (cpifaceSession, &lyrics[0], event->time, t, e - t);
962+
}
963+
}
964+
}
965+
}
966+
}
967+
968+
for (event = events; event->type != ME_EOT; event++)
969+
{
970+
if ((event->type == ME_LYRIC) || (event->type == ME_TEXT) || (event->type == ME_CHORUS_TEXT))
971+
{
972+
const char *t = event2string (&tc, event->a | (int)(event->b << 8));
973+
if (t && t[0] && t[1] != '%' /* chords */)
974+
{
975+
const char *e;
976+
for (t++; t[0]; t = e)
977+
{
978+
char *p, *n;
979+
e = t + strlen(t);
980+
if ((p = strchr (t, '\n')) /* && (p < e) */)
981+
{
982+
e = p + 1;
983+
}
984+
if ((n = strchr (t, '\r')) && (n < e))
985+
{
986+
e = n + 1;
987+
}
988+
if (t[0] == '\n')
989+
{
990+
karaoke_new_paragraph (&lyrics[1]);
991+
} else if (t[0] == '\r')
992+
{
993+
karaoke_new_line (&lyrics[1]);
994+
} else {
995+
karaoke_new_syllable (cpifaceSession, &lyrics[1], event->time, t, e - t);
996+
}
997+
}
998+
}
999+
}
1000+
}
1001+
}
1002+
9251003
static int emulate_main_start(struct timiditycontext_t *c, struct cpifaceSessionAPI_t *cpifaceSession)
9261004
{
9271005
int expect_post_to_fail = 0;
@@ -1120,8 +1198,10 @@ static void emulate_main_end(struct timiditycontext_t *c)
11201198
free_drum_effect(c, i);
11211199
}
11221200

1123-
int emulate_timidity_play_main_start (struct timiditycontext_t *c)
1201+
static int emulate_timidity_play_main_start (struct timiditycontext_t *c, const char *fn, struct cpifaceSessionAPI_t *cpifaceSession)
11241202
{
1203+
int rc;
1204+
11251205
if(wrdt->open(NULL))
11261206
{
11271207
PRINT ("Couldn't open WRD Tracer: %s (`%c')\n", wrdt->name, wrdt->id);
@@ -1168,6 +1248,25 @@ int emulate_timidity_play_main_start (struct timiditycontext_t *c)
11681248
if(tc.allocate_cache_size > 0)
11691249
resamp_cache_reset(&tc);
11701250

1251+
PRINT ("Load the file!!!\n");
1252+
rc = play_midi_load_file(&tc, (char *)fn, &timidity_main_session.event, &timidity_main_session.nsamples);
1253+
dump_rc (rc);
1254+
if ((rc != RC_NONE) || (!timidity_main_session.event) || (!timidity_main_session.nsamples))
1255+
{
1256+
return 3;
1257+
}
1258+
PRINT ("play_midi_load_file => s->event=%p s->nsamples=%lu\n", timidity_main_session.event, (unsigned long int)timidity_main_session.nsamples);
1259+
debug_events (timidity_main_session.event);
1260+
scan_lyrics (cpifaceSession, timidity_main_session.event);
1261+
1262+
if (lyrics[0].lines && (lyrics[0].lines > lyrics[1].lines))
1263+
{
1264+
cpiKaraokeInit (cpifaceSession, lyrics + 0);
1265+
} else if (lyrics[1].lines)
1266+
{
1267+
cpiKaraokeInit (cpifaceSession, lyrics + 1);
1268+
}
1269+
11711270
return 0;
11721271
}
11731272

@@ -1386,7 +1485,7 @@ static int emulate_play_event (struct timiditycontext_t *c, MidiEvent *ev)
13861485
}
13871486
}
13881487

1389-
_PRINT ("Allow\n");
1488+
_PRINT ("Allow (%.8d)\n", ev->time);
13901489

13911490
PRINT ("emulate_play_event calling play_event\n");
13921491

@@ -1564,116 +1663,27 @@ static void debug_events(MidiEvent *events)
15641663
#endif
15651664
}
15661665

1567-
struct lyric_t lyrics[2];
1568-
1569-
static void scan_lyrics (struct cpifaceSessionAPI_t *cpifaceSession, const MidiEvent *events)
1570-
{
1571-
const MidiEvent *event;
1572-
1573-
for (event = events; event->type != ME_EOT; event++)
1574-
{
1575-
if (event->type == ME_KARAOKE_LYRIC)
1576-
{
1577-
const char *t = event2string (&tc, event->a | (int)(event->b << 8));
1578-
if (t && t[0] && ((event->time != 0) || (t[1] != '@')))
1579-
{
1580-
const char *e;
1581-
for (t++; t[0]; t = e)
1582-
{
1583-
char *p, *n;
1584-
e = t + strlen(t);
1585-
if ((p = strchr (t, '/')) /* && (p < e) */)
1586-
{
1587-
e = p + 1;
1588-
}
1589-
if ((n = strchr (t, '\\')) && (n < e))
1590-
{
1591-
e = n + 1;
1592-
}
1593-
if (t[0] == '/')
1594-
{
1595-
karaoke_new_paragraph (&lyrics[0]);
1596-
} else if (t[0] == '\\')
1597-
{
1598-
karaoke_new_line (&lyrics[0]);
1599-
} else {
1600-
karaoke_new_syllable (cpifaceSession, &lyrics[0], event->time, t, e - t);
1601-
}
1602-
}
1603-
}
1604-
}
1605-
}
1606-
1607-
for (event = events; event->type != ME_EOT; event++)
1608-
{
1609-
if ((event->type == ME_LYRIC) || (event->type == ME_TEXT) || (event->type == ME_CHORUS_TEXT))
1610-
{
1611-
const char *t = event2string (&tc, event->a | (int)(event->b << 8));
1612-
if (t && t[0] && t[1] != '%' /* chords */)
1613-
{
1614-
const char *e;
1615-
for (t++; t[0]; t = e)
1616-
{
1617-
char *p, *n;
1618-
e = t + strlen(t);
1619-
if ((p = strchr (t, '\n')) /* && (p < e) */)
1620-
{
1621-
e = p + 1;
1622-
}
1623-
if ((n = strchr (t, '\r')) && (n < e))
1624-
{
1625-
e = n + 1;
1626-
}
1627-
if (t[0] == '\n')
1628-
{
1629-
karaoke_new_paragraph (&lyrics[1]);
1630-
} else if (t[0] == '\r')
1631-
{
1632-
karaoke_new_line (&lyrics[1]);
1633-
} else {
1634-
karaoke_new_syllable (cpifaceSession, &lyrics[1], event->time, t, e - t);
1635-
}
1636-
}
1637-
}
1638-
}
1639-
}
1640-
}
1641-
1642-
static int emulate_play_midi_file_iterate (struct cpifaceSessionAPI_t *cpifaceSession, struct timiditycontext_t *c, const char *fn, struct emulate_play_midi_file_session *s)
1666+
static int emulate_play_midi_file_iterate (struct cpifaceSessionAPI_t *cpifaceSession, struct timiditycontext_t *c, struct emulate_play_midi_file_session *s)
16431667
{
16441668
int i, rc;
16451669

16461670
if (s->first)
16471671
{
1648-
play_reload: /* Come here to reload MIDI file */
1649-
PRINT ("RELOAD RELOAD RELOAD RC_TUNE_END perhaps?\n");
1672+
PRINT ("FIRST FIRST FIRST, load the file!!!\n");
16501673
s->first = 0;
1651-
rc = play_midi_load_file(&tc, (char *)fn, &s->event, &s->nsamples);
1652-
if (s->event)
1653-
{
1654-
debug_events (s->event);
1655-
}
1656-
scan_lyrics (cpifaceSession, s->event);
1657-
1658-
if (lyrics[0].lines && (lyrics[0].lines > lyrics[1].lines))
1659-
{
1660-
cpiKaraokeInit (cpifaceSession, lyrics + 0);
1661-
} else if (lyrics[1].lines)
1674+
while (0)
16621675
{
1663-
cpiKaraokeInit (cpifaceSession, lyrics + 1);
1676+
play_reload: /* Come here to reload MIDI file */
1677+
PRINT ("RESTART RESTART RESTART RC_TUNE_END perhaps?\n");
1678+
{}; /* if PRINT is defined away, we must have atleast have an empty block to make the label valid */
16641679
}
16651680

1666-
dump_rc (rc);
1667-
if (RC_IS_SKIP_FILE(rc))
1668-
goto play_end; /* skip playing */
1669-
16701681
init_mblock(&c->playmidi_pool);
16711682

16721683
ctl_mode_event(&tc, CTLE_PLAY_START, 0, s->nsamples, 0);
16731684
play_mode->acntl(PM_REQ_PLAY_START, NULL);
16741685

16751686
rc = emulate_play_midi_start(&tc, s->event, s->nsamples);
1676-
16771687
if (rc != RC_NONE)
16781688
return rc;
16791689
}
@@ -1694,38 +1704,6 @@ static int emulate_play_midi_file_iterate (struct cpifaceSessionAPI_t *cpifaceSe
16941704
memset(tc.channel[i].drums, 0, sizeof(tc.channel[i].drums));
16951705
}
16961706

1697-
play_end:
1698-
free_all_midi_file_info (&tc);
1699-
#if defined(TILD_SCHEME_ENABLE)
1700-
free (tc.url_expand_home_dir_path);
1701-
free (tc.url_unexpand_home_dir_path);
1702-
tc.url_expand_home_dir_path = 0;
1703-
tc.url_unexpand_home_dir_path = 0;
1704-
#endif
1705-
free (tc.current_filename);
1706-
tc.current_filename = 0;
1707-
1708-
if(wrdt->opened)
1709-
wrdt->end();
1710-
1711-
if(c->free_instruments_afterwards)
1712-
{
1713-
int cnt;
1714-
free_instruments(&tc, 0);
1715-
cnt = free_global_mblock(c); /* free unused memory */
1716-
if(cnt > 0)
1717-
{
1718-
ctl->cmsg(CMSG_INFO, VERB_VERBOSE, "%d memory blocks are free", cnt);
1719-
}
1720-
}
1721-
1722-
free_special_patch(c, -1);
1723-
1724-
if(s->event != NULL)
1725-
{
1726-
free(s->event);
1727-
s->event = NULL;
1728-
}
17291707
if ((rc == RC_JUMP) || (rc == RC_RELOAD) || ((rc == RC_TUNE_END) && (!donotloop)) )
17301708
{
17311709
goto play_reload;
@@ -1746,7 +1724,7 @@ static void timidityIdler(struct cpifaceSessionAPI_t *cpifaceSession, struct tim
17461724
break;
17471725
if (gmibuffree >= (audio_buffer_size*2))
17481726
{
1749-
rc = emulate_play_midi_file_iterate (cpifaceSession, &tc, current_path, &timidity_main_session);
1727+
rc = emulate_play_midi_file_iterate (cpifaceSession, &tc, &timidity_main_session);
17501728
if (rc == RC_ASYNC_HACK)
17511729
break;
17521730
} else {
@@ -2280,14 +2258,14 @@ OCP_INTERNAL int timidityOpenPlayer (const char *path, uint8_t *buffer, size_t b
22802258
gmi_looped=0;
22812259
gmi_eof=0;
22822260

2283-
if (emulate_timidity_play_main_start (&tc))
2261+
current_path = strdup (path);
2262+
emulate_play_midi_file_start(current_path, buffer, bufferlen, &timidity_main_session); /* gmibuflen etc must be set, since we will start to get events already here... */
2263+
2264+
if (emulate_timidity_play_main_start (&tc, current_path, cpifaceSession))
22842265
{
22852266
return errGen;
22862267
}
22872268

2288-
current_path = strdup (path);
2289-
emulate_play_midi_file_start(current_path, buffer, bufferlen, &timidity_main_session); /* gmibuflen etc must be set, since we will start to get events already here... */
2290-
22912269
cpifaceSession->mcpSet = timiditySet;
22922270
cpifaceSession->mcpGet = timidityGet;
22932271

0 commit comments

Comments
 (0)