home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 24 / CD_ASCQ_24_0995.iso / dos / prg / dsik205 / dsik.dat / SOURCE / MODLOAD.C < prev    next >
C/C++ Source or Header  |  1995-04-10  |  14KB  |  498 lines

  1. /****************************************************************************
  2. *
  3. *                   Digital Sound Interface Kit (DSIK)
  4. *                            Version 2.00
  5. *
  6. *                           by Carlos Hasan
  7. *
  8. * Filename:     modload.c
  9. * Version:      Revision 1.0
  10. *
  11. * Language:     WATCOM C
  12. * Environment:  IBM PC (DOS/4GW)
  13. *
  14. * Description:  File loading routines for module and sample files.
  15. *
  16. * Revision History:
  17. * ----------------
  18. *
  19. * Revision 1.0  94/09/24  16:57:58  chv
  20. * Initial revision
  21. *
  22. ****************************************************************************/
  23.  
  24. #include <io.h>
  25. #include <fcntl.h>
  26. #include <malloc.h>
  27. #include "audio.h"
  28.  
  29. int dError;
  30. char *dErrorMsg[] = {
  31.     "Ok",
  32.     "Invalid or unsupported file format",
  33.     "Unable to open file",
  34.     "File is corrupted",
  35.     "Not enough system memory",
  36.     "Not enough soundcard memory" };
  37.  
  38.  
  39. /****************************************************************************
  40. *
  41. * Function:     LoadSample
  42. * Parameters:   Handle  - file handle
  43. *               Length  - sample block length
  44. *
  45. * Returns:      Sample structure containing the WAVE digital sample
  46. *               or NULL when an error has occurred.
  47. *
  48. * Description:  Used to load RIFF/DSMF sample blocks.
  49. *
  50. ****************************************************************************/
  51.  
  52. static Sample *LoadSample(int Handle, long Length)
  53. {
  54.     Sample *SampPtr;
  55.     void *DataPtr;
  56.  
  57.     if (!(SampPtr = (Sample*)malloc(sizeof(Sample)))) {
  58.         dError = ERR_NOMEM;
  59.         return NULL;
  60.     }
  61.     if (read(Handle,SampPtr,sizeof(Sample)) != sizeof(Sample)) {
  62.         dError = ERR_FILEIO;
  63.         free(SampPtr);
  64.         return NULL;
  65.     }
  66.     if (!SampPtr->Length || (SampPtr->Flags & SF_LIBRARY)) {
  67.         SampPtr->DataPtr = NULL;
  68.         return SampPtr;
  69.     }
  70.     if (!(DataPtr = SampPtr->DataPtr = malloc(SampPtr->Length))) {
  71.         dError = ERR_NOMEM;
  72.         free(SampPtr);
  73.         return NULL;
  74.     }
  75.     if (read(Handle,SampPtr->DataPtr,SampPtr->Length) != SampPtr->Length) {
  76.         dError = ERR_FILEIO;
  77.         free(DataPtr);
  78.         free(SampPtr);
  79.         return NULL;
  80.     }
  81.     if (!dMemAlloc(SampPtr)) {
  82.         dError = ERR_NODRAM;
  83.         free(DataPtr);
  84.         free(SampPtr);
  85.         return NULL;
  86.     }
  87.     if (dGetDriverFlags() & AF_DRAM) {
  88.         free(DataPtr);
  89.     }
  90.     if (!(SampPtr->Flags & SF_LOOPED)) {
  91.         SampPtr->LoopStart = SampPtr->LoopEnd = SampPtr->Length;
  92.     }
  93.     return SampPtr;
  94. }
  95.  
  96.  
  97. /****************************************************************************
  98. *
  99. * Function:     FreeSample
  100. * Parameters:   SampPtr - Sample structure pointer
  101. *
  102. * Description:  Releases memory used by digital samples.
  103. *
  104. ****************************************************************************/
  105.  
  106. static void FreeSample(Sample *SampPtr)
  107. {
  108.     if (SampPtr) {
  109.         if (SampPtr->DataPtr && !(SampPtr->Flags & SF_LIBRARY)) {
  110.             dMemFree(SampPtr);
  111.             if (!(dGetDriverFlags() & AF_DRAM))
  112.                 free(SampPtr->DataPtr);
  113.         }
  114.         free(SampPtr);
  115.     }
  116. }
  117.  
  118.  
  119. /****************************************************************************
  120. *
  121. * Function:     LoadPattern
  122. * Parameters:   Handle  - file handle
  123. *               Length  - RIFF pattern block length
  124. *
  125. * Returns:      Pattern structure containing the music pattern data
  126. *               or NULL when an error has occurred.
  127. *
  128. * Description:  Used to load RIFF/DSMF pattern blocks.
  129. *
  130. ****************************************************************************/
  131.  
  132. static Pattern *LoadPattern(int Handle, long Length)
  133. {
  134.     Pattern *PattPtr;
  135.  
  136.     if (!(PattPtr = (Pattern*)malloc(Length))) {
  137.         dError = ERR_NOMEM;
  138.         return NULL;
  139.     }
  140.     if (read(Handle,PattPtr,Length) != Length) {
  141.         dError = ERR_FILEIO;
  142.         free(PattPtr);
  143.         return NULL;
  144.     }
  145.     return PattPtr;
  146. }
  147.  
  148.  
  149. /****************************************************************************
  150. *
  151. * Function:     FreePattern
  152. * Parameters:   PattPtr - pattern data pointer
  153. *
  154. * Description:  Releases memory used by the patterns.
  155. *
  156. ****************************************************************************/
  157.  
  158. static void FreePattern(Pattern *PattPtr)
  159. {
  160.     if (PattPtr) free(PattPtr);
  161. }
  162.  
  163.  
  164. /****************************************************************************
  165. *
  166. * Function:     dLoadModuleFile
  167. * Parameters:   Handle      - DOS file handle
  168. *               Length      - file length
  169. *
  170. * Returns:      Music module address or NULL when an error has occurred
  171. *               while loading the file.
  172. *
  173. * Description:  Load RIFF/DSMF music modules from disk.
  174. *
  175. ****************************************************************************/
  176.  
  177. DSM *dLoadModuleFile(int Handle, long Length)
  178. {
  179.     RiffHeader Header;
  180.     RiffBlock Block;
  181.     DSM *Module;
  182.     Sample *SampPtr;
  183.     int SampNum, PattNum;
  184.  
  185.     if (!(Module = (DSM*)calloc(1,sizeof(DSM)))) {
  186.         dError = ERR_NOMEM;
  187.         return NULL;
  188.     }
  189.     SampNum = PattNum = 0;
  190.  
  191.     if (read(Handle,&Header,sizeof(Header)) != sizeof(Header)) {
  192.         dError = ERR_FILEIO;
  193.         dFreeModule(Module);
  194.         return NULL;
  195.     }
  196.     if (Header.ID != ID_RIFF || Header.Type != ID_DSMF) {
  197.         dError = ERR_FORMAT;
  198.         dFreeModule(Module);
  199.         return NULL;
  200.     }
  201.     Header.Length -= sizeof(Header.Type);
  202.     if ((sizeof(Header) + Header.Length) > Length) {
  203.         dError = ERR_FORMAT;
  204.         dFreeModule(Module);
  205.         return NULL;
  206.     }
  207.     while (Header.Length) {
  208.         if (read(Handle,&Block,sizeof(Block)) != sizeof(Block)) {
  209.             dError = ERR_FILEIO;
  210.             dFreeModule(Module);
  211.             return NULL;
  212.         }
  213.         Header.Length -= sizeof(Block) + Block.Length;
  214.         if (Block.ID == ID_SONG) {
  215.             if (read(Handle,&Module->Header,Block.Length) != Block.Length) {
  216.                 dError = ERR_FILEIO;
  217.                 dFreeModule(Module);
  218.                 return NULL;
  219.             }
  220.             Module->Samples = (Sample**)calloc(Module->Header.NumSamples,sizeof(Sample *));
  221.             Module->Patterns = (Pattern**)calloc(Module->Header.NumPatterns,sizeof(Pattern *));
  222.             if (!(Module->Samples && Module->Patterns)) {
  223.                 dError = ERR_NOMEM;
  224.                 dFreeModule(Module);
  225.                 return NULL;
  226.             }
  227.         }
  228.         else if (Block.ID == ID_INST) {
  229.             if (SampNum >= Module->Header.NumSamples) {
  230.                 dError = ERR_FORMAT;
  231.                 dFreeModule(Module);
  232.                 return NULL;
  233.             }
  234.             if (!(Module->Samples[SampNum++] =
  235.                     LoadSample(Handle,Block.Length))) {
  236.                 dFreeModule(Module);
  237.                 return NULL;
  238.             }
  239.         }
  240.         else if (Block.ID == ID_PATT) {
  241.             if (PattNum >= Module->Header.NumPatterns) {
  242.                 dError = ERR_FORMAT;
  243.                 dFreeModule(Module);
  244.                 return NULL;
  245.             }
  246.             if (!(Module->Patterns[PattNum++] =
  247.                     LoadPattern(Handle,Block.Length))) {
  248.                 dFreeModule(Module);
  249.                 return NULL;
  250.             }
  251.         }
  252.         else {
  253.             if (lseek(Handle,Block.Length,SEEK_CUR) < 0) {
  254.                 dError = ERR_FILEIO;
  255.                 dFreeModule(Module);
  256.                 return NULL;
  257.             }
  258.         }
  259.     }
  260.     return Module;
  261. }
  262.  
  263.  
  264. /****************************************************************************
  265. *
  266. * Function:     dFreeModule
  267. * Parameters:   Module  - music module pointer
  268. *
  269. * Description:  Releases all the resources used by the music module.
  270. *
  271. ****************************************************************************/
  272.  
  273. void dFreeModule(DSM *Module)
  274. {
  275.     int Index;
  276.  
  277.     if (Module) {
  278.         if (Module->Samples) {
  279.             for (Index = 0; Index < Module->Header.NumSamples; Index++)
  280.                 if (Module->Samples[Index])
  281.                     FreeSample(Module->Samples[Index]);
  282.             free(Module->Samples);
  283.         }
  284.         if (Module->Patterns) {
  285.             for (Index = 0; Index < Module->Header.NumPatterns; Index++)
  286.                 if (Module->Patterns[Index])
  287.                     FreePattern(Module->Patterns[Index]);
  288.             free(Module->Patterns);
  289.         }
  290.         free(Module);
  291.     }
  292. }
  293.  
  294.  
  295. /****************************************************************************
  296. *
  297. * Function:     dLoadSampleFile
  298. * Parameters:   Handle  - file handle
  299. *               Length  - sample length
  300. *
  301. * Returns:      Sample structure containing the WAVE digital sample
  302. *               or NULL when an error has occurred.
  303. *
  304. * Description:  Used to load RIFF/WAVE sample files.
  305. *
  306. ****************************************************************************/
  307.  
  308. Sample *dLoadSampleFile(int Handle, long Length)
  309. {
  310.     Sample *SampPtr;
  311.     void *DataPtr;
  312.     struct {
  313.         RiffHeader Hdr;
  314.         RiffBlock Fmt;
  315.         WaveFmt F;
  316.         RiffBlock Data;
  317.     } Wave;
  318.  
  319.     if (read(Handle,&Wave,sizeof(Wave)) != sizeof(Wave)) {
  320.         dError = ERR_FILEIO;
  321.         return NULL;
  322.     }
  323.     if (Wave.Hdr.ID != ID_RIFF || Wave.Hdr.Type != ID_WAVE ||
  324.             Wave.Fmt.ID != ID_FMT || Wave.Data.ID != ID_DATA ||
  325.             Wave.F.Format != WAVE_FMT_PCM || Wave.F.Channels != 1 ||
  326.             Wave.F.BitsPerSample != 8 ||
  327.             (sizeof(RiffBlock) + Wave.Hdr.Length) > Length) {
  328.         dError = ERR_FORMAT;
  329.         return NULL;
  330.     }
  331.     if (!(SampPtr = (Sample*)calloc(1,sizeof(Sample)))) {
  332.         dError = ERR_NOMEM;
  333.         return NULL;
  334.     }
  335.     SampPtr->Flags = SF_8BITS | SF_UNSIGNED;
  336.     SampPtr->Volume = 64;
  337.     SampPtr->Length = SampPtr->LoopStart = SampPtr->LoopEnd = Wave.Data.Length;
  338.     SampPtr->DataPtr = NULL;
  339.     SampPtr->Rate = Wave.F.SampleRate;
  340.     if (!SampPtr->Length) {
  341.         return SampPtr;
  342.     }
  343.     if (!(SampPtr->DataPtr = DataPtr = malloc(SampPtr->Length))) {
  344.         dError = ERR_NOMEM;
  345.         free(SampPtr);
  346.         return NULL;
  347.     }
  348.     if (read(Handle,DataPtr,SampPtr->Length) != SampPtr->Length) {
  349.         dError = ERR_FILEIO;
  350.         free(DataPtr);
  351.         free(SampPtr);
  352.         return NULL;
  353.     }
  354.     if (!dMemAlloc(SampPtr)) {
  355.         dError = ERR_NODRAM;
  356.         free(DataPtr);
  357.         free(SampPtr);
  358.         return NULL;
  359.     }
  360.     if (dGetDriverFlags() & AF_DRAM) {
  361.         free(DataPtr);
  362.     }
  363.     return SampPtr;
  364. }
  365.  
  366.  
  367. /****************************************************************************
  368. *
  369. * Function:     dFreeSample
  370. * Parameters:   SampPtr - Sample pointer
  371. *
  372. * Description:  Releases the memory used by a WAVE sample.
  373. *
  374. ****************************************************************************/
  375.  
  376. void dFreeSample(Sample *SampPtr)
  377. {
  378.     FreeSample(SampPtr);
  379. }
  380.  
  381.  
  382. /****************************************************************************
  383. *
  384. * Function:     dLoadModule
  385. * Parameters:   Filename    - music module path filename
  386. *
  387. * Returns:      Music module address or NULL when an error has occurred
  388. *               while loading the file.
  389. *
  390. * Description:  Load RIFF/DSMF music modules from disk.
  391. *
  392. ****************************************************************************/
  393.  
  394. DSM *dLoadModule(char *Filename)
  395. {
  396.     int Handle;
  397.     long Length;
  398.     DSM *Module;
  399.  
  400.     if ((Handle = open(Filename,O_RDONLY|O_BINARY)) < 0) {
  401.         dError = ERR_NOFILE;
  402.         return NULL;
  403.     }
  404.     if ((Length = filelength(Handle)) < 0) {
  405.         dError = ERR_FILEIO;
  406.         close(Handle);
  407.         return NULL;
  408.     }
  409.     Module = dLoadModuleFile(Handle,Length);
  410.     close(Handle);
  411.     return Module;
  412. }
  413.  
  414.  
  415. /****************************************************************************
  416. *
  417. * Function:     dLoadSample
  418. * Parameters:   Filename    - music module path filename
  419. *
  420. * Returns:      Music module address or NULL when an error has occurred
  421. *               while loading the file.
  422. *
  423. * Description:  Load RIFF/WAVE sample files from disk.
  424. *
  425. ****************************************************************************/
  426.  
  427. Sample *dLoadSample(char *Filename)
  428. {
  429.     int Handle;
  430.     long Length;
  431.     Sample *SampPtr;
  432.  
  433.     if ((Handle = open(Filename,O_RDONLY|O_BINARY)) < 0) {
  434.         dError = ERR_NOFILE;
  435.         return NULL;
  436.     }
  437.     if ((Length = filelength(Handle)) < 0) {
  438.         dError = ERR_FILEIO;
  439.         close(Handle);
  440.         return NULL;
  441.     }
  442.     SampPtr = dLoadSampleFile(Handle,Length);
  443.     close(Handle);
  444.     return SampPtr;
  445. }
  446.  
  447.  
  448. /****************************************************************************
  449. *
  450. * Function:     dLoadSetup
  451. * Parameters:   SC          - soundcard structure
  452. *               Filename    - full config path filename
  453. *
  454. * Returns:      Zero value on success.
  455. *
  456. * Description:  Load the soundcard configuration parameters.
  457. *
  458. ****************************************************************************/
  459.  
  460. int dLoadSetup(SoundCard *SC, char *Filename)
  461. {
  462.     int Handle;
  463.     if ((Handle = open(Filename,O_RDONLY|O_BINARY)) < 0)
  464.         return 1;
  465.     if (read(Handle,SC,sizeof(SoundCard)) != sizeof(SoundCard)) {
  466.         close(Handle);
  467.         return 1;
  468.     }
  469.     close(Handle);
  470.     return 0;
  471. }
  472.  
  473.  
  474. /****************************************************************************
  475. *
  476. * Function:     dSaveSetup
  477. * Parameters:   SC          - soundcard structure
  478. *               Filename    - full config path filename
  479. *
  480. * Returns:      Zero value on success.
  481. *
  482. * Description:  Save the soundcard configuration parameters.
  483. *
  484. ****************************************************************************/
  485.  
  486. int dSaveSetup(SoundCard *SC, char *Filename)
  487. {
  488.     int Handle;
  489.     if ((Handle = open(Filename,O_CREAT|O_WRONLY|O_BINARY,S_IRWXU)) < 0)
  490.         return 1;
  491.     if (write(Handle,SC,sizeof(SoundCard)) != sizeof(SoundCard)) {
  492.         close(Handle);
  493.         return 1;
  494.     }
  495.     close(Handle);
  496.     return 0;
  497. }
  498.