DirectSound application development question.
Hi all,
I'm new to DirectX application development, and i seek some help from
this group.
Problem Statement:
I've a USB microphone, that sends the sound data via USB at 44.1khz. I
need to capture the sound and analyze the data and process it.
I've gone through the source code of DirectX c++ sample of
'capturesound' and there they easily capture the data in the capture
buffer and write the captured data to a wav file.
What kind of data is the raw data, which is coming from the USB port
to the Capture buffer?
The data which is in capture buffer can be written to a wav file, When
i want the data which is actually in the capture buffer, the read
operation from the capture buffer the same as what we get from the USB
port?
When i read the data from the capture buffer, is it possible to
analyze and process each and every byte and store it in another buffer
instead of saving it into a file of .wav format?
Also, when i try to record my voice using a normal microphone in
'capturesound' application, the voice is not getting recorded, however
when i use some other application like gtalk to do voice chat,the
other person is able to hear me, what may be the reason for this
failure?
Please answer. Thank you.
Re: DirectSound application development question.
Which headphone you are using? A good USB headset has a mic response range of 100 Hz - 8 kHz. This will capture all the low and high tones of any human voice, plus leave some room for the harmonic overtones present in every voice. A better choice, however, is to find a headset mic with a response of 100 Hz - 16 kHz or more. The extra 8 kHz of range on the high end has an audible impact on the brightness and sibilance of a recorded voice. You might also want to consider whether or not the microphone features "Digital Signal Processing".
Re: DirectSound application development question.
thanks for the reply.
The second issue is solved. I'm able to record from the microphone.:thumbup1:
I need some guidance regarding the first issue though.:yes:
Re: DirectSound application development question.
hi
can any one give me source code for record mic with directsound !
i need one simple program that record mic in wav file !
please help me !
Re: DirectSound application development question.
Create a capture object..and you can record sound and transferred it to a secondary buffer via memory stream.But you have to remember that the read position is the end of the data that has been taken into the buffer at this point. The capture position is the end of the array of data that is presently being copied from the hardware. You can easily copy data from the buffer up to the read position.
Re: DirectSound application development question.
hi
this is my code:
work but give me empty wav ?
what is my problem in write buffers in wav file?
//-----------------------------------------------------------------------------
// File: CreateDevice.cpp
//
// Desc: This is the first tutorial for using Direct3D. In this tutorial, all
// we are doing is creating a Direct3D device and using it to clear the
// window.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#include <d3d9.h>
#pragma warning( disable : 4996 ) // disable deprecated warning
#include <strsafe.h>
#pragma warning( default : 4996 )
#define INITGUID
#include <windows.h>
#include <dsound.h>
#include "resource.h"
#include "CreateDevice.h"
//extern "C" {
#include "dsenum.h"
//}
#define NUMCAPTUREEVENTS 2
#define BUFFER_LEN 102400
LPDIRECTSOUNDCAPTURE lpdsc;
LPDIRECTSOUNDCAPTUREBUFFER lpdscb;
LPDIRECTSOUNDNOTIFY lpdsNotify;
DSCBUFFERDESC dscbDesc;
HANDLE rghEvent[NUMCAPTUREEVENTS];
DSBPOSITIONNOTIFY rgdscbpn[NUMCAPTUREEVENTS];
WAVEFORMATEX wfx = {WAVE_FORMAT_PCM, 1, 22050, 44100,2,16,0};
HMMIO hmmio;
MMCKINFO mmckinfoData, mmckinfoParent;
MMIOINFO mmioinfo;
DWORD dwTotalBytesWritten;
//--------------------------------------------------------------------------------------
// Global Variables
//--------------------------------------------------------------------------------------
HINSTANCE g_hInst = NULL;
HWND g_hWnd = NULL;
//HWND hWndMain = NULL;
HMMIO hFile;
MMCKINFO chunk, chunk2;
MMRESULT soundfileopen;
HWAVEIN hwi;
char buffer1[BUFFER_LEN];
WAVEHDR buffer;
DWORD dwReadPos;
DWORD dwNumBytes;
LPBYTE pbInput1, pbInput2;
DWORD cbInput1, cbInput2;
static DWORD dwMyReadCursor = 0;
UINT dwBytesWritten;
//--------------------------------------------------------------------------------------
// Forward declarations
//--------------------------------------------------------------------------------------
HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow );
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
//-----------------------------------------------------------------------------
// Name: MsgProc()
// Desc: The window's message handler
//-----------------------------------------------------------------------------
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
//-----------------------------------------------------------------------------
// Name: wWinMain()
// Desc: The application's entry point
//-----------------------------------------------------------------------------
INT WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE, LPWSTR, int nCmdShow)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = L"TutorialWindowClass";
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_APPLICATION);
if( !RegisterClassEx(&wcex) )
return E_FAIL;
// Create window
g_hInst = hInstance;
RECT rc = { 0, 0, 640, 480 };
AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE );
g_hWnd = CreateWindow( L"TutorialWindowClass", L"Direct3D 10 Tutorial 0: Setting Up Window", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance, NULL);
if( !g_hWnd )
return E_FAIL;
hWndMain = g_hWnd;
ShowWindow( g_hWnd, nCmdShow );
if( FAILED( InitWindow( hInstance, nCmdShow ) ) )
return 0;
hInst = hInstance;
// Main message loop
MSG msg = {0};
BOOL Done = FALSE;
while (!Done)
{
DWORD dwEvt = MsgWaitForMultipleObjects(
NUMCAPTUREEVENTS, // How many possible events
rghEvent, // Location of handles
FALSE, // Wait for all?
INFINITE, // How long to wait
QS_ALLINPUT); // Any message is an event
dwEvt -= WAIT_OBJECT_0;
// If the event was set by the buffer, there's input
// to process.
if (dwEvt < NUMCAPTUREEVENTS)
{
// StreamToFile();
IDirectSoundCaptureBuffer_GetCurrentPosition(lpdscb,
NULL, &dwReadPos);
if (dwReadPos < dwMyReadCursor)
dwReadPos += dscbDesc.dwBufferBytes;
dwNumBytes = dwReadPos - dwMyReadCursor;
if FAILED(IDirectSoundCaptureBuffer_Lock(lpdscb,
dwMyReadCursor, dwNumBytes,
(LPVOID *)&pbInput1, &cbInput1,
(LPVOID *)&pbInput2, &cbInput2, 0))
MessageBox(g_hWnd, L"failed Buffer Lock",L"DirectSound Demo", MB_OK);
else {
::mmioWrite(hFile, (const char*)&pbInput1, cbInput1);
::mmioAscend(hFile, &mmckinfoData, 0);
mmioAscend( hFile, &chunk, 0);
dwTotalBytesWritten += dwBytesWritten;
// Wrap around
if (pbInput2 != NULL)
{
::mmioWrite(hFile, (const char*)&pbInput2, cbInput2);
::mmioAscend(hFile, &mmckinfoData, 0);
mmioAscend( hFile, &chunk, 0);
dwTotalBytesWritten += dwBytesWritten;
}
IDirectSoundCaptureBuffer_Unlock(lpdscb,
pbInput1, cbInput1,
pbInput2, cbInput2);
}
dwMyReadCursor += dwNumBytes;
if (dwMyReadCursor >= dscbDesc.dwBufferBytes)
dwMyReadCursor -= dscbDesc.dwBufferBytes;
}
// If it's the last event, it's a message
else if (dwEvt == NUMCAPTUREEVENTS)
{
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
IDirectSoundCaptureBuffer_Stop(lpdscb);
::mmioClose(hFile, 0);
if (lpdsNotify)
IDirectSoundNotify_Release(lpdsNotify);
if (lpdscb)
IDirectSoundCaptureBuffer_Release(lpdscb);
if (lpdsc)
IDirectSoundCapture_Release(lpdsc);
Done = TRUE;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
} // end message processing
} // while (!Done)
while( GetMessage( &msg, NULL, 0, 0 ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
return (int) msg.wParam;
}
HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow )
{
// Register class
DoDSoundEnumerate(&guID);
//Direct Sound
if FAILED(DirectSoundCaptureCreate(&guID, &lpdsc, NULL))
return FALSE;
DSCCAPS dsccaps;
dsccaps.dwSize = sizeof(DSCCAPS);
if FAILED(IDirectSoundCapture_GetCaps(lpdsc, &dsccaps))
return FALSE;
if ((dsccaps.dwFormats & WAVE_FORMAT_2M16) == 0)
{
wfx.nSamplesPerSec = 11025;
wfx.nAvgBytesPerSec = 11025;
wfx.nBlockAlign = 1;
wfx.wBitsPerSample = 8;
}
dscbDesc.dwSize = sizeof(DSCBUFFERDESC);
dscbDesc.dwFlags = 0;
// Buffer will hold one second's worth of audio
dscbDesc.dwBufferBytes = wfx.nAvgBytesPerSec;
dscbDesc.dwReserved = 0;
dscbDesc.lpwfxFormat = &wfx;
if FAILED(IDirectSoundCapture_CreateCaptureBuffer(lpdsc,
&dscbDesc, &lpdscb, NULL))
return FALSE;
for (int i = 0; i < NUMCAPTUREEVENTS; i++)
{
rghEvent[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
if (NULL == rghEvent[i]) return FALSE;
}
rgdscbpn[0].dwOffset = 0;
rgdscbpn[0].hEventNotify = rghEvent[0];
rgdscbpn[1].dwOffset = dscbDesc.dwBufferBytes/2;
rgdscbpn[1].hEventNotify = rghEvent[1];
if FAILED(IDirectSoundCaptureBuffer_QueryInterface(lpdscb,
IID_IDirectSoundNotify, (VOID **)&lpdsNotify))
return FALSE;
if FAILED(IDirectSoundNotify_SetNotificationPositions(lpdsNotify,
NUMCAPTUREEVENTS, rgdscbpn))
{
IDirectSoundNotify_Release(lpdsNotify);
return FALSE;
}
IDirectSoundCaptureBuffer_Start(lpdscb,DSCBSTART_LOOPING);
//WAVEINCAPS lpwaveincaps;
//MMRESULT sounddeviceinfo;
//sounddeviceinfo = waveInGetDevCaps(0, &lpwaveincaps, sizeof(WAVEINCAPS));
WAVEFORMATEX formatinfo;
formatinfo.cbSize = 0;
formatinfo.wFormatTag = WAVE_FORMAT_PCM;
formatinfo.nChannels = 1; // 1 for mono 2 and 2 for stereo
formatinfo.wBitsPerSample = 16; // can be 8 or 16
formatinfo.nSamplesPerSec = 8000; // u can set nSamplesPerSec as 16000, 24000.
formatinfo.nBlockAlign = formatinfo.nChannels * (formatinfo.wBitsPerSample / 8);
formatinfo.nAvgBytesPerSec = formatinfo.nSamplesPerSec * formatinfo.nBlockAlign;
hFile = mmioOpen(L"NEWFILE.WAV", NULL, MMIO_CREATE | MMIO_READWRITE);
if (hFile != NULL)
MessageBox(g_hWnd, L"Success",L"DirectSound Demo", MB_OK);
else
MessageBox(g_hWnd, L"failed",L"DirectSound Demo", MB_OK);
int fmtSize = 28;
chunk.fccType = mmioFOURCC('W','A','V','E');
chunk.cksize = 28;
::mmioCreateChunk(hFile, &chunk, MMIO_CREATERIFF);
chunk2.ckid = mmioFOURCC('f','m','t',' ');
chunk2.cksize = sizeof(WAVEFORMATEX);
::mmioCreateChunk(hFile, &chunk2, 0);
::mmioWrite(hFile, (const char*)&formatinfo,sizeof(formatinfo));
::mmioAscend(hFile, &chunk2, 0);
mmckinfoData.ckid = mmioFOURCC('d','a','t','a');
mmckinfoData.cksize = formatinfo.nAvgBytesPerSec;
::mmioCreateChunk(hFile, &mmckinfoData, 0);
return S_OK;
}