Example #1
0
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();
  }
}
Example #2
0
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];
}
Example #3
0
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;
      }
    }
  }
}
Example #4
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_);

}
Example #5
0
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] );
  }
}
Example #6
0
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++] );
  }
}
Example #7
0
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;
      }
    }
  }
}
Example #8
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();
    }
  }
}
Example #10
0
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;
    }

}
Example #11
0
// 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;
}
Example #12
0
File: play.cpp Project: johnty/stk
// 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;
}
Example #13
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;
}
Example #14
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);
}
Example #15
0
File: play.cpp Project: johnty/stk
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( &parameters, 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;
}
Example #16
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;
    }
  }
Example #17
0
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);
}
Example #18
0
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);
}