mirror of
https://github.com/thestk/stk
synced 2026-01-14 13:31:53 +00:00
Version 4.2.1
This commit is contained in:
committed by
Stephen Sinclair
parent
a6381b9d38
commit
2cbce2d8bd
116
src/RtWvIn.cpp
116
src/RtWvIn.cpp
@@ -2,68 +2,63 @@
|
||||
/*! \class RtWvIn
|
||||
\brief STK realtime audio (blocking) input class.
|
||||
|
||||
This class provides a simplified interface to
|
||||
RtAudio for realtime audio input. It is a
|
||||
protected subclass of WvIn.
|
||||
This class provides a simplified interface to RtAudio for realtime
|
||||
audio input. It is a protected subclass of WvIn. Because this
|
||||
class makes use of RtAudio's blocking output routines, its
|
||||
performance is less robust on systems where the audio API is
|
||||
callback-based (Macintosh CoreAudio and Windows ASIO).
|
||||
|
||||
RtWvIn supports multi-channel data in
|
||||
interleaved format. It is important to
|
||||
distinguish the tick() methods, which return
|
||||
samples produced by averaging across sample
|
||||
frames, from the tickFrame() methods, which
|
||||
return pointers to multi-channel sample frames.
|
||||
For single-channel data, these methods return
|
||||
equivalent values.
|
||||
RtWvIn supports multi-channel data in interleaved format. It is
|
||||
important to distinguish the tick() methods, which return samples
|
||||
produced by averaging across sample frames, from the tickFrame()
|
||||
methods, which return references or pointers to multi-channel
|
||||
sample frames.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2004.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2005.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#include "RtWvIn.h"
|
||||
|
||||
RtWvIn :: RtWvIn(int nChannels, StkFloat sampleRate, int device, int bufferFrames, int nBuffers )
|
||||
RtWvIn :: RtWvIn( unsigned int nChannels, StkFloat sampleRate, int device, int bufferFrames, int nBuffers )
|
||||
: stopped_( true ), bufferIndex_( 0 )
|
||||
{
|
||||
channels_ = nChannels;
|
||||
int size = bufferFrames;
|
||||
RtAudioFormat format = ( sizeof(StkFloat) == 8 ) ? RTAUDIO_FLOAT64 : RTAUDIO_FLOAT32;
|
||||
|
||||
audio_ = 0;
|
||||
adc_ = 0;
|
||||
try {
|
||||
audio_ = new RtAudio();
|
||||
adc_ = new RtAudio();
|
||||
}
|
||||
catch (RtError &error) {
|
||||
handleError( error.getMessageString(), StkError::AUDIO_SYSTEM );
|
||||
}
|
||||
|
||||
// Now open a stream and get the buffer pointer.
|
||||
// Allocate the adc and get the buffer pointer.
|
||||
try {
|
||||
audio_->openStream(0, 0, device, channels_, format,
|
||||
(int)sampleRate, &size, nBuffers);
|
||||
data_ = (StkFloat *) audio_->getStreamBuffer();
|
||||
adc_->openStream( 0, 0, device, (int)nChannels, format,
|
||||
(int)sampleRate, &size, nBuffers );
|
||||
buffer_ = (StkFloat *) adc_->getStreamBuffer();
|
||||
}
|
||||
catch (RtError &error) {
|
||||
handleError( error.getMessageString(), StkError::AUDIO_SYSTEM );
|
||||
}
|
||||
|
||||
bufferSize_ = size;
|
||||
lastOutputs_ = (StkFloat *) new StkFloat[channels_];
|
||||
for (unsigned int i=0; i<channels_; i++) lastOutputs_[i] = 0.0;
|
||||
counter_ = 0;
|
||||
stopped_ = true;
|
||||
bufferFrames_ = size;
|
||||
lastOutputs_.resize( 1, nChannels );
|
||||
}
|
||||
|
||||
RtWvIn :: ~RtWvIn()
|
||||
{
|
||||
if ( !stopped_ )
|
||||
audio_->stopStream();
|
||||
delete audio_;
|
||||
data_ = 0; // RtAudio deletes the buffer itself.
|
||||
if ( !stopped_ ) adc_->stopStream();
|
||||
adc_->closeStream();
|
||||
delete adc_;
|
||||
}
|
||||
|
||||
void RtWvIn :: start()
|
||||
{
|
||||
if ( stopped_ ) {
|
||||
audio_->startStream();
|
||||
adc_->startStream();
|
||||
stopped_ = false;
|
||||
}
|
||||
}
|
||||
@@ -71,68 +66,29 @@ void RtWvIn :: start()
|
||||
void RtWvIn :: stop()
|
||||
{
|
||||
if ( !stopped_ ) {
|
||||
audio_->stopStream();
|
||||
adc_->stopStream();
|
||||
stopped_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
StkFloat RtWvIn :: lastOut(void) const
|
||||
void RtWvIn :: computeFrame( void )
|
||||
{
|
||||
return WvIn::lastOut();
|
||||
}
|
||||
if ( stopped_ ) this->start();
|
||||
|
||||
StkFloat RtWvIn :: tick(void)
|
||||
{
|
||||
this->tickFrame();
|
||||
return lastOut();
|
||||
}
|
||||
|
||||
StkFloat *RtWvIn :: tick(StkFloat *vector, unsigned int vectorSize)
|
||||
{
|
||||
return WvIn::tick( vector, vectorSize );
|
||||
}
|
||||
|
||||
StkFrames& RtWvIn :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
return WvIn::tick( frames, channel );
|
||||
}
|
||||
|
||||
const StkFloat *RtWvIn :: lastFrame() const
|
||||
{
|
||||
return lastOutputs_;
|
||||
}
|
||||
|
||||
const StkFloat *RtWvIn :: tickFrame(void)
|
||||
{
|
||||
if ( stopped_ )
|
||||
this->start();
|
||||
|
||||
if (counter_ == 0) {
|
||||
if ( bufferIndex_ == 0) {
|
||||
try {
|
||||
audio_->tickStream();
|
||||
adc_->tickStream();
|
||||
}
|
||||
catch (RtError &error) {
|
||||
handleError( error.getMessageString(), StkError::AUDIO_SYSTEM );
|
||||
}
|
||||
}
|
||||
|
||||
long temp = counter_ * channels_;
|
||||
for (unsigned int i=0; i<channels_; i++)
|
||||
lastOutputs_[i] = data_[temp++];
|
||||
long iBuffer = bufferIndex_ * lastOutputs_.size();
|
||||
for (unsigned int i=0; i<lastOutputs_.size(); i++)
|
||||
lastOutputs_[i] = buffer_[iBuffer++];
|
||||
|
||||
counter_++;
|
||||
if (counter_ >= (long) bufferSize_)
|
||||
counter_ = 0;
|
||||
|
||||
return lastOutputs_;
|
||||
}
|
||||
|
||||
StkFloat *RtWvIn :: tickFrame(StkFloat *frameVector, unsigned int frames)
|
||||
{
|
||||
return WvIn::tickFrame( frameVector, frames );
|
||||
}
|
||||
|
||||
StkFrames& RtWvIn :: tickFrame( StkFrames& frames )
|
||||
{
|
||||
return WvIn::tickFrame( frames );
|
||||
bufferIndex_++;
|
||||
if ( bufferIndex_ >= bufferFrames_ )
|
||||
bufferIndex_ = 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user