/************************************************************************ Auxiliary function for midi-file IO Copyright (C) 1994, 1995 by R.Harmsen Original date: 26 December 1994. Slight corrections, for portability to Linux, under standard C (C89, C90 or C99): 7 March 2025. ***********************************************************************/ #include "stddef.h" #include "midiutil.h" /******************************************************************** Puts the binary number in in the two-byte buffer out, in a little-endian fashion: most-significant left (low address), less significant more to the right (higher adresses). On little-endian processors (Motorola for example) this is just a binary copy, but on big-endians like Intel-80x86, it is physically a wordwise byte swap. Returns out. *******************************************************************/ unsigned char *int2twochars (unsigned char *out, int in) { out[1] = (in >> 0) & 0xff; out[0] = (in >> 8) & 0xff; return out; } /******************************************************************** Same for longs of 4 bytes. Returns out. *******************************************************************/ unsigned char *long2fourchars (unsigned char *out, long in) { out[3] = (in >> 0) & 0xff; out[2] = (in >> 8) & 0xff; out[1] = (in >> 16) & 0xff; out[0] = (in >> 24) & 0xff; return out; } /******************************************************************** *******************************************************************/ int twochars2int (unsigned char *in) { return ((long)in[0] << (8 * 1)) | (long)in[1]; } /******************************************************************** *******************************************************************/ long fourchars2long (unsigned char *in) { return ((long)in[0] << (8 * 3)) | ((long)in[1] << (8 * 2)) | ((long)in[2] << (8 * 1)) | (long)in[3]; } /******************************************************************** Input is a 32 bit number. Output, in buf, is the same number split into 7-bits portions, where all but the rightmost character have their bit 7 set. The filled length of the buffer (min 1, max 5) is returned. (This variable length count format is used frequently in MIDI-files, for delta-time, and the length of the data portion of meta-messages, starting with 0xff.) *******************************************************************/ int var_length (long in, unsigned char *buf) { unsigned char *b = buf, *p, *e; ptrdiff_t cnt; *b++ = in & 0x7f; while (in >>= 7) { *b++ = (in & 0x7f) | 0x80; } cnt = b - buf; /* Buffer is now filled the wrong way round: therefore swap it */ e = buf + (int)((b - buf) >> 1); for (p = buf; p < e; p++) { unsigned char c = *p; *p = *--b; *b = c; } return (int)cnt; } /******************************************************************** Conversion the other way round. *******************************************************************/ long varlen2long (unsigned char *buf, int *p_bytes_used) { long retval = 0; unsigned char *b; for (b = buf; *b & 0x80; b++) { retval += *b & 0x80; retval <<= 7; } retval += *b; *p_bytes_used = (b - buf) + 1; return retval; }