Changeset 2288
- Timestamp:
- Sep 17, 2008 11:56:44 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia/dsound.c
r2286 r2288 39 39 40 40 41 42 41 #define THIS_FILE "dsound.c" 43 42 #define BITS_PER_SAMPLE 16 … … 114 113 115 114 pj_thread_t *thread; /**< Thread handle. */ 116 pj_bool_t thread_quit_flag; /**< Quit signal to thread */115 HANDLE thread_quit_event; /**< Quit signal to thread */ 117 116 }; 118 117 … … 433 432 } 434 433 435 436 /* 437 * Check if there are captured frames in DirectSound capture buffer. 438 */ 439 static unsigned dsound_captured_size(struct dsound_stream *dsound_strm) 434 /* 435 * Check if there is space in playing buffer. 436 */ 437 static unsigned dsound_play_empty_size(struct dsound_stream *dsound_strm) 440 438 { 441 439 HRESULT hr; … … 443 441 DWORD writePos, readPos; 444 442 445 hr = IDirectSoundCaptureBuffer_GetCurrentPosition(dsound_strm->ds.capture.lpDsBuffer, 446 &writePos, &readPos); 443 hr = IDirectSoundBuffer_GetCurrentPosition(dsound_strm->ds.play.lpDsBuffer, 444 &readPos, &writePos); 445 if FAILED(hr) 446 return PJ_FALSE; 447 448 if (readPos < dsound_strm->dwBytePos) 449 size_available = readPos + dsound_strm->dwDsBufferSize - 450 dsound_strm->dwBytePos; 451 else 452 size_available = readPos - dsound_strm->dwBytePos; 453 454 return size_available; 455 } 456 457 458 /* 459 * Check if there are captured frames in DirectSound capture buffer. 460 */ 461 static unsigned dsound_captured_size(struct dsound_stream *dsound_strm) 462 { 463 HRESULT hr; 464 long size_available; 465 DWORD writePos, readPos; 466 467 hr = IDirectSoundCaptureBuffer_GetCurrentPosition( 468 dsound_strm->ds.capture.lpDsBuffer, 469 &writePos, &readPos); 447 470 if FAILED(hr) 448 471 return PJ_FALSE; … … 463 486 { 464 487 pjmedia_snd_stream *strm = arg; 465 HANDLE events[ 2];488 HANDLE events[3]; 466 489 unsigned eventCount; 467 490 unsigned bytes_per_frame; … … 470 493 471 494 eventCount = 0; 495 events[eventCount++] = strm->thread_quit_event; 472 496 if (strm->dir & PJMEDIA_DIR_PLAYBACK) 473 497 events[eventCount++] = strm->play_strm.hEvent; … … 479 503 * system activity. 480 504 */ 481 //SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_HIGHEST);505 SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_HIGHEST); 482 506 483 507 /* Calculate bytes per frame */ … … 488 512 * signalled by DirectSound capture and play buffer. 489 513 */ 490 while ( !strm->thread_quit_flag) {514 while (PJ_TRUE) { 491 515 492 516 DWORD rc; 493 517 pjmedia_dir signalled_dir; 494 518 495 rc = WaitForMultipleObjects(eventCount, events, FALSE, 496 100); 519 rc = WaitForMultipleObjects(eventCount, events, FALSE, INFINITE); 497 520 if (rc < WAIT_OBJECT_0 || rc >= WAIT_OBJECT_0+eventCount) 498 521 continue; 499 522 500 523 501 if (rc == WAIT_OBJECT_0) { 502 if (events[0] == strm->play_strm.hEvent) 503 signalled_dir = PJMEDIA_DIR_PLAYBACK; 524 if (rc == WAIT_OBJECT_0) 525 break; 526 if (rc == (WAIT_OBJECT_0 + 1)) { 527 if (events[1] == strm->play_strm.hEvent) 528 signalled_dir = PJMEDIA_DIR_PLAYBACK; 504 529 else 505 530 signalled_dir = PJMEDIA_DIR_CAPTURE; 506 531 } else { 507 if (events[ 1] == strm->play_strm.hEvent)508 532 if (events[2] == strm->play_strm.hEvent) 533 signalled_dir = PJMEDIA_DIR_PLAYBACK; 509 534 else 510 535 signalled_dir = PJMEDIA_DIR_CAPTURE; 511 536 } 512 537 … … 524 549 status = PJ_SUCCESS; 525 550 526 /* Get frame from application. */ 527 status = (*strm->play_cb)(strm->user_data, 528 dsound_strm->timestamp.u32.lo, 529 strm->buffer, 551 while (dsound_play_empty_size(dsound_strm) > bytes_per_frame) { 552 /* Get frame from application. */ 553 status = (*strm->play_cb)(strm->user_data, 554 dsound_strm->timestamp.u32.lo, 555 strm->buffer, 556 bytes_per_frame); 557 if (status != PJ_SUCCESS) 558 break; 559 560 /* Write to DirectSound buffer. */ 561 AppWriteDataToBuffer( dsound_strm->ds.play.lpDsBuffer, 562 dsound_strm->dwBytePos, 563 (LPBYTE)strm->buffer, 530 564 bytes_per_frame); 531 if (status != PJ_SUCCESS) 532 break; 533 534 /* Write to DirectSound buffer. */ 535 AppWriteDataToBuffer( dsound_strm->ds.play.lpDsBuffer, 536 dsound_strm->dwBytePos, 537 (LPBYTE)strm->buffer, 538 bytes_per_frame); 539 540 /* Increment position. */ 541 dsound_strm->dwBytePos += bytes_per_frame; 542 if (dsound_strm->dwBytePos >= dsound_strm->dwDsBufferSize) 543 dsound_strm->dwBytePos -= dsound_strm->dwDsBufferSize; 544 dsound_strm->timestamp.u64 += strm->samples_per_frame; 565 566 /* Increment position. */ 567 dsound_strm->dwBytePos += bytes_per_frame; 568 if (dsound_strm->dwBytePos >= dsound_strm->dwDsBufferSize) 569 dsound_strm->dwBytePos -= dsound_strm->dwDsBufferSize; 570 dsound_strm->timestamp.u64 += strm->samples_per_frame; 571 } 545 572 546 573 } else { … … 555 582 dsound_strm = &strm->rec_strm; 556 583 557 do { 584 /* Fetch while we have more than 1 frame */ 585 while (dsound_captured_size(dsound_strm) > bytes_per_frame) { 586 558 587 /* Capture from DirectSound buffer. */ 559 588 rc = AppReadDataFromBuffer(dsound_strm->ds.capture.lpDsBuffer, … … 561 590 (LPBYTE)strm->buffer, 562 591 bytes_per_frame); 563 592 564 593 if (!rc) { 565 594 pj_bzero(strm->buffer, bytes_per_frame); … … 582 611 dsound_strm->dwBytePos -= dsound_strm->dwDsBufferSize; 583 612 dsound_strm->timestamp.u64 += strm->samples_per_frame; 584 585 /* Fetch while we have more than 1 frame */ 586 } while (dsound_captured_size(dsound_strm) > bytes_per_frame); 587 613 } 588 614 } 589 615 } … … 628 654 629 655 #ifdef UNICODE 630 WideCharToMultiByte(CP_ACP, 0, lpcstrDescription, wcslen(lpcstrDescription), dev_info[index].info.name, max, NULL, NULL); 656 WideCharToMultiByte(CP_ACP, 0, lpcstrDescription, wcslen(lpcstrDescription), 657 dev_info[index].info.name, max, NULL, NULL); 631 658 #else 632 659 strncpy(dev_info[index].info.name, lpcstrDescription, max); … … 768 795 } 769 796 797 /* 798 * Create event for stopping the worker thread. 799 */ 800 strm->thread_quit_event = CreateEvent(NULL, FALSE, FALSE, NULL); 801 if (strm->thread_quit_event == NULL) { 802 status = pj_get_os_error(); 803 pj_pool_release(pool); 804 return status; 805 } 806 770 807 /* Create player stream */ 771 808 if (dir & PJMEDIA_DIR_PLAYBACK) { … … 900 937 pi->samples_per_frame = strm->samples_per_frame; 901 938 pi->bits_per_sample = strm->bits_per_sample; 902 pi->rec_latency = strm->rec_strm.latency; 903 pi->play_latency = strm->play_strm.latency; 939 pi->rec_latency = strm->rec_strm.latency * strm->clock_rate * 940 strm->channel_count/ 1000; 941 pi->play_latency = strm->play_strm.latency * strm->clock_rate * 942 strm->channel_count/ 1000; 904 943 905 944 return PJ_SUCCESS; … … 914 953 HRESULT hr; 915 954 916 PJ_UNUSED_ARG(stream);917 918 955 if (stream->play_strm.ds.play.lpDsBuffer) { 956 hr = IDirectSoundBuffer_SetCurrentPosition( 957 stream->play_strm.ds.play.lpDsBuffer, 0); 958 if (FAILED(hr)) 959 return PJ_RETURN_OS_ERROR(hr); 960 961 stream->play_strm.dwBytePos = 0; 962 919 963 hr = IDirectSoundBuffer_Play(stream->play_strm.ds.play.lpDsBuffer, 920 964 0, 0, DSBPLAY_LOOPING); … … 925 969 926 970 if (stream->rec_strm.ds.capture.lpDsBuffer) { 927 hr = IDirectSoundCaptureBuffer_Start(stream->rec_strm.ds.capture.lpDsBuffer, 928 DSCBSTART_LOOPING ); 971 hr = IDirectSoundCaptureBuffer_GetCurrentPosition( 972 stream->rec_strm.ds.capture.lpDsBuffer, 973 NULL, &stream->rec_strm.dwBytePos ); 974 if (FAILED(hr)) 975 return PJ_RETURN_OS_ERROR(hr); 976 977 hr = IDirectSoundCaptureBuffer_Start( 978 stream->rec_strm.ds.capture.lpDsBuffer, 979 DSCBSTART_LOOPING ); 929 980 if (FAILED(hr)) 930 981 return PJ_RETURN_OS_ERROR(hr); … … 966 1017 967 1018 if (stream->thread) { 968 stream->thread_quit_flag = 1; 1019 pj_assert(stream->thread_quit_event); 1020 SetEvent(stream->thread_quit_event); 969 1021 pj_thread_join(stream->thread); 970 1022 pj_thread_destroy(stream->thread); 971 1023 stream->thread = NULL; 1024 } 1025 1026 if (stream->thread_quit_event) { 1027 CloseHandle(stream->thread_quit_event); 1028 stream->thread_quit_event = NULL; 972 1029 } 973 1030
Note: See TracChangeset
for help on using the changeset viewer.