Снять звук с микрофона.Что я делаю не так?

Тема в разделе "WASM.AUDIO", создана пользователем _nic, 19 июл 2010.

  1. _nic

    _nic New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2007
    Сообщения:
    372
    Сейчас хочу научится работать со звуковухой через винапи.Набросал для этого прогу попроще:
    Код (Text):
    1. HINSTANCE hInst;                               
    2. TCHAR szTitle[MAX_LOADSTRING];                 
    3. TCHAR szWindowClass[MAX_LOADSTRING];           
    4.  
    5. ATOM                MyRegisterClass(HINSTANCE hInstance);
    6. BOOL                InitInstance(HINSTANCE, int);
    7. LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
    8. INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);
    9. HANDLE file;
    10. HWAVEIN in;
    11. char *buf;
    12. WAVEHDR wd;
    13. long bufsz;
    14. __int64 filePosition=0;
    15. int recordseconds=0;
    16. int APIENTRY _tWinMain(HINSTANCE hInstance,
    17.                      HINSTANCE hPrevInstance,
    18.                      LPTSTR    lpCmdLine,
    19.                      int       nCmdShow)
    20. {
    21.     UNREFERENCED_PARAMETER(hPrevInstance);
    22.     UNREFERENCED_PARAMETER(lpCmdLine);
    23.     MSG msg;
    24.     HACCEL hAccelTable;
    25.     LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    26.     LoadString(hInstance, IDC_WAVE2, szWindowClass, MAX_LOADSTRING);
    27.     MyRegisterClass(hInstance);
    28.     if (!InitInstance (hInstance, nCmdShow))
    29.     {
    30.         return FALSE;
    31.     }
    32.  
    33.     hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WAVE2));
    34.     while (GetMessage(&msg, NULL, 0, 0))
    35.     {
    36.         if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
    37.         {
    38.             TranslateMessage(&msg);
    39.             DispatchMessage(&msg);
    40.         }
    41.     }
    42.  
    43.     return (int) msg.wParam;
    44. }
    45. ATOM MyRegisterClass(HINSTANCE hInstance)
    46. {
    47.     WNDCLASSEX wcex;
    48.  
    49.     wcex.cbSize = sizeof(WNDCLASSEX);
    50.  
    51.     wcex.style          = CS_HREDRAW | CS_VREDRAW;
    52.     wcex.lpfnWndProc    = WndProc;
    53.     wcex.cbClsExtra     = 0;
    54.     wcex.cbWndExtra     = 0;
    55.     wcex.hInstance      = hInstance;
    56.     wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WAVE2));
    57.     wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    58.     wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    59.     wcex.lpszMenuName   = MAKEINTRESOURCE(IDC_WAVE2);
    60.     wcex.lpszClassName  = szWindowClass;
    61.     wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
    62.  
    63.     return RegisterClassEx(&wcex);
    64. }
    65. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
    66. {
    67.    HWND hWnd;
    68.  
    69.    hInst = hInstance;
    70.  
    71.    hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
    72.       CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
    73.  
    74.    if (!hWnd)
    75.    {
    76.       return FALSE;
    77.    }
    78.  
    79.    ShowWindow(hWnd, nCmdShow);
    80.    UpdateWindow(hWnd);
    81.    SetWindowPos(hWnd,HWND_TOP,100,100,300,150,SWP_SHO  WWINDOW);
    82.    return TRUE;
    83. }
    84.    
    85. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    86. {
    87.     int wmId, wmEvent;
    88.     PAINTSTRUCT ps;
    89.     HDC hdc;
    90.     DWORD wb;
    91.     char timert[1024]="";
    92.     switch (message)
    93.     {
    94.     case WM_COMMAND:
    95.         {
    96.         wmId    = LOWORD(wParam);
    97.         wmEvent = HIWORD(wParam);
    98.             if(LOWORD(wParam)==200)
    99.                 {
    100.                     waveInClose(in);
    101.                     CloseHandle(file);
    102.                     recordseconds=0;
    103.                 }
    104.                 if(LOWORD(wParam)==201)
    105.                 {
    106.                        WAVEFORMATEX wf;
    107.                         ZeroMemory(&wf,sizeof(WAVEFORMATEX));
    108.                         wf.cbSize=0;
    109.                         wf.wFormatTag=WAVE_FORMAT_PCM;
    110.                         wf.wBitsPerSample=16;
    111.                         wf.nSamplesPerSec=16000L;
    112.                         wf.nChannels=1;
    113.                         wf.nBlockAlign=2;
    114.                         wf.nAvgBytesPerSec=wf.nSamplesPerSec*wf.nBlockAlig  n;
    115.                         waveInOpen(&in,WAVE_MAPPER,&wf,(DWORD)hWnd,0L, CALLBACK_WINDOW);
    116.                         bufsz=wf.nBlockAlign*wf.nSamplesPerSec;
    117.                         buf=new char[bufsz];
    118.                         wd.dwBufferLength=bufsz;
    119.                         wd.lpData=buf;
    120.                         waveInPrepareHeader(in,&wd,sizeof(WAVEHDR));
    121.                         waveInAddBuffer(in,&wd,sizeof(WAVEHDR));
    122.                         waveInStart(in);
    123.                         file=CreateFileA("rec.wav",GENERIC_WRITE,FILE_SHARE_WRITE,0,CREATE_ALWAYS,FI  LE_ATTRIBUTE_NORMAL,0);
    124.                 }
    125.         }break;
    126.         case WM_CREATE:
    127.             {
    128.                 CreateWindow("button",TEXT("Stop"),WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON ,25,50,70,30,hWnd,(HMENU)200,hInst,NULL);
    129.                 CreateWindow("button",TEXT("Start"),WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON ,200,50,70,30,hWnd,(HMENU)201,hInst,NULL);
    130.             }break;
    131.         case MM_WIM_DATA:
    132.                 {
    133.                     char er[1024];
    134.                     MMRESULT result=0;
    135.                     waveInUnprepareHeader(in, &wd, sizeof(WAVEHDR));
    136.                     SetFilePointer(file,filePosition,NULL,FILE_BEGIN);  
    137.                     filePosition=filePosition+bufsz;
    138.                     WriteFile(file,buf,bufsz,&wb,0);
    139.                     memset(buf,NULL,bufsz);
    140.                     wd.lpData=buf;
    141.                     waveInPrepareHeader(in,&wd,sizeof(WAVEHDR));
    142.                     waveInAddBuffer(in,&wd,sizeof(WAVEHDR));
    143.                     result=waveInStart(in);
    144.                     if(result!=MMSYSERR_NOERROR)
    145.                     {
    146.                         waveInGetErrorText(result,er,1024);
    147.                         MessageBox(hWnd,er,"",MB_OK);
    148.                     }
    149.                     recordseconds++;
    150.                     wsprintf(timert,"ВРЕМЯ ЗАПИСИ:%d",recordseconds);
    151.                     //MessageBox(0,timert,"",MB_OK);
    152.                 }break;
    153.         case WM_NCCREATE:
    154.         {
    155.             LPCREATESTRUCT lpcp=(LPCREATESTRUCT)lParam;
    156.             lpcp->style &= (~WS_MAXIMIZEBOX );
    157.             lpcp->style &= (~WS_SIZEBOX );
    158.             SetWindowLong(hWnd, GWL_STYLE, lpcp->style);
    159.             return true;
    160.         }
    161.         break;
    162.     case WM_PAINT:
    163.         hdc = BeginPaint(hWnd, &ps);
    164.         RECT timeIndic;
    165.         timeIndic.bottom=50;
    166.         timeIndic.left=260;
    167.         timeIndic.right=40;
    168.         timeIndic.top=20;
    169.         DrawText(hdc,timert,1024,&timeIndic,DT_CENTER);
    170.         EndPaint(hWnd, &ps);
    171.         break;
    172.     case WM_DESTROY:
    173.         PostQuitMessage(0);
    174.         break;
    175.     default:
    176.         return DefWindowProc(hWnd, message, wParam, lParam);
    177.     }
    178.     return 0;
    179. }
    Только вот почему то,получаемый файл не читается неодним плеером :dntknw: Подскажите что нетак.
     
  2. skomarov

    skomarov New Member

    Публикаций:
    0
    Регистрация:
    14 май 2008
    Сообщения:
    389
    _nic
    Файлы .wav имеют свой формат. [1]
     
  3. _nic

    _nic New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2007
    Сообщения:
    372
    Издеваешся?
    Что по твоему снимает с микрофона мой код?mp3 что ли?
     
  4. CyberManiac

    CyberManiac New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2003
    Сообщения:
    2.473
    Адрес:
    Russia
    А ни один плеер и не должен. Откуда ему знать, какая у тебя битность звука и частота дискретизации, а без этого колдунства звук играть как-то трудновато. CoolEdit, он же ныне Адобий Audition, умеет читать "сырые" аудифайлы, но частоту и битность ему всё равно придётся показать на пальцах.
     
  5. skomarov

    skomarov New Member

    Публикаций:
    0
    Регистрация:
    14 май 2008
    Сообщения:
    389
    _nic
    Снимает несжатый PCM, а для хранения в файле, как минимум, нужна шапка файла.
     
  6. skomarov

    skomarov New Member

    Публикаций:
    0
    Регистрация:
    14 май 2008
    Сообщения:
    389
    _nic
    По ссылке, которую привел, можно увидеть краткое описание формата.
     
  7. skomarov

    skomarov New Member

    Публикаций:
    0
    Регистрация:
    14 май 2008
    Сообщения:
    389
    _nic
    А здесь выдержки из курсового проекта 1998 года, в котором приведено краткое описание формата, а также исходный код для чтения заголовка .wav файла, содержащего несжатый PCM поток. Формат потока рассчитывается по данным заголовка. Итак, чтобы сохранять данные в .wav файле необходимо поддерживать формат файла. Другой способ, предложенный CyberManiac, заключается в сохранении PCM потока в файл данных с дальнейшим использованием его в CoolEdit, когда при открытии файла указываются параметры потока. Первый способ позволит разобраться с форматом хранения. Второй способ позволит освоить необходимый для анализа аудио данных инструмент. Для серьезного исследования необходимо освоить все эти способы.
    Код (Text):
    1. Формат мультимедийных данных Audio Wav
    2.  
    3. WAV файл использует структуру RIFF файла, который был спроектирован для хранения мультимедиа данных.
    4. Структура файл состоит из набора блоков (chunks).
    5.  
    6. Смещение, байт  Название  Длина, байт Описание
    7. +00h  rId             04h   Содержит строку “RIFF”
    8. +04h  rLen            04h   Размер данных в следующем блоке
    9. +08h  rData           rLen  Следующий блок
    10.  
    11. Смещение в блоке rData, байт  Название  Длина, байт Описание
    12. +00h  wId             04h   Содержит строку “WAVE”
    13. +04h  Format Chunk    18h   Блок параметров, определяющих данные в блоке аудио данных
    14. +1Сh  WAVE Data Chunk ?     Блок аудио данных
    15.  
    16. Смещение в блоке Format Chunk, байт Название  Длина, байт Описание
    17.  00h fId              04h   Содержит строку “fmt “
    18.  04h fLen             04h   Длина данных в блоке параметров
    19.  08h wFormatTag       02h   Формат (1 = Pulse Code Modulation)
    20.  0Ah nChannels        02h   Количество каналов (1=mono,2=stereo)
    21.  0Ch nSamplesPerSec   04h   Частота проигрывания данных
    22.  10h nAvgBytesPerSec  04h   Среднее количество байт проигрываемых в секунду
    23.  14h nBlockAlign      02h   Граница выравнивания данных
    24.  16h wBitsPerSample   02h   Количество бит в группе
    25.  
    26. Некоторые значения в блоке параметров связаны простыми соотношениями:
    27. 1.  nAvgBytesPerSec = nChannels*nSamplesPerSec*(nBitsPerSample/8)
    28. 2.  nBlockAlign = nChannels*(nBitsPerSample/8)
    29.  
    30. Смещение в блоке Data Chunk, байт Название  Длина, байт Описание
    31.  00h dId              04h   Содержит строку “data”
    32.  04h dLen             04h   Размер данных бока dData
    33.  08h dData            dLen  Аудио данные
    34.  
    35. Структура простого заголовка
    36. TWavHeader = record
    37.                              {The RIFF File Format}
    38.   rId: Longint;              {Contains the characters "RIFF"}
    39.   rLen: Longint;             {The length of the data in the next chunk}
    40.                              {The WAVE Form Definition}
    41.   wId: Longint;              {Contains the characters "WAVE"}
    42.                              {The Format Chunk}
    43.   fId: Longint;              {Contains the characters "fmt"}
    44.   fLen: Longint;             {Length of data in the format chunk}
    45.   wFormatTag: Word;
    46.   nChannels: Word;           {Number of channels, 1=mono, 2=stereo}
    47.   nSamplesPerSec: Longint;   {Playback frequency}
    48.   nAvgBytesPerSec: Longint;
    49.   nBlockAlign: Word;
    50.   nBitsPerSample: Word;      {Format specific data area}
    51.                              {The Data Chunk}
    52.   dId: Longint;              {Contains the characters "data"}
    53.   dLen: Longint;             {Length of data in the dData field}
    54. end;
    55.  
    56. Функция чтения .wav файла
    57. procedure LoadWavFile(FileName:string; AudioData:PAudioData);
    58. var
    59.   AudioFile:file;
    60.   NumRead,Count:Integer;
    61.   Header:TWavHeader;
    62.   Buffer:PBArray;
    63.   s:string;
    64. begin
    65.   try
    66.     // check for error
    67.     LastPossibleAudioError:=errReading;
    68.     AssignFile(AudioFile,FileName);
    69.     Reset(AudioFile,1);
    70.     BlockRead(AudioFile,Header,36,NumRead);
    71.     if NumRead<>36 then Abort;
    72.     // check for error
    73.     LastPossibleAudioError:=errData;
    74.     if (Header.rId<>$46464952) then Abort; {Not a RIFF format file}
    75.     if (Header.wId<>$45564157) then Abort; {Not a WAVE format chunk}
    76.     if (Header.fId<>$20746D66) then Abort; {Not a fmt WAVE Format Chunk}
    77.     // check for error
    78.     LastPossibleAudioError:=errOnlyPCM;
    79.     if (Header.wFormatTag<>1)  then Abort; {Data is not PCM}
    80.     // check for error
    81.     LastPossibleAudioError:=errOnlyMono;
    82.     if (Header.nChannels<>1) then Abort; {Must be MONO or STEREO data}
    83.     // check for error
    84.     LastPossibleAudioError:=errBits;
    85.     if not (Header.nBitsPerSample in [8,16]) then Abort; {Must be 8 or 16 bits}
    86.     // check for error
    87.     LastPossibleAudioError:=errReading;
    88.     if (Header.fLen>16) then seek(AudioFile,20+Header.fLen);
    89.     BlockRead(AudioFile,Header.dId,8,NumRead);
    90.     if NumRead<>8 then Abort;
    91.     // check for error
    92.     LastPossibleAudioError:=errData;
    93.     if (Header.dId<>$61746164) then Abort; {Not a DATA chunk}
    94.     // check for error
    95.     LastPossibleAudioError:=errLong;
    96.     if (Header.dLen<1)or(Header.dLen>MaxFileSize) then Abort;
    97.     // check for error
    98.     LastPossibleAudioError:=errNoMemory;
    99.     s:=IntToStr(Header.nBitsPerSample)+'-bit ';
    100.     if Header.nChannels=1
    101.       then s:=Concat(s,'mono')
    102.       else s:=Concat(s,'stereo');
    103.     AudioData^.info:=Concat(s,' ',IntToStr(Header.nSamplesPerSec),'Hz ');
    104.     AudioData^.freq:=Header.nSamplesPerSec;
    105.   finally
    106.     CloseFile(AudioFile);
    107.   end;
    108. end;
     
  8. fragment

    fragment New Member

    Публикаций:
    0
    Регистрация:
    11 июн 2008
    Сообщения:
    266
    Где-то на прасторах интернета видел статью, куски кода, как снимать звук с микрофона с помощью апи.
     
  9. _nic

    _nic New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2007
    Сообщения:
    372
    Спасибо.Выходной файл удается вопроизвести средсвами winapi.Надо было мне сразу так и попробовать :)
    ЗЫ:Только вот неясно как задать чуствительность микрофону??
     
  10. fragment

    fragment New Member

    Публикаций:
    0
    Регистрация:
    11 июн 2008
    Сообщения:
    266
    В виндовсе есть чуствительность [​IMG]
    наверное это гдето в реестре и можно , я так думаю , узнать какие ключи реестра и какие функции использует стандартная программа настройки и действовать по аналогии, может есть вообще специальная либа подхватывающая ети натройки
     
  11. _nic

    _nic New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2007
    Сообщения:
    372
    Набиваешь посты или незнаешь для чего этот форум? Мне это надо сделать ПРОГРАММНО!
     
  12. fragment

    fragment New Member

    Публикаций:
    0
    Регистрация:
    11 июн 2008
    Сообщения:
    266
    я понмаю что руками ты ето зделать не можешь.
     
  13. bolkin

    bolkin New Member

    Публикаций:
    0
    Регистрация:
    5 июл 2005
    Сообщения:
    34
    Адрес:
    Israel
    mixerSetControlDetails

    http://pcbunn.cithep.caltech.edu/jjb/MixerControl.txt

    Но в висте видимо уже не работает.