src/java.desktop/unix/native/libjsound/PLATFORM_API_SolarisOS_PCM.c
author ihse
Sat, 03 Mar 2018 08:21:47 +0100
branchihse-warnings-cflags-branch
changeset 56230 489867818774
parent 47216 71c04702a3d5
permissions -rw-r--r--
No longer disable E_OLD_STYLE_FUNC_DEF.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
23010
6dadb192ad81 8029235: Update copyright year to match last edit in jdk8 jdk repository for 2013
lana
parents: 21278
diff changeset
     2
 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
#define USE_ERROR
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
#define USE_TRACE
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
#include "PLATFORM_API_SolarisOS_Utils.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
#include "DirectAudio.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
#if USE_DAUDIO == TRUE
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
// The default buffer time
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
#define DEFAULT_PERIOD_TIME_MILLIS 50
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
///// implemented functions of DirectAudio.h
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
56230
489867818774 No longer disable E_OLD_STYLE_FUNC_DEF.
ihse
parents: 47216
diff changeset
    40
INT32 DAUDIO_GetDirectAudioDeviceCount(void) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
    return (INT32) getAudioDeviceCount();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
INT32 DAUDIO_GetDirectAudioDeviceDescription(INT32 mixerIndex,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
                                             DirectAudioDeviceDescription* description) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
    AudioDeviceDescription desc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
    if (getAudioDeviceDescriptionByIndex(mixerIndex, &desc, TRUE)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
        description->maxSimulLines = desc.maxSimulLines;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
        strncpy(description->name, desc.name, DAUDIO_STRING_LENGTH-1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
        description->name[DAUDIO_STRING_LENGTH-1] = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
        strncpy(description->vendor, desc.vendor, DAUDIO_STRING_LENGTH-1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
        description->vendor[DAUDIO_STRING_LENGTH-1] = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
        strncpy(description->version, desc.version, DAUDIO_STRING_LENGTH-1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
        description->version[DAUDIO_STRING_LENGTH-1] = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
        /*strncpy(description->description, desc.description, DAUDIO_STRING_LENGTH-1);*/
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
        strncpy(description->description, "Solaris Mixer", DAUDIO_STRING_LENGTH-1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
        description->description[DAUDIO_STRING_LENGTH-1] = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
        return TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
    return FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
#define MAX_SAMPLE_RATES   20
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
void DAUDIO_GetFormats(INT32 mixerIndex, INT32 deviceID, int isSource, void* creator) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
    int fd = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
    AudioDeviceDescription desc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
    am_sample_rates_t      *sr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
    /* hardcoded bits and channels */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
    int bits[] = {8, 16};
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
    int bitsCount = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
    int channels[] = {1, 2};
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
    int channelsCount = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
    /* for querying sample rates */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
    int err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
    int ch, b, s;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    TRACE2("DAUDIO_GetFormats, mixer %d, isSource=%d\n", mixerIndex, isSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
    if (getAudioDeviceDescriptionByIndex(mixerIndex, &desc, FALSE)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
        fd = open(desc.pathctl, O_RDONLY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
    if (fd < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
        ERROR1("Couldn't open audio device ctl for device %d!\n", mixerIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
    /* get sample rates */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
    sr = (am_sample_rates_t*) malloc(AUDIO_MIXER_SAMP_RATES_STRUCT_SIZE(MAX_SAMPLE_RATES));
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
    if (sr == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
        ERROR1("DAUDIO_GetFormats: out of memory for mixer %d\n", (int) mixerIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
        close(fd);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
    sr->num_samp_rates = MAX_SAMPLE_RATES;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    sr->type = isSource?AUDIO_PLAY:AUDIO_RECORD;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
    sr->samp_rates[0] = -2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
    err = ioctl(fd, AUDIO_MIXER_GET_SAMPLE_RATES, sr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
    if (err < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
        ERROR1("  DAUDIO_GetFormats: AUDIO_MIXER_GET_SAMPLE_RATES failed for mixer %d!\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
               (int)mixerIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
        ERROR2(" -> num_sample_rates=%d sample_rates[0] = %d\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
               (int) sr->num_samp_rates,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
               (int) sr->samp_rates[0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
        /* Some Solaris 8 drivers fail for get sample rates!
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
         * Do as if we support all sample rates
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
        sr->flags = MIXER_SR_LIMITS;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
    if ((sr->flags & MIXER_SR_LIMITS)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
        || (sr->num_samp_rates > MAX_SAMPLE_RATES)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
#ifdef USE_TRACE
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
        if ((sr->flags & MIXER_SR_LIMITS)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
            TRACE1("  DAUDIO_GetFormats: floating sample rate allowed by mixer %d\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
                   (int)mixerIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
        if (sr->num_samp_rates > MAX_SAMPLE_RATES) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
            TRACE2("  DAUDIO_GetFormats: more than %d formats. Use -1 for sample rates mixer %d\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
                   MAX_SAMPLE_RATES, (int)mixerIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
         * Fake it to have only one sample rate: -1
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
        sr->num_samp_rates = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
        sr->samp_rates[0] = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
    close(fd);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
    for (ch = 0; ch < channelsCount; ch++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
        for (b = 0; b < bitsCount; b++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
            for (s = 0; s < sr->num_samp_rates; s++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
                DAUDIO_AddAudioFormat(creator,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
                                      bits[b], /* significant bits */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
                                      0, /* frameSize: let it be calculated */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
                                      channels[ch],
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
                                      (float) ((int) sr->samp_rates[s]),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
                                      DAUDIO_PCM, /* encoding - let's only do PCM */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
                                      (bits[b] > 8)?TRUE:TRUE, /* isSigned */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
#ifdef _LITTLE_ENDIAN
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
                                      FALSE /* little endian */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
#else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
                                      (bits[b] > 8)?TRUE:FALSE  /* big endian */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
                                      );
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
    free(sr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
typedef struct {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
    int fd;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
    audio_info_t info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
    int bufferSizeInBytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
    int frameSize; /* storage size in Bytes */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
    /* how many bytes were written or read */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
    INT32 transferedBytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
    /* if transferedBytes exceed 32-bit boundary,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
     * it will be reset and positionOffset will receive
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
     * the offset
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
    INT64 positionOffset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
} SolPcmInfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
void* DAUDIO_Open(INT32 mixerIndex, INT32 deviceID, int isSource,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
                  int encoding, float sampleRate, int sampleSizeInBits,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
                  int frameSize, int channels,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
                  int isSigned, int isBigEndian, int bufferSizeInBytes) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
    int err = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
    int openMode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
    AudioDeviceDescription desc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
    SolPcmInfo* info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
    TRACE0("> DAUDIO_Open\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
    if (encoding != DAUDIO_PCM) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
        ERROR1(" DAUDIO_Open: invalid encoding %d\n", (int) encoding);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
        return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
    }
41566
f52207d194bf 8157753: Audio replay enhancement
serb
parents: 25859
diff changeset
   185
    if (channels <= 0) {
f52207d194bf 8157753: Audio replay enhancement
serb
parents: 25859
diff changeset
   186
        ERROR1(" DAUDIO_Open: Invalid number of channels=%d!\n", channels);
f52207d194bf 8157753: Audio replay enhancement
serb
parents: 25859
diff changeset
   187
        return NULL;
f52207d194bf 8157753: Audio replay enhancement
serb
parents: 25859
diff changeset
   188
    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
    info = (SolPcmInfo*) malloc(sizeof(SolPcmInfo));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
    if (!info) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
        ERROR0("Out of memory\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
        return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
    memset(info, 0, sizeof(SolPcmInfo));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
    info->frameSize = frameSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
    info->fd = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
    if (isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
        openMode = O_WRONLY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
        openMode = O_RDONLY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
#ifndef __linux__
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
    /* blackdown does not use NONBLOCK */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
    openMode |= O_NONBLOCK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
    if (getAudioDeviceDescriptionByIndex(mixerIndex, &desc, FALSE)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
        info->fd = open(desc.path, openMode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
    if (info->fd < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
        ERROR1("Couldn't open audio device for mixer %d!\n", mixerIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
        free(info);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
        return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
    /* set to multiple open */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
    if (ioctl(info->fd, AUDIO_MIXER_MULTIPLE_OPEN, NULL) >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
        TRACE1("DAUDIO_Open: %s set to multiple open\n", desc.path);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
        ERROR1("DAUDIO_Open: ioctl AUDIO_MIXER_MULTIPLE_OPEN failed on %s!\n", desc.path);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
    AUDIO_INITINFO(&(info->info));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
    /* need AUDIO_GETINFO ioctl to get this to work on solaris x86  */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
    err = ioctl(info->fd, AUDIO_GETINFO, &(info->info));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
    /* not valid to call AUDIO_SETINFO ioctl with all the fields from AUDIO_GETINFO. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
    AUDIO_INITINFO(&(info->info));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
    if (isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
        info->info.play.sample_rate = sampleRate;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
        info->info.play.precision = sampleSizeInBits;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
        info->info.play.channels = channels;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
        info->info.play.encoding = AUDIO_ENCODING_LINEAR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
        info->info.play.buffer_size = bufferSizeInBytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
        info->info.play.pause = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
        info->info.record.sample_rate = sampleRate;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
        info->info.record.precision = sampleSizeInBits;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
        info->info.record.channels = channels;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
        info->info.record.encoding = AUDIO_ENCODING_LINEAR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
        info->info.record.buffer_size = bufferSizeInBytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
        info->info.record.pause = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
    err = ioctl(info->fd, AUDIO_SETINFO,  &(info->info));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
    if (err < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
        ERROR0("DAUDIO_Open: could not set info!\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
        DAUDIO_Close((void*) info, isSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
        return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
    DAUDIO_Flush((void*) info, isSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
    err = ioctl(info->fd, AUDIO_GETINFO, &(info->info));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
    if (err >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
        if (isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
            info->bufferSizeInBytes = info->info.play.buffer_size;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
            info->bufferSizeInBytes = info->info.record.buffer_size;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
        TRACE2("DAUDIO: buffersize in bytes: requested=%d, got %d\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
               (int) bufferSizeInBytes,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
               (int) info->bufferSizeInBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
        ERROR0("DAUDIO_Open: cannot get info!\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
        DAUDIO_Close((void*) info, isSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
        return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
    TRACE0("< DAUDIO_Open: Opened device successfully.\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
    return (void*) info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
int DAUDIO_Start(void* id, int isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
    SolPcmInfo* info = (SolPcmInfo*) id;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
    int err, modified;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
    audio_info_t audioInfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
    TRACE0("> DAUDIO_Start\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
    AUDIO_INITINFO(&audioInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
    err = ioctl(info->fd, AUDIO_GETINFO, &audioInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
    if (err >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
        // unpause
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
        modified = FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
        if (isSource && audioInfo.play.pause) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
            audioInfo.play.pause = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
            modified = TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
        if (!isSource && audioInfo.record.pause) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
            audioInfo.record.pause = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
            modified = TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
        if (modified) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
            err = ioctl(info->fd, AUDIO_SETINFO, &audioInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
    TRACE1("< DAUDIO_Start %s\n", (err>=0)?"success":"error");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
    return (err >= 0)?TRUE:FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
int DAUDIO_Stop(void* id, int isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
    SolPcmInfo* info = (SolPcmInfo*) id;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
    int err, modified;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
    audio_info_t audioInfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
    TRACE0("> DAUDIO_Stop\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
    AUDIO_INITINFO(&audioInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
    err = ioctl(info->fd, AUDIO_GETINFO, &audioInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
    if (err >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
        // pause
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
        modified = FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
        if (isSource && !audioInfo.play.pause) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
            audioInfo.play.pause = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
            modified = TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
        if (!isSource && !audioInfo.record.pause) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
            audioInfo.record.pause = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
            modified = TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
        if (modified) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
            err = ioctl(info->fd, AUDIO_SETINFO, &audioInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
    TRACE1("< DAUDIO_Stop %s\n", (err>=0)?"success":"error");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
    return (err >= 0)?TRUE:FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
void DAUDIO_Close(void* id, int isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
    SolPcmInfo* info = (SolPcmInfo*) id;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
    TRACE0("DAUDIO_Close\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
    if (info != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
        if (info->fd >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
            DAUDIO_Flush(id, isSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
            close(info->fd);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
        free(info);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
#ifndef USE_TRACE
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
/* close to 2^31 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
#define POSITION_MAX 2000000000
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
#else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
/* for testing */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
#define POSITION_MAX 1000000
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
void resetErrorFlagAndAdjustPosition(SolPcmInfo* info, int isSource, int count) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
    audio_info_t audioInfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
    audio_prinfo_t* prinfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
    int err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
    int offset = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
    int underrun = FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
    int devBytes = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
    if (count > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
        info->transferedBytes += count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
        if (isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
            prinfo = &(audioInfo.play);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
            prinfo = &(audioInfo.record);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
        AUDIO_INITINFO(&audioInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
        err = ioctl(info->fd, AUDIO_GETINFO, &audioInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
        if (err >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
            underrun = prinfo->error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
            devBytes = prinfo->samples * info->frameSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
        AUDIO_INITINFO(&audioInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
        if (underrun) {
21278
ef8a3a2a72f2 8022746: List of spelling errors in API doc
malenkov
parents: 5506
diff changeset
   378
            /* if an underrun occurred, reset */
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
            ERROR1("DAUDIO_Write/Read: Underrun/overflow: adjusting positionOffset by %d:\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
                   (devBytes - info->transferedBytes));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
            ERROR1("    devBytes from %d to 0, ", devBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
            ERROR2(" positionOffset from %d to %d ",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
                   (int) info->positionOffset,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
                   (int) (info->positionOffset + info->transferedBytes));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
            ERROR1(" transferedBytes from %d to 0\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
                   (int) info->transferedBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
            prinfo->samples = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
            info->positionOffset += info->transferedBytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
            info->transferedBytes = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
        else if (info->transferedBytes > POSITION_MAX) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
            /* we will reset transferedBytes and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
             * the samples field in prinfo
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
            offset = devBytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
            prinfo->samples = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
        /* reset error flag */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
        prinfo->error = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
        err = ioctl(info->fd, AUDIO_SETINFO, &audioInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
        if (err >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
            if (offset > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
                /* upon exit of AUDIO_SETINFO, the samples parameter
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
                 * was set to the previous value. This is our
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
                 * offset.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
                 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
                TRACE1("Adjust samplePos: offset=%d, ", (int) offset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
                TRACE2("transferedBytes=%d -> %d, ",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
                       (int) info->transferedBytes,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
                       (int) (info->transferedBytes - offset));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
                TRACE2("positionOffset=%d -> %d\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
                       (int) (info->positionOffset),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
                       (int) (((int) info->positionOffset) + offset));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
                info->transferedBytes -= offset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
                info->positionOffset += offset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
            ERROR0("DAUDIO: resetErrorFlagAndAdjustPosition ioctl failed!\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
// returns -1 on error
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
int DAUDIO_Write(void* id, char* data, int byteSize) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
    SolPcmInfo* info = (SolPcmInfo*) id;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
    int ret = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
    TRACE1("> DAUDIO_Write %d bytes\n", byteSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
    if (info!=NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
        ret = write(info->fd, data, byteSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
        resetErrorFlagAndAdjustPosition(info, TRUE, ret);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
        /* sets ret to -1 if buffer full, no error! */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
        if (ret < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
            ret = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
    TRACE1("< DAUDIO_Write: returning %d bytes.\n", ret);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
    return ret;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
// returns -1 on error
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
int DAUDIO_Read(void* id, char* data, int byteSize) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
    SolPcmInfo* info = (SolPcmInfo*) id;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
    int ret = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
    TRACE1("> DAUDIO_Read %d bytes\n", byteSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
    if (info != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
        ret = read(info->fd, data, byteSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
        resetErrorFlagAndAdjustPosition(info, TRUE, ret);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
        /* sets ret to -1 if buffer full, no error! */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
        if (ret < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
            ret = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
    TRACE1("< DAUDIO_Read: returning %d bytes.\n", ret);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
    return ret;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
int DAUDIO_GetBufferSize(void* id, int isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
    SolPcmInfo* info = (SolPcmInfo*) id;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
    if (info) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
        return info->bufferSizeInBytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
    return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
int DAUDIO_StillDraining(void* id, int isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
    SolPcmInfo* info = (SolPcmInfo*) id;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
    audio_info_t audioInfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
    audio_prinfo_t* prinfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
    int ret = FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
    if (info!=NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
        if (isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
            prinfo = &(audioInfo.play);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
            prinfo = &(audioInfo.record);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
        /* check error flag */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
        AUDIO_INITINFO(&audioInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
        ioctl(info->fd, AUDIO_GETINFO, &audioInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
        ret = (prinfo->error != 0)?FALSE:TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
    return ret;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
int getDevicePosition(SolPcmInfo* info, int isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
    audio_info_t audioInfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
    audio_prinfo_t* prinfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
    int err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
    if (isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
        prinfo = &(audioInfo.play);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
        prinfo = &(audioInfo.record);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
    AUDIO_INITINFO(&audioInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
    err = ioctl(info->fd, AUDIO_GETINFO, &audioInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
    if (err >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
        /*TRACE2("---> device paused: %d  eof=%d\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
               prinfo->pause, prinfo->eof);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
        */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
        return (int) (prinfo->samples * info->frameSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
    ERROR0("DAUDIO: getDevicePosition: ioctl failed!\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
    return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
int DAUDIO_Flush(void* id, int isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
    SolPcmInfo* info = (SolPcmInfo*) id;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
    int err = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
    int pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
    TRACE0("DAUDIO_Flush\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
    if (info) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
        if (isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
            err = ioctl(info->fd, I_FLUSH, FLUSHW);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
            err = ioctl(info->fd, I_FLUSH, FLUSHR);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
        if (err >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
            /* resets the transferedBytes parameter to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
             * the current samples count of the device
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
            pos = getDevicePosition(info, isSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
            if (pos >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
                info->transferedBytes = pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
    if (err < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
        ERROR0("ERROR in DAUDIO_Flush\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
    return (err < 0)?FALSE:TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
int DAUDIO_GetAvailable(void* id, int isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
    SolPcmInfo* info = (SolPcmInfo*) id;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
    int ret = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
    int pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
    if (info) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
        /* unfortunately, the STREAMS architecture
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
         * seems to not have a method for querying
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
         * the available bytes to read/write!
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
         * estimate it...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
        pos = getDevicePosition(info, isSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
        if (pos >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
            if (isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
                /* we usually have written more bytes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
                 * to the queue than the device position should be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
                 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
                ret = (info->bufferSizeInBytes) - (info->transferedBytes - pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
                /* for record, the device stream should
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
                 * be usually ahead of our read actions
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
                 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
                ret = pos - info->transferedBytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
            if (ret > info->bufferSizeInBytes) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
                ERROR2("DAUDIO_GetAvailable: available=%d, too big at bufferSize=%d!\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
                       (int) ret, (int) info->bufferSizeInBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
                ERROR2("                     devicePos=%d, transferedBytes=%d\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
                       (int) pos, (int) info->transferedBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
                ret = info->bufferSizeInBytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
            else if (ret < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
                ERROR1("DAUDIO_GetAvailable: available=%d, in theory not possible!\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
                       (int) ret);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
                ERROR2("                     devicePos=%d, transferedBytes=%d\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
                       (int) pos, (int) info->transferedBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
                ret = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
    TRACE1("DAUDIO_GetAvailable returns %d bytes\n", ret);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
    return ret;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
INT64 DAUDIO_GetBytePosition(void* id, int isSource, INT64 javaBytePos) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
    SolPcmInfo* info = (SolPcmInfo*) id;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
    int ret;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
    int pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
    INT64 result = javaBytePos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
    if (info) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
        pos = getDevicePosition(info, isSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
        if (pos >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
            result = info->positionOffset + pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
    //printf("getbyteposition: javaBytePos=%d , return=%d\n", (int) javaBytePos, (int) result);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
    return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
void DAUDIO_SetBytePosition(void* id, int isSource, INT64 javaBytePos) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
    SolPcmInfo* info = (SolPcmInfo*) id;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
    int ret;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
    int pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
    if (info) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
        pos = getDevicePosition(info, isSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
        if (pos >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
            info->positionOffset = javaBytePos - pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
int DAUDIO_RequiresServicing(void* id, int isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
    // never need servicing on Solaris
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
    return FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
void DAUDIO_Service(void* id, int isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
    // never need servicing on Solaris
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
#endif // USE_DAUDIO