| @@ -2186,6 +2186,77 @@ void AudioFilterBiquad::update(void) | |||
| /******************************************************************/ | |||
| extern "C" { | |||
| extern const int16_t fader_table[256]; | |||
| }; | |||
| void AudioEffectFade::update(void) | |||
| { | |||
| audio_block_t *block; | |||
| uint32_t i, pos, inc, index, scale; | |||
| int32_t val1, val2, val, sample; | |||
| uint8_t dir; | |||
| pos = position; | |||
| if (pos == 0) { | |||
| // output is silent | |||
| block = receiveReadOnly(); | |||
| if (block) release(block); | |||
| return; | |||
| } else if (pos == 0xFFFFFFFF) { | |||
| // output is 100% | |||
| block = receiveReadOnly(); | |||
| if (!block) return; | |||
| transmit(block); | |||
| release(block); | |||
| return; | |||
| } | |||
| block = receiveWritable(); | |||
| if (!block) return; | |||
| inc = rate; | |||
| dir = direction; | |||
| for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) { | |||
| index = pos >> 24; | |||
| val1 = fader_table[index]; | |||
| val2 = fader_table[index+1]; | |||
| scale = (pos >> 8) & 0xFFFF; | |||
| val2 *= scale; | |||
| val1 *= 0x10000 - scale; | |||
| val = (val1 + val2) >> 16; | |||
| sample = block->data[i]; | |||
| sample = (sample * val) >> 15; | |||
| block->data[i] = sample; | |||
| if (dir > 0) { | |||
| // output is increasing | |||
| if (inc < 0xFFFFFFFF - pos) pos += inc; | |||
| else pos = 0xFFFFFFFF; | |||
| } else { | |||
| // output is decreasing | |||
| if (inc < pos) pos -= inc; | |||
| else pos = 0; | |||
| } | |||
| } | |||
| position = pos; | |||
| transmit(block); | |||
| release(block); | |||
| } | |||
| void AudioEffectFade::fadeBegin(uint32_t newrate, uint8_t dir) | |||
| { | |||
| __disable_irq(); | |||
| uint32_t pos = position; | |||
| if (pos == 0) position = 1; | |||
| else if (pos == 0xFFFFFFFF) position = 0xFFFFFFFE; | |||
| rate = newrate; | |||
| direction = dir; | |||
| __enable_irq(); | |||
| } | |||
| /******************************************************************/ | |||
| @@ -2901,15 +2972,15 @@ bool AudioControlWM8731master::enable(void) | |||
| bool AudioControlSGTL5000::enable(void) | |||
| { | |||
| unsigned int n; | |||
| //unsigned int n; | |||
| muted = true; | |||
| Wire.begin(); | |||
| delay(5); | |||
| Serial.print("chip ID = "); | |||
| delay(5); | |||
| n = read(CHIP_ID); | |||
| Serial.println(n, HEX); | |||
| //Serial.print("chip ID = "); | |||
| //delay(5); | |||
| //n = read(CHIP_ID); | |||
| //Serial.println(n, HEX); | |||
| write(CHIP_ANA_POWER, 0x4060); // VDDD is externally driven with 1.8V | |||
| write(CHIP_LINREG_CTRL, 0x006C); // VDDA & VDDIO both over 3.1V | |||
| @@ -384,7 +384,29 @@ private: | |||
| class AudioEffectFade : public AudioStream | |||
| { | |||
| public: | |||
| AudioEffectFade(void) | |||
| : AudioStream(1, inputQueueArray), position(0xFFFFFFFF) {} | |||
| void fadeIn(uint32_t milliseconds) { | |||
| uint32_t samples = (uint32_t)(milliseconds * 441u + 5u) / 10u; | |||
| //Serial.printf("fadeIn, %u samples\n", samples); | |||
| fadeBegin(0xFFFFFFFFu / samples, 1); | |||
| } | |||
| void fadeOut(uint32_t milliseconds) { | |||
| uint32_t samples = (uint32_t)(milliseconds * 441u + 5u) / 10u; | |||
| //Serial.printf("fadeOut, %u samples\n", samples); | |||
| fadeBegin(0xFFFFFFFFu / samples, 0); | |||
| } | |||
| virtual void update(void); | |||
| private: | |||
| void fadeBegin(uint32_t newrate, uint8_t dir); | |||
| uint32_t position; // 0 = off, 0xFFFFFFFF = on | |||
| uint32_t rate; | |||
| uint8_t direction; // 0 = fading out, 1 = fading in | |||
| audio_block_t *inputQueueArray[1]; | |||
| }; | |||
| @@ -205,4 +205,46 @@ print "};\n"; | |||
| const int16_t fader_table[257] = { | |||
| 0, 1, 4, 11, 19, 30, 44, 60, 78, 99, | |||
| 123, 149, 177, 208, 241, 276, 314, 355, 398, 443, | |||
| 490, 541, 593, 648, 705, 764, 826, 891, 957, 1026, | |||
| 1097, 1171, 1247, 1325, 1405, 1488, 1572, 1660, 1749, 1840, | |||
| 1934, 2030, 2128, 2228, 2330, 2435, 2541, 2650, 2761, 2873, | |||
| 2988, 3105, 3224, 3344, 3467, 3592, 3718, 3847, 3977, 4109, | |||
| 4243, 4379, 4517, 4657, 4798, 4941, 5086, 5232, 5380, 5530, | |||
| 5682, 5835, 5989, 6145, 6303, 6462, 6623, 6785, 6949, 7114, | |||
| 7281, 7448, 7618, 7788, 7960, 8133, 8307, 8483, 8660, 8838, | |||
| 9017, 9197, 9378, 9560, 9743, 9928,10113,10299,10486,10674, | |||
| 10863,11053,11244,11435,11627,11820,12013,12207,12402,12597, | |||
| 12793,12989,13186,13384,13582,13780,13979,14178,14377,14577, | |||
| 14777,14977,15177,15378,15579,15780,15981,16182,16383,16584, | |||
| 16785,16986,17187,17387,17588,17788,17989,18188,18388,18588, | |||
| 18787,18985,19184,19382,19579,19776,19972,20168,20364,20558, | |||
| 20752,20946,21139,21331,21522,21712,21902,22091,22279,22466, | |||
| 22652,22838,23022,23205,23388,23569,23749,23928,24106,24283, | |||
| 24458,24633,24806,24977,25148,25317,25485,25651,25817,25980, | |||
| 26142,26303,26463,26620,26776,26931,27084,27236,27385,27534, | |||
| 27680,27825,27968,28109,28249,28386,28522,28656,28789,28919, | |||
| 29048,29174,29299,29422,29542,29661,29778,29893,30006,30116, | |||
| 30225,30331,30436,30538,30638,30736,30832,30926,31017,31107, | |||
| 31194,31279,31361,31442,31520,31596,31669,31740,31809,31876, | |||
| 31940,32002,32062,32119,32174,32226,32276,32324,32369,32412, | |||
| 32452,32490,32526,32559,32590,32618,32644,32667,32688,32707, | |||
| 32723,32737,32748,32756,32763,32766,32767 | |||
| }; | |||
| #if 0 | |||
| #! /usr/bin/perl | |||
| print "const int16_t fader_table[257] = {\n"; | |||
| $len = 256; | |||
| for ($i=0; $i < $len+1; $i++) { | |||
| $a = cos(3.14149 * $i / $len); | |||
| $in = (1 - $a) / 2; | |||
| $d = $in * 32768; | |||
| $d = 32767 if $d >= 32767.5; | |||
| printf "%5d", $d; | |||
| print "," if ($i < $len); | |||
| print "\n" if ($i % 10) == 9; | |||
| } | |||
| print "\n};\n"; | |||
| #endif | |||