Browse Source

Merge remote-tracking branch 'upstream/master'

dds
awalch6679 4 years ago
parent
commit
0ef86b456c
18 changed files with 288 additions and 40 deletions
  1. +1
    -1
      control_sgtl5000.cpp
  2. +39
    -0
      examples/HardwareTesting/PassThroughADCtoI2S/PassThroughADCtoI2S.ino
  3. +1
    -1
      gui/index.html
  4. +227
    -16
      input_adc.cpp
  5. +0
    -1
      input_adc.h
  6. +2
    -2
      input_adcs.cpp
  7. +2
    -4
      input_i2s.cpp
  8. +4
    -4
      input_i2s2.cpp
  9. +1
    -1
      input_i2s_hex.cpp
  10. +1
    -1
      input_i2s_quad.cpp
  11. +1
    -1
      input_pdm.cpp
  12. +1
    -1
      output_adat.cpp
  13. +1
    -1
      output_dac.cpp
  14. +1
    -1
      output_dacs.cpp
  15. +1
    -0
      output_i2s.cpp
  16. +2
    -2
      output_pt8211.cpp
  17. +2
    -2
      output_pt8211_2.cpp
  18. +1
    -1
      output_pwm.cpp

+ 1
- 1
control_sgtl5000.cpp View File

delay(400); delay(400);
write(CHIP_LINE_OUT_VOL, 0x1D1D); // default approx 1.3 volts peak-to-peak write(CHIP_LINE_OUT_VOL, 0x1D1D); // default approx 1.3 volts peak-to-peak
write(CHIP_CLK_CTRL, 0x0004); // 44.1 kHz, 256*Fs write(CHIP_CLK_CTRL, 0x0004); // 44.1 kHz, 256*Fs
write(CHIP_I2S_CTRL, 0x0130); // SCLK=32*Fs, 16bit, I2S format
write(CHIP_I2S_CTRL, 0x0030); // SCLK=64*Fs, 16bit, I2S format
// default signal routing is ok? // default signal routing is ok?
write(CHIP_SSS_CTRL, 0x0010); // ADC->I2S, I2S->DAC write(CHIP_SSS_CTRL, 0x0010); // ADC->I2S, I2S->DAC
write(CHIP_ADCDAC_CTRL, 0x0000); // disable dac mute write(CHIP_ADCDAC_CTRL, 0x0000); // disable dac mute

+ 39
- 0
examples/HardwareTesting/PassThroughADCtoI2S/PassThroughADCtoI2S.ino View File

/*
* A simple hardware test which receives audio on the A2 analog pin
* and sends it to the audio shield (I2S digital audio)
*
* This example code is in the public domain.
*/

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioInputAnalog adc1; //xy=197,73
AudioOutputI2S i2s1; //xy=375,85
AudioConnection patchCord1(adc1, 0, i2s1, 0);
AudioConnection patchCord2(adc1, 0, i2s1, 1);
AudioControlSGTL5000 sgtl5000_1; //xy=314,158
// GUItool: end automatically generated code


void setup() {
// Audio connections require memory to work. For more
// detailed information, see the MemoryAndCpuUsage example
AudioMemory(12);

// Enable the audio shield
sgtl5000_1.enable();
sgtl5000_1.volume(0.5);
}

void loop() {
// Do nothing here. The Audio flows automatically

// When AudioInputAnalog is running, analogRead() must NOT be used.
}



+ 1
- 1
gui/index.html View File

at altered speed. The grainLength is specified in milliseconds, up to at altered speed. The grainLength is specified in milliseconds, up to
one third of the memory from begin(); one third of the memory from begin();
</p> </p>
<p class=func><span class=keyword>end</span>();</p>
<p class=func><span class=keyword>stop</span>();</p>
<p class=desc>Stop granual processing. The input signal is passed to the <p class=desc>Stop granual processing. The input signal is passed to the
output without any changes. output without any changes.
</p> </p>

+ 227
- 16
input_adc.cpp View File

* THE SOFTWARE. * THE SOFTWARE.
*/ */


#if !defined(__IMXRT1052__) && !defined(__IMXRT1062__)
#if defined(KINETISK)
#include <Arduino.h> #include <Arduino.h>
#include "input_adc.h" #include "input_adc.h"


#define COEF_HPF_DCBLOCK (1048300<<10) // DC Removal filter coefficient in S1.30 #define COEF_HPF_DCBLOCK (1048300<<10) // DC Removal filter coefficient in S1.30


DMAMEM static uint16_t analog_rx_buffer[AUDIO_BLOCK_SAMPLES];
DMAMEM __attribute__((aligned(32))) static uint16_t analog_rx_buffer[AUDIO_BLOCK_SAMPLES];
audio_block_t * AudioInputAnalog::block_left = NULL; audio_block_t * AudioInputAnalog::block_left = NULL;
uint16_t AudioInputAnalog::block_offset = 0; uint16_t AudioInputAnalog::block_offset = 0;
int32_t AudioInputAnalog::hpf_y1 = 0; int32_t AudioInputAnalog::hpf_y1 = 0;


void AudioInputAnalog::init(uint8_t pin) void AudioInputAnalog::init(uint8_t pin)
{ {
int32_t tmp;
int32_t tmp;


// Configure the ADC and run at least one software-triggered // Configure the ADC and run at least one software-triggered
// conversion. This completes the self calibration stuff and // conversion. This completes the self calibration stuff and
analogReadAveraging(4); analogReadAveraging(4);
#endif #endif
// Note for review: // Note for review:
// Probably not useful to spin cycles here stabilizing
// since DC blocking is similar to te external analog filters
tmp = (uint16_t) analogRead(pin);
tmp = ( ((int32_t) tmp) << 14);
hpf_x1 = tmp; // With constant DC level x1 would be x0
hpf_y1 = 0; // Output will settle here when stable
// Probably not useful to spin cycles here stabilizing
// since DC blocking is similar to te external analog filters
tmp = (uint16_t) analogRead(pin);
tmp = ( ((int32_t) tmp) << 14);
hpf_x1 = tmp; // With constant DC level x1 would be x0
hpf_y1 = 0; // Output will settle here when stable


// set the programmable delay block to trigger the ADC at 44.1 kHz // set the programmable delay block to trigger the ADC at 44.1 kHz
#if defined(KINETISK)
if (!(SIM_SCGC6 & SIM_SCGC6_PDB) if (!(SIM_SCGC6 & SIM_SCGC6_PDB)
|| (PDB0_SC & PDB_CONFIG) != PDB_CONFIG || (PDB0_SC & PDB_CONFIG) != PDB_CONFIG
|| PDB0_MOD != PDB_PERIOD || PDB0_MOD != PDB_PERIOD
PDB0_SC = PDB_CONFIG | PDB_SC_SWTRIG; PDB0_SC = PDB_CONFIG | PDB_SC_SWTRIG;
PDB0_CH0C1 = 0x0101; PDB0_CH0C1 = 0x0101;
} }
#endif
// enable the ADC for hardware trigger and DMA // enable the ADC for hardware trigger and DMA
ADC0_SC2 |= ADC_SC2_ADTRG | ADC_SC2_DMAEN; ADC0_SC2 |= ADC_SC2_ADTRG | ADC_SC2_DMAEN;


// set up a DMA channel to store the ADC data // set up a DMA channel to store the ADC data
dma.begin(true); dma.begin(true);
#if defined(KINETISK)
dma.TCD->SADDR = &ADC0_RA; dma.TCD->SADDR = &ADC0_RA;
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(analog_rx_buffer); dma.TCD->DLASTSGA = -sizeof(analog_rx_buffer);
dma.TCD->BITER_ELINKNO = sizeof(analog_rx_buffer) / 2; dma.TCD->BITER_ELINKNO = sizeof(analog_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_ADC0); dma.triggerAtHardwareEvent(DMAMUX_SOURCE_ADC0);
update_responsibility = update_setup(); update_responsibility = update_setup();
dma.enable(); dma.enable();
uint16_t *dest_left; uint16_t *dest_left;
audio_block_t *left; audio_block_t *left;


#if defined(KINETISK)
daddr = (uint32_t)(dma.TCD->DADDR); daddr = (uint32_t)(dma.TCD->DADDR);
#endif
dma.clearInterrupt(); dma.clearInterrupt();


if (daddr < (uint32_t)analog_rx_buffer + sizeof(analog_rx_buffer) / 2) { if (daddr < (uint32_t)analog_rx_buffer + sizeof(analog_rx_buffer) / 2) {
transmit(out_left); transmit(out_left);
release(out_left); release(out_left);
} }
#endif
#endif



#if defined(__IMXRT1062__)

#include <Arduino.h>
#include "input_adc.h"

extern "C" void xbar_connect(unsigned int input, unsigned int output);

#define FILTERLEN 15

DMAChannel AudioInputAnalog::dma(false);
// TODO: how much extra space is needed to avoid wrap-around timing? 200 seems a safe guess
static __attribute__((aligned(32))) uint16_t adc_buffer[AUDIO_BLOCK_SAMPLES*4+200];
static int16_t capture_buffer[AUDIO_BLOCK_SAMPLES*4+FILTERLEN];
// TODO: these big buffers should be in DMAMEM, rather than consuming precious DTCM

PROGMEM static const uint8_t adc2_pin_to_channel[] = {
7, // 0/A0 AD_B1_02
8, // 1/A1 AD_B1_03
12, // 2/A2 AD_B1_07
11, // 3/A3 AD_B1_06
6, // 4/A4 AD_B1_01
5, // 5/A5 AD_B1_00
15, // 6/A6 AD_B1_10
0, // 7/A7 AD_B1_11
13, // 8/A8 AD_B1_08
14, // 9/A9 AD_B1_09
255, // 10/A10 AD_B0_12 - only on ADC1, 1 - can't use for audio
255, // 11/A11 AD_B0_13 - only on ADC1, 2 - can't use for audio
3, // 12/A12 AD_B1_14
4, // 13/A13 AD_B1_15
7, // 14/A0 AD_B1_02
8, // 15/A1 AD_B1_03
12, // 16/A2 AD_B1_07
11, // 17/A3 AD_B1_06
6, // 18/A4 AD_B1_01
5, // 19/A5 AD_B1_00
15, // 20/A6 AD_B1_10
0, // 21/A7 AD_B1_11
13, // 22/A8 AD_B1_08
14, // 23/A9 AD_B1_09
255, // 24/A10 AD_B0_12 - only on ADC1, 1 - can't use for audio
255, // 25/A11 AD_B0_13 - only on ADC1, 2 - can't use for audio
3, // 26/A12 AD_B1_14 - only on ADC2, do not use analogRead()
4, // 27/A13 AD_B1_15 - only on ADC2, do not use analogRead()
#ifdef ARDUINO_TEENSY41
255, // 28
255, // 29
255, // 30
255, // 31
255, // 32
255, // 33
255, // 34
255, // 35
255, // 36
255, // 37
1, // 38/A14 AD_B1_12 - only on ADC2, do not use analogRead()
2, // 39/A15 AD_B1_13 - only on ADC2, do not use analogRead()
9, // 40/A16 AD_B1_04
10, // 41/A17 AD_B1_05
#endif
};

static const int16_t filter[FILTERLEN] = {
1449,
3676,
6137,
9966,
13387,
16896,
18951,
19957,
18951,
16896,
13387,
9966,
6137,
3676,
1449
};


void AudioInputAnalog::init(uint8_t pin)
{
if (pin >= sizeof(adc2_pin_to_channel)) return;
const uint8_t adc_channel = adc2_pin_to_channel[pin];
if (adc_channel == 255) return;

// configure a timer to trigger ADC
// TODO: sample rate should be slightly lower than 4X AUDIO_SAMPLE_RATE_EXACT
// linear interpolation is supposed to resample it to exactly 4X
// the sample rate, so we avoid artifacts boundaries between captures
const int comp1 = ((float)F_BUS_ACTUAL) / (AUDIO_SAMPLE_RATE_EXACT * 4.0f) / 2.0f + 0.5f;
TMR4_ENBL &= ~(1<<3);
TMR4_SCTRL3 = TMR_SCTRL_OEN | TMR_SCTRL_FORCE;
TMR4_CSCTRL3 = TMR_CSCTRL_CL1(1) | TMR_CSCTRL_TCF1EN;
TMR4_CNTR3 = 0;
TMR4_LOAD3 = 0;
TMR4_COMP13 = comp1;
TMR4_CMPLD13 = comp1;
TMR4_CTRL3 = TMR_CTRL_CM(1) | TMR_CTRL_PCS(8) | TMR_CTRL_LENGTH | TMR_CTRL_OUTMODE(3);
TMR4_DMA3 = TMR_DMA_CMPLD1DE;
TMR4_CNTR3 = 0;
TMR4_ENBL |= (1<<3);

// connect the timer output the ADC_ETC input
const int trigger = 4; // 0-3 for ADC1, 4-7 for ADC2
CCM_CCGR2 |= CCM_CCGR2_XBAR1(CCM_CCGR_ON);
xbar_connect(XBARA1_IN_QTIMER4_TIMER3, XBARA1_OUT_ADC_ETC_TRIG00 + trigger);

// turn on ADC_ETC and configure to receive trigger
if (ADC_ETC_CTRL & (ADC_ETC_CTRL_SOFTRST | ADC_ETC_CTRL_TSC_BYPASS)) {
ADC_ETC_CTRL = 0; // clears SOFTRST only
ADC_ETC_CTRL = 0; // clears TSC_BYPASS
}
ADC_ETC_CTRL |= ADC_ETC_CTRL_TRIG_ENABLE(1 << trigger) | ADC_ETC_CTRL_DMA_MODE_SEL;
ADC_ETC_DMA_CTRL |= ADC_ETC_DMA_CTRL_TRIQ_ENABLE(trigger);

// configure ADC_ETC trigger4 to make one ADC2 measurement on pin A2
const int len = 1;
IMXRT_ADC_ETC.TRIG[trigger].CTRL = ADC_ETC_TRIG_CTRL_TRIG_CHAIN(len - 1) |
ADC_ETC_TRIG_CTRL_TRIG_PRIORITY(7);
IMXRT_ADC_ETC.TRIG[trigger].CHAIN_1_0 = ADC_ETC_TRIG_CHAIN_HWTS0(1) |
ADC_ETC_TRIG_CHAIN_CSEL0(adc2_pin_to_channel[pin]) | ADC_ETC_TRIG_CHAIN_B2B0;

// set up ADC2 for 12 bit mode, hardware trigger
Serial.printf("ADC2_CFG = %08X\n", ADC2_CFG);
ADC2_CFG |= ADC_CFG_ADTRG;
ADC2_CFG = ADC_CFG_MODE(2) | ADC_CFG_ADSTS(3) | ADC_CFG_ADLSMP | ADC_CFG_ADTRG |
ADC_CFG_ADICLK(1) | ADC_CFG_ADIV(0) /*| ADC_CFG_ADHSC*/;
ADC2_GC &= ~ADC_GC_AVGE; // single sample, no averaging
ADC2_HC0 = ADC_HC_ADCH(16); // 16 = controlled by ADC_ETC

// use a DMA channel to capture ADC_ETC output
dma.begin();
dma.TCD->SADDR = &(IMXRT_ADC_ETC.TRIG[4].RESULT_1_0);
dma.TCD->SOFF = 0;
dma.TCD->ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1);
dma.TCD->NBYTES_MLNO = 2;
dma.TCD->SLAST = 0;
dma.TCD->DADDR = adc_buffer;
dma.TCD->DOFF = 2;
dma.TCD->CITER_ELINKNO = sizeof(adc_buffer) / 2;
dma.TCD->DLASTSGA = -sizeof(adc_buffer);
dma.TCD->BITER_ELINKNO = sizeof(adc_buffer) / 2;
dma.TCD->CSR = 0;
dma.triggerAtHardwareEvent(DMAMUX_SOURCE_ADC_ETC);
dma.enable();

// TODO: configure I2S1 to interrupt every 128 audio samples
}

static int16_t fir(const int16_t *data, const int16_t *impulse, int len)
{
int64_t sum=0;

while (len > 0) {
sum += *data++ * *impulse++; // TODO: optimize with DSP inst and filter symmetry
len --;
}
sum = sum >> 15; // TODO: adjust filter coefficients for proper gain, 12 to 16 bits
if (sum > 32767) return 32767;
if (sum < -32768) return -32768;
return sum;
}

void AudioInputAnalog::update(void)
{
audio_block_t *output=NULL;
output = allocate();
if (output == NULL) return;

uint16_t *p = (uint16_t *)dma.TCD->DADDR;
//int offset = p - adc_buffer;
//if (--offset < 0) offset = sizeof(adc_buffer) / 2 - 1;
//Serial.printf("offset = %4d, val = %4d\n", offset + 1, adc_buffer[offset]);

// copy adc buffer to capture buffer
// FIXME: this should be done from the I2S interrupt, for precise capture timing
const unsigned int capture_len = sizeof(capture_buffer) / 2;
for (unsigned int i=0; i < capture_len; i++) {
// TODO: linear interpolate to exactly 4X sample rate
if (--p < adc_buffer) p = adc_buffer + (sizeof(adc_buffer) / 2 - 1);

// remove DC offset
// TODO: very slow low pass filter for DC offset
int dc_offset = 550; // FIXME: quick kludge for testing!!

int n = (int)*p - dc_offset;
if (n > 4095) n = 4095;
if (n < -4095) n = -4095;

capture_buffer[i] = n;
}
//printbuf(capture_buffer, 8);

// low pass filter and subsample (this part belongs here)
int16_t *dest = output->data + AUDIO_BLOCK_SAMPLES - 1;
for (int i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
#if 1
// proper low-pass filter sounds pretty good
*dest-- = fir(capture_buffer + i * 4, filter, sizeof(filter)/2);
#else
// just averge 4 samples together, lower quality but much faster
*dest-- = capture_buffer[i * 4] + capture_buffer[i * 4 + 1]
+ capture_buffer[i * 4 + 2] + capture_buffer[i * 4 + 3];
#endif
}
transmit(output);
release(output);
}



#endif

+ 0
- 1
input_adc.h View File

AudioInputAnalog() : AudioStream(0, NULL) { init(A2); } AudioInputAnalog() : AudioStream(0, NULL) { init(A2); }
AudioInputAnalog(uint8_t pin) : AudioStream(0, NULL) { init(pin); } AudioInputAnalog(uint8_t pin) : AudioStream(0, NULL) { init(pin); }
virtual void update(void); virtual void update(void);
friend void dma_ch9_isr(void);
private: private:
static audio_block_t *block_left; static audio_block_t *block_left;
static uint16_t block_offset; static uint16_t block_offset;

+ 2
- 2
input_adcs.cpp View File



#define COEF_HPF_DCBLOCK (1048300<<10) // DC Removal filter coefficient in S1.30 #define COEF_HPF_DCBLOCK (1048300<<10) // DC Removal filter coefficient in S1.30


DMAMEM static uint16_t left_buffer[AUDIO_BLOCK_SAMPLES];
DMAMEM static uint16_t right_buffer[AUDIO_BLOCK_SAMPLES];
DMAMEM __attribute__((aligned(32))) static uint16_t left_buffer[AUDIO_BLOCK_SAMPLES];
DMAMEM __attribute__((aligned(32))) static uint16_t right_buffer[AUDIO_BLOCK_SAMPLES];
audio_block_t * AudioInputAnalogStereo::block_left = NULL; audio_block_t * AudioInputAnalogStereo::block_left = NULL;
audio_block_t * AudioInputAnalogStereo::block_right = NULL; audio_block_t * AudioInputAnalogStereo::block_right = NULL;
uint16_t AudioInputAnalogStereo::offset_left = 0; uint16_t AudioInputAnalogStereo::offset_left = 0;

+ 2
- 4
input_i2s.cpp View File

#include "input_i2s.h" #include "input_i2s.h"
#include "output_i2s.h" #include "output_i2s.h"


static uint32_t i2s_rx_buffer[AUDIO_BLOCK_SAMPLES];
DMAMEM __attribute__((aligned(32))) static uint32_t i2s_rx_buffer[AUDIO_BLOCK_SAMPLES];
audio_block_t * AudioInputI2S::block_left = NULL; audio_block_t * AudioInputI2S::block_left = NULL;
audio_block_t * AudioInputI2S::block_right = NULL; audio_block_t * AudioInputI2S::block_right = NULL;
uint16_t AudioInputI2S::block_offset = 0; uint16_t AudioInputI2S::block_offset = 0;
dest_left = &(left->data[offset]); dest_left = &(left->data[offset]);
dest_right = &(right->data[offset]); dest_right = &(right->data[offset]);
AudioInputI2S::block_offset = offset + AUDIO_BLOCK_SAMPLES/2; AudioInputI2S::block_offset = offset + AUDIO_BLOCK_SAMPLES/2;
#if IMXRT_CACHE_ENABLED >=1
arm_dcache_delete(src, sizeof(i2s_rx_buffer) / 2);
#endif
arm_dcache_delete((void*)src, sizeof(i2s_rx_buffer) / 2);
do { do {
*dest_left++ = *src++; *dest_left++ = *src++;
*dest_right++ = *src++; *dest_right++ = *src++;

+ 4
- 4
input_i2s2.cpp View File

#include "input_i2s2.h" #include "input_i2s2.h"
#include "output_i2s2.h" #include "output_i2s2.h"


static uint32_t i2s2_rx_buffer[AUDIO_BLOCK_SAMPLES];
DMAMEM __attribute__((aligned(32))) static uint32_t i2s2_rx_buffer[AUDIO_BLOCK_SAMPLES];
audio_block_t * AudioInputI2S2::block_left = NULL; audio_block_t * AudioInputI2S2::block_left = NULL;
audio_block_t * AudioInputI2S2::block_right = NULL; audio_block_t * AudioInputI2S2::block_right = NULL;
uint16_t AudioInputI2S2::block_offset = 0; uint16_t AudioInputI2S2::block_offset = 0;
dest_left = &(left->data[offset]); dest_left = &(left->data[offset]);
dest_right = &(right->data[offset]); dest_right = &(right->data[offset]);
AudioInputI2S2::block_offset = offset + AUDIO_BLOCK_SAMPLES/2; AudioInputI2S2::block_offset = offset + AUDIO_BLOCK_SAMPLES/2;
#if IMXRT_CACHE_ENABLED >=1
arm_dcache_delete(src, sizeof(i2s_rx_buffer) / 2);
#endif
arm_dcache_delete((void*)src, sizeof(i2s2_rx_buffer) / 2);
do { do {
*dest_left++ = *src++; *dest_left++ = *src++;
*dest_right++ = *src++; *dest_right++ = *src++;

+ 1
- 1
input_i2s_hex.cpp View File

if (block_ch1) { if (block_ch1) {
offset = block_offset; offset = block_offset;
if (offset <= AUDIO_BLOCK_SAMPLES/2) { if (offset <= AUDIO_BLOCK_SAMPLES/2) {
arm_dcache_delete(src, sizeof(i2s_rx_buffer) / 2);
arm_dcache_delete((void*)src, sizeof(i2s_rx_buffer) / 2);
block_offset = offset + AUDIO_BLOCK_SAMPLES/2; block_offset = offset + AUDIO_BLOCK_SAMPLES/2;
dest1 = &(block_ch1->data[offset]); dest1 = &(block_ch1->data[offset]);
dest2 = &(block_ch2->data[offset]); dest2 = &(block_ch2->data[offset]);

+ 1
- 1
input_i2s_quad.cpp View File

if (block_ch1) { if (block_ch1) {
offset = block_offset; offset = block_offset;
if (offset <= AUDIO_BLOCK_SAMPLES/2) { if (offset <= AUDIO_BLOCK_SAMPLES/2) {
arm_dcache_delete(src, sizeof(i2s_rx_buffer) / 2);
arm_dcache_delete((void*)src, sizeof(i2s_rx_buffer) / 2);
block_offset = offset + AUDIO_BLOCK_SAMPLES/2; block_offset = offset + AUDIO_BLOCK_SAMPLES/2;
dest1 = &(block_ch1->data[offset]); dest1 = &(block_ch1->data[offset]);
dest2 = &(block_ch2->data[offset]); dest2 = &(block_ch2->data[offset]);

+ 1
- 1
input_pdm.cpp View File

// but its performance should be *much* better than the rapid passband rolloff // but its performance should be *much* better than the rapid passband rolloff
// of Cascaded Integrator Comb (CIC) or moving average filters. // of Cascaded Integrator Comb (CIC) or moving average filters.


DMAMEM static uint32_t pdm_buffer[AUDIO_BLOCK_SAMPLES*4];
DMAMEM __attribute__((aligned(32))) static uint32_t pdm_buffer[AUDIO_BLOCK_SAMPLES*4];
static uint32_t leftover[14]; static uint32_t leftover[14];
audio_block_t * AudioInputPDM::block_left = NULL; audio_block_t * AudioInputPDM::block_left = NULL;
bool AudioInputPDM::update_responsibility = false; bool AudioInputPDM::update_responsibility = false;

+ 1
- 1
output_adat.cpp View File

bool AudioOutputADAT::update_responsibility = false; bool AudioOutputADAT::update_responsibility = false;
//uint32_t AudioOutputADAT::vucp = VUCP_VALID; //uint32_t AudioOutputADAT::vucp = VUCP_VALID;


DMAMEM static uint32_t ADAT_tx_buffer[AUDIO_BLOCK_SAMPLES * 8]; //4 KB, AUDIO_BLOCK_SAMPLES is usually 128
DMAMEM __attribute__((aligned(32))) static uint32_t ADAT_tx_buffer[AUDIO_BLOCK_SAMPLES * 8]; //4 KB, AUDIO_BLOCK_SAMPLES is usually 128


DMAChannel AudioOutputADAT::dma(false); DMAChannel AudioOutputADAT::dma(false);



+ 1
- 1
output_dac.cpp View File



#if defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) #if defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)


DMAMEM static uint16_t dac_buffer[AUDIO_BLOCK_SAMPLES*2];
DMAMEM __attribute__((aligned(32))) static uint16_t dac_buffer[AUDIO_BLOCK_SAMPLES*2];
audio_block_t * AudioOutputAnalog::block_left_1st = NULL; audio_block_t * AudioOutputAnalog::block_left_1st = NULL;
audio_block_t * AudioOutputAnalog::block_left_2nd = NULL; audio_block_t * AudioOutputAnalog::block_left_2nd = NULL;
bool AudioOutputAnalog::update_responsibility = false; bool AudioOutputAnalog::update_responsibility = false;

+ 1
- 1
output_dacs.cpp View File



#if defined(__MK64FX512__) || defined(__MK66FX1M0__) #if defined(__MK64FX512__) || defined(__MK66FX1M0__)


DMAMEM static uint32_t dac_buffer[AUDIO_BLOCK_SAMPLES*2];
DMAMEM __attribute__((aligned(32))) static uint32_t dac_buffer[AUDIO_BLOCK_SAMPLES*2];
audio_block_t * AudioOutputAnalogStereo::block_left_1st = NULL; audio_block_t * AudioOutputAnalogStereo::block_left_1st = NULL;
audio_block_t * AudioOutputAnalogStereo::block_left_2nd = NULL; audio_block_t * AudioOutputAnalogStereo::block_left_2nd = NULL;
audio_block_t * AudioOutputAnalogStereo::block_right_1st = NULL; audio_block_t * AudioOutputAnalogStereo::block_right_1st = NULL;

+ 1
- 0
output_i2s.cpp View File

dma.TCD->DLASTSGA = 0; dma.TCD->DLASTSGA = 0;
dma.TCD->BITER_ELINKNO = sizeof(i2s_tx_buffer) / 2; dma.TCD->BITER_ELINKNO = sizeof(i2s_tx_buffer) / 2;
dma.TCD->DADDR = (void *)((uint32_t)&I2S1_TDR0 + 2); dma.TCD->DADDR = (void *)((uint32_t)&I2S1_TDR0 + 2);
dma.TCD->CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR;
dma.triggerAtHardwareEvent(DMAMUX_SOURCE_SAI1_TX); dma.triggerAtHardwareEvent(DMAMUX_SOURCE_SAI1_TX);
dma.enable(); dma.enable();



+ 2
- 2
output_pt8211.cpp View File

uint16_t AudioOutputPT8211::block_right_offset = 0; uint16_t AudioOutputPT8211::block_right_offset = 0;
bool AudioOutputPT8211::update_responsibility = false; bool AudioOutputPT8211::update_responsibility = false;
#if defined(AUDIO_PT8211_OVERSAMPLING) #if defined(AUDIO_PT8211_OVERSAMPLING)
static uint32_t i2s_tx_buffer[AUDIO_BLOCK_SAMPLES*4];
DMAMEM __attribute__((aligned(32))) static uint32_t i2s_tx_buffer[AUDIO_BLOCK_SAMPLES*4];
#else #else
static uint32_t i2s_tx_buffer[AUDIO_BLOCK_SAMPLES];
DMAMEM __attribute__((aligned(32))) static uint32_t i2s_tx_buffer[AUDIO_BLOCK_SAMPLES];
#endif #endif
DMAChannel AudioOutputPT8211::dma(false); DMAChannel AudioOutputPT8211::dma(false);



+ 2
- 2
output_pt8211_2.cpp View File

uint16_t AudioOutputPT8211_2::block_right_offset = 0; uint16_t AudioOutputPT8211_2::block_right_offset = 0;
bool AudioOutputPT8211_2::update_responsibility = false; bool AudioOutputPT8211_2::update_responsibility = false;
#if defined(AUDIO_PT8211_OVERSAMPLING) #if defined(AUDIO_PT8211_OVERSAMPLING)
static uint32_t i2s_tx_buffer[AUDIO_BLOCK_SAMPLES*4];
DMAMEM __attribute__((aligned(32))) static uint32_t i2s_tx_buffer[AUDIO_BLOCK_SAMPLES*4];
#else #else
static uint32_t i2s_tx_buffer[AUDIO_BLOCK_SAMPLES];
DMAMEM __attribute__((aligned(32))) static uint32_t i2s_tx_buffer[AUDIO_BLOCK_SAMPLES];
#endif #endif
DMAChannel AudioOutputPT8211_2::dma(false); DMAChannel AudioOutputPT8211_2::dma(false);



+ 1
- 1
output_pwm.cpp View File

extern const struct _pwm_pin_info_struct pwm_pin_info[]; extern const struct _pwm_pin_info_struct pwm_pin_info[];
audio_block_t * AudioOutputPWM::block = NULL; audio_block_t * AudioOutputPWM::block = NULL;
DMAMEM __attribute__((aligned(32))) static uint16_t pwm_tx_buffer[2][AUDIO_BLOCK_SAMPLES * 2]; DMAMEM __attribute__((aligned(32))) static uint16_t pwm_tx_buffer[2][AUDIO_BLOCK_SAMPLES * 2];
DMAChannel AudioOutputPWM::dma[2](false);
DMAChannel AudioOutputPWM::dma[2];
_audio_info_flexpwm AudioOutputPWM::apins[2]; _audio_info_flexpwm AudioOutputPWM::apins[2];


FLASHMEM FLASHMEM

Loading…
Cancel
Save