Link to home
Start Free TrialLog in
Avatar of jstray
jstray

asked on

Truespeech recording without ACM

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;
   } GSM610WAVEFORMAT;

   typedef GSM610WAVEFORMAT FAR *LPGSM610WAVEFORMAT;

   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
Avatar of Tyrsis
Tyrsis

Hello,

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!

Tyrsis

Avatar of jstray

ASKER

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 = (LPTRUESPEECHWAVEFORMAT)malloc(sizeof(TRUESPEECHWAVEFORMAT)+32);

tsp->wfx.wFormatTag      = WAVE_FORMAT_DSPGROUP_TRUESPEECH;
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

ASKER CERTIFIED SOLUTION
Avatar of Tyrsis
Tyrsis

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of jstray

ASKER

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!