|
- #include "Audio.h"
- #include "arm_math.h"
-
-
-
-
- static arm_cfft_radix4_instance_q15 fft_inst;
-
- void AudioAnalyzeFFT256::init(void)
- {
-
- arm_cfft_radix4_init_q15(&fft_inst, 256, 0, 1);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- }
-
- static void copy_to_fft_buffer(void *destination, const void *source)
- {
- const int16_t *src = (const int16_t *)source;
- int16_t *dst = (int16_t *)destination;
-
-
- for (int i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
- *dst++ = *src++;
- *dst++ = 0;
- }
- }
-
-
- static inline int32_t signed_saturate_rshift(int32_t val, int bits, int rshift) __attribute__((always_inline));
- static inline int32_t signed_saturate_rshift(int32_t val, int bits, int rshift)
- {
- int32_t out;
- asm volatile("ssat %0, %1, %2, asr %3" : "=r" (out) : "I" (bits), "r" (val), "I" (rshift));
- return out;
- }
-
- static void apply_window_to_fft_buffer(void *buffer, const void *window)
- {
- int16_t *buf = (int16_t *)buffer;
- const int16_t *win = (int16_t *)window;;
-
- for (int i=0; i < 256; i++) {
- int32_t val = *buf * *win++;
-
- *buf = val >> 15;
- buf += 2;
- }
-
- }
-
- void AudioAnalyzeFFT256::update(void)
- {
- audio_block_t *block;
-
- block = receiveReadOnly();
- if (!block) return;
- if (!prevblock) {
- prevblock = block;
- return;
- }
- copy_to_fft_buffer(buffer, prevblock->data);
- copy_to_fft_buffer(buffer+256, block->data);
-
-
- if (window) apply_window_to_fft_buffer(buffer, window);
- arm_cfft_radix4_q15(&fft_inst, buffer);
-
-
-
- arm_cmplx_mag_q15(buffer, buffer, 128);
- if (count == 0) {
- for (int i=0; i < 128; i++) {
- output[i] = buffer[i];
- }
- } else {
- for (int i=0; i < 128; i++) {
- output[i] += buffer[i];
- }
- }
- if (++count == naverage) {
- count = 0;
- for (int i=0; i < 128; i++) {
- output[i] /= naverage;
- }
- outputflag = true;
- }
-
- release(prevblock);
- prevblock = block;
-
- #if 0
- block = receiveReadOnly();
- if (state == 0) {
-
- if (block == NULL) return;
- copy_to_fft_buffer(buffer, block->data);
- state = 1;
- } else if (state == 1) {
-
- if (block == NULL) return;
- copy_to_fft_buffer(buffer+256, block->data);
- arm_cfft_radix4_q15(&fft_inst, buffer);
- state = 2;
- } else {
-
- arm_cmplx_mag_q15(buffer, output, 128);
- outputflag = true;
- if (block == NULL) return;
- copy_to_fft_buffer(buffer, block->data);
- state = 1;
- }
- release(block);
- #endif
- }
-
-
-
-
-
-
- void AudioSynthWaveform::set_ramp_length(uint16_t r_length)
- {
- if(r_length < 0) {
- ramp_length = 0;
- return;
- }
-
- if(r_length > 44*4) {
- ramp_length = 44*4;
- return;
- }
- ramp_length = r_length;
- }
-
- void AudioSynthWaveform::update(void)
- {
- audio_block_t *block;
- uint32_t i, ph, inc, index, scale;
- int32_t val1, val2, val3;
-
-
- if (((magnitude > 0) || ramp_down) && (block = allocate()) != NULL) {
- ph = phase;
- inc = phase_increment;
- for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
- index = ph >> 24;
- val1 = wavetable[index];
- val2 = wavetable[index+1];
- scale = (ph >> 8) & 0xFFFF;
- val2 *= scale;
- val1 *= 0xFFFF - scale;
- val3 = (val1 + val2) >> 16;
-
-
-
-
-
-
- if(ramp_up) {
-
-
-
- ramp_mag = ((ramp_length-ramp_up)<<15)/ramp_length;
- ramp_up--;
- block->data[i] = (val3 * ((ramp_mag * magnitude)>>15)) >> 15;
-
- } else if(ramp_down) {
-
-
-
-
-
-
-
- ramp_mag = ((ramp_down - 1)<<15)/ramp_length;
- ramp_down--;
- block->data[i] = (val3 * ((ramp_mag * last_magnitude)>>15)) >> 15;
- } else {
- block->data[i] = (val3 * magnitude) >> 15;
- }
-
-
-
-
- ph += inc;
- }
-
- phase = ph;
- transmit(block);
- release(block);
- } else {
-
- phase += phase_increment * AUDIO_BLOCK_SAMPLES;
- }
- }
-
-
-
-
-
-
-
-
- #if 0
- void AudioSineWaveMod::frequency(float f)
- {
- if (f > AUDIO_SAMPLE_RATE_EXACT / 2 || f < 0.0) return;
- phase_increment = (f / AUDIO_SAMPLE_RATE_EXACT) * 4294967296.0f;
- }
-
- void AudioSineWaveMod::update(void)
- {
- audio_block_t *block, *modinput;
- uint32_t i, ph, inc, index, scale;
- int32_t val1, val2;
-
-
- modinput = receiveReadOnly();
- ph = phase;
- inc = phase_increment;
- block = allocate();
- if (!block) {
-
- if (modinput) {
-
- for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
- ph += inc + modinput->data[i] * modulation_factor;
- }
- release(modinput);
- } else {
- ph += phase_increment * AUDIO_BLOCK_SAMPLES;
- }
- phase = ph;
- return;
- }
- if (modinput) {
- for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
- index = ph >> 24;
- val1 = sine_table[index];
- val2 = sine_table[index+1];
- scale = (ph >> 8) & 0xFFFF;
- val2 *= scale;
- val1 *= 0xFFFF - scale;
- block->data[i] = (val1 + val2) >> 16;
-
-
-
- ph += inc + modinput->data[i] * modulation_factor;
- }
- release(modinput);
- } else {
- ph = phase;
- inc = phase_increment;
- for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
- index = ph >> 24;
- val1 = sine_table[index];
- val2 = sine_table[index+1];
- scale = (ph >> 8) & 0xFFFF;
- val2 *= scale;
- val1 *= 0xFFFF - scale;
- block->data[i] = (val1 + val2) >> 16;
-
-
-
- ph += inc;
- }
- }
- phase = ph;
- transmit(block);
- release(block);
- }
- #endif
-
-
-
-
-
-
-
-
-
- void AudioPrint::update(void)
- {
- audio_block_t *block;
- uint32_t i;
-
- Serial.println("AudioPrint::update");
- Serial.println(name);
- block = receiveReadOnly();
- if (block) {
- for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
- Serial.print(block->data[i]);
- Serial.print(", ");
- if ((i % 12) == 11) Serial.println();
- }
- Serial.println();
- release(block);
- }
- }
-
-
-
-
- audio_block_t * AudioOutputPWM::block_1st = NULL;
- audio_block_t * AudioOutputPWM::block_2nd = NULL;
- uint32_t AudioOutputPWM::block_offset = 0;
- bool AudioOutputPWM::update_responsibility = false;
- uint8_t AudioOutputPWM::interrupt_count = 0;
-
- DMAMEM uint32_t pwm_dma_buffer[AUDIO_BLOCK_SAMPLES*2];
-
- void AudioOutputPWM::begin(void)
- {
-
- block_1st = NULL;
- FTM1_SC = 0;
- FTM1_CNT = 0;
- FTM1_MOD = 543;
- FTM1_C0SC = 0x69;
- FTM1_C1SC = 0x28;
- FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0);
- CORE_PIN3_CONFIG = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
- CORE_PIN4_CONFIG = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
- FTM1_C0V = 120;
- FTM1_C1V = 0;
- for (int i=0; i<256; i+=2) {
- pwm_dma_buffer[i] = 120;
- pwm_dma_buffer[i+1] = 0;
- }
- SIM_SCGC7 |= SIM_SCGC7_DMA;
- SIM_SCGC6 |= SIM_SCGC6_DMAMUX;
- DMA_CR = 0;
- DMA_TCD3_SADDR = pwm_dma_buffer;
- DMA_TCD3_SOFF = 4;
- DMA_TCD3_ATTR = DMA_TCD_ATTR_SSIZE(2) | DMA_TCD_ATTR_DSIZE(2) | DMA_TCD_ATTR_DMOD(4);
- DMA_TCD3_NBYTES_MLNO = 8;
- DMA_TCD3_SLAST = -sizeof(pwm_dma_buffer);
- DMA_TCD3_DADDR = &FTM1_C0V;
- DMA_TCD3_DOFF = 8;
- DMA_TCD3_CITER_ELINKNO = sizeof(pwm_dma_buffer) / 8;
- DMA_TCD3_DLASTSGA = 0;
- DMA_TCD3_BITER_ELINKNO = sizeof(pwm_dma_buffer) / 8;
- DMA_TCD3_CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR;
- DMAMUX0_CHCFG3 = DMAMUX_DISABLE;
- DMAMUX0_CHCFG3 = DMAMUX_SOURCE_FTM1_CH0 | DMAMUX_ENABLE;
- DMA_SERQ = 3;
- update_responsibility = update_setup();
- NVIC_ENABLE_IRQ(IRQ_DMA_CH3);
- }
-
- void AudioOutputPWM::update(void)
- {
- audio_block_t *block;
- block = receiveReadOnly();
- if (!block) return;
- __disable_irq();
- if (block_1st == NULL) {
- block_1st = block;
- block_offset = 0;
- __enable_irq();
- } else if (block_2nd == NULL) {
- block_2nd = block;
- __enable_irq();
- } else {
- audio_block_t *tmp = block_1st;
- block_1st = block_2nd;
- block_2nd = block;
- block_offset = 0;
- __enable_irq();
- release(tmp);
- }
- }
-
- void dma_ch3_isr(void)
- {
- int16_t *src;
- uint32_t *dest;
- audio_block_t *block;
- uint32_t saddr, offset;
-
- saddr = (uint32_t)DMA_TCD3_SADDR;
- DMA_CINT = 3;
- if (saddr < (uint32_t)pwm_dma_buffer + sizeof(pwm_dma_buffer) / 2) {
-
-
- dest = &pwm_dma_buffer[AUDIO_BLOCK_SAMPLES];
- } else {
-
-
- dest = pwm_dma_buffer;
- }
- block = AudioOutputPWM::block_1st;
- offset = AudioOutputPWM::block_offset;
-
- if (block) {
- src = &block->data[offset];
- for (int i=0; i < AUDIO_BLOCK_SAMPLES/4; i++) {
- uint16_t sample = *src++ + 0x8000;
- uint32_t msb = ((sample >> 8) & 255) + 120;
- uint32_t lsb = sample & 255;
- *dest++ = msb;
- *dest++ = lsb;
- *dest++ = msb;
- *dest++ = lsb;
- }
- offset += AUDIO_BLOCK_SAMPLES/4;
- if (offset < AUDIO_BLOCK_SAMPLES) {
- AudioOutputPWM::block_offset = offset;
- } else {
- AudioOutputPWM::block_offset = 0;
- AudioStream::release(block);
- AudioOutputPWM::block_1st = AudioOutputPWM::block_2nd;
- AudioOutputPWM::block_2nd = NULL;
- }
- } else {
-
- for (int i=0; i < AUDIO_BLOCK_SAMPLES/4; i++) {
- *dest++ = 248;
- *dest++ = 0;
- *dest++ = 248;
- *dest++ = 0;
- }
- }
- if (AudioOutputPWM::update_responsibility) {
- if (++AudioOutputPWM::interrupt_count >= 4) {
- AudioOutputPWM::interrupt_count = 0;
- AudioStream::update_all();
- }
- }
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- audio_block_t * AudioOutputI2S::block_left_1st = NULL;
- audio_block_t * AudioOutputI2S::block_right_1st = NULL;
- audio_block_t * AudioOutputI2S::block_left_2nd = NULL;
- audio_block_t * AudioOutputI2S::block_right_2nd = NULL;
- uint16_t AudioOutputI2S::block_left_offset = 0;
- uint16_t AudioOutputI2S::block_right_offset = 0;
- bool AudioOutputI2S::update_responsibility = false;
- DMAMEM static uint32_t i2s_tx_buffer[AUDIO_BLOCK_SAMPLES];
-
- void AudioOutputI2S::begin(void)
- {
-
- block_left_1st = NULL;
- block_right_1st = NULL;
-
- config_i2s();
- CORE_PIN22_CONFIG = PORT_PCR_MUX(6);
-
- DMA_CR = 0;
- DMA_TCD0_SADDR = i2s_tx_buffer;
- DMA_TCD0_SOFF = 2;
- DMA_TCD0_ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1);
- DMA_TCD0_NBYTES_MLNO = 2;
- DMA_TCD0_SLAST = -sizeof(i2s_tx_buffer);
- DMA_TCD0_DADDR = &I2S0_TDR0;
- DMA_TCD0_DOFF = 0;
- DMA_TCD0_CITER_ELINKNO = sizeof(i2s_tx_buffer) / 2;
- DMA_TCD0_DLASTSGA = 0;
- DMA_TCD0_BITER_ELINKNO = sizeof(i2s_tx_buffer) / 2;
- DMA_TCD0_CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR;
-
- DMAMUX0_CHCFG0 = DMAMUX_DISABLE;
- DMAMUX0_CHCFG0 = DMAMUX_SOURCE_I2S0_TX | DMAMUX_ENABLE;
- update_responsibility = update_setup();
- DMA_SERQ = 0;
-
- I2S0_TCSR |= I2S_TCSR_TE | I2S_TCSR_BCE | I2S_TCSR_FRDE | I2S_TCSR_FR;
- NVIC_ENABLE_IRQ(IRQ_DMA_CH0);
- }
-
-
-
-
- void dma_ch0_isr(void)
- {
- const int16_t *src, *end;
- int16_t *dest;
- audio_block_t *block;
- uint32_t saddr, offset;
-
- saddr = (uint32_t)DMA_TCD0_SADDR;
- DMA_CINT = 0;
- if (saddr < (uint32_t)i2s_tx_buffer + sizeof(i2s_tx_buffer) / 2) {
-
-
- dest = (int16_t *)&i2s_tx_buffer[AUDIO_BLOCK_SAMPLES/2];
- end = (int16_t *)&i2s_tx_buffer[AUDIO_BLOCK_SAMPLES];
- if (AudioOutputI2S::update_responsibility) AudioStream::update_all();
- } else {
-
-
- dest = (int16_t *)i2s_tx_buffer;
- end = (int16_t *)&i2s_tx_buffer[AUDIO_BLOCK_SAMPLES/2];
- }
-
-
- block = AudioOutputI2S::block_left_1st;
- if (block) {
- offset = AudioOutputI2S::block_left_offset;
- src = &block->data[offset];
- do {
- *dest = *src++;
- dest += 2;
- } while (dest < end);
- offset += AUDIO_BLOCK_SAMPLES/2;
- if (offset < AUDIO_BLOCK_SAMPLES) {
- AudioOutputI2S::block_left_offset = offset;
- } else {
- AudioOutputI2S::block_left_offset = 0;
- AudioStream::release(block);
- AudioOutputI2S::block_left_1st = AudioOutputI2S::block_left_2nd;
- AudioOutputI2S::block_left_2nd = NULL;
- }
- } else {
- do {
- *dest = 0;
- dest += 2;
- } while (dest < end);
- }
- dest -= AUDIO_BLOCK_SAMPLES - 1;
- block = AudioOutputI2S::block_right_1st;
- if (block) {
- offset = AudioOutputI2S::block_right_offset;
- src = &block->data[offset];
- do {
- *dest = *src++;
- dest += 2;
- } while (dest < end);
- offset += AUDIO_BLOCK_SAMPLES/2;
- if (offset < AUDIO_BLOCK_SAMPLES) {
- AudioOutputI2S::block_right_offset = offset;
- } else {
- AudioOutputI2S::block_right_offset = 0;
- AudioStream::release(block);
- AudioOutputI2S::block_right_1st = AudioOutputI2S::block_right_2nd;
- AudioOutputI2S::block_right_2nd = NULL;
- }
- } else {
- do {
- *dest = 0;
- dest += 2;
- } while (dest < end);
- }
- }
-
-
-
-
- void AudioOutputI2S::update(void)
- {
-
-
-
-
-
- audio_block_t *block;
- block = receiveReadOnly(0);
- if (block) {
- __disable_irq();
- if (block_left_1st == NULL) {
- block_left_1st = block;
- block_left_offset = 0;
- __enable_irq();
- } else if (block_left_2nd == NULL) {
- block_left_2nd = block;
- __enable_irq();
- } else {
- audio_block_t *tmp = block_left_1st;
- block_left_1st = block_left_2nd;
- block_left_2nd = block;
- block_left_offset = 0;
- __enable_irq();
- release(tmp);
- }
- }
- block = receiveReadOnly(1);
- if (block) {
- __disable_irq();
- if (block_right_1st == NULL) {
- block_right_1st = block;
- block_right_offset = 0;
- __enable_irq();
- } else if (block_right_2nd == NULL) {
- block_right_2nd = block;
- __enable_irq();
- } else {
- audio_block_t *tmp = block_right_1st;
- block_right_1st = block_right_2nd;
- block_right_2nd = block;
- block_right_offset = 0;
- __enable_irq();
- release(tmp);
- }
- }
- }
-
-
-
- void AudioOutputI2S::config_i2s(void)
- {
- SIM_SCGC6 |= SIM_SCGC6_I2S;
- SIM_SCGC7 |= SIM_SCGC7_DMA;
- SIM_SCGC6 |= SIM_SCGC6_DMAMUX;
-
-
- if (I2S0_TCSR & I2S_TCSR_TE) return;
- if (I2S0_RCSR & I2S_RCSR_RE) return;
-
-
- I2S0_MCR = I2S_MCR_MICS(3) | I2S_MCR_MOE;
- I2S0_MDR = I2S_MDR_FRACT(1) | I2S_MDR_DIVIDE(16);
-
-
- I2S0_TMR = 0;
- I2S0_TCR1 = I2S_TCR1_TFW(1);
- I2S0_TCR2 = I2S_TCR2_SYNC(0) | I2S_TCR2_BCP | I2S_TCR2_MSEL(1)
- | I2S_TCR2_BCD | I2S_TCR2_DIV(3);
- I2S0_TCR3 = I2S_TCR3_TCE;
- I2S0_TCR4 = I2S_TCR4_FRSZ(1) | I2S_TCR4_SYWD(15) | I2S_TCR4_MF
- | I2S_TCR4_FSE | I2S_TCR4_FSP | I2S_TCR4_FSD;
- I2S0_TCR5 = I2S_TCR5_WNW(15) | I2S_TCR5_W0W(15) | I2S_TCR5_FBT(15);
-
-
- I2S0_RMR = 0;
- I2S0_RCR1 = I2S_RCR1_RFW(1);
- I2S0_RCR2 = I2S_RCR2_SYNC(1) | I2S_TCR2_BCP | I2S_RCR2_MSEL(1)
- | I2S_RCR2_BCD | I2S_RCR2_DIV(3);
- I2S0_RCR3 = I2S_RCR3_RCE;
- I2S0_RCR4 = I2S_RCR4_FRSZ(1) | I2S_RCR4_SYWD(15) | I2S_RCR4_MF
- | I2S_RCR4_FSE | I2S_RCR4_FSP | I2S_RCR4_FSD;
- I2S0_RCR5 = I2S_RCR5_WNW(15) | I2S_RCR5_W0W(15) | I2S_RCR5_FBT(15);
-
-
- CORE_PIN23_CONFIG = PORT_PCR_MUX(6);
- CORE_PIN9_CONFIG = PORT_PCR_MUX(6);
- CORE_PIN11_CONFIG = PORT_PCR_MUX(6);
- }
-
-
-
-
-
- void AudioOutputI2Sslave::begin(void)
- {
-
- block_left_1st = NULL;
- block_right_1st = NULL;
-
- AudioOutputI2Sslave::config_i2s();
- CORE_PIN22_CONFIG = PORT_PCR_MUX(6);
-
- DMA_CR = 0;
- DMA_TCD0_SADDR = i2s_tx_buffer;
- DMA_TCD0_SOFF = 2;
- DMA_TCD0_ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1);
- DMA_TCD0_NBYTES_MLNO = 2;
- DMA_TCD0_SLAST = -sizeof(i2s_tx_buffer);
- DMA_TCD0_DADDR = &I2S0_TDR0;
- DMA_TCD0_DOFF = 0;
- DMA_TCD0_CITER_ELINKNO = sizeof(i2s_tx_buffer) / 2;
- DMA_TCD0_DLASTSGA = 0;
- DMA_TCD0_BITER_ELINKNO = sizeof(i2s_tx_buffer) / 2;
- DMA_TCD0_CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR;
-
- DMAMUX0_CHCFG0 = DMAMUX_DISABLE;
- DMAMUX0_CHCFG0 = DMAMUX_SOURCE_I2S0_TX | DMAMUX_ENABLE;
- update_responsibility = update_setup();
- DMA_SERQ = 0;
-
- I2S0_TCSR |= I2S_TCSR_TE | I2S_TCSR_BCE | I2S_TCSR_FRDE | I2S_TCSR_FR;
- NVIC_ENABLE_IRQ(IRQ_DMA_CH0);
- }
-
- void AudioOutputI2Sslave::config_i2s(void)
- {
- SIM_SCGC6 |= SIM_SCGC6_I2S;
- SIM_SCGC7 |= SIM_SCGC7_DMA;
- SIM_SCGC6 |= SIM_SCGC6_DMAMUX;
-
-
- if (I2S0_TCSR & I2S_TCSR_TE) return;
- if (I2S0_RCSR & I2S_RCSR_RE) return;
-
-
-
- I2S0_MCR = I2S_MCR_MICS(0);
- I2S0_MDR = 0;
-
-
- I2S0_TMR = 0;
- I2S0_TCR1 = I2S_TCR1_TFW(1);
- I2S0_TCR2 = I2S_TCR2_SYNC(0) | I2S_TCR2_BCP;
-
- I2S0_TCR3 = I2S_TCR3_TCE;
- I2S0_TCR4 = I2S_TCR4_FRSZ(1) | I2S_TCR4_SYWD(15) | I2S_TCR4_MF
- | I2S_TCR4_FSE | I2S_TCR4_FSP;
-
- I2S0_TCR5 = I2S_TCR5_WNW(15) | I2S_TCR5_W0W(15) | I2S_TCR5_FBT(15);
-
-
- I2S0_RMR = 0;
- I2S0_RCR1 = I2S_RCR1_RFW(1);
- I2S0_RCR2 = I2S_RCR2_SYNC(1) | I2S_TCR2_BCP;
-
- I2S0_RCR3 = I2S_RCR3_RCE;
- I2S0_RCR4 = I2S_RCR4_FRSZ(1) | I2S_RCR4_SYWD(15) | I2S_RCR4_MF
- | I2S_RCR4_FSE | I2S_RCR4_FSP | I2S_RCR4_FSD;
-
- I2S0_RCR5 = I2S_RCR5_WNW(15) | I2S_RCR5_W0W(15) | I2S_RCR5_FBT(15);
-
-
- CORE_PIN23_CONFIG = PORT_PCR_MUX(6);
- CORE_PIN9_CONFIG = PORT_PCR_MUX(6);
- CORE_PIN11_CONFIG = PORT_PCR_MUX(6);
- }
-
-
-
-
- DMAMEM static uint32_t i2s_rx_buffer[AUDIO_BLOCK_SAMPLES];
- audio_block_t * AudioInputI2S::block_left = NULL;
- audio_block_t * AudioInputI2S::block_right = NULL;
- uint16_t AudioInputI2S::block_offset = 0;
- bool AudioInputI2S::update_responsibility = false;
-
-
- void AudioInputI2S::begin(void)
- {
-
-
-
-
-
-
-
-
- AudioOutputI2S::config_i2s();
-
- CORE_PIN13_CONFIG = PORT_PCR_MUX(4);
-
- DMA_CR = 0;
- DMA_TCD1_SADDR = &I2S0_RDR0;
- DMA_TCD1_SOFF = 0;
- DMA_TCD1_ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1);
- DMA_TCD1_NBYTES_MLNO = 2;
- DMA_TCD1_SLAST = 0;
- DMA_TCD1_DADDR = i2s_rx_buffer;
- DMA_TCD1_DOFF = 2;
- DMA_TCD1_CITER_ELINKNO = sizeof(i2s_rx_buffer) / 2;
- DMA_TCD1_DLASTSGA = -sizeof(i2s_rx_buffer);
- DMA_TCD1_BITER_ELINKNO = sizeof(i2s_rx_buffer) / 2;
- DMA_TCD1_CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR;
-
- DMAMUX0_CHCFG1 = DMAMUX_DISABLE;
- DMAMUX0_CHCFG1 = DMAMUX_SOURCE_I2S0_RX | DMAMUX_ENABLE;
- update_responsibility = update_setup();
- DMA_SERQ = 1;
-
-
-
- I2S0_RCSR |= I2S_RCSR_RE | I2S_RCSR_FRDE | I2S_RCSR_FR;
- NVIC_ENABLE_IRQ(IRQ_DMA_CH1);
- }
-
- void dma_ch1_isr(void)
- {
- uint32_t daddr, offset;
- const int16_t *src, *end;
- int16_t *dest_left, *dest_right;
- audio_block_t *left, *right;
-
-
- daddr = (uint32_t)DMA_TCD1_DADDR;
- DMA_CINT = 1;
-
- if (daddr < (uint32_t)i2s_rx_buffer + sizeof(i2s_rx_buffer) / 2) {
-
-
- src = (int16_t *)&i2s_rx_buffer[AUDIO_BLOCK_SAMPLES/2];
- end = (int16_t *)&i2s_rx_buffer[AUDIO_BLOCK_SAMPLES];
- if (AudioInputI2S::update_responsibility) AudioStream::update_all();
- } else {
-
-
- src = (int16_t *)&i2s_rx_buffer[0];
- end = (int16_t *)&i2s_rx_buffer[AUDIO_BLOCK_SAMPLES/2];
- }
- left = AudioInputI2S::block_left;
- right = AudioInputI2S::block_right;
- if (left != NULL && right != NULL) {
- offset = AudioInputI2S::block_offset;
- if (offset <= AUDIO_BLOCK_SAMPLES/2) {
- dest_left = &(left->data[offset]);
- dest_right = &(right->data[offset]);
- AudioInputI2S::block_offset = offset + AUDIO_BLOCK_SAMPLES/2;
- do {
-
-
-
- *dest_left++ = *src++;
- *dest_right++ = *src++;
- } while (src < end);
- }
- }
-
- }
-
-
-
- void AudioInputI2S::update(void)
- {
- audio_block_t *new_left=NULL, *new_right=NULL, *out_left=NULL, *out_right=NULL;
-
-
- new_left = allocate();
- if (new_left != NULL) {
- new_right = allocate();
- if (new_right == NULL) {
- release(new_left);
- new_left = NULL;
- }
- }
- __disable_irq();
- if (block_offset >= AUDIO_BLOCK_SAMPLES) {
-
-
- out_left = block_left;
- block_left = new_left;
- out_right = block_right;
- block_right = new_right;
- block_offset = 0;
- __enable_irq();
-
- transmit(out_left, 0);
- release(out_left);
- transmit(out_right, 1);
- release(out_right);
-
- } else if (new_left != NULL) {
-
- if (block_left == NULL) {
-
-
- block_left = new_left;
- block_right = new_right;
- block_offset = 0;
- __enable_irq();
- } else {
-
- __enable_irq();
- release(new_left);
- release(new_right);
- }
- } else {
-
-
-
- __enable_irq();
- }
- }
-
-
-
-
-
- void AudioInputI2Sslave::begin(void)
- {
-
-
-
-
-
-
-
-
- AudioOutputI2Sslave::config_i2s();
-
- CORE_PIN13_CONFIG = PORT_PCR_MUX(4);
-
- DMA_CR = 0;
- DMA_TCD1_SADDR = &I2S0_RDR0;
- DMA_TCD1_SOFF = 0;
- DMA_TCD1_ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1);
- DMA_TCD1_NBYTES_MLNO = 2;
- DMA_TCD1_SLAST = 0;
- DMA_TCD1_DADDR = i2s_rx_buffer;
- DMA_TCD1_DOFF = 2;
- DMA_TCD1_CITER_ELINKNO = sizeof(i2s_rx_buffer) / 2;
- DMA_TCD1_DLASTSGA = -sizeof(i2s_rx_buffer);
- DMA_TCD1_BITER_ELINKNO = sizeof(i2s_rx_buffer) / 2;
- DMA_TCD1_CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR;
-
- DMAMUX0_CHCFG1 = DMAMUX_DISABLE;
- DMAMUX0_CHCFG1 = DMAMUX_SOURCE_I2S0_RX | DMAMUX_ENABLE;
- update_responsibility = update_setup();
- DMA_SERQ = 1;
-
-
-
- I2S0_RCSR |= I2S_RCSR_RE | I2S_RCSR_FRDE | I2S_RCSR_FR;
- NVIC_ENABLE_IRQ(IRQ_DMA_CH1);
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- DMAMEM static uint16_t analog_rx_buffer[AUDIO_BLOCK_SAMPLES];
- audio_block_t * AudioInputAnalog::block_left = NULL;
- uint16_t AudioInputAnalog::block_offset = 0;
- bool AudioInputAnalog::update_responsibility = false;
-
- #define PDB_CONFIG (PDB_SC_TRGSEL(15) | PDB_SC_PDBEN | PDB_SC_CONT)
- #define PDB_PERIOD 1087
-
- void AudioInputAnalog::begin(unsigned int pin)
- {
- uint32_t i, sum=0;
-
-
-
-
- if (pin > 23 && !(pin >= 34 && pin <= 37)) return;
-
-
-
-
-
-
-
-
-
-
- analogReadRes(16);
- analogReference(INTERNAL);
-
- analogReadAveraging(8);
-
- for (i=0; i < 1024; i++) {
- sum += analogRead(pin);
- }
- dc_average = sum >> 10;
-
-
-
-
-
-
-
- SIM_SCGC6 |= SIM_SCGC6_PDB;
- PDB0_MOD = PDB_PERIOD;
- PDB0_SC = PDB_CONFIG | PDB_SC_LDOK;
- PDB0_SC = PDB_CONFIG | PDB_SC_SWTRIG;
- PDB0_CH0C1 = 0x0101;
-
-
- ADC0_SC2 |= ADC_SC2_ADTRG | ADC_SC2_DMAEN;
-
-
- SIM_SCGC7 |= SIM_SCGC7_DMA;
- SIM_SCGC6 |= SIM_SCGC6_DMAMUX;
- DMA_CR = 0;
- DMA_TCD2_SADDR = &ADC0_RA;
- DMA_TCD2_SOFF = 0;
- DMA_TCD2_ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1);
- DMA_TCD2_NBYTES_MLNO = 2;
- DMA_TCD2_SLAST = 0;
- DMA_TCD2_DADDR = analog_rx_buffer;
- DMA_TCD2_DOFF = 2;
- DMA_TCD2_CITER_ELINKNO = sizeof(analog_rx_buffer) / 2;
- DMA_TCD2_DLASTSGA = -sizeof(analog_rx_buffer);
- DMA_TCD2_BITER_ELINKNO = sizeof(analog_rx_buffer) / 2;
- DMA_TCD2_CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR;
- DMAMUX0_CHCFG2 = DMAMUX_DISABLE;
- DMAMUX0_CHCFG2 = DMAMUX_SOURCE_ADC0 | DMAMUX_ENABLE;
- update_responsibility = update_setup();
- DMA_SERQ = 2;
- NVIC_ENABLE_IRQ(IRQ_DMA_CH2);
- }
-
- void dma_ch2_isr(void)
- {
- uint32_t daddr, offset;
- const uint16_t *src, *end;
- uint16_t *dest_left;
- audio_block_t *left;
-
-
- daddr = (uint32_t)DMA_TCD2_DADDR;
- DMA_CINT = 2;
-
- if (daddr < (uint32_t)analog_rx_buffer + sizeof(analog_rx_buffer) / 2) {
-
-
- src = (uint16_t *)&analog_rx_buffer[AUDIO_BLOCK_SAMPLES/2];
- end = (uint16_t *)&analog_rx_buffer[AUDIO_BLOCK_SAMPLES];
- if (AudioInputAnalog::update_responsibility) AudioStream::update_all();
- } else {
-
-
- src = (uint16_t *)&analog_rx_buffer[0];
- end = (uint16_t *)&analog_rx_buffer[AUDIO_BLOCK_SAMPLES/2];
- }
- left = AudioInputAnalog::block_left;
- if (left != NULL) {
- offset = AudioInputAnalog::block_offset;
- if (offset > AUDIO_BLOCK_SAMPLES/2) offset = AUDIO_BLOCK_SAMPLES/2;
-
- dest_left = (uint16_t *)&(left->data[offset]);
- AudioInputAnalog::block_offset = offset + AUDIO_BLOCK_SAMPLES/2;
- do {
- *dest_left++ = *src++;
- } while (src < end);
-
- }
-
- }
-
-
- #if 0
- void adc0_isr(void)
- {
- uint32_t tmp = ADC0_RA;
- digitalWriteFast(3, HIGH);
- delayMicroseconds(1);
- digitalWriteFast(3, LOW);
- }
- #endif
-
-
- void AudioInputAnalog::update(void)
- {
- audio_block_t *new_left=NULL, *out_left=NULL;
- unsigned int dc, offset;
- int16_t s, *p, *end;
-
-
- new_left = allocate();
-
- __disable_irq();
- offset = block_offset;
- if (offset < AUDIO_BLOCK_SAMPLES) {
-
- if (new_left != NULL) {
-
- if (block_left == NULL) {
-
-
- block_left = new_left;
- block_offset = 0;
- __enable_irq();
-
- } else {
-
- __enable_irq();
- release(new_left);
-
-
- }
- } else {
-
-
-
- __enable_irq();
-
- }
- return;
- }
-
-
- out_left = block_left;
- block_left = new_left;
- block_offset = 0;
- __enable_irq();
-
-
-
- dc = dc_average;
- p = out_left->data;
- end = p + AUDIO_BLOCK_SAMPLES;
- do {
- s = (uint16_t)(*p) - dc;
- *p++ = s;
- dc += s >> 13;
- } while (p < end);
- dc_average = dc;
-
-
- transmit(out_left);
- release(out_left);
- }
-
-
-
-
-
-
-
-
-
-
- #if defined(__MK20DX256__) && defined(DMA_TCD4_SADDR)
-
- DMAMEM static uint16_t dac_buffer[AUDIO_BLOCK_SAMPLES*2];
- audio_block_t * AudioOutputAnalog::block_left_1st = NULL;
- audio_block_t * AudioOutputAnalog::block_left_2nd = NULL;
- bool AudioOutputAnalog::update_responsibility = false;
-
- void AudioOutputAnalog::begin(void)
- {
- SIM_SCGC2 |= SIM_SCGC2_DAC0;
- DAC0_C0 = DAC_C0_DACEN | DAC_C0_DACRFS;
-
- for (int16_t i=0; i<128; i++) {
- analogWrite(A14, i);
- delay(2);
- }
-
-
- SIM_SCGC6 |= SIM_SCGC6_PDB;
- PDB0_IDLY = 1;
- PDB0_MOD = PDB_PERIOD;
- PDB0_SC = PDB_CONFIG | PDB_SC_LDOK;
- PDB0_SC = PDB_CONFIG | PDB_SC_SWTRIG | PDB_SC_PDBIE | PDB_SC_DMAEN;
- SIM_SCGC7 |= SIM_SCGC7_DMA;
- SIM_SCGC6 |= SIM_SCGC6_DMAMUX;
- DMA_CR = 0;
- DMA_TCD4_SADDR = dac_buffer;
- DMA_TCD4_SOFF = 2;
- DMA_TCD4_ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1);
- DMA_TCD4_NBYTES_MLNO = 2;
- DMA_TCD4_SLAST = -sizeof(dac_buffer);
- DMA_TCD4_DADDR = &DAC0_DAT0L;
- DMA_TCD4_DOFF = 0;
- DMA_TCD4_CITER_ELINKNO = sizeof(dac_buffer) / 2;
- DMA_TCD4_DLASTSGA = 0;
- DMA_TCD4_BITER_ELINKNO = sizeof(dac_buffer) / 2;
- DMA_TCD4_CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR;
- DMAMUX0_CHCFG4 = DMAMUX_DISABLE;
- DMAMUX0_CHCFG4 = DMAMUX_SOURCE_PDB | DMAMUX_ENABLE;
- update_responsibility = update_setup();
- DMA_SERQ = 4;
- NVIC_ENABLE_IRQ(IRQ_DMA_CH4);
- }
-
- void AudioOutputAnalog::analogReference(int ref)
- {
-
- if (ref == INTERNAL) {
- DAC0_C0 &= ~DAC_C0_DACRFS;
- } else {
- DAC0_C0 |= DAC_C0_DACRFS;
- }
- }
-
-
- void AudioOutputAnalog::update(void)
- {
- audio_block_t *block;
- block = receiveReadOnly(0);
- if (block) {
- __disable_irq();
- if (block_left_1st == NULL) {
- block_left_1st = block;
- __enable_irq();
- } else if (block_left_2nd == NULL) {
- block_left_2nd = block;
- __enable_irq();
- } else {
- audio_block_t *tmp = block_left_1st;
- block_left_1st = block_left_2nd;
- block_left_2nd = block;
- __enable_irq();
- release(tmp);
- }
- }
- }
-
-
-
-
- void dma_ch4_isr(void)
- {
- const int16_t *src, *end;
- int16_t *dest;
- audio_block_t *block;
- uint32_t saddr, offset;
-
- saddr = (uint32_t)DMA_TCD4_SADDR;
- DMA_CINT = 4;
- if (saddr < (uint32_t)dac_buffer + sizeof(dac_buffer) / 2) {
-
-
- dest = (int16_t *)&dac_buffer[AUDIO_BLOCK_SAMPLES];
- end = (int16_t *)&dac_buffer[AUDIO_BLOCK_SAMPLES*2];
- } else {
-
-
- dest = (int16_t *)dac_buffer;
- end = (int16_t *)&dac_buffer[AUDIO_BLOCK_SAMPLES];
- }
- block = AudioOutputAnalog::block_left_1st;
- if (block) {
- src = &block->data[offset];
- do {
-
- *dest++ = ((*src++) + 32767) >> 4;
- } while (dest < end);
- AudioStream::release(block);
- AudioOutputAnalog::block_left_1st = AudioOutputAnalog::block_left_2nd;
- AudioOutputAnalog::block_left_2nd = NULL;
- } else {
- do {
- *dest++ = 2047;
- } while (dest < end);
- }
- if (AudioOutputAnalog::update_responsibility) AudioStream::update_all();
- }
-
- #else
-
-
- void AudioOutputAnalog::begin(void)
- {
- }
-
- void AudioOutputAnalog::update(void)
- {
- audio_block_t *block;
- block = receiveReadOnly(0);
- if (block) release(block);
- }
-
- #endif
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #define STATE_DIRECT_8BIT_MONO 0
- #define STATE_DIRECT_8BIT_STEREO 1
- #define STATE_DIRECT_16BIT_MONO 2
- #define STATE_DIRECT_16BIT_STEREO 3
- #define STATE_CONVERT_8BIT_MONO 4
- #define STATE_CONVERT_8BIT_STEREO 5
- #define STATE_CONVERT_16BIT_MONO 6
- #define STATE_CONVERT_16BIT_STEREO 7
- #define STATE_PARSE1 8
- #define STATE_PARSE2 9
- #define STATE_PARSE3 10
- #define STATE_PARSE4 11
- #define STATE_STOP 12
-
- void AudioPlaySDcardWAV::begin(void)
- {
- state = STATE_STOP;
- state_play = STATE_STOP;
- data_length = 0;
- if (block_left) {
- release(block_left);
- block_left = NULL;
- }
- if (block_right) {
- release(block_right);
- block_right = NULL;
- }
- }
-
-
- bool AudioPlaySDcardWAV::play(const char *filename)
- {
- stop();
- wavfile = SD.open(filename);
- if (!wavfile) return false;
- buffer_remaining = 0;
- state_play = STATE_STOP;
- data_length = 0;
- state = STATE_PARSE1;
- return true;
- }
-
- void AudioPlaySDcardWAV::stop(void)
- {
- __disable_irq();
- if (state != STATE_STOP) {
- audio_block_t *b1 = block_left;
- block_left = NULL;
- audio_block_t *b2 = block_right;
- block_right = NULL;
- state = STATE_STOP;
- __enable_irq();
- if (b1) release(b1);
- if (b2) release(b2);
- wavfile.close();
- } else {
- __enable_irq();
- }
- }
-
- bool AudioPlaySDcardWAV::start(void)
- {
- __disable_irq();
- if (state == STATE_STOP) {
- if (state_play == STATE_STOP) {
- __enable_irq();
- return false;
- }
- state = state_play;
- }
- __enable_irq();
- return true;
- }
-
-
- void AudioPlaySDcardWAV::update(void)
- {
-
- if (state == STATE_STOP) return;
-
-
- block_left = allocate();
- if (block_left == NULL) return;
- if (state < 8 && (state & 1) == 1) {
-
-
- block_right = allocate();
- if (block_right == NULL) {
- release(block_left);
- return;
- }
- } else {
-
-
- block_right = NULL;
- }
- block_offset = 0;
-
-
-
-
- if (buffer_remaining > 0) {
-
- if (consume()) return;
- }
-
-
- if (state != STATE_STOP && wavfile.available()) {
-
- buffer_remaining = wavfile.read(buffer, 512);
- if (consume()) {
-
- return;
- } else {
-
- buffer_remaining = 0;
- if (block_left) {
- release(block_left);
- block_left = NULL;
- }
- if (block_right) {
- release(block_right);
- block_right = NULL;
- }
-
-
-
-
- if (state != STATE_STOP) return;
- }
- }
-
- wavfile.close();
- if (block_left) {
- release(block_left);
- block_left = NULL;
- }
- if (block_right) {
- release(block_right);
- block_right = NULL;
- }
- state_play = STATE_STOP;
- state = STATE_STOP;
- }
-
-
-
-
-
- bool AudioPlaySDcardWAV::consume(void)
- {
- uint32_t len, size;
- uint8_t lsb, msb;
- const uint8_t *p;
-
- size = buffer_remaining;
- p = buffer + 512 - size;
- start:
- if (size == 0) return false;
-
-
-
-
-
-
- switch (state) {
-
- case STATE_PARSE1:
- len = 20 - data_length;
- if (size < len) len = size;
- memcpy((uint8_t *)header + data_length, p, len);
- data_length += len;
- if (data_length < 20) return false;
-
- if (header[0] == 0x46464952 && header[2] == 0x45564157
- && header[3] == 0x20746D66 && header[4] == 16) {
-
- state = STATE_PARSE2;
- p += len;
- size -= len;
- data_length = 0;
- goto start;
- }
-
- break;
-
-
- case STATE_PARSE2:
- len = 16 - data_length;
- if (size < len) len = size;
- memcpy((uint8_t *)header + data_length, p, len);
- data_length += len;
- if (data_length < 16) return false;
- if (parse_format()) {
-
- p += len;
- size -= len;
- data_length = 0;
- state = STATE_PARSE3;
- goto start;
- }
-
- break;
-
-
- case STATE_PARSE3:
- len = 8 - data_length;
- if (size < len) len = size;
- memcpy((uint8_t *)header + data_length, p, len);
- data_length += len;
- if (data_length < 8) return false;
-
-
-
-
- p += len;
- size -= len;
- data_length = header[1];
- if (header[0] == 0x61746164) {
-
-
-
-
- leftover_bytes = 0;
- state = state_play;
- if (state & 1) {
-
-
- block_right = allocate();
- if (!block_right) return false;
- }
- } else {
- state = STATE_PARSE4;
- }
- goto start;
-
-
- case STATE_PARSE4:
- if (size < data_length) {
- data_length -= size;
- return false;
- }
- p += data_length;
- size -= data_length;
- data_length = 0;
- state = STATE_PARSE3;
- goto start;
-
-
- case STATE_DIRECT_8BIT_MONO:
- return false;
-
-
- case STATE_DIRECT_8BIT_STEREO:
- return false;
-
-
- case STATE_DIRECT_16BIT_MONO:
- if (size > data_length) size = data_length;
- data_length -= size;
- while (1) {
- lsb = *p++;
- msb = *p++;
- size -= 2;
- block_left->data[block_offset++] = (msb << 8) | lsb;
- if (block_offset >= AUDIO_BLOCK_SAMPLES) {
- transmit(block_left, 0);
- transmit(block_left, 1);
-
-
- release(block_left);
- block_left = NULL;
- data_length += size;
- buffer_remaining = size;
- if (block_right) release(block_right);
- return true;
- }
- if (size == 0) {
- if (data_length == 0) break;
- return false;
- }
- }
-
- if (block_offset > 0) {
-
- }
- state = STATE_STOP;
- return false;
-
-
- case STATE_DIRECT_16BIT_STEREO:
- if (size > data_length) size = data_length;
- data_length -= size;
- if (leftover_bytes) {
- block_left->data[block_offset] = header[0];
- goto right16;
- }
- while (1) {
- lsb = *p++;
- msb = *p++;
- size -= 2;
- if (size == 0) {
- if (data_length == 0) break;
- header[0] = (msb << 8) | lsb;
- leftover_bytes = 2;
- return false;
- }
- block_left->data[block_offset] = (msb << 8) | lsb;
- right16:
- lsb = *p++;
- msb = *p++;
- size -= 2;
- block_right->data[block_offset++] = (msb << 8) | lsb;
- if (block_offset >= AUDIO_BLOCK_SAMPLES) {
- transmit(block_left, 0);
- release(block_left);
- block_left = NULL;
- transmit(block_right, 1);
- release(block_right);
- block_right = NULL;
- data_length += size;
- buffer_remaining = size;
- return true;
- }
- if (size == 0) {
- if (data_length == 0) break;
- leftover_bytes = 0;
- return false;
- }
- }
-
- if (block_offset > 0) {
-
- }
- state = STATE_STOP;
- return false;
-
-
- case STATE_CONVERT_8BIT_MONO :
- return false;
-
-
- case STATE_CONVERT_8BIT_STEREO:
- return false;
-
-
- case STATE_CONVERT_16BIT_MONO:
- return false;
-
-
- case STATE_CONVERT_16BIT_STEREO:
- return false;
-
-
-
- case STATE_STOP:
- return false;
-
-
-
-
- }
- state_play = STATE_STOP;
- state = STATE_STOP;
- return false;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- bool AudioPlaySDcardWAV::parse_format(void)
- {
- uint8_t num = 0;
- uint16_t format;
- uint16_t channels;
- uint32_t rate;
- uint16_t bits;
-
- format = header[0];
-
-
- if (format != 1) return false;
-
- channels = header[0] >> 16;
-
-
- if (channels == 1) {
- } else if (channels == 2) {
- num = 1;
- } else {
- return false;
- }
-
- bits = header[3] >> 16;
-
-
- if (bits == 8) {
- } else if (bits == 16) {
- num |= 2;
- } else {
- return false;
- }
-
- rate = header[1];
-
-
- if (rate == AUDIO_SAMPLE_RATE) {
- } else if (rate >= 8000 && rate <= 48000) {
- num |= 4;
- } else {
- return false;
- }
-
-
-
-
- state_play = num;
- return true;
- }
-
-
-
-
-
-
- void AudioPlaySDcardRAW::begin(void)
- {
- playing = false;
- if (block) {
- release(block);
- block = NULL;
- }
- }
-
-
- bool AudioPlaySDcardRAW::play(const char *filename)
- {
- stop();
- rawfile = SD.open(filename);
- if (!rawfile) {
- Serial.println("unable to open file");
- return false;
- }
- Serial.println("able to open file");
- playing = true;
- return true;
- }
-
- void AudioPlaySDcardRAW::stop(void)
- {
- __disable_irq();
- if (playing) {
- playing = false;
- __enable_irq();
- rawfile.close();
- } else {
- __enable_irq();
- }
- }
-
-
- void AudioPlaySDcardRAW::update(void)
- {
- unsigned int i, n;
-
-
- if (!playing) return;
-
-
- block = allocate();
- if (block == NULL) return;
-
- if (rawfile.available()) {
-
- n = rawfile.read(block->data, AUDIO_BLOCK_SAMPLES*2);
- for (i=n/2; i < AUDIO_BLOCK_SAMPLES; i++) {
- block->data[i] = 0;
- }
- transmit(block);
- release(block);
- } else {
- rawfile.close();
- playing = false;
- }
- }
-
-
-
-
-
-
- void AudioPlayMemory::play(const unsigned int *data)
- {
- uint32_t format;
-
- playing = 0;
- prior = 0;
- format = *data++;
- next = data;
- length = format & 0xFFFFFF;
- playing = format >> 24;
- }
-
- void AudioPlayMemory::stop(void)
- {
- playing = 0;
- }
-
- extern "C" {
- extern const int16_t ulaw_decode_table[256];
- };
-
- void AudioPlayMemory::update(void)
- {
- audio_block_t *block;
- const unsigned int *in;
- int16_t *out;
- uint32_t tmp32, consumed;
- int16_t s0, s1, s2, s3, s4;
- int i;
-
- if (!playing) return;
- block = allocate();
- if (block == NULL) return;
-
-
-
- out = block->data;
- in = next;
- s0 = prior;
-
- switch (playing) {
- case 0x01:
- for (i=0; i < AUDIO_BLOCK_SAMPLES; i += 4) {
- tmp32 = *in++;
- *out++ = ulaw_decode_table[(tmp32 >> 0) & 255];
- *out++ = ulaw_decode_table[(tmp32 >> 8) & 255];
- *out++ = ulaw_decode_table[(tmp32 >> 16) & 255];
- *out++ = ulaw_decode_table[(tmp32 >> 24) & 255];
- }
- consumed = 128;
- break;
-
- case 0x81:
- for (i=0; i < AUDIO_BLOCK_SAMPLES; i += 2) {
- tmp32 = *in++;
- *out++ = (int16_t)(tmp32 & 65535);
- *out++ = (int16_t)(tmp32 >> 16);
- }
- consumed = 128;
- break;
-
- case 0x02:
- for (i=0; i < AUDIO_BLOCK_SAMPLES; i += 8) {
- tmp32 = *in++;
- s1 = ulaw_decode_table[(tmp32 >> 0) & 255];
- s2 = ulaw_decode_table[(tmp32 >> 8) & 255];
- s3 = ulaw_decode_table[(tmp32 >> 16) & 255];
- s4 = ulaw_decode_table[(tmp32 >> 24) & 255];
- *out++ = (s0 + s1) >> 1;
- *out++ = s1;
- *out++ = (s1 + s2) >> 1;
- *out++ = s2;
- *out++ = (s2 + s3) >> 1;
- *out++ = s3;
- *out++ = (s3 + s4) >> 1;
- *out++ = s4;
- s0 = s4;
- }
- consumed = 64;
- break;
-
- case 0x82:
- for (i=0; i < AUDIO_BLOCK_SAMPLES; i += 4) {
- tmp32 = *in++;
- s1 = (int16_t)(tmp32 & 65535);
- s2 = (int16_t)(tmp32 >> 16);
- *out++ = (s0 + s1) >> 1;
- *out++ = s1;
- *out++ = (s1 + s2) >> 1;
- *out++ = s2;
- s0 = s2;
- }
- consumed = 64;
- break;
-
- case 0x03:
- for (i=0; i < AUDIO_BLOCK_SAMPLES; i += 16) {
- tmp32 = *in++;
- s1 = ulaw_decode_table[(tmp32 >> 0) & 255];
- s2 = ulaw_decode_table[(tmp32 >> 8) & 255];
- s3 = ulaw_decode_table[(tmp32 >> 16) & 255];
- s4 = ulaw_decode_table[(tmp32 >> 24) & 255];
- *out++ = (s0 * 3 + s1) >> 2;
- *out++ = (s0 + s1) >> 1;
- *out++ = (s0 + s1 * 3) >> 2;
- *out++ = s1;
- *out++ = (s1 * 3 + s2) >> 2;
- *out++ = (s1 + s2) >> 1;
- *out++ = (s1 + s2 * 3) >> 2;
- *out++ = s2;
- *out++ = (s2 * 3 + s3) >> 2;
- *out++ = (s2 + s3) >> 1;
- *out++ = (s2 + s3 * 3) >> 2;
- *out++ = s3;
- *out++ = (s3 * 3 + s4) >> 2;
- *out++ = (s3 + s4) >> 1;
- *out++ = (s3 + s4 * 3) >> 2;
- *out++ = s4;
- s0 = s4;
- }
- consumed = 32;
- break;
-
- case 0x83:
- for (i=0; i < AUDIO_BLOCK_SAMPLES; i += 8) {
- tmp32 = *in++;
- s1 = (int16_t)(tmp32 & 65535);
- s2 = (int16_t)(tmp32 >> 16);
- *out++ = (s0 * 3 + s1) >> 2;
- *out++ = (s0 + s1) >> 1;
- *out++ = (s0 + s1 * 3) >> 2;
- *out++ = s1;
- *out++ = (s1 * 3 + s2) >> 2;
- *out++ = (s1 + s2) >> 1;
- *out++ = (s1 + s2 * 3) >> 2;
- *out++ = s2;
- s0 = s2;
- }
- consumed = 32;
- break;
-
- default:
- release(block);
- playing = 0;
- return;
- }
- prior = s0;
- next = in;
- if (length > consumed) {
- length -= consumed;
- } else {
- playing = 0;
- }
- transmit(block);
- release(block);
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- static inline int32_t signed_multiply_32x16b(int32_t a, uint32_t b) __attribute__((always_inline));
- static inline int32_t signed_multiply_32x16b(int32_t a, uint32_t b)
- {
- int32_t out;
- asm volatile("smulwb %0, %1, %2" : "=r" (out) : "r" (a), "r" (b));
- return out;
- }
-
-
- static inline int32_t signed_multiply_32x16t(int32_t a, uint32_t b) __attribute__((always_inline));
- static inline int32_t signed_multiply_32x16t(int32_t a, uint32_t b)
- {
- int32_t out;
- asm volatile("smulwt %0, %1, %2" : "=r" (out) : "r" (a), "r" (b));
- return out;
- }
-
-
- static inline int32_t multiply_32x32_rshift32(int32_t a, int32_t b) __attribute__((always_inline));
- static inline int32_t multiply_32x32_rshift32(int32_t a, int32_t b)
- {
- int32_t out;
- asm volatile("smmul %0, %1, %2" : "=r" (out) : "r" (a), "r" (b));
- return out;
- }
-
-
- static inline int32_t multiply_32x32_rshift32_rounded(int32_t a, int32_t b) __attribute__((always_inline));
- static inline int32_t multiply_32x32_rshift32_rounded(int32_t a, int32_t b)
- {
- int32_t out;
- asm volatile("smmulr %0, %1, %2" : "=r" (out) : "r" (a), "r" (b));
- return out;
- }
-
-
- static inline int32_t multiply_accumulate_32x32_rshift32_rounded(int32_t sum, int32_t a, int32_t b) __attribute__((always_inline));
- static inline int32_t multiply_accumulate_32x32_rshift32_rounded(int32_t sum, int32_t a, int32_t b)
- {
- int32_t out;
- asm volatile("smmlar %0, %2, %3, %1" : "=r" (out) : "r" (sum), "r" (a), "r" (b));
- return out;
- }
-
-
- static inline int32_t multiply_subtract_32x32_rshift32_rounded(int32_t sum, int32_t a, int32_t b) __attribute__((always_inline));
- static inline int32_t multiply_subtract_32x32_rshift32_rounded(int32_t sum, int32_t a, int32_t b)
- {
- int32_t out;
- asm volatile("smmlsr %0, %2, %3, %1" : "=r" (out) : "r" (sum), "r" (a), "r" (b));
- return out;
- }
-
-
- static inline uint32_t pack_16x16(int32_t a, int32_t b) __attribute__((always_inline));
- static inline uint32_t pack_16x16(int32_t a, int32_t b)
- {
- int32_t out;
- asm volatile("pkhbt %0, %1, %2, lsl #16" : "=r" (out) : "r" (b), "r" (a));
- return out;
- }
-
-
- static inline uint32_t signed_add_16_and_16(uint32_t a, uint32_t b) __attribute__((always_inline));
- static inline uint32_t signed_add_16_and_16(uint32_t a, uint32_t b)
- {
- int32_t out;
- asm volatile("qadd16 %0, %1, %2" : "=r" (out) : "r" (a), "r" (b));
- return out;
- }
-
-
- static inline int32_t signed_multiply_accumulate_32x16b(int32_t sum, int32_t a, uint32_t b)
- {
- int32_t out;
- asm volatile("smlawb %0, %2, %3, %1" : "=r" (out) : "r" (sum), "r" (a), "r" (b));
- return out;
- }
-
-
- static inline int32_t signed_multiply_accumulate_32x16t(int32_t sum, int32_t a, uint32_t b)
- {
- int32_t out;
- asm volatile("smlawt %0, %2, %3, %1" : "=r" (out) : "r" (sum), "r" (a), "r" (b));
- return out;
- }
-
-
- static inline uint32_t logical_and(uint32_t a, uint32_t b)
- {
- asm volatile("and %0, %1" : "+r" (a) : "r" (b));
- return a;
- }
-
-
-
-
- void applyGain(int16_t *data, int32_t mult)
- {
- uint32_t *p = (uint32_t *)data;
- const uint32_t *end = (uint32_t *)(data + AUDIO_BLOCK_SAMPLES);
-
- do {
- uint32_t tmp32 = *p;
- int32_t val1 = signed_multiply_32x16b(mult, tmp32);
- int32_t val2 = signed_multiply_32x16t(mult, tmp32);
- val1 = signed_saturate_rshift(val1, 16, 0);
- val2 = signed_saturate_rshift(val2, 16, 0);
- *p++ = pack_16x16(val2, val1);
- } while (p < end);
- }
-
-
-
- void applyGainThenAdd(int16_t *data, const int16_t *in, int32_t mult)
- {
- uint32_t *dst = (uint32_t *)data;
- const uint32_t *src = (uint32_t *)in;
- const uint32_t *end = (uint32_t *)(data + AUDIO_BLOCK_SAMPLES);
-
- if (mult == 65536) {
- do {
- uint32_t tmp32 = *dst;
- *dst++ = signed_add_16_and_16(tmp32, *src++);
- tmp32 = *dst;
- *dst++ = signed_add_16_and_16(tmp32, *src++);
- } while (dst < end);
- } else {
- do {
- uint32_t tmp32 = *src++;
- int32_t val1 = signed_multiply_32x16b(mult, tmp32);
- int32_t val2 = signed_multiply_32x16t(mult, tmp32);
- val1 = signed_saturate_rshift(val1, 16, 0);
- val2 = signed_saturate_rshift(val2, 16, 0);
- tmp32 = pack_16x16(val2, val1);
- uint32_t tmp32b = *dst;
- *dst++ = signed_add_16_and_16(tmp32, tmp32b);
- } while (dst < end);
- }
- }
-
-
- void AudioMixer4::update(void)
- {
- audio_block_t *in, *out=NULL;
- unsigned int channel;
-
- for (channel=0; channel < 4; channel++) {
- if (!out) {
- out = receiveWritable(channel);
- if (out) {
- int32_t mult = multiplier[channel];
- if (mult != 65536) applyGain(out->data, mult);
- }
- } else {
- in = receiveReadOnly(channel);
- if (in) {
- applyGainThenAdd(out->data, in->data, multiplier[channel]);
- release(in);
- }
- }
- }
- if (out) {
- transmit(out);
- release(out);
- }
- }
-
-
-
-
-
-
-
-
- void AudioFilterBiquad::update(void)
- {
- audio_block_t *block;
- int32_t a0, a1, a2, b1, b2, sum;
- uint32_t in2, out2, aprev, bprev, flag;
- uint32_t *data, *end;
- int32_t *state;
-
- block = receiveWritable();
- if (!block) return;
- data = (uint32_t *)(block->data);
- end = data + AUDIO_BLOCK_SAMPLES/2;
- state = (int32_t *)definition;
- do {
- a0 = *state++;
- a1 = *state++;
- a2 = *state++;
- b1 = *state++;
- b2 = *state++;
- aprev = *state++;
- bprev = *state++;
- sum = *state & 0x3FFF;
- do {
- in2 = *data;
- sum = signed_multiply_accumulate_32x16b(sum, a0, in2);
- sum = signed_multiply_accumulate_32x16t(sum, a1, aprev);
- sum = signed_multiply_accumulate_32x16b(sum, a2, aprev);
- sum = signed_multiply_accumulate_32x16t(sum, b1, bprev);
- sum = signed_multiply_accumulate_32x16b(sum, b2, bprev);
- out2 = (uint32_t)sum >> 14;
- sum &= 0x3FFF;
- sum = signed_multiply_accumulate_32x16t(sum, a0, in2);
- sum = signed_multiply_accumulate_32x16b(sum, a1, in2);
- sum = signed_multiply_accumulate_32x16t(sum, a2, aprev);
- sum = signed_multiply_accumulate_32x16b(sum, b1, out2);
- sum = signed_multiply_accumulate_32x16t(sum, b2, bprev);
- aprev = in2;
- bprev = pack_16x16(sum >> 14, out2);
- sum &= 0x3FFF;
- aprev = in2;
- *data++ = bprev;
- } while (data < end);
- flag = *state & 0x80000000;
- *state++ = sum | flag;
- *(state-2) = bprev;
- *(state-3) = aprev;
- } while (flag);
- transmit(block);
- release(block);
- }
-
-
-
-
-
-
- extern "C" {
- extern const int16_t fader_table[256];
- };
-
-
- void AudioEffectFade::update(void)
- {
- audio_block_t *block;
- uint32_t i, pos, inc, index, scale;
- int32_t val1, val2, val, sample;
- uint8_t dir;
-
- pos = position;
- if (pos == 0) {
-
- block = receiveReadOnly();
- if (block) release(block);
- return;
- } else if (pos == 0xFFFFFFFF) {
-
- block = receiveReadOnly();
- if (!block) return;
- transmit(block);
- release(block);
- return;
- }
- block = receiveWritable();
- if (!block) return;
- inc = rate;
- dir = direction;
- for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
- index = pos >> 24;
- val1 = fader_table[index];
- val2 = fader_table[index+1];
- scale = (pos >> 8) & 0xFFFF;
- val2 *= scale;
- val1 *= 0x10000 - scale;
- val = (val1 + val2) >> 16;
- sample = block->data[i];
- sample = (sample * val) >> 15;
- block->data[i] = sample;
- if (dir > 0) {
-
- if (inc < 0xFFFFFFFF - pos) pos += inc;
- else pos = 0xFFFFFFFF;
- } else {
-
- if (inc < pos) pos -= inc;
- else pos = 0;
- }
- }
- position = pos;
- transmit(block);
- release(block);
- }
-
- void AudioEffectFade::fadeBegin(uint32_t newrate, uint8_t dir)
- {
- __disable_irq();
- uint32_t pos = position;
- if (pos == 0) position = 1;
- else if (pos == 0xFFFFFFFF) position = 0xFFFFFFFE;
- rate = newrate;
- direction = dir;
- __enable_irq();
- }
-
-
-
-
-
-
- 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)
- {
- return ((int64_t)a * (int64_t)b) >> 30;
- }
-
-
-
- void AudioAnalyzeToneDetect::update(void)
- {
- audio_block_t *block;
- int32_t q0, q1, q2, coef;
- const int16_t *p, *end;
- uint16_t n;
-
- block = receiveReadOnly();
- if (!block) return;
- if (!enabled) {
- release(block);
- return;
- }
- p = block->data;
- end = p + AUDIO_BLOCK_SAMPLES;
- n = count;
- coef = coefficient;
- q1 = s1;
- q2 = s2;
- do {
-
- #ifdef TONE_DETECT_FAST
- q0 = (*p++) + (multiply_32x32_rshift32_rounded(coef, q1) << 2) - q2;
- #else
- q0 = (*p++) + multiply_32x32_rshift30(coef, q1) - q2;
-
- #endif
- q2 = q1;
- q1 = q0;
- if (--n == 0) {
- out1 = q1;
- out2 = q2;
- q1 = 0;
- q2 = 0;
- new_output = true;
- n = length;
- }
- } while (p < end);
- count = n;
- s1 = q1;
- s2 = q2;
- release(block);
- }
-
- void AudioAnalyzeToneDetect::set_params(int32_t coef, uint16_t cycles, uint16_t len)
- {
- __disable_irq();
- coefficient = coef;
- ncycles = cycles;
- length = len;
- count = len;
- s1 = 0;
- s2 = 0;
- enabled = true;
- __enable_irq();
-
- }
-
- float AudioAnalyzeToneDetect::read(void)
- {
- int32_t coef, q1, q2, power;
- uint16_t len;
-
- __disable_irq();
- coef = coefficient;
- q1 = out1;
- q2 = out2;
- len = length;
- __enable_irq();
- #ifdef TONE_DETECT_FAST
- power = multiply_32x32_rshift32_rounded(q2, q2);
- power = multiply_accumulate_32x32_rshift32_rounded(power, q1, q1);
- power = multiply_subtract_32x32_rshift32_rounded(power,
- multiply_32x32_rshift30(q1, q2), coef);
- power <<= 4;
- #else
- int64_t power64;
- power64 = (int64_t)q2 * (int64_t)q2;
- power64 += (int64_t)q1 * (int64_t)q1;
- power64 -= (((int64_t)q1 * (int64_t)q2) >> 30) * (int64_t)coef;
- power = power64 >> 28;
- #endif
- return sqrtf((float)power) / (float)len;
- }
-
-
- AudioAnalyzeToneDetect::operator bool()
- {
- int32_t coef, q1, q2, power, trigger;
- uint16_t len;
-
- __disable_irq();
- coef = coefficient;
- q1 = out1;
- q2 = out2;
- len = length;
- __enable_irq();
- #ifdef TONE_DETECT_FAST
- power = multiply_32x32_rshift32_rounded(q2, q2);
- power = multiply_accumulate_32x32_rshift32_rounded(power, q1, q1);
- power = multiply_subtract_32x32_rshift32_rounded(power,
- multiply_32x32_rshift30(q1, q2), coef);
- power <<= 4;
- #else
- int64_t power64;
- power64 = (int64_t)q2 * (int64_t)q2;
- power64 += (int64_t)q1 * (int64_t)q1;
- power64 -= (((int64_t)q1 * (int64_t)q2) >> 30) * (int64_t)coef;
- power = power64 >> 28;
- #endif
- trigger = (uint32_t)len * thresh;
- trigger = multiply_32x32_rshift32(trigger, trigger);
-
- Serial.printf("bool: power=%d, trig=%d\n", power, trigger);
- return (power >= trigger);
- }
-
-
-
-
-
-
- #include "Wire.h"
-
- #define WM8731_I2C_ADDR 0x1A
-
-
- #define WM8731_REG_LLINEIN 0
- #define WM8731_REG_RLINEIN 1
- #define WM8731_REG_LHEADOUT 2
- #define WM8731_REG_RHEADOUT 3
- #define WM8731_REG_ANALOG 4
- #define WM8731_REG_DIGITAL 5
- #define WM8731_REG_POWERDOWN 6
- #define WM8731_REG_INTERFACE 7
- #define WM8731_REG_SAMPLING 8
- #define WM8731_REG_ACTIVE 9
- #define WM8731_REG_RESET 15
-
- bool AudioControlWM8731::enable(void)
- {
- Wire.begin();
- delay(5);
-
-
- write(WM8731_REG_INTERFACE, 0x02);
- write(WM8731_REG_SAMPLING, 0x20);
-
-
-
-
-
- write(WM8731_REG_DIGITAL, 0x08);
- write(WM8731_REG_ANALOG, 0x00);
-
- write(WM8731_REG_POWERDOWN, 0x00);
-
- write(WM8731_REG_LHEADOUT, 0x80);
- write(WM8731_REG_RHEADOUT, 0x80);
-
- delay(100);
-
- write(WM8731_REG_ACTIVE, 1);
- delay(5);
- write(WM8731_REG_DIGITAL, 0x00);
- write(WM8731_REG_ANALOG, 0x10);
-
- return true;
- }
-
-
- bool AudioControlWM8731::write(unsigned int reg, unsigned int val)
- {
- Wire.beginTransmission(WM8731_I2C_ADDR);
- Wire.write((reg << 1) | ((val >> 8) & 1));
- Wire.write(val & 0xFF);
- Wire.endTransmission();
- return true;
- }
-
- bool AudioControlWM8731::volumeInteger(unsigned int n)
- {
- if (n > 127) n = 127;
-
-
- write(WM8731_REG_LHEADOUT, n | 0x180);
- write(WM8731_REG_RHEADOUT, n | 0x80);
- return true;
- }
-
-
-
-
-
-
- bool AudioControlWM8731master::enable(void)
- {
- Wire.begin();
- delay(5);
-
-
- write(WM8731_REG_INTERFACE, 0x42);
- write(WM8731_REG_SAMPLING, 0x20);
-
-
-
-
-
- write(WM8731_REG_DIGITAL, 0x08);
- write(WM8731_REG_ANALOG, 0x00);
-
- write(WM8731_REG_POWERDOWN, 0x00);
-
- write(WM8731_REG_LHEADOUT, 0x80);
- write(WM8731_REG_RHEADOUT, 0x80);
-
- delay(100);
-
- write(WM8731_REG_ACTIVE, 1);
- delay(5);
- write(WM8731_REG_DIGITAL, 0x00);
- write(WM8731_REG_ANALOG, 0x10);
-
- return true;
- }
-
-
-
- #define CHIP_ID 0x0000
-
-
-
- #define CHIP_DIG_POWER 0x0002
-
-
-
-
-
-
- #define CHIP_CLK_CTRL 0x0004
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #define CHIP_I2S_CTRL 0x0006
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #define CHIP_SSS_CTRL 0x000A
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #define CHIP_ADCDAC_CTRL 0x000E
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #define CHIP_DAC_VOL 0x0010
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #define CHIP_PAD_STRENGTH 0x0014
-
-
-
-
-
-
-
-
-
-
-
-
-
- #define CHIP_ANA_ADC_CTRL 0x0020
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #define CHIP_ANA_HP_CTRL 0x0022
-
-
-
-
-
-
-
-
-
-
- #define CHIP_ANA_CTRL 0x0024
-
-
-
-
-
-
-
-
-
-
-
-
- #define CHIP_LINREG_CTRL 0x0026
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #define CHIP_REF_CTRL 0x0028
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #define CHIP_MIC_CTRL 0x002A
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #define CHIP_LINE_OUT_CTRL 0x002C
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #define CHIP_LINE_OUT_VOL 0x002E
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #define CHIP_ANA_POWER 0x0030
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #define CHIP_PLL_CTRL 0x0032
-
-
-
- #define CHIP_CLK_TOP_CTRL 0x0034
-
-
-
-
-
-
-
-
-
-
-
-
- #define CHIP_ANA_STATUS 0x0036
-
-
-
-
-
-
- #define CHIP_ANA_TEST1 0x0038
- #define CHIP_ANA_TEST2 0x003A
-
- #define CHIP_SHORT_CTRL 0x003C
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #define DAP_CONTROL 0x0100
- #define DAP_PEQ 0x0102
- #define DAP_BASS_ENHANCE 0x0104
- #define DAP_BASS_ENHANCE_CTRL 0x0106
- #define DAP_AUDIO_EQ 0x0108
- #define DAP_SGTL_SURROUND 0x010A
- #define DAP_FILTER_COEF_ACCES 0x010C
- #define DAP_COEF_WR_B0_MSB 0x010E
- #define DAP_COEF_WR_B0_LSB 0x0110
- #define DAP_AUDIO_EQ_BASS_BAND0 0x0116
- #define DAP_AUDIO_EQ_BAND1 0x0118
- #define DAP_AUDIO_EQ_BAND2 0x011A
- #define DAP_AUDIO_EQ_BAND3 0x011C
- #define DAP_AUDIO_EQ_TREBLE_BAND4 0x011E
- #define DAP_MAIN_CHAN 0x0120
- #define DAP_MIX_CHAN 0x0122
- #define DAP_AVC_CTRL 0x0124
- #define DAP_AVC_THRESHOLD 0x0126
- #define DAP_AVC_ATTACK 0x0128
- #define DAP_AVC_DECAY 0x012A
- #define DAP_COEF_WR_B1_MSB 0x012C
- #define DAP_COEF_WR_B1_LSB 0x012E
- #define DAP_COEF_WR_B2_MSB 0x0130
- #define DAP_COEF_WR_B2_LSB 0x0132
- #define DAP_COEF_WR_A1_MSB 0x0134
- #define DAP_COEF_WR_A1_LSB 0x0136
- #define DAP_COEF_WR_A2_MSB 0x0138
- #define DAP_COEF_WR_A2_LSB 0x013A
-
- #define SGTL5000_I2C_ADDR 0x0A
-
-
-
-
- bool AudioControlSGTL5000::enable(void)
- {
-
-
- muted = true;
- Wire.begin();
- delay(5);
-
-
-
-
-
- write(CHIP_ANA_POWER, 0x4060);
- write(CHIP_LINREG_CTRL, 0x006C);
- write(CHIP_REF_CTRL, 0x01F1);
- write(CHIP_LINE_OUT_CTRL, 0x0322);
- write(CHIP_SHORT_CTRL, 0x4446);
- write(CHIP_ANA_CTRL, 0x0137);
- write(CHIP_ANA_POWER, 0x40FF);
- write(CHIP_DIG_POWER, 0x0073);
- delay(400);
- write(CHIP_LINE_OUT_VOL, 0x0505);
- write(CHIP_CLK_CTRL, 0x0004);
- write(CHIP_I2S_CTRL, 0x0130);
-
- write(CHIP_SSS_CTRL, 0x0010);
- write(CHIP_ADCDAC_CTRL, 0x0000);
- write(CHIP_DAC_VOL, 0x3C3C);
- write(CHIP_ANA_HP_CTRL, 0x7F7F);
- write(CHIP_ANA_CTRL, 0x0136);
-
- return true;
- }
-
- unsigned int AudioControlSGTL5000::read(unsigned int reg)
- {
- unsigned int val;
-
- Wire.beginTransmission(SGTL5000_I2C_ADDR);
- Wire.write(reg >> 8);
- Wire.write(reg);
- if (Wire.endTransmission(false) != 0) return 0;
- if (Wire.requestFrom(SGTL5000_I2C_ADDR, 2) < 2) return 0;
- val = Wire.read() << 8;
- val |= Wire.read();
- return val;
- }
-
- bool AudioControlSGTL5000::write(unsigned int reg, unsigned int val)
- {
- if (reg == CHIP_ANA_CTRL) ana_ctrl = val;
- Wire.beginTransmission(SGTL5000_I2C_ADDR);
- Wire.write(reg >> 8);
- Wire.write(reg);
- Wire.write(val >> 8);
- Wire.write(val);
- if (Wire.endTransmission() == 0) return true;
- return false;
- }
-
- bool AudioControlSGTL5000::volumeInteger(unsigned int n)
- {
- if (n == 0) {
- muted = true;
- write(CHIP_ANA_HP_CTRL, 0x7F7F);
- return muteHeadphone();
- } else if (n > 0x80) {
- n = 0;
- } else {
- n = 0x80 - n;
- }
- if (muted) {
- muted = false;
- unmuteHeadphone();
- }
- n = n | (n << 8);
- return write(CHIP_ANA_HP_CTRL, n);
- }
-
-
-
-
-
-
-
-
-
- q15_t AudioFilterFIR::l_StateQ15[AUDIO_BLOCK_SAMPLES + MAX_COEFFS];
- q15_t AudioFilterFIR::r_StateQ15[AUDIO_BLOCK_SAMPLES + MAX_COEFFS];
- arm_fir_instance_q15 AudioFilterFIR::l_fir_inst;
- arm_fir_instance_q15 AudioFilterFIR::r_fir_inst;
-
-
- short * AudioFilterFIR::coeff_p = NULL;
-
- void AudioFilterFIR::begin(short *cp,int n_coeffs)
- {
-
- coeff_p = cp;
-
- if(coeff_p && (coeff_p != FIR_PASSTHRU)) {
- arm_fir_init_q15(&l_fir_inst, n_coeffs, coeff_p, &l_StateQ15[0], AUDIO_BLOCK_SAMPLES);
- arm_fir_init_q15(&r_fir_inst, n_coeffs, coeff_p, &r_StateQ15[0], AUDIO_BLOCK_SAMPLES);
- }
- }
-
-
- void AudioFilterFIR::stop(void)
- {
- coeff_p = NULL;
- }
-
-
- void AudioFilterFIR::update(void)
- {
- audio_block_t *block,*b_new;
-
-
- if(coeff_p == NULL)return;
-
-
- if(coeff_p == FIR_PASSTHRU) {
-
- block = receiveWritable(0);
- if(block) {
- transmit(block,0);
- release(block);
- }
- block = receiveWritable(1);
- if(block) {
- transmit(block,1);
- release(block);
- }
- return;
- }
-
- block = receiveWritable(0);
-
- b_new = allocate();
- if(block && b_new) {
- arm_fir_q15(&l_fir_inst, (q15_t *)block->data, (q15_t *)b_new->data, AUDIO_BLOCK_SAMPLES);
-
- transmit(b_new,0);
- }
- if(block)release(block);
- if(b_new)release(b_new);
-
-
- block = receiveWritable(1);
- b_new = allocate();
- if(block && b_new) {
- arm_fir_q15(&r_fir_inst, (q15_t *)block->data, (q15_t *)b_new->data, AUDIO_BLOCK_SAMPLES);
- transmit(b_new,1);
- }
- if(block)release(block);
- if(b_new)release(b_new);
- }
-
-
-
-
-
-
-
- short AudioEffectFlange::l_circ_idx;
- short AudioEffectFlange::r_circ_idx;
-
- short * AudioEffectFlange::l_delayline = NULL;
- short * AudioEffectFlange::r_delayline = NULL;
-
-
-
- int AudioEffectFlange::delay_offset_idx = DELAY_PASSTHRU;
- int AudioEffectFlange::delay_length;
-
- int AudioEffectFlange::delay_depth;
- int AudioEffectFlange::delay_rate_incr;
- unsigned int AudioEffectFlange::l_delay_rate_index;
- unsigned int AudioEffectFlange::r_delay_rate_index;
-
-
-
-
-
-
-
- boolean AudioEffectFlange::begin(short *delayline,int d_length,int delay_offset,int d_depth,float delay_rate)
- {
- boolean all_ok = true;
-
- if(0) {
- Serial.print("AudioEffectFlange.begin(offset = ");
- Serial.print(delay_offset);
- Serial.print(", depth = ");
- Serial.print(d_depth);
- Serial.print(", rate = ");
- Serial.print(delay_rate,3);
- Serial.println(")");
- Serial.print(" FLANGE_DELAY_LENGTH = ");
- Serial.println(d_length);
- }
-
- delay_length = d_length/2;
- l_delayline = delayline;
- r_delayline = delayline + delay_length;
-
- delay_depth = d_depth;
-
- l_delay_rate_index = 0;
- r_delay_rate_index = 0;
- l_circ_idx = 0;
- r_circ_idx = 0;
- delay_rate_incr = 2*PI*delay_rate/44100.*2147483648.;
-
-
- delay_offset_idx = delay_offset;
-
- if(delay_offset_idx < -1) {
- delay_offset_idx = 0;
- all_ok = false;
- }
- if(delay_offset_idx >= delay_length) {
- delay_offset_idx = delay_length - 1;
- all_ok = false;
- }
- return(all_ok);
- }
-
-
- boolean AudioEffectFlange::modify(int delay_offset,int d_depth,float delay_rate)
- {
- boolean all_ok = true;
-
- delay_depth = d_depth;
-
- delay_rate_incr = 2*PI*delay_rate/44100.*2147483648.;
-
- delay_offset_idx = delay_offset;
-
- if(delay_offset_idx < -1) {
- delay_offset_idx = 0;
- all_ok = false;
- }
- if(delay_offset_idx >= delay_length) {
- delay_offset_idx = delay_length - 1;
- all_ok = false;
- }
- l_delay_rate_index = 0;
- r_delay_rate_index = 0;
- l_circ_idx = 0;
- r_circ_idx = 0;
- return(all_ok);
- }
-
- void AudioEffectFlange::update(void)
- {
- audio_block_t *block;
- int idx;
- short *bp;
- short frac;
- int idx1;
-
- if(l_delayline == NULL)return;
- if(r_delayline == NULL)return;
-
-
- if(delay_offset_idx == DELAY_PASSTHRU) {
-
- block = receiveWritable(0);
- if(block) {
- bp = block->data;
- for(int i = 0;i < AUDIO_BLOCK_SAMPLES;i++) {
- l_circ_idx++;
- if(l_circ_idx >= delay_length) {
- l_circ_idx = 0;
- }
- l_delayline[l_circ_idx] = *bp++;
- }
- transmit(block,0);
- release(block);
- }
- block = receiveWritable(1);
- if(block) {
- bp = block->data;
- for(int i = 0;i < AUDIO_BLOCK_SAMPLES;i++) {
- r_circ_idx++;
- if(r_circ_idx >= delay_length) {
- r_circ_idx = 0;
- }
- r_delayline[r_circ_idx] = *bp++;
- }
- transmit(block,1);
- release(block);
- }
- return;
- }
-
-
-
- block = receiveWritable(0);
- if(block) {
- bp = block->data;
- for(int i = 0;i < AUDIO_BLOCK_SAMPLES;i++) {
- l_circ_idx++;
- if(l_circ_idx >= delay_length) {
- l_circ_idx = 0;
- }
- l_delayline[l_circ_idx] = *bp;
- idx = arm_sin_q15( (q15_t)((l_delay_rate_index >> 16) & 0x7fff));
- idx = (idx * delay_depth) >> 15;
-
- idx = l_circ_idx - (delay_offset_idx + idx);
- if(idx < 0) {
- idx += delay_length;
- }
- if(idx >= delay_length) {
- idx -= delay_length;
- }
-
- if(frac < 0)
- idx1 = idx - 1;
- else
- idx1 = idx + 1;
- if(idx1 < 0) {
- idx1 += delay_length;
- }
- if(idx1 >= delay_length) {
- idx1 -= delay_length;
- }
- frac = (l_delay_rate_index >> 1) &0x7fff;
- frac = (( (int)(l_delayline[idx1] - l_delayline[idx])*frac) >> 15);
-
-
- *bp++ = (l_delayline[l_circ_idx]
- + l_delayline[idx] + frac
-
- )/2;
-
- l_delay_rate_index += delay_rate_incr;
- if(l_delay_rate_index & 0x80000000) {
- l_delay_rate_index &= 0x7fffffff;
- }
- }
-
- transmit(block,0);
- release(block);
- }
-
-
-
- block = receiveWritable(1);
- if(block) {
- bp = block->data;
- for(int i = 0;i < AUDIO_BLOCK_SAMPLES;i++) {
- r_circ_idx++;
- if(r_circ_idx >= delay_length) {
- r_circ_idx = 0;
- }
- r_delayline[r_circ_idx] = *bp;
- idx = arm_sin_q15( (q15_t)((r_delay_rate_index >> 16)&0x7fff));
- idx = (idx * delay_depth) >> 15;
-
- idx = r_circ_idx - (delay_offset_idx + idx);
- if(idx < 0) {
- idx += delay_length;
- }
- if(idx >= delay_length) {
- idx -= delay_length;
- }
-
- if(frac < 0)
- idx1 = idx - 1;
- else
- idx1 = idx + 1;
- if(idx1 < 0) {
- idx1 += delay_length;
- }
- if(idx1 >= delay_length) {
- idx1 -= delay_length;
- }
- frac = (r_delay_rate_index >> 1) &0x7fff;
- frac = (( (int)(r_delayline[idx1] - r_delayline[idx])*frac) >> 15);
-
-
-
- *bp++ = (r_delayline[r_circ_idx]
- + r_delayline[idx] + frac
- )/2;
-
- r_delay_rate_index += delay_rate_incr;
- if(r_delay_rate_index & 0x80000000) {
- r_delay_rate_index &= 0x7fffffff;
- }
-
- }
-
- transmit(block,1);
- release(block);
- }
- }
-
-
-
-
-
-
-
-
-
- short AudioEffectChorus::l_circ_idx;
- short AudioEffectChorus::r_circ_idx;
-
- short * AudioEffectChorus::l_delayline = NULL;
- short * AudioEffectChorus::r_delayline = NULL;
- int AudioEffectChorus::delay_length;
-
- int AudioEffectChorus::num_chorus = 0;
-
-
-
- boolean AudioEffectChorus::begin(short *delayline,int d_length,int n_chorus)
- {
- Serial.print("AudioEffectChorus.begin(Chorus delay line length = ");
- Serial.print(d_length);
- Serial.print(", n_chorus = ");
- Serial.print(n_chorus);
- Serial.println(")");
-
- l_delayline = NULL;
- r_delayline = NULL;
- delay_length = 0;
- l_circ_idx = 0;
- r_circ_idx = 0;
-
- if(delayline == NULL) {
- return(false);
- }
- if(d_length < 10) {
- return(false);
- }
- if(n_chorus < 1) {
- return(false);
- }
-
- l_delayline = delayline;
- r_delayline = delayline + d_length/2;
- delay_length = d_length/2;
- num_chorus = n_chorus;
-
- return(true);
- }
-
-
- void AudioEffectChorus::stop(void)
- {
-
- }
-
- void AudioEffectChorus::modify(int n_chorus)
- {
- num_chorus = n_chorus;
- }
-
- int iabs(int x)
- {
- if(x < 0)return(-x);
- return(x);
- }
-
-
- int last_idx = 0;
- void AudioEffectChorus::update(void)
- {
- audio_block_t *block;
- short *bp;
- int sum;
- int c_idx;
-
- if(l_delayline == NULL)return;
- if(r_delayline == NULL)return;
-
-
-
-
- if(num_chorus < 1) {
-
- block = receiveWritable(0);
- if(block) {
- bp = block->data;
- for(int i = 0;i < AUDIO_BLOCK_SAMPLES;i++) {
- l_circ_idx++;
- if(l_circ_idx >= delay_length) {
- l_circ_idx = 0;
- }
- l_delayline[l_circ_idx] = *bp++;
- }
- transmit(block,0);
- release(block);
- }
- block = receiveWritable(1);
- if(block) {
- bp = block->data;
- for(int i = 0;i < AUDIO_BLOCK_SAMPLES;i++) {
- r_circ_idx++;
- if(r_circ_idx >= delay_length) {
- r_circ_idx = 0;
- }
- r_delayline[r_circ_idx] = *bp++;
- }
- transmit(block,1);
- release(block);
- }
- return;
- }
-
-
-
- block = receiveWritable(0);
- if(block) {
- bp = block->data;
- for(int i = 0;i < AUDIO_BLOCK_SAMPLES;i++) {
- l_circ_idx++;
- if(l_circ_idx >= delay_length) {
- l_circ_idx = 0;
- }
- l_delayline[l_circ_idx] = *bp;
- sum = 0;
- c_idx = l_circ_idx;
- for(int k = 0; k < num_chorus; k++) {
- sum += l_delayline[c_idx];
- if(num_chorus > 1)c_idx -= delay_length/(num_chorus - 1) - 1;
- if(c_idx < 0) {
- c_idx += delay_length;
- }
- }
- *bp++ = sum/num_chorus;
- }
-
-
- transmit(block,0);
- release(block);
- }
-
-
-
- block = receiveWritable(1);
- if(block) {
- bp = block->data;
- for(int i = 0;i < AUDIO_BLOCK_SAMPLES;i++) {
- r_circ_idx++;
- if(r_circ_idx >= delay_length) {
- r_circ_idx = 0;
- }
- r_delayline[r_circ_idx] = *bp;
- sum = 0;
- c_idx = r_circ_idx;
- for(int k = 0; k < num_chorus; k++) {
- sum += r_delayline[c_idx];
- if(num_chorus > 1)c_idx -= delay_length/(num_chorus - 1) - 1;
- if(c_idx < 0) {
- c_idx += delay_length;
- }
- }
- *bp++ = sum/num_chorus;
- }
-
-
- transmit(block,1);
- release(block);
- }
- }
|