You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

802 line
20KB

  1. #include "AudioStream.h"
  2. #include "arm_math.h"
  3. // When changing multiple audio object settings that must update at
  4. // the same time, these functions allow the audio library interrupt
  5. // to be disabled. For example, you may wish to begin playing a note
  6. // in response to reading an analog sensor. If you have "velocity"
  7. // information, you might start the sample playing and also adjust
  8. // the gain of a mixer channel. Use AudioNoInterrupts() first, then
  9. // make both changes to the 2 separate objects. Then allow the audio
  10. // library to update with AudioInterrupts(). Both changes will happen
  11. // at the same time, because AudioNoInterrupts() prevents any updates
  12. // while you make changes.
  13. #define AudioNoInterrupts() (NVIC_DISABLE_IRQ(IRQ_SOFTWARE))
  14. #define AudioInterrupts() (NVIC_ENABLE_IRQ(IRQ_SOFTWARE))
  15. // waveforms.c
  16. extern "C" {
  17. extern const int16_t AudioWaveformSine[257];
  18. extern const int16_t AudioWaveformTriangle[257];
  19. extern const int16_t AudioWaveformSquare[257];
  20. extern const int16_t AudioWaveformSawtooth[257];
  21. }
  22. // windows.c
  23. extern "C" {
  24. extern const int16_t AudioWindowHanning256[];
  25. extern const int16_t AudioWindowBartlett256[];
  26. extern const int16_t AudioWindowBlackman256[];
  27. extern const int16_t AudioWindowFlattop256[];
  28. extern const int16_t AudioWindowBlackmanHarris256[];
  29. extern const int16_t AudioWindowNuttall256[];
  30. extern const int16_t AudioWindowBlackmanNuttall256[];
  31. extern const int16_t AudioWindowWelch256[];
  32. extern const int16_t AudioWindowHamming256[];
  33. extern const int16_t AudioWindowCosine256[];
  34. extern const int16_t AudioWindowTukey256[];
  35. }
  36. class AudioAnalyzeFFT256 : public AudioStream
  37. {
  38. public:
  39. AudioAnalyzeFFT256(uint8_t navg = 8, const int16_t *win = AudioWindowHanning256)
  40. : AudioStream(1, inputQueueArray), window(win),
  41. prevblock(NULL), count(0), naverage(navg), outputflag(false) { init(); }
  42. bool available() {
  43. if (outputflag == true) {
  44. outputflag = false;
  45. return true;
  46. }
  47. return false;
  48. }
  49. virtual void update(void);
  50. //uint32_t cycles;
  51. int32_t output[128] __attribute__ ((aligned (4)));
  52. private:
  53. void init(void);
  54. const int16_t *window;
  55. audio_block_t *prevblock;
  56. int16_t buffer[512] __attribute__ ((aligned (4)));
  57. uint8_t count;
  58. uint8_t naverage;
  59. bool outputflag;
  60. audio_block_t *inputQueueArray[1];
  61. };
  62. #ifdef ORIGINAL_AUDIOSYNTHWAVEFORM
  63. class AudioSynthWaveform : public AudioStream
  64. {
  65. public:
  66. AudioSynthWaveform(const int16_t *waveform)
  67. : AudioStream(0, NULL), wavetable(waveform), magnitude(0), phase(0)
  68. , ramp_down(0), ramp_up(0), ramp_mag(0), ramp_length(0)
  69. { }
  70. void frequency(float freq) {
  71. if (freq > AUDIO_SAMPLE_RATE_EXACT / 2 || freq < 0.0) return;
  72. phase_increment = (freq / AUDIO_SAMPLE_RATE_EXACT) * 4294967296.0f;
  73. }
  74. void amplitude(float n) { // 0 to 1.0
  75. if (n < 0) n = 0;
  76. else if (n > 1.0) n = 1.0;
  77. // Ramp code
  78. if(magnitude && (n == 0)) {
  79. ramp_down = ramp_length;
  80. ramp_up = 0;
  81. last_magnitude = magnitude;
  82. }
  83. else if((magnitude == 0) && n) {
  84. ramp_up = ramp_length;
  85. ramp_down = 0;
  86. }
  87. // set new magnitude
  88. magnitude = n * 32767.0;
  89. }
  90. virtual void update(void);
  91. void set_ramp_length(uint16_t r_length);
  92. private:
  93. const int16_t *wavetable;
  94. uint16_t magnitude;
  95. uint16_t last_magnitude;
  96. uint32_t phase;
  97. uint32_t phase_increment;
  98. uint32_t ramp_down;
  99. uint32_t ramp_up;
  100. uint32_t ramp_mag;
  101. uint16_t ramp_length;
  102. };
  103. #else
  104. #define AUDIO_SAMPLE_RATE_ROUNDED (44118)
  105. #define DELAY_PASSTHRU -1
  106. #define TONE_TYPE_SINE 0
  107. #define TONE_TYPE_SAWTOOTH 1
  108. #define TONE_TYPE_SQUARE 2
  109. #define TONE_TYPE_TRIANGLE 3
  110. class AudioSynthWaveform :
  111. public AudioStream
  112. {
  113. public:
  114. AudioSynthWaveform(void) :
  115. AudioStream(0,NULL),
  116. tone_freq(0), tone_phase(0), tone_incr(0), tone_type(0),
  117. ramp_down(0), ramp_up(0), ramp_length(0)
  118. {
  119. }
  120. // Change the frequency on-the-fly to permit a phase-continuous
  121. // change between two frequencies.
  122. void frequency(int t_hi)
  123. {
  124. tone_incr = (0x100000000LL*t_hi)/AUDIO_SAMPLE_RATE_EXACT;
  125. }
  126. // If ramp_length is non-zero this will set up
  127. // either a rmap up or a ramp down when a wave
  128. // first starts or when the amplitude is set
  129. // back to zero.
  130. // Note that if the ramp_length is N, the generated
  131. // wave will be N samples longer than when it is not
  132. // ramp
  133. void amplitude(float n) { // 0 to 1.0
  134. if (n < 0) n = 0;
  135. else if (n > 1.0) n = 1.0;
  136. // Ramp code
  137. if(tone_amp && (n == 0)) {
  138. ramp_down = ramp_length;
  139. ramp_up = 0;
  140. last_tone_amp = tone_amp;
  141. }
  142. else if((tone_amp == 0) && n) {
  143. ramp_up = ramp_length;
  144. ramp_down = 0;
  145. // reset the phase when the amplitude was zero
  146. // and has now been increased. Note that this
  147. // happens even if the wave is not ramped
  148. // so that the signal starts at zero
  149. tone_phase = 0;
  150. }
  151. // set new magnitude
  152. tone_amp = n * 32767.0;
  153. }
  154. boolean begin(float t_amp,int t_hi,short t_type);
  155. virtual void update(void);
  156. void set_ramp_length(uint16_t r_length);
  157. private:
  158. short tone_amp;
  159. short last_tone_amp;
  160. short tone_freq;
  161. uint32_t tone_phase;
  162. uint32_t tone_incr;
  163. short tone_type;
  164. uint32_t ramp_down;
  165. uint32_t ramp_up;
  166. uint16_t ramp_length;
  167. };
  168. #endif
  169. #if 0
  170. class AudioSineWaveMod : public AudioStream
  171. {
  172. public:
  173. AudioSineWaveMod() : AudioStream(1, inputQueueArray) {}
  174. void frequency(float freq);
  175. //void amplitude(q15 n);
  176. virtual void update(void);
  177. private:
  178. uint32_t phase;
  179. uint32_t phase_increment;
  180. uint32_t modulation_factor;
  181. audio_block_t *inputQueueArray[1];
  182. };
  183. #endif
  184. class AudioOutputPWM : public AudioStream
  185. {
  186. public:
  187. AudioOutputPWM(void) : AudioStream(1, inputQueueArray) { begin(); }
  188. virtual void update(void);
  189. void begin(void);
  190. friend void dma_ch3_isr(void);
  191. private:
  192. static audio_block_t *block_1st;
  193. static audio_block_t *block_2nd;
  194. static uint32_t block_offset;
  195. static bool update_responsibility;
  196. static uint8_t interrupt_count;
  197. audio_block_t *inputQueueArray[1];
  198. };
  199. class AudioOutputAnalog : public AudioStream
  200. {
  201. public:
  202. AudioOutputAnalog(void) : AudioStream(1, inputQueueArray) { begin(); }
  203. virtual void update(void);
  204. void begin(void);
  205. void analogReference(int ref);
  206. friend void dma_ch4_isr(void);
  207. private:
  208. static audio_block_t *block_left_1st;
  209. static audio_block_t *block_left_2nd;
  210. static bool update_responsibility;
  211. audio_block_t *inputQueueArray[1];
  212. };
  213. class AudioPrint : public AudioStream
  214. {
  215. public:
  216. AudioPrint(const char *str) : AudioStream(1, inputQueueArray), name(str) {}
  217. virtual void update(void);
  218. private:
  219. const char *name;
  220. audio_block_t *inputQueueArray[1];
  221. };
  222. // Multiple input & output objects use the Programmable Delay Block
  223. // to set their sample rate. They must all configure the same
  224. // period to avoid chaos.
  225. #define PDB_CONFIG (PDB_SC_TRGSEL(15) | PDB_SC_PDBEN | PDB_SC_CONT)
  226. #define PDB_PERIOD 1087 // 48e6 / 44100
  227. class AudioInputI2S : public AudioStream
  228. {
  229. public:
  230. AudioInputI2S(void) : AudioStream(0, NULL) { begin(); }
  231. virtual void update(void);
  232. void begin(void);
  233. friend void dma_ch1_isr(void);
  234. protected:
  235. AudioInputI2S(int dummy): AudioStream(0, NULL) {} // to be used only inside AudioInputI2Sslave !!
  236. static bool update_responsibility;
  237. private:
  238. static audio_block_t *block_left;
  239. static audio_block_t *block_right;
  240. static uint16_t block_offset;
  241. };
  242. class AudioOutputI2S : public AudioStream
  243. {
  244. public:
  245. AudioOutputI2S(void) : AudioStream(2, inputQueueArray) { begin(); }
  246. virtual void update(void);
  247. void begin(void);
  248. friend void dma_ch0_isr(void);
  249. friend class AudioInputI2S;
  250. protected:
  251. AudioOutputI2S(int dummy): AudioStream(2, inputQueueArray) {} // to be used only inside AudioOutputI2Sslave !!
  252. static void config_i2s(void);
  253. static audio_block_t *block_left_1st;
  254. static audio_block_t *block_right_1st;
  255. static bool update_responsibility;
  256. private:
  257. static audio_block_t *block_left_2nd;
  258. static audio_block_t *block_right_2nd;
  259. static uint16_t block_left_offset;
  260. static uint16_t block_right_offset;
  261. audio_block_t *inputQueueArray[2];
  262. };
  263. class AudioInputI2Sslave : public AudioInputI2S
  264. {
  265. public:
  266. AudioInputI2Sslave(void) : AudioInputI2S(0) { begin(); }
  267. void begin(void);
  268. friend void dma_ch1_isr(void);
  269. };
  270. class AudioOutputI2Sslave : public AudioOutputI2S
  271. {
  272. public:
  273. AudioOutputI2Sslave(void) : AudioOutputI2S(0) { begin(); } ;
  274. void begin(void);
  275. friend class AudioInputI2Sslave;
  276. friend void dma_ch0_isr(void);
  277. protected:
  278. static void config_i2s(void);
  279. };
  280. class AudioInputAnalog : public AudioStream
  281. {
  282. public:
  283. AudioInputAnalog(unsigned int pin) : AudioStream(0, NULL) { begin(pin); }
  284. virtual void update(void);
  285. void begin(unsigned int pin);
  286. friend void dma_ch2_isr(void);
  287. private:
  288. static audio_block_t *block_left;
  289. static uint16_t block_offset;
  290. uint16_t dc_average;
  291. static bool update_responsibility;
  292. };
  293. #include "SD.h"
  294. class AudioPlaySDcardWAV : public AudioStream
  295. {
  296. public:
  297. AudioPlaySDcardWAV(void) : AudioStream(0, NULL) { begin(); }
  298. void begin(void);
  299. bool play(const char *filename);
  300. void stop(void);
  301. bool start(void);
  302. virtual void update(void);
  303. private:
  304. File wavfile;
  305. bool consume(void);
  306. bool parse_format(void);
  307. uint32_t header[5];
  308. uint32_t data_length; // number of bytes remaining in data section
  309. audio_block_t *block_left;
  310. audio_block_t *block_right;
  311. uint16_t block_offset;
  312. uint8_t buffer[512];
  313. uint16_t buffer_remaining;
  314. uint8_t state;
  315. uint8_t state_play;
  316. uint8_t leftover_bytes;
  317. };
  318. class AudioPlaySDcardRAW : public AudioStream
  319. {
  320. public:
  321. AudioPlaySDcardRAW(void) : AudioStream(0, NULL) { begin(); }
  322. void begin(void);
  323. bool play(const char *filename);
  324. void stop(void);
  325. virtual void update(void);
  326. private:
  327. File rawfile;
  328. audio_block_t *block;
  329. bool playing;
  330. bool paused;
  331. };
  332. class AudioPlayMemory : public AudioStream
  333. {
  334. public:
  335. AudioPlayMemory(void) : AudioStream(0, NULL), playing(0) { }
  336. void play(const unsigned int *data);
  337. void stop(void);
  338. virtual void update(void);
  339. private:
  340. const unsigned int *next;
  341. uint32_t length;
  342. int16_t prior;
  343. volatile uint8_t playing;
  344. };
  345. class AudioMixer4 : public AudioStream
  346. {
  347. public:
  348. AudioMixer4(void) : AudioStream(4, inputQueueArray) {
  349. for (int i=0; i<4; i++) multiplier[i] = 65536;
  350. }
  351. virtual void update(void);
  352. void gain(unsigned int channel, float gain) {
  353. if (channel >= 4) return;
  354. if (gain > 32767.0f) gain = 32767.0f;
  355. else if (gain < 0.0f) gain = 0.0f;
  356. multiplier[channel] = gain * 65536.0f; // TODO: proper roundoff?
  357. }
  358. private:
  359. int32_t multiplier[4];
  360. audio_block_t *inputQueueArray[4];
  361. };
  362. class AudioFilterBiquad : public AudioStream
  363. {
  364. public:
  365. AudioFilterBiquad(int *parameters)
  366. : AudioStream(1, inputQueueArray), definition(parameters) { }
  367. virtual void update(void);
  368. void updateCoefs(int *source, bool doReset);
  369. void updateCoefs(int *source);
  370. private:
  371. int *definition;
  372. audio_block_t *inputQueueArray[1];
  373. };
  374. class AudioEffectFade : public AudioStream
  375. {
  376. public:
  377. AudioEffectFade(void)
  378. : AudioStream(1, inputQueueArray), position(0xFFFFFFFF) {}
  379. void fadeIn(uint32_t milliseconds) {
  380. uint32_t samples = (uint32_t)(milliseconds * 441u + 5u) / 10u;
  381. //Serial.printf("fadeIn, %u samples\n", samples);
  382. fadeBegin(0xFFFFFFFFu / samples, 1);
  383. }
  384. void fadeOut(uint32_t milliseconds) {
  385. uint32_t samples = (uint32_t)(milliseconds * 441u + 5u) / 10u;
  386. //Serial.printf("fadeOut, %u samples\n", samples);
  387. fadeBegin(0xFFFFFFFFu / samples, 0);
  388. }
  389. virtual void update(void);
  390. private:
  391. void fadeBegin(uint32_t newrate, uint8_t dir);
  392. uint32_t position; // 0 = off, 0xFFFFFFFF = on
  393. uint32_t rate;
  394. uint8_t direction; // 0 = fading out, 1 = fading in
  395. audio_block_t *inputQueueArray[1];
  396. };
  397. class AudioAnalyzeToneDetect : public AudioStream
  398. {
  399. public:
  400. AudioAnalyzeToneDetect(void)
  401. : AudioStream(1, inputQueueArray), thresh(6554), enabled(false) { }
  402. void frequency(float freq, uint16_t cycles=10) {
  403. set_params((int32_t)(cos((double)freq
  404. * (2.0 * 3.14159265358979323846 / AUDIO_SAMPLE_RATE_EXACT))
  405. * (double)2147483647.999), cycles,
  406. (float)AUDIO_SAMPLE_RATE_EXACT / freq * (float)cycles + 0.5f);
  407. }
  408. void set_params(int32_t coef, uint16_t cycles, uint16_t len);
  409. bool available(void) {
  410. __disable_irq();
  411. bool flag = new_output;
  412. if (flag) new_output = false;
  413. __enable_irq();
  414. return flag;
  415. }
  416. float read(void);
  417. void threshold(float level) {
  418. if (level < 0.01f) thresh = 655;
  419. else if (level > 0.99f) thresh = 64881;
  420. else thresh = level * 65536.0f + 0.5f;
  421. }
  422. operator bool(); // true if at or above threshold, false if below
  423. virtual void update(void);
  424. private:
  425. int32_t coefficient; // Goertzel algorithm coefficient
  426. int32_t s1, s2; // Goertzel algorithm state
  427. int32_t out1, out2; // Goertzel algorithm state output
  428. uint16_t length; // number of samples to analyze
  429. uint16_t count; // how many left to analyze
  430. uint16_t ncycles; // number of waveform cycles to seek
  431. uint16_t thresh; // threshold, 655 to 64881 (1% to 99%)
  432. bool enabled;
  433. volatile bool new_output;
  434. audio_block_t *inputQueueArray[1];
  435. };
  436. // TODO: more audio processing objects....
  437. // sine wave with frequency modulation (phase)
  438. // waveforms with bandwidth limited tables for synth
  439. // envelope: attack-decay-sustain-release, maybe other more complex?
  440. // MP3 decoding - it is possible with optimized code?
  441. // other decompression, ADPCM, Vorbis, Speex, etc?
  442. // A base class for all Codecs, DACs and ADCs, so at least the
  443. // most basic functionality is consistent.
  444. #define AUDIO_INPUT_LINEIN 0
  445. #define AUDIO_INPUT_MIC 1
  446. class AudioControl
  447. {
  448. public:
  449. virtual bool enable(void) = 0;
  450. virtual bool disable(void) = 0;
  451. virtual bool volume(float volume) = 0; // volume 0.0 to 100.0
  452. virtual bool inputLevel(float volume) = 0; // volume 0.0 to 100.0
  453. virtual bool inputSelect(int n) = 0;
  454. };
  455. class AudioControlWM8731 : public AudioControl
  456. {
  457. public:
  458. bool enable(void);
  459. bool disable(void) { return false; }
  460. bool volume(float n) { return volumeInteger(n * 0.8 + 47.499); }
  461. bool inputLevel(float n) { return false; }
  462. bool inputSelect(int n) { return false; }
  463. protected:
  464. bool write(unsigned int reg, unsigned int val);
  465. bool volumeInteger(unsigned int n); // range: 0x2F to 0x7F
  466. };
  467. class AudioControlWM8731master : public AudioControlWM8731
  468. {
  469. public:
  470. bool enable(void);
  471. };
  472. class AudioControlSGTL5000 : public AudioControl
  473. {
  474. public:
  475. bool enable(void);
  476. bool disable(void) { return false; }
  477. bool volume(float n) { return volumeInteger(n * 1.29 + 0.499); }
  478. bool inputLevel(float n) {return false;}
  479. bool muteHeadphone(void) { return write(0x0024, ana_ctrl | (1<<4)); }
  480. bool unmuteHeadphone(void) { return write(0x0024, ana_ctrl & ~(1<<4)); }
  481. bool muteLineout(void) { return write(0x0024, ana_ctrl | (1<<8)); }
  482. bool unmuteLineout(void) { return write(0x0024, ana_ctrl & ~(1<<8)); }
  483. bool inputSelect(int n) {
  484. if (n == AUDIO_INPUT_LINEIN) {
  485. return write(0x0024, ana_ctrl | (1<<2));
  486. } else if (n == AUDIO_INPUT_MIC) {
  487. //return write(0x002A, 0x0172) && write(0x0024, ana_ctrl & ~(1<<2));
  488. return write(0x002A, 0x0173) && write(0x0024, ana_ctrl & ~(1<<2)); // +40dB
  489. } else {
  490. return false;
  491. }
  492. }
  493. //bool inputLinein(void) { return write(0x0024, ana_ctrl | (1<<2)); }
  494. //bool inputMic(void) { return write(0x002A, 0x0172) && write(0x0024, ana_ctrl & ~(1<<2)); }
  495. bool volume(float left, float right);
  496. unsigned short micGain(unsigned int n) { return modify(0x002A, n&3, 3); }
  497. unsigned short lo_lvl(uint8_t n);
  498. unsigned short lo_lvl(uint8_t left, uint8_t right);
  499. unsigned short dac_vol(float n);
  500. unsigned short dac_vol(float left, float right);
  501. unsigned short dap_mix_enable(uint8_t n);
  502. unsigned short dap_enable(uint8_t n);
  503. unsigned short dap_enable(void);
  504. unsigned short dap_peqs(uint8_t n);
  505. unsigned short dap_audio_eq(uint8_t n);
  506. unsigned short dap_audio_eq_band(uint8_t bandNum, float n);
  507. void dap_audio_eq_geq(float bass, float mid_bass, float midrange, float mid_treble, float treble);
  508. void dap_audio_eq_tone(float bass, float treble);
  509. void load_peq(uint8_t filterNum, int *filterParameters);
  510. protected:
  511. bool muted;
  512. bool volumeInteger(unsigned int n); // range: 0x00 to 0x80
  513. uint16_t ana_ctrl;
  514. unsigned char calcVol(float n, unsigned char range);
  515. unsigned int read(unsigned int reg);
  516. bool write(unsigned int reg, unsigned int val);
  517. unsigned int modify(unsigned int reg, unsigned int val, unsigned int iMask);
  518. };
  519. //For Filter Type: 0 = LPF, 1 = HPF, 2 = BPF, 3 = NOTCH, 4 = PeakingEQ, 5 = LowShelf, 6 = HighShelf
  520. #define FILTER_LOPASS 0
  521. #define FILTER_HIPASS 1
  522. #define FILTER_BANDPASS 2
  523. #define FILTER_NOTCH 3
  524. #define FILTER_PARAEQ 4
  525. #define FILTER_LOSHELF 5
  526. #define FILTER_HISHELF 6
  527. void calcBiquad(uint8_t filtertype, float fC, float dB_Gain, float Q, uint32_t quantization_unit, uint32_t fS, int *coef);
  528. /******************************************************************/
  529. // Maximum number of coefficients in a FIR filter
  530. // The audio breaks up with 128 coefficients so a
  531. // maximum of 150 is more than sufficient
  532. #define MAX_COEFFS 150
  533. // Indicates that the code should just pass through the audio
  534. // without any filtering (as opposed to doing nothing at all)
  535. #define FIR_PASSTHRU ((short *) 1)
  536. class AudioFilterFIR :
  537. public AudioStream
  538. {
  539. public:
  540. AudioFilterFIR(void):
  541. AudioStream(2,inputQueueArray), coeff_p(NULL)
  542. {
  543. }
  544. void begin(short *coeff_p,int f_pin);
  545. virtual void update(void);
  546. void stop(void);
  547. private:
  548. audio_block_t *inputQueueArray[2];
  549. // arm state arrays and FIR instances for left and right channels
  550. // the state arrays are defined to handle a maximum of MAX_COEFFS
  551. // coefficients in a filter
  552. q15_t l_StateQ15[AUDIO_BLOCK_SAMPLES + MAX_COEFFS];
  553. q15_t r_StateQ15[AUDIO_BLOCK_SAMPLES + MAX_COEFFS];
  554. arm_fir_instance_q15 l_fir_inst;
  555. arm_fir_instance_q15 r_fir_inst;
  556. // pointer to current coefficients or NULL or FIR_PASSTHRU
  557. short *coeff_p;
  558. };
  559. /******************************************************************/
  560. // A u d i o E f f e c t F l a n g e
  561. // Written by Pete (El Supremo) Jan 2014
  562. #define DELAY_PASSTHRU 0
  563. class AudioEffectFlange :
  564. public AudioStream
  565. {
  566. public:
  567. AudioEffectFlange(void):
  568. AudioStream(2,inputQueueArray) {
  569. }
  570. boolean begin(short *delayline,int d_length,int delay_offset,int d_depth,float delay_rate);
  571. boolean modify(int delay_offset,int d_depth,float delay_rate);
  572. virtual void update(void);
  573. void stop(void);
  574. private:
  575. audio_block_t *inputQueueArray[2];
  576. static short *l_delayline;
  577. static short *r_delayline;
  578. static int delay_length;
  579. static short l_circ_idx;
  580. static short r_circ_idx;
  581. static int delay_depth;
  582. static int delay_offset_idx;
  583. static int delay_rate_incr;
  584. static unsigned int l_delay_rate_index;
  585. static unsigned int r_delay_rate_index;
  586. };
  587. /******************************************************************/
  588. // A u d i o E f f e c t C h o r u s
  589. // Written by Pete (El Supremo) Jan 2014
  590. class AudioEffectChorus :
  591. public AudioStream
  592. {
  593. public:
  594. AudioEffectChorus(void):
  595. AudioStream(2,inputQueueArray) {
  596. }
  597. boolean begin(short *delayline,int delay_length,int n_chorus);
  598. virtual void update(void);
  599. void stop(void);
  600. void modify(int n_chorus);
  601. private:
  602. audio_block_t *inputQueueArray[2];
  603. static short *l_delayline;
  604. static short *r_delayline;
  605. static short l_circ_idx;
  606. static short r_circ_idx;
  607. static int num_chorus;
  608. static int delay_length;
  609. };
  610. /******************************************************************/
  611. // A u d i o T o n e S w e e p
  612. // Written by Pete (El Supremo) Feb 2014
  613. class AudioToneSweep : public AudioStream
  614. {
  615. public:
  616. AudioToneSweep(void) :
  617. AudioStream(0,NULL), sweep_busy(0)
  618. { }
  619. boolean begin(short t_amp,int t_lo,int t_hi,float t_time);
  620. virtual void update(void);
  621. unsigned char busy(void);
  622. private:
  623. short tone_amp;
  624. int tone_lo;
  625. int tone_hi;
  626. uint64_t tone_freq;
  627. uint64_t tone_phase;
  628. uint64_t tone_incr;
  629. int tone_sign;
  630. unsigned char sweep_busy;
  631. };