Some support for ASSA in TTS

This commit is contained in:
Nikolaj Olsson 2024-04-09 21:56:11 +02:00
parent a4b079f142
commit d7698208cb
4 changed files with 182 additions and 27 deletions

View File

@ -19027,7 +19027,7 @@ namespace Nikse.SubtitleEdit.Forms
}
else if (e.Modifiers == (Keys.Alt | Keys.Shift | Keys.Control) && e.KeyCode == Keys.T)
{
using (var form = new TextToSpeech(_subtitle, _videoFileName, _videoInfo))
using (var form = new TextToSpeech(_subtitle, GetCurrentSubtitleFormat(), _videoFileName, _videoInfo))
{
if (form.ShowDialog(this) != DialogResult.OK)
{

View File

@ -28,6 +28,7 @@
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.buttonOK = new System.Windows.Forms.Button();
this.labelProgress = new System.Windows.Forms.Label();
this.buttonGenerateTTS = new System.Windows.Forms.Button();
@ -35,9 +36,13 @@
this.labelEngine = new System.Windows.Forms.Label();
this.groupBoxMsSettings = new System.Windows.Forms.GroupBox();
this.labelMsVoice = new System.Windows.Forms.Label();
this.checkBoxAddToVideoFile = new System.Windows.Forms.CheckBox();
this.listView1 = new System.Windows.Forms.ListView();
this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.contextMenuStripActors = new System.Windows.Forms.ContextMenuStrip(this.components);
this.nikseComboBoxVoice = new Nikse.SubtitleEdit.Controls.NikseComboBox();
this.nikseComboBoxEngine = new Nikse.SubtitleEdit.Controls.NikseComboBox();
this.checkBoxAddToVideoFile = new System.Windows.Forms.CheckBox();
this.groupBoxMsSettings.SuspendLayout();
this.SuspendLayout();
//
@ -45,7 +50,7 @@
//
this.buttonOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.buttonOK.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.buttonOK.Location = new System.Drawing.Point(724, 407);
this.buttonOK.Location = new System.Drawing.Point(767, 456);
this.buttonOK.Name = "buttonOK";
this.buttonOK.Size = new System.Drawing.Size(75, 23);
this.buttonOK.TabIndex = 7;
@ -55,9 +60,10 @@
//
// labelProgress
//
this.labelProgress.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.labelProgress.AutoSize = true;
this.labelProgress.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.labelProgress.Location = new System.Drawing.Point(12, 384);
this.labelProgress.Location = new System.Drawing.Point(12, 433);
this.labelProgress.Name = "labelProgress";
this.labelProgress.Size = new System.Drawing.Size(70, 13);
this.labelProgress.TabIndex = 9;
@ -67,7 +73,7 @@
//
this.buttonGenerateTTS.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.buttonGenerateTTS.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.buttonGenerateTTS.Location = new System.Drawing.Point(571, 374);
this.buttonGenerateTTS.Location = new System.Drawing.Point(614, 423);
this.buttonGenerateTTS.Name = "buttonGenerateTTS";
this.buttonGenerateTTS.Size = new System.Drawing.Size(228, 23);
this.buttonGenerateTTS.TabIndex = 11;
@ -79,9 +85,9 @@
//
this.progressBar1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.progressBar1.Location = new System.Drawing.Point(12, 407);
this.progressBar1.Location = new System.Drawing.Point(12, 456);
this.progressBar1.Name = "progressBar1";
this.progressBar1.Size = new System.Drawing.Size(706, 23);
this.progressBar1.Size = new System.Drawing.Size(749, 10);
this.progressBar1.TabIndex = 12;
//
// labelEngine
@ -89,7 +95,7 @@
this.labelEngine.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.labelEngine.AutoSize = true;
this.labelEngine.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.labelEngine.Location = new System.Drawing.Point(405, 12);
this.labelEngine.Location = new System.Drawing.Point(448, 12);
this.labelEngine.Name = "labelEngine";
this.labelEngine.Size = new System.Drawing.Size(40, 13);
this.labelEngine.TabIndex = 14;
@ -101,9 +107,9 @@
| System.Windows.Forms.AnchorStyles.Right)));
this.groupBoxMsSettings.Controls.Add(this.labelMsVoice);
this.groupBoxMsSettings.Controls.Add(this.nikseComboBoxVoice);
this.groupBoxMsSettings.Location = new System.Drawing.Point(408, 57);
this.groupBoxMsSettings.Location = new System.Drawing.Point(451, 57);
this.groupBoxMsSettings.Name = "groupBoxMsSettings";
this.groupBoxMsSettings.Size = new System.Drawing.Size(391, 311);
this.groupBoxMsSettings.Size = new System.Drawing.Size(391, 320);
this.groupBoxMsSettings.TabIndex = 15;
this.groupBoxMsSettings.TabStop = false;
this.groupBoxMsSettings.Text = "Settings";
@ -119,6 +125,51 @@
this.labelMsVoice.TabIndex = 16;
this.labelMsVoice.Text = "Voice";
//
// checkBoxAddToVideoFile
//
this.checkBoxAddToVideoFile.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.checkBoxAddToVideoFile.AutoSize = true;
this.checkBoxAddToVideoFile.Location = new System.Drawing.Point(614, 397);
this.checkBoxAddToVideoFile.Name = "checkBoxAddToVideoFile";
this.checkBoxAddToVideoFile.Size = new System.Drawing.Size(176, 17);
this.checkBoxAddToVideoFile.TabIndex = 16;
this.checkBoxAddToVideoFile.Text = "Add audio to video file (new file)";
this.checkBoxAddToVideoFile.UseVisualStyleBackColor = true;
//
// listView1
//
this.listView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.listView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.columnHeader1,
this.columnHeader2});
this.listView1.ContextMenuStrip = this.contextMenuStripActors;
this.listView1.FullRowSelect = true;
this.listView1.GridLines = true;
this.listView1.HideSelection = false;
this.listView1.Location = new System.Drawing.Point(12, 28);
this.listView1.Name = "listView1";
this.listView1.Size = new System.Drawing.Size(421, 349);
this.listView1.TabIndex = 17;
this.listView1.UseCompatibleStateImageBehavior = false;
this.listView1.View = System.Windows.Forms.View.Details;
//
// columnHeader1
//
this.columnHeader1.Text = "Style";
this.columnHeader1.Width = 200;
//
// columnHeader2
//
this.columnHeader2.Text = "Voice";
this.columnHeader2.Width = 200;
//
// contextMenuStripActors
//
this.contextMenuStripActors.Name = "contextMenuStripActors";
this.contextMenuStripActors.Size = new System.Drawing.Size(61, 4);
//
// nikseComboBoxVoice
//
this.nikseComboBoxVoice.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
@ -157,7 +208,7 @@
this.nikseComboBoxEngine.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDown;
this.nikseComboBoxEngine.DropDownWidth = 195;
this.nikseComboBoxEngine.FormattingEnabled = false;
this.nikseComboBoxEngine.Location = new System.Drawing.Point(408, 28);
this.nikseComboBoxEngine.Location = new System.Drawing.Point(451, 28);
this.nikseComboBoxEngine.MaxLength = 32767;
this.nikseComboBoxEngine.Name = "nikseComboBoxEngine";
this.nikseComboBoxEngine.SelectedIndex = -1;
@ -170,21 +221,12 @@
this.nikseComboBoxEngine.UsePopupWindow = false;
this.nikseComboBoxEngine.SelectedIndexChanged += new System.EventHandler(this.nikseComboBoxEngine_SelectedIndexChanged);
//
// checkBoxAddToVideoFile
//
this.checkBoxAddToVideoFile.AutoSize = true;
this.checkBoxAddToVideoFile.Location = new System.Drawing.Point(15, 82);
this.checkBoxAddToVideoFile.Name = "checkBoxAddToVideoFile";
this.checkBoxAddToVideoFile.Size = new System.Drawing.Size(176, 17);
this.checkBoxAddToVideoFile.TabIndex = 16;
this.checkBoxAddToVideoFile.Text = "Add audio to video file (new file)";
this.checkBoxAddToVideoFile.UseVisualStyleBackColor = true;
//
// TextToSpeech
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(811, 442);
this.ClientSize = new System.Drawing.Size(854, 491);
this.Controls.Add(this.listView1);
this.Controls.Add(this.checkBoxAddToVideoFile);
this.Controls.Add(this.groupBoxMsSettings);
this.Controls.Add(this.labelEngine);
@ -218,5 +260,9 @@
private System.Windows.Forms.Label labelMsVoice;
private Controls.NikseComboBox nikseComboBoxVoice;
private System.Windows.Forms.CheckBox checkBoxAddToVideoFile;
private System.Windows.Forms.ListView listView1;
private System.Windows.Forms.ColumnHeader columnHeader1;
private System.Windows.Forms.ColumnHeader columnHeader2;
private System.Windows.Forms.ContextMenuStrip contextMenuStripActors;
}
}

View File

@ -7,6 +7,7 @@ using System.IO;
using System.Linq;
using System.Speech.Synthesis;
using System.Windows.Forms;
using Nikse.SubtitleEdit.Core.SubtitleFormats;
namespace Nikse.SubtitleEdit.Forms
{
@ -16,8 +17,17 @@ namespace Nikse.SubtitleEdit.Forms
private readonly string _videoFileName;
private readonly VideoInfo _videoInfo;
private string _waveFolder;
private readonly List<ActorAndVoice> _actorAndVoices;
public TextToSpeech(Subtitle subtitle, string videoFileName, VideoInfo videoInfo)
public class ActorAndVoice
{
public string Actor { get; set; }
public int UseCount { get; set; }
public string Voice { get; set; }
public int VoiceIndex { get; set; }
}
public TextToSpeech(Subtitle subtitle, SubtitleFormat subtitleFormat, string videoFileName, VideoInfo videoInfo)
{
UiUtil.PreInitialize(this);
InitializeComponent();
@ -39,6 +49,81 @@ namespace Nikse.SubtitleEdit.Forms
nikseComboBoxEngine.Items.Add("Tortoise TTS (very slow/very good)");
nikseComboBoxEngine.Items.Add("Mimic3");
nikseComboBoxEngine.SelectedIndex = 0;
_actorAndVoices = new List<ActorAndVoice>();
listView1.Visible = false;
if (subtitleFormat.GetType() == typeof(AdvancedSubStationAlpha))
{
var actors = _subtitle.Paragraphs
.Where(p => !string.IsNullOrEmpty(p.Actor))
.Select(p => p.Actor)
.Distinct()
.ToList();
if (actors.Any())
{
foreach (var actor in actors)
{
var actorAndVoice = new ActorAndVoice
{
Actor = actor,
UseCount = _subtitle.Paragraphs.Count(p => p.Actor == actor),
};
_actorAndVoices.Add(actorAndVoice);
}
FillActorListView();
for (var index = 0; index < nikseComboBoxVoice.Items.Count; index++)
{
var item = nikseComboBoxVoice.Items[index];
var tsi = new ToolStripMenuItem();
tsi.Tag = new ActorAndVoice { Voice = item.ToString(), VoiceIndex = index };
tsi.Text = item.ToString();
tsi.Click += (sender, args) =>
{
var a = (ActorAndVoice)(sender as ToolStripItem).Tag;
SetActor(a);
};
contextMenuStripActors.Items.Add(tsi);
listView1.Visible = true;
}
}
}
}
private void SetActor(ActorAndVoice actor)
{
foreach (int index in listView1.SelectedIndices)
{
ListViewItem item = listView1.Items[index];
var itemActor = (ActorAndVoice)item.Tag;
itemActor.Voice = actor.Voice;
itemActor.VoiceIndex = actor.VoiceIndex;
item.SubItems[1].Text = actor.Voice;
}
}
private void FillActorListView()
{
listView1.BeginUpdate();
listView1.Items.Clear();
foreach (var actor in _actorAndVoices)
{
var lvi = new ListViewItem
{
Tag = actor,
Text = actor.Actor,
};
lvi.SubItems.Add(actor.Voice);
listView1.Items.Add(lvi);
}
listView1.EndUpdate();
}
private void ButtonGenerateTtsClick(object sender, EventArgs e)
@ -226,7 +311,18 @@ namespace Nikse.SubtitleEdit.Forms
var builder = new PromptBuilder();
if (voiceInfo != null)
{
builder.StartVoice(voiceInfo);
var v = voiceInfo;
if (_actorAndVoices.Count > 0 && !string.IsNullOrEmpty(p.Actor))
{
var f = _actorAndVoices.FirstOrDefault(x => x.Actor == p.Actor);
if (f != null && !string.IsNullOrEmpty(f.Voice))
{
var item = vs[f.VoiceIndex];
v = item.VoiceInfo;
}
}
builder.StartVoice(v);
}
builder.AppendText(p.Text);
@ -283,13 +379,23 @@ namespace Nikse.SubtitleEdit.Forms
var p = _subtitle.Paragraphs[index];
var outputFileName = Path.Combine(_waveFolder, index + ".wav");
var v = voice;
if (_actorAndVoices.Count > 0 && !string.IsNullOrEmpty(p.Actor))
{
var f = _actorAndVoices.FirstOrDefault(x => x.Actor == p.Actor);
if (f != null && !string.IsNullOrEmpty(f.Voice))
{
v = f.Voice;
}
}
var processTortoiseTts = new Process
{
StartInfo =
{
WorkingDirectory = Path.GetDirectoryName(files[0]),
FileName = pythonExe,
Arguments = $"do_tts.py --output_path \"{_waveFolder}\" --preset ultra_fast --voice {voice} --text \"{p.Text.RemoveChar('"')}\"",
Arguments = $"do_tts.py --output_path \"{_waveFolder}\" --preset ultra_fast --voice {v} --text \"{p.Text.RemoveChar('"')}\"",
UseShellExecute = false,
CreateNoWindow = true,
}
@ -298,7 +404,7 @@ namespace Nikse.SubtitleEdit.Forms
processTortoiseTts.Start();
processTortoiseTts.WaitForExit();
var inputFile = Path.Combine(_waveFolder, $"{voice}_0_2.wav");
var inputFile = Path.Combine(_waveFolder, $"{v}_0_2.wav");
File.Move(inputFile, outputFileName);
progressBar1.Refresh();

View File

@ -117,4 +117,7 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="contextMenuStripActors.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>