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.

преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. #include "AudioStream.h"
  2. // waveforms.c
  3. extern "C" {
  4. extern const int16_t AudioWaveformSine[257];
  5. extern const int16_t AudioWaveformTriangle[257];
  6. extern const int16_t AudioWaveformSquare[257];
  7. extern const int16_t AudioWaveformSawtooth[257];
  8. }
  9. // windows.c
  10. extern "C" {
  11. extern const int16_t AudioWindowHanning256[];
  12. extern const int16_t AudioWindowBartlett256[];
  13. extern const int16_t AudioWindowBlackman256[];
  14. extern const int16_t AudioWindowFlattop256[];
  15. extern const int16_t AudioWindowBlackmanHarris256[];
  16. extern const int16_t AudioWindowNuttall256[];
  17. extern const int16_t AudioWindowBlackmanNuttall256[];
  18. extern const int16_t AudioWindowWelch256[];
  19. extern const int16_t AudioWindowHamming256[];
  20. extern const int16_t AudioWindowCosine256[];
  21. extern const int16_t AudioWindowTukey256[];
  22. }
  23. class AudioAnalyzeFFT256 : public AudioStream
  24. {
  25. public:
  26. AudioAnalyzeFFT256(uint8_t navg = 8, const int16_t *win = AudioWindowHanning256)
  27. : AudioStream(1, inputQueueArray), outputflag(false),
  28. prevblock(NULL), count(0), naverage(navg), window(win) { init(); }
  29. bool available() {
  30. if (outputflag == true) {
  31. outputflag = false;
  32. return true;
  33. }
  34. return false;
  35. }
  36. virtual void update(void);
  37. //uint32_t cycles;
  38. int32_t output[128] __attribute__ ((aligned (4)));
  39. private:
  40. void init(void);
  41. const int16_t *window;
  42. audio_block_t *prevblock;
  43. int16_t buffer[512] __attribute__ ((aligned (4)));
  44. uint8_t count;
  45. uint8_t naverage;
  46. bool outputflag;
  47. audio_block_t *inputQueueArray[1];
  48. };
  49. class AudioSynthWaveform : public AudioStream
  50. {
  51. public:
  52. AudioSynthWaveform(const int16_t *waveform)
  53. : AudioStream(0, NULL), wavetable(waveform), magnitude(0), phase(0) { }
  54. void frequency(float freq) {
  55. if (freq > AUDIO_SAMPLE_RATE_EXACT / 2 || freq < 0.0) return;
  56. phase_increment = (freq / AUDIO_SAMPLE_RATE_EXACT) * 4294967296.0f;
  57. }
  58. void amplitude(float n) { // 0 to 1.0
  59. if (n < 0) n = 0;
  60. else if (n > 1.0) n = 1.0;
  61. magnitude = n * 32767.0;
  62. }
  63. virtual void update(void);
  64. private:
  65. const int16_t *wavetable;
  66. uint16_t magnitude;
  67. uint32_t phase;
  68. uint32_t phase_increment;
  69. };
  70. #if 0
  71. class AudioSineWaveMod : public AudioStream
  72. {
  73. public:
  74. AudioSineWaveMod() : AudioStream(1, inputQueueArray) {}
  75. void frequency(float freq);
  76. //void amplitude(q15 n);
  77. virtual void update(void);
  78. private:
  79. uint32_t phase;
  80. uint32_t phase_increment;
  81. uint32_t modulation_factor;
  82. audio_block_t *inputQueueArray[1];
  83. };
  84. #endif
  85. class AudioOutputPWM : public AudioStream
  86. {
  87. public:
  88. AudioOutputPWM(void) : AudioStream(1, inputQueueArray) { begin(); }
  89. virtual void update(void);
  90. void begin(void);
  91. friend void dma_ch3_isr(void);
  92. private:
  93. static audio_block_t *block_1st;
  94. static audio_block_t *block_2nd;
  95. static uint32_t block_offset;
  96. static bool update_responsibility;
  97. static uint8_t interrupt_count;
  98. audio_block_t *inputQueueArray[1];
  99. };
  100. class AudioOutputAnalog : public AudioStream
  101. {
  102. public:
  103. AudioOutputAnalog(void) : AudioStream(1, inputQueueArray) { begin(); }
  104. virtual void update(void);
  105. void begin(void);
  106. void analogReference(int ref);
  107. friend void dma_ch4_isr(void);
  108. private:
  109. static audio_block_t *block_left_1st;
  110. static audio_block_t *block_left_2nd;
  111. static bool update_responsibility;
  112. audio_block_t *inputQueueArray[1];
  113. };
  114. class AudioPrint : public AudioStream
  115. {
  116. public:
  117. AudioPrint(const char *str) : AudioStream(1, inputQueueArray), name(str) {}
  118. virtual void update(void);
  119. private:
  120. const char *name;
  121. audio_block_t *inputQueueArray[1];
  122. };
  123. class AudioInputI2S : public AudioStream
  124. {
  125. public:
  126. AudioInputI2S(void) : AudioStream(0, NULL) { begin(); }
  127. virtual void update(void);
  128. void begin(void);
  129. friend void dma_ch1_isr(void);
  130. private:
  131. static audio_block_t *block_left;
  132. static audio_block_t *block_right;
  133. static uint16_t block_offset;
  134. static bool update_responsibility; // TODO: implement and test this.
  135. };
  136. class AudioOutputI2S : public AudioStream
  137. {
  138. public:
  139. AudioOutputI2S(void) : AudioStream(2, inputQueueArray) { begin(); }
  140. virtual void update(void);
  141. void begin(void);
  142. friend void dma_ch0_isr(void);
  143. friend class AudioInputI2S;
  144. private:
  145. static void config_i2s(void);
  146. static audio_block_t *block_left_1st;
  147. static audio_block_t *block_right_1st;
  148. static audio_block_t *block_left_2nd;
  149. static audio_block_t *block_right_2nd;
  150. static uint16_t block_left_offset;
  151. static uint16_t block_right_offset;
  152. static bool update_responsibility;
  153. audio_block_t *inputQueueArray[2];
  154. };
  155. class AudioInputAnalog : public AudioStream
  156. {
  157. public:
  158. AudioInputAnalog(unsigned int pin) : AudioStream(0, NULL) { begin(pin); }
  159. virtual void update(void);
  160. void begin(unsigned int pin);
  161. friend void dma_ch2_isr(void);
  162. private:
  163. static audio_block_t *block_left;
  164. static uint16_t block_offset;
  165. uint16_t dc_average;
  166. //static bool update_responsibility; // TODO: implement and test this.
  167. };
  168. #include "SD.h"
  169. class AudioPlaySDcardWAV : public AudioStream
  170. {
  171. public:
  172. AudioPlaySDcardWAV(void) : AudioStream(0, NULL) { begin(); }
  173. void begin(void);
  174. bool play(const char *filename);
  175. void stop(void);
  176. bool start(void);
  177. virtual void update(void);
  178. private:
  179. File wavfile;
  180. bool consume(void);
  181. bool parse_format(void);
  182. uint32_t header[5];
  183. uint32_t data_length; // number of bytes remaining in data section
  184. audio_block_t *block_left;
  185. audio_block_t *block_right;
  186. uint16_t block_offset;
  187. uint8_t buffer[512];
  188. uint16_t buffer_remaining;
  189. uint8_t state;
  190. uint8_t state_play;
  191. uint8_t leftover_bytes;
  192. };
  193. class AudioPlaySDcardRAW : public AudioStream
  194. {
  195. public:
  196. AudioPlaySDcardRAW(void) : AudioStream(0, NULL) { begin(); }
  197. void begin(void);
  198. bool play(const char *filename);
  199. void stop(void);
  200. virtual void update(void);
  201. private:
  202. File rawfile;
  203. audio_block_t *block;
  204. bool playing;
  205. bool paused;
  206. };
  207. class AudioPlayMemory : public AudioStream
  208. {
  209. public:
  210. AudioPlayMemory(void) : AudioStream(0, NULL), playing(0) { }
  211. void play(const unsigned int *data);
  212. void stop(void);
  213. virtual void update(void);
  214. private:
  215. const unsigned int *next;
  216. uint32_t length;
  217. int16_t prior;
  218. volatile uint8_t playing;
  219. };
  220. class AudioMixer4 : public AudioStream
  221. {
  222. public:
  223. AudioMixer4(void) : AudioStream(4, inputQueueArray) {
  224. for (int i=0; i<4; i++) multiplier[i] = 65536;
  225. }
  226. virtual void update(void);
  227. void gain(unsigned int channel, float gain) {
  228. if (channel >= 4) return;
  229. if (gain > 32767.0f) gain = 32767.0f;
  230. else if (gain < 0.0f) gain = 0.0f;
  231. multiplier[channel] = gain * 65536.0f; // TODO: proper roundoff?
  232. }
  233. private:
  234. int32_t multiplier[4];
  235. audio_block_t *inputQueueArray[4];
  236. };
  237. // TODO: more audio processing objects....
  238. // N-channel mixer, adjustable gain on each channel
  239. // sine wave with frequency modulation (phase)
  240. // non-sine oscillators, ramp, triangle, square/pulse, etc
  241. // envelope: attack-decay-sustain-release, maybe other more complex?
  242. // filters, low pass, high pass, bandpass, notch
  243. // frequency analysis - FFT, single frequency (eg, filter for DTMF)
  244. // MP3 decoding - it is possible with optimized code?
  245. // other decompression, ADPCM, Vorbis, Speex, etc?
  246. // A base class for all Codecs, DACs and ADCs, so at least the
  247. // most basic functionality is consistent.
  248. #define AUDIO_INPUT_LINEIN 0
  249. #define AUDIO_INPUT_MIC 1
  250. class AudioControl
  251. {
  252. public:
  253. virtual bool enable(void) = 0;
  254. virtual bool disable(void) = 0;
  255. virtual bool volume(float volume) = 0; // volume 0.0 to 100.0
  256. virtual bool inputLevel(float volume) = 0; // volume 0.0 to 100.0
  257. virtual bool inputSelect(int n) = 0;
  258. };
  259. class AudioControlWM8731 : public AudioControl
  260. {
  261. public:
  262. bool enable(void);
  263. bool volume(float n) { return volumeInteger(n * 0.8 + 47.499); }
  264. bool inputLevel(float n) { return false; }
  265. bool inputSelect(int n) { return false; }
  266. protected:
  267. bool write(unsigned int reg, unsigned int val);
  268. bool volumeInteger(unsigned int n); // range: 0x2F to 0x7F
  269. };
  270. class AudioControlSGTL5000 : public AudioControl
  271. {
  272. public:
  273. bool enable(void);
  274. bool disable(void) { return false; }
  275. bool volume(float n) { return volumeInteger(n * 1.29 + 0.499); }
  276. bool inputLevel(float n) {return false;}
  277. bool muteHeadphone(void) { return write(0x0024, ana_ctrl | (1<<4)); }
  278. bool unmuteHeadphone(void) { return write(0x0024, ana_ctrl & ~(1<<4)); }
  279. bool muteLineout(void) { return write(0x0024, ana_ctrl | (1<<8)); }
  280. bool unmuteLineout(void) { return write(0x0024, ana_ctrl & ~(1<<8)); }
  281. bool inputSelect(int n) {
  282. if (n == AUDIO_INPUT_LINEIN) {
  283. return write(0x0024, ana_ctrl | (1<<2));
  284. } else if (n == AUDIO_INPUT_MIC) {
  285. //return write(0x002A, 0x0172) && write(0x0024, ana_ctrl & ~(1<<2));
  286. return write(0x002A, 0x0173) && write(0x0024, ana_ctrl & ~(1<<2)); // +40dB
  287. } else {
  288. return false;
  289. }
  290. }
  291. //bool inputLinein(void) { return write(0x0024, ana_ctrl | (1<<2)); }
  292. //bool inputMic(void) { return write(0x002A, 0x0172) && write(0x0024, ana_ctrl & ~(1<<2)); }
  293. protected:
  294. bool muted;
  295. bool volumeInteger(unsigned int n); // range: 0x00 to 0x80
  296. uint16_t ana_ctrl;
  297. unsigned int read(unsigned int reg);
  298. bool write(unsigned int reg, unsigned int val);
  299. };