예제 #1
0
static int dsound_get_status_out (LPDIRECTSOUNDBUFFER dsb, DWORD *statusp,
                                  dsound *s)
{
    HRESULT hr;

    hr = IDirectSoundBuffer_GetStatus (dsb, statusp);
    if (FAILED (hr)) {
        dsound_logerr (hr, "Could not get playback buffer status\n");
        return -1;
    }

    if (*statusp & DSERR_BUFFERLOST) {
        dsound_restore_out(dsb, s);
        return -1;
    }

    return 0;
}
예제 #2
0
파일: dsoundaudio.c 프로젝트: CPFL/gxen
static int dsound_get_status_out (LPDIRECTSOUNDBUFFER dsb, DWORD *statusp)
{
    HRESULT hr;
    int i;

    for (i = 0; i < conf.getstatus_retries; ++i) {
        hr = IDirectSoundBuffer_GetStatus (dsb, statusp);
        if (FAILED (hr)) {
            dsound_logerr (hr, "Could not get playback buffer status\n");
            return -1;
        }

        if (*statusp & DSERR_BUFFERLOST) {
            if (dsound_restore_out (dsb)) {
                return -1;
            }
            continue;
        }
        break;
    }

    return 0;
}
예제 #3
0
static int dsound_run_out (HWVoiceOut *hw)
{
    int err;
    HRESULT hr;
    DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
    LPDIRECTSOUNDBUFFER dsb = ds->dsound_buffer;
    int live, len, hwshift;
    DWORD blen1, blen2;
    DWORD len1, len2;
    DWORD decr;
    DWORD wpos, ppos, old_pos;
    LPVOID p1, p2;
    int bufsize;

    if (!dsb) {
        dolog ("Attempt to run empty with playback buffer\n");
        return 0;
    }

    hwshift = hw->info.shift;
    bufsize = hw->samples << hwshift;

    live = audio_pcm_hw_get_live_out (hw);

    hr = IDirectSoundBuffer_GetCurrentPosition (
        dsb,
        &ppos,
        ds->first_time ? &wpos : NULL
        );
    if (hr == DSERR_BUFFERLOST) {
        if (dsound_restore_out(dsb))
            return 0;
        hr = IDirectSoundBuffer_GetCurrentPosition(dsb, &ppos, ds->first_time ? &wpos : NULL);
        if (hr == DSERR_BUFFERLOST)
            return 0;   // Avoid log flooding if the error is still there.
    }
    if (FAILED (hr)) {
        dsound_logerr (hr, "Could not get playback buffer position\n");
        return 0;
    }

    len = live << hwshift;

    if (ds->first_time) {
        if (conf.latency_millis) {
            DWORD cur_blat;

            cur_blat = audio_ring_dist (wpos, ppos, bufsize);
            ds->first_time = 0;
            old_pos = wpos;
            old_pos +=
                millis_to_bytes (&hw->info, conf.latency_millis) - cur_blat;
            old_pos %= bufsize;
            old_pos &= ~hw->info.align;
        }
        else {
            old_pos = wpos;
        }
#ifdef DEBUG_DSOUND
        ds->played = 0;
        ds->mixed = 0;
#endif
    }
    else {
        if (ds->old_pos == ppos) {
#ifdef DEBUG_DSOUND
            dolog ("old_pos == ppos\n");
#endif
            return 0;
        }

#ifdef DEBUG_DSOUND
        ds->played += audio_ring_dist (ds->old_pos, ppos, bufsize);
#endif
        old_pos = ds->old_pos;
    }

    if ((old_pos < ppos) && ((old_pos + len) > ppos)) {
        len = ppos - old_pos;
    }
    else {
        if ((old_pos > ppos) && ((old_pos + len) > (ppos + bufsize))) {
            len = bufsize - old_pos + ppos;
        }
    }

    if (audio_bug (AUDIO_FUNC, len < 0 || len > bufsize)) {
        dolog ("len=%d bufsize=%d old_pos=%ld ppos=%ld\n",
               len, bufsize, old_pos, ppos);
        return 0;
    }

    len &= ~hw->info.align;
    if (!len) {
        return 0;
    }

#ifdef DEBUG_DSOUND
    ds->old_ppos = ppos;
#endif
    err = dsound_lock_out (
        dsb,
        &hw->info,
        old_pos,
        len,
        &p1, &p2,
        &blen1, &blen2,
        0
        );
    if (err) {
        return 0;
    }

    len1 = blen1 >> hwshift;
    len2 = blen2 >> hwshift;
    decr = len1 + len2;

    if (p1 && len1) {
        dsound_write_sample (hw, p1, len1);
    }

    if (p2 && len2) {
        dsound_write_sample (hw, p2, len2);
    }

    dsound_unlock_out (dsb, p1, p2, blen1, blen2);
    ds->old_pos = (old_pos + (decr << hwshift)) % bufsize;

#ifdef DEBUG_DSOUND
    ds->mixed += decr << hwshift;

    dolog ("played %lu mixed %lu diff %ld sec %f\n",
           ds->played,
           ds->mixed,
           ds->mixed - ds->played,
           abs (ds->mixed - ds->played) / (double) hw->info.bytes_per_second);
#endif
    return decr;
}