unused but slightly tricky code to add track name/instrument to an SMF file when...
[ardour.git] / libs / evoral / src / libsmf / smf_save.c
1 /*-
2  * Copyright (c) 2007, 2008 Edward Tomasz NapieraƂa <trasz@FreeBSD.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * ALTHOUGH THIS SOFTWARE IS MADE OF WIN AND SCIENCE, IT IS PROVIDED BY THE
15  * AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
16  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
17  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
18  * THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
20  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
21  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  */
27
28 /**
29  * \file
30  *
31  * Standard MIDI File writer.
32  *
33  */
34
35 /* Reference: http://www.borg.com/~jglatt/tech/midifile.htm */
36
37 #include <stdlib.h>
38 #include <string.h>
39 #include <assert.h>
40 #include <math.h>
41 #include <errno.h>
42 #ifdef PLATFORM_WINDOWS
43 #include <winsock2.h>
44 #else
45 #include <arpa/inet.h>
46 #endif
47 #include "smf.h"
48 #include "smf_private.h"
49
50 #define MAX_VLQ_LENGTH 128
51
52 /**
53  * Extends (reallocates) smf->file_buffer and returns pointer to the newly added space,
54  * that is, pointer to the first byte after the previous buffer end.  Returns NULL in case
55  * of error.
56  */
57 static void *
58 smf_extend(smf_t *smf, const int length)
59 {
60         int i, previous_file_buffer_length = smf->file_buffer_length;
61         char *previous_file_buffer = (char*)smf->file_buffer;
62
63         /* XXX: Not terribly efficient. */
64         smf->file_buffer_length += length;
65         smf->file_buffer = realloc(smf->file_buffer, smf->file_buffer_length);
66         if (smf->file_buffer == NULL) {
67                 g_critical("realloc(3) failed: %s", strerror(errno));
68                 smf->file_buffer_length = 0;
69                 return (NULL);
70         }
71
72         /* Fix up pointers.  XXX: omgwtf. */
73         for (i = 1; i <= smf->number_of_tracks; i++) {
74                 smf_track_t *track;
75                 track = smf_get_track_by_number(smf, i);
76                 if (track->file_buffer != NULL)
77                         track->file_buffer = (char *)track->file_buffer + ((char *)smf->file_buffer - previous_file_buffer);
78         }
79
80         return ((char *)smf->file_buffer + previous_file_buffer_length);
81 }
82
83 /**
84  * Appends "buffer_length" bytes pointed to by "buffer" to the smf, reallocating storage as needed.  Returns 0
85  * if everything went ok, different value if there was any problem.
86  */
87 static int
88 smf_append(smf_t *smf, const void *buffer, const int buffer_length)
89 {
90         void *dest;
91
92         dest = smf_extend(smf, buffer_length);
93         if (dest == NULL) {
94                 g_critical("Cannot extend track buffer.");
95                 return (-1);
96         }
97
98         memcpy(dest, buffer, buffer_length);
99
100         return (0);
101 }
102
103 /**
104  * Appends MThd header to the track.  Returns 0 if everything went ok, different value if not.
105  */
106 static int
107 write_mthd_header(smf_t *smf)
108 {
109         struct mthd_chunk_struct mthd_chunk;
110
111         memcpy(mthd_chunk.mthd_header.id, "MThd", 4);
112         mthd_chunk.mthd_header.length = htonl(6);
113         mthd_chunk.format = htons(smf->format);
114         mthd_chunk.number_of_tracks = htons(smf->number_of_tracks);
115         mthd_chunk.division = htons(smf->ppqn);
116
117         return (smf_append(smf, &mthd_chunk, sizeof(mthd_chunk)));
118 }
119
120 /**
121  * Extends (reallocates) track->file_buffer and returns pointer to the newly added space,
122  * that is, pointer to the first byte after the previous buffer end.  Returns NULL in case
123  * of error.
124  */
125 static void *
126 track_extend(smf_track_t *track, const int length)
127 {
128         void *buf;
129
130         assert(track->smf);
131
132         buf = smf_extend(track->smf, length);
133         if (buf == NULL)
134                 return (NULL);
135
136         track->file_buffer_length += length;
137         if (track->file_buffer == NULL)
138                 track->file_buffer = buf;
139
140         return (buf);
141 }
142
143 /**
144  * Appends "buffer_length" bytes pointed to by "buffer" to the track, reallocating storage as needed.  Returns 0
145  * if everything went ok, different value if there was any problem.
146  */
147 static int
148 track_append(smf_track_t *track, const void *buffer, const int buffer_length)
149 {
150         void *dest;
151
152         dest = track_extend(track, buffer_length);
153         if (dest == NULL) {
154                 g_critical("Cannot extend track buffer.");
155                 return (-1);
156         }
157
158         memcpy(dest, buffer, buffer_length);
159
160         return (0);
161 }
162
163 int
164 smf_format_vlq(unsigned char *buf, int length, unsigned long value)
165 {
166         int i;
167         unsigned long buffer;
168
169         /* Taken from http://www.borg.com/~jglatt/tech/midifile/vari.htm */
170         buffer = value & 0x7F;
171
172         while ((value >>= 7)) {
173                 buffer <<= 8;
174                 buffer |= ((value & 0x7F) | 0x80);
175         }
176
177         for (i = 0;; i++) {
178                 buf[i] = buffer;
179
180                 if (buffer & 0x80)
181                         buffer >>= 8;
182                 else
183                         break;
184         }
185
186         assert(i <= length);
187
188         /* + 1, because "i" is an offset, not a count. */
189         return (i + 1);
190 }
191
192 smf_event_t *
193 smf_event_new_textual(int type, const char *text)
194 {
195         int vlq_length, text_length, copied_length;
196         smf_event_t *event;
197
198         assert(type >= 1 && type <= 9);
199
200         text_length = strlen(text);
201
202         event = smf_event_new();
203         if (event == NULL)
204                 return (NULL);
205
206         /* "2 +" is for leading 0xFF 0xtype. */
207         event->midi_buffer_length = 2 + text_length + MAX_VLQ_LENGTH;
208         event->midi_buffer = (uint8_t*)malloc(event->midi_buffer_length);
209         if (event->midi_buffer == NULL) {
210                 g_critical("Cannot allocate MIDI buffer structure: %s", strerror(errno));
211                 smf_event_delete(event);
212
213                 return (NULL);
214         }
215
216         event->midi_buffer[0] = 0xFF;
217         event->midi_buffer[1] = type;
218
219         vlq_length = smf_format_vlq(event->midi_buffer + 2, MAX_VLQ_LENGTH - 2, text_length);
220         copied_length = snprintf((char *)event->midi_buffer + vlq_length + 2, event->midi_buffer_length - vlq_length - 2, "%s", text);
221
222 #ifndef NDEBUG
223         (void) copied_length; /* stop gcc warning about unusued vars for non-debug build */
224 #else
225         assert(copied_length == text_length);
226 #endif
227
228         event->midi_buffer_length = 2 + vlq_length + text_length;
229
230         return event;
231 }
232
233 /**
234   * Appends value, expressed as Variable Length Quantity, to event->track.
235   */
236 static int
237 write_vlq(smf_event_t *event, unsigned long value)
238 {
239         unsigned char buf[MAX_VLQ_LENGTH];
240         int vlq_length;
241
242         vlq_length = smf_format_vlq(buf, MAX_VLQ_LENGTH, value);
243
244         return (track_append(event->track, buf, vlq_length));
245 }
246
247 /**
248  * Appends event time as Variable Length Quantity.  Returns 0 if everything went ok,
249  * different value in case of error.
250  */
251 static int
252 write_event_time(smf_event_t *event)
253 {
254         assert(event->delta_time_pulses >= 0);
255
256         return (write_vlq(event, event->delta_time_pulses));
257 }
258
259 static int
260 write_sysex_contents(smf_event_t *event)
261 {
262         int ret;
263         unsigned char sysex_status = 0xF0;
264
265         assert(smf_event_is_sysex(event));
266
267         ret = track_append(event->track, &sysex_status, 1);
268         if (ret)
269                 return (ret);
270
271         /* -1, because length does not include status byte. */
272         ret = write_vlq(event, event->midi_buffer_length - 1);
273         if (ret)
274                 return (ret);
275
276         ret = track_append(event->track, event->midi_buffer + 1, event->midi_buffer_length - 1);
277         if (ret)
278                 return (ret);
279
280         return (0);
281 }
282
283 /**
284   * Appends contents of event->midi_buffer wrapped into 0xF7 MIDI event.
285   */
286 static int
287 write_escaped_event_contents(smf_event_t *event)
288 {
289         int ret;
290         unsigned char escape_status = 0xF7;
291
292         if (smf_event_is_sysex(event))
293                 return (write_sysex_contents(event));
294
295         ret = track_append(event->track, &escape_status, 1);
296         if (ret)
297                 return (ret);
298
299         ret = write_vlq(event, event->midi_buffer_length);
300         if (ret)
301                 return (ret);
302
303         ret = track_append(event->track, event->midi_buffer, event->midi_buffer_length);
304         if (ret)
305                 return (ret);
306
307         return (0);
308 }
309
310 /**
311  * Appends contents of event->midi_buffer.  Returns 0 if everything went 0,
312  * different value in case of error.
313  */
314 static int
315 write_event_contents(smf_event_t *event)
316 {
317         if (smf_event_is_system_realtime(event) || smf_event_is_system_common(event))
318                 return (write_escaped_event_contents(event));
319
320         return (track_append(event->track, event->midi_buffer, event->midi_buffer_length));
321 }
322
323 /**
324  * Writes out an event.
325  */
326 static int
327 write_event(smf_event_t *event)
328 {
329         int ret;
330
331         ret = write_event_time(event);
332         if (ret)
333                 return (ret);
334
335         ret = write_event_contents(event);
336         if (ret)
337                 return (ret);
338
339         return (0);
340 }
341
342 /**
343  * Writes out MTrk header, except of MTrk chunk length, which is written by write_mtrk_length().
344  */
345 static int
346 write_mtrk_header(smf_track_t *track)
347 {
348         struct chunk_header_struct mtrk_header;
349
350         memcpy(mtrk_header.id, "MTrk", 4);
351
352         return (track_append(track, &mtrk_header, sizeof(mtrk_header)));
353 }
354
355 /**
356  * Updates MTrk chunk length of a given track.
357  */
358 static int
359 write_mtrk_length(smf_track_t *track)
360 {
361         struct chunk_header_struct *mtrk_header;
362
363         assert(track->file_buffer != NULL);
364         assert(track->file_buffer_length >= 6);
365
366         mtrk_header = (struct chunk_header_struct *)track->file_buffer;
367         mtrk_header->length = htonl(track->file_buffer_length - sizeof(struct chunk_header_struct));
368
369         return (0);
370 }
371
372 /**
373  * Writes out the track.
374  */
375 static int
376 write_track(smf_track_t *track)
377 {
378         int ret;
379         smf_event_t *event;
380
381         ret = write_mtrk_header(track);
382         if (ret)
383                 return (ret);
384
385         if (track->name) {
386                 printf ("save track name [%s]\n", track->name);
387                 smf_event_t *ev = smf_event_new_textual (0x03, track->name);
388                 ev->delta_time_pulses = 0; /* time zero */
389                 ev->track = track;
390                 ret = write_event (ev);
391                 ev->track = 0;
392                 smf_event_delete (ev);
393                 if (ret) {
394                         return ret;
395                 }
396         }
397
398         if (track->instrument) {
399                 printf ("save track instrument [%s]\n", track->instrument);
400                 smf_event_t *ev = smf_event_new_textual (0x04, track->instrument);
401                 ev->delta_time_pulses = 0; /* time zero */
402                 ev->track = track;
403                 ret = write_event (ev);
404                 ev->track = 0;
405                 smf_event_delete (ev);
406                 if (ret) {
407                         return ret;
408                 }
409         }
410
411         while ((event = smf_track_get_next_event(track)) != NULL) {
412                 ret = write_event(event);
413                 if (ret)
414                         return (ret);
415         }
416
417         ret = write_mtrk_length(track);
418         if (ret)
419                 return (ret);
420
421         return (0);
422 }
423
424 /**
425  * Takes smf->file_buffer and saves it to the file.
426  */
427 static int
428 write_file(smf_t *smf, FILE* stream)
429 {
430         if (fwrite(smf->file_buffer, 1, smf->file_buffer_length, stream) != smf->file_buffer_length) {
431                 g_critical("fwrite(3) failed: %s", strerror(errno));
432
433                 return (-2);
434         }
435
436         return (0);
437 }
438
439 static void
440 free_buffer(smf_t *smf)
441 {
442         int i;
443         smf_track_t *track;
444
445         /* Clear the pointers. */
446         memset(smf->file_buffer, 0, smf->file_buffer_length);
447         free(smf->file_buffer);
448         smf->file_buffer = NULL;
449         smf->file_buffer_length = 0;
450
451         for (i = 1; i <= smf->number_of_tracks; i++) {
452                 track = smf_get_track_by_number(smf, i);
453                 assert(track);
454                 track->file_buffer = NULL;
455                 track->file_buffer_length = 0;
456         }
457 }
458
459 #ifndef NDEBUG
460
461 /**
462  * \return Nonzero, if all pointers supposed to be NULL are NULL.  Triggers assertion if not.
463  */
464 static int
465 pointers_are_clear(smf_t *smf)
466 {
467         int i;
468
469         smf_track_t *track;
470         if (smf->file_buffer != NULL) {
471                 fprintf (stderr, "SFB != null but == %p\n", smf->file_buffer);
472         }
473         assert(smf->file_buffer == NULL);
474         assert(smf->file_buffer_length == 0);
475
476         for (i = 1; i <= smf->number_of_tracks; i++) {
477                 track = smf_get_track_by_number(smf, i);
478
479                 assert(track != NULL);
480                 assert(track->file_buffer == NULL);
481                 assert(track->file_buffer_length == 0);
482         }
483
484         return (1);
485 }
486
487 #endif /* !NDEBUG */
488
489 /**
490  * \return Nonzero, if event is End Of Track metaevent.
491  */
492 int
493 smf_event_is_eot(const smf_event_t *event)
494 {
495         if (event->midi_buffer_length != 3)
496                 return (0);
497
498         if (event->midi_buffer[0] != 0xFF || event->midi_buffer[1] != 0x2F || event->midi_buffer[2] != 0x00)
499                 return (0);
500
501         return (1);
502 }
503
504 /**
505  * Check if SMF is valid and add missing EOT events.
506  *
507  * \return 0, if SMF is valid.
508  */
509 static int
510 smf_validate(smf_t *smf)
511 {
512         int trackno, eot_found;
513         size_t eventno;
514         smf_track_t *track;
515         smf_event_t *event;
516
517         if (smf->format < 0 || smf->format > 2) {
518                 g_critical("SMF error: smf->format is less than zero of greater than two.");
519                 return (-1);
520         }
521
522         if (smf->number_of_tracks < 1) {
523                 g_critical("SMF error: number of tracks is less than one.");
524                 return (-2);
525         }
526
527         if (smf->format == 0 && smf->number_of_tracks > 1) {
528                 g_critical("SMF error: format is 0, but number of tracks is more than one.");
529                 return (-3);
530         }
531
532         if (smf->ppqn <= 0) {
533                 g_critical("SMF error: PPQN has to be > 0.");
534                 return (-4);
535         }
536
537         for (trackno = 1; trackno <= smf->number_of_tracks; trackno++) {
538                 track = smf_get_track_by_number(smf, trackno);
539                 assert(track);
540
541                 eot_found = 0;
542
543                 for (eventno = 1; eventno <= track->number_of_events; eventno++) {
544                         event = smf_track_get_event_by_number(track, eventno);
545                         assert(event);
546
547                         if (!smf_event_is_valid(event)) {
548                                 g_critical("Event #%" G_GSIZE_FORMAT " on track #%d is invalid.", eventno, trackno);
549                                 return (-5);
550                         }
551
552                         if (smf_event_is_eot(event)) {
553                                 if (eot_found) {
554                                         g_critical("Duplicate End Of Track event on track #%d.", trackno);
555                                         return (-6);
556                                 }
557
558                                 eot_found = 1;
559                         }
560                 }
561
562                 if (!eot_found) {
563                         if (smf_track_add_eot_delta_pulses(track, 0)) {
564                                 g_critical("smf_track_add_eot_delta_pulses failed.");
565                                 return (-6);
566                         }
567                 }
568
569         }
570
571         return (0);
572 }
573
574 #ifndef NDEBUG
575
576 #define CHECK(cond) if (!(cond)) { return -1; }
577
578 static int
579 check_smf_event_is_identical(const smf_event_t *a, const smf_event_t *b)
580 {
581         CHECK(a->event_number == b->event_number);
582         CHECK(a->delta_time_pulses == b->delta_time_pulses);
583         CHECK(abs((long)(a->time_pulses - b->time_pulses)) <= 2);
584         CHECK(fabs(a->time_seconds - b->time_seconds) <= 0.01);
585         CHECK(a->track_number == b->track_number);
586         CHECK(a->midi_buffer_length == b->midi_buffer_length);
587         CHECK(memcmp(a->midi_buffer, b->midi_buffer, a->midi_buffer_length) == 0);
588         return 0;
589 }
590
591 static int
592 check_smf_track_is_identical(const smf_track_t *a, const smf_track_t *b)
593 {
594         size_t i;
595
596         CHECK(a->track_number == b->track_number);
597         CHECK(a->number_of_events == b->number_of_events);
598
599         for (i = 1; i <= a->number_of_events; i++)
600                 check_smf_event_is_identical(smf_track_get_event_by_number(a, i), smf_track_get_event_by_number(b, i));
601
602         return 0;
603 }
604
605 static int
606 check_smf_is_identical(const smf_t *a, const smf_t *b)
607 {
608         int i;
609
610         CHECK(a->format == b->format);
611         CHECK(a->ppqn == b->ppqn);
612         CHECK(a->frames_per_second == b->frames_per_second);
613         CHECK(a->resolution == b->resolution);
614         CHECK(a->number_of_tracks == b->number_of_tracks);
615
616         for (i = 1; i <= a->number_of_tracks; i++)
617                 check_smf_track_is_identical(smf_get_track_by_number(a, i), smf_get_track_by_number(b, i));
618
619         /* We do not need to compare tempos explicitly, as tempo is always computed from track contents. */
620         return 0;
621 }
622
623 static int
624 check_smf_saved_correctly(const smf_t *smf, FILE* file)
625 {
626         smf_t *saved;
627         int ret;
628
629         saved = smf_load (file);
630         if (!saved) {
631                 ret = -1;
632         } else {
633                 ret = check_smf_is_identical(smf, saved);
634         }
635
636         smf_delete(saved);
637         return (ret);
638 }
639
640 #endif /* !NDEBUG */
641
642 /**
643   * Writes the contents of SMF to the file given.
644   * \param smf SMF.
645   * \param file File descriptor.
646   * \return 0, if saving was successfull.
647   */
648 int
649 smf_save(smf_t *smf, FILE* file)
650 {
651         int i, error;
652         smf_track_t *track;
653
654         smf_rewind(smf);
655
656         assert(pointers_are_clear(smf));
657
658         if (smf_validate(smf))
659                 return (-1);
660
661         if (write_mthd_header(smf))
662                 return (-2);
663
664         for (i = 1; i <= smf->number_of_tracks; i++) {
665                 track = smf_get_track_by_number(smf, i);
666
667                 assert(track != NULL);
668
669                 error = write_track(track);
670                 if (error) {
671                         free_buffer(smf);
672                         return (error);
673                 }
674         }
675
676         error = write_file(smf, file);
677
678         free_buffer(smf);
679
680         if (error)
681                 return (error);
682
683 #ifndef NDEBUG
684         if (check_smf_saved_correctly(smf, file)) {
685                 g_warning("SMF warning: Did not save correctly, possible data loss.");
686         }
687 #endif
688
689         return (0);
690 }
691