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

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;
1.1.1.2 ! root       73:     DWORD flag;
1.1       root       74: 
1.1.1.2 ! root       75: #ifdef DSBTYPE_IN
        !            76:     flag = entire ? DSCBLOCK_ENTIREBUFFER : 0;
        !            77: #else
        !            78:     flag = entire ? DSBLOCK_ENTIREBUFFER : 0;
        !            79: #endif
1.1       root       80:     for (i = 0; i < conf.lock_retries; ++i) {
                     81:         hr = glue (IFACE, _Lock) (
                     82:             buf,
                     83:             pos,
                     84:             len,
                     85:             &p1,
                     86:             &blen1,
                     87:             &p2,
                     88:             &blen2,
1.1.1.2 ! root       89:             flag
1.1       root       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;
1.1.1.2 ! root      253:     obt_as.endianness = 0;
        !           254:     audio_pcm_init_info (&hw->info, &obt_as);
1.1       root      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.