Initial code for voice synchronization.

git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@566 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
ghaushe
2003-01-18 23:26:17 +00:00
parent 2975dd0e52
commit 7b9af3cc3b
10 changed files with 1328 additions and 0 deletions
+22
View File
@@ -0,0 +1,22 @@
Ur-Quan Masters Voice-over synchronization tool
For Windows:
Unpack into any directory.
From a DOS prompt, execute Synchronizer.exx from within the UQM content
directory it will write out files into content/timestamp/race
When you are done, archive them, and send to:
tcpaiqgvnmbf28f001@sneakemail.com
To use, select the files you want to play, and hit start.
hitting 'n' is the same as 'Next Screen', and 'p' will pause/unpause.
Hitting 'space' or 'enter' may have adverse effects, so don't
For Linux:
The code can be compiled with:
gcc synch.cpp synchronizer.cpp audioSDL.cpp audio.cpp -o synch -DUSE_SDLAUDIO=1 -lfltk -lvorbisfile -lvorbis `sdl-config --cflags --libs`
You'll need fltk (1.1.x), oggvorbis, and SDL development libraries
installed.
If you have any questions or issues, please send them to the e-mail above
+102
View File
@@ -0,0 +1,102 @@
//
//
// Ur-Quan Masters Voice-over / Subtitle Synchronization tool
// Copyright 2003 by Geoffrey Hausheer
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA.
//
// contact tcpaiqgvnmbf28f001@sneakemail.com for bugs/issues
//
#if (USE_SDLAUDIO != 1)
char AUDIO_TYPE[] = "Native";
#include <windows.h>
#include <mmsystem.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include "audio.h"
typedef struct {
HWAVEOUT hWaveOut;
WAVEFORMATEX wfx;
WAVEHDR header;
int paused;
unsigned long time;
} WAVESTRUCT;
unsigned long clocks_per_sec = CLOCKS_PER_SEC;
unsigned long get_clock()
{
return (clock());
}
void init_sound ()
{
}
void reset_sound (WAVESTRUCT *WaveData)
{
if (WaveData)
{
waveOutReset (WaveData->hWaveOut);
waveOutUnprepareHeader(WaveData->hWaveOut, &WaveData->header, sizeof(WAVEHDR));
waveOutClose(WaveData->hWaveOut);
delete WaveData->header.lpData;
delete WaveData;
}
}
void pause_sound (WAVESTRUCT *WaveData)
{
if (WaveData)
waveOutPause (WaveData->hWaveOut);
}
void unpause_sound (WAVESTRUCT *WaveData)
{
if (WaveData)
waveOutRestart (WaveData->hWaveOut);
}
WAVESTRUCT *play_sound(AUDIOHDR *audiohdr)
{
WAVESTRUCT *WaveData = new WAVESTRUCT;
WaveData->hWaveOut = 0;
WaveData->wfx.nSamplesPerSec = audiohdr->samp_freq;
WaveData->wfx.wBitsPerSample = audiohdr->bits_per_sample;
WaveData->wfx.nChannels = audiohdr->channels;
WaveData->wfx.cbSize = 0;
WaveData->wfx.wFormatTag = WAVE_FORMAT_PCM;
WaveData->wfx.nBlockAlign = (WaveData->wfx.wBitsPerSample >> 3) * WaveData->wfx.nChannels;
WaveData->wfx.nAvgBytesPerSec = WaveData->wfx.nBlockAlign * WaveData->wfx.nSamplesPerSec;
if(waveOutOpen(&WaveData->hWaveOut, WAVE_MAPPER, &WaveData->wfx,
0, 0, CALLBACK_NULL) != MMSYSERR_NOERROR) {
fprintf(stderr, "unable to open WAVE_MAPPER device\n");
return(0);
}
ZeroMemory(&WaveData->header, sizeof(WAVEHDR));
WaveData->header.dwBufferLength = audiohdr->data_len;
WaveData->header.lpData = audiohdr->data;
waveOutPrepareHeader(WaveData->hWaveOut, &WaveData->header, sizeof(WAVEHDR));
waveOutWrite(WaveData->hWaveOut, &WaveData->header, sizeof(WAVEHDR));
return (WaveData);
}
#endif
+29
View File
@@ -0,0 +1,29 @@
//
//
// Ur-Quan Masters Voice-over / Subtitle Synchronization tool
// Copyright 2003 by Geoffrey Hausheer
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA.
//
// contact tcpaiqgvnmbf28f001@sneakemail.com for bugs/issues
//
typedef struct {
unsigned long samp_freq;
unsigned long bits_per_sample;
unsigned long channels;
char *data;
unsigned long data_len;
} AUDIOHDR;
+142
View File
@@ -0,0 +1,142 @@
//
//
// Ur-Quan Masters Voice-over / Subtitle Synchronization tool
// Copyright 2003 by Geoffrey Hausheer
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA.
//
// contact tcpaiqgvnmbf28f001@sneakemail.com for bugs/issues
//
#if (USE_SDLAUDIO == 1)
char AUDIO_TYPE[] = "SDL";
#include <SDL.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "audio.h"
/* doesn't Win32 have M_PI? */
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
typedef struct {
SDL_AudioSpec spec;
char *data;
unsigned long data_len;
unsigned long data_pos;
} WAVESTRUCT;
void fill_audio(void *u, Uint8 *stream, int len);
unsigned long clocks_per_sec = 1000;
unsigned long get_clock()
{
return (SDL_GetTicks());
}
void init_sound ()
{
if(SDL_Init(SDL_INIT_AUDIO) < 0) {
fprintf(stderr,"could not initialize SDL audio\n");
exit(-1);
}
}
WAVESTRUCT *play_sound(AUDIOHDR *audiohdr)
{
WAVESTRUCT *WaveData = new WAVESTRUCT;
/*
WaveData->spec.freq = 22050;
WaveData->spec.format = AUDIO_S16;
WaveData->spec.channels = 2;
WaveData->spec.samples = 1024;
WaveData->spec.callback = fill_audio;
*/
WaveData->spec.freq = audiohdr->samp_freq;
WaveData->spec.format = AUDIO_S16;
WaveData->spec.channels = audiohdr->channels;
WaveData->spec.samples = 1024;
WaveData->spec.callback = fill_audio;
WaveData->spec.userdata = WaveData;
WaveData->data = audiohdr->data;
WaveData->data_len = audiohdr->data_len;
WaveData->data_pos = 0;
if(SDL_OpenAudio(&WaveData->spec, NULL) < 0) {
fprintf(stderr,"could not open SDL audio\n");
exit(-1);
}
SDL_PauseAudio(0);
return (WaveData);
}
void pause_sound(WAVESTRUCT *WaveData)
{
if (WaveData)
SDL_PauseAudio(1);
}
void unpause_sound (WAVESTRUCT *WaveData)
{
if (WaveData)
SDL_PauseAudio(0);
}
void reset_sound (WAVESTRUCT *WaveData)
{
if (WaveData) {
SDL_CloseAudio();
delete WaveData->data;
delete WaveData;
}
}
/*
void fill_audio (void *u, Uint8 *stream, int len)
{
Sint16 *b;
int l, i;
double factor;
printf("%p is %d\n", u, *(int*)u);
factor = Frequency / 22050.0 * 2.0 * M_PI;
l = len * sizeof *stream / sizeof *b; // yuck
b = (Sint16 *)malloc(l * sizeof *b);
for(i = 0; i < l / 2; i++, Offset++) {
double v = cos(Offset * factor);
b[i * 2] = b[i * 2 + 1] = (int)(v * 32767);
}
memcpy(stream, b, len);
free(b);
}
*/
void fill_audio (void *u, Uint8 *stream, int len)
{
Sint16 *b;
int l, i;
long amt_left;
WAVESTRUCT *WaveData = (WAVESTRUCT *)u;
amt_left = WaveData->data_len - WaveData->data_pos;
if (amt_left > len)
amt_left = len;
memcpy(stream, WaveData->data + WaveData->data_pos, amt_left);
WaveData->data_pos += amt_left;
}
#endif
+82
View File
@@ -0,0 +1,82 @@
#!/usr/bin/perl -w
@txtlist = ();
@tsdir = ();
if (! scalar (@ARGV)) {
if (! -d "./comm") {
print "Didn't find 'comm' directory\n";
exit(1);
}
if (! -d "./timestamp") {
print "Didn't find 'timestamp' directory\n";
exit(1);
}
foreach $dir (glob "./comm/*") {
($root) = ($dir =~ /([^\/\\]+)$/);
($txt) = glob "$dir/*.txt";
if (! defined $txt) {
printf "Couldn't find $dir/*.txt\n";
} elsif (-d $dir && -f $txt && -d "./timestamp/$root") {
print "Found $dir\n";
push @txtlist, $txt;
push @tsdir, "./timestamp/$root";
}
}
} else {
if ($ARGV[0] =~ /^(.*).txt$/ && -e $ARGV[0]) {
push @txtlist, $ARGV[0];
} else {
print "Didn't find file: $ARGV[0]\n";
exit (1);
}
if (! -d $ARGV[1]) {
print "Couldn't find timestamp directory: $ts_dir\n";
exit (1);
} else {
push @tsdir, $ARGV[1];
}
}
while (@txtlist) {
$txt_file = pop @txtlist;
$ts_dir = pop @tsdir;
$ts_merge_file = $txt_file;
$ts_merge_file =~ s/\.txt$/.ts/;
print "building $ts_merge_file from $txt_file and $ts_dir\n";
open (FH, $txt_file);
open (tsFH, ">$ts_merge_file");
while (<FH>) {
if (/^#\((\S+)\)/) {
$name = $1;
$str = "";
if (/\s+(\S+)\s*$/) {
$voice_file = $1;
($ts_file) = ($voice_file =~ /^(.*).ogg/);
$ts_file = "$ts_dir/$ts_file.ts";
if (-f $ts_file) {
open (ts1FH, $ts_file);
@data=();
$chksum = 0;
print "$ts_file\n";
while (<ts1FH>) {
chomp;
if (/Checksum:\s+(\d+)/) {
$chksum = $1;
}
if (/^\s+(\S+)/) {
$value = int ($1 *1000);
if ($value != 0) {
push @data, $value - $last_val;
}
$last_val = $value;
}
}
close (ts1FH);
$str = join ",", @data;
# print "$chksum: $str\n";
}
}
print tsFH "#($name) $str\n";
}
}
close (FH);
close tsFH;
}
+480
View File
@@ -0,0 +1,480 @@
//
//
// Ur-Quan Masters Voice-over / Subtitle Synchronization tool
// Copyright 2003 by Geoffrey Hausheer
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA.
//
// contact tcpaiqgvnmbf28f001@sneakemail.com for bugs/issues
//
#define SYNC_VER "0.12"
#define SKIP_SINGLE_LINES
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#ifdef WIN32
#include <io.h>
#include <direct.h>
#define MKDIR mkdir
#else
#include <unistd.h>
#define MKDIR(dir) mkdir((dir), 0777)
#endif
#ifdef __linux__
#define SYNC_EXTRA_VER "Linux"
#elif defined WIN32
#define SYNC_EXTRA_VER "Windows"
#else
#define SYNC_EXTRA_VER "Unknown"
#endif
#include <math.h>
#include <vorbis/codec.h>
#include <vorbis/vorbisfile.h>
#include <FL/Fl.H>
#include <FL/fl_ask.H>
#include "synchronizer.h"
#include "synch.h"
#define WRAP_LEN 50
const char races[][13] = {
"arilou",
"blackur",
"chmmr",
"comandr",
"druuge",
"ilwrath",
"melnorm",
"mycon",
"orz",
"pkunk",
"rebel",
"shofixt",
"slyhome",
"slyland",
"spahome",
"spathi",
"starbas",
"supox",
"syreen",
"talkpet",
"thradd",
"umgah",
"urquan",
"utwig",
"vux",
"yehat",
"zoqfot",
""
};
FILEDATA *curtrack, *racedata[MAX_TRACKS];
CLIPTXTDATA *playing_clip;
XTRATRACKDATA *trackxtra;
Synchronizer *synch;
WAVESTRUCT *WaveData;
char path[80];
char savepath[80] = ".";
int
main(int argc, char **argv) {
int i = 0;
synch = new Synchronizer;
trackxtra = new XTRATRACKDATA;
init_sound ();
//Initial global objects.
while (strlen(races[i]))
{
synch->RaceChooser->add (races[i], (void *)i);
i++;
}
synch->show(argc, argv);
return Fl::run();
}
void CleanUp()
{
int i;
int max = synch->TrackSelector->nitems();
for (i=0;i<max;i++)
if (racedata[i])
delete racedata[i];
}
void DoExit()
{
reset_sound (WaveData);
CleanUp();
exit(0);
}
void DeactivateOptions()
{
synch->TrackSelector->deactivate();
synch->RaceChooser->deactivate();
synch->ChooseAllButton->deactivate();
synch->ClearAllButton->deactivate();
}
void ActivateOptions()
{
synch->TrackSelector->activate();
synch->RaceChooser->activate();
synch->ChooseAllButton->activate();
synch->ClearAllButton->activate();
}
void PrintFrameNum ()
{
char buf[20];
sprintf(buf,"%d of %d",playing_clip->frame_num, curtrack->num_lines);
synch->CurrentFrame->value(buf);
}
void UpdatePlayTime (int start)
{
int i, max, mins, secs;
unsigned long tracktime = 0;
char buf[20];
max = synch->TrackSelector->nitems();
for (i= start; i <= max; i++)
if (synch->TrackSelector->checked(i))
tracktime += racedata[i-1]->tracktime;
mins = tracktime / 60;
secs = tracktime - 60 * mins;
sprintf (buf,"%d:%02d",mins,secs);
synch->PlayTime->value(buf);
}
void StopPlayback ()
{
reset_sound (WaveData);
WaveData=NULL;
trackxtra->tracknum = 0;
ActivateOptions();
}
void StartPlayback ()
{
int i, start, max;
max = synch->TrackSelector->nitems();
if (! trackxtra->tracknum)
{
start = 1;
} else {
start = trackxtra->tracknum + 1;
}
trackxtra->tracknum = 0;
for (i=start; i<= max; i++) {
if (synch->TrackSelector->checked(i))
{
trackxtra->tracknum = i;
break;
}
}
if (trackxtra->tracknum)
{
char *block;/* pointer to the block */
unsigned long blockSize;/* holds the size of the block */
char buf[80];
AUDIOHDR audiohdr;
trackxtra->paused = 0;
reset_sound (WaveData);
WaveData = NULL;
DeactivateOptions();
curtrack = racedata[trackxtra->tracknum-1];
playing_clip = curtrack->clip;
if (! playing_clip) {
fprintf (stderr, "Couldn't find track text for %s\n",curtrack->filename);
return;
}
synch->CurrentTrack->value(curtrack->filename);
UpdatePlayTime(trackxtra->tracknum);
PrintFrameNum();
synch->TextScreen->value(playing_clip->str);
sprintf (buf, "%s/%s",path, curtrack->filename);
if (read_ogg (buf, &audiohdr)) {
fprintf (stderr, "Ogg Read failed!\n");
playing_clip = 0;
return;
}
curtrack->chksum = checksum(buf);
WaveData = play_sound(&audiohdr);
trackxtra->time=get_clock();
} else {
StopPlayback();
}
}
void RestartFrame ()
{
if (trackxtra->tracknum) {
trackxtra->tracknum--;
}
StartPlayback();
}
void SaveTimestamps()
{
char buf[80], buf1[80];
CLIPTXTDATA *curclip;
FILE *fh;
strcpy (buf1, curtrack->filename);
buf1[strlen(buf1)-4]=0;
sprintf (buf, "%s/%s.ts",savepath, buf1);
fh = fopen(buf,"w");
fprintf(fh,"Version: %s-%s-%s\n",SYNC_VER, SYNC_EXTRA_VER, AUDIO_TYPE);
fprintf(fh,"Checksum: %lu\n",curtrack->chksum);
curclip = curtrack->clip;
while (curclip != NULL) {
fprintf(fh,"%8.3f\n",(double)(curclip->time)/clocks_per_sec);
curclip = curclip->Next;
}
fclose (fh);
}
void NextFrame ()
{
unsigned long curtime;
if (! trackxtra->tracknum || trackxtra->paused)
return;
if (playing_clip->Next == NULL)
StartPlayback();
else {
curtime = get_clock();
printf ("Frame time: %d\n",curtime-trackxtra->time);
playing_clip = playing_clip->Next;
playing_clip->time = curtime-trackxtra->time;
synch->TextScreen->value(playing_clip->str);
PrintFrameNum();
if (playing_clip->Next == NULL)
SaveTimestamps();
}
}
void wrapstr (char *dst, char *src)
{
int i,j,last=0;
for (i = 0; i < strlen (src); i++) {
*dst++ = src[i];
if (i == last) {
if (i != 0) {
*dst++ = '\n';
}
last = strlen(src);
for (j=i+1; j < strlen (src); j++) {
if (j -i > WRAP_LEN)
break;
if (src[j] == ' ') {
last = j;
}
}
if (j == strlen (src))
last = j;
}
}
*dst = 0;
}
void PauseFrame ()
{
unsigned long curtime;
if(trackxtra->paused)
unpause_sound(WaveData);
else
pause_sound(WaveData);
curtime = get_clock();
trackxtra->time = curtime - trackxtra->time;
trackxtra->paused = ! trackxtra->paused;
}
void GetTracks (int value)
{
const char *race;
char buf[80];
char str[MAX_LEN];
int i = 0, read_data = 0;
CLIPTXTDATA *curclip;
FILE *fh;
race = races[value - 1];
CleanUp();
sprintf (path, "comm/%s",race);
sprintf (buf, "%s/%s.txt",path, race);
fh = fopen (buf, "r");
if (!fh) {
char buf1[100];
sprintf (buf1, "Could not find %s!",buf);
fl_alert (buf1);
return;
}
char tmp[80];
MKDIR ("timestamp");
sprintf(savepath,"timestamp/%s",race);
MKDIR (savepath);
synch->TrackSelector->clear ();
while (fgets(str,512,fh))
{
str[strlen (str) - 1] = 0;
if(str[0] == '#')
{
char *tmp;
read_data = 0;
tmp = strtok (str, "\t ");
if ((tmp = strtok (NULL, "\t ")) != NULL)
{
#ifdef SKIP_SINGLE_LINES
if (i && racedata[i-1]->num_lines < 2) {
delete racedata[i-1];
i--;
}
#endif
if (i && ! racedata[i-1]->tracktime) {
char buf[80];
sprintf(buf,"%s/%s",path, racedata[i-1]->filename);
racedata[i-1]->tracktime = get_ogg_runtime(buf);
synch->TrackSelector->add (racedata[i-1]->filename);
if (! racedata[i-1]->tracktime) {
fprintf(stderr, "couldn't read %s\n", racedata[i-1]->filename);
racedata[i-1]->tracktime = 1;
}
}
i++;
racedata[i-1] = new FILEDATA;
strcpy (racedata[i-1]->filename, tmp);
curclip = NULL;
read_data = 1;
}
}
else if (read_data && strlen (str))
{
if (racedata[i-1]->clip == NULL) {
racedata[i-1]->clip = new CLIPTXTDATA;
curclip = racedata[i-1]->clip;
} else {
curclip->Next = new CLIPTXTDATA;
curclip = curclip->Next;
}
wrapstr (curclip->str, str);
racedata[i-1]->num_lines++;
curclip->frame_num = racedata[i-1]->num_lines;
}
if (feof (fh))
break;
}
#ifdef SKIP_SINGLE_LINES
if (i && racedata[i-1]->num_lines < 2) {
delete racedata[i-1];
i--;
}
#endif
if (i && ! racedata[i-1]->tracktime) {
char buf[80];
sprintf(buf,"%s/%s",path, racedata[i-1]->filename);
racedata[i-1]->tracktime = get_ogg_runtime(buf);
synch->TrackSelector->add (racedata[i-1]->filename);
}
synch->TrackSelector->position (1);
}
unsigned long
get_ogg_runtime (char *filename) {
OggVorbis_File vf;
vorbis_info *vi;
FILE *fh;
unsigned long runtime;
double rt;
fh = fopen(filename, "rb");
if (fh == NULL)
return (0);
if(ov_open(fh, &vf, NULL, 0) < 0)
return (0);
rt = ov_time_total(&vf, -1);
runtime = (unsigned long)(rt + 0.5);
ov_clear(&vf);
fclose(fh);
printf("%s : %lu (%f)\n",filename, runtime, rt);
return(runtime);
}
int
read_ogg (char *filename, AUDIOHDR *audiohdr) {
OggVorbis_File vf;
vorbis_info *vi;
FILE *fh;
char *wav;
int current_section;
fh = fopen(filename, "rb");
if (fh == NULL) {
fprintf (stderr, "Couldn't find file: %s\n", filename);
return (1);
}
if(ov_open(fh, &vf, NULL, 0) < 0) {
fprintf(stderr,"Input does not appear to be an Ogg bitstream.\n");
return (1);
}
vi=ov_info(&vf,-1);
audiohdr->samp_freq = vi->rate;
audiohdr->channels = vi->channels;
audiohdr->bits_per_sample = 16;
{
const unsigned int extra=10000;
unsigned int numsamples = extra+(unsigned int)ov_pcm_total(&vf,0);
unsigned int numbytes = numsamples*vi->channels*2; // 16bit output wav
char *wavptr;
int eof = 0;
unsigned long readbytes = 0;
audiohdr->data = new char[numbytes];
wavptr = audiohdr->data;
while(!eof){
long ret=ov_read(&vf,wavptr,numbytes-readbytes,0,2,1,&current_section);
if (ret == 0) {
eof=1;
} else if (ret > 0) {
readbytes += ret;
wavptr += ret;
}
}
audiohdr->data_len = readbytes;
}
ov_clear(&vf);
fclose(fh);
return (0);
}
unsigned long checksum(char *filename)
{
int fh;
unsigned long chk= 0, buf = 0;
fh = open(filename,O_RDONLY);
if (fh == -1)
return 0;
while (read (fh,&buf,sizeof(buf)) > 0 )
chk = ((chk << 1) | (chk >> 31)) ^ buf;
close(fh);
return (chk);
}
+94
View File
@@ -0,0 +1,94 @@
//
//
// Ur-Quan Masters Voice-over / Subtitle Synchronization tool
// Copyright 2003 by Geoffrey Hausheer
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA.
//
// contact tcpaiqgvnmbf28f001@sneakemail.com for bugs/issues
//
#include "audio.h"
#define MAX_LEN 200
#define MAX_TRACKS 300
typedef struct CLIPTXTDATA {
char str[MAX_LEN];
unsigned long time;
int frame_num;
CLIPTXTDATA *Next;
CLIPTXTDATA ()
{
str[0] = 0;
time = 0;
frame_num = 0;
Next = NULL;
}
~CLIPTXTDATA ()
{
if(Next !=NULL)
delete Next;
}
} CLIPTXTDATA;
typedef struct FILEDATA {
char filename[20];
int num_lines;
long chksum;
unsigned long tracktime;
CLIPTXTDATA *clip;
FILEDATA ()
{
num_lines = 0;
clip = NULL;
chksum = 0;
tracktime = 0;
filename[0] = 0;
}
~FILEDATA()
{
if (clip != NULL)
delete clip;
clip = NULL;
}
} FILEDATA;
typedef struct XTRATRACKDATA {
unsigned long time;
int tracknum;
int paused;
XTRATRACKDATA () {
time = 0;
tracknum = 0;
paused = 0;
}
} XTRATRACKDATA;
int read_ogg (char *filename, AUDIOHDR *audiohdr);
unsigned long get_ogg_runtime (char *filename);
unsigned long checksum(char *filename);
unsigned long get_clock();
extern unsigned long clocks_per_sec;
extern char AUDIO_TYPE[];
typedef struct {int bogus;} WAVESTRUCT;
void init_sound ();
void reset_sound (WAVESTRUCT *WaveData);
void pause_sound (WAVESTRUCT *WaveData);
void unpause_sound (WAVESTRUCT *WaveData);
WAVESTRUCT *play_sound(AUDIOHDR *audiohdr);
+158
View File
@@ -0,0 +1,158 @@
// generated by Fast Light User Interface Designer (fluid) version 1.0102
#include "synchronizer.h"
inline void Synchronizer::cb_Exit_i(Fl_Menu_*, void*) {
DoExit();
}
void Synchronizer::cb_Exit(Fl_Menu_* o, void* v) {
((Synchronizer*)(o->parent()->user_data()))->cb_Exit_i(o,v);
}
Fl_Menu_Item Synchronizer::menu_MainMenu[] = {
{"File", 0, 0, 0, 64, 0, 0, 14, 56},
{"Exit", 0, (Fl_Callback*)Synchronizer::cb_Exit, 0, 0, 0, 0, 14, 56},
{0},
{0}
};
Fl_Menu_Item* Synchronizer::File = Synchronizer::menu_MainMenu + 0;
Fl_Menu_Item* Synchronizer::Exit = Synchronizer::menu_MainMenu + 1;
inline void Synchronizer::cb_RaceChooser_i(Fl_Browser*, void*) {
GetTracks (RaceChooser->value());
}
void Synchronizer::cb_RaceChooser(Fl_Browser* o, void* v) {
((Synchronizer*)(o->parent()->user_data()))->cb_RaceChooser_i(o,v);
}
inline void Synchronizer::cb_TrackSelector_i(Fl_Check_Browser*, void*) {
UpdatePlayTime(1);
}
void Synchronizer::cb_TrackSelector(Fl_Check_Browser* o, void* v) {
((Synchronizer*)(o->parent()->user_data()))->cb_TrackSelector_i(o,v);
}
inline void Synchronizer::cb_ChooseAllButton_i(Fl_Button*, void*) {
TrackSelector->check_all();UpdatePlayTime(1);
}
void Synchronizer::cb_ChooseAllButton(Fl_Button* o, void* v) {
((Synchronizer*)(o->parent()->user_data()))->cb_ChooseAllButton_i(o,v);
}
inline void Synchronizer::cb_ClearAllButton_i(Fl_Button*, void*) {
TrackSelector->check_none();UpdatePlayTime(1);
}
void Synchronizer::cb_ClearAllButton(Fl_Button* o, void* v) {
((Synchronizer*)(o->parent()->user_data()))->cb_ClearAllButton_i(o,v);
}
inline void Synchronizer::cb_PauseButton_i(Fl_Button*, void*) {
PauseFrame ();
}
void Synchronizer::cb_PauseButton(Fl_Button* o, void* v) {
((Synchronizer*)(o->parent()->user_data()))->cb_PauseButton_i(o,v);
}
inline void Synchronizer::cb_NextButton_i(Fl_Button*, void*) {
NextFrame();
}
void Synchronizer::cb_NextButton(Fl_Button* o, void* v) {
((Synchronizer*)(o->parent()->user_data()))->cb_NextButton_i(o,v);
}
inline void Synchronizer::cb_StartButton_i(Fl_Button*, void*) {
StartPlayback ();
}
void Synchronizer::cb_StartButton(Fl_Button* o, void* v) {
((Synchronizer*)(o->parent()->user_data()))->cb_StartButton_i(o,v);
}
inline void Synchronizer::cb_RestartButton_i(Fl_Button*, void*) {
RestartFrame ();
}
void Synchronizer::cb_RestartButton(Fl_Button* o, void* v) {
((Synchronizer*)(o->parent()->user_data()))->cb_RestartButton_i(o,v);
}
inline void Synchronizer::cb_StopButton_i(Fl_Button*, void*) {
StopPlayback();
}
void Synchronizer::cb_StopButton(Fl_Button* o, void* v) {
((Synchronizer*)(o->parent()->user_data()))->cb_StopButton_i(o,v);
}
Synchronizer::Synchronizer() {
Fl_Window* w;
{ Fl_Window* o = MainWindow = new Fl_Window(597, 356);
w = o;
o->user_data((void*)(this));
{ Fl_Menu_Bar* o = MainMenu = new Fl_Menu_Bar(0, 0, 475, 25);
o->menu(menu_MainMenu);
}
{ Fl_Output* o = CurrentTrack = new Fl_Output(245, 25, 135, 25, "Playing track:");
CurrentTrack->deactivate();
}
{ Fl_Output* o = CurrentFrame = new Fl_Output(455, 25, 135, 25, "Frame:");
CurrentFrame->deactivate();
}
{ Fl_Output* o = PlayTime = new Fl_Output(475, 0, 115, 25, "Time left:");
PlayTime->deactivate();
}
{ Fl_Output* o = TextScreen = new Fl_Output(155, 50, 435, 180);
o->type(12);
o->textsize(16);
TextScreen->deactivate();
}
{ Fl_Slider* o = Slider = new Fl_Slider(155, 235, 435, 30);
o->type(5);
Slider->deactivate();
}
{ Fl_Browser* o = RaceChooser = new Fl_Browser(0, 50, 145, 105);
o->type(2);
o->callback((Fl_Callback*)cb_RaceChooser);
RaceChooser->has_scrollbar(Fl_Browser_::VERTICAL);
}
{ Fl_Check_Browser* o = TrackSelector = new Fl_Check_Browser(0, 180, 145, 120);
o->callback((Fl_Callback*)cb_TrackSelector);
o->when(FL_WHEN_RELEASE);
TrackSelector->has_scrollbar(Fl_Browser_::VERTICAL);
}
{ Fl_Button* o = ChooseAllButton = new Fl_Button(10, 305, 120, 20, "Choose All");
o->callback((Fl_Callback*)cb_ChooseAllButton);
}
{ Fl_Button* o = ClearAllButton = new Fl_Button(10, 330, 120, 20, "Clear All");
o->callback((Fl_Callback*)cb_ClearAllButton);
}
new Fl_Box(0, 30, 130, 20, "Race");
new Fl_Box(5, 160, 120, 20, "Track");
{ Fl_Button* o = PauseButton = new Fl_Button(335, 280, 105, 45, " Pause");
o->shortcut(0x70);
o->labelfont(1);
o->labelsize(16);
o->callback((Fl_Callback*)cb_PauseButton);
}
{ Fl_Button* o = NextButton = new Fl_Button(155, 280, 135, 45, "Next Screen");
o->shortcut(0x6e);
o->labelfont(1);
o->labelsize(16);
o->callback((Fl_Callback*)cb_NextButton);
}
{ Fl_Button* o = StartButton = new Fl_Button(490, 305, 100, 20, "Start");
o->labelfont(1);
o->callback((Fl_Callback*)cb_StartButton);
}
{ Fl_Button* o = RestartButton = new Fl_Button(490, 280, 100, 20, "Restart");
o->labelfont(1);
o->callback((Fl_Callback*)cb_RestartButton);
}
{ Fl_Button* o = StopButton = new Fl_Button(490, 330, 100, 20, "Stop");
o->labelfont(1);
o->callback((Fl_Callback*)cb_StopButton);
}
o->end();
}
}
void Synchronizer::show(int argc, char **argv) {
MainWindow->show(argc, argv);
}
+132
View File
@@ -0,0 +1,132 @@
# data file for the Fltk User Interface Designer (fluid)
version 1.0102
header_name {.h}
code_name {.cpp}
decl {extern void NextFrame ();} {public
}
decl {extern void PauseFrame ();} {public
}
decl {extern void GetTracks(int value);} {public
}
decl {extern void StartPlayback();} {public
}
decl {extern void StopPlayback();} {public
}
decl {extern void RestartFrame();} {public
}
decl {extern void DoExit();} {public
}
decl {extern void UpdatePlayTime(int);} {selected public
}
class Synchronizer {open
} {
Function {Synchronizer()} {open
} {
Fl_Window MainWindow {open
xywh {366 309 597 356} visible
} {
Fl_Menu_Bar MainMenu {open
xywh {0 0 475 25}
} {
submenu File {
label File open
xywh {0 0 100 20}
} {
menuitem Exit {
label Exit
callback {DoExit();}
xywh {5 5 100 20}
}
}
}
Fl_Output CurrentTrack {
label {Playing track:}
xywh {245 25 135 25}
code0 {CurrentTrack->deactivate();}
}
Fl_Output CurrentFrame {
label {Frame:}
xywh {455 25 135 25}
code0 {CurrentFrame->deactivate();}
}
Fl_Output PlayTime {
label {Time left:}
xywh {475 0 115 25}
code0 {PlayTime->deactivate();}
}
Fl_Output TextScreen {
xywh {155 50 435 180} type Multiline textsize 16
code0 {TextScreen->deactivate();}
}
Fl_Slider Slider {
xywh {155 235 435 30} type {Horz Knob}
code0 {Slider->deactivate();}
}
Fl_Browser RaceChooser {
callback {GetTracks (RaceChooser->value());}
xywh {0 50 145 105} type Hold
code0 {RaceChooser->has_scrollbar(Fl_Browser_::VERTICAL);}
}
Fl_Check_Browser TrackSelector {
callback {UpdatePlayTime(1);}
xywh {0 180 145 120} when 4
code0 {TrackSelector->has_scrollbar(Fl_Browser_::VERTICAL);}
}
Fl_Button ChooseAllButton {
label {Choose All}
callback {TrackSelector->check_all();UpdatePlayTime(1);}
xywh {10 305 120 20}
}
Fl_Button ClearAllButton {
label {Clear All}
callback {TrackSelector->check_none();UpdatePlayTime(1);}
xywh {10 330 120 20}
}
Fl_Box {} {
label Race
xywh {0 30 130 20}
}
Fl_Box {} {
label Track
xywh {5 160 120 20}
}
Fl_Button PauseButton {
label { Pause}
callback {PauseFrame ();}
xywh {335 280 105 45} shortcut 0x70 labelfont 1 labelsize 16
}
Fl_Button NextButton {
label {Next Screen}
callback {NextFrame();}
xywh {155 280 135 45} shortcut 0x6e labelfont 1 labelsize 16
}
Fl_Button StartButton {
label Start
callback {StartPlayback ();}
xywh {490 305 100 20} labelfont 1
}
Fl_Button RestartButton {
label Restart
callback {RestartFrame ();}
xywh {490 280 100 20} labelfont 1
}
Fl_Button StopButton {
label Stop
callback {StopPlayback();}
xywh {490 330 100 20} labelfont 1
}
}
}
Function {show(int argc, char **argv)} {open
} {
code {MainWindow->show(argc, argv);} {}
}
}
+87
View File
@@ -0,0 +1,87 @@
// generated by Fast Light User Interface Designer (fluid) version 1.0102
#ifndef synchronizer_h
#define synchronizer_h
#include <FL/Fl.H>
extern void NextFrame ();
extern void PauseFrame ();
extern void GetTracks(int value);
extern void StartPlayback();
extern void StopPlayback();
extern void RestartFrame();
extern void DoExit();
extern void UpdatePlayTime(int);
#include <FL/Fl_Window.H>
#include <FL/Fl_Menu_Bar.H>
#include <FL/Fl_Output.H>
#include <FL/Fl_Slider.H>
#include <FL/Fl_Browser.H>
#include <FL/Fl_Check_Browser.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Box.H>
class Synchronizer {
public:
Synchronizer();
Fl_Window *MainWindow;
Fl_Menu_Bar *MainMenu;
static Fl_Menu_Item menu_MainMenu[];
static Fl_Menu_Item *File;
static Fl_Menu_Item *Exit;
private:
inline void cb_Exit_i(Fl_Menu_*, void*);
static void cb_Exit(Fl_Menu_*, void*);
public:
Fl_Output *CurrentTrack;
Fl_Output *CurrentFrame;
Fl_Output *PlayTime;
Fl_Output *TextScreen;
Fl_Slider *Slider;
Fl_Browser *RaceChooser;
private:
inline void cb_RaceChooser_i(Fl_Browser*, void*);
static void cb_RaceChooser(Fl_Browser*, void*);
public:
Fl_Check_Browser *TrackSelector;
private:
inline void cb_TrackSelector_i(Fl_Check_Browser*, void*);
static void cb_TrackSelector(Fl_Check_Browser*, void*);
public:
Fl_Button *ChooseAllButton;
private:
inline void cb_ChooseAllButton_i(Fl_Button*, void*);
static void cb_ChooseAllButton(Fl_Button*, void*);
public:
Fl_Button *ClearAllButton;
private:
inline void cb_ClearAllButton_i(Fl_Button*, void*);
static void cb_ClearAllButton(Fl_Button*, void*);
public:
Fl_Button *PauseButton;
private:
inline void cb_PauseButton_i(Fl_Button*, void*);
static void cb_PauseButton(Fl_Button*, void*);
public:
Fl_Button *NextButton;
private:
inline void cb_NextButton_i(Fl_Button*, void*);
static void cb_NextButton(Fl_Button*, void*);
public:
Fl_Button *StartButton;
private:
inline void cb_StartButton_i(Fl_Button*, void*);
static void cb_StartButton(Fl_Button*, void*);
public:
Fl_Button *RestartButton;
private:
inline void cb_RestartButton_i(Fl_Button*, void*);
static void cb_RestartButton(Fl_Button*, void*);
public:
Fl_Button *StopButton;
private:
inline void cb_StopButton_i(Fl_Button*, void*);
static void cb_StopButton(Fl_Button*, void*);
public:
void show(int argc, char **argv);
};
#endif