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.

700 lines
17KB

  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. class AudioSynthWaveform : public AudioStream
  63. {
  64. public:
  65. AudioSynthWaveform(const int16_t *waveform)
  66. : AudioStream(0, NULL), wavetable(waveform), magnitude(0), phase(0)
  67. , ramp_down(0), ramp_up(0), ramp_mag(0), ramp_length(0)
  68. { }
  69. void frequency(float freq) {
  70. if (freq > AUDIO_SAMPLE_RATE_EXACT / 2 || freq < 0.0) return;
  71. phase_increment = (freq / AUDIO_SAMPLE_RATE_EXACT) * 4294967296.0f;
  72. }
  73. void amplitude(float n) { // 0 to 1.0
  74. if (n < 0) n = 0;
  75. else if (n > 1.0) n = 1.0;
  76. // Ramp code
  77. if(magnitude && (n == 0)) {
  78. ramp_down = ramp_length;
  79. ramp_up = 0;
  80. last_magnitude = magnitude;
  81. }
  82. else if((magnitude == 0) && n) {
  83. ramp_up = ramp_length;
  84. ramp_down = 0;
  85. }
  86. // set new magnitude
  87. magnitude = n * 32767.0;
  88. }
  89. virtual void update(void);
  90. void set_ramp_length(uint16_t r_length);
  91. private:
  92. const int16_t *wavetable;
  93. uint16_t magnitude;
  94. uint16_t last_magnitude;
  95. uint32_t phase;
  96. uint32_t phase_increment;
  97. uint32_t ramp_down;
  98. uint32_t ramp_up;
  99. uint32_t ramp_mag;
  100. uint16_t ramp_length;
  101. };
  102. #if 0
  103. class AudioSineWaveMod : public AudioStream
  104. {
  105. public:
  106. AudioSineWaveMod() : AudioStream(1, inputQueueArray) {}
  107. void frequency(float freq);
  108. //void amplitude(q15 n);
  109. virtual void update(void);
  110. private:
  111. uint32_t phase;
  112. uint32_t phase_increment;
  113. uint32_t modulation_factor;
  114. audio_block_t *inputQueueArray[1];
  115. };
  116. #endif
  117. class AudioOutputPWM : public AudioStream
  118. {
  119. public:
  120. AudioOutputPWM(void) : AudioStream(1, inputQueueArray) { begin(); }
  121. virtual void update(void);
  122. void begin(void);
  123. friend void dma_ch3_isr(void);
  124. private:
  125. static audio_block_t *block_1st;
  126. static audio_block_t *block_2nd;
  127. static uint32_t block_offset;
  128. static bool update_responsibility;
  129. static uint8_t interrupt_count;
  130. audio_block_t *inputQueueArray[1];
  131. };
  132. class AudioOutputAnalog : public AudioStream
  133. {
  134. public:
  135. AudioOutputAnalog(void) : AudioStream(1, inputQueueArray) { begin(); }
  136. virtual void update(void);
  137. void begin(void);
  138. void analogReference(int ref);
  139. friend void dma_ch4_isr(void);
  140. private:
  141. static audio_block_t *block_left_1st;
  142. static audio_block_t *block_left_2nd;
  143. static bool update_responsibility;
  144. audio_block_t *inputQueueArray[1];
  145. };
  146. class AudioPrint : public AudioStream
  147. {
  148. public:
  149. AudioPrint(const char *str) : AudioStream(1, inputQueueArray), name(str) {}
  150. virtual void update(void);
  151. private:
  152. const char *name;
  153. audio_block_t *inputQueueArray[1];
  154. };
  155. class AudioInputI2S : public AudioStream
  156. {
  157. public:
  158. AudioInputI2S(void) : AudioStream(0, NULL) { begin(); }
  159. virtual void update(void);
  160. void begin(void);
  161. friend void dma_ch1_isr(void);
  162. protected:
  163. AudioInputI2S(int dummy): AudioStream(0, NULL) {} // to be used only inside AudioInputI2Sslave !!
  164. static bool update_responsibility;
  165. private:
  166. static audio_block_t *block_left;
  167. static audio_block_t *block_right;
  168. static uint16_t block_offset;
  169. };
  170. class AudioOutputI2S : public AudioStream
  171. {
  172. public:
  173. AudioOutputI2S(void) : AudioStream(2, inputQueueArray) { begin(); }
  174. virtual void update(void);
  175. void begin(void);
  176. friend void dma_ch0_isr(void);
  177. friend class AudioInputI2S;
  178. protected:
  179. AudioOutputI2S(int dummy): AudioStream(2, inputQueueArray) {} // to be used only inside AudioOutputI2Sslave !!
  180. static void config_i2s(void);
  181. static audio_block_t *block_left_1st;
  182. static audio_block_t *block_right_1st;
  183. static bool update_responsibility;
  184. private:
  185. static audio_block_t *block_left_2nd;
  186. static audio_block_t *block_right_2nd;
  187. static uint16_t block_left_offset;
  188. static uint16_t block_right_offset;
  189. audio_block_t *inputQueueArray[2];
  190. };
  191. class AudioInputI2Sslave : public AudioInputI2S
  192. {
  193. public:
  194. AudioInputI2Sslave(void) : AudioInputI2S(0) { begin(); }
  195. void begin(void);
  196. friend void dma_ch1_isr(void);
  197. };
  198. class AudioOutputI2Sslave : public AudioOutputI2S
  199. {
  200. public:
  201. AudioOutputI2Sslave(void) : AudioOutputI2S(0) { begin(); } ;
  202. void begin(void);
  203. friend class AudioInputI2Sslave;
  204. friend void dma_ch0_isr(void);
  205. protected:
  206. static void config_i2s(void);
  207. };
  208. class AudioInputAnalog : public AudioStream
  209. {
  210. public:
  211. AudioInputAnalog(unsigned int pin) : AudioStream(0, NULL) { begin(pin); }
  212. virtual void update(void);
  213. void begin(unsigned int pin);
  214. friend void dma_ch2_isr(void);
  215. private:
  216. static audio_block_t *block_left;
  217. static uint16_t block_offset;
  218. uint16_t dc_average;
  219. static bool update_responsibility;
  220. };
  221. #include "SD.h"
  222. class AudioPlaySDcardWAV : public AudioStream
  223. {
  224. public:
  225. AudioPlaySDcardWAV(void) : AudioStream(0, NULL) { begin(); }
  226. void begin(void);
  227. bool play(const char *filename);
  228. void stop(void);
  229. bool start(void);
  230. virtual void update(void);
  231. private:
  232. File wavfile;
  233. bool consume(void);
  234. bool parse_format(void);
  235. uint32_t header[5];
  236. uint32_t data_length; // number of bytes remaining in data section
  237. audio_block_t *block_left;
  238. audio_block_t *block_right;
  239. uint16_t block_offset;
  240. uint8_t buffer[512];
  241. uint16_t buffer_remaining;
  242. uint8_t state;
  243. uint8_t state_play;
  244. uint8_t leftover_bytes;
  245. };
  246. class AudioPlaySDcardRAW : public AudioStream
  247. {
  248. public:
  249. AudioPlaySDcardRAW(void) : AudioStream(0, NULL) { begin(); }
  250. void begin(void);
  251. bool play(const char *filename);
  252. void stop(void);
  253. virtual void update(void);
  254. private:
  255. File rawfile;
  256. audio_block_t *block;
  257. bool playing;
  258. bool paused;
  259. };
  260. class AudioPlayMemory : public AudioStream
  261. {
  262. public:
  263. AudioPlayMemory(void) : AudioStream(0, NULL), playing(0) { }
  264. void play(const unsigned int *data);
  265. void stop(void);
  266. virtual void update(void);
  267. private:
  268. const unsigned int *next;
  269. uint32_t length;
  270. int16_t prior;
  271. volatile uint8_t playing;
  272. };
  273. class AudioMixer4 : public AudioStream
  274. {
  275. public:
  276. AudioMixer4(void) : AudioStream(4, inputQueueArray) {
  277. for (int i=0; i<4; i++) multiplier[i] = 65536;
  278. }
  279. virtual void update(void);
  280. void gain(unsigned int channel, float gain) {
  281. if (channel >= 4) return;
  282. if (gain > 32767.0f) gain = 32767.0f;
  283. else if (gain < 0.0f) gain = 0.0f;
  284. multiplier[channel] = gain * 65536.0f; // TODO: proper roundoff?
  285. }
  286. private:
  287. int32_t multiplier[4];
  288. audio_block_t *inputQueueArray[4];
  289. };
  290. class AudioFilterBiquad : public AudioStream
  291. {
  292. public:
  293. AudioFilterBiquad(int *parameters)
  294. : AudioStream(1, inputQueueArray), definition(parameters) { }
  295. virtual void update(void);
  296. void updateCoefs(int *source, bool doReset);
  297. void updateCoefs(int *source);
  298. private:
  299. int *definition;
  300. audio_block_t *inputQueueArray[1];
  301. };
  302. class AudioEffectFade : public AudioStream
  303. {
  304. public:
  305. AudioEffectFade(void)
  306. : AudioStream(1, inputQueueArray), position(0xFFFFFFFF) {}
  307. void fadeIn(uint32_t milliseconds) {
  308. uint32_t samples = (uint32_t)(milliseconds * 441u + 5u) / 10u;
  309. //Serial.printf("fadeIn, %u samples\n", samples);
  310. fadeBegin(0xFFFFFFFFu / samples, 1);
  311. }
  312. void fadeOut(uint32_t milliseconds) {
  313. uint32_t samples = (uint32_t)(milliseconds * 441u + 5u) / 10u;
  314. //Serial.printf("fadeOut, %u samples\n", samples);
  315. fadeBegin(0xFFFFFFFFu / samples, 0);
  316. }
  317. virtual void update(void);
  318. private:
  319. void fadeBegin(uint32_t newrate, uint8_t dir);
  320. uint32_t position; // 0 = off, 0xFFFFFFFF = on
  321. uint32_t rate;
  322. uint8_t direction; // 0 = fading out, 1 = fading in
  323. audio_block_t *inputQueueArray[1];
  324. };
  325. class AudioAnalyzeToneDetect : public AudioStream
  326. {
  327. public:
  328. AudioAnalyzeToneDetect(void)
  329. : AudioStream(1, inputQueueArray), thresh(6554), enabled(false) { }
  330. void frequency(float freq, uint16_t cycles=10) {
  331. set_params((int32_t)(cos((double)freq
  332. * (2.0 * 3.14159265358979323846 / AUDIO_SAMPLE_RATE_EXACT))
  333. * (double)2147483647.999), cycles,
  334. (float)AUDIO_SAMPLE_RATE_EXACT / freq * (float)cycles + 0.5f);
  335. }
  336. void set_params(int32_t coef, uint16_t cycles, uint16_t len);
  337. bool available(void) {
  338. __disable_irq();
  339. bool flag = new_output;
  340. if (flag) new_output = false;
  341. __enable_irq();
  342. return flag;
  343. }
  344. float read(void);
  345. void threshold(float level) {
  346. if (level < 0.01f) thresh = 655;
  347. else if (level > 0.99f) thresh = 64881;
  348. else thresh = level * 65536.0f + 0.5f;
  349. }
  350. operator bool(); // true if at or above threshold, false if below
  351. virtual void update(void);
  352. private:
  353. int32_t coefficient; // Goertzel algorithm coefficient
  354. int32_t s1, s2; // Goertzel algorithm state
  355. int32_t out1, out2; // Goertzel algorithm state output
  356. uint16_t length; // number of samples to analyze
  357. uint16_t count; // how many left to analyze
  358. uint16_t ncycles; // number of waveform cycles to seek
  359. uint16_t thresh; // threshold, 655 to 64881 (1% to 99%)
  360. bool enabled;
  361. volatile bool new_output;
  362. audio_block_t *inputQueueArray[1];
  363. };
  364. // TODO: more audio processing objects....
  365. // sine wave with frequency modulation (phase)
  366. // waveforms with bandwidth limited tables for synth
  367. // envelope: attack-decay-sustain-release, maybe other more complex?
  368. // MP3 decoding - it is possible with optimized code?
  369. // other decompression, ADPCM, Vorbis, Speex, etc?
  370. // A base class for all Codecs, DACs and ADCs, so at least the
  371. // most basic functionality is consistent.
  372. #define AUDIO_INPUT_LINEIN 0
  373. #define AUDIO_INPUT_MIC 1
  374. class AudioControl
  375. {
  376. public:
  377. virtual bool enable(void) = 0;
  378. virtual bool disable(void) = 0;
  379. virtual bool volume(float volume) = 0; // volume 0.0 to 100.0
  380. virtual bool inputLevel(float volume) = 0; // volume 0.0 to 100.0
  381. virtual bool inputSelect(int n) = 0;
  382. };
  383. class AudioControlWM8731 : public AudioControl
  384. {
  385. public:
  386. bool enable(void);
  387. bool disable(void) { return false; }
  388. bool volume(float n) { return volumeInteger(n * 0.8 + 47.499); }
  389. bool inputLevel(float n) { return false; }
  390. bool inputSelect(int n) { return false; }
  391. protected:
  392. bool write(unsigned int reg, unsigned int val);
  393. bool volumeInteger(unsigned int n); // range: 0x2F to 0x7F
  394. };
  395. class AudioControlWM8731master : public AudioControlWM8731
  396. {
  397. public:
  398. bool enable(void);
  399. };
  400. class AudioControlSGTL5000 : public AudioControl
  401. {
  402. public:
  403. bool enable(void);
  404. bool disable(void) { return false; }
  405. bool volume(float n) { return volumeInteger(n * 1.29 + 0.499); }
  406. bool inputLevel(float n) {return false;}
  407. bool muteHeadphone(void) { return write(0x0024, ana_ctrl | (1<<4)); }
  408. bool unmuteHeadphone(void) { return write(0x0024, ana_ctrl & ~(1<<4)); }
  409. bool muteLineout(void) { return write(0x0024, ana_ctrl | (1<<8)); }
  410. bool unmuteLineout(void) { return write(0x0024, ana_ctrl & ~(1<<8)); }
  411. bool inputSelect(int n) {
  412. if (n == AUDIO_INPUT_LINEIN) {
  413. return write(0x0024, ana_ctrl | (1<<2));
  414. } else if (n == AUDIO_INPUT_MIC) {
  415. //return write(0x002A, 0x0172) && write(0x0024, ana_ctrl & ~(1<<2));
  416. return write(0x002A, 0x0173) && write(0x0024, ana_ctrl & ~(1<<2)); // +40dB
  417. } else {
  418. return false;
  419. }
  420. }
  421. //bool inputLinein(void) { return write(0x0024, ana_ctrl | (1<<2)); }
  422. //bool inputMic(void) { return write(0x002A, 0x0172) && write(0x0024, ana_ctrl & ~(1<<2)); }
  423. bool volume(float left, float right);
  424. unsigned short micGain(unsigned int n) { return modify(0x002A, n&3, 3); }
  425. unsigned short lo_lvl(uint8_t n);
  426. unsigned short lo_lvl(uint8_t left, uint8_t right);
  427. unsigned short dac_vol(float n);
  428. unsigned short dac_vol(float left, float right);
  429. unsigned short dap_mix_enable(uint8_t n);
  430. unsigned short dap_enable(uint8_t n);
  431. unsigned short dap_enable(void);
  432. unsigned short dap_peqs(uint8_t n);
  433. unsigned short dap_audio_eq(uint8_t n);
  434. unsigned short dap_audio_eq_band(uint8_t bandNum, float n);
  435. void dap_audio_eq_geq(float bass, float mid_bass, float midrange, float mid_treble, float treble);
  436. void dap_audio_eq_tone(float bass, float treble);
  437. void load_peq(uint8_t filterNum, int *filterParameters);
  438. protected:
  439. bool muted;
  440. bool volumeInteger(unsigned int n); // range: 0x00 to 0x80
  441. uint16_t ana_ctrl;
  442. unsigned char calcVol(float n, unsigned char range);
  443. unsigned int read(unsigned int reg);
  444. bool write(unsigned int reg, unsigned int val);
  445. unsigned int modify(unsigned int reg, unsigned int val, unsigned int iMask);
  446. };
  447. //For Filter Type: 0 = LPF, 1 = HPF, 2 = BPF, 3 = NOTCH, 4 = PeakingEQ, 5 = LowShelf, 6 = HighShelf
  448. #define FILTER_LOPASS 0
  449. #define FILTER_HIPASS 1
  450. #define FILTER_BANDPASS 2
  451. #define FILTER_NOTCH 3
  452. #define FILTER_PARAEQ 4
  453. #define FILTER_LOSHELF 5
  454. #define FILTER_HISHELF 6
  455. void calcBiquad(uint8_t filtertype, float fC, float dB_Gain, float Q, uint32_t quantization_unit, uint32_t fS, int *coef);
  456. /******************************************************************/
  457. // Maximum number of coefficients in a FIR filter
  458. // The audio breaks up with 128 coefficients so a
  459. // maximum of 150 is more than sufficient
  460. #define MAX_COEFFS 150
  461. // Indicates that the code should just pass through the audio
  462. // without any filtering (as opposed to doing nothing at all)
  463. #define FIR_PASSTHRU ((short *) 1)
  464. class AudioFilterFIR :
  465. public AudioStream
  466. {
  467. public:
  468. AudioFilterFIR(void):
  469. AudioStream(2,inputQueueArray), coeff_p(NULL)
  470. {
  471. }
  472. void begin(short *coeff_p,int f_pin);
  473. virtual void update(void);
  474. void stop(void);
  475. private:
  476. audio_block_t *inputQueueArray[2];
  477. // arm state arrays and FIR instances for left and right channels
  478. // the state arrays are defined to handle a maximum of MAX_COEFFS
  479. // coefficients in a filter
  480. q15_t l_StateQ15[AUDIO_BLOCK_SAMPLES + MAX_COEFFS];
  481. q15_t r_StateQ15[AUDIO_BLOCK_SAMPLES + MAX_COEFFS];
  482. arm_fir_instance_q15 l_fir_inst;
  483. arm_fir_instance_q15 r_fir_inst;
  484. // pointer to current coefficients or NULL or FIR_PASSTHRU
  485. short *coeff_p;
  486. };
  487. /******************************************************************/
  488. // A u d i o E f f e c t F l a n g e
  489. // Written by Pete (El Supremo) Jan 2014
  490. #define DELAY_PASSTHRU 0
  491. class AudioEffectFlange :
  492. public AudioStream
  493. {
  494. public:
  495. AudioEffectFlange(void):
  496. AudioStream(2,inputQueueArray) {
  497. }
  498. boolean begin(short *delayline,int d_length,int delay_offset,int d_depth,float delay_rate);
  499. boolean modify(int delay_offset,int d_depth,float delay_rate);
  500. virtual void update(void);
  501. void stop(void);
  502. private:
  503. audio_block_t *inputQueueArray[2];
  504. static short *l_delayline;
  505. static short *r_delayline;
  506. static int delay_length;
  507. static short l_circ_idx;
  508. static short r_circ_idx;
  509. static int delay_depth;
  510. static int delay_offset_idx;
  511. static int delay_rate_incr;
  512. static unsigned int l_delay_rate_index;
  513. static unsigned int r_delay_rate_index;
  514. };
  515. /******************************************************************/
  516. // A u d i o E f f e c t C h o r u s
  517. // Written by Pete (El Supremo) Jan 2014
  518. class AudioEffectChorus :
  519. public AudioStream
  520. {
  521. public:
  522. AudioEffectChorus(void):
  523. AudioStream(2,inputQueueArray) {
  524. }
  525. boolean begin(short *delayline,int delay_length,int n_chorus);
  526. virtual void update(void);
  527. void stop(void);
  528. void modify(int n_chorus);
  529. private:
  530. audio_block_t *inputQueueArray[2];
  531. static short *l_delayline;
  532. static short *r_delayline;
  533. static short l_circ_idx;
  534. static short r_circ_idx;
  535. static int num_chorus;
  536. static int delay_length;
  537. };