home *** CD-ROM | disk | FTP | other *** search
/ Prima Shareware 3 / DuCom_Prima-Shareware-3_cd1.bin / PROGRAMO / PASCAL / HUBI / MLB_NFIX.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1995-05-25  |  8.1 KB  |  272 lines

  1. unit MLB_nfix;
  2. { non - permanent MIDI part }
  3.  
  4. {$C PRELOAD FIXED DISCARDABLE}
  5.  
  6. interface
  7. uses MMSYSTEM;
  8. const
  9.       DRIVER_VERSION = 1;
  10.  
  11. procedure modGetDevCaps(id:WORD;var lpCaps; wSize:WORD);
  12. procedure PortName( name:PChar; id:integer );
  13. function midMessage(id:WORD; msg: WORD; dwUser, dwparam1, dwparam2:LongInt):Longint;export;
  14.  
  15. const       gszPort : PChar = 'LB%c';
  16.             gszSection : PChar = 'midlpbk.drv';
  17.             gszIniFile : PChar = 'system.ini';
  18.  
  19.  
  20. implementation
  21. uses WinTypes,WinProcs,MLB_fix;
  22.  
  23. { --------------------------------------------------------------------------
  24.   UTILITY Functions
  25.   -------------------------------------------------------------------------- }
  26. function Min(a:Word;b:Word):Word;
  27. begin
  28.   if a<b then Min:=a else Min:=b;
  29. end;
  30.  
  31. { return name of port[id] in name }
  32. procedure PortName( name:PChar; id:integer );
  33. begin
  34.    inc(id,Ord('1'));
  35.    wvsprintf(name,gszPort,id);
  36.    { if an entry e.g. 'LB1=Cubase to Cakewalk' exist, use this as displayed device name }
  37.    GetPrivateProfileString(gszSection,name,name,name,MaxPNameLen,gszIniFile);
  38. end;
  39.  
  40. procedure modGetDevCaps(id:WORD;var lpCaps; wSize:WORD);
  41. VAR mc : TMIDIOUTCAPS;
  42.     name: array[0..MAXPNAMELEN-1] of char;
  43. BEGIN
  44.     mc.wMid := 0;
  45.     mc.wPid := 0;
  46.     mc.vDriverVersion := DRIVER_VERSION;
  47.     mc.wTechnology := MOD_MIDIPORT;
  48.     mc.wVoices := 0;           { not used for ports }
  49.     mc.wNotes := 0;            { not used for ports }
  50.     mc.wChannelMask := $FFFF;  { all channels }
  51.     mc.dwSupport := 0;
  52.     PortName(mc.szPname,id);
  53.     Move(mc,lpCaps,Min(wSize,sizeof(mc)));
  54. END;
  55.  
  56. {-------------------------------------------------------------------------
  57.   BEGIN OF MIDI INPUT PART
  58.   -------------------------------------------------------------------------  }
  59. procedure midGetDevCaps(id:WORD;var lpCaps; wSize:WORD);
  60. VAR mc : TMIDIINCAPS;
  61. BEGIN
  62.     mc.wMid := 0;
  63.     mc.wPid := 0;
  64.     mc.vDriverVersion := DRIVER_VERSION;
  65.     PortName(mc.szPName,id);
  66.     Move(mc,lpCaps, Min(wSize,sizeof(mc)));
  67. END;
  68.  
  69. function midAddBuffer(id,cl:Integer; lpmh:PMIDIHDR ):Longint;
  70. VAR lpN:PMIDIHDR;
  71. BEGIN
  72.     { check if it's been prepared }
  73.     if (lpmh^.dwFlags and MHDR_PREPARED)=0 then
  74.         midAddBuffer := MIDIERR_UNPREPARED
  75.     else
  76.     { check if it's in our queue already }
  77.     if (lpmh^.dwFlags and MHDR_INQUEUE)<>0 then
  78.         midAddBuffer := MIDIERR_STILLPLAYING
  79.     else BEGIN
  80.          { add the buffer to our queue }
  81.          with lpmh^ do BEGIN
  82.               dwFlags := dwFlags or MHDR_INQUEUE;
  83.               dwFlags := dwFlags and (not MHDR_DONE);
  84.  
  85.               { sanity }
  86.               dwBytesRecorded := 0;
  87.               lpNext := nil;
  88.          end;
  89. {         CritEnter;}
  90.  
  91.          lpN := gMIMC[id,cl].lpmhQueue;
  92.          if lpN<>nil then
  93.             begin
  94.                while ( lpN<>nil ) and ( lpN^.lpNext<>nil )
  95.                do lpN := lpN^.lpNext;
  96.  
  97.                lpN^.lpNext := lpmh;
  98.             end
  99.         else
  100.             gMIMC[id,cl].lpmhQueue := lpmh;
  101.  
  102. {       CritLeave;}
  103.  
  104.        { return success }
  105.        midAddBuffer := 0;
  106.     END;
  107. END;
  108.  
  109. procedure midFreeQ(id,cl:integer);
  110. VAR
  111.      lpH, lpN:PMIDIHDR;
  112.      dwTime:LongInt;
  113. BEGIN
  114.     With gMIMC[id,cl] do begin
  115.        lpH := lpmhQueue;  { point to top of the queue }
  116.        lpmhQueue := nil;  { mark the queue as empty }
  117.        dwCurData := 0;
  118.        dwTime := timeGetTime - dwRefTime;
  119.     end;
  120.  
  121.     while (lpH <> nil) do BEGIN
  122.         lpN := lpH^.lpNext;
  123.         with lpH^ do begin
  124.              dwFlags := dwFlags or MHDR_DONE;
  125.              dwFlags := dwFlags and (not MHDR_INQUEUE);
  126.         end;
  127.         lpH^.dwBytesRecorded := 0;
  128.         MsgCallBack(gMidiInClient[id,cl],MIM_LONGDATA, LongInt(lpH), dwTime);
  129.         lpH := lpN;
  130.     END;
  131. END;
  132.  
  133. procedure midSendPartBuffer(id,cl:integer);
  134. var lpH : PMIDIHDR;
  135. BEGIN
  136.    with gMIMC[id,cl] do
  137.     if ( lpmhQueue <> nil) and (dwCurData<>0) then begin
  138.         lpH := lpmhQueue;
  139.         lpmhQueue := lpmhQueue^.lpNext;
  140.         dwCurData := 0;
  141.         lpH^.dwFlags := lpH^.dwflags or MHDR_DONE;
  142.         lpH^.dwFlags := lpH^.dwFlags and (not MHDR_INQUEUE);
  143.         MsgCallBack(gMidiInClient[id,cl],MIM_LONGERROR, LongInt(lpH), dwMsgTime);
  144.    end;
  145. end;
  146.  
  147.  
  148. procedure midStop(id,cl:integer);
  149. BEGIN
  150.    if gMIMC[id,cl].bStarted then midSendPartBuffer(id,cl);
  151.    gMIMC[id,cl].bstarted := false;
  152. END;
  153.  
  154. { -------------------------------------------------------------------------
  155.   MIDI INPUT MESSAGE PROCESSING
  156.   ------------------------------------------------------------------------- }
  157. function midMessage(id:WORD; msg: WORD; dwUser, dwparam1, dwparam2:LongInt):Longint;
  158. const { from MMDDK.INC}
  159.      MIDM_GETNUMDEVS  =53;
  160.      MIDM_GETDEVCAPS  =54;
  161.      MIDM_OPEN        =55;
  162.      MIDM_CLOSE       =56;
  163.      MIDM_PREPARE     =57;
  164.      MIDM_UNPREPARE   =58;
  165.      MIDM_ADDBUFFER   =59;
  166.      MIDM_START       =60;
  167.      MIDM_STOP        =61;
  168.      MIDM_RESET       =62;
  169.  
  170. var cl:integer;
  171.  
  172. BEGIN
  173.      if (id >= gActivePorts) then begin
  174.         midMessage := MMSYSERR_BADDEVICEID;
  175.         exit;
  176.      end;
  177.      MidMessage := 0; { some fewer BEGINs req'd so}
  178.      case msg of
  179.      MIDM_GETNUMDEVS:
  180.           midMessage := gActivePorts;
  181.      MIDM_GETDEVCAPS:
  182.           midGetDevCaps(id,Pointer(dwparam1)^,WORD(dwparam2));
  183.      MIDM_OPEN:
  184.           BEGIN
  185.             midMessage:=MMSYSERR_ALLOCATED;
  186.             for cl:=0 to gNumInClients-1 do begin
  187.               if gMidiInClient[id,cl].h_Midi=0 then begin
  188.                  { use this port }
  189.                  PLongInt(dwUser)^:=cl;
  190.                  { save client information }
  191.                  with gMidiInClient[id,cl] do begin
  192.                     dwCallback := PMIDIOPENDESC(dwParam1)^.dwCallback;
  193.                     dwInstance := PMIDIOPENDESC(dwParam1)^.dwInstance;
  194.                     h_Midi     := PMIDIOPENDESC(dwParam1)^.hMidi;
  195.                     dwFlags    := dwParam2;
  196.  
  197.                  { initialize queue stuff }
  198.                    with gMIMC[id,cl] do begin
  199.                         dwCurData := 0;
  200.                         lpmhQueue := nil;
  201.  
  202.                       {  NOTE: we must initialize reference time in case someone adds }
  203.                       {  longdata buffers after opening, then resets the midi stream }
  204.                       {  without starting midi input.  Otherwise, midFreeQ would give }
  205.                       {  inconsistent timestamps }
  206.                          dwRefTime := timeGetTime;
  207.  
  208.                          bStarted := false;
  209.                    end;
  210.                  end;
  211.                  MsgCallBack(gMidiInClient[id,cl],MIM_OPEN,0,0);
  212.                  midMessage:=0;
  213.                  break;
  214.               end;
  215.             end;
  216.           END;
  217.      MIDM_CLOSE:
  218.           begin
  219.            cl:=dwUser;
  220.            midStop(id,cl);
  221.            if gMIMC[id,cl].lpmhQueue <> nil then
  222.              midMessage := MIDIERR_STILLPLAYING
  223.            else BEGIN
  224.              MsgCallBack(gMidiInClient[id,cl],MIM_CLOSE,0,0);
  225.              gMidiInClient[id,cl].h_Midi := 0; { Mark as closed }
  226.            END;
  227.           end;
  228.  
  229.        MIDM_ADDBUFFER:
  230.             { attempt to add the buffer }
  231.             midMessage := midAddBuffer(id,dwUser,PMIDIHDR(dwParam1));
  232.  
  233.        MIDM_START:
  234.             with gMIMC[id,dwUser] do begin
  235.             { initialize all the parsing status variables }
  236.                  bstarted := true;
  237.                  fSysEx := false;
  238.                  bStatus := 0;
  239.                  bBytesLeft := 0;
  240.                  bBytePos := 0;
  241.                  dwShortMsg := 0;
  242.                  dwMsgTime := 0;
  243.                  dwRefTime := 0;
  244.                  dwCurData := 0;
  245.  
  246.                  { get a new reference time }
  247.                  dwRefTime := timeGetTime;
  248.             end;
  249.  
  250.         MIDM_STOP:
  251.             midStop(id,dwUser);
  252.  
  253.         MIDM_RESET:
  254.             BEGIN
  255.              cl:=dwUser;
  256.              { stop if it is started and release all buffers }
  257.              midStop(id,cl);
  258.              midFreeQ(id,cl);
  259.             END;
  260.  
  261. {        MIDM_UNPREPARE:
  262.         MIDM_PREPARE:
  263. }
  264.      else
  265.           midMessage := MMSYSERR_NOTSUPPORTED;
  266.      end;
  267. END;
  268.  
  269.  
  270.  
  271. begin
  272. end.