瀏覽代碼

Merge remote-tracking branch 'refs/remotes/PaulStoffregen/master'

dds
Jacquot-SFE 9 年之前
父節點
當前提交
1202a93c58
共有 13 個檔案被更改,包括 89 行新增34 行删除
  1. +1
    -1
      examples/Effects/Filter_FIR/Filter_FIR.ino
  2. +5
    -2
      filter_fir.h
  3. 二進制
      gui/img/audioshield_quad_in.jpg
  4. 二進制
      gui/img/audioshield_quad_out.jpg
  5. +18
    -3
      gui/index.html
  6. +1
    -1
      input_i2s_quad.cpp
  7. +23
    -24
      library.json
  8. +1
    -1
      memcpy_audio.S
  9. +1
    -1
      output_dac.cpp
  10. +7
    -0
      output_i2s.cpp
  11. +8
    -1
      output_i2s_quad.cpp
  12. +7
    -0
      output_spdif.cpp
  13. +17
    -0
      utility/dspinst.h

+ 1
- 1
examples/Effects/Filter_FIR/Filter_FIR.ino 查看文件



struct fir_filter { struct fir_filter {
short *coeffs; short *coeffs;
short num_coeffs;
short num_coeffs; // num_coeffs must be an even number, 4 or higher
}; };


// index of current filter. Start with the low pass. // index of current filter. Start with the low pass.

+ 5
- 2
filter_fir.h 查看文件

coeff_p = cp; coeff_p = cp;
// Initialize FIR instance (ARM DSP Math Library) // Initialize FIR instance (ARM DSP Math Library)
if (coeff_p && (coeff_p != FIR_PASSTHRU) && n_coeffs <= FIR_MAX_COEFFS) { if (coeff_p && (coeff_p != FIR_PASSTHRU) && n_coeffs <= FIR_MAX_COEFFS) {
arm_fir_init_q15(&fir_inst, n_coeffs, (q15_t *)coeff_p,
&StateQ15[0], AUDIO_BLOCK_SAMPLES);
if (arm_fir_init_q15(&fir_inst, n_coeffs, (q15_t *)coeff_p,
&StateQ15[0], AUDIO_BLOCK_SAMPLES) != ARM_MATH_SUCCESS) {
// n_coeffs must be an even number, 4 or larger
coeff_p = NULL;
}
} }
} }
void end(void) { void end(void) {

二進制
gui/img/audioshield_quad_in.jpg 查看文件

Before After
Width: 240  |  Height: 266  |  Size: 28KB

二進制
gui/img/audioshield_quad_out.jpg 查看文件

Before After
Width: 240  |  Height: 209  |  Size: 23KB

+ 18
- 3
gui/index.html 查看文件

<p>Receive 16 bit quad (4) channel audio from two <p>Receive 16 bit quad (4) channel audio from two
<a href="http://www.pjrc.com/store/teensy3_audio.html" target="_blank">audio shields</a> <a href="http://www.pjrc.com/store/teensy3_audio.html" target="_blank">audio shields</a>
or another I2S devices, using I2S master mode.</p> or another I2S devices, using I2S master mode.</p>
<p align=center><img src="img/audioshield_quad_in.jpg"></p>
</div> </div>
<h3>Audio Connections</h3> <h3>Audio Connections</h3>
<table class=doc align=center cellpadding=3> <table class=doc align=center cellpadding=3>
<h3>Summary</h3> <h3>Summary</h3>
<div class=tooltipinfo> <div class=tooltipinfo>
<p>Transmit quad (4) channel 16 bit audio, using I2S master mode.</p> <p>Transmit quad (4) channel 16 bit audio, using I2S master mode.</p>
<p align=center><img src="img/audioshield_quad_out.jpg"></p>
</div> </div>
<h3>Audio Connections</h3> <h3>Audio Connections</h3>
<table class=doc align=center cellpadding=3> <table class=doc align=center cellpadding=3>
<h3>Functions</h3> <h3>Functions</h3>
<p class=func><span class=keyword>delay</span>(channel, milliseconds);</p> <p class=func><span class=keyword>delay</span>(channel, milliseconds);</p>
<p class=desc>Set output channel (0 to 7) to delay the signals by <p class=desc>Set output channel (0 to 7) to delay the signals by
milliseconds. The maximum delay is approx 333 ms. The actual delay
milliseconds. The maximum delay is approx 425 ms. The actual delay
is rounded to the nearest sample. Each channel can be configured for is rounded to the nearest sample. Each channel can be configured for
any delay. There is no requirement to configure the "taps" in increasing any delay. There is no requirement to configure the "taps" in increasing
delay order. delay order.
<h3>Functions</h3> <h3>Functions</h3>
<p class=func><span class=keyword>delay</span>(channel, milliseconds);</p> <p class=func><span class=keyword>delay</span>(channel, milliseconds);</p>
<p class=desc>Set output channel (0 to 7) to delay the signals by <p class=desc>Set output channel (0 to 7) to delay the signals by
milliseconds. The maximum delay is approx 333 ms. The actual delay
milliseconds. The maximum delay is approx 1.5 seconds for each 23LC1024 chip.
The actual delay
is rounded to the nearest sample. Each channel can be configured for is rounded to the nearest sample. Each channel can be configured for
any delay. There is no requirement to configure the "taps" in increasing any delay. There is no requirement to configure the "taps" in increasing
delay order. delay order.
<h3>Examples</h3> <h3>Examples</h3>
<p class=exam>File &gt; Examples &gt; Audio &gt; Effects &gt; Filter_FIR <p class=exam>File &gt; Examples &gt; Audio &gt; Effects &gt; Filter_FIR
</p> </p>
<h3>Known Issues</h3>
<p>Your filter's impulse response array must have an even length. If you have
add odd number of taps, you must add an extra zero to increase the length
to an even number.
</p>
<p>The minimum number of taps is 4. If you use less, add extra zeros to increase
the length to 4.
</p>
<p>The impulse response must be given in reverse order. Many filters have
symetrical impluse response, making this a non-issue. If your filter has
a non-symetrical response, make sure the data is in reverse time order.
</p>
<h3>Notes</h3> <h3>Notes</h3>
<p>FIR filters requires more CPU time than Biquad (IIR), but they can <p>FIR filters requires more CPU time than Biquad (IIR), but they can
implement filters with better phase response. implement filters with better phase response.
supported filter length is 200 points. supported filter length is 200 points.
</p> </p>
<p>The free <p>The free
<a href="http://t-filter.appspot.com/fir/index.html" target="_blank"> TFilter Design Tool</a>
<a href="http://t-filter.engineerjs.com/" target="_blank"> TFilter Design Tool</a>
can be used to create the impulse response array. Be sure to set the sampling can be used to create the impulse response array. Be sure to set the sampling
frequency to 44117 HZ (it defaults to only 2000 Hz) and the output type to "int" (16 bit). frequency to 44117 HZ (it defaults to only 2000 Hz) and the output type to "int" (16 bit).
</p> </p>

+ 1
- 1
input_i2s_quad.cpp 查看文件

bool AudioInputI2SQuad::update_responsibility = false; bool AudioInputI2SQuad::update_responsibility = false;
DMAChannel AudioInputI2SQuad::dma(false); DMAChannel AudioInputI2SQuad::dma(false);


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


void AudioInputI2SQuad::begin(void) void AudioInputI2SQuad::begin(void)
{ {

+ 23
- 24
library.json 查看文件

{ {
"name": "Audio",
"frameworks": "Arduino",
"platforms": "Teensy",
"keywords": "sound, audio, FFT, filter, effect",
"description": "Teensy Audio Library",
"url": "http://www.pjrc.com/teensy/td_libs_Audio.html",
"downloadUrl": "https://github.com/PaulStoffregen/Audio/archive/master.zip",
"version": "1.03",
"exclude": "extras",
"authors":
{
"name": "Paul Stoffregen",
"maintainer": true
},
"repository":
{
"type": "git",
"url": "https://github.com/PaulStoffregen/Audio"
},
"dependencies":
{
"name": "SerialFlash",
"frameworks": "arduino"
},
"name": "Audio",
"frameworks": "Arduino",
"platforms": "Teensy",
"keywords": "sound, audio, FFT, filter, effect",
"description": "Teensy Audio Library",
"url": "http://www.pjrc.com/teensy/td_libs_Audio.html",
"version": "1.03",
"exclude": "extras",
"authors":
{
"name": "Paul Stoffregen",
"maintainer": true
},
"repository":
{
"type": "git",
"url": "https://github.com/PaulStoffregen/Audio"
},
"dependencies":
{
"name": "SerialFlash",
"frameworks": "arduino"
},
"examples": [ "examples": [
"examples/*/*.ino", "examples/*/*.ino",
"examples/*/*/*.ino" "examples/*/*/*.ino"

+ 1
- 1
memcpy_audio.S 查看文件

* SOFTWARE. * SOFTWARE.
*/ */


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


.cpu cortex-m4 .cpu cortex-m4
.syntax unified .syntax unified

+ 1
- 1
output_dac.cpp 查看文件

#include "output_dac.h" #include "output_dac.h"
#include "utility/pdb.h" #include "utility/pdb.h"


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


DMAMEM static uint16_t dac_buffer[AUDIO_BLOCK_SAMPLES*2]; DMAMEM 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;

+ 7
- 0
output_i2s.cpp 查看文件

#elif F_CPU == 168000000 #elif F_CPU == 168000000
#define MCLK_MULT 8 #define MCLK_MULT 8
#define MCLK_DIV 119 #define MCLK_DIV 119
#elif F_CPU == 180000000
#define MCLK_MULT 16
#define MCLK_DIV 255
#elif F_CPU == 192000000
#define MCLK_MULT 1
#define MCLK_DIV 17
#elif F_CPU == 16000000 #elif F_CPU == 16000000
#define MCLK_MULT 12 #define MCLK_MULT 12
#define MCLK_DIV 17 #define MCLK_DIV 17


// enable MCLK output // enable MCLK output
I2S0_MCR = I2S_MCR_MICS(MCLK_SRC) | I2S_MCR_MOE; I2S0_MCR = I2S_MCR_MICS(MCLK_SRC) | I2S_MCR_MOE;
while (I2S0_MCR & I2S_MCR_DUF) ;
I2S0_MDR = I2S_MDR_FRACT((MCLK_MULT-1)) | I2S_MDR_DIVIDE((MCLK_DIV-1)); I2S0_MDR = I2S_MDR_FRACT((MCLK_MULT-1)) | I2S_MDR_DIVIDE((MCLK_DIV-1));


// configure transmitter // configure transmitter

+ 8
- 1
output_i2s_quad.cpp 查看文件

#include "output_i2s_quad.h" #include "output_i2s_quad.h"
#include "memcpy_audio.h" #include "memcpy_audio.h"


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


audio_block_t * AudioOutputI2SQuad::block_ch1_1st = NULL; audio_block_t * AudioOutputI2SQuad::block_ch1_1st = NULL;
audio_block_t * AudioOutputI2SQuad::block_ch2_1st = NULL; audio_block_t * AudioOutputI2SQuad::block_ch2_1st = NULL;
#elif F_CPU == 168000000 #elif F_CPU == 168000000
#define MCLK_MULT 8 #define MCLK_MULT 8
#define MCLK_DIV 119 #define MCLK_DIV 119
#elif F_CPU == 180000000
#define MCLK_MULT 16
#define MCLK_DIV 255
#elif F_CPU == 192000000
#define MCLK_MULT 1
#define MCLK_DIV 17
#elif F_CPU == 16000000 #elif F_CPU == 16000000
#define MCLK_MULT 12 #define MCLK_MULT 12
#define MCLK_DIV 17 #define MCLK_DIV 17


// enable MCLK output // enable MCLK output
I2S0_MCR = I2S_MCR_MICS(MCLK_SRC) | I2S_MCR_MOE; I2S0_MCR = I2S_MCR_MICS(MCLK_SRC) | I2S_MCR_MOE;
while (I2S0_MCR & I2S_MCR_DUF) ;
I2S0_MDR = I2S_MDR_FRACT((MCLK_MULT-1)) | I2S_MDR_DIVIDE((MCLK_DIV-1)); I2S0_MDR = I2S_MDR_FRACT((MCLK_MULT-1)) | I2S_MDR_DIVIDE((MCLK_DIV-1));


// configure transmitter // configure transmitter

+ 7
- 0
output_spdif.cpp 查看文件

#elif F_CPU == 168000000 #elif F_CPU == 168000000
#define MCLK_MULT 8 #define MCLK_MULT 8
#define MCLK_DIV 119 #define MCLK_DIV 119
#elif F_CPU == 180000000
#define MCLK_MULT 16
#define MCLK_DIV 255
#elif F_CPU == 192000000
#define MCLK_MULT 1
#define MCLK_DIV 17
#elif F_CPU == 16000000 #elif F_CPU == 16000000
#define MCLK_MULT 12 #define MCLK_MULT 12
#define MCLK_DIV 17 #define MCLK_DIV 17


// enable MCLK output // enable MCLK output
I2S0_MCR = I2S_MCR_MICS(MCLK_SRC) | I2S_MCR_MOE; I2S0_MCR = I2S_MCR_MICS(MCLK_SRC) | I2S_MCR_MOE;
while (I2S0_MCR & I2S_MCR_DUF) ;
I2S0_MDR = I2S_MDR_FRACT((MCLK_MULT-1)) | I2S_MDR_DIVIDE((MCLK_DIV-1)); I2S0_MDR = I2S_MDR_FRACT((MCLK_MULT-1)) | I2S_MDR_DIVIDE((MCLK_DIV-1));


// configure transmitter // configure transmitter

+ 17
- 0
utility/dspinst.h 查看文件

return out; return out;
} }


//get Q from PSR
static inline uint32_t get_q_psr(void) __attribute__((always_inline, unused));
static inline uint32_t get_q_psr(void)
{
uint32_t out;
asm volatile("mrs %0, APSR" : "=r" (out));
return (out & 0x8000000)>>27;
}


//clear Q BIT in PSR
static inline void clr_q_psr(void) __attribute__((always_inline, unused));
static inline void clr_q_psr(void)
{
uint32_t t;
asm volatile("mrs %0,APSR " : "=r" (t));
asm volatile("bfc %0, #27, #1" : "=r" (t));
asm volatile("msr APSR_nzcvq,%0" : "=r" (t));
}


#endif #endif

Loading…
取消
儲存