Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

11 роки тому
11 роки тому
11 роки тому
11 роки тому
11 роки тому
11 роки тому
11 роки тому
11 роки тому
11 роки тому
11 роки тому
11 роки тому
11 роки тому
11 роки тому
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699
  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. };