Conflicts: Audio.cpp Audio.hdds
a2/=a0; | a2/=a0; | ||||
*coef++=(int)(a2+0.499); | *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); | |||||
} | |||||
} |
}; | }; | ||||
/******************************************************************/ | |||||
// 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; | |||||
}; | |||||
/* | |||||
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) | |||||
{ | |||||
} | |||||