Beszédszintézis szövegből

Referenciadokumentáció-csomag (NuGet) | További minták a GitHubon |

Ebben az útmutatóban megismerheti a szöveg beszédszintézishez való használatának gyakori tervezési mintáit.

További információ a következő területekről: Mi az a beszédszöveg?

  • Válaszok lekérése memóriabeli streamekként.
  • A kimeneti mintasebesség és a bitsebesség testreszabása.
  • Szintéziskérések beküldése a Speech Synthesis Markup Language (SSML) használatával.
  • Neurális hangok használata.
  • Feliratkozás eseményekre, és az eredményekre való cselekvés.

A szintézis nyelvének és hangának kiválasztása

A Speech szolgáltatás szövegfelolvasási funkciója több mint 400 hangot és több mint 140 nyelvet és változatot támogat. Lekérheti a teljes listát , vagy kipróbálhatja őket a Hangtárban.

Adja meg a bemeneti szövegnek megfelelő nyelvet vagy hangot SpeechConfig , és használja a megadott hangot. A következő kódrészlet a technika működését mutatja be:

static async Task SynthesizeAudioAsync()
{
    var speechConfig = SpeechConfig.FromSubscription("YourSpeechKey", "YourSpeechRegion");
    // Set either the `SpeechSynthesisVoiceName` or `SpeechSynthesisLanguage`.
    speechConfig.SpeechSynthesisLanguage = "en-US"; 
    speechConfig.SpeechSynthesisVoiceName = "en-US-AvaMultilingualNeural";
}

Minden neurális hang többnyelvű és folyékony a saját nyelvén és angolul. Ha például a bemeneti szöveg angolul van, a következő: "Izgatottan várom, hogy kipróbálhassam a szöveget a beszédhez", és ön kiválasztja es-ES-ElviraNeural, hogy a szöveg angol nyelven, spanyol akcentussal szólaljon meg.

Ha a hang nem beszéli a bemeneti szöveg nyelvét, a Speech szolgáltatás nem hoz létre szintetizált hangot. A támogatott neurális hangok teljes listájáért tekintse meg a Speech szolgáltatás nyelv- és hangtámogatását.

Feljegyzés

Az alapértelmezett hang az első hang, amelyet területi beállításonként a Voice List API-ból ad vissza.

A beszélő hang prioritási sorrendben van meghatározva az alábbiak szerint:

  • Ha nem állítja be SpeechSynthesisVoiceName , vagy SpeechSynthesisLanguageaz alapértelmezett beszédhang en-US .
  • Ha csak be van állítva SpeechSynthesisLanguage, a megadott területi beállítás alapértelmezett hangja beszél.
  • Ha mindkettő SpeechSynthesisVoiceNameSpeechSynthesisLanguage be van állítva, a SpeechSynthesisLanguage beállítás figyelmen kívül lesz hagyva. A beszéd használatával SpeechSynthesisVoiceName megadott hang.
  • Ha a hangelem a Beszédszintézis korrektúranyelv (SSML) használatával van beállítva, a rendszer figyelmen kívül hagyja a beállításokat és SpeechSynthesisLanguage a SpeechSynthesisVoiceName beállításokat.

Beszédszintézis fájlba

SpeechSynthesizer objektum létrehozása. Ez az alábbi kódrészletekben látható objektum szöveget futtat beszédkonvertálásra, valamint a hangszórókra, fájlokra vagy más kimeneti streamekre történő kimeneteket. SpeechSynthesizer a következő paramétereket fogadja el:

  1. Hozzon létre egy példánytAudioConfig, amely automatikusan egy .wav fájlba írja a kimenetet a FromWavFileOutput() függvény használatával. Példányosíthatja egy using utasítással.

    static async Task SynthesizeAudioAsync()
    {
        var speechConfig = SpeechConfig.FromSubscription("YourSpeechKey", "YourSpeechRegion");
        using var audioConfig = AudioConfig.FromWavFileOutput("path/to/write/file.wav");
    }
    

    Az using ebben a kontextusban lévő utasítás automatikusan megsemmisíti a nem felügyelt erőforrásokat, és az objektum az elidegenítés után megszűnik a hatókörből.

  2. Példány példányosítása SpeechSynthesizer egy másik using utasítással. Adja át az speechConfig objektumot és az audioConfig objektumot paraméterekként. A beszéd szintetizálásához és egy fájlba való íráshoz futtasson SpeakTextAsync() egy szöveges sztringet.

static async Task SynthesizeAudioAsync()
{
    var speechConfig = SpeechConfig.FromSubscription("YourSpeechKey", "YourSpeechRegion");
    using var audioConfig = AudioConfig.FromWavFileOutput("path/to/write/file.wav");
    using var speechSynthesizer = new SpeechSynthesizer(speechConfig, audioConfig);
    await speechSynthesizer.SpeakTextAsync("I'm excited to try text to speech");
}

A program futtatásakor létrehoz egy szintetizált .wav fájlt, amelyet a program a megadott helyre ír. Ez az eredmény jó példa a legalapvetőbb használatra. Ezután testre szabhatja a kimenetet, és memóriabeli streamként kezelheti a kimeneti választ az egyéni forgatókönyvek kezeléséhez.

Szintetizálás előadói kimenetre

Ha szintetizált beszédet szeretne kibocsátani az aktuális aktív kimeneti eszközre, például egy hangszóróra, hagyja ki a AudioConfig paramétert a SpeechSynthesizer példány létrehozásakor. Példa:

static async Task SynthesizeAudioAsync()
{
    var speechConfig = SpeechConfig.FromSubscription("YourSpeechKey", "YourSpeechRegion");
    using var speechSynthesizer = new SpeechSynthesizer(speechConfig);
    await speechSynthesizer.SpeakTextAsync("I'm excited to try text to speech");
}

Eredmény lekérése memórián belüli streamként

Az eredményül kapott hangadatokat használhatja memórián belüli streamként ahelyett, hogy közvetlenül egy fájlba írnál. A memórián belüli adatfolyammal egyéni viselkedést hozhat létre:

  • Az eredményként kapott bájttömb absztrakciója kereshető streamként egyéni alárendelt szolgáltatásokhoz.
  • Integrálja az eredményt más API-kkal vagy szolgáltatásokkal.
  • Módosítsa a hangadatokat, írjon egyéni .wav fejléceket, és végezze el a kapcsolódó feladatokat.

Ezt a módosítást az előző példára módosíthatja. Először távolítsa el a AudioConfig blokkot, mert a nagyobb vezérlés érdekében manuálisan kezeli a kimeneti viselkedést. Pass null for AudioConfig a SpeechSynthesizer konstruktorban.

Feljegyzés

nullAudioConfigA továbbítás – ahelyett, hogy kihagyja azt az előző előadói kimeneti példában leírtak szerint – alapértelmezés szerint nem játssza le a hangot az aktuális aktív kimeneti eszközön.

Mentse az eredményt egy SpeechSynthesisResult változóba. A AudioData tulajdonság a kimeneti adatok egy példányát byte [] tartalmazza. Ezt a byte [] példányt manuálisan is használhatja, vagy használhatja az AudioDataStream osztályt a memóriabeli stream kezeléséhez.

Ebben a példában a AudioDataStream.FromResult() statikus függvénnyel kap streamet az eredményből:

static async Task SynthesizeAudioAsync()
{
    var speechConfig = SpeechConfig.FromSubscription("YourSpeechKey", "YourSpeechRegion");
    using var speechSynthesizer = new SpeechSynthesizer(speechConfig, null);

    var result = await speechSynthesizer.SpeakTextAsync("I'm excited to try text to speech");
    using var stream = AudioDataStream.FromResult(result);
}

Ezen a ponton bármilyen egyéni viselkedést implementálhat az eredményként kapott stream objektum használatával.

Hangformátum testreszabása

Testre szabhatja a hangkimeneti attribútumokat, többek között a következőket:

  • Hangfájl típusa
  • Mintasebesség
  • Bitmélység

A hangformátum módosításához használja az SetSpeechSynthesisOutputFormat() objektum függvényét SpeechConfig . Ez a függvény egy enum SpeechSynthesisOutputFormat típusú példányt vár. Válassza ki a enum kimeneti formátumot a listában. Az elérhető formátumokért tekintse meg a hangformátumok listáját.

A követelményektől függően különböző fájltípusok érhetők el. Definíció szerint a nyers formátumok, például Raw24Khz16BitMonoPcm nem tartalmaznak hangfejléceket. Nyers formátumokat csak az alábbi helyzetek egyikében használjon:

  • Tudja, hogy az alsóbb rétegbeli implementáció képes dekódolni egy nyers bitstreamet.
  • A fejlécek manuális összeállítását olyan tényezők alapján tervezi, mint a bitmélység, a mintasebesség és a csatornák száma.

Ez a példa az objektum beállításával SpeechSynthesisOutputFormatSpeechConfig adja meg a magas megbízhatóságú RIFF formátumotRiff24Khz16BitMonoPcm. Az előző szakaszban bemutatott példához hasonlóan az AudioDataStream használatával lekérheti az eredmény memóriabeli adatfolyamát, majd egy fájlba írhatja.

static async Task SynthesizeAudioAsync()
{
    var speechConfig = SpeechConfig.FromSubscription("YourSpeechKey", "YourSpeechRegion");
    speechConfig.SetSpeechSynthesisOutputFormat(SpeechSynthesisOutputFormat.Riff24Khz16BitMonoPcm);

    using var speechSynthesizer = new SpeechSynthesizer(speechConfig, null);
    var result = await speechSynthesizer.SpeakTextAsync("I'm excited to try text to speech");

    using var stream = AudioDataStream.FromResult(result);
    await stream.SaveToWaveFileAsync("path/to/write/file.wav");
}

A program futtatásakor egy .wav fájlt ír a megadott elérési útra.

Beszédjellemzők testreszabása az SSML használatával

Az SSML használatával finomhangolhatja a hangmagasságot, a kiejtést, a beszédsebességet, a hangerőt és a szöveg egyéb aspektusait a beszédkimenetre, ha a kéréseket XML-sémából küldi el. Ez a szakasz egy példát mutat be a hang módosítására. További információt a Beszédszintézis korrektúranyelv áttekintése című témakörben talál.

Az SSML testreszabáshoz való használatához egy kisebb módosítást kell végeznie, amely átváltja a hangot.

  1. Hozzon létre egy új XML-fájlt az SSML-konfigurációhoz a gyökérprojekt könyvtárában.

    <speak version="1.0" xmlns="https://www.w3.org/2001/10/synthesis" xml:lang="en-US">
      <voice name="en-US-AvaMultilingualNeural">
        When you're on the freeway, it's a good idea to use a GPS.
      </voice>
    </speak>
    

    Ebben a példában a fájl ssml.xml. A gyökérelem mindig <speak>. Az elem szövegének <voice> körbefuttatásával a paraméter használatával módosíthatja a name hangot. A támogatott neurális hangok teljes listájáért tekintse meg a támogatott nyelveket.

  2. Módosítsa a beszédszintézis-kérést az XML-fájlra való hivatkozáshoz. A kérés többnyire ugyanaz, de a függvény használata helyett a függvényt SpeakTextAsync() használja SpeakSsmlAsync(). Ez a függvény egy XML-sztringet vár. Először töltse be az SSML-konfigurációt sztringként a használatával File.ReadAllText(). Ettől a ponttól kezdve az eredményobjektum pontosan ugyanaz, mint az előző példák.

    Feljegyzés

    Ha Visual Studiót használ, a buildkonfiguráció valószínűleg nem fogja alapértelmezés szerint megtalálni az XML-fájlt. Kattintson a jobb gombbal az XML-fájlra, és válassza a Tulajdonságok lehetőséget. Módosítsa a buildelési műveletet tartalomra. Módosítsa a másolást kimeneti könyvtárra, hogy mindig másolás legyen.

    public static async Task SynthesizeAudioAsync()
    {
        var speechConfig = SpeechConfig.FromSubscription("YourSpeechKey", "YourSpeechRegion");
        using var speechSynthesizer = new SpeechSynthesizer(speechConfig, null);
    
        var ssml = File.ReadAllText("./ssml.xml");
        var result = await speechSynthesizer.SpeakSsmlAsync(ssml);
    
        using var stream = AudioDataStream.FromResult(result);
        await stream.SaveToWaveFileAsync("path/to/write/file.wav");
    }
    

Feljegyzés

Ha SSML használata nélkül szeretné módosítani a hangot, a tulajdonságot SpeechConfig a következővel SpeechConfig.SpeechSynthesisVoiceName = "en-US-AvaMultilingualNeural";állíthatja be: .

Feliratkozás szintetizátoreseményekre

Előfordulhat, hogy további elemzéseket szeretne a szövegről a beszédfeldolgozáshoz és az eredményekhez. Előfordulhat például, hogy tudni szeretné, hogy mikor indul el és áll le a szintetizátor, vagy érdemes lehet tudnia a szintézis során előforduló egyéb eseményekről.

Miközben a SpeechSynthesizert használja a szövegfelolvasáshoz, előfizethet a táblázatban szereplő eseményekre:

Esemény Leírás Használati eset
BookmarkReached Azt jelzi, hogy egy könyvjelző el lett érve. A könyvjelző által elért esemény aktiválásához egy bookmark elem szükséges az SSML-ben. Ez az esemény a kimeneti hangnak a szintézis kezdete és bookmark az elem közötti eltelt idejét jelenti. Az esemény tulajdonsága Text a könyvjelző mark attribútumában beállított sztringérték. Az bookmark elemek nincsenek kimondva. Az elem használatával bookmark egyéni jelölőket szúrhat be az SSML-be az egyes jelölők eltolásának lekéréséhez a hangstreamben. Az bookmark elem a szöveg vagy a címkesorozat egy adott helyére hivatkozhat.
SynthesisCanceled Azt jelzi, hogy a beszédszintézis megszakadt. Ellenőrizheti, hogy a szintézis mikor lesz megszakítva.
SynthesisCompleted Azt jelzi, hogy a beszédszintézis befejeződött. Ellenőrizheti, hogy a szintézis befejeződött-e.
SynthesisStarted Azt jelzi, hogy a beszédszintézis elindult. Ellenőrizheti, hogy mikor kezdődött el a szintézis.
Synthesizing Azt jelzi, hogy a beszédszintézis folyamatban van. Ez az esemény minden alkalommal aktiválódik, amikor az SDK hangrészletet kap a Speech szolgáltatástól. Ellenőrizheti, hogy a szintézis folyamatban van-e.
VisemeReceived Azt jelzi, hogy egy viseme esemény érkezett. A visemeket gyakran használják a megfigyelt beszéd legfontosabb pózainak ábrázolására. A fő pózok közé tartozik az ajkak, az állkapocs és a nyelv pozíciója egy adott fonál előállításában. A visemek használatával animálhatja egy karakter arcát a beszédhang lejátszása során.
WordBoundary Azt jelzi, hogy egy szóhatár érkezett. Ez az esemény minden új kimondott szó, írásjel és mondat elején jelenik meg. Az esemény az aktuális szó időeltolódását jelenti pipákban a kimeneti hang elejétől. Ez az esemény közvetlenül a kimondandó szó előtt jelenti a bemeneti szöveg vagy az SSML karakterpozícióját is. Ezt az eseményt gyakran használják a szöveg és a megfelelő hang relatív pozícióinak lekérésére. Érdemes lehet tudni egy új szóról, majd az időzítés alapján cselekedni. Például olyan információkat kaphat, amelyek segítségével eldöntheti, hogy mikor és mennyi ideig emelheti ki a szavakat a beszéd közben.

Feljegyzés

Az események akkor jönnek létre, amikor a kimeneti hangadatok elérhetővé válnak, ami gyorsabb, mint egy kimeneti eszköz lejátszása. A hívónak megfelelően szinkronizálnia kell a streamelést és a valós idejűt.

Íme egy példa, amely bemutatja, hogyan iratkozhat fel eseményekre beszédszintézis céljából. Kövesse a rövid útmutató utasításait, de cserélje le a Program.cs fájl tartalmát a következő C#-kódra:

using Microsoft.CognitiveServices.Speech;

class Program 
{
    // This example requires environment variables named "SPEECH_KEY" and "SPEECH_REGION"
    static string speechKey = Environment.GetEnvironmentVariable("SPEECH_KEY");
    static string speechRegion = Environment.GetEnvironmentVariable("SPEECH_REGION");

    async static Task Main(string[] args)
    {
        var speechConfig = SpeechConfig.FromSubscription(speechKey, speechRegion);
         
        var speechSynthesisVoiceName  = "en-US-AvaMultilingualNeural";  
        var ssml = @$"<speak version='1.0' xml:lang='en-US' xmlns='http://www.w3.org/2001/10/synthesis' xmlns:mstts='http://www.w3.org/2001/mstts'>
            <voice name='{speechSynthesisVoiceName}'>
                <mstts:viseme type='redlips_front'/>
                The rainbow has seven colors: <bookmark mark='colors_list_begin'/>Red, orange, yellow, green, blue, indigo, and violet.<bookmark mark='colors_list_end'/>.
            </voice>
        </speak>";

        // Required for sentence-level WordBoundary events
        speechConfig.SetProperty(PropertyId.SpeechServiceResponse_RequestSentenceBoundary, "true");

        using (var speechSynthesizer = new SpeechSynthesizer(speechConfig))
        {
            // Subscribe to events

            speechSynthesizer.BookmarkReached += (s, e) =>
            {
                Console.WriteLine($"BookmarkReached event:" +
                    $"\r\n\tAudioOffset: {(e.AudioOffset + 5000) / 10000}ms" +
                    $"\r\n\tText: \"{e.Text}\".");
            };

            speechSynthesizer.SynthesisCanceled += (s, e) =>
            {
                Console.WriteLine("SynthesisCanceled event");
            };

            speechSynthesizer.SynthesisCompleted += (s, e) =>
            {                
                Console.WriteLine($"SynthesisCompleted event:" +
                    $"\r\n\tAudioData: {e.Result.AudioData.Length} bytes" +
                    $"\r\n\tAudioDuration: {e.Result.AudioDuration}");
            };

            speechSynthesizer.SynthesisStarted += (s, e) =>
            {
                Console.WriteLine("SynthesisStarted event");
            };

            speechSynthesizer.Synthesizing += (s, e) =>
            {
                Console.WriteLine($"Synthesizing event:" +
                    $"\r\n\tAudioData: {e.Result.AudioData.Length} bytes");
            };

            speechSynthesizer.VisemeReceived += (s, e) =>
            {
                Console.WriteLine($"VisemeReceived event:" +
                    $"\r\n\tAudioOffset: {(e.AudioOffset + 5000) / 10000}ms" +
                    $"\r\n\tVisemeId: {e.VisemeId}");
            };

            speechSynthesizer.WordBoundary += (s, e) =>
            {
                Console.WriteLine($"WordBoundary event:" +
                    // Word, Punctuation, or Sentence
                    $"\r\n\tBoundaryType: {e.BoundaryType}" +
                    $"\r\n\tAudioOffset: {(e.AudioOffset + 5000) / 10000}ms" +
                    $"\r\n\tDuration: {e.Duration}" +
                    $"\r\n\tText: \"{e.Text}\"" +
                    $"\r\n\tTextOffset: {e.TextOffset}" +
                    $"\r\n\tWordLength: {e.WordLength}");
            };

            // Synthesize the SSML
            Console.WriteLine($"SSML to synthesize: \r\n{ssml}");
            var speechSynthesisResult = await speechSynthesizer.SpeakSsmlAsync(ssml);

            // Output the results
            switch (speechSynthesisResult.Reason)
            {
                case ResultReason.SynthesizingAudioCompleted:
                    Console.WriteLine("SynthesizingAudioCompleted result");
                    break;
                case ResultReason.Canceled:
                    var cancellation = SpeechSynthesisCancellationDetails.FromResult(speechSynthesisResult);
                    Console.WriteLine($"CANCELED: Reason={cancellation.Reason}");

                    if (cancellation.Reason == CancellationReason.Error)
                    {
                        Console.WriteLine($"CANCELED: ErrorCode={cancellation.ErrorCode}");
                        Console.WriteLine($"CANCELED: ErrorDetails=[{cancellation.ErrorDetails}]");
                        Console.WriteLine($"CANCELED: Did you set the speech resource key and region values?");
                    }
                    break;
                default:
                    break;
            }
        }

        Console.WriteLine("Press any key to exit...");
        Console.ReadKey();
    }
}

A GitHubon további szövegfelolvasási mintákat találhat.

Egyéni végpont használata

Az egyéni végpont funkcionálisan megegyezik a szövegfelolvasási kérelmekhez használt szabványos végpontokkal.

Az egyik különbség az, hogy meg kell adni az EndpointId egyéni hang használatát a Speech SDK-val. A szöveggel kezdheti a beszéd gyorsútmutatóját , majd frissítheti a kódot a EndpointId következővel: és SpeechSynthesisVoiceName.

var speechConfig = SpeechConfig.FromSubscription(speechKey, speechRegion);     
speechConfig.SpeechSynthesisVoiceName = "YourCustomVoiceName";
speechConfig.EndpointId = "YourEndpointId";

Ha egyéni hangot szeretne használni a Speech Synthesis Markup Language (SSML) használatával, adja meg a modell nevét hangnévként. Ez a példa a YourCustomVoiceName hangot használja.

<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="en-US">
    <voice name="YourCustomVoiceName">
        This is the text that is spoken. 
    </voice>
</speak>

Tároló futtatása és használata

A Speech-tárolók websocket-alapú lekérdezésvégpont API-kat biztosítanak, amelyek a Speech SDK-n és a Speech CLI-n keresztül érhetők el. Alapértelmezés szerint a Speech SDK és a Speech CLI a nyilvános Speech szolgáltatást használja. A tároló használatához módosítania kell az inicializálási módszert. Kulcs és régió helyett használjon tároló gazdagép URL-címét.

További információ a tárolókról: Speech-tárolók telepítése és futtatása a Dockerrel.

Referenciadokumentáció-csomag (NuGet) | További minták a GitHubon |

Ebben az útmutatóban megismerheti a szöveg beszédszintézishez való használatának gyakori tervezési mintáit.

További információ a következő területekről: Mi az a beszédszöveg?

  • Válaszok lekérése memóriabeli streamekként.
  • A kimeneti mintasebesség és a bitsebesség testreszabása.
  • Szintéziskérések beküldése a Speech Synthesis Markup Language (SSML) használatával.
  • Neurális hangok használata.
  • Feliratkozás eseményekre, és az eredményekre való cselekvés.

A szintézis nyelvének és hangának kiválasztása

A Speech szolgáltatás szövegfelolvasási funkciója több mint 400 hangot és több mint 140 nyelvet és változatot támogat. Tekintse meg a támogatott szövegek teljes listáját a beszéd területi beállításai között, vagy próbálja ki őket a Hangtárban.

Adja meg a SpeechConfig osztály nyelvét vagy hangját, hogy megfeleljen a bemeneti szövegnek, és használja a megadott hangot. A következő kódrészlet a technika működését mutatja be:

void synthesizeSpeech()
{
    auto speechConfig = SpeechConfig::FromSubscription("YourSpeechKey", "YourSpeechRegion");
    // Set either the `SpeechSynthesisVoiceName` or `SpeechSynthesisLanguage`.
    speechConfig->SetSpeechSynthesisLanguage("en-US"); 
    speechConfig->SetSpeechSynthesisVoiceName("en-US-AvaMultilingualNeural");
}

Minden neurális hang többnyelvű és folyékony a saját nyelvén és angolul. Ha például az angol nyelvű beviteli szöveg a következő: "Izgatottan várom, hogy kipróbálhassam a szöveget a beszédhez", és ön kiválasztja es-ES-ElviraNeural, a szöveg angol nyelven, spanyol akcentussal szólal meg.

Ha a hang nem beszéli a bemeneti szöveg nyelvét, a Speech szolgáltatás nem hoz létre szintetizált hangot. A támogatott neurális hangok teljes listájáért tekintse meg a Speech szolgáltatás nyelv- és hangtámogatását.

Feljegyzés

Az alapértelmezett hang az első hang, amelyet területi beállításonként a Voice List API-ból ad vissza.

A beszélő hang prioritási sorrendben van meghatározva az alábbiak szerint:

  • Ha nem állítja be SpeechSynthesisVoiceName , vagy SpeechSynthesisLanguageaz alapértelmezett beszédhang en-US .
  • Ha csak be van állítva SpeechSynthesisLanguage, a megadott területi beállítás alapértelmezett hangja beszél.
  • Ha mindkettő SpeechSynthesisVoiceNameSpeechSynthesisLanguage be van állítva, a SpeechSynthesisLanguage beállítás figyelmen kívül lesz hagyva. A beszéd használatával SpeechSynthesisVoiceName megadott hang.
  • Ha a hangelem a Beszédszintézis korrektúranyelv (SSML) használatával van beállítva, a rendszer figyelmen kívül hagyja a beállításokat és SpeechSynthesisLanguage a SpeechSynthesisVoiceName beállításokat.

Beszédszintézis fájlba

SpeechSynthesizer objektum létrehozása. Ez az alábbi kódrészletekben látható objektum szöveget futtat beszédkonvertálásra, valamint a hangszórókra, fájlokra vagy más kimeneti streamekre történő kimeneteket. SpeechSynthesizer a következő paramétereket fogadja el:

  1. Hozzon létre egy példánytAudioConfig, amely automatikusan egy .wav fájlba írja a kimenetet a FromWavFileOutput() függvény használatával:

    void synthesizeSpeech()
    {
        auto speechConfig = SpeechConfig::FromSubscription("YourSpeechKey", "YourSpeechRegion");
        auto audioConfig = AudioConfig::FromWavFileOutput("path/to/write/file.wav");
    }
    
  2. Példány példányosítása SpeechSynthesizer . Adja át az speechConfig objektumot és az audioConfig objektumot paraméterekként. A beszéd szintetizálásához és egy fájlba való íráshoz futtasson SpeakTextAsync() egy szöveges sztringet.

    void synthesizeSpeech()
    {
        auto speechConfig = SpeechConfig::FromSubscription("YourSpeechKey", "YourSpeechRegion");
        auto audioConfig = AudioConfig::FromWavFileOutput("path/to/write/file.wav");
        auto speechSynthesizer = SpeechSynthesizer::FromConfig(speechConfig, audioConfig);
        auto result = speechSynthesizer->SpeakTextAsync("A simple test to write to a file.").get();
    }
    

A program futtatásakor létrehoz egy szintetizált .wav fájlt, amelyet a program a megadott helyre ír. Ez az eredmény jó példa a legalapvetőbb használatra. Ezután testre szabhatja a kimenetet, és memóriabeli streamként kezelheti a kimeneti választ az egyéni forgatókönyvek kezeléséhez.

Szintetizálás előadói kimenetre

Ha szintetizált beszédet szeretne kibocsátani az aktuális aktív kimeneti eszközre, például egy hangszóróra, hagyja ki a AudioConfig paramétert a SpeechSynthesizer példány létrehozásakor. Példa:

void synthesizeSpeech()
{
    auto speechConfig = SpeechConfig::FromSubscription("YourSpeechKey", "YourSpeechRegion");
    auto speechSynthesizer = SpeechSynthesizer::FromConfig(speechConfig);
    auto result = speechSynthesizer->SpeakTextAsync("I'm excited to try text to speech").get();
}

Eredmény lekérése memórián belüli streamként

Az eredményül kapott hangadatokat használhatja memórián belüli streamként ahelyett, hogy közvetlenül egy fájlba írnál. A memórián belüli adatfolyammal egyéni viselkedést hozhat létre:

  • Az eredményként kapott bájttömb absztrakciója kereshető streamként egyéni alárendelt szolgáltatásokhoz.
  • Integrálja az eredményt más API-kkal vagy szolgáltatásokkal.
  • Módosítsa a hangadatokat, írjon egyéni .wav fejléceket, és végezze el a kapcsolódó feladatokat.

Ezt a módosítást az előző példára módosíthatja. Először távolítsa el a AudioConfig blokkot, mert a nagyobb vezérlés érdekében manuálisan kezeli a kimeneti viselkedést. Pass NULL for AudioConfig a SpeechSynthesizer konstruktorban.

Feljegyzés

NULLAudioConfigA továbbítás – ahelyett, hogy kihagyja azt az előző előadói kimeneti példában leírtak szerint – alapértelmezés szerint nem játssza le a hangot az aktuális aktív kimeneti eszközön.

Mentse az eredményt egy SpeechSynthesisResult változóba. A GetAudioData lekérő a kimeneti adatok egy byte [] példányát adja vissza. Ezt a byte [] példányt manuálisan is használhatja, vagy használhatja az AudioDataStream osztályt a memóriabeli stream kezeléséhez.

Ebben a példában a statikus függvény használatával kérje le a AudioDataStream.FromResult() streamet az eredményből:

void synthesizeSpeech()
{
    auto speechConfig = SpeechConfig::FromSubscription("YourSpeechKey", "YourSpeechRegion");
    auto speechSynthesizer = SpeechSynthesizer::FromConfig(speechConfig);

    auto result = speechSynthesizer->SpeakTextAsync("Getting the response as an in-memory stream.").get();
    auto stream = AudioDataStream::FromResult(result);
}

Ezen a ponton bármilyen egyéni viselkedést implementálhat az eredményként kapott stream objektum használatával.

Hangformátum testreszabása

Testre szabhatja a hangkimeneti attribútumokat, többek között a következőket:

  • Hangfájl típusa
  • Mintasebesség
  • Bitmélység

A hangformátum módosításához használja az SetSpeechSynthesisOutputFormat() objektum függvényét SpeechConfig . Ez a függvény egy enum SpeechSynthesisOutputFormat típusú példányt vár. Válassza ki a enum kimeneti formátumot a listában. Az elérhető formátumokért tekintse meg a hangformátumok listáját.

A követelményektől függően különböző fájltípusok érhetők el. Definíció szerint a nyers formátumok, például Raw24Khz16BitMonoPcm nem tartalmaznak hangfejléceket. Nyers formátumokat csak az alábbi helyzetek egyikében használjon:

  • Tudja, hogy az alsóbb rétegbeli implementáció képes dekódolni egy nyers bitstreamet.
  • A fejlécek manuális összeállítását olyan tényezők alapján tervezi, mint a bitmélység, a mintasebesség és a csatornák száma.

Ez a példa az objektum beállításával SpeechSynthesisOutputFormatSpeechConfig adja meg a magas megbízhatóságú RIFF formátumotRiff24Khz16BitMonoPcm. Az előző szakaszban szereplő példához hasonlóan az eredmény memórián belüli adatfolyamát is AudioDataStream lekérheti, majd egy fájlba írhatja.

void synthesizeSpeech()
{
    auto speechConfig = SpeechConfig::FromSubscription("YourSpeechKey", "YourSpeechRegion");
    speechConfig->SetSpeechSynthesisOutputFormat(SpeechSynthesisOutputFormat::Riff24Khz16BitMonoPcm);

    auto speechSynthesizer = SpeechSynthesizer::FromConfig(speechConfig);
    auto result = speechSynthesizer->SpeakTextAsync("A simple test to write to a file.").get();

    auto stream = AudioDataStream::FromResult(result);
    stream->SaveToWavFileAsync("path/to/write/file.wav").get();
}

A program futtatásakor egy .wav fájlt ír a megadott elérési útra.

Beszédjellemzők testreszabása az SSML használatával

Az SSML használatával finomhangolhatja a hangmagasságot, a kiejtést, a beszédsebességet, a hangerőt és a szöveg egyéb aspektusait a beszédkimenetre, ha a kéréseket XML-sémából küldi el. Ez a szakasz egy példát mutat be a hang módosítására. További információt a Beszédszintézis korrektúranyelv áttekintése című témakörben talál.

Ha az SSML-t szeretné használni a testreszabáshoz, hozzon létre egy kisebb módosítást, amely átváltja a hangot.

  1. Hozzon létre egy új XML-fájlt az SSML-konfigurációhoz a gyökérprojekt könyvtárában.

    <speak version="1.0" xmlns="https://www.w3.org/2001/10/synthesis" xml:lang="en-US">
      <voice name="en-US-AvaMultilingualNeural">
        When you're on the freeway, it's a good idea to use a GPS.
      </voice>
    </speak>
    

    Ebben a példában a fájl ssml.xml. A gyökérelem mindig <speak>. Az elem szövegének <voice> körbefuttatásával a paraméter használatával módosíthatja a name hangot. A támogatott neurális hangok teljes listájáért tekintse meg a támogatott nyelveket.

  2. Módosítsa a beszédszintézis-kérést az XML-fájlra való hivatkozáshoz. A kérés többnyire ugyanaz. A függvény használata helyett a SpeakTextAsync() .SpeakSsmlAsync() Ez a függvény egy XML-sztringet vár. Először töltse be az SSML-konfigurációt sztringként. Ettől a ponttól kezdve az eredményobjektum pontosan ugyanaz, mint az előző példák.

    void synthesizeSpeech()
    {
        auto speechConfig = SpeechConfig::FromSubscription("YourSpeechKey", "YourSpeechRegion");
        auto speechSynthesizer = SpeechSynthesizer::FromConfig(speechConfig);
    
        std::ifstream file("./ssml.xml");
        std::string ssml, line;
        while (std::getline(file, line))
        {
            ssml += line;
            ssml.push_back('\n');
        }
        auto result = speechSynthesizer->SpeakSsmlAsync(ssml).get();
    
        auto stream = AudioDataStream::FromResult(result);
        stream->SaveToWavFileAsync("path/to/write/file.wav").get();
    }
    

Feljegyzés

Ha SSML használata nélkül szeretné módosítani a hangot, a tulajdonságot SpeechConfig a következővel SpeechConfig.SetSpeechSynthesisVoiceName("en-US-AndrewMultilingualNeural")állíthatja be: .

Feliratkozás szintetizátoreseményekre

Előfordulhat, hogy további elemzéseket szeretne a szövegről a beszédfeldolgozáshoz és az eredményekhez. Előfordulhat például, hogy tudni szeretné, hogy mikor indul el és áll le a szintetizátor, vagy érdemes lehet tudnia a szintézis során előforduló egyéb eseményekről.

Miközben a SpeechSynthesizert használja a szövegfelolvasáshoz, előfizethet a táblázatban szereplő eseményekre:

Esemény Leírás Használati eset
BookmarkReached Azt jelzi, hogy egy könyvjelző el lett érve. A könyvjelző által elért esemény aktiválásához egy bookmark elem szükséges az SSML-ben. Ez az esemény a kimeneti hangnak a szintézis kezdete és bookmark az elem közötti eltelt idejét jelenti. Az esemény tulajdonsága Text a könyvjelző mark attribútumában beállított sztringérték. Az bookmark elemek nincsenek kimondva. Az elem használatával bookmark egyéni jelölőket szúrhat be az SSML-be az egyes jelölők eltolásának lekéréséhez a hangstreamben. Az bookmark elem a szöveg vagy a címkesorozat egy adott helyére hivatkozhat.
SynthesisCanceled Azt jelzi, hogy a beszédszintézis megszakadt. Ellenőrizheti, hogy a szintézis mikor lesz megszakítva.
SynthesisCompleted Azt jelzi, hogy a beszédszintézis befejeződött. Ellenőrizheti, hogy a szintézis befejeződött-e.
SynthesisStarted Azt jelzi, hogy a beszédszintézis elindult. Ellenőrizheti, hogy mikor kezdődött el a szintézis.
Synthesizing Azt jelzi, hogy a beszédszintézis folyamatban van. Ez az esemény minden alkalommal aktiválódik, amikor az SDK hangrészletet kap a Speech szolgáltatástól. Ellenőrizheti, hogy a szintézis folyamatban van-e.
VisemeReceived Azt jelzi, hogy egy viseme esemény érkezett. A visemeket gyakran használják a megfigyelt beszéd legfontosabb pózainak ábrázolására. A fő pózok közé tartozik az ajkak, az állkapocs és a nyelv pozíciója egy adott fonál előállításában. A visemek használatával animálhatja egy karakter arcát a beszédhang lejátszása során.
WordBoundary Azt jelzi, hogy egy szóhatár érkezett. Ez az esemény minden új kimondott szó, írásjel és mondat elején jelenik meg. Az esemény az aktuális szó időeltolódását jelenti pipákban a kimeneti hang elejétől. Ez az esemény közvetlenül a kimondandó szó előtt jelenti a bemeneti szöveg vagy az SSML karakterpozícióját is. Ezt az eseményt gyakran használják a szöveg és a megfelelő hang relatív pozícióinak lekérésére. Érdemes lehet tudni egy új szóról, majd az időzítés alapján cselekedni. Például olyan információkat kaphat, amelyek segítségével eldöntheti, hogy mikor és mennyi ideig emelheti ki a szavakat a beszéd közben.

Feljegyzés

Az események akkor jönnek létre, amikor a kimeneti hangadatok elérhetővé válnak, ami gyorsabb, mint egy kimeneti eszköz lejátszása. A hívónak megfelelően szinkronizálnia kell a streamelést és a valós idejűt.

Íme egy példa, amely bemutatja, hogyan iratkozhat fel eseményekre beszédszintézis céljából. Kövesse a rövid útmutató utasításait, de cserélje le a main.cpp fájl tartalmát a következő kódra:

#include <iostream> 
#include <stdlib.h>
#include <speechapi_cxx.h>

using namespace Microsoft::CognitiveServices::Speech;
using namespace Microsoft::CognitiveServices::Speech::Audio;

std::string getEnvironmentVariable(const char* name);

int main()
{
    // This example requires environment variables named "SPEECH_KEY" and "SPEECH_REGION"
    auto speechKey = getEnvironmentVariable("SPEECH_KEY");
    auto speechRegion = getEnvironmentVariable("SPEECH_REGION");

    if ((size(speechKey) == 0) || (size(speechRegion) == 0)) {
        std::cout << "Please set both SPEECH_KEY and SPEECH_REGION environment variables." << std::endl;
        return -1;
    }

    auto speechConfig = SpeechConfig::FromSubscription(speechKey, speechRegion);

    // Required for WordBoundary event sentences.
    speechConfig->SetProperty(PropertyId::SpeechServiceResponse_RequestSentenceBoundary, "true");

    const auto ssml = R"(<speak version='1.0' xml:lang='en-US' xmlns='http://www.w3.org/2001/10/synthesis' xmlns:mstts='http://www.w3.org/2001/mstts'>
        <voice name = 'en-US-AvaMultilingualNeural'>
            <mstts:viseme type = 'redlips_front' />
            The rainbow has seven colors : <bookmark mark = 'colors_list_begin' />Red, orange, yellow, green, blue, indigo, and violet.<bookmark mark = 'colors_list_end' />.
        </voice>
        </speak>)";

    auto speechSynthesizer = SpeechSynthesizer::FromConfig(speechConfig);

    // Subscribe to events

    speechSynthesizer->BookmarkReached += [](const SpeechSynthesisBookmarkEventArgs& e)
    {
        std::cout << "Bookmark reached. "
            << "\r\n\tAudioOffset: " << round(e.AudioOffset / 10000) << "ms"
            << "\r\n\tText: " << e.Text << std::endl;
    };

    speechSynthesizer->SynthesisCanceled += [](const SpeechSynthesisEventArgs& e)
    {
        std::cout << "SynthesisCanceled event" << std::endl;
    };

    speechSynthesizer->SynthesisCompleted += [](const SpeechSynthesisEventArgs& e)
    {
        auto audioDuration = std::chrono::duration_cast<std::chrono::milliseconds>(e.Result->AudioDuration).count();

        std::cout << "SynthesisCompleted event:"
            << "\r\n\tAudioData: " << e.Result->GetAudioData()->size() << "bytes"
            << "\r\n\tAudioDuration: " << audioDuration << std::endl;
    };

    speechSynthesizer->SynthesisStarted += [](const SpeechSynthesisEventArgs& e)
    {
        std::cout << "SynthesisStarted event" << std::endl;
    };

    speechSynthesizer->Synthesizing += [](const SpeechSynthesisEventArgs& e)
    {
        std::cout << "Synthesizing event:"
            << "\r\n\tAudioData: " << e.Result->GetAudioData()->size() << "bytes" << std::endl;
    };

    speechSynthesizer->VisemeReceived += [](const SpeechSynthesisVisemeEventArgs& e)
    {
        std::cout << "VisemeReceived event:"
            << "\r\n\tAudioOffset: " << round(e.AudioOffset / 10000) << "ms"
            << "\r\n\tVisemeId: " << e.VisemeId << std::endl;
    };

    speechSynthesizer->WordBoundary += [](const SpeechSynthesisWordBoundaryEventArgs& e)
    {
        auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(e.Duration).count();
        
        auto boundaryType = "";
        switch (e.BoundaryType) {
        case SpeechSynthesisBoundaryType::Punctuation:
            boundaryType = "Punctuation";
            break;
        case SpeechSynthesisBoundaryType::Sentence:
            boundaryType = "Sentence";
            break;
        case SpeechSynthesisBoundaryType::Word:
            boundaryType = "Word";
            break;
        }

        std::cout << "WordBoundary event:"
            // Word, Punctuation, or Sentence
            << "\r\n\tBoundaryType: " << boundaryType
            << "\r\n\tAudioOffset: " << round(e.AudioOffset / 10000) << "ms"
            << "\r\n\tDuration: " << duration
            << "\r\n\tText: \"" << e.Text << "\""
            << "\r\n\tTextOffset: " << e.TextOffset
            << "\r\n\tWordLength: " << e.WordLength << std::endl;
    };

    auto result = speechSynthesizer->SpeakSsmlAsync(ssml).get();

    // Checks result.
    if (result->Reason == ResultReason::SynthesizingAudioCompleted)
    {
        std::cout << "SynthesizingAudioCompleted result" << std::endl;
    }
    else if (result->Reason == ResultReason::Canceled)
    {
        auto cancellation = SpeechSynthesisCancellationDetails::FromResult(result);
        std::cout << "CANCELED: Reason=" << (int)cancellation->Reason << std::endl;

        if (cancellation->Reason == CancellationReason::Error)
        {
            std::cout << "CANCELED: ErrorCode=" << (int)cancellation->ErrorCode << std::endl;
            std::cout << "CANCELED: ErrorDetails=[" << cancellation->ErrorDetails << "]" << std::endl;
            std::cout << "CANCELED: Did you set the speech resource key and region values?" << std::endl;
        }
    }

    std::cout << "Press enter to exit..." << std::endl;
    std::cin.get();
}

std::string getEnvironmentVariable(const char* name)
{
#if defined(_MSC_VER)
    size_t requiredSize = 0;
    (void)getenv_s(&requiredSize, nullptr, 0, name);
    if (requiredSize == 0)
    {
        return "";
    }
    auto buffer = std::make_unique<char[]>(requiredSize);
    (void)getenv_s(&requiredSize, buffer.get(), requiredSize, name);
    return buffer.get();
#else
    auto value = getenv(name);
    return value ? value : "";
#endif
}

A GitHubon további szövegfelolvasási mintákat találhat.

Egyéni végpont használata

Az egyéni végpont funkcionálisan megegyezik a szövegfelolvasási kérelmekhez használt szabványos végpontokkal.

Az egyik különbség az, hogy meg kell adni az EndpointId egyéni hang használatát a Speech SDK-val. A szöveggel kezdheti a beszéd gyorsútmutatóját , majd frissítheti a kódot a EndpointId következővel: és SpeechSynthesisVoiceName.

auto speechConfig = SpeechConfig::FromSubscription(speechKey, speechRegion);
speechConfig->SetSpeechSynthesisVoiceName("YourCustomVoiceName");
speechConfig->SetEndpointId("YourEndpointId");

Ha egyéni hangot szeretne használni a Speech Synthesis Markup Language (SSML) használatával, adja meg a modell nevét hangnévként. Ez a példa a YourCustomVoiceName hangot használja.

<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="en-US">
    <voice name="YourCustomVoiceName">
        This is the text that is spoken. 
    </voice>
</speak>

Tároló futtatása és használata

A Speech-tárolók websocket-alapú lekérdezésvégpont API-kat biztosítanak, amelyek a Speech SDK-n és a Speech CLI-n keresztül érhetők el. Alapértelmezés szerint a Speech SDK és a Speech CLI a nyilvános Speech szolgáltatást használja. A tároló használatához módosítania kell az inicializálási módszert. Kulcs és régió helyett használjon tároló gazdagép URL-címét.

További információ a tárolókról: Speech-tárolók telepítése és futtatása a Dockerrel.

Referenciadokumentáció csomag (Go) | További minták a GitHubon |

Ebben az útmutatóban megismerheti a szöveg beszédszintézishez való használatának gyakori tervezési mintáit.

További információ a következő területekről: Mi az a beszédszöveg?

  • Válaszok lekérése memóriabeli streamekként.
  • A kimeneti mintasebesség és a bitsebesség testreszabása.
  • Szintéziskérések beküldése a Speech Synthesis Markup Language (SSML) használatával.
  • Neurális hangok használata.
  • Feliratkozás eseményekre, és az eredményekre való cselekvés.

Előfeltételek

A Speech SDK telepítése

Mielőtt bármit megtehet, telepítenie kell a Speech SDK for Go-t.

Szövegfelolvasás előadónak

Az alábbi kódmintával beszédszintézist futtathat az alapértelmezett hangkimeneti eszközön. Cserélje le a változókat subscription és region a beszédkulcsot és a helyet/régiót. A szkript futtatása a bemeneti szöveget az alapértelmezett hangszóróhoz beszéli.

package main

import (
    "bufio"
    "fmt"
    "os"
    "strings"
    "time"

    "github.com/Microsoft/cognitive-services-speech-sdk-go/audio"
    "github.com/Microsoft/cognitive-services-speech-sdk-go/common"
    "github.com/Microsoft/cognitive-services-speech-sdk-go/speech"
)

func synthesizeStartedHandler(event speech.SpeechSynthesisEventArgs) {
    defer event.Close()
    fmt.Println("Synthesis started.")
}

func synthesizingHandler(event speech.SpeechSynthesisEventArgs) {
    defer event.Close()
    fmt.Printf("Synthesizing, audio chunk size %d.\n", len(event.Result.AudioData))
}

func synthesizedHandler(event speech.SpeechSynthesisEventArgs) {
    defer event.Close()
    fmt.Printf("Synthesized, audio length %d.\n", len(event.Result.AudioData))
}

func cancelledHandler(event speech.SpeechSynthesisEventArgs) {
    defer event.Close()
    fmt.Println("Received a cancellation.")
}

func main() {
    subscription := "YourSpeechKey"
    region := "YourSpeechRegion"

    audioConfig, err := audio.NewAudioConfigFromDefaultSpeakerOutput()
    if err != nil {
        fmt.Println("Got an error: ", err)
        return
    }
    defer audioConfig.Close()
    speechConfig, err := speech.NewSpeechConfigFromSubscription(subscription, region)
    if err != nil {
        fmt.Println("Got an error: ", err)
        return
    }
    defer speechConfig.Close()
    speechSynthesizer, err := speech.NewSpeechSynthesizerFromConfig(speechConfig, audioConfig)
    if err != nil {
        fmt.Println("Got an error: ", err)
        return
    }
    defer speechSynthesizer.Close()

    speechSynthesizer.SynthesisStarted(synthesizeStartedHandler)
    speechSynthesizer.Synthesizing(synthesizingHandler)
    speechSynthesizer.SynthesisCompleted(synthesizedHandler)
    speechSynthesizer.SynthesisCanceled(cancelledHandler)

    for {
        fmt.Printf("Enter some text that you want to speak, or enter empty text to exit.\n> ")
        text, _ := bufio.NewReader(os.Stdin).ReadString('\n')
        text = strings.TrimSuffix(text, "\n")
        if len(text) == 0 {
            break
        }

        task := speechSynthesizer.SpeakTextAsync(text)
        var outcome speech.SpeechSynthesisOutcome
        select {
        case outcome = <-task:
        case <-time.After(60 * time.Second):
            fmt.Println("Timed out")
            return
        }
        defer outcome.Close()
        if outcome.Error != nil {
            fmt.Println("Got an error: ", outcome.Error)
            return
        }

        if outcome.Result.Reason == common.SynthesizingAudioCompleted {
            fmt.Printf("Speech synthesized to speaker for text [%s].\n", text)
        } else {
            cancellation, _ := speech.NewCancellationDetailsFromSpeechSynthesisResult(outcome.Result)
            fmt.Printf("CANCELED: Reason=%d.\n", cancellation.Reason)

            if cancellation.Reason == common.Error {
                fmt.Printf("CANCELED: ErrorCode=%d\nCANCELED: ErrorDetails=[%s]\nCANCELED: Did you set the speech resource key and region values?\n",
                    cancellation.ErrorCode,
                    cancellation.ErrorDetails)
            }
        }
    }
}

Futtassa a következő parancsokat egy go.mod fájl létrehozásához, amely a GitHubon üzemeltetett összetevőkre hivatkozik:

go mod init quickstart
go get github.com/Microsoft/cognitive-services-speech-sdk-go

Most hozza létre és futtassa a kódot:

go build
go run quickstart

Az osztályokkal kapcsolatos részletes információkért tekintse meg a dokumentációt és SpeechSynthesizer a SpeechConfig referencia-dokumentumokat.

Szövegfelolvasás a memórián belüli streambe

Az eredményül kapott hangadatokat használhatja memórián belüli streamként ahelyett, hogy közvetlenül egy fájlba írnál. A memórián belüli adatfolyammal egyéni viselkedést hozhat létre:

  • Az eredményként kapott bájttömb absztrakciója kereshető streamként egyéni alárendelt szolgáltatásokhoz.
  • Integrálja az eredményt más API-kkal vagy szolgáltatásokkal.
  • Módosítsa a hangadatokat, írjon egyéni .wav fejléceket, és végezze el a kapcsolódó feladatokat.

Ezt a módosítást az előző példára módosíthatja. Távolítsa el a AudioConfig blokkot, mert ettől a ponttól kezdve manuálisan kezeli a kimeneti viselkedést a nagyobb vezérlés érdekében. Ezután adja át nil a AudioConfigSpeechSynthesizer konstruktornak.

Feljegyzés

nilAudioConfigA továbbítás – ahelyett, hogy kihagyta volna az előző előadói kimeneti példában – alapértelmezés szerint nem fogja lejátszani a hangot az aktuális aktív kimeneti eszközön.

Mentse az eredményt egy változóba SpeechSynthesisResult . A AudioData tulajdonság a kimeneti adatok egy []byte példányát adja vissza. Ezt a []byte példányt manuálisan is használhatja, vagy használhatja az AudioDataStream osztályt a memóriabeli stream kezeléséhez. Ebben a példában a NewAudioDataStreamFromSpeechSynthesisResult() statikus függvény használatával kap streamet az eredményből.

Cserélje le a változókat subscription és region a beszédkulcsot és a helyet/régiót:

package main

import (
    "bufio"
    "fmt"
    "io"
    "os"
    "strings"
    "time"

    "github.com/Microsoft/cognitive-services-speech-sdk-go/speech"
)

func synthesizeStartedHandler(event speech.SpeechSynthesisEventArgs) {
    defer event.Close()
    fmt.Println("Synthesis started.")
}

func synthesizingHandler(event speech.SpeechSynthesisEventArgs) {
    defer event.Close()
    fmt.Printf("Synthesizing, audio chunk size %d.\n", len(event.Result.AudioData))
}

func synthesizedHandler(event speech.SpeechSynthesisEventArgs) {
    defer event.Close()
    fmt.Printf("Synthesized, audio length %d.\n", len(event.Result.AudioData))
}

func cancelledHandler(event speech.SpeechSynthesisEventArgs) {
    defer event.Close()
    fmt.Println("Received a cancellation.")
}

func main() {
    subscription := "YourSpeechKey"
    region := "YourSpeechRegion"

    speechConfig, err := speech.NewSpeechConfigFromSubscription(subscription, region)
    if err != nil {
        fmt.Println("Got an error: ", err)
        return
    }
    defer speechConfig.Close()
    speechSynthesizer, err := speech.NewSpeechSynthesizerFromConfig(speechConfig, nil)
    if err != nil {
        fmt.Println("Got an error: ", err)
        return
    }
    defer speechSynthesizer.Close()

    speechSynthesizer.SynthesisStarted(synthesizeStartedHandler)
    speechSynthesizer.Synthesizing(synthesizingHandler)
    speechSynthesizer.SynthesisCompleted(synthesizedHandler)
    speechSynthesizer.SynthesisCanceled(cancelledHandler)

    for {
        fmt.Printf("Enter some text that you want to speak, or enter empty text to exit.\n> ")
        text, _ := bufio.NewReader(os.Stdin).ReadString('\n')
        text = strings.TrimSuffix(text, "\n")
        if len(text) == 0 {
            break
        }

        // StartSpeakingTextAsync sends the result to channel when the synthesis starts.
        task := speechSynthesizer.StartSpeakingTextAsync(text)
        var outcome speech.SpeechSynthesisOutcome
        select {
        case outcome = <-task:
        case <-time.After(60 * time.Second):
            fmt.Println("Timed out")
            return
        }
        defer outcome.Close()
        if outcome.Error != nil {
            fmt.Println("Got an error: ", outcome.Error)
            return
        }

        // In most cases, we want to streaming receive the audio to lower the latency.
        // We can use AudioDataStream to do so.
        stream, err := speech.NewAudioDataStreamFromSpeechSynthesisResult(outcome.Result)
        defer stream.Close()
        if err != nil {
            fmt.Println("Got an error: ", err)
            return
        }

        var all_audio []byte
        audio_chunk := make([]byte, 2048)
        for {
            n, err := stream.Read(audio_chunk)

            if err == io.EOF {
                break
            }

            all_audio = append(all_audio, audio_chunk[:n]...)
        }

        fmt.Printf("Read [%d] bytes from audio data stream.\n", len(all_audio))
    }
}

Futtassa a következő parancsokat egy go.mod fájl létrehozásához, amely a GitHubon üzemeltetett összetevőkre hivatkozik:

go mod init quickstart
go get github.com/Microsoft/cognitive-services-speech-sdk-go

Most hozza létre és futtassa a kódot:

go build
go run quickstart

Az osztályokkal kapcsolatos részletes információkért tekintse meg a dokumentációt és SpeechSynthesizer a SpeechConfig referencia-dokumentumokat.

A szintézis nyelvének és hangának kiválasztása

A Speech szolgáltatás szövegfelolvasási funkciója több mint 400 hangot és több mint 140 nyelvet és változatot támogat. Lekérheti a teljes listát , vagy kipróbálhatja őket a Hangtárban.

Adja meg a bemeneti szövegnek megfelelő nyelvet vagy hangot SpeechConfig , és használja a megadott hangot:

speechConfig, err := speech.NewSpeechConfigFromSubscription(key, region)
if err != nil {
    fmt.Println("Got an error: ", err)
    return
}
defer speechConfig.Close()

speechConfig.SetSpeechSynthesisLanguage("en-US")
speechConfig.SetSpeechSynthesisVoiceName("en-US-AvaMultilingualNeural")

Minden neurális hang többnyelvű és folyékony a saját nyelvén és angolul. Ha például az angol nyelvű beviteli szöveg a következő: "Izgatottan várom, hogy kipróbálhassam a szöveget a beszédhez", és ön kiválasztja es-ES-ElviraNeural, a szöveg angol nyelven, spanyol akcentussal szólal meg.

Ha a hang nem beszéli a bemeneti szöveg nyelvét, a Speech szolgáltatás nem hoz létre szintetizált hangot. A támogatott neurális hangok teljes listájáért tekintse meg a Speech szolgáltatás nyelv- és hangtámogatását.

Feljegyzés

Az alapértelmezett hang az első hang, amelyet területi beállításonként a Voice List API-ból ad vissza.

A beszélő hang prioritási sorrendben van meghatározva az alábbiak szerint:

  • Ha nem állítja be SpeechSynthesisVoiceName , vagy SpeechSynthesisLanguageaz alapértelmezett beszédhang en-US .
  • Ha csak be van állítva SpeechSynthesisLanguage, a megadott területi beállítás alapértelmezett hangja beszél.
  • Ha mindkettő SpeechSynthesisVoiceNameSpeechSynthesisLanguage be van állítva, a SpeechSynthesisLanguage beállítás figyelmen kívül lesz hagyva. A beszéd használatával SpeechSynthesisVoiceName megadott hang.
  • Ha a hangelem a Beszédszintézis korrektúranyelv (SSML) használatával van beállítva, a rendszer figyelmen kívül hagyja a beállításokat és SpeechSynthesisLanguage a SpeechSynthesisVoiceName beállításokat.

Beszédjellemzők testreszabása az SSML használatával

A beszédszintézis korrektúranyelvével (SSML) finomhangolhatja a hangmagasságot, a kiejtést, a beszédsebességet, a hangerőt és egyebeket a beszédkimenethez, ha xml-sémából küldi el a kéréseket. Ez a szakasz egy példát mutat be a hang módosítására. További információt a Beszédszintézis korrektúranyelv áttekintése című témakörben talál.

Az SSML testreszabáshoz való használatához egy kisebb módosítást kell végeznie, amely átváltja a hangot.

Először hozzon létre egy új XML-fájlt az SSML-konfigurációhoz a gyökérprojekt könyvtárában. Ebben a példában ez a következő ssml.xml: . A gyökérelem mindig <speak>. Az elem szövegének <voice> körbefuttatásával a paraméter használatával módosíthatja a name hangot. A támogatott neurális hangok teljes listájáért tekintse meg a támogatott nyelveket.

<speak version="1.0" xmlns="https://www.w3.org/2001/10/synthesis" xml:lang="en-US">
  <voice name="en-US-AvaMultilingualNeural">
    When you're on the freeway, it's a good idea to use a GPS.
  </voice>
</speak>

Ezután módosítania kell a beszédszintézis-kérést, hogy hivatkozzon az XML-fájlra. A kérés többnyire ugyanaz, de a függvény használata helyett a függvényt SpeakTextAsync() használja SpeakSsmlAsync(). Ez a függvény egy XML-sztringre számít, ezért először sztringként tölti be az SSML-konfigurációt. Ettől a ponttól kezdve az eredményobjektum pontosan ugyanaz, mint az előző példák.

Feljegyzés

Ha SSML használata nélkül szeretné beállítani a hangot, a tulajdonságot SpeechConfig a következővel speechConfig.SetSpeechSynthesisVoiceName("en-US-AvaMultilingualNeural")állíthatja be: .

Feliratkozás szintetizátoreseményekre

Előfordulhat, hogy további elemzéseket szeretne a szövegről a beszédfeldolgozáshoz és az eredményekhez. Előfordulhat például, hogy tudni szeretné, hogy mikor indul el és áll le a szintetizátor, vagy érdemes lehet tudnia a szintézis során előforduló egyéb eseményekről.

Miközben a SpeechSynthesizert használja a szövegfelolvasáshoz, előfizethet a táblázatban szereplő eseményekre:

Esemény Leírás Használati eset
BookmarkReached Azt jelzi, hogy egy könyvjelző el lett érve. A könyvjelző által elért esemény aktiválásához egy bookmark elem szükséges az SSML-ben. Ez az esemény a kimeneti hangnak a szintézis kezdete és bookmark az elem közötti eltelt idejét jelenti. Az esemény tulajdonsága Text a könyvjelző mark attribútumában beállított sztringérték. Az bookmark elemek nincsenek kimondva. Az elem használatával bookmark egyéni jelölőket szúrhat be az SSML-be az egyes jelölők eltolásának lekéréséhez a hangstreamben. Az bookmark elem a szöveg vagy a címkesorozat egy adott helyére hivatkozhat.
SynthesisCanceled Azt jelzi, hogy a beszédszintézis megszakadt. Ellenőrizheti, hogy a szintézis mikor lesz megszakítva.
SynthesisCompleted Azt jelzi, hogy a beszédszintézis befejeződött. Ellenőrizheti, hogy a szintézis befejeződött-e.
SynthesisStarted Azt jelzi, hogy a beszédszintézis elindult. Ellenőrizheti, hogy mikor kezdődött el a szintézis.
Synthesizing Azt jelzi, hogy a beszédszintézis folyamatban van. Ez az esemény minden alkalommal aktiválódik, amikor az SDK hangrészletet kap a Speech szolgáltatástól. Ellenőrizheti, hogy a szintézis folyamatban van-e.
VisemeReceived Azt jelzi, hogy egy viseme esemény érkezett. A visemeket gyakran használják a megfigyelt beszéd legfontosabb pózainak ábrázolására. A fő pózok közé tartozik az ajkak, az állkapocs és a nyelv pozíciója egy adott fonál előállításában. A visemek használatával animálhatja egy karakter arcát a beszédhang lejátszása során.
WordBoundary Azt jelzi, hogy egy szóhatár érkezett. Ez az esemény minden új kimondott szó, írásjel és mondat elején jelenik meg. Az esemény az aktuális szó időeltolódását jelenti pipákban a kimeneti hang elejétől. Ez az esemény közvetlenül a kimondandó szó előtt jelenti a bemeneti szöveg vagy az SSML karakterpozícióját is. Ezt az eseményt gyakran használják a szöveg és a megfelelő hang relatív pozícióinak lekérésére. Érdemes lehet tudni egy új szóról, majd az időzítés alapján cselekedni. Például olyan információkat kaphat, amelyek segítségével eldöntheti, hogy mikor és mennyi ideig emelheti ki a szavakat a beszéd közben.

Feljegyzés

Az események akkor jönnek létre, amikor a kimeneti hangadatok elérhetővé válnak, ami gyorsabb, mint egy kimeneti eszköz lejátszása. A hívónak megfelelően szinkronizálnia kell a streamelést és a valós idejűt.

Íme egy példa, amely bemutatja, hogyan iratkozhat fel eseményekre beszédszintézis céljából. A rövid útmutató utasításait követve a fájl tartalmát speech-synthesis.go a következő Go-kódra cserélheti:

package main

import (
    "fmt"
    "os"
    "time"

    "github.com/Microsoft/cognitive-services-speech-sdk-go/audio"
    "github.com/Microsoft/cognitive-services-speech-sdk-go/common"
    "github.com/Microsoft/cognitive-services-speech-sdk-go/speech"
)

func bookmarkReachedHandler(event speech.SpeechSynthesisBookmarkEventArgs) {
    defer event.Close()
    fmt.Println("BookmarkReached event")
}

func synthesisCanceledHandler(event speech.SpeechSynthesisEventArgs) {
    defer event.Close()
    fmt.Println("SynthesisCanceled event")
}

func synthesisCompletedHandler(event speech.SpeechSynthesisEventArgs) {
    defer event.Close()
    fmt.Println("SynthesisCompleted event")
    fmt.Printf("\tAudioData: %d bytes\n", len(event.Result.AudioData))
    fmt.Printf("\tAudioDuration: %d\n", event.Result.AudioDuration)
}

func synthesisStartedHandler(event speech.SpeechSynthesisEventArgs) {
    defer event.Close()
    fmt.Println("SynthesisStarted event")
}

func synthesizingHandler(event speech.SpeechSynthesisEventArgs) {
    defer event.Close()
    fmt.Println("Synthesizing event")
    fmt.Printf("\tAudioData %d bytes\n", len(event.Result.AudioData))
}

func visemeReceivedHandler(event speech.SpeechSynthesisVisemeEventArgs) {
    defer event.Close()
    fmt.Println("VisemeReceived event")
    fmt.Printf("\tAudioOffset: %dms\n", (event.AudioOffset+5000)/10000)
    fmt.Printf("\tVisemeID %d\n", event.VisemeID)
}

func wordBoundaryHandler(event speech.SpeechSynthesisWordBoundaryEventArgs) {
    defer event.Close()
    boundaryType := ""
    switch event.BoundaryType {
    case 0:
        boundaryType = "Word"
    case 1:
        boundaryType = "Punctuation"
    case 2:
        boundaryType = "Sentence"
    }
    fmt.Println("WordBoundary event")
    fmt.Printf("\tBoundaryType %v\n", boundaryType)
    fmt.Printf("\tAudioOffset: %dms\n", (event.AudioOffset+5000)/10000)
    fmt.Printf("\tDuration %d\n", event.Duration)
    fmt.Printf("\tText %s\n", event.Text)
    fmt.Printf("\tTextOffset %d\n", event.TextOffset)
    fmt.Printf("\tWordLength %d\n", event.WordLength)
}

func main() {
    // This example requires environment variables named "SPEECH_KEY" and "SPEECH_REGION"
    speechKey := os.Getenv("SPEECH_KEY")
    speechRegion := os.Getenv("SPEECH_REGION")

    audioConfig, err := audio.NewAudioConfigFromDefaultSpeakerOutput()
    if err != nil {
        fmt.Println("Got an error: ", err)
        return
    }
    defer audioConfig.Close()
    speechConfig, err := speech.NewSpeechConfigFromSubscription(speechKey, speechRegion)
    if err != nil {
        fmt.Println("Got an error: ", err)
        return
    }
    defer speechConfig.Close()

    // Required for WordBoundary event sentences.
    speechConfig.SetProperty(common.SpeechServiceResponseRequestSentenceBoundary, "true")

    speechSynthesizer, err := speech.NewSpeechSynthesizerFromConfig(speechConfig, audioConfig)
    if err != nil {
        fmt.Println("Got an error: ", err)
        return
    }
    defer speechSynthesizer.Close()

    speechSynthesizer.BookmarkReached(bookmarkReachedHandler)
    speechSynthesizer.SynthesisCanceled(synthesisCanceledHandler)
    speechSynthesizer.SynthesisCompleted(synthesisCompletedHandler)
    speechSynthesizer.SynthesisStarted(synthesisStartedHandler)
    speechSynthesizer.Synthesizing(synthesizingHandler)
    speechSynthesizer.VisemeReceived(visemeReceivedHandler)
    speechSynthesizer.WordBoundary(wordBoundaryHandler)

    speechSynthesisVoiceName := "en-US-AvaMultilingualNeural"

    ssml := fmt.Sprintf(`<speak version='1.0' xml:lang='en-US' xmlns='http://www.w3.org/2001/10/synthesis' xmlns:mstts='http://www.w3.org/2001/mstts'>
            <voice name='%s'>
                <mstts:viseme type='redlips_front'/>
                The rainbow has seven colors: <bookmark mark='colors_list_begin'/>Red, orange, yellow, green, blue, indigo, and violet.<bookmark mark='colors_list_end'/>.
            </voice>
        </speak>`, speechSynthesisVoiceName)

    // Synthesize the SSML
    fmt.Printf("SSML to synthesize: \n\t%s\n", ssml)
    task := speechSynthesizer.SpeakSsmlAsync(ssml)

    var outcome speech.SpeechSynthesisOutcome
    select {
    case outcome = <-task:
    case <-time.After(60 * time.Second):
        fmt.Println("Timed out")
        return
    }
    defer outcome.Close()
    if outcome.Error != nil {
        fmt.Println("Got an error: ", outcome.Error)
        return
    }

    if outcome.Result.Reason == common.SynthesizingAudioCompleted {
        fmt.Println("SynthesizingAudioCompleted result")
    } else {
        cancellation, _ := speech.NewCancellationDetailsFromSpeechSynthesisResult(outcome.Result)
        fmt.Printf("CANCELED: Reason=%d.\n", cancellation.Reason)

        if cancellation.Reason == common.Error {
            fmt.Printf("CANCELED: ErrorCode=%d\nCANCELED: ErrorDetails=[%s]\nCANCELED: Did you set the speech resource key and region values?\n",
                cancellation.ErrorCode,
                cancellation.ErrorDetails)
        }
    }
}

A GitHubon további szövegfelolvasási mintákat találhat.

Tároló futtatása és használata

A Speech-tárolók websocket-alapú lekérdezésvégpont API-kat biztosítanak, amelyek a Speech SDK-n és a Speech CLI-n keresztül érhetők el. Alapértelmezés szerint a Speech SDK és a Speech CLI a nyilvános Speech szolgáltatást használja. A tároló használatához módosítania kell az inicializálási módszert. Kulcs és régió helyett használjon tároló gazdagép URL-címét.

További információ a tárolókról: Speech-tárolók telepítése és futtatása a Dockerrel.

Referenciadokumentáció | – További minták a GitHubon

Ebben az útmutatóban megismerheti a szöveg beszédszintézishez való használatának gyakori tervezési mintáit.

További információ a következő területekről: Mi az a beszédszöveg?

  • Válaszok lekérése memóriabeli streamekként.
  • A kimeneti mintasebesség és a bitsebesség testreszabása.
  • Szintéziskérések beküldése a Speech Synthesis Markup Language (SSML) használatával.
  • Neurális hangok használata.
  • Feliratkozás eseményekre, és az eredményekre való cselekvés.

A szintézis nyelvének és hangának kiválasztása

A Speech szolgáltatás szövegfelolvasási funkciója több mint 400 hangot és több mint 140 nyelvet és változatot támogat. Lekérheti a teljes listát , vagy kipróbálhatja őket a Hangtárban.

Adja meg a SpeechConfig nyelvét vagy hangját, hogy megfeleljen a bemeneti szövegnek, és használja a megadott hangot. A következő kódrészlet a technika működését mutatja be:

public static void main(String[] args) {
    SpeechConfig speechConfig = SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
    // Set either the `SpeechSynthesisVoiceName` or `SpeechSynthesisLanguage`.
    speechConfig.setSpeechSynthesisLanguage("en-US"); 
    speechConfig.setSpeechSynthesisVoiceName("en-US-AvaMultilingualNeural");
}

Minden neurális hang többnyelvű és folyékony a saját nyelvén és angolul. Ha például az angol nyelvű beviteli szöveg a következő: "Izgatottan várom, hogy kipróbálhassam a szöveget a beszédhez", és ön kiválasztja es-ES-ElviraNeural, a szöveg angol nyelven, spanyol akcentussal szólal meg.

Ha a hang nem beszéli a bemeneti szöveg nyelvét, a Speech szolgáltatás nem hoz létre szintetizált hangot. A támogatott neurális hangok teljes listájáért tekintse meg a Speech szolgáltatás nyelv- és hangtámogatását.

Feljegyzés

Az alapértelmezett hang az első hang, amelyet területi beállításonként a Voice List API-ból ad vissza.

A beszélő hang prioritási sorrendben van meghatározva az alábbiak szerint:

  • Ha nem állítja be SpeechSynthesisVoiceName , vagy SpeechSynthesisLanguageaz alapértelmezett beszédhang en-US .
  • Ha csak be van állítva SpeechSynthesisLanguage, a megadott területi beállítás alapértelmezett hangja beszél.
  • Ha mindkettő SpeechSynthesisVoiceNameSpeechSynthesisLanguage be van állítva, a SpeechSynthesisLanguage beállítás figyelmen kívül lesz hagyva. A beszéd használatával SpeechSynthesisVoiceName megadott hang.
  • Ha a hangelem a Beszédszintézis korrektúranyelv (SSML) használatával van beállítva, a rendszer figyelmen kívül hagyja a beállításokat és SpeechSynthesisLanguage a SpeechSynthesisVoiceName beállításokat.

Beszédszintézis fájlba

Hozzon létre egy objektumot SpeechSynthesizer . Ez az objektum szöveget futtat beszédkonvertálások és kimenetek hangszórókra, fájlokra vagy más kimeneti streamekre. SpeechSynthesizer a következő paramétereket fogadja el:

  • Az SpeechConfig előző lépésben létrehozott objektum.
  • Egy AudioConfig objektum, amely meghatározza, hogyan kell kezelni a kimeneti eredményeket.
  1. Hozzon létre egy példányt AudioConfig , amely automatikusan írja a kimenetet egy .wav fájlba a fromWavFileOutput() statikus függvény használatával:

    public static void main(String[] args) {
        SpeechConfig speechConfig = SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
        AudioConfig audioConfig = AudioConfig.fromWavFileOutput("path/to/write/file.wav");
    }
    
  2. Példány példányosítása SpeechSynthesizer . Adja át az speechConfig objektumot és az audioConfig objektumot paraméterekként. A beszéd szintetizálásához és egy fájlba való íráshoz futtasson SpeakText() egy szöveges sztringet.

    public static void main(String[] args) {
        SpeechConfig speechConfig = SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
        AudioConfig audioConfig = AudioConfig.fromWavFileOutput("path/to/write/file.wav");
    
        SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer(speechConfig, audioConfig);
        speechSynthesizer.SpeakText("I'm excited to try text to speech");
    }
    

A program futtatásakor létrehoz egy szintetizált .wav fájlt, amelyet a program a megadott helyre ír. Ez az eredmény jó példa a legalapvetőbb használatra. Ezután testre szabhatja a kimenetet, és memóriabeli streamként kezelheti a kimeneti választ az egyéni forgatókönyvek kezeléséhez.

Szintetizálás előadói kimenetre

Előfordulhat, hogy további elemzéseket szeretne a szövegről a beszédfeldolgozáshoz és az eredményekhez. Előfordulhat például, hogy tudni szeretné, hogy mikor indul el és áll le a szintetizátor, vagy érdemes lehet tudnia a szintézis során előforduló egyéb eseményekről.

Ha szintetizált beszédet szeretne kiadni az aktuális aktív kimeneti eszközre, például egy hangszóróra, a statikus függvény használatával példányosíthatja a fromDefaultSpeakerOutput() beszédetAudioConfig. Példa:

public static void main(String[] args) {
    SpeechConfig speechConfig = SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
    AudioConfig audioConfig = AudioConfig.fromDefaultSpeakerOutput();

    SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer(speechConfig, audioConfig);
    speechSynthesizer.SpeakText("I'm excited to try text to speech");
}

Eredmény lekérése memórián belüli streamként

Az eredményül kapott hangadatokat használhatja memórián belüli streamként ahelyett, hogy közvetlenül egy fájlba írnál. A memórián belüli adatfolyammal egyéni viselkedést hozhat létre:

  • Az eredményként kapott bájttömb absztrakciója kereshető streamként egyéni alárendelt szolgáltatásokhoz.
  • Integrálja az eredményt más API-kkal vagy szolgáltatásokkal.
  • Módosítsa a hangadatokat, írjon egyéni .wav fejléceket, és végezze el a kapcsolódó feladatokat.

Ezt a módosítást az előző példára módosíthatja. Először távolítsa el a AudioConfig blokkot, mert a nagyobb vezérlés érdekében manuálisan kezeli a kimeneti viselkedést. Ezután adja át null a AudioConfigSpeechSynthesizer konstruktornak.

Feljegyzés

nullAudioConfigA továbbítás – ahelyett, hogy kihagyta volna az előző előadói kimeneti példában – nem játssza le alapértelmezés szerint a hangot az aktuális aktív kimeneti eszközön.

Mentse az eredményt egy változóba SpeechSynthesisResult . A SpeechSynthesisResult.getAudioData() függvény a kimeneti adatok egy byte [] példányát adja vissza. Ezt a byte [] példányt manuálisan is használhatja, vagy használhatja az AudioDataStream osztályt a memóriabeli stream kezeléséhez.

Ebben a példában a statikus függvény használatával kérje le a AudioDataStream.fromResult() streamet az eredményből:

public static void main(String[] args) {
    SpeechConfig speechConfig = SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
    SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer(speechConfig, null);

    SpeechSynthesisResult result = speechSynthesizer.SpeakText("I'm excited to try text to speech");
    AudioDataStream stream = AudioDataStream.fromResult(result);
    System.out.print(stream.getStatus());
}

Ezen a ponton bármilyen egyéni viselkedést implementálhat az eredményként kapott stream objektum használatával.

Hangformátum testreszabása

Testre szabhatja a hangkimeneti attribútumokat, többek között a következőket:

  • Hangfájl típusa
  • Mintasebesség
  • Bitmélység

A hangformátum módosításához használja az setSpeechSynthesisOutputFormat() objektum függvényét SpeechConfig . Ez a függvény egy enum SpeechSynthesisOutputFormat típusú példányt vár. Válassza ki a enum kimeneti formátumot a listában. Az elérhető formátumokért tekintse meg a hangformátumok listáját.

A követelményektől függően különböző fájltípusok érhetők el. Definíció szerint a nyers formátumok, például Raw24Khz16BitMonoPcm nem tartalmaznak hangfejléceket. Nyers formátumokat csak az alábbi helyzetek egyikében használjon:

  • Tudja, hogy az alsóbb rétegbeli implementáció képes dekódolni egy nyers bitstreamet.
  • A fejlécek manuális összeállítását olyan tényezők alapján tervezi, mint a bitmélység, a mintasebesség és a csatornák száma.

Ez a példa az objektum beállításával SpeechSynthesisOutputFormatSpeechConfig adja meg a magas megbízhatóságú RIFF formátumotRiff24Khz16BitMonoPcm. Az előző szakaszban szereplő példához hasonlóan az eredmény memórián belüli adatfolyamát is AudioDataStream lekérheti, majd egy fájlba írhatja.

public static void main(String[] args) {
    SpeechConfig speechConfig = SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");

    // set the output format
    speechConfig.setSpeechSynthesisOutputFormat(SpeechSynthesisOutputFormat.Riff24Khz16BitMonoPcm);

    SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer(speechConfig, null);
    SpeechSynthesisResult result = speechSynthesizer.SpeakText("I'm excited to try text to speech");
    AudioDataStream stream = AudioDataStream.fromResult(result);
    stream.saveToWavFile("path/to/write/file.wav");
}

A program futtatásakor egy .wav fájlt ír a megadott elérési útra.

Beszédjellemzők testreszabása az SSML használatával

Az SSML használatával finomhangolhatja a hangmagasságot, a kiejtést, a beszédsebességet, a hangerőt és a szöveg egyéb aspektusait a beszédkimenetre, ha a kéréseket XML-sémából küldi el. Ez a szakasz egy példát mutat be a hang módosítására. További információkért tekintse meg az SSML útmutatóját.

Az SSML testreszabáshoz való használatához egy kisebb módosítást kell végeznie, amely átváltja a hangot.

  1. Hozzon létre egy új XML-fájlt az SSML-konfigurációhoz a gyökérprojekt könyvtárában.

    <speak version="1.0" xmlns="https://www.w3.org/2001/10/synthesis" xml:lang="en-US">
      <voice name="en-US-AvaMultilingualNeural">
        When you're on the freeway, it's a good idea to use a GPS.
      </voice>
    </speak>
    

    Ebben a példában a fájl ssml.xml. A gyökérelem mindig <speak>. Az elem szövegének <voice> körbefuttatásával a paraméter használatával módosíthatja a name hangot. A támogatott neurális hangok teljes listájáért tekintse meg a támogatott nyelveket.

  2. Módosítsa a beszédszintézis-kérést az XML-fájlra való hivatkozáshoz. A kérés többnyire ugyanaz. A függvény használata helyett a SpeakText() .SpeakSsml() Ez a függvény egy XML-sztringet vár, ezért először hozzon létre egy függvényt, amely betölt egy XML-fájlt, és sztringként adja vissza:

    private static String xmlToString(String filePath) {
        File file = new File(filePath);
        StringBuilder fileContents = new StringBuilder((int)file.length());
    
        try (Scanner scanner = new Scanner(file)) {
            while(scanner.hasNextLine()) {
                fileContents.append(scanner.nextLine() + System.lineSeparator());
            }
            return fileContents.toString().trim();
        } catch (FileNotFoundException ex) {
            return "File not found.";
        }
    }
    

    Ezen a ponton az eredményobjektum pontosan ugyanaz, mint a korábbi példák:

    public static void main(String[] args) {
        SpeechConfig speechConfig = SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
        SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer(speechConfig, null);
    
        String ssml = xmlToString("ssml.xml");
        SpeechSynthesisResult result = speechSynthesizer.SpeakSsml(ssml);
        AudioDataStream stream = AudioDataStream.fromResult(result);
        stream.saveToWavFile("path/to/write/file.wav");
    }
    

Feljegyzés

Ha SSML használata nélkül szeretné módosítani a hangot, állítsa be a tulajdonságot SpeechConfig a következő használatával SpeechConfig.setSpeechSynthesisVoiceName("en-US-AvaMultilingualNeural");: .

Feliratkozás szintetizátoreseményekre

Előfordulhat, hogy további elemzéseket szeretne a szövegről a beszédfeldolgozáshoz és az eredményekhez. Előfordulhat például, hogy tudni szeretné, hogy mikor indul el és áll le a szintetizátor, vagy érdemes lehet tudnia a szintézis során előforduló egyéb eseményekről.

Miközben a SpeechSynthesizert használja a szövegfelolvasáshoz, előfizethet a táblázatban szereplő eseményekre:

Esemény Leírás Használati eset
BookmarkReached Azt jelzi, hogy egy könyvjelző el lett érve. A könyvjelző által elért esemény aktiválásához egy bookmark elem szükséges az SSML-ben. Ez az esemény a kimeneti hangnak a szintézis kezdete és bookmark az elem közötti eltelt idejét jelenti. Az esemény tulajdonsága Text a könyvjelző mark attribútumában beállított sztringérték. Az bookmark elemek nincsenek kimondva. Az elem használatával bookmark egyéni jelölőket szúrhat be az SSML-be az egyes jelölők eltolásának lekéréséhez a hangstreamben. Az bookmark elem a szöveg vagy a címkesorozat egy adott helyére hivatkozhat.
SynthesisCanceled Azt jelzi, hogy a beszédszintézis megszakadt. Ellenőrizheti, hogy a szintézis mikor lesz megszakítva.
SynthesisCompleted Azt jelzi, hogy a beszédszintézis befejeződött. Ellenőrizheti, hogy a szintézis befejeződött-e.
SynthesisStarted Azt jelzi, hogy a beszédszintézis elindult. Ellenőrizheti, hogy mikor kezdődött el a szintézis.
Synthesizing Azt jelzi, hogy a beszédszintézis folyamatban van. Ez az esemény minden alkalommal aktiválódik, amikor az SDK hangrészletet kap a Speech szolgáltatástól. Ellenőrizheti, hogy a szintézis folyamatban van-e.
VisemeReceived Azt jelzi, hogy egy viseme esemény érkezett. A visemeket gyakran használják a megfigyelt beszéd legfontosabb pózainak ábrázolására. A fő pózok közé tartozik az ajkak, az állkapocs és a nyelv pozíciója egy adott fonál előállításában. A visemek használatával animálhatja egy karakter arcát a beszédhang lejátszása során.
WordBoundary Azt jelzi, hogy egy szóhatár érkezett. Ez az esemény minden új kimondott szó, írásjel és mondat elején jelenik meg. Az esemény az aktuális szó időeltolódását jelenti pipákban a kimeneti hang elejétől. Ez az esemény közvetlenül a kimondandó szó előtt jelenti a bemeneti szöveg vagy az SSML karakterpozícióját is. Ezt az eseményt gyakran használják a szöveg és a megfelelő hang relatív pozícióinak lekérésére. Érdemes lehet tudni egy új szóról, majd az időzítés alapján cselekedni. Például olyan információkat kaphat, amelyek segítségével eldöntheti, hogy mikor és mennyi ideig emelheti ki a szavakat a beszéd közben.

Feljegyzés

Az események akkor jönnek létre, amikor a kimeneti hangadatok elérhetővé válnak, ami gyorsabb, mint egy kimeneti eszköz lejátszása. A hívónak megfelelően szinkronizálnia kell a streamelést és a valós idejűt.

Íme egy példa, amely bemutatja, hogyan iratkozhat fel eseményekre beszédszintézis céljából. Kövesse a rövid útmutató utasításait, de cserélje le a SpeechSynthesis.java fájl tartalmát a következő Java-kódra:

import com.microsoft.cognitiveservices.speech.*;
import com.microsoft.cognitiveservices.speech.audio.*;

import java.util.Scanner;
import java.util.concurrent.ExecutionException;

public class SpeechSynthesis {
    // This example requires environment variables named "SPEECH_KEY" and "SPEECH_REGION"
    private static String speechKey = System.getenv("SPEECH_KEY");
    private static String speechRegion = System.getenv("SPEECH_REGION");

    public static void main(String[] args) throws InterruptedException, ExecutionException {

        SpeechConfig speechConfig = SpeechConfig.fromSubscription(speechKey, speechRegion);
        
        // Required for WordBoundary event sentences.
        speechConfig.setProperty(PropertyId.SpeechServiceResponse_RequestSentenceBoundary, "true");

        String speechSynthesisVoiceName = "en-US-AvaMultilingualNeural"; 
        
        String ssml = String.format("<speak version='1.0' xml:lang='en-US' xmlns='http://www.w3.org/2001/10/synthesis' xmlns:mstts='http://www.w3.org/2001/mstts'>"
            .concat(String.format("<voice name='%s'>", speechSynthesisVoiceName))
            .concat("<mstts:viseme type='redlips_front'/>")
            .concat("The rainbow has seven colors: <bookmark mark='colors_list_begin'/>Red, orange, yellow, green, blue, indigo, and violet.<bookmark mark='colors_list_end'/>.")
            .concat("</voice>")
            .concat("</speak>"));

        SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer(speechConfig);
        {
            // Subscribe to events

            speechSynthesizer.BookmarkReached.addEventListener((o, e) -> {
                System.out.println("BookmarkReached event:");
                System.out.println("\tAudioOffset: " + ((e.getAudioOffset() + 5000) / 10000) + "ms");
                System.out.println("\tText: " + e.getText());
            });

            speechSynthesizer.SynthesisCanceled.addEventListener((o, e) -> {
                System.out.println("SynthesisCanceled event");
            });

            speechSynthesizer.SynthesisCompleted.addEventListener((o, e) -> {
                SpeechSynthesisResult result = e.getResult();                
                byte[] audioData = result.getAudioData();
                System.out.println("SynthesisCompleted event:");
                System.out.println("\tAudioData: " + audioData.length + " bytes");
                System.out.println("\tAudioDuration: " + result.getAudioDuration());
                result.close();
            });
            
            speechSynthesizer.SynthesisStarted.addEventListener((o, e) -> {
                System.out.println("SynthesisStarted event");
            });

            speechSynthesizer.Synthesizing.addEventListener((o, e) -> {
                SpeechSynthesisResult result = e.getResult();
                byte[] audioData = result.getAudioData();
                System.out.println("Synthesizing event:");
                System.out.println("\tAudioData: " + audioData.length + " bytes");
                result.close();
            });

            speechSynthesizer.VisemeReceived.addEventListener((o, e) -> {
                System.out.println("VisemeReceived event:");
                System.out.println("\tAudioOffset: " + ((e.getAudioOffset() + 5000) / 10000) + "ms");
                System.out.println("\tVisemeId: " + e.getVisemeId());
            });

            speechSynthesizer.WordBoundary.addEventListener((o, e) -> {
                System.out.println("WordBoundary event:");
                System.out.println("\tBoundaryType: " + e.getBoundaryType());
                System.out.println("\tAudioOffset: " + ((e.getAudioOffset() + 5000) / 10000) + "ms");
                System.out.println("\tDuration: " + e.getDuration());
                System.out.println("\tText: " + e.getText());
                System.out.println("\tTextOffset: " + e.getTextOffset());
                System.out.println("\tWordLength: " + e.getWordLength());
            });

            // Synthesize the SSML
            System.out.println("SSML to synthesize:");
            System.out.println(ssml);
            SpeechSynthesisResult speechSynthesisResult = speechSynthesizer.SpeakSsmlAsync(ssml).get();

            if (speechSynthesisResult.getReason() == ResultReason.SynthesizingAudioCompleted) {
                System.out.println("SynthesizingAudioCompleted result");
            }
            else if (speechSynthesisResult.getReason() == ResultReason.Canceled) {
                SpeechSynthesisCancellationDetails cancellation = SpeechSynthesisCancellationDetails.fromResult(speechSynthesisResult);
                System.out.println("CANCELED: Reason=" + cancellation.getReason());

                if (cancellation.getReason() == CancellationReason.Error) {
                    System.out.println("CANCELED: ErrorCode=" + cancellation.getErrorCode());
                    System.out.println("CANCELED: ErrorDetails=" + cancellation.getErrorDetails());
                    System.out.println("CANCELED: Did you set the speech resource key and region values?");
                }
            }
        }
        speechSynthesizer.close();

        System.exit(0);
    }
}

A GitHubon további szövegfelolvasási mintákat találhat.

Egyéni végpont használata

Az egyéni végpont funkcionálisan megegyezik a szövegfelolvasási kérelmekhez használt szabványos végpontokkal.

Az egyik különbség az, hogy meg kell adni az EndpointId egyéni hang használatát a Speech SDK-val. A szöveggel kezdheti a beszéd gyorsútmutatóját , majd frissítheti a kódot a EndpointId következővel: és SpeechSynthesisVoiceName.

SpeechConfig speechConfig = SpeechConfig.fromSubscription(speechKey, speechRegion);
speechConfig.setSpeechSynthesisVoiceName("YourCustomVoiceName");
speechConfig.setEndpointId("YourEndpointId");

Ha egyéni hangot szeretne használni a Speech Synthesis Markup Language (SSML) használatával, adja meg a modell nevét hangnévként. Ez a példa a YourCustomVoiceName hangot használja.

<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="en-US">
    <voice name="YourCustomVoiceName">
        This is the text that is spoken. 
    </voice>
</speak>

Tároló futtatása és használata

A Speech-tárolók websocket-alapú lekérdezésvégpont API-kat biztosítanak, amelyek a Speech SDK-n és a Speech CLI-n keresztül érhetők el. Alapértelmezés szerint a Speech SDK és a Speech CLI a nyilvános Speech szolgáltatást használja. A tároló használatához módosítania kell az inicializálási módszert. Kulcs és régió helyett használjon tároló gazdagép URL-címét.

További információ a tárolókról: Speech-tárolók telepítése és futtatása a Dockerrel.

Referenciadokumentáció csomag (npm) | További minták a GitHub | Library forráskódján |

Ebben az útmutatóban megismerheti a szöveg beszédszintézishez való használatának gyakori tervezési mintáit.

További információ a következő területekről: Mi az a beszédszöveg?

  • Válaszok lekérése memóriabeli streamekként.
  • A kimeneti mintasebesség és a bitsebesség testreszabása.
  • Szintéziskérések beküldése a Speech Synthesis Markup Language (SSML) használatával.
  • Neurális hangok használata.
  • Feliratkozás eseményekre, és az eredményekre való cselekvés.

A szintézis nyelvének és hangának kiválasztása

A Speech szolgáltatás szövegfelolvasási funkciója több mint 400 hangot és több mint 140 nyelvet és változatot támogat. Lekérheti a teljes listát , vagy kipróbálhatja őket a Hangtárban.

Adja meg a bemeneti szövegnek megfelelő nyelvet vagy hangot SpeechConfig , és használja a megadott hangot:

function synthesizeSpeech() {
    const speechConfig = sdk.SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
    // Set either the `SpeechSynthesisVoiceName` or `SpeechSynthesisLanguage`.
    speechConfig.speechSynthesisLanguage = "en-US"; 
    speechConfig.speechSynthesisVoiceName = "en-US-AvaMultilingualNeural";
}

synthesizeSpeech();

Minden neurális hang többnyelvű és folyékony a saját nyelvén és angolul. Ha például az angol nyelvű beviteli szöveg a következő: "Izgatottan várom, hogy kipróbálhassam a szöveget a beszédhez", és ön kiválasztja es-ES-ElviraNeural, a szöveg angol nyelven, spanyol akcentussal szólal meg.

Ha a hang nem beszéli a bemeneti szöveg nyelvét, a Speech szolgáltatás nem hoz létre szintetizált hangot. A támogatott neurális hangok teljes listájáért tekintse meg a Speech szolgáltatás nyelv- és hangtámogatását.

Feljegyzés

Az alapértelmezett hang az első hang, amelyet területi beállításonként a Voice List API-ból ad vissza.

A beszélő hang prioritási sorrendben van meghatározva az alábbiak szerint:

  • Ha nem állítja be SpeechSynthesisVoiceName , vagy SpeechSynthesisLanguageaz alapértelmezett beszédhang en-US .
  • Ha csak be van állítva SpeechSynthesisLanguage, a megadott területi beállítás alapértelmezett hangja beszél.
  • Ha mindkettő SpeechSynthesisVoiceNameSpeechSynthesisLanguage be van állítva, a SpeechSynthesisLanguage beállítás figyelmen kívül lesz hagyva. A beszéd használatával SpeechSynthesisVoiceName megadott hang.
  • Ha a hangelem a Beszédszintézis korrektúranyelv (SSML) használatával van beállítva, a rendszer figyelmen kívül hagyja a beállításokat és SpeechSynthesisLanguage a SpeechSynthesisVoiceName beállításokat.

Szövegszintézis beszédszintézise

Ha szintetizált beszédet szeretne kiadni az aktuális aktív kimeneti eszközre, például egy hangszóróra, a statikus függvény használatával példányosíthatja a fromDefaultSpeakerOutput() beszédetAudioConfig. Példa:

function synthesizeSpeech() {
    const speechConfig = sdk.SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
    const audioConfig = sdk.AudioConfig.fromDefaultSpeakerOutput();

    const speechSynthesizer = new SpeechSynthesizer(speechConfig, audioConfig);
    speechSynthesizer.speakTextAsync(
        "I'm excited to try text to speech",
        result => {
            if (result) {
                speechSynthesizer.close();
                return result.audioData;
            }
        },
        error => {
            console.log(error);
            speechSynthesizer.close();
        });
}

A program futtatásakor a rendszer szintetizált hangot játszik le a hangszóróról. Ez az eredmény jó példa a legalapvetőbb használatra. Ezután testre szabhatja a kimenetet, és memóriabeli streamként kezelheti a kimeneti választ az egyéni forgatókönyvek kezeléséhez.

Eredmény lekérése memórián belüli streamként

Az eredményül kapott hangadatokat használhatja memórián belüli streamként ahelyett, hogy közvetlenül egy fájlba írnál. A memórián belüli adatfolyammal egyéni viselkedést hozhat létre:

  • Az eredményként kapott bájttömb absztrakciója kereshető streamként egyéni alárendelt szolgáltatásokhoz.
  • Integrálja az eredményt más API-kkal vagy szolgáltatásokkal.
  • Módosítsa a hangadatokat, írjon egyéni .wav fejléceket, és végezze el a kapcsolódó feladatokat.

Ezt a módosítást az előző példára módosíthatja. Távolítsa el a AudioConfig blokkot, mert ettől a ponttól kezdve manuálisan kezeli a kimeneti viselkedést a nagyobb vezérlés érdekében. Ezután adja át null a AudioConfigSpeechSynthesizer konstruktornak.

Feljegyzés

nullAudioConfigA továbbítás – ahelyett, hogy kihagyta volna az előző előadói kimeneti példában – nem játssza le alapértelmezés szerint a hangot az aktuális aktív kimeneti eszközön.

Mentse az eredményt egy SpeechSynthesisResult változóba. A SpeechSynthesisResult.audioData tulajdonság a kimeneti adatok értékét adja vissza ArrayBuffer , az alapértelmezett böngészőstream-típust. Kiszolgálóoldali kód esetén konvertálja ArrayBuffer pufferfolyammá.

Az ügyféloldalon a következő kód működik:

function synthesizeSpeech() {
    const speechConfig = sdk.SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
    const speechSynthesizer = new sdk.SpeechSynthesizer(speechConfig);

    speechSynthesizer.speakTextAsync(
        "I'm excited to try text to speech",
        result => {
            speechSynthesizer.close();
            return result.audioData;
        },
        error => {
            console.log(error);
            speechSynthesizer.close();
        });
}

Az eredményként ArrayBuffer kapott objektummal bármilyen egyéni viselkedést implementálhat. ArrayBuffer a böngészőben való fogadás és az ilyen formátumú lejátszások gyakori típusa.

Bármely kiszolgálóalapú kód esetében, ha streamként kell dolgoznia az adatokkal, az ArrayBuffer objektumot streamké kell alakítania:

function synthesizeSpeech() {
    const speechConfig = sdk.SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
    const speechSynthesizer = new sdk.SpeechSynthesizer(speechConfig);

    speechSynthesizer.speakTextAsync(
        "I'm excited to try text to speech",
        result => {
            const { audioData } = result;

            speechSynthesizer.close();

            // convert arrayBuffer to stream
            // return stream
            const bufferStream = new PassThrough();
            bufferStream.end(Buffer.from(audioData));
            return bufferStream;
        },
        error => {
            console.log(error);
            speechSynthesizer.close();
        });
}

Hangformátum testreszabása

Testre szabhatja a hangkimeneti attribútumokat, többek között a következőket:

  • Hangfájl típusa
  • Mintasebesség
  • Bitmélység

A hangformátum módosításához használja az speechSynthesisOutputFormat objektum tulajdonságát SpeechConfig . Ez a tulajdonság egy enum SpeechSynthesisOutputFormat típusú példányt vár. Válassza ki a enum kimeneti formátumot a listában. Az elérhető formátumokért tekintse meg a hangformátumok listáját.

A követelményektől függően különböző fájltípusok érhetők el. Definíció szerint a nyers formátumok, például Raw24Khz16BitMonoPcm nem tartalmaznak hangfejléceket. Nyers formátumokat csak az alábbi helyzetek egyikében használjon:

  • Tudja, hogy az alsóbb rétegbeli implementáció képes dekódolni egy nyers bitstreamet.
  • A fejlécek manuális összeállítását olyan tényezők alapján tervezi, mint a bitmélység, a mintasebesség és a csatornák száma.

Ez a példa az objektum beállításával speechSynthesisOutputFormatSpeechConfig adja meg a magas megbízhatóságú RIFF formátumotRiff24Khz16BitMonoPcm. Az előző szakaszban szereplő példához hasonlóan kérje le a hangadatokat ArrayBuffer , és használja azokat.

function synthesizeSpeech() {
    const speechConfig = SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");

    // Set the output format
    speechConfig.speechSynthesisOutputFormat = sdk.SpeechSynthesisOutputFormat.Riff24Khz16BitMonoPcm;

    const speechSynthesizer = new sdk.SpeechSynthesizer(speechConfig, null);
    speechSynthesizer.speakTextAsync(
        "I'm excited to try text to speech",
        result => {
            // Interact with the audio ArrayBuffer data
            const audioData = result.audioData;
            console.log(`Audio data byte size: ${audioData.byteLength}.`)

            speechSynthesizer.close();
        },
        error => {
            console.log(error);
            speechSynthesizer.close();
        });
}

Beszédjellemzők testreszabása az SSML használatával

Az SSML használatával finomhangolhatja a hangmagasságot, a kiejtést, a beszédsebességet, a hangerőt és a szöveg egyéb aspektusait a beszédkimenetre, ha a kéréseket XML-sémából küldi el. Ez a szakasz egy példát mutat be a hang módosítására. További információt a Beszédszintézis korrektúranyelv áttekintése című témakörben talál.

Az SSML testreszabáshoz való használatához egy kisebb módosítást kell végeznie, amely átváltja a hangot.

  1. Hozzon létre egy új XML-fájlt az SSML-konfigurációhoz a gyökérprojekt könyvtárában.

    <speak version="1.0" xmlns="https://www.w3.org/2001/10/synthesis" xml:lang="en-US">
      <voice name="en-US-AvaMultilingualNeural">
        When you're on the freeway, it's a good idea to use a GPS.
      </voice>
    </speak>
    

    Ebben a példában ez ssml.xml. A gyökérelem mindig <speak>. Az elem szövegének <voice> körbefuttatásával a paraméter használatával módosíthatja a name hangot. A támogatott neurális hangok teljes listájáért tekintse meg a támogatott nyelveket.

  2. Módosítsa a beszédszintézis-kérést az XML-fájlra való hivatkozáshoz. A kérés többnyire ugyanaz, de a függvény használata helyett a függvényt speakTextAsync() használja speakSsmlAsync(). Ez a függvény egy XML-sztringet vár. Hozzon létre egy függvényt egy XML-fájl betöltéséhez és sztringként való visszaadásához:

    function xmlToString(filePath) {
        const xml = readFileSync(filePath, "utf8");
        return xml;
    }
    

    További információ: readFileSyncNode.js fájlrendszer.

    Az eredményobjektum pontosan ugyanaz, mint a korábbi példák:

    function synthesizeSpeech() {
        const speechConfig = sdk.SpeechConfig.fromSubscription("YourSpeechKey", "YourSpeechRegion");
        const speechSynthesizer = new sdk.SpeechSynthesizer(speechConfig, null);
    
        const ssml = xmlToString("ssml.xml");
        speechSynthesizer.speakSsmlAsync(
            ssml,
            result => {
                if (result.errorDetails) {
                    console.error(result.errorDetails);
                } else {
                    console.log(JSON.stringify(result));
                }
    
                speechSynthesizer.close();
            },
            error => {
                console.log(error);
                speechSynthesizer.close();
            });
    }
    

Feljegyzés

Ha SSML használata nélkül szeretné módosítani a hangot, a tulajdonságot SpeechConfig a következővel SpeechConfig.speechSynthesisVoiceName = "en-US-AvaMultilingualNeural";állíthatja be: .

Feliratkozás szintetizátoreseményekre

Előfordulhat, hogy további elemzéseket szeretne a szövegről a beszédfeldolgozáshoz és az eredményekhez. Előfordulhat például, hogy tudni szeretné, hogy mikor indul el és áll le a szintetizátor, vagy érdemes lehet tudnia a szintézis során előforduló egyéb eseményekről.

Miközben a SpeechSynthesizert használja a szövegfelolvasáshoz, előfizethet a táblázatban szereplő eseményekre:

Esemény Leírás Használati eset
BookmarkReached Azt jelzi, hogy egy könyvjelző el lett érve. A könyvjelző által elért esemény aktiválásához egy bookmark elem szükséges az SSML-ben. Ez az esemény a kimeneti hangnak a szintézis kezdete és bookmark az elem közötti eltelt idejét jelenti. Az esemény tulajdonsága Text a könyvjelző mark attribútumában beállított sztringérték. Az bookmark elemek nincsenek kimondva. Az elem használatával bookmark egyéni jelölőket szúrhat be az SSML-be az egyes jelölők eltolásának lekéréséhez a hangstreamben. Az bookmark elem a szöveg vagy a címkesorozat egy adott helyére hivatkozhat.
SynthesisCanceled Azt jelzi, hogy a beszédszintézis megszakadt. Ellenőrizheti, hogy a szintézis mikor lesz megszakítva.
SynthesisCompleted Azt jelzi, hogy a beszédszintézis befejeződött. Ellenőrizheti, hogy a szintézis befejeződött-e.
SynthesisStarted Azt jelzi, hogy a beszédszintézis elindult. Ellenőrizheti, hogy mikor kezdődött el a szintézis.
Synthesizing Azt jelzi, hogy a beszédszintézis folyamatban van. Ez az esemény minden alkalommal aktiválódik, amikor az SDK hangrészletet kap a Speech szolgáltatástól. Ellenőrizheti, hogy a szintézis folyamatban van-e.
VisemeReceived Azt jelzi, hogy egy viseme esemény érkezett. A visemeket gyakran használják a megfigyelt beszéd legfontosabb pózainak ábrázolására. A fő pózok közé tartozik az ajkak, az állkapocs és a nyelv pozíciója egy adott fonál előállításában. A visemek használatával animálhatja egy karakter arcát a beszédhang lejátszása során.
WordBoundary Azt jelzi, hogy egy szóhatár érkezett. Ez az esemény minden új kimondott szó, írásjel és mondat elején jelenik meg. Az esemény az aktuális szó időeltolódását jelenti pipákban a kimeneti hang elejétől. Ez az esemény közvetlenül a kimondandó szó előtt jelenti a bemeneti szöveg vagy az SSML karakterpozícióját is. Ezt az eseményt gyakran használják a szöveg és a megfelelő hang relatív pozícióinak lekérésére. Érdemes lehet tudni egy új szóról, majd az időzítés alapján cselekedni. Például olyan információkat kaphat, amelyek segítségével eldöntheti, hogy mikor és mennyi ideig emelheti ki a szavakat a beszéd közben.

Feljegyzés

Az események akkor jönnek létre, amikor a kimeneti hangadatok elérhetővé válnak, ami gyorsabb, mint egy kimeneti eszköz lejátszása. A hívónak megfelelően szinkronizálnia kell a streamelést és a valós idejűt.

Íme egy példa, amely bemutatja, hogyan iratkozhat fel eseményekre beszédszintézis céljából. A rövid útmutató utasításait követve azonban cserélje le a SpeechSynthesis.js fájl tartalmát a következő JavaScript-kódra.

(function() {

    "use strict";

    var sdk = require("microsoft-cognitiveservices-speech-sdk");

    var audioFile = "YourAudioFile.wav";
    // This example requires environment variables named "SPEECH_KEY" and "SPEECH_REGION"
    const speechConfig = sdk.SpeechConfig.fromSubscription(process.env.SPEECH_KEY, process.env.SPEECH_REGION);
    const audioConfig = sdk.AudioConfig.fromAudioFileOutput(audioFile);

    var speechSynthesisVoiceName  = "en-US-AvaMultilingualNeural";  
    var ssml = `<speak version='1.0' xml:lang='en-US' xmlns='http://www.w3.org/2001/10/synthesis' xmlns:mstts='http://www.w3.org/2001/mstts'> \r\n \
        <voice name='${speechSynthesisVoiceName}'> \r\n \
            <mstts:viseme type='redlips_front'/> \r\n \
            The rainbow has seven colors: <bookmark mark='colors_list_begin'/>Red, orange, yellow, green, blue, indigo, and violet.<bookmark mark='colors_list_end'/>. \r\n \
        </voice> \r\n \
    </speak>`;
    
    // Required for WordBoundary event sentences.
    speechConfig.setProperty(sdk.PropertyId.SpeechServiceResponse_RequestSentenceBoundary, "true");

    // Create the speech speechSynthesizer.
    var speechSynthesizer = new sdk.SpeechSynthesizer(speechConfig, audioConfig);

    speechSynthesizer.bookmarkReached = function (s, e) {
        var str = `BookmarkReached event: \
            \r\n\tAudioOffset: ${(e.audioOffset + 5000) / 10000}ms \
            \r\n\tText: \"${e.text}\".`;
        console.log(str);
    };

    speechSynthesizer.synthesisCanceled = function (s, e) {
        console.log("SynthesisCanceled event");
    };
    
    speechSynthesizer.synthesisCompleted = function (s, e) {
        var str = `SynthesisCompleted event: \
                    \r\n\tAudioData: ${e.result.audioData.byteLength} bytes \
                    \r\n\tAudioDuration: ${e.result.audioDuration}`;
        console.log(str);
    };

    speechSynthesizer.synthesisStarted = function (s, e) {
        console.log("SynthesisStarted event");
    };

    speechSynthesizer.synthesizing = function (s, e) {
        var str = `Synthesizing event: \
            \r\n\tAudioData: ${e.result.audioData.byteLength} bytes`;
        console.log(str);
    };
    
    speechSynthesizer.visemeReceived = function(s, e) {
        var str = `VisemeReceived event: \
            \r\n\tAudioOffset: ${(e.audioOffset + 5000) / 10000}ms \
            \r\n\tVisemeId: ${e.visemeId}`;
        console.log(str);
    };

    speechSynthesizer.wordBoundary = function (s, e) {
        // Word, Punctuation, or Sentence
        var str = `WordBoundary event: \
            \r\n\tBoundaryType: ${e.boundaryType} \
            \r\n\tAudioOffset: ${(e.audioOffset + 5000) / 10000}ms \
            \r\n\tDuration: ${e.duration} \
            \r\n\tText: \"${e.text}\" \
            \r\n\tTextOffset: ${e.textOffset} \
            \r\n\tWordLength: ${e.wordLength}`;
        console.log(str);
    };

    // Synthesize the SSML
    console.log(`SSML to synthesize: \r\n ${ssml}`)
    console.log(`Synthesize to: ${audioFile}`);
    speechSynthesizer.speakSsmlAsync(ssml,
        function (result) {
      if (result.reason === sdk.ResultReason.SynthesizingAudioCompleted) {
        console.log("SynthesizingAudioCompleted result");
      } else {
        console.error("Speech synthesis canceled, " + result.errorDetails +
            "\nDid you set the speech resource key and region values?");
      }
      speechSynthesizer.close();
      speechSynthesizer = null;
    },
        function (err) {
      console.trace("err - " + err);
      speechSynthesizer.close();
      speechSynthesizer = null;
    });
}());

A GitHubon további szövegfelolvasási mintákat találhat.

Tároló futtatása és használata

A Speech-tárolók websocket-alapú lekérdezésvégpont API-kat biztosítanak, amelyek a Speech SDK-n és a Speech CLI-n keresztül érhetők el. Alapértelmezés szerint a Speech SDK és a Speech CLI a nyilvános Speech szolgáltatást használja. A tároló használatához módosítania kell az inicializálási módszert. Kulcs és régió helyett használjon tároló gazdagép URL-címét.

További információ a tárolókról: Speech-tárolók telepítése és futtatása a Dockerrel.

Referenciadokumentáció csomag (Letöltés) | További minták a GitHubon |

Ebben az útmutatóban megismerheti a szöveg beszédszintézishez való használatának gyakori tervezési mintáit.

További információ a következő területekről: Mi az a beszédszöveg?

  • Válaszok lekérése memóriabeli streamekként.
  • A kimeneti mintasebesség és a bitsebesség testreszabása.
  • Szintéziskérések beküldése a Speech Synthesis Markup Language (SSML) használatával.
  • Neurális hangok használata.
  • Feliratkozás eseményekre, és az eredményekre való cselekvés.

Előfeltételek

A Speech SDK és a minták telepítése

Az Azure-Samples/cognitive-services-speech-sdk adattár iOS és Mac rendszerhez készült Objective-C nyelven írt mintákat tartalmaz. Kattintson egy hivatkozásra az egyes minták telepítési utasításainak megtekintéséhez:

Egyéni végpont használata

Az egyéni végpont funkcionálisan megegyezik a szövegfelolvasási kérelmekhez használt szabványos végpontokkal.

Az egyik különbség az, hogy meg kell adni az EndpointId egyéni hang használatát a Speech SDK-val. A szöveggel kezdheti a beszéd gyorsútmutatóját , majd frissítheti a kódot a EndpointId következővel: és SpeechSynthesisVoiceName.

SPXSpeechConfiguration *speechConfig = [[SPXSpeechConfiguration alloc] initWithSubscription:speechKey region:speechRegion];
speechConfig.speechSynthesisVoiceName = @"YourCustomVoiceName";
speechConfig.EndpointId = @"YourEndpointId";

Ha egyéni hangot szeretne használni a Speech Synthesis Markup Language (SSML) használatával, adja meg a modell nevét hangnévként. Ez a példa a YourCustomVoiceName hangot használja.

<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="en-US">
    <voice name="YourCustomVoiceName">
        This is the text that is spoken. 
    </voice>
</speak>

Tároló futtatása és használata

A Speech-tárolók websocket-alapú lekérdezésvégpont API-kat biztosítanak, amelyek a Speech SDK-n és a Speech CLI-n keresztül érhetők el. Alapértelmezés szerint a Speech SDK és a Speech CLI a nyilvános Speech szolgáltatást használja. A tároló használatához módosítania kell az inicializálási módszert. Kulcs és régió helyett használjon tároló gazdagép URL-címét.

További információ a tárolókról: Speech-tárolók telepítése és futtatása a Dockerrel.

Referenciadokumentáció csomag (Letöltés) | További minták a GitHubon |

Ebben az útmutatóban megismerheti a szöveg beszédszintézishez való használatának gyakori tervezési mintáit.

További információ a következő területekről: Mi az a beszédszöveg?

  • Válaszok lekérése memóriabeli streamekként.
  • A kimeneti mintasebesség és a bitsebesség testreszabása.
  • Szintéziskérések beküldése a Speech Synthesis Markup Language (SSML) használatával.
  • Neurális hangok használata.
  • Feliratkozás eseményekre, és az eredményekre való cselekvés.

Előfeltételek

A Speech SDK és a minták telepítése

Az Azure-Samples/cognitive-services-speech-sdk adattár az iOS-hez és Machez készült Swiftben írt mintákat tartalmazza. Kattintson egy hivatkozásra az egyes minták telepítési utasításainak megtekintéséhez:

Tároló futtatása és használata

A Speech-tárolók websocket-alapú lekérdezésvégpont API-kat biztosítanak, amelyek a Speech SDK-n és a Speech CLI-n keresztül érhetők el. Alapértelmezés szerint a Speech SDK és a Speech CLI a nyilvános Speech szolgáltatást használja. A tároló használatához módosítania kell az inicializálási módszert. Kulcs és régió helyett használjon tároló gazdagép URL-címét.

További információ a tárolókról: Speech-tárolók telepítése és futtatása a Dockerrel.

Referenciadokumentáció-csomag (PyPi) | További minták a GitHubon |

Ebben az útmutatóban megismerheti a szöveg beszédszintézishez való használatának gyakori tervezési mintáit.

További információ a következő területekről: Mi az a beszédszöveg?

  • Válaszok lekérése memóriabeli streamekként.
  • A kimeneti mintasebesség és a bitsebesség testreszabása.
  • Szintéziskérések beküldése a Speech Synthesis Markup Language (SSML) használatával.
  • Neurális hangok használata.
  • Feliratkozás eseményekre, és az eredményekre való cselekvés.

A szintézis nyelvének és hangának kiválasztása

A Speech szolgáltatás szövegfelolvasási funkciója több mint 400 hangot és több mint 140 nyelvet és változatot támogat. Lekérheti a teljes listát , vagy kipróbálhatja őket a Hangtárban.

Adja meg a bemeneti szövegnek megfelelő nyelvet vagy hangot SpeechConfig , és használja a megadott hangot:

# Set either the `SpeechSynthesisVoiceName` or `SpeechSynthesisLanguage`.
speech_config.speech_synthesis_language = "en-US" 
speech_config.speech_synthesis_voice_name ="en-US-AvaMultilingualNeural"

Minden neurális hang többnyelvű és folyékony a saját nyelvén és angolul. Ha például az angol nyelvű beviteli szöveg a következő: "Izgatottan várom, hogy kipróbálhassam a szöveget a beszédhez", és ön kiválasztja es-ES-ElviraNeural, a szöveg angol nyelven, spanyol akcentussal szólal meg.

Ha a hang nem beszéli a bemeneti szöveg nyelvét, a Speech szolgáltatás nem hoz létre szintetizált hangot. A támogatott neurális hangok teljes listájáért tekintse meg a Speech szolgáltatás nyelv- és hangtámogatását.

Feljegyzés

Az alapértelmezett hang az első hang, amelyet területi beállításonként a Voice List API-ból ad vissza.

A beszélő hang prioritási sorrendben van meghatározva az alábbiak szerint:

  • Ha nem állítja be SpeechSynthesisVoiceName , vagy SpeechSynthesisLanguageaz alapértelmezett beszédhang en-US .
  • Ha csak be van állítva SpeechSynthesisLanguage, a megadott területi beállítás alapértelmezett hangja beszél.
  • Ha mindkettő SpeechSynthesisVoiceNameSpeechSynthesisLanguage be van állítva, a SpeechSynthesisLanguage beállítás figyelmen kívül lesz hagyva. A beszéd használatával SpeechSynthesisVoiceName megadott hang.
  • Ha a hangelem a Beszédszintézis korrektúranyelv (SSML) használatával van beállítva, a rendszer figyelmen kívül hagyja a beállításokat és SpeechSynthesisLanguage a SpeechSynthesisVoiceName beállításokat.

Beszédszintézis fájlba

SpeechSynthesizer objektum létrehozása. Ez az objektum szöveget futtat beszédkonvertálások és kimenetek hangszórókra, fájlokra vagy más kimeneti streamekre. SpeechSynthesizer a következő paramétereket fogadja el:

  • Az SpeechConfig előző lépésben létrehozott objektum.
  • Egy AudioOutputConfig objektum, amely meghatározza, hogyan kell kezelni a kimeneti eredményeket.
  1. Hozzon létre egy példánytAudioOutputConfig, amely automatikusan egy .wav fájlba írja a kimenetet a filename konstruktorparaméter használatával:

    audio_config = speechsdk.audio.AudioOutputConfig(filename="path/to/write/file.wav")
    
  2. Példányosítás SpeechSynthesizer az objektum és az audio_config objektum paraméterként való speech_config átadásával. A beszéd szintetizálásához és egy fájlba való íráshoz futtasson speak_text_async() egy szöveges sztringet.

    speech_synthesizer = speechsdk.SpeechSynthesizer(speech_config=speech_config, audio_config=audio_config)
    speech_synthesizer.speak_text_async("I'm excited to try text to speech")
    

A program futtatásakor létrehoz egy szintetizált .wav fájlt, amelyet a program a megadott helyre ír. Ez az eredmény jó példa a legalapvetőbb használatra. Ezután testre szabhatja a kimenetet, és memóriabeli streamként kezelheti a kimeneti választ az egyéni forgatókönyvek kezeléséhez.

Szintetizálás előadói kimenetre

Ha szintetizált beszédet szeretne kiállítani az aktuális aktív kimeneti eszközre, például egy hangszóróra, állítsa be a use_default_speaker paramétert a AudioOutputConfig példány létrehozásakor. Példa:

audio_config = speechsdk.audio.AudioOutputConfig(use_default_speaker=True)

Eredmény lekérése memórián belüli streamként

Az eredményül kapott hangadatokat használhatja memórián belüli streamként ahelyett, hogy közvetlenül egy fájlba írnál. A memórián belüli adatfolyammal egyéni viselkedést hozhat létre:

  • Az eredményként kapott bájttömb absztrakciója kereshető streamként egyéni alárendelt szolgáltatásokhoz.
  • Integrálja az eredményt más API-kkal vagy szolgáltatásokkal.
  • Módosítsa a hangadatokat, írjon egyéni .wav fejléceket, és végezze el a kapcsolódó feladatokat.

Ezt a módosítást az előző példára módosíthatja. Először távolítsa el AudioConfig, mert a nagyobb vezérlés érdekében manuálisan kezeli a kimeneti viselkedést ettől a ponttól kezdve. Pass None for AudioConfig a SpeechSynthesizer konstruktorban.

Feljegyzés

NoneAudioConfigA továbbítás – ahelyett, hogy kihagyta volna az előző előadói kimeneti példában – nem játssza le alapértelmezés szerint a hangot az aktuális aktív kimeneti eszközön.

Mentse az eredményt egy változóba SpeechSynthesisResult . A audio_data tulajdonság a kimeneti adatok objektumát bytes tartalmazza. Ezt az objektumot manuálisan is használhatja, vagy használhatja az AudioDataStream osztályt a memóriabeli stream kezeléséhez.

Ebben a példában a AudioDataStream konstruktor használatával kérje le a streamet az eredményből:

speech_synthesizer = speechsdk.SpeechSynthesizer(speech_config=speech_config, audio_config=None)
result = speech_synthesizer.speak_text_async("I'm excited to try text to speech").get()
stream = AudioDataStream(result)

Ezen a ponton bármilyen egyéni viselkedést implementálhat az eredményként kapott stream objektum használatával.

Hangformátum testreszabása

Testre szabhatja a hangkimeneti attribútumokat, többek között a következőket:

  • Hangfájl típusa
  • Mintasebesség
  • Bitmélység

A hangformátum módosításához használja az set_speech_synthesis_output_format() objektum függvényét SpeechConfig . Ez a függvény egy enum SpeechSynthesisOutputFormat típusú példányt vár. Válassza ki a enum kimeneti formátumot a listában. Az elérhető formátumokért tekintse meg a hangformátumok listáját.

A követelményektől függően különböző fájltípusok érhetők el. Definíció szerint a nyers formátumok, például Raw24Khz16BitMonoPcm nem tartalmaznak hangfejléceket. Nyers formátumokat csak az alábbi helyzetek egyikében használjon:

  • Tudja, hogy az alsóbb rétegbeli implementáció képes dekódolni egy nyers bitstreamet.
  • A fejlécek manuális összeállítását olyan tényezők alapján tervezi, mint a bitmélység, a mintasebesség és a csatornák száma.

Ez a példa az objektum beállításával SpeechSynthesisOutputFormatSpeechConfig adja meg a magas megbízhatóságú RIFF formátumotRiff24Khz16BitMonoPcm. Az előző szakaszban szereplő példához hasonlóan az eredmény memórián belüli adatfolyamát is AudioDataStream lekérheti, majd egy fájlba írhatja.

speech_config.set_speech_synthesis_output_format(speechsdk.SpeechSynthesisOutputFormat.Riff24Khz16BitMonoPcm)
speech_synthesizer = speechsdk.SpeechSynthesizer(speech_config=speech_config, audio_config=None)

result = speech_synthesizer.speak_text_async("I'm excited to try text to speech").get()
stream = speechsdk.AudioDataStream(result)
stream.save_to_wav_file("path/to/write/file.wav")

A program futtatásakor egy .wav fájlt ír a megadott elérési útra.

Beszédjellemzők testreszabása az SSML használatával

Az SSML használatával finomhangolhatja a hangmagasságot, a kiejtést, a beszédsebességet, a hangerőt és a szöveg egyéb aspektusait a beszédkimenetre, ha a kéréseket XML-sémából küldi el. Ez a szakasz egy példát mutat be a hang módosítására. További információt a Beszédszintézis korrektúranyelv áttekintése című témakörben talál.

Ha az SSML-t szeretné használni a testreszabáshoz, hozzon létre egy kisebb módosítást, amely átváltja a hangot.

  1. Hozzon létre egy új XML-fájlt az SSML-konfigurációhoz a gyökérprojekt könyvtárában.

    <speak version="1.0" xmlns="https://www.w3.org/2001/10/synthesis" xml:lang="en-US">
      <voice name="en-US-AvaMultilingualNeural">
        When you're on the freeway, it's a good idea to use a GPS.
      </voice>
    </speak>
    

    Ebben a példában a fájl ssml.xml. A gyökérelem mindig <speak>. Az elem szövegének <voice> körbefuttatásával a paraméter használatával módosíthatja a name hangot. A támogatott neurális hangok teljes listájáért tekintse meg a támogatott nyelveket.

  2. Módosítsa a beszédszintézis-kérést az XML-fájlra való hivatkozáshoz. A kérés többnyire ugyanaz. A függvény használata helyett használja speak_ssml_async()a speak_text_async() . Ez a függvény egy XML-sztringet vár. Először olvassa el sztringként az SSML-konfigurációt. Ettől a ponttól kezdve az eredményobjektum pontosan ugyanaz, mint az előző példák.

    Feljegyzés

    Ha a ssml_string sztring elején található  , le kell vennie a BOM formátumot, vagy a szolgáltatás hibát fog visszaadni. Ezt úgy teheti meg, hogy a paramétert a encoding következőképpen állítja be: open("ssml.xml", "r", encoding="utf-8-sig").

    speech_synthesizer = speechsdk.SpeechSynthesizer(speech_config=speech_config, audio_config=None)
    
    ssml_string = open("ssml.xml", "r").read()
    result = speech_synthesizer.speak_ssml_async(ssml_string).get()
    
    stream = speechsdk.AudioDataStream(result)
    stream.save_to_wav_file("path/to/write/file.wav")
    

Feljegyzés

Ha SSML használata nélkül szeretné módosítani a hangot, a tulajdonságot SpeechConfig a következővel speech_config.speech_synthesis_voice_name = "en-US-AvaMultilingualNeural"állíthatja be: .

Feliratkozás szintetizátoreseményekre

Előfordulhat, hogy további elemzéseket szeretne a szövegről a beszédfeldolgozáshoz és az eredményekhez. Előfordulhat például, hogy tudni szeretné, hogy mikor indul el és áll le a szintetizátor, vagy érdemes lehet tudnia a szintézis során előforduló egyéb eseményekről.

Miközben a SpeechSynthesizert használja a szövegfelolvasáshoz, előfizethet a táblázatban szereplő eseményekre:

Esemény Leírás Használati eset
BookmarkReached Azt jelzi, hogy egy könyvjelző el lett érve. A könyvjelző által elért esemény aktiválásához egy bookmark elem szükséges az SSML-ben. Ez az esemény a kimeneti hangnak a szintézis kezdete és bookmark az elem közötti eltelt idejét jelenti. Az esemény tulajdonsága Text a könyvjelző mark attribútumában beállított sztringérték. Az bookmark elemek nincsenek kimondva. Az elem használatával bookmark egyéni jelölőket szúrhat be az SSML-be az egyes jelölők eltolásának lekéréséhez a hangstreamben. Az bookmark elem a szöveg vagy a címkesorozat egy adott helyére hivatkozhat.
SynthesisCanceled Azt jelzi, hogy a beszédszintézis megszakadt. Ellenőrizheti, hogy a szintézis mikor lesz megszakítva.
SynthesisCompleted Azt jelzi, hogy a beszédszintézis befejeződött. Ellenőrizheti, hogy a szintézis befejeződött-e.
SynthesisStarted Azt jelzi, hogy a beszédszintézis elindult. Ellenőrizheti, hogy mikor kezdődött el a szintézis.
Synthesizing Azt jelzi, hogy a beszédszintézis folyamatban van. Ez az esemény minden alkalommal aktiválódik, amikor az SDK hangrészletet kap a Speech szolgáltatástól. Ellenőrizheti, hogy a szintézis folyamatban van-e.
VisemeReceived Azt jelzi, hogy egy viseme esemény érkezett. A visemeket gyakran használják a megfigyelt beszéd legfontosabb pózainak ábrázolására. A fő pózok közé tartozik az ajkak, az állkapocs és a nyelv pozíciója egy adott fonál előállításában. A visemek használatával animálhatja egy karakter arcát a beszédhang lejátszása során.
WordBoundary Azt jelzi, hogy egy szóhatár érkezett. Ez az esemény minden új kimondott szó, írásjel és mondat elején jelenik meg. Az esemény az aktuális szó időeltolódását jelenti pipákban a kimeneti hang elejétől. Ez az esemény közvetlenül a kimondandó szó előtt jelenti a bemeneti szöveg vagy az SSML karakterpozícióját is. Ezt az eseményt gyakran használják a szöveg és a megfelelő hang relatív pozícióinak lekérésére. Érdemes lehet tudni egy új szóról, majd az időzítés alapján cselekedni. Például olyan információkat kaphat, amelyek segítségével eldöntheti, hogy mikor és mennyi ideig emelheti ki a szavakat a beszéd közben.

Feljegyzés

Az események akkor jönnek létre, amikor a kimeneti hangadatok elérhetővé válnak, ami gyorsabb, mint egy kimeneti eszköz lejátszása. A hívónak megfelelően szinkronizálnia kell a streamelést és a valós idejűt.

Íme egy példa, amely bemutatja, hogyan iratkozhat fel eseményekre beszédszintézis céljából. Kövesse a rövid útmutató utasításait, de cserélje le a speech-synthesis.py fájl tartalmát a következő Python-kódra:

import os
import azure.cognitiveservices.speech as speechsdk

def speech_synthesizer_bookmark_reached_cb(evt: speechsdk.SessionEventArgs):
    print('BookmarkReached event:')
    print('\tAudioOffset: {}ms'.format((evt.audio_offset + 5000) / 10000))
    print('\tText: {}'.format(evt.text))

def speech_synthesizer_synthesis_canceled_cb(evt: speechsdk.SessionEventArgs):
    print('SynthesisCanceled event')

def speech_synthesizer_synthesis_completed_cb(evt: speechsdk.SessionEventArgs):
    print('SynthesisCompleted event:')
    print('\tAudioData: {} bytes'.format(len(evt.result.audio_data)))
    print('\tAudioDuration: {}'.format(evt.result.audio_duration))

def speech_synthesizer_synthesis_started_cb(evt: speechsdk.SessionEventArgs):
    print('SynthesisStarted event')

def speech_synthesizer_synthesizing_cb(evt: speechsdk.SessionEventArgs):
    print('Synthesizing event:')
    print('\tAudioData: {} bytes'.format(len(evt.result.audio_data)))

def speech_synthesizer_viseme_received_cb(evt: speechsdk.SessionEventArgs):
    print('VisemeReceived event:')
    print('\tAudioOffset: {}ms'.format((evt.audio_offset + 5000) / 10000))
    print('\tVisemeId: {}'.format(evt.viseme_id))

def speech_synthesizer_word_boundary_cb(evt: speechsdk.SessionEventArgs):
    print('WordBoundary event:')
    print('\tBoundaryType: {}'.format(evt.boundary_type))
    print('\tAudioOffset: {}ms'.format((evt.audio_offset + 5000) / 10000))
    print('\tDuration: {}'.format(evt.duration))
    print('\tText: {}'.format(evt.text))
    print('\tTextOffset: {}'.format(evt.text_offset))
    print('\tWordLength: {}'.format(evt.word_length))

# This example requires environment variables named "SPEECH_KEY" and "SPEECH_REGION"
speech_config = speechsdk.SpeechConfig(subscription=os.environ.get('SPEECH_KEY'), region=os.environ.get('SPEECH_REGION'))

# Required for WordBoundary event sentences.
speech_config.set_property(property_id=speechsdk.PropertyId.SpeechServiceResponse_RequestSentenceBoundary, value='true')

audio_config = speechsdk.audio.AudioOutputConfig(use_default_speaker=True)
speech_synthesizer = speechsdk.SpeechSynthesizer(speech_config=speech_config, audio_config=audio_config)

# Subscribe to events
speech_synthesizer.bookmark_reached.connect(speech_synthesizer_bookmark_reached_cb)
speech_synthesizer.synthesis_canceled.connect(speech_synthesizer_synthesis_canceled_cb)
speech_synthesizer.synthesis_completed.connect(speech_synthesizer_synthesis_completed_cb)
speech_synthesizer.synthesis_started.connect(speech_synthesizer_synthesis_started_cb)
speech_synthesizer.synthesizing.connect(speech_synthesizer_synthesizing_cb)
speech_synthesizer.viseme_received.connect(speech_synthesizer_viseme_received_cb)
speech_synthesizer.synthesis_word_boundary.connect(speech_synthesizer_word_boundary_cb)

# The language of the voice that speaks.
speech_synthesis_voice_name='en-US-AvaMultilingualNeural'

ssml = """<speak version='1.0' xml:lang='en-US' xmlns='http://www.w3.org/2001/10/synthesis' xmlns:mstts='http://www.w3.org/2001/mstts'>
    <voice name='{}'>
        <mstts:viseme type='redlips_front'/>
        The rainbow has seven colors: <bookmark mark='colors_list_begin'/>Red, orange, yellow, green, blue, indigo, and violet.<bookmark mark='colors_list_end'/>.
    </voice>
</speak>""".format(speech_synthesis_voice_name)

# Synthesize the SSML
print("SSML to synthesize: \r\n{}".format(ssml))
speech_synthesis_result = speech_synthesizer.speak_ssml_async(ssml).get()

if speech_synthesis_result.reason == speechsdk.ResultReason.SynthesizingAudioCompleted:
    print("SynthesizingAudioCompleted result")
elif speech_synthesis_result.reason == speechsdk.ResultReason.Canceled:
    cancellation_details = speech_synthesis_result.cancellation_details
    print("Speech synthesis canceled: {}".format(cancellation_details.reason))
    if cancellation_details.reason == speechsdk.CancellationReason.Error:
        if cancellation_details.error_details:
            print("Error details: {}".format(cancellation_details.error_details))
            print("Did you set the speech resource key and region values?")

A GitHubon további szövegfelolvasási mintákat találhat.

Egyéni végpont használata

Az egyéni végpont funkcionálisan megegyezik a szövegfelolvasási kérelmekhez használt szabványos végpontokkal.

Az egyik különbség az, hogy meg kell adni az endpoint_id egyéni hang használatát a Speech SDK-val. A szöveggel kezdheti a beszéd gyorsútmutatóját , majd frissítheti a kódot a endpoint_id következővel: és speech_synthesis_voice_name.

speech_config = speechsdk.SpeechConfig(subscription=os.environ.get('SPEECH_KEY'), region=os.environ.get('SPEECH_REGION'))
speech_config.endpoint_id = "YourEndpointId"
speech_config.speech_synthesis_voice_name = "YourCustomVoiceName"

Ha egyéni hangot szeretne használni a Speech Synthesis Markup Language (SSML) használatával, adja meg a modell nevét hangnévként. Ez a példa a YourCustomVoiceName hangot használja.

<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="en-US">
    <voice name="YourCustomVoiceName">
        This is the text that is spoken. 
    </voice>
</speak>

Tároló futtatása és használata

A Speech-tárolók websocket-alapú lekérdezésvégpont API-kat biztosítanak, amelyek a Speech SDK-n és a Speech CLI-n keresztül érhetők el. Alapértelmezés szerint a Speech SDK és a Speech CLI a nyilvános Speech szolgáltatást használja. A tároló használatához módosítania kell az inicializálási módszert. Kulcs és régió helyett használjon tároló gazdagép URL-címét.

További információ a tárolókról: Speech-tárolók telepítése és futtatása a Dockerrel.

Speech to text REST API reference | Speech to text REST API for short audio reference | Additional Samples on GitHub

Ebben az útmutatóban megismerheti a szöveg beszédszintézishez való használatának gyakori tervezési mintáit.

További információ a következő területekről: Mi az a beszédszöveg?

  • Válaszok lekérése memóriabeli streamekként.
  • A kimeneti mintasebesség és a bitsebesség testreszabása.
  • Szintéziskérések beküldése a Speech Synthesis Markup Language (SSML) használatával.
  • Neurális hangok használata.
  • Feliratkozás eseményekre, és az eredményekre való cselekvés.

Előfeltételek

Szöveg átalakítása beszédté

Futtassa a következő parancsot egy parancssorban. Szúrja be ezeket az értékeket a parancsba:

  • A Speech erőforráskulcsa
  • A Speech erőforrásrégió

A következő értékeket is módosíthatja:

  • A X-Microsoft-OutputFormat hangkimenet formátumát vezérlő fejlécérték. A rest API-referenciaszövegben megtalálható a támogatott hangkimeneti formátumok listája.
  • A kimeneti hang. A Beszédszolgáltatás végpontjához elérhető hangok listájának lekéréséhez tekintse meg a Voice List API-t.
  • A kimeneti fájl. Ebben a példában a kiszolgáló válaszát egy nevesített output.mp3fájlba irányítjuk.
curl --location --request POST 'https://YOUR_RESOURCE_REGION.tts.speech.microsoft.com/cognitiveservices/v1' \
--header 'Ocp-Apim-Subscription-Key: YOUR_RESOURCE_KEY' \
--header 'Content-Type: application/ssml+xml' \
--header 'X-Microsoft-OutputFormat: audio-16khz-128kbitrate-mono-mp3' \
--header 'User-Agent: curl' \
--data-raw '<speak version='\''1.0'\'' xml:lang='\''en-US'\''>
    <voice name='\''en-US-AvaMultilingualNeural'\''>
        I am excited to try text to speech
    </voice>
</speak>' > output.mp3

Ebben az útmutatóban megismerheti a szöveg beszédszintézishez való használatának gyakori tervezési mintáit.

További információ a következő területekről: Mi az a beszédszöveg?

  • Válaszok lekérése memóriabeli streamekként.
  • A kimeneti mintasebesség és a bitsebesség testreszabása.
  • Szintéziskérések beküldése a Speech Synthesis Markup Language (SSML) használatával.
  • Neurális hangok használata.
  • Feliratkozás eseményekre, és az eredményekre való cselekvés.

Előfeltételek

Letöltés és telepítés

Kövesse ezeket a lépéseket, és tekintse meg a Speech CLI rövid útmutatóját a platform egyéb követelményeiről.

  1. Futtassa a következő .NET CLI-parancsot a Speech CLI telepítéséhez:

    dotnet tool install --global Microsoft.CognitiveServices.Speech.CLI
    
  2. Futtassa az alábbi parancsokat a Speech-erőforráskulcs és -régió konfigurálásához. Cserélje le SUBSCRIPTION-KEY a Speech erőforráskulcsot, és cserélje le REGION a Speech erőforrásrégiójára.

    spx config @key --set SUBSCRIPTION-KEY
    spx config @region --set REGION
    

Beszédszintézis hangszóróra

Most már készen áll a Speech CLI futtatására a beszéd szövegből való szintetizálásához.

  • A konzolablakban váltson a Speech CLI bináris fájlt tartalmazó könyvtárra. Ezt követően futtassa a következő parancsot:

    spx synthesize --text "I'm excited to try text to speech"
    

A Speech CLI természetes nyelvet állít elő angolul a számítógép hangszórója segítségével.

Beszédszintézis fájlba

  • Futtassa a következő parancsot a hangszóró kimenetének .wav fájlra való módosításához:

    spx synthesize --text "I'm excited to try text to speech" --audio output greetings.wav
    

A Speech CLI természetes nyelvet állít elő angolul a greetings.wav hangfájlba.

Tároló futtatása és használata

A Speech-tárolók websocket-alapú lekérdezésvégpont API-kat biztosítanak, amelyek a Speech SDK-n és a Speech CLI-n keresztül érhetők el. Alapértelmezés szerint a Speech SDK és a Speech CLI a nyilvános Speech szolgáltatást használja. A tároló használatához módosítania kell az inicializálási módszert. Kulcs és régió helyett használjon tároló gazdagép URL-címét.

További információ a tárolókról: Speech-tárolók telepítése és futtatása a Dockerrel.

Következő lépések