Сейчас хочу научится работать со звуковухой через винапи.Набросал для этого прогу попроще: Код (Text): HINSTANCE hInst; TCHAR szTitle[MAX_LOADSTRING]; TCHAR szWindowClass[MAX_LOADSTRING]; ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); HANDLE file; HWAVEIN in; char *buf; WAVEHDR wd; long bufsz; __int64 filePosition=0; int recordseconds=0; int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); MSG msg; HACCEL hAccelTable; LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_WAVE2, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WAVE2)); while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return (int) msg.wParam; } ATOM MyRegisterClass(HINSTANCE hInstance) { 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, MAKEINTRESOURCE(IDI_WAVE2)); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = MAKEINTRESOURCE(IDC_WAVE2); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassEx(&wcex); } BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hInst = hInstance; hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); SetWindowPos(hWnd,HWND_TOP,100,100,300,150,SWP_SHO WWINDOW); return TRUE; } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; DWORD wb; char timert[1024]=""; switch (message) { case WM_COMMAND: { wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); if(LOWORD(wParam)==200) { waveInClose(in); CloseHandle(file); recordseconds=0; } if(LOWORD(wParam)==201) { WAVEFORMATEX wf; ZeroMemory(&wf,sizeof(WAVEFORMATEX)); wf.cbSize=0; wf.wFormatTag=WAVE_FORMAT_PCM; wf.wBitsPerSample=16; wf.nSamplesPerSec=16000L; wf.nChannels=1; wf.nBlockAlign=2; wf.nAvgBytesPerSec=wf.nSamplesPerSec*wf.nBlockAlig n; waveInOpen(&in,WAVE_MAPPER,&wf,(DWORD)hWnd,0L, CALLBACK_WINDOW); bufsz=wf.nBlockAlign*wf.nSamplesPerSec; buf=new char[bufsz]; wd.dwBufferLength=bufsz; wd.lpData=buf; waveInPrepareHeader(in,&wd,sizeof(WAVEHDR)); waveInAddBuffer(in,&wd,sizeof(WAVEHDR)); waveInStart(in); file=CreateFileA("rec.wav",GENERIC_WRITE,FILE_SHARE_WRITE,0,CREATE_ALWAYS,FI LE_ATTRIBUTE_NORMAL,0); } }break; case WM_CREATE: { CreateWindow("button",TEXT("Stop"),WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON ,25,50,70,30,hWnd,(HMENU)200,hInst,NULL); CreateWindow("button",TEXT("Start"),WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON ,200,50,70,30,hWnd,(HMENU)201,hInst,NULL); }break; case MM_WIM_DATA: { char er[1024]; MMRESULT result=0; waveInUnprepareHeader(in, &wd, sizeof(WAVEHDR)); SetFilePointer(file,filePosition,NULL,FILE_BEGIN); filePosition=filePosition+bufsz; WriteFile(file,buf,bufsz,&wb,0); memset(buf,NULL,bufsz); wd.lpData=buf; waveInPrepareHeader(in,&wd,sizeof(WAVEHDR)); waveInAddBuffer(in,&wd,sizeof(WAVEHDR)); result=waveInStart(in); if(result!=MMSYSERR_NOERROR) { waveInGetErrorText(result,er,1024); MessageBox(hWnd,er,"",MB_OK); } recordseconds++; wsprintf(timert,"ВРЕМЯ ЗАПИСИ:%d",recordseconds); //MessageBox(0,timert,"",MB_OK); }break; case WM_NCCREATE: { LPCREATESTRUCT lpcp=(LPCREATESTRUCT)lParam; lpcp->style &= (~WS_MAXIMIZEBOX ); lpcp->style &= (~WS_SIZEBOX ); SetWindowLong(hWnd, GWL_STYLE, lpcp->style); return true; } break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); RECT timeIndic; timeIndic.bottom=50; timeIndic.left=260; timeIndic.right=40; timeIndic.top=20; DrawText(hdc,timert,1024,&timeIndic,DT_CENTER); EndPaint(hWnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } Только вот почему то,получаемый файл не читается неодним плеером Подскажите что нетак.
А ни один плеер и не должен. Откуда ему знать, какая у тебя битность звука и частота дискретизации, а без этого колдунства звук играть как-то трудновато. CoolEdit, он же ныне Адобий Audition, умеет читать "сырые" аудифайлы, но частоту и битность ему всё равно придётся показать на пальцах.
_nic А здесь выдержки из курсового проекта 1998 года, в котором приведено краткое описание формата, а также исходный код для чтения заголовка .wav файла, содержащего несжатый PCM поток. Формат потока рассчитывается по данным заголовка. Итак, чтобы сохранять данные в .wav файле необходимо поддерживать формат файла. Другой способ, предложенный CyberManiac, заключается в сохранении PCM потока в файл данных с дальнейшим использованием его в CoolEdit, когда при открытии файла указываются параметры потока. Первый способ позволит разобраться с форматом хранения. Второй способ позволит освоить необходимый для анализа аудио данных инструмент. Для серьезного исследования необходимо освоить все эти способы. Код (Text): Формат мультимедийных данных Audio Wav WAV файл использует структуру RIFF файла, который был спроектирован для хранения мультимедиа данных. Структура файл состоит из набора блоков (chunks). Смещение, байт Название Длина, байт Описание +00h rId 04h Содержит строку “RIFF” +04h rLen 04h Размер данных в следующем блоке +08h rData rLen Следующий блок Смещение в блоке rData, байт Название Длина, байт Описание +00h wId 04h Содержит строку “WAVE” +04h Format Chunk 18h Блок параметров, определяющих данные в блоке аудио данных +1Сh WAVE Data Chunk ? Блок аудио данных Смещение в блоке Format Chunk, байт Название Длина, байт Описание 00h fId 04h Содержит строку “fmt “ 04h fLen 04h Длина данных в блоке параметров 08h wFormatTag 02h Формат (1 = Pulse Code Modulation) 0Ah nChannels 02h Количество каналов (1=mono,2=stereo) 0Ch nSamplesPerSec 04h Частота проигрывания данных 10h nAvgBytesPerSec 04h Среднее количество байт проигрываемых в секунду 14h nBlockAlign 02h Граница выравнивания данных 16h wBitsPerSample 02h Количество бит в группе Некоторые значения в блоке параметров связаны простыми соотношениями: 1. nAvgBytesPerSec = nChannels*nSamplesPerSec*(nBitsPerSample/8) 2. nBlockAlign = nChannels*(nBitsPerSample/8) Смещение в блоке Data Chunk, байт Название Длина, байт Описание 00h dId 04h Содержит строку “data” 04h dLen 04h Размер данных бока dData 08h dData dLen Аудио данные Структура простого заголовка TWavHeader = record {The RIFF File Format} rId: Longint; {Contains the characters "RIFF"} rLen: Longint; {The length of the data in the next chunk} {The WAVE Form Definition} wId: Longint; {Contains the characters "WAVE"} {The Format Chunk} fId: Longint; {Contains the characters "fmt"} fLen: Longint; {Length of data in the format chunk} wFormatTag: Word; nChannels: Word; {Number of channels, 1=mono, 2=stereo} nSamplesPerSec: Longint; {Playback frequency} nAvgBytesPerSec: Longint; nBlockAlign: Word; nBitsPerSample: Word; {Format specific data area} {The Data Chunk} dId: Longint; {Contains the characters "data"} dLen: Longint; {Length of data in the dData field} end; Функция чтения .wav файла procedure LoadWavFile(FileName:string; AudioData:PAudioData); var AudioFile:file; NumRead,Count:Integer; Header:TWavHeader; Buffer:PBArray; s:string; begin try // check for error LastPossibleAudioError:=errReading; AssignFile(AudioFile,FileName); Reset(AudioFile,1); BlockRead(AudioFile,Header,36,NumRead); if NumRead<>36 then Abort; // check for error LastPossibleAudioError:=errData; if (Header.rId<>$46464952) then Abort; {Not a RIFF format file} if (Header.wId<>$45564157) then Abort; {Not a WAVE format chunk} if (Header.fId<>$20746D66) then Abort; {Not a fmt WAVE Format Chunk} // check for error LastPossibleAudioError:=errOnlyPCM; if (Header.wFormatTag<>1) then Abort; {Data is not PCM} // check for error LastPossibleAudioError:=errOnlyMono; if (Header.nChannels<>1) then Abort; {Must be MONO or STEREO data} // check for error LastPossibleAudioError:=errBits; if not (Header.nBitsPerSample in [8,16]) then Abort; {Must be 8 or 16 bits} // check for error LastPossibleAudioError:=errReading; if (Header.fLen>16) then seek(AudioFile,20+Header.fLen); BlockRead(AudioFile,Header.dId,8,NumRead); if NumRead<>8 then Abort; // check for error LastPossibleAudioError:=errData; if (Header.dId<>$61746164) then Abort; {Not a DATA chunk} // check for error LastPossibleAudioError:=errLong; if (Header.dLen<1)or(Header.dLen>MaxFileSize) then Abort; // check for error LastPossibleAudioError:=errNoMemory; s:=IntToStr(Header.nBitsPerSample)+'-bit '; if Header.nChannels=1 then s:=Concat(s,'mono') else s:=Concat(s,'stereo'); AudioData^.info:=Concat(s,' ',IntToStr(Header.nSamplesPerSec),'Hz '); AudioData^.freq:=Header.nSamplesPerSec; finally CloseFile(AudioFile); end; end;
Спасибо.Выходной файл удается вопроизвести средсвами winapi.Надо было мне сразу так и попробовать ЗЫ:Только вот неясно как задать чуствительность микрофону??
В виндовсе есть чуствительность наверное это гдето в реестре и можно , я так думаю , узнать какие ключи реестра и какие функции использует стандартная программа настройки и действовать по аналогии, может есть вообще специальная либа подхватывающая ети натройки
mixerSetControlDetails http://pcbunn.cithep.caltech.edu/jjb/MixerControl.txt Но в висте видимо уже не работает.