Ignore:
Timestamp:
May 21, 2006 7:00:15 PM (18 years ago)
Author:
bennylp
Message:

DirectSound? capture device queries stream position and retrieves any captured frames

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/src/pjmedia/dsound.c

    r462 r463  
    100100 
    101101    void                   *buffer;             /**< Temp. frame buffer.    */ 
     102    unsigned                clock_rate;         /**< Clock rate.            */ 
    102103    unsigned                samples_per_frame;  /**< Samples per frame.     */ 
    103104 
     
    233234    /* Done setting up play device. */ 
    234235    PJ_LOG(5,(THIS_FILE,  
    235               " DirectSound player stream initialized (clock_rate=%d, " 
    236               "channel_count=%d, samples_per_frame=%d", 
    237               clock_rate, channel_count, samples_per_frame)); 
     236              " DirectSound player \"%s\" initialized (clock_rate=%d, " 
     237              "channel_count=%d, samples_per_frame=%d (%dms))", 
     238              dev_info[dev_id].info.name, 
     239              clock_rate, channel_count, samples_per_frame, 
     240              samples_per_frame * 1000 / clock_rate)); 
    238241 
    239242    return PJ_SUCCESS; 
     
    336339    /* Done setting up recorder device. */ 
    337340    PJ_LOG(5,(THIS_FILE,  
    338               " DirectSound capture stream initialized (clock_rate=%d, " 
    339               "channel_count=%d, samples_per_frame=%d", 
    340               clock_rate, channel_count, samples_per_frame)); 
     341              " DirectSound capture \"%s\" initialized (clock_rate=%d, " 
     342              "channel_count=%d, samples_per_frame=%d (%dms))", 
     343              dev_info[dev_id].info.name, 
     344              clock_rate, channel_count, samples_per_frame, 
     345              samples_per_frame * 1000 / clock_rate)); 
    341346 
    342347    return PJ_SUCCESS; 
     
    417422 
    418423/* 
    419  * Player thread. 
     424 * Check if there are captured frames in DirectSound capture buffer. 
     425 */ 
     426static unsigned dsound_captured_size(struct dsound_stream *dsound_strm) 
     427{ 
     428    HRESULT hr; 
     429    long size_available; 
     430    DWORD writePos, readPos; 
     431 
     432    hr = IDirectSoundCaptureBuffer_GetCurrentPosition(dsound_strm->ds.capture.lpDsBuffer,  
     433                                                      &writePos, &readPos); 
     434    if FAILED(hr) 
     435        return PJ_FALSE; 
     436 
     437    if (readPos < dsound_strm->dwBytePos) 
     438        size_available = readPos + 
     439                    (dsound_strm->dwDsBufferSize) - dsound_strm->dwBytePos; 
     440    else 
     441        size_available = readPos - dsound_strm->dwBytePos; 
     442 
     443    return size_available; 
     444} 
     445 
     446/* 
     447 * DirectSound capture and playback thread. 
    420448 */ 
    421449static int dsound_dev_thread(void *arg) 
     
    424452    HANDLE events[2]; 
    425453    unsigned eventCount; 
     454    unsigned bytes_per_frame; 
    426455    pj_status_t status; 
    427456 
     
    435464 
    436465    /* Raise self priority */ 
    437     SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_HIGHEST); 
     466    //SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_HIGHEST); 
     467 
     468    /* Calculate bytes per frame */ 
     469    bytes_per_frame = strm->samples_per_frame * BYTES_PER_SAMPLE; 
    438470 
    439471    /* 
    440      * Loop while not signalled to quit, wait for event object to be signalled 
    441      * by DirectSound play buffer, then request for sound data from the  
    442      * application and write it to DirectSound buffer. 
     472     * Loop while not signalled to quit, wait for event objects to be  
     473     * signalled by DirectSound capture and play buffer. 
    443474     */ 
    444475    while (!strm->thread_quit_flag) { 
     
    446477        DWORD rc; 
    447478        pjmedia_dir signalled_dir; 
    448         struct dsound_stream *dsound_strm; 
    449  
    450         rc = WaitForMultipleObjects(eventCount, events, FALSE, 100); 
     479 
     480        rc = WaitForMultipleObjects(eventCount, events, FALSE,  
     481                                    100); 
    451482        if (rc < WAIT_OBJECT_0 || rc >= WAIT_OBJECT_0+eventCount) 
    452483            continue; 
     
    468499        if (signalled_dir == PJMEDIA_DIR_PLAYBACK) { 
    469500             
     501            struct dsound_stream *dsound_strm; 
     502 
     503            /* 
     504             * DirectSound has requested us to feed some frames to 
     505             * playback buffer. 
     506             */ 
     507 
    470508            dsound_strm = &strm->play_strm; 
    471509 
     
    474512                                      dsound_strm->timestamp.u32.lo, 
    475513                                      strm->buffer, 
    476                                       strm->samples_per_frame *  
    477                                         BYTES_PER_SAMPLE); 
     514                                      bytes_per_frame); 
    478515            if (status != PJ_SUCCESS) 
    479516                break; 
     
    483520                                  dsound_strm->dwBytePos, 
    484521                                  (LPBYTE)strm->buffer,  
    485                                   strm->samples_per_frame * BYTES_PER_SAMPLE); 
     522                                  bytes_per_frame); 
     523 
     524            /* Increment position. */ 
     525            dsound_strm->dwBytePos += bytes_per_frame; 
     526            if (dsound_strm->dwBytePos >= dsound_strm->dwDsBufferSize) 
     527                dsound_strm->dwBytePos -= dsound_strm->dwDsBufferSize; 
     528            dsound_strm->timestamp.u64 += strm->samples_per_frame; 
    486529 
    487530        } else { 
     531            /* 
     532             * DirectSound has indicated that it has some frames ready 
     533             * in the capture buffer. Get as much frames as possible to 
     534             * prevent overflows. 
     535             */ 
     536            struct dsound_stream *dsound_strm; 
    488537            BOOL rc; 
    489538 
    490539            dsound_strm = &strm->rec_strm; 
    491540 
    492             /* Capture from DirectSound buffer. */ 
    493             rc = AppReadDataFromBuffer(dsound_strm->ds.capture.lpDsBuffer,  
    494                                        dsound_strm->dwBytePos, 
    495                                        (LPBYTE)strm->buffer,  
    496                                        strm->samples_per_frame *  
    497                                         BYTES_PER_SAMPLE); 
    498              
    499             if (!rc) { 
    500                 pj_memset(strm->buffer, 0, strm->samples_per_frame *  
    501                                             BYTES_PER_SAMPLE); 
    502             } 
    503  
    504             /* Call callback */ 
    505             status = (*strm->rec_cb)(strm->user_data,  
    506                                      dsound_strm->timestamp.u32.lo,  
    507                                      strm->buffer,  
    508                                      strm->samples_per_frame *  
    509                                         BYTES_PER_SAMPLE); 
    510  
    511             /* Quit thread on error. */ 
    512             if (status != PJ_SUCCESS) 
    513                 break; 
    514  
     541            do { 
     542                /* Capture from DirectSound buffer. */ 
     543                rc = AppReadDataFromBuffer(dsound_strm->ds.capture.lpDsBuffer,  
     544                                           dsound_strm->dwBytePos, 
     545                                           (LPBYTE)strm->buffer,  
     546                                           bytes_per_frame); 
     547                 
     548                if (!rc) { 
     549                    pj_memset(strm->buffer, 0, bytes_per_frame); 
     550                } 
     551 
     552                /* Call callback */ 
     553                status = (*strm->rec_cb)(strm->user_data,  
     554                                         dsound_strm->timestamp.u32.lo,  
     555                                         strm->buffer,  
     556                                         bytes_per_frame); 
     557 
     558                /* Quit thread on error. */ 
     559                if (status != PJ_SUCCESS) 
     560                    goto on_error; 
     561 
     562 
     563                /* Increment position. */ 
     564                dsound_strm->dwBytePos += bytes_per_frame; 
     565                if (dsound_strm->dwBytePos >= dsound_strm->dwDsBufferSize) 
     566                    dsound_strm->dwBytePos -= dsound_strm->dwDsBufferSize; 
     567                dsound_strm->timestamp.u64 += strm->samples_per_frame; 
     568 
     569            } while (dsound_captured_size(dsound_strm) >= bytes_per_frame); 
    515570        } 
    516  
    517         /* Increment position. */ 
    518         dsound_strm->dwBytePos += strm->samples_per_frame * BYTES_PER_SAMPLE; 
    519         if (dsound_strm->dwBytePos >= dsound_strm->dwDsBufferSize) 
    520             dsound_strm->dwBytePos -= dsound_strm->dwDsBufferSize; 
    521         dsound_strm->timestamp.u64 += strm->samples_per_frame; 
    522     } 
    523  
    524  
     571    } 
     572 
     573 
     574on_error: 
    525575    PJ_LOG(5,(THIS_FILE, "DirectSound: thread stopping..")); 
    526  
    527576    return 0; 
    528577} 
     
    670719    strm->play_cb = play_cb; 
    671720    strm->user_data = user_data; 
    672  
     721    strm->clock_rate = clock_rate; 
    673722    strm->samples_per_frame = samples_per_frame; 
    674723    strm->buffer = pj_pool_alloc(pool, samples_per_frame * BYTES_PER_SAMPLE); 
Note: See TracChangeset for help on using the changeset viewer.