home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: Multimed / Multimed.zip / lbraplay.zip / dart.c next >
C/C++ Source or Header  |  1999-04-22  |  5KB  |  159 lines

  1.  
  2. #define USE_OS2_TOOLKIT_HEADERS
  3. #define INCL_DOSSEMAPHORES
  4. #define INCL_DOSPROCESS
  5. #define INCL_NOPMAPI
  6. #define INCL_OS2MM
  7.  
  8. #include <stdio.h>
  9. #include <os2.h>
  10. #include <os2me.h>
  11.  
  12. #define DATA_RATE 8000
  13. #define BUFFER_SIZE 16384
  14. #define PRIORTY_DELTA 30
  15.  
  16. int use8bit=FALSE;
  17. int dyn_prio=TRUE;
  18. int max_buffers=16;
  19.  
  20. int dart_open();
  21. void dart_flush();
  22. void dart_close(void);
  23. void dart_put(short *buff, int count);
  24. LONG MyEvent (ULONG ulStatus, PMCI_MIX_BUFFER pBuffer, ULONG ulFlags);
  25.  
  26.  
  27. static int gohigh,offhigh;
  28. static MCI_MIX_BUFFER Buffers[100];
  29. static MCI_MIXSETUP_PARMS MixSetupParms = {NULLHANDLE,0,MCI_WAVE_FORMAT_PCM,0,0,MCI_PLAY,MCI_DEVTYPE_WAVEFORM_AUDIO,0,NULL,NULL,MyEvent,NULL,0,0};
  30. static MCI_AMP_OPEN_PARMS AmpOpenParms = {NULLHANDLE,0,0,(PSZ)MCI_DEVTYPE_AUDIO_AMPMIX,NULL,NULL,NULL};
  31. static MCI_BUFFER_PARMS BufferParms = {NULLHANDLE,sizeof(MCI_BUFFER_PARMS),0,
  32.                 BUFFER_SIZE,0,0,0,Buffers};
  33. static int buffcount=0,
  34.     numout=0,
  35.     blocking=FALSE,
  36.     flushing=FALSE,
  37.     hipri=FALSE,
  38.     isplaying=FALSE;
  39. static HEV sem;
  40. static TID threadID;
  41.  
  42. LONG MyEvent (ULONG ulStatus, PMCI_MIX_BUFFER pBuffer, ULONG ulFlags) {
  43.    if (ulFlags & MIX_STREAM_ERROR && ulStatus==ERROR_DEVICE_UNDERRUN) {
  44.       if (!hipri && !flushing && dyn_prio) {
  45.      hipri=TRUE;
  46.      DosSetPriority(PRTYS_THREAD,PRTYC_NOCHANGE,PRIORTY_DELTA,threadID);
  47.       }
  48.       if (flushing) {
  49.      DosPostEventSem(sem);
  50.      blocking=FALSE;
  51.       }
  52.    }
  53.    if (ulFlags & MIX_WRITE_COMPLETE) {
  54.       numout--;
  55.       if (numout<gohigh && !hipri && !flushing && dyn_prio) {
  56.          hipri=TRUE;
  57.      DosSetPriority(PRTYS_THREAD,PRTYC_NOCHANGE,PRIORTY_DELTA,threadID);
  58.       }
  59.       if (blocking || (flushing && !numout)) {
  60.          DosPostEventSem(sem);
  61.          blocking=FALSE;
  62.       }
  63.    }
  64.    return 0;
  65. }
  66.  
  67. void error(ULONG rc) {
  68.    char errstr[80];
  69.  
  70.    mciGetErrorString(rc,errstr,80);
  71.    fprintf(stderr,"\nMMOS/2 error: %s\n",errstr);
  72. }
  73.  
  74. int dart_open(void) {
  75.    ULONG rc;
  76.    PPIB ppib=NULL;
  77.    PTIB ptib=NULL;
  78.  
  79.    rc = mciSendCommand(0,MCI_OPEN,MCI_WAIT | MCI_OPEN_TYPE_ID,&AmpOpenParms,0);
  80.    if (ULONG_LOWD(rc)!=MCIERR_SUCCESS) error(rc);
  81.    MixSetupParms.ulBitsPerSample=use8bit?8:16;
  82.    MixSetupParms.ulSamplesPerSec=DATA_RATE;
  83.    MixSetupParms.ulChannels=1;
  84.    rc=mciSendCommand(AmpOpenParms.usDeviceID,MCI_MIXSETUP,
  85.              MCI_WAIT | MCI_MIXSETUP_INIT,&MixSetupParms,0);
  86.    if (ULONG_LOWD(rc)!=MCIERR_SUCCESS) error(rc);
  87.    if (!use8bit) BufferParms.ulBufferSize*=2;
  88.    BufferParms.ulNumBuffers=max_buffers;
  89.    gohigh=max_buffers/4;
  90.    offhigh=max_buffers/2;
  91.    rc=mciSendCommand(AmpOpenParms.usDeviceID,MCI_BUFFER,
  92.                      MCI_WAIT | MCI_ALLOCATE_MEMORY,&BufferParms,0);
  93.    if (ULONG_LOWD(rc)!=MCIERR_SUCCESS) error(rc);
  94.    DosCreateEventSem(NULL,&sem,0,TRUE);
  95.    DosGetInfoBlocks(&ptib,&ppib);
  96.    threadID=ptib->tib_ptib2->tib2_ultid;
  97.    return 0;
  98. }
  99.  
  100. void dart_put(short *buff, int count) {
  101.    static ULONG numposted;
  102.  
  103.    if (!isplaying) numout=0;
  104.  
  105.    if (numout>=max_buffers-1) {
  106.       DosResetEventSem(sem,&numposted);
  107.       blocking=TRUE;
  108.       DosWaitEventSem(sem,-1);
  109.    }
  110.    if (numout>offhigh && hipri) {
  111.       hipri=FALSE;
  112.       DosSetPriority(PRTYS_THREAD,PRTYC_NOCHANGE,-PRIORTY_DELTA,threadID);
  113.    }
  114.    if (use8bit) {
  115.       int i;
  116.       unsigned char *dp;
  117.  
  118.       dp=Buffers[buffcount].pBuffer;
  119.       for (i=count;i;i--) *dp++ = 0x80 ^ ((unsigned char) ((*buff++)>>8) );
  120.       }
  121.    else {
  122.       count*=2;
  123.       memcpy(Buffers[buffcount].pBuffer,buff,count);
  124.       }
  125.    Buffers[buffcount].ulBufferLength=count;
  126.    MixSetupParms.pmixWrite(MixSetupParms.ulMixHandle,&Buffers[buffcount++],1);
  127.    if (buffcount>=max_buffers) buffcount=0;
  128.    numout++;
  129.    isplaying=TRUE;
  130. }
  131.  
  132. void dart_close(void) {
  133.    MCI_GENERIC_PARMS GenericParms;
  134.    ULONG rc;
  135.  
  136.    DosCloseEventSem(sem);
  137.    rc=mciSendCommand(AmpOpenParms.usDeviceID,MCI_BUFFER,
  138.                      MCI_WAIT | MCI_DEALLOCATE_MEMORY,&BufferParms,0);
  139.    if (ULONG_LOWD(rc)!=MCIERR_SUCCESS) error(rc);
  140.    rc=mciSendCommand(AmpOpenParms.usDeviceID,MCI_CLOSE,MCI_WAIT,&GenericParms,0);
  141.    if (ULONG_LOWD(rc)!=MCIERR_SUCCESS) error(rc);
  142. }
  143.  
  144. void dart_flush() {
  145.    ULONG numposted;
  146.  
  147.    DosResetEventSem(sem,&numposted);
  148.    flushing=TRUE;
  149.    isplaying=FALSE;
  150.    if (!numout) DosPostEventSem(sem);
  151.    else DosWaitEventSem(sem,-1);
  152.    flushing=FALSE;
  153.    if (hipri) {
  154.       hipri=FALSE;
  155.       DosSetPriority(PRTYS_THREAD,PRTYC_NOCHANGE,-PRIORTY_DELTA,threadID);
  156.    }
  157. }
  158.  
  159.