Click here to Skip to main content
15,867,330 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi!

Im working on following program, getting audio data from mic input:


C++
#include <windows.h>
#include <mmsystem.h>
#include <mmreg.h>
#include <ksmedia.h>

//#include "stdafx.h" //ez a harom a fileba iras miatt kell
#include <iostream>
#include <fstream>


/*					// additional sample code for definitions, doesnt help
#define _KSDATAFORMAT_SUBTYPE_ANALOG         (GUID) {0x6dba3190,0x67bd,0x11cf,{0xa0,0xf7,0x00,0x20,0xaf,0xd1,0x56,0xe4}}
//#define KSDATAFORMAT_SUBTYPE_PCM             (GUID) {0x00000001,0x0000,0x0010,{0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71}}
#define _KSDATAFORMAT_SUBTYPE_IEEE_FLOAT     (GUID) {0x00000003,0x0000,0x0010,{0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71}}
#define _KSDATAFORMAT_SUBTYPE_DRM            (GUID) {0x00000009,0x0000,0x0010,{0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71}}
#define _KSDATAFORMAT_SUBTYPE_ALAW           (GUID) {0x00000006,0x0000,0x0010,{0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71}}
#define _KSDATAFORMAT_SUBTYPE_MULAW          (GUID) {0x00000007,0x0000,0x0010,{0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71}}
#define _KSDATAFORMAT_SUBTYPE_ADPCM          (GUID) {0x00000002,0x0000,0x0010,{0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71}}
#define _KSDATAFORMAT_SUBTYPE_MPEG           (GUID) {0x00000050,0x0000,0x0010,{0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71}}
#define _KSDATAFORMAT_SPECIFIER_VC_ID        (GUID) {0xad98d184,0xaac3,0x11d0,{0xa4,0x1c,0x00,0xa0,0xc9,0x22,0x31,0x96}}
#define _KSDATAFORMAT_SPECIFIER_WAVEFORMATEX (GUID) {0x05589f81,0xc356,0x11ce,{0xbf,0x01,0x00,0xaa,0x00,0x55,0x59,0x5a}}
#define _KSDATAFORMAT_SPECIFIER_DSOUND       (GUID) {0x518590a2,0xa184,0x11d0,{0x85,0x22,0x00,0xc0,0x4f,0xd9,0xba,0xf3}}

#define KSDATAFORMAT_SUBTYPE_PCM 

//#define KSDATAFORMAT_SUBTYPE_PCM             (GUID)

*/

using namespace std;

template <typename T>
void write(std::ofstream& stream, const T& t) {
  stream.write((const char*)&t, sizeof(T));
}

int main()
{

 const int NUMPTS = 44100 * 5;   // 5 seconds
 int sampleRate = 44100;
 short int waveIn[NUMPTS];   // 'short int' is a 16-bit type; I request 16-bit samples below
                             // for 8-bit capture, you'd use 'unsigned char' or 'BYTE' 8-bit types
 //string textout; 

	ofstream outputFile("auddata.txt", ios::trunc);	   //kiiras


 HWAVEIN      hWaveIn;
 WAVEHDR      WaveInHdr;
 MMRESULT result;


 // Specify recording parameters
 /*
WAVEFORMATEX Format;					// basic 16bit format - working
 Format.wFormatTag=WAVE_FORMAT_PCM;     // 
 Format.nChannels=1;                    //  1=mono, 2=stereo
 Format.nSamplesPerSec=sampleRate;      // 44100
 Format.nAvgBytesPerSec=sampleRate*2;   // = nSamplesPerSec * n.Channels * wBitsPerSample/8
 Format.nBlockAlign=2;                  // = n.Channels * wBitsPerSample/8
 Format.wBitsPerSample=16;              //  16 for high quality, 8 for telephone-grade
 Format.cbSize=0;
*/ 
 
///* 
 WAVEFORMATEXTENSIBLE pFormat;					// 24 bit format - not working
 pFormat.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE;     // bõvített formátum lesz, késõbb
 pFormat.Format.nChannels=1;                    //  1=mono, 2=stereo
 pFormat.Format.nSamplesPerSec=sampleRate;      // 44100
 pFormat.Format.nAvgBytesPerSec=sampleRate*3;   // = nSamplesPerSec * n.Channels * wBitsPerSample/8
 pFormat.Format.nBlockAlign=3;                  // = n.Channels * wBitsPerSample/8
 pFormat.Format.wBitsPerSample=24;              //  16 for high quality, 8 for telephone-grade
 //pFormat.Format.wValidBitsPerSample = 20;
 pFormat.Format.cbSize=22;
 pFormat.dwChannelMask=SPEAKER_FRONT_LEFT;
 pFormat.SubFormat=KSDATAFORMAT_SUBTYPE_PCM;
//}

//*/
/*												//sample code
WAVEFORMATPCMEX pFormat;
pFormat.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
pFormat.Format.nChannels = 1;
pFormat.Format.nSamplesPerSec = 44100L;
pFormat.Format.nAvgBytesPerSec = 264600L; // Compute using nBlkAlign * nSamp/Sec
waveFormatPCMEx.Format.nBlockAlign = 6;
waveFormatPCMEx.Format.wBitsPerSample = 24; //Container has 3 bytes waveFormatPCMEx.Format.cbSize = 22;
waveFormatPCMEx.wValidBitsPerSample = 20;  // Top 20 bits have data
waveFormatPCMEx.dwChannelMask = SPEAKER_FRONT_LEFT |
                                SPEAKER_FRONT_RIGHT | 
                                // Stereo = 0x00000003
waveFormatPCMEx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;  // Specify PCM
*/

 result = waveInOpen(&hWaveIn, WAVE_MAPPER,&pFormat.Format,
            0L, 0L, WAVE_FORMAT_DIRECT);
 if (result)
 {
  char fault[256];
  waveInGetErrorText(result, fault, 256);
  //Application->
  MessageBox(NULL, "Failed to open waveform input device.", NULL,
              MB_OK | MB_ICONEXCLAMATION);
  return(0);
 }

 // Set up and prepare header for input
 WaveInHdr.lpData = (LPSTR)waveIn;
 WaveInHdr.dwBufferLength = NUMPTS*2;
 WaveInHdr.dwBytesRecorded=0;
 WaveInHdr.dwUser = 0L;
 WaveInHdr.dwFlags = 0L;
 WaveInHdr.dwLoops = 0L;
 waveInPrepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));

 // Insert a wave input buffer
 result = waveInAddBuffer(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));
 if (result)
 {
  MessageBox(NULL, "Failed to read block from device",
                   NULL, MB_OK | MB_ICONEXCLAMATION);
  return(0);
 }


 // Commence sampling input
 result = waveInStart(hWaveIn);
 if (result)
 {
  MessageBox(NULL, "Failed to start recording",
                   NULL, MB_OK | MB_ICONEXCLAMATION);
  return(0);
 }


 // Wait until finished recording
 do {} while (waveInUnprepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR))==WAVERR_STILLPLAYING);

for( int a = 0; a < NUMPTS; a = a + 1 )
   {
	outputFile << a << ": " << waveIn[a] << endl;
	
   }

	outputFile.close();



MessageBox(NULL, "Recorded",
                   NULL, MB_OK | MB_ICONEXCLAMATION);
 
 

 
 
 waveInClose(hWaveIn);

return(0);

 }


16 bit input works fine with WAVEFORMATEX, but 24 bit i just cant get working, getting following error:
"KSDATAFORMAT_SUBTYPE_PCM was not declared in this scope"

I googled a lot on this message, but cant find a solution. There is propably some trivial mistake, since im not a programmer.
Posted
Comments
András Naszály 11-Nov-13 3:11am    
JOB OFFER!

If anybody would like to solve this, i am willing to pay for it!

You need to add a definition for KSDATAFORMAT_SUBTYPE_PCM, see http://msdn.microsoft.com/en-us/library/windows/hardware/gg463006.aspx[^], for details.
 
Share this answer
 
Comments
András Naszály 5-Nov-13 14:33pm    
Hi Richard,

thanks for the tip, i tried it, but doesnt work. Now i have "expected constructor, destructor, or type conversion before ( token" error.

Where exactly do i need to add the definition in the code? Anyway i dont understand, if i link ksmedia.h which includes the definition do i have to define the subtype once more?
Richard MacCutchan 5-Nov-13 14:52pm    
Sorry, but the only information I have is in the link to the MSDN reference that I gave you. As to your error message, you need to look at the code where it occurs, we cannot guess.
The above source does compile with some changes without problems in VS2010.

The Changes I made:

Added tchar.h and ks.h because VS asked for that.

C
#include <tchar.h>
#include <ks.h>      //  KS.H must be included before KSMEDIA.H
#include <ksmedia.h>


Added winmm.lib to linker options.

Changed main

C
// int main()
int _tmain(int argc, _TCHAR* argv[])


Declarated several Text as UNICODE

C
TCHAR fault[256];
waveInGetErrorText(result, fault, 256);


C
TEXT("Failed to start recording")


No error; no warning.

After run there is a file "auddata.txt" with 2,92 MB.
 
Share this answer
 
v2
Comments
András Naszály 12-Nov-13 15:32pm    
Hi, thanks for the help. First of all i switched to VS2013 from quincy.

I tried Your changes, builds now, but cant open device with waveformatextensible. Im trying 16bit since it should be working, but it doesnt:

<pre>
WAVEFORMATEXTENSIBLE pFormat; // 24 bit format - not working
pFormat.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; // bővített formátum lesz, később
pFormat.Format.nChannels = 1; // 1=mono, 2=stereo
pFormat.Format.nSamplesPerSec = sampleRate; // 44100
pFormat.Format.nAvgBytesPerSec = sampleRate * 2; // = nSamplesPerSec * n.Channels * wBitsPerSample/8
pFormat.Format.nBlockAlign = 2; // = n.Channels * wBitsPerSample/8
pFormat.Format.wBitsPerSample = 16; // 16 for high quality, 8 for telephone-grade
//pFormat.Format.wValidBitsPerSample = 20;
pFormat.Format.cbSize = 22;
pFormat.dwChannelMask = SPEAKER_FRONT_LEFT;
pFormat.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
</pre>

How come i can open device with same settings through waveformatex but not with waveformatextensible structure?
merano 12-Nov-13 16:19pm    
The waveformatextensible is working here. Where is the exact error line ?
Do you get an Error Code or Message?
András Naszály 13-Nov-13 3:28am    
Error message during program run:
"The specified format is not supported or cannot be translated. Use the Capabilities function to determine the supported formats."
merano 13-Nov-13 14:12pm    
Did you check the Capabilities ?Here are some more hints:

http://msdn.microsoft.com/en-us/library/windows/hardware/ff536383.aspx

WAVEFORMATEX is sufficient for describing formats with sample sizes of 8 or 16 bits,

but WAVEFORMATEXTENSIBLE is necessary to adequately describe formats with a sample

precision of greater than 16 bits.
András Naszály 14-Nov-13 9:17am    
How can i check the capabilities?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900