11
11
#include " AudioFile.h"
12
12
#include " MathDefs.h"
13
13
#include < climits>
14
+ #include < cstring>
14
15
#include < utility>
15
16
16
17
#ifdef _WIN32 // Windows specific
39
40
#define F_F32 0x32336c66 // supported AIFF data compression
40
41
#define F_F32CSND 0x32334c46 // tags: NONE, float (std + CSound)
41
42
#define F_NONE 0x454e4f4e //
43
+ #define T_IXML 0x4C4D5869 // http://www.ixml.info/
42
44
43
45
namespace icstdsp { // begin library specific namespace
44
46
@@ -65,6 +67,8 @@ AudioFile::AudioFile()
65
67
resolution = 0 ; // resolution in bit
66
68
channels = 0 ; // number of channels
67
69
spkpos = 0 ; // speaker positions
70
+ iXMLData = NULL ; // iXML data
71
+ iXMLDataSize = 0 ; // iXML data size
68
72
}
69
73
70
74
AudioFile::AudioFile (AudioFile&& src)
@@ -84,12 +88,15 @@ AudioFile& AudioFile::operator = (AudioFile&& src)
84
88
std::swap (spkpos, src.spkpos );
85
89
std::swap (resolution, src.resolution );
86
90
std::swap (channels, src.channels );
91
+ std::swap (iXMLData, src.iXMLData );
92
+ std::swap (iXMLDataSize, src.iXMLDataSize );
87
93
return *this ;
88
94
}
89
95
90
96
AudioFile::~AudioFile ()
91
97
{
92
98
if (audio) {delete[] audio;}
99
+ SetiXMLData (NULL , 0 );
93
100
}
94
101
95
102
// create new audio file
@@ -297,6 +304,16 @@ int AudioFile::LoadWave(unsigned int offset, unsigned int frames, bool nodata)
297
304
}
298
305
else {return NOSUPPORT;}
299
306
307
+ SetiXMLData (NULL , 0 );
308
+ if (GotoChunk (T_IXML, false ))
309
+ {
310
+ fread (&chunksize, sizeof (int ), 1 , file);
311
+ try {iXMLData = new unsigned char [chunksize];} catch (...) {iXMLData = NULL ;}
312
+ if (iXMLData == NULL ) {return NOMEMORY;}
313
+ fread (iXMLData, 1 , chunksize, file);
314
+ iXMLDataSize = chunksize;
315
+ }
316
+
300
317
// update properties and clean up
301
318
size = psize; resolution = presolution; channels = pchannels; rate = prate;
302
319
spkpos = pspkpos;
@@ -337,6 +354,16 @@ int AudioFile::LoadAiff(unsigned int offset, unsigned int frames, bool nodata)
337
354
if ((presolution == 0 ) || (pchannels == 0 )) {return CORRUPT;}
338
355
bytesperword = 1 + (presolution-1 )/8 ;
339
356
357
+ SetiXMLData (NULL , 0 );
358
+ if (GotoChunk (T_IXML, false ))
359
+ {
360
+ fread (&chunksize, sizeof (int ), 1 , file);
361
+ try {iXMLData = new unsigned char [chunksize];} catch (...) {iXMLData = NULL ;}
362
+ if (iXMLData == NULL ) {return NOMEMORY;}
363
+ fread (iXMLData, 1 , chunksize, file);
364
+ iXMLDataSize = chunksize;
365
+ }
366
+
340
367
// go back to the end of the form chunk and start searching for a
341
368
// sound data chunk skipping other chunks, jump to start of audio data,
342
369
// AIFF files without audio data do not require a sound chunk
@@ -715,6 +742,8 @@ int AudioFile::SaveWave(const char *filename)
715
742
else {allcsize = 36 + audiobytes + fill; fmtcsize = 16 ;}
716
743
if (bytesperword > 3 ) {usefloat = true ;}
717
744
745
+ if (iXMLData) allcsize += (8 + iXMLDataSize) + (iXMLDataSize % 2 );
746
+
718
747
// open file
719
748
if (filename[0 ] == 0 ) return NOFILE;
720
749
if ((file = fopen (filename," wb" )) == NULL ) return NOFILE;
@@ -811,6 +840,14 @@ int AudioFile::SaveWave(const char *filename)
811
840
delete[] buf;
812
841
}
813
842
843
+ if (iXMLData)
844
+ {
845
+ data32 = T_IXML; fwrite (&data32, sizeof (int ), 1 , file);
846
+ data32 = iXMLDataSize; fwrite (&data32, sizeof (int ), 1 , file);
847
+ fwrite (iXMLData, 1 , data32, file);
848
+ if (iXMLDataSize % 2 ) { const char space = ' ' ; fwrite (&space, 1 , 1 , file); }
849
+ }
850
+
814
851
// clean up
815
852
fclose (file);
816
853
return 0 ;
@@ -977,6 +1014,23 @@ float* AudioFile::GetSafePt(unsigned int channel, bool lock)
977
1014
return audio + channel*size;
978
1015
}
979
1016
1017
+ // return iXML chunk data bytes
1018
+ const unsigned char * AudioFile::GetiXMLData (unsigned int * dataLength) const
1019
+ {
1020
+ *dataLength = iXMLDataSize;
1021
+ return iXMLData;
1022
+ }
1023
+
1024
+ // set/clear iXML chunk data bytes
1025
+ void AudioFile::SetiXMLData (const unsigned char * data, unsigned int dataLength)
1026
+ {
1027
+ if (iXMLData) {delete[] iXMLData;}
1028
+ try {iXMLData = new unsigned char [dataLength];} catch (...) {iXMLData = NULL ;}
1029
+ if (iXMLData == NULL ) {iXMLDataSize = 0 ; return ;}
1030
+ memcpy (iXMLData, data, dataLength);
1031
+ iXMLDataSize = dataLength;
1032
+ }
1033
+
980
1034
// return array size in frames (samples / channels)
981
1035
unsigned int AudioFile::GetSize () const {return size;}
982
1036
0 commit comments