#include "analyze_tonedetect.h" | #include "analyze_tonedetect.h" | ||||
#include "utility/dspinst.h" | #include "utility/dspinst.h" | ||||
#if defined(KINETISK) | |||||
static inline int32_t multiply_32x32_rshift30(int32_t a, int32_t b) __attribute__((always_inline)); | static inline int32_t multiply_32x32_rshift30(int32_t a, int32_t b) __attribute__((always_inline)); | ||||
static inline int32_t multiply_32x32_rshift30(int32_t a, int32_t b) | static inline int32_t multiply_32x32_rshift30(int32_t a, int32_t b) | ||||
{ | { | ||||
trigger = (uint32_t)len * thresh; | trigger = (uint32_t)len * thresh; | ||||
trigger = multiply_32x32_rshift32(trigger, trigger); | trigger = multiply_32x32_rshift32(trigger, trigger); | ||||
Serial.printf("bool: power=%d, trig=%d\n", power, trigger); | |||||
//Serial.printf("bool: power=%d, trig=%d\n", power, trigger); | |||||
return (power >= trigger); | return (power >= trigger); | ||||
// TODO: this should really remember if it's retuned true previously, | // TODO: this should really remember if it's retuned true previously, | ||||
// so it can give a single true response each time a tone is seen. | // so it can give a single true response each time a tone is seen. | ||||
} | } | ||||
#elif defined(KINETISL) | |||||
void AudioAnalyzeToneDetect::update(void) | |||||
{ | |||||
audio_block_t *block; | |||||
block = receiveReadOnly(); | |||||
if (block) release(block); | |||||
} | |||||
#endif | |||||
void AudioEffectMultiply::update(void) | void AudioEffectMultiply::update(void) | ||||
{ | { | ||||
#if defined(KINETISK) | |||||
audio_block_t *blocka, *blockb; | audio_block_t *blocka, *blockb; | ||||
uint32_t *pa, *pb, *end; | uint32_t *pa, *pb, *end; | ||||
uint32_t a12, a34; //, a56, a78; | uint32_t a12, a34; //, a56, a78; | ||||
transmit(blocka); | transmit(blocka); | ||||
release(blocka); | release(blocka); | ||||
release(blockb); | release(blockb); | ||||
#elif defined(KINETISL) | |||||
audio_block_t *block; | |||||
block = receiveReadOnly(0); | |||||
if (block) release(block); | |||||
block = receiveReadOnly(1); | |||||
if (block) release(block); | |||||
#endif | |||||
} | } | ||||
#include "filter_biquad.h" | #include "filter_biquad.h" | ||||
#include "utility/dspinst.h" | #include "utility/dspinst.h" | ||||
#if defined(KINETISK) | |||||
void AudioFilterBiquad::update(void) | void AudioFilterBiquad::update(void) | ||||
{ | { | ||||
audio_block_t *block; | audio_block_t *block; | ||||
sum = signed_multiply_accumulate_32x16b(sum, a1, out2); | sum = signed_multiply_accumulate_32x16b(sum, a1, out2); | ||||
sum = signed_multiply_accumulate_32x16t(sum, a2, aprev); | sum = signed_multiply_accumulate_32x16t(sum, a2, aprev); | ||||
bprev = in2; | bprev = in2; | ||||
aprev = pack_16x16( | |||||
aprev = pack_16b_16b( | |||||
signed_saturate_rshift(sum, 16, 14), out2); | signed_saturate_rshift(sum, 16, 14), out2); | ||||
sum &= 0x3FFF; | sum &= 0x3FFF; | ||||
bprev = in2; | bprev = in2; | ||||
*dest &= 0x80000000; | *dest &= 0x80000000; | ||||
__enable_irq(); | __enable_irq(); | ||||
} | } | ||||
#elif defined(KINETISL) | |||||
void AudioFilterBiquad::update(void) | |||||
{ | |||||
audio_block_t *block; | |||||
block = receiveReadOnly(); | |||||
if (block) release(block); | |||||
} | |||||
#endif |
// no audible difference. | // no audible difference. | ||||
//#define IMPROVE_EXPONENTIAL_ACCURACY | //#define IMPROVE_EXPONENTIAL_ACCURACY | ||||
#if defined(KINETISK) | |||||
void AudioFilterStateVariable::update_fixed(const int16_t *in, | void AudioFilterStateVariable::update_fixed(const int16_t *in, | ||||
int16_t *lp, int16_t *bp, int16_t *hp) | int16_t *lp, int16_t *bp, int16_t *hp) | ||||
{ | { | ||||
return; | return; | ||||
} | } | ||||
#elif defined(KINETISL) | |||||
void AudioFilterStateVariable::update(void) | |||||
{ | |||||
audio_block_t *block; | |||||
block = receiveReadOnly(0); | |||||
if (block) release(block); | |||||
block = receiveReadOnly(1); | |||||
if (block) release(block); | |||||
} | |||||
#endif | |||||
AudioOutputI2S::config_i2s(); | AudioOutputI2S::config_i2s(); | ||||
CORE_PIN13_CONFIG = PORT_PCR_MUX(4); // pin 13, PTC5, I2S0_RXD0 | CORE_PIN13_CONFIG = PORT_PCR_MUX(4); // pin 13, PTC5, I2S0_RXD0 | ||||
#if defined(KINETISK) | |||||
dma.TCD->SADDR = &I2S0_RDR0; | dma.TCD->SADDR = &I2S0_RDR0; | ||||
dma.TCD->SOFF = 0; | dma.TCD->SOFF = 0; | ||||
dma.TCD->ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1); | dma.TCD->ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1); | ||||
dma.TCD->DLASTSGA = -sizeof(i2s_rx_buffer); | dma.TCD->DLASTSGA = -sizeof(i2s_rx_buffer); | ||||
dma.TCD->BITER_ELINKNO = sizeof(i2s_rx_buffer) / 2; | dma.TCD->BITER_ELINKNO = sizeof(i2s_rx_buffer) / 2; | ||||
dma.TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR; | dma.TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR; | ||||
#endif | |||||
dma.triggerAtHardwareEvent(DMAMUX_SOURCE_I2S0_RX); | dma.triggerAtHardwareEvent(DMAMUX_SOURCE_I2S0_RX); | ||||
update_responsibility = update_setup(); | update_responsibility = update_setup(); | ||||
dma.enable(); | dma.enable(); | ||||
audio_block_t *left, *right; | audio_block_t *left, *right; | ||||
//digitalWriteFast(3, HIGH); | //digitalWriteFast(3, HIGH); | ||||
#if defined(KINETISK) | |||||
daddr = (uint32_t)(dma.TCD->DADDR); | daddr = (uint32_t)(dma.TCD->DADDR); | ||||
#endif | |||||
dma.clearInterrupt(); | dma.clearInterrupt(); | ||||
if (daddr < (uint32_t)i2s_rx_buffer + sizeof(i2s_rx_buffer) / 2) { | if (daddr < (uint32_t)i2s_rx_buffer + sizeof(i2s_rx_buffer) / 2) { | ||||
AudioOutputI2Sslave::config_i2s(); | AudioOutputI2Sslave::config_i2s(); | ||||
CORE_PIN13_CONFIG = PORT_PCR_MUX(4); // pin 13, PTC5, I2S0_RXD0 | CORE_PIN13_CONFIG = PORT_PCR_MUX(4); // pin 13, PTC5, I2S0_RXD0 | ||||
#if defined(KINETISK) | |||||
dma.TCD->SADDR = &I2S0_RDR0; | dma.TCD->SADDR = &I2S0_RDR0; | ||||
dma.TCD->SOFF = 0; | dma.TCD->SOFF = 0; | ||||
dma.TCD->ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1); | dma.TCD->ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1); | ||||
dma.TCD->DLASTSGA = -sizeof(i2s_rx_buffer); | dma.TCD->DLASTSGA = -sizeof(i2s_rx_buffer); | ||||
dma.TCD->BITER_ELINKNO = sizeof(i2s_rx_buffer) / 2; | dma.TCD->BITER_ELINKNO = sizeof(i2s_rx_buffer) / 2; | ||||
dma.TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR; | dma.TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR; | ||||
#endif | |||||
dma.triggerAtHardwareEvent(DMAMUX_SOURCE_I2S0_RX); | dma.triggerAtHardwareEvent(DMAMUX_SOURCE_I2S0_RX); | ||||
update_responsibility = update_setup(); | update_responsibility = update_setup(); | ||||
dma.enable(); | dma.enable(); |
// TODO: this code assumes F_BUS is 48 MHz. | // TODO: this code assumes F_BUS is 48 MHz. | ||||
// supporting other speeds is not easy, but should be done someday | // supporting other speeds is not easy, but should be done someday | ||||
#if defined(KINETISK) | |||||
void AudioOutputPWM::begin(void) | void AudioOutputPWM::begin(void) | ||||
{ | { | ||||
dma.begin(true); // Allocate the DMA channel first | dma.begin(true); // Allocate the DMA channel first | ||||
// biter = sizeof(buffer) / 8 (no minor loop linking) | // biter = sizeof(buffer) / 8 (no minor loop linking) | ||||
#elif defined(KINETISL) | |||||
void AudioOutputPWM::update(void) | |||||
{ | |||||
audio_block_t *block; | |||||
block = receiveReadOnly(); | |||||
if (block) release(block); | |||||
} | |||||
#endif |
#include "output_spdif.h" | #include "output_spdif.h" | ||||
#if defined(KINETISK) | |||||
#define PREAMBLE_B (0xE8) //11101000 | #define PREAMBLE_B (0xE8) //11101000 | ||||
#define PREAMBLE_M (0xE2) //11100010 | #define PREAMBLE_M (0xE2) //11100010 | ||||
#define PREAMBLE_W (0xE4) //11100100 | #define PREAMBLE_W (0xE4) //11100100 | ||||
// CORE_PIN11_CONFIG = PORT_PCR_MUX(6); // pin 11, PTC6, I2S0_MCLK | // CORE_PIN11_CONFIG = PORT_PCR_MUX(6); // pin 11, PTC6, I2S0_MCLK | ||||
#endif | #endif | ||||
} | } | ||||
#elif defined(KINETISL) | |||||
void AudioOutputSPDIF::update(void) | |||||
{ | |||||
audio_block_t *block; | |||||
block = receiveReadOnly(0); // input 0 = left channel | |||||
if (block) release(block); | |||||
block = receiveReadOnly(1); // input 1 = right channel | |||||
if (block) release(block); | |||||
} | |||||
#endif |
scale = (ph >> 8) & 0xFFFF; | scale = (ph >> 8) & 0xFFFF; | ||||
val2 *= scale; | val2 *= scale; | ||||
val1 *= 0xFFFF - scale; | val1 *= 0xFFFF - scale; | ||||
//block->data[i] = (((val1 + val2) >> 16) * magnitude) >> 16; | |||||
#if defined(KINETISK) | |||||
block->data[i] = multiply_32x32_rshift32(val1 + val2, magnitude); | block->data[i] = multiply_32x32_rshift32(val1 + val2, magnitude); | ||||
#elif defined(KINETISL) | |||||
block->data[i] = (((val1 + val2) >> 16) * magnitude) >> 16; | |||||
#endif | |||||
ph += inc; | ph += inc; | ||||
} | } | ||||
phase_accumulator = ph; | phase_accumulator = ph; | ||||
} | } | ||||
#if defined(KINETISK) | |||||
void AudioSynthWaveformSineModulated::update(void) | void AudioSynthWaveformSineModulated::update(void) | ||||
{ | { | ||||
audio_block_t *block, *modinput; | audio_block_t *block, *modinput; | ||||
release(block); | release(block); | ||||
} | } | ||||
#elif defined(KINETISL) | |||||
void AudioSynthWaveformSineModulated::update(void) | |||||
{ | |||||
audio_block_t *block; | |||||
block = receiveReadOnly(); | |||||
if (block) release(block); | |||||
} | |||||
#endif | |||||
end = p + AUDIO_BLOCK_SAMPLES/2; | end = p + AUDIO_BLOCK_SAMPLES/2; | ||||
lo = seed; | lo = seed; | ||||
do { | do { | ||||
#if defined(KINETISK) | |||||
hi = multiply_16bx16t(16807, lo); // 16807 * (lo >> 16) | hi = multiply_16bx16t(16807, lo); // 16807 * (lo >> 16) | ||||
lo = 16807 * (lo & 0xFFFF); | lo = 16807 * (lo & 0xFFFF); | ||||
lo += (hi & 0x7FFF) << 16; | lo += (hi & 0x7FFF) << 16; | ||||
val2 = pack_16b_16b(n2, n1); | val2 = pack_16b_16b(n2, n1); | ||||
*p++ = val1; | *p++ = val1; | ||||
*p++ = val2; | *p++ = val2; | ||||
#elif defined(KINETISL) | |||||
hi = 16807 * (lo >> 16); | |||||
lo = 16807 * (lo & 0xFFFF); | |||||
lo += (hi & 0x7FFF) << 16; | |||||
lo += hi >> 15; | |||||
lo = (lo & 0x7FFFFFFF) + (lo >> 31); | |||||
n1 = signed_multiply_32x16b(gain, lo); | |||||
hi = 16807 * (lo >> 16); | |||||
lo = 16807 * (lo & 0xFFFF); | |||||
lo += (hi & 0x7FFF) << 16; | |||||
lo += hi >> 15; | |||||
lo = (lo & 0x7FFFFFFF) + (lo >> 31); | |||||
n2 = signed_multiply_32x16b(gain, lo); | |||||
val1 = pack_16b_16b(n2, n1); | |||||
*p++ = val1; | |||||
#endif | |||||
} while (p < end); | } while (p < end); | ||||
seed = lo; | seed = lo; | ||||
transmit(block); | transmit(block); |