2010-05-07 10 views
5

Ho cercato di capire come "parlare" un testo in un buffer di memoria utilizzando Windows SAPI 5.1 ma fino ad ora non ha avuto successo, anche se sembra che dovrebbe essere abbastanza semplice.C++ Microsoft SAPI: come impostare l'output text-to-text di Windows su un buffer di memoria?

C'è an example di streaming del parlato sintetizzato in un file .wav, ma nessun esempio di come eseguire il flusso in un buffer di memoria.

Alla fine ho bisogno di avere il parlato sintetizzato in un array char * in formato PCM little-endian 16 kHz 16-bit. Attualmente creo un file .wav temporaneo, rediretto l'output vocale lì, quindi lo leggo, ma sembra essere una soluzione piuttosto stupida.

Qualcuno sa come farlo?

Grazie!

+0

hai fatto a farlo? – Yashasvi

risposta

0

Sai come creare un file mappato in memoria? Si potrebbe vedere se il ISpStream si legherà ad esso.

6

Vedere ISpStream :: SetBaseStream. Ecco un piccolo aiuto:

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, Come si può scoprire la dimensione necessaria per la chiamata GlobalAlloc per ottenere l'handle di memoria HGLOBAL? Immagino che cambierà a seconda di quanto discorso si parla, ma come puoi scoprirlo? –

+0

Non è necessario. Lo stream di memoria gestito da :: CreateStreamOnHGlobal rialloca la memoria secondo necessità. –

+0

Ho usato questo esempio come base per la mia implementazione del parlato in streaming su un buffer. Ma leggendo dall'oggetto IStream ottengo sempre zero byte letti. Guardando l'oggetto stream, sono stati scritti dei byte (usando Stream :: Stat). Devo usare IStream :: LockRegion per ottenere i dati? – pettersson

1

L'ho realizzato utilizzando l'ISpStream. Utilizzare la funzione Setbasestream di ispstream per collegarlo a un istream e quindi impostare l'output di ispvoice su ispstream.

Qui è la mia soluzione di lavoro se qualcuno lo vuole:

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

Problemi correlati