Solved

Truespeech recording without ACM

Posted on 2004-08-17
4
742 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

Windows Server 2016: All you need to know

Learn about Hyper-V features that increase functionality and usability of Microsoft Windows Server 2016. Also, throughout this eBook, you’ll find some basic PowerShell examples that will help you leverage the scripts in your environments!

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
how to convert c++ code to Android App 3 97
Should CArray be used for a list of pointers in C++? 19 102
sorting efficency of sorting algorithm 30 113
Safe conversion? 4 69
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…
IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
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.

810 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