⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dsoundaudio.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 2 页
字号:
    err = waveformat_from_audio_settings (&wfx, &conf.settings);    if (err) {        return -1;    }    memset (&dsbd, 0, sizeof (dsbd));    dsbd.dwSize = sizeof (dsbd);    dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER;    dsbd.dwBufferBytes = 0;    dsbd.lpwfxFormat = NULL;    hr = IDirectSound_CreateSoundBuffer (        s->dsound,        &dsbd,        &s->dsound_primary_buffer,        NULL        );    if (FAILED (hr)) {        dsound_logerr (hr, "Could not create primary playback buffer\n");        return -1;    }    hr = IDirectSoundBuffer_SetFormat (s->dsound_primary_buffer, &wfx);    if (FAILED (hr)) {        dsound_logerr (hr, "Could not set primary playback buffer format\n");    }    hr = IDirectSoundBuffer_GetFormat (        s->dsound_primary_buffer,        &wfx,        sizeof (wfx),        NULL        );    if (FAILED (hr)) {        dsound_logerr (hr, "Could not get primary playback buffer format\n");        goto fail0;    }#ifdef DEBUG_DSOUND    dolog ("Primary\n");    print_wave_format (&wfx);#endif    err = waveformat_to_audio_settings (&wfx, &s->settings);    if (err) {        goto fail0;    }    return 0; fail0:    dsound_close (s);    return -1;}static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...){    HRESULT hr;    DWORD status;    DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;    LPDIRECTSOUNDBUFFER dsb = ds->dsound_buffer;    if (!dsb) {        dolog ("Attempt to control voice without a buffer\n");        return 0;    }    switch (cmd) {    case VOICE_ENABLE:        if (dsound_get_status_out (dsb, &status)) {            return -1;        }        if (status & DSBSTATUS_PLAYING) {            dolog ("warning: Voice is already playing\n");            return 0;        }        dsound_clear_sample (hw, dsb);        hr = IDirectSoundBuffer_Play (dsb, 0, 0, DSBPLAY_LOOPING);        if (FAILED (hr)) {            dsound_logerr (hr, "Could not start playing buffer\n");            return -1;        }        break;    case VOICE_DISABLE:        if (dsound_get_status_out (dsb, &status)) {            return -1;        }        if (status & DSBSTATUS_PLAYING) {            hr = IDirectSoundBuffer_Stop (dsb);            if (FAILED (hr)) {                dsound_logerr (hr, "Could not stop playing buffer\n");                return -1;            }        }        else {            dolog ("warning: Voice is not playing\n");        }        break;    }    return 0;}static int dsound_write (SWVoiceOut *sw, void *buf, int len){    return audio_pcm_sw_write (sw, buf, len);}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 (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, hw->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;}static int dsound_ctl_in (HWVoiceIn *hw, int cmd, ...){    HRESULT hr;    DWORD status;    DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;    LPDIRECTSOUNDCAPTUREBUFFER dscb = ds->dsound_capture_buffer;    if (!dscb) {        dolog ("Attempt to control capture voice without a buffer\n");        return -1;    }    switch (cmd) {    case VOICE_ENABLE:        if (dsound_get_status_in (dscb, &status)) {            return -1;        }        if (status & DSCBSTATUS_CAPTURING) {            dolog ("warning: Voice is already capturing\n");            return 0;        }        /* clear ?? */        hr = IDirectSoundCaptureBuffer_Start (dscb, DSCBSTART_LOOPING);        if (FAILED (hr)) {            dsound_logerr (hr, "Could not start capturing\n");            return -1;        }        break;    case VOICE_DISABLE:        if (dsound_get_status_in (dscb, &status)) {            return -1;        }        if (status & DSCBSTATUS_CAPTURING) {            hr = IDirectSoundCaptureBuffer_Stop (dscb);            if (FAILED (hr)) {                dsound_logerr (hr, "Could not stop capturing\n");                return -1;            }        }        else {            dolog ("warning: Voice is not capturing\n");        }        break;    }    return 0;}static int dsound_read (SWVoiceIn *sw, void *buf, int len){    return audio_pcm_sw_read (sw, buf, len);}static int dsound_run_in (HWVoiceIn *hw){    int err;    HRESULT hr;    DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;    LPDIRECTSOUNDCAPTUREBUFFER dscb = ds->dsound_capture_buffer;    int live, len, dead;    DWORD blen1, blen2;    DWORD len1, len2;    DWORD decr;    DWORD cpos, rpos;    LPVOID p1, p2;    int hwshift;    if (!dscb) {        dolog ("Attempt to run without capture buffer\n");        return 0;    }    hwshift = hw->info.shift;    live = audio_pcm_hw_get_live_in (hw);    dead = hw->samples - live;    if (!dead) {        return 0;    }    hr = IDirectSoundCaptureBuffer_GetCurrentPosition (        dscb,        &cpos,        ds->first_time ? &rpos : NULL        );    if (FAILED (hr)) {        dsound_logerr (hr, "Could not get capture buffer position\n");        return 0;    }    if (ds->first_time) {        ds->first_time = 0;        if (rpos & hw->info.align) {            ldebug ("warning: Misaligned capture read position %ld(%d)\n",                    rpos, hw->info.align);        }        hw->wpos = rpos >> hwshift;    }    if (cpos & hw->info.align) {        ldebug ("warning: Misaligned capture position %ld(%d)\n",                cpos, hw->info.align);    }    cpos >>= hwshift;    len = audio_ring_dist (cpos, hw->wpos, hw->samples);    if (!len) {        return 0;    }    len = audio_MIN (len, dead);    err = dsound_lock_in (        dscb,        &hw->info,        hw->wpos << hwshift,        len << hwshift,        &p1,        &p2,        &blen1,        &blen2,        0        );    if (err) {        return 0;    }    len1 = blen1 >> hwshift;    len2 = blen2 >> hwshift;    decr = len1 + len2;    if (p1 && len1) {        hw->conv (hw->conv_buf + hw->wpos, p1, len1, &nominal_volume);    }    if (p2 && len2) {        hw->conv (hw->conv_buf, p2, len2, &nominal_volume);    }    dsound_unlock_in (dscb, p1, p2, blen1, blen2);    hw->wpos = (hw->wpos + decr) % hw->samples;    return decr;}static void dsound_audio_fini (void *opaque){    HRESULT hr;    dsound *s = opaque;    if (!s->dsound) {        return;    }    hr = IDirectSound_Release (s->dsound);    if (FAILED (hr)) {        dsound_logerr (hr, "Could not release DirectSound\n");    }    s->dsound = NULL;    if (!s->dsound_capture) {        return;    }    hr = IDirectSoundCapture_Release (s->dsound_capture);    if (FAILED (hr)) {        dsound_logerr (hr, "Could not release DirectSoundCapture\n");    }    s->dsound_capture = NULL;}static void *dsound_audio_init (void){    int err;    HRESULT hr;    dsound *s = &glob_dsound;    hr = CoInitialize (NULL);    if (FAILED (hr)) {        dsound_logerr (hr, "Could not initialize COM\n");        return NULL;    }    hr = CoCreateInstance (        &CLSID_DirectSound,        NULL,        CLSCTX_ALL,        &IID_IDirectSound,        (void **) &s->dsound        );    if (FAILED (hr)) {        dsound_logerr (hr, "Could not create DirectSound instance\n");        return NULL;    }    hr = IDirectSound_Initialize (s->dsound, NULL);    if (FAILED (hr)) {        dsound_logerr (hr, "Could not initialize DirectSound\n");        hr = IDirectSound_Release (s->dsound);        if (FAILED (hr)) {            dsound_logerr (hr, "Could not release DirectSound\n");        }        s->dsound = NULL;        return NULL;    }    hr = CoCreateInstance (        &CLSID_DirectSoundCapture,        NULL,        CLSCTX_ALL,        &IID_IDirectSoundCapture,        (void **) &s->dsound_capture        );    if (FAILED (hr)) {        dsound_logerr (hr, "Could not create DirectSoundCapture instance\n");    }    else {        hr = IDirectSoundCapture_Initialize (s->dsound_capture, NULL);        if (FAILED (hr)) {            dsound_logerr (hr, "Could not initialize DirectSoundCapture\n");            hr = IDirectSoundCapture_Release (s->dsound_capture);            if (FAILED (hr)) {                dsound_logerr (hr, "Could not release DirectSoundCapture\n");            }            s->dsound_capture = NULL;        }    }    err = dsound_open (s);    if (err) {        dsound_audio_fini (s);        return NULL;    }    return s;}static struct audio_option dsound_options[] = {    {"LOCK_RETRIES", AUD_OPT_INT, &conf.lock_retries,     "Number of times to attempt locking the buffer", NULL, 0},    {"RESTOURE_RETRIES", AUD_OPT_INT, &conf.restore_retries,     "Number of times to attempt restoring the buffer", NULL, 0},    {"GETSTATUS_RETRIES", AUD_OPT_INT, &conf.getstatus_retries,     "Number of times to attempt getting status of the buffer", NULL, 0},    {"SET_PRIMARY", AUD_OPT_BOOL, &conf.set_primary,     "Set the parameters of primary buffer", NULL, 0},    {"LATENCY_MILLIS", AUD_OPT_INT, &conf.latency_millis,     "(undocumented)", NULL, 0},    {"PRIMARY_FREQ", AUD_OPT_INT, &conf.settings.freq,     "Primary buffer frequency", NULL, 0},    {"PRIMARY_CHANNELS", AUD_OPT_INT, &conf.settings.nchannels,     "Primary buffer number of channels (1 - mono, 2 - stereo)", NULL, 0},    {"PRIMARY_FMT", AUD_OPT_FMT, &conf.settings.fmt,     "Primary buffer format", NULL, 0},    {"BUFSIZE_OUT", AUD_OPT_INT, &conf.bufsize_out,     "(undocumented)", NULL, 0},    {"BUFSIZE_IN", AUD_OPT_INT, &conf.bufsize_in,     "(undocumented)", NULL, 0},    {NULL, 0, NULL, NULL, NULL, 0}};static struct audio_pcm_ops dsound_pcm_ops = {    dsound_init_out,    dsound_fini_out,    dsound_run_out,    dsound_write,    dsound_ctl_out,    dsound_init_in,    dsound_fini_in,    dsound_run_in,    dsound_read,    dsound_ctl_in};struct audio_driver dsound_audio_driver = {    INIT_FIELD (name           = ) "dsound",    INIT_FIELD (descr          = )    "DirectSound http://wikipedia.org/wiki/DirectSound",    INIT_FIELD (options        = ) dsound_options,    INIT_FIELD (init           = ) dsound_audio_init,    INIT_FIELD (fini           = ) dsound_audio_fini,    INIT_FIELD (pcm_ops        = ) &dsound_pcm_ops,    INIT_FIELD (can_be_default = ) 1,    INIT_FIELD (max_voices_out = ) INT_MAX,    INIT_FIELD (max_voices_in  = ) 1,    INIT_FIELD (voice_size_out = ) sizeof (DSoundVoiceOut),    INIT_FIELD (voice_size_in  = ) sizeof (DSoundVoiceIn)};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -