Reading/Writing .wav Files
Summer 2002
Table of Contents
1. Introduction
2. Source Code
Section 1. Introduction

This example demonstrates how to use Dr. Fred DePiero's classes to read and write to/from files in the .wav format. All of Dr. DePiero's classes needed to read/write .wav files are included without comment. The program also demonstrates the use of command line arguments.

Section 2. Source Code
driver.cpp
   1// driver.cpp
   2// Example program that uses the WAV_IN and WAV_OUT classes
   3//  written by Dr. Fred DePiero.
   4// t a y l o r@msoe.edu, 6-26-2002
   5
   6#include <iostream>
   7
   8#include "wav_in.h"
   9#include "wav_out.h"
  10
  11int main(int argc, char** argv)
  12{
  13  if(argc!=3) {
  14    std::cerr<<"Reads in a .wav file and writes it out.\n"
  15      << "         by Dr. Chris Taylor, t a y l o r@msoe.edu, 6-26-2002\n"
  16      << "         Makes use of utility code written by Dr. Fred DePiero\n\n"
  17      << "Usage: " << argv[0] << " infilename.wav outfilename.wav\n";
  18  } else {
  19    WAV_IN infile(argv[1]);
  20    double sampleRate = infile.get_sample_rate_hz();
  21    unsigned int bitsPerSample = infile.get_bits_per_sample();
  22    unsigned int channels = infile.get_num_channels();
  23    WAV_OUT outfile(sampleRate, bitsPerSample, channels);
  24    while(infile.more_data_available()) {
  25      double data = infile.read_current_input();
  26      // If this were a real application, you'd probably do something
  27      //  to the data here.
  28      outfile.write_current_output(data);
  29    }
  30    outfile.save_wave_file(argv[2]);
  31  }
  32  return 0;
  33}
wav_in.h
   1/******************* FILE : wav_in.h *********************/
   2
   3
   4/****** NOTICE: LIMITATIONS ON USE AND DISTRIBUTION ********\
   5
   6  This software is provided on an as-is basis, it may be
   7  distributed in an unlimited fashion without charge provided
   8  that it is used for scholarly purposes - it is not for
   9  commercial use or profit. This notice must remain unaltered.
  10
  11  Software by Dr Fred DePiero - CalPoly State University
  12
  13\******************** END OF NOTICE ************************/

  14
  15
  16
  17
  18#ifndef INCLUDE_WAV_IN
  19#define INCLUDE_WAV_IN
  20
  21class WAV_OUT;
  22
  23class WAV_IN
  24{
  25
  26public:
  27
  28   WAV_IN(char *wav_file_name);   
  29   ~WAV_IN();
  30   
  31   // routine for reading one sample from a (previously loaded) wave file
  32   //  returns current sample as a double
  33   double read_current_input();
  34
  35   // determines end-of-file condition, returns 1==true if more data ready
  36   int more_data_available();
  37
  38   // returns number of samples in file
  39   long int get_num_samples();
  40
  41   // reports number of channels (1==mono, 2==stereo)
  42   int get_num_channels();
  43
  44   // reports the number of bits in each sample
  45   int get_bits_per_sample();
  46
  47   // reports sample rate in Hz
  48   double get_sample_rate_hz();
  49
  50protected:
  51      
  52   double fs_hz;
  53   int bits_per_sample;
  54   int num_ch;
  55
  56   double *g_wdata_in;
  57   int g_num_isamp;
  58   long int g_max_isamp;
  59
  60   friend WAV_OUT;
  61};
  62
  63#endif
wav_out.h
   1/******************* FILE : wav_out.h *********************/
   2
   3
   4/****** NOTICE: LIMITATIONS ON USE AND DISTRIBUTION ********\
   5
   6  This software is provided on an as-is basis, it may be
   7  distributed in an unlimited fashion without charge provided
   8  that it is used for scholarly purposes - it is not for
   9  commercial use or profit. This notice must remain unaltered.
  10
  11  Software by Dr Fred DePiero - CalPoly State University
  12
  13\******************** END OF NOTICE ************************/

  14
  15
  16
  17
  18#ifndef INCLUDE_WAV_OUT
  19#define INCLUDE_WAV_OUT
  20
  21class WAV_IN;
  22
  23
  24class WAV_OUT
  25{
  26
  27public:
  28
  29   // create a new wav_out with given parameters
  30   //  note: soundcards typically support a limited range of values!
  31   //        hence the next constructor is safer: WAV_OUT(WAV_IN *wav);
  32   WAV_OUT(double fs_hz,int bits_per_sample,int num_ch);
  33   
  34   // create a wav_out with the same parameters as a given wav_in
  35   WAV_OUT(WAV_IN *wav_in);   
  36
  37   ~WAV_OUT();
  38   
  39   // routine for writing one output sample
  40   //  samples are stored in a buffer, until save_wave_file() is called
  41   //  returns 0 on success
  42   int write_current_output(double ooo);
  43
  44   // routine for saving a wave file.
  45   //  returns 0 on success, negative value on error
  46   int save_wave_file(char *wav_file_name);
  47
  48protected:
  49      
  50   double fs_hz;
  51   int bits_per_sample;
  52   int num_ch;
  53
  54   double *g_wdata_out;
  55   int g_num_osamp;
  56   long int g_max_osamp;
  57
  58   friend WAV_IN;
  59};
  60
  61#endif
wav_def.h
   1/******************* FILE : wav_def.h ********************/
   2
   3
   4
   5/****** NOTICE: LIMITATIONS ON USE AND DISTRIBUTION ********\
   6
   7  This software is provided on an as-is basis, it may be
   8  distributed in an unlimited fashion without charge provided
   9  that it is used for scholarly purposes - it is not for
  10  commercial use or profit. This notice must remain unaltered.
  11
  12  Software by Dr Fred DePiero - CalPoly State University
  13
  14\******************** END OF NOTICE ************************/

  15
  16
  17
  18
  19// header of wav file
  20typedef struct{
  21   char rID[4];            // 'RIFF'
  22   long int rLen;
  23      
  24   char wID[4];            // 'WAVE'
  25      
  26   char fId[4];            // 'fmt '
  27   long int pcm_header_len;   // varies...
  28   short int wFormatTag;
  29   short int nChannels;      // 1,2 for stereo data is (l,r) pairs
  30   long int nSamplesPerSec;
  31   long int nAvgBytesPerSec;
  32   short int nBlockAlign;      
  33   short int nBitsPerSample;
  34}   WAV_HDR;
  35
  36   
  37// header of wav file
  38typedef struct{
  39   char dId[4];            // 'data' or 'fact'
  40   long int dLen;
  41//   unsigned char *data;
  42}   CHUNK_HDR;
  43
  44
  45
f_ptch.h
   1/************************** FILE : f_ptch.h ***************************/
   2
   3
   4/****** NOTICE: LIMITATIONS ON USE AND DISTRIBUTION ********\
   5
   6  This software is provided on an as-is basis, it may be
   7  distributed in an unlimited fashion without charge provided
   8  that it is used for scholarly purposes - it is not for
   9  commercial use or profit. This notice must remain unaltered.
  10
  11  Software by Dr Fred DePiero - CalPoly State University
  12
  13\******************** END OF NOTICE ************************/

  14
  15
  16
  17
  18#ifndef F_PTCH_HH
  19#define F_PTCH_HH
  20
  21#include <string.h>
  22#include <memory.h>
  23
  24#define PI (3.14159265359)
  25 
  26#define bcopy(src,dest,sz) memcpy(dest,src,(size_t)sz)
  27
  28#endif
  29
f_err.h
   1/************************ FILE : ferr.h ***************************/
   2
   3
   4/****** NOTICE: LIMITATIONS ON USE AND DISTRIBUTION ********\
   5
   6  This software is provided on an as-is basis, it may be
   7  distributed in an unlimited fashion without charge provided
   8  that it is used for scholarly purposes - it is not for
   9  commercial use or profit. This notice must remain unaltered.
  10
  11  Software by Dr Fred DePiero - CalPoly State University
  12
  13\******************** END OF NOTICE ************************/

  14
  15
  16
  17
  18#ifndef FERR_H
  19#define FERR_H
  20
  21#define thret_gerr(n,s) { printf("%s (%d)\n",s,n); exit(n); }
  22#define threx_gerr(n,s) { printf("%s (%d)\n",s,n); exit(n); }
  23#define threv_gerr(n,s) { printf("%s (%d)\n",s,n); exit(n); }
  24#define throw_gerr(n,s) { printf("%s (%d)\n",s,n); exit(n); }
  25#define reton_gerr()   
  26#define revon_gerr()   
  27#define clear_gerr()   
  28#define print_gerr()   
  29#define catch_gerr()   0   
  30
  31#endif
  32
wav_in.cpp
   1/*************** FILE : wav_in.cpp *******************/
   2
   3
   4/****** NOTICE: LIMITATIONS ON USE AND DISTRIBUTION ********\
   5
   6  This software is provided on an as-is basis, it may be
   7  distributed in an unlimited fashion without charge provided
   8  that it is used for scholarly purposes - it is not for
   9  commercial use or profit. This notice must remain unaltered.
  10
  11  Software by Dr Fred DePiero - CalPoly State University
  12
  13\******************** END OF NOTICE ************************/

  14
  15
  16
  17
  18#include <cstdio>
  19#include <cstdlib>
  20#include <cmath>
  21
  22#include "f_err.h"
  23#include "f_ptch.h"
  24
  25#include "wav_def.h"
  26#include "wav_in.h"
  27
  28
  29
  30
  31
  32
  33/********************************************\
  34\********************************************/

  35long int WAV_IN::get_num_samples(){ return g_max_isamp; }
  36
  37/********************************************\
  38\********************************************/

  39int WAV_IN::get_num_channels(){ return num_ch; }
  40
  41/********************************************\
  42\********************************************/

  43int WAV_IN::get_bits_per_sample(){ return bits_per_sample; }
  44
  45/********************************************\
  46\********************************************/

  47double WAV_IN::get_sample_rate_hz(){ return fs_hz; }
  48
  49/********************************************\
  50\********************************************/

  51int WAV_IN::more_data_available()
  52{
  53   if(g_num_isamp>=g_max_isamp) return 0;
  54
  55   return 1;
  56}
  57
  58
  59
  60/**********************************************************
  61**********************************************************/

  62double WAV_IN::read_current_input()
  63{
  64   if( (g_wdata_in==NULL) || (g_max_isamp<=0) || (g_num_isamp<0) )
  65   {
  66      printf("input file not ready (or not loaded)!!!\n");
  67      exit(1);
  68   }
  69   if(g_num_isamp>=g_max_isamp)
  70   {
  71      printf("attempt to read past end of input buffer!\n");
  72      exit(1);
  73   }
  74
  75   return( g_wdata_in[g_num_isamp++] );
  76}
  77
  78
  79
  80
  81
  82/********************************************\
  83\********************************************/

  84WAV_IN::WAV_IN(char *file_name)
  85{   
  86   int i;
  87   FILE *fw;
  88   unsigned int wstat;
  89   char obuff[80];
  90
  91   WAV_HDR *wav;
  92   CHUNK_HDR *chk;
  93   short int *uptr;
  94   unsigned char *cptr;
  95   int sflag;
  96   long int rmore;
  97
  98   char *wbuff;
  99   int wbuff_len;
 100
 101   // set defaults
 102   g_wdata_in = NULL;
 103   g_num_isamp = 0;
 104   g_max_isamp = 0;
 105
 106   // allocate wav header
 107   wav = new WAV_HDR;
 108   chk = new CHUNK_HDR;
 109   if(wav==NULL){ printf("cant new headers\n"); exit(-1); }
 110   if(chk==NULL){ printf("cant new headers\n"); exit(-1); }
 111
 112   /* open wav file */
 113   fw = fopen(file_name,"rb");
 114   if(fw==NULL){ printf("cant open wav file\n"); exit(-1); }
 115
 116   /* read riff/wav header */
 117   wstat = fread((void *)wav,sizeof(WAV_HDR),(size_t)1,fw);
 118   if(wstat!=1){ printf("cant read wav\n"); exit(-1); }
 119
 120   // check format of header
 121   for(i=0;i<4;i++) obuff[i] = wav->rID[i];
 122   obuff[4] = 0;
 123   if(strcmp(obuff,"RIFF")!=0){ printf("bad RIFF format\n"); exit(-1); }
 124
 125   for(i=0;i<4;i++) obuff[i] = wav->wID[i];
 126   obuff[4] = 0;
 127   if(strcmp(obuff,"WAVE")!=0){ printf("bad WAVE format\n"); exit(-1); }
 128
 129   for(i=0;i<3;i++) obuff[i] = wav->fId[i];
 130   obuff[3] = 0;
 131   if(strcmp(obuff,"fmt")!=0){ printf("bad fmt format\n"); exit(-1); }
 132
 133   if(wav->wFormatTag!=1){ printf("bad wav wFormatTag\n"); exit(-1); }
 134   
 135   if( (wav->nBitsPerSample != 16) && (wav->nBitsPerSample != 8) ){
 136      printf("bad wav nBitsPerSample\n"); exit(-1); }
 137
 138
 139   // skip over any remaining portion of wav header
 140   rmore = wav->pcm_header_len - (sizeof(WAV_HDR) - 20);
 141   wstat = fseek(fw,rmore,SEEK_CUR);
 142   if(wstat!=0){ printf("cant seek\n"); exit(-1); }
 143
 144
 145   // read chunks until a 'data' chunk is found
 146   sflag = 1;
 147   while(sflag!=0){
 148
 149      // check attempts
 150      if(sflag>10){ printf("too many chunks\n"); exit(-1); }
 151
 152      // read chunk header
 153      wstat = fread((void *)chk,sizeof(CHUNK_HDR),(size_t)1,fw);
 154      if(wstat!=1){ printf("cant read chunk\n"); exit(-1); }
 155
 156      // check chunk type
 157      for(i=0;i<4;i++) obuff[i] = chk->dId[i];
 158      obuff[4] = 0;
 159      if(strcmp(obuff,"data")==0) break;
 160      
 161      // skip over chunk
 162      sflag++;
 163      wstat = fseek(fw,chk->dLen,SEEK_CUR);
 164      if(wstat!=0){ printf("cant seek\n"); exit(-1); }
 165   }
 166
 167   /* find length of remaining data */
 168   wbuff_len = chk->dLen;
 169
 170   // find number of samples
 171   g_max_isamp = chk->dLen;
 172   g_max_isamp /= wav->nBitsPerSample / 8;
 173
 174   /* allocate new buffers */
 175   wbuff = new char [wbuff_len];
 176   if(wbuff==NULL){ printf("cant alloc\n"); exit(-1); }
 177
 178//   if(g_wdata_in!=NULL) delete g_wdata_in;
 179   g_wdata_in = new double [g_max_isamp];
 180   if(g_wdata_in==NULL){ printf("cant alloc\n"); exit(-1); }
 181
 182
 183   /* read signal data */
 184   wstat = fread((void *)wbuff,wbuff_len,(size_t)1,fw);
 185   if(wstat!=1){ printf("cant read wbuff\n"); exit(-1); }
 186
 187   // convert data
 188   if(wav->nBitsPerSample == 16){
 189      uptr = (short *) wbuff;
 190      for(i=0;i<g_max_isamp;i++) g_wdata_in[i] = (double) (uptr[i]);
 191   }
 192   else{
 193      cptr = (unsigned char *) wbuff;
 194      for(i=0;i<g_max_isamp;i++) g_wdata_in[i] = (double) (cptr[i]);
 195   }
 196
 197   // save demographics
 198   fs_hz = (double) (wav->nSamplesPerSec);
 199   bits_per_sample = wav->nBitsPerSample;
 200   num_ch = wav->nChannels;
 201   
 202   printf("\nLoaded WAV File: %s\n",file_name);
 203   printf(" Sample Rate = %1.0lf (Hz)\n",fs_hz);
 204   printf(" Number of Samples = %ld\n",g_max_isamp);
 205   printf(" Bits Per Sample = %d\n",bits_per_sample);
 206   printf(" Number of Channels = %d\n\n",num_ch);
 207
 208   // reset buffer stream index
 209   g_num_isamp = 0;
 210
 211   // be polite - clean up
 212   if(wbuff!=NULL) delete wbuff;
 213   if(wav!=NULL) delete wav;
 214   if(chk!=NULL) delete chk;
 215   fclose(fw);
 216
 217   return;
 218
 219/* WAV_IN::WAV_IN() */}
 220
 221
 222
 223
 224
 225
 226/********************************************\
 227\********************************************/

 228WAV_IN::~WAV_IN(){ }
 229
 230
 231
 232
wav_out.cpp
   1/******************* FILE : wav_out.cpp ********************/
   2
   3
   4/****** NOTICE: LIMITATIONS ON USE AND DISTRIBUTION ********\
   5
   6  This software is provided on an as-is basis, it may be
   7  distributed in an unlimited fashion without charge provided
   8  that it is used for scholarly purposes - it is not for
   9  commercial use or profit. This notice must remain unaltered.
  10
  11  Software by Dr Fred DePiero - CalPoly State University
  12
  13\******************** END OF NOTICE ************************/

  14
  15
  16
  17
  18#include <cstdio>
  19#include <cstdlib>
  20#include <cmath>
  21
  22#include "f_err.h"
  23#include "f_ptch.h"
  24
  25#include "wav_def.h"
  26#include "wav_out.h"
  27#include "wav_in.h"
  28
  29
  30
  31
  32
  33/**********************************************************
  34**********************************************************/

  35int WAV_OUT::write_current_output(double ooo)
  36{
  37   int i;
  38   double *tmp = NULL;
  39
  40   // alloc initial buffer
  41   if(g_wdata_out==NULL)
  42   {
  43      g_max_osamp = 1024;
  44
  45      g_wdata_out = new double [g_max_osamp];
  46      for(i=0;i<g_num_osamp;i++) g_wdata_out[i] = 0.0;
  47
  48      if(g_wdata_out==NULL){ printf("cant alloc in WAV_OUT\n"); exit(-1); }
  49   }
  50
  51   // enlarge buffer
  52   if(g_num_osamp>=g_max_osamp)
  53   {
  54      g_max_osamp *= 2;
  55      tmp = new double [g_max_osamp];
  56      if(tmp==NULL){  printf("cant realloc in WAV_OUT\n");  exit(-1); }
  57
  58      // copy over
  59      for(i=0;i<g_num_osamp;i++) tmp[i] = g_wdata_out[i];
  60      for(i=g_num_osamp;i<g_max_osamp;i++) tmp[i] = 0.0;
  61
  62      // swap buffers
  63      delete g_wdata_out;
  64      g_wdata_out = tmp;
  65   }
  66
  67   // buffer input data
  68   g_wdata_out[g_num_osamp++] = ooo;
  69
  70   // be polite
  71   return 0;
  72
  73/* int WAV_OUT::write(double ooo) */}
  74
  75
  76
  77
  78
  79
  80/**********************************************************
  81**********************************************************/

  82int WAV_OUT::save_wave_file(char *fname)
  83{
  84   FILE *fw;
  85   unsigned int wstat;
  86   int i;
  87   char obuff[80];
  88
  89   WAV_HDR *wav;
  90   CHUNK_HDR *chk;
  91   char *wbuff;
  92   int wbuff_len;
  93
  94   short int *uptr;
  95   double ttt;
  96   double max_uuu =  (65536.0 / 2.0) - 1.0;
  97   double min_uuu = -(65536.0 / 2.0);
  98
  99   unsigned char *cptr;
 100   double max_ccc = 256.0;
 101   double min_ccc = 0.0;
 102
 103   if(g_num_osamp<=0) printf("warning, no new data written to output\n");
 104
 105   // allocate wav header
 106   wav = new WAV_HDR;
 107   chk = new CHUNK_HDR;
 108   if(wav==NULL){ printf("cant new headers\n"); exit(-1); }
 109   if(chk==NULL){ printf("cant new headers\n"); exit(-1); }
 110
 111   /* allocate new data buffers */
 112   wbuff_len = g_num_osamp * bits_per_sample / 8;
 113   wbuff = new char [wbuff_len];
 114   if(wbuff==NULL){ printf("cant alloc\n"); exit(-1); }
 115
 116   // setup wav header
 117   sprintf(obuff,"RIFF");
 118   for(i=0;i<4;i++) wav->rID[i] = obuff[i];
 119
 120   sprintf(obuff,"WAVE");
 121   for(i=0;i<4;i++) wav->wID[i] = obuff[i];
 122
 123   sprintf(obuff,"fmt ");
 124   for(i=0;i<4;i++) wav->fId[i] = obuff[i];
 125
 126   wav->nBitsPerSample = bits_per_sample;
 127   wav->nSamplesPerSec = (int) fs_hz;
 128   wav->nAvgBytesPerSec = (int) fs_hz;
 129   wav->nAvgBytesPerSec *= bits_per_sample / 8;
 130   wav->nAvgBytesPerSec *= num_ch;
 131   wav->nChannels = num_ch;
 132   
 133   wav->pcm_header_len = 16;
 134   wav->wFormatTag = 1;
 135   wav->rLen = sizeof(WAV_HDR) + sizeof(CHUNK_HDR) + wbuff_len;
 136   wav->nBlockAlign = num_ch * bits_per_sample / 8;
 137
 138
 139   // setup chunk header
 140   sprintf(obuff,"data");
 141   for(i=0;i<4;i++) chk->dId[i] = obuff[i];
 142
 143   chk->dLen = wbuff_len;
 144
 145
 146   // convert data
 147   if(bits_per_sample == 16){
 148      uptr = (short *) wbuff;
 149      for(i=0;i<g_num_osamp;i++){
 150         ttt = g_wdata_out[i];
 151         if(ttt>max_uuu) ttt = max_uuu;
 152         if(ttt<min_uuu) ttt = min_uuu;
 153         uptr[i] = (short int) ttt;
 154      }
 155   }
 156   else if(bits_per_sample == 8){
 157      cptr = (unsigned char *) wbuff;
 158      for(i=0;i<g_num_osamp;i++){
 159         ttt = g_wdata_out[i];
 160         if(ttt>max_ccc) ttt = max_ccc;
 161         if(ttt<min_ccc) ttt = min_ccc;
 162         cptr[i] = (unsigned char) ttt;
 163      }
 164   }
 165   else{ printf("bunk bits_per_sample\n"); exit(-1); }
 166
 167
 168   /* open wav file */
 169   fw = fopen(fname,"wb");
 170   if(fw==NULL){ printf("cant open wav file\n"); exit(-1); }
 171
 172
 173   /* write riff/wav header */
 174   wstat = fwrite((void *)wav,sizeof(WAV_HDR),(size_t)1,fw);
 175   if(wstat!=1){ printf("cant write wav\n"); exit(-1); }
 176
 177   /* write chunk header */
 178   wstat = fwrite((void *)chk,sizeof(CHUNK_HDR),(size_t)1,fw);
 179   if(wstat!=1){ printf("cant write chk\n"); exit(-1); }
 180
 181   /* write data */
 182   wstat = fwrite((void *)wbuff,wbuff_len,(size_t)1,fw);
 183   if(wstat!=1){ printf("cant write wbuff\n"); exit(-1); }
 184
 185
 186   printf("\nSaved WAV File: %s\n",fname);
 187   printf(" Sample Rate = %1.0lf (Hz)\n",fs_hz);
 188   printf(" Number of Samples = %ld\n",g_num_osamp);
 189   printf(" Bits Per Sample = %d\n",bits_per_sample);
 190   printf(" Number of Channels = %d\n\n",num_ch);
 191
 192
 193   // reset output stream index
 194   g_num_osamp = 0;
 195
 196   // be polite
 197   if(wbuff!=NULL) delete wbuff;
 198   if(wav!=NULL) delete wav;
 199   if(chk!=NULL) delete chk;
 200   fclose(fw);
 201   return 0;
 202
 203/* int WAV_OUT::save_wave_file(char *fname) */}
 204
 205
 206
 207
 208
 209/********************************************\
 210\********************************************/

 211WAV_OUT::WAV_OUT(double _fs_hz,int _bits_per_sample,int _num_ch)
 212{
 213
 214   fs_hz = _fs_hz;
 215   bits_per_sample = _bits_per_sample;
 216   num_ch = _num_ch;
 217
 218   g_wdata_out = NULL;
 219   g_num_osamp = 0;
 220   g_max_osamp = 0;
 221
 222   return;
 223   
 224/* WAV_OUT::WAV_OUT(,,,) */}
 225
 226
 227
 228
 229
 230/********************************************\
 231\********************************************/

 232WAV_OUT::WAV_OUT(WAV_IN *wav_in)
 233{
 234
 235   fs_hz = wav_in->fs_hz;
 236   bits_per_sample = wav_in->bits_per_sample;
 237   num_ch = wav_in->num_ch;
 238
 239   g_wdata_out = NULL;
 240   g_num_osamp = 0;
 241   g_max_osamp = 0;
 242
 243   return;
 244   
 245/* WAV_OUT::WAV_OUT(,,,) */}
 246
 247
 248
 249
 250
 251
 252
 253/********************************************\
 254\********************************************/

 255WAV_OUT::~WAV_OUT(){ }
 256
 257
 258
 259
Copyright   2002 Dr. Christopher C. Taylor t a y l o r@m s o e.e d u Last updated: Tue Oct 8 11:11:18 2002