|
|
|
/*
|
|
|
|
|
|
|
|
Copyright (C) 2000 Stefan Westerfeld
|
|
|
|
stefan@space.twc.de
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
Boston, MA 02110-1301, USA.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef ARTS_FLOW_RESAMPLE_H
|
|
|
|
#define ARTS_FLOW_RESAMPLE_H
|
|
|
|
|
|
|
|
#include "arts_export.h"
|
|
|
|
|
|
|
|
/*
|
|
|
|
* BC - Status (2002-03-08): Resampler / Refiller.
|
|
|
|
*
|
|
|
|
* These classes will be kept binary compatible. Resampler has a private
|
|
|
|
* data pointer for this purpose.
|
|
|
|
*/
|
|
|
|
|
|
|
|
namespace Arts {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Refiller interface
|
|
|
|
*
|
|
|
|
* this is used by the resampler class
|
|
|
|
*/
|
|
|
|
class ARTS_EXPORT Refiller {
|
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* callback method to supply data to the Resampler
|
|
|
|
*
|
|
|
|
* here you supply data in the encoding specified in the Resampler class
|
|
|
|
* (bits, channels, endianness) to the Resampler
|
|
|
|
*
|
|
|
|
* @param buffer a pointer to a buffer where the data can be filled to
|
|
|
|
* @param len the size of the buffer in bytes
|
|
|
|
*
|
|
|
|
* @returns the number of bytes really available
|
|
|
|
*/
|
|
|
|
virtual unsigned long read(unsigned char *buffer, unsigned long len) = 0;
|
|
|
|
virtual ~Refiller();
|
|
|
|
};
|
|
|
|
|
|
|
|
class ResamplerPrivate;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The Resampler class resamples data from an input stream, which is read
|
|
|
|
* through the Refiller interface, and renders it into the float format which
|
|
|
|
* aRts usually uses, converting the sampling rate and format as needed.
|
|
|
|
*/
|
|
|
|
class ARTS_EXPORT Resampler {
|
|
|
|
protected:
|
|
|
|
static const unsigned int bufferSize = 256; // 64 samples in buffer
|
|
|
|
static const unsigned int bufferWrap = 64; // + "wrap around"
|
|
|
|
/*
|
|
|
|
* BC: bufferWrap just needs channels * (filtersize - 1) * bytes per sample
|
|
|
|
* bytes wrap around - this used to be 4: 2 channels, linear interpolation,
|
|
|
|
* 16bit. However, for supporting float resampling and/or better filters,
|
|
|
|
* we'll make this 64 to be safe.
|
|
|
|
*/
|
|
|
|
|
|
|
|
int bufferSamples;
|
|
|
|
int sampleSize;
|
|
|
|
int dropBytes;
|
|
|
|
|
|
|
|
Refiller *refiller;
|
|
|
|
double pos, step;
|
|
|
|
int channels,bits;
|
|
|
|
|
|
|
|
unsigned char buffer[bufferSize+bufferWrap];
|
|
|
|
float fbuffer[bufferSize+bufferWrap];
|
|
|
|
long block, haveBlock;
|
|
|
|
|
|
|
|
class ResamplerPrivate *d;
|
|
|
|
|
|
|
|
void updateSampleSize();
|
|
|
|
void ensureRefill();
|
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* constructor
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
Resampler(Refiller *refiller);
|
|
|
|
~Resampler();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* sets the resampling step in the input stream
|
|
|
|
*
|
|
|
|
* for instance, settings step to 2.0, the file would be played twice as
|
|
|
|
* fast - you can calculate the resampling step from the sampling rate
|
|
|
|
* the stream you resample was recorded at, and the sampling rate you want
|
|
|
|
* it to be resampled to, using
|
|
|
|
*
|
|
|
|
* step = originalSamplingRate / desiredSamplingRate
|
|
|
|
*
|
|
|
|
* for instance, if a stream recorded at 22050 Hz is to be played at 48000
|
|
|
|
* Hz, step would be
|
|
|
|
*
|
|
|
|
* step = 22050 / 48000 = 0.46
|
|
|
|
*/
|
|
|
|
void setStep(double step);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* sets the number of channels in the input stream
|
|
|
|
*
|
|
|
|
* the channels are expected to be interleaved, thus if you have two
|
|
|
|
* channels, you will have one sample for the left stream, one for the
|
|
|
|
* right, one for the left, ... and so on
|
|
|
|
*
|
|
|
|
* currently only either mono (channels = 1) or stereo (channels = 2)
|
|
|
|
* streams are supported
|
|
|
|
*/
|
|
|
|
void setChannels(int channels);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* sets the number of bits in the input stream
|
|
|
|
*
|
|
|
|
* currently, only 16 bit and 8 bit streams are supported
|
|
|
|
*/
|
|
|
|
void setBits(int bits);
|
|
|
|
|
|
|
|
enum Endianness { bigEndian, littleEndian };
|
|
|
|
|
|
|
|
/**
|
|
|
|
* sets the endianess of the input stream
|
|
|
|
*
|
|
|
|
* supported are bigEndian and littleEndian
|
|
|
|
*/
|
|
|
|
void setEndianness(Endianness endianness);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* renders a buffer of float samples from the input stream
|
|
|
|
*
|
|
|
|
* the data is obtained by querying the refiller for data from the
|
|
|
|
* input stream and filling them into the float array pointed to by
|
|
|
|
* left and right - if reading data fails, the underrun flag is set
|
|
|
|
*/
|
|
|
|
void run(float *left, float *right, unsigned long samples);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* query the underrun flag
|
|
|
|
*
|
|
|
|
* underruns occur if run is called, but no data is available from the
|
|
|
|
* Refiller object
|
|
|
|
*/
|
|
|
|
bool underrun();
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* ARTS_FLOW_RESAMPLE_H */
|