aifc.c
上传用户:xiejiait
上传日期:2007-01-06
资源大小:881k
文件大小:6k
源码类别:

SCSI/ASPI

开发平台:

MultiPlatform

  1. /* @(#)aifc.c 1.2 99/12/19 Copyright 1998,1999 Heiko Eissfeldt */
  2. #ifndef lint
  3. static char     sccsid[] =
  4. "@(#)aifc.c 1.2 99/12/19 Copyright 1998,1999 Heiko Eissfeldt";
  5. #endif
  6. /***
  7.  * CopyPolicy: GNU Public License 2 applies
  8.  * Copyright (C) by Heiko Eissfeldt
  9.  *
  10.  *
  11.  * ---------------------------------------------------------------------
  12.  *  definitions for aifc pcm output
  13.  * ---------------------------------------------------------------------
  14.  */
  15. #include "config.h"
  16. #include "mytype.h"
  17. #include <stdio.h>
  18. #include <standard.h>
  19. #if defined (HAVE_UNISTD_H) && (HAVE_UNISTD_H == 1)
  20. #include <sys/types.h>
  21. #include <unistd.h>
  22. #endif
  23. #include <string.h>
  24. #include "byteorder.h"
  25. #include "sndfile.h"
  26. typedef UINT4 FOURCC;    /* a four character code */
  27. typedef struct CHUNKHDR {
  28.   FOURCC ckid;          /* chunk ID */
  29.   UINT4 dwSize; /* chunk size */
  30. } CHUNKHDR;
  31. #define mmioFOURCC(ch0, ch1, ch2, ch3) 
  32.   ((UINT4)(unsigned char)(ch3) | ((UINT4)(unsigned char)(ch2) << 8) | 
  33.   ((UINT4)(unsigned char)(ch1) << 16) | ((UINT4)(unsigned char)(ch0) << 24))
  34. #define FOURCC_FORM     mmioFOURCC ('F', 'O', 'R', 'M')
  35. #define FOURCC_AIFC     mmioFOURCC ('A', 'I', 'F', 'C')
  36. #define FOURCC_FVER     mmioFOURCC ('F', 'V', 'E', 'R')
  37. #define FOURCC_COMM     mmioFOURCC ('C', 'O', 'M', 'M')
  38. #define FOURCC_NONE     mmioFOURCC ('N', 'O', 'N', 'E')
  39. #define FOURCC_SSND     mmioFOURCC ('S', 'S', 'N', 'D')
  40. #define NO_COMPRESSION "not compressed"
  41. /* brain dead construction from apple involving bigendian 80-bit doubles.
  42.    Definitely designed not to be portable. Alignment is a nightmare too. */
  43. typedef struct AIFCHDR {
  44.   CHUNKHDR formChk;
  45.   FOURCC formType;
  46.   CHUNKHDR fverChk; /* Version chunk */
  47.   UINT4 timestamp; /* timestamp identifies version */
  48.   CHUNKHDR commChk; /* Common chunk */
  49.   /* from now on, alignment prevents us from using the original types :-(( */
  50.   unsigned char numChannels[2]; /* Audio Channels */
  51.   unsigned char numSampleFrames[4]; /* # of samples */
  52.   unsigned char samplesize[2]; /* bits per sample */
  53.   unsigned char sample_rate[10]; /* sample rate in extended float */
  54.   unsigned char compressionType[4]; /* AIFC extension */
  55.   unsigned char compressionNameLen; /* AIFC extension */
  56.    char compressionName[sizeof(NO_COMPRESSION)]; /* AIFC extension */
  57.   unsigned char ssndChkid[4]; /* Sound data chunk */
  58.   unsigned char dwSize[4]; /* size of chunk */
  59.   unsigned char offset[4]; /* start of 1st sample */
  60.   unsigned char blocksize[4]; /* aligned sound data block size */
  61. } AIFCHDR;
  62. static AIFCHDR AifcHdr;
  63. /* format the sample rate into an
  64.    bigendian 10-byte IEEE-754 floating point number
  65.  */
  66. static int Format_samplerate __PR((unsigned long rate, unsigned char the_rate[10]));
  67. static int Format_samplerate(rate, the_rate)
  68.         unsigned long rate;
  69.         unsigned char the_rate[10];
  70. {
  71.   int i;
  72.   /* normalize rate */
  73.   for (i = 0; (rate & 0xffff) != 0; rate <<= 1, i++) {
  74.     if ((rate & 0x8000) != 0) {
  75.       break;
  76.     }
  77.   }
  78.   /* set exponent and sign */
  79.   the_rate[1] = 14-i;
  80.   the_rate[0] = 0x40; /* LSB = sign */
  81.   /* 16-bit part of mantisse for sample rate */
  82.   the_rate[3] = rate & 0xff;
  83.   the_rate[2] = (rate >> 8) & 0xff;
  84.   /* initialize lower digits of mantisse */
  85.   the_rate[4] = the_rate[5] = the_rate[6] =
  86.   the_rate[7] = the_rate[8] = the_rate[9] = 0;
  87.   return 0;
  88. }
  89. static int InitSound __PR(( int audio, long channels, unsigned long rate, long nBitsPerSample, unsigned long expected_bytes ));
  90. static int InitSound ( audio, channels, rate, nBitsPerSample, expected_bytes)
  91. int audio;
  92. long channels;
  93. unsigned long rate;
  94. long nBitsPerSample;
  95. unsigned long expected_bytes;
  96. {
  97.   UINT4 tmp;
  98.   fillbytes(&AifcHdr, sizeof(AifcHdr), '');
  99.   AifcHdr.formChk.ckid = cpu_to_be32(FOURCC_FORM);
  100.   AifcHdr.formChk.dwSize= cpu_to_be32(expected_bytes +
  101.                         offset_of(AIFCHDR,blocksize)+sizeof(AifcHdr.blocksize)
  102. - offsetof(AIFCHDR,commChk));
  103.   AifcHdr.formType = cpu_to_be32(FOURCC_AIFC);
  104.   AifcHdr.fverChk.ckid = cpu_to_be32(FOURCC_FVER);
  105.   AifcHdr.fverChk.dwSize= cpu_to_be32(offsetof(AIFCHDR,commChk)
  106. - offsetof(AIFCHDR,timestamp));
  107.   AifcHdr.compressionType[0]='N';
  108.   AifcHdr.compressionType[1]='O';
  109.   AifcHdr.compressionType[2]='N';
  110.   AifcHdr.compressionType[3]='E';
  111.   AifcHdr.compressionNameLen = sizeof(NO_COMPRESSION)-1;
  112.   strcpy(AifcHdr.compressionName, NO_COMPRESSION);
  113.   AifcHdr.timestamp = cpu_to_be32(UINT4_C(0xA2805140)); /* AIFC Version 1 */
  114.   AifcHdr.commChk.ckid = cpu_to_be32(FOURCC_COMM);
  115.   AifcHdr.commChk.dwSize= cpu_to_be32(offset_of(AIFCHDR,ssndChkid)
  116. - offset_of(AIFCHDR,numChannels));
  117.   AifcHdr.numChannels[1]= channels;
  118.   tmp = cpu_to_be32(expected_bytes/(channels * (nBitsPerSample/8)));
  119.   AifcHdr.numSampleFrames[0] = tmp >> 24;
  120.   AifcHdr.numSampleFrames[1] = tmp >> 16;
  121.   AifcHdr.numSampleFrames[2] = tmp >> 8;
  122.   AifcHdr.numSampleFrames[3] = tmp >> 0;
  123.   AifcHdr.samplesize[1] = nBitsPerSample;
  124.   Format_samplerate(rate, AifcHdr.sample_rate);
  125.   memcpy(AifcHdr.ssndChkid, "SSND", 4);
  126.   tmp = cpu_to_be32(expected_bytes + offset_of(AIFCHDR,blocksize)+sizeof(AifcHdr.blocksize) - offset_of(AIFCHDR, offset));
  127.   AifcHdr.dwSize[0] = tmp >> 24;
  128.   AifcHdr.dwSize[1] = tmp >> 16;
  129.   AifcHdr.dwSize[2] = tmp >> 8;
  130.   AifcHdr.dwSize[3] = tmp >> 0;
  131.   return write (audio, &AifcHdr, sizeof (AifcHdr));
  132. }
  133. static int ExitSound __PR(( int audio, unsigned long nBytesDone ));
  134. static int ExitSound ( audio, nBytesDone )
  135. int audio;
  136. unsigned long nBytesDone;
  137. {
  138.   UINT4 tmp;
  139.   AifcHdr.formChk.dwSize= cpu_to_be32(nBytesDone + sizeof(AIFCHDR)
  140. - offsetof(AIFCHDR,commChk));
  141.   tmp = cpu_to_be32(nBytesDone/(
  142. AifcHdr.numChannels[1] * AifcHdr.samplesize[1]/ULONG_C(8)));
  143.   AifcHdr.numSampleFrames[0] = tmp >> 24;
  144.   AifcHdr.numSampleFrames[1] = tmp >> 16;
  145.   AifcHdr.numSampleFrames[2] = tmp >> 8;
  146.   AifcHdr.numSampleFrames[3] = tmp >> 0;
  147.   /* If an odd number of bytes has been written,
  148.      extend the chunk with one dummy byte. This is a requirement for AIFC. */
  149.   if ((nBytesDone & 1) && (lseek(audio, 1L, SEEK_CUR) == -1)) {
  150.     return 0;
  151.   }
  152.   /* goto beginning */
  153.   if (lseek(audio, 0L, SEEK_SET) == -1) {
  154.     return 0;
  155.   }
  156.   return write (audio, &AifcHdr, sizeof (AifcHdr));
  157. }
  158. static unsigned long GetHdrSize __PR(( void ));
  159. static unsigned long GetHdrSize( )
  160. {
  161.   return sizeof( AifcHdr );
  162. }
  163. struct soundfile aifcsound =
  164. {
  165. InitSound, /* init header method */
  166. ExitSound, /* exit header method */
  167. GetHdrSize, /* report header size method */
  168. 1 /* needs big endian samples */
  169. };