home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Misc / DC-POS24.LZX / pOS / pOS_RKRM.lzx / pOS_RKRM / pAudio / Dt8svx.c < prev   
Encoding:
C/C++ Source or Header  |  1997-03-18  |  12.3 KB  |  510 lines

  1. /*******************************************************************
  2.  $CRT 18 Dec 1996 : hb
  3.  
  4.  $AUT Holger Burkarth
  5.  $DAT >>Dt8svx.c<<   29 Jan 1997    13:37:35 - (C) ProDAD
  6. *******************************************************************/
  7.  
  8. //##ex mcpp:cppc -gs -o pos:pos/Libs/8svxdt.library p:pLib/LibCode.o p:/pOS_RKRM/pAudio/Dt8svx.c -l pOSStub -l pOS -l CPPList
  9.  
  10. /***********************************************************
  11.   pOS programing example - Copyright (C) 1995-97 proDAD
  12.  
  13.   This code was written as an easy to understand example,
  14.   how to program pOS features. It is provided 'as-is',
  15.   without any express or implied warranty.
  16.  
  17.   Permission is hereby granted to use, copy and modify
  18.   this source code for any purpose, without fee, subject
  19.   to the following conditions:
  20.  
  21.     (1) This notice may not be removed or altered from any
  22.         source distribution.
  23.  
  24.     (2) Altered source versions must be plainly marked as
  25.         such, and must not be misrepresented as being
  26.         the original source code.
  27.  
  28.     (3) If only executable code is distributed, then the
  29.         accompanying documentation have to state that
  30.         "this software is based in part on examples of
  31.         the pOS developer packet".
  32.  
  33.     (4) Permission for use of this code is granted only
  34.         if the user accepts full responsibility for any
  35.         undesirable consequences. proDAD accept NO LIABILITY
  36.         for damages of any kind.
  37.  
  38.   ©proDAD
  39. ***********************************************************/
  40.  
  41. /*\
  42. *** Example:
  43. ***
  44. \*/
  45.  
  46.  
  47. #define __COMPUTER_AMIGA 1
  48. #define NOMYDEBUG
  49.  
  50. #include "p:pExec/Library.h"
  51. #include "p:pExec/Diagnos.h"
  52. #include "p:pExec/TstTags.h"
  53. #include "p:pDOS/ArgTags.h"
  54. #include "p:pDOS/DosSig.h"
  55. #include "p:pDOS/DosErrors.h"
  56. #include "p:pDOS/Segment.h"
  57. #include "p:pDOS/Files.h"
  58. #include "p:pAudio/Audio.h"
  59. #include "p:pAudio/AudioTags.h"
  60. #include "p:pAudio/InfoData.h"
  61. #include "p:pAudio/StdAMap.h"
  62. #include "p:pDtType/DtBase.h"
  63. #include "p:pDtType/DtTags.h"
  64. #include "p:pDtType/Sample.h"
  65. #include "p:pDtType/DClass.h"
  66.  
  67. #include "p:proto/pLibExt.h"
  68. #include "p:proto/pExec2.h"
  69. #include "p:proto/pDOS2.h"
  70. #include "p:proto/pAudio2.h"
  71. #include "p:proto/pList.h"
  72.  
  73. #ifdef _____ME_____
  74.   #include "grund/inc_string.h"
  75.   #include "grund/inc_limits.h"
  76. #else
  77.  #ifdef __cplusplus
  78.  extern "C" {
  79.  #endif
  80.   #include <string.h>
  81.   #include <limits.h>
  82.  #ifdef __cplusplus
  83.  }
  84.  #endif
  85. #endif
  86.  
  87.  
  88.  
  89. #ifdef __cplusplus
  90. extern "C"
  91. {
  92.   void InitModules();
  93.   void CleanupModules();
  94. }
  95. #endif
  96.  
  97.  
  98. #define MAXOCT 4
  99.  
  100. struct Voice8Header
  101. {
  102.   ULONG oneShotHiSamples;
  103.   ULONG repeatHiSamples;
  104.   ULONG samplesPerHiCycle;
  105.   UWORD samplesPerSec;
  106.   UBYTE ctOctave;
  107.   UBYTE sCompression;
  108.   ULONG volume;
  109. };
  110.  
  111. struct EightSVXInfo
  112. {
  113.   struct Voice8Header Vhdr;
  114.   SBYTE              *osamps[MAXOCT];
  115.   ULONG               osizes[MAXOCT];
  116.   SBYTE              *rsamps[MAXOCT];
  117.   ULONG               rsizes[MAXOCT];
  118.   ULONG               spcycs[MAXOCT];
  119. };
  120.  
  121.  
  122.  
  123.  
  124. struct pOSp_DtLib
  125. {
  126.   pOS_Library  dl_Lib;
  127.  
  128.   pOS_NClass  *dl_DtClass;
  129. };
  130.  
  131.  
  132. struct pOSp_DtData
  133. {
  134.   Voice8Header VH;
  135.   UBYTE        *Body;
  136.   size_t        BodySize;
  137. };
  138.  
  139.  
  140. #ifndef MAKE_ID
  141.  #define MAKE_ID(a,b,c,d) ( (LONG)(a)<<24L | (LONG)(b)<<16L | (c)<<8 | (d) )
  142. #endif
  143.  
  144.  
  145.  
  146. struct pOS_ExecBase* gb_ExecBase;
  147. struct pOS_ExecLibFunction* gb_ExecLib;
  148. struct pOS_DosBase     *gb_DosBase;
  149. struct pOS_UtilityBase *gb_UtilityBase;
  150.  
  151. extern ULONG *FuncTable[];
  152. const CHAR LibraryName[]  ="8svxdt.library";
  153. const CHAR LibraryIDName[]="8svxdt.library 1.0 ("__DATE2__") (Copyright proDAD, Created by Holger Burkarth)";
  154.  
  155. const pOS_TagItem LibraryDescribe[]=
  156. {
  157.   EXTSTTAG_MainOSID, pOS_MAINOSID,
  158.   TAG_END
  159. };
  160.  
  161.  
  162. BOOL pLibMain(_R_LB pOS_ExecBase*,_R_A0 pOSp_DtLib*);
  163. ULONG DtDispatcher(_R_LB pOS_ExecBase*,_R_A0 const pOS_Class*,_R_A1 pOSp_DtData*,_R_A2 pOS_DtTypeMethod*);
  164. VOID DtDispose(pOSp_DtData* obj);
  165.  
  166.  
  167. pOS_ResidentLibInit InitTable=
  168. {
  169.   sizeof(pOSp_DtLib),
  170.   FuncTable,
  171.   NULL,
  172.   (BOOL(*)(_R_LB pOS_ExecBase*,_R_A0 pOS_Library*))pLibMain
  173. };
  174.  
  175.  
  176. /*----------------------------------
  177.  Wird in dieser Library nicht benötigt.
  178. -----------------------------------*/
  179. BOOL Open_func(_R_LB pOSp_DtLib*)      { return(1); }
  180. VOID Close_func(_R_LB pOSp_DtLib*)     {}
  181. ULONG Reserved_func(_R_LB pOSp_DtLib*) { return(0); }
  182.  
  183.  
  184.  
  185. /*----------------------------------
  186. -----------------------------------*/
  187. pOS_SegmentLst* Expunge_func(_R_LB pOSp_DtLib* lib)
  188. {
  189.   if(lib->dl_Lib.lib_OpenCnt==0) {
  190.     pOS_SegmentLst* Seg=lib->dl_Lib.lib_Segm;
  191.  
  192.     pOS_ListRemove(&lib->dl_Lib.lib_Node);
  193.  
  194.     if(lib->dl_DtClass) pOS_DeleteClass(lib->dl_DtClass);
  195.  
  196.     _pOS_FreeLibraryMem2(&lib->dl_Lib); /* Lib-Memory freigeben */
  197.     pOS_CloseLibrary((pOS_Library*)gb_DosBase);
  198.     pOS_CloseLibrary((pOS_Library*)gb_UtilityBase);
  199. #ifdef __cplusplus
  200.     CleanupModules();
  201. #endif
  202.     return(Seg);
  203.   }
  204.   return(0);
  205. }
  206.  
  207.  
  208. ULONG *FuncTable[]=
  209. {
  210.  (ULONG*)Open_func,
  211.  (ULONG*)Close_func,
  212.  (ULONG*)Expunge_func,
  213. // ------------
  214.  (ULONG*)Reserved_func,
  215.  (ULONG*)Reserved_func,
  216.  (ULONG*)Reserved_func,
  217.  (ULONG*)Reserved_func,
  218.  (ULONG*)Reserved_func,
  219.  (ULONG*)Reserved_func,
  220.  (ULONG*)Reserved_func,
  221.  (ULONG*)Reserved_func,
  222. // ------------
  223.  
  224.  (ULONG*)ULONG_MAX
  225. };
  226.  
  227.  
  228.  
  229. /*----------------------------------
  230. -----------------------------------*/
  231. BOOL pLibMain(_R_LB pOS_ExecBase* exec,_R_A0 pOSp_DtLib* lib)
  232. {
  233. #ifdef __pOS_EXECPRECODE
  234.   extern struct pOS_ExecBase* gb_ExecBase;
  235.   extern struct pOS_ExecLibFunction* gb_ExecLib;
  236.  
  237.   gb_ExecBase=(struct pOS_ExecBase*)exec;
  238.   gb_ExecLib=*((struct pOS_ExecLibFunction**)lib->dl_Lib.lib_Segm->sel_Seg.seg_Reserved2);
  239.   gb_DosBase  =(pOS_DosBase*)pOS_OpenLibrary("pdos.library",0);
  240.   gb_UtilityBase=(pOS_UtilityBase*)pOS_OpenLibrary("putility.library",0);
  241. #else
  242.  #error hier fehlt etwas
  243. #endif
  244.  
  245. #ifdef __cplusplus
  246.   InitModules();
  247. #endif
  248.  
  249.   strcmp("",""); // Linker Dummy
  250.  
  251.   {
  252.     lib->dl_DtClass =
  253.        pOS_CreateClass("DtType/8svx.class",pOS_DTNAME_SAMPLE,NULL,
  254.                        (APTR)DtDispatcher,sizeof(pOSp_DtData),0);
  255.   }
  256.  
  257.   if(lib->dl_DtClass==NULL) {
  258.     pOS_CloseLibrary((pOS_Library*)gb_DosBase);
  259.     pOS_CloseLibrary((pOS_Library*)gb_UtilityBase);
  260. #ifdef __cplusplus
  261.     CleanupModules();
  262. #endif
  263.   }
  264.   return(lib->dl_DtClass!=NULL);
  265. }
  266.  
  267. /*******************************************************************************/
  268. typedef ULONG(*AFunc)(pOSp_DtData*,const pOS_DClassInfo*,
  269.                       const pOS_TagItem*,pOS_FileHandle*,APTR);
  270.  
  271.  
  272. /*----------------------------------------
  273. ---------------------------------------*/
  274. VOID D1Unpack(const SBYTE *source,size_t n,SBYTE *dest)
  275. {
  276.   static const SBYTE codeToDelta[16] = {-34,-21,-13,-8,-5,-3,-2,-1,0,1,2,3,5,8,13,21};
  277.   UBYTE d;
  278.   SBYTE x;
  279.  
  280.   source++; // Pad-Byte
  281.   x=*source++;
  282.   n=(n-2)/2;
  283.  
  284.   for(; n>0; --n) {
  285.     d = *source++;
  286.  
  287.     x += codeToDelta[d>>4];
  288.     *dest++ = x;
  289.  
  290.     x += codeToDelta[d & 0x0f];
  291.     *dest++ = x;
  292.   }
  293. }
  294.  
  295.  
  296. /*----------------------------------
  297. -----------------------------------*/
  298. ULONG DtStdFunc(pOSp_DtData *obj,const pOS_DClassInfo* dci,const pOS_TagItem* tags,
  299.                 AFunc func)
  300. {
  301.   ULONG ret=0;
  302.  
  303.   switch(dci->dci_Flags & DCLINFOF_HandleMask) {
  304.  
  305.     case DCLINFOF_FileName:
  306.       {
  307.         pOS_FileHandle *FH;
  308.  
  309.         if(FH=pOS_OpenFile(NULL,dci->dci_U.dci_FileName,FILEHDMOD_Read)) {
  310.           ret=(*func)(obj,dci,tags,FH,dci->dci_Format ? dci->dci_Data:NULL);
  311.           pOS_CloseFile(FH);
  312.         }
  313.       }
  314.       break;
  315.  
  316.     case DCLINFOF_FH:
  317.       ret=(*func)(obj,dci,tags,dci->dci_U.dci_FH,dci->dci_Format ? dci->dci_Data:NULL);
  318.       break;
  319.   }
  320.  
  321.   return(ret);
  322. }
  323.  
  324.  
  325. /*----------------------------------
  326. -----------------------------------*/
  327. size_t GetSampleSize(const pOSp_DtData* obj)
  328. {
  329.   BOOL M1=(obj->VH.repeatHiSamples==0);
  330.   return( M1 ? obj->VH.oneShotHiSamples : obj->VH.repeatHiSamples );
  331. }
  332.  
  333. /*----------------------------------
  334. -----------------------------------*/
  335. VOID GetInfoData(const pOSp_DtData* obj,pOS_DtTypeSample* data)
  336. {
  337.   data->dtsmp_ID[0]='8';
  338.   data->dtsmp_ID[1]='S';
  339.   data->dtsmp_ID[2]='V';
  340.   data->dtsmp_ID[3]='X';
  341.   data->dtsmp_ID[4]='\0';
  342.  
  343.   data->dtsmp_AudioMapType=AUDIOMAPTYP_Std8Bit;
  344.   data->dtsmp_Compression  = obj->VH.sCompression;
  345.   data->dtsmp_Volume       = (obj->VH.volume & 0x3f)<<10;
  346.   data->dtsmp_Cycles       = obj->VH.samplesPerHiCycle;
  347.   data->dtsmp_Frames       = 1;
  348.   data->dtsmp_Frequence    = obj->VH.samplesPerSec;
  349.   data->dtsmp_Length       = GetSampleSize(obj);
  350.  
  351.   if(data->dtsmp_Volume==0) data->dtsmp_Volume=0xffff;
  352.   if(data->dtsmp_Cycles==0) data->dtsmp_Cycles=1;
  353. }
  354.  
  355.  
  356.  
  357. /*----------------------------------
  358. -----------------------------------*/
  359. ULONG DtObtainFile_func(pOSp_DtData* obj,const pOS_DClassInfo* dci,
  360.                const pOS_TagItem *tags,pOS_FileHandle* fh,APTR data)
  361. {
  362.   UBYTE Buffer[12];
  363.   ULONG Res=DCLMTHR_None;
  364.  
  365.   pOS_ReadFile(fh,Buffer,12);
  366.   if(    *((ULONG*)&Buffer[0]) == MAKE_ID('F','O','R','M')
  367.       && *((ULONG*)&Buffer[8]) == MAKE_ID('8','S','V','X'))
  368.   {
  369.     pOS_ReadFile(fh,Buffer,8);
  370.     if( *((ULONG*)&Buffer[0]) == MAKE_ID('V','H','D','R') ) {
  371.       if(sizeof(obj->VH)==pOS_ReadFile(fh,&obj->VH,sizeof(obj->VH))) {
  372.         if(data) GetInfoData(obj,(pOS_DtTypeSample*)data);
  373.         Res=DCLMTHR_Match;
  374.       }
  375.     }
  376.   }
  377.   return(Res);
  378. }
  379.  
  380.  
  381. /*----------------------------------
  382. -----------------------------------*/
  383. ULONG DtLoadFile_func(pOSp_DtData* obj,const pOS_DClassInfo* dci,
  384.                const pOS_TagItem *tags,pOS_FileHandle* fh,APTR data)
  385. {
  386.   UBYTE Buffer[8];
  387.   ULONG Res=DCLMTHR_None;
  388.  
  389.   DtDispose(obj);
  390.  
  391.   Res=DtObtainFile_func(obj,dci,tags,fh,data);
  392.   if(Res & DCLMTHR_Match) {
  393.     UWORD Anz;
  394.  
  395.     for(Anz=16 ;Anz>0; --Anz) {
  396.       if(8 != pOS_ReadFile(fh,Buffer,8) ) break;
  397.  
  398.       if( *((ULONG*)&Buffer[0]) == MAKE_ID('B','O','D','Y') ) {
  399.         obj->BodySize=*((ULONG*)&Buffer[4]);
  400.         if(obj->BodySize!=0) {
  401.           obj->Body=(UBYTE*)pOS_AllocMem(obj->BodySize,MEMF_PUBLIC|MEMF_VMEM);
  402.           if(obj->Body) {
  403.             pOS_ReadFile(fh,obj->Body,obj->BodySize);
  404.             Res |= DCLMTHR_Ok;
  405.           }
  406.         }
  407.         break;
  408.       }
  409.       else pOS_SeekFile(fh,*((ULONG*)&Buffer[4]),FILEHDSEK_Current);
  410.     }
  411.   }
  412.   return(Res);
  413. }
  414.  
  415.  
  416. /*----------------------------------
  417. -----------------------------------*/
  418. ULONG DtRead(const pOSp_DtData* obj,const pOS_DClassInfo* dci,
  419.              const pOS_TagItem *tags,pOS_DtTypeSampleFrame* fra)
  420. {
  421.   ULONG Res=0;
  422.  
  423.   if(obj->Body) {
  424.     pOS_Std8AudioMap *const Map=(pOS_Std8AudioMap*)fra->dtsmpf_AudioMap;
  425.     size_t Len=GetSampleSize(obj);
  426.     if(Map
  427.       && Map->bam_Audio.am_Type==AUDIOMAPTYP_Std8Bit
  428.       && (fra->dtsmpf_Length==0 || fra->dtsmpf_Length==Len) )
  429.     {
  430.       if(Len>Map->bam_Length) Len=Map->bam_Length;
  431.       if(obj->VH.sCompression==0) {
  432.         memcpy(Map->bam_Sample,obj->Body,Len);
  433.         Res=DCLMTHR_Ok;
  434.       }
  435.       else if(obj->VH.sCompression==1) {
  436.         D1Unpack(obj->Body,Len,Map->bam_Sample);
  437.         Res=DCLMTHR_Ok;
  438.       }
  439.     }
  440.     else Res=DCLMTHR_Warn;
  441.   }
  442.   return(Res);
  443. }
  444.  
  445.  
  446.  
  447.  
  448. /*----------------------------------
  449. -----------------------------------*/
  450. VOID DtDispose(pOSp_DtData* obj)
  451. {
  452.   if(obj->Body) {
  453.     pOS_FreeMem(obj->Body,obj->BodySize);
  454.     obj->Body=NULL;
  455.   }
  456. }
  457.  
  458.  
  459. /*----------------------------------
  460. -----------------------------------*/
  461. ULONG DtDispatcher(_R_LB pOS_ExecBase* exec,_R_A0 const pOS_Class* cl,
  462.                    _R_A1 pOSp_DtData *obj,_R_A2 pOS_DtTypeMethod* mth)
  463. {
  464.   const pOS_DClassInfo* DC;
  465.   ULONG ret=0;
  466.  
  467.   switch(mth->dtth_Method) {
  468. // -----
  469.     case DCLMTH_New:
  470.       break;
  471.  
  472.     case DCLMTH_XObtain:
  473.       DC=mth->dtth_U.dtth_Obtain.dtob_Info;
  474.       if( (DC->dci_Flags & DCLINFOF_HandleMask)!=DCLINFOF_None) {
  475.         if(DC->dci_Format==NULL || stricmp(DC->dci_Format,pOS_DTFORM_SAMPLE)==0) {
  476.           ret=DtStdFunc(obj,DC,mth->dtth_U.dtth_Obtain.dtob_Tags,DtObtainFile_func);
  477.         }
  478.       }
  479.       else if(obj->Body!=NULL && DC->dci_Data) {
  480.         GetInfoData(obj,(pOS_DtTypeSample*)DC->dci_Data);
  481.         ret=DCLMTHR_Ok | DCLMTHR_Match;
  482.       }
  483.       break;
  484.  
  485.     case DCLMTH_XLoad:
  486.       DC=mth->dtth_U.dtth_Load.dtld_Info;
  487.       if(stricmp(DC->dci_Format,pOS_DTFORM_SAMPLE)==0) {
  488.         ret=DtStdFunc(obj,DC,mth->dtth_U.dtth_Load.dtld_Tags,DtLoadFile_func);
  489.       }
  490.       else ret=pOS_DoAbsMethodA(cl,obj,(pOS_Method*)mth);
  491.       break;
  492.  
  493.     case DCLMTH_XRead:
  494.       DC=mth->dtth_U.dtth_Load.dtld_Info;
  495.       ret=DtRead(obj,DC,mth->dtth_U.dtth_Read.dtrd_Tags,
  496.                  (pOS_DtTypeSampleFrame*)mth->dtth_U.dtth_Read.dtrd_Data);
  497.       break;
  498.  
  499.     case DCLMTH_Dispose:
  500.       DtDispose(obj);
  501.       ret=pOS_DoAbsMethodA(cl,obj,(pOS_Method*)mth);
  502.       break;
  503.  
  504.     default: ret=pOS_DoAbsMethodA(cl,obj,(pOS_Method*)mth);
  505.   }
  506.  
  507.   return(ret);
  508. }
  509.  
  510.