Пример #1
0
HRESULT wasapi_change_init(struct ao *ao)
{
    MP_DBG(ao, "Setting up monitoring on playback device\n");
    struct wasapi_state *state = (struct wasapi_state *)ao->priv;
    struct change_notify *change = &state->change;
    /* COM voodoo to emulate c++ class */
    change->client.lpVtbl = &sIMMDeviceEnumeratorVtbl_vtbl;

    /* so the callbacks can access the ao */
    change->ao = ao;

    /* get the device string to compare with the pwstrDeviceId argument in callbacks */
    HRESULT hr = IMMDevice_GetId(state->pDevice, &change->monitored);
    EXIT_ON_ERROR(hr);

    /* register the change notification client */
    hr = IMMDeviceEnumerator_RegisterEndpointNotificationCallback(
        state->pEnumerator, (IMMNotificationClient *)change);
    EXIT_ON_ERROR(hr);

    MP_VERBOSE(state, "Monitoring changes in device: %S\n", state->change.monitored);
    return hr;
exit_label:
    MP_ERR(state, "Error setting up device change monitoring: %s\n",
           wasapi_explain_err(hr));
    wasapi_change_uninit(ao);
    return hr;
}
Пример #2
0
static double get_device_delay(struct wasapi_state *state) {
    UINT64 sample_count = atomic_load(&state->sample_count);
    UINT64 position, qpc_position;
    HRESULT hr;

    switch (hr = IAudioClock_GetPosition(state->pAudioClock, &position, &qpc_position)) {
        case S_OK: case S_FALSE:
            break;
        default:
            MP_ERR(state, "IAudioClock::GetPosition returned %s\n", wasapi_explain_err(hr));
    }

    LARGE_INTEGER qpc_count;
    QueryPerformanceCounter(&qpc_count);
    double qpc_diff = (qpc_count.QuadPart * 1e7 / state->qpc_frequency.QuadPart) - qpc_position;

    position += state->clock_frequency * (uint64_t)(qpc_diff / 1e7);

    /* convert position to the same base as sample_count */
    position = position * state->format.Format.nSamplesPerSec / state->clock_frequency;

    double diff = sample_count - position;
    double delay = diff / state->format.Format.nSamplesPerSec;

    MP_TRACE(state, "device delay: %g samples (%g ms)\n", diff, delay * 1000);

    return delay;
}