home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format 119 / af119sub.adf / SamEd.lzx / SamEd / Developers / extproc.h < prev    next >
C/C++ Source or Header  |  2001-04-09  |  17KB  |  583 lines

  1.  
  2.         /*name of the message port*/
  3. #define EPMPORT_NAME    "SamED_EPMPort"
  4.  
  5.         /*External Processor Commands*/
  6.         /*commands always available...*/
  7. #define EPC_VERSION     0   /* returns current version */
  8. #define EPC_AUTOQUIT    1   /* set auto quit mode for a specific task (given a pointer to the task, and a sigbit number */
  9. #define EPC_IDNUM       2   /* returns your (the ext. proc.) id number given a pointer to your task */
  10. #define EPC_MULTI       3   /* set multi load mode, the given ext. proc. can be opened multiple times */
  11. #define EPC_QUIT        4   /* tell SamEd you will quit, given your ID no. and/or task pointer */
  12. #define EPC_TOTALNUM    5   /* ask for maximum number of samples */
  13.  
  14.         /*lock commands...*/
  15. #define EPC_LOCK        6   /* set lock, required to alter data and/or to safely read data*/
  16. #define EPC_UNLOCK      7   /* unlock lock */
  17.  
  18.         /*commands requiring you to hold the lock to the system...*/
  19. #define EPC_GETSAMPLE   8   /* get pointer to current sam_info structure */
  20. #define EPC_GETSAMPLES  9   /* get pointer to array of all sam_info structs */
  21. #define EPC_GETBUFFER   10  /* get pointer to sample[0] / the copy buffer */
  22. #define EPC_GETSAMNUM   11  /* get current sample number */
  23. #define EPC_GETRSTART   12  /* get range start */
  24. #define EPC_GETREND     13  /* get range end */
  25. #define EPC_SETSAMNUM   14  /* set current sample */
  26. #define EPC_SETRSTART   15  /* set range start */
  27. #define EPC_SETREND     16  /* set range end */
  28. #define EPC_FLUSH       17  /* flush current sample from memory */
  29. #define EPC_PIOPEN      19  /* open progress indicator */
  30. #define EPC_PISTRING    20
  31. #define EPC_PIMAX       21
  32. #define EPC_PIVAL       22
  33. #define EPC_PICLOSE     23
  34.  
  35.  
  36.         /*EPCErrors...*/
  37. #define EPCERR_NOERR    0   /* command sucessful */
  38. #define EPCERR_NOCOMMAND    1   /* unrecognised command */
  39. #define EPCERR_SAMNUM   2   /* sample id number out of range */
  40. #define EPCERR_NOAQUIT  3   /* auto quit could not be allocated */
  41. #define EPCERR_LOCKED   4   /* returned by EPC_LOCK when system is already locked */
  42.  
  43.         /*Procs magic number*/
  44. #define PROC_MAGIC      ('S'<<24 | 'E'<<16 | 'P'<<8 | 0)        /*SamEd Proc version 0*/
  45.  
  46.  
  47.         /*Filer errors*/
  48. #define FERR_NOERR      0   /* no error */
  49. #define FERR_GENERAL    1   /* general error. The minimum you should return if an error occurs */
  50. #define FERR_FILEERR    2   /* file error. General error with the actual file processing */
  51. #define FERR_ACTIONNA   3   /* action (load / save / etc.) not supported */
  52. #define FERR_STYPENA    4   /* sample type not supported */
  53. #define FERR_NOTMAGIC   5   /* the 'magic number' did not match */
  54.  
  55.         /*Filer actions*/
  56. #define FACT_LOAD       1   /* load action */
  57. #define FACT_SAVE       2   /* save action */
  58.  
  59.         /*Filers magic number*/
  60. #define FILER_MAGIC     ('S'<<24 | 'E'<<16 | 'F'<<8 | 0)        /*SamEd Filer version 0*/
  61.  
  62.  
  63.         /*structures...*/
  64.  
  65. static struct Ext_Proc_Msg{
  66.     struct Message  epm_Msg;
  67.     ULONG           epm_Command;
  68.     ULONG           epm_Error;
  69.     APTR            epm_Data;
  70. };
  71.  
  72. static struct Ext_Proc_ID{
  73.     struct Task *task;
  74.     ULONG number;
  75. };
  76.  
  77. static struct sam_info {
  78.     BYTE *waveform;
  79.     ULONG length;
  80.     ULONG type;
  81.     ULONG loop_begin;
  82.     ULONG loop_length;
  83.     BOOL  loop;
  84.     BYTE  reserved[3];
  85.     ULONG def_freq;
  86.     ULONG def_vol;
  87.     ULONG file_type;
  88.     char *dir;
  89.     char *name;
  90. };
  91.  
  92.     /*sound types, these are the same as AHI*/
  93. #define STYPE_M8            0                     /* Mono, 8 bit signed (BYTE) */
  94. #define STYPE_M16           1                     /* Mono, 16 bit signed (WORD) */
  95. #define STYPE_M32           8                     /* Mono, 32 bit signed (LONG) */
  96. #define STYPE_S8            2                     /* Stereo, 8 bit signed (2×BYTE) */
  97. #define STYPE_S16           3                     /* Stereo, 16 bit signed (2×WORD) */
  98. #define STYPE_S32           10                    /* Stereo, 32 bit signed (2×LONG) */
  99.  
  100.  
  101.  
  102. /*---------------------------------------------------------------------------------------------------\
  103. |       The following functions are to help with communication with SamEd.                           |
  104. |       define NO_EPP_HELP if you do not require them.                                               |
  105. \---------------------------------------------------------------------------------------------------*/
  106.  
  107. #ifndef NO_EPP_HELP
  108.  
  109. struct EP_Port {
  110.     struct MsgPort *our_mp;
  111.     struct Ext_Proc_Msg message;
  112.     ULONG button;
  113.     BOOL lock;
  114.     };
  115.  
  116. typedef struct EP_Port * EPP_HANDLE;
  117.  
  118. EPP_HANDLE  EP_NewPort (ULONG);
  119. void        EP_DeletePort (EPP_HANDLE);
  120. BOOL        EP_SendMsg (EPP_HANDLE, ULONG, void *);
  121. BOOL        EP_SendIDMsg (EPP_HANDLE, ULONG, struct Task *, ULONG);
  122. BOOL        EP_Quit (EPP_HANDLE);
  123. BYTE        EP_AllocQSig (EPP_HANDLE);
  124. void        EP_DeallocQSig (BYTE);
  125. BOOL        EP_Lock (EPP_HANDLE);
  126. BOOL        EP_Unlock (EPP_HANDLE);
  127. BOOL        EP_GetSample (EPP_HANDLE, struct sam_info **, struct sam_info **, ULONG *);
  128.  
  129.  
  130. EPP_HANDLE EP_NewPort (ULONG button)
  131. {
  132.     EPP_HANDLE ep_port;
  133.  
  134.     if (ep_port = AllocMem(sizeof (struct EP_Port), MEMF_CLEAR))
  135.     {
  136.         if (ep_port->our_mp = (struct MsgPort *)CreatePort(NULL,0))
  137.         {
  138.             ep_port->message.epm_Msg.mn_Node.ln_Type = NT_MESSAGE;
  139.             ep_port->message.epm_Msg.mn_ReplyPort = ep_port->our_mp;
  140.             ep_port->message.epm_Msg.mn_Length = sizeof(struct Ext_Proc_Msg);
  141.             ep_port->button = button;
  142.             ep_port->lock = FALSE;
  143.             return (ep_port);
  144.         }
  145.         else
  146.         {
  147.             FreeMem(ep_port, sizeof (struct EP_Port));
  148.             return(NULL);
  149.         }
  150.     }
  151.     else
  152.         return (NULL);
  153. }
  154.  
  155. void EP_DeletePort (EPP_HANDLE ep_port)
  156. {
  157.     if (ep_port->lock) EP_Unlock (ep_port);
  158.  
  159.     if (ep_port)
  160.     {
  161.         if (ep_port->our_mp)
  162.         {
  163.             while(GetMsg(ep_port->our_mp));
  164.             DeletePort(ep_port->our_mp);
  165.         }
  166.  
  167.         FreeMem(ep_port, sizeof (struct EP_Port));
  168.     }
  169. }
  170.  
  171. BYTE EP_AllocQSig (EPP_HANDLE ep_port)
  172. {
  173.     BYTE signal;
  174.  
  175.     if (-1 == (signal = AllocSignal(-1)))
  176.         return(-1);
  177.  
  178.     if (EP_SendIDMsg(ep_port, EPC_AUTOQUIT, FindTask(0), signal))
  179.         return(signal);
  180.  
  181.     FreeSignal (signal);
  182.     return(-1);
  183. }
  184.  
  185. void EP_DeallocQSig (BYTE signal)
  186. {
  187.     if (signal != -1)
  188.         FreeSignal (signal);
  189. }
  190.  
  191. BOOL EP_SendMsg (EPP_HANDLE ep_port, ULONG command, void * data)
  192. {
  193.     printf("Try to send...\n");
  194.     struct MsgPort *dest_mp;
  195.  
  196.     ep_port->message.epm_Command = command;
  197.     ep_port->message.epm_Data = data;
  198.  
  199.     Forbid();
  200.     if (dest_mp = (struct MsgPort *)FindPort(EPMPORT_NAME))
  201.         PutMsg(dest_mp, (struct Message *)&ep_port->message);
  202.     Permit();
  203.     if (dest_mp)
  204.     {
  205.         printf("Sent!!!\n");
  206.         WaitPort(ep_port->our_mp);
  207.         while(GetMsg(ep_port->our_mp));
  208.     }
  209.  
  210.     return (dest_mp ? TRUE : FALSE);
  211. }
  212.  
  213. BOOL EP_SendIDMsg (EPP_HANDLE ep_port, ULONG command, struct Task * task, ULONG number)
  214. {
  215.     struct Ext_Proc_ID id_data;
  216.     id_data.task = task;
  217.     id_data.number = number;
  218.  
  219.     return (EP_SendMsg (ep_port, command, &id_data));
  220. }
  221.  
  222. BOOL EP_Quit (EPP_HANDLE ep_port)
  223. {
  224.     return (EP_SendIDMsg (ep_port, EPC_QUIT, FindTask(0), ep_port->button));
  225. }
  226.  
  227. BOOL EP_Lock (EPP_HANDLE ep_port)
  228. {
  229.     if (ep_port->lock == TRUE)
  230.         return (TRUE);
  231.  
  232.     if (!EP_SendMsg (ep_port, EPC_LOCK, NULL))
  233.         return (FALSE);
  234.  
  235.     if (ep_port->message.epm_Error)
  236.         return (FALSE);
  237.  
  238.     ep_port->lock = TRUE;
  239.     return (TRUE);
  240. }
  241.  
  242. BOOL EP_Unlock (EPP_HANDLE ep_port)
  243. {
  244.     if (ep_port->lock == FALSE)
  245.         return (TRUE);
  246.  
  247.     if (!EP_SendMsg (ep_port, EPC_UNLOCK, NULL))
  248.         return (FALSE);
  249.  
  250.     if (ep_port->message.epm_Error)
  251.         return (FALSE);
  252.  
  253.     ep_port->lock = FALSE;
  254.     return (TRUE);
  255. }
  256.  
  257. BOOL EP_GetSample (EPP_HANDLE ep_port, struct sam_info **sample, struct sam_info **copybuf, ULONG *range)
  258. {
  259.     BOOL sucess = TRUE, old_lock = ep_port->lock;
  260.  
  261.     if (ep_port->lock == FALSE)
  262.         if (!EP_Lock (ep_port)) return(FALSE);
  263.  
  264.     if (sample)
  265.     {
  266.         if (EP_SendMsg (ep_port, EPC_GETSAMPLE, NULL))
  267.             *(sample) = ep_port->message.epm_Data;
  268.         else
  269.             {*(sample) = NULL; sucess = FALSE;}
  270.     }
  271.  
  272.     if (copybuf)
  273.     {
  274.         if (EP_SendMsg (ep_port, EPC_GETBUFFER, NULL))
  275.             *(copybuf) = ep_port->message.epm_Data;
  276.         else
  277.             {*(copybuf) = NULL; sucess = FALSE;}
  278.     }
  279.  
  280.     if (range)
  281.     {
  282.         if(EP_SendMsg (ep_port, EPC_GETRSTART, NULL))
  283.         {
  284.             *(range++) = *((ULONG *)ep_port->message.epm_Data);
  285.  
  286.             if (EP_SendMsg (ep_port, EPC_GETREND, NULL))
  287.             {
  288.                 *range = *((ULONG *)ep_port->message.epm_Data);
  289.             }
  290.             else
  291.             {
  292.                 *(range--) = 0;
  293.                 *(range) = 0;
  294.                 sucess = FALSE;
  295.             }
  296.         }
  297.     }
  298.  
  299.     if (!old_lock) EP_Unlock(ep_port);
  300.  
  301.     return(sucess);
  302. }
  303.  
  304. #endif  /*NO_EPP_HELP*/
  305.  
  306.  
  307.  
  308. /*---------------------------------------------------------------------------------------------------\
  309. |       These functions help with 8 / 16 / mono / stereo data processing.                            |
  310. |       32 bit floating point versions are also included (I don't know if they work, nor do I        |
  311. |       know how 32 bit fp data is supposed to be interpreted!).                                     |
  312. |                                                                                                    |
  313. |       All data is changed to 16 bit resolution.                                                    |
  314. |                                                                                                    |
  315. |       I have estimated the Macros SET_ / GET_LEVEL to be 50% quicker than the functions            |
  316. |       Set_ / Get_Level().                                                                          |
  317. |                                                                                                    |
  318. |       define NO_DATA_HELP to disable.                                                              |
  319. \---------------------------------------------------------------------------------------------------*/
  320.  
  321. #ifndef NO_DATA_HELP
  322.  
  323. void    Set_Level (BYTE *, ULONG, LONG, ULONG, UBYTE);
  324. WORD    Get_Level (BYTE *, ULONG, ULONG, UBYTE);
  325. ULONG   Sams_To_Bytes (ULONG, ULONG);
  326. ULONG   Bytes_To_Sams (ULONG, ULONG);
  327. void    CopyWave (BYTE *, ULONG, BYTE *, ULONG, ULONG);
  328. void    setb_lev (BYTE *, ULONG, LONG, UBYTE);
  329. void    setw_lev (BYTE *, ULONG, LONG, UBYTE);
  330. void    setl_lev (BYTE *, ULONG, LONG, UBYTE);
  331. void    setsb_lev (BYTE *, ULONG, LONG, UBYTE);
  332. void    setsw_lev (BYTE *, ULONG, LONG, UBYTE);
  333. void    setsl_lev (BYTE *, ULONG, LONG, UBYTE);
  334. void    setnon_lev (BYTE *, ULONG, LONG, UBYTE);
  335. LONG    getb_lev (BYTE *, ULONG, UBYTE);
  336. LONG    getw_lev (BYTE *, ULONG, UBYTE);
  337. LONG    getl_lev (BYTE *, ULONG, UBYTE);
  338. LONG    getsb_lev (BYTE *, ULONG, UBYTE);
  339. LONG    getsw_lev (BYTE *, ULONG, UBYTE);
  340. LONG    getsl_lev (BYTE *, ULONG, UBYTE);
  341. LONG    getnon_lev (BYTE *, ULONG, UBYTE);
  342.  
  343. static void (*Set_Level_Function[])(BYTE *, ULONG, LONG, UBYTE) = {
  344.     setb_lev,
  345.     setw_lev,
  346.     setsb_lev,
  347.     setsw_lev,
  348.     setnon_lev,
  349.     setnon_lev,
  350.     setnon_lev,
  351.     setnon_lev,
  352.     setnon_lev,
  353.     setl_lev,
  354.     setnon_lev,
  355.     setsl_lev,
  356.     };
  357.  
  358. static LONG (*Get_Level_Function[])(BYTE *, ULONG, UBYTE) = {
  359.     getb_lev,
  360.     getw_lev,
  361.     getsb_lev,
  362.     getsw_lev,
  363.     getnon_lev,
  364.     getnon_lev,
  365.     getnon_lev,
  366.     getnon_lev,
  367.     getnon_lev,
  368.     getl_lev,
  369.     getnon_lev,
  370.     getsl_lev,
  371.     };
  372.  
  373. /*Macros use 'type' to index an array of pointers to edit functions. SET_LEVELN does not clip*/
  374.  
  375. #define GET_LEVEL(start, pos, type, chan) (*Get_Level_Function[(type)])((start), (pos), (chan))
  376. #define SET_LEVELN(start, pos, lev, type, chan) (*Set_Level_Function[(type)])((start), (pos), (lev), (chan))
  377. #define SET_LEVEL(start, pos, lev, type, chan) LONG macro_level = lev;\
  378.         if (macro_level > 32767) macro_level = 32767;\
  379.         else if (macro_level < -32768) macro_level = -32768;\
  380.         (*Set_Level_Function[(type)])((start), (pos), macro_level, (chan))
  381.  
  382. void Set_Level(BYTE *start, ULONG pos, LONG level, ULONG type, UBYTE channel)
  383. {
  384.     if (level > 32767) level = 32767;
  385.     else if (level < -32768) level = -32768;
  386.  
  387.     switch (type)
  388.     {
  389.         case STYPE_M8:
  390.             *((BYTE *) start + pos) = level >>8;
  391.             break;
  392.  
  393.         case STYPE_M16:
  394.             *((WORD *) start + pos) = level;
  395.             break;
  396.  
  397.         case STYPE_M32:
  398.             *((float *) start + pos) = (float)level;
  399.             break;
  400.  
  401.         case STYPE_S8:
  402.             *((BYTE *) start + (pos <<1) +channel) = level >>8;
  403.             break;
  404.  
  405.         case STYPE_S16:
  406.             *((WORD *) start + (pos <<1) +channel) = level;
  407.             break;
  408.  
  409.         case STYPE_S32:
  410.             *((float *) start + (pos <<1) +channel) = (float)level;
  411.             break;
  412.     }
  413. }
  414.  
  415. WORD Get_Level(BYTE *start, ULONG pos, ULONG type, UBYTE channel)
  416. {
  417.     switch (type)
  418.     {
  419.         case STYPE_M8:  return( *(start + pos) <<8);
  420.  
  421.         case STYPE_M16: return( *((WORD *)start + pos));
  422.  
  423.         case STYPE_M32: return( (WORD) *((float *)start + pos));
  424.  
  425.         case STYPE_S8:  return( *(start + (pos <<1) +channel) <<8);
  426.  
  427.         case STYPE_S16: return( *((WORD *)start + (pos <<1) +channel));
  428.  
  429.         case STYPE_S32: return( (WORD) *((float *)start + (pos <<1) +channel));
  430.     }
  431. }
  432.  
  433. ULONG Sams_To_Bytes(ULONG sams, ULONG type)
  434. {
  435.     ULONG bytes;
  436.     switch (type)
  437.     {
  438.         case STYPE_M8:
  439.             bytes = sams;
  440.             break;
  441.  
  442.         case STYPE_M16:
  443.             bytes = sams *2;
  444.             break;
  445.  
  446.         case STYPE_M32:
  447.             bytes = sams *4;
  448.             break;
  449.  
  450.         case STYPE_S8:
  451.             bytes = sams *2;
  452.             break;
  453.  
  454.         case STYPE_S16:
  455.             bytes = sams *4;
  456.             break;
  457.  
  458.         case STYPE_S32:
  459.             bytes = sams *8;
  460.             break;
  461.     }
  462.     return(bytes);
  463. }
  464.  
  465. ULONG Bytes_To_Sams(ULONG bytes, ULONG type)
  466. {
  467.     ULONG sams;
  468.     switch (type)
  469.     {
  470.         case STYPE_M8:
  471.             sams = bytes;
  472.             break;
  473.  
  474.         case STYPE_M16:
  475.             sams = bytes /2;
  476.             break;
  477.  
  478.         case STYPE_M32:
  479.             sams = bytes /4;
  480.             break;
  481.  
  482.         case STYPE_S8:
  483.             sams = bytes /2;
  484.             break;
  485.  
  486.         case STYPE_S16:
  487.             sams = bytes /4;
  488.             break;
  489.  
  490.         case STYPE_S32:
  491.             sams = bytes /8;
  492.             break;
  493.     }
  494.     return(sams);
  495. }
  496.  
  497. void CopyWave (BYTE *from, ULONG fromtype, BYTE *to, ULONG totype, ULONG length)
  498. {
  499.     if (fromtype == totype)
  500.     {
  501.         length = Sams_To_Bytes (length, fromtype);
  502.         CopyMem(from, to, length);
  503.         return();
  504.     }
  505.  
  506.     if (totype & 2)/*both stereo, or mono to stereo*/
  507.     {
  508.         for (ULONG n =0; n < length; n++)
  509.         {
  510.             SET_LEVELN(to, n, GET_LEVEL(from, n, fromtype, 0), totype, 0);
  511.         }
  512.         for (ULONG n =0; n < length; n++)
  513.         {
  514.             SET_LEVELN(to, n, GET_LEVEL(from, n, fromtype, 1), totype, 1);
  515.         }
  516.         return();
  517.     }
  518.  
  519.     if (fromtype & 2)/*from stereo to mono*/
  520.     {
  521.         for (ULONG n =0; n < length; n++)
  522.         {
  523.             SET_LEVELN(to, n,
  524.                 (GET_LEVEL(from, n, fromtype, 0) + GET_LEVEL(from, n, fromtype, 1)) /2
  525.                 , totype, 0);
  526.         }
  527.         return();
  528.     }
  529.  
  530.     /*else both mono*/
  531.     {
  532.         for (ULONG n =0; n < length; n++)
  533.         {
  534.             SET_LEVELN(to, n, GET_LEVEL(from, n, fromtype, 0), totype, 0);
  535.         }
  536.     }
  537. }
  538.  
  539. void setb_lev (BYTE *start, ULONG pos, LONG level, UBYTE dummy)
  540. { *((BYTE *) start + pos) = level >>8; }
  541.  
  542. void setw_lev (BYTE *start, ULONG pos, LONG level, UBYTE dummy)
  543. { *((WORD *) start + pos) = level; }
  544.  
  545. void setl_lev (BYTE *start, ULONG pos, LONG level, UBYTE dummy)
  546. { *((float *) start + pos) = (float)level; }
  547.  
  548. void setsb_lev (BYTE *start, ULONG pos, LONG level, UBYTE chan)
  549. { *((BYTE *) start + (pos <<1) +chan) = level >>8; }
  550.  
  551. void setsw_lev (BYTE *start, ULONG pos, LONG level, UBYTE chan)
  552. { *((WORD *) start + (pos <<1) +chan) = level; }
  553.  
  554. void setsl_lev (BYTE *start, ULONG pos, LONG level, UBYTE chan)
  555. { *((float *) start + (pos <<1) +chan) = (float)level; }
  556.  
  557. void setnon_lev (BYTE *start, ULONG pos, LONG level, UBYTE dummy)
  558. {}
  559.  
  560.  
  561. LONG getb_lev (BYTE *start, ULONG pos, UBYTE dummy)
  562. { return (*(start + pos) <<8); }
  563.  
  564. LONG getw_lev (BYTE *start, ULONG pos, UBYTE dummy)
  565. { return (*((WORD *)start + pos)); }
  566.  
  567. LONG getl_lev (BYTE *start, ULONG pos, UBYTE dummy)
  568. { return ((WORD) *((float *)start + pos)); }
  569.  
  570. LONG getsb_lev (BYTE *start, ULONG pos, UBYTE chan)
  571. { return (*(start + (pos <<1) +chan) <<8); }
  572.  
  573. LONG getsw_lev (BYTE *start, ULONG pos, UBYTE chan)
  574. { return (*((WORD *)start + (pos <<1) +chan)); }
  575.  
  576. LONG getsl_lev (BYTE *start, ULONG pos, UBYTE chan)
  577. { return ((WORD) *((float *)start + (pos <<1) +chan)); }
  578.  
  579. LONG getnon_lev (BYTE *start, ULONG pos, UBYTE dummy)
  580. { return (0); }
  581.  
  582. #endif  /*NO_DATA_HELP*/
  583.