Esempio n. 1
0
//residualSpecgram 波形のコピーが入る。メモリを確保せずに渡す。この関数により必要なメモリが確保される。
//residualSpecgramLength 波形の長さが入る。メモリを確保せずに渡す。この関数により必要なメモリが確保される。
//residualSpecgramIndex 各フレームの波形を指定するインデックスが入る。
//戻り値波形の数(pCount)
int pt101(double *x, int xLen, int fs, double *timeAxis, double *f0, 
		 double ***residualSpecgram, int **residualSpecgramLength, int *residualSpecgramIndex)
{
	int i, index;
	double framePeriod = (timeAxis[1]-timeAxis[0])*1000.0;

	int	fftl = (int)pow(2.0, 1.0+(int)(log(3.0*fs/FLOOR_F0+1) / log(2.0)));
	int tLen = getSamplesForDIO(fs, xLen, framePeriod);

	int vuvNum;
//	vuvNum = 0;
	vuvNum = 1;	//tn_fuds
	for(i = 1;i < tLen;i++)
	{
		if(f0[i]!=0.0 && f0[i-1]==0.0) vuvNum++;	//無声→有声
		if(f0[i]==0.0 && f0[i-1]!=0.0) vuvNum++;	//有声→無声  tn_fnds
	}
//	vuvNum+=vuvNum-1; // 島数の調整 (有声島と無声島)  tn_fnds コメントアウト
//	if(f0[0] == 0) vuvNum++;  tn_fnds コメントアウト
//	if(f0[tLen-1] == 0) vuvNum++;  tn_fnds コメントアウト

	int stCount, edCount;
	int *stList, *edList;
	stList = (int *)malloc(sizeof(int) * vuvNum);
	edList = (int *)malloc(sizeof(int) * vuvNum);
	edCount = 0;

	stList[0] = 0;
	stCount = 1;
	index = 1;
	if(f0[0] != 0)	//有声から始まる場合
	{
		for(i = 1;i < tLen;i++)
		{
			if(f0[i]==0 && f0[i-1]!=0)	//有声→無声
			{
				edList[0] = i-1;
				edCount++;
				stList[1] = i;
				stCount++;
				index = i;

				break;	//tn_fnds
			}
		}
	}

	edList[vuvNum-1] = tLen-1;
	for(i = index;i < tLen;i++)
	{
		if(f0[i]!=0.0 && f0[i-1]==0.0) //無声→有声
		{
			edList[edCount++] = i-1;
			stList[stCount++] = i;
		}
		if(f0[i]==0.0 && f0[i-1]!=0.0) //有声→無声
		{
			edList[edCount++] = i-1;
			stList[stCount++] = i;
		}
	}

	int *wedgeList;
	wedgeList = (int *)malloc(sizeof(int) * vuvNum);
	getWedgeList(x, xLen, vuvNum, stList, edList, fs, framePeriod, f0, wedgeList);//島中央のピーク位置を取得

	double *signalTime, *f0interpolatedRaw, *totalPhase;
	double *fixedF0;
	fixedF0				= (double *)malloc(sizeof(double) * tLen);
	signalTime			= (double *)malloc(sizeof(double) * xLen);
	f0interpolatedRaw	= (double *)malloc(sizeof(double) * xLen);
	totalPhase			= (double *)malloc(sizeof(double) * xLen);

	for(i = 0;i < tLen;i++) fixedF0[i] = f0[i] == 0 ? DEFAULT_F0 : f0[i]; //F0が0ならデフォルトに補正
	for(i = 0;i < xLen;i++) signalTime[i] = (double)i / (double)fs;       //サンプル位置の時刻
	interp1(timeAxis, fixedF0, tLen, signalTime, xLen, f0interpolatedRaw);//各サンプルのF0
	totalPhase[0] = f0interpolatedRaw[0]*2*PI/(double)fs;                 //各サンプルの位相
	for(i = 1;i < xLen;i++) totalPhase[i] = totalPhase[i-1] + f0interpolatedRaw[i]*2*PI/(double)fs;

	double *pulseLocations;
	pulseLocations		= (double *)malloc(sizeof(double) * xLen);
	int pCount;
	pCount = getPulseLocations(x, xLen, totalPhase, vuvNum, stList,
				edList, fs, framePeriod, wedgeList, pulseLocations);//位相が大きく動くサンプル位置の時刻

//tn_fndsデバッグ
//zeroXToFile(x, xLen, f0interpolatedRaw, totalPhase, pCount, pulseLocations, fs, vuvNum, wedgeList);

	pCount++;//長さ0のダミーパルスを追加

	*residualSpecgram	= (double **)malloc(sizeof(double *) * pCount);
	for(i = 0;i < pCount;i++) (*residualSpecgram)[i] = (double *)malloc(sizeof(double) * fftl);
	*residualSpecgramLength = (int *)malloc(sizeof(int) * pCount);
	
	getOnePulseResidualSignal(x, xLen, fs, framePeriod/1000.0, f0, fftl, pulseLocations, pCount,
							   *residualSpecgram, *residualSpecgramLength);

	getFrameResidualIndex(tLen, pCount, framePeriod/1000, pulseLocations, residualSpecgramIndex);


//	pulseToFile(pCount, pulseLocations, *residualSpecgramLength);

	free(fixedF0);
	free(pulseLocations);
	free(totalPhase); free(f0interpolatedRaw); free(signalTime);
	free(wedgeList);
	free(edList); free(stList);
	return pCount;
}
Esempio n. 2
0
int main(int argc, char *argv[])
{
	int i;

	double *x,*x_cut,*f0,*t,*y;
	double **residualSpecgram;
	int fftl;

	int signalLen;
	int tLen;
	
	int offset,blank;
	int offsetSample, lengthSample;

	if(argc < 3) 
	{
		printf("error: 引数の数が不正です.\n");
		return 0;
	}

	/*
	printf("argc:%d\n", argc);
	for(i = 0;i < argc;i++)
		printf("%d:%s\n",i, argv[i]);
	//*/

	FILE *fp;

	int fs, nbit;
	x = wavread(argv[1], &fs, &nbit, &signalLen);
	if(x == NULL)
	{
		printf("error: 指定されたファイルは存在しません.\n");
		return 0;
	}

	printf("File information\n");
	printf("Sampling : %d Hz %d Bit\n", fs, nbit);
	printf("Length %d [sample]\n", signalLen);
	printf("Length %f [sec]\n", (double)signalLen/(double)fs);
	
	// Cut x by offset and blank
	offset = atoi(argv[6]);
	offsetSample = offset*fs/1000;
	blank = atoi(argv[9]);
	if(blank < 0) // 負の場合はoffsetからの距離
	{
		lengthSample = (-blank)*fs/1000;
	} else {
		lengthSample = signalLen - offsetSample - (blank*fs/1000);
	}
	if (lengthSample <= 0) {
		printf("Error: offset passes blank\n");
		exit(0);
	}
	printf ("lengthSample: %d\n",lengthSample);
	x_cut = (double *)malloc(sizeof(double)*lengthSample);
	for (i=0; i<lengthSample ; i++) {
		if (i+offsetSample < signalLen) {
			x_cut[i] = x[i+offsetSample];
		} else {
			x_cut[i] = 0.0;
		}
	}
	// F0は何サンプル分あるかを事前に計算する.
	tLen = getSamplesForDIO(fs, lengthSample, FRAMEPERIOD);
	printf ("tLen: %d\n",tLen);
	f0 = (double *)malloc(sizeof(double)*tLen);
	t  = (double *)malloc(sizeof(double)*tLen);
	// f0 estimation by DIO
	DWORD elapsedTime;

	printf("\nAnalysis\n");
	elapsedTime = timeGetTime();
	dio(x_cut, lengthSample, fs, FRAMEPERIOD, t, f0);
	printf("DIO: %d [msec]\n", timeGetTime() - elapsedTime);

	fftl = getFFTLengthForStar(fs);

	residualSpecgram	= (double **)malloc(sizeof(double *) * tLen);
	for(i = 0;i < tLen;i++) residualSpecgram[i] = (double *)malloc(sizeof(double) * (fftl/2+1));

	// 非周期性指標の分析
	elapsedTime = timeGetTime();
	pt100(x_cut, lengthSample, fs, t, f0, residualSpecgram);
	printf("PLATINUM: %d [msec]\n", timeGetTime() - elapsedTime);

	// 時間長の伸縮
	int lengthMsec, stLengthMsec, inputLengthMsec;
	double ratio;
	inputLengthMsec = (int)(tLen*FRAMEPERIOD);
	lengthMsec = atoi(argv[7]);
	stLengthMsec = atoi(argv[8]);

	int loop;
	loop = (lengthMsec-stLengthMsec)/(inputLengthMsec-stLengthMsec);
	ratio = (double)(lengthMsec) / (double)(inputLengthMsec - stLengthMsec);

	// 制御パラメタのメモリ確保
	double *fixedF0;
	double **fixedResidualSpecgram;
	int tLen2;
//	tLen2 = (int)(0.5+(double)(lengthMsec+offset)/FRAMEPERIOD); //ここを修正
	tLen2 = (int)(0.5+(double)(lengthMsec+stLengthMsec)/FRAMEPERIOD);

	fixedF0					= (double *) malloc(sizeof(double)   * tLen2);
	fixedResidualSpecgram	= (double **)malloc(sizeof(double *) * tLen2);
	for(i = 0;i < tLen2;i++) fixedResidualSpecgram[i]	= (double *)malloc(sizeof(double) * (fftl/2+1));

	// 最終波形のメモリ確保
	int signalLen2;
	signalLen2 = (int)((lengthMsec+stLengthMsec)/1000.0*(double)fs);
	y  = (double *)malloc(sizeof(double)*signalLen2);
	if (!y) {
		printf ("Error: y malloc() NULL\n");
	}
	for(i = 0;i < signalLen2;i++) y[i] = 0.0;
//	printf("length:%d, %f\n",signalLen2, (double)signalLen2/(double)fs*1000.0);
//	printf("%d, %d, %d\n",lengthMsec, offset, fs);


	// 合成の前にF0の操作 (引数)
	equalizingPicth(f0, tLen, argv[3], atoi(argv[11]) );
//	stretchTime(f0, tLen, fftl, residualSpecgram, 
//				 fixedF0, tLen2, fixedResidualSpecgram, stLengthMsec/(int)FRAMEPERIOD, ratio);
	int st, ed;
	int tempo;
	int pitchType;
	st = stLengthMsec+(inputLengthMsec-stLengthMsec)/3;
	ed = stLengthMsec+2*(inputLengthMsec-stLengthMsec)/3;

	tLen2 = stretchTime(f0, tLen, fftl, residualSpecgram, 
				 fixedF0, tLen2, fixedResidualSpecgram, st/(int)FRAMEPERIOD, ed/(int)FRAMEPERIOD, loop);
	pitchType=0;
	if (argc >= 13 && argv[12][0]=='!') {
		tempo = atoi(&(argv[12][1]));
		pitchType=0;
	} else if (argc >= 13 && strchr(argv[12],'Q') != NULL) {
	        char *c;
	        pitchType=1;
		c = strchr(argv[12],'Q');
		c++;
		tempo = atoi(c);
	} else if (argc >= 13) {
		tempo = atoi(argv[12]);
	} else {
		tempo = 120;
	}
	printf ("tempo: %d\n",tempo);

	// ピッチベンドの取得
	double *pitchBend=NULL;
	int bLen=0;
	if (pitchType==0) {
	  if (argc >= 14) {
	    bLen = getF0Contour(argv[13],NULL);
	    pitchBend = (double *)malloc(sizeof(double) * bLen);
	    bLen = getF0Contour(argv[13], pitchBend);
	  } else {
	    bLen = 3;
	    pitchBend = (double *)malloc(sizeof(double) * bLen);
	    pitchBend[0]=1.0;
	    pitchBend[1]=1.0;
	    pitchBend[2]=1.0;
	  }
	} else if (pitchType==1) {
	  int i,j;
	  char arg1[100];
	  bLen = argc - 12;
	  pitchBend = (double *)malloc(sizeof(double) * bLen);
	  for (i=0; i<bLen; i++) {
	    memset(arg1,0,sizeof(arg1));
	    for (j=0; j+1<sizeof(arg1) && argv[i+12][j] != '\0'; j++) {
	      if (isdigit(argv[i+12][j]) || argv[i+12][j]=='.' || argv[i+12][j]=='+' || argv[i+12][j]=='-') {
		arg1[j]=argv[i+12][j];
	      } else {
		break;
	      }
	    }
	    sscanf(arg1,"%lf",&(pitchBend[i]));
	    pitchBend[i] = pow(2.0, pitchBend[i]/1200.0);
	  }
	}
	createFinalPitch2(fixedF0, tLen2, pitchBend, bLen, fs, tempo);

	// 合成
	printf("\nSynthesis\n");
	elapsedTime = timeGetTime();
	synthesisPt100(fixedF0, tLen2, fixedResidualSpecgram, fftl, FRAMEPERIOD, fs, y, signalLen2);
	printf("WORLD: %d [msec]\n", timeGetTime() - elapsedTime);
	// オフセットの設定
	//offset = (int)((double)(offset+endOffset)/1000.0*(double)fs);
	//signalLen2 = (int)((lengthMsec)/1000.0*(double)fs);
//	signalLen2 -= offset;
	//for(i = 0;i < signalLen2;i++) y[i] = y[i+offset];

//	printf("%d\n", signalLen2);
//	printf("%f %d\n", (double)signalLen2/(double)fs*1000, offset);
//	getch();


	// ファイルの書き出し (内容には関係ないよ)
	char header[44];
	short *output;
	double maxAmp;
	output = (short *)malloc(sizeof(short) * signalLen2);
 
	// 振幅の正規化
	maxAmp = 0.0;
	double volume;
	volume = (double)atoi(argv[10]) / 100.0;
	printf ("volume: %lf\n",volume);
	for(i = 0;i < signalLen2;i++) maxAmp = (maxAmp < fabs(y[i])) ? fabs(y[i]) : maxAmp;
	if (maxAmp<=0.0) maxAmp=1.0;
	printf ("maxAmp: %lf\n",maxAmp);
	for(i = 0;i < signalLen2;i++) output[i] = (short)(32768.0*(y[i]*0.5 * volume/maxAmp));

	fp = fopen(argv[1], "rb");
	fread(header, sizeof(char), 44, fp);
	fclose(fp);

	fp = fopen(argv[2],"wb");
	fwrite(header, sizeof(char), 44, fp);
	fwrite(output, sizeof(short), signalLen2, fp);
	fseek(fp, 40, SEEK_SET);
	signalLen2*=2;
	fwrite(&signalLen2, sizeof(int), 1, fp);
	fclose(fp);
	free(output);

	free(pitchBend);
	free(x); free(t); free(f0); free(fixedF0); free(y);
	for(i = 0;i < tLen;i++)
	{
		free(residualSpecgram[i]);
	}
	for(i = 0;i < tLen2;i++)
	{
		free(fixedResidualSpecgram[i]);
	}
	free(fixedResidualSpecgram);
	free(residualSpecgram); 

	printf("complete.\n");
	return 0;
}
Esempio n. 3
0
void pt100(double *x, int xLen, int fs, double *timeAxis, double *f0, 
		 double **residualSpecgram)
{
	int i, j, index;
	double framePeriod = (timeAxis[1]-timeAxis[0])*1000.0;

	int	fftl = (int)pow(2.0, 1.0+(int)(log(3.0*fs/FLOOR_F0+1) / log(2.0)));
	int tLen = getSamplesForDIO(fs, xLen, framePeriod);

	int vuvNum;
	vuvNum = 0;
	for(i = 1;i < tLen;i++)
	{
		if(f0[i]!=0.0 && f0[i-1]==0.0) vuvNum++;
	}
	vuvNum+=vuvNum-1; // 島数の調整 (有声島と無声島)
	if(f0[0] == 0) vuvNum++;
	if(f0[tLen-1] == 0) vuvNum++;

	int stCount, edCount;
	int *stList, *edList;
	stList = (int *)malloc(sizeof(int) * vuvNum);
	edList = (int *)malloc(sizeof(int) * vuvNum);
	edCount = 0;

	stList[0] = 0;
	stCount = 1;
	index = 1;
	if(f0[0] != 0)
	{
		for(i = 1;i < tLen;i++)
		{
			if(f0[i]==0 && f0[i-1]!=0)
			{
				edList[0] = i-1;
				edCount++;
				stList[1] = i;
				stCount++;
				index = i;
			}
		}
	}

	edList[vuvNum-1] = tLen-1;
	for(i = index;i < tLen;i++)
	{
		if(f0[i]!=0.0 && f0[i-1]==0.0) 
		{
			edList[edCount++] = i-1;
			stList[stCount++] = i;
		}
		if(f0[i]==0.0 && f0[i-1]!=0.0) 
		{
			edList[edCount++] = i-1;
			stList[stCount++] = i;
		}
	}

	int *wedgeList;
	wedgeList = (int *)malloc(sizeof(int) * vuvNum);
	getWedgeList(x, xLen, vuvNum, stList, edList, fs, framePeriod, f0, wedgeList);//島中央のピーク位置を取得

	double *signalTime, *f0interpolatedRaw, *totalPhase;
	double *fixedF0;
	fixedF0				= (double *)malloc(sizeof(double) * tLen);
	signalTime			= (double *)malloc(sizeof(double) * xLen);
	f0interpolatedRaw	= (double *)malloc(sizeof(double) * xLen);
	totalPhase			= (double *)malloc(sizeof(double) * xLen);

	for(i = 0;i < tLen;i++) fixedF0[i] = f0[i] == 0 ? DEFAULT_F0 : f0[i]; //F0が0ならデフォルトに補正
	for(i = 0;i < xLen;i++) signalTime[i] = (double)i / (double)fs;       //サンプル位置の時刻
	interp1(timeAxis, fixedF0, tLen, signalTime, xLen, f0interpolatedRaw);//各サンプルのF0
	totalPhase[0] = f0interpolatedRaw[0]*2*PI/(double)fs;                 //各サンプルの位相
	for(i = 1;i < xLen;i++) totalPhase[i] = totalPhase[i-1] + f0interpolatedRaw[i]*2*PI/(double)fs;

	double *pulseLocations;
	pulseLocations		= (double *)malloc(sizeof(double) * xLen);
	int pCount;
	pCount = getPulseLocations(x, xLen, totalPhase, vuvNum, stList, edList, fs, framePeriod, wedgeList, pulseLocations);//位相が大きく動くサンプル位置の時刻

	double *tmpResidualSpec;
	tmpResidualSpec = (double *)malloc(sizeof(double) * fftl);
	double currentF0;

	for(j = 0;j < fftl/2;j++) residualSpecgram[0][j] = 0.0;
	for(i = 1;i < tLen;i++)
	{
		currentF0 = f0[i] <= FLOOR_F0 ? DEFAULT_F0 : f0[i];  //フレームのF0 下限ならデフォルトに補正
		getOneFrameResidualSignal(x, xLen, fs, i, framePeriod/1000.0, currentF0, fftl, pulseLocations, pCount, //最も近いパルス?前後1周期分の波形に窓をかけたものを取得
						tmpResidualSpec);
		for(j = 0;j < fftl/2;j++) residualSpecgram[i][j] = tmpResidualSpec[j];
	}

	free(fixedF0);
	free(tmpResidualSpec);
	free(pulseLocations);
	free(totalPhase); free(f0interpolatedRaw); free(signalTime);
	free(wedgeList);
	free(edList); free(stList);
	return;
}