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

📄 coreaudio.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * QEMU OS X CoreAudio audio driver * * Copyright (c) 2005 Mike Kronenberg * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */#include <CoreAudio/CoreAudio.h>#include <string.h>             /* strerror */#include <pthread.h>            /* pthread_X */#include "vl.h"#define AUDIO_CAP "coreaudio"#include "audio_int.h"struct {    int buffer_frames;    int nbuffers;    int isAtexit;} conf = {    .buffer_frames = 512,    .nbuffers = 4,    .isAtexit = 0};typedef struct coreaudioVoiceOut {    HWVoiceOut hw;    pthread_mutex_t mutex;    int isAtexit;    AudioDeviceID outputDeviceID;    UInt32 audioDevicePropertyBufferFrameSize;    AudioStreamBasicDescription outputStreamBasicDescription;    int live;    int decr;    int rpos;} coreaudioVoiceOut;static void coreaudio_logstatus (OSStatus status){    char *str = "BUG";    switch(status) {    case kAudioHardwareNoError:        str = "kAudioHardwareNoError";        break;    case kAudioHardwareNotRunningError:        str = "kAudioHardwareNotRunningError";        break;    case kAudioHardwareUnspecifiedError:        str = "kAudioHardwareUnspecifiedError";        break;    case kAudioHardwareUnknownPropertyError:        str = "kAudioHardwareUnknownPropertyError";        break;    case kAudioHardwareBadPropertySizeError:        str = "kAudioHardwareBadPropertySizeError";        break;    case kAudioHardwareIllegalOperationError:        str = "kAudioHardwareIllegalOperationError";        break;    case kAudioHardwareBadDeviceError:        str = "kAudioHardwareBadDeviceError";        break;    case kAudioHardwareBadStreamError:        str = "kAudioHardwareBadStreamError";        break;    case kAudioHardwareUnsupportedOperationError:        str = "kAudioHardwareUnsupportedOperationError";        break;    case kAudioDeviceUnsupportedFormatError:        str = "kAudioDeviceUnsupportedFormatError";        break;    case kAudioDevicePermissionsError:        str = "kAudioDevicePermissionsError";        break;    default:        AUD_log (AUDIO_CAP, "Reason: status code %ld\n", status);        return;    }    AUD_log (AUDIO_CAP, "Reason: %s\n", str);}static void GCC_FMT_ATTR (2, 3) coreaudio_logerr (    OSStatus status,    const char *fmt,    ...    ){    va_list ap;    va_start (ap, fmt);    AUD_log (AUDIO_CAP, fmt, ap);    va_end (ap);    coreaudio_logstatus (status);}static void GCC_FMT_ATTR (3, 4) coreaudio_logerr2 (    OSStatus status,    const char *typ,    const char *fmt,    ...    ){    va_list ap;    AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);    va_start (ap, fmt);    AUD_vlog (AUDIO_CAP, fmt, ap);    va_end (ap);    coreaudio_logstatus (status);}static inline UInt32 isPlaying (AudioDeviceID outputDeviceID){    OSStatus status;    UInt32 result = 0;    UInt32 propertySize = sizeof(outputDeviceID);    status = AudioDeviceGetProperty(        outputDeviceID, 0, 0,        kAudioDevicePropertyDeviceIsRunning, &propertySize, &result);    if (status != kAudioHardwareNoError) {        coreaudio_logerr(status,                         "Could not determine whether Device is playing\n");    }    return result;}static void coreaudio_atexit (void){    conf.isAtexit = 1;}static int coreaudio_lock (coreaudioVoiceOut *core, const char *fn_name){    int err;    err = pthread_mutex_lock (&core->mutex);    if (err) {        dolog ("Could not lock voice for %s\nReason: %s\n",               fn_name, strerror (err));        return -1;    }    return 0;}static int coreaudio_unlock (coreaudioVoiceOut *core, const char *fn_name){    int err;    err = pthread_mutex_unlock (&core->mutex);    if (err) {        dolog ("Could not unlock voice for %s\nReason: %s\n",               fn_name, strerror (err));        return -1;    }    return 0;}static int coreaudio_run_out (HWVoiceOut *hw){    int live, decr;    coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;    if (coreaudio_lock (core, "coreaudio_run_out")) {        return 0;    }    live = audio_pcm_hw_get_live_out (hw);    if (core->decr > live) {        ldebug ("core->decr %d live %d core->live %d\n",                core->decr,                live,                core->live);    }    decr = audio_MIN (core->decr, live);    core->decr -= decr;    core->live = live - decr;    hw->rpos = core->rpos;    coreaudio_unlock (core, "coreaudio_run_out");    return decr;}/* callback to feed audiooutput buffer */static OSStatus audioDeviceIOProc(    AudioDeviceID inDevice,    const AudioTimeStamp* inNow,    const AudioBufferList* inInputData,    const AudioTimeStamp* inInputTime,    AudioBufferList* outOutputData,    const AudioTimeStamp* inOutputTime,    void* hwptr){    UInt32 frame, frameCount;    float *out = outOutputData->mBuffers[0].mData;    HWVoiceOut *hw = hwptr;    coreaudioVoiceOut *core = (coreaudioVoiceOut *) hwptr;    int rpos, live;    st_sample_t *src;#ifndef FLOAT_MIXENG#ifdef RECIPROCAL    const float scale = 1.f / UINT_MAX;#else    const float scale = UINT_MAX;#endif#endif    if (coreaudio_lock (core, "audioDeviceIOProc")) {        inInputTime = 0;        return 0;    }    frameCount = core->audioDevicePropertyBufferFrameSize;    live = core->live;    /* if there are not enough samples, set signal and return */    if (live < frameCount) {        inInputTime = 0;        coreaudio_unlock (core, "audioDeviceIOProc(empty)");        return 0;    }    rpos = core->rpos;    src = hw->mix_buf + rpos;    /* fill buffer */    for (frame = 0; frame < frameCount; frame++) {#ifdef FLOAT_MIXENG        *out++ = src[frame].l; /* left channel */        *out++ = src[frame].r; /* right channel */#else#ifdef RECIPROCAL        *out++ = src[frame].l * scale; /* left channel */        *out++ = src[frame].r * scale; /* right channel */#else        *out++ = src[frame].l / scale; /* left channel */        *out++ = src[frame].r / scale; /* right channel */#endif#endif    }    rpos = (rpos + frameCount) % hw->samples;

⌨️ 快捷键说明

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