Browse Source

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

dds
Jacquot-SFE 9 years ago
parent
commit
1202a93c58
13 changed files with 89 additions and 34 deletions
  1. +1
    -1
      examples/Effects/Filter_FIR/Filter_FIR.ino
  2. +5
    -2
      filter_fir.h
  3. BIN
      gui/img/audioshield_quad_in.jpg
  4. BIN
      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 View File



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 View File

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) {

BIN
gui/img/audioshield_quad_in.jpg View File

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

BIN
gui/img/audioshield_quad_out.jpg View File

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

+ 18
- 3
gui/index.html View File

<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 View File

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 View File

{ {
"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 View File

* 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 View File

#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 View File

#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 View File

#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 View File

#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 View File

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…
Cancel
Save