Browse Source

cmAudioFile.h/c : Added cmAudioFileSetSRate(), cmAudioFileSine() and chnaged cmAudioFileTest() to take a variable argument list.

Added the ability to write WAV files.
cmAudioFileCreate() now creates a WAV or AIF header based on the file name extension.
master
Kevin Larke 9 years ago
parent
commit
072831b32a
2 changed files with 364 additions and 139 deletions
  1. 352
    137
      cmAudioFile.c
  2. 12
    2
      cmAudioFile.h

+ 352
- 137
cmAudioFile.c View File

12
 
12
 
13
 
13
 
14
 // #define _24to32_aif( p ) ((int)( ((p[0]>127?255:0) << 24) + (((int)p[0]) << 16) +  (((int)p[1]) <<8) + p[2]))  // no-swap equivalent
14
 // #define _24to32_aif( p ) ((int)( ((p[0]>127?255:0) << 24) + (((int)p[0]) << 16) +  (((int)p[1]) <<8) + p[2]))  // no-swap equivalent
15
-// See note in:_cmAudioFileReadAiffHeader()
15
+// See note in:_cmAudioFileReadFileHdr()
16
 // Note that this code byte swaps as it converts - this is to counter the byte swap that occurs in cmAudioFileReadInt().
16
 // Note that this code byte swaps as it converts - this is to counter the byte swap that occurs in cmAudioFileReadInt().
17
 #define _24to32_aif( p ) ((int)( ((p[0]>127?255:0) <<  0) + (((int)p[2]) << 24) +  (((int)p[1]) <<16) + (((int)p[0]) << 8)))
17
 #define _24to32_aif( p ) ((int)( ((p[0]>127?255:0) <<  0) + (((int)p[2]) << 24) +  (((int)p[1]) <<16) + (((int)p[0]) << 8)))
18
 
18
 
19
 #define _24to32_wav( p ) ((int)( ((p[2]>127?255:0) << 24) + (((int)p[2]) << 16) +  (((int)p[1]) <<8) + p[0]))
19
 #define _24to32_wav( p ) ((int)( ((p[2]>127?255:0) << 24) + (((int)p[2]) << 16) +  (((int)p[1]) <<8) + p[0]))
20
 
20
 
21
+#define _cmAfSwap16(v)  cmSwap16(v)
22
+#define _cmAfSwap32(v)  cmSwap32(v)
23
+
21
 #ifdef cmBIG_ENDIAN
24
 #ifdef cmBIG_ENDIAN
22
-#define _cmAfSwap16(v)  (v)
23
-#define _cmAfSwap32(v)  (v)
24
 #define _cmAifSwapFl    (0)
25
 #define _cmAifSwapFl    (0)
25
 #define _cmWavSwapFl    (1)
26
 #define _cmWavSwapFl    (1)
26
 #else
27
 #else
27
-#define _cmAfSwap16(v)  cmSwap16(v)
28
-#define _cmAfSwap32(v)  cmSwap32(v)
29
 #define _cmAifSwapFl    (1)
28
 #define _cmAifSwapFl    (1)
30
 #define _cmWavSwapFl    (0)
29
 #define _cmWavSwapFl    (0)
31
 #endif
30
 #endif
61
   cmAudioFileMarker_t* markArray;
60
   cmAudioFileMarker_t* markArray;
62
   unsigned             flags;
61
   unsigned             flags;
63
   cmChar_t*            fn;
62
   cmChar_t*            fn;
64
-} cmAudioFileGuts;
63
+} cmAf_t;
65
 
64
 
66
 cmAudioErrRecd _cmAudioFileErrArray[] = 
65
 cmAudioErrRecd _cmAudioFileErrArray[] = 
67
 {
66
 {
81
 
80
 
82
 cmAudioFileH_t cmNullAudioFileH = { NULL };
81
 cmAudioFileH_t cmNullAudioFileH = { NULL };
83
 
82
 
84
-cmAudioFileGuts* _cmAudioFileGutsPtr( cmAudioFileH_t h )
83
+cmAf_t* _cmAudioFileHandleToPtr( cmAudioFileH_t h )
85
 {
84
 {
86
-  cmAudioFileGuts* p = (cmAudioFileGuts*)h.h;
85
+  cmAf_t* p = (cmAf_t*)h.h;
87
   
86
   
88
   if( p == NULL )
87
   if( p == NULL )
89
     assert(p!=NULL);
88
     assert(p!=NULL);
91
   return p;
90
   return p;
92
 }
91
 }
93
 
92
 
94
-cmRC_t _cmAudioFileError( cmAudioFileGuts* p, cmRC_t rc )
93
+cmRC_t _cmAudioFileError( cmAf_t* p, cmRC_t rc )
95
 {
94
 {
96
   if( rc > kUnknownErrAfRC )
95
   if( rc > kUnknownErrAfRC )
97
     rc = kUnknownErrAfRC;
96
     rc = kUnknownErrAfRC;
100
   return rc;
99
   return rc;
101
 }
100
 }
102
 
101
 
103
-cmAudioFileGuts* _cmAudioFileValidate( cmAudioFileH_t h, cmRC_t* rcPtr, bool writeFl )
102
+cmAf_t* _cmAudioFileValidate( cmAudioFileH_t h, cmRC_t* rcPtr, bool writeFl )
104
 {
103
 {
105
   *rcPtr = kOkAfRC;
104
   *rcPtr = kOkAfRC;
106
 
105
 
107
-  cmAudioFileGuts* p = _cmAudioFileGutsPtr(h);
106
+  cmAf_t* p = _cmAudioFileHandleToPtr(h);
108
 
107
 
109
   if( p == NULL )
108
   if( p == NULL )
110
     *rcPtr =  kInvalidHandleAfRC;
109
     *rcPtr =  kInvalidHandleAfRC;
116
   return *rcPtr == kOkAfRC ? p : NULL;
115
   return *rcPtr == kOkAfRC ? p : NULL;
117
 }
116
 }
118
 
117
 
119
-cmAudioFileGuts* _cmAudioFileReadGutsPtr( cmAudioFileH_t h, cmRC_t* rcPtr )
118
+cmAf_t* _cmAudioFileReadGutsPtr( cmAudioFileH_t h, cmRC_t* rcPtr )
120
 { return _cmAudioFileValidate( h, rcPtr, false ); }
119
 { return _cmAudioFileValidate( h, rcPtr, false ); }
121
 
120
 
122
-cmAudioFileGuts* _cmAudioFileWriteGutsPtr( cmAudioFileH_t h, cmRC_t* rcPtr )
121
+cmAf_t* _cmAudioFileWriteGutsPtr( cmAudioFileH_t h, cmRC_t* rcPtr )
123
 { return _cmAudioFileValidate( h, rcPtr, true ); }
122
 { return _cmAudioFileValidate( h, rcPtr, true ); }
124
 
123
 
125
 
124
 
126
 
125
 
127
-cmRC_t _cmAudioFileSeek( cmAudioFileGuts* p, long byteOffset, int origin )
126
+cmRC_t _cmAudioFileSeek( cmAf_t* p, long byteOffset, int origin )
128
 {
127
 {
129
   if( fseek(p->fp,byteOffset,origin) != 0 )
128
   if( fseek(p->fp,byteOffset,origin) != 0 )
130
     return _cmAudioFileError(p,kSeekFailAfRC);
129
     return _cmAudioFileError(p,kSeekFailAfRC);
131
   return kOkAfRC;
130
   return kOkAfRC;
132
 }
131
 }
133
 
132
 
134
-cmRC_t _cmAudioFileRead( cmAudioFileGuts* p, void* eleBuf, unsigned bytesPerEle, unsigned eleCnt )
133
+cmRC_t _cmAudioFileRead( cmAf_t* p, void* eleBuf, unsigned bytesPerEle, unsigned eleCnt )
135
 {
134
 {
136
   if( fread(eleBuf,bytesPerEle,eleCnt,p->fp) != eleCnt )
135
   if( fread(eleBuf,bytesPerEle,eleCnt,p->fp) != eleCnt )
137
     return _cmAudioFileError(p,kReadFailAfRC);
136
     return _cmAudioFileError(p,kReadFailAfRC);
139
   return kOkAfRC;
138
   return kOkAfRC;
140
 }
139
 }
141
 
140
 
142
-cmRC_t _cmAudioFileReadUInt32( cmAudioFileGuts* p, cmUInt32_t* valuePtr )
141
+cmRC_t _cmAudioFileReadUInt32( cmAf_t* p, cmUInt32_t* valuePtr )
143
 {
142
 {
144
   cmRC_t rc;
143
   cmRC_t rc;
145
 
144
 
146
   if(( rc = _cmAudioFileRead(p, valuePtr, sizeof(*valuePtr), 1 )) != kOkAfRC )
145
   if(( rc = _cmAudioFileRead(p, valuePtr, sizeof(*valuePtr), 1 )) != kOkAfRC )
147
     return rc;
146
     return rc;
148
-
149
     
147
     
150
   if( cmIsFlag(p->info.flags,kSwapAfFl) )
148
   if( cmIsFlag(p->info.flags,kSwapAfFl) )
151
       *valuePtr = _cmAfSwap32(*valuePtr);
149
       *valuePtr = _cmAfSwap32(*valuePtr);
154
 } 
152
 } 
155
 
153
 
156
 
154
 
157
-cmRC_t _cmAudioFileReadUInt16( cmAudioFileGuts* p, cmUInt16_t* valuePtr )
155
+cmRC_t _cmAudioFileReadUInt16( cmAf_t* p, cmUInt16_t* valuePtr )
158
 {
156
 {
159
   cmRC_t rc;
157
   cmRC_t rc;
160
 
158
 
167
   return rc;
165
   return rc;
168
 } 
166
 } 
169
 
167
 
170
-cmRC_t _cmAudioFileReadPascalString( cmAudioFileGuts* p, char s[kAudioFileLabelCharCnt] )
168
+cmRC_t _cmAudioFileReadPascalString( cmAf_t* p, char s[kAudioFileLabelCharCnt] )
171
 {
169
 {
172
   cmRC_t rc;
170
   cmRC_t rc;
173
   unsigned char n;
171
   unsigned char n;
186
   return rc;
184
   return rc;
187
 }
185
 }
188
 
186
 
189
-cmRC_t _cmAudioFileReadString( cmAudioFileGuts* p, char* s, unsigned sn )
187
+cmRC_t _cmAudioFileReadString( cmAf_t* p, char* s, unsigned sn )
190
 {
188
 {
191
   cmRC_t rc;
189
   cmRC_t rc;
192
   if((rc = _cmAudioFileRead(p,s,sn,1)) != kOkAfRC )
190
   if((rc = _cmAudioFileRead(p,s,sn,1)) != kOkAfRC )
195
   return kOkAfRC;
193
   return kOkAfRC;
196
 }
194
 }
197
 
195
 
198
-cmRC_t _cmAudioFileReadX80( cmAudioFileGuts* p, double* x80Ptr )
196
+cmRC_t _cmAudioFileReadX80( cmAf_t* p, double* x80Ptr )
199
 {
197
 {
200
   unsigned char s[10];
198
   unsigned char s[10];
201
   cmRC_t rc = kOkAfRC;
199
   cmRC_t rc = kOkAfRC;
207
   return kOkAfRC;
205
   return kOkAfRC;
208
 }
206
 }
209
 
207
 
210
-cmRC_t _cmAudioFileReadChunkHdr( cmAudioFileGuts* p, cmUInt32_t* chkIdPtr, unsigned* chkByteCntPtr )
208
+cmRC_t _cmAudioFileReadChunkHdr( cmAf_t* p, cmUInt32_t* chkIdPtr, unsigned* chkByteCntPtr )
211
 {
209
 {
212
   cmRC_t rc      = kOkAfRC;
210
   cmRC_t rc      = kOkAfRC;
213
 
211
 
226
   return rc;
224
   return rc;
227
 }
225
 }
228
 
226
 
229
-cmRC_t _cmAudioFileReadAiffHeader( cmAudioFileGuts* p, unsigned constFormId, unsigned constAifId, bool swapFl )
227
+cmRC_t _cmAudioFileReadFileHdr( cmAf_t* p, unsigned constFormId, unsigned constAifId, bool swapFl )
230
 {
228
 {
231
   cmRC_t     rc         = kOkAfRC;
229
   cmRC_t     rc         = kOkAfRC;
232
   cmUInt32_t formId     = 0;
230
   cmUInt32_t formId     = 0;
280
   return rc;
278
   return rc;
281
 }
279
 }
282
 
280
 
283
-cmRC_t _cmAudioFileReadCommChunk( cmAudioFileGuts* p )
281
+cmRC_t _cmAudioFileReadCommChunk( cmAf_t* p )
284
 {
282
 {
285
   cmRC_t rc = kOkAfRC;
283
   cmRC_t rc = kOkAfRC;
286
   cmUInt16_t ui16;
284
   cmUInt16_t ui16;
330
   return rc;
328
   return rc;
331
 }
329
 }
332
 
330
 
333
-cmRC_t _cmAudioFileReadSsndChunk( cmAudioFileGuts* p )
331
+cmRC_t _cmAudioFileReadSsndChunk( cmAf_t* p )
334
 {
332
 {
335
   cmRC_t rc = kOkAfRC;
333
   cmRC_t rc = kOkAfRC;
336
 
334
 
350
   return rc;
348
   return rc;
351
 }
349
 }
352
 
350
 
353
-cmRC_t _cmAudioFileReadMarkerChunk( cmAudioFileGuts* p )
351
+cmRC_t _cmAudioFileReadMarkerChunk( cmAf_t* p )
354
 {
352
 {
355
   cmRC_t rc = kOkAfRC;
353
   cmRC_t rc = kOkAfRC;
356
 
354
 
388
   return rc;
386
   return rc;
389
 }
387
 }
390
 
388
 
391
-cmRC_t _cmAudioFileReadFmtChunk( cmAudioFileGuts* p )
389
+cmRC_t _cmAudioFileReadFmtChunk( cmAf_t* p )
392
 {
390
 {
393
   cmRC_t rc = kOkAfRC;
391
   cmRC_t rc = kOkAfRC;
394
   unsigned short fmtId, chCnt, blockAlign, bits;
392
   unsigned short fmtId, chCnt, blockAlign, bits;
424
   return rc;
422
   return rc;
425
 }
423
 }
426
 
424
 
427
-cmRC_t _cmAudioFileReadDatcmhunk( cmAudioFileGuts* p, unsigned chkByteCnt )
425
+cmRC_t _cmAudioFileReadDatcmhunk( cmAf_t* p, unsigned chkByteCnt )
428
 {
426
 {
429
   // if the 'fmt' chunk was read before the 'data' chunk then info.chCnt is non-zero
427
   // if the 'fmt' chunk was read before the 'data' chunk then info.chCnt is non-zero
430
   if( p->info.chCnt != 0 )
428
   if( p->info.chCnt != 0 )
437
   return kOkAfRC;
435
   return kOkAfRC;
438
 }
436
 }
439
 
437
 
440
-cmRC_t _cmAudioFileReadBextChunk( cmAudioFileGuts* p)
438
+cmRC_t _cmAudioFileReadBextChunk( cmAf_t* p)
441
 {
439
 {
442
   cmRC_t rc = kOkAfRC;
440
   cmRC_t rc = kOkAfRC;
443
 
441
 
472
   cmAudioFileH_t h;
470
   cmAudioFileH_t h;
473
   cmRC_t       rc        = kOkAfRC;
471
   cmRC_t       rc        = kOkAfRC;
474
 
472
 
475
-  h.h = cmMemAllocZ( cmAudioFileGuts, 1 );  
476
-  cmErrSetup(&((cmAudioFileGuts*)h.h)->err,rpt,"Audio File");
473
+  h.h = cmMemAllocZ( cmAf_t, 1 );  
474
+  cmErrSetup(&((cmAf_t*)h.h)->err,rpt,"Audio File");
477
 
475
 
478
   if( fn != NULL )
476
   if( fn != NULL )
479
     if((rc = cmAudioFileOpen(h,fn,afInfoPtr)) != kOkAfRC )
477
     if((rc = cmAudioFileOpen(h,fn,afInfoPtr)) != kOkAfRC )
496
   cmAudioFileH_t h;
494
   cmAudioFileH_t h;
497
   cmRC_t rc = kOkAfRC;
495
   cmRC_t rc = kOkAfRC;
498
 
496
 
499
-  h.h = cmMemAllocZ(cmAudioFileGuts,1);
500
-  cmErrSetup(&((cmAudioFileGuts*)h.h)->err,rpt,"Audio File");
497
+  h.h = cmMemAllocZ(cmAf_t,1);
498
+  cmErrSetup(&((cmAf_t*)h.h)->err,rpt,"Audio File");
501
   
499
   
502
   if( fn != NULL )
500
   if( fn != NULL )
503
     if((rc = cmAudioFileCreate(h,fn,srate,bits,chCnt)) != kOkAfRC )
501
     if((rc = cmAudioFileCreate(h,fn,srate,bits,chCnt)) != kOkAfRC )
515
   return h;    
513
   return h;    
516
 }
514
 }
517
 
515
 
518
-cmRC_t     cmAudioFileOpen(  cmAudioFileH_t h, const cmChar_t* fn, cmAudioFileInfo_t* infoPtr )
516
+cmRC_t _cmAudioFileOpen( cmAf_t* p, const cmChar_t* fn, const char* fileModeStr )
519
 {
517
 {
520
   cmRC_t rc = kOkAfRC;
518
   cmRC_t rc = kOkAfRC;
521
-
522
-  cmAudioFileGuts* p = _cmAudioFileGutsPtr(h);
523
-
524
-  // verify the file is closed before opening
525
-  if( cmAudioFileIsOpen(h) )
526
-    if((rc = cmAudioFileClose(&h)) != kOkAfRC )
527
-      return rc;
528
-
519
+  
529
   // zero the info record
520
   // zero the info record
530
   memset(&p->info,0,sizeof(p->info));
521
   memset(&p->info,0,sizeof(p->info));
531
 
522
 
532
-
533
   // open the file
523
   // open the file
534
-  if((p->fp = fopen(fn,"rb")) == NULL )
524
+  if((p->fp = fopen(fn,fileModeStr)) == NULL )
535
   {
525
   {
536
     p->fn = (cmChar_t*)fn; // set the file name so that the error msg can use it
526
     p->fn = (cmChar_t*)fn; // set the file name so that the error msg can use it
537
     rc    = _cmAudioFileError(p,kOpenFailAfRC);
527
     rc    = _cmAudioFileError(p,kOpenFailAfRC);
540
   }
530
   }
541
 
531
 
542
   // read the file header
532
   // read the file header
543
-  if((rc = _cmAudioFileReadAiffHeader(p,kAiffFileId,kAiffChkId,_cmAifSwapFl)) != kOkAfRC )
544
-    if((rc = _cmAudioFileReadAiffHeader(p,kWavFileId,kWavChkId,_cmWavSwapFl)) != kOkAfRC )
533
+  if((rc = _cmAudioFileReadFileHdr(p,kAiffFileId,kAiffChkId,_cmAifSwapFl)) != kOkAfRC )
534
+    if((rc = _cmAudioFileReadFileHdr(p,kWavFileId,kWavChkId,_cmWavSwapFl)) != kOkAfRC )
545
       goto errLabel;
535
       goto errLabel;
546
   
536
   
547
   // seek past the file header
537
   // seek past the file header
603
       goto errLabel;
593
       goto errLabel;
604
   }
594
   }
605
 
595
 
596
+ errLabel:
597
+  if( rc!=kOkAfRC && p->fp != NULL )
598
+  {
599
+    fclose(p->fp);
600
+    p->fp = NULL;
601
+  }
602
+
603
+  return rc;
604
+}
605
+
606
+
607
+cmRC_t     cmAudioFileOpen(  cmAudioFileH_t h, const cmChar_t* fn, cmAudioFileInfo_t* infoPtr )
608
+{
609
+  cmRC_t rc = kOkAfRC;
610
+
611
+  cmAf_t* p = _cmAudioFileHandleToPtr(h);
612
+
613
+  // verify the file is closed before opening
614
+  if( cmAudioFileIsOpen(h) )
615
+    if((rc = cmAudioFileClose(&h)) != kOkAfRC )
616
+      return rc;
617
+
618
+  // read the file header
619
+  if((rc = _cmAudioFileOpen(p, fn, "rb" )) != kOkAfRC )
620
+    goto errLabel;
621
+
606
   // seek to the first sample offset
622
   // seek to the first sample offset
607
   if((rc = _cmAudioFileSeek(p,p->smpByteOffs,SEEK_SET)) != kOkAfRC )
623
   if((rc = _cmAudioFileSeek(p,p->smpByteOffs,SEEK_SET)) != kOkAfRC )
608
     goto errLabel;
624
     goto errLabel;
617
 
633
 
618
  errLabel:
634
  errLabel:
619
   cmAudioFileClose(&h);
635
   cmAudioFileClose(&h);
620
-  return rc;
621
-  
636
+  return rc;  
622
 }
637
 }
623
 
638
 
624
-cmRC_t   _cmAudioFileWriteBytes( cmAudioFileGuts* p, const void* b, unsigned bn )
639
+cmRC_t   _cmAudioFileWriteBytes( cmAf_t* p, const void* b, unsigned bn )
625
 {
640
 {
626
   cmRC_t rc = kOkAfRC;
641
   cmRC_t rc = kOkAfRC;
627
   if( fwrite( b, bn, 1, p->fp ) != 1 )
642
   if( fwrite( b, bn, 1, p->fp ) != 1 )
630
   return rc;
645
   return rc;
631
 }
646
 }
632
 
647
 
633
-cmRC_t _cmAudioFileWriteId( cmAudioFileGuts* p, const char* s )
648
+cmRC_t _cmAudioFileWriteId( cmAf_t* p, const char* s )
634
 {  return _cmAudioFileWriteBytes( p,  s, strlen(s)) ; }
649
 {  return _cmAudioFileWriteBytes( p,  s, strlen(s)) ; }
635
 
650
 
636
-cmRC_t _cmAudioFileWriteUInt32( cmAudioFileGuts* p, unsigned v )
651
+cmRC_t _cmAudioFileWriteUInt32( cmAf_t* p, unsigned v )
637
 {
652
 {
638
-  v = _cmAfSwap32(v);
653
+  if( cmIsFlag(p->info.flags,kSwapAfFl) )
654
+    v = _cmAfSwap32(v);
655
+  
639
   return _cmAudioFileWriteBytes( p, &v, sizeof(v)) ; 
656
   return _cmAudioFileWriteBytes( p, &v, sizeof(v)) ; 
640
 }
657
 }
641
 
658
 
642
-cmRC_t _cmAudioFileWriteUInt16( cmAudioFileGuts* p, unsigned short v )
643
-{  
644
-  v = _cmAfSwap16(v);
659
+cmRC_t _cmAudioFileWriteUInt16( cmAf_t* p, unsigned short v )
660
+{
661
+  if( cmIsFlag(p->info.flags,kSwapAfFl) )
662
+    v = _cmAfSwap16(v);
663
+  
645
   return _cmAudioFileWriteBytes( p, &v, sizeof(v)) ; 
664
   return _cmAudioFileWriteBytes( p, &v, sizeof(v)) ; 
646
 
665
 
647
 }
666
 }
648
 
667
 
649
-cmRC_t   _cmAudioFileWriteHdr( cmAudioFileGuts* p )
668
+cmRC_t _cmAudioFileWriteAiffHdr( cmAf_t* p )
650
 {
669
 {
651
   cmRC_t        rc = kOkAfRC;
670
   cmRC_t        rc = kOkAfRC;
652
   unsigned char srateX80[10];
671
   unsigned char srateX80[10];
685
   return rc;
704
   return rc;
686
 }
705
 }
687
 
706
 
707
+cmRC_t _cmAudioFileWriteWavHdr( cmAf_t* p )
708
+{
709
+  cmRC_t   rc            = kOkAfRC;
710
+  short    chCnt         = p->info.chCnt;
711
+  unsigned frmCnt        = p->info.frameCnt;
712
+  short    bits          = p->info.bits;
713
+  unsigned srate         = p->info.srate;
714
+  short    fmtId         = 1;
715
+  unsigned bytesPerSmp   = bits/8;
716
+  unsigned hdrByteCnt    = 36;
717
+  unsigned fmtByteCnt    = 16;
718
+  unsigned blockAlignCnt = chCnt * bytesPerSmp;
719
+  unsigned sampleCnt     = chCnt * frmCnt;
720
+  unsigned dataByteCnt   = sampleCnt * bytesPerSmp;
721
+
722
+  if(( rc = _cmAudioFileSeek( p, 0, SEEK_SET )) != kOkAfRC )
723
+    return rc;
724
+
725
+  if((rc = _cmAudioFileWriteId(     p, "RIFF"))                   != kOkAfRC ) goto errLabel;
726
+  if((rc = _cmAudioFileWriteUInt32( p, hdrByteCnt + dataByteCnt)) != kOkAfRC ) goto errLabel;
727
+  if((rc = _cmAudioFileWriteId(     p, "WAVE"))                   != kOkAfRC ) goto errLabel;
728
+  if((rc = _cmAudioFileWriteId(     p, "fmt "))                   != kOkAfRC ) goto errLabel;
729
+  if((rc = _cmAudioFileWriteUInt32( p, fmtByteCnt))               != kOkAfRC ) goto errLabel;
730
+  if((rc = _cmAudioFileWriteUInt16( p, fmtId))                    != kOkAfRC ) goto errLabel;
731
+  if((rc = _cmAudioFileWriteUInt16( p, chCnt))                    != kOkAfRC ) goto errLabel;
732
+  if((rc = _cmAudioFileWriteUInt32( p, srate))                    != kOkAfRC ) goto errLabel;
733
+  if((rc = _cmAudioFileWriteUInt32( p, srate * blockAlignCnt))    != kOkAfRC ) goto errLabel;
734
+  if((rc = _cmAudioFileWriteUInt16( p, blockAlignCnt))            != kOkAfRC ) goto errLabel;
735
+  if((rc = _cmAudioFileWriteUInt16( p, bits))                     != kOkAfRC ) goto errLabel;
736
+  if((rc = _cmAudioFileWriteId(     p, "data"))                   != kOkAfRC ) goto errLabel;
737
+  if((rc = _cmAudioFileWriteUInt32( p, dataByteCnt))              != kOkAfRC ) goto errLabel;
738
+
739
+ errLabel:
740
+  return rc;
741
+}
742
+
743
+cmRC_t _cmAudioFileWriteHdr( cmAf_t* p )
744
+{
745
+  if( cmIsFlag(p->info.flags,kWavAfFl) )
746
+    return _cmAudioFileWriteWavHdr(p);
747
+
748
+  return _cmAudioFileWriteAiffHdr(p);
749
+}
750
+
688
 cmRC_t     cmAudioFileCreate(  cmAudioFileH_t h, const cmChar_t* fn, double srate, unsigned bits, unsigned chCnt )
751
 cmRC_t     cmAudioFileCreate(  cmAudioFileH_t h, const cmChar_t* fn, double srate, unsigned bits, unsigned chCnt )
689
 {
752
 {
690
-  cmRC_t           rc  = kOkAfRC;
691
-  cmAudioFileGuts* p   = _cmAudioFileGutsPtr(h);
692
-  cmFileSysPathPart_t* pp = NULL;
753
+  cmRC_t               rc     = kOkAfRC;
754
+  cmAf_t*              p      = _cmAudioFileHandleToPtr(h);
755
+  cmFileSysPathPart_t* pp     = NULL;
693
 
756
 
694
   // verify the file is closed before opening
757
   // verify the file is closed before opening
695
   if( cmAudioFileIsOpen(h) )
758
   if( cmAudioFileIsOpen(h) )
696
     if((rc = cmAudioFileClose(&h)) != kOkAfRC )
759
     if((rc = cmAudioFileClose(&h)) != kOkAfRC )
697
       return rc;
760
       return rc;
698
 
761
 
699
-  // all audio files are written as AIF's - if the file name is given some other extension then issue a warning
762
+  // all audio files are written as AIF's or WAV's -
763
+  // if the file name is given some other extension then issue a warning and write an AIF.
700
   if( fn!=NULL && strlen(fn) && ((pp = cmFsPathParts(fn)) != NULL) )
764
   if( fn!=NULL && strlen(fn) && ((pp = cmFsPathParts(fn)) != NULL) )
701
   {
765
   {
702
     unsigned i;
766
     unsigned i;
712
         ext[i] = toupper(ext[i]);
776
         ext[i] = toupper(ext[i]);
713
     }
777
     }
714
 
778
 
715
-    if( pp->extStr==NULL || (strcmp(ext,"AIF") && strcmp(ext,"AIFF")) )
716
-      cmRptPrintf(p->err.rpt,"The AIF audio file '%s' is being written with a file extension other than 'AIF' or 'AIFF'.",cmStringNullGuard(fn));
779
+    // determine the file type to write
780
+    if( cmIsFlag(p->info.flags,kWavAfFl) || strcmp(ext,"WAV")==0 )
781
+    {
782
+      p->info.flags = cmSetFlag(p->info.flags,kWavAfFl);
783
+      p->info.flags = cmClrFlag(p->info.flags,kAiffAfFl);      
784
+    }
785
+    else
786
+    {
787
+      if( pp->extStr==NULL || (strcmp(ext,"AIF") && strcmp(ext,"AIFF")) )
788
+        cmRptPrintf(p->err.rpt,"The AIF audio file '%s' is being written with a file extension other than 'AIF' or 'AIFF'.",cmStringNullGuard(fn));
717
       
789
       
790
+      p->info.flags = cmClrFlag(p->info.flags,kWavAfFl);
791
+      p->info.flags = cmSetFlag(p->info.flags,kAiffAfFl);
792
+    }
793
+    
718
     cmFsFreePathParts(pp);
794
     cmFsFreePathParts(pp);
719
   }
795
   }
720
 
796
 
721
-  // open the file
797
+  // open the file for writing
722
   if((p->fp = fopen(fn,"wb")) == NULL )
798
   if((p->fp = fopen(fn,"wb")) == NULL )
723
   {
799
   {
724
     p->fn = (cmChar_t*)fn; // set the file name so that the error msg can use it
800
     p->fn = (cmChar_t*)fn; // set the file name so that the error msg can use it
727
     goto errLabel;
803
     goto errLabel;
728
   }
804
   }
729
 
805
 
730
-  p->fn = cmMemResize( char, p->fn, strlen(fn)+1 );
806
+  p->fn            = cmMemResize( char, p->fn, strlen(fn)+1 );
731
   p->info.srate    = srate;
807
   p->info.srate    = srate;
732
   p->info.bits     = bits;
808
   p->info.bits     = bits;
733
   p->info.chCnt    = chCnt;
809
   p->info.chCnt    = chCnt;
734
   p->info.frameCnt = 0;
810
   p->info.frameCnt = 0;
735
   p->flags         = kWriteAudioGutsFl;
811
   p->flags         = kWriteAudioGutsFl;
812
+
813
+    // set the swap flags
814
+  bool swapFl = cmIsFlag(p->info.flags,kWavAfFl) ?  _cmWavSwapFl :  _cmAifSwapFl;
815
+
816
+  p->info.flags = cmEnaFlag(p->info.flags,kSwapAfFl,       swapFl);
817
+  p->info.flags = cmEnaFlag(p->info.flags,kSwapSamplesAfFl,swapFl);
818
+
736
   
819
   
737
   strcpy(p->fn,fn);
820
   strcpy(p->fn,fn);
738
 
821
 
739
-  if((rc = _cmAudioFileWriteHdr( p )) != kOkAfRC )
822
+  if((rc = _cmAudioFileWriteHdr(p)) != kOkAfRC )
740
     goto errLabel;
823
     goto errLabel;
741
-
824
+    
742
   return rc;
825
   return rc;
743
 
826
 
744
  errLabel:
827
  errLabel:
751
 {
834
 {
752
   assert( h != NULL);
835
   assert( h != NULL);
753
 
836
 
754
-  cmAudioFileGuts* p  = _cmAudioFileGutsPtr(*h);
837
+  cmAf_t* p  = _cmAudioFileHandleToPtr(*h);
755
   cmRC_t         rc = kOkAfRC;
838
   cmRC_t         rc = kOkAfRC;
756
 
839
 
757
   if( p->fp == NULL )
840
   if( p->fp == NULL )
785
   if( h->h == NULL )
868
   if( h->h == NULL )
786
     return kOkAfRC;
869
     return kOkAfRC;
787
 
870
 
788
-  cmAudioFileGuts* p = _cmAudioFileGutsPtr(*h);
871
+  cmAf_t* p = _cmAudioFileHandleToPtr(*h);
789
 
872
 
790
   if( p->fp != NULL )
873
   if( p->fp != NULL )
791
     rc = cmAudioFileClose(h);
874
     rc = cmAudioFileClose(h);
805
   if( !cmAudioFileIsValid(h) )
888
   if( !cmAudioFileIsValid(h) )
806
     return false;
889
     return false;
807
  
890
  
808
-  return _cmAudioFileGutsPtr(h)->fp != NULL;
891
+  return _cmAudioFileHandleToPtr(h)->fp != NULL;
809
 }
892
 }
810
 
893
 
811
 
894
 
812
 bool   cmAudioFileIsEOF(      cmAudioFileH_t h )
895
 bool   cmAudioFileIsEOF(      cmAudioFileH_t h )
813
 {
896
 {
814
   cmRC_t           rc = kOkAfRC;
897
   cmRC_t           rc = kOkAfRC;
815
-  cmAudioFileGuts* p  = _cmAudioFileReadGutsPtr(h,&rc);
898
+  cmAf_t* p  = _cmAudioFileReadGutsPtr(h,&rc);
816
   return  (rc != kOkAfRC) || (p==NULL) || (p->curFrmIdx >= p->info.frameCnt) || (p->fp==NULL) ||  feof(p->fp) ? true : false;
899
   return  (rc != kOkAfRC) || (p==NULL) || (p->curFrmIdx >= p->info.frameCnt) || (p->fp==NULL) ||  feof(p->fp) ? true : false;
817
 }
900
 }
818
 
901
 
819
 unsigned   cmAudioFileTell(       cmAudioFileH_t h )
902
 unsigned   cmAudioFileTell(       cmAudioFileH_t h )
820
 {
903
 {
821
   cmRC_t           rc = kOkAfRC;
904
   cmRC_t           rc = kOkAfRC;
822
-  cmAudioFileGuts* p  = _cmAudioFileReadGutsPtr(h,&rc);
905
+  cmAf_t* p  = _cmAudioFileReadGutsPtr(h,&rc);
823
   return (rc==kOkAfRC && p!=NULL) ? p->curFrmIdx : cmInvalidIdx;
906
   return (rc==kOkAfRC && p!=NULL) ? p->curFrmIdx : cmInvalidIdx;
824
 }
907
 }
825
 
908
 
826
 cmRC_t     cmAudioFileSeek(       cmAudioFileH_t h, unsigned frmIdx )
909
 cmRC_t     cmAudioFileSeek(       cmAudioFileH_t h, unsigned frmIdx )
827
 {
910
 {
828
   cmRC_t           rc = kOkAfRC;
911
   cmRC_t           rc = kOkAfRC;
829
-  cmAudioFileGuts* p  = _cmAudioFileReadGutsPtr(h,&rc);
912
+  cmAf_t* p  = _cmAudioFileReadGutsPtr(h,&rc);
830
   
913
   
831
   if( rc != kOkAfRC )
914
   if( rc != kOkAfRC )
832
     return rc;
915
     return rc;
840
 
923
 
841
 }
924
 }
842
 
925
 
843
-
844
-
845
 cmRC_t _cmAudioFileReadInt( cmAudioFileH_t h, unsigned totalFrmCnt, unsigned chIdx, unsigned chCnt, int* buf[], unsigned* actualFrmCntPtr, bool sumFl )
926
 cmRC_t _cmAudioFileReadInt( cmAudioFileH_t h, unsigned totalFrmCnt, unsigned chIdx, unsigned chCnt, int* buf[], unsigned* actualFrmCntPtr, bool sumFl )
846
 {
927
 {
847
   cmRC_t           rc  = kOkAfRC;
928
   cmRC_t           rc  = kOkAfRC;
848
-  cmAudioFileGuts* p   = _cmAudioFileReadGutsPtr(h,&rc);
929
+  cmAf_t* p   = _cmAudioFileReadGutsPtr(h,&rc);
849
 
930
 
850
   if( rc != kOkAfRC )
931
   if( rc != kOkAfRC )
851
     return rc;  
932
     return rc;  
1013
 cmRC_t _cmAudioFileReadRealSamples(  cmAudioFileH_t h, unsigned totalFrmCnt, unsigned chIdx, unsigned chCnt, float**  fbuf, double** dbuf, unsigned* actualFrmCntPtr, bool sumFl )
1094
 cmRC_t _cmAudioFileReadRealSamples(  cmAudioFileH_t h, unsigned totalFrmCnt, unsigned chIdx, unsigned chCnt, float**  fbuf, double** dbuf, unsigned* actualFrmCntPtr, bool sumFl )
1014
 {
1095
 {
1015
   cmRC_t           rc = kOkAfRC;
1096
   cmRC_t           rc = kOkAfRC;
1016
-  cmAudioFileGuts* p  = _cmAudioFileReadGutsPtr(h,&rc);
1097
+  cmAf_t* p  = _cmAudioFileReadGutsPtr(h,&rc);
1017
 
1098
 
1018
   if( rc != kOkAfRC )
1099
   if( rc != kOkAfRC )
1019
     return rc;
1100
     return rc;
1243
 
1324
 
1244
 
1325
 
1245
 
1326
 
1246
-cmRC_t    cmAudioFileWriteInt(    cmAudioFileH_t h, unsigned frmCnt, unsigned chCnt, int**    srcPtrPtr )
1327
+cmRC_t    cmAudioFileWriteInt(    cmAudioFileH_t h, unsigned frmCnt, unsigned chCnt, int** srcPtrPtr )
1247
 {
1328
 {
1248
-  cmRC_t           rc          = kOkAfRC;
1249
-  cmAudioFileGuts* p           = _cmAudioFileWriteGutsPtr(h,&rc );
1329
+  cmRC_t  rc = kOkAfRC;
1330
+  cmAf_t* p  = _cmAudioFileWriteGutsPtr(h,&rc );
1250
 
1331
 
1251
   if( rc != kOkAfRC )
1332
   if( rc != kOkAfRC )
1252
     return rc;
1333
     return rc;
1253
 
1334
 
1254
-  unsigned         bytesPerSmp =  p->info.bits / 8;
1255
-  unsigned         bufFrmCnt   = 1024;
1256
-  unsigned         bufByteCnt  = bufFrmCnt * bytesPerSmp;
1257
-  unsigned         ci;
1258
-  unsigned         wrFrmCnt    = 0;
1259
-  char buf[ bufByteCnt * chCnt ];
1335
+  unsigned bytesPerSmp = p->info.bits / 8;
1336
+  unsigned bufFrmCnt   = 1024;
1337
+  unsigned bufByteCnt  = bufFrmCnt * bytesPerSmp;
1338
+  unsigned ci;
1339
+  unsigned wrFrmCnt    = 0;
1340
+  char     buf[ bufByteCnt * chCnt ];
1260
   
1341
   
1261
   while( wrFrmCnt < frmCnt )
1342
   while( wrFrmCnt < frmCnt )
1262
   {
1343
   {
1263
     unsigned n = cmMin( frmCnt-wrFrmCnt, bufFrmCnt );
1344
     unsigned n = cmMin( frmCnt-wrFrmCnt, bufFrmCnt );
1264
 
1345
 
1346
+    // interleave each channel into buf[]
1265
     for(ci=0; ci<chCnt; ++ci)
1347
     for(ci=0; ci<chCnt; ++ci)
1266
     {
1348
     {
1349
+      // get the begin and end source pointers
1267
       const int* sbp = srcPtrPtr[ci] + wrFrmCnt;
1350
       const int* sbp = srcPtrPtr[ci] + wrFrmCnt;
1268
       const int* sep = sbp + n;
1351
       const int* sep = sbp + n;
1269
 
1352
 
1270
-      switch( p->info.bits )
1353
+      // 8 bit samples can't be byte swapped
1354
+      if( p->info.bits == 8 )
1271
       {
1355
       {
1272
-        case 8:
1356
+        char*  dbp = buf + ci;
1357
+        for(; sbp < sep; dbp+=chCnt )
1358
+          *dbp = (char)*sbp++;             
1359
+      }
1360
+      else
1361
+      {
1362
+        // if the samples do need to be byte swapped
1363
+        if( cmIsFlag(p->info.flags,kSwapSamplesAfFl) )
1364
+        {
1365
+          switch( p->info.bits )
1273
           {
1366
           {
1274
-            char*  dbp = buf + ci;
1275
-            for(; sbp < sep; dbp+=chCnt )
1276
-              *dbp = (char)*sbp++;             
1277
-          }
1278
-          break;
1367
+            case 16:
1368
+              {
1369
+                short*  dbp = (short*)buf;
1370
+                for(dbp+=ci; sbp < sep; dbp+=chCnt, ++sbp )
1371
+                  *dbp = _cmAfSwap16((short)*sbp);
1372
+              }
1373
+              break;
1374
+
1375
+            case 24:
1376
+              {
1377
+                unsigned char* dbp = (unsigned char*)buf;
1378
+                for( dbp+=(ci*3); sbp < sep; dbp+=(3*chCnt), ++sbp)
1379
+                {
1380
+                  unsigned char* s = (unsigned char*)sbp;
1381
+                  dbp[0] = s[2];
1382
+                  dbp[1] = s[1];
1383
+                  dbp[2] = s[0];
1384
+                }
1385
+              }
1386
+              break;
1387
+          
1279
 
1388
 
1280
-        case 16:
1281
-          {
1282
-            short*  dbp = (short*)buf;
1283
-            for(dbp+=ci; sbp < sep; dbp+=chCnt, ++sbp )
1284
-              *dbp = _cmAfSwap16((short)*sbp);
1285
-          }
1286
-          break;
1389
+            case 32:
1390
+              {
1391
+                int*  dbp = (int*)buf;
1392
+                for(dbp+=ci; sbp < sep; dbp+=chCnt, ++sbp )
1393
+                  *dbp = _cmAfSwap32(*sbp);
1394
+              }
1395
+              break;
1287
 
1396
 
1288
-        case 24:
1289
-          {
1290
-            unsigned char* dbp = (unsigned char*)buf;
1291
-            for( dbp+=(ci*3); sbp < sep; dbp+=(3*chCnt), ++sbp)
1292
-            {
1293
-              unsigned char* s = (unsigned char*)sbp;
1294
-              dbp[0] = s[2];
1295
-              dbp[1] = s[1];
1296
-              dbp[2] = s[0];
1297
-            }
1298
-          }
1299
-          break;
1300
-          
1397
+            default:
1398
+              { assert(0);}
1399
+          } 
1301
 
1400
 
1302
-        case 32:
1401
+        }
1402
+        else // interleave without byte swapping
1403
+        {
1404
+          switch( p->info.bits )
1303
           {
1405
           {
1304
-            int*  dbp = (int*)buf;
1305
-            for(dbp+=ci; sbp < sep; dbp+=chCnt, ++sbp )
1306
-              *dbp = _cmAfSwap32(*sbp);
1307
-          }
1308
-          break;
1309
-
1310
-        default:
1311
-          { assert(0);}
1312
-      }
1313
-    }
1406
+            case 16:
1407
+              {
1408
+                short*  dbp = (short*)buf;
1409
+                for(dbp+=ci; sbp < sep; dbp+=chCnt, ++sbp )
1410
+                  *dbp = (short)*sbp;
1411
+              }
1412
+              break;
1413
+              
1414
+            case 24:
1415
+              {
1416
+                unsigned char* dbp = (unsigned char*)buf;
1417
+                for( dbp+=(ci*3); sbp < sep; dbp+=(3*chCnt), ++sbp)
1418
+                {
1419
+                  unsigned char* s = (unsigned char*)sbp;
1420
+                  dbp[0] = s[0];
1421
+                  dbp[1] = s[1];
1422
+                  dbp[2] = s[2];
1423
+                }
1424
+              }
1425
+              break;
1426
+          
1314
 
1427
 
1428
+            case 32:
1429
+              {
1430
+                int*  dbp = (int*)buf;
1431
+                for(dbp+=ci; sbp < sep; dbp+=chCnt, ++sbp )
1432
+                  *dbp = *sbp;
1433
+              }
1434
+              break;
1435
+
1436
+            default:
1437
+              { assert(0);}
1438
+          } // switch
1439
+        } // don't swap
1440
+      } // 8 bits
1441
+    } // ch
1442
+
1443
+    // advance the source pointer index
1315
     wrFrmCnt+=n;
1444
     wrFrmCnt+=n;
1316
 
1445
 
1317
     if( fwrite( buf, n*bytesPerSmp*chCnt, 1, p->fp ) != 1)
1446
     if( fwrite( buf, n*bytesPerSmp*chCnt, 1, p->fp ) != 1)
1318
     {
1447
     {
1319
-      rc = _cmAudioFileError(p,kWriteFailAfRC);
1320
-      break;
1448
+        rc = _cmAudioFileError(p,kWriteFailAfRC);
1449
+        break;
1321
     }
1450
     }
1322
-  }
1451
+    
1452
+  } // while
1323
 
1453
 
1324
   p->info.frameCnt += wrFrmCnt;
1454
   p->info.frameCnt += wrFrmCnt;
1325
 
1455
 
1329
 cmRC_t    _cmAudioFileWriteRealSamples( cmAudioFileH_t h, unsigned frmCnt, unsigned chCnt, const void*  srcPtrPtr, unsigned realSmpByteCnt )
1459
 cmRC_t    _cmAudioFileWriteRealSamples( cmAudioFileH_t h, unsigned frmCnt, unsigned chCnt, const void*  srcPtrPtr, unsigned realSmpByteCnt )
1330
 {
1460
 {
1331
   cmRC_t           rc        = kOkAfRC;
1461
   cmRC_t           rc        = kOkAfRC;
1332
-  cmAudioFileGuts* p         = _cmAudioFileWriteGutsPtr(h,&rc );
1462
+  cmAf_t* p         = _cmAudioFileWriteGutsPtr(h,&rc );
1333
 
1463
 
1334
   if( rc != kOkAfRC )
1464
   if( rc != kOkAfRC )
1335
     return rc;
1465
     return rc;
1428
   *meanPtr = 0;
1558
   *meanPtr = 0;
1429
 
1559
 
1430
   cmRC_t           rc = kOkAfRC;
1560
   cmRC_t           rc = kOkAfRC;
1431
-  cmAudioFileGuts* p  = _cmAudioFileReadGutsPtr(h,&rc );
1561
+  cmAf_t* p  = _cmAudioFileReadGutsPtr(h,&rc );
1432
 
1562
 
1433
   if( rc != kOkAfRC )
1563
   if( rc != kOkAfRC )
1434
     return rc;
1564
     return rc;
1548
 const cmChar_t* cmAudioFileName( cmAudioFileH_t h )
1678
 const cmChar_t* cmAudioFileName( cmAudioFileH_t h )
1549
 {
1679
 {
1550
   cmRC_t rc;
1680
   cmRC_t rc;
1551
-  cmAudioFileGuts* p  = _cmAudioFileReadGutsPtr(h,&rc );
1681
+  cmAf_t* p  = _cmAudioFileReadGutsPtr(h,&rc );
1552
 
1682
 
1553
   if( rc != kOkAfRC )
1683
   if( rc != kOkAfRC )
1554
     return NULL;
1684
     return NULL;
1568
 
1698
 
1569
 }
1699
 }
1570
 
1700
 
1571
-
1572
-
1573
 cmRC_t cmAudioFileGetInfo(   const cmChar_t* fn, cmAudioFileInfo_t* infoPtr, cmRpt_t* rpt  )
1701
 cmRC_t cmAudioFileGetInfo(   const cmChar_t* fn, cmAudioFileInfo_t* infoPtr, cmRpt_t* rpt  )
1574
 {
1702
 {
1575
   cmRC_t rc = kOkAfRC;
1703
   cmRC_t rc = kOkAfRC;
1625
 
1753
 
1626
 cmRC_t     cmAudioFileReport( cmAudioFileH_t h, cmRpt_t* rpt, unsigned frmIdx, unsigned frmCnt )
1754
 cmRC_t     cmAudioFileReport( cmAudioFileH_t h, cmRpt_t* rpt, unsigned frmIdx, unsigned frmCnt )
1627
 {
1755
 {
1628
-  cmRC_t           rc = kOkAfRC;
1629
-  cmAudioFileGuts* p  = _cmAudioFileReadGutsPtr(h,&rc);
1756
+  cmRC_t  rc = kOkAfRC;
1757
+  cmAf_t* p  = _cmAudioFileReadGutsPtr(h,&rc);
1630
   
1758
   
1631
   if( rc != kOkAfRC )
1759
   if( rc != kOkAfRC )
1632
     return rc;
1760
     return rc;
1676
   return cmAudioFileDelete(&h);
1804
   return cmAudioFileDelete(&h);
1677
 }
1805
 }
1678
 
1806
 
1679
-/// [cmAudioFileExample]
1807
+cmRC_t     cmAudioFileSetSrate( const cmChar_t* fn, unsigned srate )
1808
+{
1809
+  cmRC_t  rc = kOkAfRC;
1810
+  cmAf_t  af;
1811
+  cmAf_t* p  = &af;
1812
+
1813
+  memset(&af,0,sizeof(af));
1814
+
1815
+  if((rc = _cmAudioFileOpen(p, fn, "r+b")) != kOkAfRC )
1816
+    goto errLabel;  
1817
+
1818
+  if( p->info.srate != srate )
1819
+  {
1820
+    // change the sample rate
1821
+    p->info.srate = srate;
1822
+
1823
+    // write the file header
1824
+    if((rc = _cmAudioFileWriteHdr(p)) != kOkAfRC )
1825
+      goto errLabel;
1826
+  }
1827
+  
1828
+ errLabel:
1829
+  if( p->fp != NULL )
1830
+    fclose(p->fp);
1831
+  
1832
+  return rc;
1833
+}
1680
 
1834
 
1681
-void cmAudioFileTest( const cmChar_t* audioFn, const cmChar_t* outFn, cmRpt_t* rpt )
1835
+void _cmAudioFileTest( const cmChar_t* audioFn, cmRpt_t* rpt )
1682
 {
1836
 {
1683
-  cmAudioFileInfo_t  afInfo;
1684
-  cmRC_t           cmRC;
1837
+  cmAudioFileInfo_t afInfo;
1838
+  cmRC_t            cmRC;
1685
 
1839
 
1686
   // open an audio file
1840
   // open an audio file
1687
   cmAudioFileH_t     afH   = cmAudioFileNewOpen( audioFn, &afInfo, &cmRC, rpt ); 
1841
   cmAudioFileH_t     afH   = cmAudioFileNewOpen( audioFn, &afInfo, &cmRC, rpt ); 
1698
 
1852
 
1699
   // close and delete the audio file handle
1853
   // close and delete the audio file handle
1700
   cmAudioFileDelete(&afH);
1854
   cmAudioFileDelete(&afH);
1855
+}
1856
+
1857
+cmRC_t     cmAudioFileSine( cmCtx_t* ctx, const cmChar_t* fn, double srate, unsigned bits, double hz, double gain, double secs )
1858
+{
1859
+  cmRC_t      rc    = kOkAfRC;
1860
+  unsigned    bN    = srate * secs;
1861
+  cmSample_t* b     = cmMemAlloc(cmSample_t,bN);
1862
+  unsigned    chCnt = 1;
1863
+
1864
+  unsigned    i;
1865
+  for(i=0; i<bN; ++i)
1866
+    b[i] = gain * sin(2.0*M_PI*hz*i/srate);
1701
 
1867
 
1868
+  if((rc = cmAudioFileWriteFileFloat(fn, srate, bits, bN, chCnt, &b, &ctx->rpt)) != kOkAfRC)
1869
+    return rc;
1702
 
1870
 
1871
+  return rc;
1703
 }
1872
 }
1873
+
1874
+/// [cmAudioFileExample]
1875
+
1876
+void cmAudioFileTest(cmCtx_t* ctx, int argc, const char* argv[])
1877
+{
1878
+  switch( argc )
1879
+  {
1880
+    case 3:
1881
+      //_cmAudioFileTest(argv[2],&ctx->rpt);
1882
+      cmAudioFileReportFn(argv[2],0,0,&ctx->rpt);
1883
+      break;
1884
+      
1885
+    case 4:
1886
+      {
1887
+        errno = 0;
1888
+        long srate =  strtol(argv[3], NULL, 10);
1889
+        if( srate == 0 && errno != 0 )
1890
+          cmRptPrintf(&ctx->rpt,"Invalid sample rate argument to cmAudioFileTest().");
1891
+        else
1892
+          cmAudioFileSetSrate(argv[2],srate);                
1893
+      }
1894
+      break;
1895
+
1896
+    case 8:
1897
+      {
1898
+        errno = 0;
1899
+        double   srate = strtod(argv[3],NULL);
1900
+        unsigned bits  = strtol(argv[4],NULL,10);
1901
+        double   hz    = strtod(argv[5],NULL);
1902
+        double   gain  = strtod(argv[6],NULL);
1903
+        double   secs  = strtod(argv[7],NULL);
1904
+        
1905
+        if( errno != 0 )
1906
+          cmRptPrintf(&ctx->rpt,"Invalid arg. to cmAudioFileTest().");
1907
+        
1908
+        cmAudioFileSine( ctx, argv[2], srate, bits,  hz, gain,  secs );
1909
+      }
1910
+      break;
1911
+
1912
+    default:
1913
+      cmRptPrintf(&ctx->rpt,"Invalid argument count to cmAudioFileTest().");
1914
+      break;
1915
+  }
1916
+}
1917
+
1918
+
1704
 /// [cmAudioFileExample]
1919
 /// [cmAudioFileExample]

+ 12
- 2
cmAudioFile.h View File

129
   /// reopened with the new file.
129
   /// reopened with the new file.
130
   cmRC_t     cmAudioFileOpen(       cmAudioFileH_t h, const cmChar_t* fn, cmAudioFileInfo_t* infoPtr );
130
   cmRC_t     cmAudioFileOpen(       cmAudioFileH_t h, const cmChar_t* fn, cmAudioFileInfo_t* infoPtr );
131
 
131
 
132
-  /// Open an audio file for writing.
132
+  /// Open an audio file for writing.  The type of the audio file, AIF or WAV
133
+  /// is determined by the file name extension.
133
   cmRC_t     cmAudioFileCreate(     
134
   cmRC_t     cmAudioFileCreate(     
134
     cmAudioFileH_t h,    ///< Handle returned from an earlier call to cmAudioFileNewCreate() or cmAudioFileNewOpen().
135
     cmAudioFileH_t h,    ///< Handle returned from an earlier call to cmAudioFileNewCreate() or cmAudioFileNewOpen().
135
     const cmChar_t* fn,  ///< File name of the new file.
136
     const cmChar_t* fn,  ///< File name of the new file.
295
   cmRC_t     cmAudioFileReportFn( const cmChar_t* fn, unsigned frmIdx, unsigned frmCnt, cmRpt_t* rpt );
296
   cmRC_t     cmAudioFileReportFn( const cmChar_t* fn, unsigned frmIdx, unsigned frmCnt, cmRpt_t* rpt );
296
   ///@}
297
   ///@}
297
 
298
 
299
+  /// Change the sample rate value in the header.  Note that this function does not resample the audio
300
+  /// signal it simply changes the value of the sample rate in the header.
301
+  cmRC_t     cmAudioFileSetSrate( const cmChar_t* audioFn, unsigned srate );
302
+
303
+  // Generate a sine tone and write it to a file.
304
+  cmRC_t     cmAudioFileSine( cmCtx_t* ctx, const cmChar_t* fn, double srate, unsigned bits, double hz, double gain, double secs );
305
+
306
+
298
   /// Testing and example routine for functions in cmAudioFile.h.
307
   /// Testing and example routine for functions in cmAudioFile.h.
299
   /// Also see cmProcTest.c cmAudioFileReadWriteTest()
308
   /// Also see cmProcTest.c cmAudioFileReadWriteTest()
300
-  void       cmAudioFileTest( const cmChar_t* audioFn, const cmChar_t* outFn, cmRpt_t* rpt );
309
+  void       cmAudioFileTest( cmCtx_t* ctx, int argc, const char* argv[] );
301
 
310
 
311
+  
302
 #ifdef __cplusplus
312
 #ifdef __cplusplus
303
 }
313
 }
304
 #endif
314
 #endif

Loading…
Cancel
Save