home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / MM1 / SOUNDUTILS / mm1_tracker.lzh / TRACKER4.6 / Amiga / server / timer.c < prev   
Text File  |  1994-11-24  |  4KB  |  157 lines

  1. /* amiga/server/timer.c */
  2.  
  3. /* $Id: timer.c,v 1.4 1994/01/07 15:58:17 Espie Rel Espie $
  4.  * $Log: timer.c,v $
  5.  * Revision 1.4  1994/01/07  15:58:17  Espie
  6.  * Semantics of TIME_WAIT has changed:
  7.  * we now input delays and the server computes what's needed.
  8.  * Makes Pause feasible !
  9.  *
  10.  * Revision 1.3  1994/01/05  14:56:02  Espie
  11.  * *** empty log message ***
  12.  *
  13.  * Revision 1.2  1994/01/05  04:35:23  Espie
  14.  * Suppressed old debug messages.
  15.  *
  16.  * Revision 1.1  1994/01/04  15:45:37  Espie
  17.  * Initial revision
  18.  *
  19.  */
  20.  
  21. #include <exec/nodes.h>
  22. #include <exec/memory.h>
  23. #include <devices/timer.h>
  24. #include <proto/exec.h>
  25. #include <proto/timer.h>
  26.  
  27. #ifdef EXTERNAL
  28. #include <stdio.h>
  29. #endif
  30.  
  31. #include "defs.h"
  32. #include "amiga/amiga.h"
  33. #include "amiga/server/server.h"
  34.  
  35. ID("$Id$")
  36. LOCAL struct MsgPort *tport = 0;
  37. LOCAL struct timerequest *tr = 0;
  38. LOCAL int timer_opened = FALSE;
  39. LOCAL struct Library *TimerBase = 0;
  40.  
  41. /* the reference time at which the sound should play */
  42. LOCAL struct EClockVal play_time;
  43.  
  44.  
  45. /* auto adjusting facilities */
  46.  
  47. /* quantum = EClockFreq >> FRACTION
  48.  * Initially, time_lag = quantum << INITIAL
  49.  */
  50. #define FRACTION 7
  51. #define INITIAL 3
  52. /* the time lag between the current time and the time at which
  53.  * we want to play
  54.  */
  55. LOCAL ULONG time_lag;
  56. /* value to adjust it by each time we miss */
  57. LOCAL ULONG quantum;
  58.  
  59. /* check the time it is: have we got enough time left ? */
  60. LOCAL void check_time()
  61.    {
  62.    struct EClockVal current_time;
  63.    struct ext_message *msg;
  64.    unsigned long freq;
  65.  
  66.    freq = ReadEClock(¤t_time);
  67.    
  68.       /* compare time_play against current_time */
  69.    if (play_time.ev_hi < current_time.ev_hi ||
  70.       (play_time.ev_hi == current_time.ev_hi && play_time.ev_lo < current_time.ev_lo) )
  71.       {
  72.          /* we've fallen behind -> adjust play_time */
  73.       play_time.ev_hi = current_time.ev_hi;      
  74.       play_time.ev_lo = current_time.ev_lo + time_lag;
  75.       if (play_time.ev_lo < time_lag)
  76.          play_time.ev_hi++;
  77.          /* adjust delay */
  78.       time_lag += quantum;
  79.       }
  80.    }
  81.  
  82. struct MsgPort *open_timer()
  83.    {
  84.    int fail;
  85.  
  86.    tport = CreateMsgPort();
  87.    if (!tport)
  88.       return 0;
  89.    tr = CreateIORequest(tport, sizeof(struct timerequest));
  90.    if (!tr)
  91.       return 0;
  92.    fail = OpenDevice(TIMERNAME, UNIT_WAITECLOCK, (struct IORequest *)tr, 0);
  93.    if (fail)
  94.       return 0;
  95.    else
  96.       {
  97.       timer_opened = TRUE;
  98.       TimerBase = (struct Library *)tr->tr_node.io_Device;
  99.       return tport;
  100.       }
  101.    }
  102.  
  103. void close_timer(void)
  104.    {
  105.    if (timer_opened)
  106.       {
  107.       if (!CheckIO((struct IORequest *)tr))
  108.          {
  109.          AbortIO((struct IORequest *)tr);
  110.          WaitIO((struct IORequest *)tr);
  111.          }
  112.       CloseDevice((struct IORequest *)tr);
  113.       }
  114.    if (tr)
  115.       DeleteIORequest(tr);
  116.    if (tport)
  117.       DeleteMsgPort(tport);
  118.    }
  119.    
  120. void handle_timer(struct List *events, int signaled)
  121.    {
  122.    LOCAL int not_waiting = TRUE;
  123.    struct ext_message *msg;
  124.  
  125.    if (signaled)
  126.       {
  127.       while(GetMsg(tport))
  128.          {
  129.          do_events(events);
  130.          not_waiting = TRUE;
  131.          }
  132.       }
  133.  
  134.          /* if there is no timer request pending and some messages waiting, 
  135.           * we post one ! */
  136.    if (not_waiting && (msg = RemHead(events)))
  137.       {        /* if there is a time request, we use it */
  138.       if (msg->type == TYPE_WAIT)   
  139.          {
  140.          play_time.ev_lo += msg->data.time.low;
  141.          if (play_time.ev_lo < msg->data.time.low)
  142.             play_time.ev_hi++;
  143.          play_time.ev_hi += msg->data.time.high;
  144.          ReplyMsg(msg);
  145.          }
  146.       else     /* else we fake one (delay 0) */
  147.          AddHead(events, msg);
  148.       check_time();
  149.       tr->tr_node.io_Command = TR_ADDREQUEST;
  150.       tr->tr_time.tv_secs = play_time.ev_hi;
  151.       tr->tr_time.tv_micro = play_time.ev_lo;
  152.       SendIO((struct IORequest *)tr);
  153.       not_waiting = FALSE;
  154.       }
  155.    }   
  156.  
  157.