home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume43
/
tclmidi
/
part06
< prev
next >
Wrap
Internet Message Format
|
1994-07-21
|
62KB
From: durian@boogie.com (Mike Durian)
Newsgroups: comp.sources.misc
Subject: v43i114: tclmidi - A language for manipulating MIDI files, v2.0, Part06/14
Date: 21 Jul 1994 19:26:54 -0500
Organization: Sterling Software
Sender: kent@sparky.sterling.com
Approved: kent@sparky.sterling.com
Message-ID: <30n3oe$74r@sparky.sterling.com>
X-Md4-Signature: 0f4176b9fb1b820fc1cf4157df28ed05
Submitted-by: durian@boogie.com (Mike Durian)
Posting-number: Volume 43, Issue 114
Archive-name: tclmidi/part06
Environment: POSIX, (BSDI, NetBSD, LINUX, SVR4 for optional driver), C++, TCL
Supersedes: tclm: Volume 37, Issue 43-47
#! /bin/sh
# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# Contents: tclmidi-2.0/drivers/BSD/quad.c
# tclmidi-2.0/drivers/LINUX/quad.c tclmidi-2.0/drivers/SVR4/quad.c
# tclmidi-2.0/events/MetaInstName.C tclmidi-2.0/events/MetaKey.C
# Wrapped by kent@sparky on Thu Jul 21 19:05:15 1994
PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 6 (of 14)."'
if test -f 'tclmidi-2.0/drivers/BSD/quad.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'tclmidi-2.0/drivers/BSD/quad.c'\"
else
echo shar: Extracting \"'tclmidi-2.0/drivers/BSD/quad.c'\" \(15157 characters\)
sed "s/^X//" >'tclmidi-2.0/drivers/BSD/quad.c' <<'END_OF_FILE'
X/*
X * I need long long for midi timing accuracy. - mbd
X */
X/*-
X * Copyright (c) 1992 The Regents of the University of California.
X * All rights reserved.
X *
X * This software was developed by the Computer Systems Engineering group
X * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
X * contributed to Berkeley.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X * 1. Redistributions of source code must retain the above copyright
X * notice, this list of conditions and the following disclaimer.
X * 2. Redistributions in binary form must reproduce the above copyright
X * notice, this list of conditions and the following disclaimer in the
X * documentation and/or other materials provided with the distribution.
X * 3. All advertising materials mentioning features or use of this software
X * must display the following acknowledgement:
X * This product includes software developed by the University of
X * California, Berkeley and its contributors.
X * 4. Neither the name of the University nor the names of its contributors
X * may be used to endorse or promote products derived from this software
X * without specific prior written permission.
X *
X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
X * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X * SUCH DAMAGE.
X */
X
X#if defined(LIBC_SCCS) && !defined(lint)
Xstatic char sccsid[] = "@(#)adddi3.c 5.5 (Berkeley) 6/25/92";
X#endif /* LIBC_SCCS and not lint */
X
X#include "quad.h"
X
X/*
X * Add two quads. This is trivial since a one-bit carry from a single
X * u_long addition x+y occurs if and only if the sum x+y is less than
X * either x or y (the choice to compare with x or y is arbitrary).
X */
Xquad_t
X__adddi3(a, b)
X quad_t a, b;
X{
X union uu aa, bb, sum;
X
X aa.q = a;
X bb.q = b;
X sum.ul[L] = aa.ul[L] + bb.ul[L];
X sum.ul[H] = aa.ul[H] + bb.ul[H] + (sum.ul[L] < bb.ul[L]);
X return (sum.q);
X}
X
X/*
X * Divide two signed quads.
X * ??? if -1/2 should produce -1 on this machine, this code is wrong
X */
Xquad_t
X__divdi3(a, b)
X quad_t a, b;
X{
X u_quad_t ua, ub, uq;
X int neg;
X
X if (a < 0)
X ua = -(u_quad_t)a, neg = 1;
X else
X ua = a, neg = 0;
X if (b < 0)
X ub = -(u_quad_t)b, neg ^= 1;
X else
X ub = b;
X uq = __qdivrem(ua, ub, (u_quad_t *)0);
X return (neg ? -uq : uq);
X}
X
X
X/*
X * Multiply two quads.
X *
X * Our algorithm is based on the following. Split incoming quad values
X * u and v (where u,v >= 0) into
X *
X * u = 2^n u1 * u0 (n = number of bits in `u_long', usu. 32)
X *
X * and
X *
X * v = 2^n v1 * v0
X *
X * Then
X *
X * uv = 2^2n u1 v1 + 2^n u1 v0 + 2^n v1 u0 + u0 v0
X * = 2^2n u1 v1 + 2^n (u1 v0 + v1 u0) + u0 v0
X *
X * Now add 2^n u1 v1 to the first term and subtract it from the middle,
X * and add 2^n u0 v0 to the last term and subtract it from the middle.
X * This gives:
X *
X * uv = (2^2n + 2^n) (u1 v1) +
X * (2^n) (u1 v0 - u1 v1 + u0 v1 - u0 v0) +
X * (2^n + 1) (u0 v0)
X *
X * Factoring the middle a bit gives us:
X *
X * uv = (2^2n + 2^n) (u1 v1) + [u1v1 = high]
X * (2^n) (u1 - u0) (v0 - v1) + [(u1-u0)... = mid]
X * (2^n + 1) (u0 v0) [u0v0 = low]
X *
X * The terms (u1 v1), (u1 - u0) (v0 - v1), and (u0 v0) can all be done
X * in just half the precision of the original. (Note that either or both
X * of (u1 - u0) or (v0 - v1) may be negative.)
X *
X * This algorithm is from Knuth vol. 2 (2nd ed), section 4.3.3, p. 278.
X *
X * Since C does not give us a `long * long = quad' operator, we split
X * our input quads into two longs, then split the two longs into two
X * shorts. We can then calculate `short * short = long' in native
X * arithmetic.
X *
X * Our product should, strictly speaking, be a `long quad', with 128
X * bits, but we are going to discard the upper 64. In other words,
X * we are not interested in uv, but rather in (uv mod 2^2n). This
X * makes some of the terms above vanish, and we get:
X *
X * (2^n)(high) + (2^n)(mid) + (2^n + 1)(low)
X *
X * or
X *
X * (2^n)(high + mid + low) + low
X *
X * Furthermore, `high' and `mid' can be computed mod 2^n, as any factor
X * of 2^n in either one will also vanish. Only `low' need be computed
X * mod 2^2n, and only because of the final term above.
X */
Xstatic quad_t __lmulq(u_long, u_long);
X
Xquad_t
X__muldi3(a, b)
X quad_t a, b;
X{
X union uu u, v, low, prod;
X register u_long high, mid, udiff, vdiff;
X register int negall, negmid;
X#define u1 u.ul[H]
X#define u0 u.ul[L]
X#define v1 v.ul[H]
X#define v0 v.ul[L]
X
X /*
X * Get u and v such that u, v >= 0. When this is finished,
X * u1, u0, v1, and v0 will be directly accessible through the
X * longword fields.
X */
X if (a >= 0)
X u.q = a, negall = 0;
X else
X u.q = -a, negall = 1;
X if (b >= 0)
X v.q = b;
X else
X v.q = -b, negall ^= 1;
X
X if (u1 == 0 && v1 == 0) {
X /*
X * An (I hope) important optimization occurs when u1 and v1
X * are both 0. This should be common since most numbers
X * are small. Here the product is just u0*v0.
X */
X prod.q = __lmulq(u0, v0);
X } else {
X /*
X * Compute the three intermediate products, remembering
X * whether the middle term is negative. We can discard
X * any upper bits in high and mid, so we can use native
X * u_long * u_long => u_long arithmetic.
X */
X low.q = __lmulq(u0, v0);
X
X if (u1 >= u0)
X negmid = 0, udiff = u1 - u0;
X else
X negmid = 1, udiff = u0 - u1;
X if (v0 >= v1)
X vdiff = v0 - v1;
X else
X vdiff = v1 - v0, negmid ^= 1;
X mid = udiff * vdiff;
X
X high = u1 * v1;
X
X /*
X * Assemble the final product.
X */
X prod.ul[H] = high + (negmid ? -mid : mid) + low.ul[L] +
X low.ul[H];
X prod.ul[L] = low.ul[L];
X }
X return (negall ? -prod.q : prod.q);
X#undef u1
X#undef u0
X#undef v1
X#undef v0
X}
X
X/*
X * Multiply two 2N-bit longs to produce a 4N-bit quad, where N is half
X * the number of bits in a long (whatever that is---the code below
X * does not care as long as quad.h does its part of the bargain---but
X * typically N==16).
X *
X * We use the same algorithm from Knuth, but this time the modulo refinement
X * does not apply. On the other hand, since N is half the size of a long,
X * we can get away with native multiplication---none of our input terms
X * exceeds (ULONG_MAX >> 1).
X *
X * Note that, for u_long l, the quad-precision result
X *
X * l << N
X *
X * splits into high and low longs as HHALF(l) and LHUP(l) respectively.
X */
Xstatic quad_t
X__lmulq(u_long u, u_long v)
X{
X u_long u1, u0, v1, v0, udiff, vdiff, high, mid, low;
X u_long prodh, prodl, was;
X union uu prod;
X int neg;
X
X u1 = HHALF(u);
X u0 = LHALF(u);
X v1 = HHALF(v);
X v0 = LHALF(v);
X
X low = u0 * v0;
X
X /* This is the same small-number optimization as before. */
X if (u1 == 0 && v1 == 0)
X return (low);
X
X if (u1 >= u0)
X udiff = u1 - u0, neg = 0;
X else
X udiff = u0 - u1, neg = 1;
X if (v0 >= v1)
X vdiff = v0 - v1;
X else
X vdiff = v1 - v0, neg ^= 1;
X mid = udiff * vdiff;
X
X high = u1 * v1;
X
X /* prod = (high << 2N) + (high << N); */
X prodh = high + HHALF(high);
X prodl = LHUP(high);
X
X /* if (neg) prod -= mid << N; else prod += mid << N; */
X if (neg) {
X was = prodl;
X prodl -= LHUP(mid);
X prodh -= HHALF(mid) + (prodl > was);
X } else {
X was = prodl;
X prodl += LHUP(mid);
X prodh += HHALF(mid) + (prodl < was);
X }
X
X /* prod += low << N */
X was = prodl;
X prodl += LHUP(low);
X prodh += HHALF(low) + (prodl < was);
X /* ... + low; */
X if ((prodl += low) < low)
X prodh++;
X
X /* return 4N-bit product */
X prod.ul[H] = prodh;
X prod.ul[L] = prodl;
X return (prod.q);
X}
X
X/*
X * Return remainder after dividing two signed quads.
X *
X * XXX
X * If -1/2 should produce -1 on this machine, this code is wrong.
X */
Xquad_t
X__moddi3(a, b)
X quad_t a, b;
X{
X u_quad_t ua, ub, ur;
X int neg;
X
X if (a < 0)
X ua = -(u_quad_t)a, neg = 1;
X else
X ua = a, neg = 0;
X if (b < 0)
X ub = -(u_quad_t)b, neg ^= 1;
X else
X ub = b;
X (void)__qdivrem(ua, ub, &ur);
X return (neg ? -ur : ur);
X}
X
X/*
X * Return 0, 1, or 2 as a <, =, > b respectively.
X * Both a and b are considered signed---which means only the high word is
X * signed.
X */
Xint
X__cmpdi2(a, b)
X quad_t a, b;
X{
X union uu aa, bb;
X
X aa.q = a;
X bb.q = b;
X return (aa.sl[H] < bb.sl[H] ? 0 : aa.sl[H] > bb.sl[H] ? 2 :
X aa.ul[L] < bb.ul[L] ? 0 : aa.ul[L] > bb.ul[L] ? 2 : 1);
X}
X
X/*
X * Return -a (or, equivalently, 0 - a), in quad. See subdi3.c.
X */
Xquad_t
X__negdi2(a)
X quad_t a;
X{
X union uu aa, res;
X
X aa.q = a;
X res.ul[L] = -aa.ul[L];
X res.ul[H] = -aa.ul[H] - (res.ul[L] > 0);
X return (res.q);
X}
X
X/*
X * Multiprecision divide. This algorithm is from Knuth vol. 2 (2nd ed),
X * section 4.3.1, pp. 257--259.
X */
X
X#define B (1 << HALF_BITS) /* digit base */
X
X/* Combine two `digits' to make a single two-digit number. */
X#define COMBINE(a, b) (((u_long)(a) << HALF_BITS) | (b))
X
X/* select a type for digits in base B: use unsigned short if they fit */
X#if ULONG_MAX == 0xffffffff && USHRT_MAX >= 0xffff
Xtypedef unsigned short digit;
X#else
Xtypedef u_long digit;
X#endif
X
X/*
X * Shift p[0]..p[len] left `sh' bits, ignoring any bits that
X * `fall out' the left (there never will be any such anyway).
X * We may assume len >= 0. NOTE THAT THIS WRITES len+1 DIGITS.
X */
Xstatic void
Xshl(register digit *p, register int len, register int sh)
X{
X register int i;
X
X for (i = 0; i < len; i++)
X p[i] = LHALF(p[i] << sh) | (p[i + 1] >> (HALF_BITS - sh));
X p[i] = LHALF(p[i] << sh);
X}
X
X/*
X * __qdivrem(u, v, rem) returns u/v and, optionally, sets *rem to u%v.
X *
X * We do this in base 2-sup-HALF_BITS, so that all intermediate products
X * fit within u_long. As a consequence, the maximum length dividend and
X * divisor are 4 `digits' in this base (they are shorter if they have
X * leading zeros).
X */
Xu_quad_t
X__qdivrem(uq, vq, arq)
X u_quad_t uq, vq, *arq;
X{
X union uu tmp;
X digit *u, *v, *q;
X register digit v1, v2;
X u_long qhat, rhat, t;
X int m, n, d, j, i;
X digit uspace[5], vspace[5], qspace[5];
X
X /*
X * Take care of special cases: divide by zero, and u < v.
X */
X if (vq == 0) {
X /* divide by zero. */
X static volatile const unsigned int zero = 0;
X
X tmp.ul[H] = tmp.ul[L] = 1 / zero;
X if (arq)
X *arq = uq;
X return (tmp.q);
X }
X if (uq < vq) {
X if (arq)
X *arq = uq;
X return (0);
X }
X u = &uspace[0];
X v = &vspace[0];
X q = &qspace[0];
X
X /*
X * Break dividend and divisor into digits in base B, then
X * count leading zeros to determine m and n. When done, we
X * will have:
X * u = (u[1]u[2]...u[m+n]) sub B
X * v = (v[1]v[2]...v[n]) sub B
X * v[1] != 0
X * 1 < n <= 4 (if n = 1, we use a different division algorithm)
X * m >= 0 (otherwise u < v, which we already checked)
X * m + n = 4
X * and thus
X * m = 4 - n <= 2
X */
X tmp.uq = uq;
X u[0] = 0;
X u[1] = HHALF(tmp.ul[H]);
X u[2] = LHALF(tmp.ul[H]);
X u[3] = HHALF(tmp.ul[L]);
X u[4] = LHALF(tmp.ul[L]);
X tmp.uq = vq;
X v[1] = HHALF(tmp.ul[H]);
X v[2] = LHALF(tmp.ul[H]);
X v[3] = HHALF(tmp.ul[L]);
X v[4] = LHALF(tmp.ul[L]);
X for (n = 4; v[1] == 0; v++) {
X if (--n == 1) {
X u_long rbj; /* r*B+u[j] (not root boy jim) */
X digit q1, q2, q3, q4;
X
X /*
X * Change of plan, per exercise 16.
X * r = 0;
X * for j = 1..4:
X * q[j] = floor((r*B + u[j]) / v),
X * r = (r*B + u[j]) % v;
X * We unroll this completely here.
X */
X t = v[2]; /* nonzero, by definition */
X q1 = u[1] / t;
X rbj = COMBINE(u[1] % t, u[2]);
X q2 = rbj / t;
X rbj = COMBINE(rbj % t, u[3]);
X q3 = rbj / t;
X rbj = COMBINE(rbj % t, u[4]);
X q4 = rbj / t;
X if (arq)
X *arq = rbj % t;
X tmp.ul[H] = COMBINE(q1, q2);
X tmp.ul[L] = COMBINE(q3, q4);
X return (tmp.q);
X }
X }
X
X /*
X * By adjusting q once we determine m, we can guarantee that
X * there is a complete four-digit quotient at &qspace[1] when
X * we finally stop.
X */
X for (m = 4 - n; u[1] == 0; u++)
X m--;
X for (i = 4 - m; --i >= 0;)
X q[i] = 0;
X q += 4 - m;
X
X /*
X * Here we run Program D, translated from MIX to C and acquiring
X * a few minor changes.
X *
X * D1: choose multiplier 1 << d to ensure v[1] >= B/2.
X */
X d = 0;
X for (t = v[1]; t < B / 2; t <<= 1)
X d++;
X if (d > 0) {
X shl(&u[0], m + n, d); /* u <<= d */
X shl(&v[1], n - 1, d); /* v <<= d */
X }
X /*
X * D2: j = 0.
X */
X j = 0;
X v1 = v[1]; /* for D3 -- note that v[1..n] are constant */
X v2 = v[2]; /* for D3 */
X do {
X register digit uj0, uj1, uj2;
X
X /*
X * D3: Calculate qhat (\^q, in TeX notation).
X * Let qhat = min((u[j]*B + u[j+1])/v[1], B-1), and
X * let rhat = (u[j]*B + u[j+1]) mod v[1].
X * While rhat < B and v[2]*qhat > rhat*B+u[j+2],
X * decrement qhat and increase rhat correspondingly.
X * Note that if rhat >= B, v[2]*qhat < rhat*B.
X */
X uj0 = u[j + 0]; /* for D3 only -- note that u[j+...] change */
X uj1 = u[j + 1]; /* for D3 only */
X uj2 = u[j + 2]; /* for D3 only */
X if (uj0 == v1) {
X qhat = B;
X rhat = uj1;
X goto qhat_too_big;
X } else {
X u_long n = COMBINE(uj0, uj1);
X qhat = n / v1;
X rhat = n % v1;
X }
X while (v2 * qhat > COMBINE(rhat, uj2)) {
X qhat_too_big:
X qhat--;
X if ((rhat += v1) >= B)
X break;
X }
X /*
X * D4: Multiply and subtract.
X * The variable `t' holds any borrows across the loop.
X * We split this up so that we do not require v[0] = 0,
X * and to eliminate a final special case.
X */
X for (t = 0, i = n; i > 0; i--) {
X t = u[i + j] - v[i] * qhat - t;
X u[i + j] = LHALF(t);
X t = (B - HHALF(t)) & (B - 1);
X }
X t = u[j] - t;
X u[j] = LHALF(t);
X /*
X * D5: test remainder.
X * There is a borrow if and only if HHALF(t) is nonzero;
X * in that (rare) case, qhat was too large (by exactly 1).
X * Fix it by adding v[1..n] to u[j..j+n].
X */
X if (HHALF(t)) {
X qhat--;
X for (t = 0, i = n; i > 0; i--) { /* D6: add back. */
X t += u[i + j] + v[i];
X u[i + j] = LHALF(t);
X t = HHALF(t);
X }
X u[j] = LHALF(u[j] + t);
X }
X q[j] = qhat;
X } while (++j <= m); /* D7: loop on j. */
X
X /*
X * If caller wants the remainder, we have to calculate it as
X * u[m..m+n] >> d (this is at most n digits and thus fits in
X * u[m+1..m+n], but we may need more source digits).
X */
X if (arq) {
X if (d) {
X for (i = m + n; i > m; --i)
X u[i] = (u[i] >> d) |
X LHALF(u[i - 1] << (HALF_BITS - d));
X u[i] = 0;
X }
X tmp.ul[H] = COMBINE(uspace[1], uspace[2]);
X tmp.ul[L] = COMBINE(uspace[3], uspace[4]);
X *arq = tmp.q;
X }
X
X tmp.ul[H] = COMBINE(qspace[1], qspace[2]);
X tmp.ul[L] = COMBINE(qspace[3], qspace[4]);
X return (tmp.q);
X}
X
X/*
X * Return 0, 1, or 2 as a <, =, > b respectively.
X * Neither a nor b are considered signed.
X */
Xint
X__ucmpdi2(a, b)
X u_quad_t a, b;
X{
X union uu aa, bb;
X
X aa.uq = a;
X bb.uq = b;
X return (aa.ul[H] < bb.ul[H] ? 0 : aa.ul[H] > bb.ul[H] ? 2 :
X aa.ul[L] < bb.ul[L] ? 0 : aa.ul[L] > bb.ul[L] ? 2 : 1);
X}
END_OF_FILE
if test 15157 -ne `wc -c <'tclmidi-2.0/drivers/BSD/quad.c'`; then
echo shar: \"'tclmidi-2.0/drivers/BSD/quad.c'\" unpacked with wrong size!
fi
# end of 'tclmidi-2.0/drivers/BSD/quad.c'
fi
if test -f 'tclmidi-2.0/drivers/LINUX/quad.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'tclmidi-2.0/drivers/LINUX/quad.c'\"
else
echo shar: Extracting \"'tclmidi-2.0/drivers/LINUX/quad.c'\" \(15234 characters\)
sed "s/^X//" >'tclmidi-2.0/drivers/LINUX/quad.c' <<'END_OF_FILE'
X/*
X * I need long long for midi timing accuracy. - mbd
X *
X * Inline argument prototype declarations to suppress gcc 2 warnings - lig
X */
X
X/*-
X * Copyright (c) 1992 The Regents of the University of California.
X * All rights reserved.
X *
X * This software was developed by the Computer Systems Engineering group
X * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
X * contributed to Berkeley.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X * 1. Redistributions of source code must retain the above copyright
X * notice, this list of conditions and the following disclaimer.
X * 2. Redistributions in binary form must reproduce the above copyright
X * notice, this list of conditions and the following disclaimer in the
X * documentation and/or other materials provided with the distribution.
X * 3. All advertising materials mentioning features or use of this software
X * must display the following acknowledgement:
X * This product includes software developed by the University of
X * California, Berkeley and its contributors.
X * 4. Neither the name of the University nor the names of its contributors
X * may be used to endorse or promote products derived from this software
X * without specific prior written permission.
X *
X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
X * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X * SUCH DAMAGE.
X */
X
X#if defined(LIBC_SCCS) && !defined(lint)
Xstatic char sccsid[] = "@(#)adddi3.c 5.5 (Berkeley) 6/25/92";
X#endif /* LIBC_SCCS and not lint */
X
X#include "quad.h"
X
X/*
X * Add two quads. This is trivial since a one-bit carry from a single
X * u_long addition x+y occurs if and only if the sum x+y is less than
X * either x or y (the choice to compare with x or y is arbitrary).
X */
Xquad_t
X__adddi3(quad_t a, quad_t b)
X{
X union uu aa, bb, sum;
X
X aa.q = a;
X bb.q = b;
X sum.ul[L] = aa.ul[L] + bb.ul[L];
X sum.ul[H] = aa.ul[H] + bb.ul[H] + (sum.ul[L] < bb.ul[L]);
X return (sum.q);
X}
X
X/*
X * Divide two signed quads.
X * ??? if -1/2 should produce -1 on this machine, this code is wrong
X */
Xquad_t
X__divdi3(quad_t a, quad_t b)
X{
X u_quad_t ua, ub, uq;
X int neg;
X
X if (a < 0)
X ua = -(u_quad_t)a, neg = 1;
X else
X ua = a, neg = 0;
X if (b < 0)
X ub = -(u_quad_t)b, neg ^= 1;
X else
X ub = b;
X uq = __qdivrem(ua, ub, (u_quad_t *)0);
X return (neg ? -uq : uq);
X}
X
X
X/*
X * Multiply two quads.
X *
X * Our algorithm is based on the following. Split incoming quad values
X * u and v (where u,v >= 0) into
X *
X * u = 2^n u1 * u0 (n = number of bits in `u_long', usu. 32)
X *
X * and
X *
X * v = 2^n v1 * v0
X *
X * Then
X *
X * uv = 2^2n u1 v1 + 2^n u1 v0 + 2^n v1 u0 + u0 v0
X * = 2^2n u1 v1 + 2^n (u1 v0 + v1 u0) + u0 v0
X *
X * Now add 2^n u1 v1 to the first term and subtract it from the middle,
X * and add 2^n u0 v0 to the last term and subtract it from the middle.
X * This gives:
X *
X * uv = (2^2n + 2^n) (u1 v1) +
X * (2^n) (u1 v0 - u1 v1 + u0 v1 - u0 v0) +
X * (2^n + 1) (u0 v0)
X *
X * Factoring the middle a bit gives us:
X *
X * uv = (2^2n + 2^n) (u1 v1) + [u1v1 = high]
X * (2^n) (u1 - u0) (v0 - v1) + [(u1-u0)... = mid]
X * (2^n + 1) (u0 v0) [u0v0 = low]
X *
X * The terms (u1 v1), (u1 - u0) (v0 - v1), and (u0 v0) can all be done
X * in just half the precision of the original. (Note that either or both
X * of (u1 - u0) or (v0 - v1) may be negative.)
X *
X * This algorithm is from Knuth vol. 2 (2nd ed), section 4.3.3, p. 278.
X *
X * Since C does not give us a `long * long = quad' operator, we split
X * our input quads into two longs, then split the two longs into two
X * shorts. We can then calculate `short * short = long' in native
X * arithmetic.
X *
X * Our product should, strictly speaking, be a `long quad', with 128
X * bits, but we are going to discard the upper 64. In other words,
X * we are not interested in uv, but rather in (uv mod 2^2n). This
X * makes some of the terms above vanish, and we get:
X *
X * (2^n)(high) + (2^n)(mid) + (2^n + 1)(low)
X *
X * or
X *
X * (2^n)(high + mid + low) + low
X *
X * Furthermore, `high' and `mid' can be computed mod 2^n, as any factor
X * of 2^n in either one will also vanish. Only `low' need be computed
X * mod 2^2n, and only because of the final term above.
X */
Xstatic quad_t __lmulq(u_long, u_long);
X
Xquad_t
X__muldi3(quad_t a, quad_t b)
X{
X union uu u, v, low, prod;
X register u_long high, mid, udiff, vdiff;
X register int negall, negmid;
X#define u1 u.ul[H]
X#define u0 u.ul[L]
X#define v1 v.ul[H]
X#define v0 v.ul[L]
X
X /*
X * Get u and v such that u, v >= 0. When this is finished,
X * u1, u0, v1, and v0 will be directly accessible through the
X * longword fields.
X */
X if (a >= 0)
X u.q = a, negall = 0;
X else
X u.q = -a, negall = 1;
X if (b >= 0)
X v.q = b;
X else
X v.q = -b, negall ^= 1;
X
X if (u1 == 0 && v1 == 0) {
X /*
X * An (I hope) important optimization occurs when u1 and v1
X * are both 0. This should be common since most numbers
X * are small. Here the product is just u0*v0.
X */
X prod.q = __lmulq(u0, v0);
X } else {
X /*
X * Compute the three intermediate products, remembering
X * whether the middle term is negative. We can discard
X * any upper bits in high and mid, so we can use native
X * u_long * u_long => u_long arithmetic.
X */
X low.q = __lmulq(u0, v0);
X
X if (u1 >= u0)
X negmid = 0, udiff = u1 - u0;
X else
X negmid = 1, udiff = u0 - u1;
X if (v0 >= v1)
X vdiff = v0 - v1;
X else
X vdiff = v1 - v0, negmid ^= 1;
X mid = udiff * vdiff;
X
X high = u1 * v1;
X
X /*
X * Assemble the final product.
X */
X prod.ul[H] = high + (negmid ? -mid : mid) + low.ul[L] +
X low.ul[H];
X prod.ul[L] = low.ul[L];
X }
X return (negall ? -prod.q : prod.q);
X#undef u1
X#undef u0
X#undef v1
X#undef v0
X}
X
X/*
X * Multiply two 2N-bit longs to produce a 4N-bit quad, where N is half
X * the number of bits in a long (whatever that is---the code below
X * does not care as long as quad.h does its part of the bargain---but
X * typically N==16).
X *
X * We use the same algorithm from Knuth, but this time the modulo refinement
X * does not apply. On the other hand, since N is half the size of a long,
X * we can get away with native multiplication---none of our input terms
X * exceeds (ULONG_MAX >> 1).
X *
X * Note that, for u_long l, the quad-precision result
X *
X * l << N
X *
X * splits into high and low longs as HHALF(l) and LHUP(l) respectively.
X */
Xstatic quad_t
X__lmulq(u_long u, u_long v)
X{
X u_long u1, u0, v1, v0, udiff, vdiff, high, mid, low;
X u_long prodh, prodl, was;
X union uu prod;
X int neg;
X
X u1 = HHALF(u);
X u0 = LHALF(u);
X v1 = HHALF(v);
X v0 = LHALF(v);
X
X low = u0 * v0;
X
X /* This is the same small-number optimization as before. */
X if (u1 == 0 && v1 == 0)
X return (low);
X
X if (u1 >= u0)
X udiff = u1 - u0, neg = 0;
X else
X udiff = u0 - u1, neg = 1;
X if (v0 >= v1)
X vdiff = v0 - v1;
X else
X vdiff = v1 - v0, neg ^= 1;
X mid = udiff * vdiff;
X
X high = u1 * v1;
X
X /* prod = (high << 2N) + (high << N); */
X prodh = high + HHALF(high);
X prodl = LHUP(high);
X
X /* if (neg) prod -= mid << N; else prod += mid << N; */
X if (neg) {
X was = prodl;
X prodl -= LHUP(mid);
X prodh -= HHALF(mid) + (prodl > was);
X } else {
X was = prodl;
X prodl += LHUP(mid);
X prodh += HHALF(mid) + (prodl < was);
X }
X
X /* prod += low << N */
X was = prodl;
X prodl += LHUP(low);
X prodh += HHALF(low) + (prodl < was);
X /* ... + low; */
X if ((prodl += low) < low)
X prodh++;
X
X /* return 4N-bit product */
X prod.ul[H] = prodh;
X prod.ul[L] = prodl;
X return (prod.q);
X}
X
X/*
X * Return remainder after dividing two signed quads.
X *
X * XXX
X * If -1/2 should produce -1 on this machine, this code is wrong.
X */
Xquad_t
X__moddi3(quad_t a, quad_t b)
X{
X u_quad_t ua, ub, ur;
X int neg;
X
X if (a < 0)
X ua = -(u_quad_t)a, neg = 1;
X else
X ua = a, neg = 0;
X if (b < 0)
X ub = -(u_quad_t)b, neg ^= 1;
X else
X ub = b;
X (void)__qdivrem(ua, ub, &ur);
X return (neg ? -ur : ur);
X}
X
X/*
X * Return 0, 1, or 2 as a <, =, > b respectively.
X * Both a and b are considered signed---which means only the high word is
X * signed.
X */
Xint
X__cmpdi2(quad_t a, quad_t b)
X{
X union uu aa, bb;
X
X aa.q = a;
X bb.q = b;
X return (aa.sl[H] < bb.sl[H] ? 0 : aa.sl[H] > bb.sl[H] ? 2 :
X aa.ul[L] < bb.ul[L] ? 0 : aa.ul[L] > bb.ul[L] ? 2 : 1);
X}
X
X/*
X * Return -a (or, equivalently, 0 - a), in quad. See subdi3.c.
X */
Xquad_t
X__negdi2(quad_t a)
X{
X union uu aa, res;
X
X aa.q = a;
X res.ul[L] = -aa.ul[L];
X res.ul[H] = -aa.ul[H] - (res.ul[L] > 0);
X return (res.q);
X}
X
X/*
X * Multiprecision divide. This algorithm is from Knuth vol. 2 (2nd ed),
X * section 4.3.1, pp. 257--259.
X */
X
X#define B (1 << HALF_BITS) /* digit base */
X
X/* Combine two `digits' to make a single two-digit number. */
X#define COMBINE(a, b) (((u_long)(a) << HALF_BITS) | (b))
X
X/* select a type for digits in base B: use unsigned short if they fit */
X#if ULONG_MAX == 0xffffffff && USHRT_MAX >= 0xffff
Xtypedef unsigned short digit;
X#else
Xtypedef u_long digit;
X#endif
X
X/*
X * Shift p[0]..p[len] left `sh' bits, ignoring any bits that
X * `fall out' the left (there never will be any such anyway).
X * We may assume len >= 0. NOTE THAT THIS WRITES len+1 DIGITS.
X */
Xstatic void
Xshl(register digit *p, register int len, register int sh)
X{
X register int i;
X
X for (i = 0; i < len; i++)
X p[i] = LHALF(p[i] << sh) | (p[i + 1] >> (HALF_BITS - sh));
X p[i] = LHALF(p[i] << sh);
X}
X
X/*
X * __qdivrem(u, v, rem) returns u/v and, optionally, sets *rem to u%v.
X *
X * We do this in base 2-sup-HALF_BITS, so that all intermediate products
X * fit within u_long. As a consequence, the maximum length dividend and
X * divisor are 4 `digits' in this base (they are shorter if they have
X * leading zeros).
X */
Xu_quad_t
X__qdivrem(uq, vq, arq)
X u_quad_t uq, vq, *arq;
X{
X union uu tmp;
X digit *u, *v, *q;
X register digit v1, v2;
X u_long qhat, rhat, t;
X int m, n, d, j, i;
X digit uspace[5], vspace[5], qspace[5];
X
X /*
X * Take care of special cases: divide by zero, and u < v.
X */
X if (vq == 0) {
X /* divide by zero. */
X static volatile const unsigned int zero = 0;
X
X tmp.ul[H] = tmp.ul[L] = 1 / zero;
X if (arq)
X *arq = uq;
X return (tmp.q);
X }
X if (uq < vq) {
X if (arq)
X *arq = uq;
X return (0);
X }
X u = &uspace[0];
X v = &vspace[0];
X q = &qspace[0];
X
X /*
X * Break dividend and divisor into digits in base B, then
X * count leading zeros to determine m and n. When done, we
X * will have:
X * u = (u[1]u[2]...u[m+n]) sub B
X * v = (v[1]v[2]...v[n]) sub B
X * v[1] != 0
X * 1 < n <= 4 (if n = 1, we use a different division algorithm)
X * m >= 0 (otherwise u < v, which we already checked)
X * m + n = 4
X * and thus
X * m = 4 - n <= 2
X */
X tmp.uq = uq;
X u[0] = 0;
X u[1] = HHALF(tmp.ul[H]);
X u[2] = LHALF(tmp.ul[H]);
X u[3] = HHALF(tmp.ul[L]);
X u[4] = LHALF(tmp.ul[L]);
X tmp.uq = vq;
X v[1] = HHALF(tmp.ul[H]);
X v[2] = LHALF(tmp.ul[H]);
X v[3] = HHALF(tmp.ul[L]);
X v[4] = LHALF(tmp.ul[L]);
X for (n = 4; v[1] == 0; v++) {
X if (--n == 1) {
X u_long rbj; /* r*B+u[j] (not root boy jim) */
X digit q1, q2, q3, q4;
X
X /*
X * Change of plan, per exercise 16.
X * r = 0;
X * for j = 1..4:
X * q[j] = floor((r*B + u[j]) / v),
X * r = (r*B + u[j]) % v;
X * We unroll this completely here.
X */
X t = v[2]; /* nonzero, by definition */
X q1 = u[1] / t;
X rbj = COMBINE(u[1] % t, u[2]);
X q2 = rbj / t;
X rbj = COMBINE(rbj % t, u[3]);
X q3 = rbj / t;
X rbj = COMBINE(rbj % t, u[4]);
X q4 = rbj / t;
X if (arq)
X *arq = rbj % t;
X tmp.ul[H] = COMBINE(q1, q2);
X tmp.ul[L] = COMBINE(q3, q4);
X return (tmp.q);
X }
X }
X
X /*
X * By adjusting q once we determine m, we can guarantee that
X * there is a complete four-digit quotient at &qspace[1] when
X * we finally stop.
X */
X for (m = 4 - n; u[1] == 0; u++)
X m--;
X for (i = 4 - m; --i >= 0;)
X q[i] = 0;
X q += 4 - m;
X
X /*
X * Here we run Program D, translated from MIX to C and acquiring
X * a few minor changes.
X *
X * D1: choose multiplier 1 << d to ensure v[1] >= B/2.
X */
X d = 0;
X for (t = v[1]; t < B / 2; t <<= 1)
X d++;
X if (d > 0) {
X shl(&u[0], m + n, d); /* u <<= d */
X shl(&v[1], n - 1, d); /* v <<= d */
X }
X /*
X * D2: j = 0.
X */
X j = 0;
X v1 = v[1]; /* for D3 -- note that v[1..n] are constant */
X v2 = v[2]; /* for D3 */
X do {
X register digit uj0, uj1, uj2;
X
X /*
X * D3: Calculate qhat (\^q, in TeX notation).
X * Let qhat = min((u[j]*B + u[j+1])/v[1], B-1), and
X * let rhat = (u[j]*B + u[j+1]) mod v[1].
X * While rhat < B and v[2]*qhat > rhat*B+u[j+2],
X * decrement qhat and increase rhat correspondingly.
X * Note that if rhat >= B, v[2]*qhat < rhat*B.
X */
X uj0 = u[j + 0]; /* for D3 only -- note that u[j+...] change */
X uj1 = u[j + 1]; /* for D3 only */
X uj2 = u[j + 2]; /* for D3 only */
X if (uj0 == v1) {
X qhat = B;
X rhat = uj1;
X goto qhat_too_big;
X } else {
X u_long n = COMBINE(uj0, uj1);
X qhat = n / v1;
X rhat = n % v1;
X }
X while (v2 * qhat > COMBINE(rhat, uj2)) {
X qhat_too_big:
X qhat--;
X if ((rhat += v1) >= B)
X break;
X }
X /*
X * D4: Multiply and subtract.
X * The variable `t' holds any borrows across the loop.
X * We split this up so that we do not require v[0] = 0,
X * and to eliminate a final special case.
X */
X for (t = 0, i = n; i > 0; i--) {
X t = u[i + j] - v[i] * qhat - t;
X u[i + j] = LHALF(t);
X t = (B - HHALF(t)) & (B - 1);
X }
X t = u[j] - t;
X u[j] = LHALF(t);
X /*
X * D5: test remainder.
X * There is a borrow if and only if HHALF(t) is nonzero;
X * in that (rare) case, qhat was too large (by exactly 1).
X * Fix it by adding v[1..n] to u[j..j+n].
X */
X if (HHALF(t)) {
X qhat--;
X for (t = 0, i = n; i > 0; i--) { /* D6: add back. */
X t += u[i + j] + v[i];
X u[i + j] = LHALF(t);
X t = HHALF(t);
X }
X u[j] = LHALF(u[j] + t);
X }
X q[j] = qhat;
X } while (++j <= m); /* D7: loop on j. */
X
X /*
X * If caller wants the remainder, we have to calculate it as
X * u[m..m+n] >> d (this is at most n digits and thus fits in
X * u[m+1..m+n], but we may need more source digits).
X */
X if (arq) {
X if (d) {
X for (i = m + n; i > m; --i)
X u[i] = (u[i] >> d) |
X LHALF(u[i - 1] << (HALF_BITS - d));
X u[i] = 0;
X }
X tmp.ul[H] = COMBINE(uspace[1], uspace[2]);
X tmp.ul[L] = COMBINE(uspace[3], uspace[4]);
X *arq = tmp.q;
X }
X
X tmp.ul[H] = COMBINE(qspace[1], qspace[2]);
X tmp.ul[L] = COMBINE(qspace[3], qspace[4]);
X return (tmp.q);
X}
X
X/*
X * Return 0, 1, or 2 as a <, =, > b respectively.
X * Neither a nor b are considered signed.
X */
Xint
X__ucmpdi2(u_quad_t a, u_quad_t b)
X{
X union uu aa, bb;
X
X aa.uq = a;
X bb.uq = b;
X return (aa.ul[H] < bb.ul[H] ? 0 : aa.ul[H] > bb.ul[H] ? 2 :
X aa.ul[L] < bb.ul[L] ? 0 : aa.ul[L] > bb.ul[L] ? 2 : 1);
X}
END_OF_FILE
if test 15234 -ne `wc -c <'tclmidi-2.0/drivers/LINUX/quad.c'`; then
echo shar: \"'tclmidi-2.0/drivers/LINUX/quad.c'\" unpacked with wrong size!
fi
# end of 'tclmidi-2.0/drivers/LINUX/quad.c'
fi
if test -f 'tclmidi-2.0/drivers/SVR4/quad.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'tclmidi-2.0/drivers/SVR4/quad.c'\"
else
echo shar: Extracting \"'tclmidi-2.0/drivers/SVR4/quad.c'\" \(15234 characters\)
sed "s/^X//" >'tclmidi-2.0/drivers/SVR4/quad.c' <<'END_OF_FILE'
X/*
X * I need long long for midi timing accuracy. - mbd
X *
X * Inline argument prototype declarations to suppress gcc 2 warnings - lig
X */
X
X/*-
X * Copyright (c) 1992 The Regents of the University of California.
X * All rights reserved.
X *
X * This software was developed by the Computer Systems Engineering group
X * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
X * contributed to Berkeley.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X * 1. Redistributions of source code must retain the above copyright
X * notice, this list of conditions and the following disclaimer.
X * 2. Redistributions in binary form must reproduce the above copyright
X * notice, this list of conditions and the following disclaimer in the
X * documentation and/or other materials provided with the distribution.
X * 3. All advertising materials mentioning features or use of this software
X * must display the following acknowledgement:
X * This product includes software developed by the University of
X * California, Berkeley and its contributors.
X * 4. Neither the name of the University nor the names of its contributors
X * may be used to endorse or promote products derived from this software
X * without specific prior written permission.
X *
X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
X * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X * SUCH DAMAGE.
X */
X
X#if defined(LIBC_SCCS) && !defined(lint)
Xstatic char sccsid[] = "@(#)adddi3.c 5.5 (Berkeley) 6/25/92";
X#endif /* LIBC_SCCS and not lint */
X
X#include "quad.h"
X
X/*
X * Add two quads. This is trivial since a one-bit carry from a single
X * u_long addition x+y occurs if and only if the sum x+y is less than
X * either x or y (the choice to compare with x or y is arbitrary).
X */
Xquad_t
X__adddi3(quad_t a, quad_t b)
X{
X union uu aa, bb, sum;
X
X aa.q = a;
X bb.q = b;
X sum.ul[L] = aa.ul[L] + bb.ul[L];
X sum.ul[H] = aa.ul[H] + bb.ul[H] + (sum.ul[L] < bb.ul[L]);
X return (sum.q);
X}
X
X/*
X * Divide two signed quads.
X * ??? if -1/2 should produce -1 on this machine, this code is wrong
X */
Xquad_t
X__divdi3(quad_t a, quad_t b)
X{
X u_quad_t ua, ub, uq;
X int neg;
X
X if (a < 0)
X ua = -(u_quad_t)a, neg = 1;
X else
X ua = a, neg = 0;
X if (b < 0)
X ub = -(u_quad_t)b, neg ^= 1;
X else
X ub = b;
X uq = __qdivrem(ua, ub, (u_quad_t *)0);
X return (neg ? -uq : uq);
X}
X
X
X/*
X * Multiply two quads.
X *
X * Our algorithm is based on the following. Split incoming quad values
X * u and v (where u,v >= 0) into
X *
X * u = 2^n u1 * u0 (n = number of bits in `u_long', usu. 32)
X *
X * and
X *
X * v = 2^n v1 * v0
X *
X * Then
X *
X * uv = 2^2n u1 v1 + 2^n u1 v0 + 2^n v1 u0 + u0 v0
X * = 2^2n u1 v1 + 2^n (u1 v0 + v1 u0) + u0 v0
X *
X * Now add 2^n u1 v1 to the first term and subtract it from the middle,
X * and add 2^n u0 v0 to the last term and subtract it from the middle.
X * This gives:
X *
X * uv = (2^2n + 2^n) (u1 v1) +
X * (2^n) (u1 v0 - u1 v1 + u0 v1 - u0 v0) +
X * (2^n + 1) (u0 v0)
X *
X * Factoring the middle a bit gives us:
X *
X * uv = (2^2n + 2^n) (u1 v1) + [u1v1 = high]
X * (2^n) (u1 - u0) (v0 - v1) + [(u1-u0)... = mid]
X * (2^n + 1) (u0 v0) [u0v0 = low]
X *
X * The terms (u1 v1), (u1 - u0) (v0 - v1), and (u0 v0) can all be done
X * in just half the precision of the original. (Note that either or both
X * of (u1 - u0) or (v0 - v1) may be negative.)
X *
X * This algorithm is from Knuth vol. 2 (2nd ed), section 4.3.3, p. 278.
X *
X * Since C does not give us a `long * long = quad' operator, we split
X * our input quads into two longs, then split the two longs into two
X * shorts. We can then calculate `short * short = long' in native
X * arithmetic.
X *
X * Our product should, strictly speaking, be a `long quad', with 128
X * bits, but we are going to discard the upper 64. In other words,
X * we are not interested in uv, but rather in (uv mod 2^2n). This
X * makes some of the terms above vanish, and we get:
X *
X * (2^n)(high) + (2^n)(mid) + (2^n + 1)(low)
X *
X * or
X *
X * (2^n)(high + mid + low) + low
X *
X * Furthermore, `high' and `mid' can be computed mod 2^n, as any factor
X * of 2^n in either one will also vanish. Only `low' need be computed
X * mod 2^2n, and only because of the final term above.
X */
Xstatic quad_t __lmulq(u_long, u_long);
X
Xquad_t
X__muldi3(quad_t a, quad_t b)
X{
X union uu u, v, low, prod;
X register u_long high, mid, udiff, vdiff;
X register int negall, negmid;
X#define u1 u.ul[H]
X#define u0 u.ul[L]
X#define v1 v.ul[H]
X#define v0 v.ul[L]
X
X /*
X * Get u and v such that u, v >= 0. When this is finished,
X * u1, u0, v1, and v0 will be directly accessible through the
X * longword fields.
X */
X if (a >= 0)
X u.q = a, negall = 0;
X else
X u.q = -a, negall = 1;
X if (b >= 0)
X v.q = b;
X else
X v.q = -b, negall ^= 1;
X
X if (u1 == 0 && v1 == 0) {
X /*
X * An (I hope) important optimization occurs when u1 and v1
X * are both 0. This should be common since most numbers
X * are small. Here the product is just u0*v0.
X */
X prod.q = __lmulq(u0, v0);
X } else {
X /*
X * Compute the three intermediate products, remembering
X * whether the middle term is negative. We can discard
X * any upper bits in high and mid, so we can use native
X * u_long * u_long => u_long arithmetic.
X */
X low.q = __lmulq(u0, v0);
X
X if (u1 >= u0)
X negmid = 0, udiff = u1 - u0;
X else
X negmid = 1, udiff = u0 - u1;
X if (v0 >= v1)
X vdiff = v0 - v1;
X else
X vdiff = v1 - v0, negmid ^= 1;
X mid = udiff * vdiff;
X
X high = u1 * v1;
X
X /*
X * Assemble the final product.
X */
X prod.ul[H] = high + (negmid ? -mid : mid) + low.ul[L] +
X low.ul[H];
X prod.ul[L] = low.ul[L];
X }
X return (negall ? -prod.q : prod.q);
X#undef u1
X#undef u0
X#undef v1
X#undef v0
X}
X
X/*
X * Multiply two 2N-bit longs to produce a 4N-bit quad, where N is half
X * the number of bits in a long (whatever that is---the code below
X * does not care as long as quad.h does its part of the bargain---but
X * typically N==16).
X *
X * We use the same algorithm from Knuth, but this time the modulo refinement
X * does not apply. On the other hand, since N is half the size of a long,
X * we can get away with native multiplication---none of our input terms
X * exceeds (ULONG_MAX >> 1).
X *
X * Note that, for u_long l, the quad-precision result
X *
X * l << N
X *
X * splits into high and low longs as HHALF(l) and LHUP(l) respectively.
X */
Xstatic quad_t
X__lmulq(u_long u, u_long v)
X{
X u_long u1, u0, v1, v0, udiff, vdiff, high, mid, low;
X u_long prodh, prodl, was;
X union uu prod;
X int neg;
X
X u1 = HHALF(u);
X u0 = LHALF(u);
X v1 = HHALF(v);
X v0 = LHALF(v);
X
X low = u0 * v0;
X
X /* This is the same small-number optimization as before. */
X if (u1 == 0 && v1 == 0)
X return (low);
X
X if (u1 >= u0)
X udiff = u1 - u0, neg = 0;
X else
X udiff = u0 - u1, neg = 1;
X if (v0 >= v1)
X vdiff = v0 - v1;
X else
X vdiff = v1 - v0, neg ^= 1;
X mid = udiff * vdiff;
X
X high = u1 * v1;
X
X /* prod = (high << 2N) + (high << N); */
X prodh = high + HHALF(high);
X prodl = LHUP(high);
X
X /* if (neg) prod -= mid << N; else prod += mid << N; */
X if (neg) {
X was = prodl;
X prodl -= LHUP(mid);
X prodh -= HHALF(mid) + (prodl > was);
X } else {
X was = prodl;
X prodl += LHUP(mid);
X prodh += HHALF(mid) + (prodl < was);
X }
X
X /* prod += low << N */
X was = prodl;
X prodl += LHUP(low);
X prodh += HHALF(low) + (prodl < was);
X /* ... + low; */
X if ((prodl += low) < low)
X prodh++;
X
X /* return 4N-bit product */
X prod.ul[H] = prodh;
X prod.ul[L] = prodl;
X return (prod.q);
X}
X
X/*
X * Return remainder after dividing two signed quads.
X *
X * XXX
X * If -1/2 should produce -1 on this machine, this code is wrong.
X */
Xquad_t
X__moddi3(quad_t a, quad_t b)
X{
X u_quad_t ua, ub, ur;
X int neg;
X
X if (a < 0)
X ua = -(u_quad_t)a, neg = 1;
X else
X ua = a, neg = 0;
X if (b < 0)
X ub = -(u_quad_t)b, neg ^= 1;
X else
X ub = b;
X (void)__qdivrem(ua, ub, &ur);
X return (neg ? -ur : ur);
X}
X
X/*
X * Return 0, 1, or 2 as a <, =, > b respectively.
X * Both a and b are considered signed---which means only the high word is
X * signed.
X */
Xint
X__cmpdi2(quad_t a, quad_t b)
X{
X union uu aa, bb;
X
X aa.q = a;
X bb.q = b;
X return (aa.sl[H] < bb.sl[H] ? 0 : aa.sl[H] > bb.sl[H] ? 2 :
X aa.ul[L] < bb.ul[L] ? 0 : aa.ul[L] > bb.ul[L] ? 2 : 1);
X}
X
X/*
X * Return -a (or, equivalently, 0 - a), in quad. See subdi3.c.
X */
Xquad_t
X__negdi2(quad_t a)
X{
X union uu aa, res;
X
X aa.q = a;
X res.ul[L] = -aa.ul[L];
X res.ul[H] = -aa.ul[H] - (res.ul[L] > 0);
X return (res.q);
X}
X
X/*
X * Multiprecision divide. This algorithm is from Knuth vol. 2 (2nd ed),
X * section 4.3.1, pp. 257--259.
X */
X
X#define B (1 << HALF_BITS) /* digit base */
X
X/* Combine two `digits' to make a single two-digit number. */
X#define COMBINE(a, b) (((u_long)(a) << HALF_BITS) | (b))
X
X/* select a type for digits in base B: use unsigned short if they fit */
X#if ULONG_MAX == 0xffffffff && USHRT_MAX >= 0xffff
Xtypedef unsigned short digit;
X#else
Xtypedef u_long digit;
X#endif
X
X/*
X * Shift p[0]..p[len] left `sh' bits, ignoring any bits that
X * `fall out' the left (there never will be any such anyway).
X * We may assume len >= 0. NOTE THAT THIS WRITES len+1 DIGITS.
X */
Xstatic void
Xshl(register digit *p, register int len, register int sh)
X{
X register int i;
X
X for (i = 0; i < len; i++)
X p[i] = LHALF(p[i] << sh) | (p[i + 1] >> (HALF_BITS - sh));
X p[i] = LHALF(p[i] << sh);
X}
X
X/*
X * __qdivrem(u, v, rem) returns u/v and, optionally, sets *rem to u%v.
X *
X * We do this in base 2-sup-HALF_BITS, so that all intermediate products
X * fit within u_long. As a consequence, the maximum length dividend and
X * divisor are 4 `digits' in this base (they are shorter if they have
X * leading zeros).
X */
Xu_quad_t
X__qdivrem(uq, vq, arq)
X u_quad_t uq, vq, *arq;
X{
X union uu tmp;
X digit *u, *v, *q;
X register digit v1, v2;
X u_long qhat, rhat, t;
X int m, n, d, j, i;
X digit uspace[5], vspace[5], qspace[5];
X
X /*
X * Take care of special cases: divide by zero, and u < v.
X */
X if (vq == 0) {
X /* divide by zero. */
X static volatile const unsigned int zero = 0;
X
X tmp.ul[H] = tmp.ul[L] = 1 / zero;
X if (arq)
X *arq = uq;
X return (tmp.q);
X }
X if (uq < vq) {
X if (arq)
X *arq = uq;
X return (0);
X }
X u = &uspace[0];
X v = &vspace[0];
X q = &qspace[0];
X
X /*
X * Break dividend and divisor into digits in base B, then
X * count leading zeros to determine m and n. When done, we
X * will have:
X * u = (u[1]u[2]...u[m+n]) sub B
X * v = (v[1]v[2]...v[n]) sub B
X * v[1] != 0
X * 1 < n <= 4 (if n = 1, we use a different division algorithm)
X * m >= 0 (otherwise u < v, which we already checked)
X * m + n = 4
X * and thus
X * m = 4 - n <= 2
X */
X tmp.uq = uq;
X u[0] = 0;
X u[1] = HHALF(tmp.ul[H]);
X u[2] = LHALF(tmp.ul[H]);
X u[3] = HHALF(tmp.ul[L]);
X u[4] = LHALF(tmp.ul[L]);
X tmp.uq = vq;
X v[1] = HHALF(tmp.ul[H]);
X v[2] = LHALF(tmp.ul[H]);
X v[3] = HHALF(tmp.ul[L]);
X v[4] = LHALF(tmp.ul[L]);
X for (n = 4; v[1] == 0; v++) {
X if (--n == 1) {
X u_long rbj; /* r*B+u[j] (not root boy jim) */
X digit q1, q2, q3, q4;
X
X /*
X * Change of plan, per exercise 16.
X * r = 0;
X * for j = 1..4:
X * q[j] = floor((r*B + u[j]) / v),
X * r = (r*B + u[j]) % v;
X * We unroll this completely here.
X */
X t = v[2]; /* nonzero, by definition */
X q1 = u[1] / t;
X rbj = COMBINE(u[1] % t, u[2]);
X q2 = rbj / t;
X rbj = COMBINE(rbj % t, u[3]);
X q3 = rbj / t;
X rbj = COMBINE(rbj % t, u[4]);
X q4 = rbj / t;
X if (arq)
X *arq = rbj % t;
X tmp.ul[H] = COMBINE(q1, q2);
X tmp.ul[L] = COMBINE(q3, q4);
X return (tmp.q);
X }
X }
X
X /*
X * By adjusting q once we determine m, we can guarantee that
X * there is a complete four-digit quotient at &qspace[1] when
X * we finally stop.
X */
X for (m = 4 - n; u[1] == 0; u++)
X m--;
X for (i = 4 - m; --i >= 0;)
X q[i] = 0;
X q += 4 - m;
X
X /*
X * Here we run Program D, translated from MIX to C and acquiring
X * a few minor changes.
X *
X * D1: choose multiplier 1 << d to ensure v[1] >= B/2.
X */
X d = 0;
X for (t = v[1]; t < B / 2; t <<= 1)
X d++;
X if (d > 0) {
X shl(&u[0], m + n, d); /* u <<= d */
X shl(&v[1], n - 1, d); /* v <<= d */
X }
X /*
X * D2: j = 0.
X */
X j = 0;
X v1 = v[1]; /* for D3 -- note that v[1..n] are constant */
X v2 = v[2]; /* for D3 */
X do {
X register digit uj0, uj1, uj2;
X
X /*
X * D3: Calculate qhat (\^q, in TeX notation).
X * Let qhat = min((u[j]*B + u[j+1])/v[1], B-1), and
X * let rhat = (u[j]*B + u[j+1]) mod v[1].
X * While rhat < B and v[2]*qhat > rhat*B+u[j+2],
X * decrement qhat and increase rhat correspondingly.
X * Note that if rhat >= B, v[2]*qhat < rhat*B.
X */
X uj0 = u[j + 0]; /* for D3 only -- note that u[j+...] change */
X uj1 = u[j + 1]; /* for D3 only */
X uj2 = u[j + 2]; /* for D3 only */
X if (uj0 == v1) {
X qhat = B;
X rhat = uj1;
X goto qhat_too_big;
X } else {
X u_long n = COMBINE(uj0, uj1);
X qhat = n / v1;
X rhat = n % v1;
X }
X while (v2 * qhat > COMBINE(rhat, uj2)) {
X qhat_too_big:
X qhat--;
X if ((rhat += v1) >= B)
X break;
X }
X /*
X * D4: Multiply and subtract.
X * The variable `t' holds any borrows across the loop.
X * We split this up so that we do not require v[0] = 0,
X * and to eliminate a final special case.
X */
X for (t = 0, i = n; i > 0; i--) {
X t = u[i + j] - v[i] * qhat - t;
X u[i + j] = LHALF(t);
X t = (B - HHALF(t)) & (B - 1);
X }
X t = u[j] - t;
X u[j] = LHALF(t);
X /*
X * D5: test remainder.
X * There is a borrow if and only if HHALF(t) is nonzero;
X * in that (rare) case, qhat was too large (by exactly 1).
X * Fix it by adding v[1..n] to u[j..j+n].
X */
X if (HHALF(t)) {
X qhat--;
X for (t = 0, i = n; i > 0; i--) { /* D6: add back. */
X t += u[i + j] + v[i];
X u[i + j] = LHALF(t);
X t = HHALF(t);
X }
X u[j] = LHALF(u[j] + t);
X }
X q[j] = qhat;
X } while (++j <= m); /* D7: loop on j. */
X
X /*
X * If caller wants the remainder, we have to calculate it as
X * u[m..m+n] >> d (this is at most n digits and thus fits in
X * u[m+1..m+n], but we may need more source digits).
X */
X if (arq) {
X if (d) {
X for (i = m + n; i > m; --i)
X u[i] = (u[i] >> d) |
X LHALF(u[i - 1] << (HALF_BITS - d));
X u[i] = 0;
X }
X tmp.ul[H] = COMBINE(uspace[1], uspace[2]);
X tmp.ul[L] = COMBINE(uspace[3], uspace[4]);
X *arq = tmp.q;
X }
X
X tmp.ul[H] = COMBINE(qspace[1], qspace[2]);
X tmp.ul[L] = COMBINE(qspace[3], qspace[4]);
X return (tmp.q);
X}
X
X/*
X * Return 0, 1, or 2 as a <, =, > b respectively.
X * Neither a nor b are considered signed.
X */
Xint
X__ucmpdi2(u_quad_t a, u_quad_t b)
X{
X union uu aa, bb;
X
X aa.uq = a;
X bb.uq = b;
X return (aa.ul[H] < bb.ul[H] ? 0 : aa.ul[H] > bb.ul[H] ? 2 :
X aa.ul[L] < bb.ul[L] ? 0 : aa.ul[L] > bb.ul[L] ? 2 : 1);
X}
END_OF_FILE
if test 15234 -ne `wc -c <'tclmidi-2.0/drivers/SVR4/quad.c'`; then
echo shar: \"'tclmidi-2.0/drivers/SVR4/quad.c'\" unpacked with wrong size!
fi
# end of 'tclmidi-2.0/drivers/SVR4/quad.c'
fi
if test -f 'tclmidi-2.0/events/MetaInstName.C' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'tclmidi-2.0/events/MetaInstName.C'\"
else
echo shar: Extracting \"'tclmidi-2.0/events/MetaInstName.C'\" \(2447 characters\)
sed "s/^X//" >'tclmidi-2.0/events/MetaInstName.C' <<'END_OF_FILE'
X/*-
X * Copyright (c) 1993, 1994 Michael B. Durian. All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X * 1. Redistributions of source code must retain the above copyright
X * notice, this list of conditions and the following disclaimer.
X * 2. Redistributions in binary form must reproduce the above copyright
X * notice, this list of conditions and the following disclaimer in the
X * documentation and/or other materials provided with the distribution.
X * 3. All advertising materials mentioning features or use of this software
X * must display the following acknowledgement:
X * This product includes software developed by Michael B. Durian.
X * 4. The name of the the Author may be used to endorse or promote
X * products derived from this software without specific prior written
X * permission.
X *
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
X * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
X * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X * SUCH DAMAGE.
X */
X#include "MetaInstName.h"
X
XMetaInstrumentNameEvent::MetaInstrumentNameEvent()
X{
X}
X
XMetaInstrumentNameEvent::MetaInstrumentNameEvent(unsigned long t,
X const char *str) : MetaTextEvent(t, str)
X{
X}
X
XMetaInstrumentNameEvent::MetaInstrumentNameEvent(
X const MetaInstrumentNameEvent &e) : MetaTextEvent(e)
X{
X}
X
XMetaInstrumentNameEvent::~MetaInstrumentNameEvent()
X{
X}
X
X
XMetaInstrumentNameEvent &
XMetaInstrumentNameEvent::operator=(const MetaInstrumentNameEvent &e)
X{
X
X (MetaTextEvent)*this = (MetaTextEvent)e;
X return (*this);
X}
X
Xchar *
XMetaInstrumentNameEvent::GetEventStr(void) const
X{
X
X return (MetaTextEvent::GetEventStr());
X}
X
Xostream &
Xoperator<<(ostream &os, const MetaInstrumentNameEvent &e)
X{
X char *str;
X
X os << (str = e.GetEventStr());
X delete str;
X return (os);
X}
END_OF_FILE
if test 2447 -ne `wc -c <'tclmidi-2.0/events/MetaInstName.C'`; then
echo shar: \"'tclmidi-2.0/events/MetaInstName.C'\" unpacked with wrong size!
fi
# end of 'tclmidi-2.0/events/MetaInstName.C'
fi
if test -f 'tclmidi-2.0/events/MetaKey.C' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'tclmidi-2.0/events/MetaKey.C'\"
else
echo shar: Extracting \"'tclmidi-2.0/events/MetaKey.C'\" \(7506 characters\)
sed "s/^X//" >'tclmidi-2.0/events/MetaKey.C' <<'END_OF_FILE'
X/*-
X * Copyright (c) 1993, 1994 Michael B. Durian. All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X * 1. Redistributions of source code must retain the above copyright
X * notice, this list of conditions and the following disclaimer.
X * 2. Redistributions in binary form must reproduce the above copyright
X * notice, this list of conditions and the following disclaimer in the
X * documentation and/or other materials provided with the distribution.
X * 3. All advertising materials mentioning features or use of this software
X * must display the following acknowledgement:
X * This product includes software developed by Michael B. Durian.
X * 4. The name of the the Author may be used to endorse or promote
X * products derived from this software without specific prior written
X * permission.
X *
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
X * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
X * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X * SUCH DAMAGE.
X */
X#include <ctype.h>
X#include <string.h>
X#include "MetaKey.h"
X
XKey
XIntToKey(int i)
X{
X
X switch (i) {
X case -7:
X return (KEY_CFLAT);
X case -6:
X return (KEY_GFLAT);
X case -5:
X return (KEY_DFLAT);
X case -4:
X return (KEY_AFLAT);
X case -3:
X return (KEY_EFLAT);
X case -2:
X return (KEY_BFLAT);
X case -1:
X return (KEY_F);
X case 0:
X return (KEY_C);
X case 1:
X return (KEY_G);
X case 2:
X return (KEY_D);
X case 3:
X return (KEY_A);
X case 4:
X return (KEY_E);
X case 5:
X return (KEY_B);
X case 6:
X return (KEY_FSHARP);
X case 7:
X return (KEY_CSHARP);
X default:
X return (KEY_C);
X }
X}
X
Xint
XKeyToInt(Key k)
X{
X
X switch (k) {
X case KEY_CFLAT:
X return (-7);
X case KEY_GFLAT:
X return (-6);
X case KEY_DFLAT:
X return (-5);
X case KEY_AFLAT:
X return (-4);
X case KEY_EFLAT:
X return (-3);
X case KEY_BFLAT:
X return (-2);
X case KEY_F:
X return (-1);
X case KEY_C:
X return (0);
X case KEY_G:
X return (1);
X case KEY_D:
X return (2);
X case KEY_A:
X return (3);
X case KEY_E:
X return (4);
X case KEY_B:
X return (5);
X case KEY_FSHARP:
X return (6);
X case KEY_CSHARP:
X return (7);
X default:
X return (0);
X }
X}
X
XMetaKeyEvent::MetaKeyEvent() : key(KEY_C), mode(MODE_MAJOR)
X{
X}
X
XMetaKeyEvent::MetaKeyEvent(unsigned long t, Key k, Mode m) : MetaEvent(t),
X key(k), mode(m)
X{
X}
X
XMetaKeyEvent::MetaKeyEvent(const MetaKeyEvent &e) : MetaEvent(e),
X key(e.key), mode(e.mode)
X{
X}
X
Xconst char *
XMetaKeyEvent::GetKeyStr(void) const
X{
X
X switch (key) {
X case KEY_CFLAT:
X return ("C Flat");
X case KEY_GFLAT:
X return ("G Flat");
X case KEY_DFLAT:
X return ("D Flat");
X case KEY_AFLAT:
X return ("A Flat");
X case KEY_EFLAT:
X return ("E Flat");
X case KEY_BFLAT:
X return ("B Flat");
X case KEY_F:
X return ("F");
X case KEY_C:
X return ("C");
X case KEY_G:
X return ("G");
X case KEY_D:
X return ("D");
X case KEY_A:
X return ("A");
X case KEY_E:
X return ("E");
X case KEY_B:
X return ("B");
X case KEY_FSHARP:
X return ("F Sharp");
X case KEY_CSHARP:
X return ("C Sharp");
X }
X return ("");
X}
X
Xconst char *
XMetaKeyEvent::GetModeStr(void) const
X{
X
X switch (mode) {
X case MODE_MAJOR:
X return ("major");
X case MODE_MINOR:
X return ("minor");
X }
X return ("");
X}
X
XMetaKeyEvent &
XMetaKeyEvent::operator=(const MetaKeyEvent &e)
X{
X
X (MetaEvent)*this = (MetaEvent)e;
X key = e.key;
X mode = e.mode;
X return (*this);
X}
X
Xchar *
XMetaKeyEvent::GetEventStr(void) const
X{
X ostrstream buf;
X char *tbuf;
X
X tbuf = MetaEvent::GetEventStr();
X buf << tbuf << " Key: " << GetKeyStr() << " Mode: " << GetModeStr()
X << ends;
X delete tbuf;
X return (buf.str());
X}
X
Xconst char *
XMetaKeyEvent::SMFRead(SMFTrack &t)
X{
X const unsigned char *ptr;
X
X // get and throw away length
X if (t.GetVarValue() != 2)
X return ("Incomplete MetaKeyEvent - bad length");
X
X if ((ptr = t.GetByte()) == 0)
X return ("Incomplete MetaKeyEvent - missing key");
X key = IntToKey((signed char)*ptr);
X if ((ptr = t.GetByte()) == 0)
X return ("Incomplete MetaKeyEvent - missing mode");
X mode = (Mode)*ptr;
X return (0);
X}
X
Xconst char *
XMetaKeyEvent::SMFWrite(SMFTrack &t) const
X{
X
X if (!t.PutFixValue(2))
X return ("Out of memory");
X if (!t.PutByte((unsigned char)KeyToInt(key)))
X return ("Out of memory");
X if (!t.PutByte((unsigned char)mode))
X return ("Out of memory");
X return (0);
X}
X
Xint
XMetaKeyEvent::Equal(const Event *e) const
X{
X MetaKeyEvent *eptr = (MetaKeyEvent *)e;
X
X return (MetaEvent::Equal(e) && key == eptr->key && mode == eptr->mode);
X}
X
Xostream &
Xoperator<<(ostream &os, const MetaKeyEvent &e)
X{
X char *str;
X
X os << (str = e.GetEventStr());
X delete str;
X return (os);
X}
X
XKey
XStrToKey(const char *str, int *match)
X{
X Key key;
X char *keystr;
X int badkey, i, keylen;
X
X keylen = strlen(str);
X keystr = new char[keylen + 1];
X for (i = 0; i < keylen; i++)
X keystr[i] = tolower(str[i]);
X keystr[i] = '\0';
X
X /* shut up warning */
X key = KEY_C;
X badkey = 0;
X switch (keystr[0]) {
X case 'a':
X if (strcmp(keystr, "a") == 0)
X key = KEY_A;
X else if (strcmp(keystr, "a flat") == 0)
X key = KEY_AFLAT;
X else if (strcmp(keystr, "a sharp") == 0)
X key = KEY_BFLAT;
X else
X badkey = 1;
X break;
X case 'b':
X if (strcmp(keystr, "b") == 0)
X key = KEY_B;
X else if (strcmp(keystr, "b flat") == 0)
X key = KEY_BFLAT;
X else if (strcmp(keystr, "b sharp") == 0)
X key = KEY_C;
X else
X badkey = 1;
X break;
X case 'c':
X if (strcmp(keystr, "c") == 0)
X key = KEY_C;
X else if (strcmp(keystr, "c flat") == 0)
X key = KEY_CFLAT;
X else if (strcmp(keystr, "c sharp") == 0)
X key = KEY_CSHARP;
X else
X badkey = 1;
X break;
X case 'd':
X if (strcmp(keystr, "d") == 0)
X key = KEY_D;
X else if (strcmp(keystr, "d flat") == 0)
X key = KEY_DFLAT;
X else if (strcmp(keystr, "d sharp") == 0)
X key = KEY_EFLAT;
X else
X badkey = 1;
X break;
X case 'e':
X if (strcmp(keystr, "e") == 0)
X key = KEY_E;
X else if (strcmp(keystr, "e flat") == 0)
X key = KEY_EFLAT;
X else if (strcmp(keystr, "e sharp") == 0)
X key = KEY_F;
X else
X badkey = 1;
X break;
X case 'f':
X if (strcmp(keystr, "f") == 0)
X key = KEY_F;
X else if (strcmp(keystr, "f flat") == 0)
X key = KEY_E;
X else if (strcmp(keystr, "f sharp") == 0)
X key = KEY_FSHARP;
X else
X badkey = 1;
X break;
X case 'g':
X if (strcmp(keystr, "g") == 0)
X key = KEY_G;
X else if (strcmp(keystr, "g flat") == 0)
X key = KEY_GFLAT;
X else if (strcmp(keystr, "g sharp") == 0)
X key = KEY_AFLAT;
X else
X badkey = 1;
X break;
X default:
X badkey = 1;
X }
X
X delete keystr;
X if (badkey)
X *match = 0;
X else
X *match = 1;
X
X return (key);
X}
X
XMode
XStrToMode(const char *str, int *match)
X{
X Mode mode;
X char *modestr;
X int i, modelen;
X
X modelen = strlen(str);
X modestr = new char[modelen + 1];
X for (i = 0; i < modelen; i++)
X modestr[i] = tolower(str[i]);
X modestr[i] = '\0';
X
X *match = 1;
X if (strcmp(modestr, "minor") == 0)
X mode = MODE_MINOR;
X else if (strcmp(modestr, "major") == 0)
X mode = MODE_MAJOR;
X else {
X mode = MODE_MAJOR;
X *match = 0;
X }
X
X return (mode);
X}
END_OF_FILE
if test 7506 -ne `wc -c <'tclmidi-2.0/events/MetaKey.C'`; then
echo shar: \"'tclmidi-2.0/events/MetaKey.C'\" unpacked with wrong size!
fi
# end of 'tclmidi-2.0/events/MetaKey.C'
fi
echo shar: End of archive 6 \(of 14\).
cp /dev/null ark6isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 14 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still must unpack the following archives:
echo " " ${MISSING}
fi
exit 0
exit 0 # Just in case...