JD2022-TU1/main/extern/Camcam/LIBS/Mixer/Subtitles.cpp

388 lines
8.8 KiB
C++

#include "SCENE.h"
#include "Subtitles.h"
int nbSubfiles = 0;
int maxSubfiles = 16;
Subfile* subfiles = (Subfile*)ZeroAlloc(maxSubfiles*sizeof(Subfile));
void SaveSubtitle(char * filename, char* dest)
{
for(int i=0; i<nbSubfiles; i++)
{
if (strcmp(subfiles[i].filename, filename)==0)
{
Subfile* subfile = subfiles+i;
FILE* file = CC_fopen(dest, "wt");
if (!file) return;
for(int j=0; j<subfile->count; j++)
{
fprintf(file, "%d\n", j+1);
int fh, fm, fs, fml, th, tm, ts, tml;
float from = subfile->subtitles[j].from;
float to = subfile->subtitles[j].to;
fh = floor(from/3600);
th = floor(to/3600);
fm = floor((from-fh*3600)/60);
tm = floor((to-th*3600)/60);
fs = floor(from-fh*3600-fm*60);
ts = floor(to-th*3600-tm*60);
fml = (int)((from - (int)(from))*1000);
if ((int)(from*10000)%10==9) fml++;
tml = (int)((to - (int)(to))*1000);
if ((int)(to*10000)%10==9) tml++;
fprintf(file, "%d%d:%d%d:%d%d,%3d --> %d%d:%d%d:%d%d,%3d\n", fh/10, fh%10, fm/10, fm%10, fs/10, fs%10, fml, th/10, th%10, tm/10, tm%10, ts/10, ts%10, tml);
if (*subfile->subtitles[j].newText)
fprintf(file, "%s\n\n", subfile->subtitles[j].newText);
else
fprintf(file, "%s\n\n", subfile->subtitles[j].text);
}
CC_fclose(file);
return;
}
}
}
void SetSubtitle(char * filename, char* text, float time)
{
for(int i=0; i<nbSubfiles; i++)
{
if (strcmp(subfiles[i].filename, filename)==0)
{
Subfile* subfile = subfiles+i;
for(int j=0; j<subfile->count; j++)
{
if (time>=subfile->subtitles[j].from && time<=subfile->subtitles[j].to)
strcpy(subfile->subtitles[j].newText, text);
}
return;
}
}
}
bool SetNewSubtitle(char * filename, char* text, float from, float to)
{
for(int i=0; i<nbSubfiles; i++)
{
if (strcmp(subfiles[i].filename, filename)==0)
{
Subfile* subfile = subfiles+i;
for(int j=0; j<subfile->count; j++)
{
if (subfile->subtitles[j].from == from &&
subfile->subtitles[j].to == to)
{
strcpy(subfile->subtitles[j].newText, text);
return true;
}
if ((from>subfile->subtitles[j].from && from<subfile->subtitles[j].to) ||
(to>subfile->subtitles[j].from && to<subfile->subtitles[j].to))
return false;
}
if (subfile->maxSub <= subfile->count)
{
subfile->subtitles = (Subtitle*)CC_realloc(subfile->subtitles, 2*subfile->maxSub*sizeof(Subtitle));
memset(subfile->subtitles + subfile->maxSub, 0, subfile->maxSub*sizeof(Subtitle));
subfile->maxSub *= 2;
}
subfile->subtitles[subfile->count].from = from;
subfile->subtitles[subfile->count].to = to;
strcpy(subfile->subtitles[subfile->count].text, text);
subfile->count++;
return true;
}
}
return false;
}
char * GetSubtitle(char * filename, float time)
{
for(int i=0; i<nbSubfiles; i++)
{
if (strcmp(subfiles[i].filename, filename)==0)
{
Subfile* subfile = subfiles+i;
for(int j=0; j<subfile->count; j++)
{
if (time>=subfile->subtitles[j].from && time<=subfile->subtitles[j].to)
{
if (*subfile->subtitles[j].newText)
return subfile->subtitles[j].newText;
else
return subfile->subtitles[j].text;
}
}
return 0;
}
}
return 0;
}
int GetSubtitleIndex(char * filename, float time)
{
for(int i=0; i<nbSubfiles; i++)
{
if (strcmp(subfiles[i].filename, filename)==0)
{
Subfile* subfile = subfiles+i;
for(int j=0; j<subfile->count; j++)
{
if (time>=subfile->subtitles[j].from && time<=subfile->subtitles[j].to)
{
return j;
}
}
return -1;
}
}
return -1;
}
char * GetSubtitleByIndex(char * filename, int index)
{
for(int i=0; i<nbSubfiles; i++)
{
if (strcmp(subfiles[i].filename, filename)==0)
{
Subfile* subfile = subfiles+i;
if (index < subfile->count)
{
if (*subfile->subtitles[index].newText)
return subfile->subtitles[index].newText;
else
return subfile->subtitles[index].text;
}
return NULL;
}
}
return NULL;
}
void LoadSubtitle(char* filename)
{
if(filename==0) return;
FILE* file = CC_fopen(filename,"rt");
Subfile* subfile = 0;
for(int i=0; i<nbSubfiles; i++)
{
if (strcmp(subfiles[i].filename, filename)==0)
{
subfile = subfiles+i;
if (subfile->subtitles)
{
CC_free(subfile->subtitles);
subfile->maxSub = initMaxSub;
subfile->subtitles = (Subtitle*)ZeroAlloc(subfile->maxSub*sizeof(Subtitle));
subfile->count = 0;
}
if (subfile->filename)
{
CC_free(subfile->filename);
subfile->filename = 0;
}
i = nbSubfiles;
}
}
if (subfile==0)
{
if(nbSubfiles==maxSubfiles)
{
maxSubfiles*=2;
subfiles = (Subfile*)CC_realloc(subfiles,maxSubfiles*sizeof(Subfile));
}
subfile = subfiles+nbSubfiles;
nbSubfiles++;
subfile->maxSub = initMaxSub;
subfile->subtitles = (Subtitle*)ZeroAlloc(subfile->maxSub*sizeof(Subtitle));
subfile->count = 0;
subfile->filename = 0;
}
subfile->filename = (char*)ZeroAlloc(strlen(filename)+1);
strcpy(subfile->filename, filename);
if(!file) return;
int fileLen = lengthOfFile(filename);
char* contents = (char*)ZeroAlloc(fileLen);
long int pos = 0;
char c;
bool read;
do
{
read = fread(&c, 1, 1, file);
if(read)
contents[pos++] = c;
}while(read);
CC_fclose(file);
contents[pos] = 0;
long int lastPos = 0;
pos = 0;
char line[1024];
int fh, fm, fs, fml, th, tm, ts, tml;
fh= fm= fs= fml= th= tm= ts= tml= 0;
do
{
if(subfile->count==subfile->maxSub)
{
subfile->maxSub*=2;
subfile->subtitles = (Subtitle*)CC_realloc(subfile->subtitles,subfile->maxSub*sizeof(Subtitle));
}
while(contents[pos]!='\n') pos++;
pos++;
lastPos = pos;
while(contents[pos]!='\n') pos++;
strncpy(line, contents+lastPos, pos-lastPos);
line[pos-lastPos] = 0;
sscanf(line, "%d:%d:%d,%d --> %d:%d:%d,%d", &fh, &fm, &fs, &fml, &th, &tm, &ts, &tml);
subfile->subtitles[subfile->count].from = fh*3600 + fm*60 + fs + fml/1000.0;
subfile->subtitles[subfile->count].to = th*3600 + tm*60 + ts + tml/1000.0;
int textSize = 0;
memset(subfile->subtitles[subfile->count].text, 0, 1024);
memset(subfile->subtitles[subfile->count].newText, 0, 1024);
do
{
pos++;
lastPos = pos;
while(pos < fileLen && contents[pos]!='\n') pos++;
if(lastPos!=pos)
{
int lineSize = pos-lastPos+1;
textSize+=lineSize;
if (textSize<1024)
{
strncat(subfile->subtitles[subfile->count].text, contents+lastPos, lineSize);
}
}
}while (lastPos!=pos);
if (*subfile->subtitles[subfile->count].text)
{
subfile->subtitles[subfile->count].text[textSize-1] = 0;
}
pos++;
lastPos = pos;
subfile->count++;
}while(contents[pos] && pos < fileLen);
}
void DestroySubtitle(char* filename)
{
for(int i=0; i<nbSubfiles; i++)
{
if (strcmp(subfiles[i].filename, filename)==0)
{
Subfile* subfile = subfiles+i;
CC_free(subfile->subtitles);
memset(subfile, 0, sizeof(Subfile));
for (int j=i+1; j<nbSubfiles; j++)
{
subfiles[j-1] = subfiles[j];
}
nbSubfiles--;
return;
}
}
}
u32 ReadLine(FILE *F,char *LineFeed);
float ProcessLine(char *subFile, char *line, char *text, float prevTime, int unit, float timePerUnit)
{
char *ptrText = strstr(line, ";text");
char *unitText;
float newTime;
if (!ptrText) return prevTime;
*ptrText = 0;
ptrText += 7;
unitText = strchr(line, '/');
if (unitText)
{
*unitText = 0;
newTime = (float) unit * atof(line) / atof(unitText+1) * timePerUnit + prevTime;
} else
{
newTime = atoi(line) * timePerUnit + prevTime;
}
SetNewSubtitle(subFile, text, prevTime, newTime - 0.001);
strcpy(text, ptrText);
text[strlen(text)-1] = 0;
return newTime;
}
//void MidiTextToSubtitle(char *txtFile, char *subFile);
//MidiTextToSubtitle("aaabb.txt", "aaabb.sub");
//SaveSubtitle("aaabb.sub", "aaabb.sub");
void MidiTextToSubtitle(char *txtFile, char *subFile)
{
char line[2048];
char text[1024] = " ";
int mode = 0;
int unit;
float timePerUnit;
float prevTime = 0;
FILE *F;
LoadSubtitle(subFile);
F = CC_fopen(txtFile, "rt");
while (ReadLine(F,line))
{
// use only
switch (mode)
{
case 0: // nothing
if (!strncmp(line, "mthd", 4))
mode = 1;
if (!strncmp(line, "mtrk", 4))
mode = 2;
break;
case 1: // in track
if (!strncmp(line, "end mthd", 8))
mode = 0;
if (strstr(line, "unit"))
{
strcpy(line, strstr(line, "unit") + 5);
*strchr(line, ' ') = 0;
unit = atoi(line) * 4;
}
break;
case 2: // nothing
if (!strncmp(line, "end mtrk", 8))
mode = 0;
if (strstr(line, "beats "))
{
float beatsPerMinute;
char *beatPtr = strstr(line, "beats ") + 6;
*strchr(beatPtr, ' ') = 0;
beatsPerMinute = atof(beatPtr);
timePerUnit = 60.0/(beatsPerMinute*unit) * 4;
}
if (strstr(line, "trackname \"Words\""))
mode = 3;
break;
case 3: // in TEXT track
if (!strncmp(line, "end mtrk", 8))
return;
prevTime = ProcessLine(subFile, line, text, prevTime, unit, timePerUnit);
break;
}
}
}