/*
 * QEMU OS X CoreAudio audio driver
 *
 * Copyright (c) 2008 The Android Open Source Project
 * 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 "qemu-common.h"
#include "audio.h"

#define AUDIO_CAP "coreaudio"
#include "audio_int.h"

#if 0
#  define  D(...)  fprintf(stderr, __VA_ARGS__)
#else
#  define  D(...)  ((void)0)
#endif

struct {
    int out_buffer_frames;
    int out_nbuffers;
    int in_buffer_frames;
    int in_nbuffers;
    int isAtexit;
} conf = {
    .out_buffer_frames = 512,
    .out_nbuffers = 4,
    .in_buffer_frames = 512,
    .in_nbuffers = 4,
    .isAtexit = 0
};

/***************************************************************************************/
/***************************************************************************************/
/***                                                                                 ***/
/***       U T I L I T Y   R O U T I N E S                                           ***/
/***                                                                                 ***/
/***************************************************************************************/
/***************************************************************************************/

static void coreaudio_logstatus (OSStatus status)
{
    const 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 %" PRId32 "\n", (int32_t)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);
}

/***************************************************************************************/
/***************************************************************************************/
/***                                                                                 ***/
/***       S H A R E D   I N / O U T   V O I C E                                     ***/
/***                                                                                 ***/
/***************************************************************************************/
/***************************************************************************************/

typedef struct coreAudioVoice {
    pthread_mutex_t              mutex;
    AudioDeviceID                deviceID;
    Boolean                      isInput;
    UInt32                       bufferFrameSize;
    AudioStreamBasicDescription  streamBasicDescription;
    AudioDeviceIOProc            ioproc;
    int                          live;
    int                          decr;
    int                          pos;
} coreaudioVoice;

static inline UInt32 coreaudio_voice_isPlaying (coreaudioVoice *core)
{
    OSStatus status;
    UInt32 result = 0;
    UInt32 propertySize = sizeof(core->deviceID);
    status = AudioDeviceGetProperty(
        core->deviceID, 0, core->isInput,
        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_voice_lock (coreaudioVoice *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_voice_unlock (coreaudioVoice *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_voice_ctl (coreaudioVoice *core, int cmd)
{
    OSStatus status;

    switch (cmd) {
    case VOICE_ENABLE:
        /* start playback */
        D("%s: %s started\n", __FUNCTION__, core->isInput ? "input" : "output");
        if (!coreaudio_voice_isPlaying(core)) {
            status = AudioDeviceStart(core->deviceID, core->ioproc);
            if (status != kAudioHardwareNoError) {
                coreaudio_logerr (status, "Could not resume playback\n");
            }
        }
        break;

    case VOICE_DISABLE:
        /* stop playback */
        D("%s: %s stopped\n", __FUNCTION__, core->isInput ? "input" : "output");
        if (!conf.isAtexit) {
            if (coreaudio_voice_isPlaying(core)) {
                status = AudioDeviceStop(core->deviceID, core->ioproc);
                if (status != kAudioHardwareNoError) {
                    coreaudio_logerr (status, "Could not pause playback\n");
                }
            }
        }
        break;
    }
    return 0;
}

static void coreaudio_voice_fini (coreaudioVoice *core)
{
    OSStatus status;
    int err;

    if (!conf.isAtexit) {
        /* stop playback */
        coreaudio_voice_ctl(core, VOICE_DISABLE);

        /* remove callback */
        status = AudioDeviceRemoveIOProc(core->deviceID, core->ioproc);
        if (status != kAudioHardwareNoError) {
            coreaudio_logerr (status, "Could not remove IOProc\n");
        }
    }
    core->deviceID = kAudioDeviceUnknown;

    /* destroy mutex */
    err = pthread_mutex_destroy(&core->mutex);
    if (err) {
        dolog("Could not destroy mutex\nReason: %s\n", strerror (err));
    }
}


static int coreaudio_voice_init (coreaudioVoice *core, struct audsettings *as,
                                 int frameSize, AudioDeviceIOProc ioproc,
                                 void *hw, int input)
{
    OSStatus  status;
    UInt32    propertySize;
    int       err;
    int       bits = 8;
    AudioValueRange frameRange;
    const char*  typ = input ? "input" : "playback";

    core->isInput = input ? true : false;

    /* create mutex */
    err = pthread_mutex_init(&core->mutex, NULL);
    if (err) {
        dolog("Could not create mutex\nReason: %s\n", strerror (err));
        return -1;
    }

    if (as->fmt == AUD_FMT_S16 || as->fmt == AUD_FMT_U16) {
        bits = 16;
    }

    // TODO: audio_pcm_init_info (&hw->info, as);
    /* open default output device */
    /* note: we use DefaultSystemOutputDevice because DefaultOutputDevice seems to
     * always link to the internal speakers, and not the ones selected through system properties
     * go figure...
     */
    propertySize = sizeof(core->deviceID);
    status = AudioHardwareGetProperty(
        input ? kAudioHardwarePropertyDefaultInputDevice :
                kAudioHardwarePropertyDefaultSystemOutputDevice,
        &propertySize,
        &core->deviceID);
    if (status != kAudioHardwareNoError) {
        coreaudio_logerr2 (status, typ,
                           "Could not get default %s device\n", typ);
        return -1;
    }
    if (core->deviceID == kAudioDeviceUnknown) {
        dolog ("Could not initialize %s - Unknown Audiodevice\n", typ);
        return -1;
    }

    /* get minimum and maximum buffer frame sizes */
    propertySize = sizeof(frameRange);
    status = AudioDeviceGetProperty(
        core->deviceID,
        0,
        core->isInput,
        kAudioDevicePropertyBufferFrameSizeRange,
        &propertySize,
        &frameRange);
    if (status != kAudioHardwareNoError) {
        coreaudio_logerr2 (status, typ,
                           "Could not get device buffer frame range\n");
        return -1;
    }

    if (frameRange.mMinimum > frameSize) {
        core->bufferFrameSize = (UInt32) frameRange.mMinimum;
        dolog ("warning: Upsizing Output Buffer Frames to %f\n", frameRange.mMinimum);
    }
    else if (frameRange.mMaximum < frameSize) {
        core->bufferFrameSize = (UInt32) frameRange.mMaximum;
        dolog ("warning: Downsizing Output Buffer Frames to %f\n", frameRange.mMaximum);
    }
    else {
        core->bufferFrameSize = frameSize;
    }

    /* set Buffer Frame Size */
    propertySize = sizeof(core->bufferFrameSize);
    status = AudioDeviceSetProperty(
        core->deviceID,
        NULL,
        0,
        core->isInput,
        kAudioDevicePropertyBufferFrameSize,
        propertySize,
        &core->bufferFrameSize);
    if (status != kAudioHardwareNoError) {
        coreaudio_logerr2 (status, typ,
                           "Could not set device buffer frame size %" PRIu32 "\n",
                           (uint32_t)core->bufferFrameSize);
        return -1;
    }

    /* get Buffer Frame Size */
    propertySize = sizeof(core->bufferFrameSize);
    status = AudioDeviceGetProperty(
        core->deviceID,
        0,
        core->isInput,
        kAudioDevicePropertyBufferFrameSize,
        &propertySize,
        &core->bufferFrameSize);
    if (status != kAudioHardwareNoError) {
        coreaudio_logerr2 (status, typ,
                           "Could not get device buffer frame size\n");
        return -1;
    }
    // TODO: hw->samples = *pNBuffers * core->bufferFrameSize;

    /* get StreamFormat */
    propertySize = sizeof(core->streamBasicDescription);
    status = AudioDeviceGetProperty(
        core->deviceID,
        0,
        core->isInput,
        kAudioDevicePropertyStreamFormat,
        &propertySize,
        &core->streamBasicDescription);
    if (status != kAudioHardwareNoError) {
        coreaudio_logerr2 (status, typ,
                           "Could not get Device Stream properties\n");
        core->deviceID = kAudioDeviceUnknown;
        return -1;
    }

    /* set Samplerate */
    core->streamBasicDescription.mSampleRate = (Float64) as->freq;
    propertySize = sizeof(core->streamBasicDescription);
    status = AudioDeviceSetProperty(
        core->deviceID,
        0,
        0,
        core->isInput,
        kAudioDevicePropertyStreamFormat,
        propertySize,
        &core->streamBasicDescription);
    if (status != kAudioHardwareNoError) {
        coreaudio_logerr2 (status, typ, "Could not set samplerate %d\n",
                           as->freq);
        core->deviceID = kAudioDeviceUnknown;
        return -1;
    }

    /* set Callback */
    core->ioproc = ioproc;
    status = AudioDeviceAddIOProc(core->deviceID, ioproc, hw);
    if (status != kAudioHardwareNoError) {
        coreaudio_logerr2 (status, typ, "Could not set IOProc\n");
        core->deviceID = kAudioDeviceUnknown;
        return -1;
    }

    /* start Playback */
    if (!input && !coreaudio_voice_isPlaying(core)) {
        status = AudioDeviceStart(core->deviceID, core->ioproc);
        if (status != kAudioHardwareNoError) {
            coreaudio_logerr2 (status, typ, "Could not start playback\n");
            AudioDeviceRemoveIOProc(core->deviceID, core->ioproc);
            core->deviceID = kAudioDeviceUnknown;
            return -1;
        }
    }

    return 0;
}


/***************************************************************************************/
/***************************************************************************************/
/***                                                                                 ***/
/***       O U T P U T   V O I C E                                                   ***/
/***                                                                                 ***/
/***************************************************************************************/
/***************************************************************************************/

typedef struct coreaudioVoiceOut {
    HWVoiceOut                   hw;
    coreaudioVoice               core[1];
} coreaudioVoiceOut;

#define  CORE_OUT(hw)  ((coreaudioVoiceOut*)(hw))->core


static int coreaudio_run_out (HWVoiceOut *hw, int live)
{
    int decr;
    coreaudioVoice *core = CORE_OUT(hw);

    if (coreaudio_voice_lock (core, "coreaudio_run_out")) {
        return 0;
    }

    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->pos;

    coreaudio_voice_unlock (core, "coreaudio_run_out");
    return decr;
}

/* callback to feed audiooutput buffer */
static OSStatus audioOutDeviceIOProc(
    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;
    coreaudioVoice *core = CORE_OUT(hw);
    int rpos, live;
    struct st_sample *src;
#ifndef FLOAT_MIXENG
#ifdef RECIPROCAL
    const float scale = 1.f / UINT_MAX;
#else
    const float scale = UINT_MAX;
#endif
#endif

    if (coreaudio_voice_lock (core, "audioDeviceIOProc")) {
        inInputTime = 0;
        return 0;
    }

    frameCount = core->bufferFrameSize;
    live = core->live;

    /* if there are not enough samples, set signal and return */
    if (live < (int)frameCount) {
        inInputTime = 0;
        coreaudio_voice_unlock (core, "audioDeviceIOProc(empty)");
        return 0;
    }

    rpos = core->pos;
    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;
    core->decr += frameCount;
    core->pos = rpos;

    coreaudio_voice_unlock (core, "audioDeviceIOProc");
    return 0;
}

static int coreaudio_write (SWVoiceOut *sw, void *buf, int len)
{
    return audio_pcm_sw_write (sw, buf, len);
}

static int coreaudio_init_out (HWVoiceOut *hw, struct audsettings *as)
{
    coreaudioVoice *core = CORE_OUT(hw);
    int err;

    audio_pcm_init_info (&hw->info, as);

    err = coreaudio_voice_init (core, as, conf.out_buffer_frames, audioOutDeviceIOProc, hw, 0);
    if (err < 0)
        return err;

    hw->samples = core->bufferFrameSize * conf.out_nbuffers;
    return 0;
}

static void coreaudio_fini_out (HWVoiceOut *hw)
{
    coreaudioVoice *core = CORE_OUT(hw);

    coreaudio_voice_fini (core);
}

static int
coreaudio_ctl_out (HWVoiceOut *hw, int cmd, ...)
{
    coreaudioVoice *core = CORE_OUT(hw);

    return coreaudio_voice_ctl (core, cmd);
}

/***************************************************************************************/
/***************************************************************************************/
/***                                                                                 ***/
/***       I N P U T   V O I C E                                                     ***/
/***                                                                                 ***/
/***************************************************************************************/
/***************************************************************************************/



typedef struct coreaudioVoiceIn {
    HWVoiceIn        hw;
    coreaudioVoice   core[1];
} coreaudioVoiceIn;

#define  CORE_IN(hw)  ((coreaudioVoiceIn *) (hw))->core


static int coreaudio_run_in (HWVoiceIn *hw)
{
    int decr;

    coreaudioVoice *core = CORE_IN(hw);

    if (coreaudio_voice_lock (core, "coreaudio_run_in")) {
        return 0;
    }
    D("%s: core.decr=%d core.pos=%d\n", __FUNCTION__, core->decr, core->pos);
    decr        = core->decr;
    core->decr -= decr;
    hw->wpos    = core->pos;

    coreaudio_voice_unlock (core, "coreaudio_run_in");
    return decr;
}


/* callback to feed audiooutput buffer */
static OSStatus audioInDeviceIOProc(
    AudioDeviceID inDevice,
    const AudioTimeStamp* inNow,
    const AudioBufferList* inInputData,
    const AudioTimeStamp* inInputTime,
    AudioBufferList* outOutputData,
    const AudioTimeStamp* inOutputTime,
    void* hwptr)
{
    UInt32 frame, frameCount;
    float *in = inInputData->mBuffers[0].mData;
    HWVoiceIn *hw = hwptr;
    coreaudioVoice *core = CORE_IN(hw);
    int wpos, avail;
    struct st_sample *dst;
#ifndef FLOAT_MIXENG
#ifdef RECIPROCAL
    const float scale = 1.f / UINT_MAX;
#else
    const float scale = UINT_MAX;
#endif
#endif

    if (coreaudio_voice_lock (core, "audioDeviceIOProc")) {
        inInputTime = 0;
        return 0;
    }

    frameCount = core->bufferFrameSize;
    avail      = hw->samples - hw->total_samples_captured - core->decr;

    D("%s: enter avail=%d core.decr=%d core.pos=%d hw.samples=%d hw.total_samples_captured=%d frameCount=%d\n",
      __FUNCTION__, avail, core->decr, core->pos, hw->samples, hw->total_samples_captured, (int)frameCount);

    /* if there are not enough samples, set signal and return */
    if (avail < (int)frameCount) {
        inInputTime = 0;
        coreaudio_voice_unlock (core, "audioDeviceIOProc(empty)");
        return 0;
    }

    wpos = core->pos;
    dst  = hw->conv_buf + wpos;

    /* fill buffer */
    for (frame = 0; frame < frameCount; frame++) {
#ifdef FLOAT_MIXENG
        dst[frame].l = *in++; /* left channel */
        dst[frame].r = *in++; /* right channel */
#else
#ifdef RECIPROCAL
        dst[frame].l = *in++ * scale; /* left channel */
        dst[frame].r = *in++ * scale; /* right channel */
#else
        dst[frame].l = *in++ / scale; /* left channel */
        dst[frame].r = *in++ / scale; /* right channel */
#endif
#endif
    }

    wpos = (wpos + frameCount) % hw->samples;
    core->decr += frameCount;
    core->pos   = wpos;

    D("exit: core.decr=%d core.pos=%d\n", core->decr, core->pos);
    coreaudio_voice_unlock (core, "audioDeviceIOProc");
    return 0;
}

static int coreaudio_read (SWVoiceIn *sw, void *buf, int len)
{
    int  result = audio_pcm_sw_read (sw, buf, len);
    D("%s: audio_pcm_sw_read(%d) returned %d\n", __FUNCTION__, len, result);
    return result;
}

static int coreaudio_init_in (HWVoiceIn *hw, struct audsettings *as)
{
    coreaudioVoice*  core = CORE_IN(hw);
    int              err;

    audio_pcm_init_info (&hw->info, as);

    err = coreaudio_voice_init (core, as, conf.in_buffer_frames, audioInDeviceIOProc, hw, 1);
    if (err < 0) {
        return err;
    }

    hw->samples = core->bufferFrameSize * conf.in_nbuffers;
    return 0;
}

static void coreaudio_fini_in (HWVoiceIn *hw)
{

    coreaudioVoice*  core = CORE_IN(hw);

    coreaudio_voice_fini(core);
}

static int coreaudio_ctl_in (HWVoiceIn *hw, int cmd, ...)
{
    coreaudioVoice*  core = CORE_IN(hw);

    return coreaudio_voice_ctl(core, cmd);
}

static void *coreaudio_audio_init (void)
{
    atexit(coreaudio_atexit);
    return &coreaudio_audio_init;
}

static void coreaudio_audio_fini (void *opaque)
{
    (void) opaque;
}

static struct audio_option coreaudio_options[] = {
    {
        .name  = "OUT_BUFFER_SIZE",
        .tag   = AUD_OPT_INT,
        .valp  = &conf.out_buffer_frames,
        .descr = "Size of the output buffer in frames"
    },
    {
        .name  = "OUT_BUFFER_COUNT",
        .tag   = AUD_OPT_INT,
        .valp  = &conf.out_nbuffers,
        .descr = "Number of output buffers"
    },
    {
        .name  = "IN_BUFFER_SIZE",
        .tag   = AUD_OPT_INT,
        .valp  = &conf.in_buffer_frames,
        .descr = "Size of the input buffer in frames"
    },
    {
        .name  = "IN_BUFFER_COUNT",
        .tag   = AUD_OPT_INT,
        .valp  = &conf.in_nbuffers,
        .descr = "Number of input buffers"
    },
    { /* End of list */ }
};

static struct audio_pcm_ops coreaudio_pcm_ops = {
    .init_out = coreaudio_init_out,
    .fini_out = coreaudio_fini_out,
    .run_out  = coreaudio_run_out,
    .write    = coreaudio_write,
    .ctl_out  = coreaudio_ctl_out,

    .init_in = coreaudio_init_in,
    .fini_in = coreaudio_fini_in,
    .run_in  = coreaudio_run_in,
    .read    = coreaudio_read,
    .ctl_in  = coreaudio_ctl_in
};

struct audio_driver coreaudio_audio_driver = {
    .name           = "coreaudio",
    .descr          = "CoreAudio http://developer.apple.com/audio/coreaudio.html",
    .options        = coreaudio_options,
    .init           = coreaudio_audio_init,
    .fini           = coreaudio_audio_fini,
    .pcm_ops        = &coreaudio_pcm_ops,
    .can_be_default = 1,
    .max_voices_out = 1,
    .max_voices_in  = 1,
    .voice_size_out = sizeof (coreaudioVoiceOut),
    .voice_size_in  = sizeof (coreaudioVoiceIn),
};
