Conflicts: Audio.cpp Audio.hdds
@@ -3823,3 +3823,107 @@ void calcBiquad(uint8_t filtertype, float fC, float dB_Gain, float Q, uint32_t q | |||
a2/=a0; | |||
*coef++=(int)(a2+0.499); | |||
} | |||
/******************************************************************/ | |||
// A u d i o T o n e S w e e p | |||
// Written by Pete (El Supremo) Feb 2014 | |||
boolean AudioToneSweep::begin(short t_amp,int t_lo,int t_hi,float t_time) | |||
{ | |||
double tone_tmp; | |||
if(0) { | |||
Serial.print("AudioToneSweep.begin(tone_amp = "); | |||
Serial.print(t_amp); | |||
Serial.print(", tone_lo = "); | |||
Serial.print(t_lo); | |||
Serial.print(", tone_hi = "); | |||
Serial.print(t_hi); | |||
Serial.print(", tone_time = "); | |||
Serial.print(t_time,1); | |||
Serial.println(")"); | |||
} | |||
tone_amp = 0; | |||
if(t_amp < 0)return false; | |||
if(t_lo < 1)return false; | |||
if(t_hi < 1)return false; | |||
if(t_hi >= 44100/2)return false; | |||
if(t_lo >= 44100/2)return false; | |||
if(t_time < 0)return false; | |||
tone_lo = t_lo; | |||
tone_hi = t_hi; | |||
tone_phase = 0; | |||
tone_amp = t_amp; | |||
// Limit the output amplitude to prevent aliasing | |||
// until I can figure out why this "overtops" | |||
// above 29000. | |||
if(tone_amp > 29000)tone_amp = 29000; | |||
tone_tmp = tone_hi - tone_lo; | |||
tone_sign = 1; | |||
tone_freq = tone_lo*0x100000000LL; | |||
if(tone_tmp < 0) { | |||
tone_sign = -1; | |||
tone_tmp = -tone_tmp; | |||
} | |||
tone_tmp = tone_tmp/t_time/44100.; | |||
tone_incr = (tone_tmp * 0x100000000LL); | |||
sweep_busy = 1; | |||
return(true); | |||
} | |||
unsigned char AudioToneSweep::busy(void) | |||
{ | |||
return(sweep_busy); | |||
} | |||
int b_count = 0; | |||
void AudioToneSweep::update(void) | |||
{ | |||
audio_block_t *block; | |||
short *bp; | |||
int i; | |||
if(!sweep_busy)return; | |||
// L E F T C H A N N E L O N L Y | |||
block = allocate(); | |||
if(block) { | |||
bp = block->data; | |||
// Generate the sweep | |||
for(i = 0;i < AUDIO_BLOCK_SAMPLES;i++) { | |||
*bp++ = (short)(( (short)(arm_sin_q31((uint32_t)((tone_phase >> 15)&0x7fffffff))>>16) *tone_amp) >> 16); | |||
uint64_t tone_tmp = (0x400000000000LL * (int)((tone_freq >> 32)&0x7fffffff))/44100; | |||
tone_phase += tone_tmp; | |||
if(tone_phase & 0x800000000000LL)tone_phase &= 0x7fffffffffffLL; | |||
if(tone_sign > 0) { | |||
if((tone_freq >> 32) > tone_hi) { | |||
sweep_busy = 0; | |||
break; | |||
} | |||
tone_freq += tone_incr; | |||
} else { | |||
if((tone_freq >> 32) < tone_hi) { | |||
sweep_busy = 0; | |||
break; | |||
} | |||
tone_freq -= tone_incr; | |||
} | |||
} | |||
while(i < AUDIO_BLOCK_SAMPLES) { | |||
*bp++ = 0; | |||
i++; | |||
} | |||
b_count++; | |||
// send the samples to the left channel | |||
transmit(block,0); | |||
release(block); | |||
} | |||
} |
@@ -696,4 +696,30 @@ private: | |||
}; | |||
/******************************************************************/ | |||
// A u d i o T o n e S w e e p | |||
// Written by Pete (El Supremo) Feb 2014 | |||
class AudioToneSweep : public AudioStream | |||
{ | |||
public: | |||
AudioToneSweep(void) : | |||
AudioStream(0,NULL), sweep_busy(0) | |||
{ } | |||
boolean begin(short t_amp,int t_lo,int t_hi,float t_time); | |||
virtual void update(void); | |||
unsigned char busy(void); | |||
private: | |||
short tone_amp; | |||
int tone_lo; | |||
int tone_hi; | |||
uint64_t tone_freq; | |||
uint64_t tone_phase; | |||
uint64_t tone_incr; | |||
int tone_sign; | |||
unsigned char sweep_busy; | |||
}; | |||
@@ -0,0 +1,88 @@ | |||
/* | |||
Demo of the audio sweep function. | |||
The user specifies the amplitude, | |||
start and end frequencies (which can sweep up or down) | |||
and the length of time of the sweep. | |||
FMI: | |||
The audio board uses the following pins. | |||
6 - MEMCS | |||
7 - MOSI | |||
9 - BCLK | |||
10 - SDCS | |||
11 - MCLK | |||
12 - MISO | |||
13 - RX | |||
14 - SCLK | |||
15 - VOL | |||
18 - SDA | |||
19 - SCL | |||
22 - TX | |||
23 - LRCLK | |||
*/ | |||
#include <arm_math.h> | |||
#include <Audio.h> | |||
#include <Wire.h> | |||
//#include <WM8731.h> | |||
#include <SD.h> | |||
#include <SPI.h> | |||
#include <Bounce.h> | |||
AudioToneSweep myEffect; | |||
AudioOutputI2S audioOutput; // audio shield: headphones & line-out | |||
// The tone sweep goes to left and right channels | |||
AudioConnection c1(myEffect, 0, audioOutput, 0); | |||
AudioConnection c2(myEffect, 0, audioOutput, 1); | |||
AudioControlSGTL5000 audioShield; | |||
int t_ampx = 20000; | |||
int t_lox = 10; | |||
int t_hix = 22000; | |||
// Length of time for the sweep in seconds | |||
float t_timex = 10; | |||
// <<<<<<<<<<<<<<>>>>>>>>>>>>>>>> | |||
void setup(void) | |||
{ | |||
Serial.begin(9600); | |||
while (!Serial) ; | |||
delay(3000); | |||
AudioMemory(2); | |||
audioShield.enable(); | |||
audioShield.volume(50); | |||
// I want output on the line out too | |||
audioShield.unmuteLineout(); | |||
// audioShield.muteHeadphone(); | |||
Serial.println("setup done"); | |||
if(!myEffect.begin(t_ampx,t_lox,t_hix,t_timex)) { | |||
Serial.println("AudioToneSweep - begin failed"); | |||
while(1); | |||
} | |||
// wait for the sweep to end | |||
while(myEffect.busy()); | |||
// and now reverse the sweep | |||
if(!myEffect.begin(t_ampx,t_hix,t_lox,t_timex)) { | |||
Serial.println("AudioToneSweep - begin failed"); | |||
while(1); | |||
} | |||
// wait for the sweep to end | |||
while(myEffect.busy()); | |||
Serial.println("Done"); | |||
} | |||
void loop(void) | |||
{ | |||
} | |||