void FileWvOut :: tick( const StkFrames& frames ) { #if defined(_STK_DEBUG_) if ( !file_.isOpen() ) { oStream_ << "FileWvOut::tick(): no file open!"; handleError( StkError::WARNING ); return; } if ( data_.channels() != frames.channels() ) { oStream_ << "FileWvOut::tick(): incompatible channel value in StkFrames argument!"; handleError( StkError::FUNCTION_ARGUMENT ); } #endif unsigned int iFrames = 0; unsigned int j, nChannels = data_.channels(); for ( unsigned int i=0; i<frames.frames(); i++ ) { for ( j=0; j<nChannels; j++ ) { data_[iData_] = frames[iFrames++]; clipTest( data_[iData_++] ); } this->incrementFrame(); } }
StkFrames :: StkFrames( const StkFrames& f ) : data_(0), size_(0), bufferSize_(0) { resize( f.frames(), f.channels() ); dataRate_ = Stk::sampleRate(); for ( unsigned int i=0; i<size_; i++ ) data_[i] = f[i]; }
void RtWvOut :: tickFrame( const StkFrames& frames ) { if ( channels_ != frames.channels() ) { errorString_ << "RtWvOut::tickFrame(): incompatible channel value in StkFrames argument!"; handleError( StkError::FUNCTION_ARGUMENT ); } if ( stopped_ ) start(); unsigned int j; StkFloat sample; if ( channels_ == 1 || frames.interleaved() ) { unsigned long iFrames = 0, iData = counter_; for ( unsigned int i=0; i<frames.frames(); i++ ) { for ( j=0; j<channels_; j++ ) { sample = frames[iFrames++]; this->clipTest( sample ); dataPtr_[iData++] = sample; } counter_++; totalCount_++; if ( counter_ >= (unsigned int)bufferSize_ ) { try { audio_->tickStream(); } catch (RtError &error) { handleError( error.getMessageString(), StkError::AUDIO_SYSTEM ); } counter_ = 0; } } } else { unsigned int hop = frames.frames(); unsigned long iData = counter_; for ( unsigned int i=0; i<frames.frames(); i++ ) { for ( j=0; j<channels_; j++ ) { sample = frames[i + j*hop]; this->clipTest( sample ); dataPtr_[iData++] = sample; } counter_++; totalCount_++; if ( counter_ >= (unsigned int)bufferSize_ ) { try { audio_->tickStream(); } catch (RtError &error) { handleError( error.getMessageString(), StkError::AUDIO_SYSTEM ); } counter_ = 0; } } } }
StkFrames :: StkFrames( const StkFrames& f ) : size_(0), bufferSize_(0) { resize( f.frames(), f.channels() ); dataRate_ = Stk::sampleRate(); for ( unsigned int i=0; i<size_; i++ ) data_[i] = f[i]; printf("StkFrames created with size %d\n", size_); }
void RtWvOut :: tick( const StkFrames& frames, unsigned int channel ) { if ( channel == 0 || frames.channels() < channel ) { errorString_ << "RtWvOut::tick(): channel argument (" << channel << ") is zero or > channels in StkFrames argument!"; handleError( StkError::FUNCTION_ARGUMENT ); } if ( stopped_ ) start(); if ( frames.channels() == 1 ) { for ( unsigned int i=0; i<frames.frames(); i++ ) tick( frames[i] ); } else if ( frames.interleaved() ) { unsigned int hop = frames.channels(); unsigned int index = channel - 1; for ( unsigned int i=0; i<frames.frames(); i++ ) { tick( frames[index] ); index += hop; } } else { unsigned int iStart = (channel - 1) * frames.frames(); for ( unsigned int i=0; i<frames.frames(); i++ ) tick( frames[iStart + i] ); } }
void WvOut :: tick( const StkFrames& frames, unsigned int channel ) { if ( channel >= frames.channels() ) { errorString_ << "WvOut::tick(): channel argument (" << channel << ") is incompatible with StkFrames argument!"; handleError( StkError::FUNCTION_ARGUMENT ); } if ( frames.channels() == 1 ) { for ( unsigned int i=0; i<frames.frames(); i++ ) computeSample( frames[i] ); } else if ( frames.interleaved() ) { unsigned int hop = frames.channels(); unsigned int index = channel; for ( unsigned int i=0; i<frames.frames(); i++ ) { computeSample( frames[index] ); index += hop; } } else { unsigned int iStart = channel * frames.frames(); for ( unsigned int i=0; i<frames.frames(); i++ ) computeSample( frames[iStart++] ); } }
void WvOut :: tickFrame( const StkFrames& frames ) { if ( !fd_ ) { errorString_ << "WvOut::tickFrame(): no file open!"; handleError( StkError::WARNING ); return; } if ( channels_ != frames.channels() ) { errorString_ << "WvOut::tickFrame(): incompatible channel value in StkFrames argument!"; handleError( StkError::FUNCTION_ARGUMENT ); } unsigned int j; if ( channels_ == 1 || frames.interleaved() ) { unsigned long iFrames = 0, iData = counter_; for ( unsigned int i=0; i<frames.frames(); i++ ) { for ( j=0; j<channels_; j++ ) { data_[iData++] = frames[iFrames++]; } counter_++; totalCount_++; if ( counter_ == BUFFER_SIZE ) { this->writeData( BUFFER_SIZE ); counter_ = 0; } } } else { unsigned int hop = frames.frames(); unsigned long iData = counter_; for ( unsigned int i=0; i<frames.frames(); i++ ) { for ( j=0; j<channels_; j++ ) { data_[iData++] = frames[i + j*hop]; } counter_++; totalCount_++; if ( counter_ == BUFFER_SIZE ) { this->writeData( BUFFER_SIZE ); counter_ = 0; } } } }
void RtWvOut :: tick( const StkFrames& frames ) { #if defined(_STK_DEBUG_) if ( data_.channels() != frames.channels() ) { oStream_ << "RtWvOut::tick(): incompatible channel value in StkFrames argument!"; handleError( StkError::FUNCTION_ARGUMENT ); } #endif if ( stopped_ ) this->start(); // See how much space we have and fill as much as we can ... if we // still have samples left in the frames object, then wait and // repeat. unsigned int framesEmpty, nFrames, bytes, framesWritten = 0; unsigned int nChannels = data_.channels(); while ( framesWritten < frames.frames() ) { // Block until we have some room for output data. while ( framesFilled_ == (long) data_.frames() ) Stk::sleep( 1 ); framesEmpty = data_.frames() - framesFilled_; // Copy data in one chunk up to the end of the data buffer. nFrames = framesEmpty; if ( writeIndex_ + nFrames > data_.frames() ) nFrames = data_.frames() - writeIndex_; if ( nFrames > frames.frames() - framesWritten ) nFrames = frames.frames() - framesWritten; bytes = nFrames * nChannels * sizeof( StkFloat ); StkFloat *samples = &data_[writeIndex_ * nChannels]; StkFrames *ins = (StkFrames *) &frames; memcpy( samples, &(*ins)[framesWritten * nChannels], bytes ); for ( unsigned int i=0; i<nFrames * nChannels; i++ ) clipTest( *samples++ ); writeIndex_ += nFrames; if ( writeIndex_ == data_.frames() ) writeIndex_ = 0; framesWritten += nFrames; mutex_.lock(); framesFilled_ += nFrames; mutex_.unlock(); frameCounter_ += nFrames; } }
void FileWvOut :: computeFrames( const StkFrames& frames ) { if ( !file_.isOpen() ) { errorString_ << "FileWvOut::computeFrames(): no file open!"; handleError( StkError::WARNING ); return; } if ( data_.channels() != frames.channels() ) { errorString_ << "FileWvOut::computeFrames(): incompatible channel value in StkFrames argument!"; handleError( StkError::FUNCTION_ARGUMENT ); } unsigned int j, nChannels = data_.channels(); if ( nChannels == 1 || frames.interleaved() ) { unsigned int iFrames = 0; for ( unsigned int i=0; i<frames.frames(); i++ ) { for ( j=0; j<nChannels; j++ ) { data_[iData_] = frames[iFrames++]; clipTest( data_[iData_++] ); } this->incrementFrame(); } } else { // non-interleaved frames unsigned long hop = frames.frames(); unsigned int index; for ( unsigned int i=0; i<frames.frames(); i++ ) { index = i; for ( j=0; j<nChannels; j++ ) { data_[iData_] = frames[index]; clipTest( data_[iData_++] ); index += hop; } this->incrementFrame(); } } }
void normalize( StkFrames& buffer ) { // this code is from the STK FileWvIn class size_t i; StkFloat max = 0.0; for ( i=0; i<buffer.size(); i++ ) { if ( fabs( buffer[i] ) > max ) max = (StkFloat) fabs((double) buffer[i]); } std::cout << "normalize(): max amplitude found is " << max << std::endl; if (max > 0.0) { max = 1.0 / max; for ( i=0; i<buffer.size(); i++ ) buffer[i] *= max; } }
// callback funtion used by the audio engine inline int audioCallback( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames, double streamTime, RtAudioStreamStatus status, void *dataPointer ) { Marionette *marionette = (Marionette *) dataPointer; // not sure why this pointer needs to be essentially renamed register StkFloat *samples = (StkFloat *) outputBuffer; // run Marionette - calculate all the dependencies and what not marionette->execute(); for ( unsigned int i=0; i<frames.size(); i++ ) *samples++ = frames[i]; return 0; }
// This tick() function handles sample computation only. It will be // called automatically when the system needs a new buffer of audio // samples. int tick( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames, double streamTime, RtAudioStreamStatus status, void *userData ) { FileWvIn *input = (FileWvIn *) userData; register StkFloat *samples = (StkFloat *) outputBuffer; input->tick( frames ); for ( unsigned int i=0; i<frames.size(); i++ ) *samples++ = frames[i]; //if ( input->isFinished() ) { if ( false ) { done = true; return 1; } else return 0; }
// This tick() function handles sample computation only. It will be // called automatically when the system needs a new buffer of audio // samples. int tick( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames, double streamTime, RtAudioStreamStatus status, void *userData ) { FileWvIn *input = (FileWvIn *) userData; StkFloat *samples = (StkFloat *) outputBuffer; input->tick( frames ); for ( unsigned int i=0; i<frames.size(); i++ ) { *samples++ = frames[i]; if ( input->channelsOut() == 1 ) *samples++ = frames[i]; // play mono files in stereo } if ( input->isFinished() ) { done = true; return 1; } else return 0; }
Marionette::Marionette(int outdevice, float samplerate) { //std::cout << "initializing Marionette C++ object" << std::endl; dac = new RtAudio; int output_device_id = outdevice; int num_out_channels = dac->getDeviceInfo(output_device_id).outputChannels; parameters.deviceId = output_device_id; parameters.nChannels = num_out_channels; printf("Device id: %d , channels %d\n", output_device_id, num_out_channels); // Resize the StkFrames object appropriately. frames.resize( RT_BUFFER_SIZE, num_out_channels ); // default sample rate Stk::setSampleRate( samplerate ); // create the global outs out = new Bus(num_out_channels); // create the global ins in = new Bus(0); }
int main(int argc, char *argv[]) { // Minimal command-line checking. if ( argc < 3 || argc > 4 ) usage(); // Set the global sample rate before creating class instances. Stk::setSampleRate( (StkFloat) atof( argv[2] ) ); // Initialize our WvIn and RtAudio pointers. RtAudio dac; FileWvIn input; FileLoop inputLoop; // Try to load the soundfile. try { input.openFile( argv[1] ); inputLoop.openFile( argv[1] ); } catch ( StkError & ) { exit( 1 ); } // Set input read rate based on the default STK sample rate. double rate = 1.0; rate = input.getFileRate() / Stk::sampleRate(); rate = inputLoop.getFileRate() / Stk::sampleRate(); if ( argc == 4 ) rate *= atof( argv[3] ); input.setRate( rate ); input.ignoreSampleRateChange(); // Find out how many channels we have. int channels = input.channelsOut(); // Figure out how many bytes in an StkFloat and setup the RtAudio stream. RtAudio::StreamParameters parameters; parameters.deviceId = dac.getDefaultOutputDevice(); parameters.nChannels = channels; RtAudioFormat format = ( sizeof(StkFloat) == 8 ) ? RTAUDIO_FLOAT64 : RTAUDIO_FLOAT32; unsigned int bufferFrames = RT_BUFFER_SIZE; try { dac.openStream( ¶meters, NULL, format, (unsigned int)Stk::sampleRate(), &bufferFrames, &tick, (void *)&inputLoop ); } catch ( RtAudioError &error ) { error.printMessage(); goto cleanup; } // Install an interrupt handler function. (void) signal(SIGINT, finish); // Resize the StkFrames object appropriately. frames.resize( bufferFrames, channels ); try { dac.startStream(); } catch ( RtAudioError &error ) { error.printMessage(); goto cleanup; } // Block waiting until callback signals done. while ( !done ) Stk::sleep( 100 ); // By returning a non-zero value in the callback above, the stream // is automatically stopped. But we should still close it. try { dac.closeStream(); } catch ( RtAudioError &error ) { error.printMessage(); } cleanup: return 0; }
void FileRead :: read( StkFrames& buffer, unsigned long startFrame, bool doNormalize ) { // Make sure we have an open file. if ( fd_ == 0 ) { errorString_ << "FileRead::read: a file is not open!"; Stk::handleError( StkError::WARNING ); return; } // Check the buffer size. unsigned int nFrames = buffer.frames(); if ( nFrames == 0 ) { errorString_ << "FileRead::read: StkFrames buffer size is zero ... no data read!"; Stk::handleError( StkError::WARNING ); return; } if ( buffer.channels() != channels_ ) { errorString_ << "FileRead::read: StkFrames argument has incompatible number of channels!"; Stk::handleError( StkError::FUNCTION_ARGUMENT ); } // Check for file end. if ( startFrame + nFrames >= fileSize_ ) nFrames = fileSize_ - startFrame; long i, nSamples = (long) ( nFrames * channels_ ); unsigned long offset = startFrame * channels_; // Read samples into StkFrames data buffer. if ( dataType_ == STK_SINT16 ) { SINT16 *buf = (SINT16 *) &buffer[0]; if ( fseek( fd_, dataOffset_+(offset*2), SEEK_SET ) == -1 ) goto error; if ( fread( buf, nSamples * 2, 1, fd_ ) != 1 ) goto error; if ( byteswap_ ) { SINT16 *ptr = buf; for ( i=nSamples-1; i>=0; i-- ) swap16( (unsigned char *) ptr++ ); } if ( doNormalize ) { StkFloat gain = 1.0 / 32768.0; for ( i=nSamples-1; i>=0; i-- ) buffer[i] = buf[i] * gain; } else { for ( i=nSamples-1; i>=0; i-- ) buffer[i] = buf[i]; } } else if ( dataType_ == STK_SINT32 ) { SINT32 *buf = (SINT32 *) &buffer[0]; if ( fseek( fd_, dataOffset_+(offset*4 ), SEEK_SET ) == -1 ) goto error; if ( fread( buf, nSamples * 4, 1, fd_ ) != 1 ) goto error; if ( byteswap_ ) { SINT32 *ptr = buf; for ( i=nSamples-1; i>=0; i-- ) swap32( (unsigned char *) ptr++ ); } if ( doNormalize ) { StkFloat gain = 1.0 / 2147483648.0; for ( i=nSamples-1; i>=0; i-- ) buffer[i] = buf[i] * gain; } else { for ( i=nSamples-1; i>=0; i-- ) buffer[i] = buf[i]; } } else if ( dataType_ == STK_FLOAT32 ) { FLOAT32 *buf = (FLOAT32 *) &buffer[0]; if ( fseek( fd_, dataOffset_+(offset*4), SEEK_SET ) == -1 ) goto error; if ( fread( buf, nSamples * 4, 1, fd_ ) != 1 ) goto error; if ( byteswap_ ) { FLOAT32 *ptr = buf; for ( i=nSamples-1; i>=0; i-- ) swap32( (unsigned char *) ptr++ ); } for ( i=nSamples-1; i>=0; i-- ) buffer[i] = buf[i]; } else if ( dataType_ == STK_FLOAT64 ) { FLOAT64 *buf = (FLOAT64 *) &buffer[0]; if ( fseek( fd_, dataOffset_+(offset*8), SEEK_SET ) == -1 ) goto error; if ( fread( buf, nSamples * 8, 1, fd_ ) != 1 ) goto error; if ( byteswap_ ) { FLOAT64 *ptr = buf; for ( i=nSamples-1; i>=0; i-- ) swap64( (unsigned char *) ptr++ ); } for ( i=nSamples-1; i>=0; i-- ) buffer[i] = buf[i]; } else if ( dataType_ == STK_SINT8 && wavFile_ ) { // 8-bit WAV data is unsigned! unsigned char *buf = (unsigned char *) &buffer[0]; if ( fseek( fd_, dataOffset_+offset, SEEK_SET ) == -1 ) goto error; if ( fread( buf, nSamples, 1, fd_) != 1 ) goto error; if ( doNormalize ) { StkFloat gain = 1.0 / 128.0; for ( i=nSamples-1; i>=0; i-- ) buffer[i] = ( buf[i] - 128 ) * gain; } else { for ( i=nSamples-1; i>=0; i-- ) buffer[i] = buf[i] - 128.0; } } else if ( dataType_ == STK_SINT8 ) { // signed 8-bit data char *buf = (char *) &buffer[0]; if ( fseek( fd_, dataOffset_+offset, SEEK_SET ) == -1 ) goto error; if ( fread( buf, nSamples, 1, fd_ ) != 1 ) goto error; if ( doNormalize ) { StkFloat gain = 1.0 / 128.0; for ( i=nSamples-1; i>=0; i-- ) buffer[i] = buf[i] * gain; } else { for ( i=nSamples-1; i>=0; i-- ) buffer[i] = buf[i]; } } else if ( dataType_ == STK_SINT24 ) { // 24-bit values are harder to import efficiently since there is // no native 24-bit type. The following routine works but is much // less efficient that that used for the other data types. SINT32 buf; StkFloat gain = 1.0 / 8388608.0; if ( fseek(fd_, dataOffset_+(offset*3), SEEK_SET ) == -1 ) goto error; for ( i=0; i<nSamples; i++ ) { if ( fread( &buf, 3, 1, fd_ ) != 1 ) goto error; buf >>= 8; if ( byteswap_ ) swap32( (unsigned char *) &buf ); if ( doNormalize ) buffer[i] = buf * gain; else buffer[i] = buf; } }
void FileRead :: read( StkFrames& buffer, unsigned long startFrame, bool doNormalize ) { // Make sure we have an open file. if ( fd_ == 0 ) { oStream_ << "FileRead::read: a file is not open!"; Stk::handleError( StkError::WARNING ); return; } // Check the buffer size. unsigned long nFrames = buffer.frames(); if ( nFrames == 0 ) { oStream_ << "FileRead::read: StkFrames buffer size is zero ... no data read!"; Stk::handleError( StkError::WARNING ); return; } if ( buffer.channels() != channels_ ) { oStream_ << "FileRead::read: StkFrames argument has incompatible number of channels!"; Stk::handleError( StkError::FUNCTION_ARGUMENT ); } if ( startFrame >= fileSize_ ) { oStream_ << "FileRead::read: startFrame argument is greater than or equal to the file size!"; Stk::handleError( StkError::FUNCTION_ARGUMENT ); } // Check for file end. if ( startFrame + nFrames > fileSize_ ) nFrames = fileSize_ - startFrame; long i, nSamples = (long) ( nFrames * channels_ ); unsigned long offset = startFrame * channels_; // Read samples into StkFrames data buffer. if ( dataType_ == STK_SINT16 ) { SINT16 *buf = (SINT16 *) &buffer[0]; if ( fseek( fd_, dataOffset_+(offset*2), SEEK_SET ) == -1 ) goto error; if ( fread( buf, nSamples * 2, 1, fd_ ) != 1 ) goto error; if ( byteswap_ ) { SINT16 *ptr = buf; for ( i=nSamples-1; i>=0; i-- ) swap16( (unsigned char *) ptr++ ); } if ( doNormalize ) { StkFloat gain = 1.0 / 32768.0; for ( i=nSamples-1; i>=0; i-- ) buffer[i] = buf[i] * gain; } else { for ( i=nSamples-1; i>=0; i-- ) buffer[i] = buf[i]; } } else if ( dataType_ == STK_SINT32 ) { SINT32 *buf = (SINT32 *) &buffer[0]; if ( fseek( fd_, dataOffset_+(offset*4 ), SEEK_SET ) == -1 ) goto error; if ( fread( buf, nSamples * 4, 1, fd_ ) != 1 ) goto error; if ( byteswap_ ) { SINT32 *ptr = buf; for ( i=nSamples-1; i>=0; i-- ) swap32( (unsigned char *) ptr++ ); } if ( doNormalize ) { StkFloat gain = 1.0 / 2147483648.0; for ( i=nSamples-1; i>=0; i-- ) buffer[i] = buf[i] * gain; } else { for ( i=nSamples-1; i>=0; i-- ) buffer[i] = buf[i]; } } else if ( dataType_ == STK_FLOAT32 ) { FLOAT32 *buf = (FLOAT32 *) &buffer[0]; if ( fseek( fd_, dataOffset_+(offset*4), SEEK_SET ) == -1 ) goto error; if ( fread( buf, nSamples * 4, 1, fd_ ) != 1 ) goto error; if ( byteswap_ ) { FLOAT32 *ptr = buf; for ( i=nSamples-1; i>=0; i-- ) swap32( (unsigned char *) ptr++ ); } for ( i=nSamples-1; i>=0; i-- ) buffer[i] = buf[i]; } else if ( dataType_ == STK_FLOAT64 ) { FLOAT64 *buf = (FLOAT64 *) &buffer[0]; if ( fseek( fd_, dataOffset_+(offset*8), SEEK_SET ) == -1 ) goto error; if ( fread( buf, nSamples * 8, 1, fd_ ) != 1 ) goto error; if ( byteswap_ ) { FLOAT64 *ptr = buf; for ( i=nSamples-1; i>=0; i-- ) swap64( (unsigned char *) ptr++ ); } for ( i=nSamples-1; i>=0; i-- ) buffer[i] = buf[i]; } else if ( dataType_ == STK_SINT8 && wavFile_ ) { // 8-bit WAV data is unsigned! unsigned char *buf = (unsigned char *) &buffer[0]; if ( fseek( fd_, dataOffset_+offset, SEEK_SET ) == -1 ) goto error; if ( fread( buf, nSamples, 1, fd_) != 1 ) goto error; if ( doNormalize ) { StkFloat gain = 1.0 / 128.0; for ( i=nSamples-1; i>=0; i-- ) buffer[i] = ( buf[i] - 128 ) * gain; } else { for ( i=nSamples-1; i>=0; i-- ) buffer[i] = buf[i] - 128.0; } } else if ( dataType_ == STK_SINT8 ) { // signed 8-bit data char *buf = (char *) &buffer[0]; if ( fseek( fd_, dataOffset_+offset, SEEK_SET ) == -1 ) goto error; if ( fread( buf, nSamples, 1, fd_ ) != 1 ) goto error; if ( doNormalize ) { StkFloat gain = 1.0 / 128.0; for ( i=nSamples-1; i>=0; i-- ) buffer[i] = buf[i] * gain; } else { for ( i=nSamples-1; i>=0; i-- ) buffer[i] = buf[i]; } } else if ( dataType_ == STK_SINT24 ) { // 24-bit values are harder to import efficiently since there is // no native 24-bit type. The following routine works but is much // less efficient than that used for the other data types. SINT32 temp; unsigned char *ptr = (unsigned char *) &temp; StkFloat gain = 1.0 / 2147483648.0; if ( fseek(fd_, dataOffset_+(offset*3), SEEK_SET ) == -1 ) goto error; for ( i=0; i<nSamples; i++ ) { #ifdef __LITTLE_ENDIAN__ if ( byteswap_ ) { if ( fread( ptr, 3, 1, fd_ ) != 1 ) goto error; temp &= 0x00ffffff; swap32( (unsigned char *) ptr ); } else { if ( fread( ptr+1, 3, 1, fd_ ) != 1 ) goto error; temp &= 0xffffff00; } #else if ( byteswap_ ) { if ( fread( ptr+1, 3, 1, fd_ ) != 1 ) goto error; temp &= 0xffffff00; swap32( (unsigned char *) ptr ); } else { if ( fread( ptr, 3, 1, fd_ ) != 1 ) goto error; temp &= 0x00ffffff; } #endif if ( doNormalize ) { buffer[i] = (StkFloat) temp * gain; // "gain" also includes 1 / 256 factor. } else buffer[i] = (StkFloat) temp / 256; // right shift without affecting the sign bit } } buffer.setDataRate( fileRate_ ); return; error: oStream_ << "FileRead: Error reading file data."; handleError( StkError::FILE_ERROR); }
void FileWrite ::write(StkFrames &buffer) { if (fd_ == 0) { oStream_ << "FileWrite::write(): a file has not yet been opened!"; handleError(StkError::WARNING); return; } if (buffer.channels() != channels_) { oStream_ << "FileWrite::write(): number of channels in the StkFrames " "argument does not match that specified to open() function!"; handleError(StkError::FUNCTION_ARGUMENT); 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; } } else if (dataType_ == STK_SINT24) { SINT32 sample; for (unsigned long k = 0; k < nSamples; k++) { sample = (SINT32)(buffer[k] * 8388607.0); if (byteswap_) { swap32((unsigned char *)&sample); unsigned char *ptr = (unsigned char *)&sample; if (fwrite(ptr + 1, 3, 1, fd_) != 1) goto error; } else if (fwrite(&sample, 3, 1, fd_) != 1) goto error; } } frameCounter_ += buffer.frames(); return; error: oStream_ << "FileWrite::write(): error writing data to file!"; handleError(StkError::FILE_ERROR); }