1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
/*
MIDI File Input/Output Utilities
*/
#include <stdio.h>
#include <stdlib.h>
#include "types.h"
#include "midifile.h"
#include "midio.h"
/* Low level input functions. */
/* READLONG -- Read long from a file (byte-order independent) */
long readlong(FILE *fp)
{
unsigned char c[4];
fread((char *) c, 1, sizeof c, fp);
return (long) ((c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3]);
}
/* READSHORT -- Read short from a file (byte-order independent) */
short readshort(FILE *fp)
{
unsigned char c[2];
fread((char *) c, 1, sizeof c, fp);
return (short) ((c[0] << 8) | c[1]);
}
/* READVARLEN -- Parse variable length value from MIDI file */
vlint readVarLen(FILE *fp)
{
long value;
int ch;
if ((value = getc(fp)) & 0x80) {
value &= 0x7F;
do {
value = (value << 7) | ((ch = getc(fp)) & 0x7F);
} while (ch & 0x80);
}
return value;
}
/* High level input functions. */
/* READMIDIFILEHEADER -- Read file header structure. */
void readMidiFileHeader(FILE *fp, struct mhead *h)
{
fread(h->chunktype, sizeof h->chunktype, 1, fp);
h->length = readlong(fp);
h->format = readshort(fp);
h->ntrks = readshort(fp);
h->division = readshort(fp);
}
/* READMIDITRACKHEADER -- Read track header structure. */
void readMidiTrackHeader(FILE *fp, struct mtrack *t)
{
fread(t->chunktype, sizeof t->chunktype, 1, fp);
t->length = readlong(fp);
}
/* Low level output functions. */
/* WRITELONG -- Write a long to a file in big-endian order */
void writelong(FILE *fp, const long l)
{
putc((l >> 24) & 0xFF, fp);
putc((l >> 16) & 0xFF, fp);
putc((l >> 8) & 0xFF, fp);
putc(l & 0xFF, fp);
}
/* WRITESHORT -- Write a short to a file in big-endian order */
void writeshort(FILE *fp, const short s)
{
putc((s >> 8) & 0xFF, fp);
putc(s & 0xFF, fp);
}
/* WRITEVARLEN -- Write variable length value to MIDI file */
void writeVarLen(FILE *fp, const vlint v)
{
vlint value = v;
long buffer;
buffer = value & 0x7F;
while ((value >>= 7) > 0) {
buffer <<= 8;
buffer |= 0x80;
buffer += (value & 0x7F);
}
while (1) {
putc((int) (buffer & 0xFF), fp);
if (buffer & 0x80) {
buffer >>= 8;
} else {
break;
}
}
}
/* High level output functions. */
/* WRITEMIDIFILEHEADER -- Write file header structure. */
void writeMidiFileHeader(FILE *fp, struct mhead *h)
{
fwrite(h->chunktype, sizeof h->chunktype, 1, fp);
writelong(fp, h->length);
writeshort(fp, h->format);
writeshort(fp, h->ntrks);
writeshort(fp, h->division);
}
/* WRITEMIDITRACKHEADER -- Write track header structure. */
void writeMidiTrackHeader(FILE *fp, struct mtrack *t)
{
fwrite(t->chunktype, sizeof t->chunktype, 1, fp);
writelong(fp, t->length);
}
|