AGS Awards votes close at 13:59 BST on Wednesday 07 March 2018. You've already voted, so you've got 12 days and 0 hours left to wait before voting closes!

Author Topic: MODULE: TotalLipSync v0.5  (Read 3052 times)

Re: MODULE: TotalLipSync v0.5
« Reply #20 on: 07 Jun 2017, 03:16 »
Exactly how does the EXE reference it's own install dir? Should I make it '/sync/' or 'C:/moci/Compile/Windows/sync' or...?
It seems the directory where the TSV files are stored is hard-coded in, so it will only work if the game is in '/programme files (x86)/moci/sync', and nothing else -- which makes it hard for testing.

Re: MODULE: TotalLipSync v0.5
« Reply #21 on: 07 Jun 2017, 03:17 »
Ah, okay.

Crimson Wizard

  • AGS Project Tracker Admins
    • Best Innovation Award Winner 2013, for spearheading the AGS 3.3.0 project
    •  
    • Lifetime Achievement Award Winner
    •  
    • Crimson Wizard worked on a game that was nominated for an AGS Award!
Re: MODULE: TotalLipSync v0.5
« Reply #22 on: 07 Jun 2017, 03:21 »
Exactly how does the EXE reference it's own install dir? Should I make it '/sync/' or 'C:/moci/Compile/Windows/sync' or...?

In script you reference install dir using $INSTALLDIR$ tag like
Code: Adventure Game Studio
  1. File.Open("$INSTALLDIR$/sync/data.dat");
  2.  

There is also "old style" without such tag:
Code: Adventure Game Studio
  1. File.Open("sync/data.dat");
  2.  
But that will work only to read files, not write.

Also, AGS does not allow to use absolute paths (like C:/...), it simply won't open anything even if such file exists. This is done for security reasons.

Snarky

  • Global Moderator
  • Mittens Earl
  • Private Insultant
    • I can help with proof reading
    •  
    • I can help with translating
    •  
Re: MODULE: TotalLipSync v0.5
« Reply #23 on: 07 Jun 2017, 07:43 »
I notice '$INSTALLDIR$/sync' - is this "C:\Program Files (x86)\Adventure Game Studio 3.4.0\sync" or "my installed game\sync" dir, or "my currently un-installed un-compiled game directory\sync", or...?
Exactly how does the EXE reference it's own install dir?

:-\

AFAIK when you run the game from the Editor (with F5), game does not look into Compiled at all, it gets files and subfolders that are located right in the project's root folder.

Well, I just tested it, and if you have a "sync" folder inside "Compiled", it will be read when you run the game from the editor and reference files in "$INSTALLDIR$/sync". (But you are correct that the directory is not automatically copied into "Compiled/Windows/sync"; you have to do that yourself when you're ready to distribute the game.)

Crimson Wizard

  • AGS Project Tracker Admins
    • Best Innovation Award Winner 2013, for spearheading the AGS 3.3.0 project
    •  
    • Lifetime Achievement Award Winner
    •  
    • Crimson Wizard worked on a game that was nominated for an AGS Award!
Re: MODULE: TotalLipSync v0.5
« Reply #24 on: 07 Jun 2017, 15:05 »
AFAIK when you run the game from the Editor (with F5), game does not look into Compiled at all, it gets files and subfolders that are located right in the project's root folder.

Well, I just tested it, and if you have a "sync" folder inside "Compiled", it will be read when you run the game from the editor and reference files in "$INSTALLDIR$/sync". (But you are correct that the directory is not automatically copied into "Compiled/Windows/sync"; you have to do that yourself when you're ready to distribute the game.)

Oh right... probably I had a moment of amnesia; it was just couple of months ago what I was working around that, because in 3.4.1 Compiled folder is now Compiled/Data.

So, yes, when debugging from Editor the rules are a bit complicated, the "installdir" is actually "made" of three folders:
- working directory, which is project root folder: for example game takes font files from there
- Compiled folder: I think this was made to take speech.vox from there, and maybe something else, like translation files.
- AudioCache folder: it takes audio files from there.

Basically it looks into project root first, and if it did not find needed files, it also checks either Compiled or AudioCache, depending on what kind of material it is looking for.

Why it was made so: I think to increase compilation speeds when testing, because it does not have to gather/package all those files every time.
« Last Edit: 07 Jun 2017, 15:09 by Crimson Wizard »

Snarky

  • Global Moderator
  • Mittens Earl
  • Private Insultant
    • I can help with proof reading
    •  
    • I can help with translating
    •  
Re: MODULE: TotalLipSync v0.5
« Reply #25 on: 07 Jun 2017, 15:22 »
For the record, I think this is a good thing, because it means you can keep all your "to be distributed" files in "Compiled/", and you don't need separate copies for each target platform (with the potential nightmare of keeping all the copies in sync).

(I might split this whole discussion off as a separate thread, since it doesn't really have much to do with this module specifically.)

Snarky

  • Global Moderator
  • Mittens Earl
  • Private Insultant
    • I can help with proof reading
    •  
    • I can help with translating
    •  
Re: MODULE: TotalLipSync v0.5
« Reply #26 on: 13 Jan 2018, 12:50 »
I wrote a little script to help people who use Rhubarb to do lip-syncing.

Rhubarb does the lip-sync tracking automatically by analyzing the audio, but you can also supply the actual text of the dialog to help guide it, improving the results. Using something like this batch file, you can then create the lip-sync tracking for the entire game automatically:

Code: Bash
  1. for %%F in (clips/*.wav) do (
  2.     rhubarb.exe clips/%%~nxF -d guide/%%~nF.txt > sync/%%~nF.tsv
  3. )

There hasn't been a convenient way to create these guide files from AGS, however. This script helps to automate the task.

It works with the voice acting HTML scripts generated by the Speech Center plugin. Once you've created the voice acting scripts, place them in a subfolder (e.g. /VoiceScripts) inside your compiled game folder. Place a call to this function in your game, and run it to extract the guide files, like so:

Code: Adventure Game Studio
  1.   ExtractVoiceScriptLines("$INSTALLDIR$/VoiceScripts", "$APPDATADIR$/guide");

(The output directory must be in $APPDATADIR$ or an existing subfolder of it. Where %APPDATADIR% is pointing can be set in winsetup.exe under Advanced.)

Here's the script (yeah, I know it's ugly, but it seems to work OK):
Code: Adventure Game Studio
  1. #define SCRIPT_TOKEN_LINE_NUMBER "<span class=\"lineNumber\">"
  2. #define SCRIPT_TOKEN_TEXT_START ":</b> "
  3. #define SCRIPT_TOKEN_TEXT_END "</span>"
  4.  
  5. static String ExtractVoiceScriptLines(String sourceDirectory, String targetDirectory)
  6. {
  7.   int i=0;
  8.   String tokenLineNumber = String.Format("%s", SCRIPT_TOKEN_LINE_NUMBER);
  9.   String tokenTextStart = SCRIPT_TOKEN_TEXT_START;
  10.   String tokenTextEnd = SCRIPT_TOKEN_TEXT_END;
  11.   while(i < Game.CharacterCount)
  12.   {
  13.     String prefix = character[i].GetSpeechPrefix();
  14.     String scriptPath = String.Format("%s/char%s.html", sourceDirectory, prefix);
  15.     if(File.Exists(scriptPath))
  16.     {
  17.       File* scriptFile = File.Open(scriptPath, eFileRead);
  18.       String lineNumberPrefix = prefix;
  19.       while(!scriptFile.EOF)
  20.       {
  21.         String scriptLine = scriptFile.ReadRawLineBack();
  22.         int startLineNumberTag = scriptLine.IndexOf(tokenLineNumber);
  23.         if(startLineNumberTag != -1)
  24.         {
  25.           int startLineNumber = scriptLine.IndexOf(lineNumberPrefix);
  26.           int endLineNumber = scriptLine.IndexOf("]");
  27.           if(startLineNumber > 0 && endLineNumber > 0 && endLineNumber > startLineNumber + lineNumberPrefix.Length)
  28.           {
  29.             String strLineNumber = scriptLine.Substring(startLineNumber+lineNumberPrefix.Length, endLineNumber - startLineNumber - lineNumberPrefix.Length);
  30.             int lineNumber = strLineNumber.AsInt;
  31.             //Display("Writing %s%d", prefix, lineNumber);
  32.             if(lineNumber>0)
  33.             {
  34.               String message = "";
  35.               String dialogLine = scriptFile.ReadRawLineBack();
  36.               int startTextTag = dialogLine.IndexOf(tokenTextStart);
  37.               int endTextTag = dialogLine.IndexOf(tokenTextEnd);
  38.               if(startTextTag > 0)
  39.               {
  40.                 while(endTextTag == -1 && !scriptFile.EOF)
  41.                 {
  42.                   dialogLine = dialogLine.AppendChar(' ');
  43.                  dialogLine = dialogLine.Append(scriptFile.ReadRawLineBack());
  44.                   endTextTag = dialogLine.IndexOf(tokenTextEnd);
  45.                 }
  46.                 int textLength = endTextTag - startTextTag - tokenTextStart.Length;
  47.                 if(startTextTag > 0 && endTextTag > 0 && textLength >= 0)
  48.                   message = dialogLine.Substring(startTextTag+tokenTextStart.Length, textLength);
  49.                
  50.                 String linePath = String.Format("%s/%s%d.txt", targetDirectory, prefix, lineNumber);
  51.                 //Display("Writing line \"%s\" to file %s", message, linePath);
  52.                 File* lineFile = File.Open(linePath, eFileWrite);
  53.                 if(lineFile != null)
  54.                 {
  55.                   //Display("Writing line \"%s\" to file %s", message, linePath);
  56.                   lineFile.WriteRawLine(message);
  57.                   lineFile.Close();
  58.                 }
  59.                 else
  60.                   Display("Couldn't write line \"%s\" to file %s", message, linePath);
  61.               }
  62.             }
  63.           }
  64.         }
  65.       } // while(!scriptFile.EOF)
  66.       scriptFile.Close();
  67.     }
  68.     i++;
  69.   }
  70. }
« Last Edit: 13 Jan 2018, 12:54 by Snarky »