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

SCSI/ASPI

开发平台:

MultiPlatform

  1. /* @(#)aiff.c 1.2 99/12/19 Copyright 1998,1999 Heiko Eissfeldt */
  2. #ifndef lint
  3. static char     sccsid[] =
  4. "@(#)aiff.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 aiff pcm output
  13.  * ---------------------------------------------------------------------
  14.  */
  15. #include "config.h"
  16. #include <stdio.h>
  17. #if defined (HAVE_UNISTD_H) && (HAVE_UNISTD_H == 1)
  18. #include <sys/types.h>
  19. #include <unistd.h>
  20. #endif
  21. #include <strdefs.h>
  22. #include <standard.h>
  23. #include "mytype.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_AIFF     mmioFOURCC ('A', 'I', 'F', 'F')
  36. #define FOURCC_COMM     mmioFOURCC ('C', 'O', 'M', 'M')
  37. #define FOURCC_SSND     mmioFOURCC ('S', 'S', 'N', 'D')
  38. typedef struct AIFFHDR {
  39.   CHUNKHDR formChk;
  40.   FOURCC formType;
  41.   CHUNKHDR commChk; /* Common chunk */
  42.   /* from now on, alignment prevents us from using the original types :-(( */
  43.   unsigned char numChannels[2];         /* Audio Channels */
  44.   unsigned char numSampleFrames[4];     /* # of samples */
  45.   unsigned char samplesize[2];          /* bits per sample */
  46.   unsigned char sample_rate[10];        /* sample rate in extended float */
  47.   unsigned char ssndChkid[4];           /* Sound data chunk */
  48.   unsigned char dwSize[4];              /* size of chunk */
  49.   unsigned char offset[4];              /* start of 1st sample */
  50.   unsigned char blocksize[4];           /* aligned sound data block size */
  51. } AIFFHDR;
  52. static AIFFHDR AiffHdr;
  53. /* format the sample rate into an
  54.    bigendian 10-byte IEEE-754 floating point number
  55.  */
  56. static int Format_samplerate __PR((unsigned long rate, unsigned char the_rate[10]));
  57. static int Format_samplerate(rate, the_rate)
  58. unsigned long rate;
  59. unsigned char the_rate[10];
  60. {
  61.   int i;
  62.   /* normalize rate */
  63.   for (i = 0; (rate & 0xffff) != 0; rate <<= 1, i++) {
  64.     if ((rate & 0x8000) != 0) {
  65.       break;
  66.     }
  67.   }
  68.   /* set exponent and sign */
  69.   the_rate[1] = 14-i;
  70.   the_rate[0] = 0x40;           /* LSB = sign */
  71.   /* 16-bit part of mantisse for sample rate */
  72.   the_rate[3] = rate & 0xff;
  73.   the_rate[2] = (rate >> 8) & 0xff;
  74.   /* initialize lower digits of mantisse */
  75.   the_rate[4] = the_rate[5] = the_rate[6] =
  76.   the_rate[7] = the_rate[8] = the_rate[9] = 0;
  77.   return 0;
  78. }
  79. static int InitSound __PR(( int audio, long channels, unsigned long rate, long nBitsPerSample, unsigned long expected_bytes ));
  80. static int InitSound ( audio, channels, rate, nBitsPerSample, expected_bytes)
  81. int audio;
  82. long channels;
  83. unsigned long rate;
  84. long nBitsPerSample;
  85. unsigned long expected_bytes;
  86. {
  87.   UINT4 tmp;
  88.   fillbytes(&AiffHdr, sizeof(AiffHdr), '');
  89.   AiffHdr.formChk.ckid  = cpu_to_be32(FOURCC_FORM);
  90.   AiffHdr.formChk.dwSize= cpu_to_be32(expected_bytes +
  91. offset_of(AIFFHDR,blocksize)+sizeof(AiffHdr.blocksize)
  92. - offsetof(AIFFHDR,formType));
  93.   AiffHdr.formType = cpu_to_be32(FOURCC_AIFF);
  94.   AiffHdr.commChk.ckid = cpu_to_be32(FOURCC_COMM);
  95.   AiffHdr.commChk.dwSize= cpu_to_be32(offset_of(AIFFHDR,ssndChkid)
  96. - offset_of(AIFFHDR,numChannels));
  97.   AiffHdr.numChannels[1]= channels;
  98.   tmp = cpu_to_be32(expected_bytes/(channels * (nBitsPerSample/8)));
  99.   AiffHdr.numSampleFrames[0] = tmp >> 24;
  100.   AiffHdr.numSampleFrames[1] = tmp >> 16;
  101.   AiffHdr.numSampleFrames[2] = tmp >> 8;
  102.   AiffHdr.numSampleFrames[3] = tmp >> 0;
  103.   AiffHdr.samplesize[1] = nBitsPerSample;
  104.   Format_samplerate(rate, AiffHdr.sample_rate);
  105.   memcpy(AiffHdr.ssndChkid, "SSND", 4);
  106.   tmp = cpu_to_be32(expected_bytes + offset_of(AIFFHDR,blocksize)+sizeof(AiffHdr.blocksize) - offset_of(AIFFHDR, offset));
  107.   AiffHdr.dwSize[0] = tmp >> 24;
  108.   AiffHdr.dwSize[1] = tmp >> 16;
  109.   AiffHdr.dwSize[2] = tmp >> 8;
  110.   AiffHdr.dwSize[3] = tmp >> 0;
  111.   return write (audio, &AiffHdr, sizeof (AiffHdr));
  112. }
  113. static int ExitSound __PR(( int audio, unsigned long nBytesDone ));
  114. static int ExitSound ( audio, nBytesDone )
  115. int audio;
  116. unsigned long nBytesDone;
  117. {
  118.   UINT4 tmp;
  119.   AiffHdr.formChk.dwSize= cpu_to_be32(nBytesDone + sizeof(AIFFHDR)
  120. - offsetof(AIFFHDR,commChk));
  121.   tmp = cpu_to_be32(nBytesDone/(
  122.         AiffHdr.numChannels[1] * AiffHdr.samplesize[1]/ULONG_C(8)));
  123.   AiffHdr.numSampleFrames[0] = tmp >> 24;
  124.   AiffHdr.numSampleFrames[1] = tmp >> 16;
  125.   AiffHdr.numSampleFrames[2] = tmp >> 8;
  126.   AiffHdr.numSampleFrames[3] = tmp >> 0;
  127.   /* If an odd number of bytes has been written,
  128.      extend the chunk with one dummy byte. This is a requirement for AIFF. */
  129.   if ((nBytesDone & 1) && (lseek(audio, 1L, SEEK_CUR) == -1)) {
  130.     return 0;
  131.   }
  132.   /* goto beginning */
  133.   if (lseek(audio, 0L, SEEK_SET) == -1) {
  134.     return 0;
  135.   }
  136.   return write (audio, &AiffHdr, sizeof (AiffHdr));
  137. }
  138. static unsigned long GetHdrSize __PR(( void ));
  139. static unsigned long GetHdrSize( )
  140. {
  141.   return sizeof( AiffHdr );
  142. }
  143. struct soundfile aiffsound =
  144. {
  145. InitSound, /* init header method */
  146. ExitSound, /* exit header method */
  147. GetHdrSize, /* report header size method */
  148. 1 /* needs big endian samples */
  149. };