src/java.desktop/macosx/native/libjsound/PLATFORM_API_MacOSX_PCM.cpp
author coleenp
Fri, 09 Mar 2018 12:03:20 -0500
changeset 49366 f95ef5511e1f
parent 47216 71c04702a3d5
permissions -rw-r--r--
Merge
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
12047
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
     1
/*
29258
adf046d51c1c 8068412: [macosx] Initialization of Cocoa hangs if CoreAudio was initialized before
serb
parents: 25859
diff changeset
     2
 * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
12047
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
     4
 *
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    10
 *
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    15
 * accompanied this code).
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    16
 *
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    20
 *
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    23
 * questions.
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    24
 */
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    25
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    26
//#define USE_ERROR
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    27
//#define USE_TRACE
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    28
//#define USE_VERBOSE_TRACE
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    29
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    30
#include <AudioUnit/AudioUnit.h>
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    31
#include <AudioToolbox/AudioConverter.h>
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    32
#include <pthread.h>
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    33
#include <math.h>
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    34
/*
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    35
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    36
#include <CoreAudio/CoreAudioTypes.h>
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    37
#else
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    38
#include <CoreAudioTypes.h>
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    39
#endif
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    40
*/
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    41
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    42
#include "PLATFORM_API_MacOSX_Utils.h"
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    43
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    44
extern "C" {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    45
#include "Utilities.h"
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    46
#include "DirectAudio.h"
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    47
}
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    48
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    49
#if USE_DAUDIO == TRUE
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    50
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    51
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    52
#ifdef USE_TRACE
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    53
static void PrintStreamDesc(const AudioStreamBasicDescription *inDesc) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    54
    TRACE4("ID='%c%c%c%c'", (char)(inDesc->mFormatID >> 24), (char)(inDesc->mFormatID >> 16), (char)(inDesc->mFormatID >> 8), (char)(inDesc->mFormatID));
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    55
    TRACE2(", %f Hz, flags=0x%lX", (float)inDesc->mSampleRate, (long unsigned)inDesc->mFormatFlags);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    56
    TRACE2(", %ld channels, %ld bits", (long)inDesc->mChannelsPerFrame, (long)inDesc->mBitsPerChannel);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    57
    TRACE1(", %ld bytes per frame\n", (long)inDesc->mBytesPerFrame);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    58
}
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    59
#else
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    60
static inline void PrintStreamDesc(const AudioStreamBasicDescription *inDesc) { }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    61
#endif
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    62
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    63
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    64
#define MAX(x, y)   ((x) >= (y) ? (x) : (y))
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    65
#define MIN(x, y)   ((x) <= (y) ? (x) : (y))
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    66
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    67
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    68
// =======================================
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    69
// MixerProvider functions implementation
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    70
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    71
static DeviceList deviceCache;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    72
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    73
INT32 DAUDIO_GetDirectAudioDeviceCount() {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    74
    deviceCache.Refresh();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    75
    int count = deviceCache.GetCount();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    76
    if (count > 0) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    77
        // add "default" device
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    78
        count++;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    79
        TRACE1("DAUDIO_GetDirectAudioDeviceCount: returns %d devices\n", count);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    80
    } else {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    81
        TRACE0("DAUDIO_GetDirectAudioDeviceCount: no devices found\n");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    82
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    83
    return count;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    84
}
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    85
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    86
INT32 DAUDIO_GetDirectAudioDeviceDescription(INT32 mixerIndex, DirectAudioDeviceDescription *desc) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    87
    bool result = true;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    88
    desc->deviceID = 0;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    89
    if (mixerIndex == 0) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    90
        // default device
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    91
        strncpy(desc->name, "Default Audio Device", DAUDIO_STRING_LENGTH);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    92
        strncpy(desc->description, "Default Audio Device", DAUDIO_STRING_LENGTH);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    93
        desc->maxSimulLines = -1;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    94
    } else {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    95
        AudioDeviceID deviceID;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    96
        result = deviceCache.GetDeviceInfo(mixerIndex-1, &deviceID, DAUDIO_STRING_LENGTH,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    97
            desc->name, desc->vendor, desc->description, desc->version);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    98
        if (result) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
    99
            desc->deviceID = (INT32)deviceID;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   100
            desc->maxSimulLines = -1;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   101
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   102
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   103
    return result ? TRUE : FALSE;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   104
}
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   105
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   106
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   107
void DAUDIO_GetFormats(INT32 mixerIndex, INT32 deviceID, int isSource, void* creator) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   108
    TRACE3(">>DAUDIO_GetFormats mixerIndex=%d deviceID=0x%x isSource=%d\n", (int)mixerIndex, (int)deviceID, isSource);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   109
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   110
    AudioDeviceID audioDeviceID = deviceID == 0 ? GetDefaultDevice(isSource) : (AudioDeviceID)deviceID;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   111
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   112
    if (audioDeviceID == 0) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   113
        return;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   114
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   115
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   116
    int totalChannels = GetChannelCount(audioDeviceID, isSource);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   117
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   118
    if (totalChannels == 0) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   119
        TRACE0("<<DAUDIO_GetFormats, no streams!\n");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   120
        return;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   121
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   122
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   123
    if (isSource && totalChannels < 2) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   124
        // report 2 channels even if only mono is supported
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   125
        totalChannels = 2;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   126
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   127
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   128
    int channels[] = {1, 2, totalChannels};
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   129
    int channelsCount = MIN(totalChannels, 3);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   130
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   131
    float hardwareSampleRate = GetSampleRate(audioDeviceID, isSource);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   132
    TRACE2("  DAUDIO_GetFormats: got %d channels, sampleRate == %f\n", totalChannels, hardwareSampleRate);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   133
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   134
    // any sample rates are supported
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   135
    float sampleRate = -1;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   136
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   137
    static int sampleBits[] = {8, 16, 24};
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   138
    static int sampleBitsCount = sizeof(sampleBits)/sizeof(sampleBits[0]);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   139
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   140
    // the last audio format is the default one (used by DataLine.open() if format is not specified)
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   141
    // consider as default 16bit PCM stereo (mono is stereo is not supported) with the current sample rate
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   142
    int defBits = 16;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   143
    int defChannels = MIN(2, channelsCount);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   144
    float defSampleRate = hardwareSampleRate;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   145
    // don't add default format is sample rate is not specified
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   146
    bool addDefault = defSampleRate > 0;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   147
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   148
    // TODO: CoreAudio can handle signed/unsigned, little-endian/big-endian
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   149
    // TODO: register the formats (to prevent DirectAudio software conversion) - need to fix DirectAudioDevice.createDataLineInfo
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   150
    // to avoid software conversions if both signed/unsigned or big-/little-endian are supported
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   151
    for (int channelIndex = 0; channelIndex < channelsCount; channelIndex++) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   152
        for (int bitIndex = 0; bitIndex < sampleBitsCount; bitIndex++) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   153
            int bits = sampleBits[bitIndex];
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   154
            if (addDefault && bits == defBits && channels[channelIndex] != defChannels && sampleRate == defSampleRate) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   155
                // the format is the default one, don't add it now
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   156
                continue;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   157
            }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   158
            DAUDIO_AddAudioFormat(creator,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   159
                bits,                       // sample size in bits
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   160
                -1,                         // frame size (auto)
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   161
                channels[channelIndex],     // channels
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   162
                sampleRate,                 // sample rate
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   163
                DAUDIO_PCM,                 // only accept PCM
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   164
                bits == 8 ? FALSE : TRUE,   // signed
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   165
                bits == 8 ? FALSE           // little-endian for 8bit
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   166
                    : UTIL_IsBigEndianPlatform());
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   167
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   168
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   169
    // add default format
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   170
    if (addDefault) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   171
        DAUDIO_AddAudioFormat(creator,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   172
            defBits,                        // 16 bits
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   173
            -1,                             // automatically calculate frame size
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   174
            defChannels,                    // channels
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   175
            defSampleRate,                  // sample rate
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   176
            DAUDIO_PCM,                     // PCM
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   177
            TRUE,                           // signed
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   178
            UTIL_IsBigEndianPlatform());    // native endianess
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   179
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   180
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   181
    TRACE0("<<DAUDIO_GetFormats\n");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   182
}
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   183
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   184
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   185
// =======================================
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   186
// Source/Target DataLine functions implementation
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   187
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   188
// ====
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   189
/* 1writer-1reader ring buffer class with flush() support */
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   190
class RingBuffer {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   191
public:
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   192
    RingBuffer() : pBuffer(NULL), nBufferSize(0) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   193
        pthread_mutex_init(&lockMutex, NULL);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   194
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   195
    ~RingBuffer() {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   196
        Deallocate();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   197
        pthread_mutex_destroy(&lockMutex);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   198
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   199
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   200
    // extraBytes: number of additionally allocated bytes to prevent data
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   201
    // overlapping when almost whole buffer is filled
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   202
    // (required only if Write() can override the buffer)
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   203
    bool Allocate(int requestedBufferSize, int extraBytes) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   204
        int fullBufferSize = requestedBufferSize + extraBytes;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   205
        int powerOfTwo = 1;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   206
        while (powerOfTwo < fullBufferSize) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   207
            powerOfTwo <<= 1;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   208
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   209
        pBuffer = (Byte*)malloc(powerOfTwo);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   210
        if (pBuffer == NULL) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   211
            ERROR0("RingBuffer::Allocate: OUT OF MEMORY\n");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   212
            return false;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   213
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   214
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   215
        nBufferSize = requestedBufferSize;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   216
        nAllocatedBytes = powerOfTwo;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   217
        nPosMask = powerOfTwo - 1;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   218
        nWritePos = 0;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   219
        nReadPos = 0;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   220
        nFlushPos = -1;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   221
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   222
        TRACE2("RingBuffer::Allocate: OK, bufferSize=%d, allocated:%d\n", nBufferSize, nAllocatedBytes);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   223
        return true;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   224
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   225
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   226
    void Deallocate() {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   227
        if (pBuffer) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   228
            free(pBuffer);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   229
            pBuffer = NULL;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   230
            nBufferSize = 0;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   231
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   232
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   233
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   234
    inline int GetBufferSize() {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   235
        return nBufferSize;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   236
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   237
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   238
    inline int GetAllocatedSize() {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   239
        return nAllocatedBytes;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   240
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   241
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   242
    // gets number of bytes available for reading
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   243
    int GetValidByteCount() {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   244
        lock();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   245
        INT64 result = nWritePos - (nFlushPos >= 0 ? nFlushPos : nReadPos);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   246
        unlock();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   247
        return result > (INT64)nBufferSize ? nBufferSize : (int)result;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   248
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   249
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   250
    int Write(void *srcBuffer, int len, bool preventOverflow) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   251
        lock();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   252
        TRACE2("RingBuffer::Write (%d bytes, preventOverflow=%d)\n", len, preventOverflow ? 1 : 0);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   253
        TRACE2("  writePos = %lld (%d)", (long long)nWritePos, Pos2Offset(nWritePos));
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   254
        TRACE2("  readPos=%lld (%d)", (long long)nReadPos, Pos2Offset(nReadPos));
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   255
        TRACE2("  flushPos=%lld (%d)\n", (long long)nFlushPos, Pos2Offset(nFlushPos));
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   256
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   257
        INT64 writePos = nWritePos;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   258
        if (preventOverflow) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   259
            INT64 avail_read = writePos - (nFlushPos >= 0 ? nFlushPos : nReadPos);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   260
            if (avail_read >= (INT64)nBufferSize) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   261
                // no space
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   262
                TRACE0("  preventOverlow: OVERFLOW => len = 0;\n");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   263
                len = 0;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   264
            } else {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   265
                int avail_write = nBufferSize - (int)avail_read;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   266
                if (len > avail_write) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   267
                    TRACE2("  preventOverlow: desrease len: %d => %d\n", len, avail_write);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   268
                    len = avail_write;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   269
                }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   270
            }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   271
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   272
        unlock();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   273
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   274
        if (len > 0) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   275
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   276
            write((Byte *)srcBuffer, Pos2Offset(writePos), len);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   277
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   278
            lock();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   279
            TRACE4("--RingBuffer::Write writePos: %lld (%d) => %lld, (%d)\n",
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   280
                (long long)nWritePos, Pos2Offset(nWritePos), (long long)nWritePos + len, Pos2Offset(nWritePos + len));
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   281
            nWritePos += len;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   282
            unlock();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   283
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   284
        return len;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   285
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   286
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   287
    int Read(void *dstBuffer, int len) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   288
        lock();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   289
        TRACE1("RingBuffer::Read (%d bytes)\n", len);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   290
        TRACE2("  writePos = %lld (%d)", (long long)nWritePos, Pos2Offset(nWritePos));
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   291
        TRACE2("  readPos=%lld (%d)", (long long)nReadPos, Pos2Offset(nReadPos));
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   292
        TRACE2("  flushPos=%lld (%d)\n", (long long)nFlushPos, Pos2Offset(nFlushPos));
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   293
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   294
        applyFlush();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   295
        INT64 avail_read = nWritePos - nReadPos;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   296
        // check for overflow
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   297
        if (avail_read > (INT64)nBufferSize) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   298
            nReadPos = nWritePos - nBufferSize;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   299
            avail_read = nBufferSize;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   300
            TRACE0("  OVERFLOW\n");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   301
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   302
        INT64 readPos = nReadPos;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   303
        unlock();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   304
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   305
        if (len > (int)avail_read) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   306
            TRACE2("  RingBuffer::Read - don't have enough data, len: %d => %d\n", len, (int)avail_read);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   307
            len = (int)avail_read;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   308
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   309
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   310
        if (len > 0) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   311
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   312
            read((Byte *)dstBuffer, Pos2Offset(readPos), len);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   313
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   314
            lock();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   315
            if (applyFlush()) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   316
                // just got flush(), results became obsolete
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   317
                TRACE0("--RingBuffer::Read, got Flush, return 0\n");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   318
                len = 0;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   319
            } else {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   320
                TRACE4("--RingBuffer::Read readPos: %lld (%d) => %lld (%d)\n",
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   321
                    (long long)nReadPos, Pos2Offset(nReadPos), (long long)nReadPos + len, Pos2Offset(nReadPos + len));
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   322
                nReadPos += len;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   323
            }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   324
            unlock();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   325
        } else {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   326
            // underrun!
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   327
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   328
        return len;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   329
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   330
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   331
    // returns number of the flushed bytes
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   332
    int Flush() {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   333
        lock();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   334
        INT64 flushedBytes = nWritePos - (nFlushPos >= 0 ? nFlushPos : nReadPos);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   335
        nFlushPos = nWritePos;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   336
        unlock();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   337
        return flushedBytes > (INT64)nBufferSize ? nBufferSize : (int)flushedBytes;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   338
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   339
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   340
private:
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   341
    Byte *pBuffer;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   342
    int nBufferSize;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   343
    int nAllocatedBytes;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   344
    INT64 nPosMask;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   345
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   346
    pthread_mutex_t lockMutex;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   347
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   348
    volatile INT64 nWritePos;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   349
    volatile INT64 nReadPos;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   350
    // Flush() sets nFlushPos value to nWritePos;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   351
    // next Read() sets nReadPos to nFlushPos and resests nFlushPos to -1
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   352
    volatile INT64 nFlushPos;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   353
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   354
    inline void lock() {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   355
        pthread_mutex_lock(&lockMutex);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   356
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   357
    inline void unlock() {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   358
        pthread_mutex_unlock(&lockMutex);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   359
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   360
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   361
    inline bool applyFlush() {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   362
        if (nFlushPos >= 0) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   363
            nReadPos = nFlushPos;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   364
            nFlushPos = -1;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   365
            return true;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   366
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   367
        return false;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   368
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   369
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   370
    inline int Pos2Offset(INT64 pos) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   371
        return (int)(pos & nPosMask);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   372
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   373
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   374
    void write(Byte *srcBuffer, int dstOffset, int len) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   375
        int dstEndOffset = dstOffset + len;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   376
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   377
        int lenAfterWrap = dstEndOffset - nAllocatedBytes;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   378
        if (lenAfterWrap > 0) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   379
            // dest.buffer does wrap
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   380
            len = nAllocatedBytes - dstOffset;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   381
            memcpy(pBuffer+dstOffset, srcBuffer, len);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   382
            memcpy(pBuffer, srcBuffer+len, lenAfterWrap);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   383
        } else {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   384
            // dest.buffer does not wrap
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   385
            memcpy(pBuffer+dstOffset, srcBuffer, len);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   386
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   387
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   388
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   389
    void read(Byte *dstBuffer, int srcOffset, int len) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   390
        int srcEndOffset = srcOffset + len;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   391
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   392
        int lenAfterWrap = srcEndOffset - nAllocatedBytes;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   393
        if (lenAfterWrap > 0) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   394
            // need to unwrap data
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   395
            len = nAllocatedBytes - srcOffset;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   396
            memcpy(dstBuffer, pBuffer+srcOffset, len);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   397
            memcpy(dstBuffer+len, pBuffer, lenAfterWrap);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   398
        } else {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   399
            // source buffer is not wrapped
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   400
            memcpy(dstBuffer, pBuffer+srcOffset, len);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   401
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   402
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   403
};
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   404
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   405
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   406
class Resampler {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   407
private:
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   408
    enum {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   409
        kResamplerEndOfInputData = 1 // error to interrupt conversion (end of input data)
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   410
    };
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   411
public:
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   412
    Resampler() : converter(NULL), outBuffer(NULL) { }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   413
    ~Resampler() {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   414
        if (converter != NULL) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   415
            AudioConverterDispose(converter);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   416
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   417
        if (outBuffer != NULL) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   418
            free(outBuffer);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   419
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   420
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   421
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   422
    // inFormat & outFormat must be interleaved!
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   423
    bool Init(const AudioStreamBasicDescription *inFormat, const AudioStreamBasicDescription *outFormat,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   424
            int inputBufferSizeInBytes)
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   425
    {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   426
        TRACE0(">>Resampler::Init\n");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   427
        TRACE0("  inFormat: ");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   428
        PrintStreamDesc(inFormat);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   429
        TRACE0("  outFormat: ");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   430
        PrintStreamDesc(outFormat);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   431
        TRACE1("  inputBufferSize: %d bytes\n", inputBufferSizeInBytes);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   432
        OSStatus err;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   433
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   434
        if ((outFormat->mFormatFlags & kAudioFormatFlagIsNonInterleaved) != 0 && outFormat->mChannelsPerFrame != 1) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   435
            ERROR0("Resampler::Init ERROR: outFormat is non-interleaved\n");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   436
            return false;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   437
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   438
        if ((inFormat->mFormatFlags & kAudioFormatFlagIsNonInterleaved) != 0 && inFormat->mChannelsPerFrame != 1) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   439
            ERROR0("Resampler::Init ERROR: inFormat is non-interleaved\n");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   440
            return false;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   441
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   442
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   443
        memcpy(&asbdIn, inFormat, sizeof(AudioStreamBasicDescription));
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   444
        memcpy(&asbdOut, outFormat, sizeof(AudioStreamBasicDescription));
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   445
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   446
        err = AudioConverterNew(inFormat, outFormat, &converter);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   447
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   448
        if (err || converter == NULL) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   449
            OS_ERROR1(err, "Resampler::Init (AudioConverterNew), converter=%p", converter);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   450
            return false;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   451
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   452
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   453
        // allocate buffer for output data
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   454
        int maximumInFrames = inputBufferSizeInBytes / inFormat->mBytesPerFrame;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   455
        // take into account trailingFrames
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   456
        AudioConverterPrimeInfo primeInfo = {0, 0};
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   457
        UInt32 sizePrime = sizeof(primeInfo);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   458
        err = AudioConverterGetProperty(converter, kAudioConverterPrimeInfo, &sizePrime, &primeInfo);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   459
        if (err) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   460
            OS_ERROR0(err, "Resampler::Init (get kAudioConverterPrimeInfo)");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   461
            // ignore the error
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   462
        } else {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   463
            // the default primeMethod is kConverterPrimeMethod_Normal, so we need only trailingFrames
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   464
            maximumInFrames += primeInfo.trailingFrames;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   465
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   466
        float outBufferSizeInFrames = (outFormat->mSampleRate / inFormat->mSampleRate) * ((float)maximumInFrames);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   467
        // to avoid complex calculation just set outBufferSize as double of the calculated value
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   468
        outBufferSize = (int)outBufferSizeInFrames * outFormat->mBytesPerFrame * 2;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   469
        // safety check - consider 256 frame as the minimum input buffer
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   470
        int minOutSize = 256 * outFormat->mBytesPerFrame;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   471
        if (outBufferSize < minOutSize) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   472
            outBufferSize = minOutSize;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   473
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   474
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   475
        outBuffer = malloc(outBufferSize);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   476
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   477
        if (outBuffer == NULL) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   478
            ERROR1("Resampler::Init ERROR: malloc failed (%d bytes)\n", outBufferSize);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   479
            AudioConverterDispose(converter);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   480
            converter = NULL;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   481
            return false;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   482
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   483
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   484
        TRACE1("  allocated: %d bytes for output buffer\n", outBufferSize);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   485
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   486
        TRACE0("<<Resampler::Init: OK\n");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   487
        return true;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   488
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   489
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   490
    // returns size of the internal output buffer
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   491
    int GetOutBufferSize() {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   492
        return outBufferSize;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   493
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   494
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   495
    // process next part of data (writes resampled data to the ringBuffer without overflow check)
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   496
    int Process(void *srcBuffer, int len, RingBuffer *ringBuffer) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   497
        int bytesWritten = 0;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   498
        TRACE2(">>Resampler::Process: %d bytes, converter = %p\n", len, converter);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   499
        if (converter == NULL) {    // sanity check
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   500
            bytesWritten = ringBuffer->Write(srcBuffer, len, false);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   501
        } else {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   502
            InputProcData data;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   503
            data.pThis = this;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   504
            data.data = (Byte *)srcBuffer;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   505
            data.dataSize = len;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   506
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   507
            OSStatus err;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   508
            do {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   509
                AudioBufferList abl;    // by default it contains 1 AudioBuffer
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   510
                abl.mNumberBuffers = 1;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   511
                abl.mBuffers[0].mNumberChannels = asbdOut.mChannelsPerFrame;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   512
                abl.mBuffers[0].mDataByteSize   = outBufferSize;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   513
                abl.mBuffers[0].mData           = outBuffer;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   514
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   515
                UInt32 packets = (UInt32)outBufferSize / asbdOut.mBytesPerPacket;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   516
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   517
                TRACE2(">>AudioConverterFillComplexBuffer: request %d packets, provide %d bytes buffer\n",
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   518
                    (int)packets, (int)abl.mBuffers[0].mDataByteSize);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   519
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   520
                err = AudioConverterFillComplexBuffer(converter, ConverterInputProc, &data, &packets, &abl, NULL);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   521
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   522
                TRACE2("<<AudioConverterFillComplexBuffer: got %d packets (%d bytes)\n",
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   523
                    (int)packets, (int)abl.mBuffers[0].mDataByteSize);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   524
                if (packets > 0) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   525
                    int bytesToWrite = (int)(packets * asbdOut.mBytesPerPacket);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   526
                    bytesWritten += ringBuffer->Write(abl.mBuffers[0].mData, bytesToWrite, false);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   527
                }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   528
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   529
                // if outputBuffer is small to store all available frames,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   530
                // we get noErr here. In the case just continue the conversion
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   531
            } while (err == noErr);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   532
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   533
            if (err != kResamplerEndOfInputData) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   534
                // unexpected error
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   535
                OS_ERROR0(err, "Resampler::Process (AudioConverterFillComplexBuffer)");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   536
            }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   537
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   538
        TRACE2("<<Resampler::Process: written %d bytes (converted from %d bytes)\n", bytesWritten, len);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   539
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   540
        return bytesWritten;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   541
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   542
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   543
    // resets internal bufferes
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   544
    void Discontinue() {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   545
        TRACE0(">>Resampler::Discontinue\n");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   546
        if (converter != NULL) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   547
            AudioConverterReset(converter);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   548
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   549
        TRACE0("<<Resampler::Discontinue\n");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   550
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   551
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   552
private:
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   553
    AudioConverterRef converter;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   554
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   555
    // buffer for output data
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   556
    // note that there is no problem if the buffer is not big enough to store
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   557
    // all converted data - it's only performance issue
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   558
    void *outBuffer;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   559
    int outBufferSize;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   560
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   561
    AudioStreamBasicDescription asbdIn;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   562
    AudioStreamBasicDescription asbdOut;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   563
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   564
    struct InputProcData {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   565
        Resampler *pThis;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   566
        Byte *data;     // data == NULL means we handle Discontinue(false)
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   567
        int dataSize;   // == 0 if all data was already provided to the converted of we handle Discontinue(false)
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   568
    };
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   569
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   570
    static OSStatus ConverterInputProc(AudioConverterRef inAudioConverter, UInt32 *ioNumberDataPackets,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   571
            AudioBufferList *ioData, AudioStreamPacketDescription **outDataPacketDescription, void *inUserData)
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   572
    {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   573
        InputProcData *data = (InputProcData *)inUserData;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   574
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   575
        TRACE3("  >>ConverterInputProc: requested %d packets, data contains %d bytes (%d packets)\n",
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   576
            (int)*ioNumberDataPackets, (int)data->dataSize, (int)(data->dataSize / data->pThis->asbdIn.mBytesPerPacket));
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   577
        if (data->dataSize == 0) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   578
            // already called & provided all input data
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   579
            // interrupt conversion by returning error
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   580
            *ioNumberDataPackets = 0;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   581
            TRACE0("  <<ConverterInputProc: returns kResamplerEndOfInputData\n");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   582
            return kResamplerEndOfInputData;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   583
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   584
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   585
        ioData->mNumberBuffers = 1;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   586
        ioData->mBuffers[0].mNumberChannels = data->pThis->asbdIn.mChannelsPerFrame;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   587
        ioData->mBuffers[0].mDataByteSize   = data->dataSize;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   588
        ioData->mBuffers[0].mData           = data->data;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   589
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   590
        *ioNumberDataPackets = data->dataSize / data->pThis->asbdIn.mBytesPerPacket;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   591
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   592
        // all data has been provided to the converter
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   593
        data->dataSize = 0;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   594
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   595
        TRACE1("  <<ConverterInputProc: returns %d packets\n", (int)(*ioNumberDataPackets));
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   596
        return noErr;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   597
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   598
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   599
};
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   600
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   601
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   602
struct OSX_DirectAudioDevice {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   603
    AudioUnit   audioUnit;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   604
    RingBuffer  ringBuffer;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   605
    AudioStreamBasicDescription asbd;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   606
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   607
    // only for target lines
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   608
    UInt32      inputBufferSizeInBytes;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   609
    Resampler   *resampler;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   610
    // to detect discontinuity (to reset resampler)
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   611
    SInt64      lastWrittenSampleTime;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   612
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   613
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   614
    OSX_DirectAudioDevice() : audioUnit(NULL), asbd(), resampler(NULL), lastWrittenSampleTime(0) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   615
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   616
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   617
    ~OSX_DirectAudioDevice() {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   618
        if (audioUnit) {
29258
adf046d51c1c 8068412: [macosx] Initialization of Cocoa hangs if CoreAudio was initialized before
serb
parents: 25859
diff changeset
   619
            AudioComponentInstanceDispose(audioUnit);
12047
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   620
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   621
        if (resampler) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   622
            delete resampler;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   623
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   624
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   625
};
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   626
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   627
static AudioUnit CreateOutputUnit(AudioDeviceID deviceID, int isSource)
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   628
{
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   629
    OSStatus err;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   630
    AudioUnit unit;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   631
29258
adf046d51c1c 8068412: [macosx] Initialization of Cocoa hangs if CoreAudio was initialized before
serb
parents: 25859
diff changeset
   632
    AudioComponentDescription desc;
12047
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   633
    desc.componentType         = kAudioUnitType_Output;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   634
    desc.componentSubType      = (deviceID == 0 && isSource) ? kAudioUnitSubType_DefaultOutput : kAudioUnitSubType_HALOutput;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   635
    desc.componentManufacturer = kAudioUnitManufacturer_Apple;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   636
    desc.componentFlags        = 0;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   637
    desc.componentFlagsMask    = 0;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   638
29258
adf046d51c1c 8068412: [macosx] Initialization of Cocoa hangs if CoreAudio was initialized before
serb
parents: 25859
diff changeset
   639
    AudioComponent comp = AudioComponentFindNext(NULL, &desc);
adf046d51c1c 8068412: [macosx] Initialization of Cocoa hangs if CoreAudio was initialized before
serb
parents: 25859
diff changeset
   640
    err = AudioComponentInstanceNew(comp, &unit);
12047
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   641
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   642
    if (err) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   643
        OS_ERROR0(err, "CreateOutputUnit:OpenAComponent");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   644
        return NULL;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   645
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   646
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   647
    if (!isSource) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   648
        int enableIO = 0;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   649
        err = AudioUnitSetProperty(unit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   650
                                    0, &enableIO, sizeof(enableIO));
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   651
        if (err) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   652
            OS_ERROR0(err, "SetProperty (output EnableIO)");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   653
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   654
        enableIO = 1;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   655
        err = AudioUnitSetProperty(unit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   656
                                    1, &enableIO, sizeof(enableIO));
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   657
        if (err) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   658
            OS_ERROR0(err, "SetProperty (input EnableIO)");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   659
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   660
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   661
        if (!deviceID) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   662
            // get real AudioDeviceID for default input device (macosx current input device)
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   663
            deviceID = GetDefaultDevice(isSource);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   664
            if (!deviceID) {
29258
adf046d51c1c 8068412: [macosx] Initialization of Cocoa hangs if CoreAudio was initialized before
serb
parents: 25859
diff changeset
   665
                AudioComponentInstanceDispose(unit);
12047
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   666
                return NULL;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   667
            }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   668
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   669
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   670
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   671
    if (deviceID) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   672
        err = AudioUnitSetProperty(unit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   673
                                    0, &deviceID, sizeof(deviceID));
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   674
        if (err) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   675
            OS_ERROR0(err, "SetProperty (CurrentDevice)");
29258
adf046d51c1c 8068412: [macosx] Initialization of Cocoa hangs if CoreAudio was initialized before
serb
parents: 25859
diff changeset
   676
            AudioComponentInstanceDispose(unit);
12047
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   677
            return NULL;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   678
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   679
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   680
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   681
    return unit;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   682
}
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   683
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   684
static OSStatus OutputCallback(void                         *inRefCon,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   685
                               AudioUnitRenderActionFlags   *ioActionFlags,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   686
                               const AudioTimeStamp         *inTimeStamp,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   687
                               UInt32                       inBusNumber,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   688
                               UInt32                       inNumberFrames,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   689
                               AudioBufferList              *ioData)
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   690
{
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   691
    OSX_DirectAudioDevice *device = (OSX_DirectAudioDevice*)inRefCon;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   692
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   693
    int nchannels = ioData->mNumberBuffers; // should be always == 1 (interleaved channels)
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   694
    AudioBuffer *audioBuffer = ioData->mBuffers;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   695
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   696
    TRACE3(">>OutputCallback: busNum=%d, requested %d frames (%d bytes)\n",
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   697
        (int)inBusNumber, (int)inNumberFrames, (int)(inNumberFrames * device->asbd.mBytesPerFrame));
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   698
    TRACE3("  abl: %d buffers, buffer[0].channels=%d, buffer.size=%d\n",
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   699
        nchannels, (int)audioBuffer->mNumberChannels, (int)audioBuffer->mDataByteSize);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   700
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   701
    int bytesToRead = inNumberFrames * device->asbd.mBytesPerFrame;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   702
    if (bytesToRead > (int)audioBuffer->mDataByteSize) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   703
        TRACE0("--OutputCallback: !!! audioBuffer IS TOO SMALL!!!\n");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   704
        bytesToRead = audioBuffer->mDataByteSize / device->asbd.mBytesPerFrame * device->asbd.mBytesPerFrame;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   705
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   706
    int bytesRead = device->ringBuffer.Read(audioBuffer->mData, bytesToRead);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   707
    if (bytesRead < bytesToRead) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   708
        // no enough data (underrun)
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   709
        TRACE2("--OutputCallback: !!! UNDERRUN (read %d bytes of %d)!!!\n", bytesRead, bytesToRead);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   710
        // silence the rest
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   711
        memset((Byte*)audioBuffer->mData + bytesRead, 0, bytesToRead-bytesRead);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   712
        bytesRead = bytesToRead;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   713
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   714
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   715
    audioBuffer->mDataByteSize = (UInt32)bytesRead;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   716
    // SAFETY: set mDataByteSize for all other AudioBuffer in the AudioBufferList to zero
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   717
    while (--nchannels > 0) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   718
        audioBuffer++;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   719
        audioBuffer->mDataByteSize = 0;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   720
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   721
    TRACE1("<<OutputCallback (returns %d)\n", bytesRead);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   722
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   723
    return noErr;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   724
}
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   725
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   726
static OSStatus InputCallback(void                          *inRefCon,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   727
                              AudioUnitRenderActionFlags    *ioActionFlags,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   728
                              const AudioTimeStamp          *inTimeStamp,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   729
                              UInt32                        inBusNumber,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   730
                              UInt32                        inNumberFrames,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   731
                              AudioBufferList               *ioData)
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   732
{
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   733
    OSX_DirectAudioDevice *device = (OSX_DirectAudioDevice*)inRefCon;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   734
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   735
    TRACE4(">>InputCallback: busNum=%d, timeStamp=%lld, %d frames (%d bytes)\n",
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   736
        (int)inBusNumber, (long long)inTimeStamp->mSampleTime, (int)inNumberFrames, (int)(inNumberFrames * device->asbd.mBytesPerFrame));
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   737
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   738
    AudioBufferList abl;    // by default it contains 1 AudioBuffer
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   739
    abl.mNumberBuffers = 1;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   740
    abl.mBuffers[0].mNumberChannels = device->asbd.mChannelsPerFrame;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   741
    abl.mBuffers[0].mDataByteSize   = device->inputBufferSizeInBytes;   // assume this is == (inNumberFrames * device->asbd.mBytesPerFrame)
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   742
    abl.mBuffers[0].mData           = NULL;     // request for the audioUnit's buffer
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   743
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   744
    OSStatus err = AudioUnitRender(device->audioUnit, ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, &abl);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   745
    if (err) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   746
        OS_ERROR0(err, "<<InputCallback: AudioUnitRender");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   747
    } else {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   748
        if (device->resampler != NULL) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   749
            // test for discontinuity
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   750
            // AUHAL starts timestamps at zero, so test if the current timestamp less then the last written
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   751
            SInt64 sampleTime = inTimeStamp->mSampleTime;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   752
            if (sampleTime < device->lastWrittenSampleTime) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   753
                // discontinuity, reset the resampler
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   754
                TRACE2("  InputCallback (RESAMPLED), DISCONTINUITY (%f -> %f)\n",
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   755
                    (float)device->lastWrittenSampleTime, (float)sampleTime);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   756
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   757
                device->resampler->Discontinue();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   758
            } else {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   759
                TRACE2("  InputCallback (RESAMPLED), continuous: lastWrittenSampleTime = %f, sampleTime=%f\n",
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   760
                    (float)device->lastWrittenSampleTime, (float)sampleTime);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   761
            }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   762
            device->lastWrittenSampleTime = sampleTime + inNumberFrames;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   763
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   764
            int bytesWritten = device->resampler->Process(abl.mBuffers[0].mData, (int)abl.mBuffers[0].mDataByteSize, &device->ringBuffer);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   765
            TRACE2("<<InputCallback (RESAMPLED, saved %d bytes of %d)\n", bytesWritten, (int)abl.mBuffers[0].mDataByteSize);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   766
        } else {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   767
            int bytesWritten = device->ringBuffer.Write(abl.mBuffers[0].mData, (int)abl.mBuffers[0].mDataByteSize, false);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   768
            TRACE2("<<InputCallback (saved %d bytes of %d)\n", bytesWritten, (int)abl.mBuffers[0].mDataByteSize);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   769
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   770
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   771
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   772
    return noErr;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   773
}
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   774
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   775
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   776
static void FillASBDForNonInterleavedPCM(AudioStreamBasicDescription& asbd,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   777
    float sampleRate, int channels, int sampleSizeInBits, bool isFloat, int isSigned, bool isBigEndian)
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   778
{
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   779
    // FillOutASBDForLPCM cannot produce unsigned integer format
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   780
    asbd.mSampleRate = sampleRate;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   781
    asbd.mFormatID = kAudioFormatLinearPCM;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   782
    asbd.mFormatFlags = (isFloat ? kAudioFormatFlagIsFloat : (isSigned ? kAudioFormatFlagIsSignedInteger : 0))
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   783
        | (isBigEndian ? (kAudioFormatFlagIsBigEndian) : 0)
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   784
        | kAudioFormatFlagIsPacked;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   785
    asbd.mBytesPerPacket = channels * ((sampleSizeInBits + 7) / 8);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   786
    asbd.mFramesPerPacket = 1;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   787
    asbd.mBytesPerFrame = asbd.mBytesPerPacket;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   788
    asbd.mChannelsPerFrame = channels;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   789
    asbd.mBitsPerChannel = sampleSizeInBits;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   790
}
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   791
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   792
void* DAUDIO_Open(INT32 mixerIndex, INT32 deviceID, int isSource,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   793
                  int encoding, float sampleRate, int sampleSizeInBits,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   794
                  int frameSize, int channels,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   795
                  int isSigned, int isBigEndian, int bufferSizeInBytes)
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   796
{
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   797
    TRACE3(">>DAUDIO_Open: mixerIndex=%d deviceID=0x%x isSource=%d\n", (int)mixerIndex, (unsigned int)deviceID, isSource);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   798
    TRACE3("  sampleRate=%d sampleSizeInBits=%d channels=%d\n", (int)sampleRate, sampleSizeInBits, channels);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   799
#ifdef USE_TRACE
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   800
    {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   801
        AudioDeviceID audioDeviceID = deviceID;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   802
        if (audioDeviceID == 0) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   803
            // default device
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   804
            audioDeviceID = GetDefaultDevice(isSource);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   805
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   806
        char name[256];
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   807
        OSStatus err = GetAudioObjectProperty(audioDeviceID, kAudioUnitScope_Global, kAudioDevicePropertyDeviceName, 256, &name, 0);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   808
        if (err != noErr) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   809
            OS_ERROR1(err, "  audioDeviceID=0x%x, name is N/A:", (int)audioDeviceID);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   810
        } else {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   811
            TRACE2("  audioDeviceID=0x%x, name=%s\n", (int)audioDeviceID, name);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   812
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   813
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   814
#endif
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   815
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   816
    if (encoding != DAUDIO_PCM) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   817
        ERROR1("<<DAUDIO_Open: ERROR: unsupported encoding (%d)\n", encoding);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   818
        return NULL;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   819
    }
41566
f52207d194bf 8157753: Audio replay enhancement
serb
parents: 29258
diff changeset
   820
    if (channels <= 0) {
f52207d194bf 8157753: Audio replay enhancement
serb
parents: 29258
diff changeset
   821
        ERROR1("<<DAUDIO_Open: ERROR: Invalid number of channels=%d!\n", channels);
f52207d194bf 8157753: Audio replay enhancement
serb
parents: 29258
diff changeset
   822
        return NULL;
f52207d194bf 8157753: Audio replay enhancement
serb
parents: 29258
diff changeset
   823
    }
12047
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   824
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   825
    OSX_DirectAudioDevice *device = new OSX_DirectAudioDevice();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   826
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   827
    AudioUnitScope scope = isSource ? kAudioUnitScope_Input : kAudioUnitScope_Output;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   828
    int element = isSource ? 0 : 1;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   829
    OSStatus err = noErr;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   830
    int extraBufferBytes = 0;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   831
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   832
    device->audioUnit = CreateOutputUnit(deviceID, isSource);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   833
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   834
    if (!device->audioUnit) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   835
        delete device;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   836
        return NULL;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   837
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   838
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   839
    if (!isSource) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   840
        AudioDeviceID actualDeviceID = deviceID != 0 ? deviceID : GetDefaultDevice(isSource);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   841
        float hardwareSampleRate = GetSampleRate(actualDeviceID, isSource);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   842
        TRACE2("--DAUDIO_Open: sampleRate = %f, hardwareSampleRate=%f\n", sampleRate, hardwareSampleRate);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   843
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   844
        if (fabs(sampleRate - hardwareSampleRate) > 1) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   845
            device->resampler = new Resampler();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   846
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   847
            // request HAL for Float32 with native endianess
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   848
            FillASBDForNonInterleavedPCM(device->asbd, hardwareSampleRate, channels, 32, true, false, kAudioFormatFlagsNativeEndian != 0);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   849
        } else {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   850
            sampleRate = hardwareSampleRate;    // in case sample rates are not exactly equal
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   851
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   852
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   853
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   854
    if (device->resampler == NULL) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   855
        // no resampling, request HAL for the requested format
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   856
        FillASBDForNonInterleavedPCM(device->asbd, sampleRate, channels, sampleSizeInBits, false, isSigned, isBigEndian);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   857
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   858
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   859
    err = AudioUnitSetProperty(device->audioUnit, kAudioUnitProperty_StreamFormat, scope, element, &device->asbd, sizeof(device->asbd));
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   860
    if (err) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   861
        OS_ERROR0(err, "<<DAUDIO_Open set StreamFormat");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   862
        delete device;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   863
        return NULL;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   864
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   865
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   866
    AURenderCallbackStruct output;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   867
    output.inputProc       = isSource ? OutputCallback : InputCallback;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   868
    output.inputProcRefCon = device;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   869
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   870
    err = AudioUnitSetProperty(device->audioUnit,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   871
                                isSource
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   872
                                    ? (AudioUnitPropertyID)kAudioUnitProperty_SetRenderCallback
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   873
                                    : (AudioUnitPropertyID)kAudioOutputUnitProperty_SetInputCallback,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   874
                                kAudioUnitScope_Global, 0, &output, sizeof(output));
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   875
    if (err) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   876
        OS_ERROR0(err, "<<DAUDIO_Open set RenderCallback");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   877
        delete device;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   878
        return NULL;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   879
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   880
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   881
    err = AudioUnitInitialize(device->audioUnit);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   882
    if (err) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   883
        OS_ERROR0(err, "<<DAUDIO_Open UnitInitialize");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   884
        delete device;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   885
        return NULL;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   886
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   887
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   888
    if (!isSource) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   889
        // for target lines we need extra bytes in the ringBuffer
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   890
        // to prevent collisions when InputCallback overrides data on overflow
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   891
        UInt32 size;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   892
        OSStatus err;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   893
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   894
        size = sizeof(device->inputBufferSizeInBytes);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   895
        err  = AudioUnitGetProperty(device->audioUnit, kAudioDevicePropertyBufferFrameSize, kAudioUnitScope_Global,
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   896
                                    0, &device->inputBufferSizeInBytes, &size);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   897
        if (err) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   898
            OS_ERROR0(err, "<<DAUDIO_Open (TargetDataLine)GetBufferSize\n");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   899
            delete device;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   900
            return NULL;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   901
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   902
        device->inputBufferSizeInBytes *= device->asbd.mBytesPerFrame;  // convert frames to bytes
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   903
        extraBufferBytes = (int)device->inputBufferSizeInBytes;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   904
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   905
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   906
    if (device->resampler != NULL) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   907
        // resampler output format is a user requested format (== ringBuffer format)
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   908
        AudioStreamBasicDescription asbdOut; // ringBuffer format
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   909
        FillASBDForNonInterleavedPCM(asbdOut, sampleRate, channels, sampleSizeInBits, false, isSigned, isBigEndian);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   910
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   911
        // set resampler input buffer size to the HAL buffer size
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   912
        if (!device->resampler->Init(&device->asbd, &asbdOut, (int)device->inputBufferSizeInBytes)) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   913
            ERROR0("<<DAUDIO_Open: resampler.Init() FAILED.\n");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   914
            delete device;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   915
            return NULL;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   916
        }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   917
        // extra bytes in the ringBuffer (extraBufferBytes) should be equal resampler output buffer size
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   918
        extraBufferBytes = device->resampler->GetOutBufferSize();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   919
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   920
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   921
    if (!device->ringBuffer.Allocate(bufferSizeInBytes, extraBufferBytes)) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   922
        ERROR0("<<DAUDIO_Open: Ring buffer allocation error\n");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   923
        delete device;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   924
        return NULL;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   925
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   926
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   927
    TRACE0("<<DAUDIO_Open: OK\n");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   928
    return device;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   929
}
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   930
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   931
int DAUDIO_Start(void* id, int isSource) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   932
    OSX_DirectAudioDevice *device = (OSX_DirectAudioDevice*)id;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   933
    TRACE0("DAUDIO_Start\n");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   934
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   935
    OSStatus err = AudioOutputUnitStart(device->audioUnit);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   936
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   937
    if (err != noErr) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   938
        OS_ERROR0(err, "DAUDIO_Start");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   939
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   940
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   941
    return err == noErr ? TRUE : FALSE;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   942
}
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   943
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   944
int DAUDIO_Stop(void* id, int isSource) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   945
    OSX_DirectAudioDevice *device = (OSX_DirectAudioDevice*)id;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   946
    TRACE0("DAUDIO_Stop\n");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   947
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   948
    OSStatus err = AudioOutputUnitStop(device->audioUnit);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   949
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   950
    return err == noErr ? TRUE : FALSE;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   951
}
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   952
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   953
void DAUDIO_Close(void* id, int isSource) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   954
    OSX_DirectAudioDevice *device = (OSX_DirectAudioDevice*)id;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   955
    TRACE0("DAUDIO_Close\n");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   956
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   957
    delete device;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   958
}
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   959
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   960
int DAUDIO_Write(void* id, char* data, int byteSize) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   961
    OSX_DirectAudioDevice *device = (OSX_DirectAudioDevice*)id;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   962
    TRACE1(">>DAUDIO_Write: %d bytes to write\n", byteSize);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   963
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   964
    int result = device->ringBuffer.Write(data, byteSize, true);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   965
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   966
    TRACE1("<<DAUDIO_Write: %d bytes written\n", result);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   967
    return result;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   968
}
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   969
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   970
int DAUDIO_Read(void* id, char* data, int byteSize) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   971
    OSX_DirectAudioDevice *device = (OSX_DirectAudioDevice*)id;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   972
    TRACE1(">>DAUDIO_Read: %d bytes to read\n", byteSize);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   973
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   974
    int result = device->ringBuffer.Read(data, byteSize);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   975
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   976
    TRACE1("<<DAUDIO_Read: %d bytes has been read\n", result);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   977
    return result;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   978
}
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   979
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   980
int DAUDIO_GetBufferSize(void* id, int isSource) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   981
    OSX_DirectAudioDevice *device = (OSX_DirectAudioDevice*)id;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   982
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   983
    int bufferSizeInBytes = device->ringBuffer.GetBufferSize();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   984
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   985
    TRACE1("DAUDIO_GetBufferSize returns %d\n", bufferSizeInBytes);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   986
    return bufferSizeInBytes;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   987
}
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   988
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   989
int DAUDIO_StillDraining(void* id, int isSource) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   990
    OSX_DirectAudioDevice *device = (OSX_DirectAudioDevice*)id;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   991
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   992
    int draining = device->ringBuffer.GetValidByteCount() > 0 ? TRUE : FALSE;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   993
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   994
    TRACE1("DAUDIO_StillDraining returns %d\n", draining);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   995
    return draining;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   996
}
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   997
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   998
int DAUDIO_Flush(void* id, int isSource) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
   999
    OSX_DirectAudioDevice *device = (OSX_DirectAudioDevice*)id;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1000
    TRACE0("DAUDIO_Flush\n");
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1001
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1002
    device->ringBuffer.Flush();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1003
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1004
    return TRUE;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1005
}
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1006
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1007
int DAUDIO_GetAvailable(void* id, int isSource) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1008
    OSX_DirectAudioDevice *device = (OSX_DirectAudioDevice*)id;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1009
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1010
    int bytesInBuffer = device->ringBuffer.GetValidByteCount();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1011
    if (isSource) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1012
        return device->ringBuffer.GetBufferSize() - bytesInBuffer;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1013
    } else {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1014
        return bytesInBuffer;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1015
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1016
}
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1017
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1018
INT64 DAUDIO_GetBytePosition(void* id, int isSource, INT64 javaBytePos) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1019
    OSX_DirectAudioDevice *device = (OSX_DirectAudioDevice*)id;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1020
    INT64 position;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1021
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1022
    if (isSource) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1023
        position = javaBytePos - device->ringBuffer.GetValidByteCount();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1024
    } else {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1025
        position = javaBytePos + device->ringBuffer.GetValidByteCount();
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1026
    }
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1027
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1028
    TRACE2("DAUDIO_GetBytePosition returns %lld (javaBytePos = %lld)\n", (long long)position, (long long)javaBytePos);
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1029
    return position;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1030
}
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1031
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1032
void DAUDIO_SetBytePosition(void* id, int isSource, INT64 javaBytePos) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1033
    // no need javaBytePos (it's available in DAUDIO_GetBytePosition)
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1034
}
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1035
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1036
int DAUDIO_RequiresServicing(void* id, int isSource) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1037
    return FALSE;
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1038
}
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1039
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1040
void DAUDIO_Service(void* id, int isSource) {
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1041
    // unreachable
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1042
}
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1043
320a714614e9 7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
diff changeset
  1044
#endif  // USE_DAUDIO == TRUE