/******************************************************************/ | |||||
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(); | |||||
} | |||||
/******************************************************************/ | /******************************************************************/ | ||||
bool AudioControlSGTL5000::enable(void) | bool AudioControlSGTL5000::enable(void) | ||||
{ | { | ||||
unsigned int n; | |||||
//unsigned int n; | |||||
muted = true; | muted = true; | ||||
Wire.begin(); | Wire.begin(); | ||||
delay(5); | 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_ANA_POWER, 0x4060); // VDDD is externally driven with 1.8V | ||||
write(CHIP_LINREG_CTRL, 0x006C); // VDDA & VDDIO both over 3.1V | write(CHIP_LINREG_CTRL, 0x006C); // VDDA & VDDIO both over 3.1V |
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]; | |||||
}; | |||||
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 |