📄 filewrite.cpp
字号:
void FileWrite :: closeSndFile( void ){ int bytes_per_sample = 1; if ( dataType_ == STK_SINT16 ) bytes_per_sample = 2; else if ( dataType_ == STK_SINT32 ) bytes_per_sample = 4; else if ( dataType_ == STK_FLOAT32 ) bytes_per_sample = 4; else if ( dataType_ == STK_FLOAT64 ) bytes_per_sample = 8; SINT32 bytes = frameCounter_ * bytes_per_sample * channels_;#ifdef __LITTLE_ENDIAN__ swap32 ((unsigned char *)&bytes);#endif fseek(fd_, 8, SEEK_SET); // jump to data size fwrite(&bytes, 4, 1, fd_); fclose(fd_);}bool FileWrite :: setAifFile( const char *fileName ){ char name[8192]; strncpy(name, fileName, 8192); if ( strstr(name, ".aif") == NULL) strcat(name, ".aif"); fd_ = fopen(name, "wb"); if ( !fd_ ) {#if !defined(SYMBIAN) errorString_ << "FileWrite: could not create AIF file: " << name;#endif return false; } // Common parts of AIFF/AIFC header. struct aifhdr hdr = {"FOR", 46, "AIF", "COM", 18, 0, 0, 16, "0"}; struct aifssnd ssnd = {"SSN", 8, 0, 0}; hdr.form[3] = 'M'; hdr.aiff[3] = 'F'; hdr.comm[3] = 'M'; ssnd.ssnd[3] = 'D'; hdr.num_chans = channels_; if ( dataType_ == STK_SINT8 ) hdr.sample_size = 8; else if ( dataType_ == STK_SINT16 ) hdr.sample_size = 16; else if ( dataType_ == STK_SINT32 ) hdr.sample_size = 32; else if ( dataType_ == STK_FLOAT32 ) { hdr.aiff[3] = 'C'; hdr.sample_size = 32; hdr.comm_size = 24; } else if ( dataType_ == STK_FLOAT64 ) { hdr.aiff[3] = 'C'; hdr.sample_size = 64; hdr.comm_size = 24; } // For AIFF files, the sample rate is stored in a 10-byte, // IEEE Standard 754 floating point number, so we need to // convert to that. SINT16 i; unsigned long exp; unsigned long rate = (unsigned long) Stk::sampleRate(); memset(hdr.srate, 0, 10); exp = rate; for (i=0; i<32; i++) { exp >>= 1; if (!exp) break; } i += 16383;#ifdef __LITTLE_ENDIAN__ swap16((unsigned char *)&i);#endif *(SINT16 *)(hdr.srate) = (SINT16) i; for (i=32; i; i--) { if (rate & 0x80000000) break; rate <<= 1; }#ifdef __LITTLE_ENDIAN__ swap32((unsigned char *)&rate);#endif *(unsigned long *)(hdr.srate+2) = (unsigned long) rate; byteswap_ = false; #ifdef __LITTLE_ENDIAN__ byteswap_ = true; swap32((unsigned char *)&hdr.form_size); swap32((unsigned char *)&hdr.comm_size); swap16((unsigned char *)&hdr.num_chans); swap16((unsigned char *)&hdr.sample_size); swap32((unsigned char *)&ssnd.ssnd_size); swap32((unsigned char *)&ssnd.offset); swap32((unsigned char *)&ssnd.block_size);#endif // The structure boundaries don't allow a single write of 54 bytes. if ( fwrite(&hdr, 4, 5, fd_) != 5 ) goto error; if ( fwrite(&hdr.num_chans, 2, 1, fd_) != 1 ) goto error; if ( fwrite(&hdr.sample_frames, 4, 1, fd_) != 1 ) goto error; if ( fwrite(&hdr.sample_size, 2, 1, fd_) != 1 ) goto error; if ( fwrite(&hdr.srate, 10, 1, fd_) != 1 ) goto error; if ( dataType_ == STK_FLOAT32 ) { char type[4] = {'f','l','3','2'}; char zeroes[2] = { 0, 0 }; if ( fwrite(&type, 4, 1, fd_) != 1 ) goto error; if ( fwrite(&zeroes, 2, 1, fd_) != 1 ) goto error; } else if ( dataType_ == STK_FLOAT64 ) { char type[4] = {'f','l','6','4'}; char zeroes[2] = { 0, 0 }; if ( fwrite(&type, 4, 1, fd_) != 1 ) goto error; if ( fwrite(&zeroes, 2, 1, fd_) != 1 ) goto error; } if ( fwrite(&ssnd, 4, 4, fd_) != 4 ) goto error;#if !defined(SYMBIAN) errorString_ << "FileWrite: creating AIF file: " << name; handleError( StkError::STATUS );#endif return true; error:#if !defined(SYMBIAN) errorString_ << "FileWrite: could not write AIF header for file: " << name;#endif return false;}void FileWrite :: closeAifFile( void ){ unsigned long frames = (unsigned long) frameCounter_;#ifdef __LITTLE_ENDIAN__ swap32((unsigned char *)&frames);#endif fseek(fd_, 22, SEEK_SET); // jump to "COMM" sample_frames fwrite(&frames, 4, 1, fd_); 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; unsigned long bytes = frameCounter_ * bytes_per_sample * channels_ + 46; if ( dataType_ == STK_FLOAT32 || dataType_ == STK_FLOAT64 ) bytes += 6;#ifdef __LITTLE_ENDIAN__ swap32((unsigned char *)&bytes);#endif fseek(fd_, 4, SEEK_SET); // jump to file size fwrite(&bytes, 4, 1, fd_); bytes = frameCounter_ * bytes_per_sample * channels_ + 8; if ( dataType_ == STK_FLOAT32 || dataType_ == STK_FLOAT64 ) bytes += 6;#ifdef __LITTLE_ENDIAN__ swap32((unsigned char *)&bytes);#endif if ( dataType_ == STK_FLOAT32 || dataType_ == STK_FLOAT64 ) fseek(fd_, 48, SEEK_SET); // jump to "SSND" chunk size else fseek(fd_, 42, SEEK_SET); // jump to "SSND" chunk size fwrite(&bytes, 4, 1, fd_); fclose( fd_ );}bool FileWrite :: setMatFile( const char *fileName ){ char name[8192]; strncpy(name, fileName, 8192); if ( strstr(name, ".mat") == NULL) strcat(name, ".mat"); fd_ = fopen(name, "w+b"); if ( !fd_ ) {#if !defined(SYMBIAN) errorString_ << "FileWrite: could not create MAT file: " << name;#endif return false; } if ( dataType_ != STK_FLOAT64 ) { dataType_ = STK_FLOAT64;#if !defined(SYMBIAN) errorString_ << "FileWrite: using 64-bit floating-point data format for file " << name << '.'; handleError( StkError::DEBUG_WARNING );#endif } struct mathdr hdr; strcpy(hdr.heading,"MATLAB 5.0 MAT-file, Generated using the Synthesis ToolKit in C++ (STK). By Perry R. Cook and Gary P. Scavone."); int i; for (i=strlen(hdr.heading);i<124;i++) hdr.heading[i] = ' '; // Header Flag Fields hdr.hff[0] = (SINT16) 0x0100; // Version field hdr.hff[1] = (SINT16) 'M'; // Endian indicator field ("MI") hdr.hff[1] <<= 8; hdr.hff[1] += 'I'; hdr.adf[0] = (SINT32) 14; // Matlab array data type value hdr.adf[1] = (SINT32) 0; // Size of file after this point to end (in bytes) // Don't know size yet. // Numeric Array Subelements (4): // 1. Array Flags hdr.adf[2] = (SINT32) 6; // Matlab 32-bit unsigned integer data type value hdr.adf[3] = (SINT32) 8; // 8 bytes of data to follow hdr.adf[4] = (SINT32) 6; // Double-precision array, no array flags set hdr.adf[5] = (SINT32) 0; // 4 bytes undefined // 2. Array Dimensions hdr.adf[6] = (SINT32) 5; // Matlab 32-bit signed integer data type value hdr.adf[7] = (SINT32) 8; // 8 bytes of data to follow (2D array) hdr.adf[8] = (SINT32) channels_; // This is the number of rows hdr.adf[9] = (SINT32) 0; // This is the number of columns // 3. Array Name // We'll use fileName for the matlab array name (as well as the file name). // If fileName is 4 characters or less, we have to use a compressed data element // format for the array name data element. Otherwise, the array name must // be formatted in 8-byte increments (up to 31 characters + NULL). SINT32 namelength = (SINT32) strlen(fileName); if (strstr(fileName, ".mat")) namelength -= 4; if (namelength > 31) namelength = 31; // Truncate name to 31 characters. char arrayName[64]; strncpy(arrayName, fileName, namelength); arrayName[namelength] = '\0'; if (namelength > 4) { hdr.adf[10] = (SINT32) 1; // Matlab 8-bit signed integer data type value } else { // Compressed data element format hdr.adf[10] = namelength; hdr.adf[10] <<= 16; hdr.adf[10] += 1; } SINT32 headsize = 40; // Number of bytes in data element so far. // Write the fixed portion of the header if ( fwrite(&hdr, 172, 1, fd_) != 1 ) goto error; // Write MATLAB array name SINT32 tmp; if (namelength > 4) { if ( fwrite(&namelength, 4, 1, fd_) != 1) goto error; if ( fwrite(arrayName, namelength, 1, fd_) != 1 ) goto error; tmp = (SINT32) ceil((float)namelength / 8); if ( fseek(fd_, tmp*8-namelength, SEEK_CUR) == -1 ) goto error; headsize += tmp * 8; } else { // Compressed data element format if ( fwrite(arrayName, namelength, 1, fd_) != 1 ) goto error; tmp = 4 - namelength; if ( fseek(fd_, tmp, SEEK_CUR) == -1 ) goto error; } // Finish writing known header information tmp = 9; // Matlab IEEE 754 double data type if ( fwrite(&tmp, 4, 1, fd_) != 1 ) goto error; tmp = 0; // Size of real part subelement in bytes (8 per sample) if ( fwrite(&tmp, 4, 1, fd_) != 1 ) goto error; headsize += 8; // Total number of bytes in data element so far if ( fseek(fd_, 132, SEEK_SET) == -1 ) goto error; if ( fwrite(&headsize, 4, 1, fd_) != 1 ) goto error; // Write header size ... will update at end if ( fseek(fd_, 0, SEEK_END) == -1 ) goto error; byteswap_ = false;#if !defined(SYMBIAN) errorString_ << "FileWrite: creating MAT-file (" << name << ") containing MATLAB array: " << arrayName; handleError( StkError::STATUS );#endif return true; error:#if !defined(SYMBIAN) errorString_ << "FileWrite: could not write MAT-file header for file " << name << '.';#endif return false;}void FileWrite :: closeMatFile( void ){ fseek(fd_, 164, SEEK_SET); // jump to number of columns fwrite(&frameCounter_, 4, 1, fd_); SINT32 headsize, temp; fseek(fd_, 132, SEEK_SET); // jump to header size fread(&headsize, 4, 1, fd_); temp = headsize; headsize += (SINT32) (frameCounter_ * 8 * channels_); fseek(fd_, 132, SEEK_SET); // Write file size (minus some header info) fwrite(&headsize, 4, 1, fd_); fseek(fd_, temp+132, SEEK_SET); // jumpt to data size (in bytes) temp = frameCounter_ * 8 * channels_; fwrite(&temp, 4, 1, fd_); fclose(fd_);}void FileWrite :: write( StkFrames& buffer ){ if ( fd_ == 0 ) {#if !defined(SYMBIAN) errorString_ << "FileWrite::write(): a file has not yet been opened!"; handleError( StkError::WARNING );#endif return; } if ( buffer.channels() != channels_ ) {#if !defined(SYMBIAN) errorString_ << "FileWrite::write(): number of channels in the StkFrames argument does not match that specified to open() function!"; handleError( StkError::FUNCTION_ARGUMENT );#endif return; } unsigned long nSamples = buffer.size(); if ( dataType_ == STK_SINT16 ) { SINT16 sample; for ( unsigned long k=0; k<nSamples; k++ ) { sample = (SINT16) (buffer[k] * 32767.0); //sample = ((SINT16) (( buffer[k] + 1.0 ) * 32767.5 + 0.5)) - 32768; if ( byteswap_ ) swap16( (unsigned char *)&sample ); if ( fwrite(&sample, 2, 1, fd_) != 1 ) goto error; } } else if ( dataType_ == STK_SINT8 ) { if ( fileType_ == FILE_WAV ) { // 8-bit WAV data is unsigned! unsigned char sample; for ( unsigned long k=0; k<nSamples; k++ ) { sample = (unsigned char) (buffer[k] * 127.0 + 128.0); if ( fwrite(&sample, 1, 1, fd_) != 1 ) goto error; } } else { signed char sample; for ( unsigned long k=0; k<nSamples; k++ ) { sample = (signed char) (buffer[k] * 127.0); //sample = ((signed char) (( buffer[k] + 1.0 ) * 127.5 + 0.5)) - 128; if ( fwrite(&sample, 1, 1, fd_) != 1 ) goto error; } } } else if ( dataType_ == STK_SINT32 ) { SINT32 sample; for ( unsigned long k=0; k<nSamples; k++ ) { sample = (SINT32) (buffer[k] * 2147483647.0); //sample = ((SINT32) (( buffer[k] + 1.0 ) * 2147483647.5 + 0.5)) - 2147483648; if ( byteswap_ ) swap32( (unsigned char *)&sample ); if ( fwrite(&sample, 4, 1, fd_) != 1 ) goto error; } } else if ( dataType_ == STK_FLOAT32 ) { FLOAT32 sample; for ( unsigned long k=0; k<nSamples; k++ ) { sample = (FLOAT32) (buffer[k]); if ( byteswap_ ) swap32( (unsigned char *)&sample ); if ( fwrite(&sample, 4, 1, fd_) != 1 ) goto error; } } else if ( dataType_ == STK_FLOAT64 ) { FLOAT64 sample; for ( unsigned long k=0; k<nSamples; k++ ) { sample = (FLOAT64) (buffer[k]); if ( byteswap_ ) swap64( (unsigned char *)&sample ); if ( fwrite(&sample, 8, 1, fd_) != 1 ) goto error; } } frameCounter_ += buffer.frames(); return; error:#if !defined(SYMBIAN) errorString_ << "FileWrite::write(): error writing data to file!"; handleError( StkError::FILE_ERROR );#else {}#endif}//#endif // SYMBIAN
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -