⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 psych.c

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 C
📖 第 1 页 / 共 3 页
字号:

		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 + -