Solved

Truespeech recording without ACM

Posted on 2004-08-17
4
739 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
  • 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 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.

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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.

910 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

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now