Truespeech recording without ACM

Posted on 2004-08-17
Last Modified: 2012-08-13
Hi all,
sorry but I've got another question on recording sound.

Please look at this sample:
   #define WAVE_FORMAT_GSM610 (0x0031)

   typedef struct gsm610waveformat_tag
         WAVEFORMATEX    wfx;
         WORD            wSamplesPerBlock;


   LPGSM610WAVEFORMAT pgsmwavefmt;
   hgsmwavefmt = GlobalAlloc(GMEM_MOVEABLE, (UINT)(sizeof(GSM610WAVEFORMAT) +32 ));
   pgsmwavefmt =     (LPGSM610WAVEFORMAT)GlobalLock(hgsmwavefmt);
   pgsmwavefmt->wfx.wFormatTag = WAVE_FORMAT_GSM610;
   pgsmwavefmt->wfx.nChannels = 1;
   pgsmwavefmt->wfx.nSamplesPerSec = 8000;
   pgsmwavefmt->wfx.nAvgBytesPerSec = 1625;
   pgsmwavefmt->wfx.nBlockAlign = 65;
   pgsmwavefmt->wfx.wBitsPerSample = 0;
   pgsmwavefmt->wfx.cbSize = 2;
   pgsmwavefmt->wSamplesPerBlock = 320;
   GSM610WAVEFORMAT struct's WAVEFORMATEX struct:    waveInOpen(&hwavein, (UINT)WAVE_MAPPER,
      (LPWAVEFORMATEX)&(pgsmwavefmt->wfx), (DWORD)(UINT)hwnd, (DWORD)NULL, CALLBACK_WINDOW);

It's for recording in GSM format....It works with these parameters....can someone tell how it can works in TRUESPEECH format? I use the same method for GSM but the error I get is BAD WAVE FORMAT when I open wave device with WaveInopen.....

Tnx a lot
Question by:jstray
  • 2
  • 2

Expert Comment

ID: 11827829

The TRUESPEECH codec requires extra information that is appended after the WAVEFORMATEX structure.  Without this information, you can't get it to work in any way.  Unfortunately, the only way I was able to get this "extra" information was to use acm functions.  Perhaps you can use acm functions to obtain this extra information that is added after the WAVEFORMATEX structure.  The easiest method I found was to do the following:

    wfxPCM->wFormatTag      = WAVE_FORMAT_PCM;
    wfxPCM->nChannels       = 1;
    wfxPCM->nSamplesPerSec  = 8000;
    wfxPCM->nAvgBytesPerSec = 16000;
    wfxPCM->nBlockAlign     = 2;
    wfxPCM->wBitsPerSample  = 16;

    wfxTrueSpeech->wFormatTag      = WAVE_FORMAT_DSPGROUP_TRUESPEECH;
    wfxTrueSpeech->nChannels       = 1;
    wfxTrueSpeech->nSamplesPerSec  = 8000;
    wfxTrueSpeech->nAvgBytesPerSec = 1067;
    wfxTrueSpeech->nBlockAlign     = 32;
    wfxTrueSpeech->wBitsPerSample  = 1;
    wfxTrueSpeech->cbSize          = 32;

    // TrueSpeech end tags
    cbSize = sizeof(WAVEFORMATEX) + wfxTrueSpeech->cbSize;

    mmr = acmFormatSuggest(NULL, wfxPCM, wfxTrueSpeech, cbSize, ACM_FORMATSUGGESTF_WFORMATTAG);

After you do acmFormatSuggest, the 32 bytes after the WAVEFORMATEX structure will be filled with the extra data required to make TRUESPEECH codec work.  You can probably just memcpy that out and then just make it a constant, copy it to a structure that has a char extra[32]; in it, and then pass that to waveInOpen() .  Though I'm unsure if it changes or is dynamic in any way.  If it is, then you may be out of luck in terms of not using acm functions at all.  Unfortunately I've only used TRUESPEECH using acm functions, so the extra data appended might have something to do with the PCM format I'm converting to.  I do not know for certain.  Hopefully this helps some though!



Author Comment

ID: 11846142
Nothing, my friend

look at this:
wfxPCM.wFormatTag      = WAVE_FORMAT_PCM;
wfxPCM.nChannels       = 1;
wfxPCM.nSamplesPerSec  = 8000;
wfxPCM.nAvgBytesPerSec = 16000;
wfxPCM.nBlockAlign     = 2;
wfxPCM.wBitsPerSample  = 16;
wfxPCM.cbSize          = 0;


tsp->wfx.nChannels       = 1;
tsp->wfx.nSamplesPerSec  = 8000;
tsp->wfx.nAvgBytesPerSec = 1067;
tsp->wfx.nBlockAlign     = 32;
tsp->wfx.wBitsPerSample  = 1;
tsp->wfx.cbSize          = 32;
int cbSize = sizeof(WAVEFORMATEX) + tsp->wfx.cbSize;

MMRESULT mmr = acmFormatSuggest(NULL, &wfxPCM, &(tsp->wfx), cbSize, ACM_FORMATSUGGESTF_WFORMATTAG);

************acmFormatSuggest is ok and the extension of truespeechformat if filled by 1, 240 and 28 "\000"....but.....
Res = waveInOpen(&WaveHandle, WAVE_MAPPER, &(tsp->wfx),(DWORD)waveInProc, 0, CALLBACK_FUNCTION);

THIS ONE FAILS! Res = 32 (WAVERR_BADFORMAT) after executing waveinopen......

I can't understand.....I heard that MS for certain formats allows only playback an not recording...I start to think so the story goes for TrueSpeech format.....

Have you another idea?
You know books speaking of this?

Tnx, Lorz


Accepted Solution

Tyrsis earned 450 total points
ID: 11846245
Hi there,

To be perfectly honest I can't remember specifically, but I do believe that TRUESPEECH can't be recorded in the manner you are trying.  I think I actually attempted to do it once, and ran into the same problem.  I was forced to record using PCM, then convert to truespeech, and back to PCM when I wanted to play the audio.  This was because I needed a compressed audio stream that was sent over TCP.  So in my case, using ACM was ok.  Perhaps others have had a better experience with truespeech, but I'm pretty positive that I tried everything just like you have, and failed until I used ACM to convert between formats and recorded using PCM.

Sorry if this is no help.


Author Comment

ID: 11859816
Ok Tyrsis,
probably the method I use doesn't work...I didn't try (and verify...) yet with ACM, but I appreciate the same your help!

Tnx a lot...See ya!

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

821 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question