⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fileread.cpp

📁 Mobile STK for Symbian OS V0.1
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/***************************************************//*! \class FileRead    \brief STK audio file input class.    This class provides input support for various    audio file formats.  Multi-channel (>2)    soundfiles are supported.  The file data is    returned via an external StkFrames object    passed to the read() function.  This class    does not store its own copy of the file data,    rather the data is read directly from disk.    FileRead currently supports uncompressed WAV,    AIFF/AIFC, SND (AU), MAT-file (Matlab), and    STK RAW file formats.  Signed integer (8-,    16-, and 32-bit) and floating-point (32- and    64-bit) data types are supported.  Compressed    data types are not supported.    STK RAW files have no header and are assumed    to contain a monophonic stream of 16-bit    signed integers in big-endian byte order at a    sample rate of 22050 Hz.  MAT-file data should    be saved in an array with each data channel    filling a matrix row.  The sample rate for    MAT-files is assumed to be 44100 Hz.    by Perry R. Cook and Gary P. Scavone, 1995 - 2005.*//***************************************************/#include "FileRead.h"#if !defined(SYMBIAN)#include <sys/stat.h>#include <sys/types.h>#include <cmath>#else#include "symbmath.h"#endifFileRead :: FileRead()  : fd_(0){}#if !defined(SYMBIAN)FileRead :: FileRead( std::string fileName, bool typeRaw )#elseFileRead :: FileRead( const char* fileName, bool typeRaw )#endif  : fd_(0){  open( fileName, typeRaw );}FileRead :: ~FileRead(){  if ( fd_ )    fclose( fd_ );}void FileRead :: close( void ){  if ( fd_ ) fclose( fd_ );  fd_ = 0;  wavFile_ = false;}bool FileRead :: isOpen( void ){  if ( fd_ ) return true;  else return false;}#if !defined(SYMBIAN)void FileRead :: open( std::string fileName, bool typeRaw ) {#elsevoid FileRead :: open( const char *fileName, TBool typeRaw ){#endif  // If another file is open, close it.  close();  // Try to open the file.#if !defined(SYMBIAN)  fd_ = fopen( fileName.c_str(), "rb" );#else  fd_ = fopen( fileName, "rb" );#endif  if ( !fd_ ) {	  /*    errorString_ << "FileRead::open: could not open or find file (" << fileName << ")!";    handleError( StkError::FILE_NOT_FOUND );	*/  }  // Attempt to determine file type from header (unless RAW).  bool result = false;  if ( typeRaw )#if !defined(SYMBIAN)    result = getRawInfo( fileName.c_str() );#else    result = getRawInfo( fileName );#endif  else {    char header[12];    if ( fread( &header, 4, 3, fd_ ) != 3 ) goto error;    if ( !strncmp( header, "RIFF", 4 ) &&         !strncmp( &header[8], "WAVE", 4 ) )#if !defined(SYMBIAN)      result = getWavInfo( fileName.c_str() );#else      result = getWavInfo( fileName );#endif    else if ( !strncmp( header, ".snd", 4 ) )#if !defined(SYMBIAN)      result = getSndInfo( fileName.c_str() );#else      result = getSndInfo( fileName );#endif    else if ( !strncmp( header, "FORM", 4 ) &&              ( !strncmp( &header[8], "AIFF", 4 ) || !strncmp(&header[8], "AIFC", 4) ) )#if !defined(SYMBIAN)      result = getAifInfo( fileName.c_str() );#else      result = getAifInfo( fileName );#endif    else {      if ( fseek( fd_, 126, SEEK_SET ) == -1 ) goto error;      if ( fread( &header, 2, 1, fd_ ) != 1 ) goto error;      if ( !strncmp( header, "MI", 2 ) ||           !strncmp( header, "IM", 2 ) )#if !defined(SYMBIAN)        result = getMatInfo( fileName.c_str() );#else        result = getMatInfo( fileName );#endif      else {#if !defined(SYMBIAN)        errorString_ << "FileRead::open: file (" << fileName << ") format unknown.";        handleError( StkError::FILE_UNKNOWN_FORMAT );#endif      }    }  }  // If here, we had a file type candidate but something else went wrong.#if !defined(SYMBIAN)  if ( result == false )    handleError( StkError::FILE_ERROR );#endif  // Check for empty files.  if ( fileSize_ == 0 ) {#if !defined(SYMBIAN)    errorString_ << "FileRead::open: file (" << fileName << ") data size is zero!";    handleError( StkError::FILE_ERROR );#endif  }  return; error:#if !defined(SYMBIAN)  errorString_ << "FileRead::open: error reading file (" << fileName << ")!";  handleError( StkError::FILE_ERROR );#else  {}#endif}bool FileRead :: getRawInfo( const char *fileName ){  // Use the system call "stat" to determine the file length.  struct stat filestat;  if ( stat(fileName, &filestat) == -1 ) {#if !defined(SYMBIAN)    errorString_ << "FileRead: Could not stat RAW file (" << fileName << ").";#endif    return false;  }  // STK rawwave files have no header and are assumed to contain a  // monophonic stream of 16-bit signed integers in big-endian byte  // order at a sample rate of 22050 Hz.  channels_ = 1;  fileSize_ = (long) filestat.st_size / 2;  // length in 2-byte samples  dataOffset_ = 0;  fileRate_ = 22050.0;  dataType_ = STK_SINT16;  byteswap_ = false;#ifdef __LITTLE_ENDIAN__  byteswap_ = true;#endif  return true;}bool FileRead :: getWavInfo( const char *fileName ){  // Find "format" chunk ... it must come before the "data" chunk.  char id[4];  SINT32 chunkSize;  if ( fread(&id, 4, 1, fd_) != 1 ) goto error;  while ( strncmp(id, "fmt ", 4) ) {    if ( fread(&chunkSize, 4, 1, fd_) != 1 ) goto error;#ifndef __LITTLE_ENDIAN__    swap32((unsigned char *)&chunkSize);#endif    if ( fseek(fd_, chunkSize, SEEK_CUR) == -1 ) goto error;    if ( fread(&id, 4, 1, fd_) != 1 ) goto error;  }  // Check that the data is not compressed.  unsigned short format_tag;  if ( fread(&chunkSize, 4, 1, fd_) != 1 ) goto error; // Read fmt chunk size.  if ( fread(&format_tag, 2, 1, fd_) != 1 ) goto error;#ifndef __LITTLE_ENDIAN__  swap16((unsigned char *)&format_tag);  swap32((unsigned char *)&chunkSize);#endif  if ( format_tag == 0xFFFE ) { // WAVE_FORMAT_EXTENSIBLE    dataOffset_ = ftell(fd_);    if ( fseek(fd_, 14, SEEK_CUR) == -1 ) goto error;    unsigned short extSize;    if ( fread(&extSize, 2, 1, fd_) != 1 ) goto error;#ifndef __LITTLE_ENDIAN__    swap16((unsigned char *)&extSize);#endif    if ( extSize == 0 ) goto error;    if ( fseek(fd_, 6, SEEK_CUR) == -1 ) goto error;    if ( fread(&format_tag, 2, 1, fd_) != 1 ) goto error;#ifndef __LITTLE_ENDIAN__    swap16((unsigned char *)&format_tag);#endif    if ( fseek(fd_, dataOffset_, SEEK_SET) == -1 ) goto error;  }  if (format_tag != 1 && format_tag != 3 ) { // PCM = 1, FLOAT = 3#if !defined(SYMBIAN)    errorString_ << "FileRead: "<< fileName << " contains an unsupported data format type (" << format_tag << ").";#endif    return false;  }  // Get number of channels from the header.  SINT16 temp;  if ( fread(&temp, 2, 1, fd_) != 1 ) goto error;#ifndef __LITTLE_ENDIAN__  swap16((unsigned char *)&temp);#endif  channels_ = (unsigned int ) temp;  // Get file sample rate from the header.  SINT32 srate;  if ( fread(&srate, 4, 1, fd_) != 1 ) goto error;#ifndef __LITTLE_ENDIAN__  swap32((unsigned char *)&srate);#endif  fileRate_ = (StkFloat) srate;  // Determine the data type.  dataType_ = 0;  if ( fseek(fd_, 6, SEEK_CUR) == -1 ) goto error;   // Locate bits_per_sample info.  if ( fread(&temp, 2, 1, fd_) != 1 ) goto error;#ifndef __LITTLE_ENDIAN__  swap16((unsigned char *)&temp);#endif  if ( format_tag == 1 ) {    if (temp == 8)      dataType_ = STK_SINT8;    else if (temp == 16)      dataType_ = STK_SINT16;    else if (temp == 32)      dataType_ = STK_SINT32;  }  else if ( format_tag == 3 ) {    if (temp == 32)      dataType_ = STK_FLOAT32;    else if (temp == 64)      dataType_ = STK_FLOAT64;  }  if ( dataType_ == 0 ) {#if !defined(SYMBIAN)    errorString_ << "FileRead: " << temp << " bits per sample with data format " << format_tag << " are not supported (" << fileName << ").";#endif    return false;  }  // Jump over any remaining part of the "fmt" chunk.  if ( fseek(fd_, chunkSize-16, SEEK_CUR) == -1 ) goto error;  // Find "data" chunk ... it must come after the "fmt" chunk.  if ( fread(&id, 4, 1, fd_) != 1 ) goto error;  while ( strncmp(id, "data", 4) ) {    if ( fread(&chunkSize, 4, 1, fd_) != 1 ) goto error;#ifndef __LITTLE_ENDIAN__    swap32((unsigned char *)&chunkSize);#endif    chunkSize += chunkSize % 2; // chunk sizes must be even    if ( fseek(fd_, chunkSize, SEEK_CUR) == -1 ) goto error;    if ( fread(&id, 4, 1, fd_) != 1 ) goto error;  }  // Get length of data from the header.  SINT32 bytes;  if ( fread(&bytes, 4, 1, fd_) != 1 ) goto error;#ifndef __LITTLE_ENDIAN__  swap32((unsigned char *)&bytes);#endif  fileSize_ = 8 * bytes / temp / channels_;  // sample frames  dataOffset_ = ftell(fd_);  byteswap_ = false;#ifndef __LITTLE_ENDIAN__  byteswap_ = true;#endif  wavFile_ = true;  return true; error:#if !defined(SYMBIAN)  errorString_ << "FileRead: error reading WAV file (" << fileName << ").";#endif  return false;}bool FileRead :: getSndInfo( const char *fileName ){  // Determine the data type.  UINT32 format;  if ( fseek(fd_, 12, SEEK_SET) == -1 ) goto error;   // Locate format  if ( fread(&format, 4, 1, fd_) != 1 ) goto error;#ifdef __LITTLE_ENDIAN__    swap32((unsigned char *)&format);#endif  if (format == 2) dataType_ = STK_SINT8;  else if (format == 3) dataType_ = STK_SINT16;  else if (format == 4) dataType_ = STK_SINT24;  else if (format == 5) dataType_ = STK_SINT32;  else if (format == 6) dataType_ = STK_FLOAT32;  else if (format == 7) dataType_ = STK_FLOAT64;  else {#if !defined(SYMBIAN)    errorString_ << "FileRead: data format in file " << fileName << " is not supported.";#endif    return false;  }  // Get file sample rate from the header.  UINT32 srate;  if ( fread(&srate, 4, 1, fd_) != 1 ) goto error;#ifdef __LITTLE_ENDIAN__  swap32((unsigned char *)&srate);#endif  fileRate_ = (StkFloat) srate;  // Get number of channels from the header.  UINT32 chans;  if ( fread(&chans, 4, 1, fd_) != 1 ) goto error;#ifdef __LITTLE_ENDIAN__  swap32((unsigned char *)&chans);#endif  channels_ = chans;  if ( fseek(fd_, 4, SEEK_SET) == -1 ) goto error;  if ( fread(&dataOffset_, 4, 1, fd_) != 1 ) goto error;#ifdef __LITTLE_ENDIAN__  swap32((unsigned char *)&dataOffset_);#endif  // Get length of data from the header.  if ( fread(&fileSize_, 4, 1, fd_) != 1 ) goto error;#ifdef __LITTLE_ENDIAN__  swap32((unsigned char *)&fileSize_);#endif  // Convert to sample frames.  if ( dataType_ == STK_SINT8 )    fileSize_ /= channels_;  if ( dataType_ == STK_SINT16 )    fileSize_ /= 2 * channels_;  else if ( dataType_ == STK_SINT24 )    fileSize_ /= 3 * channels_;  else if ( dataType_ == STK_SINT32 || dataType_ == STK_FLOAT32 )    fileSize_ /= 4 * channels_;  else if ( dataType_ == STK_FLOAT64 )    fileSize_ /= 8 * channels_;  byteswap_ = false;#ifdef __LITTLE_ENDIAN__  byteswap_ = true;#endif  return true; error:#if !defined(SYMBIAN)  errorString_ << "FileRead: Error reading SND file (" << fileName << ").";#endif  return false;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -