Reputation: 4454
Based on the answer to the question How to record wav sound from mic using Windows API?, I went to the page whose link is provided in the answer and found an example code that records audio from microphone.
I would like to know how to change the code to:
1-Record from speakers instead.
2-If possible, stop recording by pressing a key instead of waiting the amount of time given as a function argument.
#include <Windows.h>
#pragma comment (lib, "Winmm.lib")
DWORD recordWAVEFile(DWORD dwMilliSeconds)
{
UINT wDeviceID;
DWORD dwReturn;
MCI_OPEN_PARMS mciOpenParms;
MCI_RECORD_PARMS mciRecordParms;
MCI_SAVE_PARMS mciSaveParms;
MCI_PLAY_PARMS mciPlayParms;
mciOpenParms.lpstrDeviceType = "waveaudio";
mciOpenParms.lpstrElementName = "";
if (dwReturn = mciSendCommand(0, MCI_OPEN,
MCI_OPEN_ELEMENT | MCI_OPEN_TYPE,
(DWORD)(LPVOID)&mciOpenParms))
{
return (dwReturn);
}
wDeviceID = mciOpenParms.wDeviceID;
mciRecordParms.dwTo = dwMilliSeconds;
if (dwReturn = mciSendCommand(wDeviceID, MCI_RECORD,
MCI_TO | MCI_WAIT, (DWORD)(LPVOID)&mciRecordParms))
{
mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL);
return (dwReturn);
}
mciPlayParms.dwFrom = 0L;
if (dwReturn = mciSendCommand(wDeviceID, MCI_PLAY,
MCI_FROM | MCI_WAIT, (DWORD)(LPVOID)&mciPlayParms))
{
mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL);
return (dwReturn);
}
if (MessageBox(NULL, "Do you want to save this recording?",
"", MB_YESNO) == IDNO)
{
mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL);
return (0L);
}
mciSaveParms.lpfilename = "tempfile.wav";
if (dwReturn = mciSendCommand(wDeviceID, MCI_SAVE,
MCI_SAVE_FILE | MCI_WAIT, (DWORD)(LPVOID)&mciSaveParms))
{
mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL);
return (dwReturn);
}
return (0L);
}
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine,
int iCmdShow)
{
char szAppName[] = "App";
char szWinName[] = "App";
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
if (!RegisterClass(&wndclass))
{
MessageBox(
NULL,
TEXT("Failed to register window class."),
szAppName,
MB_ICONERROR);
return 0;
}
HWND hwnd;
hwnd = CreateWindow(
szAppName,
szWinName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
if (!hwnd)
{
return 0;
}
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(
HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
switch (message)
{
case WM_KEYDOWN:
switch (wParam)
{
case VK_RETURN:
recordWAVEFile(4000);
break;
default:
break;
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
Upvotes: 1
Views: 551
Reputation: 11158
With MCI you cannot pick a source other than the default. You have to use waveIn* functions (waveInOpen() accepts a parameter to select the input source).
The other option is to set the default input to something available using the (horrible) Mixer API, so MCI uses it.
However, not all sound cards support recording from the speakers ("what you hear" input). Actually, most of nowadays cheap cards coming with the motherboard do not have such an option.
The other question, to stop the recording, waveIn functions these are asynchronous, so you can simply stop recording with waveInStop(), waveInReset() and waveInClose() when a key is pressed.
Generally, sound business in Windows is not done with MCI, MCI is a very simple interface for quick playback and recording.
Upvotes: 1