You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

904 lines
28KB

  1. /***************************************************/
  2. /*! \class FileRead
  3. \brief STK audio file input class.
  4. This class provides input support for various
  5. audio file formats. Multi-channel (>2)
  6. soundfiles are supported. The file data is
  7. returned via an external StkFrames object
  8. passed to the read() function. This class
  9. does not store its own copy of the file data,
  10. rather the data is read directly from disk.
  11. FileRead currently supports uncompressed WAV,
  12. AIFF/AIFC, SND (AU), MAT-file (Matlab), and
  13. STK RAW file formats. Signed integer (8-,
  14. 16-, 24- and 32-bit) and floating-point (32- and
  15. 64-bit) data types are supported. Compressed
  16. data types are not supported.
  17. STK RAW files have no header and are assumed to
  18. contain a monophonic stream of 16-bit signed
  19. integers in big-endian byte order at a sample
  20. rate of 22050 Hz. MAT-file data should be saved
  21. in an array with each data channel filling a
  22. matrix row. The sample rate for MAT-files should
  23. be specified in a variable named "fs". If no
  24. such variable is found, the sample rate is
  25. assumed to be 44100 Hz.
  26. by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
  27. */
  28. /***************************************************/
  29. #include "FileRead.h"
  30. #include <sys/stat.h>
  31. #include <sys/types.h>
  32. #include <cstring>
  33. #include <cmath>
  34. #include <cstdio>
  35. namespace stk {
  36. FileRead :: FileRead()
  37. : fd_(0), fileSize_(0), channels_(0), dataType_(0), fileRate_(0.0)
  38. {
  39. }
  40. FileRead :: FileRead( std::string fileName, bool typeRaw, unsigned int nChannels,
  41. StkFormat format, StkFloat rate )
  42. : fd_(0)
  43. {
  44. open( fileName, typeRaw, nChannels, format, rate );
  45. }
  46. FileRead :: ~FileRead()
  47. {
  48. if ( fd_ )
  49. fclose( fd_ );
  50. }
  51. void FileRead :: close( void )
  52. {
  53. if ( fd_ ) fclose( fd_ );
  54. fd_ = 0;
  55. wavFile_ = false;
  56. fileSize_ = 0;
  57. channels_ = 0;
  58. dataType_ = 0;
  59. fileRate_ = 0.0;
  60. }
  61. bool FileRead :: isOpen( void )
  62. {
  63. if ( fd_ ) return true;
  64. else return false;
  65. }
  66. void FileRead :: open( std::string fileName, bool typeRaw, unsigned int nChannels,
  67. StkFormat format, StkFloat rate )
  68. {
  69. // If another file is open, close it.
  70. close();
  71. // Try to open the file.
  72. fd_ = fopen( fileName.c_str(), "rb" );
  73. if ( !fd_ ) {
  74. oStream_ << "FileRead::open: could not open or find file (" << fileName << ")!";
  75. handleError( StkError::FILE_NOT_FOUND );
  76. }
  77. // Attempt to determine file type from header (unless RAW).
  78. bool result = false;
  79. if ( typeRaw )
  80. result = getRawInfo( fileName.c_str(), nChannels, format, rate );
  81. else {
  82. char header[12];
  83. if ( fread( &header, 4, 3, fd_ ) != 3 ) goto error;
  84. if ( !strncmp( header, "RIFF", 4 ) &&
  85. !strncmp( &header[8], "WAVE", 4 ) )
  86. result = getWavInfo( fileName.c_str() );
  87. else if ( !strncmp( header, ".snd", 4 ) )
  88. result = getSndInfo( fileName.c_str() );
  89. else if ( !strncmp( header, "FORM", 4 ) &&
  90. ( !strncmp( &header[8], "AIFF", 4 ) || !strncmp(&header[8], "AIFC", 4) ) )
  91. result = getAifInfo( fileName.c_str() );
  92. else {
  93. if ( fseek( fd_, 126, SEEK_SET ) == -1 ) goto error;
  94. if ( fread( &header, 2, 1, fd_ ) != 1 ) goto error;
  95. if ( !strncmp( header, "MI", 2 ) ||
  96. !strncmp( header, "IM", 2 ) )
  97. result = getMatInfo( fileName.c_str() );
  98. else {
  99. oStream_ << "FileRead::open: file (" << fileName << ") format unknown.";
  100. handleError( StkError::FILE_UNKNOWN_FORMAT );
  101. }
  102. }
  103. }
  104. // If here, we had a file type candidate but something else went wrong.
  105. if ( result == false )
  106. handleError( StkError::FILE_ERROR );
  107. // Check for empty files.
  108. if ( fileSize_ == 0 ) {
  109. oStream_ << "FileRead::open: file (" << fileName << ") data size is zero!";
  110. handleError( StkError::FILE_ERROR );
  111. }
  112. return;
  113. error:
  114. oStream_ << "FileRead::open: error reading file (" << fileName << ")!";
  115. handleError( StkError::FILE_ERROR );
  116. }
  117. bool FileRead :: getRawInfo( const char *fileName, unsigned int nChannels, StkFormat format, StkFloat rate )
  118. {
  119. // Use the system call "stat" to determine the file length.
  120. struct stat filestat;
  121. if ( stat(fileName, &filestat) == -1 ) {
  122. oStream_ << "FileRead: Could not stat RAW file (" << fileName << ").";
  123. return false;
  124. }
  125. if ( nChannels == 0 ) {
  126. oStream_ << "FileRead: number of channels can't be 0 (" << fileName << ").";
  127. return false;
  128. }
  129. // Rawwave files have no header and by default, are assumed to
  130. // contain a monophonic stream of 16-bit signed integers in
  131. // big-endian byte order at a sample rate of 22050 Hz. However,
  132. // different parameters can be specified if desired.
  133. dataOffset_ = 0;
  134. channels_ = nChannels;
  135. dataType_ = format;
  136. fileRate_ = rate;
  137. int sampleBytes = 0;
  138. if ( format == STK_SINT8 ) sampleBytes = 1;
  139. else if ( format == STK_SINT16 ) sampleBytes = 2;
  140. else if ( format == STK_SINT32 || format == STK_FLOAT32 ) sampleBytes = 4;
  141. else if ( format == STK_FLOAT64 ) sampleBytes = 8;
  142. else {
  143. oStream_ << "FileRead: StkFormat " << format << " is invalid (" << fileName << ").";
  144. return false;
  145. }
  146. fileSize_ = (long) filestat.st_size / sampleBytes / channels_; // length in frames
  147. byteswap_ = false;
  148. #ifdef __LITTLE_ENDIAN__
  149. byteswap_ = true;
  150. #endif
  151. return true;
  152. }
  153. bool FileRead :: getWavInfo( const char *fileName )
  154. {
  155. // Find "format" chunk ... it must come before the "data" chunk.
  156. char id[4];
  157. SINT32 chunkSize;
  158. if ( fread(&id, 4, 1, fd_) != 1 ) goto error;
  159. while ( strncmp(id, "fmt ", 4) ) {
  160. if ( fread(&chunkSize, 4, 1, fd_) != 1 ) goto error;
  161. #ifndef __LITTLE_ENDIAN__
  162. swap32((unsigned char *)&chunkSize);
  163. #endif
  164. if ( fseek(fd_, chunkSize, SEEK_CUR) == -1 ) goto error;
  165. if ( fread(&id, 4, 1, fd_) != 1 ) goto error;
  166. }
  167. // Check that the data is not compressed.
  168. unsigned short format_tag;
  169. if ( fread(&chunkSize, 4, 1, fd_) != 1 ) goto error; // Read fmt chunk size.
  170. if ( fread(&format_tag, 2, 1, fd_) != 1 ) goto error;
  171. #ifndef __LITTLE_ENDIAN__
  172. swap16((unsigned char *)&format_tag);
  173. swap32((unsigned char *)&chunkSize);
  174. #endif
  175. if ( format_tag == 0xFFFE ) { // WAVE_FORMAT_EXTENSIBLE
  176. dataOffset_ = ftell(fd_);
  177. if ( fseek(fd_, 14, SEEK_CUR) == -1 ) goto error;
  178. unsigned short extSize;
  179. if ( fread(&extSize, 2, 1, fd_) != 1 ) goto error;
  180. #ifndef __LITTLE_ENDIAN__
  181. swap16((unsigned char *)&extSize);
  182. #endif
  183. if ( extSize == 0 ) goto error;
  184. if ( fseek(fd_, 6, SEEK_CUR) == -1 ) goto error;
  185. if ( fread(&format_tag, 2, 1, fd_) != 1 ) goto error;
  186. #ifndef __LITTLE_ENDIAN__
  187. swap16((unsigned char *)&format_tag);
  188. #endif
  189. if ( fseek(fd_, dataOffset_, SEEK_SET) == -1 ) goto error;
  190. }
  191. if ( format_tag != 1 && format_tag != 3 ) { // PCM = 1, FLOAT = 3
  192. oStream_ << "FileRead: "<< fileName << " contains an unsupported data format type (" << format_tag << ").";
  193. return false;
  194. }
  195. // Get number of channels from the header.
  196. SINT16 temp;
  197. if ( fread(&temp, 2, 1, fd_) != 1 ) goto error;
  198. #ifndef __LITTLE_ENDIAN__
  199. swap16((unsigned char *)&temp);
  200. #endif
  201. channels_ = (unsigned int ) temp;
  202. // Get file sample rate from the header.
  203. SINT32 srate;
  204. if ( fread(&srate, 4, 1, fd_) != 1 ) goto error;
  205. #ifndef __LITTLE_ENDIAN__
  206. swap32((unsigned char *)&srate);
  207. #endif
  208. fileRate_ = (StkFloat) srate;
  209. // Determine the data type.
  210. dataType_ = 0;
  211. if ( fseek(fd_, 6, SEEK_CUR) == -1 ) goto error; // Locate bits_per_sample info.
  212. if ( fread(&temp, 2, 1, fd_) != 1 ) goto error;
  213. #ifndef __LITTLE_ENDIAN__
  214. swap16((unsigned char *)&temp);
  215. #endif
  216. if ( format_tag == 1 ) {
  217. if ( temp == 8 )
  218. dataType_ = STK_SINT8;
  219. else if ( temp == 16 )
  220. dataType_ = STK_SINT16;
  221. else if ( temp == 24 )
  222. dataType_ = STK_SINT24;
  223. else if ( temp == 32 )
  224. dataType_ = STK_SINT32;
  225. }
  226. else if ( format_tag == 3 ) {
  227. if ( temp == 32 )
  228. dataType_ = STK_FLOAT32;
  229. else if ( temp == 64 )
  230. dataType_ = STK_FLOAT64;
  231. }
  232. if ( dataType_ == 0 ) {
  233. oStream_ << "FileRead: " << temp << " bits per sample with data format " << format_tag << " are not supported (" << fileName << ").";
  234. return false;
  235. }
  236. // Jump over any remaining part of the "fmt" chunk.
  237. if ( fseek(fd_, chunkSize-16, SEEK_CUR) == -1 ) goto error;
  238. // Find "data" chunk ... it must come after the "fmt" chunk.
  239. if ( fread(&id, 4, 1, fd_) != 1 ) goto error;
  240. while ( strncmp(id, "data", 4) ) {
  241. if ( fread(&chunkSize, 4, 1, fd_) != 1 ) goto error;
  242. #ifndef __LITTLE_ENDIAN__
  243. swap32((unsigned char *)&chunkSize);
  244. #endif
  245. chunkSize += chunkSize % 2; // chunk sizes must be even
  246. if ( fseek(fd_, chunkSize, SEEK_CUR) == -1 ) goto error;
  247. if ( fread(&id, 4, 1, fd_) != 1 ) goto error;
  248. }
  249. // Get length of data from the header.
  250. SINT32 bytes;
  251. if ( fread(&bytes, 4, 1, fd_) != 1 ) goto error;
  252. #ifndef __LITTLE_ENDIAN__
  253. swap32((unsigned char *)&bytes);
  254. #endif
  255. fileSize_ = bytes / temp / channels_; // sample frames
  256. fileSize_ *= 8; // sample frames
  257. dataOffset_ = ftell(fd_);
  258. byteswap_ = false;
  259. #ifndef __LITTLE_ENDIAN__
  260. byteswap_ = true;
  261. #endif
  262. wavFile_ = true;
  263. return true;
  264. error:
  265. oStream_ << "FileRead: error reading WAV file (" << fileName << ").";
  266. return false;
  267. }
  268. bool FileRead :: getSndInfo( const char *fileName )
  269. {
  270. // Determine the data type.
  271. UINT32 format;
  272. if ( fseek(fd_, 12, SEEK_SET) == -1 ) goto error; // Locate format
  273. if ( fread(&format, 4, 1, fd_) != 1 ) goto error;
  274. #ifdef __LITTLE_ENDIAN__
  275. swap32((unsigned char *)&format);
  276. #endif
  277. if (format == 2) dataType_ = STK_SINT8;
  278. else if (format == 3) dataType_ = STK_SINT16;
  279. else if (format == 4) dataType_ = STK_SINT24;
  280. else if (format == 5) dataType_ = STK_SINT32;
  281. else if (format == 6) dataType_ = STK_FLOAT32;
  282. else if (format == 7) dataType_ = STK_FLOAT64;
  283. else {
  284. oStream_ << "FileRead: data format in file " << fileName << " is not supported.";
  285. return false;
  286. }
  287. // Get file sample rate from the header.
  288. UINT32 srate;
  289. if ( fread(&srate, 4, 1, fd_) != 1 ) goto error;
  290. #ifdef __LITTLE_ENDIAN__
  291. swap32((unsigned char *)&srate);
  292. #endif
  293. fileRate_ = (StkFloat) srate;
  294. // Get number of channels from the header.
  295. UINT32 chans;
  296. if ( fread(&chans, 4, 1, fd_) != 1 ) goto error;
  297. #ifdef __LITTLE_ENDIAN__
  298. swap32((unsigned char *)&chans);
  299. #endif
  300. channels_ = chans;
  301. UINT32 offset;
  302. if ( fseek(fd_, 4, SEEK_SET) == -1 ) goto error;
  303. if ( fread(&offset, 4, 1, fd_) != 1 ) goto error;
  304. #ifdef __LITTLE_ENDIAN__
  305. swap32((unsigned char *)&offset);
  306. #endif
  307. dataOffset_ = offset;
  308. // Get length of data from the header.
  309. if ( fread(&fileSize_, 4, 1, fd_) != 1 ) goto error;
  310. #ifdef __LITTLE_ENDIAN__
  311. swap32((unsigned char *)&fileSize_);
  312. #endif
  313. // Convert to sample frames.
  314. if ( dataType_ == STK_SINT8 )
  315. fileSize_ /= channels_;
  316. if ( dataType_ == STK_SINT16 )
  317. fileSize_ /= 2 * channels_;
  318. else if ( dataType_ == STK_SINT24 )
  319. fileSize_ /= 3 * channels_;
  320. else if ( dataType_ == STK_SINT32 || dataType_ == STK_FLOAT32 )
  321. fileSize_ /= 4 * channels_;
  322. else if ( dataType_ == STK_FLOAT64 )
  323. fileSize_ /= 8 * channels_;
  324. byteswap_ = false;
  325. #ifdef __LITTLE_ENDIAN__
  326. byteswap_ = true;
  327. #endif
  328. return true;
  329. error:
  330. oStream_ << "FileRead: Error reading SND file (" << fileName << ").";
  331. return false;
  332. }
  333. bool FileRead :: getAifInfo( const char *fileName )
  334. {
  335. bool aifc = false;
  336. char id[4];
  337. // Determine whether this is AIFF or AIFC.
  338. if ( fseek(fd_, 8, SEEK_SET) == -1 ) goto error;
  339. if ( fread(&id, 4, 1, fd_) != 1 ) goto error;
  340. if ( !strncmp(id, "AIFC", 4) ) aifc = true;
  341. // Find "common" chunk
  342. SINT32 chunkSize;
  343. if ( fread(&id, 4, 1, fd_) != 1) goto error;
  344. while ( strncmp(id, "COMM", 4) ) {
  345. if ( fread(&chunkSize, 4, 1, fd_) != 1 ) goto error;
  346. #ifdef __LITTLE_ENDIAN__
  347. swap32((unsigned char *)&chunkSize);
  348. #endif
  349. chunkSize += chunkSize % 2; // chunk sizes must be even
  350. if ( fseek(fd_, chunkSize, SEEK_CUR) == -1 ) goto error;
  351. if ( fread(&id, 4, 1, fd_) != 1 ) goto error;
  352. }
  353. // Get number of channels from the header.
  354. SINT16 temp;
  355. if ( fseek(fd_, 4, SEEK_CUR) == -1 ) goto error; // Jump over chunk size
  356. if ( fread(&temp, 2, 1, fd_) != 1 ) goto error;
  357. #ifdef __LITTLE_ENDIAN__
  358. swap16((unsigned char *)&temp);
  359. #endif
  360. channels_ = temp;
  361. // Get length of data from the header.
  362. SINT32 frames;
  363. if ( fread(&frames, 4, 1, fd_) != 1 ) goto error;
  364. #ifdef __LITTLE_ENDIAN__
  365. swap32((unsigned char *)&frames);
  366. #endif
  367. fileSize_ = frames; // sample frames
  368. // Read the number of bits per sample.
  369. if ( fread(&temp, 2, 1, fd_) != 1 ) goto error;
  370. #ifdef __LITTLE_ENDIAN__
  371. swap16((unsigned char *)&temp);
  372. #endif
  373. // Get file sample rate from the header. For AIFF files, this value
  374. // is stored in a 10-byte, IEEE Standard 754 floating point number,
  375. // so we need to convert it first.
  376. unsigned char srate[10];
  377. unsigned char exp;
  378. unsigned long mantissa;
  379. unsigned long last;
  380. if ( fread(&srate, 10, 1, fd_) != 1 ) goto error;
  381. mantissa = (unsigned long) *(unsigned long *)(srate+2);
  382. #ifdef __LITTLE_ENDIAN__
  383. swap32((unsigned char *)&mantissa);
  384. #endif
  385. exp = 30 - *(srate+1);
  386. last = 0;
  387. while (exp--) {
  388. last = mantissa;
  389. mantissa >>= 1;
  390. }
  391. if (last & 0x00000001) mantissa++;
  392. fileRate_ = (StkFloat) mantissa;
  393. byteswap_ = false;
  394. #ifdef __LITTLE_ENDIAN__
  395. byteswap_ = true;
  396. #endif
  397. // Determine the data format.
  398. dataType_ = 0;
  399. if ( aifc == false ) {
  400. if ( temp <= 8 ) dataType_ = STK_SINT8;
  401. else if ( temp <= 16 ) dataType_ = STK_SINT16;
  402. else if ( temp <= 24 ) dataType_ = STK_SINT24;
  403. else if ( temp <= 32 ) dataType_ = STK_SINT32;
  404. }
  405. else {
  406. if ( fread(&id, 4, 1, fd_) != 1 ) goto error;
  407. if ( !strncmp(id, "sowt", 4) ) { // uncompressed little-endian
  408. if ( byteswap_ == false ) byteswap_ = true;
  409. else byteswap_ = false;
  410. }
  411. if ( !strncmp(id, "NONE", 4) || !strncmp(id, "sowt", 4) ) {
  412. if ( temp <= 8 ) dataType_ = STK_SINT8;
  413. else if ( temp <= 16 ) dataType_ = STK_SINT16;
  414. else if ( temp <= 24 ) dataType_ = STK_SINT24;
  415. else if ( temp <= 32 ) dataType_ = STK_SINT32;
  416. }
  417. else if ( (!strncmp(id, "fl32", 4) || !strncmp(id, "FL32", 4)) && temp == 32 ) dataType_ = STK_FLOAT32;
  418. else if ( (!strncmp(id, "fl64", 4) || !strncmp(id, "FL64", 4)) && temp == 64 ) dataType_ = STK_FLOAT64;
  419. }
  420. if ( dataType_ == 0 ) {
  421. oStream_ << "FileRead: AIFF/AIFC file (" << fileName << ") has unsupported data type (" << id << ").";
  422. return false;
  423. }
  424. // Start at top to find data (SSND) chunk ... chunk order is undefined.
  425. if ( fseek(fd_, 12, SEEK_SET) == -1 ) goto error;
  426. // Find data (SSND) chunk
  427. if ( fread(&id, 4, 1, fd_) != 1 ) goto error;
  428. while ( strncmp(id, "SSND", 4) ) {
  429. if ( fread(&chunkSize, 4, 1, fd_) != 1 ) goto error;
  430. #ifdef __LITTLE_ENDIAN__
  431. swap32((unsigned char *)&chunkSize);
  432. #endif
  433. chunkSize += chunkSize % 2; // chunk sizes must be even
  434. if ( fseek(fd_, chunkSize, SEEK_CUR) == -1 ) goto error;
  435. if ( fread(&id, 4, 1, fd_) != 1 ) goto error;
  436. }
  437. // Skip over chunk size, offset, and blocksize fields
  438. if ( fseek(fd_, 12, SEEK_CUR) == -1 ) goto error;
  439. dataOffset_ = ftell(fd_);
  440. return true;
  441. error:
  442. oStream_ << "FileRead: Error reading AIFF file (" << fileName << ").";
  443. return false;
  444. }
  445. bool FileRead :: findNextMatArray( SINT32 *chunkSize, SINT32 *rows, SINT32 *columns, SINT32 *nametype )
  446. {
  447. // Look for the next data array element. The file pointer should be
  448. // at the data element type when this function is called.
  449. SINT32 datatype;
  450. *chunkSize = 0;
  451. do {
  452. if ( fseek(fd_, *chunkSize, SEEK_CUR) == -1 ) return false;
  453. if ( fread(&datatype, 4, 1, fd_) != 1 ) return false;
  454. if ( byteswap_ ) swap32((unsigned char *)&datatype);
  455. if ( fread(chunkSize, 4, 1, fd_) != 1 ) return false;
  456. if ( byteswap_ ) swap32((unsigned char *)chunkSize);
  457. } while ( datatype != 14 );
  458. // Check dimension subelement size to make sure 2D
  459. if ( fseek(fd_, 20, SEEK_CUR) == -1 ) return false;
  460. SINT32 size;
  461. if ( fread(&size, 4, 1, fd_) != 1 ) return false;
  462. if ( byteswap_ ) swap32((unsigned char *)&size);
  463. if ( size != 8 ) return false;
  464. // Read dimensions data
  465. if ( fread(rows, 4, 1, fd_) != 1 ) return false;
  466. if ( byteswap_ ) swap32((unsigned char *)rows);
  467. if ( fread(columns, 4, 1, fd_) != 1 ) return false;
  468. if ( byteswap_ ) swap32((unsigned char *)columns);
  469. // Read array name subelement type
  470. if ( fread(nametype, 4, 1, fd_) != 1 ) return false;
  471. if ( byteswap_ ) swap32((unsigned char *)nametype);
  472. return true;
  473. }
  474. bool FileRead :: getMatInfo( const char *fileName )
  475. {
  476. // MAT-file formatting information is available at:
  477. // http://www.mathworks.com/access/helpdesk/help/pdf_doc/matlab/matfile_format.pdf
  478. // Verify this is a version 5 MAT-file format.
  479. char head[5];
  480. if ( fseek(fd_, 0, SEEK_SET) == -1 ) goto error;
  481. if ( fread(&head, 4, 1, fd_) != 1 ) goto error;
  482. // If any of the first 4 characters of the header = 0, then this is
  483. // a Version 4 MAT-file.
  484. head[4] = '\0';
  485. if ( strstr(head, "0") ) {
  486. oStream_ << "FileRead: " << fileName << " appears to be a Version 4 MAT-file, which is not currently supported.";
  487. return false;
  488. }
  489. // Determine the endian-ness of the file.
  490. char mi[2];
  491. byteswap_ = false;
  492. // Locate "M" and "I" characters in header.
  493. if ( fseek(fd_, 126, SEEK_SET) == -1 ) goto error;
  494. if ( fread(&mi, 2, 1, fd_) != 1) goto error;
  495. #ifdef __LITTLE_ENDIAN__
  496. if ( !strncmp(mi, "MI", 2) )
  497. byteswap_ = true;
  498. else if ( strncmp(mi, "IM", 2) ) goto error;
  499. #else
  500. if ( !strncmp(mi, "IM", 2))
  501. byteswap_ = true;
  502. else if ( strncmp(mi, "MI", 2) ) goto error;
  503. #endif
  504. // We are expecting a data element containing the audio data and an
  505. // optional data element containing the sample rate (with an array
  506. // name of "fs"). Both elements should be stored as a Matlab array
  507. // type (14).
  508. bool doneParsing, haveData, haveSampleRate;
  509. SINT32 chunkSize, rows, columns, nametype;
  510. long dataoffset;
  511. doneParsing = false;
  512. haveData = false;
  513. haveSampleRate = false;
  514. while ( !doneParsing ) {
  515. dataoffset = ftell( fd_ ); // save location in file
  516. if ( findNextMatArray( &chunkSize, &rows, &columns, &nametype ) == false ) {
  517. // No more Matlab array type chunks found.
  518. if ( !haveData ) {
  519. oStream_ << "FileRead: No audio data found in MAT-file (" << fileName << ").";
  520. return false;
  521. }
  522. else if ( !haveSampleRate ) {
  523. fileRate_ = 44100.0;
  524. oStream_ << "FileRead: No sample rate found ... assuming 44100.0";
  525. handleError( StkError::WARNING );
  526. return true;
  527. }
  528. else return true;
  529. }
  530. if ( !haveSampleRate && rows == 1 && columns == 1 ) { // Parse for sample rate.
  531. SINT32 namesize = 4;
  532. if ( nametype == 1 ) { // array name > 4 characters
  533. if ( fread(&namesize, 4, 1, fd_) != 1 ) goto error;
  534. if ( byteswap_ ) swap32((unsigned char *)&namesize);
  535. if ( namesize != 2 ) goto tryagain; // expecting name = "fs"
  536. namesize = 8; // field must be padded to multiple of 8 bytes
  537. }
  538. char name[3]; name[2] = '\0';
  539. if ( fread(&name, 2, 1, fd_) != 1) goto error;
  540. if ( strncmp(name, "fs", 2) ) goto tryagain;
  541. // Jump to real part data subelement, which is likely to be in a
  542. // small data format.
  543. if ( fseek(fd_, namesize-2, SEEK_CUR) == -1 ) goto error;
  544. UINT32 type;
  545. StkFloat srate;
  546. if ( fread(&type, 4, 1, fd_) != 1 ) goto error;
  547. if ( byteswap_ ) swap32((unsigned char *)&type);
  548. if ( (type & 0xffff0000) != 0 ) // small data format
  549. type = (type & 0x0000ffff);
  550. else
  551. if ( fseek(fd_, 4, SEEK_CUR) == -1 ) goto error;
  552. if ( type == 1 ) { // SINT8
  553. signed char rate;
  554. if ( fread(&rate, 1, 1, fd_) != 1 ) goto error;
  555. srate = (StkFloat) rate;
  556. }
  557. else if ( type == 2 ) { // UINT8
  558. unsigned char rate;
  559. if ( fread(&rate, 1, 1, fd_) != 1 ) goto error;
  560. srate = (StkFloat) rate;
  561. }
  562. else if ( type == 3 ) { // SINT16
  563. SINT16 rate;
  564. if ( fread(&rate, 2, 1, fd_) != 1 ) goto error;
  565. if ( byteswap_ ) swap16((unsigned char *)&rate);
  566. srate = (StkFloat) rate;
  567. }
  568. else if ( type == 4 ) { // UINT16
  569. UINT16 rate;
  570. if ( fread(&rate, 2, 1, fd_) != 1 ) goto error;
  571. if ( byteswap_ ) swap16((unsigned char *)&rate);
  572. srate = (StkFloat) rate;
  573. }
  574. else if ( type == 5 ) { // SINT32
  575. SINT32 rate;
  576. if ( fread(&rate, 4, 1, fd_) != 1 ) goto error;
  577. if ( byteswap_ ) swap32((unsigned char *)&rate);
  578. srate = (StkFloat) rate;
  579. }
  580. else if ( type == 6 ) { // UINT32
  581. UINT32 rate;
  582. if ( fread(&rate, 4, 1, fd_) != 1 ) goto error;
  583. if ( byteswap_ ) swap32((unsigned char *)&rate);
  584. srate = (StkFloat) rate;
  585. }
  586. else if ( type == 7 ) { // FLOAT32
  587. FLOAT32 rate;
  588. if ( fread(&rate, 4, 1, fd_) != 1 ) goto error;
  589. if ( byteswap_ ) swap32((unsigned char *)&rate);
  590. srate = (StkFloat) rate;
  591. }
  592. else if ( type == 9 ) { // FLOAT64
  593. FLOAT64 rate;
  594. if ( fread(&rate, 8, 1, fd_) != 1 ) goto error;
  595. if ( byteswap_ ) swap64((unsigned char *)&rate);
  596. srate = (StkFloat) rate;
  597. }
  598. else
  599. goto tryagain;
  600. if ( srate > 0 ) fileRate_ = srate;
  601. haveSampleRate = true;
  602. }
  603. else if ( !haveData ) { // Parse for data.
  604. // Assume channels = smaller of rows or columns.
  605. if ( rows < columns ) {
  606. channels_ = rows;
  607. fileSize_ = columns;
  608. }
  609. else {
  610. oStream_ << "FileRead: Transpose the MAT-file array so that audio channels fill matrix rows (not columns).";
  611. return false;
  612. }
  613. SINT32 namesize = 4;
  614. if ( nametype == 1 ) { // array name > 4 characters
  615. if ( fread(&namesize, 4, 1, fd_) != 1 ) goto error;
  616. if ( byteswap_ ) swap32((unsigned char *)&namesize);
  617. namesize = (SINT32) ceil((float)namesize / 8);
  618. if ( fseek( fd_, namesize*8, SEEK_CUR) == -1 ) goto error; // jump over array name
  619. }
  620. else {
  621. if ( fseek( fd_, 4, SEEK_CUR ) == -1 ) goto error;
  622. }
  623. // Now at real part data subelement
  624. SINT32 type;
  625. if ( fread(&type, 4, 1, fd_) != 1 ) goto error;
  626. if ( byteswap_ ) swap32((unsigned char *)&type);
  627. if ( type == 1 ) dataType_ = STK_SINT8;
  628. else if ( type == 3 ) dataType_ = STK_SINT16;
  629. else if ( type == 5 ) dataType_ = STK_SINT32;
  630. else if ( type == 7 ) dataType_ = STK_FLOAT32;
  631. else if ( type == 9 ) dataType_ = STK_FLOAT64;
  632. else {
  633. oStream_ << "FileRead: The MAT-file array data format (" << type << ") is not supported.";
  634. return false;
  635. }
  636. // Jump to the data.
  637. if ( fseek(fd_, 4, SEEK_CUR) == -1 ) goto error;
  638. dataOffset_ = ftell(fd_);
  639. haveData = true;
  640. }
  641. tryagain:
  642. if ( haveData && haveSampleRate ) doneParsing = true;
  643. else // jump to end of data element and keep trying
  644. if ( fseek( fd_, dataoffset+chunkSize+8, SEEK_SET) == -1 ) goto error;
  645. }
  646. return true;
  647. error:
  648. oStream_ << "FileRead: Error reading MAT-file (" << fileName << ") header.";
  649. return false;
  650. }
  651. void FileRead :: read( StkFrames& buffer, unsigned long startFrame, bool doNormalize )
  652. {
  653. // Make sure we have an open file.
  654. if ( fd_ == 0 ) {
  655. oStream_ << "FileRead::read: a file is not open!";
  656. Stk::handleError( StkError::WARNING ); return;
  657. }
  658. // Check the buffer size.
  659. unsigned long nFrames = buffer.frames();
  660. if ( nFrames == 0 ) {
  661. oStream_ << "FileRead::read: StkFrames buffer size is zero ... no data read!";
  662. Stk::handleError( StkError::WARNING ); return;
  663. }
  664. if ( buffer.channels() != channels_ ) {
  665. oStream_ << "FileRead::read: StkFrames argument has incompatible number of channels!";
  666. Stk::handleError( StkError::FUNCTION_ARGUMENT );
  667. }
  668. if ( startFrame >= fileSize_ ) {
  669. oStream_ << "FileRead::read: startFrame argument is greater than or equal to the file size!";
  670. Stk::handleError( StkError::FUNCTION_ARGUMENT );
  671. }
  672. // Check for file end.
  673. if ( startFrame + nFrames > fileSize_ )
  674. nFrames = fileSize_ - startFrame;
  675. long i, nSamples = (long) ( nFrames * channels_ );
  676. unsigned long offset = startFrame * channels_;
  677. // Read samples into StkFrames data buffer.
  678. if ( dataType_ == STK_SINT16 ) {
  679. SINT16 *buf = (SINT16 *) &buffer[0];
  680. if ( fseek( fd_, dataOffset_+(offset*2), SEEK_SET ) == -1 ) goto error;
  681. if ( fread( buf, nSamples * 2, 1, fd_ ) != 1 ) goto error;
  682. if ( byteswap_ ) {
  683. SINT16 *ptr = buf;
  684. for ( i=nSamples-1; i>=0; i-- )
  685. swap16( (unsigned char *) ptr++ );
  686. }
  687. if ( doNormalize ) {
  688. StkFloat gain = 1.0 / 32768.0;
  689. for ( i=nSamples-1; i>=0; i-- )
  690. buffer[i] = buf[i] * gain;
  691. }
  692. else {
  693. for ( i=nSamples-1; i>=0; i-- )
  694. buffer[i] = buf[i];
  695. }
  696. }
  697. else if ( dataType_ == STK_SINT32 ) {
  698. SINT32 *buf = (SINT32 *) &buffer[0];
  699. if ( fseek( fd_, dataOffset_+(offset*4 ), SEEK_SET ) == -1 ) goto error;
  700. if ( fread( buf, nSamples * 4, 1, fd_ ) != 1 ) goto error;
  701. if ( byteswap_ ) {
  702. SINT32 *ptr = buf;
  703. for ( i=nSamples-1; i>=0; i-- )
  704. swap32( (unsigned char *) ptr++ );
  705. }
  706. if ( doNormalize ) {
  707. StkFloat gain = 1.0 / 2147483648.0;
  708. for ( i=nSamples-1; i>=0; i-- )
  709. buffer[i] = buf[i] * gain;
  710. }
  711. else {
  712. for ( i=nSamples-1; i>=0; i-- )
  713. buffer[i] = buf[i];
  714. }
  715. }
  716. else if ( dataType_ == STK_FLOAT32 ) {
  717. FLOAT32 *buf = (FLOAT32 *) &buffer[0];
  718. if ( fseek( fd_, dataOffset_+(offset*4), SEEK_SET ) == -1 ) goto error;
  719. if ( fread( buf, nSamples * 4, 1, fd_ ) != 1 ) goto error;
  720. if ( byteswap_ ) {
  721. FLOAT32 *ptr = buf;
  722. for ( i=nSamples-1; i>=0; i-- )
  723. swap32( (unsigned char *) ptr++ );
  724. }
  725. for ( i=nSamples-1; i>=0; i-- )
  726. buffer[i] = buf[i];
  727. }
  728. else if ( dataType_ == STK_FLOAT64 ) {
  729. FLOAT64 *buf = (FLOAT64 *) &buffer[0];
  730. if ( fseek( fd_, dataOffset_+(offset*8), SEEK_SET ) == -1 ) goto error;
  731. if ( fread( buf, nSamples * 8, 1, fd_ ) != 1 ) goto error;
  732. if ( byteswap_ ) {
  733. FLOAT64 *ptr = buf;
  734. for ( i=nSamples-1; i>=0; i-- )
  735. swap64( (unsigned char *) ptr++ );
  736. }
  737. for ( i=nSamples-1; i>=0; i-- )
  738. buffer[i] = buf[i];
  739. }
  740. else if ( dataType_ == STK_SINT8 && wavFile_ ) { // 8-bit WAV data is unsigned!
  741. unsigned char *buf = (unsigned char *) &buffer[0];
  742. if ( fseek( fd_, dataOffset_+offset, SEEK_SET ) == -1 ) goto error;
  743. if ( fread( buf, nSamples, 1, fd_) != 1 ) goto error;
  744. if ( doNormalize ) {
  745. StkFloat gain = 1.0 / 128.0;
  746. for ( i=nSamples-1; i>=0; i-- )
  747. buffer[i] = ( buf[i] - 128 ) * gain;
  748. }
  749. else {
  750. for ( i=nSamples-1; i>=0; i-- )
  751. buffer[i] = buf[i] - 128.0;
  752. }
  753. }
  754. else if ( dataType_ == STK_SINT8 ) { // signed 8-bit data
  755. char *buf = (char *) &buffer[0];
  756. if ( fseek( fd_, dataOffset_+offset, SEEK_SET ) == -1 ) goto error;
  757. if ( fread( buf, nSamples, 1, fd_ ) != 1 ) goto error;
  758. if ( doNormalize ) {
  759. StkFloat gain = 1.0 / 128.0;
  760. for ( i=nSamples-1; i>=0; i-- )
  761. buffer[i] = buf[i] * gain;
  762. }
  763. else {
  764. for ( i=nSamples-1; i>=0; i-- )
  765. buffer[i] = buf[i];
  766. }
  767. }
  768. else if ( dataType_ == STK_SINT24 ) {
  769. // 24-bit values are harder to import efficiently since there is
  770. // no native 24-bit type. The following routine works but is much
  771. // less efficient than that used for the other data types.
  772. SINT32 temp;
  773. unsigned char *ptr = (unsigned char *) &temp;
  774. StkFloat gain = 1.0 / 2147483648.0;
  775. if ( fseek(fd_, dataOffset_+(offset*3), SEEK_SET ) == -1 ) goto error;
  776. for ( i=0; i<nSamples; i++ ) {
  777. #ifdef __LITTLE_ENDIAN__
  778. if ( byteswap_ ) {
  779. if ( fread( ptr, 3, 1, fd_ ) != 1 ) goto error;
  780. temp &= 0x00ffffff;
  781. swap32( (unsigned char *) ptr );
  782. }
  783. else {
  784. if ( fread( ptr+1, 3, 1, fd_ ) != 1 ) goto error;
  785. temp &= 0xffffff00;
  786. }
  787. #else
  788. if ( byteswap_ ) {
  789. if ( fread( ptr+1, 3, 1, fd_ ) != 1 ) goto error;
  790. temp &= 0xffffff00;
  791. swap32( (unsigned char *) ptr );
  792. }
  793. else {
  794. if ( fread( ptr, 3, 1, fd_ ) != 1 ) goto error;
  795. temp &= 0x00ffffff;
  796. }
  797. #endif
  798. if ( doNormalize ) {
  799. buffer[i] = (StkFloat) temp * gain; // "gain" also includes 1 / 256 factor.
  800. }
  801. else
  802. buffer[i] = (StkFloat) temp / 256; // right shift without affecting the sign bit
  803. }
  804. }
  805. buffer.setDataRate( fileRate_ );
  806. return;
  807. error:
  808. oStream_ << "FileRead: Error reading file data.";
  809. handleError( StkError::FILE_ERROR);
  810. }
  811. } // stk namespace