Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/Speech/Controller/AIVOICEController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,23 @@ public float GetPitchRange()
return GetMaster().PitchRange;
}

public SoundStream ExportToStream(string text)
{
_ttsControl.Text = text;

var filePath = Path.Combine(Path.GetTempPath(), $"{this.GetType().Name}_{(uint)text.GetHashCode()}.wav");
if (File.Exists(filePath))
{
File.Delete(filePath);
}
_ttsControl.SaveAudioToFile(filePath);
if(File.Exists(filePath))
{
return SoundStream.Open(filePath);
}
return null;
}

#region IDisposable Support
private bool disposedValue = false;

Expand Down
10 changes: 10 additions & 0 deletions src/Speech/Controller/CeVIO64Controller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,16 @@ public uint GetVoiceQuality()
return _talker.Alpha;
}

public SoundStream ExportToStream(string text)
{
string tempFile = Path.GetTempFileName();
if (_talker.OutputWaveToFile(text, tempFile))
{
return SoundStream.Open(tempFile);
}
return null;
}

#region IDisposable Support
private bool disposedValue = false;

Expand Down
10 changes: 10 additions & 0 deletions src/Speech/Controller/CeVIOAIController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,16 @@ public uint GetVoiceQuality()
return _talker.Alpha;
}

public SoundStream ExportToStream(string text)
{
string tempFile = Path.GetTempFileName();
if (_talker.OutputWaveToFile(text, tempFile))
{
return SoundStream.Open(tempFile);
}
return null;
}


#region IDisposable Support
private bool disposedValue = false;
Expand Down
10 changes: 10 additions & 0 deletions src/Speech/Controller/CeVIOController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,16 @@ public uint GetVoiceQuality()
return _talker.Alpha;
}

public SoundStream ExportToStream(string text)
{
string tempFile = Path.GetTempFileName();
if (_talker.OutputWaveToFile(text, tempFile))
{
return SoundStream.Open(tempFile);
}
return null;
}

#region IDisposable Support
private bool disposedValue = false;

Expand Down
6 changes: 6 additions & 0 deletions src/Speech/Controller/ISpeechController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ public interface ISpeechController
/// </summary>
/// <returns>起動していれば true </returns>
bool IsActive();
/// <summary>
/// 指定した文字列を合成した音声を取得します
/// </summary>
/// <param name="text">合成する文字列</param>
/// <returns>出力された音声の Stream</returns>
SoundStream ExportToStream(string text);

}
}
5 changes: 5 additions & 0 deletions src/Speech/Controller/OtomachiUnaTalkController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,11 @@ private void RestoreMinimizedWindow()
}
}

public SoundStream ExportToStream(string text)
{
throw new NotImplementedException();
}

#region IDisposable Support
private bool disposedValue = false;

Expand Down
10 changes: 10 additions & 0 deletions src/Speech/Controller/SAPI5Controller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,16 @@ public float GetPitchRange()
return 1f;
}

public SoundStream ExportToStream(string text)
{
var ms = new MemoryStream();
synthesizer.SetOutputToWaveStream(ms);
synthesizer.Speak(text);
synthesizer.SetOutputToDefaultAudioDevice();
ms.Position = 0;
return new SoundStream(ms);
}

#region IDisposable Support
private bool disposedValue = false;

Expand Down
72 changes: 39 additions & 33 deletions src/Speech/Controller/VOICEVOXController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,43 +100,23 @@ private string ReplaceParam(string str, string key, float value)
public void Play(string text)
{
string tempFile = Path.GetTempFileName();

var content = new StringContent("", Encoding.UTF8, @"application/json");
var encodeText = Uri.EscapeDataString(text);

int talkerNo = _enumerator.Names[_libraryName];

string queryData = "";
using (var client = new HttpClient())
try
{
try
{
var response = client.PostAsync($"{_baseUrl}/audio_query?text={encodeText}&speaker={talkerNo}", content).GetAwaiter().GetResult();
if (response.StatusCode != HttpStatusCode.OK) { return; }
queryData = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
var soundData = ExportToStream(text);

// 音量等のパラメータを反映させる
queryData = UpdateParam(queryData);

content = new StringContent(queryData, Encoding.UTF8, @"application/json");
response = client.PostAsync($"{_baseUrl}/synthesis?speaker={talkerNo}", content).GetAwaiter().GetResult();
if (response.StatusCode != HttpStatusCode.OK) { return; }

var soundData = response.Content.ReadAsStreamAsync().GetAwaiter().GetResult();

using (var fileStream = new FileStream(tempFile, FileMode.Create, FileAccess.Write, FileShare.None))
{
soundData.CopyTo(fileStream);

}

SoundPlayer sp = new SoundPlayer();
sp.Play(tempFile);
}
finally
using (var fileStream = new FileStream(tempFile, FileMode.Create, FileAccess.Write, FileShare.None))
{
OnFinished();
soundData.CopyTo(fileStream);

}

SoundPlayer sp = new SoundPlayer();
sp.Play(tempFile);
File.Delete(tempFile);
}
finally
{
OnFinished();
}

}
Expand Down Expand Up @@ -220,6 +200,32 @@ public float GetPitchRange()
return Intonation;
}

public SoundStream ExportToStream(string text)
{
var content = new StringContent("", Encoding.UTF8, @"application/json");
var encodeText = Uri.EscapeDataString(text);

int talkerNo = _enumerator.Names[_libraryName];

string queryData = "";
using (var client = new HttpClient())
{
var response = client.PostAsync($"{_baseUrl}/audio_query?text={encodeText}&speaker={talkerNo}", content).GetAwaiter().GetResult();
if (response.StatusCode != HttpStatusCode.OK) { return null; }
queryData = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();

// 音量等のパラメータを反映させる
queryData = UpdateParam(queryData);

content = new StringContent(queryData, Encoding.UTF8, @"application/json");
response = client.PostAsync($"{_baseUrl}/synthesis?speaker={talkerNo}", content).GetAwaiter().GetResult();
if (response.StatusCode != HttpStatusCode.OK) { return null; }

return new SoundStream(response.Content.ReadAsStreamAsync().GetAwaiter().GetResult());
}
}



#region IDisposable Support
private bool disposedValue = false;
Expand Down
Loading