Solved

Playing Microphone Input.

Posted on 2000-03-13
14
314 Views
Last Modified: 2013-12-03
I'm looking for code to read in the audio input from the Microphone and play it out again throught the soundcard.

I believe it can be done using the waveIn* and waveOut* api calls but I cant suss out the buffer stuff.

Thanks in advance
Gordon
0
Comment
Question by:Gordonp
  • 7
  • 6
14 Comments
 
LVL 5

Expert Comment

by:Wyn
ID: 2611421
Hi,Gordon .There are many ways to record input from soundcard.

Qed:
1. MCIWnd Window Class

Recording with MCIWnd Controls
http://msdn.microsoft.com/library/psdk/multimed/mciwnd_0e43.htm 

2. MCI

Recording with a Waveform-Audio Device
http://msdn.microsoft.com/library/psdk/multimed/mci_4wpx.htm 

3. Waveform Audio

Example of Writing Waveform Data
http://msdn.microsoft.com/library/psdk/multimed/wave_8rj5.htm 

Recording and Playing Waveform Audio
http://msdn.microsoft.com/library/techart/msdn_spellit.htm 

4. DirectSound

Tutorial 2: Capturing a Sound
http://msdn.microsoft.com/library/psdk/directx/dstut_9ox0.htm

Regards
0
 
LVL 5

Expert Comment

by:Wyn
ID: 2611450
And here are some info you need:

some samples:
Audio Mixer Functions Demo
http://www.codeguru.com/multimedia/ADMixer.shtml 


http://msdn.microsoft.com/workshop/c-frame.htm?944437056110#/workshop/imedia/windowsmedia/sdk/wmsdk_fmt.asp

And if you want to use waveinxxx waveoutxx .I can write another sample but it will take some time.First check above info.

Regards
W.Yinan
0
 
LVL 3

Author Comment

by:Gordonp
ID: 2611491
Wyn>
All bar one of your links are for recording an audio input, and the other link is broken.

I want to play the audio input straight out again on the speakers, not record it into a file.

GordonP
0
 
LVL 5

Expert Comment

by:Wyn
ID: 2611528
I know what you want and Okay now I will write one for you .But I dont think it's big different to above!

Waiting....
0
 
LVL 5

Expert Comment

by:Wyn
ID: 2611619
One Directions:
Use threads for this application. One for receiving and playing the voice you are receiving and another for recording and sending the voice.

One question:
Is your card duplex?
0
 
LVL 3

Author Comment

by:Gordonp
ID: 2611625
> One question:
> Is your card duplex?
Yes!
0
 
LVL 5

Expert Comment

by:Wyn
ID: 2611651
You will find code how to record in above links.Here is how to play them concurrently

The MM_WIM_DATA message will be sent when the input structure are filled.
Then you create a create in handler code:

case MM_WIM_DATA:
_beginthread(doit,0,buffer);
The doit will the function you want to do with the buffer.

0
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.

 
LVL 3

Author Comment

by:Gordonp
ID: 2611710
can I just use one buffer! do I need to use synchro for buffer access??

GordonP
0
 
LVL 3

Author Comment

by:Gordonp
ID: 2611726
the link "Recording and Playing Waveform Audio" doesnt work.

I assume this would have shown me how to read the data into the buffer, do you have a working link for this!!

GordonP
0
 
LVL 5

Accepted Solution

by:
Wyn earned 300 total points
ID: 2612590
Here is some info I quote ,hope helpful.I'm keeping write a array-sort program,thus late here:
Quoted :
Before starting the process of voice recording and playing you have to declare and initialize the above described structures and handles related to wave input/output.

Two important handle types are :
HWAVEIN = This handle identifies the open waveform-audio input device.
HWAVEOUT = This handle identifies the open waveform-audio output device.

Let's define a structure for our convenience to be used in the code as :
typedef struct _LevelStreamData {
LPWAVEHDR alpWave[BUFFERSNO];
WAVEFORMATEX FAR *pwf;
HWAVEIN hwi;
int buffersize;
} LEVELSTREAMDATA, FAR * PLEVELSTREAMDATA;

BUFFERSNO are defined as
#define BUFFERSNO 4

Here you can define the total number of buffers that you want to use.

Now before starting the recording and playing of voice data you have to initialize these voice related structures and prepare the audio input and output device.

Inthe following lines of code we will see how one can open a wave device in the given format, queue up all the buffers and start data streaming.

step 1: Declare a member of PLEVELSTREAMDATA structure defined above.
PLEVELSTREAMDATA pInfo;

step 2: Initialize the above declared structure member with appropriate value like
pInfo->pwf->nChannels = 1;
pInfo->pwf->wBitsPerSample = 8;
pInfo->pwf->nSamplesPerSec = 11025;
pInfo->pwf->wFormatTag = WAVE_FORMAT_PCM;
pInfo->pwf->nBlockAlign = pInfo->pwf->nChannels * pInfo->pwf->wBitsPerSample / 8;
pInfo->pwf->nAvgBytesPerSec = pInfo->pwf->nSamplesPerSec * pInfo->pwf->nBlockAlign;

pInfo->buffersize = pInfo->pwf->nAvgBytesPerSec/UPDATES_PER_SEC;

Where UPDATES_PER_SEC is the part of a second for which you want to record the voice data and is defined as

#define UPDATES_PER_SEC 5
In which case your buffer size will record one fifth second's voice.

step 3: Opening the waveform input device (soundcard) for recording
The function for this goes like this :
waveInOpen(&pInfo->hwi, WAVE_MAPPER, (LPWAVEFORMATEX)pwf, (DWORD) hDlg, 0, CALL_BACK_WINDOW)

where hDlg is the handle to the window receiving messages.

step 4: Setting all the wave headers to NULL for cleanup
for( i=0; i<BUFFERSNO; i++)
pInfo->alpWave[i] = NULL;

step 5: Allocate, prepare and add all the buffers
for(i=0; i<BUFFERSNO; i++)
{
pInfo->alpWave[i] = (LPWAVEHDR) GlobalLock(GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, sizeof(WAVEHDR) + pInfo->buffersize));

if(pInfo->alpWave[i] == NULL) return FALSE;   //Unable to allocate memory

pInfo->alpWave[i]->lpData = (LPSTR)(LPBYTE)(pInfo->alpWave[i] + 1);
pInfo->alpWave[i]->dwBufferLength = pInfo->buffersize;
pInfo->alpWave[i]->dwBytesRecorded = 0;
pInfo->alpWave[i]->dwUser = 0;
pInfo->alpWave[i]->dwFlags = 0;
pInfo->alpWave[i]->dwLoops = 0;

if(waveInPrepareHeader(pInfo->hwi, pInfo->alpWave[i], sizeof(WAVEHDR))) return FALSE;
//Above function prepare these buffers for waveform input finally

if(waveInAddBuffer(pInfo->hwi, pInfo->alpWave[i], sizeof(WAVEHDR)))
return FALSE;
//Above function sends these buffers to the given waveform input device
}

step 7: Finally starting the wave input
With the execution of waveInStart() function the waveform input device starts recording. The function is called like this.
int errorCode = waveInStart( pInfo->hwi);
if(errorCode) {
MessageBox("Error in starting wave recording");
return FALSE;
}



With the above WaveInStart() packets will start arriving. To get those packets process the
MM_WIM_DATA message as shown below:

case MM_WIM_DATA:
wRBuffer=(char*)((LPWAVEHDR)lParam)->lpData;
_beginthread((void (__cdecl *)(void *))sendAThread,0,(void (__cdecl *)(void *))wRBuffer);
waveInUnprepareHeader((HWAVEIN)wParam,(LPWAVEHDR)lParam,sizeof(WAVEHDR));
waveInPrepareHeader((HWAVEIN)wParam,(LPWAVEHDR)lParam,sizeof(WAVEHDR));
waveInAddBuffer((HWAVEIN)wParam,(LPWAVEHDR)lParam,sizeof(WAVEHDR));
return TRUE;
break;

where -
wrBuffer is declared as char *wrBuffer;
_beginThread will start execution of a thread and pass to that the voice packet
which contains the recorded voice.
sendAThread is the thread function to which this data is passed. In this function you can
process this voice packet and do with that whatever u like, (i.e. u can send this packet to
some other machine or play it back)

sendAThread can be written as follows :

void sendAThread(char *sbuffer)
{
//code to process the received buffer
return;
}

So, you can see how easy is it to create a thread and than pass to it the required data.
But before using threads remember to include process.h header file.
================

Hope helpful.
Regards
W.Yinan

0
 
LVL 5

Expert Comment

by:Wyn
ID: 2612594

->can I just use one buffer! do I need to use synchro for buffer access??  
================
All above:)
0
 
LVL 3

Author Comment

by:Gordonp
ID: 2614994
Thanks I'll try it and get back to you

Gordon
0
 
LVL 3

Author Comment

by:Gordonp
ID: 2640221
Thanks for your help

Gordon
0
 

Expert Comment

by:gptreven
ID: 8583296
I have a problem in that I have two sound cards in the one machine and I am having troubles selecting the individual device under waveinopen.  It keeps returning error 32 any help
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

Suggested Solutions

Title # Comments Views Activity
Clean Uninstall of VS Professional 2015 5 51
wordpress limitations 4 105
Where to obtain Oracle Data Provider for .NET 3.5 7 47
Post a good COM tutorial 1 50
What my article will show is if you ever had to do processing to a listbox without being able to just select all the items in it. My software Visual Studio 2008 crystal report v11 My issue was I wanted to add crystal report to a form and show…
After several hours of googling I could not gather any information on this topic. There are several ways of controlling the USB port connected to any storage device. The best example of that is by changing the registry value of "HKEY_LOCAL_MACHINE\S…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Internet Business Fax to Email Made Easy - With  eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, f…

867 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

20 Experts available now in Live!

Get 1:1 Help Now