Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Truespeech recording without ACM

Posted on 2004-08-17
4
Medium Priority
?
748 Views
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;
   } 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
0
Comment
Question by:jstray
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
4 Comments
 
LVL 3

Expert Comment

by:Tyrsis
ID: 11827829
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

0
 

Author Comment

by:jstray
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 = (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

0
 
LVL 3

Accepted Solution

by:
Tyrsis earned 1350 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.

Tyrsis
0
 

Author Comment

by:jstray
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!
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone 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

In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. A…
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…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

721 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