The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: realcr on March 16, 2006, 03:05:47 PM

Title: Reading from a mic
Post by: realcr on March 16, 2006, 03:05:47 PM
I'm trying to write a simple echo program (the speaker should repeat what was said).
Where can I find information about reading from the mic and writing to the speaker , or any examples on this topic?
Under linux/Unix it used to be as easy as reading from a file , but I feel like it won't going to be the same under Windows.

realcr.
Title: Re: Reading from a mic
Post by: arafel on March 16, 2006, 09:36:52 PM
Not sure, but perhaps waveIn\waveOut functions are the right direction.

From a quick peeking in the sdk it seems like, first the input device should be located with mixerGet* functions. waveInOpen initiated with the found microphone device handle (or WAVE_MAPPER which will force it to select most appropriate device accordingly to the specified format), then waveInPrepareHeader plus waveInAddBuffer. And finely waveInstart to make the recording.
Title: Re: Reading from a mic
Post by: Tedd on March 17, 2006, 11:12:37 AM
Setup:
- fill-in a WAVEFORMATEX structure, use it in "waveOutOpen" (-1 for default DevID; ADDR waveOutProc) ==> hWaveOut
- fill-in a WAVEFORMATEX structure, use it in "waveInOpen" (-1 for default DevId; ADDR waveInProc) ==> hWaveIn

Record:
- "waveInPrepareHeader" with hWaveIn
- "waveInAddBuffer" with hWaveIn

Playback:
- "waveOutPrepareHeader" with hWaveOut
- "waveOutWrite" with hWaveOut

* waveInProc
  - if (uMsg==WOM_DONE)
        waveInUnprepareHeader
        playback

* waveOutProc
  - if (uMsg==WOM_DONE)
        waveOutUnprepareHeader
        (buffer is now spare - send it for recording again, or delete it)


Hopefully that should be enough to get you started :wink
But make sure you read all of the info for those functions, and related stuff, so you understand how it works.
Title: Re: Reading from a mic
Post by: realcr on March 17, 2006, 02:10:28 PM
thank you Tedd and Arafel.
I was also wondering if I can ever read the data encoded this way from another operation system , for example if I send it and want to recieve and hear it.

realcr.
Title: Re: Reading from a mic
Post by: Tedd on March 17, 2006, 06:24:46 PM
After seeing your networking questions, I was expecting you're doing something like this :wink
As long as you label the voice packets with enough information that the receiver will know what format it is, then there shouldn't be any problem. If the receiver has the correct codec, then it should be okay (could there be byte-order problems?)

Once you get the wav version working, you might want to consider using the audio coding manager (acm) which will allow you to encode in a more efficient format, mp3 for example (there are more efficient ones for voice, but they require support on the other systems too.)
Title: Re: Reading from a mic
Post by: realcr on March 17, 2006, 08:26:23 PM
Hi there Ted.

The information you sent about how to write the program was really helpful... I finally know what to look for and the name of the functions. Can you recommend a name of a book or somewhere I can read about audio processing in windows? It is really important for me to write reliable code and understand everything I'm doing , So I'm planning to learn stuff from the inside.

again thanks for your help,
realcr.
Title: Re: Reading from a mic
Post by: Tedd on March 20, 2006, 10:21:58 AM
No books I'm afirad :P
Just use http://msdn.microsoft.com/library/ for reference, and experiment for learning :green2
A quick web-search should provide you with other information if you need it.

For simple recording and playback, there isn't too much you need to know, except for how to use the functions. If you really want to understand audio processing, then you'll want to look into DSP (digital signal processing) but it's not for the faint-hearted :bdg
Title: Re: Reading from a mic
Post by: realcr on March 21, 2006, 11:52:30 AM
Lol not for the faint-hearted...
Things start to work now , I managed to write some working code to hear things (Accidently played a zip file which was really painful).

Great thanks again for your help,
realcr.
Title: Re: Reading from a mic
Post by: Emperor on March 22, 2006, 06:43:21 PM
May not be what your looking for but here's a small example of recording, saving, and playing a sound using mciSendString


.486
.model flat, stdcall
option casemap :none

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\winmm.inc
include \masm32\macros\macros.asm

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\winmm.lib

.code

start:

fn mciSendString, "open new type waveaudio alias recorddata", NULL, 65535, NULL

fn MessageBox, NULL, "Will now record a sound for 5 seconds", "Example", MB_OK
fn mciSendString, "record recorddata from 0 to 5000 wait", NULL, 65535, NULL
fn mciSendString, "stop recorddata", NULL, 65535, NULL

fn MessageBox, NULL, "Will now save recorded sound", "Example", MB_OK
fn mciSendString, "save recorddata record.wav", NULL, 65535, NULL

fn MessageBox, NULL, "Will now play saved sound", "Example", MB_OK
fn mciSendString, "open record.wav alias recordfile", NULL, 65535, NULL
fn mciSendString, "play recordfile wait", NULL, 65535, NULL

invoke ExitProcess, NULL

end start
Title: Re: Reading from a mic
Post by: elmo on April 15, 2011, 12:18:45 PM
before we do sound record or playing sound, first
We must know: our computer system has sound card or not.

how to detect this?
what API we must use?
thank you.
sorry for my bad english.
Title: Re: Reading from a mic
Post by: clive on April 15, 2011, 01:04:29 PM
My vague recollection is that you could use the MM API and enumerate devices/resources.

http://msdn.microsoft.com/en-us/library/dd370784%28v=vs.85%29.aspx

The might be better ways now, but depends on your need for backward compatibility, or not.
Title: Re: Reading from a mic
Post by: Tedd on April 15, 2011, 02:43:07 PM
You can check the number of wave input and output devices..

waveOutGetNumDevs -- http://msdn.microsoft.com/en-us/library/ms713748.aspx
waveInGetNumDevs-- http://msdn.microsoft.com/en-us/library/dd743844%28VS.85%29.aspx

They return zero if there are none.
Title: Re: Reading from a mic
Post by: farrier on April 16, 2011, 05:40:10 PM
elmo,

If you are using DirectSound:

;Enumerate all sound cards available on the system
;Looks for my 'iMic' USB "SoundCard" and retrieve the GUID for that card to use with DirectSoundCreate8

mov [pRecGUID], NULL ;Use default device if Enumerate fails
invoke SendMessage, [stat_handle], SB_SETTEXT, 0, szEnum

;Set Input and Output SoundCards by enumerating all sound cards
invoke DirectSoundEnumerate, DSEcallback, NULL

;Create the DirectSound object
invoke DirectSoundCreate8, [pRecGUID], dsc, NULL

;set cooperative level of the object
cominvk dsc, SetCooperativeLevel, [hwnd], DSSCL_NORMAL

;Create Sound Capture object
invoke DirectSoundCaptureEnumerate, DSEcallback, NULL
invoke DirectSoundCaptureCreate8, [pRecGUID], dscc, NULL

_____________________________________________________________________
DSEcallback proc lpGuid, lpcstrDescription, lpcstrModule, lpContext

;When DirectSound...Enumerate is called, Each audio device supported causes this callback routine to trigger
; the "default device" triggers this routine twice, once with a NULL GUID and once with its "real" GUID.
mov eax, [lpcstrDescription]
mov eax, [eax]
.if eax, e, 'iMic' ;my USB audio device is found and we will use it
push [lpGuid]
pop [pRecGUID]
.endif
ret

DSEcallback endp


I use this in a program to get the GUID for the iMic USB sound card on my system. 

hth,

farrier