Annotation of qemu/audio/dsound_template.h, revision 1.1

1.1     ! root        1: /*
        !             2:  * QEMU DirectSound audio driver header
        !             3:  *
        !             4:  * Copyright (c) 2005 Vassili Karpov (malc)
        !             5:  *
        !             6:  * Permission is hereby granted, free of charge, to any person obtaining a copy
        !             7:  * of this software and associated documentation files (the "Software"), to deal
        !             8:  * in the Software without restriction, including without limitation the rights
        !             9:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        !            10:  * copies of the Software, and to permit persons to whom the Software is
        !            11:  * furnished to do so, subject to the following conditions:
        !            12:  *
        !            13:  * The above copyright notice and this permission notice shall be included in
        !            14:  * all copies or substantial portions of the Software.
        !            15:  *
        !            16:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        !            17:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
        !            19:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        !            20:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        !            21:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
        !            22:  * THE SOFTWARE.
        !            23:  */
        !            24: #ifdef DSBTYPE_IN
        !            25: #define NAME "capture buffer"
        !            26: #define TYPE in
        !            27: #define IFACE IDirectSoundCaptureBuffer
        !            28: #define BUFPTR LPDIRECTSOUNDCAPTUREBUFFER
        !            29: #define FIELD dsound_capture_buffer
        !            30: #else
        !            31: #define NAME "playback buffer"
        !            32: #define TYPE out
        !            33: #define IFACE IDirectSoundBuffer
        !            34: #define BUFPTR LPDIRECTSOUNDBUFFER
        !            35: #define FIELD dsound_buffer
        !            36: #endif
        !            37: 
        !            38: static int glue (dsound_unlock_, TYPE) (
        !            39:     BUFPTR buf,
        !            40:     LPVOID p1,
        !            41:     LPVOID p2,
        !            42:     DWORD blen1,
        !            43:     DWORD blen2
        !            44:     )
        !            45: {
        !            46:     HRESULT hr;
        !            47: 
        !            48:     hr = glue (IFACE, _Unlock) (buf, p1, blen1, p2, blen2);
        !            49:     if (FAILED (hr)) {
        !            50:         dsound_logerr (hr, "Could not unlock " NAME "\n");
        !            51:         return -1;
        !            52:     }
        !            53: 
        !            54:     return 0;
        !            55: }
        !            56: 
        !            57: static int glue (dsound_lock_, TYPE) (
        !            58:     BUFPTR buf,
        !            59:     struct audio_pcm_info *info,
        !            60:     DWORD pos,
        !            61:     DWORD len,
        !            62:     LPVOID *p1p,
        !            63:     LPVOID *p2p,
        !            64:     DWORD *blen1p,
        !            65:     DWORD *blen2p,
        !            66:     int entire
        !            67:     )
        !            68: {
        !            69:     HRESULT hr;
        !            70:     int i;
        !            71:     LPVOID p1 = NULL, p2 = NULL;
        !            72:     DWORD blen1 = 0, blen2 = 0;
        !            73: 
        !            74:     for (i = 0; i < conf.lock_retries; ++i) {
        !            75:         hr = glue (IFACE, _Lock) (
        !            76:             buf,
        !            77:             pos,
        !            78:             len,
        !            79:             &p1,
        !            80:             &blen1,
        !            81:             &p2,
        !            82:             &blen2,
        !            83:             (entire
        !            84: #ifdef DSBTYPE_IN
        !            85:              ? DSCBLOCK_ENTIREBUFFER
        !            86: #else
        !            87:              ? DSBLOCK_ENTIREBUFFER
        !            88: #endif
        !            89:              : 0)
        !            90:             );
        !            91: 
        !            92:         if (FAILED (hr)) {
        !            93: #ifndef DSBTYPE_IN
        !            94:             if (hr == DSERR_BUFFERLOST) {
        !            95:                 if (glue (dsound_restore_, TYPE) (buf)) {
        !            96:                     dsound_logerr (hr, "Could not lock " NAME "\n");
        !            97:                     goto fail;
        !            98:                 }
        !            99:                 continue;
        !           100:             }
        !           101: #endif
        !           102:             dsound_logerr (hr, "Could not lock " NAME "\n");
        !           103:             goto fail;
        !           104:         }
        !           105: 
        !           106:         break;
        !           107:     }
        !           108: 
        !           109:     if (i == conf.lock_retries) {
        !           110:         dolog ("%d attempts to lock " NAME " failed\n", i);
        !           111:         goto fail;
        !           112:     }
        !           113: 
        !           114:     if ((p1 && (blen1 & info->align)) || (p2 && (blen2 & info->align))) {
        !           115:         dolog ("DirectSound returned misaligned buffer %ld %ld\n",
        !           116:                blen1, blen2);
        !           117:         glue (dsound_unlock_, TYPE) (buf, p1, p2, blen1, blen2);
        !           118:         goto fail;
        !           119:     }
        !           120: 
        !           121:     if (!p1 && blen1) {
        !           122:         dolog ("warning: !p1 && blen1=%ld\n", blen1);
        !           123:         blen1 = 0;
        !           124:     }
        !           125: 
        !           126:     if (!p2 && blen2) {
        !           127:         dolog ("warning: !p2 && blen2=%ld\n", blen2);
        !           128:         blen2 = 0;
        !           129:     }
        !           130: 
        !           131:     *p1p = p1;
        !           132:     *p2p = p2;
        !           133:     *blen1p = blen1;
        !           134:     *blen2p = blen2;
        !           135:     return 0;
        !           136: 
        !           137:  fail:
        !           138:     *p1p = NULL - 1;
        !           139:     *p2p = NULL - 1;
        !           140:     *blen1p = -1;
        !           141:     *blen2p = -1;
        !           142:     return -1;
        !           143: }
        !           144: 
        !           145: #ifdef DSBTYPE_IN
        !           146: static void dsound_fini_in (HWVoiceIn *hw)
        !           147: #else
        !           148: static void dsound_fini_out (HWVoiceOut *hw)
        !           149: #endif
        !           150: {
        !           151:     HRESULT hr;
        !           152: #ifdef DSBTYPE_IN
        !           153:     DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
        !           154: #else
        !           155:     DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
        !           156: #endif
        !           157: 
        !           158:     if (ds->FIELD) {
        !           159:         hr = glue (IFACE, _Stop) (ds->FIELD);
        !           160:         if (FAILED (hr)) {
        !           161:             dsound_logerr (hr, "Could not stop " NAME "\n");
        !           162:         }
        !           163: 
        !           164:         hr = glue (IFACE, _Release) (ds->FIELD);
        !           165:         if (FAILED (hr)) {
        !           166:             dsound_logerr (hr, "Could not release " NAME "\n");
        !           167:         }
        !           168:         ds->FIELD = NULL;
        !           169:     }
        !           170: }
        !           171: 
        !           172: #ifdef DSBTYPE_IN
        !           173: static int dsound_init_in (HWVoiceIn *hw, audsettings_t *as)
        !           174: #else
        !           175: static int dsound_init_out (HWVoiceOut *hw, audsettings_t *as)
        !           176: #endif
        !           177: {
        !           178:     int err;
        !           179:     HRESULT hr;
        !           180:     dsound *s = &glob_dsound;
        !           181:     WAVEFORMATEX wfx;
        !           182:     audsettings_t obt_as;
        !           183: #ifdef DSBTYPE_IN
        !           184:     const char *typ = "ADC";
        !           185:     DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
        !           186:     DSCBUFFERDESC bd;
        !           187:     DSCBCAPS bc;
        !           188: #else
        !           189:     const char *typ = "DAC";
        !           190:     DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
        !           191:     DSBUFFERDESC bd;
        !           192:     DSBCAPS bc;
        !           193: #endif
        !           194: 
        !           195:     err = waveformat_from_audio_settings (&wfx, as);
        !           196:     if (err) {
        !           197:         return -1;
        !           198:     }
        !           199: 
        !           200:     memset (&bd, 0, sizeof (bd));
        !           201:     bd.dwSize = sizeof (bd);
        !           202:     bd.lpwfxFormat = &wfx;
        !           203: #ifdef DSBTYPE_IN
        !           204:     bd.dwBufferBytes = conf.bufsize_in;
        !           205:     hr = IDirectSoundCapture_CreateCaptureBuffer (
        !           206:         s->dsound_capture,
        !           207:         &bd,
        !           208:         &ds->dsound_capture_buffer,
        !           209:         NULL
        !           210:         );
        !           211: #else
        !           212:     bd.dwFlags = DSBCAPS_STICKYFOCUS | DSBCAPS_GETCURRENTPOSITION2;
        !           213:     bd.dwBufferBytes = conf.bufsize_out;
        !           214:     hr = IDirectSound_CreateSoundBuffer (
        !           215:         s->dsound,
        !           216:         &bd,
        !           217:         &ds->dsound_buffer,
        !           218:         NULL
        !           219:         );
        !           220: #endif
        !           221: 
        !           222:     if (FAILED (hr)) {
        !           223:         dsound_logerr2 (hr, typ, "Could not create " NAME "\n");
        !           224:         return -1;
        !           225:     }
        !           226: 
        !           227:     hr = glue (IFACE, _GetFormat) (ds->FIELD, &wfx, sizeof (wfx), NULL);
        !           228:     if (FAILED (hr)) {
        !           229:         dsound_logerr2 (hr, typ, "Could not get " NAME " format\n");
        !           230:         goto fail0;
        !           231:     }
        !           232: 
        !           233: #ifdef DEBUG_DSOUND
        !           234:     dolog (NAME "\n");
        !           235:     print_wave_format (&wfx);
        !           236: #endif
        !           237: 
        !           238:     memset (&bc, 0, sizeof (bc));
        !           239:     bc.dwSize = sizeof (bc);
        !           240: 
        !           241:     hr = glue (IFACE, _GetCaps) (ds->FIELD, &bc);
        !           242:     if (FAILED (hr)) {
        !           243:         dsound_logerr2 (hr, typ, "Could not get " NAME " format\n");
        !           244:         goto fail0;
        !           245:     }
        !           246: 
        !           247:     err = waveformat_to_audio_settings (&wfx, &obt_as);
        !           248:     if (err) {
        !           249:         goto fail0;
        !           250:     }
        !           251: 
        !           252:     ds->first_time = 1;
        !           253: 
        !           254:     audio_pcm_init_info (&hw->info, &obt_as, audio_need_to_swap_endian (0));
        !           255: 
        !           256:     if (bc.dwBufferBytes & hw->info.align) {
        !           257:         dolog (
        !           258:             "GetCaps returned misaligned buffer size %ld, alignment %d\n",
        !           259:             bc.dwBufferBytes, hw->info.align + 1
        !           260:             );
        !           261:     }
        !           262:     hw->samples = bc.dwBufferBytes >> hw->info.shift;
        !           263: 
        !           264: #ifdef DEBUG_DSOUND
        !           265:     dolog ("caps %ld, desc %ld\n",
        !           266:            bc.dwBufferBytes, bd.dwBufferBytes);
        !           267: 
        !           268:     dolog ("bufsize %d, freq %d, chan %d, fmt %d\n",
        !           269:            hw->bufsize, settings.freq, settings.nchannels, settings.fmt);
        !           270: #endif
        !           271:     return 0;
        !           272: 
        !           273:  fail0:
        !           274:     glue (dsound_fini_, TYPE) (hw);
        !           275:     return -1;
        !           276: }
        !           277: 
        !           278: #undef NAME
        !           279: #undef TYPE
        !           280: #undef IFACE
        !           281: #undef BUFPTR
        !           282: #undef FIELD

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.