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

📄 filewrite.cpp

📁 Mobile STK for Symbian OS V0.1
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/***************************************************//*! \class FileWrite    \brief STK audio file output class.    This class provides output support for various    audio file formats.    FileWrite writes samples to an audio file.  It supports    multi-channel data.    FileWrite 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.  STK RAW files use 16-bit integers by    definition.  MAT-files will always be written as 64-bit floats.    If a data type specification does not match the specified file    type, the data type will automatically be modified.  Compressed    data types are not supported.    by Perry R. Cook and Gary P. Scavone, 1995 - 2005.*//***************************************************/#include "FileWrite.h"#if !defined(SYMBIAN)#include <cmath>#else#include "symbmath.h"#endifconst FileWrite::FILE_TYPE FileWrite :: FILE_RAW = 1;const FileWrite::FILE_TYPE FileWrite :: FILE_WAV = 2;const FileWrite::FILE_TYPE FileWrite :: FILE_SND = 3;const FileWrite::FILE_TYPE FileWrite :: FILE_AIF = 4;const FileWrite::FILE_TYPE FileWrite :: FILE_MAT = 5;// WAV header structure. See ftp://ftp.isi.edu/in-notes/rfc2361.txt// for information regarding format codes.struct wavhdr {  char riff[4];           // "RIFF"  SINT32 file_size;       // in bytes  char wave[4];           // "WAVE"  char fmt[4];            // "fmt "  SINT32 chunk_size;      // in bytes (16 for PCM)  SINT16 format_tag;      // 1=PCM, 2=ADPCM, 3=IEEE float, 6=A-Law, 7=Mu-Law  SINT16 num_chans;       // 1=mono, 2=stereo  SINT32 sample_rate;  SINT32 bytes_per_sec;  SINT16 bytes_per_samp;  // 2=16-bit mono, 4=16-bit stereo  SINT16 bits_per_samp;  char data[4];           // "data"  SINT32 data_length;     // in bytes};// SND (AU) header structure (NeXT and Sun).struct sndhdr {  char pref[4];  SINT32 hdr_length;  SINT32 data_length;  SINT32 format;  SINT32 sample_rate;  SINT32 num_channels;  char comment[16];};// AIFF/AIFC header structure ... only the part common to both// formats.struct aifhdr {  char form[4];                // "FORM"  SINT32 form_size;            // in bytes  char aiff[4];                // "AIFF" or "AIFC"  char comm[4];                // "COMM"  SINT32 comm_size;            // "COMM" chunk size (18 for AIFF, 24 for AIFC)  SINT16 num_chans;            // number of channels  unsigned long sample_frames; // sample frames of audio data  SINT16 sample_size;          // in bits  unsigned char srate[10];     // IEEE 754 floating point format};struct aifssnd {  char ssnd[4];               // "SSND"  SINT32 ssnd_size;           // "SSND" chunk size  unsigned long offset;       // data offset in data block (should be 0)  unsigned long block_size;   // not used by STK (should be 0)};// MAT-file 5 header structure.struct mathdr {  char heading[124];   // Header text field  SINT16 hff[2];       // Header flag fields  SINT32 adf[11];      // Array data format fields  // There's more, but it's of variable length};FileWrite :: FileWrite()  : fd_( 0 ){}#if !defined(SYMBIAN)FileWrite::FileWrite( std::string fileName, unsigned int nChannels, FILE_TYPE type, Stk::StkFormat format )#elseFileWrite::FileWrite( const char *fileName, unsigned int nChannels, FILE_TYPE type, Stk::StkFormat format )#endif  : fd_( 0 ){  this->open( fileName, nChannels, type, format );}FileWrite :: ~FileWrite(){  this->close();}void FileWrite :: close( void ){  if ( fd_ == 0 ) return;  if ( fileType_ == FILE_RAW )    fclose( fd_ );  else if ( fileType_ == FILE_WAV )    this->closeWavFile();  else if ( fileType_ == FILE_SND )    this->closeSndFile();  else if ( fileType_ == FILE_AIF )    this->closeAifFile();  else if ( fileType_ == FILE_MAT )    this->closeMatFile();  fd_ = 0;}bool FileWrite :: isOpen( void ){  if ( fd_ ) return true;  else return false;}#if !defined(SYMBIAN)void FileWrite :: open( std::string fileName, unsigned int nChannels, FileWrite::FILE_TYPE type, Stk::StkFormat format )#elsevoid FileWrite :: open( const char *fileName, unsigned int nChannels, FileWrite::FILE_TYPE type, Stk::StkFormat format )#endif{  // Call close() in case another file is already open.  this->close();  if ( nChannels < 1 ) {#if !defined(SYMBIAN)    errorString_ << "FileWrite::open: then channels argument must be greater than zero!";    handleError( StkError::FUNCTION_ARGUMENT );#endif  }  channels_ = nChannels;  fileType_ = type;  if ( format != STK_SINT8 && format != STK_SINT16 &&       format != STK_SINT32 && format != STK_FLOAT32 &&        format != STK_FLOAT64 ) {#if !defined(SYMBIAN)    errorString_ << "FileWrite::open: unknown data type (" << format << ") specified!";    handleError( StkError::FUNCTION_ARGUMENT );#endif  }   dataType_ = format;  bool result = false;  if ( fileType_ == FILE_RAW ) {    if ( channels_ != 1 ) {#if !defined(SYMBIAN)      errorString_ << "FileWrite::open: STK RAW files are, by definition, always monaural (channels = " << nChannels << " not supported)!";      handleError( StkError::FUNCTION_ARGUMENT );#endif    }#if !defined(SYMBIAN)    result = setRawFile( fileName.c_str() );#else    result = setRawFile( fileName );#endif  }  else if ( fileType_ == FILE_WAV )#if !defined(SYMBIAN)    result = setWavFile( fileName.c_str() );#else    result = setWavFile( fileName );#endif  else if ( fileType_ == FILE_SND )#if !defined(SYMBIAN)    result = setSndFile( fileName.c_str() );#else    result = setSndFile( fileName );#endif  else if ( fileType_ == FILE_AIF )#if !defined(SYMBIAN)    result = setAifFile( fileName.c_str() );#else    result = setAifFile( fileName );#endif  else if ( fileType_ == FILE_MAT )#if !defined(SYMBIAN)    result = setMatFile( fileName.c_str() );#else    result = setMatFile( fileName );#endif  else {#if !defined(SYMBIAN)    errorString_ << "FileWrite::open: unknown file type (" << fileType_ << ") specified!";    handleError( StkError::FUNCTION_ARGUMENT );#endif  }#if !defined(SYMBIAN)  if ( result == false )    handleError( StkError::FILE_ERROR );#endif  frameCounter_ = 0;}bool FileWrite :: setRawFile( const char *fileName ){  char name[8192];  strncpy(name, fileName, 8192);  if ( strstr(name, ".raw") == NULL) strcat(name, ".raw");  fd_ = fopen(name, "wb");  if ( !fd_ ) {#if !defined(SYMBIAN)    errorString_ << "FileWrite: could not create RAW file: " << name << '.';#endif    return false;  }  if ( dataType_ != STK_SINT16 ) {    dataType_ = STK_SINT16;#if !defined(SYMBIAN)    errorString_ << "FileWrite: using 16-bit signed integer data format for file " << name << '.';    handleError( StkError::DEBUG_WARNING );#endif  }  byteswap_ = false;#ifdef __LITTLE_ENDIAN__  byteswap_ = true;#endif#if !defined(SYMBIAN)  errorString_ << "FileWrite: creating RAW file: " << name;  handleError( StkError::STATUS );#endif  return true;}bool FileWrite :: setWavFile( const char *fileName ){  char name[8192];  strncpy(name, fileName, 8192);  if ( strstr(name, ".wav") == NULL) strcat(name, ".wav");  fd_ = fopen(name, "wb");  if ( !fd_ ) {#if !defined(SYMBIAN)    errorString_ << "FileWrite: could not create WAV file: " << name;#endif    return false;  }  struct wavhdr hdr = {"RIF", 44, "WAV", "fmt", 16, 1, 1,                        (SINT32) Stk::sampleRate(), 0, 2, 16, "dat", 0};  hdr.riff[3] = 'F';  hdr.wave[3] = 'E';  hdr.fmt[3]  = ' ';  hdr.data[3] = 'a';  hdr.num_chans = (SINT16) channels_;  if ( dataType_ == STK_SINT8 )    hdr.bits_per_samp = 8;  else if ( dataType_ == STK_SINT16 )    hdr.bits_per_samp = 16;  else if ( dataType_ == STK_SINT32 )    hdr.bits_per_samp = 32;  else if ( dataType_ == STK_FLOAT32 ) {    hdr.format_tag = 3;    hdr.bits_per_samp = 32;  }  else if ( dataType_ == STK_FLOAT64 ) {    hdr.format_tag = 3;    hdr.bits_per_samp = 64;  }  hdr.bytes_per_samp = (SINT16) (channels_ * hdr.bits_per_samp / 8);  hdr.bytes_per_sec = (SINT32) (hdr.sample_rate * hdr.bytes_per_samp);  byteswap_ = false;#ifndef __LITTLE_ENDIAN__  byteswap_ = true;  swap32((unsigned char *)&hdr.file_size);  swap32((unsigned char *)&hdr.chunk_size);  swap16((unsigned char *)&hdr.format_tag);  swap16((unsigned char *)&hdr.num_chans);  swap32((unsigned char *)&hdr.sample_rate);  swap32((unsigned char *)&hdr.bytes_per_sec);  swap16((unsigned char *)&hdr.bytes_per_samp);  swap16((unsigned char *)&hdr.bits_per_samp);#endif  if ( fwrite(&hdr, 4, 11, fd_) != 11 ) {#if !defined(SYMBIAN)    errorString_ << "FileWrite: could not write WAV header for file " << name << '.';#endif    return false;  }#if !defined(SYMBIAN)  errorString_ << "FileWrite: creating WAV file: " << name;  handleError( StkError::STATUS );#endif  return true;}void FileWrite :: closeWavFile( void ){  int bytes_per_sample = 1;  if ( dataType_ == STK_SINT16 )    bytes_per_sample = 2;  else if ( dataType_ == STK_SINT32 || dataType_ == STK_FLOAT32 )    bytes_per_sample = 4;  else if ( dataType_ == STK_FLOAT64 )    bytes_per_sample = 8;  SINT32 bytes = frameCounter_ * channels_ * bytes_per_sample;#ifndef __LITTLE_ENDIAN__  swap32((unsigned char *)&bytes);#endif  fseek(fd_, 40, SEEK_SET); // jump to data length  fwrite(&bytes, 4, 1, fd_);  bytes = frameCounter_ * channels_ * bytes_per_sample + 44;#ifndef __LITTLE_ENDIAN__  swap32((unsigned char *)&bytes);#endif  fseek(fd_, 4, SEEK_SET); // jump to file size  fwrite(&bytes, 4, 1, fd_);  fclose( fd_ );}bool FileWrite :: setSndFile( const char *fileName ){  char name[8192];  strncpy(name, fileName, 8192);  if ( strstr(name, ".snd") == NULL) strcat(name, ".snd");  fd_ = fopen(name, "wb");  if ( !fd_ ) {#if !defined(SYMBIAN)    errorString_ << "FileWrite: could not create SND file: " << name;#endif    return false;  }  struct sndhdr hdr = {".sn", 40, 0, 3, (SINT32) Stk::sampleRate(), 1, "Created by STK"};  hdr.pref[3] = 'd';  hdr.num_channels = channels_;  if ( dataType_ == STK_SINT8 )    hdr.format = 2;  else if ( dataType_ == STK_SINT16 )    hdr.format = 3;  else if ( dataType_ == STK_SINT32 )    hdr.format = 5;  else if ( dataType_ == STK_FLOAT32 )    hdr.format = 6;  else if ( dataType_ == STK_FLOAT64 )    hdr.format = 7;  byteswap_ = false;#ifdef __LITTLE_ENDIAN__  byteswap_ = true;  swap32 ((unsigned char *)&hdr.hdr_length);  swap32 ((unsigned char *)&hdr.format);  swap32 ((unsigned char *)&hdr.sample_rate);  swap32 ((unsigned char *)&hdr.num_channels);#endif  if ( fwrite(&hdr, 4, 10, fd_) != 10 ) {#if !defined(SYMBIAN)    errorString_ << "FileWrite: Could not write SND header for file " << name << '.';#endif    return false;  }#if !defined(SYMBIAN)  errorString_ << "FileWrite: creating SND file: " << name;  handleError( StkError::STATUS );#endif  return true;}

⌨️ 快捷键说明

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