[comp.sys.amiga] <scream of agony>

peter@sugar.UUCP (08/28/87)

As the originator of the latest MIDI thread, I'd like to say one thing...

In article <3826@well.UUCP>, ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) writes:
                                                   ^^^^^^^^^^
						What does this mean?

> 	As I understand it, all you need to do MIDI is a serial port that
> will run fast enough, and some level conversion hadrware.  This pretty much
> inidcates to me that *ANY* computer can do MIDI, from a Timex-Sinclair to a
> Cray 2.  What really counts is the MIDI control software running on the
> computer in question.

You also need accurate timing. I have been informed that the Amiga does
not produce accurate enough timing for professional musicians. I am still
trying to determine if this is because:

	a) You can still lose timing despite following the rules in
	   the RKM/Libraries.

	b) The authors of SoundScape, etc, don't follow the rules.

	c) Something else.

Do you know, Leo?

If you don't, could you let someone who does know explain what is going on.

I'd also like to make a wish. Attention Commodore-Amiga:

	In 1.3, could you please add a mode to timer.device
	whereby I get periodic signals, and can take the rather
	complex procedure described in the RKM for keeping time
	events synched down the toilet?
-- 
-- Peter da Silva `-_-' ...!seismo!soma!uhnix1!sugar!peter
--                  U   <--- not a copyrighted cartoon :->

andy@cbmvax.UUCP (09/01/87)

In article <586@sugar.UUCP> peter@sugar.UUCP (Peter da Silva) writes:
>As the originator of the latest MIDI thread, I'd like to say one thing...
>You also need accurate timing. I have been informed that the Amiga does
>not produce accurate enough timing for professional musicians. I am still
>trying to determine if this is because:
>
>	a) You can still lose timing despite following the rules in
>	   the RKM/Libraries.
>
>	b) The authors of SoundScape, etc, don't follow the rules.
>
>	c) Something else.

All that is needed is a midi.device version of the serial.device
that timestamps the midi events, so that, even if you have to
go away for awhile (because another task would like a bit of time)
you can tell exactly when the event happened.

(occasionally you find musicians complaining about the time intervals
 that a given program lets them use, but that's another story entirely.
 In that case, you just have to point out that program X is placing
 the limit on them, not the Amiga.  No matter what the seller of
 program X says :-)  )

>I'd also like to make a wish. Attention Commodore-Amiga:
>
>	In 1.3, could you please add a mode to timer.device
>	whereby I get periodic signals, and can take the rather
>	complex procedure described in the RKM for keeping time
>	events synched down the toilet?

Timer.device use is *not* complicated.  In fact, its no more complicated
that if I added a mode for repeated events.  But I'd heard this
complaint enough so here's a simple example of using the timer.device
to get a tick every 300 microseconds or so.  Its pretty short...
(Example compiled under Greenhills; your compiler may vary a little)
		

---------------------- CUT HERE ------------------------------------
#include "exec/types.h"
#include "intuition/intuition.h"

struct IntuitionBase *IntuitionBase=NULL;
struct GfxBase *GfxBase=NULL;
struct NewWindow nw = {
    100, 10,
    300,40,
    -1, -1,
    CLOSEWINDOW,
    SMART_REFRESH | NOCAREREFRESH | WINDOWCLOSE,
    NULL,
    NULL,
    "Timer Example", 
    NULL, 
    NULL, 
    10, 10, ~0, ~0,
    WBENCHSCREEN};
    
    
struct Window *window=NULL;
struct MsgPort *timerport=NULL;
struct IOStdReq *timermsg=NULL;
ULONG timerbit=NULL;
UBYTE buffer[80];
struct IntuiText text = {0,1,JAM2,0,0,NULL,buffer,NULL};

SetTimer(sec, micro, timermsg)
ULONG sec, micro;
struct IOStdReq *timermsg;
/* This routine simply sets the timer to interrupt us after secs.micros */
{
    timermsg->io_Command = TR_ADDREQUEST;    /* add a new timer request */
    timermsg->io_Actual = sec;    /* seconds */
    timermsg->io_Length = micro;    /* microseconds */
    SendIO(timermsg);	/* post a request to the timer */
}


main()
{
    ULONG wakeupbits, windowbit;
    struct IntuiMessage *message;
    ULONG class;
    USHORT code;
    int i;

    if(!(IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",0)
	))cleanup(20);

    if ((window = (struct Window *)OpenWindow(&nw)) == NULL)
	cleanup(20);

    if(!(timerport = (struct MsgPort *)CreatePort(0, 0)))cleanup(20);
    if(!(timermsg = (struct IOStdReq *)CreateStdIO(timerport)))cleanup(20);
    if (OpenDevice(TIMERNAME, UNIT_VBLANK, timermsg, 0))cleanup(20);
    
    timerbit = 1 << timerport->mp_SigBit;
    windowbit = 1 << window->UserPort->mp_SigBit;
    SetTimer(0, 300, timermsg); /* set for first message */

    while (TRUE) {
	wakeupbits = Wait(timerbit | windowbit);

	if (wakeupbits & timerbit) {
	    GetMsg(timerport);	/* this does nothing more than "clear" */
	    SetTimer(0, 300, timermsg);
	    sprintf(buffer,"timer tick %8ld received\0",i++);
	    PrintIText(window->RPort,&text,10,25);
	    }

	if (wakeupbits & windowbit) {
	    message = (struct IntuiMessage *)GetMsg(window->UserPort);
	    class = message->Class;
	    code = message->Code;
	    ReplyMsg(message);
	    switch (class) {
		case CLOSEWINDOW:
		    cleanup(0);
		    break;
	    }
	}
    }
}

cleanup(err)
int err;
{
    if (window) CloseWindow(window);
    if (timerport) {
	Wait(timerbit);
	GetMsg(timerport);
	CloseDevice(timermsg);
	DeleteStdIO(timermsg);
	DeletePort(timerport);
	}
    OpenWorkBench();
    if(IntuitionBase)CloseLibrary(IntuitionBase);
    exit(err);
}
------------------- CUT HERE -------------------------------
-- 
andy finkel		{ihnp4|seismo|allegra}!cbmvax!andy 
Commodore-Amiga, Inc.

"Interfere?  Of course we'll interfere.  Always do what you're best at,
 I always say."

Any expressed opinions are mine; but feel free to share.
I disclaim all responsibilities, all shapes, all sizes, all colors.

peter@sugar.UUCP (Peter da Silva) (09/03/87)

Andy:

	Thanks for the code, but it still chews up a few cycles between
the return from Wait and the time you set the timer. After a while you'll
find your time is off. On page 254 of my edition of the RKM, under the
heading "WHY USE TIME ARITHMETIC?", is the procedure for correcting for
this effect. It is what I was referring to as "rather complex". This is
also what I think the music programs people have been bitching about have
missed. It's nothing to do with MIDI per-se.

	According to the credits, you were a contributing editor to this
book, so I'm surprised I have to point this out.

	This is why I would like to be able to ask the timer.device to
wake me every <n> <time-units>. This sort of thing shouldn't have to be
duplicated in every music program.

PS: While I'm on the subject of the book. Why couldn't you [corporate
you] have escaped the \n" as \en" before running through nroff? I'm not
really interested in the zero in numeric register doublequote.
-- 
-- Peter da Silva `-_-' ...!seismo!soma!uhnix1!sugar!peter
--                  U   <--- not a copyrighted cartoon :->