drv_aiff.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:10k
源码类别:

Windows CE

开发平台:

C/C++

  1. /* MikMod sound library
  2.     (c) 2004, Raphael Assenat
  3. (c) 1998, 1999, 2000 Miodrag Vallat and others - see file AUTHORS for
  4. complete list.
  5. This library is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU Library General Public License as
  7. published by the Free Software Foundation; either version 2 of
  8. the License, or (at your option) any later version.
  9.  
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU Library General Public License for more details.
  14.  
  15. You should have received a copy of the GNU Library General Public
  16. License along with this library; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  18. 02111-1307, USA.
  19. */
  20. /*==============================================================================
  21.   $Id: drv_aiff.c,v 1.4 2004/02/20 22:08:33 raph Exp $
  22.   Driver for output to a file called MUSIC.AIFF [or .AIF on Windows].
  23. ==============================================================================*/
  24. /*
  25.         
  26. Written by Axel "awe" Wefers <awe@fruitz-of-dojo.de>
  27.    
  28. Raphael Assenat: 19 Feb 2004: Command line options documented in the MDRIVER structure,
  29.  and I added #if 0 's around pragmas, since gcc complaines about them. 
  30.  Hopefully, the IDE which uses them wont care about that?
  31. */
  32. /*_______________________________________________________________________________________________iNCLUDES
  33. */
  34. #if 0
  35. #pragma mark INCLUDES
  36. #endif
  37. #ifdef HAVE_CONFIG_H
  38. #include "config.h"
  39. #endif
  40. #include "mikmod_internals.h"
  41. #ifdef DRV_AIFF
  42. #ifdef HAVE_UNISTD_H
  43. #include <unistd.h>
  44. #endif
  45. #include <stdio.h>
  46. #include <math.h> /* required for IEEE extended conversion */
  47. #if 0
  48. #pragma mark -
  49. #endif
  50. /*________________________________________________________________________________________________dEFINES
  51. */
  52. #if 0
  53. #pragma mark DEFINES
  54. #endif
  55. #define AIFF_BUFFERSIZE 32768
  56. #if defined(WIN32) || defined(DJGPP)
  57. #define AIFF_FILENAME "music.aif"
  58. #else
  59. #define AIFF_FILENAME "music.aiff"
  60. #endif /* WIN32 */
  61. #if 0
  62. #pragma mark -
  63. #endif
  64. /*_________________________________________________________________________________________________mACROS
  65. */
  66. #if 0
  67. #pragma mark MACROS
  68. #endif
  69. #define AIFF_FLOAT_TO_UNSIGNED(f)     ((unsigned long)(((long)(f - 2147483648.0)) + 2147483647L + 1))
  70. #if 0
  71. #pragma mark -
  72. #endif
  73. /*___________________________________________________________________________________________________vARS
  74. */
  75. #if 0 
  76. #pragma mark VARIABLES
  77. #endif
  78. static MWRITER *gAiffOut = NULL;
  79. static FILE *gAiffFile = NULL;
  80. static SBYTE *gAiffAudioBuffer = NULL;
  81. static CHAR *gAiffFileName = NULL;
  82. static ULONG gAiffDumpSize = 0;
  83. #if 0
  84. #pragma mark -
  85. #endif
  86. /*____________________________________________________________________________________fUNCTION_pROTOTYPES
  87. */
  88. #if 0
  89. #pragma mark FUNCTION PROTOTYPES
  90. #endif
  91. #ifdef SUNOS
  92. extern int fclose(FILE *);
  93. #endif
  94. static void AIFF_ConvertToIeeeExtended (double theValue, char *theBytes);
  95. static void AIFF_PutHeader (void);
  96. static void AIFF_CommandLine (CHAR *theCmdLine);
  97. static BOOL AIFF_IsThere (void);
  98. static BOOL AIFF_Init (void);
  99. static void AIFF_Exit (void);
  100. static void AIFF_Update (void);
  101. #if 0
  102. #pragma mark -
  103. #endif
  104. /*___________________________________________________________________________AIFF_ConvertToIeeeExtended()
  105. */
  106. void AIFF_ConvertToIeeeExtended (double theValue, char *theBytes)
  107. {
  108.     int mySign;
  109.     int myExponent;
  110.     double myFMant, myFsMant;
  111.     unsigned long myHiMant, myLoMant;
  112.     if (theValue < 0)
  113.     {
  114.         mySign = 0x8000;
  115.         theValue *= -1;
  116.     } else
  117.     {
  118.         mySign = 0;
  119.     }
  120.     if (theValue == 0)
  121.     {
  122.         myExponent = 0;
  123.         myHiMant = 0;
  124.         myLoMant = 0;
  125.     }
  126.     else
  127.     {
  128.         myFMant = frexp (theValue, &myExponent);
  129.         if ((myExponent > 16384) || !(myFMant < 1))
  130.         {
  131.             myExponent = mySign | 0x7FFF;
  132.             myHiMant = 0;
  133.             myLoMant = 0;
  134.         }
  135.         else
  136.         {
  137.             myExponent += 16382;
  138.             if (myExponent < 0)
  139.             {
  140.                 myFMant = ldexp (myFMant, myExponent);
  141.                 myExponent = 0;
  142.             }
  143.             myExponent |= mySign;
  144.             myFMant = ldexp (myFMant, 32);          
  145.             myFsMant = floor (myFMant); 
  146.             myHiMant = AIFF_FLOAT_TO_UNSIGNED (myFsMant);
  147.             myFMant = ldexp (myFMant - myFsMant, 32); 
  148.             myFsMant = floor (myFMant); 
  149.             myLoMant = AIFF_FLOAT_TO_UNSIGNED (myFsMant);
  150.         }
  151.     }
  152.     
  153.     theBytes[0] = myExponent >> 8;
  154.     theBytes[1] = myExponent;
  155.     theBytes[2] = myHiMant >> 24;
  156.     theBytes[3] = myHiMant >> 16;
  157.     theBytes[4] = myHiMant >> 8;
  158.     theBytes[5] = myHiMant;
  159.     theBytes[6] = myLoMant >> 24;
  160.     theBytes[7] = myLoMant >> 16;
  161.     theBytes[8] = myLoMant >> 8;
  162.     theBytes[9] = myLoMant;
  163. }
  164. /*_______________________________________________________________________________________AIFF_PutHeader()
  165. */
  166. static void AIFF_PutHeader(void)
  167. {
  168.     ULONG myFrames;
  169.     UBYTE myIEEE[10];
  170.     
  171.     myFrames = gAiffDumpSize / (((md_mode&DMODE_STEREO) ? 2 : 1) * ((md_mode & DMODE_16BITS) ? 2 : 1));
  172.     AIFF_ConvertToIeeeExtended ((double) md_mixfreq, myIEEE);
  173.     _mm_fseek (gAiffOut, 0, SEEK_SET);
  174.     _mm_write_string  ("FORM", gAiffOut); /* chunk 'FORM' */
  175.     _mm_write_M_ULONG (gAiffDumpSize + 36, gAiffOut); /* length of the file */
  176.     _mm_write_string  ("AIFFCOMM", gAiffOut); /* chunk 'AIFF', 'COMM' */
  177.     _mm_write_M_ULONG (18, gAiffOut); /* length of this AIFF block */
  178.     _mm_write_M_UWORD ((md_mode & DMODE_STEREO) ? 2 : 1, gAiffOut); /* channels */
  179.     _mm_write_M_ULONG (myFrames, gAiffOut); /* frames = freq * secs */
  180.     _mm_write_M_UWORD ((md_mode & DMODE_16BITS) ? 16 : 8, gAiffOut); /* bits per sample */
  181.     _mm_write_UBYTES  (myIEEE, 10, gAiffOut); /* frequency [IEEE extended] */
  182.     _mm_write_string  ("SSND", gAiffOut); /* data chunk 'SSND' */
  183.     _mm_write_M_ULONG (gAiffDumpSize, gAiffOut); /* data length */
  184.     _mm_write_M_ULONG (0, gAiffOut); /* data offset, always zero */
  185.     _mm_write_M_ULONG (0, gAiffOut); /* data blocksize, always zero */
  186. }
  187. /*_____________________________________________________________________________________AIFF_CommandLine()
  188. */
  189. static void AIFF_CommandLine (CHAR *theCmdLine)
  190. {
  191.     CHAR *myFileName = MD_GetAtom ("file", theCmdLine,0);
  192.     if (myFileName != NULL)
  193.     {
  194.         _mm_free (gAiffFileName);
  195.         gAiffFileName = myFileName;
  196.     }
  197. }
  198. /*_________________________________________________________________________________________AIFF_isThere()
  199. */
  200. static BOOL AIFF_IsThere (void)
  201. {
  202.     return (1);
  203. }
  204. /*____________________________________________________________________________________________AIFF_Init()
  205. */
  206. static BOOL AIFF_Init (void)
  207. {
  208. #if defined unix || (defined __APPLE__ && defined __MACH__)
  209.     if (!MD_Access (gAiffFileName ? gAiffFileName : AIFF_FILENAME))
  210.     {
  211.         _mm_errno=MMERR_OPENING_FILE;
  212.         return (1);
  213.     }
  214. #endif
  215.     if (!(gAiffFile = fopen (gAiffFileName ? gAiffFileName : AIFF_FILENAME, "wb")))
  216.     {
  217.         _mm_errno = MMERR_OPENING_FILE;
  218.         return (1);
  219.     }
  220.     if (!(gAiffOut =_mm_new_file_writer (gAiffFile)))
  221.     {
  222.         fclose (gAiffFile);
  223.         unlink(gAiffFileName ? gAiffFileName : AIFF_FILENAME);
  224.         gAiffFile = NULL;
  225.         return (1);
  226.     }
  227.     if (!(gAiffAudioBuffer = (SBYTE*) _mm_malloc (AIFF_BUFFERSIZE)))
  228.     {
  229.         _mm_delete_file_writer (gAiffOut);
  230.         fclose (gAiffFile);
  231.         unlink (gAiffFileName ? gAiffFileName : AIFF_FILENAME);
  232.         gAiffFile = NULL;
  233.         gAiffOut = NULL;
  234.         return 1;
  235.     }
  236.     md_mode|=DMODE_SOFT_MUSIC|DMODE_SOFT_SNDFX;
  237.     if (VC_Init ())
  238.     {
  239.         _mm_delete_file_writer (gAiffOut);
  240.         fclose (gAiffFile);
  241.         unlink (gAiffFileName ? gAiffFileName : AIFF_FILENAME);
  242.         gAiffFile = NULL;
  243.         gAiffOut = NULL;
  244.         return 1;
  245.     }
  246.     
  247.     gAiffDumpSize = 0;
  248.     AIFF_PutHeader ();
  249.     return (0);
  250. }
  251. /*____________________________________________________________________________________________AIFF_Exit()
  252. */
  253. static void AIFF_Exit (void)
  254. {
  255.     VC_Exit ();
  256.     /* write in the actual sizes now */
  257.     if (gAiffOut != NULL)
  258.     {
  259.         AIFF_PutHeader ();
  260.         _mm_delete_file_writer (gAiffOut);
  261.         fclose (gAiffFile);
  262.         gAiffFile = NULL;
  263.         gAiffOut = NULL;
  264.     }
  265.     if (gAiffAudioBuffer != NULL)
  266.     {
  267.         free (gAiffAudioBuffer);
  268.         gAiffAudioBuffer = NULL;
  269.     }
  270. }
  271. /*__________________________________________________________________________________________AIFF_Update()
  272. */
  273. static void AIFF_Update (void)
  274. {
  275.     ULONG myByteCount;
  276.     myByteCount = VC_WriteBytes (gAiffAudioBuffer, AIFF_BUFFERSIZE);
  277.     if (md_mode & DMODE_16BITS)
  278.     {
  279.         _mm_write_M_UWORDS ((UWORD *) gAiffAudioBuffer, myByteCount >> 1, gAiffOut);
  280.     }
  281.     else
  282.     {
  283.         ULONG i;
  284.         
  285.         for (i = 0; i < myByteCount; i++)
  286.         {
  287.             gAiffAudioBuffer[i] -= 0x80; /* convert to signed PCM */
  288.         }
  289.         _mm_write_UBYTES (gAiffAudioBuffer, myByteCount, gAiffOut);
  290.     }
  291.     gAiffDumpSize += myByteCount;
  292. }
  293. /*________________________________________________________________________________________________drv_osx
  294. */
  295. MIKMODAPI MDRIVER drv_aiff = {
  296.     NULL,
  297.     "Disk writer (aiff)",
  298.     "AIFF disk writer (music.aiff) v1.1",
  299.     0,255,
  300.     "aif",
  301. "file:t:music.aiff:Output file namen",
  302.     AIFF_CommandLine,
  303.     AIFF_IsThere,
  304.     VC_SampleLoad,
  305.     VC_SampleUnload,
  306.     VC_SampleSpace,
  307.     VC_SampleLength,
  308.     AIFF_Init,
  309.     AIFF_Exit,
  310.     NULL,
  311.     VC_SetNumVoices,
  312.     VC_PlayStart,
  313.     VC_PlayStop,
  314.     AIFF_Update,
  315.     NULL,
  316.     VC_VoiceSetVolume,
  317.     VC_VoiceGetVolume,
  318.     VC_VoiceSetFrequency,
  319.     VC_VoiceGetFrequency,
  320.     VC_VoiceSetPanning,
  321.     VC_VoiceGetPanning,
  322.     VC_VoicePlay,
  323.     VC_VoiceStop,
  324.     VC_VoiceStopped,
  325.     VC_VoiceGetPosition,
  326.     VC_VoiceRealVolume
  327. };
  328. #else
  329. MISSING(drv_aiff);
  330. #endif
  331. /*____________________________________________________________________________________________________eOF
  332. */