News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Reading from a mic

Started by realcr, March 16, 2006, 03:05:47 PM

Previous topic - Next topic

realcr

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.

arafel

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.

Tedd

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.
No snowflake in an avalanche feels responsible.

realcr

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.

Tedd

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.)
No snowflake in an avalanche feels responsible.

realcr

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.

Tedd

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
No snowflake in an avalanche feels responsible.

realcr

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.

Emperor

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

elmo

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.
be the king of accounting programmer world!

clive

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.
It could be a random act of randomness. Those happen a lot as well.

Tedd

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.
No snowflake in an avalanche feels responsible.

farrier

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
It is a GOOD day to code!
Some assembly required!
ASM me!
With every mistake, we must surely be learning. (George...Bush)