Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

575 Zeilen
14KB

  1. #include "AudioStream.h"
  2. // When changing multiple audio object settings that must update at
  3. // the same time, these functions allow the audio library interrupt
  4. // to be disabled. For example, you may wish to begin playing a note
  5. // in response to reading an analog sensor. If you have "velocity"
  6. // information, you might start the sample playing and also adjust
  7. // the gain of a mixer channel. Use AudioNoInterrupts() first, then
  8. // make both changes to the 2 separate objects. Then allow the audio
  9. // library to update with AudioInterrupts(). Both changes will happen
  10. // at the same time, because AudioNoInterrupts() prevents any updates
  11. // while you make changes.
  12. #define AudioNoInterrupts() (NVIC_DISABLE_IRQ(IRQ_SOFTWARE))
  13. #define AudioInterrupts() (NVIC_ENABLE_IRQ(IRQ_SOFTWARE))
  14. // waveforms.c
  15. extern "C" {
  16. extern const int16_t AudioWaveformSine[257];
  17. extern const int16_t AudioWaveformTriangle[257];
  18. extern const int16_t AudioWaveformSquare[257];
  19. extern const int16_t AudioWaveformSawtooth[257];
  20. }
  21. // windows.c
  22. extern "C" {
  23. extern const int16_t AudioWindowHanning256[];
  24. extern const int16_t AudioWindowBartlett256[];
  25. extern const int16_t AudioWindowBlackman256[];
  26. extern const int16_t AudioWindowFlattop256[];
  27. extern const int16_t AudioWindowBlackmanHarris256[];
  28. extern const int16_t AudioWindowNuttall256[];
  29. extern const int16_t AudioWindowBlackmanNuttall256[];
  30. extern const int16_t AudioWindowWelch256[];
  31. extern const int16_t AudioWindowHamming256[];
  32. extern const int16_t AudioWindowCosine256[];
  33. extern const int16_t AudioWindowTukey256[];
  34. }
  35. class AudioAnalyzeFFT256 : public AudioStream
  36. {
  37. public:
  38. AudioAnalyzeFFT256(uint8_t navg = 8, const int16_t *win = AudioWindowHanning256)
  39. : AudioStream(1, inputQueueArray), outputflag(false),
  40. prevblock(NULL), count(0), naverage(navg), window(win) { init(); }
  41. bool available() {
  42. if (outputflag == true) {
  43. outputflag = false;
  44. return true;
  45. }
  46. return false;
  47. }
  48. virtual void update(void);
  49. //uint32_t cycles;
  50. int32_t output[128] __attribute__ ((aligned (4)));
  51. private:
  52. void init(void);
  53. const int16_t *window;
  54. audio_block_t *prevblock;
  55. int16_t buffer[512] __attribute__ ((aligned (4)));
  56. uint8_t count;
  57. uint8_t naverage;
  58. bool outputflag;
  59. audio_block_t *inputQueueArray[1];
  60. };
  61. class AudioSynthWaveform : public AudioStream
  62. {
  63. public:
  64. AudioSynthWaveform(const int16_t *waveform)
  65. : AudioStream(0, NULL), wavetable(waveform), magnitude(0), phase(0) { }
  66. void frequency(float freq) {
  67. if (freq > AUDIO_SAMPLE_RATE_EXACT / 2 || freq < 0.0) return;
  68. phase_increment = (freq / AUDIO_SAMPLE_RATE_EXACT) * 4294967296.0f;
  69. }
  70. void amplitude(float n) { // 0 to 1.0
  71. if (n < 0) n = 0;
  72. else if (n > 1.0) n = 1.0;
  73. magnitude = n * 32767.0;
  74. }
  75. virtual void update(void);
  76. private:
  77. const int16_t *wavetable;
  78. uint16_t magnitude;
  79. uint32_t phase;
  80. uint32_t phase_increment;
  81. };
  82. #if 0
  83. class AudioSineWaveMod : public AudioStream
  84. {
  85. public:
  86. AudioSineWaveMod() : AudioStream(1, inputQueueArray) {}
  87. void frequency(float freq);
  88. //void amplitude(q15 n);
  89. virtual void update(void);
  90. private:
  91. uint32_t phase;
  92. uint32_t phase_increment;
  93. uint32_t modulation_factor;
  94. audio_block_t *inputQueueArray[1];
  95. };
  96. #endif
  97. class AudioOutputPWM : public AudioStream
  98. {
  99. public:
  100. AudioOutputPWM(void) : AudioStream(1, inputQueueArray) { begin(); }
  101. virtual void update(void);
  102. void begin(void);
  103. friend void dma_ch3_isr(void);
  104. private:
  105. static audio_block_t *block_1st;
  106. static audio_block_t *block_2nd;
  107. static uint32_t block_offset;
  108. static bool update_responsibility;
  109. static uint8_t interrupt_count;
  110. audio_block_t *inputQueueArray[1];
  111. };
  112. class AudioOutputAnalog : public AudioStream
  113. {
  114. public:
  115. AudioOutputAnalog(void) : AudioStream(1, inputQueueArray) { begin(); }
  116. virtual void update(void);
  117. void begin(void);
  118. void analogReference(int ref);
  119. friend void dma_ch4_isr(void);
  120. private:
  121. static audio_block_t *block_left_1st;
  122. static audio_block_t *block_left_2nd;
  123. static bool update_responsibility;
  124. audio_block_t *inputQueueArray[1];
  125. };
  126. class AudioPrint : public AudioStream
  127. {
  128. public:
  129. AudioPrint(const char *str) : AudioStream(1, inputQueueArray), name(str) {}
  130. virtual void update(void);
  131. private:
  132. const char *name;
  133. audio_block_t *inputQueueArray[1];
  134. };
  135. class AudioInputI2S : public AudioStream
  136. {
  137. public:
  138. AudioInputI2S(void) : AudioStream(0, NULL) { begin(); }
  139. virtual void update(void);
  140. void begin(void);
  141. friend void dma_ch1_isr(void);
  142. protected:
  143. AudioInputI2S(int dummy): AudioStream(0, NULL) {} // to be used only inside AudioInputI2Sslave !!
  144. static bool update_responsibility;
  145. private:
  146. static audio_block_t *block_left;
  147. static audio_block_t *block_right;
  148. static uint16_t block_offset;
  149. };
  150. class AudioOutputI2S : public AudioStream
  151. {
  152. public:
  153. AudioOutputI2S(void) : AudioStream(2, inputQueueArray) { begin(); }
  154. virtual void update(void);
  155. void begin(void);
  156. friend void dma_ch0_isr(void);
  157. friend class AudioInputI2S;
  158. protected:
  159. AudioOutputI2S(int dummy): AudioStream(2, inputQueueArray) {} // to be used only inside AudioOutputI2Sslave !!
  160. static void config_i2s(void);
  161. static audio_block_t *block_left_1st;
  162. static audio_block_t *block_right_1st;
  163. static bool update_responsibility;
  164. private:
  165. static audio_block_t *block_left_2nd;
  166. static audio_block_t *block_right_2nd;
  167. static uint16_t block_left_offset;
  168. static uint16_t block_right_offset;
  169. audio_block_t *inputQueueArray[2];
  170. };
  171. class AudioInputI2Sslave : public AudioInputI2S
  172. {
  173. public:
  174. AudioInputI2Sslave(void) : AudioInputI2S(0) { begin(); }
  175. void begin(void);
  176. friend void dma_ch1_isr(void);
  177. };
  178. class AudioOutputI2Sslave : public AudioOutputI2S
  179. {
  180. public:
  181. AudioOutputI2Sslave(void) : AudioOutputI2S(0) { begin(); } ;
  182. void begin(void);
  183. friend class AudioInputI2Sslave;
  184. friend void dma_ch0_isr(void);
  185. protected:
  186. static void config_i2s(void);
  187. };
  188. class AudioInputAnalog : public AudioStream
  189. {
  190. public:
  191. AudioInputAnalog(unsigned int pin) : AudioStream(0, NULL) { begin(pin); }
  192. virtual void update(void);
  193. void begin(unsigned int pin);
  194. friend void dma_ch2_isr(void);
  195. private:
  196. static audio_block_t *block_left;
  197. static uint16_t block_offset;
  198. uint16_t dc_average;
  199. static bool update_responsibility;
  200. };
  201. #include "SD.h"
  202. class AudioPlaySDcardWAV : public AudioStream
  203. {
  204. public:
  205. AudioPlaySDcardWAV(void) : AudioStream(0, NULL) { begin(); }
  206. void begin(void);
  207. bool play(const char *filename);
  208. void stop(void);
  209. bool start(void);
  210. virtual void update(void);
  211. private:
  212. File wavfile;
  213. bool consume(void);
  214. bool parse_format(void);
  215. uint32_t header[5];
  216. uint32_t data_length; // number of bytes remaining in data section
  217. audio_block_t *block_left;
  218. audio_block_t *block_right;
  219. uint16_t block_offset;
  220. uint8_t buffer[512];
  221. uint16_t buffer_remaining;
  222. uint8_t state;
  223. uint8_t state_play;
  224. uint8_t leftover_bytes;
  225. };
  226. class AudioPlaySDcardRAW : public AudioStream
  227. {
  228. public:
  229. AudioPlaySDcardRAW(void) : AudioStream(0, NULL) { begin(); }
  230. void begin(void);
  231. bool play(const char *filename);
  232. void stop(void);
  233. virtual void update(void);
  234. private:
  235. File rawfile;
  236. audio_block_t *block;
  237. bool playing;
  238. bool paused;
  239. };
  240. class AudioPlayMemory : public AudioStream
  241. {
  242. public:
  243. AudioPlayMemory(void) : AudioStream(0, NULL), playing(0) { }
  244. void play(const unsigned int *data);
  245. void stop(void);
  246. virtual void update(void);
  247. private:
  248. const unsigned int *next;
  249. uint32_t length;
  250. int16_t prior;
  251. volatile uint8_t playing;
  252. };
  253. class AudioMixer4 : public AudioStream
  254. {
  255. public:
  256. AudioMixer4(void) : AudioStream(4, inputQueueArray) {
  257. for (int i=0; i<4; i++) multiplier[i] = 65536;
  258. }
  259. virtual void update(void);
  260. void gain(unsigned int channel, float gain) {
  261. if (channel >= 4) return;
  262. if (gain > 32767.0f) gain = 32767.0f;
  263. else if (gain < 0.0f) gain = 0.0f;
  264. multiplier[channel] = gain * 65536.0f; // TODO: proper roundoff?
  265. }
  266. private:
  267. int32_t multiplier[4];
  268. audio_block_t *inputQueueArray[4];
  269. };
  270. class AudioFilterBiquad : public AudioStream
  271. {
  272. public:
  273. AudioFilterBiquad(int *parameters)
  274. : AudioStream(1, inputQueueArray), definition(parameters) { }
  275. virtual void update(void);
  276. void updateCoefs(int *source, bool doReset);
  277. void updateCoefs(int *source);
  278. private:
  279. int *definition;
  280. audio_block_t *inputQueueArray[1];
  281. };
  282. class AudioEffectFade : public AudioStream
  283. {
  284. public:
  285. AudioEffectFade(void)
  286. : AudioStream(1, inputQueueArray), position(0xFFFFFFFF) {}
  287. void fadeIn(uint32_t milliseconds) {
  288. uint32_t samples = (uint32_t)(milliseconds * 441u + 5u) / 10u;
  289. //Serial.printf("fadeIn, %u samples\n", samples);
  290. fadeBegin(0xFFFFFFFFu / samples, 1);
  291. }
  292. void fadeOut(uint32_t milliseconds) {
  293. uint32_t samples = (uint32_t)(milliseconds * 441u + 5u) / 10u;
  294. //Serial.printf("fadeOut, %u samples\n", samples);
  295. fadeBegin(0xFFFFFFFFu / samples, 0);
  296. }
  297. virtual void update(void);
  298. private:
  299. void fadeBegin(uint32_t newrate, uint8_t dir);
  300. uint32_t position; // 0 = off, 0xFFFFFFFF = on
  301. uint32_t rate;
  302. uint8_t direction; // 0 = fading out, 1 = fading in
  303. audio_block_t *inputQueueArray[1];
  304. };
  305. class AudioAnalyzeToneDetect : public AudioStream
  306. {
  307. public:
  308. AudioAnalyzeToneDetect(void)
  309. : AudioStream(1, inputQueueArray), thresh(6554), enabled(false) { }
  310. void frequency(float freq, uint16_t cycles=10) {
  311. set_params((int32_t)(cos((double)freq
  312. * (2.0 * 3.14159265358979323846 / AUDIO_SAMPLE_RATE_EXACT))
  313. * (double)2147483647.999), cycles,
  314. (float)AUDIO_SAMPLE_RATE_EXACT / freq * (float)cycles + 0.5f);
  315. }
  316. void set_params(int32_t coef, uint16_t cycles, uint16_t len);
  317. bool available(void) {
  318. __disable_irq();
  319. bool flag = new_output;
  320. if (flag) new_output = false;
  321. __enable_irq();
  322. return flag;
  323. }
  324. float read(void);
  325. void threshold(float level) {
  326. if (level < 0.01f) thresh = 655;
  327. else if (level > 0.99f) thresh = 64881;
  328. else thresh = level * 65536.0f + 0.5f;
  329. }
  330. operator bool(); // true if at or above threshold, false if below
  331. virtual void update(void);
  332. private:
  333. int32_t coefficient; // Goertzel algorithm coefficient
  334. int32_t s1, s2; // Goertzel algorithm state
  335. int32_t out1, out2; // Goertzel algorithm state output
  336. uint16_t length; // number of samples to analyze
  337. uint16_t count; // how many left to analyze
  338. uint16_t ncycles; // number of waveform cycles to seek
  339. uint16_t thresh; // threshold, 655 to 64881 (1% to 99%)
  340. bool enabled;
  341. volatile bool new_output;
  342. audio_block_t *inputQueueArray[1];
  343. };
  344. // TODO: more audio processing objects....
  345. // sine wave with frequency modulation (phase)
  346. // waveforms with bandwidth limited tables for synth
  347. // envelope: attack-decay-sustain-release, maybe other more complex?
  348. // MP3 decoding - it is possible with optimized code?
  349. // other decompression, ADPCM, Vorbis, Speex, etc?
  350. // A base class for all Codecs, DACs and ADCs, so at least the
  351. // most basic functionality is consistent.
  352. #define AUDIO_INPUT_LINEIN 0
  353. #define AUDIO_INPUT_MIC 1
  354. class AudioControl
  355. {
  356. public:
  357. virtual bool enable(void) = 0;
  358. virtual bool disable(void) = 0;
  359. virtual bool volume(float volume) = 0; // volume 0.0 to 100.0
  360. virtual bool inputLevel(float volume) = 0; // volume 0.0 to 100.0
  361. virtual bool inputSelect(int n) = 0;
  362. };
  363. class AudioControlWM8731 : public AudioControl
  364. {
  365. public:
  366. bool enable(void);
  367. bool disable(void) { return false; }
  368. bool volume(float n) { return volumeInteger(n * 0.8 + 47.499); }
  369. bool inputLevel(float n) { return false; }
  370. bool inputSelect(int n) { return false; }
  371. protected:
  372. bool write(unsigned int reg, unsigned int val);
  373. bool volumeInteger(unsigned int n); // range: 0x2F to 0x7F
  374. };
  375. class AudioControlWM8731master : public AudioControlWM8731
  376. {
  377. public:
  378. bool enable(void);
  379. };
  380. class AudioControlSGTL5000 : public AudioControl
  381. {
  382. public:
  383. bool enable(void);
  384. bool disable(void) { return false; }
  385. bool volume(float n) { return volumeInteger(n * 1.29 + 0.499); }
  386. bool inputLevel(float n) {return false;}
  387. bool muteHeadphone(void) { return write(0x0024, ana_ctrl | (1<<4)); }
  388. bool unmuteHeadphone(void) { return write(0x0024, ana_ctrl & ~(1<<4)); }
  389. bool muteLineout(void) { return write(0x0024, ana_ctrl | (1<<8)); }
  390. bool unmuteLineout(void) { return write(0x0024, ana_ctrl & ~(1<<8)); }
  391. bool inputSelect(int n) {
  392. if (n == AUDIO_INPUT_LINEIN) {
  393. return write(0x0024, ana_ctrl | (1<<2));
  394. } else if (n == AUDIO_INPUT_MIC) {
  395. //return write(0x002A, 0x0172) && write(0x0024, ana_ctrl & ~(1<<2));
  396. return write(0x002A, 0x0173) && write(0x0024, ana_ctrl & ~(1<<2)); // +40dB
  397. } else {
  398. return false;
  399. }
  400. }
  401. //bool inputLinein(void) { return write(0x0024, ana_ctrl | (1<<2)); }
  402. //bool inputMic(void) { return write(0x002A, 0x0172) && write(0x0024, ana_ctrl & ~(1<<2)); }
  403. unsigned short micGain(unsigned int n) { return modify(0x002A, n&3, 3); }
  404. unsigned short hp_vol_right(float n);
  405. unsigned short hp_vol_left(float n);
  406. unsigned short lo_lvl_right(uint8_t n);
  407. unsigned short lo_lvl_left(uint8_t n);
  408. unsigned short lo_lvl(uint8_t n);
  409. unsigned short dac_vol_right(float n);
  410. unsigned short dac_vol_left(float n);
  411. unsigned short dac_vol(float n);
  412. unsigned short dap_mix_enable(uint8_t n);
  413. unsigned short dap_enable(uint8_t n);
  414. unsigned short dap_enable(void);
  415. unsigned short dap_peqs(uint8_t n);
  416. unsigned short dap_audio_eq(uint8_t n);
  417. unsigned short dap_audio_eq_band(uint8_t bandNum, float n);
  418. void dap_audio_eq_geq(float bass, float mid_bass, float midrange, float mid_treble, float treble);
  419. void dap_audio_eq_tone(float bass, float treble);
  420. void load_peq(uint8_t filterNum, int *filterParameters);
  421. protected:
  422. bool muted;
  423. bool volumeInteger(unsigned int n); // range: 0x00 to 0x80
  424. uint16_t ana_ctrl;
  425. unsigned char calcVol(float n, unsigned char range);
  426. unsigned int read(unsigned int reg);
  427. bool write(unsigned int reg, unsigned int val);
  428. unsigned int modify(unsigned int reg, unsigned int val, unsigned int iMask);
  429. };
  430. //For Filter Type: 0 = LPF, 1 = HPF, 2 = BPF, 3 = NOTCH, 4 = PeakingEQ, 5 = LowShelf, 6 = HighShelf
  431. #define FILTER_LOPASS 0
  432. #define FILTER_HIPASS 1
  433. #define FILTER_BANDPASS 2
  434. #define FILTER_NOTCH 3
  435. #define FILTER_PARAEQ 4
  436. #define FILTER_LOSHELF 5
  437. #define FILTER_HISHELF 6
  438. void calcBiquad(uint8_t filtertype, float fC, float dB_Gain, float Q, uint32_t quantization_unit, uint32_t fS, int *coef);