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

SCSI/ASPI

开发平台:

MultiPlatform

  1. /* @(#)wav.c 1.2 99/12/19 Copyright 1998,1999 Heiko Eissfeldt */
  2. #ifndef lint
  3. static char     sccsid[] =
  4. "@(#)wav.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. #include "config.h"
  13. #include <stdio.h>
  14. #if defined (HAVE_UNISTD_H) && (HAVE_UNISTD_H == 1)
  15. #include <sys/types.h>
  16. #include <unistd.h>
  17. #endif
  18. #include "byteorder.h"
  19. #include "sndfile.h"
  20. /***
  21.  * ---------------------------------------------------------------------
  22.  *  definitions for RIFF-output (from windows MMSYSTEM)
  23.  * ---------------------------------------------------------------------
  24.  */
  25. typedef unsigned int FOURCC; /* a four character code */
  26. typedef struct CHUNKHDR {
  27.   FOURCC ckid; /* chunk ID */
  28.   unsigned int dwSize;  /* chunk size */
  29. } CHUNKHDR;
  30. /* flags for 'wFormatTag' field of WAVEFORMAT */
  31. #define WAVE_FORMAT_PCM 1
  32. /* specific waveform format structure for PCM data */
  33. typedef struct pcmwaveformat_tag {
  34.   unsigned short wFormatTag; /* format type */
  35.   unsigned short nChannels; /* number of channels (i.e. mono, stereo, etc.) */
  36.   unsigned int nSamplesPerSec; /* sample rate */
  37.   unsigned int nAvgBytesPerSec;/* for buffer size estimate */
  38.   unsigned short nBlockAlign; /* block size of data */
  39.   unsigned short wBitsPerSample;
  40. } PCMWAVEFORMAT;
  41. typedef PCMWAVEFORMAT *PPCMWAVEFORMAT;
  42. /* MMIO macros */
  43. #define mmioFOURCC(ch0, ch1, ch2, ch3) 
  44.   ((unsigned int)(unsigned char)(ch0) | ((unsigned int)(unsigned char)(ch1) << 8) | 
  45.   ((unsigned int)(unsigned char)(ch2) << 16) | ((unsigned int)(unsigned char)(ch3) << 24))
  46. #define FOURCC_RIFF mmioFOURCC ('R', 'I', 'F', 'F')
  47. #define FOURCC_LIST mmioFOURCC ('L', 'I', 'S', 'T')
  48. #define FOURCC_WAVE mmioFOURCC ('W', 'A', 'V', 'E')
  49. #define FOURCC_FMT mmioFOURCC ('f', 'm', 't', ' ')
  50. #define FOURCC_DATA mmioFOURCC ('d', 'a', 't', 'a')
  51. /* simplified Header for standard WAV files */
  52. typedef struct WAVEHDR {
  53.   CHUNKHDR chkRiff;
  54.   FOURCC fccWave;
  55.   CHUNKHDR chkFmt;
  56.   unsigned short wFormatTag; /* format type */
  57.   unsigned short nChannels; /* number of channels (i.e. mono, stereo, etc.) */
  58.   unsigned int nSamplesPerSec; /* sample rate */
  59.   unsigned int nAvgBytesPerSec;/* for buffer estimation */
  60.   unsigned short nBlockAlign; /* block size of data */
  61.   unsigned short wBitsPerSample;
  62.   CHUNKHDR chkData;
  63. } WAVEHDR;
  64. #define IS_STD_WAV_HEADER(waveHdr) ( 
  65.   waveHdr.chkRiff.ckid == FOURCC_RIFF && 
  66.   waveHdr.fccWave == FOURCC_WAVE && 
  67.   waveHdr.chkFmt.ckid == FOURCC_FMT && 
  68.   waveHdr.chkData.ckid == FOURCC_DATA && 
  69.   waveHdr.wFormatTag == WAVE_FORMAT_PCM)
  70. static WAVEHDR waveHdr;
  71. static int _InitSound __PR(( int audio, long channels, unsigned long rate, long nBitsPerSample, unsigned long expected_bytes ));
  72. static int _InitSound ( audio , channels , rate , nBitsPerSample , expected_bytes )
  73. int audio;
  74. long channels;
  75. unsigned long rate;
  76. long nBitsPerSample;
  77. unsigned long expected_bytes;
  78. {
  79.   unsigned long nBlockAlign = channels * ((nBitsPerSample + 7) / 8);
  80.   unsigned long nAvgBytesPerSec = nBlockAlign * rate;
  81.   unsigned long temp = expected_bytes + sizeof(WAVEHDR) - sizeof(CHUNKHDR);
  82.   waveHdr.chkRiff.ckid    = cpu_to_le32(FOURCC_RIFF);
  83.   waveHdr.fccWave         = cpu_to_le32(FOURCC_WAVE);
  84.   waveHdr.chkFmt.ckid     = cpu_to_le32(FOURCC_FMT);
  85.   waveHdr.chkFmt.dwSize   = cpu_to_le32(sizeof (PCMWAVEFORMAT));
  86.   waveHdr.wFormatTag      = cpu_to_le16(WAVE_FORMAT_PCM);
  87.   waveHdr.nChannels       = cpu_to_le16(channels);
  88.   waveHdr.nSamplesPerSec  = cpu_to_le32(rate);
  89.   waveHdr.nBlockAlign     = cpu_to_le16(nBlockAlign);
  90.   waveHdr.nAvgBytesPerSec = cpu_to_le32(nAvgBytesPerSec);
  91.   waveHdr.wBitsPerSample  = cpu_to_le16(nBitsPerSample);
  92.   waveHdr.chkData.ckid    = cpu_to_le32(FOURCC_DATA);
  93.   waveHdr.chkRiff.dwSize  = cpu_to_le32(temp);
  94.   waveHdr.chkData.dwSize  = cpu_to_le32(expected_bytes);
  95.   return write (audio, &waveHdr, sizeof (waveHdr));
  96. }
  97. static int _ExitSound __PR(( int audio, unsigned long nBytesDone ));
  98. static int _ExitSound ( audio , nBytesDone )
  99. int audio;
  100. unsigned long nBytesDone;
  101. {
  102.   unsigned long temp = nBytesDone + sizeof(WAVEHDR) - sizeof(CHUNKHDR);
  103.   waveHdr.chkRiff.dwSize = cpu_to_le32(temp);
  104.   waveHdr.chkData.dwSize = cpu_to_le32(nBytesDone);
  105.   /* goto beginning */
  106.   if (lseek(audio, 0L, SEEK_SET) == -1) {
  107.     return 0;
  108.   }
  109.   return write (audio, &waveHdr, sizeof (waveHdr));
  110. }
  111. static unsigned long _GetHdrSize __PR(( void ));
  112. static unsigned long _GetHdrSize( )
  113. {
  114.   return sizeof( waveHdr );
  115. }
  116. struct soundfile wavsound =
  117. {
  118. _InitSound, /* init header method */
  119. _ExitSound, /* exit header method */
  120. _GetHdrSize, /* report header size method */
  121. 0 /* needs big endian samples */
  122. };