From 117343a4d4c85e2790f0d0e0bda2b8ba493fadcc Mon Sep 17 00:00:00 2001 From: pichenettes Date: Tue, 26 Apr 2011 22:07:25 +0200 Subject: [PATCH] Added wavetable interpolation function --- op.h | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/op.h b/op.h index af328cd..c51991d 100755 --- a/op.h +++ b/op.h @@ -21,6 +21,8 @@ #ifndef AVRLIB_OP_H_ #define AVRLIB_OP_H_ +#include + #include "avrlib/base.h" namespace avrlib { @@ -389,6 +391,37 @@ static inline uint8_t ShiftRight7(uint16_t value) { return result; } +static inline uint8_t InterpolateSample( + const prog_uint8_t* table, + uint16_t phase) __attribute__((always_inline)); + +static inline uint8_t InterpolateSample( + const prog_uint8_t* table, + uint16_t phase) { + uint8_t result; + uint8_t work; + asm( + "movw r30, %A2" "\n\t" // copy base address to r30:r31 + "add r30, %B3" "\n\t" // increment table address by phaseH + "adc r31, r1" "\n\t" // just carry + "mov %1, %A3" "\n\t" // move phaseL to working register + "lpm %0, z+" "\n\t" // load sample[n] + "lpm r1, z+" "\n\t" // load sample[n+1] + "mul %1, r1" "\n\t" // multiply second sample by phaseL + "movw r30, r0" "\n\t" // result to accumulator + "com %1" "\n\t" // 255 - phaseL -> phaseL + "mul %1, %0" "\n\t" // multiply first sample by phaseL + "add r30, r0" "\n\t" // accumulate L + "adc r31, r1" "\n\t" // accumulate H + "eor r1, r1" "\n\t" // reset r1 after multiplication + "mov %0, r31" "\n\t" // use sum H as output + : "=r" (result), "=r" (work) + : "r" (table), "r" (phase) + : "r30", "r31" + ); + return result; +} + #else static inline uint8_t Clip8(int16_t value) { @@ -463,6 +496,15 @@ static inline uint8_t ShiftRight7(uint16_t value) { return value >> 7; } +static inline uint8_t InterpolateSample( + const prog_uint8_t* table, + uint16_t phase) { + return Mix( + pgm_read_byte(table + (phase >> 8)), + pgm_read_byte(1 + table + (phase >> 8)), + phase & 0xff); +} + #endif // USE_OPTIMIZED_OP } // namespace avrlib