home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume43
/
tclmidi
/
part08
< prev
next >
Wrap
Internet Message Format
|
1994-07-21
|
63KB
From: durian@boogie.com (Mike Durian)
Newsgroups: comp.sources.misc
Subject: v43i116: tclmidi - A language for manipulating MIDI files, v2.0, Part08/14
Date: 21 Jul 1994 19:27:19 -0500
Organization: Sterling Software
Sender: kent@sparky.sterling.com
Approved: kent@sparky.sterling.com
Message-ID: <30n3p7$765@sparky.sterling.com>
X-Md4-Signature: 858c7bfafc8f225597cc841c91a53844
Submitted-by: durian@boogie.com (Mike Durian)
Posting-number: Volume 43, Issue 116
Archive-name: tclmidi/part08
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/TclmInterp.C tclmidi-2.0/drivers/BSD/midivar.h
# tclmidi-2.0/drivers/LINUX/quad.h
# tclmidi-2.0/events/MetaChanPrefix.C tclmidi-2.0/events/MetaSMPTE.C
# tclmidi-2.0/events/MetaSeqSpec.C tclmidi-2.0/events/MetaTime.C
# tclmidi-2.0/events/MetaUnknown.C tclmidi-2.0/events/Note.h
# tclmidi-2.0/events/SystemExcl.C tclmidi-2.0/man/midievents.n
# tclmidi-2.0/rb/README
# Wrapped by kent@sparky on Thu Jul 21 19:05:16 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 8 (of 14)."'
if test -f 'tclmidi-2.0/TclmInterp.C' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'tclmidi-2.0/TclmInterp.C'\"
else
echo shar: Extracting \"'tclmidi-2.0/TclmInterp.C'\" \(4921 characters\)
sed "s/^X//" >'tclmidi-2.0/TclmInterp.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 <assert.h>
X#include <strstream.h>
X#include "TclmInterp.h"
X
XTclmInterp::TclmInterp() : current_song(0), next_event(0), device(0)
X{
X
X Tcl_InitHashTable(&hash_table, TCL_STRING_KEYS);
X}
X
XTclmInterp::TclmInterp(const TclmInterp &ti)
X{
X ostrstream *buf;
X Tcl_HashSearch search;
X Tcl_HashEntry *entry, *new_entry;
X Song *song, *new_song;
X char *key;
X int repeat;
X
X device = ti.device;
X current_song = 0;
X Tcl_InitHashTable(&hash_table, TCL_STRING_KEYS);
X entry = Tcl_FirstHashEntry((Tcl_HashTable *)&ti.hash_table, &search);
X while (entry != 0) {
X song = (Song *)Tcl_GetHashValue(entry);
X
X // make a new entry
X buf = new ostrstream;
X *buf << "song" << current_song << ends;
X key = buf->str();
X new_entry = Tcl_CreateHashEntry(&hash_table, key, &repeat);
X new_song = new Song(*song);
X assert(new_song != 0);
X Tcl_SetHashValue(new_entry, new_song);
X delete key;
X delete buf;
X current_song++;
X
X // find next entry
X entry = Tcl_NextHashEntry(&search);
X }
X}
X
XTclmInterp::~TclmInterp()
X{
X Tcl_HashSearch search;
X Tcl_HashEntry *entry;
X Song *song;
X
X // delete existing entries
X entry = Tcl_FirstHashEntry(&hash_table, &search);
X while (entry != 0) {
X song = (Song *)Tcl_GetHashValue(entry);
X delete song;
X Tcl_DeleteHashEntry(entry);
X entry = Tcl_NextHashEntry(&search);
X }
X
X // delete table
X Tcl_DeleteHashTable(&hash_table);
X
X}
X
XSong *
XTclmInterp::GetSong(const char *key) const
X{
X Tcl_HashEntry *entry;
X
X entry = Tcl_FindHashEntry((Tcl_HashTable *)&hash_table, (char *)key);
X if (entry == 0)
X return (0);
X return ((Song *)Tcl_GetHashValue(entry));
X}
X
Xchar *
XTclmInterp::AddSong(const Song *song)
X{
X ostrstream buf;
X char *key;
X Tcl_HashEntry *entry;
X int repeat;
X
X buf << "song" << current_song++ << ends;
X key = buf.str();
X entry = Tcl_CreateHashEntry(&hash_table, key, &repeat);
X Tcl_SetHashValue(entry, song);
X return (key);
X}
X
Xint
XTclmInterp::DeleteSong(const char *key)
X{
X Tcl_HashEntry *entry;
X Song *song;
X
X entry = Tcl_FindHashEntry(&hash_table, (char *)key);
X if (entry == 0)
X return (0);
X song = (Song *)Tcl_GetHashValue(entry);
X delete song;
X Tcl_DeleteHashEntry(entry);
X return (1);
X}
X
Xvoid
XTclmInterp::SetMidiDevice(MidiDevice *dev)
X{
X
X device = dev;
X}
X
XMidiDevice *
XTclmInterp::GetMidiDevice(void) const
X{
X
X return (device);
X}
X
XTclmInterp &
XTclmInterp::operator=(const TclmInterp &ti)
X{
X ostrstream *buf;
X Tcl_HashSearch search;
X Tcl_HashEntry *entry, *new_entry;
X Song *song, *new_song;
X char *key;
X int repeat;
X
X // delete existing entries
X entry = Tcl_FirstHashEntry(&hash_table, &search);
X while (entry != 0) {
X song = (Song *)Tcl_GetHashValue(entry);
X delete song;
X Tcl_DeleteHashEntry(entry);
X entry = Tcl_NextHashEntry(&search);
X }
X
X current_song = 0;
X entry = Tcl_FirstHashEntry((Tcl_HashTable *)&ti.hash_table, &search);
X while (entry != 0) {
X song = (Song *)Tcl_GetHashValue(entry);
X
X // make a new entry
X buf = new ostrstream;
X *buf << "song" << current_song << ends;
X key = buf->str();
X new_entry = Tcl_CreateHashEntry(&hash_table, key, &repeat);
X new_song = new Song(*song);
X assert(new_song != 0);
X Tcl_SetHashValue(new_entry, new_song);
X delete key;
X delete buf;
X current_song++;
X
X // find next entry
X entry = Tcl_NextHashEntry(&search);
X }
X
X device = ti.device;
X return (*this);
X}
END_OF_FILE
if test 4921 -ne `wc -c <'tclmidi-2.0/TclmInterp.C'`; then
echo shar: \"'tclmidi-2.0/TclmInterp.C'\" unpacked with wrong size!
fi
# end of 'tclmidi-2.0/TclmInterp.C'
fi
if test -f 'tclmidi-2.0/drivers/BSD/midivar.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'tclmidi-2.0/drivers/BSD/midivar.h'\"
else
echo shar: Extracting \"'tclmidi-2.0/drivers/BSD/midivar.h'\" \(4491 characters\)
sed "s/^X//" >'tclmidi-2.0/drivers/BSD/midivar.h' <<'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/*
X * midi port offsets
X */
X#define MIDI_DATA 0
X#define MIDI_STATUS 1
X#define MIDI_COMMAND 1
X
X
X/*
X * midi data transfer status bits
X */
X#define MIDI_RDY_RCV (1 << 6)
X#define MIDI_DATA_AVL (1 << 7)
X
X/*
X * midi status flags
X */
X#define MIDI_UNAVAILABLE (1 << 0) /* not in uart mode */
X#define MIDI_READING (1 << 1) /* open for reading */
X#define MIDI_WRITING (1 << 2) /* open for writing */
X#define MIDI_CALLBACK_ISSUED (1 << 3) /* waiting for a timer to expire */
X#define MIDI_RD_BLOCK (1 << 4) /* read will block */
X#define MIDI_WR_BLOCK (1 << 5) /* write will block */
X#define MIDI_WR_ABORT (1 << 6) /* write should abort */
X#define MIDI_OPEN (1 << 7) /* device is open */
X#define MIDI_FLUSH_SLEEP (1 << 8) /* blocking on flush */
X#define MIDI_RD_SLEEP (1 << 9) /* blocking on read */
X#define MIDI_WR_SLEEP (1 << 10) /* blocking on write */
X#define MIDI_BUFFER_SLEEP (1 << 11) /* blocking on buffer */
X#define MIDI_NEED_ACK (1 << 12) /* command needs and ack */
X#define MIDI_ASYNC (1 << 13) /* send sigios */
X#define MIDI_SENDIO (1 << 14) /* a sigio should be send at low h2o */
X#define MIDI_THRU (1 << 15) /* pass in port to out port? */
X#define MIDI_RECONPLAY (1 << 16) /* don't record until we start to play */
X
X/*
X * These are the various input data states
X */
Xtypedef enum {START, NEEDDATA1, NEEDDATA2, SYSEX, SYSTEM1, SYSTEM2} InputState;
X
X/*
X * midi command values
X */
X#define MIDI_RESET 0xff
X#define MIDI_UART 0x3f
X#define MIDI_ACK 0xfe
X#define MIDI_TRIES 20000
X
X/*
X * most events are short, so we use the static array,
X * but occationally we get a long event (sysex) and
X * we dynamically allocate that
X */
X#define STYNAMIC_SIZE 4
X#define STYNAMIC_ALLOC 256
X
Xstruct stynamic {
X short allocated;
X short len;
X u_char datas[4];
X u_char *datad;
X};
X
X/*
X * data from the board that hasn't formed a complete event yet
X */
Xstruct partial_event {
X struct stynamic event; /* the data */
X struct timeval time; /* when the event occured */
X /* will use ticks with 4.4 */
X long tempo; /* tempo setting when event arrived */
X InputState state; /* what we are expecting next */
X u_char rs; /* the midi running state */
X};
X
X/*
X * the internal representation of an event
X */
Xtypedef enum {NORMAL, TEMPO, TIMESIG, SYSX} EventType;
X
Xstruct event {
X u_long time; /* time until event in kernel clicks */
X long tempo; /*
X * not used in play events, but contains
X * the tempo setting current when the
X * incoming event arrived. Used for
X * convert kernel ticks to smf ticks
X */
X EventType type;
X struct stynamic data;
X};
X
X/*
X * A event queue, used for both incoming and outgoing
X */
X#define MIDI_Q_SIZE 150
X#define MIDI_LOW_WATER 40
X
Xstruct event_queue {
X int count;
X struct event events[MIDI_Q_SIZE];
X struct event *end;
X struct event *head;
X struct event *tail;
X};
END_OF_FILE
if test 4491 -ne `wc -c <'tclmidi-2.0/drivers/BSD/midivar.h'`; then
echo shar: \"'tclmidi-2.0/drivers/BSD/midivar.h'\" unpacked with wrong size!
fi
# end of 'tclmidi-2.0/drivers/BSD/midivar.h'
fi
if test -f 'tclmidi-2.0/drivers/LINUX/quad.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'tclmidi-2.0/drivers/LINUX/quad.h'\"
else
echo shar: Extracting \"'tclmidi-2.0/drivers/LINUX/quad.h'\" \(4330 characters\)
sed "s/^X//" >'tclmidi-2.0/drivers/LINUX/quad.h' <<'END_OF_FILE'
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 * @(#)quad.h 5.9 (Berkeley) 7/28/92
X */
X
X/*
X * Quad arithmetic.
X *
X * This library makes the following assumptions:
X *
X * - The type long long (aka quad_t) exists.
X *
X * - A quad variable is exactly twice as long as `long'.
X *
X * - The machine's arithmetic is two's complement.
X *
X * This library can provide 128-bit arithmetic on a machine with 128-bit
X * quads and 64-bit longs, for instance, or 96-bit arithmetic on machines
X * with 48-bit longs.
X */
X
X#ifdef __linux__
X /* Linux support added by L.Georgiev */
X
X typedef signed long long int quad_t;
X typedef unsigned long long int u_quad_t;
X
X #define _QUAD_LOWWORD 0
X #define _QUAD_HIGHWORD 1
X
X #include <sys/cdefs.h>
X#else
X #include <cdefs.h>
X#endif
X#include <sys/types.h>
X#include <limits.h>
X
X/*
X * Depending on the desired operation, we view a `long long' (aka quad_t) in
X * one or more of the following formats.
X */
Xunion uu {
X quad_t q; /* as a (signed) quad */
X quad_t uq; /* as an unsigned quad */
X long sl[2]; /* as two signed longs */
X u_long ul[2]; /* as two unsigned longs */
X};
X
X/*
X * Define high and low longwords.
X */
X#define H _QUAD_HIGHWORD
X#define L _QUAD_LOWWORD
X
X/*
X * Total number of bits in a quad_t and in the pieces that make it up.
X * These are used for shifting, and also below for halfword extraction
X * and assembly.
X */
X#define QUAD_BITS (sizeof(quad_t) * CHAR_BIT)
X#define LONG_BITS (sizeof(long) * CHAR_BIT)
X#define HALF_BITS (sizeof(long) * CHAR_BIT / 2)
X
X/*
X * Extract high and low shortwords from longword, and move low shortword of
X * longword to upper half of long, i.e., produce the upper longword of
X * ((quad_t)(x) << (number_of_bits_in_long/2)). (`x' must actually be u_long.)
X *
X * These are used in the multiply code, to split a longword into upper
X * and lower halves, and to reassemble a product as a quad_t, shifted left
X * (sizeof(long)*CHAR_BIT/2).
X */
X#define HHALF(x) ((x) >> HALF_BITS)
X#define LHALF(x) ((x) & ((1 << HALF_BITS) - 1))
X#define LHUP(x) ((x) << HALF_BITS)
X
Xextern u_quad_t __qdivrem __P((u_quad_t u, u_quad_t v, u_quad_t *rem));
X
X/*
X * XXX
X * Compensate for gcc 1 vs gcc 2. Gcc 1 defines ?sh?di3's second argument
X * as u_quad_t, while gcc 2 correctly uses int. Unfortunately, we still use
X * both compilers.
X */
X#if __GNUC__ >= 2
Xtypedef unsigned int qshift_t;
X#else
Xtypedef u_quad_t qshift_t;
X#endif
END_OF_FILE
if test 4330 -ne `wc -c <'tclmidi-2.0/drivers/LINUX/quad.h'`; then
echo shar: \"'tclmidi-2.0/drivers/LINUX/quad.h'\" unpacked with wrong size!
fi
# end of 'tclmidi-2.0/drivers/LINUX/quad.h'
fi
if test -f 'tclmidi-2.0/events/MetaChanPrefix.C' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'tclmidi-2.0/events/MetaChanPrefix.C'\"
else
echo shar: Extracting \"'tclmidi-2.0/events/MetaChanPrefix.C'\" \(4353 characters\)
sed "s/^X//" >'tclmidi-2.0/events/MetaChanPrefix.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 <assert.h>
X#include <string.h>
X
X#include "MetaChanPrefix.h"
X
XMetaChannelPrefixEvent::MetaChannelPrefixEvent() : data(0), length(0L)
X{
X}
X
XMetaChannelPrefixEvent::MetaChannelPrefixEvent(unsigned long t,
X const unsigned char *dat, long len) : MetaEvent(t), length(len)
X{
X
X data = new unsigned char[len];
X assert(data != 0);
X// memmove(data, dat, len);
X memcpy(data, dat, len);
X}
X
XMetaChannelPrefixEvent::MetaChannelPrefixEvent(const MetaChannelPrefixEvent &e) :
X MetaEvent(e), length(e.length)
X{
X
X data = new unsigned char[e.length];
X assert(data != 0);
X// memmove(data, e.data, e.length);
X memcpy(data, e.data, e.length);
X}
X
XMetaChannelPrefixEvent::~MetaChannelPrefixEvent()
X{
X
X delete data;
X}
X
Xvoid
XMetaChannelPrefixEvent::SetData(const unsigned char *dat, long len)
X{
X
X if (data != 0)
X delete data;
X data = new unsigned char[len];
X assert(data != 0);
X// memmove(data, dat, len);
X memcpy(data, dat, len);
X}
X
XMetaChannelPrefixEvent &
XMetaChannelPrefixEvent::operator=(const MetaChannelPrefixEvent &e)
X{
X
X (MetaEvent)*this = (MetaEvent)e;
X if (data != 0)
X delete data;
X data = new unsigned char[e.length];
X length = e.length;
X assert(data != 0);
X// memmove(data, e.data, e.length);
X memcpy(data, e.data, e.length);
X return (*this);
X}
X
Xchar *
XMetaChannelPrefixEvent::GetEventStr(void) const
X{
X ostrstream buf;
X char *tbuf;
X long i;
X
X tbuf = MetaEvent::GetEventStr();
X buf << tbuf << " Data:";
X buf.setf(ios::showbase | ios::internal);
X for (i = 0; i < length; i++)
X buf << " " << hex << setw(4) << setfill('0') << (int)data[i];
X buf << ends;
X delete tbuf;
X return (buf.str());
X}
X
Xconst char *
XMetaChannelPrefixEvent::SMFRead(SMFTrack &t)
X{
X const unsigned char *ptr;
X
X if (data != 0)
X delete data;
X if ((length = t.GetVarValue()) == -1)
X return ("Incomplete MetaChannelPrefixEvent - bad length");
X data = new unsigned char[length];
X if (data == 0)
X return ("Out of memory");
X if ((ptr = t.GetData(length)) == 0)
X return ("Incomplete MetaChannelPrefixEvent - bad data");
X memcpy(data, ptr, length);
X return (0);
X}
X
Xconst char *
XMetaChannelPrefixEvent::SMFWrite(SMFTrack &t) const
X{
X
X if (!t.PutFixValue(length))
X return ("Out of memory");
X if (!t.PutData(data, length))
X return ("Out of memory");
X return (0);
X}
X
Xint
XMetaChannelPrefixEvent::Equal(const Event *e) const
X{
X long i;
X MetaChannelPrefixEvent *eptr = (MetaChannelPrefixEvent *)e;
X
X if (!MetaEvent::Equal(e))
X return (0);
X if (length != eptr->length)
X return (0);
X for (i = 0; i < length; i++)
X if (data[i] != eptr->data[i])
X return (0);
X return (1);
X}
X
Xostream &
Xoperator<<(ostream &os, const MetaChannelPrefixEvent &e)
X{
X char *str;
X
X os << (str = e.GetEventStr());
X delete str;
X return (os);
X}
END_OF_FILE
if test 4353 -ne `wc -c <'tclmidi-2.0/events/MetaChanPrefix.C'`; then
echo shar: \"'tclmidi-2.0/events/MetaChanPrefix.C'\" unpacked with wrong size!
fi
# end of 'tclmidi-2.0/events/MetaChanPrefix.C'
fi
if test -f 'tclmidi-2.0/events/MetaSMPTE.C' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'tclmidi-2.0/events/MetaSMPTE.C'\"
else
echo shar: Extracting \"'tclmidi-2.0/events/MetaSMPTE.C'\" \(4375 characters\)
sed "s/^X//" >'tclmidi-2.0/events/MetaSMPTE.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 "MetaSMPTE.h"
X
XMetaSMPTEEvent::MetaSMPTEEvent() : hour(0), minute(0), second(0), frame(0),
X fractional_frame(0)
X{
X}
X
XMetaSMPTEEvent::MetaSMPTEEvent(unsigned long t, unsigned char h,
X unsigned char m, unsigned char s, unsigned char f, unsigned char ff) :
X MetaEvent(t), hour(h), minute(m), second(s), frame(f), fractional_frame(ff)
X{
X}
X
XMetaSMPTEEvent::MetaSMPTEEvent(const MetaSMPTEEvent &e) : MetaEvent(e),
X hour(e.hour), minute(e.minute), second(e.second), frame(e.frame),
X fractional_frame(e.fractional_frame)
X{
X}
X
XMetaSMPTEEvent &
XMetaSMPTEEvent::operator=(const MetaSMPTEEvent &e)
X{
X
X (MetaEvent)*this = (MetaEvent)e;
X hour = e.hour;
X minute = e.minute;
X second = e.second;
X frame = e.frame;
X fractional_frame = e.fractional_frame;
X return (*this);
X}
X
Xchar *
XMetaSMPTEEvent::GetEventStr(void) const
X{
X ostrstream buf;
X char *tbuf;
X
X tbuf = MetaEvent::GetEventStr();
X buf << tbuf << " Hour: " << (int)hour << " Minute: " << (int)minute
X << " Second: " << (int)second << " Frame: " << (int)frame
X << " Fractional Frame: " << (int)fractional_frame << ends;
X delete tbuf;
X return (buf.str());
X}
X
Xconst char *
XMetaSMPTEEvent::SMFRead(SMFTrack &t)
X{
X const unsigned char *ptr;
X
X // get and throw away length
X if (t.GetVarValue() != 5)
X return ("Incomplete metaSMPTEEvent - bad length");
X
X if ((ptr = t.GetByte()) == 0)
X return ("Incomplete MetaSMPTEEvent - missing hour");
X hour = *ptr;
X if ((ptr = t.GetByte()) == 0)
X return ("Incomplete MetaSMPTEEvent - missing minute");
X minute = *ptr;
X if ((ptr = t.GetByte()) == 0)
X return ("Incomplete MetaSMPTEEvent - missing second");
X second = *ptr;
X if ((ptr = t.GetByte()) == 0)
X return ("Incomplete MetaSMPTEEvent - missing frame");
X frame = *ptr;
X if ((ptr = t.GetByte()) == 0)
X return ("Incomplete MetaSMPTEEvent - missing fractional "
X "frame");
X fractional_frame = *ptr;
X return (0);
X}
X
Xconst char *
XMetaSMPTEEvent::SMFWrite(SMFTrack &t) const
X{
X
X if (!t.PutFixValue(5))
X return ("Out of memory");
X if (!t.PutByte(hour))
X return ("Out of memory");
X if (!t.PutByte(minute))
X return ("Out of memory");
X if (!t.PutByte(second))
X return ("Out of memory");
X if (!t.PutByte(frame))
X return ("Out of memory");
X if (!t.PutByte(fractional_frame))
X return ("Out of memory");
X return (0);
X}
X
Xint
XMetaSMPTEEvent::Equal(const Event *e) const
X{
X MetaSMPTEEvent *eptr = (MetaSMPTEEvent *)e;
X
X return (MetaEvent::Equal(e) && hour == eptr->hour &&
X minute == eptr->minute && second == eptr->second &&
X frame == eptr->frame &&
X fractional_frame == eptr->fractional_frame);
X}
X
Xostream &
Xoperator<<(ostream &os, const MetaSMPTEEvent &e)
X{
X char *str;
X
X os << (str = e.GetEventStr());
X delete str;
X return (os);
X}
END_OF_FILE
if test 4375 -ne `wc -c <'tclmidi-2.0/events/MetaSMPTE.C'`; then
echo shar: \"'tclmidi-2.0/events/MetaSMPTE.C'\" unpacked with wrong size!
fi
# end of 'tclmidi-2.0/events/MetaSMPTE.C'
fi
if test -f 'tclmidi-2.0/events/MetaSeqSpec.C' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'tclmidi-2.0/events/MetaSeqSpec.C'\"
else
echo shar: Extracting \"'tclmidi-2.0/events/MetaSeqSpec.C'\" \(4428 characters\)
sed "s/^X//" >'tclmidi-2.0/events/MetaSeqSpec.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 <assert.h>
X#include <string.h>
X
X#include "MetaSeqSpec.h"
X
XMetaSequencerSpecificEvent::MetaSequencerSpecificEvent() : data(0), length(0L)
X{
X}
X
XMetaSequencerSpecificEvent::MetaSequencerSpecificEvent(unsigned long t,
X const unsigned char *dat, long len) : MetaEvent(t), length(len)
X{
X
X data = new unsigned char[len];
X assert(data != 0);
X// memmove(data, dat, len);
X memcpy(data, dat, len);
X}
X
XMetaSequencerSpecificEvent::MetaSequencerSpecificEvent(
X const MetaSequencerSpecificEvent &e) : MetaEvent(e), length(e.length)
X{
X
X data = new unsigned char[e.length];
X assert(data != 0);
X// memmove(data, e.data, e.length);
X memcpy(data, e.data, e.length);
X}
X
XMetaSequencerSpecificEvent::~MetaSequencerSpecificEvent()
X{
X
X delete data;
X}
X
Xvoid
XMetaSequencerSpecificEvent::SetData(const unsigned char *dat, long len)
X{
X
X if (data != 0)
X delete data;
X data = new unsigned char[len];
X assert(data != 0);
X// memmove(data, dat, len);
X memcpy(data, dat, len);
X}
X
XMetaSequencerSpecificEvent &
XMetaSequencerSpecificEvent::operator=(const MetaSequencerSpecificEvent &e)
X{
X
X (MetaEvent)*this = (MetaEvent)e;
X if (data != 0)
X delete data;
X length = e.length;
X data = new unsigned char[e.length];
X assert(data != 0);
X// memmove(data, e.data, e.length);
X memcpy(data, e.data, e.length);
X return (*this);
X}
X
Xchar *
XMetaSequencerSpecificEvent::GetEventStr(void) const
X{
X ostrstream buf;
X long i;
X char *tbuf;
X
X tbuf = MetaEvent::GetEventStr();
X buf << tbuf << " Data:";
X buf.setf(ios::showbase | ios::internal);
X for (i = 0; i < length; i++)
X buf << " " << hex << setw(4) << setfill('0') << (int)data[i];
X buf << ends;
X delete tbuf;
X return (buf.str());
X}
X
Xconst char *
XMetaSequencerSpecificEvent::SMFRead(SMFTrack &t)
X{
X const unsigned char *ptr;
X
X if (data != 0)
X delete data;
X if ((length = t.GetVarValue()) == -1)
X return ("Incomplete MetaSequenceSpecificEvent - bad length");
X data = new unsigned char[length];
X if (data == 0)
X return ("Out of memory");
X if ((ptr = t.GetData(length)) == 0)
X return ("Incomplete MetaSequencerSpecificEvent");
X memcpy(data, ptr, length);
X return (0);
X}
X
Xconst char *
XMetaSequencerSpecificEvent::SMFWrite(SMFTrack &t) const
X{
X
X if (!t.PutFixValue(length))
X return ("Out of memory");
X if (!t.PutData(data, length))
X return ("Out of memory");
X return (0);
X}
X
Xint
XMetaSequencerSpecificEvent::Equal(const Event *e) const
X{
X long i;
X MetaSequencerSpecificEvent *eptr = (MetaSequencerSpecificEvent *)e;
X
X if (!MetaEvent::Equal(e))
X return (0);
X if (length != eptr->length)
X return (0);
X for (i = 0; i < length; i++)
X if (data[i] != eptr->data[i])
X return (0);
X return (1);
X}
X
Xostream &
Xoperator<<(ostream &os, const MetaSequencerSpecificEvent &e)
X{
X char *str;
X
X os << (str = e.GetEventStr());
X delete str;
X return (os);
X}
END_OF_FILE
if test 4428 -ne `wc -c <'tclmidi-2.0/events/MetaSeqSpec.C'`; then
echo shar: \"'tclmidi-2.0/events/MetaSeqSpec.C'\" unpacked with wrong size!
fi
# end of 'tclmidi-2.0/events/MetaSeqSpec.C'
fi
if test -f 'tclmidi-2.0/events/MetaTime.C' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'tclmidi-2.0/events/MetaTime.C'\"
else
echo shar: Extracting \"'tclmidi-2.0/events/MetaTime.C'\" \(4380 characters\)
sed "s/^X//" >'tclmidi-2.0/events/MetaTime.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 "MetaTime.h"
X
XMetaTimeEvent::MetaTimeEvent() : numerator(4), denominator(4), clocks(24),
X thirty_seconds(8)
X{
X}
X
XMetaTimeEvent::MetaTimeEvent(unsigned long time, unsigned char n,
X unsigned char d, unsigned char c, unsigned char t) : MetaEvent(time),
X numerator(n), denominator(d), clocks(c), thirty_seconds(t)
X{
X}
X
XMetaTimeEvent::MetaTimeEvent(const MetaTimeEvent &e) : MetaEvent(e),
X numerator(e.numerator), denominator(e.denominator), clocks(e.clocks),
X thirty_seconds(e.thirty_seconds)
X{
X}
X
XMetaTimeEvent &
XMetaTimeEvent::operator=(const MetaTimeEvent &e)
X{
X
X (MetaEvent)*this = (MetaEvent)e;
X numerator = e.numerator;
X denominator = e.denominator;
X clocks = e.clocks;
X thirty_seconds = e.thirty_seconds;
X return (*this);
X}
X
Xchar *
XMetaTimeEvent::GetEventStr(void) const
X{
X ostrstream buf;
X char *tbuf;
X
X tbuf = MetaEvent::GetEventStr();
X buf << tbuf << " Numerator: " << (int)numerator
X << " Denominator: " << (int)denominator
X << " Clocks Per Metronome Beat: " << (int)clocks
X << " 32nd Notes Per Quarter Note: " << (int)thirty_seconds
X << ends;
X delete tbuf;
X return (buf.str());
X}
X
Xconst char *
XMetaTimeEvent::SMFRead(SMFTrack &t)
X{
X const unsigned char *ptr;
X unsigned char i, powof2;
X
X // get and throw away length
X if (t.GetVarValue() != 4)
X return ("Incomplete MetaTimeEvent - bad length");
X if ((ptr = t.GetByte()) == 0)
X return ("Incomplete MetaTimeEvent - missing numerator");
X numerator = *ptr;
X if ((ptr = t.GetByte()) == 0)
X return ("Incomplete MetaTimeEvent - missing denominator");
X powof2 = *ptr;
X denominator = 1;
X for (i = 0; i < powof2; i++)
X denominator *= 2;
X if ((ptr = t.GetByte()) == 0)
X return ("Incomplete MetaTimeEvent - missing clocks");
X clocks = *ptr;
X if ((ptr = t.GetByte()) == 0)
X return ("Incomplete MetaTimeEvent - missing 32nds");
X thirty_seconds = *ptr;
X return (0);
X}
X
Xconst char *
XMetaTimeEvent::SMFWrite(SMFTrack &t) const
X{
X unsigned char i, powof2;
X
X if (!t.PutFixValue(4))
X return ("Out of memory");
X if (!t.PutByte(numerator))
X return ("Out of memory");
X for (i = 0, powof2 = 1; powof2 <= denominator; powof2 *= 2, i++);
X i--;
X if (!t.PutByte(i))
X return ("Out of memory");
X if (!t.PutByte(clocks))
X return ("Out of memory");
X if (!t.PutByte(thirty_seconds))
X return ("Out of memory");
X return (0);
X}
X
Xint
XMetaTimeEvent::Equal(const Event *e) const
X{
X MetaTimeEvent *eptr = (MetaTimeEvent *)e;
X
X return (MetaEvent::Equal(e) && numerator == eptr->numerator &&
X denominator == eptr->denominator && clocks == eptr->clocks &&
X thirty_seconds == eptr->thirty_seconds);
X}
X
Xostream &
Xoperator<<(ostream &os, const MetaTimeEvent &e)
X{
X char *str;
X
X os << (str = e.GetEventStr());
X delete str;
X return (os);
X}
END_OF_FILE
if test 4380 -ne `wc -c <'tclmidi-2.0/events/MetaTime.C'`; then
echo shar: \"'tclmidi-2.0/events/MetaTime.C'\" unpacked with wrong size!
fi
# end of 'tclmidi-2.0/events/MetaTime.C'
fi
if test -f 'tclmidi-2.0/events/MetaUnknown.C' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'tclmidi-2.0/events/MetaUnknown.C'\"
else
echo shar: Extracting \"'tclmidi-2.0/events/MetaUnknown.C'\" \(4474 characters\)
sed "s/^X//" >'tclmidi-2.0/events/MetaUnknown.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 <assert.h>
X#include <string.h>
X
X#include "MetaUnknown.h"
X
XMetaUnknownEvent::MetaUnknownEvent() : data(0), length(0L), type(0x60)
X{
X}
X
XMetaUnknownEvent::MetaUnknownEvent(unsigned char t) : type(t), data(0),
X length(0L)
X{
X}
X
XMetaUnknownEvent::MetaUnknownEvent(unsigned long t, const unsigned char *dat,
X long len, unsigned char ty) : MetaEvent(t), length(len), type(ty)
X{
X
X data = new unsigned char[len];
X assert(data != 0);
X// memmove(data, dat, len);
X memcpy(data, dat, len);
X}
X
XMetaUnknownEvent::MetaUnknownEvent(const MetaUnknownEvent &e) : MetaEvent(e),
X length(e.length), type(e.type)
X{
X
X data = new unsigned char[e.length];
X assert(data != 0);
X// memmove(data, e.data, e.length);
X memcpy(data, e.data, e.length);
X}
X
XMetaUnknownEvent::~MetaUnknownEvent()
X{
X
X delete data;
X}
X
Xvoid
XMetaUnknownEvent::SetData(const unsigned char *dat, long len)
X{
X
X if (data != 0)
X delete data;
X data = new unsigned char[len];
X assert(data != 0);
X// memmove(data, dat, len);
X memcpy(data, dat, len);
X}
X
XMetaUnknownEvent &
XMetaUnknownEvent::operator=(const MetaUnknownEvent &e)
X{
X
X (MetaEvent)*this = (MetaEvent)e;
X if (data != 0)
X delete data;
X length = e.length;
X type = e.type;
X data = new unsigned char[e.length];
X assert(data != 0);
X// memmove(data, e.data, e.length);
X memcpy(data, e.data, e.length);
X return (*this);
X}
X
Xchar *
XMetaUnknownEvent::GetEventStr(void) const
X{
X ostrstream buf;
X long i;
X char *tbuf;
X
X tbuf = MetaEvent::GetEventStr();
X buf.setf(ios::showbase | ios::internal);
X buf << tbuf << " Type: " << hex << setw(4) << setfill('0') << (int)type
X << " Data:";
X for (i = 0; i < length; i++)
X buf << " " << hex << setw(4) << setfill('0') << (int)data[i];
X buf << ends;
X delete tbuf;
X return (buf.str());
X}
X
Xconst char *
XMetaUnknownEvent::SMFRead(SMFTrack &t)
X{
X const unsigned char *ptr;
X
X if (data != 0)
X delete data;
X if ((length = t.GetVarValue()) == -1)
X return ("Incomplete MetaUnknownEvent - bad length");
X data = new unsigned char[length];
X if (data == 0)
X return ("Out of memory");
X if ((ptr = t.GetData(length)) == 0)
X return ("Incomplete MetaUnknownEvent");
X memcpy(data, ptr, length);
X return (0);
X}
X
Xconst char *
XMetaUnknownEvent::SMFWrite(SMFTrack &t) const
X{
X
X if (!t.PutFixValue(length))
X return ("Out of memory");
X if (!t.PutData(data, length))
X return ("Out of memory");
X return (0);
X}
X
Xint
XMetaUnknownEvent::Equal(const Event *e) const
X{
X long i;
X MetaUnknownEvent *eptr = (MetaUnknownEvent *)e;
X
X if (!MetaEvent::Equal(e))
X return (0);
X if (length != eptr->length)
X return (0);
X if (type != eptr->type)
X return (0);
X for (i = 0; i < length; i++)
X if (data[i] != eptr->data[i])
X return (0);
X return (1);
X}
X
Xostream &
Xoperator<<(ostream &os, const MetaUnknownEvent &e)
X{
X char *str;
X
X os << (str = e.GetEventStr());
X delete str;
X return (os);
X}
END_OF_FILE
if test 4474 -ne `wc -c <'tclmidi-2.0/events/MetaUnknown.C'`; then
echo shar: \"'tclmidi-2.0/events/MetaUnknown.C'\" unpacked with wrong size!
fi
# end of 'tclmidi-2.0/events/MetaUnknown.C'
fi
if test -f 'tclmidi-2.0/events/Note.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'tclmidi-2.0/events/Note.h'\"
else
echo shar: Extracting \"'tclmidi-2.0/events/Note.h'\" \(2843 characters\)
sed "s/^X//" >'tclmidi-2.0/events/Note.h' <<'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#ifndef NOTEEVENT_H
X#define NOTEEVENT_H
X
X#include "NormalEvent.h"
X
Xclass NoteEvent : public NormalEvent {
X friend ostream &operator<<(ostream &os, const NoteEvent &e);
Xpublic:
X NoteEvent();
X NoteEvent(unsigned long t, unsigned char chan, unsigned char pit,
X unsigned char vel, const NoteEvent *np = 0);
X NoteEvent(const NoteEvent &e);
X virtual Event *Dup(void) const {return (new NoteEvent(*this));}
X
X virtual EventType GetType(void) const {return (NOTE);}
X virtual char *GetTypeStr(void) const {return ("NoteEvent");}
X virtual char *GetEventStr(void) const;
X unsigned char GetPitch(void) const {return (pitch);}
X unsigned char GetVelocity(void) const {return (velocity);}
X NoteEvent *GetNotePair(void) const {return (note_pair);}
X
X void SetPitch(unsigned char pit) {pitch = pit;}
X void SetVelocity(unsigned char vel) {velocity = vel;}
X void SetNotePair(NoteEvent *np) {note_pair = np;}
X
X NoteEvent &operator=(const NoteEvent &e);
X
X virtual const char *SMFRead(SMFTrack &t);
X virtual const char *SMFWrite(SMFTrack &t) const;
Xprotected:
X virtual int Equal(const Event *e) const;
Xprivate:
X unsigned char pitch;
X unsigned char velocity;
X NoteEvent *note_pair;
X};
X#endif
END_OF_FILE
if test 2843 -ne `wc -c <'tclmidi-2.0/events/Note.h'`; then
echo shar: \"'tclmidi-2.0/events/Note.h'\" unpacked with wrong size!
fi
# end of 'tclmidi-2.0/events/Note.h'
fi
if test -f 'tclmidi-2.0/events/SystemExcl.C' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'tclmidi-2.0/events/SystemExcl.C'\"
else
echo shar: Extracting \"'tclmidi-2.0/events/SystemExcl.C'\" \(4546 characters\)
sed "s/^X//" >'tclmidi-2.0/events/SystemExcl.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 <assert.h>
X#include <string.h>
X
X#include "SystemExcl.h"
X
XSystemExclusiveEvent::SystemExclusiveEvent() : data(0), length(0L),
X continued(0)
X{
X}
X
XSystemExclusiveEvent::SystemExclusiveEvent(unsigned char c) : data(0),
X length(0L), continued(c)
X{
X}
X
XSystemExclusiveEvent::SystemExclusiveEvent(unsigned long t,
X const unsigned char *dat, long len) : Event(t), length(len),
X continued(0)
X{
X
X data = new unsigned char[len];
X assert(data != 0);
X// memmove(data, dat, len);
X memcpy(data, dat, len);
X}
X
XSystemExclusiveEvent::SystemExclusiveEvent(const SystemExclusiveEvent &e) :
X Event(e), length(e.length), continued(e.continued)
X{
X
X data = new unsigned char[e.length];
X assert(data != 0);
X// memmove(data, e.data, e.length);
X memcpy(data, e.data, e.length);
X}
X
XSystemExclusiveEvent::~SystemExclusiveEvent()
X{
X
X delete data;
X}
X
Xvoid
XSystemExclusiveEvent::SetData(const unsigned char *dat, long len)
X{
X
X if (data != 0)
X delete data;
X data = new unsigned char[len];
X assert(data != 0);
X// memmove(data, dat, len);
X memcpy(data, dat, len);
X}
X
XSystemExclusiveEvent &
XSystemExclusiveEvent::operator=(const SystemExclusiveEvent &e)
X{
X
X (Event)*this = (Event)e;
X if (data != 0)
X delete data;
X data = new unsigned char[e.length];
X assert(data != 0);
X// memmove(data, e.data, e.length);
X memcpy(data, e.data, e.length);
X length = e.length;
X continued = e.continued;
X return (*this);
X}
X
Xchar *
XSystemExclusiveEvent::GetEventStr(void) const
X{
X ostrstream buf;
X long i;
X char *tbuf;
X
X tbuf = Event::GetEventStr();
X buf << tbuf << " Continued: " << (int)continued << " Data:";
X buf.setf(ios::showbase | ios::internal);
X for (i = 0; i < length; i++)
X buf << " " << hex << setw(4) << setfill('0') << (int)data[i];
X buf << ends;
X delete tbuf;
X return (buf.str());
X}
X
Xconst char *
XSystemExclusiveEvent::SMFRead(SMFTrack &t)
X{
X const unsigned char *ptr;
X
X if (data != 0)
X delete data;
X if ((length = t.GetVarValue()) == -1)
X return ("Incomplete SystemExclusiveEvent - bad length");
X data = new unsigned char[length];
X if (data == 0)
X return ("Out of memory");
X if ((ptr = t.GetData(length)) == 0)
X return ("Incomplete SystemExclusiveEvent");
X memcpy(data, ptr, length);
X return (0);
X}
X
Xconst char *
XSystemExclusiveEvent::SMFWrite(SMFTrack &t) const
X{
X
X if (!t.PutFixValue(length))
X return ("Out of memory");
X if (!t.PutData(data, length))
X return ("Out of memory");
X return (0);
X}
X
Xint
XSystemExclusiveEvent::Equal(const Event *e) const
X{
X long i;
X SystemExclusiveEvent *eptr = (SystemExclusiveEvent *)e;
X
X if (!Event::Equal(e))
X return (0);
X if (continued != eptr->continued)
X return (0);
X if (length != eptr->length)
X return (0);
X for (i = 0; i < length; i++)
X if (data[i] != eptr->data[i])
X return (0);
X return (1);
X}
X
Xostream &
Xoperator<<(ostream &os, const SystemExclusiveEvent &e)
X{
X char *str;
X
X os << (str = e.GetEventStr());
X delete str;
X return (os);
X}
END_OF_FILE
if test 4546 -ne `wc -c <'tclmidi-2.0/events/SystemExcl.C'`; then
echo shar: \"'tclmidi-2.0/events/SystemExcl.C'\" unpacked with wrong size!
fi
# end of 'tclmidi-2.0/events/SystemExcl.C'
fi
if test -f 'tclmidi-2.0/man/midievents.n' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'tclmidi-2.0/man/midievents.n'\"
else
echo shar: Extracting \"'tclmidi-2.0/man/midievents.n'\" \(4691 characters\)
sed "s/^X//" >'tclmidi-2.0/man/midievents.n' <<'END_OF_FILE'
X.Dd January 30, 1994
X.Dt MIDIEVENTS N
X.Os
X.Sh NAME
X.Nm midievents
X.Nd "the description tclmidi events"
X.Sh DESCRIPTION
XThe
X.Xr midiget n
Xand
X.Xr midiput n
Xcommands both use MIDI events in the same form.
XA
X.Xr tclmidi 1
Xevent consists of a list, where the first element
Xis the time at which the event occurs and the second
Xis the name of the event.
XThe list may contain other elements too, depending on
Xthe event type.
XThis is a list of all currently supported event types:
X.Bl -tag -width {time
X.It {time NoteOff channel pitch [velocity]}
XThe NoteOff event has three arguments: the first is the channel,
Xthe second the pitch, and the optional third is the velocity.
XIf a velocity is not specified, 0 is used.
X.It {time NoteOn channel pitch velocity}
XThe NoteOn event has three arguments: the first is the channel,
Xthe second the pitch and the third the velocity.
X.It {time Note channel pitch velocity duration}
XThe Note event is really a combination of the NoteOn and NoteOff
Xevents.
XIn fact, two events exist in the \%MIDI song with a link connecting
Xthem.
XThe Note event takes four arguments.
XThe first is the channel,
Xand the second is the pitch.
XThe third is the velocity of the NoteOn, and the fourth is
Xthe duration
Xuntil the corresponding NoteOff.
XThe implied NoteOff event assumes a velocity of zero.
X.It {time KeyPressure channel pitch value}
XThe KeyPressure event takes three arguments.
XThe first is the channel, the second the pitch and the third
Xthe pressure value.
X.It {time Parameter channel parameter value}
XThe Parameter event has three arguments.
XThe first is the channel, the second the parameter number and
Xthe third the associated value.
X.It {time Program channel value}
XThe Program event has two arguments.
XThis first is the channel and the second the program value.
X.It {time ChannelPressure channel value}
XThe ChannelPressure event has two arguments.
XThe first is the channel and the second the pressure associated
Xwith that channel.
X.It {time PitchWheel channel value}
XThe PitchWheel event has two arguments.
XThe first is the channel number and the second the pitch wheel
Xsetting.
X.It {time SystemExclusive {byte byte ...}}
XThe SystemExclusive event has one argument.
XIt is a list of data bytes to be sent as a system exclusive
Xevent.
X.It {time MetaSequenceNumber number}
XThe MetaSequenceNumber event has one argument.
XIt is the sequence number.
X.It {time MetaText text}
XThe MetaText event has one argument.
XIt is a text string.
X.It {time MetaCopyright copyright}
XThe MetaCopyright event has one argument.
XIt is a text string.
X.It {time MetaSequenceName name}
XThe MetaSequenceName event has one argument.
XIt is a text string.
X.It {time MetaInstrumentName name}
XThe MetaInstrumentName event has one argument.
XIt is a text string.
X.It {time MetaLyric lyric}
XThe MetaLyric event has one argument.
XIt is a text string.
X.It {time MetaMarker mark}
XThe MetaMarker event has one argument.
XIt is a text string.
X.It {time MetaCue cue}
XThe MetaCue event has one argument.
XIt is a text string.
X.It {time MetaChannelPrefix {byte byte ...}}
X.Xr tclmidi 1
Xdoes not know the proper form for a MetaChannelPrefix
Xevent, thus it has one argument.
XThis argument is a list of data bytes.
X.It {time MetaPortNumber port}
XThis event determines which port to use on a multiport
Xsystem.
XIt takes one argument, which is the port number.
X.It {time MetaEndOfTrack}
XThe MetaEndOfTrack event has no arguments.
X.It {time MetaTempo bpm}
XThe MetaTempo event has one argument.
XIt is the tempo specified in beats per minute.
X.It {time MetaSMPTE hour minute second frame fractional_frame}
XThe MetaSMPTE event has five arguments.
XThey are the hour, minute, second, frame and fractional frame.
X.It {time MetaTime numerator denominator clocks 32nds}
XThe MetaTime event has four arguments.
XThe first is the numerator of the time signature and the
Xsecond is the denominator.
XThe third argument is clock ticks per beat, and the fourth
Xis the number of 32nd notes per quarter note.
X.It {time MetaKey key major|minor}
XThe MetaKey event has two arguments.
XThe first is a text string describing the key and the
Xsecond is either
X.Dq major
Xor
X.Dq minor.
XThe key strings may be the key name, A - G, followed by
Xan optional ``flat'' or ``sharp.''
X.It {time MetaSequencerSpecific {byte byte ...}}
XThe MetaSequencerSpecific event has one argument.
XIt is a list of data bytes.
X.It {time MetaUnknown code {byte byte ...}}
XThe MetaUnknown event is for events not directly supported
Xby
X.Xr tclmidi 1 .
XIt has two arguments.
XThe first is the one byte code of the meta event, and
Xthe second is a list of the data bytes.
X.El
X.Sh SEE ALSO
X.Xr tclmidi 1 ,
X.Xr midiput n ,
X.Xr midiget n
X.Sh AUTHOR
XMike Durian - durian@boogie.com
END_OF_FILE
if test 4691 -ne `wc -c <'tclmidi-2.0/man/midievents.n'`; then
echo shar: \"'tclmidi-2.0/man/midievents.n'\" unpacked with wrong size!
fi
# end of 'tclmidi-2.0/man/midievents.n'
fi
if test -f 'tclmidi-2.0/rb/README' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'tclmidi-2.0/rb/README'\"
else
echo shar: Extracting \"'tclmidi-2.0/rb/README'\" \(4989 characters\)
sed "s/^X//" >'tclmidi-2.0/rb/README' <<'END_OF_FILE'
X1.1.1.1
X
XRb.c, Rb.h, List.h, and list.c are files for doing red-black trees and
Xdoubly linked lists, respectively.
X
XRb.h, Rb.c:
X
XRb.h contains the typedef for red-black tree structures. Basically,
Xred-black trees are balanced trees whose external nodes are sorted
Xby a key, and connected in a linked list. The following is how
Xyou use rb.c and rb.h:
X
XInclude rb.h in your source.
X
XMake_rb() returns the head of a red-black tree. It serves two functions:
XIts p.root pointer points to the root of the red-black tree. Its
Xc.list.flink and c.list.blink pointers point to the first and last
Xexternal nodes of the tree. When the tree is empty, all these pointers
Xpoint to itself.
X
XThe external nodes can be traversed in sorted order with their
Xc.list.flink and c.list.blink pointers. The macros rb_first, rb_last,
Xrb_next, rb_prev, and rb_traverse can be used to traverse external node lists.
X
XExternal nodes hold two pieces of information: the key and the value
X(in k.key and v.val, respectively). The key can be a character
Xstring, an integer, or a general pointer. Val is typed as a character
Xpointer, but can be any pointer. If the key is a character string,
Xthen one can insert it, and a value into a tree with rb_insert(). If
Xit is an integer, then rb_inserti() should be used. If it is a general
Xpointer, then rb_insertg() must be used, with a comparison function
Xpassed as the fourth argument. This function takes two keys as arguments,
Xand returns a negative value, positive value, or 0, depending on whether
Xthe first key is less than, greater than or equal to the second. Thus,
Xone could use rb_insertg(t, s, v, strcmp) to insert the value v with
Xa character string s into the tree t.
X
XRb_find_key(t, k) returns the external node in t whose value is equal
Xk or whose value is the smallest value greater than k. (Here, k is
Xa string). If there is no value greater than or equal to k, then
Xt is returned. Rb_find_ikey(t,k) works when k is an integer, and
XRb_find_gkey(t,k,cmp) works for general pointers.
X
XRb_find_key_n(t, k, n) is the same as rb_find_key, except that it
Xreturns whether or not k was found in n (n is an int *). Rb_find_ikey_n
Xand Rb_find_gkey_n are the analogous routines for integer and general
Xkeys.
X
XRb_insert_b(e, k, v) makes a new external node with key k and val v, and
Xinserts it before the external node e. If e is the head of a tree,
Xthen the new node is inserted at the end of the external node list.
XIf this insertion violates sorted order, no error is flagged. It is
Xassumed that the user knows what he/she is doing. Rb_insert_a(e,k,v)
Xinserts the new node after e (if e = t, it inserts the new node at the
Xbeginning of the list).
X
XRb_insert() is therefore really a combination of Rb_find_key() and
XRb_insert_b().
X
XRb_delete_node(e) deletes the external node e from a tree (and thus from
Xthe linked list of external nodes). The node is free'd as well, so
Xdon't retain pointers to it.
X
XRed-black trees are spiffy because find_key, insert, and delete are all
Xdone in log(n) time. Thus, they can be freely used instead of hash-tables,
Xwith the benifit of having the elements in sorted order at all times, and
Xwith the guarantee of operations being in log(n) time.
X
XOther routines:
X
XRb_print_tree() will grossly print out a red-black tree with string keys.
XRb_iprint_tree() will do the same with trees with integer keys.
XRb_nblack(e) will report the number of black nodes on the path from external
X node e to the root. The path length is less than twice this value.
XRb_plength(e) reports the length of the path from e to the root.
X
X
XList.c and list.h
X
XThese are routines for generic doubly linked lists. Doubly linked lists
Xare any structs whose first two fields are flink and blink pointers.
XMk_list(t) returns an empty list with the type t. The empty list is
Xa struct whose flink and blink point to itself. Insert() and delete_item()
Xinsert and delete nodes from a list -- unlike the rb routines, no allocation
Xis done here. In insert(), the node to be inserted is assumed to be allocated,
Xand in delete_item(), the deleted node is not free'd.
X
XGet_node() allocates a node from a node list. The head element in the linked
Xlist has info about how big of a node to allocate. Free_node() deallocates
Xa node. In actuality, free_node doesn't call free, but chains the node onto
Xa queue of nodes. That way, get_node first returns nodes from this queue,
Xand malloc need not be called. This is quite a possible memory leak. To
Xbe safe, you can malloc and free your own nodes, instead of calling get_node()
Xand free_node().
X
XList.c and list.h are kind of gross, and should be generally avoided because
Xof allocation problems. Try dlist.c & dlist.h for doubly linked lists which
Xare more like the red-black tree structs.
X
XIf you have any questions or comments about this, please let me know.
X
XTake it Easy,
X
XJim Plank
Xjsp@princeton.edu or
Xplank@cs.utk.edu
X
X35 Olden St
XPrinceton University
XPrinceton, NJ 80544-2087
END_OF_FILE
if test 4989 -ne `wc -c <'tclmidi-2.0/rb/README'`; then
echo shar: \"'tclmidi-2.0/rb/README'\" unpacked with wrong size!
fi
# end of 'tclmidi-2.0/rb/README'
fi
echo shar: End of archive 8 \(of 14\).
cp /dev/null ark8isdone
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...