2010-05-07 10 views
5

J'ai essayé de comprendre comment "parler" un texte dans un tampon de mémoire en utilisant Windows SAPI 5.1 mais jusqu'à présent, pas de succès, même si cela semble assez simple.C++ Microsoft SAPI: Comment définir la sortie de la synthèse vocale Windows dans un tampon mémoire?

Il existe an example de diffuser le discours synthétisé dans un fichier .wav, mais aucun exemple de la façon de le diffuser dans un tampon mémoire. En fin de compte, j'ai besoin d'avoir la parole synthétisée dans un tableau char * en format PCM 16 bits 16 kHz little-endian. Actuellement, je crée un fichier .wav temp, redirige la sortie de la parole là-bas, puis le lire, mais il semble être une solution plutôt stupide.

Quelqu'un sait comment faire cela?

Merci!

+0

avez-vous réussi à le faire? – Yashasvi

Répondre

0

Savez-vous comment créer un fichier mappé en mémoire? Vous pouvez voir si le ISpStream va s'y lier.

6

Regardez ISpStream :: SetBaseStream. Voici un petit assistant:

inline HRESULT SPCreateStreamOnHGlobal(
        HGLOBAL hGlobal,   //Memory handle for the stream object 
        BOOL fDeleteOnRelease,  //Whether to free memory when the object is released 
        const WAVEFORMATEX * pwfex, //WaveFormatEx for stream 
        ISpStream ** ppStream)  //Address of variable to receive ISpStream pointer 
{ 
    HRESULT hr; 
    IStream * pMemStream; 
    *ppStream = NULL; 
    hr = ::CreateStreamOnHGlobal(hGlobal, fDeleteOnRelease, &pMemStream); 
    if (SUCCEEDED(hr)) 
    { 
     hr = ::CoCreateInstance(CLSID_SpStream, NULL, CLSCTX_ALL, __uuidof(*ppStream), (void **)ppStream); 
     if (SUCCEEDED(hr)) 
     { 
      hr = (*ppStream)->SetBaseStream(pMemStream, SPDFID_WaveFormatEx, pwfex); 
      if (FAILED(hr)) 
      { 
       (*ppStream)->Release(); 
       *ppStream = NULL; 
      } 
     } 
     pMemStream->Release(); 
    } 
    return hr; 
} 
+0

Eric, Comment pouvez-vous trouver la taille dont vous avez besoin pour l'appel GlobalAlloc pour obtenir le handle de mémoire HGLOBAL? Je suppose que cela varie en fonction de la quantité de discours parlé, mais comment pouvez-vous le savoir? –

+0

Vous n'en avez pas besoin. Le flux de mémoire géré par :: CreateStreamOnHGlobal réattribue la mémoire si nécessaire. –

+0

J'ai utilisé cet exemple comme base pour ma mise en œuvre de la parole en continu dans un tampon. Mais lors de la lecture de l'objet IStream, je reçois toujours zéro octets lus. En regardant l'objet stream, il y avait des octets écrits (en utilisant Stream :: Stat). Dois-je utiliser IStream :: LockRegion pour obtenir les données? – pettersson

1

Je l'ai accompli en utilisant le ISpStream. Utilisez la fonction Setbasestream de l'ispstream pour le lier à un istream, puis définissez la sortie de ispvoice sur ispstream.

Voici ma solution de travail si quelqu'un veut:

https://github.com/itsyash/MS-SAPI-demo