jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_SolarisOS_PCM.c
author chegar
Sun, 17 Aug 2014 15:54:13 +0100
changeset 25859 3317bb8137f4
parent 23010 jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_SolarisOS_PCM.c@6dadb192ad81
child 41566 f52207d194bf
permissions -rw-r--r--
8054834: Modular Source Code Reviewed-by: alanb, chegar, ihse, mduigou Contributed-by: alan.bateman@oracle.com, alex.buckley@oracle.com, chris.hegarty@oracle.com, erik.joelsson@oracle.com, jonathan.gibbons@oracle.com, karen.kinnear@oracle.com, magnus.ihse.bursie@oracle.com, mandy.chung@oracle.com, mark.reinhold@oracle.com, paul.sandoz@oracle.com
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
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
INT32 DAUDIO_GetDirectAudioDeviceCount() {
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
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
    info = (SolPcmInfo*) malloc(sizeof(SolPcmInfo));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
    if (!info) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
        ERROR0("Out of memory\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
        return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
    memset(info, 0, sizeof(SolPcmInfo));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
    info->frameSize = frameSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
    info->fd = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
    if (isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
        openMode = O_WRONLY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
        openMode = O_RDONLY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
#ifndef __linux__
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
    /* blackdown does not use NONBLOCK */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
    openMode |= O_NONBLOCK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
    if (getAudioDeviceDescriptionByIndex(mixerIndex, &desc, FALSE)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
        info->fd = open(desc.path, openMode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
    if (info->fd < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
        ERROR1("Couldn't open audio device for mixer %d!\n", mixerIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
        free(info);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
        return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
    /* set to multiple open */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
    if (ioctl(info->fd, AUDIO_MIXER_MULTIPLE_OPEN, NULL) >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
        TRACE1("DAUDIO_Open: %s set to multiple open\n", desc.path);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
        ERROR1("DAUDIO_Open: ioctl AUDIO_MIXER_MULTIPLE_OPEN failed on %s!\n", desc.path);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
    AUDIO_INITINFO(&(info->info));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
    /* need AUDIO_GETINFO ioctl to get this to work on solaris x86  */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
    err = ioctl(info->fd, AUDIO_GETINFO, &(info->info));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
    /* not valid to call AUDIO_SETINFO ioctl with all the fields from AUDIO_GETINFO. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
    AUDIO_INITINFO(&(info->info));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
    if (isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
        info->info.play.sample_rate = sampleRate;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
        info->info.play.precision = sampleSizeInBits;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
        info->info.play.channels = channels;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
        info->info.play.encoding = AUDIO_ENCODING_LINEAR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
        info->info.play.buffer_size = bufferSizeInBytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
        info->info.play.pause = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
        info->info.record.sample_rate = sampleRate;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
        info->info.record.precision = sampleSizeInBits;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
        info->info.record.channels = channels;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
        info->info.record.encoding = AUDIO_ENCODING_LINEAR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
        info->info.record.buffer_size = bufferSizeInBytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
        info->info.record.pause = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
    err = ioctl(info->fd, AUDIO_SETINFO,  &(info->info));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
    if (err < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
        ERROR0("DAUDIO_Open: could not set info!\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
        DAUDIO_Close((void*) info, isSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
        return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
    DAUDIO_Flush((void*) info, isSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
    err = ioctl(info->fd, AUDIO_GETINFO, &(info->info));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
    if (err >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
        if (isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
            info->bufferSizeInBytes = info->info.play.buffer_size;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
            info->bufferSizeInBytes = info->info.record.buffer_size;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
        TRACE2("DAUDIO: buffersize in bytes: requested=%d, got %d\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
               (int) bufferSizeInBytes,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
               (int) info->bufferSizeInBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
        ERROR0("DAUDIO_Open: cannot get info!\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
        DAUDIO_Close((void*) info, isSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
        return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
    TRACE0("< DAUDIO_Open: Opened device successfully.\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
    return (void*) info;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
int DAUDIO_Start(void* id, int isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
    SolPcmInfo* info = (SolPcmInfo*) id;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
    int err, modified;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
    audio_info_t audioInfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
    TRACE0("> DAUDIO_Start\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
    AUDIO_INITINFO(&audioInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
    err = ioctl(info->fd, AUDIO_GETINFO, &audioInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
    if (err >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
        // unpause
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
        modified = FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
        if (isSource && audioInfo.play.pause) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
            audioInfo.play.pause = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
            modified = TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
        if (!isSource && audioInfo.record.pause) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
            audioInfo.record.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 (modified) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
            err = ioctl(info->fd, AUDIO_SETINFO, &audioInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
    TRACE1("< DAUDIO_Start %s\n", (err>=0)?"success":"error");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
    return (err >= 0)?TRUE:FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
int DAUDIO_Stop(void* id, int isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
    SolPcmInfo* info = (SolPcmInfo*) id;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
    int err, modified;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
    audio_info_t audioInfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
    TRACE0("> DAUDIO_Stop\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
    AUDIO_INITINFO(&audioInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
    err = ioctl(info->fd, AUDIO_GETINFO, &audioInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
    if (err >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
        // pause
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
        modified = FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
        if (isSource && !audioInfo.play.pause) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
            audioInfo.play.pause = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
            modified = TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
        if (!isSource && !audioInfo.record.pause) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
            audioInfo.record.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 (modified) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
            err = ioctl(info->fd, AUDIO_SETINFO, &audioInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
    TRACE1("< DAUDIO_Stop %s\n", (err>=0)?"success":"error");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
    return (err >= 0)?TRUE:FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
void DAUDIO_Close(void* id, int isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
    SolPcmInfo* info = (SolPcmInfo*) id;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
    TRACE0("DAUDIO_Close\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
    if (info != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
        if (info->fd >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
            DAUDIO_Flush(id, isSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
            close(info->fd);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
        free(info);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
#ifndef USE_TRACE
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
/* close to 2^31 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
#define POSITION_MAX 2000000000
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
#else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
/* for testing */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
#define POSITION_MAX 1000000
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
void resetErrorFlagAndAdjustPosition(SolPcmInfo* info, int isSource, int count) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
    audio_info_t audioInfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
    audio_prinfo_t* prinfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
    int err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
    int offset = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
    int underrun = FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
    int devBytes = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
    if (count > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
        info->transferedBytes += count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
        if (isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
            prinfo = &(audioInfo.play);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
            prinfo = &(audioInfo.record);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
        AUDIO_INITINFO(&audioInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
        err = ioctl(info->fd, AUDIO_GETINFO, &audioInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
        if (err >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
            underrun = prinfo->error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
            devBytes = prinfo->samples * info->frameSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
        AUDIO_INITINFO(&audioInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
        if (underrun) {
21278
ef8a3a2a72f2 8022746: List of spelling errors in API doc
malenkov
parents: 5506
diff changeset
   374
            /* if an underrun occurred, reset */
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
            ERROR1("DAUDIO_Write/Read: Underrun/overflow: adjusting positionOffset by %d:\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
                   (devBytes - info->transferedBytes));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
            ERROR1("    devBytes from %d to 0, ", devBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
            ERROR2(" positionOffset from %d to %d ",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
                   (int) info->positionOffset,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
                   (int) (info->positionOffset + info->transferedBytes));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
            ERROR1(" transferedBytes from %d to 0\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
                   (int) info->transferedBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
            prinfo->samples = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
            info->positionOffset += info->transferedBytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
            info->transferedBytes = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
        else if (info->transferedBytes > POSITION_MAX) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
            /* we will reset transferedBytes and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
             * the samples field in prinfo
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
            offset = devBytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
            prinfo->samples = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
        /* reset error flag */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
        prinfo->error = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
        err = ioctl(info->fd, AUDIO_SETINFO, &audioInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
        if (err >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
            if (offset > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
                /* upon exit of AUDIO_SETINFO, the samples parameter
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
                 * was set to the previous value. This is our
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
                 * offset.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
                 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
                TRACE1("Adjust samplePos: offset=%d, ", (int) offset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
                TRACE2("transferedBytes=%d -> %d, ",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
                       (int) info->transferedBytes,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
                       (int) (info->transferedBytes - offset));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
                TRACE2("positionOffset=%d -> %d\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
                       (int) (info->positionOffset),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
                       (int) (((int) info->positionOffset) + offset));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
                info->transferedBytes -= offset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
                info->positionOffset += offset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
            ERROR0("DAUDIO: resetErrorFlagAndAdjustPosition ioctl failed!\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
// returns -1 on error
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
int DAUDIO_Write(void* id, char* data, int byteSize) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
    SolPcmInfo* info = (SolPcmInfo*) id;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
    int ret = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
    TRACE1("> DAUDIO_Write %d bytes\n", byteSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
    if (info!=NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
        ret = write(info->fd, data, byteSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
        resetErrorFlagAndAdjustPosition(info, TRUE, ret);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
        /* sets ret to -1 if buffer full, no error! */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
        if (ret < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
            ret = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
    TRACE1("< DAUDIO_Write: returning %d bytes.\n", ret);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
    return ret;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
// returns -1 on error
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
int DAUDIO_Read(void* id, char* data, int byteSize) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
    SolPcmInfo* info = (SolPcmInfo*) id;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
    int ret = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
    TRACE1("> DAUDIO_Read %d bytes\n", byteSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
    if (info != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
        ret = read(info->fd, data, byteSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
        resetErrorFlagAndAdjustPosition(info, TRUE, ret);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
        /* sets ret to -1 if buffer full, no error! */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
        if (ret < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
            ret = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
    TRACE1("< DAUDIO_Read: returning %d bytes.\n", ret);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
    return ret;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
int DAUDIO_GetBufferSize(void* id, int isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
    SolPcmInfo* info = (SolPcmInfo*) id;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
    if (info) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
        return info->bufferSizeInBytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
    return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
int DAUDIO_StillDraining(void* id, int isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
    SolPcmInfo* info = (SolPcmInfo*) id;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
    audio_info_t audioInfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
    audio_prinfo_t* prinfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
    int ret = FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
    if (info!=NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
        if (isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
            prinfo = &(audioInfo.play);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
            prinfo = &(audioInfo.record);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
        /* check error flag */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
        AUDIO_INITINFO(&audioInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
        ioctl(info->fd, AUDIO_GETINFO, &audioInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
        ret = (prinfo->error != 0)?FALSE:TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
    return ret;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
int getDevicePosition(SolPcmInfo* info, int isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
    audio_info_t audioInfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
    audio_prinfo_t* prinfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
    int err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
    if (isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
        prinfo = &(audioInfo.play);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
        prinfo = &(audioInfo.record);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
    AUDIO_INITINFO(&audioInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
    err = ioctl(info->fd, AUDIO_GETINFO, &audioInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
    if (err >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
        /*TRACE2("---> device paused: %d  eof=%d\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
               prinfo->pause, prinfo->eof);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
        */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
        return (int) (prinfo->samples * info->frameSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
    ERROR0("DAUDIO: getDevicePosition: ioctl failed!\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
    return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
int DAUDIO_Flush(void* id, int isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
    SolPcmInfo* info = (SolPcmInfo*) id;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
    int err = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
    int pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
    TRACE0("DAUDIO_Flush\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
    if (info) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
        if (isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
            err = ioctl(info->fd, I_FLUSH, FLUSHW);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
            err = ioctl(info->fd, I_FLUSH, FLUSHR);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
        if (err >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
            /* resets the transferedBytes parameter to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
             * the current samples count of the device
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
            pos = getDevicePosition(info, isSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
            if (pos >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
                info->transferedBytes = pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
    if (err < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
        ERROR0("ERROR in DAUDIO_Flush\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
    return (err < 0)?FALSE:TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
int DAUDIO_GetAvailable(void* id, int isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
    SolPcmInfo* info = (SolPcmInfo*) id;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
    int ret = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
    int pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
    if (info) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
        /* unfortunately, the STREAMS architecture
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
         * seems to not have a method for querying
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
         * the available bytes to read/write!
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
         * estimate it...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
        pos = getDevicePosition(info, isSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
        if (pos >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
            if (isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
                /* we usually have written more bytes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
                 * to the queue than the device position should be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
                 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
                ret = (info->bufferSizeInBytes) - (info->transferedBytes - pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
                /* for record, the device stream should
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
                 * be usually ahead of our read actions
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
                 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
                ret = pos - info->transferedBytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
            if (ret > info->bufferSizeInBytes) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
                ERROR2("DAUDIO_GetAvailable: available=%d, too big at bufferSize=%d!\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
                       (int) ret, (int) info->bufferSizeInBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
                ERROR2("                     devicePos=%d, transferedBytes=%d\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
                       (int) pos, (int) info->transferedBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
                ret = info->bufferSizeInBytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
            else if (ret < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
                ERROR1("DAUDIO_GetAvailable: available=%d, in theory not possible!\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
                       (int) ret);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
                ERROR2("                     devicePos=%d, transferedBytes=%d\n",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
                       (int) pos, (int) info->transferedBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
                ret = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
    TRACE1("DAUDIO_GetAvailable returns %d bytes\n", ret);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
    return ret;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
INT64 DAUDIO_GetBytePosition(void* id, int isSource, INT64 javaBytePos) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
    SolPcmInfo* info = (SolPcmInfo*) id;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
    int ret;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
    int pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
    INT64 result = javaBytePos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
    if (info) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
        pos = getDevicePosition(info, isSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
        if (pos >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
            result = info->positionOffset + pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
    //printf("getbyteposition: javaBytePos=%d , return=%d\n", (int) javaBytePos, (int) result);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
    return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
void DAUDIO_SetBytePosition(void* id, int isSource, INT64 javaBytePos) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
    SolPcmInfo* info = (SolPcmInfo*) id;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
    int ret;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
    int pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
    if (info) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
        pos = getDevicePosition(info, isSource);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
        if (pos >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
            info->positionOffset = javaBytePos - pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
int DAUDIO_RequiresServicing(void* id, int isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
    // never need servicing on Solaris
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
    return FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
void DAUDIO_Service(void* id, int isSource) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
    // never need servicing on Solaris
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
#endif // USE_DAUDIO