Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygensndrec32.cpp
Go to the documentation of this file.
00001 /* PROJECT: ReactOS sndrec32 00002 * LICENSE: GPL - See COPYING in the top level directory 00003 * FILE: base/applications/sndrec32/sndrec32.cpp 00004 * PURPOSE: Sound recording 00005 * PROGRAMMERS: Marco Pagliaricci (irc: rendar) 00006 */ 00007 00008 #ifndef _UNICODE 00009 #define gprintf _snprintf 00010 #else 00011 #define gprintf _snwprintf 00012 #endif 00013 00014 #include "stdafx.h" 00015 #include "sndrec32.h" 00016 00017 00018 00019 00020 00021 HINSTANCE hInst; 00022 TCHAR szTitle[MAX_LOADSTRING]; 00023 TCHAR szWindowClass[MAX_LOADSTRING]; 00024 00025 00026 ATOM MyRegisterClass( HINSTANCE hInstance ); 00027 ATOM MyRegisterClass_wave( HINSTANCE hInstance ); 00028 BOOL InitInstance( HINSTANCE, int ); 00029 BOOL InitInstance_wave( HWND, HINSTANCE, int ); 00030 LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM ); 00031 LRESULT CALLBACK WndProc_wave( HWND, UINT, WPARAM, LPARAM ); 00032 00033 BOOL win_first, wout_first; 00034 00035 HWND main_win; 00036 HWND wave_win; 00037 HWND slider; 00038 HWND buttons[5]; 00039 HBITMAP butbmps[5]; 00040 HBITMAP butbmps_dis[5]; 00041 WNDPROC buttons_std_proc; 00042 00043 BOOL butdisabled[5]; 00044 BOOL stopped_flag; 00045 BOOL isnew; 00046 BOOL display_dur; 00047 00048 00049 DWORD slider_pos; 00050 WORD slider_min; 00051 WORD slider_max; 00052 00053 DWORD samples_max; 00054 00055 OPENFILENAME ofn; 00056 TCHAR file_path[MAX_PATH]; 00057 TCHAR str_pos[MAX_LOADSTRING]; 00058 TCHAR str_dur[MAX_LOADSTRING]; 00059 TCHAR str_buf[MAX_LOADSTRING]; 00060 TCHAR str_fmt[MAX_LOADSTRING]; 00061 TCHAR str_chan[MAX_LOADSTRING]; 00062 00063 TCHAR str_mono[10]; 00064 TCHAR str_stereo[10]; 00065 00066 BOOL path_set; 00067 00068 snd::audio_membuffer * AUD_BUF; 00069 snd::audio_waveout * AUD_OUT; 00070 snd::audio_wavein * AUD_IN; 00071 00072 00073 BOOL s_recording; 00074 00075 00076 NONCLIENTMETRICS s_info; 00077 00078 00079 RECT text_rect; 00080 RECT text2_rect; 00081 RECT cli; 00082 00083 00084 INT_PTR CALLBACK AboutDlgProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) 00085 { 00086 switch (msg) 00087 { 00088 case WM_COMMAND: 00089 switch (LOWORD(wp)) 00090 { 00091 case IDOK: 00092 EndDialog(hWnd, 0); 00093 return TRUE; 00094 } 00095 break; 00096 case WM_CLOSE: 00097 EndDialog(hWnd, 0); 00098 return TRUE; 00099 } 00100 return FALSE; 00101 } 00102 00103 00104 00105 int APIENTRY _tWinMain(HINSTANCE hInstance, 00106 HINSTANCE hPrevInstance, 00107 LPTSTR lpCmdLine, 00108 int nCmdShow) 00109 { 00110 00111 UNREFERENCED_PARAMETER(hPrevInstance); 00112 UNREFERENCED_PARAMETER(lpCmdLine); 00113 00114 00115 MSG msg; 00116 HACCEL hAccelTable; 00117 00118 s_info.cbSize = sizeof( NONCLIENTMETRICS ); 00119 00120 InitCommonControls(); 00121 00122 win_first = wout_first = FALSE; 00123 00124 text_rect.left = REFRESHA_X; 00125 text_rect.top = REFRESHA_Y; 00126 text_rect.right = REFRESHA_CX; 00127 text_rect.bottom = REFRESHA_CY; 00128 00129 text2_rect.left = REFRESHB_X; 00130 text2_rect.top = REFRESHB_Y; 00131 text2_rect.right = REFRESHB_CX; 00132 text2_rect.bottom = REFRESHB_CY; 00133 00134 // 00135 // Retrieving defaul system font, and others 00136 // system informations. 00137 // 00138 00139 SystemParametersInfo( 00140 SPI_GETNONCLIENTMETRICS, 00141 sizeof( NONCLIENTMETRICS ), 00142 &s_info, 00143 0 00144 ); 00145 00146 // 00147 // Set font size 00148 // 00149 00150 s_info.lfMenuFont.lfHeight = 14; 00151 00152 // 00153 // Inits buttons bitmaps 00154 // 00155 00156 butbmps[0] = LoadBitmap( hInstance, MAKEINTRESOURCE( IDB_BITMAP2_START )); 00157 butbmps[1] = LoadBitmap( hInstance, MAKEINTRESOURCE( IDB_BITMAP2_END )); 00158 butbmps[2] = LoadBitmap( hInstance, MAKEINTRESOURCE( IDB_BITMAP2_PLAY )); 00159 butbmps[3] = LoadBitmap( hInstance, MAKEINTRESOURCE( IDB_BITMAP2_STOP )); 00160 butbmps[4] = LoadBitmap( hInstance, MAKEINTRESOURCE( IDB_BITMAP2_REC )); 00161 00162 butbmps_dis[0] = LoadBitmap( hInstance, MAKEINTRESOURCE( IDB_BITMAP2_START_DIS )); 00163 butbmps_dis[1] = LoadBitmap( hInstance, MAKEINTRESOURCE( IDB_BITMAP2_END_DIS )); 00164 butbmps_dis[2] = LoadBitmap( hInstance, MAKEINTRESOURCE( IDB_BITMAP2_PLAY_DIS )); 00165 butbmps_dis[3] = LoadBitmap( hInstance, MAKEINTRESOURCE( IDB_BITMAP2_STOP_DIS )); 00166 butbmps_dis[4] = LoadBitmap( hInstance, MAKEINTRESOURCE( IDB_BITMAP2_REC_DIS )); 00167 00168 00169 00170 // 00171 // Inits audio devices and buffers 00172 // 00173 00174 snd::audio_membuffer AUD_buffer( snd::A44100_16BIT_STEREO ); 00175 snd::audio_waveout AUD_waveout( snd::A44100_16BIT_STEREO, AUD_buffer ); 00176 snd::audio_wavein AUD_wavein( snd::A44100_16BIT_STEREO, AUD_buffer ); 00177 00178 AUD_buffer.play_finished = l_play_finished; 00179 AUD_buffer.audio_arrival = l_audio_arrival; 00180 AUD_buffer.buffer_resized = l_buffer_resized; 00181 00182 AUD_buffer.alloc_seconds( INITIAL_BUFREC_SECONDS ); 00183 00184 AUD_IN = &AUD_wavein; 00185 AUD_OUT = &AUD_waveout; 00186 AUD_BUF = &AUD_buffer; 00187 00188 // 00189 // Inits slider default parameters 00190 // 00191 00192 slider_pos = 0; 00193 slider_min = 0; 00194 slider_max = SLIDER_W; 00195 00196 00197 stopped_flag = FALSE; 00198 path_set = FALSE; 00199 isnew = TRUE; 00200 display_dur = TRUE; 00201 00202 samples_max = AUD_buffer.total_samples(); 00203 00204 s_recording = false; 00205 00206 // 00207 // Inits strings 00208 // 00209 00210 LoadString( hInstance, 00211 IDS_APP_TITLE, szTitle, MAX_LOADSTRING ); 00212 00213 LoadString( hInstance, 00214 IDC_REACTOS_SNDREC32, szWindowClass, MAX_LOADSTRING ); 00215 00216 00217 LoadString( hInstance, 00218 IDS_STRPOS, str_pos, MAX_LOADSTRING ); 00219 00220 00221 LoadString( hInstance, 00222 IDS_STRDUR, str_dur, MAX_LOADSTRING ); 00223 00224 LoadString( hInstance, 00225 IDS_STRBUF, str_buf, MAX_LOADSTRING ); 00226 00227 LoadString( hInstance, 00228 IDS_STRFMT, str_fmt, MAX_LOADSTRING ); 00229 00230 LoadString( hInstance, 00231 IDS_STRCHAN, str_chan, MAX_LOADSTRING ); 00232 00233 LoadString( hInstance, 00234 IDS_STRMONO, str_mono, 10 ); 00235 00236 LoadString( hInstance, 00237 IDS_STRSTEREO, str_stereo, 10 ); 00238 00239 00240 // 00241 // Registers sndrec32 window class 00242 // 00243 00244 MyRegisterClass( hInstance ); 00245 00246 MyRegisterClass_wave( hInstance ); 00247 00248 00249 if ( !InitInstance( hInstance, nCmdShow )) 00250 { 00251 MessageBox( 0, TEXT( "CreateWindow() Error!" ), TEXT( "ERROR" ), MB_ICONERROR ); 00252 return FALSE; 00253 } 00254 00255 // 00256 // Loads key accelerators 00257 // 00258 00259 hAccelTable = LoadAccelerators(hInstance, 00260 MAKEINTRESOURCE( IDC_REACTOS_SNDREC32 )); 00261 00262 00263 00264 // 00265 // Starts main loop 00266 // 00267 00268 while ( GetMessage( &msg, NULL, 0, 0 )) 00269 { 00270 if ( !TranslateAccelerator( msg.hwnd, hAccelTable, &msg )) 00271 { 00272 TranslateMessage( &msg ); 00273 DispatchMessage( &msg ); 00274 } 00275 } 00276 00277 if ( wout_first ) 00278 { 00279 AUD_waveout.close(); 00280 00281 } 00282 00283 00284 if ( win_first ) 00285 { 00286 AUD_wavein.close(); 00287 00288 } 00289 00290 AUD_buffer.clear(); 00291 00292 return ( int )msg.wParam; 00293 } 00294 00295 00296 00297 00298 ATOM 00299 MyRegisterClass( HINSTANCE hInstance ) 00300 { 00301 WNDCLASSEX wcex; 00302 00303 wcex.cbSize = sizeof(WNDCLASSEX); 00304 00305 wcex.style = CS_HREDRAW | CS_VREDRAW; 00306 wcex.lpfnWndProc = WndProc; 00307 wcex.cbClsExtra = 0; 00308 wcex.cbWndExtra = 0; 00309 wcex.hInstance = hInstance; 00310 wcex.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE( IDI_SNDREC32 )); 00311 wcex.hCursor = LoadCursor( NULL, IDC_ARROW ); 00312 wcex.hbrBackground = GetSysColorBrush(COLOR_BTNFACE); 00313 wcex.lpszMenuName = MAKEINTRESOURCE( IDR_MENU1 ); 00314 wcex.lpszClassName = szWindowClass; 00315 wcex.hIconSm = LoadIcon( wcex.hInstance, MAKEINTRESOURCE( IDI_SNDREC32 )); 00316 00317 00318 return RegisterClassEx( &wcex ); 00319 } 00320 00321 BOOL 00322 InitInstance( HINSTANCE hInstance, int nCmdShow ) 00323 { 00324 HWND hWnd; 00325 00326 hInst = hInstance; 00327 00328 hWnd = CreateWindow( 00329 szWindowClass, 00330 szTitle, 00331 WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, 00332 CW_USEDEFAULT, 00333 CW_USEDEFAULT, 00334 MAINWINDOW_W, 00335 MAINWINDOW_H, 00336 NULL, NULL, 00337 hInstance, NULL 00338 ); 00339 00340 if (!hWnd) 00341 { 00342 return FALSE; 00343 } 00344 00345 ShowWindow(hWnd, nCmdShow); 00346 UpdateWindow(hWnd); 00347 00348 main_win = hWnd; 00349 00350 00351 return TRUE; 00352 } 00353 00354 00355 00356 00357 00358 ATOM 00359 MyRegisterClass_wave( HINSTANCE hInstance ) 00360 { 00361 WNDCLASSEX wcex; 00362 00363 wcex.cbSize = sizeof( WNDCLASSEX ); 00364 00365 wcex.style = CS_HREDRAW | CS_VREDRAW; 00366 wcex.lpfnWndProc = WndProc_wave; 00367 wcex.cbClsExtra = 0; 00368 wcex.cbWndExtra = 0; 00369 wcex.hInstance = hInstance; 00370 wcex.hIcon = 0; 00371 wcex.hCursor = LoadCursor( NULL, IDC_ARROW ); 00372 wcex.hbrBackground = ( HBRUSH )GetStockObject( BLACK_BRUSH ); 00373 wcex.lpszMenuName = 0; 00374 wcex.lpszClassName = TEXT( "sndrec32_wave" ); 00375 wcex.hIconSm = 0; 00376 00377 00378 return RegisterClassEx( &wcex ); 00379 } 00380 00381 BOOL 00382 InitInstance_wave( HWND f, HINSTANCE hInstance, int nCmdShow ) 00383 { 00384 HWND hWnd; 00385 00386 hInst = hInstance; 00387 00388 hWnd = CreateWindow( 00389 TEXT( "sndrec32_wave" ), 00390 TEXT(""), 00391 WS_DLGFRAME|WS_VISIBLE|WS_CHILD, 00392 WAVEBAR_X, 00393 WAVEBAR_Y, 00394 WAVEBAR_CX, 00395 WAVEBAR_CY, 00396 f, ( HMENU ) 8, 00397 hInstance, 0 00398 ); 00399 00400 if ( !hWnd ) 00401 { 00402 return FALSE; 00403 } 00404 00405 ShowWindow( hWnd, nCmdShow ); 00406 UpdateWindow( hWnd ); 00407 00408 wave_win = hWnd; 00409 00410 00411 return TRUE; 00412 } 00413 00414 00415 LRESULT CALLBACK 00416 WndProc_wave( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) 00417 { 00418 PAINTSTRUCT ps; 00419 HDC hdc; 00420 HPEN pen; 00421 00422 00423 00424 unsigned int max_h = ( cli.bottom / 2 ); 00425 unsigned int samples; 00426 unsigned int x, line_h; 00427 00428 00429 00430 switch ( message ) 00431 { 00432 00433 00434 case WM_CREATE: 00435 00436 00437 GetClientRect( hWnd, &cli ); 00438 00439 break; 00440 00441 00442 case WM_PAINT: 00443 00444 // 00445 // Initialize hdc objects 00446 // 00447 00448 hdc = BeginPaint( hWnd, &ps ); 00449 00450 pen = ( HPEN ) CreatePen( PS_SOLID, 1, WAVEBAR_COLOR ); 00451 00452 SelectObject( hdc, ( HBRUSH )pen ); 00453 00454 if ( AUD_OUT->current_status() == snd::WAVEOUT_PLAYING ) 00455 { 00456 00457 samples = AUD_OUT->tot_samples_buf(); 00458 00459 00460 for ( unsigned int i = 0; i < WAVEBAR_CX; ++i ) 00461 { 00462 00463 x = ( i * samples ) / WAVEBAR_CX; 00464 00465 line_h = ( AUD_OUT->nsample( x ) * max_h ) / AUD_OUT->samplevalue_max(); 00466 00467 00468 if ( line_h ) 00469 { 00470 MoveToEx( hdc, i, max_h, 0 ); 00471 LineTo( hdc, i, max_h - ( line_h * 2 )); 00472 LineTo( hdc, i, max_h + ( line_h * 2 )); 00473 } else 00474 SetPixel( hdc, i, max_h, WAVEBAR_COLOR ); 00475 00476 } 00477 00478 00479 } else if ( AUD_IN->current_status() == snd::WAVEIN_RECORDING ) { 00480 00481 00482 samples = AUD_IN->tot_samples_buf(); 00483 00484 00485 for ( unsigned int i = 0; i < WAVEBAR_CX; ++i ) 00486 { 00487 00488 x = ( i * samples ) / WAVEBAR_CX; 00489 00490 line_h = ( AUD_IN->nsample( x ) * max_h ) / AUD_IN->samplevalue_max(); 00491 00492 00493 if ( line_h ) 00494 { 00495 MoveToEx( hdc, i, max_h, 0 ); 00496 LineTo( hdc, i, max_h - ( line_h * 2 )); 00497 LineTo( hdc, i, max_h + ( line_h * 2 )); 00498 } else 00499 SetPixel( hdc, i, max_h, WAVEBAR_COLOR ); 00500 00501 } 00502 00503 00504 } else { 00505 00506 // 00507 // In standby mode draw a simple line. 00508 // 00509 00510 MoveToEx( hdc, 0, cli.bottom / 2, 0 ); 00511 LineTo( hdc, WAVEBAR_CX, cli.bottom / 2 ); 00512 00513 } 00514 00515 00516 DeleteObject( pen ); 00517 00518 EndPaint( hWnd, &ps ); 00519 00520 break; 00521 00522 00523 case WM_USER: 00524 00525 00526 break; 00527 00528 00529 default: 00530 return DefWindowProc( hWnd, message, wParam, lParam ); 00531 00532 00533 } 00534 00535 00536 return 0; 00537 00538 } 00539 00540 00541 00542 LRESULT CALLBACK 00543 WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) 00544 { 00545 int wmId; 00546 TCHAR str_tmp[MAX_LOADSTRING]; 00547 PAINTSTRUCT ps; 00548 HDC hdc; 00549 HFONT font; 00550 long long slid_samp = 0; 00551 00552 00553 00554 // 00555 // Checking for global pointers to buffer and 00556 // io audio devices. 00557 // 00558 00559 if (( !AUD_IN ) || ( !AUD_OUT ) || ( !AUD_BUF )) 00560 { 00561 MessageBox( 0, TEXT("Buffer Error"), 0, 0 ); 00562 return 1; 00563 } 00564 00565 00566 switch ( message ) 00567 { 00568 00569 00570 case WM_CREATE: 00571 00572 00573 // 00574 // Creating the wave bar 00575 // 00576 00577 if ( !InitInstance_wave( hWnd, hInst, SW_SHOWNORMAL )) 00578 { 00579 MessageBox( 00580 0, 00581 TEXT( "CreateWindow() Error!" ), 00582 TEXT( "ERROR" ), 00583 MB_ICONERROR 00584 ); 00585 00586 return FALSE; 00587 } 00588 00589 00590 00591 00592 // 00593 // Creating ALL the buttons 00594 // 00595 00596 for ( int i = 0; i < 5; ++ i ) 00597 { 00598 00599 buttons[i] = CreateWindow( 00600 TEXT("button"), 00601 TEXT(""), 00602 WS_CHILD|WS_VISIBLE|BS_BITMAP, 00603 BUTTONS_CX + ( i * (BUTTONS_W+((i == 0)?0:BUTTONS_SPACE))), 00604 BUTTONS_CY, BUTTONS_W, BUTTONS_H, hWnd, 00605 (HMENU)i, hInst, 0 00606 ); 00607 00608 if ( !buttons[i] ) 00609 { 00610 MessageBox(0, 0, TEXT("CreateWindow() Error!"), 0); 00611 return FALSE; 00612 00613 } 00614 00615 00616 // 00617 // Realize the button bmp image 00618 // 00619 00620 SendMessage(buttons[i], BM_SETIMAGE, ( WPARAM )IMAGE_BITMAP, ( LPARAM )butbmps[i]); 00621 00622 UpdateWindow( buttons[i] ); 00623 00624 disable_but( i ); 00625 00626 } 00627 00628 00629 // 00630 // Creating the SLIDER window 00631 // 00632 00633 slider = CreateWindow( 00634 TRACKBAR_CLASS, 00635 TEXT(""), 00636 WS_CHILD|WS_VISIBLE|TBS_NOTICKS|TBS_HORZ|TBS_ENABLESELRANGE, 00637 SLIDER_CX, SLIDER_CY, SLIDER_W, SLIDER_H, hWnd, 00638 ( HMENU )SLIDER_ID, hInst, 0 00639 ); 00640 00641 00642 if ( !slider ) 00643 { 00644 MessageBox( 0, 0, TEXT( "CreateWindow() Error!" ), 0 ); 00645 return FALSE; 00646 00647 } 00648 00649 00650 // 00651 // Sets slider limits 00652 // 00653 00654 00655 SendMessage( 00656 slider, 00657 TBM_SETRANGE, 00658 ( WPARAM )TRUE, 00659 ( LPARAM )MAKELONG( slider_min, slider_max ) 00660 ); 00661 00662 00663 UpdateWindow( slider ); 00664 00665 enable_but( BUTREC_ID ); 00666 00667 EnableWindow( slider, FALSE ); 00668 00669 00670 00671 00672 break; 00673 00674 00675 00676 // 00677 // Implements slider logic 00678 // 00679 00680 case WM_HSCROLL : 00681 { 00682 switch( LOWORD( wParam )) 00683 { 00684 00685 case SB_ENDSCROLL: 00686 break; 00687 00688 case SB_PAGERIGHT: 00689 case SB_PAGELEFT: 00690 case TB_THUMBTRACK: 00691 00692 00693 // 00694 // If the user touch the slider bar, 00695 // set the audio start position properly 00696 // 00697 00698 00699 slider_pos = SendMessage( slider, TBM_GETPOS, 0, 0 ); 00700 00701 slid_samp = ( __int64 )slider_pos * ( __int64 )samples_max; 00702 00703 AUD_BUF->set_position( 00704 AUD_BUF->audinfo().bytes_in_samples( 00705 ( unsigned int )( slid_samp / ( __int64 )slider_max ) 00706 ) 00707 ); 00708 00709 InvalidateRect( hWnd, &text_rect, TRUE ); 00710 00711 00712 break; 00713 00714 } 00715 00716 break; 00717 } 00718 00719 00720 00721 00722 00723 00724 case WM_COMMAND: 00725 00726 wmId = LOWORD( wParam ); 00727 00728 if (( wmId >= 0 ) && ( wmId < 5 ) && ( butdisabled[wmId] == TRUE )) 00729 break; 00730 00731 switch ( wmId ) 00732 { 00733 00734 case ID_NEW: 00735 00736 if ( !isnew ) 00737 { 00738 00739 if ( AUD_IN->current_status() == snd::WAVEIN_RECORDING ) 00740 AUD_IN->stop_recording(); 00741 00742 00743 if (( AUD_OUT->current_status() == snd::WAVEOUT_PLAYING ) || 00744 ( AUD_OUT->current_status() == snd::WAVEOUT_PAUSED )) 00745 AUD_OUT->stop(); 00746 00747 00748 AUD_BUF->reset(); 00749 00750 enable_but( BUTREC_ID ); 00751 disable_but( BUTSTART_ID ); 00752 disable_but( BUTEND_ID ); 00753 disable_but( BUTSTOP_ID ); 00754 disable_but( BUTPLAY_ID ); 00755 00756 00757 samples_max = AUD_BUF->total_samples(); 00758 slider_pos = 0; 00759 00760 SendMessage(slider, TBM_SETPOS, (WPARAM) TRUE, (LPARAM) slider_pos); 00761 00762 EnableMenuItem( GetMenu( hWnd ), ID_FILE_SAVEAS, MF_GRAYED ); 00763 EnableMenuItem( GetMenu( hWnd ), ID_FILE_SAVE, MF_GRAYED ); 00764 00765 isnew = TRUE; 00766 display_dur = TRUE; 00767 00768 ZeroMemory( file_path, MAX_PATH * sizeof(TCHAR) ); 00769 00770 EnableWindow( slider, FALSE ); 00771 00772 InvalidateRect( hWnd, &text_rect, TRUE ); 00773 InvalidateRect( hWnd, &text2_rect, TRUE ); 00774 00775 } 00776 00777 00778 00779 break; 00780 00781 00782 00783 00784 case ID_FILE_OPEN: 00785 00786 ZeroMemory( &ofn, sizeof( ofn )); 00787 00788 ofn.lStructSize = sizeof( ofn ); 00789 ofn.hwndOwner = hWnd; 00790 ofn.lpstrFilter = TEXT("Audio Files (*.wav)\0*.wav\0All Files (*.*)\0*.*\0"); 00791 ofn.lpstrFile = file_path; 00792 ofn.nMaxFile = MAX_PATH; 00793 ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; 00794 ofn.lpstrDefExt = TEXT("wav"); 00795 00796 if( GetOpenFileName( &ofn )) 00797 { 00798 open_wav( file_path ); 00799 EnableMenuItem( GetMenu( hWnd ), ID_FILE_SAVE, MF_ENABLED ); 00800 EnableMenuItem( GetMenu( hWnd ), ID_FILE_SAVEAS, MF_ENABLED ); 00801 00802 EnableWindow( slider, TRUE ); 00803 00804 } 00805 00806 InvalidateRect( hWnd, &text_rect, TRUE ); 00807 InvalidateRect( hWnd, &text2_rect, TRUE ); 00808 00809 break; 00810 00811 00812 00813 00814 case ID__ABOUT: 00815 00816 DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, AboutDlgProc); 00817 return TRUE; 00818 break; 00819 00820 00821 case ID_FILE_SAVEAS: 00822 00823 ZeroMemory( &ofn, sizeof( ofn )); 00824 00825 ofn.lStructSize = sizeof( ofn ); 00826 ofn.hwndOwner = hWnd ; 00827 ofn.Flags = OFN_OVERWRITEPROMPT; 00828 ofn.lpstrFilter = TEXT("Audio Files (*.wav)\0*.wav\0All Files (*.*)\0*.*\0"); 00829 ofn.lpstrFile = file_path; 00830 ofn.nMaxFile = MAX_PATH; 00831 00832 ofn.lpstrDefExt = TEXT("wav"); 00833 00834 if ( GetSaveFileName ( &ofn )) 00835 { 00836 write_wav( file_path ); 00837 00838 EnableMenuItem( GetMenu( hWnd ), ID_FILE_SAVE, MF_ENABLED ); 00839 } 00840 00841 break; 00842 00843 case ID_EXIT: 00844 DestroyWindow( hWnd ); 00845 break; 00846 00847 00848 // 00849 // Sndrec32 buttons routines 00850 // 00851 00852 case BUTSTART_ID: 00853 00854 AUD_BUF->set_position_start(); 00855 00856 slider_pos = 0; 00857 00858 SendMessage( slider, TBM_SETPOS, (WPARAM) TRUE, (LPARAM) slider_pos ); 00859 00860 break; 00861 00862 00863 case BUTEND_ID: 00864 DestroyWindow( hWnd ); 00865 break; 00866 00867 case BUTPLAY_ID: 00868 00869 if ( wout_first == false ) 00870 { 00871 AUD_OUT->open(); 00872 wout_first = true; 00873 } 00874 00875 00876 AUD_OUT->play(); 00877 00878 disable_but( BUTSTART_ID ); 00879 disable_but( BUTEND_ID ); 00880 disable_but( BUTREC_ID ); 00881 disable_but( BUTPLAY_ID ); 00882 00883 00884 SetTimer( hWnd, 1, 250, 0 ); 00885 SetTimer( hWnd, WAVEBAR_TIMERID, WAVEBAR_TIMERTIME, 0 ); 00886 00887 break; 00888 00889 case BUTSTOP_ID: 00890 if ( s_recording ) 00891 { 00892 s_recording = FALSE; 00893 00894 AUD_IN->stop_recording(); 00895 00896 00897 00898 // 00899 // Resetting slider position 00900 // 00901 00902 slider_pos = 0; 00903 SendMessage(slider, TBM_SETPOS, (WPARAM) TRUE, (LPARAM) slider_pos); 00904 00905 00906 samples_max = AUD_BUF->samples_received(); 00907 00908 EnableMenuItem((HMENU)IDR_MENU1, ID_FILE_SAVEAS, MF_ENABLED ); 00909 00910 00911 enable_but( BUTSTART_ID ); 00912 enable_but( BUTEND_ID ); 00913 enable_but( BUTREC_ID ); 00914 enable_but( BUTPLAY_ID ); 00915 00916 EnableMenuItem( GetMenu( hWnd ), ID_FILE_SAVEAS, MF_ENABLED ); 00917 EnableWindow( slider, TRUE ); 00918 00919 display_dur = FALSE; 00920 00921 AUD_BUF->truncate(); 00922 00923 InvalidateRect( hWnd, &text_rect, TRUE ); 00924 InvalidateRect( wave_win, 0, TRUE ); 00925 00926 00927 } else { 00928 00929 AUD_OUT->pause(); 00930 00931 enable_but( BUTSTART_ID ); 00932 enable_but( BUTEND_ID ); 00933 enable_but( BUTREC_ID ); 00934 enable_but( BUTPLAY_ID ); 00935 00936 } 00937 00938 KillTimer( hWnd, 1 ); 00939 KillTimer( hWnd, WAVEBAR_TIMERID ); 00940 00941 InvalidateRect( hWnd, &text_rect, TRUE ); 00942 00943 break; 00944 00945 case BUTREC_ID: 00946 00947 if ( win_first == false ) 00948 { 00949 AUD_IN->open(); 00950 win_first = true; 00951 } 00952 00953 s_recording = TRUE; 00954 00955 samples_max = AUD_BUF->total_samples(); 00956 00957 AUD_IN->start_recording(); 00958 00959 enable_but( BUTSTOP_ID ); 00960 00961 disable_but( BUTSTART_ID ); 00962 disable_but( BUTEND_ID ); 00963 disable_but( BUTREC_ID ); 00964 disable_but( BUTPLAY_ID ); 00965 00966 isnew = FALSE; 00967 00968 EnableWindow( slider, FALSE ); 00969 00970 SetTimer( hWnd, 1, 150, 0 ); 00971 00972 SetTimer( hWnd, WAVEBAR_TIMERID, WAVEBAR_TIMERTIME, 0 ); 00973 00974 break; 00975 00976 00977 default: 00978 return DefWindowProc(hWnd, message, wParam, lParam); 00979 } 00980 break; 00981 00982 00983 case WM_TIMER: 00984 00985 switch ( wParam ) 00986 { 00987 00988 case 1: 00989 if ( stopped_flag ) 00990 { 00991 KillTimer( hWnd, 1 ); 00992 KillTimer( hWnd, WAVEBAR_TIMERID ); 00993 slider_pos = 0; 00994 00995 enable_but( BUTPLAY_ID ); 00996 00997 stopped_flag = FALSE; 00998 } 00999 01000 01001 01002 SendMessage( 01003 slider, 01004 TBM_SETPOS, 01005 ( WPARAM ) TRUE, 01006 ( LPARAM ) slider_pos 01007 ); 01008 01009 InvalidateRect( hWnd, &text_rect, TRUE ); 01010 break; 01011 01012 01013 01014 case WAVEBAR_TIMERID: 01015 InvalidateRect( wave_win, 0, TRUE ); 01016 SendMessage( wave_win, WM_USER, 0, 0 ); 01017 break; 01018 01019 } 01020 01021 break; 01022 01023 01024 01025 case WM_PAINT: 01026 01027 01028 hdc = BeginPaint(hWnd, &ps); 01029 01030 01031 font = CreateFontIndirect( &s_info.lfMenuFont ); 01032 01033 01034 SelectObject( hdc, font ); 01035 01036 SetBkMode( hdc, TRANSPARENT ); 01037 01038 01039 if ( AUD_IN->current_status() == snd::WAVEIN_RECORDING ) 01040 { 01041 gprintf( 01042 str_tmp, 01043 MAX_LOADSTRING, 01044 str_pos, 01045 ( float )(( float )AUD_BUF->bytes_recorded( ) / ( float )AUD_BUF->audinfo().byte_rate( )) 01046 ); 01047 01048 } else if ( AUD_OUT->current_status() == snd::WAVEOUT_PLAYING ) { 01049 01050 gprintf( 01051 str_tmp, 01052 MAX_LOADSTRING, 01053 str_pos, 01054 ( float )(( float )AUD_BUF->bytes_played() / ( float )AUD_BUF->audinfo().byte_rate( )) 01055 ); 01056 01057 } else { 01058 01059 gprintf( 01060 str_tmp, 01061 MAX_LOADSTRING, 01062 str_pos, 01063 ( float )(((( float )slider_pos * ( float )samples_max ) / ( float )slider_max ) / ( float )AUD_BUF->audinfo().sample_rate()) 01064 ); 01065 } 01066 01067 01068 ExtTextOut( hdc, STRPOS_X, STRPOS_Y, ETO_OPAQUE, 01069 0, str_tmp, _tcslen( str_tmp ), 0 ); 01070 01071 01072 if ( display_dur ) 01073 { 01074 01075 gprintf( str_tmp, MAX_LOADSTRING, str_dur, 01076 AUD_BUF->fseconds_total( )); 01077 01078 } else { 01079 01080 01081 gprintf( str_tmp, MAX_LOADSTRING, str_dur, 01082 AUD_BUF->fseconds_recorded( )); 01083 } 01084 01085 01086 01087 ExtTextOut( hdc, STRDUR_X, STRDUR_Y, ETO_OPAQUE, 01088 0, str_tmp, _tcslen( str_tmp ), 0 ); 01089 01090 01091 01092 gprintf( 01093 str_tmp, 01094 MAX_LOADSTRING, 01095 str_buf, 01096 ( float )(( float )AUD_BUF->mem_size() / 1024.0f ) 01097 ); 01098 01099 01100 ExtTextOut( hdc, STRBUF_X, STRBUF_Y, ETO_OPAQUE, 01101 0, str_tmp, _tcslen( str_tmp ), 0 ); 01102 01103 01104 01105 gprintf( 01106 str_tmp, 01107 MAX_LOADSTRING, 01108 str_fmt, 01109 ( float )(( float )AUD_BUF->audinfo().sample_rate() / 1000.0f ), 01110 AUD_BUF->audinfo().bits(), 01111 AUD_BUF->audinfo().channels() == 2 ? str_mono : str_stereo 01112 ); 01113 01114 01115 ExtTextOut( hdc, STRFMT_X, STRFMT_Y, ETO_OPAQUE, 01116 0, str_tmp, _tcslen( str_tmp ), 0 ); 01117 01118 01119 01120 gprintf( 01121 str_tmp, 01122 MAX_LOADSTRING, 01123 str_chan, 01124 AUD_BUF->audinfo().channels() == 2 ? str_stereo : str_mono 01125 ); 01126 01127 01128 ExtTextOut( hdc, STRCHAN_X, STRCHAN_Y, ETO_OPAQUE, 01129 0, str_tmp, _tcslen( str_tmp ), 0 ); 01130 01131 01132 01133 DeleteObject( font ); 01134 01135 EndPaint(hWnd, &ps); 01136 01137 01138 break; 01139 01140 01141 01142 01143 case WM_DESTROY: 01144 PostQuitMessage(0); 01145 break; 01146 default: 01147 return DefWindowProc( hWnd, message, wParam, lParam ); 01148 } 01149 return 0; 01150 } 01151 01152 01153 01154 01155 01156 void l_play_finished ( void ) 01157 { 01158 01159 stopped_flag = true; 01160 01161 01162 enable_but( BUTSTART_ID ); 01163 enable_but( BUTEND_ID ); 01164 enable_but( BUTREC_ID ); 01165 enable_but( BUTPLAY_ID ); 01166 01167 InvalidateRect( wave_win, 0, TRUE ); 01168 01169 } 01170 01171 void l_audio_arrival ( unsigned int samples_arrival ) 01172 { 01173 01174 01175 slider_pos += ( DWORD ) (( slider_max * samples_arrival ) / samples_max ); 01176 01177 01178 } 01179 01180 void l_buffer_resized ( unsigned int new_size ) 01181 { 01182 01183 01184 01185 01186 01187 } 01188 01189 VOID enable_but( DWORD id ) 01190 { 01191 01192 butdisabled[ id ] = FALSE; 01193 01194 SendMessage(buttons[ id ], BM_SETIMAGE, ( WPARAM )IMAGE_BITMAP, ( LPARAM )butbmps[ id ]); 01195 01196 01197 } 01198 VOID disable_but( DWORD id ) 01199 { 01200 01201 butdisabled[ id ] = TRUE; 01202 01203 SendMessage(buttons[ id ], BM_SETIMAGE, ( WPARAM )IMAGE_BITMAP, ( LPARAM )butbmps_dis[ id ]); 01204 01205 } 01206 01207 01208 01209 01210 01211 01212 01213 01214 01215 01216 01217 01218 01219 01220 01221 01222 BOOL open_wav( TCHAR * f ) 01223 { 01224 01225 01226 HANDLE file; 01227 01228 riff_hdr r; 01229 wave_hdr w; 01230 data_chunk d; 01231 01232 BOOL b; 01233 01234 DWORD bytes_recorded_in_wav = 0; 01235 DWORD is_read = 0; 01236 01237 01238 file = CreateFile( 01239 f, 01240 GENERIC_READ, 01241 0, 0, 01242 OPEN_EXISTING, 01243 FILE_ATTRIBUTE_NORMAL, 01244 0 01245 ); 01246 01247 01248 01249 if ( !file ) 01250 { 01251 MessageBox( 01252 main_win, 01253 TEXT("Cannot open file. CreateFile() error."), 01254 TEXT("ERROR"), 01255 MB_OK|MB_ICONERROR 01256 ); 01257 01258 return FALSE; 01259 } 01260 01261 01262 b = ReadFile( file, ( LPVOID ) &r, sizeof ( r ), &is_read, 0 ); 01263 01264 if ( !b ) 01265 { 01266 MessageBox( 01267 main_win, 01268 TEXT("Cannot read RIFF header."), 01269 TEXT("ERROR"), 01270 MB_OK|MB_ICONERROR 01271 ); 01272 01273 CloseHandle( file ); 01274 return FALSE; 01275 } 01276 01277 01278 b = ReadFile( file, ( LPVOID ) &w, sizeof ( w ), &is_read, 0 ); 01279 01280 01281 if ( !b ) 01282 { 01283 MessageBox( 01284 main_win, 01285 TEXT("Cannot read WAVE header."), 01286 TEXT("ERROR"), 01287 MB_OK|MB_ICONERROR 01288 ); 01289 01290 CloseHandle( file ); 01291 return FALSE; 01292 } 01293 01294 01295 01296 b = ReadFile( file, ( LPVOID ) &d, sizeof ( d ), &is_read, 0 ); 01297 01298 if ( !b ) 01299 { 01300 MessageBox( 01301 main_win, 01302 TEXT("Cannot read WAVE subchunk."), 01303 TEXT("ERROR"), 01304 MB_OK|MB_ICONERROR 01305 ); 01306 01307 CloseHandle( file ); 01308 return FALSE; 01309 } 01310 01311 bytes_recorded_in_wav = r.chunksize - 36; 01312 01313 01314 if ( bytes_recorded_in_wav == 0 ) 01315 { 01316 MessageBox( 01317 main_win, 01318 TEXT("Cannot read file. No audio data."), 01319 TEXT("ERROR"), 01320 MB_OK|MB_ICONERROR 01321 ); 01322 01323 CloseHandle( file ); 01324 return FALSE; 01325 } 01326 01327 01328 snd::audio_format openfmt 01329 ( w.SampleRate, w.BitsPerSample, w.NumChannels ); 01330 01331 01332 01333 AUD_BUF->clear(); 01334 01335 01336 AUD_BUF->alloc_bytes( bytes_recorded_in_wav ); 01337 01338 01339 b = ReadFile( 01340 file, 01341 ( LPVOID ) AUD_BUF->audio_buffer(), 01342 bytes_recorded_in_wav, 01343 &is_read, 01344 0 01345 ); 01346 01347 01348 AUD_BUF->set_b_received( bytes_recorded_in_wav ); 01349 01350 01351 if (( !b ) || ( is_read != bytes_recorded_in_wav )) 01352 { 01353 MessageBox( 01354 main_win, 01355 TEXT("Cannot read file. Error reading audio data."), 01356 TEXT("ERROR"), 01357 MB_OK|MB_ICONERROR 01358 ); 01359 01360 CloseHandle( file ); 01361 01362 AUD_BUF->reset(); 01363 return FALSE; 01364 } 01365 01366 CloseHandle( file ); 01367 01368 enable_but( BUTPLAY_ID ); 01369 enable_but( BUTSTOP_ID ); 01370 enable_but( BUTSTART_ID ); 01371 enable_but( BUTEND_ID ); 01372 enable_but( BUTREC_ID ); 01373 01374 01375 samples_max = AUD_BUF->samples_received(); 01376 01377 isnew = FALSE; 01378 01379 return TRUE; 01380 01381 } 01382 01383 01384 BOOL 01385 write_wav( TCHAR * f ) 01386 { 01387 01388 HANDLE file; 01389 01390 01391 DWORD written; 01392 BOOL is_writ; 01393 int i; 01394 riff_hdr r; 01395 wave_hdr w; 01396 data_chunk d; 01397 01398 01399 01400 file = CreateFile( 01401 f, 01402 GENERIC_WRITE, 01403 0, 0, 01404 CREATE_NEW, 01405 FILE_ATTRIBUTE_NORMAL, 01406 0 01407 ); 01408 01409 01410 01411 if ( !file ) 01412 { 01413 i = MessageBox( 01414 main_win, 01415 TEXT("File already exist. Overwrite it?"), 01416 TEXT("Warning"), 01417 MB_YESNO|MB_ICONQUESTION 01418 ); 01419 01420 if ( i == IDYES ) 01421 { 01422 01423 file = CreateFile( 01424 f, 01425 GENERIC_WRITE, 01426 0, 0, 01427 CREATE_ALWAYS, 01428 FILE_ATTRIBUTE_NORMAL, 01429 0 01430 ); 01431 01432 if ( !file ) 01433 { 01434 MessageBox( 01435 main_win, 01436 TEXT("File Error, CreateFile() failed."), 01437 TEXT("ERROR"), 01438 MB_OK|MB_ICONERROR 01439 ); 01440 01441 01442 return FALSE; 01443 01444 } 01445 01446 01447 } else 01448 return FALSE; 01449 } 01450 01451 01452 01453 01454 r.magic = 0x46464952; 01455 01456 01457 r.format = 0x45564157; 01458 r.chunksize = 36 + AUD_BUF->bytes_recorded(); 01459 01460 01461 w.Subchunkid = 0x20746d66; 01462 01463 w.Subchunk1Size = 16; 01464 w.AudioFormat = 1; 01465 w.NumChannels = AUD_BUF->audinfo().channels(); 01466 w.SampleRate = AUD_BUF->audinfo().sample_rate(); 01467 w.ByteRate = AUD_BUF->audinfo().byte_rate(); 01468 w.BlockAlign = AUD_BUF->audinfo().block_align(); 01469 w.BitsPerSample = AUD_BUF->audinfo().bits(); 01470 01471 01472 d.subc = 0x61746164; 01473 d.subc_size = AUD_BUF->bytes_recorded(); 01474 01475 01476 01477 // 01478 // Writing headers 01479 // 01480 01481 01482 is_writ = WriteFile( file, ( LPCVOID ) &r, sizeof ( r ), &written, 0 ); 01483 01484 if ( !is_writ ) 01485 { 01486 MessageBox( 01487 main_win, 01488 TEXT("File Error, WriteFile() failed."), 01489 TEXT("ERROR"), 01490 MB_OK|MB_ICONERROR 01491 ); 01492 01493 CloseHandle( file ); 01494 01495 return FALSE; 01496 01497 } 01498 01499 01500 is_writ = WriteFile( file, ( LPCVOID ) &w, sizeof ( w ), &written, 0 ); 01501 01502 if ( !is_writ ) 01503 { 01504 MessageBox( 01505 main_win, 01506 TEXT("File Error, WriteFile() failed."), 01507 TEXT("ERROR"), 01508 MB_OK|MB_ICONERROR 01509 ); 01510 01511 CloseHandle( file ); 01512 01513 return FALSE; 01514 01515 } 01516 01517 01518 is_writ = WriteFile( file, ( LPCVOID ) &d, sizeof ( d ), &written, 0 ); 01519 01520 01521 if ( !is_writ ) 01522 { 01523 MessageBox( 01524 main_win, 01525 TEXT("File Error, WriteFile() failed."), 01526 TEXT("ERROR"), 01527 MB_OK|MB_ICONERROR 01528 ); 01529 01530 CloseHandle( file ); 01531 01532 return FALSE; 01533 01534 } 01535 01536 01537 01538 is_writ = WriteFile( 01539 file, 01540 ( LPCVOID ) AUD_BUF->audio_buffer(), 01541 AUD_BUF->bytes_recorded(), 01542 &written, 01543 0 01544 ); 01545 01546 if ( !is_writ ) 01547 { 01548 MessageBox( 01549 main_win, 01550 TEXT("File Error, WriteFile() failed."), 01551 TEXT("ERROR"), 01552 MB_OK|MB_ICONERROR 01553 ); 01554 01555 CloseHandle( file ); 01556 01557 return FALSE; 01558 01559 } 01560 01561 01562 CloseHandle( file ); 01563 01564 return TRUE; 01565 } Generated on Sat May 26 2012 04:16:26 for ReactOS by
1.7.6.1
|