예제 #1
0
 public static void ProcessAudio(AudioClip clip, AutoSyncDataReadyDelegate dataReadyCallback, AutoSyncFailedDelegate failedCallback, string progressPrefix, AutoSyncOptions options)
 {
 }
예제 #2
0
 public static void ProcessAudio(AudioClip clip, AutoSyncDataReadyDelegate callback, AutoSyncFailedDelegate failedCallback, AutoSyncOptions options)
 {
 }
예제 #3
0
        /// <summary>
        /// Begin processing an audioclip. Phoneme data will be passed along with the input AudioClip to the AutoSyncDataReadyDelegate callback.
        /// </summary>
        /// <param name="clip">AudioClip to be processed.</param>
        /// <param name="languageModel">Name of a language model present in the project.</param>
        /// <param name="dataReadyCallback">Method that will receive the results of the process.</param>
        /// <param name="progressPrefix">Prefix shown on the progress bar.</param>
        /// <param name="enableConversion">If true, audio files will be temporarily converted if possible to maximise compatibility.</param>
        public static void ProcessAudio(AudioClip clip, AutoSyncDataReadyDelegate dataReadyCallback, AutoSyncFailedDelegate failedCallback, string progressPrefix, AutoSyncOptions options)
        {
            if (clip == null)
            {
                return;
            }
            EditorUtility.DisplayProgressBar(progressPrefix + " - Analysing Audio File", "Please wait, analysing file " + progressPrefix, 0.1f);

            bool   converted = false;
            string audioPath = AssetDatabase.GetAssetPath(clip).Substring("/Assets".Length);

            if (audioPath != null)
            {
                // Get absolute path
                audioPath = Application.dataPath + "/" + audioPath;

                // Check Path
                if (audioPath.IndexOfAny(Path.GetInvalidPathChars()) >= 0 || Path.GetFileNameWithoutExtension(audioPath).IndexOfAny(Path.GetInvalidFileNameChars()) >= 0)
                {
                    EditorUtility.ClearProgressBar();
                    failedCallback.Invoke("AutoSync failed. Audio path or filename contained invalid characters.");
                    return;
                }

                bool failed = false;
                // Convert to acceptable format
                if (options.useAudioConversion)
                {
                    if (CheckSoX())
                    {
                        EditorUtility.DisplayProgressBar(progressPrefix + " - Converting Audio File", "Please wait, converting file " + progressPrefix, 0.2f);
                        converted = true;

                        string newAudioPath = Application.dataPath + "/" + Path.GetFileNameWithoutExtension(audioPath) + "_temp_converted.wav";
                        string soXPath      = EditorPrefs.GetString("LipSync_SoXPath");

                        // Convert to compatible .wav file
                        string soXArgs = "\"" + audioPath + "\" -c 1 -b 16 -e s -r 16k \"" + newAudioPath + "\"";
                        audioPath = newAudioPath;

                        System.Diagnostics.Process process = new System.Diagnostics.Process();
                        process.StartInfo.FileName              = soXPath;
                        process.StartInfo.Arguments             = soXArgs;
                        process.StartInfo.UseShellExecute       = false;
                        process.StartInfo.CreateNoWindow        = true;
                        process.StartInfo.RedirectStandardError = true;

                        process.ErrorDataReceived += (object e, System.Diagnostics.DataReceivedEventArgs outLine) => {
                            if (!string.IsNullOrEmpty(outLine.Data))
                            {
                                if (outLine.Data.Contains("FAIL"))
                                {
                                    failed    = true;
                                    converted = false;
                                    process.Close();
                                    failedCallback.Invoke("AutoSync: SoX Conversion Failed: " + outLine.Data);
                                }
                            }
                        };

                        process.Start();
                        process.BeginErrorReadLine();
                        process.WaitForExit(5000);
                    }
                }

                if (!File.Exists(audioPath) || failed)
                {
                    EditorUtility.ClearProgressBar();
                    return;
                }

                // Split into multiple clips if necessary
                if (clip.length > 30 && options.useAudioConversion)
                {
                    multiFileLength = clip.length;
                    multiFileOffset = 0;
                    tempData        = new List <PhonemeMarker> [Mathf.CeilToInt(clip.length / 30)];
                    tempPaths       = new string[Mathf.CeilToInt(clip.length / 30)];

                    // Create paths
                    for (int l = 0; l < Mathf.CeilToInt(clip.length / 30); l++)
                    {
                        tempPaths[l] = Application.dataPath + "/" + Path.GetFileNameWithoutExtension(audioPath) + "_chunk_" + (l + 1) + ".wav";
                    }

                    string soXPath = EditorPrefs.GetString("LipSync_SoXPath");
                    string soXArgs = "\"" + audioPath + "\" \"" + Application.dataPath + "/" + Path.GetFileNameWithoutExtension(audioPath) + "_chunk_%1n.wav\" trim 0 30 : newfile : restart";

                    System.Diagnostics.Process process = new System.Diagnostics.Process();
                    process.StartInfo.FileName              = soXPath;
                    process.StartInfo.Arguments             = soXArgs;
                    process.StartInfo.UseShellExecute       = false;
                    process.StartInfo.CreateNoWindow        = true;
                    process.StartInfo.RedirectStandardError = true;

                    process.ErrorDataReceived += (object e, System.Diagnostics.DataReceivedEventArgs outLine) => {
                        if (!string.IsNullOrEmpty(outLine.Data))
                        {
                            if (outLine.Data.Contains("FAIL"))
                            {
                                failedCallback.Invoke("AutoSync: SoX Audio Splitting Failed: " + outLine.Data);
                                failed    = true;
                                converted = false;
                                process.Close();
                            }
                        }
                    };

                    process.Start();
                    process.BeginErrorReadLine();
                    process.WaitForExit(5000);

                    if (!File.Exists(audioPath) || failed)
                    {
                        EditorUtility.ClearProgressBar();
                        return;
                    }

                    // Fix paths
                    for (int l = 0; l < tempPaths.Length; l++)
                    {
                        tempPaths[l] = "Assets" + tempPaths[l].Substring(Application.dataPath.Length);
                    }

                    // Delete overlong temporary converted file and prevent autosync from attempting it
                    tempDelegate     = dataReadyCallback;
                    tempFailDelegate = failedCallback;
                    tempClip         = clip;
                    tempOptions      = options;

                    multiFileIndex = 0;

                    if (File.Exists(audioPath))
                    {
                        File.Delete(audioPath);
                        AssetDatabase.Refresh();
                    }

                    ProcessAudio(AssetDatabase.LoadAssetAtPath <AudioClip>(tempPaths[0]), MultiClipCallback, failedCallback, options);
                    return;
                }

                EditorUtility.DisplayProgressBar(progressPrefix + " - Preparing AutoSync", "Please wait, preparing AutoSync.", 0.3f);

                // Load Language Model
                AutoSyncLanguageModel model = AutoSyncLanguageModel.Load(options.languageModel);
                if (model == null)
                {
                    EditorUtility.ClearProgressBar();
                    if (converted)
                    {
                        if (File.Exists(audioPath))
                        {
                            File.Delete(audioPath);
                            AssetDatabase.Refresh();
                        }
                    }
                    failedCallback.Invoke("AutoSync Failed: Language Model was not loaded.");
                    return;
                }
                string basePath = model.GetBasePath();

                List <string> args = new List <string>();
                args.Add("-infile"); args.Add(audioPath);
                args.Add("-hmm"); args.Add(basePath + model.hmmDir);
                args.Add("-allphone"); args.Add(basePath + model.allphoneFile);
                if (options.allphone_ciEnabled)
                {
                    args.Add("-allphone_ci"); args.Add("yes");
                }
                if (options.backtraceEnabled)
                {
                    args.Add("-backtrace"); args.Add("yes");
                }
                args.Add("-time"); args.Add("yes");
                args.Add("-beam"); args.Add("1e" + options.beamExponent);
                args.Add("-pbeam"); args.Add("1e" + options.pbeamExponent);
                args.Add("-lw"); args.Add(options.lwValue.ToString());

                EditorUtility.DisplayProgressBar(progressPrefix + " - Recognising Phonemes", "Please wait, recognising phonemes.", 0.5f);
                SphinxWrapper.Recognize(args.ToArray());

                ContinuationManager.Add(() => SphinxWrapper.isFinished, () => {
                    if (SphinxWrapper.error != null)
                    {
                        EditorUtility.ClearProgressBar();
                        failedCallback.Invoke("AutoSync Failed.");
                        EditorUtility.DisplayDialog("AutoSync Failed",
                                                    "AutoSync failed. Check the console for more information.", "OK");
                        return;
                    }

                    EditorUtility.DisplayProgressBar(progressPrefix + " - Generating Data", "Please wait, generating LipSync data.", 0.85f);

                    List <PhonemeMarker> data = ParseOutput(
                        SphinxWrapper.result.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries),
                        model,
                        clip
                        );

                    if (options.useAudioConversion)
                    {
                        data = CleanupOutput(data, options.cleanupAggression);
                    }

                    dataReadyCallback.Invoke(
                        clip,
                        data
                        );

                    if (converted)
                    {
                        if (File.Exists(audioPath))
                        {
                            File.Delete(audioPath);
                            AssetDatabase.Refresh();
                        }
                    }
                });
            }
        }