home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.lang.tcl
- Path: sparky!uunet!paladin.american.edu!howland.reston.ans.net!zaphod.mps.ohio-state.edu!magnus.acs.ohio-state.edu!usenet.ins.cwru.edu!agate!boulder!csn!cherokee!durian
- From: durian@advtech.uswest.com (Mike Durian)
- Subject: tclm0.1 - tcl with MIDI extensions (6/7)
- Message-ID: <1993Jan12.203053.20069@advtech.uswest.com>
- Sender: news@advtech.uswest.com (Radio Free Boulder)
- Nntp-Posting-Host: mongo.advtech.uswest.com
- Organization: U S WEST Advanced Technologies
- Date: Tue, 12 Jan 1993 20:30:53 GMT
- Lines: 946
-
- # This is a shell archive. Save it in a file, remove anything before
- # this line, and then unpack it by entering "sh file". Note, it may
- # create directories; files and directories will be owned by you and
- # have default permissions.
- #
- # This archive contains:
- #
- # tclm0.1/mlib/Makefile
- # tclm0.1/mlib/mfileutil.c
- # tclm0.1/mplay
- #
- echo x - tclm0.1/mlib/Makefile
- sed 's/^X//' >tclm0.1/mlib/Makefile << 'END-of-tclm0.1/mlib/Makefile'
- X# add -DMPU to defines if you wish to compile in the ability to
- X# play standard MIDI files. This will only work on BSD/386
- X# (BSDI) machines equipped with a MPU401 compatible MIDI card.
- X# DEFS =
- XDEFS = -DMPU
- X
- X# set RANLIB to ranlib if your system has it - otherwise set it to
- X# true
- X# RANLIB = true
- XRANLIB = ranlib
- X
- XSRCS=mfileutil.c mplayutil.c mpu401.c
- XOBJS=mfileutil.o mplayutil.o mpu401.o
- XAR=libmutil.a
- X
- XCFLAGS= $(DEFS) -O -I.
- XCC=cc
- X
- Xall: $(AR)
- X
- X$(AR): $(OBJS)
- X rm -f $(AR)
- X ar cr $(AR) $(OBJS)
- X $(RANLIB) $(AR)
- X
- Xclean:
- X rm -f $(AR) $(OBJS)
- Xlint:
- X lint $(SRCS) > lint.out >&1
- END-of-tclm0.1/mlib/Makefile
- echo x - tclm0.1/mlib/mfileutil.c
- sed 's/^X//' >tclm0.1/mlib/mfileutil.c << 'END-of-tclm0.1/mlib/mfileutil.c'
- X/* mfileutil.c,v 1.3 1993/01/12 19:23:38 durian Exp */
- X/*
- X * Copyright (c) 1993 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 <stdio.h>
- X#include <stdlib.h>
- X#include <unistd.h>
- X#include <string.h>
- X#include <sys/fcntl.h>
- X#include "mutil.h"
- X
- X/* hack so we know if a read failed because of an eof instead of bad data */
- Xint MidiEof = 0;
- Xchar MidiError[256];
- X
- Xint
- Xread_header_chunk(mfile, hchunk)
- X int mfile;
- X HCHUNK *hchunk;
- X{
- X
- X if (mread(mfile, hchunk->str, sizeof(hchunk->str)) !=
- X sizeof(hchunk->str)) {
- X if (!MidiEof)
- X sprintf(MidiError,
- X "Couldn't read header chunk identifier");
- X return (0);
- X }
- X
- X if (mread(mfile, (char *)&hchunk->length, sizeof(hchunk->length)) !=
- X sizeof(hchunk->length)) {
- X sprintf(MidiError, "Couldn't read header chunk length");
- X return (0);
- X }
- X
- X if (mread(mfile, (char *)&hchunk->format, sizeof(hchunk->format)) !=
- X sizeof(hchunk->format)) {
- X sprintf(MidiError, "Couldn't read header chunk format");
- X return (0);
- X }
- X
- X if (mread(mfile, (char *)&hchunk->num_trks, sizeof(hchunk->num_trks))
- X != sizeof(hchunk->num_trks)) {
- X sprintf(MidiError, "Couldn't read header chunk num_trks");
- X return (0);
- X }
- X
- X if (mread(mfile, (char *)&hchunk->division, sizeof(hchunk->division))
- X != sizeof(hchunk->division)) {
- X sprintf(MidiError, "Couldn't read header chunk division");
- X return (0);
- X }
- X
- X /* fix byte ordering */
- X hchunk->length = mtohl(hchunk->length);
- X hchunk->format = mtohs(hchunk->format);
- X hchunk->num_trks = mtohs(hchunk->num_trks);
- X hchunk->division = mtohs(hchunk->division);
- X
- X if (strncmp(hchunk->str, "MThd", 4) != 0) {
- X sprintf(MidiError, "Not a standard MIDI file");
- X return (0);
- X }
- X
- X if (hchunk->length != 6) {
- X sprintf(MidiError, "Bad header chunk size");
- X return (0);
- X }
- X
- X if (hchunk->format == 0 && hchunk->num_trks != 1) {
- X sprintf(MidiError,
- X "Midi format 0, but number of tracks (%d) is > 1",
- X hchunk->num_trks);
- X return (0);
- X }
- X
- X return (1);
- X}
- X
- Xint
- Xread_track_chunk(mfile, tracks)
- X int mfile;
- X TCHUNK *tracks;
- X{
- X
- X if (mread(mfile, tracks->str, 4) != 4) {
- X sprintf(MidiError, "Couldn't read track chunk identifier");
- X return (0);
- X }
- X
- X if (strncmp(tracks->str, "MTrk", 4) != 0) {
- X sprintf(MidiError, "Bad track chunk identifier");
- X return (0);
- X }
- X
- X if (mread(mfile, (char *)&tracks->length, sizeof(tracks->length)) !=
- X sizeof(tracks->length)) {
- X sprintf(MidiError, "Couldn't read track length");
- X return (0);
- X }
- X
- X tracks->msize = tracks->length = mtohl(tracks->length);
- X tracks->pos = 0;
- X
- X /* allocate space for tracks events */
- X if ((tracks->events = (unsigned char *) malloc(tracks->length)) ==
- X NULL) {
- X sprintf(MidiError, "Not enough memory for track data");
- X return (0);
- X }
- X tracks->event_start = tracks->events;
- X
- X if (mread(mfile, (char *)tracks->events, tracks->length) !=
- X tracks->length) {
- X sprintf(MidiError, "Couldn't read track data");
- X return (0);
- X }
- X tracks->events = tracks->event_start;
- X
- X return (1);
- X}
- X
- Xint
- Xskip_track_chunk(mfile)
- X int mfile;
- X{
- X long length;
- X char str[4];
- X
- X if (mread(mfile, str, sizeof(str)) != sizeof(str)) {
- X sprintf(MidiError, "Couldn't read track chunk identifier");
- X return (0);
- X }
- X
- X if (strncmp(str, "MTrk", 4) != 0) {
- X sprintf(MidiError, "Bad track chunk identifier");
- X return (0);
- X }
- X
- X if (mread(mfile, (char *)&length, sizeof(length)) != sizeof(length)) {
- X sprintf(MidiError, "Couldn't read track length");
- X return (0);
- X }
- X
- X length = mtohl(length);
- X
- X if (lseek(mfile, length, SEEK_CUR) == -1) {
- X sprintf(MidiError, "Couldn't seek past track");
- X return (0);
- X }
- X
- X return (1);
- X}
- X
- Xint
- Xsplit_type_zero(tracks)
- X TCHUNK *tracks;
- X{
- X long tempo_delta;
- X long data_delta;
- X long timing;
- X EVENT_TYPE event_type;
- X int data_size;
- X int event_size;
- X int i;
- X int offset;
- X int malloced_data;
- X int malloced_tempo;
- X int malloc_inc;
- X int tempo_size;
- X int time_len;
- X unsigned char event[256];
- X unsigned char *data_events;
- X unsigned char *data_ptr;
- X unsigned char *last_events;
- X unsigned char *tempo_events;
- X unsigned char *tempo_ptr;
- X unsigned char var_time[4];
- X
- X data_size = 0;
- X tempo_size = 0;
- X tempo_delta = 0;
- X data_delta = 0;
- X malloc_inc = 512;
- X
- X if ((data_events = (unsigned char *) malloc(malloc_inc))
- X == NULL) {
- X sprintf(MidiError, "Not enought memory to split track");
- X return (0);
- X }
- X malloced_data = malloc_inc;
- X if ((tempo_events = (unsigned char *) malloc(malloc_inc))
- X == NULL) {
- X sprintf(MidiError, "Not enought memory to split track");
- X return (0);
- X }
- X malloced_tempo = malloc_inc;
- X
- X data_ptr = data_events;
- X tempo_ptr = tempo_events;
- X while (event_size = get_smf_event(&tracks[0], event, &event_type)) {
- X if (event_size == -1) {
- X sprintf(MidiError,
- X "Problem getting event while splitting");
- X return (0);
- X }
- X
- X if (event_type == NORMAL || event_type == SYSEX) {
- X timing = var2fix(event, &offset);
- X data_delta += timing;
- X time_len = fix2var(data_delta, var_time);
- X data_size += event_size - offset + time_len;
- X if (data_size > malloced_data) {
- X last_events = data_events;
- X if (!more_memory((char **)&data_events,
- X malloced_data + malloc_inc)) {
- X sprintf(MidiError,
- X "Not enough memory");
- X return (0);
- X }
- X if (data_events != last_events)
- X data_ptr = data_events + (data_ptr -
- X last_events);
- X }
- X /* copy in timing */
- X for (i = 0; i < time_len; i++)
- X *data_ptr++ = var_time[i];
- X
- X /* copy in data */
- X for (i = offset; i < event_size; i++)
- X *data_ptr++ = event[i];
- X
- X /* add timing to tempo delta */
- X tempo_delta += timing;
- X data_delta = 0;
- X } else {
- X timing = var2fix(event, &offset);
- X tempo_delta += timing;
- X time_len = fix2var(tempo_delta, var_time);
- X tempo_size += event_size - offset + time_len;
- X if (tempo_size > malloced_tempo) {
- X last_events = tempo_events;
- X if (!more_memory((char **)&tempo_events,
- X malloced_tempo + malloc_inc)) {
- X sprintf(MidiError,
- X "Not enough memory");
- X return (0);
- X }
- X if (tempo_events != last_events)
- X tempo_ptr = data_events + (tempo_ptr -
- X last_events);
- X }
- X /* copy in timing */
- X for (i = 0; i < time_len; i++)
- X *tempo_ptr++ = var_time[i];
- X
- X /* copy in data */
- X for (i = offset; i < event_size; i++)
- X *tempo_ptr++ = event[i];
- X
- X /* add timing to tempo delta */
- X data_delta += timing;
- X tempo_delta = 0;
- X }
- X }
- X
- X /* add eot to tempo track */
- X event[0] = 0xff;
- X event[1] = METAEOT;
- X event[2] = 0;
- X event_size = 3;
- X
- X time_len = fix2var(tempo_delta, var_time);
- X tempo_size += event_size + time_len;
- X if (tempo_size > malloced_tempo) {
- X last_events = tempo_events;
- X if (!more_memory((char **)&tempo_events, malloced_tempo +
- X malloc_inc)) {
- X sprintf(MidiError, "Not enough memory");
- X return (0);
- X }
- X if (tempo_events != last_events)
- X tempo_ptr = data_events + (tempo_ptr - last_events);
- X }
- X /* copy in timing */
- X for (i = 0; i < time_len; i++)
- X *tempo_ptr++ = var_time[i];
- X
- X /* copy in data */
- X for (i = 0; i < event_size; i++)
- X *tempo_ptr++ = event[i];
- X
- X free(tracks[0].events);
- X tracks[0].events = tracks[0].event_start = tempo_events;
- X tracks[1].events = tracks[1].event_start = data_events;
- X tracks[0].msize = malloced_tempo;
- X tracks[1].msize = malloced_data;
- X tracks[0].length = tempo_size;
- X tracks[1].length = data_size;
- X tracks[0].pos = 0;
- X tracks[1].pos = 0;
- X (void) strncpy(tracks[0].str, "MTrk", 4);
- X (void) strncpy(tracks[1].str, "MTrk", 4);
- X return (1);
- X}
- X
- Xint
- Xmore_memory(ptr, size)
- X char **ptr;
- X int size;
- X{
- X
- X if ((*ptr = realloc(*ptr, size)) == NULL)
- X return (0);
- X else
- X return (1);
- X}
- X
- Xint
- Xget_smf_event(track, event, event_type)
- X TCHUNK *track;
- X unsigned char *event;
- X EVENT_TYPE *event_type;
- X{
- X long length = 0;
- X int i;
- X int size;
- X static int extra_bytes[] = {2, 2, 2, 2, 1, 1, 2, 0};
- X unsigned char etype;
- X static unsigned char r_state;
- X
- X if (track->pos >= track->length)
- X return (0);
- X
- X /*
- X * get timing bytes
- X */
- X if (track->pos++ == track->length)
- X return (-1);
- X *event++ = *track->events++;
- X size = 1;
- X while (*(event - 1) & 0x80) {
- X if (track->pos++ == track->length)
- X return (-1);
- X *event++ = *track->events++;
- X size++;
- X }
- X
- X if (track->pos++ == track->length)
- X return (-1);
- X *event = *track->events++;
- X
- X /* get event type */
- X switch (*event) {
- X case 0xff:
- X /* meta event */
- X if (track->pos++ == track->length)
- X return (-1);
- X size++;
- X event++;
- X *event_type = *event++ = *track->events++;
- X size++;
- X /* get length as a variable length */
- X do {
- X if (track->pos++ == track->length)
- X return (-1);
- X length = (length << 7) + (*track->events & 0x7f);
- X *event = *track->events++;
- X size++;
- X } while (*event++ & 0x80);
- X for (; length > 0; length--) {
- X /* get event */
- X if (track->pos++ == track->length)
- X return (-1);
- X *event++ = *track->events++;
- X size++;
- X }
- X break;
- X case 0xf0:
- X case 0xf7:
- X event++;
- X size++;
- X *event_type = SYSEX;
- X do {
- X if (track->pos++ == track->length)
- X return (-1);
- X *event = *track->events++;
- X size++;
- X } while (*event++ != 0xf7);
- X break;
- X default:
- X *event_type = NORMAL;
- X size++;
- X if (*event & 0x80) {
- X etype = *event;
- X r_state = (*event >> 4) & 0x0f;
- X for (i = 0; i < extra_bytes[(etype >> 4) & 0x07];
- X i++) {
- X event++;
- X if (track->pos++ == track->length)
- X return(-1);
- X *event = *track->events++;
- X size++;
- X }
- X } else {
- X /* assume it is a continuation of note on */
- X /* get other data byte */
- X switch (r_state) {
- X case 0x08:
- X case 0x09:
- X case 0x0a:
- X case 0x0b:
- X case 0x0e:
- X event++;
- X if (track->pos++ == track->length)
- X return (-1);
- X *event = *track->events++;
- X size++;
- X break;
- X default:
- X break;
- X }
- X }
- X }
- X return (size);
- X}
- X
- Xint
- Xput_smf_event(track, event, event_size)
- X TCHUNK *track;
- X unsigned char *event;
- X int event_size;
- X{
- X
- X if (track->msize == 0) {
- X if ((track->event_start = (unsigned char *)malloc(
- X BUFSIZ)) == NULL) {
- X sprintf(MidiError, "Not enough memory for new event");
- X return (0);
- X }
- X track->msize = BUFSIZ;
- X track->events = track->event_start;
- X }
- X track->length += event_size;
- X if (track->pos + event_size > track->msize) {
- X track->msize += BUFSIZ;
- X if ((track->event_start =
- X (unsigned char *)realloc(track->event_start, track->msize))
- X == NULL) {
- X perror("");
- X sprintf(MidiError, "Not enough memory for new event");
- X track->length -= event_size;
- X track->msize -= BUFSIZ;
- X return (0);
- X }
- X /* starting position might move */
- X track->events = track->event_start + track->pos;
- X }
- X
- X memcpy(track->events, event, event_size);
- X track->events += event_size;
- X track->pos += event_size;
- X return (1);
- X}
- X
- Xvoid
- Xrewind_track(track)
- X TCHUNK *track;
- X{
- X track->pos = 0;
- X track->events = track->event_start;
- X}
- X
- Xvoid
- Xreset_track(track)
- X TCHUNK *track;
- X{
- X track->pos = 0;
- X track->length = 0;
- X track->events = track->event_start;
- X}
- X
- X
- Xint
- Xwrite_header_chunk(mfile, hchunk)
- X int mfile;
- X HCHUNK *hchunk;
- X{
- X
- X (void)strncpy(hchunk->str, "MThd", 4);
- X if (mwrite(mfile, hchunk->str, 4) != 4) {
- X sprintf(MidiError, "Couldn't write header chunk identifier");
- X return (0);
- X }
- X
- X hchunk->length = 6;
- X hchunk->length = htoml(hchunk->length);
- X if (mwrite(mfile, (char *)&hchunk->length, sizeof(hchunk->length)) !=
- X sizeof(hchunk->length)) {
- X sprintf(MidiError, "Couldn't write header chunk length");
- X return (0);
- X }
- X hchunk->length = mtohl(hchunk->length);
- X
- X hchunk->format = htoms(hchunk->format);
- X if (mwrite(mfile, (char *)&hchunk->format, sizeof(hchunk->format)) !=
- X sizeof(hchunk->format)) {
- X sprintf(MidiError, "Couldn't write header chunk format");
- X return (0);
- X }
- X hchunk->format = mtohs(hchunk->format);
- X
- X hchunk->num_trks = htoms(hchunk->num_trks);
- X if (mwrite(mfile, (char *)&hchunk->num_trks, sizeof(hchunk->num_trks))
- X != sizeof(hchunk->num_trks)) {
- X sprintf(MidiError, "Couldn't write number of tracks");
- X return (0);
- X }
- X hchunk->num_trks = mtohs(hchunk->num_trks);
- X
- X hchunk->division = htoms(hchunk->division);
- X if (mwrite(mfile, (char *)&hchunk->division, sizeof(hchunk->division))
- X != sizeof(hchunk->division)) {
- X sprintf(MidiError, "Couldn't write header chunk division");
- X return (0);
- X }
- X hchunk->division = mtohs(hchunk->division);
- X
- X return (1);
- X}
- X
- Xint
- Xwrite_track_chunk(mfile, tchunk)
- X int mfile;
- X TCHUNK *tchunk;
- X{
- X long midi_length;
- X
- X (void)strncpy(tchunk->str, "MTrk", 4);
- X if (mwrite(mfile, tchunk->str, 4) != 4) {
- X sprintf(MidiError, "Couldn't write track chunk identifier");
- X return (0);
- X }
- X
- X midi_length = htoml(tchunk->length);
- X if (mwrite(mfile, (char *)&midi_length, sizeof(midi_length)) !=
- X sizeof(midi_length)) {
- X sprintf(MidiError, "Couldn't write track length");
- X return (0);
- X }
- X
- X if (mwrite(mfile, (char *)tchunk->event_start, tchunk->length)
- X != tchunk->length) {
- X sprintf(MidiError, "Couldn't write track events");
- X return (0);
- X }
- X
- X return (1);
- X}
- X
- Xint
- Xload_tracks(mfile, hchunk, tracks_ptr, spec_tracks)
- X int mfile;
- X HCHUNK *hchunk;
- X TCHUNK **tracks_ptr;
- X TRKS *spec_tracks;
- X{
- X TCHUNK *tracks;
- X int i;
- X int cur_track;
- X
- X if (hchunk->format == 0) {
- X if (spec_tracks->num_tracks) {
- X sprintf(MidiError,
- X "Specified tracks are ignored on file type 0");
- X }
- X
- X if ((tracks = (TCHUNK *) malloc(sizeof(TCHUNK) * 2)) == NULL) {
- X sprintf(MidiError, "No memory available for tracks");
- X return (0);
- X }
- X
- X if (!read_track_chunk(mfile, &tracks[0])) {
- X sprintf(MidiError, "Couldn't read track 0");
- X return (0);
- X }
- X
- X if (!split_type_zero(tracks)) {
- X sprintf(MidiError, "Couldn't split MIDI file type 0");
- X return (0);
- X }
- X
- X *tracks_ptr = tracks;
- X
- X return (2);
- X }
- X
- X if (spec_tracks->num_tracks == 0) {
- X for (i = 0; i < hchunk->num_trks; i++)
- X spec_tracks->tracks[i] = i;
- X spec_tracks->num_tracks = hchunk->num_trks;
- X }
- X
- X if ((tracks = (TCHUNK *) malloc(sizeof(TCHUNK) *
- X spec_tracks->num_tracks)) == NULL) {
- X sprintf(MidiError, "No memory available for tracks");
- X return (0);
- X }
- X
- X cur_track = 0;
- X /* read in tracks */
- X for (i = 0; i <= spec_tracks->tracks[spec_tracks->num_tracks - 1];
- X i++) {
- X if (i == spec_tracks->tracks[cur_track]) {
- X /* read track chunk */
- X if (!read_track_chunk(mfile, &tracks[cur_track++])) {
- X sprintf(MidiError, "Couldn't read track %d",
- X i);
- X return (0);
- X }
- X } else {
- X if (!skip_track_chunk(mfile)) {
- X sprintf(MidiError,
- X "Couldn't skip track chunk %d", i);
- X return (0);
- X }
- X }
- X }
- X
- X *tracks_ptr = tracks;
- X return (spec_tracks->num_tracks);
- X}
- X
- Xint
- Xfix2var(val, ptr)
- X long val;
- X unsigned char *ptr;
- X{
- X int i;
- X unsigned char buf[4];
- X unsigned char *bptr;
- X
- X buf[0] = buf[1] = buf[2] = buf[3] = 0;
- X bptr = buf;
- X *bptr++ = val & 0x7f;
- X while ((val >>= 7) > 0) {
- X *bptr |= 0x80;
- X *bptr++ += (val & 0x7f);
- X }
- X
- X i = 0;
- X do {
- X *ptr++ = *--bptr;
- X i++;
- X } while (bptr != buf);
- X
- X return (i);
- X}
- X
- Xlong
- Xvar2fix(var, delta)
- X unsigned char *var;
- X int *delta;
- X{
- X long fix;
- X
- X fix = 0;
- X *delta = 0;
- X if (*var & 0x80)
- X do {
- X fix = (fix << 7) + (*var & 0x7f);
- X (*delta)++;
- X } while (*var++ & 0x80);
- X else {
- X fix = *var++;
- X (*delta)++;
- X }
- X
- X return (fix);
- X}
- X
- Xvoid
- Xfree_track(track)
- X TCHUNK *track;
- X{
- X
- X if (track->event_start != NULL)
- X free(track->event_start);
- X track->event_start = NULL;
- X track->events = NULL;
- X track->length = 0;
- X track->pos = 0;
- X track->msize = 0;
- X}
- X
- Xint
- Xmread(dev, buf, size)
- X int dev;
- X char *buf;
- X int size;
- X{
- X int num_read;
- X int total_read;
- X
- X total_read = 0;
- X do {
- X if ((num_read = read(dev, buf, size - total_read)) == -1) {
- X perror("");
- X return (-1);
- X }
- X if (num_read == 0)
- X break;
- X total_read += num_read;
- X buf += num_read;
- X } while (size > total_read);
- X if (total_read == 0)
- X MidiEof = 1;
- X return (total_read);
- X}
- X
- Xint
- Xmwrite(dev, buf, size)
- X int dev;
- X char *buf;
- X int size;
- X{
- X int num_written;
- X int total_written;
- X
- X total_written = 0;
- X do {
- X if ((num_written = write(dev, buf, size - total_written))
- X == -1) {
- X perror("");
- X return (-1);
- X }
- X if (num_written == 0)
- X break;
- X total_written += num_written;
- X buf += num_written;
- X } while (size > total_written);
- X return (total_written);
- X}
- END-of-tclm0.1/mlib/mfileutil.c
- echo x - tclm0.1/mplay
- sed 's/^X//' >tclm0.1/mplay << 'END-of-tclm0.1/mplay'
- X#!/usr/local/bin/tclm -f
- X#
- X# Copyright (c) 1993 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
- Xif {! [midimpu]} {
- X puts stderr [concat "Cannot play. Tclm was not compiled with the " \
- X "MPU functionality turned on."]
- X exit 1
- X}
- X
- Xset repeat 0
- Xset tracks {}
- Xset speed 1.0
- Xset filenames {}
- X
- Xproc parse_arg {args} {
- X global repeat
- X global tracks
- X global speed
- X global filenames
- X
- X # strip away extra {}'s
- X set args [lindex $args 0]
- X set num_args [llength $args]
- X if {$num_args > 1 && [string compare [lindex $args 0] "-f"] == 0} {
- X set i 2
- X } else {
- X set i 0
- X }
- X for {} {$i < $num_args} {incr i} {
- X
- X set arg [lindex $args $i]
- X case $arg in \
- X -r {
- X set repeat 1
- X } -t {
- X set tracks [lindex $args [incr i]]
- X } -s {
- X set speed [lindex $args [incr i]]
- X } default {
- X lappend filenames $arg
- X }
- X }
- X}
- X
- Xparse_arg $argv
- X
- X#set midi_file_name /u/durian/midi/songs/chorale.mid
- X
- Xif {$repeat} {
- X set repeat repeat
- X} else {
- X set repeat ""
- X}
- X
- Xif {[llength $tracks] != 0} {
- X set tracks "tracks \"$tracks\""
- X} else {
- X set tracks ""
- X}
- X
- Xif {$speed != 1.0} {
- X set speed "reltempo $speed"
- X} else {
- X set speed ""
- X}
- X
- Xif {[llength $filenames] == 0} {
- X set midi_file stdin
- X set done 0
- X while {1} {
- X if {[catch {midiread $midi_file} mfile]} {
- X if {[string compare "$mfile" "EOF"] == 0} {
- X exit 0
- X } else {
- X puts stderr $mfile
- X exit 1
- X }
- X }
- X eval "midiplay $repeat $tracks $speed $mfile"
- X midifree $mfile
- X }
- X} else {
- X foreach file $filenames {
- X if {[catch {open $file} midi_file]} {
- X puts stderr $midi_file
- X exit 1
- X }
- X if {[catch {midiread $midi_file} mfile]} {
- X puts stderr $mfile
- X exit 1
- X }
- X eval "midiplay $repeat $tracks $speed $mfile"
- X midifree $mfile
- X close $midi_file
- X }
- X}
- END-of-tclm0.1/mplay
- exit
-
-