Article View: net.micro.atari
Article #2023Re: ST timer tick? (includes FREE Midi Recorder program)
From: nigel
Date: Sun, 12 Jan 1986 15:04
Date: Sun, 12 Jan 1986 15:04
197 lines
4723 bytes
4723 bytes
In article <1241@gitpyr.UUCP> tynor@gitpyr.UUCP (Steve Tynor) writes:
>Can anyone tell me how I can get a simple timer tick on my ST? I need a
>high resolution timer so that I can record keystrokes off of MIDI for a
>simple sequencer I'm writing. However, I've looked through all the
>developer documentation and can't figure out how to do it... Do I have to
>write an interupt handler to count timer interupts? (ugh...) I can't believe
>it's as hard as that...
>
You're right - it's not difficult.
I have done this myself, so rather than just reply with the appropriate
routine, I draw attention to the routine hz200() in the following program.
It is a MIDI recorder - it listens to what is being played, can store it on
disk, and play it back. I hacked it together in an afternoon, so it's not
earth-shattering stuff. It only listens on one channel, and ignores all
but note information. It does preserve velocity information, and was tested
on a Yamaha DX7. If anyone does improve this, I would appreciate seeing the
source code.
PS - can anyone spot the deliberate mistake?
--------------------------------------------------------------------------
/* mr.c */
/* Nigel Roles 1986 */
#include "osbind.h"
#define MIDI 3
#define CON 2
#define GM (Bconin(MIDI)&0xff)
struct event {
int delay;
char cmd[3];
};
struct event *buffer;
int empty=1;
long bc;
long memsize;
long bmax;
long hz200()
{
register long save_ssp=Super(0L);
register long uhz200= *(long *)0x4ba;
Super(save_ssp);
return uhz200;
}
record()
{
register struct event *bp;
long now,then;
printf("Recording (any key to stop):\n");
while (Bconstat(MIDI))
Bconin(MIDI);
then=0;
bp=buffer;
bc=0;
for (;;) {
if (Bconstat(CON)) {
Bconin(CON);
bp->delay= -1;
bc++;
break;
}
if (Bconstat(MIDI)) {
int b=GM;
if (b==0xfe)
continue; /* Ignore active sensing */
if (b==0x90) {
now=hz200();
if (then==0)
bp->delay=0;
else
bp->delay=now-then;
then=now;
bp->cmd[0]=b;
bp->cmd[1]=GM;
bp++->cmd[2]=GM;
if (++bc==bmax) {
printf("Buffer full\n");
break;
}
}
}
}
}
play()
{
register struct event *bp=buffer;
long target;
printf("Playing:\n");
while (bp->delay!= -1) {
if (Bconstat(CON)) {
Bconin(CON);
break;
}
target=hz200()+bp->delay;
while (hz200()<target) ;
Midiws(2,bp->cmd);
bp++;
}
}
#define FNSIZE 20
struct filename {
char lin,lout;
char name[FNSIZE+1];
} fn;
int h;
getfn()
{
printf("Filename: ");
fn.lin=FNSIZE;
Cconrs((char *)&fn);
printf("\n");
fn.name[fn.lout]='\0';
}
load()
{
getfn();
if ((h=Fopen(fn.name,0))<0) {
printf("Can't open %s for reading (error %d)\n",fn.name,h);
return;
}
if (Fread(h,memsize,buffer)<0)
printf("Read error\n");
else
empty=0;
Fclose(h);
}
save()
{
getfn();
Fdelete(fn.name);
if ((h=Fcreate(fn.name,0))<0) {
printf("Can't create %s (error %d)\n",fn.name,h);
return;
}
if (Fwrite(h,sizeof(struct event)*(long)bc,buffer)<0)
printf("Write error\n");
Fclose(h);
}
main()
{
char c;
char *malloc();
memsize=(long)malloc(-1L);
if ((buffer=(struct event *)malloc(memsize))==(struct event *)0L) {
printf("malloc failure\n");
exit(1);
}
bmax=memsize/sizeof(struct event);
printf("\033EMidi Recorder Version 1.0 (definitely)\n");
printf("(C) N. G. Roles 1985\n\n");
printf("Capacity: %D events\n",bmax);
for (;;) {
printf("MR> ");
c=Bconin(CON);
printf("%c\n",c);
switch (c) {
case 'q':
break;
case 'r':
record();
continue;
case 'p':
if (empty)
printf("Nothing to play!\n");
else
play();
continue;
case 's':
if (empty)
printf("Nothing to save!\n");
else
save();
continue;
case 'l':
load();
continue;
default:
printf("???\n");
continue;
}
break;
}
}
Technical Details
Message-ID:
<651@minster.UUCP>Path:
arc1-ca.pugleaf.net!utzoo!watmath!clyde!burl!ulysses!gamma!epsilon!zeta!sabre!petrus!bellcore!decvax!genrad!panda!talcott!harvard!seismo!mcvax!ukc!reading!minster!nigelReferences:
<1241@gitpyr.UUCP>Show Full Headers
Complete Article Headers
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10 5/3/83; site minster.UUCP Path: arc1-ca.pugleaf.net!utzoo!watmath!clyde!burl!ulysses!gamma!epsilon!zeta!sabre!petrus!bellcore!decvax!genrad!panda!talcott!harvard!seismo!mcvax!ukc!reading!minster!nigel From: nigel@minster.UUCP (nigel) Newsgroups: net.micro.atari Subject: Re: ST timer tick? (includes FREE Midi Recorder program) Message-ID: <651@minster.UUCP> Date: Sun, 12-Jan-86 10:04:18 EST Article-I.D.: minster.651 Posted: Sun Jan 12 10:04:18 1986 Date-Received: Tue, 14-Jan-86 06:16:03 EST References: <1241@gitpyr.UUCP> Reply-To: nigel@minster.UUCP (nigel) Organization: University of York, England Lines: 197 Xpath: ukc eagle