📄 psych.c
字号:
epartM = psyInfoL->energyMS[low]; npartM = nb_tmpM[low]; epartS = psyInfoR->energyMS[low]; npartS = nb_tmpS[low]; for (w = low+1; w < high; w++) { epartM += psyInfoL->energyMS[w]; epartS += psyInfoR->energyMS[w]; if (nb_tmpM[w] < npartM) npartM = nb_tmpM[w]; if (nb_tmpS[w] < npartS) npartS = nb_tmpS[w]; } npartM *= cb_width_long[b]; npartS *= cb_width_long[b]; psyInfoL->maskThrMS[b] = psyInfoL->maskThrNextMS[b]; psyInfoR->maskThrMS[b] = psyInfoR->maskThrNextMS[b]; psyInfoL->maskEnMS[b] = psyInfoL->maskEnNextMS[b]; psyInfoR->maskEnMS[b] = psyInfoR->maskEnNextMS[b]; psyInfoL->maskThrNextMS[b] = npartM; psyInfoR->maskThrNextMS[b] = npartS; psyInfoL->maskEnNextMS[b] = epartM; psyInfoR->maskEnNextMS[b] = epartS; { double thmL = psyInfoL->maskThr[b]; double thmR = psyInfoR->maskThr[b]; double thmM = psyInfoL->maskThrMS[b]; double thmS = psyInfoR->maskThrMS[b]; double msfix = 3.5; if (thmL*msfix < (thmM+thmS)/2) { double f = thmL*msfix / ((thmM+thmS)/2); thmM *= f; thmS *= f; } if (thmR*msfix < (thmM+thmS)/2) { double f = thmR*msfix / ((thmM+thmS)/2); thmM *= f; thmS *= f; } psyInfoL->maskThrMS[b] = min(thmM,psyInfoL->maskThrMS[b]); psyInfoR->maskThrMS[b] = min(thmS,psyInfoR->maskThrMS[b]); if (psyInfoL->maskThr[b] * psyInfoR->maskThr[b] < psyInfoL->maskThrMS[b] * psyInfoR->maskThrMS[b]) channelInfoL->msInfo.ms_used[b] = 0; else channelInfoL->msInfo.ms_used[b] = 1; } }#ifdef _DEBUG printf("MSL:%3d ", ms_used);#endif /* Short windows */ for (j = 0; j < 8; j++) { /* Energy in each partition and weighted unpredictability */ high = 0; for (b = 0; b < gpsyInfo->psyPartS->len; b++) { double ebM, ebS; low = high; high += gpsyInfo->psyPartS->width[b]; ebM = psyInfoL->energySMS[j][low]; ebS = psyInfoR->energySMS[j][low]; for (w = low+1; w < high; w++) { ebM += psyInfoL->energySMS[j][w]; ebS += psyInfoR->energySMS[j][w]; } eM[b] = ebM; eS[b] = ebS; } /* Convolve the partitioned energy and unpredictability with the spreading function */ for (b = 0; b < gpsyInfo->psyPartS->len; b++) { /* Mid channel */ /* Get power ratio */ ecb = 0; for (bb = gpsyInfo->sprIndS[b][0]; bb <= gpsyInfo->sprIndS[b][1]; bb++) { ecb += gpsyInfo->spreadingS[b][bb] * eM[bb]; } /* Actual energy threshold */ nbM[b] = max(1e-6, ecb);/* nbM[b] = max(nbM[b], gpsyInfo->athS[b]);*/ /* Side channel */ /* Get power ratio */ ecb = 0; for (bb = gpsyInfo->sprIndS[b][0]; bb <= gpsyInfo->sprIndS[b][1]; bb++) { ecb += gpsyInfo->spreadingS[b][bb] * eS[bb]; } /* Actual energy threshold */ nbS[b] = max(1e-6, ecb);/* nbS[b] = max(nbS[b], gpsyInfo->athS[b]);*/ if (psyInfoL->nbS[j][b] <= 1.58*psyInfoR->nbS[j][b] && psyInfoR->nbS[j][b] <= 1.58*psyInfoL->nbS[j][b]) { mld = gpsyInfo->mldS[b]*eM[b]; tmp1 = max(nbM[b], min(nbS[b],mld)); mld = gpsyInfo->mldS[b]*eS[b]; tmp2 = max(nbS[b], min(nbM[b],mld)); nbM[b] = tmp1; nbS[b] = tmp2; } } high = 0; for (b = 0; b < gpsyInfo->psyPartS->len; b++) { low = high; high += gpsyInfo->psyPartS->width[b]; for (w = low; w < high; w++) { nb_tmpM[w] = nbM[b] / gpsyInfo->psyPartS->width[b]; nb_tmpS[w] = nbS[b] / gpsyInfo->psyPartS->width[b]; } } high = 0; for (b = 0; b < num_cb_short; b++) { low = high; high += cb_width_short[b]; epartM = psyInfoL->energySMS[j][low]; epartS = psyInfoR->energySMS[j][low]; npartM = nb_tmpM[low]; npartS = nb_tmpS[low]; for (w = low+1; w < high; w++) { epartM += psyInfoL->energySMS[j][w]; epartS += psyInfoR->energySMS[j][w]; if (nb_tmpM[w] < npartM) npartM = nb_tmpM[w]; if (nb_tmpS[w] < npartS) npartS = nb_tmpS[w]; } npartM *= cb_width_short[b]; npartS *= cb_width_short[b]; psyInfoL->maskThrSMS[j][b] = psyInfoL->maskThrNextSMS[j][b]; psyInfoR->maskThrSMS[j][b] = psyInfoR->maskThrNextSMS[j][b]; psyInfoL->maskEnSMS[j][b] = psyInfoL->maskEnNextSMS[j][b]; psyInfoR->maskEnSMS[j][b] = psyInfoR->maskEnNextSMS[j][b]; psyInfoL->maskThrNextSMS[j][b] = npartM; psyInfoR->maskThrNextSMS[j][b] = npartS; psyInfoL->maskEnNextSMS[j][b] = epartM; psyInfoR->maskEnNextSMS[j][b] = epartS; { double thmL = psyInfoL->maskThrS[j][b]; double thmR = psyInfoR->maskThrS[j][b]; double thmM = psyInfoL->maskThrSMS[j][b]; double thmS = psyInfoR->maskThrSMS[j][b]; double msfix = 3.5; if (thmL*msfix < (thmM+thmS)/2) { double f = thmL*msfix / ((thmM+thmS)/2); thmM *= f; thmS *= f; } if (thmR*msfix < (thmM+thmS)/2) { double f = thmR*msfix / ((thmM+thmS)/2); thmM *= f; thmS *= f; } psyInfoL->maskThrSMS[j][b] = min(thmM,psyInfoL->maskThrSMS[j][b]); psyInfoR->maskThrSMS[j][b] = min(thmS,psyInfoR->maskThrSMS[j][b]); if (psyInfoL->maskThrS[j][b] * psyInfoR->maskThrS[j][b] < psyInfoL->maskThrSMS[j][b] * psyInfoR->maskThrSMS[j][b]) channelInfoL->msInfo.ms_usedS[j][b] = 0; else channelInfoL->msInfo.ms_usedS[j][b] = 1; } } }#ifdef _DEBUG printf("MSS:%3d ", ms_usedS);#endif}void BlockSwitch(CoderInfo *coderInfo, PsyInfo *psyInfo, unsigned int numChannels){ unsigned int channel; int desire = ONLY_LONG_WINDOW; /* Use the same block type for all channels If there is 1 channel that wants a short block, use a short block on all channels. */ for (channel = 0; channel < numChannels; channel++) { if (psyInfo[channel].block_type == ONLY_SHORT_WINDOW) desire = ONLY_SHORT_WINDOW; } for (channel = 0; channel < numChannels; channel++) { if ((coderInfo[channel].block_type == ONLY_SHORT_WINDOW) || (coderInfo[channel].block_type == LONG_SHORT_WINDOW) ) { if ((coderInfo[channel].desired_block_type==ONLY_LONG_WINDOW) && (desire == ONLY_LONG_WINDOW) ) { coderInfo[channel].block_type = SHORT_LONG_WINDOW; } else { coderInfo[channel].block_type = ONLY_SHORT_WINDOW; } } else if (desire == ONLY_SHORT_WINDOW) { coderInfo[channel].block_type = LONG_SHORT_WINDOW; } else { coderInfo[channel].block_type = ONLY_LONG_WINDOW; } coderInfo[channel].desired_block_type = desire; }#ifdef _DEBUG printf("%s ", (coderInfo[0].block_type == ONLY_SHORT_WINDOW) ? "SHORT" : "LONG ");#endif}static double freq2bark(double freq){ double bark; if(freq > 200.0) bark = 26.81 / (1 + (1960 / freq)) - 0.53; else bark = freq / 102.9; return (bark);}static double ATHformula(double f){ double ath; f /= 1000; /* convert to khz */ f = max(0.01, f); f = min(18.0,f); /* from Painter & Spanias, 1997 */ /* modified by Gabriel Bouvigne to better fit to the reality */ ath = 3.640 * pow(f,-0.8) - 6.800 * exp(-0.6*pow(f-3.4,2.0)) + 6.000 * exp(-0.15*pow(f-8.7,2.0)) + 0.6* 0.001 * pow(f,4.0); return ath;}static PsyPartTable psyPartTableLong[12+1] ={ { 96000, 71, { /* width */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,4,4,4,5,5,5,6,6,7,7,8,8,9,10,10,11,12,13,14,15,16, 18,19,21,24,26,30,34,39,45,53,64,78,98,127,113 } }, { 88200, 72, { /* width */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,4,4,4,4,5,5,5,6,6,7,7,8,8,9,10,10,11,12,13,14,15, 16,18,19,21,23,26,29,32,37,42,49,58,69,85,106,137,35 } }, { 64000, 67, { /* width */ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3, 4,4,4,4,5,5,5,6,6,7,7,8,8,9,10,10,11,12,13,14,15,16,17, 18,20,21,23,25,28,30,34,37,42,47,54,63,73,87,105,57 } }, { 48000, 69, { /* width */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 10, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 23, 24, 26, 28, 31, 34, 37, 40, 45, 50, 56, 63, 72, 84, 86 } }, { 44100, 70, { /* width */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 23, 24, 26, 28, 30, 33, 36, 39, 43, 47, 53, 59, 67, 76, 88, 27 } }, { 32000, 66, { /* width */ 3,3,3,3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3,4,4,4, 4,4,4,4,5,5,5,5,6,6,6, 7,7,8,8,9,10,10,11,12,13,14, 15,16,17,19,20,22,23,25,27,29,31, 33,35,38,41,45,48,53,58,64,71,62 } }, { 24000, 66, { /* width */ 3,3,3,3,3,3,3,3,3,3,3, 4,4,4,4,4,4,4,4,4,4,4, 5,5,5,5,5,6,6,6,6,7,7, 7,8,8,9,9,10,11,12,12,13,14, 15,17,18,19,21,22,24,26,28,30,32, 34,37,39,42,45,49,53,57,62,67,34 } }, { 22050, 63, { /* width */ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 13, 14, 15, 16, 17, 19, 20, 22, 23, 25, 27, 29, 31, 33, 36, 38, 41, 44, 47, 51, 55, 59, 64, 61 } }, { 16000, 60, { /* width */ 5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,6,6,6,6,6, 6,6,7,7,7,7,8,8,8,9, 9,10,10,11,11,12,13,14,15,16, 17,18,19,21,22,24,26,28,30,33, 35,38,41,44,47,50,54,58,62,58 } }, { 12000, 57, { /* width */ 6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7, 8,8,8,8,8,9,9,9,10,10,11,11,12,12,13,13, 14,15,16,17,18,19,20,22,23,25,27,29,31, 34,36,39,42,45,49,53,57,61,58 } }, { 11025, 56, { /* width */ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8, 9,9,9,9,10,10,10,11,11,12,12,13,13,14,15,16,17,18,19,20, 21,23,24,26,28,30,33,35,38,41,44,48,51,55,59,64,9 } }, { 8000, 52, { /* width */ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 14, 14, 15, 15, 16, 17, 18, 18, 19, 20, 21, 23, 24, 26, 27, 29, 31, 33, 36, 38, 41, 44, 48, 52, 56, 60, 14 } }, { -1 }};static PsyPartTable psyPartTableShort[12+1] ={ { 96000, 36, { /* width */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,4,4,5,5, 6,7,9,11,14,18,7 } }, { 88200, 37, { /* width */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,4,4, 5,5,6,7,8,10,12,16,1 } }, { 64000, 39, { /* width */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,4,4,4, 5,5,6,7,8,9,11,13,10 } }, { 48000, 42, { /* width */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 8, 9, 10, 12, 1 } }, { 44100, 42, { /* width */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 7, 8, 9, 10, 12 } }, { 32000, 44, { /* width */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 2,2,2,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,6,6,7,8,8,9,8 } }, { 24000, 46, { /* width */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,5,5,5,6,6,7,7,8,8,9,1 } }, { 22050, 46, { /* width */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 7, 7, 8, 8, 7 } }, { 16000, 47, { /* width */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,5,5,5,6,6,7,7,8,8,7 } }, { 12000, 48, { /* width */ 1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,2,2,2,2,2, 2,2,2,2,2,2,3,3,3,3,3,4, 4,4,5,5,5,6,6,7,7,8,8,3 } }, { 11025, 47, { /* width */ 1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,2,2, 2,2,2,2,2,2,2,2,2,3, 3,3,3,3,4,4,4,4,5,5, 5,6,6,7,7,8,8 } }, { 8000, 40, { /* width */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 7, 7, 8, 3 } }, { -1 }};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -