hermite resampling just for fun

pull/18/head
Dimitri Diakopoulos 10 years ago
parent dcd2d1200f
commit 82939a2228

@ -41,7 +41,7 @@ int main(int argc, const char **argv) try
//loader.Load(fileData.get(), "test_data/1ch/44100/8/test.wav"); //loader.Load(fileData.get(), "test_data/1ch/44100/8/test.wav");
//loader.Load(fileData.get(), "test_data/1ch/44100/16/test.wav"); //loader.Load(fileData.get(), "test_data/1ch/44100/16/test.wav");
//loader.Load(fileData.get(), "test_data/1ch/44100/24/test.wav"); //loader.Load(fileData.get(), "test_data/1ch/44100/24/test.wav");
//loader.Load(fileData.get(), "test_data/1ch/44100/32/test.wav"); loader.Load(fileData.get(), "test_data/1ch/44100/32/test.wav");
//loader.Load(fileData.get(), "test_data/1ch/44100/64/test.wav"); //loader.Load(fileData.get(), "test_data/1ch/44100/64/test.wav");
// 2-channel wave // 2-channel wave
@ -86,14 +86,16 @@ int main(int argc, const char **argv) try
//loader.Load(fileData.get(), "test_data/ad_hoc/44_16_mono.mpc"); //loader.Load(fileData.get(), "test_data/ad_hoc/44_16_mono.mpc");
} }
/*
// Test Recording Capabilities of AudioDevice // Test Recording Capabilities of AudioDevice
fileData->samples.reserve(44100 * 2); fileData->samples.reserve(44100 * 5);
fileData->channelCount = 1; fileData->channelCount = 1;
fileData->frameSize = 32; fileData->frameSize = 32;
fileData->lengthSeconds = 2.0; fileData->lengthSeconds = 5.0;
fileData->sampleRate = 44100; fileData->sampleRate = 44100;
std::cout << "Starting recording for two seconds..." << std::endl; std::cout << "Starting recording ..." << std::endl;
myDevice.Record(fileData->sampleRate * fileData->lengthSeconds, fileData->samples); myDevice.Record(fileData->sampleRate * fileData->lengthSeconds, fileData->samples);
*/
// Libnyquist does not (currently) perform sample rate conversion - not exactly true, anymore. See below. // Libnyquist does not (currently) perform sample rate conversion - not exactly true, anymore. See below.
if (fileData->sampleRate != desiredSampleRate) if (fileData->sampleRate != desiredSampleRate)

@ -32,7 +32,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace nqr namespace nqr
{ {
// This is a naieve implementation of a resampling filter where a lerp is used as a bad low-pass. // This is a naieve implementation of a resampling filter where a lerp is used as a bad low-pass.
// It very far from the ideal case and should be used with caution (or not at all) on signals that matter. // It very far from the ideal case and should be used with caution (or not at all) on signals that matter.
// It is included here to upsample 44.1k to 48k for the purposes of microphone input => Opus, where the the // It is included here to upsample 44.1k to 48k for the purposes of microphone input => Opus, where the the
@ -46,7 +45,7 @@ namespace nqr
{ {
uint32_t readIndex = static_cast<uint32_t>(virtualReadIndex); uint32_t readIndex = static_cast<uint32_t>(virtualReadIndex);
i = virtualReadIndex - readIndex; i = virtualReadIndex - readIndex;
a = input[readIndex + 0]; a = input[readIndex + 0];
b = input[readIndex + 1]; b = input[readIndex + 1];
sample = (1.0 - i) * a + i * b; // linear interpolate sample = (1.0 - i) * a + i * b; // linear interpolate
output.push_back(sample); output.push_back(sample);
@ -54,6 +53,32 @@ namespace nqr
} }
} }
static inline double sample_hermite_4p_3o(double x, double * y)
{
static double c0, c1, c2, c3;
c0 = y[1];
c1 = (1.0/2.0)*(y[2]-y[0]);
c2 = (y[0] - (5.0/2.0)*y[1]) + (2.0*y[2] - (1.0/2.0)*y[3]);
c3 = (1.0/2.0)*(y[3]-y[0]) + (3.0/2.0)*(y[1]-y[2]);
return ((c3*x+c2)*x+c1)*x+c0;
}
static inline void hermite_resample(const double rate, const std::vector<float> & input, std::vector<float> & output, size_t samplesToProcess)
{
double virtualReadIndex = 1;
double i, sample;
uint32_t n = samplesToProcess - 1;
while (n--)
{
uint32_t readIndex = static_cast<uint32_t>(virtualReadIndex);
i = virtualReadIndex - readIndex;
double samps[4] = {input[readIndex - 1], input[readIndex], input[readIndex + 1], input[readIndex + 2]};
sample = sample_hermite_4p_3o(i, samps); // cubic hermite interpolate over 4 samples
output.push_back(sample);
virtualReadIndex += rate;
}
}
enum EncoderError enum EncoderError
{ {
NoError, NoError,

Loading…
Cancel
Save