Skip to content

Commit

Permalink
Merge pull request #2 from Uralstech/unstable
Browse files Browse the repository at this point in the history
UCloud.TextToSpeech v1.2.0: Awaitables
  • Loading branch information
Uralstech authored Dec 27, 2024
2 parents 693071b + 8cda94f commit 799e64b
Show file tree
Hide file tree
Showing 10 changed files with 61 additions and 19 deletions.
2 changes: 1 addition & 1 deletion Documentation/docfx.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
],
"dest": "api",
"filter": "filterConfig.yml",
"includePrivateMembers": true,
"includePrivateMembers": false,
"allowCompilationErrors": true
}
],
Expand Down
2 changes: 1 addition & 1 deletion Documentation/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ A Unity C# wrapper for the Google Cloud Text-To-Speech API.

## Installation

This *should* work on any reasonably modern Unity version. Built and tested in Unity 6.0.
Requires Unity 6.0 because of the plugin's usage of [*Awaitable*](https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Awaitable.html). Built and tested in Unity 6.0.

# [OpenUPM](#tab/openupm)

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ A Unity C# wrapper for the Google Cloud Text-To-Speech API.

## Installation

This *should* work on any reasonably modern Unity version. Built and tested in Unity 6.0.
Requires Unity 6.0 because of the plugin's usage of [*Awaitable*](https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Awaitable.html). Built and tested in Unity 6.0.

### OpenUPM

Expand Down
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using Newtonsoft.Json;
using System;
using System.IO;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Networking;

Expand Down Expand Up @@ -39,8 +38,9 @@ public class TextToSpeechSynthesisResponse
/// <param name="encoding">The encoding of the audio.</param>
/// <returns>The audio converted to an <see cref="AudioClip"/>.</returns>
/// <exception cref="IOException">Thrown if <paramref name="encoding"/> is unsupported.</exception>
public async Task<AudioClip> ToAudioClip(TextToSpeechSynthesisAudioEncoding encoding)
public async Awaitable<AudioClip> ToAudioClip(TextToSpeechSynthesisAudioEncoding encoding)
{
await Awaitable.MainThreadAsync();
AudioType audioType = encoding switch
{
TextToSpeechSynthesisAudioEncoding.WavLinear16 => AudioType.WAV,
Expand All @@ -50,7 +50,7 @@ public async Task<AudioClip> ToAudioClip(TextToSpeechSynthesisAudioEncoding enco

string path = Path.Combine(Application.temporaryCachePath, $"{nameof(TextToSpeechSynthesisResponse)}.bin");
byte[] buffer = Convert.FromBase64String(Audio);
File.WriteAllBytes(path, buffer);
await File.WriteAllBytesAsync(path, buffer);

using UnityWebRequest audioClipRequest = UnityWebRequestMultimedia.GetAudioClip($"file://{path}", audioType);
await audioClipRequest.SendWebRequest();
Expand All @@ -65,7 +65,7 @@ public async Task<AudioClip> ToAudioClip(TextToSpeechSynthesisAudioEncoding enco
/// </summary>
/// <returns>The audio converted to an <see cref="AudioClip"/>.</returns>
/// <exception cref="IOException">Thrown if <paramref name="encoding"/> is unsupported.</exception>
public async Task<AudioClip> ToAudioClip()
public async Awaitable<AudioClip> ToAudioClip()
{
return await ToAudioClip(AudioMetadata?.Encoding ?? TextToSpeechSynthesisAudioEncoding.Default);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
/// </summary>
public enum TextToSpeechVoiceType
{
/// <summary>
/// Default value, ignore.
/// </summary>
None,

/// <summary>
/// <seealso href="https://cloud.google.com/text-to-speech/docs/voice-types#standard_voices">Standard</seealso>
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;

Expand All @@ -16,7 +17,7 @@ public static class IEnumerableExtensions
/// <returns>Voices with the type and gender corresponding to <paramref name="type"/> and <paramref name="gender"/>.</returns>
public static IEnumerable<TextToSpeechVoice> FilterByAttributes(this IEnumerable<TextToSpeechVoice> thiz, TextToSpeechVoiceGender gender, TextToSpeechVoiceType type)
{
return from voice in thiz where voice.Gender == gender && voice.Name.Type == type select voice;
return from voice in thiz where voice?.Gender == gender && voice?.Name?.Type == type select voice;
}

/// <summary>
Expand All @@ -26,7 +27,7 @@ public static IEnumerable<TextToSpeechVoice> FilterByAttributes(this IEnumerable
/// <returns>Voices with the gender corresponding to <paramref name="gender"/>.</returns>
public static IEnumerable<TextToSpeechVoice> FilterByGender(this IEnumerable<TextToSpeechVoice> thiz, TextToSpeechVoiceGender gender)
{
return from voice in thiz where voice.Gender == gender select voice;
return from voice in thiz where voice?.Gender == gender select voice;
}

/// <summary>
Expand All @@ -36,7 +37,7 @@ public static IEnumerable<TextToSpeechVoice> FilterByGender(this IEnumerable<Tex
/// <returns>Voices with the type corresponding to <paramref name="type"/>.</returns>
public static IEnumerable<TextToSpeechVoice> FilterByType(this IEnumerable<TextToSpeechVoice> thiz, TextToSpeechVoiceType type)
{
return from voice in thiz where voice.Name.Type == type select voice;
return from voice in thiz where voice?.Name?.Type == type select voice;
}

/// <summary>
Expand All @@ -47,7 +48,42 @@ public static IEnumerable<TextToSpeechVoice> FilterByType(this IEnumerable<TextT
/// <returns>A voice with the type and gender corresponding to <paramref name="type"/> and <paramref name="gender"/>, <see langword="null"/> if not found.</returns>
public static TextToSpeechVoice FindByAttributes(this IEnumerable<TextToSpeechVoice> thiz, TextToSpeechVoiceGender gender, TextToSpeechVoiceType type)
{
return thiz.FirstOrDefault(voice => voice.Gender == gender && voice.Name.Type == type);
return thiz.FirstOrDefault(voice => voice?.Gender == gender && voice?.Name?.Type == type);
}

/// <summary>
/// Finds the first voice with the given <paramref name="gender"/> and one of the specified <paramref name="types"/>,
/// where the order of types in <paramref name="types"/> specifies preference.
/// </summary>
/// <remarks>
/// The method searches the collection and returns the first voice that matches the gender and any of the provided types,
/// preferring the order in which the types are listed.
/// </remarks>
/// <param name="thiz">The collection of voices to search within.</param>
/// <param name="gender">The gender to filter by.</param>
/// <param name="types">The types to filter by. Order indicates preference.</param>
/// <returns>The first voice matching the gender and one of the specified types, or null if none is found.</returns>
public static TextToSpeechVoice FindByAttributes(this IEnumerable<TextToSpeechVoice> thiz, TextToSpeechVoiceGender gender, params TextToSpeechVoiceType[] types)
{
if (types.Length < 2)
return types.Length == 0 ? FindByGender(thiz, gender) : FindByAttributes(thiz, gender, types[0]);

Dictionary<TextToSpeechVoiceType, TextToSpeechVoice> foundVoices = new(types.Length);
foreach (TextToSpeechVoice voice in thiz)
{
if (voice?.Gender != gender)
continue;

TextToSpeechVoiceType type = voice.Name.Type;
int index = Array.IndexOf(types, type);

if (index == 0)
return voice;
else if (index >= 0 && !foundVoices.ContainsKey(type))
foundVoices[type] = voice;
}

return (from type in types where foundVoices.ContainsKey(type) select foundVoices[type]).FirstOrDefault();
}

/// <summary>
Expand All @@ -57,7 +93,7 @@ public static TextToSpeechVoice FindByAttributes(this IEnumerable<TextToSpeechVo
/// <returns>A voice with the gender corresponding to <paramref name="gender"/>, <see langword="null"/> if not found.</returns>
public static TextToSpeechVoice FindByGender(this IEnumerable<TextToSpeechVoice> thiz, TextToSpeechVoiceGender gender)
{
return thiz.FirstOrDefault(voice => voice.Gender == gender);
return thiz.FirstOrDefault(voice => voice?.Gender == gender);
}

/// <summary>
Expand All @@ -67,7 +103,7 @@ public static TextToSpeechVoice FindByGender(this IEnumerable<TextToSpeechVoice>
/// <returns>A voice with the type corresponding to <paramref name="type"/>, <see langword="null"/> if not found.</returns>
public static TextToSpeechVoice FindByType(this IEnumerable<TextToSpeechVoice> thiz, TextToSpeechVoiceType type)
{
return thiz.FirstOrDefault(voice => voice.Name.Type == type);
return thiz.FirstOrDefault(voice => voice?.Name?.Type == type);
}

/// <summary>
Expand All @@ -77,8 +113,8 @@ public static TextToSpeechVoice FindByType(this IEnumerable<TextToSpeechVoice> t
/// <returns>A voice with the name corresponding to <paramref name="name"/>, <see langword="null"/> if not found.</returns>
public static TextToSpeechVoice FindByName(this IEnumerable<TextToSpeechVoice> thiz, TextToSpeechVoiceName name)
{
string nameStr = name.FullName;
return thiz.FirstOrDefault(voice => voice.Name.FullName == nameStr);
string nameStr = name?.FullName;
return thiz.FirstOrDefault(voice => voice?.Name?.FullName == nameStr);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Newtonsoft.Json;
using System;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Networking;
using Uralstech.UCloud.TextToSpeech.Exceptions;
Expand Down Expand Up @@ -58,8 +57,9 @@ public void SetApiKey(string apiKey)
/// <returns>The computed response.</returns>
/// <exception cref="TextToSpeechRequestException">Thrown if the API request fails.</exception>
/// <exception cref="TextToSpeechResponseParsingException">Thrown if the response could not be parsed.</exception>
public async Task<TResponse> Request<TResponse>(ITextToSpeechPostRequest request)
public async Awaitable<TResponse> Request<TResponse>(ITextToSpeechPostRequest request)
{
await Awaitable.MainThreadAsync();
string utf8RequestData = request.GetUtf8EncodedData();
string requestEndpoint = request.GetEndpointUri();

Expand All @@ -85,8 +85,9 @@ public async Task<TResponse> Request<TResponse>(ITextToSpeechPostRequest request
/// <returns>The computed response.</returns>
/// <exception cref="TextToSpeechRequestException">Thrown if the API request fails.</exception>
/// <exception cref="TextToSpeechResponseParsingException">Thrown if the response could not be parsed.</exception>
public async Task<TResponse> Request<TResponse>(ITextToSpeechGetRequest request)
public async Awaitable<TResponse> Request<TResponse>(ITextToSpeechGetRequest request)
{
await Awaitable.MainThreadAsync();
string requestEndpoint = request.GetEndpointUri();

using UnityWebRequest webRequest = UnityWebRequest.Get(requestEndpoint);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"displayName": "UCloud.TextToSpeech",
"description": "A Unity C# wrapper for the Google Cloud Text-To-Speech API.",
"keywords": [],
"version": "1.1.0",
"version": "1.2.0",
"unity": "6000.0",
"hideInEditor": false,
"documentationUrl": "https://uralstech.github.io/UCloud.TextToSpeech/",
Expand Down

0 comments on commit 799e64b

Please sign in to comment.