(linenum→info "unix/slp.c:2238")

qemu/0.9.1/audio/dsound_template.h

    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:     DWORD flag;
   74: 
   75: #ifdef DSBTYPE_IN
   76:     flag = entire ? DSCBLOCK_ENTIREBUFFER : 0;
   77: #else
   78:     flag = entire ? DSBLOCK_ENTIREBUFFER : 0;
   79: #endif
   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,
   89:             flag
   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:     obt_as.endianness = 0;
  254:     audio_pcm_init_info (&hw->info, &obt_as);
  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
Syntax (Markdown)