int main(int ArgN, char** Arg) { int RegenFlag = 0; char* CWaveFile = NULL; char* CLabelFile = NULL; char* CRecFile = NULL; char* CRegenFile = "RegeneratedTrack.txt"; int c; while((c = getopt(ArgN, Arg, "r")) != -1) { switch(c) { case 'r': RegenFlag = 1; break; case '?': printf("Usage: rsegment [-r] " "[-h] wavfile labelfile recfile\n"); return 1; default: abort(); } } int i; for(i = optind; i < ArgN; i ++) { switch(i - optind) { case 0: CWaveFile = Arg[i]; break; case 1: CLabelFile = Arg[i]; break; case 2: CRecFile = Arg[i]; break; default: fprintf(stderr, "Warning: redundant argument '%s'.\n", Arg[i]); } } if(! CWaveFile) { fprintf(stderr, "Missing argument 'wavfile'.\n"); return 1; } if(! CLabelFile) { fprintf(stderr, "Missing argument 'labelfile'.\n"); return 1; } if(! CRecFile) { fprintf(stderr, "Missing argument 'recfile'.\n"); return 1; } Wave SorcWave; File LabelFile; File RecFile; File RegenFile; String WavePath, LabelPath, RecPath, RegenPath; RNew(String, & WavePath, & LabelPath, & RecPath, & RegenPath); RNew(File, & LabelFile, & RecFile, & RegenFile); RCall(Wave, Ctor)(& SorcWave); String_SetChars(& WavePath, CWaveFile); String_SetChars(& LabelPath, CLabelFile); String_SetChars(& RecPath, CRecFile); String_SetChars(& RegenPath, CRegenFile); if(! RCall(Wave, FromFile)(& SorcWave, & WavePath)) { fprintf(stderr, "Cannot load wave file.\n"); return 1; } if(! File_Open(& LabelFile, & LabelPath, READONLY)) { fprintf(stderr, "Cannot load label file.\n"); return 1; } if(! File_Open(& RecFile, & RecPath, READONLY)) { fprintf(stderr, "Cannot load word table.\n"); return 1; } if(RegenFlag) { if(! File_Open(& RegenFile, & RegenPath, CREATE)) { fprintf(stderr, "Cannot create '%s'.\n", CRegenFile); return 1; } } Array_Ctor(String, RecList); Array_Ctor(int, SegList); ParseRecFile(& RecFile); ParseLabelFile(& LabelFile, SorcWave.SampleRate); Wave SegWave; RCall(Wave, Ctor)(& SegWave); SegWave.SampleRate = SorcWave.SampleRate; String SegName, LineBuf, TempBuf; RNew(String, & SegName, & LineBuf, & TempBuf); for(i = 0; i <= SegList_Index; i ++) { int Start = SegList[i]; int End; if(i == SegList_Index) End = SorcWave.Size; else End = SegList[i + 1]; if(i > RecList_Index) { fprintf(stderr, "Insufficient records in word table.\n"); fprintf(stderr, "Segmentation aborted at %fs.\n", (float)Start / SorcWave.SampleRate); return 1; } String* Name = & RecList[i]; String_Copy(& SegName, Name); String_JoinChars(& SegName, ".wav"); if(! RegenFlag) { int Size = End - Start; Real* Data = RCall(RAlloc, Real)(Size); RCall(Wave, Read)(& SorcWave, Data, Start, Size); RCall(Wave, Resize)(& SegWave, Size); RCall(Wave, Write)(& SegWave, Data, 0, Size); if(! RCall(Wave, ToFile)(& SegWave, & SegName)) fprintf(stderr, "Exporting '%s' failed. Skipped.\n", String_GetChars(& SegName)); RFree(Data); } if(RegenFlag) { CStrFloat(& LineBuf, (float)SegList[i] / SorcWave.SampleRate); String_Copy(& TempBuf, & LineBuf); String_JoinChars(& LineBuf, "\t"); String_Join(& LineBuf, & TempBuf); String_JoinChars(& LineBuf, "\t"); String_Join(& LineBuf, Name); File_WriteLine(& RegenFile, & LineBuf); } } if(i <= RecList_Index) fprintf(stderr, "Warning: redundant records in word table starting from" " '%s'.\n", String_GetChars(& RecList[i])); if(RegenFlag) File_Flush(& RegenFile); File_Close(& RecFile); File_Close(& LabelFile); File_Close(& RegenFile); Array_ObjDtor(String, RecList); Array_Dtor(String, RecList); Array_Dtor(int, SegList); RDelete(& WavePath, & LabelPath, & RecPath, & RegenPath, & SegName, & LineBuf, & TempBuf); RDelete(& SorcWave, & LabelFile, & RecFile, & SegWave, & RegenFile); return 0; }
//resampler <wav in> <wav out> <pitch> <velocity> <flags> int main(int ArgQ, char** ArgList) { CDSP2_SetArch(CDSP2_Arch_Gnrc); CDSP2_SetDebugOn(CDSP2_Debug_Check); printf("Sleepwalking's toy resampler v0.1.\n"); printf("Powered by Rocaloid's subprojects: CVESVP, CVEDSP2, and RFNL.\n"); String OutputPath, InputPath, StrPitch, StrVelocity, StrFlags, StrOffset, StrLength; RNew(String, & OutputPath, & InputPath, & StrPitch, & StrVelocity, & StrFlags, & StrOffset, & StrLength); if(ArgQ < 4) { printf("Wrong number of Arguments.\n"); return 1; } String_SetChars(& InputPath, ArgList[1]); String_SetChars(& OutputPath, ArgList[2]); String_SetChars(& StrPitch, ArgList[3]); String_SetChars(& StrVelocity, "100"); String_SetChars(& StrFlags, ""); String_SetChars(& StrOffset, "0"); String_SetChars(& StrLength, "-1"); if(ArgQ > 4) String_SetChars(& StrVelocity, ArgList[4]); if(ArgQ > 5) String_SetChars(& StrFlags, ArgList[5]); if(ArgQ > 6) String_SetChars(& StrOffset, ArgList[6]); if(ArgQ > 7) String_SetChars(& StrLength, ArgList[7]); number Fundamental = FreqFromPitch(& StrPitch); number Velocity = CNumberStr(& StrVelocity); int Length = CIntStr(& StrLength); if(Fundamental < 50) { printf("Wrong pitch.\n"); return 1; } /* printf("resampler (in)%s (out)%s (pitch)%s (vel)%s (flags)%s (offset)%s " "(length)%s\n", String_GetChars(& InputPath), String_GetChars(& OutputPath), String_GetChars(& StrPitch), String_GetChars(& StrVelocity), String_GetChars(& StrFlags), String_GetChars(& StrOffset), String_GetChars(& StrLength)); */ Wave InWave, OutWave; FWindow_T DyWin; PSOLAIterlyzer PAna; PSOLAItersizer PSyn; List_DataFrame DataList; number* HannWind = RCall(RAlloc, number)(2048); RNew(Wave, & InWave, & OutWave); RNew(PSOLAIterlyzer, & PAna); RNew(PSOLAItersizer, & PSyn); RNew(List_DataFrame, & DataList); RCall(CDSP2_GenHanning, number)(HannWind, 2048); RCall(Wave, Resize)(& OutWave, 100000); RCall(Wave, SetWindow)(& InWave, HannWind, 2048); RCall(Wave, SetWindow)(& OutWave, HannWind, 2048); if(! RCall(Wave, FromFile)(& InWave, & InputPath)) { printf("Cannot read file!\n"); return 1; } Length = Length * (number)InWave.SampleRate / 1000; if(Length < 0) Length = InWave.Size; int VOT = RCall(CSVP_VOTFromWave, number)(& InWave, 0, InWave.Size / 2); int Onset = RCall(CSVP_OnsetFromWave, number) (& InWave, 0.005, 0, InWave.Size); printf("Got VOT at %d.\n", VOT); printf("Got Onset at %d.\n", Onset); //Analysis process RCall(PSOLAIterlyzer, SetWave)(& PAna, & InWave); RCall(PSOLAIterlyzer, SetPosition)(& PAna, VOT + 2000); RCall(PSOLAIterlyzer, SetBound)(& PAna, VOT); if(! RCall(PSOLAIterlyzer, PreAnalysisTo)(& PAna, VOT + 4000)) { printf("Preanalysis failed.\n"); return 1; } RCall(PSOLAIterlyzer, IterNextTo)(& PAna, InWave.Size); RCall(PSOLAIterlyzer, PrevTo)(& PAna, Onset); RCall(List_DataFrame, FromWave)(& DataList, & InWave, & PAna.PulseList); int i; /* for(i = 0; i <= PAna.PulseList.Frames_Index; i ++) { int p = RCall(PSOLAIterlyzer, Fetch)(& PAna, i); printf("%f %f\n", (float)p / InWave.SampleRate , (float)p / InWave.SampleRate); }*/ //Pre-synthesis process OutWave.SampleRate = InWave.SampleRate; RCall(FWindow_T, Ctor)(& DyWin); RCall(FWindow, SetPara)(& DyWin, 30, 3000, 20); RCall(FWindow, SetFunc)(& DyWin, _C(RFNL_Hanning_Size_Gnrc, _, number), _C(RFNL_Hanning_Valu_Gnrc, _, number)); RCall(FWindow, Initialize)(& DyWin); RCall(PSOLAItersizer, SetWave)(& PSyn, & OutWave); RCall(PSOLAItersizer, SetWindow)(& PSyn, & DyWin); RCall(PSOLAItersizer, SetPosition)(& PSyn, 0); //Transposition process PMatch SorcPulse, LengthMatch; RNew(PMatch, & SorcPulse, & LengthMatch); for(i = 0; i <= PAna.PulseList.Frames_Index; i ++) PAna.PulseList.Frames[i] -= Onset; PMatchFromList_Int(& SorcPulse, & PAna.PulseList); int Fill = SorcPulse.X[1] - SorcPulse.X[0]; i = 0; number p = SorcPulse.X[0]; number Period = (number)InWave.SampleRate / Fundamental; while(p < VOT - Onset) { i = RCall(PMatch, Query)(& SorcPulse, p).LowerIndex; RCall(PSOLAItersizer, Add)(& PSyn, p, & DataList.Frames[i]); p += Fill; } RCall(PMatch, AddPair)(& LengthMatch, VOT - Onset, VOT - Onset); RCall(PMatch, AddPair)(& LengthMatch, Length, SorcPulse.X[SorcPulse.X_Index - 1]); while(p < Length) { Transition TransPulse; int p2 = RCall(PMatch, Query)(& LengthMatch, p).Y; TransPulse = RCall(PMatch, Query)(& SorcPulse, p2); i = TransPulse.LowerIndex; RCall(PSOLAItersizer, Add)(& PSyn, p, & DataList.Frames[i]); p += Period; } int Offset = (int)CNumberStr(& StrOffset) * InWave.SampleRate / 1000; //int OffIndex = RCall(PMatch, Query)(& SorcPulse, Offset).LowerIndex; RCall(PSOLAItersizer, RepositionFrom)(& PSyn, Onset - Offset); //Synthesis process RCall(PSOLAItersizer, IterNextTo)(& PSyn, InWave.Size); RCall(Wave, ToFile)(& OutWave, & OutputPath); printf("Generated.\n"); RFree(HannWind); RDelete(& OutputPath, & InputPath, & StrPitch, & StrVelocity, & StrFlags, & InWave, & OutWave, & DyWin, & PAna, & PSyn, & DataList, & SorcPulse, & LengthMatch, & StrOffset, & StrLength); }
int main(int ArgN, char** Arg) { UnFlag = 0; Level = 1; char* CInPath, *COutPath; int c; while((c = getopt(ArgN, Arg, "ul:v")) != -1) { switch(c) { case 'u': UnFlag = 1; break; case 'l': Level = atoi(optarg); break; case 'v': printf("Rocaloid PrecompDiff version " Version "\n"); return 1; break; case '?': PrintUsage(); return 1; default: abort(); } } if(optind > ArgN - 1) { fprintf(stderr, "[Error] Missing argument 'inwave', 'outwave'.\n"); PrintUsage(); return 1; } if(optind > ArgN - 2) { fprintf(stderr, "[Error] Missing argument 'outwave'.\n"); PrintUsage(); return 1; } if(optind < ArgN - 2) { fprintf(stderr, "[Error] Redundant argument '%s'.\n", Arg[optind + 2]); } CInPath = Arg[optind]; COutPath = Arg[optind + 1]; String InPath, OutPath; RNew(String, & InPath, & OutPath); String_SetChars(& InPath, CInPath); String_SetChars(& OutPath, COutPath); WaveFile IOFile; WaveFile_Ctor(& IOFile); if(WaveFile_Open(& IOFile, & InPath) != 1) { fprintf(stderr, "[Error] Cannot open '%s'.\n", CInPath); return 1; } int Size = IOFile.Header.DataNum; Int16* Data = RAlloc_Int16(Size); WaveFile_FetchAll(& IOFile, (char*)Data); WaveFile_Close(& IOFile); int i; for(i = 0; i < Level; i ++) { if(! UnFlag) { if(! PreCompressDiff(Data, Size)) { fprintf(stderr, "[Error] %dth precompress failed. " "Please try smaller precompress level.\n", i + 1); return 1; } }else DePreCompressDiff(Data, Size); } if(WaveFile_Save(& IOFile, & OutPath) != 1) { fprintf(stderr, "[Error] Cannot save to '%s'.\n", COutPath); return 1; } WaveFile_WriteAll(& IOFile, (char*)Data, Size * 2); RFree(Data); WaveFile_FinishWrite(& IOFile); WaveFile_Close(& IOFile); RDelete(& InPath, & OutPath, & IOFile); return 0; }