浏览代码

move OS-related #defines to .h file; speed improvements

Combine two loops in stereo CIC computation into one for-loop.
Add compiler optimization "unroll-loops" to isr if OS enabled. Speed
improved from 113µs to 65µs per isr call for CIC interpolation filtering
(Measured on Teensy 3.2 96MHz optimized).
dds
Benjamin 8 年前
父节点
当前提交
cf013ec88e
共有 2 个文件被更改,包括 28 次插入30 次删除
  1. +17
    -29
      output_pt8211.cpp
  2. +11
    -1
      output_pt8211.h

+ 17
- 29
output_pt8211.cpp 查看文件

@@ -29,12 +29,6 @@
#include "output_pt8211.h"
#include "memcpy_audio.h"

//uncomment to enable oversampling:
#define OVERSAMPLING
//uncomment ONE of these to define interpolation type for oversampling:
// #define INTERPOLATION_LINEAR
#define INTERPOLATION_CIC

audio_block_t * AudioOutputPT8211::block_left_1st = NULL;
audio_block_t * AudioOutputPT8211::block_right_1st = NULL;
audio_block_t * AudioOutputPT8211::block_left_2nd = NULL;
@@ -81,7 +75,6 @@ void AudioOutputPT8211::begin(void)
dma.attachInterrupt(isr);
}


void AudioOutputPT8211::isr(void)
{
int16_t *dest;
@@ -145,46 +138,42 @@ void AudioOutputPT8211::isr(void)
static int32_t combROld[2] = {0};
combL[0] = valL - oldL;
combL[1] = combL[0] - combLOld[0];
combL[2] = combL[1] - combLOld[1];
// combL[2] now holds input val
combLOld[0] = combL[0];
combLOld[1] = combL[1];
for (int j = 0; j < 4; j++) {
int32_t integrateL[3];
static int32_t integrateLOld[3] = {0};
integrateL[0] = ( (j==0) ? (combL[2]) : (0) ) + integrateLOld[0];
integrateL[1] = integrateL[0] + integrateLOld[1];
integrateL[2] = integrateL[1] + integrateLOld[2];
// integrateL[2] now holds j'th upsampled value
*(dest+j*2) = integrateL[2] >> 4;
integrateLOld[0] = integrateL[0];
integrateLOld[1] = integrateL[1];
integrateLOld[2] = integrateL[2];
}
combR[0] = valR - oldR;
combL[1] = combL[0] - combLOld[0];
combR[1] = combR[0] - combROld[0];
combL[2] = combL[1] - combLOld[1];
combR[2] = combR[1] - combROld[1];
// combL[2] now holds input val
// combR[2] now holds input val
oldL = valL;
oldR = valR;
combLOld[0] = combL[0];
combROld[0] = combR[0];
combLOld[1] = combL[1];
combROld[1] = combR[1];
for (int j = 0; j < 4; j++) {
int32_t integrateL[3];
int32_t integrateR[3];
static int32_t integrateLOld[3] = {0};
static int32_t integrateROld[3] = {0};
integrateL[0] = ( (j==0) ? (combL[2]) : (0) ) + integrateLOld[0];
integrateR[0] = ( (j==0) ? (combR[2]) : (0) ) + integrateROld[0];
integrateL[1] = integrateL[0] + integrateLOld[1];
integrateR[1] = integrateR[0] + integrateROld[1];
integrateL[2] = integrateL[1] + integrateLOld[2];
integrateR[2] = integrateR[1] + integrateROld[2];
// integrateL[2] now holds j'th upsampled value
// integrateR[2] now holds j'th upsampled value
*(dest+j*2) = integrateL[2] >> 4;
*(dest+j*2+1) = integrateR[2] >> 4;
integrateLOld[0] = integrateL[0];
integrateROld[0] = integrateR[0];
integrateLOld[1] = integrateL[1];
integrateROld[1] = integrateR[1];
integrateLOld[2] = integrateL[2];
integrateROld[2] = integrateR[2];
}

dest+=8;
oldL = valL;
oldR = valR;
}
#else
#error no interpolation method defined for oversampling.
@@ -338,7 +327,6 @@ void AudioOutputPT8211::isr(void)




void AudioOutputPT8211::update(void)
{


+ 11
- 1
output_pt8211.h 查看文件

@@ -29,6 +29,12 @@
#ifndef output_pt8211_h_
#define output_pt8211_h_

//uncomment to enable oversampling:
#define OVERSAMPLING
//uncomment ONE of these to define interpolation type for oversampling:
// #define INTERPOLATION_LINEAR
#define INTERPOLATION_CIC

#include "Arduino.h"
#include "AudioStream.h"
#include "DMAChannel.h"
@@ -47,7 +53,11 @@ protected:
static audio_block_t *block_right_1st;
static bool update_responsibility;
static DMAChannel dma;
static void isr(void);
static void isr(void)
#if defined(OVERSAMPLING)
__attribute__((optimize("unroll-loops")))
#endif
;
private:
static audio_block_t *block_left_2nd;
static audio_block_t *block_right_2nd;

正在加载...
取消
保存