[C++] Reading from an IStream to a Buffer (Audio)
-
Wednesday, March 13, 2013 6:15 AM
I am basically trying to read the contents of an audio stream into a char * buffer to apply an FFT. I am using SAPI to simplify the transformations I will need to make after applying my FFT.
I have an IStream buffer I allocated on HGLOBAL
// Address of IStream* pointer variable that receives the interface pointer to the new stream object. CComPtr<IStream> pMemStream; // A memory handle allocated by the GlobalAlloc function, or if NULL a new handle is to be allocated instead. HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, sizeof(pMemStream)); // Create stream object that uses an HGLOBAL memory handle to store the stream contents. hr = ::CreateStreamOnHGlobal(hGlobal, TRUE, &pMemStream);
I then wrote wav contents to this stream
// Variable to receive ISpStream pointer CComPtr<ISpStream> cpSpStream; hr = cpSpStream.CoCreateInstance(CLSID_SpStream); hr = cpSpStream->SetBaseStream(pMemStream, SPDFID_WaveFormatEx, defaultStreamFormat.WaveFormatExPtr()); hr = cpVoice->SetOutput(cpSpStream, TRUE); hr = cpVoice->Speak(L"This is a phrase.", SPF_DEFAULT, NULL);
I can verify that the stream contains the wav contents by speaking the stream:
// Speak the modified stream. cpVoice->SetOutput(NULL, FALSE); cpVoice->SpeakStream(cpSpStream, SPF_DEFAULT, NULL);
However, when I try and get the buffer for the stream, I read only garbage data (all '=' in buffer).
IStream *pIstream; cpSpStream->GetBaseStream(&pIstream); STATSTG stats; pIstream->Stat(&stats, STATFLAG_NONAME); ULONG sSize = stats.cbSize.QuadPart; ULONG bytesRead; char *pBuffer = new char[sSize]; pIstream->Read(pBuffer, sSize, &bytesRead);
What am I doing wrong? This is driving me nuts.
Thanks,
-Francisco
-Francisco Aguilera University of Washington Student | Prospective Computer Science Major | Microsoft Student Partner http://students.washington.edu/falven | http://www.facebook.com/falven
All Replies
-
Wednesday, March 13, 2013 2:32 PMModerator
Let me make sure I understand what you're trying to accomplish.
You're using SAPI to do text-to-speech, using the Microsoft provided voice.
Then you want to apply some effects to the captured audio, and play it back.
Is that correct?
Matthew van Eerde
-
Wednesday, March 13, 2013 4:05 PM
Yes, that is correct. However, the default SAPI effects applied using XML in the string are not sufficient. I need to calculate the DFT and extract some information to be able to apply my custom transformations.
-Francisco Aguilera University of Washington Student | Prospective Computer Science Major | Microsoft Student Partner http://students.washington.edu/falven | http://www.facebook.com/falven
-
Wednesday, March 13, 2013 5:07 PMModerator
After SAPI writes the stream, the stream position is at the end, so IStream::Read will set its "read" output to zero bytes.
Before reading from the stream, call IStream::Seek(zero, STREAM_SEEK_SET, NULL) and you will be able to read the data.
Matthew van Eerde
-
Wednesday, March 13, 2013 6:00 PMModerator
- Proposed As Answer by Maurits [MSFT]Microsoft Employee, Moderator Wednesday, March 13, 2013 7:31 PM
- Marked As Answer by falven Wednesday, March 13, 2013 10:52 PM
-
Wednesday, March 13, 2013 10:53 PM
Worked great, thanks.
And great job on the Blog entry.It is rather difficult to find information like this in bing/google for some reason.
-Falven
-Francisco Aguilera University of Washington Student | Prospective Computer Science Major | Microsoft Student Partner http://students.washington.edu/falven | http://www.facebook.com/falven


