ehe that’s cool stuff. if you want, here is some interesting code (on how to use that library for oscillator playback):
class MipMapOscillator : public AudioSource
{
public:
//! Constructor
MipMapOscillator() :
data(0),
waveSize(0),
buffer(0),
incrementPhase(0.0f)
{
}
//! Destructor
virtual ~MipMapOscillator()
{
if (buffer)
delete buffer;
}
//==============================================================================
/** Implementation of the SynthVoice method. */
void startPlayback()
{
Int64 pos = static_cast <Int64>(0) << 32 ;
pos += static_cast <Int64> (waveSize * 16) << 32;
resampler.clear_buffers();
resampler.set_playback_pos( pos );
currentPhase = 0.0;
}
/** Implementation of the SynthVoice method. */
void stopPlayback()
{
}
/** Implementation of the SynthVoice method. */
void releasePlayback()
{
}
//==============================================================================
/** Sets the signal's amplitude. */
void setAmplitude (const float newAmplitude)
{
amplitude = newAmplitude;
}
/** Sets the signal's frequency. */
void setFrequency (const double newFrequencyHz)
{
frequency = newFrequencyHz;
long pitch = ((1L << ResamplerFlt::NBR_BITS_PER_OCT) / 1200);
pitch = (long)( pitch * log(frequency / (sampleRate / (double)waveSize)) / log(2.0) * 1200 );
resampler.set_pitch( pitch );
}
/** Set the current playing sample */
void setSampleBuffer( MipMapSampleBuffer* smpl )
{
data = smpl->getMipMap();
waveSize = smpl->getSize();
totalSize = smpl->getTotalSize();
resampler.set_sample( *data );
resampler.set_interp( interpolator );
}
//==============================================================================
/** Implementation of the AudioSource method. */
void prepareToPlay (int samplesPerBlockExpected, double newSampleRate)
{
if( buffer && buffer->getNumSamples() != samplesPerBlockExpected ) {
delete buffer;
buffer = 0;
}
if( !buffer )
buffer = new AudioSampleBuffer(1,samplesPerBlockExpected);
buffer->clear();
sampleRate = newSampleRate;
}
/** Implementation of the AudioSource method. */
void releaseResources()
{
}
//==============================================================================
/** Implementation of the AudioSource method. */
void getNextAudioBlock (const AudioSourceChannelInfo& info)
{
float* out = buffer->getSampleData(0);
Int64 pos = resampler.get_playback_pos();
if ((pos >> 32) > (totalSize >> 1))
{
// Simulate "loop" by going back to the begining
pos &= (static_cast <Int64> (waveSize) << 32) - 1;
// But skip a few periods in order to ensure that we get the
// periodic waveform part on highest MIP-map levels.
// first period
pos += static_cast <Int64> (waveSize * 16) << 32;
resampler.set_playback_pos( pos );
}
resampler.interpolate_block( out, info.numSamples );
for (int j = info.buffer->getNumChannels(); --j >= 0;)
info.buffer->copyFrom( j,
info.startSample,
*buffer,
0,
0,
info.numSamples);
info.buffer->applyGain(info.startSample,info.numSamples,amplitude);
}
public:
InterpPack interpolator;
ResamplerFlt resampler;
MipMapFlt* data; // < the mipmap
unsigned long waveSize; // < size of each wave
unsigned long totalSize; // < size of wave
AudioSampleBuffer* buffer;
float incrementPhase;
double frequency, sampleRate;
double currentPhase, phasePerSample;
float amplitude;
};
that’s a bit old, but you can find some useful function, especially the one that convert frequency from (float) Hz to (long) pitch the library expects…