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

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"
1.1.1.3 ! root       26: #define NAME2 "DirectSoundCapture"
1.1       root       27: #define TYPE in
                     28: #define IFACE IDirectSoundCaptureBuffer
                     29: #define BUFPTR LPDIRECTSOUNDCAPTUREBUFFER
                     30: #define FIELD dsound_capture_buffer
1.1.1.3 ! root       31: #define FIELD2 dsound_capture
1.1       root       32: #else
                     33: #define NAME "playback buffer"
1.1.1.3 ! root       34: #define NAME2 "DirectSound"
1.1       root       35: #define TYPE out
                     36: #define IFACE IDirectSoundBuffer
                     37: #define BUFPTR LPDIRECTSOUNDBUFFER
                     38: #define FIELD dsound_buffer
1.1.1.3 ! root       39: #define FIELD2 dsound
1.1       root       40: #endif
                     41: 
                     42: static int glue (dsound_unlock_, TYPE) (
                     43:     BUFPTR buf,
                     44:     LPVOID p1,
                     45:     LPVOID p2,
                     46:     DWORD blen1,
                     47:     DWORD blen2
                     48:     )
                     49: {
                     50:     HRESULT hr;
                     51: 
                     52:     hr = glue (IFACE, _Unlock) (buf, p1, blen1, p2, blen2);
                     53:     if (FAILED (hr)) {
                     54:         dsound_logerr (hr, "Could not unlock " NAME "\n");
                     55:         return -1;
                     56:     }
                     57: 
                     58:     return 0;
                     59: }
                     60: 
                     61: static int glue (dsound_lock_, TYPE) (
                     62:     BUFPTR buf,
                     63:     struct audio_pcm_info *info,
                     64:     DWORD pos,
                     65:     DWORD len,
                     66:     LPVOID *p1p,
                     67:     LPVOID *p2p,
                     68:     DWORD *blen1p,
                     69:     DWORD *blen2p,
                     70:     int entire
                     71:     )
                     72: {
                     73:     HRESULT hr;
                     74:     int i;
                     75:     LPVOID p1 = NULL, p2 = NULL;
                     76:     DWORD blen1 = 0, blen2 = 0;
1.1.1.2   root       77:     DWORD flag;
1.1       root       78: 
1.1.1.2   root       79: #ifdef DSBTYPE_IN
                     80:     flag = entire ? DSCBLOCK_ENTIREBUFFER : 0;
                     81: #else
                     82:     flag = entire ? DSBLOCK_ENTIREBUFFER : 0;
                     83: #endif
1.1       root       84:     for (i = 0; i < conf.lock_retries; ++i) {
                     85:         hr = glue (IFACE, _Lock) (
                     86:             buf,
                     87:             pos,
                     88:             len,
                     89:             &p1,
                     90:             &blen1,
                     91:             &p2,
                     92:             &blen2,
1.1.1.2   root       93:             flag
1.1       root       94:             );
                     95: 
                     96:         if (FAILED (hr)) {
                     97: #ifndef DSBTYPE_IN
                     98:             if (hr == DSERR_BUFFERLOST) {
                     99:                 if (glue (dsound_restore_, TYPE) (buf)) {
                    100:                     dsound_logerr (hr, "Could not lock " NAME "\n");
                    101:                     goto fail;
                    102:                 }
                    103:                 continue;
                    104:             }
                    105: #endif
                    106:             dsound_logerr (hr, "Could not lock " NAME "\n");
                    107:             goto fail;
                    108:         }
                    109: 
                    110:         break;
                    111:     }
                    112: 
                    113:     if (i == conf.lock_retries) {
                    114:         dolog ("%d attempts to lock " NAME " failed\n", i);
                    115:         goto fail;
                    116:     }
                    117: 
                    118:     if ((p1 && (blen1 & info->align)) || (p2 && (blen2 & info->align))) {
                    119:         dolog ("DirectSound returned misaligned buffer %ld %ld\n",
                    120:                blen1, blen2);
                    121:         glue (dsound_unlock_, TYPE) (buf, p1, p2, blen1, blen2);
                    122:         goto fail;
                    123:     }
                    124: 
                    125:     if (!p1 && blen1) {
                    126:         dolog ("warning: !p1 && blen1=%ld\n", blen1);
                    127:         blen1 = 0;
                    128:     }
                    129: 
                    130:     if (!p2 && blen2) {
                    131:         dolog ("warning: !p2 && blen2=%ld\n", blen2);
                    132:         blen2 = 0;
                    133:     }
                    134: 
                    135:     *p1p = p1;
                    136:     *p2p = p2;
                    137:     *blen1p = blen1;
                    138:     *blen2p = blen2;
                    139:     return 0;
                    140: 
                    141:  fail:
                    142:     *p1p = NULL - 1;
                    143:     *p2p = NULL - 1;
                    144:     *blen1p = -1;
                    145:     *blen2p = -1;
                    146:     return -1;
                    147: }
                    148: 
                    149: #ifdef DSBTYPE_IN
                    150: static void dsound_fini_in (HWVoiceIn *hw)
                    151: #else
                    152: static void dsound_fini_out (HWVoiceOut *hw)
                    153: #endif
                    154: {
                    155:     HRESULT hr;
                    156: #ifdef DSBTYPE_IN
                    157:     DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
                    158: #else
                    159:     DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
                    160: #endif
                    161: 
                    162:     if (ds->FIELD) {
                    163:         hr = glue (IFACE, _Stop) (ds->FIELD);
                    164:         if (FAILED (hr)) {
                    165:             dsound_logerr (hr, "Could not stop " NAME "\n");
                    166:         }
                    167: 
                    168:         hr = glue (IFACE, _Release) (ds->FIELD);
                    169:         if (FAILED (hr)) {
                    170:             dsound_logerr (hr, "Could not release " NAME "\n");
                    171:         }
                    172:         ds->FIELD = NULL;
                    173:     }
                    174: }
                    175: 
                    176: #ifdef DSBTYPE_IN
1.1.1.3 ! root      177: static int dsound_init_in (HWVoiceIn *hw, struct audsettings *as)
1.1       root      178: #else
1.1.1.3 ! root      179: static int dsound_init_out (HWVoiceOut *hw, struct audsettings *as)
1.1       root      180: #endif
                    181: {
                    182:     int err;
                    183:     HRESULT hr;
                    184:     dsound *s = &glob_dsound;
                    185:     WAVEFORMATEX wfx;
1.1.1.3 ! root      186:     struct audsettings obt_as;
1.1       root      187: #ifdef DSBTYPE_IN
                    188:     const char *typ = "ADC";
                    189:     DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
                    190:     DSCBUFFERDESC bd;
                    191:     DSCBCAPS bc;
                    192: #else
                    193:     const char *typ = "DAC";
                    194:     DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
                    195:     DSBUFFERDESC bd;
                    196:     DSBCAPS bc;
                    197: #endif
                    198: 
1.1.1.3 ! root      199:     if (!s->FIELD2) {
        !           200:         dolog ("Attempt to initialize voice without " NAME2 " object\n");
        !           201:         return -1;
        !           202:     }
        !           203: 
1.1       root      204:     err = waveformat_from_audio_settings (&wfx, as);
                    205:     if (err) {
                    206:         return -1;
                    207:     }
                    208: 
                    209:     memset (&bd, 0, sizeof (bd));
                    210:     bd.dwSize = sizeof (bd);
                    211:     bd.lpwfxFormat = &wfx;
                    212: #ifdef DSBTYPE_IN
                    213:     bd.dwBufferBytes = conf.bufsize_in;
                    214:     hr = IDirectSoundCapture_CreateCaptureBuffer (
                    215:         s->dsound_capture,
                    216:         &bd,
                    217:         &ds->dsound_capture_buffer,
                    218:         NULL
                    219:         );
                    220: #else
                    221:     bd.dwFlags = DSBCAPS_STICKYFOCUS | DSBCAPS_GETCURRENTPOSITION2;
                    222:     bd.dwBufferBytes = conf.bufsize_out;
                    223:     hr = IDirectSound_CreateSoundBuffer (
                    224:         s->dsound,
                    225:         &bd,
                    226:         &ds->dsound_buffer,
                    227:         NULL
                    228:         );
                    229: #endif
                    230: 
                    231:     if (FAILED (hr)) {
                    232:         dsound_logerr2 (hr, typ, "Could not create " NAME "\n");
                    233:         return -1;
                    234:     }
                    235: 
                    236:     hr = glue (IFACE, _GetFormat) (ds->FIELD, &wfx, sizeof (wfx), NULL);
                    237:     if (FAILED (hr)) {
                    238:         dsound_logerr2 (hr, typ, "Could not get " NAME " format\n");
                    239:         goto fail0;
                    240:     }
                    241: 
                    242: #ifdef DEBUG_DSOUND
                    243:     dolog (NAME "\n");
                    244:     print_wave_format (&wfx);
                    245: #endif
                    246: 
                    247:     memset (&bc, 0, sizeof (bc));
                    248:     bc.dwSize = sizeof (bc);
                    249: 
                    250:     hr = glue (IFACE, _GetCaps) (ds->FIELD, &bc);
                    251:     if (FAILED (hr)) {
                    252:         dsound_logerr2 (hr, typ, "Could not get " NAME " format\n");
                    253:         goto fail0;
                    254:     }
                    255: 
                    256:     err = waveformat_to_audio_settings (&wfx, &obt_as);
                    257:     if (err) {
                    258:         goto fail0;
                    259:     }
                    260: 
                    261:     ds->first_time = 1;
1.1.1.2   root      262:     obt_as.endianness = 0;
                    263:     audio_pcm_init_info (&hw->info, &obt_as);
1.1       root      264: 
                    265:     if (bc.dwBufferBytes & hw->info.align) {
                    266:         dolog (
                    267:             "GetCaps returned misaligned buffer size %ld, alignment %d\n",
                    268:             bc.dwBufferBytes, hw->info.align + 1
                    269:             );
                    270:     }
                    271:     hw->samples = bc.dwBufferBytes >> hw->info.shift;
                    272: 
                    273: #ifdef DEBUG_DSOUND
                    274:     dolog ("caps %ld, desc %ld\n",
                    275:            bc.dwBufferBytes, bd.dwBufferBytes);
                    276: 
                    277:     dolog ("bufsize %d, freq %d, chan %d, fmt %d\n",
                    278:            hw->bufsize, settings.freq, settings.nchannels, settings.fmt);
                    279: #endif
                    280:     return 0;
                    281: 
                    282:  fail0:
                    283:     glue (dsound_fini_, TYPE) (hw);
                    284:     return -1;
                    285: }
                    286: 
                    287: #undef NAME
1.1.1.3 ! root      288: #undef NAME2
1.1       root      289: #undef TYPE
                    290: #undef IFACE
                    291: #undef BUFPTR
                    292: #undef FIELD
1.1.1.3 ! root      293: #undef FIELD2

unix.superglobalmegacorp.com

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